commit:     e99597cc31b454f97d2629f17d3d6f5145f978d7
Author:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
AuthorDate: Sun Dec 20 21:35:21 2015 +0000
Commit:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
CommitDate: Sun Dec 20 21:35:21 2015 +0000
URL:        https://gitweb.gentoo.org/proj/sandbox.git/commit/?id=e99597cc

libsandbox: new ia64 ptrace port

Signed-off-by: Mike Frysinger <vapier <AT> gentoo.org>

 libsandbox/trace.c            |  1 +
 libsandbox/trace/linux/arch.c |  2 ++
 libsandbox/trace/linux/ia64.c | 81 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 84 insertions(+)

diff --git a/libsandbox/trace.c b/libsandbox/trace.c
index 5ccda2a..fb1fc32 100644
--- a/libsandbox/trace.c
+++ b/libsandbox/trace.c
@@ -9,6 +9,7 @@
 #include "wrappers.h"
 #include "sb_nr.h"
 
+static long do_peekdata(long offset);
 static long _do_ptrace(enum __ptrace_request request, const char *srequest, 
void *addr, void *data);
 #define do_ptrace(request, addr, data) _do_ptrace(request, #request, addr, 
data)
 #define _trace_possible(data) true

diff --git a/libsandbox/trace/linux/arch.c b/libsandbox/trace/linux/arch.c
index fbf5b79..4b3d615 100644
--- a/libsandbox/trace/linux/arch.c
+++ b/libsandbox/trace/linux/arch.c
@@ -17,6 +17,8 @@
 # include "hppa.c"
 #elif defined(__i386__)
 # include "i386.c"
+#elif defined(__ia64__)
+# include "ia64.c"
 #elif defined(__powerpc__)
 # include "powerpc.c"
 #elif defined(__s390__)

diff --git a/libsandbox/trace/linux/ia64.c b/libsandbox/trace/linux/ia64.c
new file mode 100644
index 0000000..5029994
--- /dev/null
+++ b/libsandbox/trace/linux/ia64.c
@@ -0,0 +1,81 @@
+#include <asm/ptrace_offsets.h>
+#include <asm/rse.h>
+
+/* We only care about two ptrace regs, so extract them ourselves rather than
+ * get the "full" set via GETREGS.  We still need to extract the out regs by
+ * hand either way.
+ */
+#undef trace_regs
+struct sb_ia64_trace_regs {
+       unsigned long r8, r10, r15;
+       unsigned long out[6];
+};
+#define trace_regs struct sb_ia64_trace_regs
+
+#define trace_reg_sysnum r15
+
+static unsigned long trace_arg(void *vregs, int num)
+{
+       trace_regs *regs = vregs;
+       if (num < 7)
+               return regs->out[num - 1];
+       else
+               return -1;
+}
+
+static long do_peekuser(long offset)
+{
+       return do_ptrace(PTRACE_PEEKUSER, (void *)offset, NULL);
+}
+
+static long do_pokeuser(long offset, long val)
+{
+       return do_ptrace(PTRACE_POKEUSER, (void *)offset, (void *)val);
+}
+
+#undef trace_get_regs
+static long trace_get_regs(void *vregs)
+{
+       trace_regs *regs = vregs;
+       size_t i;
+       unsigned long *out0, cfm, sof, sol;
+       long rbs_end;
+
+       regs->r15 = do_peekuser(PT_R15);
+
+       /* Here there be gremlins! */
+       rbs_end = do_peekuser(PT_AR_BSP);
+       cfm = do_peekuser(PT_CFM);
+       sof = (cfm >> 0) & 0x7f;
+       sol = (cfm >> 7) & 0x7f;
+       out0 = ia64_rse_skip_regs((unsigned long *)rbs_end, -sof + sol);
+       for (i = 0; i < 7; ++i)
+               regs->out[i] = do_peekdata((uintptr_t)ia64_rse_skip_regs(out0, 
i));
+
+       return 0;
+}
+
+#undef trace_set_regs
+static long trace_set_regs(void *vregs)
+{
+       trace_regs *regs = vregs;
+       /* We only support rewriting of syscall/err # currently (not args). */
+       do_pokeuser(PT_R8, regs->r8);
+       do_pokeuser(PT_R10, regs->r10);
+       do_pokeuser(PT_R15, regs->r15);
+       return 0;
+}
+
+static long trace_raw_ret(void *vregs)
+{
+       trace_regs *regs = vregs;
+       return regs->r8;
+}
+
+static void trace_set_ret(void *vregs, int err)
+{
+       trace_regs *regs = vregs;
+       regs->r8 = err;
+       regs->r10 = -1;
+       trace_set_regs(regs);
+}

Reply via email to