#!/bin/sh # SPDX-License-Identifier: GPL-2.0 # # Generate system call table and header files # # Copyright IBM Corp. 2018 # Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com> # # File path to the system call table definition. # You can set the path with the -i option. If omitted, # system call table definitions are read from standard input. # SYSCALL_TBL="" create_syscall_table_entries() { local nr abi name entry64 entry32 _ignore local temp=$(mktemp ${TMPDIR:-/tmp}/syscalltbl-common.XXXXXXXXX) ( # # Initialize with 0 to create an NI_SYSCALL for 0 # local prev_nr=0 prev_32=sys_ni_syscall prev_64=sys_ni_syscall while read nr abi name entry64 entry32 _ignore; do test x$entry32 = x- && entry32=sys_ni_syscall test x$entry64 = x- && entry64=sys_ni_syscall if test $prev_nr -eq $nr; then # # Same syscall but different ABI, just update # the respective entry point # case $abi in 32) prev_32=$entry32 ;; 64) prev_64=$entry64 ;; esac continue; else printf "%d\t%s\t%s\n" $prev_nr $prev_64 $prev_32 fi prev_nr=$nr prev_64=$entry64 prev_32=$entry32 done printf "%d\t%s\t%s\n" $prev_nr $prev_64 $prev_32 ) >> $temp # # Check for duplicate syscall numbers # if ! cat $temp |cut -f1 |uniq -d 2>&1; then echo "Error: generated system call table contains duplicate entries: $temp" >&2 exit 1 fi # # Generate syscall table # prev_nr=0 while read nr entry64 entry32; do while test $prev_nr -lt $((nr - 1)); do printf "NI_SYSCALL\n" prev_nr=$((prev_nr + 1)) done if test x$entry64 = xsys_ni_syscall && test x$entry32 = xsys_ni_syscall; then printf "NI_SYSCALL\n" else printf "SYSCALL(%s,%s)\n" $entry64 $entry32 fi prev_nr=$nr done < $temp rm $temp } generate_syscall_table() { cat <<-EoHEADER /* SPDX-License-Identifier: GPL-2.0 */ /* * Definitions for sys_call_table, each line represents an * entry in the table in the form * SYSCALL(64 bit syscall, 31 bit emulated syscall) * * This file is meant to be included from entry.S. */ #define NI_SYSCALL SYSCALL(sys_ni_syscall,sys_ni_syscall) EoHEADER grep -Ev '^(#|[[:blank:]]*$)' $SYSCALL_TBL \ |sort -k1 -n \ |create_syscall_table_entries } create_header_defines() { local nr abi name _ignore while read nr abi name _ignore; do printf "#define __NR_%s %d\n" $name $nr done } normalize_fileguard() { local fileguard="$1" echo "$1" |tr '[[:lower:]]' '[[:upper:]]' \ |sed -e 's/[^A-Z0-9_]/_/g' -e 's/__/_/g' } generate_syscall_header() { local abis=$(echo "($1)" | tr ',' '|') local filename="$2" local fileguard suffix if test "$filename"; then fileguard=$(normalize_fileguard "__UAPI_ASM_S390_$2") else case "$abis" in *64*) suffix=64 ;; *32*) suffix=32 ;; esac fileguard=$(normalize_fileguard "__UAPI_ASM_S390_SYSCALLS_$suffix") fi cat <<-EoHEADER /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef ${fileguard} #define ${fileguard} EoHEADER grep -E "^[[:digit:]]+[[:space:]]+${abis}" $SYSCALL_TBL \ |sort -k1 -n \ |create_header_defines cat <<-EoFOOTER #endif /* ${fileguard} */ EoFOOTER } __max_syscall_nr() { local abis=$(echo "($1)" | tr ',' '|') grep -E "^[[:digit:]]+[[:space:]]+${abis}" $SYSCALL_TBL \ |sed -ne 's/^\([[:digit:]]*\)[[:space:]].*/\1/p' \ |sort -n \ |tail -1 } generate_syscall_nr() { local abis="$1" local max_syscall_nr num_syscalls max_syscall_nr=$(__max_syscall_nr "$abis") num_syscalls=$((max_syscall_nr + 1)) cat <<-EoHEADER /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_S390_SYSCALLS_NR #define __ASM_S390_SYSCALLS_NR #define NR_syscalls ${num_syscalls} #endif /* __ASM_S390_SYSCALLS_NR */ EoHEADER } # # Parse command line arguments # do_syscall_header="" do_syscall_table="" do_syscall_nr="" output_file="" abi_list="common,64" filename="" while getopts ":HNSXi:a:f:" arg; do case $arg in a) abi_list="$OPTARG" ;; i) SYSCALL_TBL="$OPTARG" ;; f) filename=${OPTARG##*/} ;; H) do_syscall_header=1 ;; N) do_syscall_nr=1 ;; S) do_syscall_table=1 ;; X) set -x ;; :) echo "Missing argument for -$OPTARG" >&2 exit 1 ;; \?) echo "Invalid option specified" >&2 exit 1 ;; esac done test "$do_syscall_header" && generate_syscall_header "$abi_list" "$filename" test "$do_syscall_table" && generate_syscall_table test "$do_syscall_nr" && generate_syscall_nr "$abi_list" exit 0