[LTP] [PATCH v2 1/2] generate_arch.sh: Fix syscall extraction bugs
Andrea Cervesato
andrea.cervesato@suse.de
Wed Sep 30 18:59:31 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")
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
include/lapi/syscalls/generate_arch.sh | 103 +++++++++++++++++----------------
1 file changed, 53 insertions(+), 50 deletions(-)
diff --git a/include/lapi/syscalls/generate_arch.sh b/include/lapi/syscalls/generate_arch.sh
index 5d731794d..b627ceae5 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
+
+ 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,47 @@ 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
+ local syscalls
+
+ syscalls=$(awk '{ printf "#ifdef __NR_%s\n\tprintf(\"%s %%d\\n\", __NR_%s);\n#endif\n", $1, $1, $1 }' \
+ "${TEMP}/syscall-names.txt")
+
+ cat << EOF >"${TEMP}/list-syscalls.c"
+#include <stdio.h>
+#include <asm/unistd.h>
+
+int main(void)
+{
+${syscalls}
+ return 0;
+}
+EOF
}
export_headers() {
@@ -128,16 +124,16 @@ do_all_tables() {
extraflags=
case ${arch} in
- Kconfig)
- continue
- ;;
- um)
+ Kconfig|um)
continue
;;
esac
+ if [ ! -f "${archdir}/Kconfig" ]; then
+ continue
+ fi
+
export_headers
- grab_syscall_names_from_unistd_h
case ${arch} in
arm)
@@ -156,8 +152,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 +161,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