From: Eugene Syromyatnikov <evgsyr@gmail.com>
Date: Mon, 17 Sep 2018 00:59:15 +0000 (+0200)
Subject: ia64: optimize syscallent table
X-Git-Tag: v5.2~14
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3efa68a0ffa1c2eda414941f546e1626279e10d2;p=strace

ia64: optimize syscallent table

Use shuffle_scno since all valid syscall numbers start from 1024.

* linux/syscallent_base_nr.h: New file.
* linux/ia64/syscallent_base_nr.h: Likewise.
* linux/ia64/shuffle_scno.c: Likewise.
* Makefile.am (EXTRA_DIST): Add them.
* linux/ia64/syscallent.h [SYSCALLENT_BASE_NR] (BASE_NR): Define to 0.
* syscall.c: Include "syscallent_base_nr.h".
* clone.c [IA64] (ARG_STACKSIZE, ARG_PTID, ARG_CTID, ARG_TLS): Use
shuffle_scno.

Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
---

diff --git a/Makefile.am b/Makefile.am
index 628e7e90..dfd79892 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -588,7 +588,9 @@ EXTRA_DIST =				\
 	linux/ia64/rt_sigframe.h	\
 	linux/ia64/set_error.c		\
 	linux/ia64/set_scno.c		\
+	linux/ia64/shuffle_scno.c	\
 	linux/ia64/syscallent.h		\
+	linux/ia64/syscallent_base_nr.h	\
 	linux/ia64/userent.h		\
 	linux/inet_diag.h		\
 	linux/m68k/arch_defs_.h		\
@@ -849,6 +851,7 @@ EXTRA_DIST =				\
 	linux/syscall.h			\
 	linux/syscallent-common-32.h	\
 	linux/syscallent-common.h	\
+	linux/syscallent_base_nr.h	\
 	linux/tile/arch_defs_.h		\
 	linux/tile/arch_get_personality.c \
 	linux/tile/arch_regs.c		\
diff --git a/clone.c b/clone.c
index e74a53ce..3da54a2a 100644
--- a/clone.c
+++ b/clone.c
@@ -25,10 +25,10 @@
 #if defined IA64
 # define ARG_FLAGS	0
 # define ARG_STACK	1
-# define ARG_STACKSIZE	(tcp->scno == __NR_clone2 ? 2 : -1)
-# define ARG_PTID	(tcp->scno == __NR_clone2 ? 3 : 2)
-# define ARG_CTID	(tcp->scno == __NR_clone2 ? 4 : 3)
-# define ARG_TLS	(tcp->scno == __NR_clone2 ? 5 : 4)
+# define ARG_STACKSIZE	(shuffle_scno(tcp->scno) == __NR_clone2 ? 2 : -1)
+# define ARG_PTID	(shuffle_scno(tcp->scno) == __NR_clone2 ? 3 : 2)
+# define ARG_CTID	(shuffle_scno(tcp->scno) == __NR_clone2 ? 4 : 3)
+# define ARG_TLS	(shuffle_scno(tcp->scno) == __NR_clone2 ? 5 : 4)
 #elif defined S390 || defined S390X
 # define ARG_STACK	0
 # define ARG_FLAGS	1
diff --git a/linux/ia64/shuffle_scno.c b/linux/ia64/shuffle_scno.c
new file mode 100644
index 00000000..6bac3a8b
--- /dev/null
+++ b/linux/ia64/shuffle_scno.c
@@ -0,0 +1,11 @@
+static_assert(!(SYSCALLENT_BASE_NR & (SYSCALLENT_BASE_NR - 1)),
+	      "SYSCALLENT_BASE_NR is not a power of 2 (or zero)");
+static_assert(nsyscalls0 < SYSCALLENT_BASE_NR,
+	      "syscall table is too big, "
+	      "shuffling will only make everything worse");
+
+kernel_ulong_t
+shuffle_scno(kernel_ulong_t scno)
+{
+	return scno ^ SYSCALLENT_BASE_NR;
+}
diff --git a/linux/ia64/syscallent.h b/linux/ia64/syscallent.h
index 86f7efd7..8a138860 100644
--- a/linux/ia64/syscallent.h
+++ b/linux/ia64/syscallent.h
@@ -7,7 +7,19 @@
  * SPDX-License-Identifier: LGPL-2.1-or-later
  */
 
-#define BASE_NR 1024
+#ifdef SYSCALLENT_BASE_NR
+/*
+ * The syscallent table starts from 0 because
+ * it is optimized for use with shuffle_scno.
+ */
+# define BASE_NR 0
+#else
+/*
+ * __NR_* constants start from 1024 as usual.
+ * (1U << 10) cannot be used here because SCNO_SED is not smart enough.
+ */
+# define BASE_NR 1024
+#endif
 [BASE_NR +   0] = { 0,	0,		SEN(printargs),			"ni_syscall"		},
 [BASE_NR +   1] = { 1,	TP|SE,		SEN(exit),			"exit"			},
 [BASE_NR +   2] = { 3,	TD,		SEN(read),			"read"			},
diff --git a/linux/ia64/syscallent_base_nr.h b/linux/ia64/syscallent_base_nr.h
new file mode 100644
index 00000000..612668ec
--- /dev/null
+++ b/linux/ia64/syscallent_base_nr.h
@@ -0,0 +1 @@
+#define SYSCALLENT_BASE_NR (1U << 10)
diff --git a/linux/syscallent_base_nr.h b/linux/syscallent_base_nr.h
new file mode 100644
index 00000000..da84fa5f
--- /dev/null
+++ b/linux/syscallent_base_nr.h
@@ -0,0 +1 @@
+/* nothing */
diff --git a/syscall.c b/syscall.c
index a67d7442..77f73cd0 100644
--- a/syscall.c
+++ b/syscall.c
@@ -41,6 +41,7 @@
 
 #include "syscall.h"
 #include "xstring.h"
+#include "syscallent_base_nr.h"
 
 /* Define these shorthand notations to simplify the syscallent files. */
 #include "sysent_shorthand_defs.h"