diff options
Diffstat (limited to 'libc/tools/checksyscalls.py')
-rwxr-xr-x | libc/tools/checksyscalls.py | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/libc/tools/checksyscalls.py b/libc/tools/checksyscalls.py new file mode 100755 index 0000000..9edb390 --- /dev/null +++ b/libc/tools/checksyscalls.py @@ -0,0 +1,175 @@ +#!/usr/bin/python +# +# this tool is used to check that the syscall numbers that are in +# SYSCALLS.TXT correspond to those found in the Linux kernel sources +# for the arm and i386 architectures +# + +import sys, re, string, os, commands +from bionic_utils import * + +# change this if necessary +syscalls_txt = "SYSCALLS.TXT" + +def usage(): + print "usage: checksyscalls [options] [kernel_headers_rootdir]" + print " options: -v enable verbose mode" + sys.exit(1) + + +linux_root = None +syscalls_file = None + +def parse_command_line(args): + global linux_root, syscalls_file, verbose + + program = args[0] + args = args[1:] + while len(args) > 0 and args[0][0] == "-": + option = args[0][1:] + args = args[1:] + + if option == "v": + D_setlevel(1) + else: + usage() + + if len(args) > 2: + usage() + + if len(args) == 0: + linux_root = find_kernel_headers() + if linux_root == None: + print "could not locate this system kernel headers root directory, please" + print "specify one when calling this program, i.e. 'checksyscalls <headers-directory>'" + sys.exit(1) + print "using the following kernel headers root: '%s'" % linux_root + else: + linux_root = args[0] + if not os.path.isdir(linux_root): + print "the directory '%s' does not exist. aborting\n" % headers_root + sys.exit(1) + +parse_command_line(sys.argv) + +syscalls_file = find_file_from_upwards(None, syscalls_txt) +if not syscalls_file: + print "could not locate the %s file. Aborting" % syscalls_txt + sys.exit(1) + +print "parsing %s" % syscalls_file + +# read the syscalls description file +# + +parser = SysCallsTxtParser() +parser.parse_file(syscalls_file) +syscalls = parser.syscalls + +re_nr_line = re.compile( r"#define __NR_(\w*)\s*\(__NR_SYSCALL_BASE\+\s*(\w*)\)" ) +re_nr_clock_line = re.compile( r"#define __NR_(\w*)\s*\(__NR_timer_create\+(\w*)\)" ) +re_arm_nr_line = re.compile( r"#define __ARM_NR_(\w*)\s*\(__ARM_NR_BASE\+\s*(\w*)\)" ) +re_x86_line = re.compile( r"#define __NR_(\w*)\s*([0-9]*)" ) + +# now read the Linux arm header +def process_nr_line(line,dict): + + m = re_nr_line.match(line) + if m: + dict[m.group(1)] = int(m.group(2)) + return + + m = re_nr_clock_line.match(line) + if m: + dict[m.group(1)] = int(m.group(2)) + 259 + return + + m = re_arm_nr_line.match(line) + if m: + #print "%s = %s" % (m.group(1), m.group(2)) + dict["ARM_"+m.group(1)] = int(m.group(2)) + 0x0f0000 + return + + m = re_x86_line.match(line) + if m: + # try block because the ARM header has some #define _NR_XXXXX /* nothing */ + try: + #print "%s = %s" % (m.group(1), m.group(2)) + dict[m.group(1)] = int(m.group(2)) + except: + pass + return + + +def process_header(header_file,dict): + fp = open(header_file) + D("reading "+header_file) + for line in fp.xreadlines(): + line = line.strip() + if not line: continue + process_nr_line(line,dict) + fp.close() + +arm_dict = {} +x86_dict = {} + + +# remove trailing slash and '/include' from the linux_root, if any +if linux_root[-1] == '/': + linux_root = linux_root[:-1] + +if len(linux_root) > 8 and linux_root[-8:] == '/include': + linux_root = linux_root[:-8] + +arm_unistd = linux_root + "/include/asm-arm/unistd.h" +if not os.path.exists(arm_unistd): + print "WEIRD: could not locate the ARM unistd.h header file" + print "tried searching in '%s'" % arm_unistd + print "maybe using a different set of kernel headers might help" + sys.exit(1) + +# on recent kernels, asm-i386 and asm-x64_64 have been merged into asm-x86 +# with two distinct unistd_32.h and unistd_64.h definition files. +# take care of this here +# +x86_unistd = linux_root + "/include/asm-i386/unistd.h" +if not os.path.exists(x86_unistd): + x86_unistd1 = x86_unistd + x86_unistd = linux_root + "/include/asm-x86/unistd_32.h" + if not os.path.exists(x86_unistd): + print "WEIRD: could not locate the i386/x86 unistd.h header file" + print "tried searching in '%s' and '%s'" % (x86_unistd1, x86_unistd) + print "maybe using a different set of kernel headers might help" + sys.exit(1) + +process_header( linux_root+"/include/asm-arm/unistd.h", arm_dict ) +process_header( x86_unistd, x86_dict ) + +# now perform the comparison +errors = 0 +for sc in syscalls: + sc_name = sc["name"] + sc_id = sc["id"] + if sc_id >= 0: + if not arm_dict.has_key(sc_name): + print "arm syscall %s not defined !!" % sc_name + errors += 1 + elif arm_dict[sc_name] != sc_id: + print "arm syscall %s should be %d instead of %d !!" % (sc_name, arm_dict[sc_name], sc_id) + errors += 1 + +for sc in syscalls: + sc_name = sc["name"] + sc_id2 = sc["id2"] + if sc_id2 >= 0: + if not x86_dict.has_key(sc_name): + print "x86 syscall %s not defined !!" % sc_name + errors += 1 + elif x86_dict[sc_name] != sc_id2: + print "x86 syscall %s should be %d instead of %d !!" % (sc_name, x86_dict[sc_name], sc_id2) + errors += 1 + +if errors == 0: + print "congratulations, everything's fine !!" +else: + print "correct %d errors !!" % errors |