233 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			233 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/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
 |