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