blob: 9edb3904483ec77b7a2e5264592340e9aad421db [file] [log] [blame]
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001#!/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