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