Skip to content

Commit

Permalink
s390/syscalls: add syscalltbl script
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: Heiko Carstens <[email protected]>
Signed-off-by: Martin Schwidefsky <[email protected]>
  • Loading branch information
hbrueckner authored and Martin Schwidefsky committed Jan 23, 2018
1 parent 857f46b commit fd834e0
Showing 1 changed file with 232 additions and 0 deletions.
232 changes: 232 additions & 0 deletions arch/s390/kernel/syscalls/syscalltbl
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>

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

0 comments on commit fd834e0

Please sign in to comment.