[PATCH] arm: make it one-personality arch

Denys Vlasenko dvlasenk at redhat.com
Thu Feb 21 12:31:18 UTC 2013


On 02/21/2013 10:24 AM, Denys Vlasenko wrote:
> By combining my patch and print_undefined_scno()
> we can have both: remapping will give us decoding,
> and print_undefined_scno() can do *reverse* remapping
> before it prints "syscall_NN()" thing.

Like this:


diff -d -urpN strace.2/linux/arm/syscallent.h strace.3/linux/arm/syscallent.h
--- strace.2/linux/arm/syscallent.h	2013-02-20 18:28:39.062552420 +0100
+++ strace.3/linux/arm/syscallent.h	2013-02-21 13:08:17.858657269 +0100
@@ -486,11 +486,15 @@
 # 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.
+	/* __ARM_NR_cmpxchg (0x000ffff0).
+	 * Remapped by shuffle_scno() to be directly after ordinary syscalls
+	 * in this table.
 	 */
+	{ 5,	0,	printargs,		"cmpxchg"		},

+	/* ARM specific syscalls. Encoded with scno 0x000f00xx.
+	 * Remapped by shuffle_scno() to be directly after __ARM_NR_cmpxchg.
+	 */
 	{ 5,	0,	NULL,			NULL			}, /* 0 */
 	{ 5,	0,	printargs,		"breakpoint"		}, /* 1 */
 	{ 5,	0,	printargs,		"cacheflush"		}, /* 2 */
diff -d -urpN strace.2/syscall.c strace.3/syscall.c
--- strace.2/syscall.c	2013-02-20 18:57:14.495845195 +0100
+++ strace.3/syscall.c	2013-02-21 13:09:58.242653484 +0100
@@ -899,6 +899,51 @@ printcall(struct tcb *tcp)
 #endif /* architecture */
 }

+/* Shuffle syscall numbers so that we don't have huge gaps in syscall table.
+ * The shuffling should be reversible: shuffle_scno(shuffle_scno(n)) == n.
+ */
+#if defined(ARM) /* So far only ARM needs this */
+static long
+shuffle_scno(unsigned long scno)
+{
+	if (scno <= ARM_LAST_ORDINARY_SYSCALL)
+		return scno;
+
+	/* __ARM_NR_cmpxchg? Swap with ARM_LAST_ORDINARY_SYSCALL+1 */
+	if (scno == 0x000ffff0)
+		return ARM_LAST_ORDINARY_SYSCALL+1;
+	if (scno == ARM_LAST_ORDINARY_SYSCALL+1)
+		return 0x000ffff0;
+
+	/* Is it ARM specific syscall?
+	 * Swap with [LAST_ORDINARY+2, LAST_ORDINARY+2+LAST_SPECIAL] range.
+	 */
+	if (scno >= 0x000f0000
+	 && scno <= 0x000f0000 + ARM_LAST_SPECIAL_SYSCALL
+	) {
+		return scno - 0x000f0000 + (ARM_LAST_ORDINARY_SYSCALL+2);
+	}
+	if (/* scno >= ARM_LAST_ORDINARY_SYSCALL+2 - always true */ 1
+	 && scno <= (ARM_LAST_ORDINARY_SYSCALL+2) + ARM_LAST_SPECIAL_SYSCALL
+	) {
+		return scno + 0x000f0000 - (ARM_LAST_ORDINARY_SYSCALL+2);
+	}
+
+	return scno;
+}
+#else
+# define shuffle_scno(scno) ((long)(scno))
+#endif
+
+static char*
+undefined_scno_name(struct tcb *tcp)
+{
+	static char buf[sizeof("syscall_%lu") + sizeof(long)*3];
+
+	sprintf(buf, "syscall_%lu", shuffle_scno(tcp->scno));
+	return buf;
+}
+
 #ifndef get_regs
 long get_regs_error;
 void
@@ -1247,25 +1292,7 @@ get_scno(struct tcb *tcp)
 		}
 	}

-//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;
-		}
-	}
+	scno = shuffle_scno(scno);
 #elif defined(M68K)
 	if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0)
 		return -1;
@@ -1848,7 +1875,7 @@ trace_syscall_entering(struct tcb *tcp)
 		if (scno_good != 1)
 			tprints("????" /* anti-trigraph gap */ "(");
 		else if (!SCNO_IS_VALID(tcp->scno))
-			tprintf("syscall_%lu(", tcp->scno);
+			tprintf("%s(", undefined_scno_name(tcp));
 		else
 			tprintf("%s(", sysent[tcp->scno].sys_name);
 		/*
@@ -1895,7 +1922,7 @@ trace_syscall_entering(struct tcb *tcp)

 	printleader(tcp);
 	if (!SCNO_IS_VALID(tcp->scno))
-		tprintf("syscall_%lu(", tcp->scno);
+		tprintf("%s(", undefined_scno_name(tcp));
 	else
 		tprintf("%s(", sysent[tcp->scno].sys_name);
 	if (!SCNO_IS_VALID(tcp->scno) ||
@@ -2382,7 +2409,7 @@ trace_syscall_exiting(struct tcb *tcp)
 		tcp->flags &= ~TCB_REPRINT;
 		printleader(tcp);
 		if (!SCNO_IS_VALID(tcp->scno))
-			tprintf("<... syscall_%lu resumed> ", tcp->scno);
+			tprintf("<... %s resumed> ", undefined_scno_name(tcp));
 		else
 			tprintf("<... %s resumed> ", sysent[tcp->scno].sys_name);
 	}




More information about the Strace-devel mailing list