public inbox for ltp@lists.linux.it
 help / color / mirror / Atom feed
From: Andrea Cervesato <andrea.cervesato@suse.de>
To: ltp@lists.linux.it
Subject: [LTP] [PATCH 2/4] Add script to generate syscalls.h
Date: Tue, 24 Sep 2024 10:06:27 +0200	[thread overview]
Message-ID: <20240924-generate_syscalls-v1-2-941507a9cdac@suse.com> (raw)
In-Reply-To: <20240924-generate_syscalls-v1-0-941507a9cdac@suse.com>

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

Replicate the https://github.com/hrw/syscalls-table project way, by
creating a script that automatically generate syscalls input files,
merge them like regen.sh script does and to create syscalls.h header
file which can be used by LTP tests to access syscalls values accoring
to the architecture.

Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
 include/lapi/syscalls/blacklist-syscalls.txt |   6 +
 include/lapi/syscalls/generate_syscalls.sh   | 292 +++++++++++++++++++++++++++
 2 files changed, 298 insertions(+)

diff --git a/include/lapi/syscalls/blacklist-syscalls.txt b/include/lapi/syscalls/blacklist-syscalls.txt
new file mode 100644
index 000000000..e1ae5f76f
--- /dev/null
+++ b/include/lapi/syscalls/blacklist-syscalls.txt
@@ -0,0 +1,6 @@
+arch_specific_syscall
+available
+ni_syscall
+reserved
+SYSCALL_MASK
+unused
diff --git a/include/lapi/syscalls/generate_syscalls.sh b/include/lapi/syscalls/generate_syscalls.sh
new file mode 100755
index 000000000..f7bcbd50e
--- /dev/null
+++ b/include/lapi/syscalls/generate_syscalls.sh
@@ -0,0 +1,292 @@
+#!/bin/sh
+#
+# Script to generate the syscalls file for supported architectures.
+# Based on https://github.com/hrw/syscalls-table/
+#
+# Author: Andrea Cervesato <andrea.cervesato@suse.com>
+
+TEMP=$(mktemp -d)
+LINUX_SRC="$1"
+SYSCALLS_FILE="$2"
+
+if [ -z "${LINUX_SRC}" ]; then
+	echo "Give the path of Linux kernel sources:"
+	echo ""
+	echo "$0 linux/kernel/sources path/to/syscalls.h"
+	echo ""
+	exit 1
+fi
+
+if [ ! -e "${LINUX_SRC}/Makefile" ]; then
+	echo "No Makefile in ${LINUX_SRC} directory!"
+	exit 1
+fi
+
+if [ -z "${SYSCALLS_FILE}" ]; then
+	echo "No syscalls.h file location has been provided:"
+	echo ""
+	echo "$0 linux/kernel/sources path/to/syscalls.h"
+	echo ""
+	exit 1
+fi
+
+export LC_ALL=C
+
+SUPPORTED_ARCH="${PWD}/supported-arch.txt"
+LINUX_HEADERS="${TEMP}/headers"
+SYSCALLS_NAMES="${TEMP}/syscalls-names.txt"
+GENERATOR_BIN="${TEMP}/list-syscalls"
+GENERATOR_SRC="${GENERATOR_BIN}.c"
+
+build_headers() {
+	local arch="$1"
+
+	echo "Building linux headers..."
+
+	make -s -C ${LINUX_SRC} \
+		ARCH=${arch} \
+		O=${LINUX_HEADERS} \
+		headers_install >/dev/null
+}
+
+extract_syscalls() {
+	local arch="$1"
+	local flags="$2"
+
+	echo "Extracting syscalls names..."
+
+	grep -E -h "^#define __NR_" \
+		${LINUX_HEADERS}/usr/include/asm/unistd*.h \
+		${LINUX_HEADERS}/usr/include/asm-generic/unistd.h > \
+		${TEMP}/syscalls-names.tosort
+
+	grep -E -v "(unistd.h|NR3264|__NR_syscall|__SC_COMP|__NR_.*Linux|__NR_FAST)" \
+		${TEMP}/syscalls-names.tosort |
+		grep -E -vi "(not implemented|available|unused|reserved|xtensa|spill)" |
+		grep -E -v "(__SYSCALL|SYSCALL_BASE|SYSCALL_MASK)" |
+		sed -e "s/#define\s*__NR_//g" -e "s/\s.*//g" |
+		sort -u >${SYSCALLS_NAMES}
+
+	grep -w -v -f ${PWD}/blacklist-syscalls.txt ${TEMP}/syscall-names.txt |
+		sort -u >${TEMP}/syscall-names.txt
+
+	(
+		echo
+		echo "
+		#include <stdio.h>
+		#include <asm/unistd.h>
+
+		int main(void) {"
+		while IFS= read -r syscall; do
+			echo "
+		#ifdef __NR_$syscall
+			printf(\"$syscall\\t%d\\n\", __NR_$syscall);
+		#endif"
+		done < ${SYSCALLS_NAMES}
+		echo "return 0; }"
+	) >> ${GENERATOR_SRC}
+
+	local uppercase_arch=$(echo "$arch" | tr '[:lower:]' '[:upper:]')
+
+	gcc ${GENERATOR_SRC} -U__LP64__ -U__ILP32__ -U__i386__ \
+		-D${uppercase_arch} -D__${arch}__ ${flags} \
+		-I ${LINUX_HEADERS}/usr/include/ \
+		-o ${GENERATOR_BIN} &>/dev/null
+
+	echo "Generating ${arch}.in ..."
+
+	${GENERATOR_BIN} > "${TEMP}/${arch}.in"
+}
+
+generate_syscalls() {
+	while IFS= read -r arch; do
+		echo "Preparing syscalls for ${arch} architecture..."
+
+		case ${arch} in
+		aarch64)
+			build_headers "arm64"
+			extract_syscalls "${arch}" "-D__ARM_EABI__"
+			;;
+		arc)
+			build_headers "arc"
+			extract_syscalls "${arch}" "-D__BITS_PER_LONG=32"
+			;;
+		arm)
+			build_headers "arm"
+			extract_syscalls "${arch}" "-D__BITS_PER_LONG=32"
+			;;
+		hppa)
+			build_headers "parisc"
+			extract_syscalls "${arch}" ""
+			;;
+		i386)
+			build_headers "x86"
+			extract_syscalls "${arch}" "-D__BITS_PER_LONG=32"
+			;;
+		ia64)
+			# ia64 has been removed from the kernel, so we copy its
+			# last generated input file
+			echo "Copying ia64.in ..."
+			cp ${PWD}/ia64.in ${TEMP}/ia64.in
+			;;
+		loongarch)
+			build_headers "loongarch"
+			extract_syscalls "${arch}" "-D_LOONGARCH_SZLONG=64"
+			;;
+		mips_n32)
+			build_headers "mips"
+			extract_syscalls "${arch}" "-D_MIPS_SIM=_MIPS_SIM_NABI32"
+			;;
+		mips_n64)
+			build_headers "mips"
+			extract_syscalls "${arch}" "-D_MIPS_SIM=_MIPS_SIM_ABI64"
+			;;
+		mips_o32)
+			build_headers "mips"
+			extract_syscalls "${arch}" "-D_MIPS_SIM=_MIPS_SIM_ABI32"
+			;;
+		powerpc)
+			build_headers "powerpc"
+			extract_syscalls "${arch}" "-D__BITS_PER_LONG=32"
+			;;
+		powerpc64)
+			build_headers "powerpc"
+			extract_syscalls "${arch}" ""
+			;;
+		s390)
+			build_headers "s390"
+			extract_syscalls "${arch}" "-D__BITS_PER_LONG=32"
+			;;
+		s390x)
+			build_headers "s390"
+			extract_syscalls "${arch}" ""
+			;;
+		sh)
+			build_headers "sh"
+			extract_syscalls "${arch}" "-D__BITS_PER_LONG=32"
+			;;
+		sparc)
+			build_headers "sparc"
+			extract_syscalls "${arch}" "-D__32bit_syscall_numbers__ -D__BITS_PER_LONG=32"
+			;;
+		sparc64)
+			build_headers "sparc64"
+			extract_syscalls "${arch}" "-D__arch64__"
+			;;
+		x86_64)
+			build_headers "x86_64"
+			extract_syscalls "${arch}" "-D__LP64__"
+			;;
+		*)
+			echo "Can't find '${arch}' architecture"
+			exit 1
+			;;
+		esac
+	done < ${SUPPORTED_ARCH}
+}
+
+merge_syscalls() {
+	echo "Merging syscalls files..."
+
+	echo '
+/************************************************
+ * GENERATED FILE: DO NOT EDIT/PATCH THIS FILE  *
+ *  change your arch specific .in file instead  *
+ ************************************************/
+
+/*
+ * Here we stick all the ugly *fallback* logic for linux
+ * system call numbers (those __NR_ thingies).
+ *
+ * Licensed under the GPLv2 or later, see the COPYING file.
+ */
+
+#ifndef LAPI_SYSCALLS_H__
+#define LAPI_SYSCALLS_H__
+
+#include <errno.h>
+#include <sys/syscall.h>
+#include <asm/unistd.h>
+
+#ifdef TST_TEST_H__
+#define TST_SYSCALL_BRK__(NR, SNR) ({ \
+	tst_brk(TCONF, \
+		"syscall(%d) " SNR " not supported on your arch", NR); \
+})
+#else
+inline static void dummy_cleanup(void) {}
+
+#define TST_SYSCALL_BRK__(NR, SNR) ({ \
+	tst_brkm(TCONF, dummy_cleanup, \
+		"syscall(%d) " SNR " not supported on your arch", NR); \
+})
+#endif
+
+#define tst_syscall(NR, ...) ({ \
+	intptr_t tst_ret; \
+	if (NR == __LTP__NR_INVALID_SYSCALL) { \
+		errno = ENOSYS; \
+		tst_ret = -1; \
+	} else { \
+		tst_ret = syscall(NR, ##__VA_ARGS__); \
+	} \
+	if (tst_ret == -1 && errno == ENOSYS) { \
+		TST_SYSCALL_BRK__(NR, #NR); \
+	} \
+	tst_ret; \
+})
+
+#define __LTP__NR_INVALID_SYSCALL -1' > ${SYSCALLS_FILE}
+
+	local syscall_nr=""
+
+	while IFS= read -r arch; do
+	(
+		echo
+		case ${arch} in
+		sparc64) echo "#if defined(__sparc__) && defined(__arch64__)" ;;
+		sparc) echo "#if defined(__sparc__) && !defined(__arch64__)" ;;
+		s390) echo "#if defined(__s390__) && !defined(__s390x__)" ;;
+		mips_n32) echo "#if defined(__mips__) && defined(_ABIN32)" ;;
+		mips_n64) echo "#if defined(__mips__) && defined(_ABI64)" ;;
+		mips_o32) echo "#if defined(__mips__) && defined(_ABIO32) && _MIPS_SZLONG == 32" ;;
+		*) echo "#ifdef __${arch}__" ;;
+		esac
+
+		while read -r line; do
+			set -- ${line}
+			syscall_nr="__NR_$1"
+			shift
+
+			echo "# ifndef ${syscall_nr}"
+			echo "#  define ${syscall_nr} $*"
+			echo "# endif"
+		done <"${TEMP}/${arch}.in"
+		echo "#endif"
+		echo
+	) >> ${SYSCALLS_FILE}
+	done < ${SUPPORTED_ARCH}
+
+	(
+		echo
+		echo "/* Common stubs */"
+		while IFS= read -r arch; do
+			while IFS= read -r line; do
+				set -- ${line}
+				syscall_nr="__NR_$1"
+				shift
+
+				echo "# ifndef ${syscall_nr}"
+				echo "#  define ${syscall_nr} __LTP__NR_INVALID_SYSCALL"
+				echo "# endif"
+			done < ${TEMP}/${arch}.in
+		done < ${SUPPORTED_ARCH}
+		echo "#endif"
+	) >> ${SYSCALLS_FILE}
+}
+
+echo "Temporary folder: ${TEMP}"
+
+generate_syscalls
+merge_syscalls
+

