-
Notifications
You must be signed in to change notification settings - Fork 2
/
gen_tables.py
executable file
·117 lines (105 loc) · 3.76 KB
/
gen_tables.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/env python3
import os
import sys
import re
import subprocess
def do_syscall_numbers(unistd_h_path):
syscalls = {}
for line in open(unistd_h_path):
m = re.search(r'^#define\s*__NR_(\w+)\s*(\d+)', line)
if m:
(name, number) = m.groups()
number = int(number)
syscalls[number] = name
return syscalls
def process_define(syscalls, text):
(name, types) = None, None
if text.startswith('SYSCALL_DEFINE('):
m = re.search(r'^SYSCALL_DEFINE\(([^)]+)\)\(([^)]+)\)$', text)
if not m:
print("Unable to parse:", text)
return
name, args = m.groups()
types = [s.strip().rsplit(" ", 1)[0] for s in args.split(",")]
else:
m = re.search(r'^SYSCALL_DEFINE(\d)\(([^,]+)\s*(?:,\s*([^)]+))?\)$', text)
if not m:
print("Unable to parse:", text)
return
nargs, name, argstr = m.groups()
if argstr is not None:
argspec = [s.strip() for s in argstr.split(",")]
types = argspec[0:len(argspec):2]
else:
types = []
syscalls[name] = types
def find_args(linux):
syscalls = {}
find = subprocess.Popen(["find"] +
[os.path.join(linux, d) for d in
"arch/x86 fs include ipc kernel mm net security".split()] +
["-name", "*.c", "-print"],
stdout = subprocess.PIPE)
for f in find.stdout:
fh = open(f.strip())
in_syscall = False
text = ''
for line in fh:
line = line.strip()
if not in_syscall and 'SYSCALL_DEFINE' in line:
text = ''
in_syscall = True
if in_syscall:
text += line
if line.endswith(')'):
in_syscall = False
process_define(syscalls, text)
else:
text += " "
return syscalls
def parse_type(t):
if re.search(r'^(const\s*)?char\s*(__user\s*)?\*\s*$', t):
return "ARG_STR"
if t.endswith('*'):
return "ARG_PTR"
return "ARG_INT"
def write_output(syscalls_h, types, numbers):
out = open(syscalls_h, 'w')
print("#define MAX_SYSCALL_NUM %d" % (max(numbers.keys()),), file=out)
print("const char* syscalls[] = {", file=out)
for i in range(max(numbers.keys()) + 1):
if i not in numbers:
print(" \"nosyscall\",", file=out);
else:
print(" \"%s\"," % (numbers[i],), file=out);
#for num in sorted(numbers.keys()):
# name = numbers[num]
# if name in types:
# args = types[name]
# else:
# args = ["void*"] * 6
#
# print >>out, " %d = {" % (num,)
# print >>out, " .name = \"%s\"," % (name,)
# print >>out, " .nargs = %d," % (len(args,))
# out.write( " .args = {")
# out.write(", ".join([parse_type(t) for t in args] + ["-1"] * (6 - len(args))))
# out.write("}},\n");
print("};", file=out)
out.close()
def main(args):
if not args:
print("Usage: %s /path/to/linux-2.6" % (sys.argv[0],), file=sys.stderr)
return 1
linux_dir = args[0]
if os.uname()[4] == 'x86_64':
#unistd_h = "arch/x86/include/asm/unistd_64.h"
unistd_h = "arch/x86/include/generated/uapi/asm/unistd_64.h"
else:
#unistd_h = "arch/x86/include/asm/unistd_32.h"
unistd_h = "arch/x86/include/generated/uapi/asm/unistd_32.h"
syscall_numbers = do_syscall_numbers(os.path.join(linux_dir, unistd_h))
syscall_types = find_args(linux_dir)
write_output('syscallents.h', syscall_types, syscall_numbers)
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))