{ 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 */
{ 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 */
{ 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 */
{ 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_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 */
+ { 5, 0, printargs, "usr26" }, /* 3 */
+ { 5, 0, printargs, "usr32" }, /* 4 */
+ { 5, 0, printargs, "set_tls" }, /* 5 */
+#define ARM_LAST_SPECIAL_SYSCALL 5
+++ /dev/null
-/* "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 */
#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 LAST_ORDINARY+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
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);
- }
+
+ scno = shuffle_scno(scno);
#elif defined(M68K)
if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0)
return -1;
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);
/*
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) ||
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);
}