1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0 3# 4# Generate all syscall tables. 5# 6# Each line of the syscall table should have the following format: 7# 8# NR ABI NAME [NATIVE] [COMPAT [noreturn]] 9# 10# NR syscall number 11# ABI ABI name 12# NAME syscall name 13# NATIVE native entry point (optional) 14# COMPAT compat entry point (optional) 15# noreturn system call doesn't return (optional) 16set -e 17 18usage() { 19 cat >&2 <<EOF 20usage: $0 <TOOLS DIRECTORY> <OUTFILE> 21 22 <TOOLS DIRECTORY> path to kernel tools directory 23 <OUTFILE> output header file 24EOF 25 exit 1 26} 27 28if [ $# -ne 2 ]; then 29 usage 30fi 31tools_dir=$1 32outfile=$2 33 34build_tables() { 35 infile="$1" 36 outfile="$2" 37 abis=$(echo "($3)" | tr ',' '|') 38 e_machine="$4" 39 40 if [ ! -f "$infile" ] 41 then 42 echo "Missing file $infile" 43 exit 1 44 fi 45 sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX) 46 grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | sort -n > "$sorted_table" 47 48 echo "static const char *const syscall_num_to_name_${e_machine}[] = {" >> "$outfile" 49 # the params are: nr abi name entry compat 50 # use _ for intentionally unused variables according to SC2034 51 while read -r nr _ name _ _; do 52 echo " [$nr] = \"$name\"," >> "$outfile" 53 done < "$sorted_table" 54 echo "};" >> "$outfile" 55 56 echo "static const uint16_t syscall_sorted_names_${e_machine}[] = {" >> "$outfile" 57 58 # When sorting by name, add a suffix of 0s upto 20 characters so that 59 # system calls that differ with a numerical suffix don't sort before 60 # those without. This default behavior of sort differs from that of 61 # strcmp used at runtime. Use sed to strip the trailing 0s suffix 62 # afterwards. 63 grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | awk '{printf $3; for (i = length($3); i < 20; i++) { printf "0"; }; print " " $1}'| sort | sed 's/\([a-zA-Z1-9]\+\)0\+ \([0-9]\+\)/\1 \2/' > "$sorted_table" 64 while read -r name nr; do 65 echo " $nr, /* $name */" >> "$outfile" 66 done < "$sorted_table" 67 echo "};" >> "$outfile" 68 69 rm -f "$sorted_table" 70} 71 72rm -f "$outfile" 73cat >> "$outfile" <<EOF 74#include <elf.h> 75#include <stdint.h> 76#include <asm/bitsperlong.h> 77#include <linux/kernel.h> 78 79struct syscalltbl { 80 const char *const *num_to_name; 81 const uint16_t *sorted_names; 82 uint16_t e_machine; 83 uint16_t num_to_name_len; 84 uint16_t sorted_names_len; 85}; 86 87#if defined(ALL_SYSCALLTBL) || defined(__alpha__) 88EOF 89build_tables "$tools_dir/perf/arch/alpha/entry/syscalls/syscall.tbl" "$outfile" common,64 EM_ALPHA 90cat >> "$outfile" <<EOF 91#endif // defined(ALL_SYSCALLTBL) || defined(__alpha__) 92 93#if defined(ALL_SYSCALLTBL) || defined(__arm__) || defined(__aarch64__) 94EOF 95build_tables "$tools_dir/perf/arch/arm/entry/syscalls/syscall.tbl" "$outfile" common,32,oabi EM_ARM 96build_tables "$tools_dir/perf/arch/arm64/entry/syscalls/syscall_64.tbl" "$outfile" common,64,renameat,rlimit,memfd_secret EM_AARCH64 97cat >> "$outfile" <<EOF 98#endif // defined(ALL_SYSCALLTBL) || defined(__arm__) || defined(__aarch64__) 99 100#if defined(ALL_SYSCALLTBL) || defined(__csky__) 101EOF 102build_tables "$tools_dir/scripts/syscall.tbl" "$outfile" common,32,csky,time32,stat64,rlimit EM_CSKY 103cat >> "$outfile" <<EOF 104#endif // defined(ALL_SYSCALLTBL) || defined(__csky__) 105 106#if defined(ALL_SYSCALLTBL) || defined(__mips__) 107EOF 108build_tables "$tools_dir/perf/arch/mips/entry/syscalls/syscall_n64.tbl" "$outfile" common,64,n64 EM_MIPS 109cat >> "$outfile" <<EOF 110#endif // defined(ALL_SYSCALLTBL) || defined(__mips__) 111 112#if defined(ALL_SYSCALLTBL) || defined(__hppa__) 113#if __BITS_PER_LONG != 64 114EOF 115build_tables "$tools_dir/perf/arch/parisc/entry/syscalls/syscall.tbl" "$outfile" common,32 EM_PARISC 116echo "#else" >> "$outfile" 117build_tables "$tools_dir/perf/arch/parisc/entry/syscalls/syscall.tbl" "$outfile" common,64 EM_PARISC 118cat >> "$outfile" <<EOF 119#endif //__BITS_PER_LONG != 64 120#endif // defined(ALL_SYSCALLTBL) || defined(__hppa__) 121 122#if defined(ALL_SYSCALLTBL) || defined(__powerpc__) || defined(__powerpc64__) 123EOF 124build_tables "$tools_dir/perf/arch/powerpc/entry/syscalls/syscall.tbl" "$outfile" common,32,nospu EM_PPC 125build_tables "$tools_dir/perf/arch/powerpc/entry/syscalls/syscall.tbl" "$outfile" common,64,nospu EM_PPC64 126cat >> "$outfile" <<EOF 127#endif // defined(ALL_SYSCALLTBL) || defined(__powerpc__) || defined(__powerpc64__) 128 129#if defined(ALL_SYSCALLTBL) || defined(__riscv) 130#if __BITS_PER_LONG != 64 131EOF 132build_tables "$tools_dir/scripts/syscall.tbl" "$outfile" common,32,riscv,memfd_secret EM_RISCV 133echo "#else" >> "$outfile" 134build_tables "$tools_dir/scripts/syscall.tbl" "$outfile" common,64,riscv,rlimit,memfd_secret EM_RISCV 135cat >> "$outfile" <<EOF 136#endif //__BITS_PER_LONG != 64 137#endif // defined(ALL_SYSCALLTBL) || defined(__riscv) 138#if defined(ALL_SYSCALLTBL) || defined(__s390x__) 139EOF 140build_tables "$tools_dir/perf/arch/s390/entry/syscalls/syscall.tbl" "$outfile" common,64,renameat,rlimit,memfd_secret EM_S390 141cat >> "$outfile" <<EOF 142#endif // defined(ALL_SYSCALLTBL) || defined(__s390x__) 143 144#if defined(ALL_SYSCALLTBL) || defined(__sh__) 145EOF 146build_tables "$tools_dir/perf/arch/sh/entry/syscalls/syscall.tbl" "$outfile" common,32 EM_SH 147cat >> "$outfile" <<EOF 148#endif // defined(ALL_SYSCALLTBL) || defined(__sh__) 149 150#if defined(ALL_SYSCALLTBL) || defined(__sparc64__) || defined(__sparc__) 151#if __BITS_PER_LONG != 64 152EOF 153build_tables "$tools_dir/perf/arch/sparc/entry/syscalls/syscall.tbl" "$outfile" common,32 EM_SPARC 154echo "#else" >> "$outfile" 155build_tables "$tools_dir/perf/arch/sparc/entry/syscalls/syscall.tbl" "$outfile" common,64 EM_SPARC 156cat >> "$outfile" <<EOF 157#endif //__BITS_PER_LONG != 64 158#endif // defined(ALL_SYSCALLTBL) || defined(__sparc64__) || defined(__sparc__) 159 160#if defined(ALL_SYSCALLTBL) || defined(__i386__) || defined(__x86_64__) 161EOF 162build_tables "$tools_dir/perf/arch/x86/entry/syscalls/syscall_32.tbl" "$outfile" common,32,i386 EM_386 163build_tables "$tools_dir/perf/arch/x86/entry/syscalls/syscall_64.tbl" "$outfile" common,64 EM_X86_64 164cat >> "$outfile" <<EOF 165#endif // defined(ALL_SYSCALLTBL) || defined(__i386__) || defined(__x86_64__) 166 167#if defined(ALL_SYSCALLTBL) || defined(__xtensa__) 168EOF 169build_tables "$tools_dir/perf/arch/xtensa/entry/syscalls/syscall.tbl" "$outfile" common,32 EM_XTENSA 170cat >> "$outfile" <<EOF 171#endif // defined(ALL_SYSCALLTBL) || defined(__xtensa__) 172 173#if __BITS_PER_LONG != 64 174EOF 175build_tables "$tools_dir/scripts/syscall.tbl" "$outfile" common,32 EM_NONE 176echo "#else" >> "$outfile" 177build_tables "$tools_dir/scripts/syscall.tbl" "$outfile" common,64 EM_NONE 178echo "#endif //__BITS_PER_LONG != 64" >> "$outfile" 179 180build_outer_table() { 181 e_machine=$1 182 outfile="$2" 183 cat >> "$outfile" <<EOF 184 { 185 .num_to_name = syscall_num_to_name_$e_machine, 186 .sorted_names = syscall_sorted_names_$e_machine, 187 .e_machine = $e_machine, 188 .num_to_name_len = ARRAY_SIZE(syscall_num_to_name_$e_machine), 189 .sorted_names_len = ARRAY_SIZE(syscall_sorted_names_$e_machine), 190 }, 191EOF 192} 193 194cat >> "$outfile" <<EOF 195static const struct syscalltbl syscalltbls[] = { 196#if defined(ALL_SYSCALLTBL) || defined(__alpha__) 197EOF 198build_outer_table EM_ALPHA "$outfile" 199cat >> "$outfile" <<EOF 200#endif // defined(ALL_SYSCALLTBL) || defined(__alpha__) 201 202#if defined(ALL_SYSCALLTBL) || defined(__arm__) || defined(__aarch64__) 203EOF 204build_outer_table EM_ARM "$outfile" 205build_outer_table EM_AARCH64 "$outfile" 206cat >> "$outfile" <<EOF 207#endif // defined(ALL_SYSCALLTBL) || defined(__arm__) || defined(__aarch64__) 208 209#if defined(ALL_SYSCALLTBL) || defined(__csky__) 210EOF 211build_outer_table EM_CSKY "$outfile" 212cat >> "$outfile" <<EOF 213#endif // defined(ALL_SYSCALLTBL) || defined(__csky__) 214 215#if defined(ALL_SYSCALLTBL) || defined(__mips__) 216EOF 217build_outer_table EM_MIPS "$outfile" 218cat >> "$outfile" <<EOF 219#endif // defined(ALL_SYSCALLTBL) || defined(__mips__) 220 221#if defined(ALL_SYSCALLTBL) || defined(__hppa__) 222EOF 223build_outer_table EM_PARISC "$outfile" 224cat >> "$outfile" <<EOF 225#endif // defined(ALL_SYSCALLTBL) || defined(__hppa__) 226 227#if defined(ALL_SYSCALLTBL) || defined(__powerpc__) || defined(__powerpc64__) 228EOF 229build_outer_table EM_PPC "$outfile" 230build_outer_table EM_PPC64 "$outfile" 231cat >> "$outfile" <<EOF 232#endif // defined(ALL_SYSCALLTBL) || defined(__powerpc__) || defined(__powerpc64__) 233 234#if defined(ALL_SYSCALLTBL) || defined(__riscv) 235EOF 236build_outer_table EM_RISCV "$outfile" 237cat >> "$outfile" <<EOF 238#endif // defined(ALL_SYSCALLTBL) || defined(__riscv) 239 240#if defined(ALL_SYSCALLTBL) || defined(__s390x__) 241EOF 242build_outer_table EM_S390 "$outfile" 243cat >> "$outfile" <<EOF 244#endif // defined(ALL_SYSCALLTBL) || defined(__s390x__) 245 246#if defined(ALL_SYSCALLTBL) || defined(__sh__) 247EOF 248build_outer_table EM_SH "$outfile" 249cat >> "$outfile" <<EOF 250#endif // defined(ALL_SYSCALLTBL) || defined(__sh__) 251 252#if defined(ALL_SYSCALLTBL) || defined(__sparc64__) || defined(__sparc__) 253EOF 254build_outer_table EM_SPARC "$outfile" 255cat >> "$outfile" <<EOF 256#endif // defined(ALL_SYSCALLTBL) || defined(__sparc64__) || defined(__sparc__) 257 258#if defined(ALL_SYSCALLTBL) || defined(__i386__) || defined(__x86_64__) 259EOF 260build_outer_table EM_386 "$outfile" 261build_outer_table EM_X86_64 "$outfile" 262cat >> "$outfile" <<EOF 263#endif // defined(ALL_SYSCALLTBL) || defined(__i386__) || defined(__x86_64__) 264 265#if defined(ALL_SYSCALLTBL) || defined(__xtensa__) 266EOF 267build_outer_table EM_XTENSA "$outfile" 268cat >> "$outfile" <<EOF 269#endif // defined(ALL_SYSCALLTBL) || defined(__xtensa__) 270EOF 271build_outer_table EM_NONE "$outfile" 272cat >> "$outfile" <<EOF 273}; 274EOF 275