[LTP] [PATCH 1/2] generate_arch.sh: Fix syscall extraction bugs

Andrea Cervesato andrea.cervesato@suse.de
Wed Sep 30 10:32:34 CEST 2026


From: Andrea Cervesato <andrea.cervesato@suse.com>

Do not filter out sys_ni_syscall from tables and seed syscall names
from generic headers and existing tables so legacy syscalls like
_sysctl and timerfd are preserved.

Check s390 header macros to detect 31-bit ABI availability instead of
overwriting s390.in with 64-bit definitions on newer kernels.

Fail immediately when compilation fails for a supported architecture
rather than silently continuing.

Fixes: 1694fd203cf1 ("Add script to generate arch(s) dependant syscalls")
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
 include/lapi/syscalls/generate_arch.sh | 99 +++++++++++++++++-----------------
 1 file changed, 49 insertions(+), 50 deletions(-)

diff --git a/include/lapi/syscalls/generate_arch.sh b/include/lapi/syscalls/generate_arch.sh
index 5d731794d..969c1b6da 100755
--- a/include/lapi/syscalls/generate_arch.sh
+++ b/include/lapi/syscalls/generate_arch.sh
@@ -33,6 +33,7 @@ if [ ! -e "${KERNELSRC}/Makefile" ]; then
 fi
 
 TEMP="$(mktemp -d)"
+trap 'rm -rf "${TEMP}"' EXIT
 KVER="$(make -C ${KERNELSRC} kernelversion -s)"
 
 SCRIPT_DIR="$(realpath $(dirname "$0"))"
