[PATCH] arm: make it one-personality arch

Denys Vlasenko dvlasenk at redhat.com
Wed Feb 20 18:08:13 UTC 2013


ARM in fact _is_ one personality.

We have two personalities for it because it has a handful of
syscalls with huge scnos (0x000f00xx).

Extending syscall table to have [0x000f0005] index is of course
not a good idea.

Someone decided to handle that by having a separate personality
just for these syscalls.

But multi-personality arch does a bit more work in other parts:
grep for "SUPPORTED_PERSONALITIES > 1".

This patch is another alternative: "move" 0x000f00nn syscalls
down to the entries just above last ordinary syscall,
by manipulating scno if it falls into the 0x000f00xx range.

Yet another alternative is to simply treat all 0x000f00nn syscalls
as "undefined" - print them as "syscall_nnn" as we do now
for undefined syscalls.
This alternative can be realized by removing from this patch
the code block below "//TODO: why bother?" comment.
This would be almost as good as what we have now:
all these "special syscalls" are printargs anyway.
The _ONLY_ thing we do for them now is we supply
somewhat meaningful names for them.

Please review and let me know what you think.
-- 
vda

diff -d -urpN strace.1/defs.h strace.2/defs.h
--- strace.1/defs.h	2013-02-20 12:15:41.000000000 +0100
+++ strace.2/defs.h	2013-02-20 17:46:08.594585704 +0100
@@ -318,9 +318,7 @@ struct arm_pt_regs {
 #endif

 #ifdef ARM
-# define SUPPORTED_PERSONALITIES 2
-# define PERSONALITY0_WORDSIZE 4
-# define PERSONALITY1_WORDSIZE 4
+/* one personality */
 #endif

 #ifdef AARCH64
diff -d -urpN strace.1/linux/arm/errnoent1.h strace.2/linux/arm/errnoent1.h
--- strace.1/linux/arm/errnoent1.h	2013-02-20 12:15:41.000000000 +0100
+++ strace.2/linux/arm/errnoent1.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,2 +0,0 @@
-/* "ARM specific syscall" personality */
-#include "../errnoent.h"
diff -d -urpN strace.1/linux/arm/ioctlent1.h strace.2/linux/arm/ioctlent1.h
--- strace.1/linux/arm/ioctlent1.h	2013-02-20 12:15:41.000000000 +0100
+++ strace.2/linux/arm/ioctlent1.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,2 +0,0 @@
-/* "ARM specific syscall" personality */
-#include "../ioctlent.h"
diff -d -urpN strace.1/linux/arm/signalent1.h strace.2/linux/arm/signalent1.h
--- strace.1/linux/arm/signalent1.h	2013-02-20 17:48:52.030494290 +0100
+++ strace.2/linux/arm/signalent1.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,2 +0,0 @@
-/* "ARM specific syscall" personality */
-#include "../signalent.h"
diff -d -urpN strace.1/linux/arm/syscallent1.h strace.2/linux/arm/syscallent1.h
--- strace.1/linux/arm/syscallent1.h	2013-02-20 12:15:41.000000000 +0100
+++ strace.2/linux/arm/syscallent1.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,7 +0,0 @@
-/* "ARM specific syscall" personality */
-	{ 5,	0,	NULL,			NULL			}, /* 0 */
-	{ 5,	0,	printargs,		"breakpoint"		}, /* 1 */
-	{ 5,	0,	printargs,		"cacheflush"		}, /* 2 */
-	{ 5,	0,	printargs,		"usr26"			}, /* 3 */
-	{ 5,	0,	printargs,		"usr32"			}, /* 4 */
-	{ 5,	0,	printargs,		"set_tls"		}, /* 5 */
diff -d -urpN strace.1/linux/arm/syscallent.h strace.2/linux/arm/syscallent.h
--- strace.1/linux/arm/syscallent.h	2013-02-20 17:51:37.039400700 +0100
+++ strace.2/linux/arm/syscallent.h	2013-02-20 18:28:39.062552420 +0100
@@ -406,8 +406,9 @@
 	{ 2,	TD,	sys_setns,		"setns"		}, /* 375 */
 	{ 6,	0,	sys_process_vm_readv,	"process_vm_readv"	}, /* 376 */
 	{ 6,	0,	sys_process_vm_writev,	"process_vm_writev"	}, /* 377 */
-
-#ifndef __ARM_EABI__
+#ifdef __ARM_EABI__
+# define ARM_LAST_ORDINARY_SYSCALL 377
+#else
 	{ 5,	0,	NULL,			NULL		}, /* 378 */
 	{ 5,	0,	NULL,			NULL		}, /* 379 */
 	{ 5,	0,	NULL,			NULL		}, /* 380 */
@@ -430,9 +431,9 @@
 	{ 5,	0,	NULL,			NULL		}, /* 397 */
 	{ 5,	0,	NULL,			NULL		}, /* 398 */
 	{ 5,	0,	NULL,			NULL		}, /* 399 */
-#if SYS_socket_subcall != 400
- #error fix me
-#endif
+# if SYS_socket_subcall != 400
+#  error fix me
+# endif
 	{ 6,	0,	printargs,		"socket_subcall"}, /* 400 */
 	{ 3,	TN,	sys_socket,		"socket"	}, /* 401 */
 	{ 3,	TN,	sys_bind,		"bind"		}, /* 402 */
@@ -454,9 +455,9 @@
 	{ 4,	TN,	sys_accept4,		"accept4"	}, /* 418 */
 	{ 5,	TN,	sys_recvmmsg,		"recvmmsg"	}, /* 419 */

-#if SYS_ipc_subcall != 420
- #error fix me
-#endif
+# if SYS_ipc_subcall != 420
+#  error fix me
+# endif
 	{ 4,	0,	printargs,		"ipc_subcall"	}, /* 420 */
 	{ 4,	TI,	sys_semop,		"semop"		}, /* 421 */
 	{ 4,	TI,	sys_semget,		"semget"	}, /* 422 */
@@ -482,4 +483,18 @@
 	{ 4,	TI,	sys_shmdt,		"shmdt"		}, /* 442 */
 	{ 4,	TI,	sys_shmget,		"shmget"	}, /* 443 */
 	{ 4,	TI,	sys_shmctl,		"shmctl"	}, /* 444 */
-#endif
+# define ARM_LAST_ORDINARY_SYSCALL 444
+#endif /* !EABI */
+
+	/* ARM specific syscalls. Encoded with scno 0x000fxxxx,
+	 * remapped by get_scno() to be directly after ordinary syscalls
+	 * in the table.
+	 */
+
+	{ 5,	0,	NULL,			NULL			}, /* 0 */
+	{ 5,	0,	printargs,		"breakpoint"		}, /* 1 */
+	{ 5,	0,	printargs,		"cacheflush"		}, /* 2 */
+	{ 5,	0,	printargs,		"usr26"			}, /* 3 */
+	{ 5,	0,	printargs,		"usr32"			}, /* 4 */
+	{ 5,	0,	printargs,		"set_tls"		}, /* 5 */
+#define ARM_LAST_SPECIAL_SYSCALL 5
diff -d -urpN strace.1/syscall.c strace.2/syscall.c
--- strace.1/syscall.c	2013-02-20 17:26:54.220397122 +0100
+++ strace.2/syscall.c	2013-02-20 18:57:14.495845195 +0100
@@ -1246,12 +1246,25 @@ get_scno(struct tcb *tcp)
 			scno &= 0x000fffff;
 		}
 	}
