1 |
commit: a178ab35775d851e65df1408471681aa023b6dbc |
2 |
Author: Mike Frysinger <vapier <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sun Dec 20 06:10:57 2015 +0000 |
4 |
Commit: Mike Frysinger <vapier <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun Dec 20 06:10:57 2015 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/sandbox.git/commit/?id=a178ab35 |
7 |
|
8 |
libsandbox: improve sparc trace code a bit more |
9 |
|
10 |
This gets most of the tests passing, but syscall canceling still |
11 |
does not work. Need to talk to upstream to figure it out. |
12 |
|
13 |
Signed-off-by: Mike Frysinger <vapier <AT> gentoo.org> |
14 |
|
15 |
libsandbox/trace/linux/sparc.c | 34 ++++++++++++++++++++++++++-------- |
16 |
1 file changed, 26 insertions(+), 8 deletions(-) |
17 |
|
18 |
diff --git a/libsandbox/trace/linux/sparc.c b/libsandbox/trace/linux/sparc.c |
19 |
index f410b73..b59a036 100644 |
20 |
--- a/libsandbox/trace/linux/sparc.c |
21 |
+++ b/libsandbox/trace/linux/sparc.c |
22 |
@@ -1,20 +1,28 @@ |
23 |
#define SB_NO_TRACE_ARCH |
24 |
#if 0 /* XXX: broken sometimes #293632 */ |
25 |
|
26 |
-/* Indexes into the pt_regs.u_reg[] array -- UREG_XX from kernel are all off |
27 |
- * by 1 and use Ix instead of Ox. These work for both 32 and 64 bit Linux. |
28 |
+/* Since sparc's g0 register is hardcoded to 0 in the ISA, the kernel does not |
29 |
+ * bother copying it out when using the regs ptrace. Instead it shifts things |
30 |
+ * by one and stores [g1..g7] in [0..6] and [o0..o7] in [7..14] (leaving the |
31 |
+ * last u_reg[15] unused). |
32 |
+ * |
33 |
+ * Oddly, the kernel defines are not adjusted to the values as they written in |
34 |
+ * the register structure -- UREG_G0 is 0, UREG_G1 is 1, etc... So we have to |
35 |
+ * define our own to get correct behavior. Also, the kernel uses UREG_I# when |
36 |
+ * it's easier for us to think of it in terms of UREG_O# (register windows!). |
37 |
+ * |
38 |
+ * This should work for both 32 and 64 bit Linux userland. |
39 |
*/ |
40 |
#define U_REG_G1 0 |
41 |
#define U_REG_O0 7 |
42 |
|
43 |
-static int trace_sysnum_regs(void *vregs) |
44 |
-{ |
45 |
- trace_regs *regs = vregs; |
46 |
- return regs->u_regs[U_REG_G1] ? : SB_SYS_EXECVE; |
47 |
-} |
48 |
- |
49 |
+/* Sparc systems have swapped the addr/data args. */ |
50 |
#undef trace_get_regs |
51 |
#define trace_get_regs(regs) do_ptrace(PTRACE_GETREGS, regs, NULL) |
52 |
+#undef trace_set_regs |
53 |
+#define trace_set_regs(regs) do_ptrace(PTRACE_SETREGS, regs, NULL) |
54 |
+ |
55 |
+#define trace_reg_sysnum u_regs[U_REG_G1] |
56 |
|
57 |
static long trace_raw_ret(void *vregs) |
58 |
{ |
59 |
@@ -22,6 +30,16 @@ static long trace_raw_ret(void *vregs) |
60 |
return regs->u_regs[U_REG_O0]; |
61 |
} |
62 |
|
63 |
+static void trace_set_ret(void *vregs, int err) |
64 |
+{ |
65 |
+ trace_regs *regs = vregs; |
66 |
+ /* The carry bit is used to flag errors. */ |
67 |
+ regs->psr |= PSR_C; |
68 |
+ /* Userland negates the value on sparc. */ |
69 |
+ regs->u_regs[U_REG_O0] = err; |
70 |
+ trace_set_regs(regs); |
71 |
+} |
72 |
+ |
73 |
static unsigned long trace_arg(void *vregs, int num) |
74 |
{ |
75 |
trace_regs *regs = vregs; |