Fix the nr_from_src script to get ARM-specific syscalls

This commit is contained in:
Tobias Bucher 2017-05-05 15:07:40 +02:00
parent cee5f075c0
commit 0f498b7a40
4 changed files with 44 additions and 28 deletions

View file

@ -1,5 +1,10 @@
/* automatically generated by nr_from_src.py */
pub const ARM_BREAKPOINT: usize = 983041;
pub const ARM_CACHEFLUSH: usize = 983042;
pub const ARM_SET_TLS: usize = 983045;
pub const ARM_USR26: usize = 983043;
pub const ARM_USR32: usize = 983044;
pub const _LLSEEK: usize = 140;
pub const _NEWSELECT: usize = 142;
pub const _SYSCTL: usize = 149;
@ -309,6 +314,7 @@ pub const STAT: usize = 106;
pub const STAT64: usize = 195;
pub const STATFS: usize = 99;
pub const STATFS64: usize = 266;
pub const STATX: usize = 397;
pub const SWAPOFF: usize = 115;
pub const SWAPON: usize = 87;
pub const SYMLINK: usize = 83;
@ -352,8 +358,3 @@ pub const WAIT4: usize = 114;
pub const WAITID: usize = 280;
pub const WRITE: usize = 4;
pub const WRITEV: usize = 146;
pub const ARM_BREAKPOINT: usize = 0xf0001;
pub const ARM_CACHEFLUSH: usize = 0xf0002;
pub const ARM_SET_TLS: usize = 0xf0005;
pub const ARM_USR26: usize = 0xf0003;
pub const ARM_USR32: usize = 0xf0004;

View file

@ -10,6 +10,7 @@ pub const ADD_KEY: usize = 286;
pub const ADJTIMEX: usize = 124;
pub const AFS_SYSCALL: usize = 137;
pub const ALARM: usize = 27;
pub const ARCH_PRCTL: usize = 384;
pub const BDFLUSH: usize = 134;
pub const BIND: usize = 361;
pub const BPF: usize = 357;
@ -326,6 +327,7 @@ pub const STAT: usize = 106;
pub const STAT64: usize = 195;
pub const STATFS: usize = 99;
pub const STATFS64: usize = 268;
pub const STATX: usize = 383;
pub const STIME: usize = 25;
pub const STTY: usize = 31;
pub const SWAPOFF: usize = 115;

View file

@ -287,6 +287,7 @@ pub const SOCKETPAIR: usize = 53;
pub const SPLICE: usize = 275;
pub const STAT: usize = 4;
pub const STATFS: usize = 137;
pub const STATX: usize = 332;
pub const SWAPOFF: usize = 168;
pub const SWAPON: usize = 167;
pub const SYMLINK: usize = 88;

View file

@ -1,15 +1,17 @@
#!/usr/bin/env python3
import os
import re
import tempfile
import subprocess
import sys
from typing import Iterable, Set
from typing import Iterable, Set, Tuple
linux_path = '.'
SIMPLE_MATH = re.compile('\((\d+)\s*\+\s*(\d+)\)')
SIMPLE_MATH = re.compile('^[()+0-9a-fx\s]*$')
NUMBER = re.compile('[0-9a-fx]+')
def load_table(path: str, arches: Set[str]):
with open('{}/{}'.format(linux_path, path)) as f:
@ -22,32 +24,39 @@ def load_table(path: str, arches: Set[str]):
yield (name, int(nr))
def eval_expr(expr: str) -> int:
ma = SIMPLE_MATH.match(expr)
if ma:
return int(ma.group(1)) + int(ma.group(2))
raise Exception('"{}" looks like an expression, but not a supported one'.format(expr))
if not SIMPLE_MATH.match(expr):
raise Exception('"{}" looks like an expression, but not a supported one'.format(expr))
return sum(int(x.group(0), 0) for x in NUMBER.finditer(expr))
def load_headers(names: Iterable[str], arch: str, extra: str = ''):
def load_headers(names: Iterable[Tuple[str, str]], arch: str, extra: str = ''):
with tempfile.NamedTemporaryFile(mode='w+', suffix='.h') as f:
f.write(extra)
f.write('\n')
f.write('#include <asm/unistd.h>\n')
for name in names:
f.write('gen_nr {0} __NR_{0}\n'.format(name))
f.flush()
lines = subprocess.check_output(['gcc', '-nostdinc',
'-I', '{}/arch/{}/include/uapi'.format(linux_path, arch),
'-I', '{}/include'.format(linux_path),
'-P', # don't include line number markers, which make the output annoying to parse
'-E', # only preprocess, don't compile
f.name]).decode('utf-8').split('\n')
with tempfile.TemporaryDirectory() as temp_include_dir:
os.mkdir('{}/asm'.format(temp_include_dir))
with open('{}/asm/unistd-eabi.h'.format(temp_include_dir), 'w'):
pass
with open('{}/asm/unistd-common.h'.format(temp_include_dir), 'w'):
pass
f.write(extra)
f.write('\n')
f.write('#include <asm/unistd.h>\n')
for prefix, name in names:
f.write('gen_nr {prefix}{name} __{prefix}NR_{name}\n'.format(prefix=prefix, name=name))
f.flush()
lines = subprocess.check_output(['gcc', '-nostdinc',
'-I', '{}/arch/{}/include/uapi'.format(linux_path, arch),
'-I', '{}/include'.format(linux_path),
'-I', temp_include_dir,
'-P', # don't include line number markers, which make the output annoying to parse
'-E', # only preprocess, don't compile
f.name]).decode('utf-8').split('\n')
for line in lines:
if not line.startswith('gen_nr '):
continue
_, name, nr = line.split(' ', 2)
if nr.startswith('__NR_'):
if nr.startswith('__'):
# unsupported on this arch
continue
if nr.startswith('('):
@ -56,15 +65,18 @@ def load_headers(names: Iterable[str], arch: str, extra: str = ''):
def main():
names = set(x.group(1) for x in re.finditer('\\b__NR_([a-z0-9_]+)\\b',
subprocess.check_output(['git', '--no-pager', 'grep', '__NR_'], cwd=linux_path)
RE_SYSCALL_NR=re.compile(r'\b__([A-Z]+_)?NR_([a-z0-9_]+)\b')
names = set(x.groups() for x in RE_SYSCALL_NR.finditer(
subprocess.check_output(['git', '--no-pager', 'grep', r'\<__\([A-Z]\+_\)\?NR_'], cwd=linux_path)
.decode('utf-8')))
if len(names) < 380:
print("didn't find anywhere near enough syscalls; hack must have failed")
subprocess.check_call(['git', '--no-pager', 'grep', r'\<__\([A-Z]\+_\)\?NR_'], cwd=linux_path)
sys.exit(1)
ARM_NAMES = ["breakpoint", "cacheflush", "usr26", "usr32", "set_tls"]
numbers = {
'linux-aarch64': dict(load_headers(names, 'arm64')),
'linux-armeabi': dict(load_table('arch/arm/tools/syscall.tbl', {'common', 'eabi'})),
'linux-armeabi': dict(list(load_table('arch/arm/tools/syscall.tbl', {'common', 'eabi'})) + list(load_headers(names, 'arm', '#define __ARM_EABI__'))),
'linux-mips': dict(load_headers(names, 'mips',
'#define _MIPS_SIM _MIPS_SIM_ABI32')),
'linux-mips64': dict(load_headers(names, 'mips',