syscalltbl 4.4 KB

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