xref: /aosp_15_r20/external/perfetto/tools/extract_linux_syscall_tables (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker#!/usr/bin/env python3
2*6dbdd20aSAndroid Build Coastguard Worker
3*6dbdd20aSAndroid Build Coastguard Workerimport contextlib
4*6dbdd20aSAndroid Build Coastguard Workerimport os
5*6dbdd20aSAndroid Build Coastguard Workerimport re
6*6dbdd20aSAndroid Build Coastguard Workerimport sys
7*6dbdd20aSAndroid Build Coastguard Worker
8*6dbdd20aSAndroid Build Coastguard Workerfrom urllib.request import urlopen
9*6dbdd20aSAndroid Build Coastguard Worker
10*6dbdd20aSAndroid Build Coastguard WorkerPROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
11*6dbdd20aSAndroid Build Coastguard WorkerSELF_PATH = os.path.relpath(__file__, PROJECT_ROOT).replace('\\', '/')
12*6dbdd20aSAndroid Build Coastguard Worker
13*6dbdd20aSAndroid Build Coastguard Workersyscalls = {}
14*6dbdd20aSAndroid Build Coastguard Workerarchs = ['arm64', 'arm32', 'x86', 'x86_64']
15*6dbdd20aSAndroid Build Coastguard Worker
16*6dbdd20aSAndroid Build Coastguard Worker
17*6dbdd20aSAndroid Build Coastguard Workerdef print_tables():
18*6dbdd20aSAndroid Build Coastguard Worker  print('// DO NOT EDIT. Auto-generated by %s' % SELF_PATH)
19*6dbdd20aSAndroid Build Coastguard Worker  print('#ifndef SRC_KERNEL_UTILS_SYSCALL_TABLE_GENERATED_H_')
20*6dbdd20aSAndroid Build Coastguard Worker  print('#define SRC_KERNEL_UTILS_SYSCALL_TABLE_GENERATED_H_')
21*6dbdd20aSAndroid Build Coastguard Worker  print('')
22*6dbdd20aSAndroid Build Coastguard Worker  print('#include <stdint.h>')
23*6dbdd20aSAndroid Build Coastguard Worker  print('')
24*6dbdd20aSAndroid Build Coastguard Worker  print('#include "src/kernel_utils/syscall_table.h"')
25*6dbdd20aSAndroid Build Coastguard Worker  print('')
26*6dbdd20aSAndroid Build Coastguard Worker  print('namespace perfetto {')
27*6dbdd20aSAndroid Build Coastguard Worker  print('')
28*6dbdd20aSAndroid Build Coastguard Worker  # First of all merge all the syscall names from all tables and emit one big
29*6dbdd20aSAndroid Build Coastguard Worker  # string with unique names.
30*6dbdd20aSAndroid Build Coastguard Worker  syscall_names = set()
31*6dbdd20aSAndroid Build Coastguard Worker  for arch in archs:
32*6dbdd20aSAndroid Build Coastguard Worker    tab = syscalls[arch]
33*6dbdd20aSAndroid Build Coastguard Worker    for i in range(max(tab.keys()) + 1):
34*6dbdd20aSAndroid Build Coastguard Worker      syscall_names.add(tab.get(i, ''))
35*6dbdd20aSAndroid Build Coastguard Worker  print('constexpr char kAllSyscalllNames[] =')
36*6dbdd20aSAndroid Build Coastguard Worker  offset_by_name = {}
37*6dbdd20aSAndroid Build Coastguard Worker  last_off = 0
38*6dbdd20aSAndroid Build Coastguard Worker  for syscall_name in sorted(syscall_names):
39*6dbdd20aSAndroid Build Coastguard Worker    if syscall_name in offset_by_name:
40*6dbdd20aSAndroid Build Coastguard Worker      continue
41*6dbdd20aSAndroid Build Coastguard Worker    print('  "%s\\0"' % syscall_name)
42*6dbdd20aSAndroid Build Coastguard Worker    offset_by_name[syscall_name] = last_off
43*6dbdd20aSAndroid Build Coastguard Worker    last_off += len(syscall_name) + 1
44*6dbdd20aSAndroid Build Coastguard Worker  if last_off >= 0xffff:
45*6dbdd20aSAndroid Build Coastguard Worker    raise Exception('SyscallTable::OffT must be increased to uint32_t')
46*6dbdd20aSAndroid Build Coastguard Worker  print(';\n')
47*6dbdd20aSAndroid Build Coastguard Worker  # Then print the individual tables.
48*6dbdd20aSAndroid Build Coastguard Worker  for arch in archs:
49*6dbdd20aSAndroid Build Coastguard Worker    tab = syscalls[arch]
50*6dbdd20aSAndroid Build Coastguard Worker    print('struct SyscallTable_%s {' % arch)
51*6dbdd20aSAndroid Build Coastguard Worker    print('  static constexpr const char* names = kAllSyscalllNames;')
52*6dbdd20aSAndroid Build Coastguard Worker    print('  static constexpr SyscallTable::OffT offsets[] {')
53*6dbdd20aSAndroid Build Coastguard Worker    for i in range(max(tab.keys()) + 1):
54*6dbdd20aSAndroid Build Coastguard Worker      syscall_name = tab.get(i, '')
55*6dbdd20aSAndroid Build Coastguard Worker      print('%d, // %d: %s' % (offset_by_name[syscall_name], i, syscall_name))
56*6dbdd20aSAndroid Build Coastguard Worker    print('  };')
57*6dbdd20aSAndroid Build Coastguard Worker    print('};\n')
58*6dbdd20aSAndroid Build Coastguard Worker  print('}  // namespace perfetto')
59*6dbdd20aSAndroid Build Coastguard Worker  print('#endif  // SRC_KERNEL_UTILS_SYSCALL_TABLE_GENERATED_H_')
60*6dbdd20aSAndroid Build Coastguard Worker
61*6dbdd20aSAndroid Build Coastguard Worker
62*6dbdd20aSAndroid Build Coastguard Worker# Parses a .tbl file (new format).
63*6dbdd20aSAndroid Build Coastguard Workerdef parse_tlb(data):
64*6dbdd20aSAndroid Build Coastguard Worker  table = {}
65*6dbdd20aSAndroid Build Coastguard Worker  for line in data.splitlines():
66*6dbdd20aSAndroid Build Coastguard Worker    line = line.strip()
67*6dbdd20aSAndroid Build Coastguard Worker    if line.startswith('#') or not (line):
68*6dbdd20aSAndroid Build Coastguard Worker      continue
69*6dbdd20aSAndroid Build Coastguard Worker    parts = line.split()
70*6dbdd20aSAndroid Build Coastguard Worker    table[int(parts[0])] = 'sys_' + parts[2]
71*6dbdd20aSAndroid Build Coastguard Worker  return table
72*6dbdd20aSAndroid Build Coastguard Worker
73*6dbdd20aSAndroid Build Coastguard Worker
74*6dbdd20aSAndroid Build Coastguard Worker# Parses a #define __NR_xx 1234 old-style unistd.h header.
75*6dbdd20aSAndroid Build Coastguard Workerdef parse_def(data):
76*6dbdd20aSAndroid Build Coastguard Worker  table = {}
77*6dbdd20aSAndroid Build Coastguard Worker  for line in data.splitlines():
78*6dbdd20aSAndroid Build Coastguard Worker    m = re.match(r'^#define\s+__NR\d*?_(\w+)\s+(\d+)\s*$', line.strip())
79*6dbdd20aSAndroid Build Coastguard Worker    if not m or m.group(1) == 'syscalls':  # __NR_syscalls is just a sentinel.
80*6dbdd20aSAndroid Build Coastguard Worker      continue
81*6dbdd20aSAndroid Build Coastguard Worker    table[int(m.group(2))] = 'sys_' + m.group(1)
82*6dbdd20aSAndroid Build Coastguard Worker  return table
83*6dbdd20aSAndroid Build Coastguard Worker
84*6dbdd20aSAndroid Build Coastguard Worker
85*6dbdd20aSAndroid Build Coastguard Workerdef Main():
86*6dbdd20aSAndroid Build Coastguard Worker  KSRC = 'https://raw.githubusercontent.com/torvalds/linux/v6.7/'
87*6dbdd20aSAndroid Build Coastguard Worker
88*6dbdd20aSAndroid Build Coastguard Worker  response = urlopen(KSRC + 'arch/x86/entry/syscalls/syscall_64.tbl')
89*6dbdd20aSAndroid Build Coastguard Worker  syscalls['x86_64'] = parse_tlb(response.read().decode())
90*6dbdd20aSAndroid Build Coastguard Worker
91*6dbdd20aSAndroid Build Coastguard Worker  response = urlopen(KSRC + 'arch/x86/entry/syscalls/syscall_32.tbl')
92*6dbdd20aSAndroid Build Coastguard Worker  syscalls['x86'] = parse_tlb(response.read().decode())
93*6dbdd20aSAndroid Build Coastguard Worker
94*6dbdd20aSAndroid Build Coastguard Worker  response = urlopen(KSRC + 'arch/arm/tools/syscall.tbl')
95*6dbdd20aSAndroid Build Coastguard Worker  syscalls['arm32'] = parse_tlb(response.read().decode())
96*6dbdd20aSAndroid Build Coastguard Worker
97*6dbdd20aSAndroid Build Coastguard Worker  # From:
98*6dbdd20aSAndroid Build Coastguard Worker  # arch/arm64/include/asm/unistd.h
99*6dbdd20aSAndroid Build Coastguard Worker  #   -> arch/arm64/include/uapi/asm/unistd.h
100*6dbdd20aSAndroid Build Coastguard Worker  #     -> include/uapi/asm-generic/unistd.h
101*6dbdd20aSAndroid Build Coastguard Worker  response = urlopen(KSRC + 'include/uapi/asm-generic/unistd.h')
102*6dbdd20aSAndroid Build Coastguard Worker  syscalls['arm64'] = parse_def(response.read().decode())
103*6dbdd20aSAndroid Build Coastguard Worker
104*6dbdd20aSAndroid Build Coastguard Worker  dst_file = os.path.join(PROJECT_ROOT, 'src', 'kernel_utils',
105*6dbdd20aSAndroid Build Coastguard Worker                          'syscall_table_generated.h')
106*6dbdd20aSAndroid Build Coastguard Worker  tmp_file = dst_file + '.tmp'
107*6dbdd20aSAndroid Build Coastguard Worker
108*6dbdd20aSAndroid Build Coastguard Worker  print('Writing ', dst_file)
109*6dbdd20aSAndroid Build Coastguard Worker  with open(tmp_file, 'w') as f:
110*6dbdd20aSAndroid Build Coastguard Worker    with contextlib.redirect_stdout(f):
111*6dbdd20aSAndroid Build Coastguard Worker      print_tables()
112*6dbdd20aSAndroid Build Coastguard Worker  os.rename(tmp_file, dst_file)
113*6dbdd20aSAndroid Build Coastguard Worker
114*6dbdd20aSAndroid Build Coastguard Worker  print('Running clang-format (might fail if depot_tools isn\'t in the PATH)')
115*6dbdd20aSAndroid Build Coastguard Worker  os.system('clang-format -i ' + dst_file)
116*6dbdd20aSAndroid Build Coastguard Worker
117*6dbdd20aSAndroid Build Coastguard Workerif __name__ == '__main__':
118*6dbdd20aSAndroid Build Coastguard Worker  sys.exit(Main())
119