@@ -41,18 +42,16 @@ LINUX_HEADERS="${TEMP}/headers"
 
 grab_syscall_names_from_tables() {
 	for tbl_file in $(find ${KERNELSRC}/arch -name syscall*.tbl); do
-		grep -E -v "(^#|^$|sys_ni_syscall)" $tbl_file |
+		grep -E -v "^(#|$)" "$tbl_file" |
 			awk '{ print $3 }' >>${TEMP}/syscall-names.tosort
 	done
 
-	drop_bad_entries
-}
-
-grab_syscall_names_from_unistd_h() {
 	grep -E -h "^#define __NR_" \
-		${LINUX_HEADERS}/usr/include/asm/unistd*.h \
-		${LINUX_HEADERS}/usr/include/asm-generic/unistd.h \
-		>${TEMP}/syscall-names.tosort
+		${KERNELSRC}/include/uapi/asm-generic/unistd.h \
+		${KERNELSRC}/arch/*/include/uapi/asm/unistd*.h \
+		>>${TEMP}/syscall-names.tosort 2>/dev/null || true
+
+	awk '{ print $1 }' ${SCRIPT_DIR}/*.in >>${TEMP}/syscall-names.tosort
 
 	drop_bad_entries
 }
@@ -60,6 +59,7 @@ grab_syscall_names_from_unistd_h() {
 drop_bad_entries() {
 	grep -E -v "(unistd.h|NR3264|__NR_syscall|__SC_COMP|__NR_.*Linux|__NR_FAST)" \
 		${TEMP}/syscall-names.tosort |
+		grep -E -vi "(not implemented|available|unused|reserved|spill|xtensa)" |
 		grep -E -v "(__SYSCALL|SYSCALL_BASE|SYSCALL_MASK)" |
 		sed -e "s/#define\s*__NR_//g" -e "s/\s.*//g" |
 		sort -u >${TEMP}/syscall-names.txt
@@ -68,51 +68,43 @@ drop_bad_entries() {
 generate_table() {
 	echo "- $arch"
 
+	local flags="${extraflags:-}"
 	if [ "$bits" -eq "32" ]; then
-		extraflags="${extraflags} -D__BITS_PER_LONG=32"
+		flags="${flags} -D__BITS_PER_LONG=32"
 	fi
 
 	local uppercase_arch=$(echo "$arch" | tr '[:lower:]' '[:upper:]')
 
-	# ignore any error generated by gcc. We want to obtain all the
-	# available architecture syscalls for the current platform and to handle
-	# only supported architectures later on
-	gcc ${TEMP}/list-syscalls.c -U__LP64__ -U__ILP32__ -U__i386__ \
+	rm -f "${TEMP}/list-syscalls"
+	gcc "${TEMP}/list-syscalls.c" -U__LP64__ -U__ILP32__ -U__i386__ \
 		-D${uppercase_arch} \
-		-D__${arch}__ ${extraflags} \
-		-I ${LINUX_HEADERS}/usr/include/ \
-		-o ${TEMP}/list-syscalls || true
+		-D__${arch}__ ${flags} \
+		-I "${LINUX_HEADERS}/usr/include/" \
+		-o "${TEMP}/list-syscalls" || {
+		echo "Failed to compile list-syscalls for $arch" >&2
+		if grep -Fxq "$arch" "${SUPPORTED_ARCH}"; then
+			return 1
+		fi
+		return 0
+	}
 
-	${TEMP}/list-syscalls >"${TEMP}/${arch}.in.tosort"
+	"${TEMP}/list-syscalls" >"${TEMP}/${arch}.in.tosort"
 
 	sort -k2,2n "${TEMP}/${arch}.in.tosort" >"${TEMP}/${arch}.in"
 }
 
 generate_list_syscalls_c() {
-	(
-		printf "
-		#include <stdio.h>
-		#include <asm/unistd.h>
-
-		int main(void)
-		{
-		"
-		for syscall in $(cat ${TEMP}/syscall-names.txt); do
-			printf "
-		#ifdef __NR_$syscall
-			printf(\"$syscall %%d"
-			# i know the following print is ugly, but dash and bash
-			# treat double quoted strings in a different way and we
-			# really need to inject '\n' character in the C code
-			# rather than carriage return
-			printf '\\n'
-			printf "\", __NR_$syscall);
-		#endif
-		"
-		done
-		printf " return 0;
-		}"
-	) >${TEMP}/list-syscalls.c
+	{
+		echo "#include <stdio.h>"
+		echo "#include <asm/unistd.h>"
+		echo
+		echo "int main(void)"
+		echo "{"
+		awk '{ printf "#ifdef __NR_%s\n\tprintf(\"%s %%d\\n\", __NR_%s);\n#endif\n", $1, $1, $1 }' \
+			"${TEMP}/syscall-names.txt"
+		echo "	return 0;"
+		echo "}"
+	} >"${TEMP}/list-syscalls.c"
 }
 
 export_headers() {
@@ -128,16 +120,16 @@ do_all_tables() {
 		extraflags=
 
 		case ${arch} in
-		Kconfig)
-			continue
-			;;
-		um)
+		Kconfig|um)
 			continue
 			;;
 		esac
 
+		if [ ! -f "${archdir}/Makefile" ] && [ ! -f "${archdir}/Kconfig" ]; then
+			continue
+		fi
+
 		export_headers
-		grab_syscall_names_from_unistd_h
 
 		case ${arch} in
 		arm)
@@ -156,8 +148,8 @@ do_all_tables() {
 			arch=mips64n32 extraflags=-D_MIPS_SIM=_MIPS_SIM_NABI32 generate_table
 			;;
 		powerpc)
-			generate_table
-			arch=powerpc64 generate_table
+			bits=32 generate_table
+			bits=64 arch=powerpc64 generate_table
 			;;
 		riscv)
 			arch=riscv64 extraflags=-D__LP64__ generate_table
@@ -165,8 +157,15 @@ do_all_tables() {
 			arch=riscv32 extraflags=-D__SIZEOF_POINTER__=4 generate_table
 			;;
 		s390)
-			bits=32
-			generate_table
+			# Older kernels define both ABIs directly in unistd.h.
+			gcc -E -dM -x c -D__s390__ -U__s390x__ \
+				-I "${LINUX_HEADERS}/usr/include/" \
+				-include asm/unistd.h /dev/null >"${TEMP}/s390-macros"
+			if grep -q '^#define __NR_getuid32 ' "${TEMP}/s390-macros"; then
+				bits=32 generate_table
+			else
+				echo "- s390 (31-bit ABI not available, skipping)"
+			fi
 			bits=64
 			arch=s390x generate_table
 			;;

-- 
2.51.0



More information about the ltp mailing list