-- 
2.43.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

  parent reply	other threads:[~2024-09-24  8:07 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-24  8:06 [LTP] [PATCH 0/4] Automatically generate syscalls.h Andrea Cervesato
2024-09-24  8:06 ` [LTP] [PATCH 1/4] Rename syscalls order file to supported-arch.txt Andrea Cervesato
2024-09-24  8:06 ` Andrea Cervesato [this message]
2024-09-24  8:06 ` [LTP] [PATCH 3/4] Deprecate old syscalls input files Andrea Cervesato
2024-09-24  8:06 ` [LTP] [PATCH 4/4] Save syscalls.h inside repo Andrea Cervesato
2024-09-24  8:46 ` [LTP] [PATCH 0/4] Automatically generate syscalls.h Andrea Cervesato via ltp
2024-09-24 13:16   ` Jan Stancek
2024-09-24 13:23     ` Andrea Cervesato via ltp
2024-09-25 20:01       ` Jan Stancek
2024-09-26  7:07         ` Andrea Cervesato via ltp
2024-09-26  7:47           ` Jan Stancek
2024-09-26  8:19             ` Andrea Cervesato via ltp

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240924-generate_syscalls-v1-2-941507a9cdac@suse.com \
    --to=andrea.cervesato@suse.de \
    --cc=ltp@lists.linux.it \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox