1#!/usr/bin/python 2# 3# this tool is used to check that the syscall numbers that are in 4# SYSCALLS.TXT correspond to those found in the Linux kernel sources 5# for the arm and i386 architectures 6# 7 8import sys, re, string, os, commands 9from bionic_utils import * 10 11# change this if necessary 12syscalls_txt = "SYSCALLS.TXT" 13 14def usage(): 15 print "usage: checksyscalls [options] [kernel_headers_rootdir]" 16 print " options: -v enable verbose mode" 17 sys.exit(1) 18 19 20linux_root = None 21syscalls_file = None 22 23def parse_command_line(args): 24 global linux_root, syscalls_file, verbose 25 26 program = args[0] 27 args = args[1:] 28 while len(args) > 0 and args[0][0] == "-": 29 option = args[0][1:] 30 args = args[1:] 31 32 if option == "v": 33 D_setlevel(1) 34 else: 35 usage() 36 37 if len(args) > 2: 38 usage() 39 40 if len(args) == 0: 41 linux_root = find_kernel_headers() 42 if linux_root == None: 43 print "could not locate this system kernel headers root directory, please" 44 print "specify one when calling this program, i.e. 'checksyscalls <headers-directory>'" 45 sys.exit(1) 46 print "using the following kernel headers root: '%s'" % linux_root 47 else: 48 linux_root = args[0] 49 if not os.path.isdir(linux_root): 50 print "the directory '%s' does not exist. aborting\n" % headers_root 51 sys.exit(1) 52 53parse_command_line(sys.argv) 54 55syscalls_file = find_file_from_upwards(None, syscalls_txt) 56if not syscalls_file: 57 print "could not locate the %s file. Aborting" % syscalls_txt 58 sys.exit(1) 59 60print "parsing %s" % syscalls_file 61 62# read the syscalls description file 63# 64 65parser = SysCallsTxtParser() 66parser.parse_file(syscalls_file) 67syscalls = parser.syscalls 68 69re_nr_line = re.compile( r"#define __NR_(\w*)\s*\(__NR_SYSCALL_BASE\+\s*(\w*)\)" ) 70re_nr_clock_line = re.compile( r"#define __NR_(\w*)\s*\(__NR_timer_create\+(\w*)\)" ) 71re_arm_nr_line = re.compile( r"#define __ARM_NR_(\w*)\s*\(__ARM_NR_BASE\+\s*(\w*)\)" ) 72re_x86_line = re.compile( r"#define __NR_(\w*)\s*([0-9]*)" ) 73 74# now read the Linux arm header 75def process_nr_line(line,dict): 76 77 m = re_nr_line.match(line) 78 if m: 79 dict[m.group(1)] = int(m.group(2)) 80 return 81 82 m = re_nr_clock_line.match(line) 83 if m: 84 dict[m.group(1)] = int(m.group(2)) + 259 85 return 86 87 m = re_arm_nr_line.match(line) 88 if m: 89 #print "%s = %s" % (m.group(1), m.group(2)) 90 dict["ARM_"+m.group(1)] = int(m.group(2)) + 0x0f0000 91 return 92 93 m = re_x86_line.match(line) 94 if m: 95 # try block because the ARM header has some #define _NR_XXXXX /* nothing */ 96 try: 97 #print "%s = %s" % (m.group(1), m.group(2)) 98 dict[m.group(1)] = int(m.group(2)) 99 except: 100 pass 101 return 102 103 104def process_header(header_file,dict): 105 fp = open(header_file) 106 D("reading "+header_file) 107 for line in fp.xreadlines(): 108 line = line.strip() 109 if not line: continue 110 process_nr_line(line,dict) 111 fp.close() 112 113arm_dict = {} 114x86_dict = {} 115 116 117# remove trailing slash and '/include' from the linux_root, if any 118if linux_root[-1] == '/': 119 linux_root = linux_root[:-1] 120 121if len(linux_root) > 8 and linux_root[-8:] == '/include': 122 linux_root = linux_root[:-8] 123 124arm_unistd = linux_root + "/include/asm-arm/unistd.h" 125if not os.path.exists(arm_unistd): 126 print "WEIRD: could not locate the ARM unistd.h header file" 127 print "tried searching in '%s'" % arm_unistd 128 print "maybe using a different set of kernel headers might help" 129 sys.exit(1) 130 131# on recent kernels, asm-i386 and asm-x64_64 have been merged into asm-x86 132# with two distinct unistd_32.h and unistd_64.h definition files. 133# take care of this here 134# 135x86_unistd = linux_root + "/include/asm-i386/unistd.h" 136if not os.path.exists(x86_unistd): 137 x86_unistd1 = x86_unistd 138 x86_unistd = linux_root + "/include/asm-x86/unistd_32.h" 139 if not os.path.exists(x86_unistd): 140 print "WEIRD: could not locate the i386/x86 unistd.h header file" 141 print "tried searching in '%s' and '%s'" % (x86_unistd1, x86_unistd) 142 print "maybe using a different set of kernel headers might help" 143 sys.exit(1) 144 145process_header( linux_root+"/include/asm-arm/unistd.h", arm_dict ) 146process_header( x86_unistd, x86_dict ) 147 148# now perform the comparison 149errors = 0 150for sc in syscalls: 151 sc_name = sc["name"] 152 sc_id = sc["id"] 153 if sc_id >= 0: 154 if not arm_dict.has_key(sc_name): 155 print "arm syscall %s not defined !!" % sc_name 156 errors += 1 157 elif arm_dict[sc_name] != sc_id: 158 print "arm syscall %s should be %d instead of %d !!" % (sc_name, arm_dict[sc_name], sc_id) 159 errors += 1 160 161for sc in syscalls: 162 sc_name = sc["name"] 163 sc_id2 = sc["id2"] 164 if sc_id2 >= 0: 165 if not x86_dict.has_key(sc_name): 166 print "x86 syscall %s not defined !!" % sc_name 167 errors += 1 168 elif x86_dict[sc_name] != sc_id2: 169 print "x86 syscall %s should be %d instead of %d !!" % (sc_name, x86_dict[sc_name], sc_id2) 170 errors += 1 171 172if errors == 0: 173 print "congratulations, everything's fine !!" 174else: 175 print "correct %d errors !!" % errors 176