aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/linux-gnu
diff options
context:
space:
mode:
authorJuan Cespedes <cespedes@debian.org>2002-03-03 00:22:06 +0100
committerJuan Cespedes <cespedes@debian.org>2002-03-03 00:22:06 +0100
commitb1dd77d66f93eeaa6cbf8b101d3e9cf70981e000 (patch)
tree497ac28a6435993d3d0f9e8845ba73d175d4baa6 /sysdeps/linux-gnu
parent6ff816fb8f8c76f9f603ca0ce006e8f980950db6 (diff)
downloadltrace-b1dd77d66f93eeaa6cbf8b101d3e9cf70981e000.tar.gz
Version 0.3.20
* Added s390 port (Timothy R. Fesig <slate@us.ibm.com>) * Modified configure process to use ltrace.spec.in to generate ltrace.spec (Timothy R. Fesig <slate@us.ibm.com>) * Fixed some problems using ltrace.spec on Intel platform. (Timothy R. Fesig <slate@us.ibm.com>)
Diffstat (limited to 'sysdeps/linux-gnu')
-rw-r--r--sysdeps/linux-gnu/Makefile2
-rw-r--r--sysdeps/linux-gnu/arm/trace.c13
-rw-r--r--sysdeps/linux-gnu/i386/trace.c12
-rw-r--r--sysdeps/linux-gnu/m68k/trace.c12
-rw-r--r--sysdeps/linux-gnu/s390/Makefile13
-rw-r--r--sysdeps/linux-gnu/s390/arch.h8
-rw-r--r--sysdeps/linux-gnu/s390/breakpoint.c70
-rw-r--r--sysdeps/linux-gnu/s390/regs.c35
-rw-r--r--sysdeps/linux-gnu/s390/signalent.h32
-rw-r--r--sysdeps/linux-gnu/s390/syscallent.h221
-rw-r--r--sysdeps/linux-gnu/s390/trace.c120
11 files changed, 518 insertions, 20 deletions
diff --git a/sysdeps/linux-gnu/Makefile b/sysdeps/linux-gnu/Makefile
index b9baa28..ed8b812 100644
--- a/sysdeps/linux-gnu/Makefile
+++ b/sysdeps/linux-gnu/Makefile
@@ -1,6 +1,6 @@
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
-CFLAGS += -I$(TOPDIR)/sysdeps/Linux/$(ARCH)
+CFLAGS += -I$(TOPDIR)/sysdeps/linux-gnu/$(ARCH)
OBJ = trace.o proc.o
diff --git a/sysdeps/linux-gnu/arm/trace.c b/sysdeps/linux-gnu/arm/trace.c
index 5e48b2e..56a3c93 100644
--- a/sysdeps/linux-gnu/arm/trace.c
+++ b/sysdeps/linux-gnu/arm/trace.c
@@ -28,8 +28,8 @@
/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
*/
-int syscall_p(struct process * proc, int status, int * sysnum)
-{
+int
+syscall_p(struct process * proc, int status, int * sysnum) {
if (WIFSTOPPED(status) && WSTOPSIG(status)==SIGTRAP) {
/* get the user's pc (plus 8) */
int pc = ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0);
@@ -45,9 +45,8 @@ int syscall_p(struct process * proc, int status, int * sysnum)
return 0;
}
-
-void continue_after_breakpoint(struct process *proc, struct breakpoint * sbp)
-{
+void
+continue_after_breakpoint(struct process *proc, struct breakpoint * sbp) {
if (sbp->enabled) disable_breakpoint(proc->pid, sbp);
ptrace(PTRACE_POKEUSER, proc->pid, off_pc, sbp->addr);
if (sbp->enabled == 0) {
@@ -58,8 +57,8 @@ void continue_after_breakpoint(struct process *proc, struct breakpoint * sbp)
}
}
-long gimme_arg(enum tof type, struct process * proc, int arg_num)
-{
+long
+gimme_arg(enum tof type, struct process * proc, int arg_num) {
if (arg_num==-1) { /* return value */
return ptrace(PTRACE_PEEKUSER, proc->pid, off_r0, 0);
}
diff --git a/sysdeps/linux-gnu/i386/trace.c b/sysdeps/linux-gnu/i386/trace.c
index 1e38a27..5a258a3 100644
--- a/sysdeps/linux-gnu/i386/trace.c
+++ b/sysdeps/linux-gnu/i386/trace.c
@@ -20,8 +20,8 @@
/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
*/
-int syscall_p(struct process * proc, int status, int * sysnum)
-{
+int
+syscall_p(struct process * proc, int status, int * sysnum) {
if (WIFSTOPPED(status) && WSTOPSIG(status)==SIGTRAP) {
*sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 4*ORIG_EAX, 0);
@@ -37,8 +37,8 @@ int syscall_p(struct process * proc, int status, int * sysnum)
return 0;
}
-void continue_after_breakpoint(struct process *proc, struct breakpoint * sbp)
-{
+void
+continue_after_breakpoint(struct process *proc, struct breakpoint * sbp) {
if (sbp->enabled) disable_breakpoint(proc->pid, sbp);
ptrace(PTRACE_POKEUSER, proc->pid, 4*EIP, sbp->addr);
if (sbp->enabled == 0) {
@@ -49,8 +49,8 @@ void continue_after_breakpoint(struct process *proc, struct breakpoint * sbp)
}
}
-long gimme_arg(enum tof type, struct process * proc, int arg_num)
-{
+long
+gimme_arg(enum tof type, struct process * proc, int arg_num) {
if (arg_num==-1) { /* return value */
return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EAX, 0);
}
diff --git a/sysdeps/linux-gnu/m68k/trace.c b/sysdeps/linux-gnu/m68k/trace.c
index 43586de..a39a6ee 100644
--- a/sysdeps/linux-gnu/m68k/trace.c
+++ b/sysdeps/linux-gnu/m68k/trace.c
@@ -20,8 +20,8 @@
/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
*/
-int syscall_p(struct process * proc, int status, int * sysnum)
-{
+int
+syscall_p(struct process * proc, int status, int * sysnum) {
int depth;
if (WIFSTOPPED(status) && WSTOPSIG(status)==SIGTRAP) {
@@ -41,8 +41,8 @@ int syscall_p(struct process * proc, int status, int * sysnum)
return 0;
}
-void continue_after_breakpoint(struct process *proc, struct breakpoint * sbp)
-{
+void
+continue_after_breakpoint(struct process *proc, struct breakpoint * sbp) {
if (sbp->enabled) disable_breakpoint(proc->pid, sbp);
ptrace(PTRACE_POKEUSER, proc->pid, 4*PT_PC, sbp->addr);
if (sbp->enabled == 0) {
@@ -53,8 +53,8 @@ void continue_after_breakpoint(struct process *proc, struct breakpoint * sbp)
}
}
-long gimme_arg(enum tof type, struct process * proc, int arg_num)
-{
+long
+gimme_arg(enum tof type, struct process * proc, int arg_num) {
if (arg_num==-1) { /* return value */
return ptrace(PTRACE_PEEKUSER, proc->pid, 4*PT_D0, 0);
}
diff --git a/sysdeps/linux-gnu/s390/Makefile b/sysdeps/linux-gnu/s390/Makefile
new file mode 100644
index 0000000..3a5f5d4
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/Makefile
@@ -0,0 +1,13 @@
+#
+# S/390 version
+# (C) Copyright 2001 IBM Poughkeepsie, IBM Corporation
+#
+OBJ = breakpoint.o trace.o regs.o
+
+all: arch.o
+
+arch.o: $(OBJ)
+ $(LD) -r -o arch.o $(OBJ)
+
+clean:
+ $(RM) $(OBJ) arch.o
diff --git a/sysdeps/linux-gnu/s390/arch.h b/sysdeps/linux-gnu/s390/arch.h
new file mode 100644
index 0000000..d37d92b
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/arch.h
@@ -0,0 +1,8 @@
+/*
+** S/390 version
+** (C) Copyright 2001 IBM Poughkeepsie, IBM Corporation
+*/
+
+#define BREAKPOINT_VALUE 0x00010000
+#define BREAKPOINT_LENGTH 2
+#define DECR_PC_AFTER_BREAK 2
diff --git a/sysdeps/linux-gnu/s390/breakpoint.c b/sysdeps/linux-gnu/s390/breakpoint.c
new file mode 100644
index 0000000..65c5e8f
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/breakpoint.c
@@ -0,0 +1,70 @@
+/*
+** S/390 version
+** (C) Copyright 2001 IBM Poughkeepsie, IBM Corporation
+*/
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/ptrace.h>
+#include "ltrace.h"
+#include "s390/arch.h"
+
+void
+enable_breakpoint(pid_t pid, struct breakpoint * sbp) {
+ long a;
+ long mask1;
+ long mask2;
+ int shift;
+ int i;
+
+ mask1 = 0xFF000000;
+ mask2 = 0x00000000;
+ shift = 24;
+
+ a = ptrace(PTRACE_PEEKTEXT, pid, sbp->addr, 0);
+
+ for( i=0; i < BREAKPOINT_LENGTH; i++ ) {
+ sbp->orig_value[i] = (a & mask1) >> shift;
+ mask2 |= mask1;
+ mask1 = (mask1 >> 8) & 0x00FFFFFF;
+ shift -= 8;
+ }
+ mask2 = ~mask2;
+
+ a &= mask2;
+ a |= BREAKPOINT_VALUE;
+
+ ptrace(PTRACE_POKETEXT, pid, sbp->addr, a);
+}
+
+void
+disable_breakpoint(pid_t pid, const struct breakpoint * sbp) {
+ long a;
+ long b;
+ long mask1;
+ long mask2;
+ int shift;
+ int i;
+
+ b = 0x00000000;
+ mask1 = 0xFF000000;
+ mask2 = 0x00000000;
+ shift = 24;
+
+ a = ptrace(PTRACE_PEEKTEXT, pid, sbp->addr, 0);
+
+ for( i=0; i < BREAKPOINT_LENGTH; i++ ) {
+ b |= sbp->orig_value[i] << shift;
+ mask2 |= mask1;
+ mask1 = (mask1 >> 8) & 0x00FFFFFF;
+ shift -= 8;
+ }
+ mask2 = ~mask2;
+
+ a &= mask2;
+ a |= b;
+
+ ptrace(PTRACE_POKETEXT, pid, sbp->addr, a);
+}
diff --git a/sysdeps/linux-gnu/s390/regs.c b/sysdeps/linux-gnu/s390/regs.c
new file mode 100644
index 0000000..9246fc5
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/regs.c
@@ -0,0 +1,35 @@
+/*
+** S/390 version
+** (C) Copyright 2001 IBM Poughkeepsie, IBM Corporation
+*/
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.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_instruction_pointer(pid_t pid) {
+ return (void *)(ptrace(PTRACE_PEEKUSER, pid, PT_PSWADDR, 0) & 0x7fffffff);
+}
+
+void *
+get_stack_pointer(pid_t pid) {
+ return (void *)ptrace(PTRACE_PEEKUSER, pid, PT_GPR15, 0);
+}
+
+void *
+get_return_addr(pid_t pid, void * stack_pointer) {
+ return (void *)(ptrace(PTRACE_PEEKUSER, pid, PT_GPR14, 0) & 0x7fffffff);
+}
diff --git a/sysdeps/linux-gnu/s390/signalent.h b/sysdeps/linux-gnu/s390/signalent.h
new file mode 100644
index 0000000..5395f82
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/signalent.h
@@ -0,0 +1,32 @@
+ "SIG_0", /* 0 */
+ "SIGHUP", /* 1 */
+ "SIGINT", /* 2 */
+ "SIGQUIT", /* 3 */
+ "SIGILL", /* 4 */
+ "SIGTRAP", /* 5 */
+ "SIGABRT", /* 6 */
+ "SIGBUS", /* 7 */
+ "SIGFPE", /* 8 */
+ "SIGKILL", /* 9 */
+ "SIGUSR1", /* 10 */
+ "SIGSEGV", /* 11 */
+ "SIGUSR2", /* 12 */
+ "SIGPIPE", /* 13 */
+ "SIGALRM", /* 14 */
+ "SIGTERM", /* 15 */
+ "SIGSTKFLT", /* 16 */
+ "SIGCHLD", /* 17 */
+ "SIGCONT", /* 18 */
+ "SIGSTOP", /* 19 */
+ "SIGTSTP", /* 20 */
+ "SIGTTIN", /* 21 */
+ "SIGTTOU", /* 22 */
+ "SIGURG", /* 23 */
+ "SIGXCPU", /* 24 */
+ "SIGXFSZ", /* 25 */
+ "SIGVTALRM", /* 26 */
+ "SIGPROF", /* 27 */
+ "SIGWINCH", /* 28 */
+ "SIGIO", /* 29 */
+ "SIGPWR", /* 30 */
+ "SIGSYS", /* 31 */
diff --git a/sysdeps/linux-gnu/s390/syscallent.h b/sysdeps/linux-gnu/s390/syscallent.h
new file mode 100644
index 0000000..219b719
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/syscallent.h
@@ -0,0 +1,221 @@
+ "0", /* 0 */
+ "exit", /* 1 */
+ "fork", /* 2 */
+ "read", /* 3 */
+ "write", /* 4 */
+ "open", /* 5 */
+ "close", /* 6 */
+ "7", /* 7 */
+ "creat", /* 8 */
+ "link", /* 9 */
+ "unlink", /* 10 */
+ "execve", /* 11 */
+ "chdir", /* 12 */
+ "time", /* 13 */
+ "mknod", /* 14 */
+ "chmod", /* 15 */
+ "lchown", /* 16 */
+ "17", /* 17 */
+ "18", /* 18 */
+ "lseek", /* 19 */
+ "getpid", /* 20 */
+ "mount", /* 21 */
+ "umount", /* 22 */
+ "setuid", /* 23 */
+ "getuid", /* 24 */
+ "stime", /* 25 */
+ "ptrace", /* 26 */
+ "alarm", /* 27 */
+ "28", /* 28 */
+ "pause", /* 29 */
+ "utime", /* 30 */
+ "31", /* 31 */
+ "32", /* 32 */
+ "access", /* 33 */
+ "nice", /* 34 */
+ "35", /* 35 */
+ "sync", /* 36 */
+ "kill", /* 37 */
+ "rename", /* 38 */
+ "mkdir", /* 39 */
+ "rmdir", /* 40 */
+ "dup", /* 41 */
+ "pipe", /* 42 */
+ "times", /* 43 */
+ "44", /* 44 */
+ "brk", /* 45 */
+ "setgid", /* 46 */
+ "getgid", /* 47 */
+ "signal", /* 48 */
+ "geteuid", /* 49 */
+ "getegid", /* 50 */
+ "acct", /* 51 */
+ "umount2", /* 52 */
+ "53", /* 53 */
+ "ioctl", /* 54 */
+ "fcntl", /* 55 */
+ "56", /* 56 */
+ "setpgid", /* 57 */
+ "58", /* 58 */
+ "59", /* 59 */
+ "umask", /* 60 */
+ "chroot", /* 61 */
+ "ustat", /* 62 */
+ "dup2", /* 63 */
+ "getppid", /* 64 */
+ "getpgrp", /* 65 */
+ "setsid", /* 66 */
+ "sigaction", /* 67 */
+ "68", /* 68 */
+ "69", /* 69 */
+ "setreuid", /* 70 */
+ "setregid", /* 71 */
+ "sigsuspend", /* 72 */
+ "sigpending", /* 73 */
+ "sethostname", /* 74 */
+ "setrlimit", /* 75 */
+ "getrlimit", /* 76 */
+ "getrusage", /* 77 */
+ "gettimeofday", /* 78 */
+ "settimeofday", /* 79 */
+ "getgroups", /* 80 */
+ "setgroups", /* 81 */
+ "82", /* 82 */
+ "symlink", /* 83 */
+ "84", /* 84 */
+ "readlink", /* 85 */
+ "uselib", /* 86 */
+ "swapon", /* 87 */
+ "reboot", /* 88 */
+ "readdir", /* 89 */
+ "mmap", /* 90 */
+ "munmap", /* 91 */
+ "truncate", /* 92 */
+ "ftruncate", /* 93 */
+ "fchmod", /* 94 */
+ "fchown", /* 95 */
+ "getpriority", /* 96 */
+ "setpriority", /* 97 */
+ "98", /* 98 */
+ "statfs", /* 99 */
+ "fstatfs", /* 100 */
+ "ioperm", /* 101 */
+ "socketcall", /* 102 */
+ "syslog", /* 103 */
+ "setitimer", /* 104 */
+ "getitimer", /* 105 */
+ "stat", /* 106 */
+ "lstat", /* 107 */
+ "fstat", /* 108 */
+ "109", /* 109 */
+ "110", /* 110 */
+ "vhangup", /* 111 */
+ "idle", /* 112 */
+ "113", /* 113 */
+ "wait4", /* 114 */
+ "swapoff", /* 115 */
+ "sysinfo", /* 116 */
+ "ipc", /* 117 */
+ "fsync", /* 118 */
+ "sigreturn", /* 119 */
+ "clone", /* 120 */
+ "setdomainname", /* 121 */
+ "uname", /* 122 */
+ "123", /* 123 */
+ "adjtimex", /* 124 */
+ "mprotect", /* 125 */
+ "sigprocmask", /* 126 */
+ "create_module", /* 127 */
+ "init_module", /* 128 */
+ "delete_module", /* 129 */
+ "get_kernel_syms", /* 130 */
+ "quotactl", /* 131 */
+ "getpgid", /* 132 */
+ "fchdir", /* 133 */
+ "bdflush", /* 134 */
+ "sysfs", /* 135 */
+ "personality", /* 136 */
+ "afs_syscall", /* 137 */
+ "setfsuid", /* 138 */
+ "setfsgid", /* 139 */
+ "_llseek", /* 140 */
+ "getdents", /* 141 */
+ "_newselect", /* 142 */
+ "flock", /* 143 */
+ "msync", /* 144 */
+ "readv", /* 145 */
+ "writev", /* 146 */
+ "getsid", /* 147 */
+ "fdatasync", /* 148 */
+ "_sysctl", /* 149 */
+ "mlock", /* 150 */
+ "munlock", /* 151 */
+ "mlockall", /* 152 */
+ "munlockall", /* 153 */
+ "sched_setparam", /* 154 */
+ "sched_getparam", /* 155 */
+ "sched_setscheduler", /* 156 */
+ "sched_getscheduler", /* 157 */
+ "sched_yield", /* 158 */
+ "sched_get_priority_max", /* 159 */
+ "sched_get_priority_min", /* 160 */
+ "sched_rr_get_interval", /* 161 */
+ "nanosleep", /* 162 */
+ "mremap", /* 163 */
+ "setresuid", /* 164 */
+ "getresuid", /* 165 */
+ "166", /* 166 */
+ "query_module", /* 167 */
+ "poll", /* 168 */
+ "nfsservctl", /* 169 */
+ "setresgid", /* 170 */
+ "getresgid", /* 171 */
+ "prctl", /* 172 */
+ "rt_sigreturn", /* 173 */
+ "rt_sigaction", /* 174 */
+ "rt_sigprocmask", /* 175 */
+ "rt_sigpending", /* 176 */
+ "rt_sigtimedwait", /* 177 */
+ "rt_sigqueueinfo", /* 178 */
+ "rt_sigsuspend", /* 179 */
+ "pread", /* 180 */
+ "pwrite", /* 181 */
+ "chown", /* 182 */
+ "getcwd", /* 183 */
+ "capget", /* 184 */
+ "capset", /* 185 */
+ "sigaltstack", /* 186 */
+ "sendfile", /* 187 */
+ "getpmsg", /* 188 */
+ "putpmsg", /* 189 */
+ "vfork", /* 190 */
+ "ugetrlimit", /* 191 */
+ "mmap2", /* 192 */
+ "truncate64", /* 193 */
+ "ftruncate64", /* 194 */
+ "stat64", /* 195 */
+ "lstat64", /* 196 */
+ "fstat64", /* 197 */
+ "lchown32", /* 198 */
+ "getuid32", /* 199 */
+ "getgid32", /* 200 */
+ "geteuid32", /* 201 */
+ "getegid32", /* 202 */
+ "setreuid32", /* 203 */
+ "setregid32", /* 204 */
+ "getgroups32", /* 205 */
+ "setgroups32", /* 206 */
+ "fchown32", /* 207 */
+ "setresuid32", /* 208 */
+ "getresuid32", /* 209 */
+ "setresgid32", /* 210 */
+ "getresgid32", /* 211 */
+ "chown32", /* 212 */
+ "setuid32", /* 213 */
+ "setgid32", /* 214 */
+ "setfsuid32", /* 215 */
+ "setfsgid32", /* 216 */
+ "pivot_root", /* 217 */
+ "mincore", /* 218 */
+ "madvise", /* 219 */
+ "getdents64", /* 220 */
diff --git a/sysdeps/linux-gnu/s390/trace.c b/sysdeps/linux-gnu/s390/trace.c
new file mode 100644
index 0000000..9b1e312
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/trace.c
@@ -0,0 +1,120 @@
+/*
+** S390 specific part of trace.c
+**
+** Other routines are in ../trace.c and need to be combined
+** at link time with this code.
+**
+** S/390 version
+** (C) Copyright 2001 IBM Poughkeepsie, IBM Corporation
+*/
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+
+#include "ltrace.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
+
+/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
+ */
+int
+syscall_p(struct process * proc, int status, int * sysnum) {
+ long pswa;
+ long svcinst;
+ long svcno;
+ long svcop;
+
+ if (WIFSTOPPED(status) && WSTOPSIG(status)==SIGTRAP) {
+
+ pswa = ptrace(PTRACE_PEEKUSER, proc->pid, PT_PSWADDR, 0);
+ svcinst = ptrace(PTRACE_PEEKTEXT, proc->pid, (char *)(pswa-4),0);
+ svcop = (svcinst >> 8) & 0xFF;
+ svcno = svcinst & 0xFF;
+
+ *sysnum = svcno;
+
+ if (*sysnum == -1) {
+ return 0;
+ }
+ if (svcop == 0 && svcno == 1) {
+ /* Breakpoint was hit... */
+ return 0;
+ }
+ if (svcop == 10 && *sysnum>=0) {
+ /* System call was encountered... */
+ if (proc->current_syscall!=*sysnum) {
+ return 1;
+ } else {
+ return 2;
+ }
+ }
+ else {
+ /* Unknown trap was encountered... */
+ return 0;
+ }
+ }
+ /* Unknown status... */
+ return 0;
+}
+
+void
+continue_after_breakpoint(struct process *proc, struct breakpoint * sbp) {
+ if (sbp->enabled) disable_breakpoint(proc->pid, sbp);
+ ptrace(PTRACE_POKEUSER, proc->pid, PT_PSWADDR, sbp->addr);
+ if (sbp->enabled == 0) {
+ continue_process(proc->pid);
+ } else {
+ proc->breakpoint_being_enabled = sbp;
+ ptrace(PTRACE_SINGLESTEP, proc->pid, 0, 0);
+ }
+}
+
+long
+gimme_arg(enum tof type, struct process * proc, int arg_num) {
+ if (arg_num==-1) { /* return value */
+ return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR2, 0);
+ }
+
+ if (type==LT_TOF_FUNCTION) {
+ switch(arg_num) {
+ case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_ORIGGPR2, 0);
+ case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR3, 0);
+ case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR4, 0);
+ case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR5, 0);
+ case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR6, 0);
+ default:
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(2);
+ }
+
+ } else if (type==LT_TOF_SYSCALL) {
+ switch(arg_num) {
+ case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_ORIGGPR2, 0);
+ case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR3, 0);
+ case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR4, 0);
+ case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR5, 0);
+ case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR6, 0);
+ default:
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(2);
+ }
+ } else {
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(1);
+ }
+
+ return 0;
+}