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