diff options
author | Hendrik Brueckner <brueckner@linux.vnet.ibm.com> | 2017-12-07 15:36:36 +0100 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2018-01-23 07:36:51 +0100 |
commit | fd834e0970efad999df3ea60c581c3d56d6444d2 (patch) | |
tree | a7546596c9b3f660c1612b30a2e71651a986e717 /arch/s390 | |
parent | 857f46bfb07f53dc112d69bdfb137cc5ec3da7c5 (diff) |
s390/syscalls: add syscalltbl script
Introduce the syscalltbl script to read the system call table and
generate respective uapi unistd.h header files. Also it generates
the contents syscalls.S - the real system call table - which is
included by arch/s390/kernel/entry.S.
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rwxr-xr-x | arch/s390/kernel/syscalls/syscalltbl | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/arch/s390/kernel/syscalls/syscalltbl b/arch/s390/kernel/syscalls/syscalltbl new file mode 100755 index 000000000000..fbac1732f874 --- /dev/null +++ b/arch/s390/kernel/syscalls/syscalltbl @@ -0,0 +1,232 @@ +#!/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 |