blob: 286e727cc7f7c748d632b6100082bd7dcf2fc841 [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:
David 'Digit' Turnerfc269312010-10-11 22:11:06 +020043 print "Could not locate original or system kernel headers root directory."
44 print "Please specify one when calling this program, i.e. 'checksyscalls <headers-directory>'"
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080045 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]*)" )
Raghu Gandham1fa0d842012-01-27 17:51:42 -080073re_mips_line = re.compile( r"#define __NR_(\w*)\s*\(__NR_Linux\s*\+\s*([0-9]*)\)" )
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080074
75# now read the Linux arm header
76def process_nr_line(line,dict):
77
Raghu Gandham1fa0d842012-01-27 17:51:42 -080078 m = re_mips_line.match(line)
79 if m:
80 if dict["Linux"]==4000:
81 dict[m.group(1)] = int(m.group(2))
82 return
83
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080084 m = re_nr_line.match(line)
85 if m:
86 dict[m.group(1)] = int(m.group(2))
87 return
88
89 m = re_nr_clock_line.match(line)
90 if m:
91 dict[m.group(1)] = int(m.group(2)) + 259
92 return
93
94 m = re_arm_nr_line.match(line)
95 if m:
JP Abgrall22b13772011-04-05 19:52:26 -070096 offset_str = m.group(2)
97 #print "%s = %s" % (m.group(1), offset_str)
98 base = 10
99 if offset_str.lower().startswith("0x"):
100 # Processing something similar to
101 # #define __ARM_NR_cmpxchg (__ARM_NR_BASE+0x00fff0)
102 base = 16
103 dict["ARM_"+m.group(1)] = int(offset_str, base) + 0x0f0000
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800104 return
105
106 m = re_x86_line.match(line)
107 if m:
108 # try block because the ARM header has some #define _NR_XXXXX /* nothing */
109 try:
110 #print "%s = %s" % (m.group(1), m.group(2))
111 dict[m.group(1)] = int(m.group(2))
112 except:
113 pass
114 return
115
116
117def process_header(header_file,dict):
118 fp = open(header_file)
119 D("reading "+header_file)
120 for line in fp.xreadlines():
121 line = line.strip()
122 if not line: continue
123 process_nr_line(line,dict)
124 fp.close()
125
126arm_dict = {}
127x86_dict = {}
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800128mips_dict = {}
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800129
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200130# remove trailing slash from the linux_root, if any
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800131if linux_root[-1] == '/':
132 linux_root = linux_root[:-1]
133
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200134arm_unistd = find_arch_header(linux_root, "arm", "unistd.h")
135if not arm_unistd:
136 print "WEIRD: Could not locate the ARM unistd.h kernel header file,"
137 print "maybe using a different set of kernel headers might help."
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800138 sys.exit(1)
139
140# on recent kernels, asm-i386 and asm-x64_64 have been merged into asm-x86
141# with two distinct unistd_32.h and unistd_64.h definition files.
142# take care of this here
143#
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200144x86_unistd = find_arch_header(linux_root, "i386", "unistd.h")
145if not x86_unistd:
146 x86_unistd = find_arch_header(linux_root, "x86", "unistd_32.h")
147 if not x86_unistd:
148 print "WEIRD: Could not locate the i386/x86 unistd.h header file,"
149 print "maybe using a different set of kernel headers might help."
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800150 sys.exit(1)
151
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800152mips_unistd = find_arch_header(linux_root, "mips", "unistd.h")
153if not mips_unistd:
154 print "WEIRD: Could not locate the Mips unistd.h kernel header file,"
155 print "maybe using a different set of kernel headers might help."
156 sys.exit(1)
157
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200158process_header( arm_unistd, arm_dict )
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800159process_header( x86_unistd, x86_dict )
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800160process_header( mips_unistd, mips_dict )
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800161
162# now perform the comparison
163errors = 0
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800164
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200165def check_syscalls(archname, idname, arch_dict):
166 errors = 0
167 for sc in syscalls:
168 sc_name = sc["name"]
169 sc_id = sc[idname]
170 if sc_id >= 0:
171 if not arch_dict.has_key(sc_name):
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800172 print "error: %s syscall %s not defined, should be %d" % (archname, sc_name, sc_id)
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200173 errors += 1
174 elif not arch_dict.has_key(sc_name):
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800175 print "error: %s syscall %s is not implemented" % (archname, sc_name)
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200176 errors += 1
177 elif arch_dict[sc_name] != sc_id:
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800178 print "error: %s syscall %s should be %d instead of %d" % (archname, sc_name, arch_dict[sc_name], sc_id)
David 'Digit' Turnerfc269312010-10-11 22:11:06 +0200179 errors += 1
180 return errors
181
Raghu Gandham1fa0d842012-01-27 17:51:42 -0800182errors += check_syscalls("arm", "armid", arm_dict)
183errors += check_syscalls("x86", "x86id", x86_dict)
184errors += check_syscalls("mips", "mipsid", mips_dict)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800185
186if errors == 0:
187 print "congratulations, everything's fine !!"
188else:
189 print "correct %d errors !!" % errors