|
@@ -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
|