1
1
#!/usr/bin/env python3
2
2
3
+ import os
3
4
import re
4
5
import tempfile
5
6
import subprocess
6
7
import sys
7
8
8
- from typing import Iterable , Set
9
+ from typing import Iterable , Set , Tuple
9
10
10
11
linux_path = '.'
11
12
12
- SIMPLE_MATH = re .compile ('\((\d+)\s*\+\s*(\d+)\)' )
13
+ SIMPLE_MATH = re .compile ('^[()+0-9a-fx\s]*$' )
14
+ NUMBER = re .compile ('[0-9a-fx]+' )
13
15
14
16
def load_table (path : str , arches : Set [str ]):
15
17
with open ('{}/{}' .format (linux_path , path )) as f :
@@ -22,32 +24,39 @@ def load_table(path: str, arches: Set[str]):
22
24
yield (name , int (nr ))
23
25
24
26
def eval_expr (expr : str ) -> int :
25
- ma = SIMPLE_MATH .match (expr )
26
- if ma :
27
- return int (ma .group (1 )) + int (ma .group (2 ))
28
- raise Exception ('"{}" looks like an expression, but not a supported one' .format (expr ))
27
+ if not SIMPLE_MATH .match (expr ):
28
+ raise Exception ('"{}" looks like an expression, but not a supported one' .format (expr ))
29
+ return sum (int (x .group (0 ), 0 ) for x in NUMBER .finditer (expr ))
29
30
30
31
31
- def load_headers (names : Iterable [str ], arch : str , extra : str = '' ):
32
+ def load_headers (names : Iterable [Tuple [ str , str ] ], arch : str , extra : str = '' ):
32
33
with tempfile .NamedTemporaryFile (mode = 'w+' , suffix = '.h' ) as f :
33
- f .write (extra )
34
- f .write ('\n ' )
35
- f .write ('#include <asm/unistd.h>\n ' )
36
- for name in names :
37
- f .write ('gen_nr {0} __NR_{0}\n ' .format (name ))
38
- f .flush ()
39
- lines = subprocess .check_output (['gcc' , '-nostdinc' ,
40
- '-I' , '{}/arch/{}/include/uapi' .format (linux_path , arch ),
41
- '-I' , '{}/include' .format (linux_path ),
42
- '-P' , # don't include line number markers, which make the output annoying to parse
43
- '-E' , # only preprocess, don't compile
44
- f .name ]).decode ('utf-8' ).split ('\n ' )
34
+ with tempfile .TemporaryDirectory () as temp_include_dir :
35
+ os .mkdir ('{}/asm' .format (temp_include_dir ))
36
+ with open ('{}/asm/unistd-eabi.h' .format (temp_include_dir ), 'w' ):
37
+ pass
38
+ with open ('{}/asm/unistd-common.h' .format (temp_include_dir ), 'w' ):
39
+ pass
40
+
41
+ f .write (extra )
42
+ f .write ('\n ' )
43
+ f .write ('#include <asm/unistd.h>\n ' )
44
+ for prefix , name in names :
45
+ f .write ('gen_nr {prefix}{name} __{prefix}NR_{name}\n ' .format (prefix = prefix , name = name ))
46
+ f .flush ()
47
+ lines = subprocess .check_output (['gcc' , '-nostdinc' ,
48
+ '-I' , '{}/arch/{}/include/uapi' .format (linux_path , arch ),
49
+ '-I' , '{}/include' .format (linux_path ),
50
+ '-I' , temp_include_dir ,
51
+ '-P' , # don't include line number markers, which make the output annoying to parse
52
+ '-E' , # only preprocess, don't compile
53
+ f .name ]).decode ('utf-8' ).split ('\n ' )
45
54
46
55
for line in lines :
47
56
if not line .startswith ('gen_nr ' ):
48
57
continue
49
58
_ , name , nr = line .split (' ' , 2 )
50
- if nr .startswith ('__NR_ ' ):
59
+ if nr .startswith ('__ ' ):
51
60
# unsupported on this arch
52
61
continue
53
62
if nr .startswith ('(' ):
@@ -56,15 +65,18 @@ def load_headers(names: Iterable[str], arch: str, extra: str = ''):
56
65
57
66
58
67
def main ():
59
- names = set (x .group (1 ) for x in re .finditer ('\\ b__NR_([a-z0-9_]+)\\ b' ,
60
- subprocess .check_output (['git' , '--no-pager' , 'grep' , '__NR_' ], cwd = linux_path )
68
+ RE_SYSCALL_NR = re .compile (r'\b__([A-Z]+_)?NR_([a-z0-9_]+)\b' )
69
+ names = set (x .groups () for x in RE_SYSCALL_NR .finditer (
70
+ subprocess .check_output (['git' , '--no-pager' , 'grep' , r'\<__\([A-Z]\+_\)\?NR_' ], cwd = linux_path )
61
71
.decode ('utf-8' )))
62
72
if len (names ) < 380 :
63
73
print ("didn't find anywhere near enough syscalls; hack must have failed" )
74
+ subprocess .check_call (['git' , '--no-pager' , 'grep' , r'\<__\([A-Z]\+_\)\?NR_' ], cwd = linux_path )
64
75
sys .exit (1 )
76
+ ARM_NAMES = ["breakpoint" , "cacheflush" , "usr26" , "usr32" , "set_tls" ]
65
77
numbers = {
66
78
'linux-aarch64' : dict (load_headers (names , 'arm64' )),
67
- 'linux-armeabi' : dict (load_table ('arch/arm/tools/syscall.tbl' , {'common' , 'eabi' })),
79
+ 'linux-armeabi' : dict (list ( load_table ('arch/arm/tools/syscall.tbl' , {'common' , 'eabi' })) + list ( load_headers ( names , 'arm' , '#define __ARM_EABI__' ) )),
68
80
'linux-mips' : dict (load_headers (names , 'mips' ,
69
81
'#define _MIPS_SIM _MIPS_SIM_ABI32' )),
70
82
'linux-mips64' : dict (load_headers (names , 'mips' ,
0 commit comments