11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#!/usr/bin/python 21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# this tool is used to check that the syscall numbers that are in 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# SYSCALLS.TXT correspond to those found in the Linux kernel sources 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# for the arm and i386 architectures 61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectimport sys, re, string, os, commands 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectfrom bionic_utils import * 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# change this if necessary 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectsyscalls_txt = "SYSCALLS.TXT" 131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectdef usage(): 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project print "usage: checksyscalls [options] [kernel_headers_rootdir]" 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project print " options: -v enable verbose mode" 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sys.exit(1) 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectlinux_root = None 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectsyscalls_file = None 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectdef parse_command_line(args): 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project global linux_root, syscalls_file, verbose 251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project program = args[0] 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project args = args[1:] 281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while len(args) > 0 and args[0][0] == "-": 291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project option = args[0][1:] 301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project args = args[1:] 311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if option == "v": 331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project D_setlevel(1) 341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else: 351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project usage() 361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if len(args) > 2: 381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project usage() 391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if len(args) == 0: 411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project linux_root = find_kernel_headers() 421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if linux_root == None: 43fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner print "Could not locate original or system kernel headers root directory." 44fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner print "Please specify one when calling this program, i.e. 'checksyscalls <headers-directory>'" 451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sys.exit(1) 461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project print "using the following kernel headers root: '%s'" % linux_root 471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else: 481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project linux_root = args[0] 491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if not os.path.isdir(linux_root): 501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project print "the directory '%s' does not exist. aborting\n" % headers_root 511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sys.exit(1) 521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectparse_command_line(sys.argv) 541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectsyscalls_file = find_file_from_upwards(None, syscalls_txt) 561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectif not syscalls_file: 571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project print "could not locate the %s file. Aborting" % syscalls_txt 581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sys.exit(1) 591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectprint "parsing %s" % syscalls_file 611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# read the syscalls description file 631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# 641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectparser = SysCallsTxtParser() 661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectparser.parse_file(syscalls_file) 671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectsyscalls = parser.syscalls 681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectre_nr_line = re.compile( r"#define __NR_(\w*)\s*\(__NR_SYSCALL_BASE\+\s*(\w*)\)" ) 701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectre_nr_clock_line = re.compile( r"#define __NR_(\w*)\s*\(__NR_timer_create\+(\w*)\)" ) 711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectre_arm_nr_line = re.compile( r"#define __ARM_NR_(\w*)\s*\(__ARM_NR_BASE\+\s*(\w*)\)" ) 721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectre_x86_line = re.compile( r"#define __NR_(\w*)\s*([0-9]*)" ) 731fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandhamre_mips_line = re.compile( r"#define __NR_(\w*)\s*\(__NR_Linux\s*\+\s*([0-9]*)\)" ) 741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# now read the Linux arm header 761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectdef process_nr_line(line,dict): 771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 781fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham m = re_mips_line.match(line) 791fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham if m: 801fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham if dict["Linux"]==4000: 811fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham dict[m.group(1)] = int(m.group(2)) 821fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham return 831fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham 841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project m = re_nr_line.match(line) 851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if m: 861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project dict[m.group(1)] = int(m.group(2)) 871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return 881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project m = re_nr_clock_line.match(line) 901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if m: 911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project dict[m.group(1)] = int(m.group(2)) + 259 921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return 931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project m = re_arm_nr_line.match(line) 951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if m: 9622b137711a2f262af78611ac57d53ddc1b0e6ff9JP Abgrall offset_str = m.group(2) 9722b137711a2f262af78611ac57d53ddc1b0e6ff9JP Abgrall #print "%s = %s" % (m.group(1), offset_str) 9822b137711a2f262af78611ac57d53ddc1b0e6ff9JP Abgrall base = 10 9922b137711a2f262af78611ac57d53ddc1b0e6ff9JP Abgrall if offset_str.lower().startswith("0x"): 10022b137711a2f262af78611ac57d53ddc1b0e6ff9JP Abgrall # Processing something similar to 10122b137711a2f262af78611ac57d53ddc1b0e6ff9JP Abgrall # #define __ARM_NR_cmpxchg (__ARM_NR_BASE+0x00fff0) 10222b137711a2f262af78611ac57d53ddc1b0e6ff9JP Abgrall base = 16 10322b137711a2f262af78611ac57d53ddc1b0e6ff9JP Abgrall dict["ARM_"+m.group(1)] = int(offset_str, base) + 0x0f0000 1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return 1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project m = re_x86_line.match(line) 1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if m: 1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project # try block because the ARM header has some #define _NR_XXXXX /* nothing */ 1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project try: 1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project #print "%s = %s" % (m.group(1), m.group(2)) 1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project dict[m.group(1)] = int(m.group(2)) 1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project except: 1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pass 1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return 1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectdef process_header(header_file,dict): 1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fp = open(header_file) 1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project D("reading "+header_file) 1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for line in fp.xreadlines(): 1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project line = line.strip() 1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if not line: continue 1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project process_nr_line(line,dict) 1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fp.close() 1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectarm_dict = {} 1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectx86_dict = {} 1281fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandhammips_dict = {} 1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 130fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner# remove trailing slash from the linux_root, if any 1311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectif linux_root[-1] == '/': 1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project linux_root = linux_root[:-1] 1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 134fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turnerarm_unistd = find_arch_header(linux_root, "arm", "unistd.h") 135fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turnerif not arm_unistd: 136fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner print "WEIRD: Could not locate the ARM unistd.h kernel header file," 137fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner print "maybe using a different set of kernel headers might help." 1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sys.exit(1) 1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# on recent kernels, asm-i386 and asm-x64_64 have been merged into asm-x86 1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# with two distinct unistd_32.h and unistd_64.h definition files. 1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# take care of this here 1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# 144fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turnerx86_unistd = find_arch_header(linux_root, "i386", "unistd.h") 145fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turnerif not x86_unistd: 146fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner x86_unistd = find_arch_header(linux_root, "x86", "unistd_32.h") 147fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner if not x86_unistd: 148fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner print "WEIRD: Could not locate the i386/x86 unistd.h header file," 149fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner print "maybe using a different set of kernel headers might help." 1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sys.exit(1) 1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1521fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandhammips_unistd = find_arch_header(linux_root, "mips", "unistd.h") 1531fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandhamif not mips_unistd: 1541fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham print "WEIRD: Could not locate the Mips unistd.h kernel header file," 1551fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham print "maybe using a different set of kernel headers might help." 1561fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham sys.exit(1) 1571fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham 158fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turnerprocess_header( arm_unistd, arm_dict ) 1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectprocess_header( x86_unistd, x86_dict ) 1601fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandhamprocess_header( mips_unistd, mips_dict ) 1611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# now perform the comparison 1631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecterrors = 0 164fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner 165fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turnerdef check_syscalls(archname, idname, arch_dict): 166fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner errors = 0 167fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner for sc in syscalls: 168fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner sc_name = sc["name"] 169fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner sc_id = sc[idname] 170fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner if sc_id >= 0: 171fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner if not arch_dict.has_key(sc_name): 1721fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham print "error: %s syscall %s not defined, should be %d" % (archname, sc_name, sc_id) 173fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner errors += 1 174fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner elif not arch_dict.has_key(sc_name): 1751fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham print "error: %s syscall %s is not implemented" % (archname, sc_name) 176fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner errors += 1 177fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner elif arch_dict[sc_name] != sc_id: 1781fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandham print "error: %s syscall %s should be %d instead of %d" % (archname, sc_name, arch_dict[sc_name], sc_id) 179fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner errors += 1 180fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner return errors 181fc2693110ee8a2ba22a445ad9855fbe9e118d439David 'Digit' Turner 1821fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandhamerrors += check_syscalls("arm", "armid", arm_dict) 1831fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandhamerrors += check_syscalls("x86", "x86id", x86_dict) 1841fa0d849576555577ffd9675677a3c95f21b754eRaghu Gandhamerrors += check_syscalls("mips", "mipsid", mips_dict) 1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectif errors == 0: 1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project print "congratulations, everything's fine !!" 1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectelse: 1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project print "correct %d errors !!" % errors 190