aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2009-10-25 07:06:30 +0000
committerMike Frysinger <vapier@gentoo.org>2009-10-25 07:06:30 +0000
commit9b53f023e6bc3675458cb891332fc6b0c39d8504 (patch)
treeb2b47925a9f0763cdca42c6d5d68b6187e1c6d00 /libsandbox
parentbump to sandbox-2.2 (diff)
downloadsandbox-9b53f023e6bc3675458cb891332fc6b0c39d8504.tar.gz
sandbox-9b53f023e6bc3675458cb891332fc6b0c39d8504.tar.bz2
sandbox-9b53f023e6bc3675458cb891332fc6b0c39d8504.zip
libsandbox: add support for tracing SPARC systems
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'libsandbox')
-rw-r--r--libsandbox/trace.c38
-rw-r--r--libsandbox/trace/common.c1
-rw-r--r--libsandbox/trace/linux/arch.c2
-rw-r--r--libsandbox/trace/linux/sparc.c29
4 files changed, 55 insertions, 15 deletions
diff --git a/libsandbox/trace.c b/libsandbox/trace.c
index 9400b9c..d669fc9 100644
--- a/libsandbox/trace.c
+++ b/libsandbox/trace.c
@@ -9,15 +9,8 @@
#include "wrappers.h"
#include "sb_nr.h"
-#include "trace/os.c"
-
-pid_t trace_pid;
-
-#ifndef SB_NO_TRACE
-
-#ifdef HAVE_OPEN64
-# define sb_openat_pre_check sb_openat64_pre_check
-#endif
+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)
#ifdef DEBUG
# define SBDEBUG 1
@@ -28,6 +21,16 @@ pid_t trace_pid;
#define _SB_DEBUG(fmt, args...) do { if (SBDEBUG) SB_EWARN("TRACE ", "(pid=%i):%s: " fmt, getpid(), __func__, ## args); } while (0)
#define SB_DEBUG(fmt, args...) _SB_DEBUG(fmt "\n", ## args)
+#include "trace/os.c"
+
+pid_t trace_pid;
+
+#ifndef SB_NO_TRACE
+
+#ifdef HAVE_OPEN64
+# define sb_openat_pre_check sb_openat64_pre_check
+#endif
+
static void trace_exit(int status)
{
/* if we were vfork-ed, clear trace_pid and exit */
@@ -63,7 +66,6 @@ static long _do_ptrace(enum __ptrace_request request, const char *srequest, void
}
return ret;
}
-#define do_ptrace(request, addr, data) _do_ptrace(request, #request, addr, data)
static long do_peekuser(long offset)
{
@@ -373,11 +375,17 @@ static bool trace_check_syscall(const struct syscall_entry *se, void *regs)
return ret;
}
-/* Some arches (like hppa) don't implement PTRACE_GETREGS ...
- * what a bunch of asshats.
+/* Some arches (like hppa) don't implement PTRACE_GETREGS, while others (like
+ * sparc) swap the meaning of "addr" and "data. What a bunch of asshats.
*/
#ifndef trace_get_regs
-# define trace_get_regs(regs) do_ptrace(PTRACE_GETREGS, NULL, regs);
+# define trace_get_regs(regs) do_ptrace(PTRACE_GETREGS, NULL, regs)
+#endif
+/* Some arches (like sparc) don't implement PTRACE_PEEK* ...
+ * more asshats !
+ */
+#ifndef trace_sysnum_regs
+# define trace_sysnum_regs(regs) trace_sysnum()
#endif
static void trace_loop(void)
@@ -394,7 +402,7 @@ static void trace_loop(void)
do {
ret = do_ptrace(PTRACE_SYSCALL, NULL, NULL);
waitpid(trace_pid, NULL, 0);
- nr = trace_sysnum();
+ nr = trace_sysnum_regs(&regs);
if (!exec_state) {
if (!tbl_at_fork)
@@ -404,7 +412,7 @@ static void trace_loop(void)
if (before_syscall)
_SB_DEBUG(">%s:%i", se ? se->name : "IDK", nr);
else
- __SB_DEBUG("(...) = ...\n");
+ __SB_DEBUG("(...pre-exec...) = ...\n");
goto loop_again;
}
++exec_state;
diff --git a/libsandbox/trace/common.c b/libsandbox/trace/common.c
index 390e343..7604440 100644
--- a/libsandbox/trace/common.c
+++ b/libsandbox/trace/common.c
@@ -4,6 +4,7 @@ struct syscall_entry {
};
static int trace_sysnum(void);
+static int trace_sysnum_regs(void *vregs);
static long trace_raw_ret(void *vregs);
static unsigned long trace_arg(void *vregs, int num);
diff --git a/libsandbox/trace/linux/arch.c b/libsandbox/trace/linux/arch.c
index f9d7762..de86109 100644
--- a/libsandbox/trace/linux/arch.c
+++ b/libsandbox/trace/linux/arch.c
@@ -9,6 +9,8 @@
# include "hppa.c"
#elif defined(__i386__)
# include "i386.c"
+#elif defined(__sparc__)
+# include "sparc.c"
#elif defined(__x86_64__)
# include "x86_64.c"
#else
diff --git a/libsandbox/trace/linux/sparc.c b/libsandbox/trace/linux/sparc.c
new file mode 100644
index 0000000..72cafc7
--- /dev/null
+++ b/libsandbox/trace/linux/sparc.c
@@ -0,0 +1,29 @@
+/* Indexes into the pt_regs.u_reg[] array -- UREG_XX from kernel are all off
+ * by 1 and use Ix instead of Ox. These work for both 32 and 64 bit Linux.
+ */
+#define U_REG_G1 0
+#define U_REG_O0 7
+
+static int trace_sysnum_regs(void *vregs)
+{
+ trace_regs *regs = vregs;
+ do_ptrace(PTRACE_GETREGS, regs, NULL);
+ return regs->u_regs[U_REG_G1] ? : SB_SYS_EXECVE;
+}
+#define trace_sysnum_regs(regs) trace_sysnum_regs(regs)
+#define trace_get_regs(regs) (0)
+
+static long trace_raw_ret(void *vregs)
+{
+ trace_regs *regs = vregs;
+ return regs->u_regs[U_REG_O0];
+}
+
+static unsigned long trace_arg(void *vregs, int num)
+{
+ trace_regs *regs = vregs;
+ if (num < 7)
+ return regs->u_regs[U_REG_O0 + num - 1];
+ else
+ return -1;
+}