Add tilegx support to strace
tilegx support has been in the kernel since 3.0.
In addition, fix some issues with the tilepro support already
present in strace, primarily the decision to use the
<asm/unistd.h> numbering space for system calls.
* defs.h [TILE]: Include <asm/ptrace.h> and provide an extern
struct pt_regs tile_regs for efficiency. Provide compat 32-bit
personality via SUPPORTED_PERSONALITIES, PERSONALITY0_WORDSIZE,
PERSONALITY1_WORDSIZE, and DEFAULT_PERSONALITY.
* linux/tile/errnoent1.h: New file, includes linux/errnoent.h.
* linux/tile/ioctlent1.h: New file, includes linux/ioctlent.h.
* linux/tile/signalent1.h: New file, includes linux/signalent.h.
* linux/tile/syscallent.h: Update with new asm-generic syscalls.
The version previously committed was the from the first tile patch
to LKML, which subsequently was changed to use <asm-generic/unistd.h>.
* linux/tile/syscallent1.h: Copy from linux/tile/syscallent.h.
* mem.c (addtileflags) [TILE]: use %ld properly for a "long" variable.
* process.c [TILE]: Choose clone arguments correctly and properly
suppress all "struct user" related offsets in user_struct_offsets.
* signal.c [TILE]: Use tile_regs not upeek.
* syscall.c (update_personality) [TILE]: Print mode.
(PT_FLAGS_COMPAT) [TILE]: Provide if not in system headers.
(tile_regs) [TILE]: Define 'struct pt_regs' variable to hold state.
(get_regs) [TILE]: use PTRACE_GETREGS to set tile_regs rather than using upeek.
(get_scno) [TILE]: Set personality.
(get_syscall_args) [TILE]: Use tile_regs.
(get_syscall_result) [TILE]: Update tile_regs.
(get_error) [TILE]: Use tile_regs.
(printcall) [TILE]: Print pc.
(arg0_offset, arg1_offset, restore_arg0, restore_arg1) [TILE]:
Properly handle tile call semantics and support tilegx.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
diff --git a/syscall.c b/syscall.c
index c31233c..cd3647d 100644
--- a/syscall.c
+++ b/syscall.c
@@ -71,6 +71,12 @@
# include <elf.h>
#endif
+#if defined(TILE)
+# ifndef PT_FLAGS_COMPAT
+# define PT_FLAGS_COMPAT 0x10000 /* from Linux 3.8 on */
+# endif
+#endif
+
#ifndef ERESTARTSYS
# define ERESTARTSYS 512
#endif
@@ -293,6 +299,12 @@
fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
tcp->pid, names[personality]);
}
+# elif defined(TILE)
+ if (!qflag) {
+ static const char *const names[] = {"64-bit", "32-bit"};
+ fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
+ tcp->pid, names[personality]);
+ }
# endif
}
#endif
@@ -699,6 +711,8 @@
static long r9;
#elif defined(CRISV10) || defined(CRISV32)
static long r10;
+#elif defined(TILE)
+struct pt_regs tile_regs;
#elif defined(MICROBLAZE)
static long r3;
#endif
@@ -829,6 +843,12 @@
return;
}
tprintf("[%08lx] ", pc);
+#elif defined(TILE)
+# ifdef _LP64
+ tprintf("[%16lx] ", tile_regs.pc);
+# else
+ tprintf("[%08lx] ", tile_regs.pc);
+# endif
#endif /* architecture */
}
@@ -865,6 +885,8 @@
get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, (void *)®s);
# elif defined(SPARC) || defined(SPARC64)
get_regs_error = ptrace(PTRACE_GETREGS, pid, (char *)®s, 0);
+# elif defined(TILE)
+ get_regs_error = ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) &tile_regs);
# endif
}
#endif
@@ -1289,8 +1311,25 @@
if (upeek(tcp, 4*PT_R9, &scno) < 0)
return -1;
#elif defined(TILE)
- if (upeek(tcp, PTREGS_OFFSET_REG(10), &scno) < 0)
- return -1;
+ int currpers;
+ scno = tile_regs.regs[10];
+# ifdef __tilepro__
+ currpers = 1;
+# else
+ if (tile_regs.flags & PT_FLAGS_COMPAT)
+ currpers = 1;
+ else
+ currpers = 0;
+# endif
+ update_personality(tcp, currpers);
+
+ if (!(tcp->flags & TCB_INSYSCALL)) {
+ /* Check if we return from execve. */
+ if (tcp->flags & TCB_WAITEXECVE) {
+ tcp->flags &= ~TCB_WAITEXECVE;
+ return 0;
+ }
+ }
#elif defined(MICROBLAZE)
if (upeek(tcp, 0, &scno) < 0)
return -1;
@@ -1664,8 +1703,7 @@
return -1;
#elif defined(TILE)
for (i = 0; i < nargs; ++i)
- if (upeek(tcp, PTREGS_OFFSET_REG(i), &tcp->u_arg[i]) < 0)
- return -1;
+ tcp->u_arg[i] = tile_regs.regs[i];
#elif defined(M68K)
for (i = 0; i < nargs; ++i)
if (upeek(tcp, (i < 5 ? i : i + 2)*4, &tcp->u_arg[i]) < 0)
@@ -1865,6 +1903,7 @@
if (upeek(tcp, 4*PT_R10, &r10) < 0)
return -1;
#elif defined(TILE)
+ /* already done by get_regs */
#elif defined(MICROBLAZE)
if (upeek(tcp, 3 * 4, &r3) < 0)
return -1;
@@ -2089,15 +2128,17 @@
tcp->u_rval = r10;
}
#elif defined(TILE)
- long rval;
- if (upeek(tcp, PTREGS_OFFSET_REG(0), &rval) < 0)
- return -1;
- if (check_errno && rval < 0 && rval > -nerrnos) {
+ /*
+ * The standard tile calling convention returns the value (or negative
+ * errno) in r0, and zero (or positive errno) in r1.
+ * Until at least kernel 3.8, however, the r1 value is not reflected
+ * in ptregs at this point, so we use r0 here.
+ */
+ if (check_errno && is_negated_errno(tile_regs.regs[0])) {
tcp->u_rval = -1;
- u_error = -rval;
- }
- else {
- tcp->u_rval = rval;
+ u_error = -tile_regs.regs[0];
+ } else {
+ tcp->u_rval = tile_regs.regs[0];
}
#elif defined(MICROBLAZE)
if (check_errno && is_negated_errno(r3)) {