-	if (scno & 0x000f0000) {
-		/* ARM specific syscall. We handle it as a separate "personality" */
-		update_personality(tcp, 1);
-		scno &= 0x0000ffff;
-	} else {
-		update_personality(tcp, 0);
+
+//TODO: why bother? All special syscalls in syscallent.h are printargs anyway
+//TODO: support "doubly special" __ARM_NR_cmpxchg with scno == 0x000ffff0
+
+# define ARM_NUM_ORDINARY_SYSCALLS (ARM_LAST_ORDINARY_SYSCALL + 1)
+
+	if (scno > ARM_LAST_ORDINARY_SYSCALL) {
+		/* Is it ARM specific syscall? */
+		if ((scno & 0xffff0000) == 0x000f0000
+		 && scno <= 0x000f0000 + ARM_LAST_SPECIAL_SYSCALL
+		) {
+			/* Yes. Remap 0x000f00nn -> ARM_NUM_ORDINARY_SYSCALLS + nn */
+			scno -= 0x000f0000 - ARM_NUM_ORDINARY_SYSCALLS;
+		} else
+		/* Is it a (bad) syscall no from the hole we remap into? */
+		if (scno <= ARM_NUM_ORDINARY_SYSCALLS + ARM_LAST_SPECIAL_SYSCALL) {
+			/* Yes. Make sure it doesn't collide with special syscalls */
+			scno += 0x000f0000 - ARM_NUM_ORDINARY_SYSCALLS;
+		}
 	}
 #elif defined(M68K)
 	if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0)




More information about the Strace-devel mailing list