xref: /openbmc/linux/arch/s390/kernel/syscalls/syscalltbl (revision 552c69b36ebd966186573b9c7a286b390935cce1)
1*fd834e09SHendrik Brueckner#!/bin/sh
2*fd834e09SHendrik Brueckner# SPDX-License-Identifier: GPL-2.0
3*fd834e09SHendrik Brueckner#
4*fd834e09SHendrik Brueckner# Generate system call table and header files
5*fd834e09SHendrik Brueckner#
6*fd834e09SHendrik Brueckner# Copyright IBM Corp. 2018
7*fd834e09SHendrik Brueckner# Author(s):  Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
8*fd834e09SHendrik Brueckner
9*fd834e09SHendrik Brueckner#
10*fd834e09SHendrik Brueckner# File path to the system call table definition.
11*fd834e09SHendrik Brueckner# You can set the path with the -i option.  If omitted,
12*fd834e09SHendrik Brueckner# system call table definitions are read from standard input.
13*fd834e09SHendrik Brueckner#
14*fd834e09SHendrik BruecknerSYSCALL_TBL=""
15*fd834e09SHendrik Brueckner
16*fd834e09SHendrik Brueckner
17*fd834e09SHendrik Bruecknercreate_syscall_table_entries()
18*fd834e09SHendrik Brueckner{
19*fd834e09SHendrik Brueckner	local nr abi name entry64 entry32 _ignore
20*fd834e09SHendrik Brueckner	local temp=$(mktemp ${TMPDIR:-/tmp}/syscalltbl-common.XXXXXXXXX)
21*fd834e09SHendrik Brueckner
22*fd834e09SHendrik Brueckner	(
23*fd834e09SHendrik Brueckner	#
24*fd834e09SHendrik Brueckner	# Initialize with 0 to create an NI_SYSCALL for 0
25*fd834e09SHendrik Brueckner	#
26*fd834e09SHendrik Brueckner	local prev_nr=0 prev_32=sys_ni_syscall prev_64=sys_ni_syscall
27*fd834e09SHendrik Brueckner	while read nr abi name entry64 entry32 _ignore; do
28*fd834e09SHendrik Brueckner		test x$entry32 = x- && entry32=sys_ni_syscall
29*fd834e09SHendrik Brueckner		test x$entry64 = x- && entry64=sys_ni_syscall
30*fd834e09SHendrik Brueckner
31*fd834e09SHendrik Brueckner		if test $prev_nr -eq $nr; then
32*fd834e09SHendrik Brueckner			#
33*fd834e09SHendrik Brueckner			# Same syscall but different ABI, just update
34*fd834e09SHendrik Brueckner			# the respective entry point
35*fd834e09SHendrik Brueckner			#
36*fd834e09SHendrik Brueckner			case $abi in
37*fd834e09SHendrik Brueckner			32)
38*fd834e09SHendrik Brueckner				prev_32=$entry32
39*fd834e09SHendrik Brueckner			;;
40*fd834e09SHendrik Brueckner			64)
41*fd834e09SHendrik Brueckner				prev_64=$entry64
42*fd834e09SHendrik Brueckner			;;
43*fd834e09SHendrik Brueckner			esac
44*fd834e09SHendrik Brueckner			continue;
45*fd834e09SHendrik Brueckner		else
46*fd834e09SHendrik Brueckner			printf "%d\t%s\t%s\n" $prev_nr $prev_64 $prev_32
47*fd834e09SHendrik Brueckner		fi
48*fd834e09SHendrik Brueckner
49*fd834e09SHendrik Brueckner		prev_nr=$nr
50*fd834e09SHendrik Brueckner		prev_64=$entry64
51*fd834e09SHendrik Brueckner		prev_32=$entry32
52*fd834e09SHendrik Brueckner	done
53*fd834e09SHendrik Brueckner	printf "%d\t%s\t%s\n" $prev_nr $prev_64 $prev_32
54*fd834e09SHendrik Brueckner	) >> $temp
55*fd834e09SHendrik Brueckner
56*fd834e09SHendrik Brueckner	#
57*fd834e09SHendrik Brueckner	# Check for duplicate syscall numbers
58*fd834e09SHendrik Brueckner	#
59*fd834e09SHendrik Brueckner	if ! cat $temp |cut -f1 |uniq -d 2>&1; then
60*fd834e09SHendrik Brueckner		echo "Error: generated system call table contains duplicate entries: $temp" >&2
61*fd834e09SHendrik Brueckner		exit 1
62*fd834e09SHendrik Brueckner	fi
63*fd834e09SHendrik Brueckner
64*fd834e09SHendrik Brueckner	#
65*fd834e09SHendrik Brueckner	# Generate syscall table
66*fd834e09SHendrik Brueckner	#
67*fd834e09SHendrik Brueckner	prev_nr=0
68*fd834e09SHendrik Brueckner	while read nr entry64 entry32; do
69*fd834e09SHendrik Brueckner		while test $prev_nr -lt $((nr - 1)); do
70*fd834e09SHendrik Brueckner			printf "NI_SYSCALL\n"
71*fd834e09SHendrik Brueckner			prev_nr=$((prev_nr + 1))
72*fd834e09SHendrik Brueckner		done
73*fd834e09SHendrik Brueckner		if test x$entry64 = xsys_ni_syscall &&
74*fd834e09SHendrik Brueckner		   test x$entry32 = xsys_ni_syscall; then
75*fd834e09SHendrik Brueckner			printf "NI_SYSCALL\n"
76*fd834e09SHendrik Brueckner		else
77*fd834e09SHendrik Brueckner			printf "SYSCALL(%s,%s)\n" $entry64 $entry32
78*fd834e09SHendrik Brueckner		fi
79*fd834e09SHendrik Brueckner		prev_nr=$nr
80*fd834e09SHendrik Brueckner	done < $temp
81*fd834e09SHendrik Brueckner	rm $temp
82*fd834e09SHendrik Brueckner}
83*fd834e09SHendrik Brueckner
84*fd834e09SHendrik Bruecknergenerate_syscall_table()
85*fd834e09SHendrik Brueckner{
86*fd834e09SHendrik Brueckner	cat <<-EoHEADER
87*fd834e09SHendrik Brueckner	/* SPDX-License-Identifier: GPL-2.0 */
88*fd834e09SHendrik Brueckner	/*
89*fd834e09SHendrik Brueckner	 * Definitions for sys_call_table, each line represents an
90*fd834e09SHendrik Brueckner	 * entry in the table in the form
91*fd834e09SHendrik Brueckner	 * SYSCALL(64 bit syscall, 31 bit emulated syscall)
92*fd834e09SHendrik Brueckner	 *
93*fd834e09SHendrik Brueckner	 * This file is meant to be included from entry.S.
94*fd834e09SHendrik Brueckner	 */
95*fd834e09SHendrik Brueckner
96*fd834e09SHendrik Brueckner	#define NI_SYSCALL SYSCALL(sys_ni_syscall,sys_ni_syscall)
97*fd834e09SHendrik Brueckner
98*fd834e09SHendrik BruecknerEoHEADER
99*fd834e09SHendrik Brueckner	grep -Ev '^(#|[[:blank:]]*$)' $SYSCALL_TBL	\
100*fd834e09SHendrik Brueckner		|sort -k1 -n				\
101*fd834e09SHendrik Brueckner		|create_syscall_table_entries
102*fd834e09SHendrik Brueckner}
103*fd834e09SHendrik Brueckner
104*fd834e09SHendrik Bruecknercreate_header_defines()
105*fd834e09SHendrik Brueckner{
106*fd834e09SHendrik Brueckner	local nr abi name _ignore
107*fd834e09SHendrik Brueckner
108*fd834e09SHendrik Brueckner	while read nr abi name _ignore; do
109*fd834e09SHendrik Brueckner		printf "#define __NR_%s %d\n" $name $nr
110*fd834e09SHendrik Brueckner	done
111*fd834e09SHendrik Brueckner}
112*fd834e09SHendrik Brueckner
113*fd834e09SHendrik Bruecknernormalize_fileguard()
114*fd834e09SHendrik Brueckner{
115*fd834e09SHendrik Brueckner	local fileguard="$1"
116*fd834e09SHendrik Brueckner
117*fd834e09SHendrik Brueckner	echo "$1" |tr '[[:lower:]]' '[[:upper:]]' \
118*fd834e09SHendrik Brueckner		  |sed -e 's/[^A-Z0-9_]/_/g' -e 's/__/_/g'
119*fd834e09SHendrik Brueckner}
120*fd834e09SHendrik Brueckner
121*fd834e09SHendrik Bruecknergenerate_syscall_header()
122*fd834e09SHendrik Brueckner{
123*fd834e09SHendrik Brueckner	local abis=$(echo "($1)" | tr ',' '|')
124*fd834e09SHendrik Brueckner	local filename="$2"
125*fd834e09SHendrik Brueckner	local fileguard suffix
126*fd834e09SHendrik Brueckner
127*fd834e09SHendrik Brueckner	if test "$filename"; then
128*fd834e09SHendrik Brueckner		fileguard=$(normalize_fileguard "__UAPI_ASM_S390_$2")
129*fd834e09SHendrik Brueckner	else
130*fd834e09SHendrik Brueckner		case "$abis" in
131*fd834e09SHendrik Brueckner		*64*) suffix=64 ;;
132*fd834e09SHendrik Brueckner		*32*) suffix=32 ;;
133*fd834e09SHendrik Brueckner		esac
134*fd834e09SHendrik Brueckner		fileguard=$(normalize_fileguard "__UAPI_ASM_S390_SYSCALLS_$suffix")
135*fd834e09SHendrik Brueckner	fi
136*fd834e09SHendrik Brueckner
137*fd834e09SHendrik Brueckner	cat <<-EoHEADER
138*fd834e09SHendrik Brueckner	/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
139*fd834e09SHendrik Brueckner	#ifndef ${fileguard}
140*fd834e09SHendrik Brueckner	#define ${fileguard}
141*fd834e09SHendrik Brueckner
142*fd834e09SHendrik BruecknerEoHEADER
143*fd834e09SHendrik Brueckner
144*fd834e09SHendrik Brueckner	grep -E "^[[:digit:]]+[[:space:]]+${abis}" $SYSCALL_TBL	\
145*fd834e09SHendrik Brueckner		|sort -k1 -n					\
146*fd834e09SHendrik Brueckner		|create_header_defines
147*fd834e09SHendrik Brueckner
148*fd834e09SHendrik Brueckner	cat <<-EoFOOTER
149*fd834e09SHendrik Brueckner
150*fd834e09SHendrik Brueckner	#endif /* ${fileguard} */
151*fd834e09SHendrik BruecknerEoFOOTER
152*fd834e09SHendrik Brueckner}
153*fd834e09SHendrik Brueckner
154*fd834e09SHendrik Brueckner__max_syscall_nr()
155*fd834e09SHendrik Brueckner{
156*fd834e09SHendrik Brueckner	local abis=$(echo "($1)" | tr ',' '|')
157*fd834e09SHendrik Brueckner
158*fd834e09SHendrik Brueckner	grep -E "^[[:digit:]]+[[:space:]]+${abis}" $SYSCALL_TBL	 \
159*fd834e09SHendrik Brueckner		|sed -ne 's/^\([[:digit:]]*\)[[:space:]].*/\1/p' \
160*fd834e09SHendrik Brueckner		|sort -n					 \
161*fd834e09SHendrik Brueckner		|tail -1
162*fd834e09SHendrik Brueckner}
163*fd834e09SHendrik Brueckner
164*fd834e09SHendrik Brueckner
165*fd834e09SHendrik Bruecknergenerate_syscall_nr()
166*fd834e09SHendrik Brueckner{
167*fd834e09SHendrik Brueckner	local abis="$1"
168*fd834e09SHendrik Brueckner	local max_syscall_nr num_syscalls
169*fd834e09SHendrik Brueckner
170*fd834e09SHendrik Brueckner	max_syscall_nr=$(__max_syscall_nr "$abis")
171*fd834e09SHendrik Brueckner	num_syscalls=$((max_syscall_nr + 1))
172*fd834e09SHendrik Brueckner
173*fd834e09SHendrik Brueckner	cat <<-EoHEADER
174*fd834e09SHendrik Brueckner	/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
175*fd834e09SHendrik Brueckner	#ifndef __ASM_S390_SYSCALLS_NR
176*fd834e09SHendrik Brueckner	#define __ASM_S390_SYSCALLS_NR
177*fd834e09SHendrik Brueckner
178*fd834e09SHendrik Brueckner	#define NR_syscalls ${num_syscalls}
179*fd834e09SHendrik Brueckner
180*fd834e09SHendrik Brueckner	#endif /* __ASM_S390_SYSCALLS_NR */
181*fd834e09SHendrik BruecknerEoHEADER
182*fd834e09SHendrik Brueckner}
183*fd834e09SHendrik Brueckner
184*fd834e09SHendrik Brueckner
185*fd834e09SHendrik Brueckner#
186*fd834e09SHendrik Brueckner# Parse command line arguments
187*fd834e09SHendrik Brueckner#
188*fd834e09SHendrik Bruecknerdo_syscall_header=""
189*fd834e09SHendrik Bruecknerdo_syscall_table=""
190*fd834e09SHendrik Bruecknerdo_syscall_nr=""
191*fd834e09SHendrik Brueckneroutput_file=""
192*fd834e09SHendrik Bruecknerabi_list="common,64"
193*fd834e09SHendrik Bruecknerfilename=""
194*fd834e09SHendrik Bruecknerwhile getopts ":HNSXi:a:f:" arg; do
195*fd834e09SHendrik Brueckner	case $arg in
196*fd834e09SHendrik Brueckner	a)
197*fd834e09SHendrik Brueckner		abi_list="$OPTARG"
198*fd834e09SHendrik Brueckner		;;
199*fd834e09SHendrik Brueckner	i)
200*fd834e09SHendrik Brueckner		SYSCALL_TBL="$OPTARG"
201*fd834e09SHendrik Brueckner		;;
202*fd834e09SHendrik Brueckner	f)
203*fd834e09SHendrik Brueckner		filename=${OPTARG##*/}
204*fd834e09SHendrik Brueckner		;;
205*fd834e09SHendrik Brueckner	H)
206*fd834e09SHendrik Brueckner		do_syscall_header=1
207*fd834e09SHendrik Brueckner		;;
208*fd834e09SHendrik Brueckner	N)
209*fd834e09SHendrik Brueckner		do_syscall_nr=1
210*fd834e09SHendrik Brueckner		;;
211*fd834e09SHendrik Brueckner	S)
212*fd834e09SHendrik Brueckner		do_syscall_table=1
213*fd834e09SHendrik Brueckner		;;
214*fd834e09SHendrik Brueckner	X)
215*fd834e09SHendrik Brueckner		set -x
216*fd834e09SHendrik Brueckner		;;
217*fd834e09SHendrik Brueckner	:)
218*fd834e09SHendrik Brueckner		echo "Missing argument for -$OPTARG" >&2
219*fd834e09SHendrik Brueckner		exit 1
220*fd834e09SHendrik Brueckner	;;
221*fd834e09SHendrik Brueckner	\?)
222*fd834e09SHendrik Brueckner		echo "Invalid option specified" >&2
223*fd834e09SHendrik Brueckner		exit 1
224*fd834e09SHendrik Brueckner	;;
225*fd834e09SHendrik Brueckner	esac
226*fd834e09SHendrik Bruecknerdone
227*fd834e09SHendrik Brueckner
228*fd834e09SHendrik Bruecknertest "$do_syscall_header" && generate_syscall_header "$abi_list" "$filename"
229*fd834e09SHendrik Bruecknertest "$do_syscall_table" && generate_syscall_table
230*fd834e09SHendrik Bruecknertest "$do_syscall_nr" && generate_syscall_nr "$abi_list"
231*fd834e09SHendrik Brueckner
232*fd834e09SHendrik Bruecknerexit 0
233