summaryrefslogtreecommitdiff
path: root/sysdeps/linux-gnu/alpha/trace.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/linux-gnu/alpha/trace.c')
-rw-r--r--sysdeps/linux-gnu/alpha/trace.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/sysdeps/linux-gnu/alpha/trace.c b/sysdeps/linux-gnu/alpha/trace.c
new file mode 100644
index 0000000..e4d4063
--- /dev/null
+++ b/sysdeps/linux-gnu/alpha/trace.c
@@ -0,0 +1,75 @@
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+
+#include "common.h"
+#include "debug.h"
+
+#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
+# define PTRACE_PEEKUSER PTRACE_PEEKUSR
+#endif
+
+#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR))
+# define PTRACE_POKEUSER PTRACE_POKEUSR
+#endif
+
+void
+get_arch_dep(Process *proc) {
+}
+
+/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
+ */
+int
+syscall_p(Process *proc, int status, int *sysnum) {
+ if (WIFSTOPPED(status)
+ && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
+ char *ip = get_instruction_pointer(proc) - 4;
+ long x = ptrace(PTRACE_PEEKTEXT, proc->pid, ip, 0);
+ debug(2, "instr: %016lx", x);
+ if ((x & 0xffffffff) != 0x00000083)
+ return 0;
+ *sysnum =
+ ptrace(PTRACE_PEEKUSER, proc->pid, 0 /* REG_R0 */ , 0);
+ if (proc->callstack_depth > 0 &&
+ proc->callstack[proc->callstack_depth - 1].is_syscall &&
+ proc->callstack[proc->callstack_depth - 1].c_un.syscall == *sysnum) {
+ return 2;
+ }
+ if (*sysnum >= 0 && *sysnum < 500) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+long
+gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) {
+ if (arg_num == -1) { /* return value */
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 0 /* REG_R0 */ , 0);
+ }
+
+ if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
+ if (arg_num <= 5)
+ return ptrace(PTRACE_PEEKUSER, proc->pid,
+ arg_num + 16 /* REG_A0 */ , 0);
+ else
+ return ptrace(PTRACE_PEEKTEXT, proc->pid,
+ proc->stack_pointer + 8 * (arg_num - 6),
+ 0);
+ } else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) {
+ return ptrace(PTRACE_PEEKUSER, proc->pid,
+ arg_num + 16 /* REG_A0 */ , 0);
+ } else {
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(1);
+ }
+ return 0;
+}
+
+void
+save_register_args(enum tof type, Process *proc) {
+}