summaryrefslogtreecommitdiff
path: root/sysdeps/linux-gnu
diff options
context:
space:
mode:
authorAnas Nashif <anas.nashif@intel.com>2012-11-13 07:28:12 -0800
committerAnas Nashif <anas.nashif@intel.com>2012-11-13 07:28:12 -0800
commit59749d048d9e452f049f9151735b5256756919c3 (patch)
tree9b0935c93a3b028fd1dd35a2c632510743e7826f /sysdeps/linux-gnu
downloadltrace-59749d048d9e452f049f9151735b5256756919c3.tar.gz
ltrace-59749d048d9e452f049f9151735b5256756919c3.tar.bz2
ltrace-59749d048d9e452f049f9151735b5256756919c3.zip
Imported Upstream version 0.5.3upstream/0.5.3
Diffstat (limited to 'sysdeps/linux-gnu')
-rw-r--r--sysdeps/linux-gnu/Makefile60
-rw-r--r--sysdeps/linux-gnu/README13
-rw-r--r--sysdeps/linux-gnu/alpha/Makefile10
-rw-r--r--sysdeps/linux-gnu/alpha/arch.h8
-rw-r--r--sysdeps/linux-gnu/alpha/plt.c12
-rw-r--r--sysdeps/linux-gnu/alpha/ptrace.h1
-rw-r--r--sysdeps/linux-gnu/alpha/regs.c40
-rw-r--r--sysdeps/linux-gnu/alpha/signalent.h32
-rw-r--r--sysdeps/linux-gnu/alpha/syscallent.h439
-rw-r--r--sysdeps/linux-gnu/alpha/trace.c75
-rw-r--r--sysdeps/linux-gnu/arch_mksyscallent42
-rw-r--r--sysdeps/linux-gnu/arm/Makefile10
-rw-r--r--sysdeps/linux-gnu/arm/arch.h11
-rw-r--r--sysdeps/linux-gnu/arm/arch_syscallent.h6
-rw-r--r--sysdeps/linux-gnu/arm/breakpoint.c77
-rw-r--r--sysdeps/linux-gnu/arm/plt.c12
-rw-r--r--sysdeps/linux-gnu/arm/ptrace.h9
-rw-r--r--sysdeps/linux-gnu/arm/regs.c51
-rw-r--r--sysdeps/linux-gnu/arm/signalent.h33
-rw-r--r--sysdeps/linux-gnu/arm/syscallent.h322
-rw-r--r--sysdeps/linux-gnu/arm/trace.c131
-rw-r--r--sysdeps/linux-gnu/breakpoint.c86
-rw-r--r--sysdeps/linux-gnu/events.c161
-rw-r--r--sysdeps/linux-gnu/i386/Makefile10
-rw-r--r--sysdeps/linux-gnu/i386/arch.h6
-rw-r--r--sysdeps/linux-gnu/i386/plt.c12
-rw-r--r--sysdeps/linux-gnu/i386/ptrace.h1
-rw-r--r--sysdeps/linux-gnu/i386/regs.c40
-rw-r--r--sysdeps/linux-gnu/i386/signalent.h32
-rw-r--r--sysdeps/linux-gnu/i386/syscallent.h317
-rw-r--r--sysdeps/linux-gnu/i386/trace.c85
-rw-r--r--sysdeps/linux-gnu/ia64/Makefile10
-rw-r--r--sysdeps/linux-gnu/ia64/arch.h13
-rw-r--r--sysdeps/linux-gnu/ia64/breakpoint.c212
-rw-r--r--sysdeps/linux-gnu/ia64/plt.c46
-rw-r--r--sysdeps/linux-gnu/ia64/ptrace.h1
-rw-r--r--sysdeps/linux-gnu/ia64/regs.c51
-rw-r--r--sysdeps/linux-gnu/ia64/signalent.h32
-rw-r--r--sysdeps/linux-gnu/ia64/syscallent.h1303
-rw-r--r--sysdeps/linux-gnu/ia64/trace.c268
-rw-r--r--sysdeps/linux-gnu/m68k/Makefile10
-rw-r--r--sysdeps/linux-gnu/m68k/arch.h6
-rw-r--r--sysdeps/linux-gnu/m68k/plt.c13
-rw-r--r--sysdeps/linux-gnu/m68k/ptrace.h1
-rw-r--r--sysdeps/linux-gnu/m68k/regs.c40
-rw-r--r--sysdeps/linux-gnu/m68k/signalent.h32
-rw-r--r--sysdeps/linux-gnu/m68k/syscallent.h282
-rw-r--r--sysdeps/linux-gnu/m68k/trace.c89
-rw-r--r--sysdeps/linux-gnu/mipsel/Doxyfile275
-rw-r--r--sysdeps/linux-gnu/mipsel/Makefile22
-rw-r--r--sysdeps/linux-gnu/mipsel/arch.h9
-rw-r--r--sysdeps/linux-gnu/mipsel/mipsel.h11
-rw-r--r--sysdeps/linux-gnu/mipsel/plt.c72
-rw-r--r--sysdeps/linux-gnu/mipsel/ptrace.h1
-rw-r--r--sysdeps/linux-gnu/mipsel/regs.c76
-rw-r--r--sysdeps/linux-gnu/mipsel/signalent.h32
-rw-r--r--sysdeps/linux-gnu/mipsel/syscallent.h241
-rw-r--r--sysdeps/linux-gnu/mipsel/trace.c167
-rwxr-xr-xsysdeps/linux-gnu/mksignalent33
-rwxr-xr-xsysdeps/linux-gnu/mksyscallent45
-rw-r--r--sysdeps/linux-gnu/mksyscallent_s39038
-rw-r--r--sysdeps/linux-gnu/ppc/Makefile10
-rw-r--r--sysdeps/linux-gnu/ppc/arch.h24
-rw-r--r--sysdeps/linux-gnu/ppc/plt.c54
-rw-r--r--sysdeps/linux-gnu/ppc/ptrace.h1
-rw-r--r--sysdeps/linux-gnu/ppc/regs.c47
-rw-r--r--sysdeps/linux-gnu/ppc/signalent.h32
-rw-r--r--sysdeps/linux-gnu/ppc/syscallent.h272
-rw-r--r--sysdeps/linux-gnu/ppc/trace.c155
-rw-r--r--sysdeps/linux-gnu/proc.c36
-rw-r--r--sysdeps/linux-gnu/s390/Makefile13
-rw-r--r--sysdeps/linux-gnu/s390/arch.h18
-rw-r--r--sysdeps/linux-gnu/s390/plt.c12
-rw-r--r--sysdeps/linux-gnu/s390/ptrace.h1
-rw-r--r--sysdeps/linux-gnu/s390/regs.c75
-rw-r--r--sysdeps/linux-gnu/s390/signalent.h33
-rw-r--r--sysdeps/linux-gnu/s390/signalent1.h1
-rw-r--r--sysdeps/linux-gnu/s390/syscallent.h5
-rw-r--r--sysdeps/linux-gnu/s390/syscallent1.h1
-rw-r--r--sysdeps/linux-gnu/s390/syscalls31.h310
-rw-r--r--sysdeps/linux-gnu/s390/syscalls64.h310
-rw-r--r--sysdeps/linux-gnu/s390/trace.c198
-rw-r--r--sysdeps/linux-gnu/sparc/Makefile9
-rw-r--r--sysdeps/linux-gnu/sparc/arch.h8
-rw-r--r--sysdeps/linux-gnu/sparc/plt.c12
-rw-r--r--sysdeps/linux-gnu/sparc/ptrace.h21
-rw-r--r--sysdeps/linux-gnu/sparc/regs.c49
-rw-r--r--sysdeps/linux-gnu/sparc/signalent.h32
-rw-r--r--sysdeps/linux-gnu/sparc/syscallent.h284
-rw-r--r--sysdeps/linux-gnu/sparc/trace.c81
-rw-r--r--sysdeps/linux-gnu/trace.c193
-rw-r--r--sysdeps/linux-gnu/x86_64/Makefile9
-rw-r--r--sysdeps/linux-gnu/x86_64/arch.h12
-rw-r--r--sysdeps/linux-gnu/x86_64/ffcheck.c0
-rw-r--r--sysdeps/linux-gnu/x86_64/plt.c12
-rw-r--r--sysdeps/linux-gnu/x86_64/ptrace.h1
-rw-r--r--sysdeps/linux-gnu/x86_64/regs.c54
-rw-r--r--sysdeps/linux-gnu/x86_64/signalent.h32
-rw-r--r--sysdeps/linux-gnu/x86_64/signalent1.h1
-rw-r--r--sysdeps/linux-gnu/x86_64/syscallent.h256
-rw-r--r--sysdeps/linux-gnu/x86_64/syscallent1.h1
-rw-r--r--sysdeps/linux-gnu/x86_64/trace.c144
102 files changed, 8394 insertions, 0 deletions
diff --git a/sysdeps/linux-gnu/Makefile b/sysdeps/linux-gnu/Makefile
new file mode 100644
index 0000000..eb1ec60
--- /dev/null
+++ b/sysdeps/linux-gnu/Makefile
@@ -0,0 +1,60 @@
+ARCH := $(shell uname -m | sed \
+ -e s/i.86/i386/ \
+ -e s/sun4u/sparc64/ \
+ -e s/sparc64/sparc/ \
+ -e s/arm.*/arm/ \
+ -e s/sa110/arm/ \
+ -e s/ppc64/ppc/ \
+ -e s/s390x/s390/ \
+ )
+
+CPPFLAGS += -I$(TOPDIR)/sysdeps/linux-gnu/$(ARCH)
+
+OBJ = events.o trace.o proc.o breakpoint.o
+
+all: sysdep.h signalent.h syscallent.h arch_syscallent.h signalent1.h syscallent1.h ../sysdep.o
+
+sysdep.h: $(ARCH)/arch.h
+ cat $(ARCH)/arch.h > sysdep.h
+
+signalent.h:
+ cp $(ARCH)/signalent.h signalent.h
+signalent1.h:
+ if [ -f $(ARCH)/signalent1.h ]; then \
+ cp $(ARCH)/signalent1.h signalent1.h; \
+ else \
+ > signalent1.h; \
+ fi
+
+syscallent.h:
+ cp $(ARCH)/syscallent.h syscallent.h
+
+syscallent1.h:
+ if [ -f $(ARCH)/syscallent1.h ]; then \
+ cp $(ARCH)/syscallent1.h syscallent1.h; \
+ else \
+ > syscallent1.h; \
+ fi
+
+arch_syscallent.h:
+ if [ -f $(ARCH)/arch_syscallent.h ]; then \
+ cp $(ARCH)/arch_syscallent.h arch_syscallent.h; \
+ else \
+ > arch_syscallent.h; \
+ fi
+
+../sysdep.o: os.o $(ARCH)/arch.o
+ $(CC) -nostdlib -r -o ../sysdep.o os.o $(ARCH)/arch.o
+
+os.o: $(OBJ)
+ $(CC) -nostdlib -r -o os.o $(OBJ)
+
+$(ARCH)/arch.o: dummy
+ $(MAKE) -C $(ARCH)
+
+clean:
+ $(MAKE) -C $(ARCH) clean
+ rm -f $(OBJ) sysdep.h signalent.h signalent1.h syscallent.h arch_syscallent.h
+ rm -f syscallent1.h os.o sysdep.o ../sysdep.o
+
+dummy:
diff --git a/sysdeps/linux-gnu/README b/sysdeps/linux-gnu/README
new file mode 100644
index 0000000..a8bc8ee
--- /dev/null
+++ b/sysdeps/linux-gnu/README
@@ -0,0 +1,13 @@
+* "arch/syscallent.h" is made from <asm/unistd.h>.
+ It can be done automatically with "mksyscallent" for all the
+ architectures except "mips" (as of linux-2.2.12)
+
+* "arch/signalent.h" is made from <asm/signal.h>.
+ It can be done automatically with "mksignalent" for all the
+ architectures. (linux-2.2.12)
+
+* s390 uses mksyscallent_s390, rather than mksyscallent
+
+* NOTE: This does not currently work for cross-compilers; Maybe
+ I should guess the architecture using `gcc -print-libgcc-file-name'
+ instead of `uname -m' (or even better, use the value returned by autoconf)
diff --git a/sysdeps/linux-gnu/alpha/Makefile b/sysdeps/linux-gnu/alpha/Makefile
new file mode 100644
index 0000000..60d7531
--- /dev/null
+++ b/sysdeps/linux-gnu/alpha/Makefile
@@ -0,0 +1,10 @@
+OBJ = trace.o regs.o plt.o
+
+all: arch.o
+
+arch.o: $(OBJ)
+ $(CC) -nostdlib -r -o arch.o $(OBJ)
+
+clean:
+ $(RM) $(OBJ) arch.o
+
diff --git a/sysdeps/linux-gnu/alpha/arch.h b/sysdeps/linux-gnu/alpha/arch.h
new file mode 100644
index 0000000..1107b5f
--- /dev/null
+++ b/sysdeps/linux-gnu/alpha/arch.h
@@ -0,0 +1,8 @@
+#define BREAKPOINT_VALUE { 0x80, 0x00, 0x00, 0x00 }
+#define BREAKPOINT_LENGTH 4
+#define DECR_PC_AFTER_BREAK 4
+
+#define LT_ELFCLASS ELFCLASS64
+#define LT_ELF_MACHINE EM_ALPHA
+#define LT_ELFCLASS2 ELFCLASS64
+#define LT_ELF_MACHINE2 EM_FAKE_ALPHA
diff --git a/sysdeps/linux-gnu/alpha/plt.c b/sysdeps/linux-gnu/alpha/plt.c
new file mode 100644
index 0000000..83337b2
--- /dev/null
+++ b/sysdeps/linux-gnu/alpha/plt.c
@@ -0,0 +1,12 @@
+#include <gelf.h>
+#include "common.h"
+
+GElf_Addr
+arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) {
+ return lte->plt_addr + ndx * 12 + 32;
+}
+
+void *
+sym2addr(Process *proc, struct library_symbol *sym) {
+ return sym->enter_addr;
+}
diff --git a/sysdeps/linux-gnu/alpha/ptrace.h b/sysdeps/linux-gnu/alpha/ptrace.h
new file mode 100644
index 0000000..c3cbcb6
--- /dev/null
+++ b/sysdeps/linux-gnu/alpha/ptrace.h
@@ -0,0 +1 @@
+#include <sys/ptrace.h>
diff --git a/sysdeps/linux-gnu/alpha/regs.c b/sysdeps/linux-gnu/alpha/regs.c
new file mode 100644
index 0000000..9554e48
--- /dev/null
+++ b/sysdeps/linux-gnu/alpha/regs.c
@@ -0,0 +1,40 @@
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+
+#include "common.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(Process *proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 64 /* REG_PC */ , 0);
+}
+
+void
+set_instruction_pointer(Process *proc, void *addr) {
+ ptrace(PTRACE_POKEUSER, proc->pid, 64 /* REG_PC */ , addr);
+}
+
+void *
+get_stack_pointer(Process *proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 30 /* REG_FP */ , 0);
+}
+
+void *
+get_return_addr(Process *proc, void *stack_pointer) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 26 /* RA */ , 0);
+}
+
+void
+set_return_addr(Process *proc, void *addr) {
+ ptrace(PTRACE_POKEUSER, proc->pid, 26 /* RA */ , addr);
+}
diff --git a/sysdeps/linux-gnu/alpha/signalent.h b/sysdeps/linux-gnu/alpha/signalent.h
new file mode 100644
index 0000000..c2a6170
--- /dev/null
+++ b/sysdeps/linux-gnu/alpha/signalent.h
@@ -0,0 +1,32 @@
+"SIG_0", /* 0 */
+ "SIGHUP", /* 1 */
+ "SIGINT", /* 2 */
+ "SIGQUIT", /* 3 */
+ "SIGILL", /* 4 */
+ "SIGTRAP", /* 5 */
+ "SIGABRT", /* 6 */
+ "SIGEMT", /* 7 */
+ "SIGFPE", /* 8 */
+ "SIGKILL", /* 9 */
+ "SIGBUS", /* 10 */
+ "SIGSEGV", /* 11 */
+ "SIGSYS", /* 12 */
+ "SIGPIPE", /* 13 */
+ "SIGALRM", /* 14 */
+ "SIGTERM", /* 15 */
+ "SIGURG", /* 16 */
+ "SIGSTOP", /* 17 */
+ "SIGTSTP", /* 18 */
+ "SIGCONT", /* 19 */
+ "SIGCHLD", /* 20 */
+ "SIGTTIN", /* 21 */
+ "SIGTTOU", /* 22 */
+ "SIGIO", /* 23 */
+ "SIGXCPU", /* 24 */
+ "SIGXFSZ", /* 25 */
+ "SIGVTALRM", /* 26 */
+ "SIGPROF", /* 27 */
+ "SIGWINCH", /* 28 */
+ "SIGINFO", /* 29 */
+ "SIGUSR1", /* 30 */
+ "SIGUSR2", /* 31 */
diff --git a/sysdeps/linux-gnu/alpha/syscallent.h b/sysdeps/linux-gnu/alpha/syscallent.h
new file mode 100644
index 0000000..7cacc8c
--- /dev/null
+++ b/sysdeps/linux-gnu/alpha/syscallent.h
@@ -0,0 +1,439 @@
+"osf_syscall", /* 0, not implemented */
+ "exit", /* 1 */
+ "fork", /* 2 */
+ "read", /* 3 */
+ "write", /* 4 */
+ "osf_old_open", /* 5, not implemented */
+ "close", /* 6 */
+ "osf_wait4", /* 7 */
+ "osf_old_creat", /* 8, not implemented */
+ "link", /* 9 */
+ "unlink", /* 10 */
+ "osf_execve", /* 11, not implemented */
+ "chdir", /* 12 */
+ "fchdir", /* 13 */
+ "mknod", /* 14 */
+ "chmod", /* 15 */
+ "chown", /* 16 */
+ "brk", /* 17 */
+ "osf_getfsstat", /* 18, not implemented */
+ "lseek", /* 19 */
+ "getxpid", /* 20 */
+ "osf_mount", /* 21 */
+ "umount", /* 22 */
+ "setuid", /* 23 */
+ "getxuid", /* 24 */
+ "exec_with_loader", /* 25, not implemented */
+ "ptrace", /* 26 */
+ "osf_nrecmsg", /* 27, not implemented */
+ "osf_nsendmsg", /* 28, not implemented */
+ "osf_nrecvfrom", /* 29, not implemented */
+ "osf_naccept", /* 30, not implemented */
+ "osf_ngetpeername", /* 31, not implemented */
+ "osf_ngetsocketname", /* 32, not implemented */
+ "access", /* 33 */
+ "osf_chflags", /* 34, not implemented */
+ "osf_fchflags", /* 35, not implemented */
+ "sync", /* 36 */
+ "kill", /* 37 */
+ "osf_old_stat", /* 38, not implemented */
+ "setpgid", /* 39 */
+ "osf_old_lstat", /* 40, not implemented */
+ "dup", /* 41 */
+ "pipe", /* 42 */
+ "osf_set_program_attributes", /* 43 */
+ "osf_profil", /* 44, not implemented */
+ "open", /* 45 */
+ "osf_old_sigaction", /* 46, not implemented */
+ "getxgid", /* 47 */
+ "osf_sigprocmask", /* 48 */
+ "osf_getlogin", /* 49, not implemented */
+ "osf_setlogin", /* 50, not implemented */
+ "acct", /* 51 */
+ "sigpending", /* 52 */
+ "SYS_53", /* 53 */
+ "ioctl", /* 54 */
+ "osf_reboot", /* 55, not implemented */
+ "osf_revoke", /* 56, not implemented */
+ "symlink", /* 57 */
+ "readlink", /* 58 */
+ "execve", /* 59 */
+ "umask", /* 60 */
+ "chroot", /* 61 */
+ "osf_old_fstat", /* 62, not implemented */
+ "getpgrp", /* 63 */
+ "getpagesize", /* 64 */
+ "osf_mremap", /* 65, not implemented */
+ "vfork", /* 66 */
+ "stat", /* 67 */
+ "lstat", /* 68 */
+ "osf_sbrk", /* 69, not implemented */
+ "osf_sstk", /* 70, not implemented */
+ "mmap", /* 71 */
+ "osf_old_vadvise", /* 72, not implemented */
+ "munmap", /* 73 */
+ "mprotect", /* 74 */
+ "madvise", /* 75 */
+ "vhangup", /* 76 */
+ "osf_kmodcall", /* 77, not implemented */
+ "osf_mincore", /* 78, not implemented */
+ "getgroups", /* 79 */
+ "setgroups", /* 80 */
+ "osf_old_getpgrp", /* 81, not implemented */
+ "setpgrp", /* 82 */
+ "osf_setitimer", /* 83 */
+ "osf_old_wait", /* 84, not implemented */
+ "osf_table", /* 85, not implemented */
+ "osf_getitimer", /* 86 */
+ "gethostname", /* 87 */
+ "sethostname", /* 88 */
+ "getdtablesize", /* 89 */
+ "dup2", /* 90 */
+ "fstat", /* 91 */
+ "fcntl", /* 92 */
+ "osf_select", /* 93 */
+ "poll", /* 94 */
+ "fsync", /* 95 */
+ "setpriority", /* 96 */
+ "socket", /* 97 */
+ "connect", /* 98 */
+ "accept", /* 99 */
+ "osf_getpriority", /* 100 */
+ "send", /* 101 */
+ "recv", /* 102 */
+ "sigreturn", /* 103 */
+ "bind", /* 104 */
+ "setsockopt", /* 105 */
+ "listen", /* 106 */
+ "osf_plock", /* 107, not implemented */
+ "osf_old_sigvec", /* 108, not implemented */
+ "osf_old_sigblock", /* 109, not implemented */
+ "osf_old_sigsetmask", /* 110, not implemented */
+ "sigsuspend", /* 111 */
+ "sigstack", /* 112 */
+ "recvmsg", /* 113 */
+ "sendmsg", /* 114 */
+ "osf_old_vtrace", /* 115, not implemented */
+ "osf_gettimeofday", /* 116 */
+ "osf_getrusage", /* 117 */
+ "getsockopt", /* 118 */
+ "SYS_119", /* 119 */
+ "readv", /* 120 */
+ "writev", /* 121 */
+ "osf_settimeofday", /* 122 */
+ "fchown", /* 123 */
+ "fchmod", /* 124 */
+ "recvfrom", /* 125 */
+ "setreuid", /* 126 */
+ "setregid", /* 127 */
+ "rename", /* 128 */
+ "truncate", /* 129 */
+ "ftruncate", /* 130 */
+ "flock", /* 131 */
+ "setgid", /* 132 */
+ "sendto", /* 133 */
+ "shutdown", /* 134 */
+ "socketpair", /* 135 */
+ "mkdir", /* 136 */
+ "rmdir", /* 137 */
+ "osf_utimes", /* 138 */
+ "osf_old_sigreturn", /* 139 */
+ "osf_adjtime", /* 140, not implemented */
+ "getpeername", /* 141 */
+ "osf_gethostid", /* 142, not implemented */
+ "osf_sethostid", /* 143, not implemented */
+ "getrlimit", /* 144 */
+ "setrlimit", /* 145 */
+ "osf_old_killpg", /* 146, not implemented */
+ "setsid", /* 147 */
+ "quotactl", /* 148 */
+ "osf_oldquota", /* 149, not implemented */
+ "getsockname", /* 150 */
+ "SYS_151", /* 151 */
+ "SYS_152", /* 152 */
+ "osf_pid_block", /* 153, not implemented */
+ "osf_pid_unblock", /* 154, not implemented */
+ "SYS_155", /* 155 */
+ "sigaction", /* 156 */
+ "osf_sigwaitprim", /* 157, not implemented */
+ "osf_nfssvc", /* 158, not implemented */
+ "osf_getdirentries", /* 159 */
+ "osf_statfs", /* 160 */
+ "osf_fstatfs", /* 161 */
+ "SYS_162", /* 162 */
+ "osf_asynch_daemon", /* 163, not implemented */
+ "osf_getfh", /* 164, not implemented */
+ "osf_getdomainname", /* 165 */
+ "setdomainname", /* 166 */
+ "SYS_167", /* 167 */
+ "SYS_168", /* 168 */
+ "osf_exportfs", /* 169, not implemented */
+ "SYS_170", /* 170 */
+ "SYS_171", /* 171 */
+ "SYS_172", /* 172 */
+ "SYS_173", /* 173 */
+ "SYS_174", /* 174 */
+ "SYS_175", /* 175 */
+ "SYS_176", /* 176 */
+ "SYS_177", /* 177 */
+ "SYS_178", /* 178 */
+ "SYS_179", /* 179 */
+ "SYS_180", /* 180 */
+ "osf_alt_plock", /* 181, not implemented */
+ "SYS_182", /* 182 */
+ "SYS_183", /* 183 */
+ "osf_getmnt", /* 184, not implemented */
+ "SYS_185", /* 185 */
+ "SYS_186", /* 186 */
+ "osf_alt_sigpending", /* 187, not implemented */
+ "osf_alt_setsid", /* 188, not implemented */
+ "SYS_189", /* 189 */
+ "SYS_190", /* 190 */
+ "SYS_191", /* 191 */
+ "SYS_192", /* 192 */
+ "SYS_193", /* 193 */
+ "SYS_194", /* 194 */
+ "SYS_195", /* 195 */
+ "SYS_196", /* 196 */
+ "SYS_197", /* 197 */
+ "SYS_198", /* 198 */
+ "osf_swapon", /* 199 */
+ "msgctl", /* 200 */
+ "msgget", /* 201 */
+ "msgrcv", /* 202 */
+ "msgsnd", /* 203 */
+ "semctl", /* 204 */
+ "semget", /* 205 */
+ "semop", /* 206 */
+ "osf_utsname", /* 207 */
+ "lchown", /* 208 */
+ "osf_shmat", /* 209 */
+ "shmctl", /* 210 */
+ "shmdt", /* 211 */
+ "shmget", /* 212 */
+ "osf_mvalid", /* 213, not implemented */
+ "osf_getaddressconf", /* 214, not implemented */
+ "osf_msleep", /* 215, not implemented */
+ "osf_mwakeup", /* 216, not implemented */
+ "msync", /* 217 */
+ "osf_signal", /* 218, not implemented */
+ "osf_utc_gettime", /* 219, not implemented */
+ "osf_utc_adjtime", /* 220, not implemented */
+ "SYS_221", /* 221 */
+ "osf_security", /* 222, not implemented */
+ "osf_kloadcall", /* 223, not implemented */
+ "SYS_224", /* 224 */
+ "SYS_225", /* 225 */
+ "SYS_226", /* 226 */
+ "SYS_227", /* 227 */
+ "SYS_228", /* 228 */
+ "SYS_229", /* 229 */
+ "SYS_230", /* 230 */
+ "SYS_231", /* 231 */
+ "SYS_232", /* 232 */
+ "getpgid", /* 233 */
+ "getsid", /* 234 */
+ "sigaltstack", /* 235 */
+ "osf_waitid", /* 236, not implemented */
+ "osf_priocntlset", /* 237, not implemented */
+ "osf_sigsendset", /* 238, not implemented */
+ "osf_set_speculative", /* 239, not implemented */
+ "osf_msfs_syscall", /* 240, not implemented */
+ "osf_sysinfo", /* 241 */
+ "osf_uadmin", /* 242, not implemented */
+ "osf_fuser", /* 243, not implemented */
+ "osf_proplist_syscall", /* 244 */
+ "osf_ntp_adjtime", /* 245, not implemented */
+ "osf_ntp_gettime", /* 246, not implemented */
+ "osf_pathconf", /* 247, not implemented */
+ "osf_fpathconf", /* 248, not implemented */
+ "SYS_249", /* 249 */
+ "osf_uswitch", /* 250, not implemented */
+ "osf_usleep_thread", /* 251 */
+ "osf_audcntl", /* 252, not implemented */
+ "osf_audgen", /* 253, not implemented */
+ "sysfs", /* 254 */
+ "osf_subsysinfo", /* 255, not implemented */
+ "osf_getsysinfo", /* 256 */
+ "osf_setsysinfo", /* 257 */
+ "osf_afs_syscall", /* 258, not implemented */
+ "osf_swapctl", /* 259, not implemented */
+ "osf_memcntl", /* 260, not implemented */
+ "osf_fdatasync", /* 261, not implemented */
+ "SYS_262", /* 262 */
+ "SYS_263", /* 263 */
+ "SYS_264", /* 264 */
+ "SYS_265", /* 265 */
+ "SYS_266", /* 266 */
+ "SYS_267", /* 267 */
+ "SYS_268", /* 268 */
+ "SYS_269", /* 269 */
+ "SYS_270", /* 270 */
+ "SYS_271", /* 271 */
+ "SYS_272", /* 272 */
+ "SYS_273", /* 273 */
+ "SYS_274", /* 274 */
+ "SYS_275", /* 275 */
+ "SYS_276", /* 276 */
+ "SYS_277", /* 277 */
+ "SYS_278", /* 278 */
+ "SYS_279", /* 279 */
+ "SYS_280", /* 280 */
+ "SYS_281", /* 281 */
+ "SYS_282", /* 282 */
+ "SYS_283", /* 283 */
+ "SYS_284", /* 284 */
+ "SYS_285", /* 285 */
+ "SYS_286", /* 286 */
+ "SYS_287", /* 287 */
+ "SYS_288", /* 288 */
+ "SYS_289", /* 289 */
+ "SYS_290", /* 290 */
+ "SYS_291", /* 291 */
+ "SYS_292", /* 292 */
+ "SYS_293", /* 293 */
+ "SYS_294", /* 294 */
+ "SYS_295", /* 295 */
+ "SYS_296", /* 296 */
+ "SYS_297", /* 297 */
+ "SYS_298", /* 298 */
+ "SYS_299", /* 299 */
+ "bdflush", /* 300 */
+ "sethae", /* 301 */
+ "mount", /* 302 */
+ "adjtimex32", /* 303 */
+ "swapoff", /* 304 */
+ "getdents", /* 305 */
+ "create_module", /* 306 */
+ "init_module", /* 307 */
+ "delete_module", /* 308 */
+ "get_kernel_syms", /* 309 */
+ "syslog", /* 310 */
+ "reboot", /* 311 */
+ "clone", /* 312 */
+ "uselib", /* 313 */
+ "mlock", /* 314 */
+ "munlock", /* 315 */
+ "mlockall", /* 316 */
+ "munlockall", /* 317 */
+ "sysinfo", /* 318 */
+ "sysctl", /* 319 */
+ "idle", /* 320 */
+ "oldumount", /* 321 */
+ "swapon", /* 322 */
+ "times", /* 323 */
+ "personality", /* 324 */
+ "setfsuid", /* 325 */
+ "setfsgid", /* 326 */
+ "ustat", /* 327 */
+ "statfs", /* 328 */
+ "fstatfs", /* 329 */
+ "sched_setparam", /* 330 */
+ "sched_getparam", /* 331 */
+ "sched_setscheduler", /* 332 */
+ "sched_getscheduler", /* 333 */
+ "sched_yield", /* 334 */
+ "sched_get_priority_max", /* 335 */
+ "sched_get_priority_min", /* 336 */
+ "sched_rr_get_interval", /* 337 */
+ "afs_syscall", /* 338 */
+ "uname", /* 339 */
+ "nanosleep", /* 340 */
+ "mremap", /* 341 */
+ "nfsservctl", /* 342 */
+ "setresuid", /* 343 */
+ "getresuid", /* 344 */
+ "pciconfig_read", /* 345 */
+ "pciconfig_write", /* 346 */
+ "query_module", /* 347 */
+ "prctl", /* 348 */
+ "pread", /* 349 */
+ "pwrite", /* 350 */
+ "rt_sigreturn", /* 351 */
+ "rt_sigaction", /* 352 */
+ "rt_sigprocmask", /* 353 */
+ "rt_sigpending", /* 354 */
+ "rt_sigtimedwait", /* 355 */
+ "rt_sigqueueinfo", /* 356 */
+ "rt_sigsuspend", /* 357 */
+ "select", /* 358 */
+ "gettimeofday", /* 359 */
+ "settimeofday", /* 360 */
+ "getitimer", /* 361 */
+ "setitimer", /* 362 */
+ "utimes", /* 363 */
+ "getrusage", /* 364 */
+ "wait4", /* 365 */
+ "adjtimex", /* 366 */
+ "getcwd", /* 367 */
+ "capget", /* 368 */
+ "capset", /* 369 */
+ "sendfile", /* 370 */
+ "setresgid", /* 371 */
+ "getresgid", /* 372 */
+ "dipc", /* 373, not implemented */
+ "pivot_root", /* 374 */
+ "mincore", /* 375 */
+ "pciconfig_iobase", /* 376 */
+ "getdents64", /* 377 */
+ "gettid", /* 378 */
+ "readahead", /* 379 */
+ "SYS_380", /* 380 */
+ "tkill", /* 381 */
+ "setxattr", /* 382 */
+ "lsetxattr", /* 383 */
+ "fsetxattr", /* 384 */
+ "getxattr", /* 385 */
+ "lgetxattr", /* 386 */
+ "fgetxattr", /* 387 */
+ "listxattr", /* 388 */
+ "llistxattr", /* 389 */
+ "flistxattr", /* 390 */
+ "removexattr", /* 391 */
+ "lremovexattr", /* 392 */
+ "fremovexattr", /* 393 */
+ "futex", /* 394 */
+ "sched_setaffinity", /* 395 */
+ "sched_getaffinity", /* 396 */
+ "tuxcall", /* 397 */
+ "io_setup", /* 398 */
+ "io_destroy", /* 399 */
+ "io_getevents", /* 400 */
+ "io_submit", /* 401 */
+ "io_cancel", /* 402 */
+ "SYS_403", /* 403 */
+ "SYS_404", /* 404 */
+ "exit_group", /* 405 */
+ "lookup_dcookie", /* 406 */
+ "epoll_create", /* 407 */
+ "epoll_ctl", /* 408 */
+ "epoll_wait", /* 409 */
+ "remap_file_pages", /* 410 */
+ "set_tid_address", /* 411 */
+ "restart_syscall", /* 412 */
+ "fadvise", /* 413 */
+ "timer_create", /* 414 */
+ "timer_settime", /* 415 */
+ "timer_gettime", /* 416 */
+ "timer_getoverrun", /* 417 */
+ "timer_delete", /* 418 */
+ "clock_settime", /* 419 */
+ "clock_gettime", /* 420 */
+ "clock_getres", /* 421 */
+ "clock_nanosleep", /* 422 */
+ "semtimedop", /* 423 */
+ "tgkill", /* 424 */
+ "stat64", /* 425 */
+ "lstat64", /* 426 */
+ "fstat64", /* 427 */
+ "vserver", /* 428 */
+ "mbind", /* 429 */
+ "get_mempolicy", /* 430 */
+ "set_mempolicy", /* 431 */
+ "mq_open", /* 432 */
+ "mq_unlink", /* 433 */
+ "mq_timedsend", /* 434 */
+ "mq_timedreceive", /* 435 */
+ "mq_notify", /* 436 */
+ "mq_getsetattr", /* 437 */
+ "waitid" /* 438 */
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) {
+}
diff --git a/sysdeps/linux-gnu/arch_mksyscallent b/sysdeps/linux-gnu/arch_mksyscallent
new file mode 100644
index 0000000..853d62d
--- /dev/null
+++ b/sysdeps/linux-gnu/arch_mksyscallent
@@ -0,0 +1,42 @@
+#!/usr/bin/awk -f
+
+# hack expression to generate arch_syscallent.h from <asm/unistd.h>
+# It reads from stdin and writes to stdout
+# Currently (linux-2.6.16), it works OK on arm
+# It is untested in other architectures
+
+BEGIN {
+ max=0;
+ FS="[ \t\n()+]+";
+}
+
+{
+# printf("/%s/%s/%s/%s/\n", $1, $2, $3, $4);
+ if (($1 ~ /^#define$/) && ($2 ~ /^__[A-Z]+_NR_/)) {
+ sub(/^__[A-Z]+_NR_/,"",$2);
+ if (($3>=0) && ($3<=1000)) {
+ SYSCALL[$3]=$2;
+ if ($3 > max) {
+ max=$3;
+ }
+ } else if (($3 ~ /^__[A-Z]+_NR_BASE$/) && ($4>=0) && ($4<=1000)) {
+ SYSCALL[$4]=$2;
+ if ($4 > max) {
+ max=$4;
+ }
+ }
+ }
+}
+
+END {
+ for(i=0; i<=max; i++) {
+ if (!SYSCALL[i]) {
+ SYSCALL[i] = i;
+ }
+ pad = 32 - length(SYSCALL[i]);
+ if (pad<1) {
+ pad=1;
+ }
+ printf("\t\"%s\",%*s/* %d */\n", SYSCALL[i], pad, "", i);
+ }
+}
diff --git a/sysdeps/linux-gnu/arm/Makefile b/sysdeps/linux-gnu/arm/Makefile
new file mode 100644
index 0000000..f55ba48
--- /dev/null
+++ b/sysdeps/linux-gnu/arm/Makefile
@@ -0,0 +1,10 @@
+OBJ = trace.o regs.o plt.o breakpoint.o
+
+all: arch.o
+
+arch.o: $(OBJ) arch.h
+ $(CC) -nostdlib -r -o arch.o $(OBJ)
+
+clean:
+ $(RM) $(OBJ) arch.o
+
diff --git a/sysdeps/linux-gnu/arm/arch.h b/sysdeps/linux-gnu/arm/arch.h
new file mode 100644
index 0000000..8f2dfb3
--- /dev/null
+++ b/sysdeps/linux-gnu/arm/arch.h
@@ -0,0 +1,11 @@
+#define ARCH_HAVE_ENABLE_BREAKPOINT 1
+#define ARCH_HAVE_DISABLE_BREAKPOINT 1
+
+#define BREAKPOINT_VALUE { 0xf0, 0x01, 0xf0, 0xe7 }
+#define BREAKPOINT_LENGTH 4
+#define THUMB_BREAKPOINT_VALUE { 0x01, 0xde }
+#define THUMB_BREAKPOINT_LENGTH 2
+#define DECR_PC_AFTER_BREAK 0
+
+#define LT_ELFCLASS ELFCLASS32
+#define LT_ELF_MACHINE EM_ARM
diff --git a/sysdeps/linux-gnu/arm/arch_syscallent.h b/sysdeps/linux-gnu/arm/arch_syscallent.h
new file mode 100644
index 0000000..ce1e844
--- /dev/null
+++ b/sysdeps/linux-gnu/arm/arch_syscallent.h
@@ -0,0 +1,6 @@
+ "0", /* 0 */
+ "breakpoint", /* 1 */
+ "cacheflush", /* 2 */
+ "usr26", /* 3 */
+ "usr32", /* 4 */
+ "set_tls", /* 5 */
diff --git a/sysdeps/linux-gnu/arm/breakpoint.c b/sysdeps/linux-gnu/arm/breakpoint.c
new file mode 100644
index 0000000..4c20260
--- /dev/null
+++ b/sysdeps/linux-gnu/arm/breakpoint.c
@@ -0,0 +1,77 @@
+/*
+ * This file is part of ltrace.
+ *
+ * Copyright (C) 2007 by Instituto Nokia de Tecnologia (INdT)
+ *
+ * Author: Anderson Lizardo <anderson.lizardo@indt.org.br>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * Modified from sysdeps/linux-gnu/breakpoint.c and added ARM Thumb support.
+ */
+
+#include <sys/ptrace.h>
+#include "config.h"
+#include "arch.h"
+#include "options.h"
+#include "output.h"
+#include "debug.h"
+
+void
+arch_enable_breakpoint(pid_t pid, Breakpoint *sbp) {
+ unsigned int i, j;
+ const unsigned char break_insn[] = BREAKPOINT_VALUE;
+ const unsigned char thumb_break_insn[] = THUMB_BREAKPOINT_VALUE;
+
+ debug(1, "arch_enable_breakpoint(%d,%p)", pid, sbp->addr);
+
+ for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
+ long a = ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long), 0);
+ unsigned char *bytes = (unsigned char *)&a;
+
+ debug(2, "current = 0x%lx, orig_value = 0x%lx, thumb_mode = %d", a, *(long *)&sbp->orig_value, sbp->thumb_mode);
+ for (j = 0; j < sizeof(long) && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
+
+ sbp->orig_value[i * sizeof(long) + j] = bytes[j];
+ if (!sbp->thumb_mode) {
+ bytes[j] = break_insn[i * sizeof(long) + j];
+ }
+ else if (j < THUMB_BREAKPOINT_LENGTH) {
+ bytes[j] = thumb_break_insn[i * sizeof(long) + j];
+ }
+ }
+ ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
+ }
+}
+
+void
+arch_disable_breakpoint(pid_t pid, const Breakpoint *sbp) {
+ unsigned int i, j;
+ const unsigned char break_insn[] = BREAKPOINT_VALUE;
+ const unsigned char thumb_break_insn[] = THUMB_BREAKPOINT_VALUE;
+
+ debug(1, "arch_disable_breakpoint(%d,%p)", pid, sbp->addr);
+
+ for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
+ long a = ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long), 0);
+ unsigned char *bytes = (unsigned char *)&a;
+
+ debug(2, "current = 0x%lx, orig_value = 0x%lx, thumb_mode = %d", a, *(long *)&sbp->orig_value, sbp->thumb_mode);
+ for (j = 0; j < sizeof(long) && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
+ bytes[j] = sbp->orig_value[i * sizeof(long) + j];
+ }
+ ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
+ }
+}
diff --git a/sysdeps/linux-gnu/arm/plt.c b/sysdeps/linux-gnu/arm/plt.c
new file mode 100644
index 0000000..bd92a63
--- /dev/null
+++ b/sysdeps/linux-gnu/arm/plt.c
@@ -0,0 +1,12 @@
+#include <gelf.h>
+#include "common.h"
+
+GElf_Addr
+arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) {
+ return lte->plt_addr + 20 + ndx * 12;
+}
+
+void *
+sym2addr(Process *proc, struct library_symbol *sym) {
+ return sym->enter_addr;
+}
diff --git a/sysdeps/linux-gnu/arm/ptrace.h b/sysdeps/linux-gnu/arm/ptrace.h
new file mode 100644
index 0000000..52215bc
--- /dev/null
+++ b/sysdeps/linux-gnu/arm/ptrace.h
@@ -0,0 +1,9 @@
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+
+typedef struct {
+ int valid;
+ struct pt_regs regs;
+ long func_arg[5];
+ long sysc_arg[5];
+} proc_archdep;
diff --git a/sysdeps/linux-gnu/arm/regs.c b/sysdeps/linux-gnu/arm/regs.c
new file mode 100644
index 0000000..2488b0a
--- /dev/null
+++ b/sysdeps/linux-gnu/arm/regs.c
@@ -0,0 +1,51 @@
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+
+#include "common.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
+
+#define off_pc 60
+#define off_lr 56
+#define off_sp 52
+
+void *
+get_instruction_pointer(Process *proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0);
+}
+
+void
+set_instruction_pointer(Process *proc, void *addr) {
+ ptrace(PTRACE_POKEUSER, proc->pid, off_pc, addr);
+}
+
+void *
+get_stack_pointer(Process *proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_sp, 0);
+}
+
+/* really, this is given the *stack_pointer expecting
+ * a CISC architecture; in our case, we don't need that */
+void *
+get_return_addr(Process *proc, void *stack_pointer) {
+ long addr = ptrace(PTRACE_PEEKUSER, proc->pid, off_lr, 0);
+
+ proc->thumb_mode = addr & 1;
+ if (proc->thumb_mode)
+ addr &= ~1;
+ return (void *)addr;
+}
+
+void
+set_return_addr(Process *proc, void *addr) {
+ ptrace(PTRACE_POKEUSER, proc->pid, off_lr, addr);
+}
diff --git a/sysdeps/linux-gnu/arm/signalent.h b/sysdeps/linux-gnu/arm/signalent.h
new file mode 100644
index 0000000..0afb004
--- /dev/null
+++ b/sysdeps/linux-gnu/arm/signalent.h
@@ -0,0 +1,33 @@
+ "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 */
+ "SIGSWI", /* 32 */
diff --git a/sysdeps/linux-gnu/arm/syscallent.h b/sysdeps/linux-gnu/arm/syscallent.h
new file mode 100644
index 0000000..4113234
--- /dev/null
+++ b/sysdeps/linux-gnu/arm/syscallent.h
@@ -0,0 +1,322 @@
+ "restart_syscall", /* 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 */
+ "48", /* 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 */
+ "select", /* 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 */
+ "101", /* 101 */
+ "socketcall", /* 102 */
+ "syslog", /* 103 */
+ "setitimer", /* 104 */
+ "getitimer", /* 105 */
+ "stat", /* 106 */
+ "lstat", /* 107 */
+ "fstat", /* 108 */
+ "109", /* 109 */
+ "110", /* 110 */
+ "vhangup", /* 111 */
+ "112", /* 112 */
+ "syscall", /* 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 */
+ "127", /* 127 */
+ "init_module", /* 128 */
+ "delete_module", /* 129 */
+ "130", /* 130 */
+ "quotactl", /* 131 */
+ "getpgid", /* 132 */
+ "fchdir", /* 133 */
+ "bdflush", /* 134 */
+ "sysfs", /* 135 */
+ "personality", /* 136 */
+ "137", /* 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 */
+ "167", /* 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 */
+ "pread64", /* 180 */
+ "pwrite64", /* 181 */
+ "chown", /* 182 */
+ "getcwd", /* 183 */
+ "capget", /* 184 */
+ "capset", /* 185 */
+ "sigaltstack", /* 186 */
+ "sendfile", /* 187 */
+ "188", /* 188 */
+ "189", /* 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 */
+ "getdents64", /* 217 */
+ "pivot_root", /* 218 */
+ "mincore", /* 219 */
+ "madvise", /* 220 */
+ "fcntl64", /* 221 */
+ "222", /* 222 */
+ "223", /* 223 */
+ "gettid", /* 224 */
+ "readahead", /* 225 */
+ "setxattr", /* 226 */
+ "lsetxattr", /* 227 */
+ "fsetxattr", /* 228 */
+ "getxattr", /* 229 */
+ "lgetxattr", /* 230 */
+ "fgetxattr", /* 231 */
+ "listxattr", /* 232 */
+ "llistxattr", /* 233 */
+ "flistxattr", /* 234 */
+ "removexattr", /* 235 */
+ "lremovexattr", /* 236 */
+ "fremovexattr", /* 237 */
+ "tkill", /* 238 */
+ "sendfile64", /* 239 */
+ "futex", /* 240 */
+ "sched_setaffinity", /* 241 */
+ "sched_getaffinity", /* 242 */
+ "io_setup", /* 243 */
+ "io_destroy", /* 244 */
+ "io_getevents", /* 245 */
+ "io_submit", /* 246 */
+ "io_cancel", /* 247 */
+ "exit_group", /* 248 */
+ "lookup_dcookie", /* 249 */
+ "epoll_create", /* 250 */
+ "epoll_ctl", /* 251 */
+ "epoll_wait", /* 252 */
+ "remap_file_pages", /* 253 */
+ "254", /* 254 */
+ "255", /* 255 */
+ "set_tid_address", /* 256 */
+ "timer_create", /* 257 */
+ "timer_settime", /* 258 */
+ "timer_gettime", /* 259 */
+ "timer_getoverrun", /* 260 */
+ "timer_delete", /* 261 */
+ "clock_settime", /* 262 */
+ "clock_gettime", /* 263 */
+ "clock_getres", /* 264 */
+ "clock_nanosleep", /* 265 */
+ "statfs64", /* 266 */
+ "fstatfs64", /* 267 */
+ "tgkill", /* 268 */
+ "utimes", /* 269 */
+ "arm_fadvise64_64", /* 270 */
+ "pciconfig_iobase", /* 271 */
+ "pciconfig_read", /* 272 */
+ "pciconfig_write", /* 273 */
+ "mq_open", /* 274 */
+ "mq_unlink", /* 275 */
+ "mq_timedsend", /* 276 */
+ "mq_timedreceive", /* 277 */
+ "mq_notify", /* 278 */
+ "mq_getsetattr", /* 279 */
+ "waitid", /* 280 */
+ "socket", /* 281 */
+ "bind", /* 282 */
+ "connect", /* 283 */
+ "listen", /* 284 */
+ "accept", /* 285 */
+ "getsockname", /* 286 */
+ "getpeername", /* 287 */
+ "socketpair", /* 288 */
+ "send", /* 289 */
+ "sendto", /* 290 */
+ "recv", /* 291 */
+ "recvfrom", /* 292 */
+ "shutdown", /* 293 */
+ "setsockopt", /* 294 */
+ "getsockopt", /* 295 */
+ "sendmsg", /* 296 */
+ "recvmsg", /* 297 */
+ "semop", /* 298 */
+ "semget", /* 299 */
+ "semctl", /* 300 */
+ "msgsnd", /* 301 */
+ "msgrcv", /* 302 */
+ "msgget", /* 303 */
+ "msgctl", /* 304 */
+ "shmat", /* 305 */
+ "shmdt", /* 306 */
+ "shmget", /* 307 */
+ "shmctl", /* 308 */
+ "add_key", /* 309 */
+ "request_key", /* 310 */
+ "keyctl", /* 311 */
+ "semtimedop", /* 312 */
+ "vserver", /* 313 */
+ "ioprio_set", /* 314 */
+ "ioprio_get", /* 315 */
+ "inotify_init", /* 316 */
+ "inotify_add_watch", /* 317 */
+ "inotify_rm_watch", /* 318 */
+ "mbind", /* 319 */
+ "get_mempolicy", /* 320 */
+ "set_mempolicy", /* 321 */
diff --git a/sysdeps/linux-gnu/arm/trace.c b/sysdeps/linux-gnu/arm/trace.c
new file mode 100644
index 0000000..10f7cc4
--- /dev/null
+++ b/sysdeps/linux-gnu/arm/trace.c
@@ -0,0 +1,131 @@
+#include "config.h"
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+
+#include "common.h"
+#include "output.h"
+#include "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
+
+#define off_r0 0
+#define off_r7 28
+#define off_ip 48
+#define off_pc 60
+
+void
+get_arch_dep(Process *proc) {
+ proc_archdep *a;
+
+ if (!proc->arch_ptr)
+ proc->arch_ptr = (void *)malloc(sizeof(proc_archdep));
+ a = (proc_archdep *) (proc->arch_ptr);
+ a->valid = (ptrace(PTRACE_GETREGS, proc->pid, 0, &a->regs) >= 0);
+}
+
+/* Returns 0 if not a syscall,
+ * 1 if syscall entry, 2 if syscall exit,
+ * 3 if arch-specific syscall entry, 4 if arch-specific syscall exit,
+ * -1 on error.
+ */
+int
+syscall_p(Process *proc, int status, int *sysnum) {
+ if (WIFSTOPPED(status)
+ && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
+ /* get the user's pc (plus 8) */
+ int pc = ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0);
+ /* fetch the SWI instruction */
+ int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 4, 0);
+ int ip = ptrace(PTRACE_PEEKUSER, proc->pid, off_ip, 0);
+
+ if (insn == 0xef000000 || insn == 0x0f000000) {
+ /* EABI syscall */
+ *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, off_r7, 0);
+ } else if ((insn & 0xfff00000) == 0xef900000) {
+ /* old ABI syscall */
+ *sysnum = insn & 0xfffff;
+ } else {
+ /* TODO: handle swi<cond> variations */
+ /* one possible reason for getting in here is that we
+ * are coming from a signal handler, so the current
+ * PC does not point to the instruction just after the
+ * "swi" one. */
+ output_line(proc, "unexpected instruction 0x%x at %p", insn, pc - 4);
+ return -1;
+ }
+ if ((*sysnum & 0xf0000) == 0xf0000) {
+ /* arch-specific syscall */
+ *sysnum &= ~0xf0000;
+ return ip ? 4 : 3;
+ }
+ /* ARM syscall convention: on syscall entry, ip is zero;
+ * on syscall exit, ip is non-zero */
+ return ip ? 2 : 1;
+ }
+ return 0;
+}
+
+long
+gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) {
+ proc_archdep *a = (proc_archdep *) proc->arch_ptr;
+
+ if (arg_num == -1) { /* return value */
+ return ptrace(PTRACE_PEEKUSER, proc->pid, off_r0, 0);
+ }
+
+ /* deal with the ARM calling conventions */
+ if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
+ if (arg_num < 4) {
+ if (a->valid && type == LT_TOF_FUNCTION)
+ return a->regs.uregs[arg_num];
+ if (a->valid && type == LT_TOF_FUNCTIONR)
+ return a->func_arg[arg_num];
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num,
+ 0);
+ } else {
+ return ptrace(PTRACE_PEEKDATA, proc->pid,
+ proc->stack_pointer + 4 * (arg_num - 4),
+ 0);
+ }
+ } else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) {
+ if (arg_num < 5) {
+ if (a->valid && type == LT_TOF_SYSCALL)
+ return a->regs.uregs[arg_num];
+ if (a->valid && type == LT_TOF_SYSCALLR)
+ return a->sysc_arg[arg_num];
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num,
+ 0);
+ } else {
+ return ptrace(PTRACE_PEEKDATA, proc->pid,
+ proc->stack_pointer + 4 * (arg_num - 5),
+ 0);
+ }
+ } else {
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(1);
+ }
+
+ return 0;
+}
+
+void
+save_register_args(enum tof type, Process *proc) {
+ proc_archdep *a = (proc_archdep *) proc->arch_ptr;
+ if (a->valid) {
+ if (type == LT_TOF_FUNCTION)
+ memcpy(a->func_arg, a->regs.uregs, sizeof(a->func_arg));
+ else
+ memcpy(a->sysc_arg, a->regs.uregs, sizeof(a->sysc_arg));
+ }
+}
diff --git a/sysdeps/linux-gnu/breakpoint.c b/sysdeps/linux-gnu/breakpoint.c
new file mode 100644
index 0000000..5ca131a
--- /dev/null
+++ b/sysdeps/linux-gnu/breakpoint.c
@@ -0,0 +1,86 @@
+#include "config.h"
+
+#include <sys/ptrace.h>
+#include <string.h>
+
+#include "common.h"
+#include "arch.h"
+
+static unsigned char break_insn[] = BREAKPOINT_VALUE;
+
+#ifdef ARCH_HAVE_ENABLE_BREAKPOINT
+extern void arch_enable_breakpoint(pid_t, Breakpoint *);
+void
+enable_breakpoint(pid_t pid, Breakpoint *sbp) {
+ if (sbp->libsym) {
+ debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name);
+ } else {
+ debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p", pid, sbp->addr);
+ }
+ arch_enable_breakpoint(pid, sbp);
+}
+#else
+void
+enable_breakpoint(pid_t pid, Breakpoint *sbp) {
+ unsigned int i, j;
+
+ if (sbp->libsym) {
+ debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name);
+ } else {
+ debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p", pid, sbp->addr);
+ }
+
+ for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
+ long a =
+ ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
+ 0);
+ for (j = 0;
+ j < sizeof(long)
+ && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
+ unsigned char *bytes = (unsigned char *)&a;
+
+ sbp->orig_value[i * sizeof(long) + j] = bytes[j];
+ bytes[j] = break_insn[i * sizeof(long) + j];
+ }
+ ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
+ }
+}
+#endif /* ARCH_HAVE_ENABLE_BREAKPOINT */
+
+#ifdef ARCH_HAVE_DISABLE_BREAKPOINT
+extern void arch_disable_breakpoint(pid_t, const Breakpoint *sbp);
+void
+disable_breakpoint(pid_t pid, const Breakpoint *sbp) {
+ if (sbp->libsym) {
+ debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name);
+ } else {
+ debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p", pid, sbp->addr);
+ }
+ arch_disable_breakpoint(pid, sbp);
+}
+#else
+void
+disable_breakpoint(pid_t pid, const Breakpoint *sbp) {
+ unsigned int i, j;
+
+ if (sbp->libsym) {
+ debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name);
+ } else {
+ debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p", pid, sbp->addr);
+ }
+
+ for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
+ long a =
+ ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
+ 0);
+ for (j = 0;
+ j < sizeof(long)
+ && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
+ unsigned char *bytes = (unsigned char *)&a;
+
+ bytes[j] = sbp->orig_value[i * sizeof(long) + j];
+ }
+ ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
+ }
+}
+#endif /* ARCH_HAVE_DISABLE_BREAKPOINT */
diff --git a/sysdeps/linux-gnu/events.c b/sysdeps/linux-gnu/events.c
new file mode 100644
index 0000000..a1e2a14
--- /dev/null
+++ b/sysdeps/linux-gnu/events.c
@@ -0,0 +1,161 @@
+#include "config.h"
+
+#define _GNU_SOURCE 1
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/ptrace.h>
+
+#include "common.h"
+
+static Event event;
+
+Event *
+next_event(void) {
+ pid_t pid;
+ int status;
+ int tmp;
+ int stop_signal;
+
+ debug(DEBUG_FUNCTION, "next_event()");
+ if (!list_of_processes) {
+ debug(DEBUG_EVENT, "event: No more traced programs: exiting");
+ exit(0);
+ }
+ pid = waitpid(-1, &status, __WALL);
+ if (pid == -1) {
+ if (errno == ECHILD) {
+ debug(DEBUG_EVENT, "event: No more traced programs: exiting");
+ exit(0);
+ } else if (errno == EINTR) {
+ debug(DEBUG_EVENT, "event: none (wait received EINTR?)");
+ event.type = EVENT_NONE;
+ return &event;
+ }
+ perror("wait");
+ exit(1);
+ }
+ event.proc = pid2proc(pid);
+ if (!event.proc || event.proc->state == STATE_BEING_CREATED) {
+ event.type = EVENT_NEW;
+ event.e_un.newpid = pid;
+ debug(DEBUG_EVENT, "event: NEW: pid=%d", pid);
+ return &event;
+ }
+ get_arch_dep(event.proc);
+ event.proc->instruction_pointer = NULL;
+ debug(3, "event from pid %u", pid);
+ if (event.proc->breakpoints_enabled == -1) {
+ enable_all_breakpoints(event.proc);
+ event.type = EVENT_NONE;
+ trace_set_options(event.proc, event.proc->pid);
+ continue_process(event.proc->pid);
+ debug(DEBUG_EVENT, "event: NONE: pid=%d (enabling breakpoints)", pid);
+ return &event;
+ }
+ if (opt_i) {
+ event.proc->instruction_pointer =
+ get_instruction_pointer(event.proc);
+ }
+ switch (syscall_p(event.proc, status, &tmp)) {
+ case 1:
+ event.type = EVENT_SYSCALL;
+ event.e_un.sysnum = tmp;
+ debug(DEBUG_EVENT, "event: SYSCALL: pid=%d, sysnum=%d", pid, tmp);
+ return &event;
+ case 2:
+ event.type = EVENT_SYSRET;
+ event.e_un.sysnum = tmp;
+ debug(DEBUG_EVENT, "event: SYSRET: pid=%d, sysnum=%d", pid, tmp);
+ return &event;
+ case 3:
+ event.type = EVENT_ARCH_SYSCALL;
+ event.e_un.sysnum = tmp;
+ debug(DEBUG_EVENT, "event: ARCH_SYSCALL: pid=%d, sysnum=%d", pid, tmp);
+ return &event;
+ case 4:
+ event.type = EVENT_ARCH_SYSRET;
+ event.e_un.sysnum = tmp;
+ debug(DEBUG_EVENT, "event: ARCH_SYSRET: pid=%d, sysnum=%d", pid, tmp);
+ return &event;
+ case -1:
+ event.type = EVENT_NONE;
+ continue_process(event.proc->pid);
+ debug(DEBUG_EVENT, "event: NONE: pid=%d (syscall_p returned -1)", pid);
+ return &event;
+ }
+ if (WIFSTOPPED(status) && ((status>>16 == PTRACE_EVENT_FORK) || (status>>16 == PTRACE_EVENT_VFORK) || (status>>16 == PTRACE_EVENT_CLONE))) {
+ unsigned long data;
+ ptrace(PTRACE_GETEVENTMSG, pid, NULL, &data);
+ event.type = EVENT_CLONE;
+ event.e_un.newpid = data;
+ debug(DEBUG_EVENT, "event: CLONE: pid=%d, newpid=%d", pid, (int)data);
+ return &event;
+ }
+ if (WIFSTOPPED(status) && (status>>16 == PTRACE_EVENT_EXEC)) {
+ event.type = EVENT_EXEC;
+ debug(DEBUG_EVENT, "event: EXEC: pid=%d", pid);
+ return &event;
+ }
+ if (WIFEXITED(status)) {
+ event.type = EVENT_EXIT;
+ event.e_un.ret_val = WEXITSTATUS(status);
+ debug(DEBUG_EVENT, "event: EXIT: pid=%d, status=%d", pid, event.e_un.ret_val);
+ return &event;
+ }
+ if (WIFSIGNALED(status)) {
+ event.type = EVENT_EXIT_SIGNAL;
+ event.e_un.signum = WTERMSIG(status);
+ debug(DEBUG_EVENT, "event: EXIT_SIGNAL: pid=%d, signum=%d", pid, event.e_un.signum);
+ return &event;
+ }
+ if (!WIFSTOPPED(status)) {
+ /* should never happen */
+ event.type = EVENT_NONE;
+ debug(DEBUG_EVENT, "event: NONE: pid=%d (wait error?)", pid);
+ return &event;
+ }
+
+ stop_signal = WSTOPSIG(status);
+
+ /* On some targets, breakpoints are signalled not using
+ SIGTRAP, but also with SIGILL, SIGSEGV or SIGEMT. Check
+ for these. (TODO: is this true?) */
+ if (stop_signal == SIGSEGV
+ || stop_signal == SIGILL
+#ifdef SIGEMT
+ || stop_signal == SIGEMT
+#endif
+ ) {
+ if (!event.proc->instruction_pointer) {
+ event.proc->instruction_pointer =
+ get_instruction_pointer(event.proc);
+ }
+
+ if (address2bpstruct(event.proc, event.proc->instruction_pointer))
+ stop_signal = SIGTRAP;
+ }
+
+ if (stop_signal != (SIGTRAP | event.proc->tracesysgood)
+ && stop_signal != SIGTRAP) {
+ event.type = EVENT_SIGNAL;
+ event.e_un.signum = stop_signal;
+ debug(DEBUG_EVENT, "event: SIGNAL: pid=%d, signum=%d", pid, stop_signal);
+ return &event;
+ }
+
+ /* last case [by exhaustion] */
+ event.type = EVENT_BREAKPOINT;
+
+ if (!event.proc->instruction_pointer) {
+ event.proc->instruction_pointer =
+ get_instruction_pointer(event.proc);
+ }
+ event.e_un.brk_addr =
+ event.proc->instruction_pointer - DECR_PC_AFTER_BREAK;
+ debug(DEBUG_EVENT, "event: BREAKPOINT: pid=%d, addr=%p", pid, event.e_un.brk_addr);
+ return &event;
+}
diff --git a/sysdeps/linux-gnu/i386/Makefile b/sysdeps/linux-gnu/i386/Makefile
new file mode 100644
index 0000000..60d7531
--- /dev/null
+++ b/sysdeps/linux-gnu/i386/Makefile
@@ -0,0 +1,10 @@
+OBJ = trace.o regs.o plt.o
+
+all: arch.o
+
+arch.o: $(OBJ)
+ $(CC) -nostdlib -r -o arch.o $(OBJ)
+
+clean:
+ $(RM) $(OBJ) arch.o
+
diff --git a/sysdeps/linux-gnu/i386/arch.h b/sysdeps/linux-gnu/i386/arch.h
new file mode 100644
index 0000000..dc7383f
--- /dev/null
+++ b/sysdeps/linux-gnu/i386/arch.h
@@ -0,0 +1,6 @@
+#define BREAKPOINT_VALUE {0xcc}
+#define BREAKPOINT_LENGTH 1
+#define DECR_PC_AFTER_BREAK 1
+
+#define LT_ELFCLASS ELFCLASS32
+#define LT_ELF_MACHINE EM_386
diff --git a/sysdeps/linux-gnu/i386/plt.c b/sysdeps/linux-gnu/i386/plt.c
new file mode 100644
index 0000000..b53ff44
--- /dev/null
+++ b/sysdeps/linux-gnu/i386/plt.c
@@ -0,0 +1,12 @@
+#include <gelf.h>
+#include "common.h"
+
+GElf_Addr
+arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) {
+ return lte->plt_addr + (ndx + 1) * 16;
+}
+
+void *
+sym2addr(Process *proc, struct library_symbol *sym) {
+ return sym->enter_addr;
+}
diff --git a/sysdeps/linux-gnu/i386/ptrace.h b/sysdeps/linux-gnu/i386/ptrace.h
new file mode 100644
index 0000000..c3cbcb6
--- /dev/null
+++ b/sysdeps/linux-gnu/i386/ptrace.h
@@ -0,0 +1 @@
+#include <sys/ptrace.h>
diff --git a/sysdeps/linux-gnu/i386/regs.c b/sysdeps/linux-gnu/i386/regs.c
new file mode 100644
index 0000000..6777f17
--- /dev/null
+++ b/sysdeps/linux-gnu/i386/regs.c
@@ -0,0 +1,40 @@
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+
+#include "common.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(Process *proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * EIP, 0);
+}
+
+void
+set_instruction_pointer(Process *proc, void *addr) {
+ ptrace(PTRACE_POKEUSER, proc->pid, 4 * EIP, (long)addr);
+}
+
+void *
+get_stack_pointer(Process *proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * UESP, 0);
+}
+
+void *
+get_return_addr(Process *proc, void *stack_pointer) {
+ return (void *)ptrace(PTRACE_PEEKTEXT, proc->pid, stack_pointer, 0);
+}
+
+void
+set_return_addr(Process *proc, void *addr) {
+ ptrace(PTRACE_POKETEXT, proc->pid, proc->stack_pointer, (long)addr);
+}
diff --git a/sysdeps/linux-gnu/i386/signalent.h b/sysdeps/linux-gnu/i386/signalent.h
new file mode 100644
index 0000000..5395f82
--- /dev/null
+++ b/sysdeps/linux-gnu/i386/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/i386/syscallent.h b/sysdeps/linux-gnu/i386/syscallent.h
new file mode 100644
index 0000000..8f4c887
--- /dev/null
+++ b/sysdeps/linux-gnu/i386/syscallent.h
@@ -0,0 +1,317 @@
+ "restart_syscall", /* 0 */
+ "exit", /* 1 */
+ "fork", /* 2 */
+ "read", /* 3 */
+ "write", /* 4 */
+ "open", /* 5 */
+ "close", /* 6 */
+ "waitpid", /* 7 */
+ "creat", /* 8 */
+ "link", /* 9 */
+ "unlink", /* 10 */
+ "execve", /* 11 */
+ "chdir", /* 12 */
+ "time", /* 13 */
+ "mknod", /* 14 */
+ "chmod", /* 15 */
+ "lchown", /* 16 */
+ "break", /* 17 */
+ "oldstat", /* 18 */
+ "lseek", /* 19 */
+ "getpid", /* 20 */
+ "mount", /* 21 */
+ "umount", /* 22 */
+ "setuid", /* 23 */
+ "getuid", /* 24 */
+ "stime", /* 25 */
+ "ptrace", /* 26 */
+ "alarm", /* 27 */
+ "oldfstat", /* 28 */
+ "pause", /* 29 */
+ "utime", /* 30 */
+ "stty", /* 31 */
+ "gtty", /* 32 */
+ "access", /* 33 */
+ "nice", /* 34 */
+ "ftime", /* 35 */
+ "sync", /* 36 */
+ "kill", /* 37 */
+ "rename", /* 38 */
+ "mkdir", /* 39 */
+ "rmdir", /* 40 */
+ "dup", /* 41 */
+ "pipe", /* 42 */
+ "times", /* 43 */
+ "prof", /* 44 */
+ "brk", /* 45 */
+ "setgid", /* 46 */
+ "getgid", /* 47 */
+ "signal", /* 48 */
+ "geteuid", /* 49 */
+ "getegid", /* 50 */
+ "acct", /* 51 */
+ "umount2", /* 52 */
+ "lock", /* 53 */
+ "ioctl", /* 54 */
+ "fcntl", /* 55 */
+ "mpx", /* 56 */
+ "setpgid", /* 57 */
+ "ulimit", /* 58 */
+ "oldolduname", /* 59 */
+ "umask", /* 60 */
+ "chroot", /* 61 */
+ "ustat", /* 62 */
+ "dup2", /* 63 */
+ "getppid", /* 64 */
+ "getpgrp", /* 65 */
+ "setsid", /* 66 */
+ "sigaction", /* 67 */
+ "sgetmask", /* 68 */
+ "ssetmask", /* 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 */
+ "select", /* 82 */
+ "symlink", /* 83 */
+ "oldlstat", /* 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 */
+ "profil", /* 98 */
+ "statfs", /* 99 */
+ "fstatfs", /* 100 */
+ "ioperm", /* 101 */
+ "socketcall", /* 102 */
+ "syslog", /* 103 */
+ "setitimer", /* 104 */
+ "getitimer", /* 105 */
+ "stat", /* 106 */
+ "lstat", /* 107 */
+ "fstat", /* 108 */
+ "olduname", /* 109 */
+ "iopl", /* 110 */
+ "vhangup", /* 111 */
+ "idle", /* 112 */
+ "vm86old", /* 113 */
+ "wait4", /* 114 */
+ "swapoff", /* 115 */
+ "sysinfo", /* 116 */
+ "ipc", /* 117 */
+ "fsync", /* 118 */
+ "sigreturn", /* 119 */
+ "clone", /* 120 */
+ "setdomainname", /* 121 */
+ "uname", /* 122 */
+ "modify_ldt", /* 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 */
+ "vm86", /* 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 */
+ "pread64", /* 180 */
+ "pwrite64", /* 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 */
+ "madvise1", /* 219 */
+ "getdents64", /* 220 */
+ "fcntl64", /* 221 */
+ "222", /* 222 */
+ "223", /* 223 */
+ "gettid", /* 224 */
+ "readahead", /* 225 */
+ "setxattr", /* 226 */
+ "lsetxattr", /* 227 */
+ "fsetxattr", /* 228 */
+ "getxattr", /* 229 */
+ "lgetxattr", /* 230 */
+ "fgetxattr", /* 231 */
+ "listxattr", /* 232 */
+ "llistxattr", /* 233 */
+ "flistxattr", /* 234 */
+ "removexattr", /* 235 */
+ "lremovexattr", /* 236 */
+ "fremovexattr", /* 237 */
+ "tkill", /* 238 */
+ "sendfile64", /* 239 */
+ "futex", /* 240 */
+ "sched_setaffinity", /* 241 */
+ "sched_getaffinity", /* 242 */
+ "set_thread_area", /* 243 */
+ "get_thread_area", /* 244 */
+ "io_setup", /* 245 */
+ "io_destroy", /* 246 */
+ "io_getevents", /* 247 */
+ "io_submit", /* 248 */
+ "io_cancel", /* 249 */
+ "fadvise64", /* 250 */
+ "251", /* 251 */
+ "exit_group", /* 252 */
+ "lookup_dcookie", /* 253 */
+ "epoll_create", /* 254 */
+ "epoll_ctl", /* 255 */
+ "epoll_wait", /* 256 */
+ "remap_file_pages", /* 257 */
+ "set_tid_address", /* 258 */
+ "timer_create", /* 259 */
+ "260", /* 260 */
+ "261", /* 261 */
+ "262", /* 262 */
+ "263", /* 263 */
+ "264", /* 264 */
+ "265", /* 265 */
+ "266", /* 266 */
+ "267", /* 267 */
+ "statfs64", /* 268 */
+ "fstatfs64", /* 269 */
+ "tgkill", /* 270 */
+ "utimes", /* 271 */
+ "fadvise64_64", /* 272 */
+ "vserver", /* 273 */
+ "mbind", /* 274 */
+ "get_mempolicy", /* 275 */
+ "set_mempolicy", /* 276 */
+ "mq_open", /* 277 */
+ "278", /* 278 */
+ "279", /* 279 */
+ "280", /* 280 */
+ "281", /* 281 */
+ "282", /* 282 */
+ "kexec_load", /* 283 */
+ "waitid", /* 284 */
+ "285", /* 285 */
+ "add_key", /* 286 */
+ "request_key", /* 287 */
+ "keyctl", /* 288 */
+ "ioprio_set", /* 289 */
+ "ioprio_get", /* 290 */
+ "inotify_init", /* 291 */
+ "inotify_add_watch", /* 292 */
+ "inotify_rm_watch", /* 293 */
+ "migrate_pages", /* 294 */
+ "openat", /* 295 */
+ "mkdirat", /* 296 */
+ "mknodat", /* 297 */
+ "fchownat", /* 298 */
+ "futimesat", /* 299 */
+ "fstatat64", /* 300 */
+ "unlinkat", /* 301 */
+ "renameat", /* 302 */
+ "linkat", /* 303 */
+ "symlinkat", /* 304 */
+ "readlinkat", /* 305 */
+ "fchmodat", /* 306 */
+ "faccessat", /* 307 */
+ "pselect6", /* 308 */
+ "ppoll", /* 309 */
+ "unshare", /* 310 */
+ "set_robust_list", /* 311 */
+ "get_robust_list", /* 312 */
+ "splice", /* 313 */
+ "sync_file_range", /* 314 */
+ "tee", /* 315 */
+ "vmsplice", /* 316 */
diff --git a/sysdeps/linux-gnu/i386/trace.c b/sysdeps/linux-gnu/i386/trace.c
new file mode 100644
index 0000000..76f1105
--- /dev/null
+++ b/sysdeps/linux-gnu/i386/trace.c
@@ -0,0 +1,85 @@
+#include "config.h"
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+
+#include "common.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)) {
+ *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 4 * ORIG_EAX, 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) {
+ 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, 4 * EAX, 0);
+ }
+
+ if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
+ return ptrace(PTRACE_PEEKTEXT, proc->pid,
+ proc->stack_pointer + 4 * (arg_num + 1), 0);
+ } else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) {
+#if 0
+ switch (arg_num) {
+ case 0:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * EBX, 0);
+ case 1:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * ECX, 0);
+ case 2:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * EDX, 0);
+ case 3:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * ESI, 0);
+ case 4:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * EDI, 0);
+ default:
+ fprintf(stderr,
+ "gimme_arg called with wrong arguments\n");
+ exit(2);
+ }
+#else
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num, 0);
+#endif
+ } else {
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(1);
+ }
+
+ return 0;
+}
+
+void
+save_register_args(enum tof type, Process *proc) {
+}
diff --git a/sysdeps/linux-gnu/ia64/Makefile b/sysdeps/linux-gnu/ia64/Makefile
new file mode 100644
index 0000000..4f0ef63
--- /dev/null
+++ b/sysdeps/linux-gnu/ia64/Makefile
@@ -0,0 +1,10 @@
+OBJ = trace.o regs.o plt.o breakpoint.o
+
+all: arch.o
+
+arch.o: $(OBJ)
+ $(LD) -r -o arch.o $(OBJ)
+
+clean:
+ $(RM) $(OBJ) arch.o
+
diff --git a/sysdeps/linux-gnu/ia64/arch.h b/sysdeps/linux-gnu/ia64/arch.h
new file mode 100644
index 0000000..673047c
--- /dev/null
+++ b/sysdeps/linux-gnu/ia64/arch.h
@@ -0,0 +1,13 @@
+#define ARCH_HAVE_DISABLE_BREAKPOINT 1
+#define ARCH_HAVE_ENABLE_BREAKPOINT 1
+
+#define BREAKPOINT_LENGTH 16
+#define BREAKPOINT_VALUE {0}
+#define DECR_PC_AFTER_BREAK 0
+
+#define LT_ELFCLASS ELFCLASS64
+#define LT_ELF_MACHINE EM_IA_64
+
+// ia64 actually does use .opd, but we don't need to do the
+// translation manually.
+#undef ARCH_SUPPORTS_OPD
diff --git a/sysdeps/linux-gnu/ia64/breakpoint.c b/sysdeps/linux-gnu/ia64/breakpoint.c
new file mode 100644
index 0000000..4f09173
--- /dev/null
+++ b/sysdeps/linux-gnu/ia64/breakpoint.c
@@ -0,0 +1,212 @@
+/* IA64 breakpoint support. Much of this clagged from gdb
+ * -Ian Wienand <ianw@gelato.unsw.edu.au> 10/3/2005
+ */
+
+#include "config.h"
+
+#include <sys/ptrace.h>
+#include <string.h>
+#include "arch.h"
+#include "options.h"
+#include "output.h"
+#include "debug.h"
+
+static long long
+extract_bit_field(char *bundle, int from, int len) {
+ long long result = 0LL;
+ int to = from + len;
+ int from_byte = from / 8;
+ int to_byte = to / 8;
+ unsigned char *b = (unsigned char *)bundle;
+ unsigned char c;
+ int lshift;
+ int i;
+
+ c = b[from_byte];
+ if (from_byte == to_byte)
+ c = ((unsigned char)(c << (8 - to % 8))) >> (8 - to % 8);
+ result = c >> (from % 8);
+ lshift = 8 - (from % 8);
+
+ for (i = from_byte + 1; i < to_byte; i++) {
+ result |= ((long long)b[i]) << lshift;
+ lshift += 8;
+ }
+
+ if (from_byte < to_byte && (to % 8 != 0)) {
+ c = b[to_byte];
+ c = ((unsigned char)(c << (8 - to % 8))) >> (8 - to % 8);
+ result |= ((long long)c) << lshift;
+ }
+
+ return result;
+}
+
+/* Replace the specified bits in an instruction bundle */
+static void
+replace_bit_field(char *bundle, long long val, int from, int len) {
+ int to = from + len;
+ int from_byte = from / 8;
+ int to_byte = to / 8;
+ unsigned char *b = (unsigned char *)bundle;
+ unsigned char c;
+
+ if (from_byte == to_byte) {
+ unsigned char left, right;
+ c = b[from_byte];
+ left = (c >> (to % 8)) << (to % 8);
+ right =
+ ((unsigned char)(c << (8 - from % 8))) >> (8 - from % 8);
+ c = (unsigned char)(val & 0xff);
+ c = (unsigned char)(c << (from % 8 + 8 - to % 8)) >> (8 -
+ to % 8);
+ c |= right | left;
+ b[from_byte] = c;
+ } else {
+ int i;
+ c = b[from_byte];
+ c = ((unsigned char)(c << (8 - from % 8))) >> (8 - from % 8);
+ c = c | (val << (from % 8));
+ b[from_byte] = c;
+ val >>= 8 - from % 8;
+
+ for (i = from_byte + 1; i < to_byte; i++) {
+ c = val & 0xff;
+ val >>= 8;
+ b[i] = c;
+ }
+
+ if (to % 8 != 0) {
+ unsigned char cv = (unsigned char)val;
+ c = b[to_byte];
+ c = c >> (to % 8) << (to % 8);
+ c |= ((unsigned char)(cv << (8 - to % 8))) >> (8 -
+ to % 8);
+ b[to_byte] = c;
+ }
+ }
+}
+
+/* Return the contents of slot N (for N = 0, 1, or 2) in
+ and instruction bundle */
+static long long
+slotN_contents(char *bundle, int slotnum) {
+ return extract_bit_field(bundle, 5 + 41 * slotnum, 41);
+}
+
+/* Store an instruction in an instruction bundle */
+
+static void
+replace_slotN_contents(char *bundle, long long instr, int slotnum) {
+ replace_bit_field(bundle, instr, 5 + 41 * slotnum, 41);
+}
+
+typedef enum instruction_type {
+ A, /* Integer ALU ; I-unit or M-unit */
+ I, /* Non-ALU integer; I-unit */
+ M, /* Memory ; M-unit */
+ F, /* Floating-point ; F-unit */
+ B, /* Branch ; B-unit */
+ L, /* Extended (L+X) ; I-unit */
+ X, /* Extended (L+X) ; I-unit */
+ undefined /* undefined or reserved */
+} instruction_type;
+
+static enum instruction_type template_encoding_table[32][3] = {
+ {M, I, I}, /* 00 */
+ {M, I, I}, /* 01 */
+ {M, I, I}, /* 02 */
+ {M, I, I}, /* 03 */
+ {M, L, X}, /* 04 */
+ {M, L, X}, /* 05 */
+ {undefined, undefined, undefined}, /* 06 */
+ {undefined, undefined, undefined}, /* 07 */
+ {M, M, I}, /* 08 */
+ {M, M, I}, /* 09 */
+ {M, M, I}, /* 0A */
+ {M, M, I}, /* 0B */
+ {M, F, I}, /* 0C */
+ {M, F, I}, /* 0D */
+ {M, M, F}, /* 0E */
+ {M, M, F}, /* 0F */
+ {M, I, B}, /* 10 */
+ {M, I, B}, /* 11 */
+ {M, B, B}, /* 12 */
+ {M, B, B}, /* 13 */
+ {undefined, undefined, undefined}, /* 14 */
+ {undefined, undefined, undefined}, /* 15 */
+ {B, B, B}, /* 16 */
+ {B, B, B}, /* 17 */
+ {M, M, B}, /* 18 */
+ {M, M, B}, /* 19 */
+ {undefined, undefined, undefined}, /* 1A */
+ {undefined, undefined, undefined}, /* 1B */
+ {M, F, B}, /* 1C */
+ {M, F, B}, /* 1D */
+ {undefined, undefined, undefined}, /* 1E */
+ {undefined, undefined, undefined}, /* 1F */
+};
+
+union bundle_t {
+ char cbundle[16];
+ unsigned long ubundle[2];
+};
+
+void
+arch_enable_breakpoint(pid_t pid, Breakpoint *sbp) {
+
+ unsigned long addr = (unsigned long)sbp->addr;
+ union bundle_t bundle;
+ int slotnum = (int)(addr & 0x0f) & 0x3;
+ long long instr;
+ int template;
+
+ debug(1, "Enable Breakpoint at %p)", sbp->addr);
+
+ if (slotnum > 2)
+ printf
+ ("Can't insert breakpoint for slot numbers greater than 2.");
+
+ addr &= ~0x0f;
+ bundle.ubundle[0] = ptrace(PTRACE_PEEKTEXT, pid, addr, 0);
+ bundle.ubundle[1] = ptrace(PTRACE_PEEKTEXT, pid, addr + 8, 0);
+
+ /* Check for L type instruction in 2nd slot, if present then
+ bump up the slot number to the 3rd slot */
+ template = extract_bit_field(bundle.cbundle, 0, 5);
+ if (slotnum == 1 && template_encoding_table[template][1] == L) {
+ slotnum = 2;
+ }
+
+ instr = slotN_contents(bundle.cbundle, slotnum);
+
+ memcpy(sbp->orig_value, &instr, sizeof(instr));
+
+ replace_slotN_contents(bundle.cbundle, 0x00002000040LL, slotnum);
+
+ ptrace(PTRACE_POKETEXT, pid, addr, bundle.ubundle[0]);
+ ptrace(PTRACE_POKETEXT, pid, addr + 8, bundle.ubundle[1]);
+
+}
+
+void
+arch_disable_breakpoint(pid_t pid, const Breakpoint *sbp) {
+
+ unsigned long addr = (unsigned long)sbp->addr;
+ int slotnum = (int)(addr & 0x0f) & 0x3;
+ union bundle_t bundle;
+ unsigned long instr;
+
+ debug(1, "Disable Breakpoint at %p", sbp->addr);
+
+ addr &= ~0x0f;
+
+ bundle.ubundle[0] = ptrace(PTRACE_PEEKTEXT, pid, addr, 0);
+ bundle.ubundle[1] = ptrace(PTRACE_PEEKTEXT, pid, addr + 8, 0);
+
+ memcpy(&instr, sbp->orig_value, sizeof(instr));
+
+ replace_slotN_contents(bundle.cbundle, instr, slotnum);
+ ptrace(PTRACE_POKETEXT, pid, addr, bundle.ubundle[0]);
+ ptrace(PTRACE_POKETEXT, pid, addr + 8, bundle.ubundle[1]);
+}
diff --git a/sysdeps/linux-gnu/ia64/plt.c b/sysdeps/linux-gnu/ia64/plt.c
new file mode 100644
index 0000000..7fd451b
--- /dev/null
+++ b/sysdeps/linux-gnu/ia64/plt.c
@@ -0,0 +1,46 @@
+#include <gelf.h>
+#include "common.h"
+
+/* A bundle is 128 bits */
+#define BUNDLE_SIZE 16
+
+/*
+
+ The PLT has
+
+ ] 3 bundles as a header
+
+ ] The special reserved entry
+
+ ] Following that, each PLT entry has it's initial code that the GOT entry
+ points to. Each PLT entry has one bundle allocated.
+
+ ] Following that, each PLT entry has two bundles of actual PLT code,
+ i.e. load up the address from the GOT and jump to it. This is the
+ point we want to insert the breakpoint, as this will be captured
+ every time we jump to the PLT entry in the code.
+
+*/
+
+GElf_Addr
+arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) {
+ /* Find number of entires by removing header and special
+ * entry, dividing total size by three, since each PLT entry
+ * will have 3 bundles (1 for inital entry and two for the PLT
+ * code). */
+ int entries = (lte->plt_size - 4 * BUNDLE_SIZE) / (3 * BUNDLE_SIZE);
+
+ /* Now the point we want to break on is the PLT entry after
+ * all the header stuff */
+ unsigned long addr =
+ lte->plt_addr + (4 * BUNDLE_SIZE) + (BUNDLE_SIZE * entries) +
+ (2 * ndx * BUNDLE_SIZE);
+ debug(3, "Found PLT %d entry at %lx\n", ndx, addr);
+
+ return addr;
+}
+
+void *
+sym2addr(Process *proc, struct library_symbol *sym) {
+ return sym->enter_addr;
+}
diff --git a/sysdeps/linux-gnu/ia64/ptrace.h b/sysdeps/linux-gnu/ia64/ptrace.h
new file mode 100644
index 0000000..c3cbcb6
--- /dev/null
+++ b/sysdeps/linux-gnu/ia64/ptrace.h
@@ -0,0 +1 @@
+#include <sys/ptrace.h>
diff --git a/sysdeps/linux-gnu/ia64/regs.c b/sysdeps/linux-gnu/ia64/regs.c
new file mode 100644
index 0000000..d161d34
--- /dev/null
+++ b/sysdeps/linux-gnu/ia64/regs.c
@@ -0,0 +1,51 @@
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+
+#include <asm/ptrace_offsets.h>
+#include <asm/rse.h>
+
+#include <stddef.h>
+#include "debug.h"
+#include "common.h"
+
+void *
+get_instruction_pointer(Process *proc) {
+ unsigned long ip = ptrace(PTRACE_PEEKUSER, proc->pid, PT_CR_IIP, 0);
+ unsigned long slot =
+ (ptrace(PTRACE_PEEKUSER, proc->pid, PT_CR_IPSR, 0) >> 41) & 3;
+
+ return (void *)(ip | slot);
+}
+
+void
+set_instruction_pointer(Process *proc, void *addr) {
+
+ unsigned long newip = (unsigned long)addr;
+ unsigned long slot = (unsigned long)addr & 0xf;
+ unsigned long psr = ptrace(PTRACE_PEEKUSER, proc->pid, PT_CR_IPSR, 0);
+
+ psr &= ~(3UL << 41);
+ psr |= (slot & 0x3) << 41;
+
+ newip &= ~0xfUL;
+
+ ptrace(PTRACE_POKEUSER, proc->pid, PT_CR_IIP, (long)newip);
+ ptrace(PTRACE_POKEUSER, proc->pid, PT_CR_IPSR, psr);
+}
+
+void *
+get_stack_pointer(Process *proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, PT_R12, 0);
+}
+
+void *
+get_return_addr(Process *proc, void *stack_pointer) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, PT_B0, 0);
+}
+
+void
+set_return_addr(Process *proc, void *addr) {
+ ptrace(PTRACE_POKEUSER, proc->pid, PT_B0, addr);
+}
diff --git a/sysdeps/linux-gnu/ia64/signalent.h b/sysdeps/linux-gnu/ia64/signalent.h
new file mode 100644
index 0000000..5395f82
--- /dev/null
+++ b/sysdeps/linux-gnu/ia64/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/ia64/syscallent.h b/sysdeps/linux-gnu/ia64/syscallent.h
new file mode 100644
index 0000000..9bb4fb8
--- /dev/null
+++ b/sysdeps/linux-gnu/ia64/syscallent.h
@@ -0,0 +1,1303 @@
+ "0", /* 0 */
+ "1", /* 1 */
+ "2", /* 2 */
+ "3", /* 3 */
+ "4", /* 4 */
+ "5", /* 5 */
+ "6", /* 6 */
+ "7", /* 7 */
+ "8", /* 8 */
+ "9", /* 9 */
+ "10", /* 10 */
+ "11", /* 11 */
+ "12", /* 12 */
+ "13", /* 13 */
+ "14", /* 14 */
+ "15", /* 15 */
+ "16", /* 16 */
+ "17", /* 17 */
+ "18", /* 18 */
+ "19", /* 19 */
+ "20", /* 20 */
+ "21", /* 21 */
+ "22", /* 22 */
+ "23", /* 23 */
+ "24", /* 24 */
+ "25", /* 25 */
+ "26", /* 26 */
+ "27", /* 27 */
+ "28", /* 28 */
+ "29", /* 29 */
+ "30", /* 30 */
+ "31", /* 31 */
+ "32", /* 32 */
+ "33", /* 33 */
+ "34", /* 34 */
+ "35", /* 35 */
+ "36", /* 36 */
+ "37", /* 37 */
+ "38", /* 38 */
+ "39", /* 39 */
+ "40", /* 40 */
+ "41", /* 41 */
+ "42", /* 42 */
+ "43", /* 43 */
+ "44", /* 44 */
+ "45", /* 45 */
+ "46", /* 46 */
+ "47", /* 47 */
+ "48", /* 48 */
+ "49", /* 49 */
+ "50", /* 50 */
+ "51", /* 51 */
+ "52", /* 52 */
+ "53", /* 53 */
+ "54", /* 54 */
+ "55", /* 55 */
+ "56", /* 56 */
+ "57", /* 57 */
+ "58", /* 58 */
+ "59", /* 59 */
+ "60", /* 60 */
+ "61", /* 61 */
+ "62", /* 62 */
+ "63", /* 63 */
+ "64", /* 64 */
+ "65", /* 65 */
+ "66", /* 66 */
+ "67", /* 67 */
+ "68", /* 68 */
+ "69", /* 69 */
+ "70", /* 70 */
+ "71", /* 71 */
+ "72", /* 72 */
+ "73", /* 73 */
+ "74", /* 74 */
+ "75", /* 75 */
+ "76", /* 76 */
+ "77", /* 77 */
+ "78", /* 78 */
+ "79", /* 79 */
+ "80", /* 80 */
+ "81", /* 81 */
+ "82", /* 82 */
+ "83", /* 83 */
+ "84", /* 84 */
+ "85", /* 85 */
+ "86", /* 86 */
+ "87", /* 87 */
+ "88", /* 88 */
+ "89", /* 89 */
+ "90", /* 90 */
+ "91", /* 91 */
+ "92", /* 92 */
+ "93", /* 93 */
+ "94", /* 94 */
+ "95", /* 95 */
+ "96", /* 96 */
+ "97", /* 97 */
+ "98", /* 98 */
+ "99", /* 99 */
+ "100", /* 100 */
+ "101", /* 101 */
+ "102", /* 102 */
+ "103", /* 103 */
+ "104", /* 104 */
+ "105", /* 105 */
+ "106", /* 106 */
+ "107", /* 107 */
+ "108", /* 108 */
+ "109", /* 109 */
+ "110", /* 110 */
+ "111", /* 111 */
+ "112", /* 112 */
+ "113", /* 113 */
+ "114", /* 114 */
+ "115", /* 115 */
+ "116", /* 116 */
+ "117", /* 117 */
+ "118", /* 118 */
+ "119", /* 119 */
+ "120", /* 120 */
+ "121", /* 121 */
+ "122", /* 122 */
+ "123", /* 123 */
+ "124", /* 124 */
+ "125", /* 125 */
+ "126", /* 126 */
+ "127", /* 127 */
+ "128", /* 128 */
+ "129", /* 129 */
+ "130", /* 130 */
+ "131", /* 131 */
+ "132", /* 132 */
+ "133", /* 133 */
+ "134", /* 134 */
+ "135", /* 135 */
+ "136", /* 136 */
+ "137", /* 137 */
+ "138", /* 138 */
+ "139", /* 139 */
+ "140", /* 140 */
+ "141", /* 141 */
+ "142", /* 142 */
+ "143", /* 143 */
+ "144", /* 144 */
+ "145", /* 145 */
+ "146", /* 146 */
+ "147", /* 147 */
+ "148", /* 148 */
+ "149", /* 149 */
+ "150", /* 150 */
+ "151", /* 151 */
+ "152", /* 152 */
+ "153", /* 153 */
+ "154", /* 154 */
+ "155", /* 155 */
+ "156", /* 156 */
+ "157", /* 157 */
+ "158", /* 158 */
+ "159", /* 159 */
+ "160", /* 160 */
+ "161", /* 161 */
+ "162", /* 162 */
+ "163", /* 163 */
+ "164", /* 164 */
+ "165", /* 165 */
+ "166", /* 166 */
+ "167", /* 167 */
+ "168", /* 168 */
+ "169", /* 169 */
+ "170", /* 170 */
+ "171", /* 171 */
+ "172", /* 172 */
+ "173", /* 173 */
+ "174", /* 174 */
+ "175", /* 175 */
+ "176", /* 176 */
+ "177", /* 177 */
+ "178", /* 178 */
+ "179", /* 179 */
+ "180", /* 180 */
+ "181", /* 181 */
+ "182", /* 182 */
+ "183", /* 183 */
+ "184", /* 184 */
+ "185", /* 185 */
+ "186", /* 186 */
+ "187", /* 187 */
+ "188", /* 188 */
+ "189", /* 189 */
+ "190", /* 190 */
+ "191", /* 191 */
+ "192", /* 192 */
+ "193", /* 193 */
+ "194", /* 194 */
+ "195", /* 195 */
+ "196", /* 196 */
+ "197", /* 197 */
+ "198", /* 198 */
+ "199", /* 199 */
+ "200", /* 200 */
+ "201", /* 201 */
+ "202", /* 202 */
+ "203", /* 203 */
+ "204", /* 204 */
+ "205", /* 205 */
+ "206", /* 206 */
+ "207", /* 207 */
+ "208", /* 208 */
+ "209", /* 209 */
+ "210", /* 210 */
+ "211", /* 211 */
+ "212", /* 212 */
+ "213", /* 213 */
+ "214", /* 214 */
+ "215", /* 215 */
+ "216", /* 216 */
+ "217", /* 217 */
+ "218", /* 218 */
+ "219", /* 219 */
+ "220", /* 220 */
+ "221", /* 221 */
+ "222", /* 222 */
+ "223", /* 223 */
+ "224", /* 224 */
+ "225", /* 225 */
+ "226", /* 226 */
+ "227", /* 227 */
+ "228", /* 228 */
+ "229", /* 229 */
+ "230", /* 230 */
+ "231", /* 231 */
+ "232", /* 232 */
+ "233", /* 233 */
+ "234", /* 234 */
+ "235", /* 235 */
+ "236", /* 236 */
+ "237", /* 237 */
+ "238", /* 238 */
+ "239", /* 239 */
+ "240", /* 240 */
+ "241", /* 241 */
+ "242", /* 242 */
+ "243", /* 243 */
+ "244", /* 244 */
+ "245", /* 245 */
+ "246", /* 246 */
+ "247", /* 247 */
+ "248", /* 248 */
+ "249", /* 249 */
+ "250", /* 250 */
+ "251", /* 251 */
+ "252", /* 252 */
+ "253", /* 253 */
+ "254", /* 254 */
+ "255", /* 255 */
+ "256", /* 256 */
+ "257", /* 257 */
+ "258", /* 258 */
+ "259", /* 259 */
+ "260", /* 260 */
+ "261", /* 261 */
+ "262", /* 262 */
+ "263", /* 263 */
+ "264", /* 264 */
+ "265", /* 265 */
+ "266", /* 266 */
+ "267", /* 267 */
+ "268", /* 268 */
+ "269", /* 269 */
+ "270", /* 270 */
+ "271", /* 271 */
+ "272", /* 272 */
+ "273", /* 273 */
+ "274", /* 274 */
+ "275", /* 275 */
+ "276", /* 276 */
+ "277", /* 277 */
+ "278", /* 278 */
+ "279", /* 279 */
+ "280", /* 280 */
+ "281", /* 281 */
+ "282", /* 282 */
+ "283", /* 283 */
+ "284", /* 284 */
+ "285", /* 285 */
+ "286", /* 286 */
+ "287", /* 287 */
+ "288", /* 288 */
+ "289", /* 289 */
+ "290", /* 290 */
+ "291", /* 291 */
+ "292", /* 292 */
+ "293", /* 293 */
+ "294", /* 294 */
+ "295", /* 295 */
+ "296", /* 296 */
+ "297", /* 297 */
+ "298", /* 298 */
+ "299", /* 299 */
+ "300", /* 300 */
+ "301", /* 301 */
+ "302", /* 302 */
+ "303", /* 303 */
+ "304", /* 304 */
+ "305", /* 305 */
+ "306", /* 306 */
+ "307", /* 307 */
+ "308", /* 308 */
+ "309", /* 309 */
+ "310", /* 310 */
+ "311", /* 311 */
+ "312", /* 312 */
+ "313", /* 313 */
+ "314", /* 314 */
+ "315", /* 315 */
+ "316", /* 316 */
+ "317", /* 317 */
+ "318", /* 318 */
+ "319", /* 319 */
+ "320", /* 320 */
+ "321", /* 321 */
+ "322", /* 322 */
+ "323", /* 323 */
+ "324", /* 324 */
+ "325", /* 325 */
+ "326", /* 326 */
+ "327", /* 327 */
+ "328", /* 328 */
+ "329", /* 329 */
+ "330", /* 330 */
+ "331", /* 331 */
+ "332", /* 332 */
+ "333", /* 333 */
+ "334", /* 334 */
+ "335", /* 335 */
+ "336", /* 336 */
+ "337", /* 337 */
+ "338", /* 338 */
+ "339", /* 339 */
+ "340", /* 340 */
+ "341", /* 341 */
+ "342", /* 342 */
+ "343", /* 343 */
+ "344", /* 344 */
+ "345", /* 345 */
+ "346", /* 346 */
+ "347", /* 347 */
+ "348", /* 348 */
+ "349", /* 349 */
+ "350", /* 350 */
+ "351", /* 351 */
+ "352", /* 352 */
+ "353", /* 353 */
+ "354", /* 354 */
+ "355", /* 355 */
+ "356", /* 356 */
+ "357", /* 357 */
+ "358", /* 358 */
+ "359", /* 359 */
+ "360", /* 360 */
+ "361", /* 361 */
+ "362", /* 362 */
+ "363", /* 363 */
+ "364", /* 364 */
+ "365", /* 365 */
+ "366", /* 366 */
+ "367", /* 367 */
+ "368", /* 368 */
+ "369", /* 369 */
+ "370", /* 370 */
+ "371", /* 371 */
+ "372", /* 372 */
+ "373", /* 373 */
+ "374", /* 374 */
+ "375", /* 375 */
+ "376", /* 376 */
+ "377", /* 377 */
+ "378", /* 378 */
+ "379", /* 379 */
+ "380", /* 380 */
+ "381", /* 381 */
+ "382", /* 382 */
+ "383", /* 383 */
+ "384", /* 384 */
+ "385", /* 385 */
+ "386", /* 386 */
+ "387", /* 387 */
+ "388", /* 388 */
+ "389", /* 389 */
+ "390", /* 390 */
+ "391", /* 391 */
+ "392", /* 392 */
+ "393", /* 393 */
+ "394", /* 394 */
+ "395", /* 395 */
+ "396", /* 396 */
+ "397", /* 397 */
+ "398", /* 398 */
+ "399", /* 399 */
+ "400", /* 400 */
+ "401", /* 401 */
+ "402", /* 402 */
+ "403", /* 403 */
+ "404", /* 404 */
+ "405", /* 405 */
+ "406", /* 406 */
+ "407", /* 407 */
+ "408", /* 408 */
+ "409", /* 409 */
+ "410", /* 410 */
+ "411", /* 411 */
+ "412", /* 412 */
+ "413", /* 413 */
+ "414", /* 414 */
+ "415", /* 415 */
+ "416", /* 416 */
+ "417", /* 417 */
+ "418", /* 418 */
+ "419", /* 419 */
+ "420", /* 420 */
+ "421", /* 421 */
+ "422", /* 422 */
+ "423", /* 423 */
+ "424", /* 424 */
+ "425", /* 425 */
+ "426", /* 426 */
+ "427", /* 427 */
+ "428", /* 428 */
+ "429", /* 429 */
+ "430", /* 430 */
+ "431", /* 431 */
+ "432", /* 432 */
+ "433", /* 433 */
+ "434", /* 434 */
+ "435", /* 435 */
+ "436", /* 436 */
+ "437", /* 437 */
+ "438", /* 438 */
+ "439", /* 439 */
+ "440", /* 440 */
+ "441", /* 441 */
+ "442", /* 442 */
+ "443", /* 443 */
+ "444", /* 444 */
+ "445", /* 445 */
+ "446", /* 446 */
+ "447", /* 447 */
+ "448", /* 448 */
+ "449", /* 449 */
+ "450", /* 450 */
+ "451", /* 451 */
+ "452", /* 452 */
+ "453", /* 453 */
+ "454", /* 454 */
+ "455", /* 455 */
+ "456", /* 456 */
+ "457", /* 457 */
+ "458", /* 458 */
+ "459", /* 459 */
+ "460", /* 460 */
+ "461", /* 461 */
+ "462", /* 462 */
+ "463", /* 463 */
+ "464", /* 464 */
+ "465", /* 465 */
+ "466", /* 466 */
+ "467", /* 467 */
+ "468", /* 468 */
+ "469", /* 469 */
+ "470", /* 470 */
+ "471", /* 471 */
+ "472", /* 472 */
+ "473", /* 473 */
+ "474", /* 474 */
+ "475", /* 475 */
+ "476", /* 476 */
+ "477", /* 477 */
+ "478", /* 478 */
+ "479", /* 479 */
+ "480", /* 480 */
+ "481", /* 481 */
+ "482", /* 482 */
+ "483", /* 483 */
+ "484", /* 484 */
+ "485", /* 485 */
+ "486", /* 486 */
+ "487", /* 487 */
+ "488", /* 488 */
+ "489", /* 489 */
+ "490", /* 490 */
+ "491", /* 491 */
+ "492", /* 492 */
+ "493", /* 493 */
+ "494", /* 494 */
+ "495", /* 495 */
+ "496", /* 496 */
+ "497", /* 497 */
+ "498", /* 498 */
+ "499", /* 499 */
+ "500", /* 500 */
+ "501", /* 501 */
+ "502", /* 502 */
+ "503", /* 503 */
+ "504", /* 504 */
+ "505", /* 505 */
+ "506", /* 506 */
+ "507", /* 507 */
+ "508", /* 508 */
+ "509", /* 509 */
+ "510", /* 510 */
+ "511", /* 511 */
+ "512", /* 512 */
+ "513", /* 513 */
+ "514", /* 514 */
+ "515", /* 515 */
+ "516", /* 516 */
+ "517", /* 517 */
+ "518", /* 518 */
+ "519", /* 519 */
+ "520", /* 520 */
+ "521", /* 521 */
+ "522", /* 522 */
+ "523", /* 523 */
+ "524", /* 524 */
+ "525", /* 525 */
+ "526", /* 526 */
+ "527", /* 527 */
+ "528", /* 528 */
+ "529", /* 529 */
+ "530", /* 530 */
+ "531", /* 531 */
+ "532", /* 532 */
+ "533", /* 533 */
+ "534", /* 534 */
+ "535", /* 535 */
+ "536", /* 536 */
+ "537", /* 537 */
+ "538", /* 538 */
+ "539", /* 539 */
+ "540", /* 540 */
+ "541", /* 541 */
+ "542", /* 542 */
+ "543", /* 543 */
+ "544", /* 544 */
+ "545", /* 545 */
+ "546", /* 546 */
+ "547", /* 547 */
+ "548", /* 548 */
+ "549", /* 549 */
+ "550", /* 550 */
+ "551", /* 551 */
+ "552", /* 552 */
+ "553", /* 553 */
+ "554", /* 554 */
+ "555", /* 555 */
+ "556", /* 556 */
+ "557", /* 557 */
+ "558", /* 558 */
+ "559", /* 559 */
+ "560", /* 560 */
+ "561", /* 561 */
+ "562", /* 562 */
+ "563", /* 563 */
+ "564", /* 564 */
+ "565", /* 565 */
+ "566", /* 566 */
+ "567", /* 567 */
+ "568", /* 568 */
+ "569", /* 569 */
+ "570", /* 570 */
+ "571", /* 571 */
+ "572", /* 572 */
+ "573", /* 573 */
+ "574", /* 574 */
+ "575", /* 575 */
+ "576", /* 576 */
+ "577", /* 577 */
+ "578", /* 578 */
+ "579", /* 579 */
+ "580", /* 580 */
+ "581", /* 581 */
+ "582", /* 582 */
+ "583", /* 583 */
+ "584", /* 584 */
+ "585", /* 585 */
+ "586", /* 586 */
+ "587", /* 587 */
+ "588", /* 588 */
+ "589", /* 589 */
+ "590", /* 590 */
+ "591", /* 591 */
+ "592", /* 592 */
+ "593", /* 593 */
+ "594", /* 594 */
+ "595", /* 595 */
+ "596", /* 596 */
+ "597", /* 597 */
+ "598", /* 598 */
+ "599", /* 599 */
+ "600", /* 600 */
+ "601", /* 601 */
+ "602", /* 602 */
+ "603", /* 603 */
+ "604", /* 604 */
+ "605", /* 605 */
+ "606", /* 606 */
+ "607", /* 607 */
+ "608", /* 608 */
+ "609", /* 609 */
+ "610", /* 610 */
+ "611", /* 611 */
+ "612", /* 612 */
+ "613", /* 613 */
+ "614", /* 614 */
+ "615", /* 615 */
+ "616", /* 616 */
+ "617", /* 617 */
+ "618", /* 618 */
+ "619", /* 619 */
+ "620", /* 620 */
+ "621", /* 621 */
+ "622", /* 622 */
+ "623", /* 623 */
+ "624", /* 624 */
+ "625", /* 625 */
+ "626", /* 626 */
+ "627", /* 627 */
+ "628", /* 628 */
+ "629", /* 629 */
+ "630", /* 630 */
+ "631", /* 631 */
+ "632", /* 632 */
+ "633", /* 633 */
+ "634", /* 634 */
+ "635", /* 635 */
+ "636", /* 636 */
+ "637", /* 637 */
+ "638", /* 638 */
+ "639", /* 639 */
+ "640", /* 640 */
+ "641", /* 641 */
+ "642", /* 642 */
+ "643", /* 643 */
+ "644", /* 644 */
+ "645", /* 645 */
+ "646", /* 646 */
+ "647", /* 647 */
+ "648", /* 648 */
+ "649", /* 649 */
+ "650", /* 650 */
+ "651", /* 651 */
+ "652", /* 652 */
+ "653", /* 653 */
+ "654", /* 654 */
+ "655", /* 655 */
+ "656", /* 656 */
+ "657", /* 657 */
+ "658", /* 658 */
+ "659", /* 659 */
+ "660", /* 660 */
+ "661", /* 661 */
+ "662", /* 662 */
+ "663", /* 663 */
+ "664", /* 664 */
+ "665", /* 665 */
+ "666", /* 666 */
+ "667", /* 667 */
+ "668", /* 668 */
+ "669", /* 669 */
+ "670", /* 670 */
+ "671", /* 671 */
+ "672", /* 672 */
+ "673", /* 673 */
+ "674", /* 674 */
+ "675", /* 675 */
+ "676", /* 676 */
+ "677", /* 677 */
+ "678", /* 678 */
+ "679", /* 679 */
+ "680", /* 680 */
+ "681", /* 681 */
+ "682", /* 682 */
+ "683", /* 683 */
+ "684", /* 684 */
+ "685", /* 685 */
+ "686", /* 686 */
+ "687", /* 687 */
+ "688", /* 688 */
+ "689", /* 689 */
+ "690", /* 690 */
+ "691", /* 691 */
+ "692", /* 692 */
+ "693", /* 693 */
+ "694", /* 694 */
+ "695", /* 695 */
+ "696", /* 696 */
+ "697", /* 697 */
+ "698", /* 698 */
+ "699", /* 699 */
+ "700", /* 700 */
+ "701", /* 701 */
+ "702", /* 702 */
+ "703", /* 703 */
+ "704", /* 704 */
+ "705", /* 705 */
+ "706", /* 706 */
+ "707", /* 707 */
+ "708", /* 708 */
+ "709", /* 709 */
+ "710", /* 710 */
+ "711", /* 711 */
+ "712", /* 712 */
+ "713", /* 713 */
+ "714", /* 714 */
+ "715", /* 715 */
+ "716", /* 716 */
+ "717", /* 717 */
+ "718", /* 718 */
+ "719", /* 719 */
+ "720", /* 720 */
+ "721", /* 721 */
+ "722", /* 722 */
+ "723", /* 723 */
+ "724", /* 724 */
+ "725", /* 725 */
+ "726", /* 726 */
+ "727", /* 727 */
+ "728", /* 728 */
+ "729", /* 729 */
+ "730", /* 730 */
+ "731", /* 731 */
+ "732", /* 732 */
+ "733", /* 733 */
+ "734", /* 734 */
+ "735", /* 735 */
+ "736", /* 736 */
+ "737", /* 737 */
+ "738", /* 738 */
+ "739", /* 739 */
+ "740", /* 740 */
+ "741", /* 741 */
+ "742", /* 742 */
+ "743", /* 743 */
+ "744", /* 744 */
+ "745", /* 745 */
+ "746", /* 746 */
+ "747", /* 747 */
+ "748", /* 748 */
+ "749", /* 749 */
+ "750", /* 750 */
+ "751", /* 751 */
+ "752", /* 752 */
+ "753", /* 753 */
+ "754", /* 754 */
+ "755", /* 755 */
+ "756", /* 756 */
+ "757", /* 757 */
+ "758", /* 758 */
+ "759", /* 759 */
+ "760", /* 760 */
+ "761", /* 761 */
+ "762", /* 762 */
+ "763", /* 763 */
+ "764", /* 764 */
+ "765", /* 765 */
+ "766", /* 766 */
+ "767", /* 767 */
+ "768", /* 768 */
+ "769", /* 769 */
+ "770", /* 770 */
+ "771", /* 771 */
+ "772", /* 772 */
+ "773", /* 773 */
+ "774", /* 774 */
+ "775", /* 775 */
+ "776", /* 776 */
+ "777", /* 777 */
+ "778", /* 778 */
+ "779", /* 779 */
+ "780", /* 780 */
+ "781", /* 781 */
+ "782", /* 782 */
+ "783", /* 783 */
+ "784", /* 784 */
+ "785", /* 785 */
+ "786", /* 786 */
+ "787", /* 787 */
+ "788", /* 788 */
+ "789", /* 789 */
+ "790", /* 790 */
+ "791", /* 791 */
+ "792", /* 792 */
+ "793", /* 793 */
+ "794", /* 794 */
+ "795", /* 795 */
+ "796", /* 796 */
+ "797", /* 797 */
+ "798", /* 798 */
+ "799", /* 799 */
+ "800", /* 800 */
+ "801", /* 801 */
+ "802", /* 802 */
+ "803", /* 803 */
+ "804", /* 804 */
+ "805", /* 805 */
+ "806", /* 806 */
+ "807", /* 807 */
+ "808", /* 808 */
+ "809", /* 809 */
+ "810", /* 810 */
+ "811", /* 811 */
+ "812", /* 812 */
+ "813", /* 813 */
+ "814", /* 814 */
+ "815", /* 815 */
+ "816", /* 816 */
+ "817", /* 817 */
+ "818", /* 818 */
+ "819", /* 819 */
+ "820", /* 820 */
+ "821", /* 821 */
+ "822", /* 822 */
+ "823", /* 823 */
+ "824", /* 824 */
+ "825", /* 825 */
+ "826", /* 826 */
+ "827", /* 827 */
+ "828", /* 828 */
+ "829", /* 829 */
+ "830", /* 830 */
+ "831", /* 831 */
+ "832", /* 832 */
+ "833", /* 833 */
+ "834", /* 834 */
+ "835", /* 835 */
+ "836", /* 836 */
+ "837", /* 837 */
+ "838", /* 838 */
+ "839", /* 839 */
+ "840", /* 840 */
+ "841", /* 841 */
+ "842", /* 842 */
+ "843", /* 843 */
+ "844", /* 844 */
+ "845", /* 845 */
+ "846", /* 846 */
+ "847", /* 847 */
+ "848", /* 848 */
+ "849", /* 849 */
+ "850", /* 850 */
+ "851", /* 851 */
+ "852", /* 852 */
+ "853", /* 853 */
+ "854", /* 854 */
+ "855", /* 855 */
+ "856", /* 856 */
+ "857", /* 857 */
+ "858", /* 858 */
+ "859", /* 859 */
+ "860", /* 860 */
+ "861", /* 861 */
+ "862", /* 862 */
+ "863", /* 863 */
+ "864", /* 864 */
+ "865", /* 865 */
+ "866", /* 866 */
+ "867", /* 867 */
+ "868", /* 868 */
+ "869", /* 869 */
+ "870", /* 870 */
+ "871", /* 871 */
+ "872", /* 872 */
+ "873", /* 873 */
+ "874", /* 874 */
+ "875", /* 875 */
+ "876", /* 876 */
+ "877", /* 877 */
+ "878", /* 878 */
+ "879", /* 879 */
+ "880", /* 880 */
+ "881", /* 881 */
+ "882", /* 882 */
+ "883", /* 883 */
+ "884", /* 884 */
+ "885", /* 885 */
+ "886", /* 886 */
+ "887", /* 887 */
+ "888", /* 888 */
+ "889", /* 889 */
+ "890", /* 890 */
+ "891", /* 891 */
+ "892", /* 892 */
+ "893", /* 893 */
+ "894", /* 894 */
+ "895", /* 895 */
+ "896", /* 896 */
+ "897", /* 897 */
+ "898", /* 898 */
+ "899", /* 899 */
+ "900", /* 900 */
+ "901", /* 901 */
+ "902", /* 902 */
+ "903", /* 903 */
+ "904", /* 904 */
+ "905", /* 905 */
+ "906", /* 906 */
+ "907", /* 907 */
+ "908", /* 908 */
+ "909", /* 909 */
+ "910", /* 910 */
+ "911", /* 911 */
+ "912", /* 912 */
+ "913", /* 913 */
+ "914", /* 914 */
+ "915", /* 915 */
+ "916", /* 916 */
+ "917", /* 917 */
+ "918", /* 918 */
+ "919", /* 919 */
+ "920", /* 920 */
+ "921", /* 921 */
+ "922", /* 922 */
+ "923", /* 923 */
+ "924", /* 924 */
+ "925", /* 925 */
+ "926", /* 926 */
+ "927", /* 927 */
+ "928", /* 928 */
+ "929", /* 929 */
+ "930", /* 930 */
+ "931", /* 931 */
+ "932", /* 932 */
+ "933", /* 933 */
+ "934", /* 934 */
+ "935", /* 935 */
+ "936", /* 936 */
+ "937", /* 937 */
+ "938", /* 938 */
+ "939", /* 939 */
+ "940", /* 940 */
+ "941", /* 941 */
+ "942", /* 942 */
+ "943", /* 943 */
+ "944", /* 944 */
+ "945", /* 945 */
+ "946", /* 946 */
+ "947", /* 947 */
+ "948", /* 948 */
+ "949", /* 949 */
+ "950", /* 950 */
+ "951", /* 951 */
+ "952", /* 952 */
+ "953", /* 953 */
+ "954", /* 954 */
+ "955", /* 955 */
+ "956", /* 956 */
+ "957", /* 957 */
+ "958", /* 958 */
+ "959", /* 959 */
+ "960", /* 960 */
+ "961", /* 961 */
+ "962", /* 962 */
+ "963", /* 963 */
+ "964", /* 964 */
+ "965", /* 965 */
+ "966", /* 966 */
+ "967", /* 967 */
+ "968", /* 968 */
+ "969", /* 969 */
+ "970", /* 970 */
+ "971", /* 971 */
+ "972", /* 972 */
+ "973", /* 973 */
+ "974", /* 974 */
+ "975", /* 975 */
+ "976", /* 976 */
+ "977", /* 977 */
+ "978", /* 978 */
+ "979", /* 979 */
+ "980", /* 980 */
+ "981", /* 981 */
+ "982", /* 982 */
+ "983", /* 983 */
+ "984", /* 984 */
+ "985", /* 985 */
+ "986", /* 986 */
+ "987", /* 987 */
+ "988", /* 988 */
+ "989", /* 989 */
+ "990", /* 990 */
+ "991", /* 991 */
+ "992", /* 992 */
+ "993", /* 993 */
+ "994", /* 994 */
+ "995", /* 995 */
+ "996", /* 996 */
+ "997", /* 997 */
+ "998", /* 998 */
+ "999", /* 999 */
+ "1000", /* 1000 */
+ "1001", /* 1001 */
+ "1002", /* 1002 */
+ "1003", /* 1003 */
+ "1004", /* 1004 */
+ "1005", /* 1005 */
+ "1006", /* 1006 */
+ "1007", /* 1007 */
+ "1008", /* 1008 */
+ "1009", /* 1009 */
+ "1010", /* 1010 */
+ "1011", /* 1011 */
+ "1012", /* 1012 */
+ "1013", /* 1013 */
+ "1014", /* 1014 */
+ "1015", /* 1015 */
+ "1016", /* 1016 */
+ "1017", /* 1017 */
+ "1018", /* 1018 */
+ "1019", /* 1019 */
+ "1020", /* 1020 */
+ "1021", /* 1021 */
+ "1022", /* 1022 */
+ "1023", /* 1023 */
+ "ni_syscall", /* 1024 */
+ "exit", /* 1025 */
+ "read", /* 1026 */
+ "write", /* 1027 */
+ "open", /* 1028 */
+ "close", /* 1029 */
+ "creat", /* 1030 */
+ "link", /* 1031 */
+ "unlink", /* 1032 */
+ "execve", /* 1033 */
+ "chdir", /* 1034 */
+ "fchdir", /* 1035 */
+ "utimes", /* 1036 */
+ "mknod", /* 1037 */
+ "chmod", /* 1038 */
+ "chown", /* 1039 */
+ "lseek", /* 1040 */
+ "getpid", /* 1041 */
+ "getppid", /* 1042 */
+ "mount", /* 1043 */
+ "umount", /* 1044 */
+ "setuid", /* 1045 */
+ "getuid", /* 1046 */
+ "geteuid", /* 1047 */
+ "ptrace", /* 1048 */
+ "access", /* 1049 */
+ "sync", /* 1050 */
+ "fsync", /* 1051 */
+ "fdatasync", /* 1052 */
+ "kill", /* 1053 */
+ "rename", /* 1054 */
+ "mkdir", /* 1055 */
+ "rmdir", /* 1056 */
+ "dup", /* 1057 */
+ "pipe", /* 1058 */
+ "times", /* 1059 */
+ "brk", /* 1060 */
+ "setgid", /* 1061 */
+ "getgid", /* 1062 */
+ "getegid", /* 1063 */
+ "acct", /* 1064 */
+ "ioctl", /* 1065 */
+ "fcntl", /* 1066 */
+ "umask", /* 1067 */
+ "chroot", /* 1068 */
+ "ustat", /* 1069 */
+ "dup2", /* 1070 */
+ "setreuid", /* 1071 */
+ "setregid", /* 1072 */
+ "getresuid", /* 1073 */
+ "setresuid", /* 1074 */
+ "getresgid", /* 1075 */
+ "setresgid", /* 1076 */
+ "getgroups", /* 1077 */
+ "setgroups", /* 1078 */
+ "getpgid", /* 1079 */
+ "setpgid", /* 1080 */
+ "setsid", /* 1081 */
+ "getsid", /* 1082 */
+ "sethostname", /* 1083 */
+ "setrlimit", /* 1084 */
+ "getrlimit", /* 1085 */
+ "getrusage", /* 1086 */
+ "gettimeofday", /* 1087 */
+ "settimeofday", /* 1088 */
+ "select", /* 1089 */
+ "poll", /* 1090 */
+ "symlink", /* 1091 */
+ "readlink", /* 1092 */
+ "uselib", /* 1093 */
+ "swapon", /* 1094 */
+ "swapoff", /* 1095 */
+ "reboot", /* 1096 */
+ "truncate", /* 1097 */
+ "ftruncate", /* 1098 */
+ "fchmod", /* 1099 */
+ "fchown", /* 1100 */
+ "getpriority", /* 1101 */
+ "setpriority", /* 1102 */
+ "statfs", /* 1103 */
+ "fstatfs", /* 1104 */
+ "gettid", /* 1105 */
+ "semget", /* 1106 */
+ "semop", /* 1107 */
+ "semctl", /* 1108 */
+ "msgget", /* 1109 */
+ "msgsnd", /* 1110 */
+ "msgrcv", /* 1111 */
+ "msgctl", /* 1112 */
+ "shmget", /* 1113 */
+ "shmat", /* 1114 */
+ "shmdt", /* 1115 */
+ "shmctl", /* 1116 */
+ "syslog", /* 1117 */
+ "setitimer", /* 1118 */
+ "getitimer", /* 1119 */
+ "1120", /* 1120 */
+ "1121", /* 1121 */
+ "1122", /* 1122 */
+ "vhangup", /* 1123 */
+ "lchown", /* 1124 */
+ "remap_file_pages", /* 1125 */
+ "wait4", /* 1126 */
+ "sysinfo", /* 1127 */
+ "clone", /* 1128 */
+ "setdomainname", /* 1129 */
+ "uname", /* 1130 */
+ "adjtimex", /* 1131 */
+ "1132", /* 1132 */
+ "init_module", /* 1133 */
+ "delete_module", /* 1134 */
+ "1135", /* 1135 */
+ "1136", /* 1136 */
+ "quotactl", /* 1137 */
+ "bdflush", /* 1138 */
+ "sysfs", /* 1139 */
+ "personality", /* 1140 */
+ "afs_syscall", /* 1141 */
+ "setfsuid", /* 1142 */
+ "setfsgid", /* 1143 */
+ "getdents", /* 1144 */
+ "flock", /* 1145 */
+ "readv", /* 1146 */
+ "writev", /* 1147 */
+ "pread64", /* 1148 */
+ "pwrite64", /* 1149 */
+ "_sysctl", /* 1150 */
+ "mmap", /* 1151 */
+ "munmap", /* 1152 */
+ "mlock", /* 1153 */
+ "mlockall", /* 1154 */
+ "mprotect", /* 1155 */
+ "mremap", /* 1156 */
+ "msync", /* 1157 */
+ "munlock", /* 1158 */
+ "munlockall", /* 1159 */
+ "sched_getparam", /* 1160 */
+ "sched_setparam", /* 1161 */
+ "sched_getscheduler", /* 1162 */
+ "sched_setscheduler", /* 1163 */
+ "sched_yield", /* 1164 */
+ "sched_get_priority_max", /* 1165 */
+ "sched_get_priority_min", /* 1166 */
+ "sched_rr_get_interval", /* 1167 */
+ "nanosleep", /* 1168 */
+ "nfsservctl", /* 1169 */
+ "prctl", /* 1170 */
+ "1171", /* 1171 */
+ "mmap2", /* 1172 */
+ "pciconfig_read", /* 1173 */
+ "pciconfig_write", /* 1174 */
+ "perfmonctl", /* 1175 */
+ "sigaltstack", /* 1176 */
+ "rt_sigaction", /* 1177 */
+ "rt_sigpending", /* 1178 */
+ "rt_sigprocmask", /* 1179 */
+ "rt_sigqueueinfo", /* 1180 */
+ "rt_sigreturn", /* 1181 */
+ "rt_sigsuspend", /* 1182 */
+ "rt_sigtimedwait", /* 1183 */
+ "getcwd", /* 1184 */
+ "capget", /* 1185 */
+ "capset", /* 1186 */
+ "sendfile", /* 1187 */
+ "getpmsg", /* 1188 */
+ "putpmsg", /* 1189 */
+ "socket", /* 1190 */
+ "bind", /* 1191 */
+ "connect", /* 1192 */
+ "listen", /* 1193 */
+ "accept", /* 1194 */
+ "getsockname", /* 1195 */
+ "getpeername", /* 1196 */
+ "socketpair", /* 1197 */
+ "send", /* 1198 */
+ "sendto", /* 1199 */
+ "recv", /* 1200 */
+ "recvfrom", /* 1201 */
+ "shutdown", /* 1202 */
+ "setsockopt", /* 1203 */
+ "getsockopt", /* 1204 */
+ "sendmsg", /* 1205 */
+ "recvmsg", /* 1206 */
+ "pivot_root", /* 1207 */
+ "mincore", /* 1208 */
+ "madvise", /* 1209 */
+ "stat", /* 1210 */
+ "lstat", /* 1211 */
+ "fstat", /* 1212 */
+ "clone2", /* 1213 */
+ "getdents64", /* 1214 */
+ "getunwind", /* 1215 */
+ "readahead", /* 1216 */
+ "setxattr", /* 1217 */
+ "lsetxattr", /* 1218 */
+ "fsetxattr", /* 1219 */
+ "getxattr", /* 1220 */
+ "lgetxattr", /* 1221 */
+ "fgetxattr", /* 1222 */
+ "listxattr", /* 1223 */
+ "llistxattr", /* 1224 */
+ "flistxattr", /* 1225 */
+ "removexattr", /* 1226 */
+ "lremovexattr", /* 1227 */
+ "fremovexattr", /* 1228 */
+ "tkill", /* 1229 */
+ "futex", /* 1230 */
+ "sched_setaffinity", /* 1231 */
+ "sched_getaffinity", /* 1232 */
+ "set_tid_address", /* 1233 */
+ "fadvise64", /* 1234 */
+ "tgkill", /* 1235 */
+ "exit_group", /* 1236 */
+ "lookup_dcookie", /* 1237 */
+ "io_setup", /* 1238 */
+ "io_destroy", /* 1239 */
+ "io_getevents", /* 1240 */
+ "io_submit", /* 1241 */
+ "io_cancel", /* 1242 */
+ "epoll_create", /* 1243 */
+ "epoll_ctl", /* 1244 */
+ "epoll_wait", /* 1245 */
+ "restart_syscall", /* 1246 */
+ "semtimedop", /* 1247 */
+ "timer_create", /* 1248 */
+ "timer_settime", /* 1249 */
+ "timer_gettime", /* 1250 */
+ "timer_getoverrun", /* 1251 */
+ "timer_delete", /* 1252 */
+ "clock_settime", /* 1253 */
+ "clock_gettime", /* 1254 */
+ "clock_getres", /* 1255 */
+ "clock_nanosleep", /* 1256 */
+ "fstatfs64", /* 1257 */
+ "statfs64", /* 1258 */
+ "mbind", /* 1259 */
+ "get_mempolicy", /* 1260 */
+ "set_mempolicy", /* 1261 */
+ "mq_open", /* 1262 */
+ "mq_unlink", /* 1263 */
+ "mq_timedsend", /* 1264 */
+ "mq_timedreceive", /* 1265 */
+ "mq_notify", /* 1266 */
+ "mq_getsetattr", /* 1267 */
+ "kexec_load", /* 1268 */
+ "vserver", /* 1269 */
+ "waitid", /* 1270 */
+ "add_key", /* 1271 */
+ "request_key", /* 1272 */
+ "keyctl", /* 1273 */
+ "ioprio_set", /* 1274 */
+ "ioprio_get", /* 1275 */
+ "1276", /* 1276 */
+ "inotify_init", /* 1277 */
+ "inotify_add_watch", /* 1278 */
+ "inotify_rm_watch", /* 1279 */
+ "migrate_pages", /* 1280 */
+ "openat", /* 1281 */
+ "mkdirat", /* 1282 */
+ "mknodat", /* 1283 */
+ "fchownat", /* 1284 */
+ "futimesat", /* 1285 */
+ "newfstatat", /* 1286 */
+ "unlinkat", /* 1287 */
+ "renameat", /* 1288 */
+ "linkat", /* 1289 */
+ "symlinkat", /* 1290 */
+ "readlinkat", /* 1291 */
+ "fchmodat", /* 1292 */
+ "faccessat", /* 1293 */
+ "1294", /* 1294 */
+ "1295", /* 1295 */
+ "unshare", /* 1296 */
+ "splice", /* 1297 */
+ "set_robust_list", /* 1298 */
+ "get_robust_list", /* 1299 */
+ "sync_file_range", /* 1300 */
+ "tee", /* 1301 */
+ "vmsplice", /* 1302 */
diff --git a/sysdeps/linux-gnu/ia64/trace.c b/sysdeps/linux-gnu/ia64/trace.c
new file mode 100644
index 0000000..799e0ff
--- /dev/null
+++ b/sysdeps/linux-gnu/ia64/trace.c
@@ -0,0 +1,268 @@
+#include "config.h"
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <sys/ptrace.h>
+#include <string.h>
+#include <asm/ptrace_offsets.h>
+#include <asm/rse.h>
+
+#include "common.h"
+
+/* What we think of as a bundle, ptrace thinks of it as two unsigned
+ * longs */
+union bundle_t {
+ /* An IA64 instruction bundle has a 5 bit header describing the
+ * type of bundle, then 3 41 bit instructions
+ */
+ struct {
+ struct {
+ unsigned long template:5;
+ unsigned long slot0:41;
+ unsigned long bot_slot1:18;
+ } word0;
+ struct {
+ unsigned long top_slot1:23;
+ unsigned long slot2:41;
+ } word1;
+ } bitmap;
+ unsigned long code[2];
+};
+
+union cfm_t {
+ struct {
+ unsigned long sof:7;
+ unsigned long sol:7;
+ unsigned long sor:4;
+ unsigned long rrb_gr:7;
+ unsigned long rrb_fr:7;
+ unsigned long rrb_pr:6;
+ } cfm;
+ unsigned long value;
+};
+
+int
+syscall_p(Process *proc, int status, int *sysnum) {
+ if (WIFSTOPPED(status)
+ && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
+ unsigned long slot =
+ (ptrace(PTRACE_PEEKUSER, proc->pid, PT_CR_IPSR, 0) >> 41) &
+ 0x3;
+ unsigned long ip =
+ ptrace(PTRACE_PEEKUSER, proc->pid, PT_CR_IIP, 0);
+
+ /* r15 holds the system call number */
+ unsigned long r15 =
+ ptrace(PTRACE_PEEKUSER, proc->pid, PT_R15, 0);
+ unsigned long insn;
+
+ union bundle_t bundle;
+
+ /* On fault, the IP has moved forward to the next
+ * slot. If that is zero, then the actual place we
+ * broke was in the previous bundle, so wind back the
+ * IP.
+ */
+ if (slot == 0)
+ ip = ip - 16;
+ bundle.code[0] = ptrace(PTRACE_PEEKTEXT, proc->pid, ip, 0);
+ bundle.code[1] = ptrace(PTRACE_PEEKTEXT, proc->pid, ip + 8, 0);
+
+ unsigned long bot = 0UL | bundle.bitmap.word0.bot_slot1;
+ unsigned long top = 0UL | bundle.bitmap.word1.top_slot1;
+
+ /* handle the rollback, slot 0 is actually slot 2 of
+ * the previous instruction (see above) */
+ switch (slot) {
+ case 0:
+ insn = bundle.bitmap.word1.slot2;
+ break;
+ case 1:
+ insn = bundle.bitmap.word0.slot0;
+ break;
+ case 2:
+ /* make sure we're shifting about longs */
+ insn = 0UL | bot | (top << 18UL);
+ break;
+ default:
+ printf("Ummm, can't find instruction slot?\n");
+ exit(1);
+ }
+
+ /* We need to support both the older break instruction
+ * type syscalls, and the new epc type ones.
+ *
+ * Bit 20 of the break constant is encoded in the "i"
+ * bit (bit 36) of the instruction, hence you should
+ * see 0x1000000000.
+ *
+ * An EPC call is just 0x1ffffffffff
+ */
+ if (insn == 0x1000000000 || insn == 0x1ffffffffff) {
+ *sysnum = r15;
+ 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;
+ }
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Stolen from David Mosberger's utrace tool, which he released under
+ the GPL
+ (http://www.gelato.unsw.edu.au/archives/linux-ia64/0104/1405.html) */
+static inline double
+fpreg_to_double (struct ia64_fpreg *fp) {
+ double result;
+
+ asm ("ldf.fill %0=%1" : "=f"(result) : "m"(*fp));
+ return result;
+}
+
+static long
+gimme_long_arg(enum tof type, Process *proc, int arg_num) {
+ union cfm_t cfm;
+ unsigned long bsp;
+
+ bsp = ptrace(PTRACE_PEEKUSER, proc->pid, PT_AR_BSP, 0);
+ cfm.value = ptrace(PTRACE_PEEKUSER, proc->pid, PT_CFM, 0);
+
+ if (arg_num == -1) /* return value */
+ return ptrace(PTRACE_PEEKUSER, proc->pid, PT_R8, 0);
+
+ /* First 8 arguments are passed in registers on the register
+ * stack, the following arguments are passed on the stack
+ * after a 16 byte scratch area
+ *
+ * If the function has returned, the ia64 register window has
+ * been reverted to the caller's configuration. So although in
+ * the callee, the first parameter is in R32, in the caller
+ * the first parameter comes in the registers after the local
+ * registers (really, input parameters plus locals, but the
+ * hardware doesn't track the distinction.) So we have to add
+ * in the size of the local area (sol) to find the first
+ * parameter passed to the callee. */
+ if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
+ if (arg_num < 8) {
+ if (type == LT_TOF_FUNCTIONR)
+ arg_num += cfm.cfm.sol;
+
+ return ptrace(PTRACE_PEEKDATA, proc->pid,
+ (long)ia64_rse_skip_regs((unsigned long *)bsp,
+ -cfm.cfm.sof + arg_num),
+ 0);
+ } else {
+ unsigned long sp =
+ ptrace(PTRACE_PEEKUSER, proc->pid, PT_R12, 0) + 16;
+ return ptrace(PTRACE_PEEKDATA, proc->pid,
+ sp + (8 * (arg_num - 8)));
+ }
+ }
+
+ if (type == LT_TOF_SYSCALL || LT_TOF_SYSCALLR)
+ return ptrace(PTRACE_PEEKDATA, proc->pid,
+ (long)ia64_rse_skip_regs((unsigned long *)bsp, arg_num),
+ 0);
+
+ /* error if we get here */
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(1);
+}
+
+static long float_regs[8] = { PT_F8, PT_F9, PT_F10, PT_F11,
+ PT_F12, PT_F13, PT_F14, PT_F15 };
+static double
+gimme_float_arg(enum tof type, Process *proc, int arg_num) {
+ union cfm_t cfm;
+ unsigned long bsp;
+ struct ia64_fpreg reg;
+
+ if (arg_num == -1) { /* return value */
+ reg.u.bits[0] = ptrace(PTRACE_PEEKUSER, proc->pid,
+ PT_F8, 0);
+ reg.u.bits[1] = ptrace(PTRACE_PEEKUSER, proc->pid,
+ PT_F8 + 0x8, 0);
+ return fpreg_to_double(&reg);
+ }
+
+ bsp = ptrace(PTRACE_PEEKUSER, proc->pid, PT_AR_BSP, 0);
+ cfm.value = ptrace(PTRACE_PEEKUSER, proc->pid, PT_CFM, 0);
+
+ /* The first 8 arguments are passed in regular registers
+ * (counting from R32), unless they are floating point values
+ * (the case in question here). In that case, up to the first
+ * 8 regular registers are still "allocated" for each of the
+ * first 8 parameters, but if a parameter is floating point,
+ * then the register is left unset and the parameter is passed
+ * in the first available floating-point register, counting
+ * from F8.
+ *
+ * Take func(int a, float f, int b, double d), for example.
+ * a - passed in R32
+ * f - R33 left unset, value passed in F8
+ * b - passed in R34
+ * d - R35 left unset, value passed in F9
+ *
+ * ltrace handles this by counting floating point arguments
+ * while parsing declarations. The "arg_num" in this routine
+ * (which is only called for floating point values) really
+ * means which floating point parameter we're looking for,
+ * ignoring everything else.
+ *
+ * Following the first 8 arguments, the remaining arguments
+ * are passed on the stack after a 16 byte scratch area
+ */
+ if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
+ if (arg_num < 8) {
+ reg.u.bits[0] = ptrace(PTRACE_PEEKUSER, proc->pid,
+ float_regs[arg_num], 0);
+ reg.u.bits[1] = ptrace(PTRACE_PEEKUSER, proc->pid,
+ float_regs[arg_num] + 0x8, 0);
+ return fpreg_to_double(&reg);
+ } else {
+ unsigned long sp =
+ ptrace(PTRACE_PEEKUSER, proc->pid, PT_R12, 0) + 16;
+ reg.u.bits[0] = ptrace(PTRACE_PEEKDATA, proc->pid,
+ sp + (8 * (arg_num - 8)));
+ reg.u.bits[0] = ptrace(PTRACE_PEEKDATA, proc->pid,
+ sp + (8 * (arg_num - 8)) + 0x8);
+ return fpreg_to_double(&reg);
+ }
+ }
+
+ /* error if we get here */
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(1);
+}
+
+long
+gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) {
+ union {
+ long l;
+ float f;
+ double d;
+ } cvt;
+
+ if (info->type == ARGTYPE_FLOAT)
+ cvt.f = gimme_float_arg(type, proc, info->u.float_info.float_index);
+ else if (info->type == ARGTYPE_DOUBLE)
+ cvt.d = gimme_float_arg(type, proc, info->u.double_info.float_index);
+ else
+ cvt.l = gimme_long_arg(type, proc, arg_num);
+
+ return cvt.l;
+}
+
+void
+save_register_args(enum tof type, Process *proc) {
+}
+
+void
+get_arch_dep(Process *proc) {
+}
diff --git a/sysdeps/linux-gnu/m68k/Makefile b/sysdeps/linux-gnu/m68k/Makefile
new file mode 100644
index 0000000..60d7531
--- /dev/null
+++ b/sysdeps/linux-gnu/m68k/Makefile
@@ -0,0 +1,10 @@
+OBJ = trace.o regs.o plt.o
+
+all: arch.o
+
+arch.o: $(OBJ)
+ $(CC) -nostdlib -r -o arch.o $(OBJ)
+
+clean:
+ $(RM) $(OBJ) arch.o
+
diff --git a/sysdeps/linux-gnu/m68k/arch.h b/sysdeps/linux-gnu/m68k/arch.h
new file mode 100644
index 0000000..1790d09
--- /dev/null
+++ b/sysdeps/linux-gnu/m68k/arch.h
@@ -0,0 +1,6 @@
+#define BREAKPOINT_VALUE { 0x4e, 0x4f }
+#define BREAKPOINT_LENGTH 2
+#define DECR_PC_AFTER_BREAK 2
+
+#define LT_ELFCLASS ELFCLASS32
+#define LT_ELF_MACHINE EM_68K
diff --git a/sysdeps/linux-gnu/m68k/plt.c b/sysdeps/linux-gnu/m68k/plt.c
new file mode 100644
index 0000000..508d7fc
--- /dev/null
+++ b/sysdeps/linux-gnu/m68k/plt.c
@@ -0,0 +1,13 @@
+#include <gelf.h>
+#include "common.h"
+
+GElf_Addr
+arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) {
+ return lte->plt_addr + (ndx + 1)
+ * ((lte->ehdr.e_flags & EF_CPU32) ? 24 : 12);
+}
+
+void *
+sym2addr(Process *proc, struct library_symbol *sym) {
+ return sym->enter_addr;
+}
diff --git a/sysdeps/linux-gnu/m68k/ptrace.h b/sysdeps/linux-gnu/m68k/ptrace.h
new file mode 100644
index 0000000..c3cbcb6
--- /dev/null
+++ b/sysdeps/linux-gnu/m68k/ptrace.h
@@ -0,0 +1 @@
+#include <sys/ptrace.h>
diff --git a/sysdeps/linux-gnu/m68k/regs.c b/sysdeps/linux-gnu/m68k/regs.c
new file mode 100644
index 0000000..959a60e
--- /dev/null
+++ b/sysdeps/linux-gnu/m68k/regs.c
@@ -0,0 +1,40 @@
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+
+#include "common.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(Process *proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_PC, 0);
+}
+
+void
+set_instruction_pointer(Process *proc, void *addr) {
+ ptrace(PTRACE_POKEUSER, proc->pid, 4 * PT_PC, addr);
+}
+
+void *
+get_stack_pointer(Process *proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_USP, 0);
+}
+
+void *
+get_return_addr(Process *proc, void *stack_pointer) {
+ return (void *)ptrace(PTRACE_PEEKTEXT, proc->pid, stack_pointer, 0);
+}
+
+void
+set_return_addr(Process *proc, void *addr) {
+ ptrace(PTRACE_POKETEXT, proc->pid, proc->stack_pointer, addr);
+}
diff --git a/sysdeps/linux-gnu/m68k/signalent.h b/sysdeps/linux-gnu/m68k/signalent.h
new file mode 100644
index 0000000..5395f82
--- /dev/null
+++ b/sysdeps/linux-gnu/m68k/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/m68k/syscallent.h b/sysdeps/linux-gnu/m68k/syscallent.h
new file mode 100644
index 0000000..4d65b39
--- /dev/null
+++ b/sysdeps/linux-gnu/m68k/syscallent.h
@@ -0,0 +1,282 @@
+ "0", /* 0 */
+ "exit", /* 1 */
+ "fork", /* 2 */
+ "read", /* 3 */
+ "write", /* 4 */
+ "open", /* 5 */
+ "close", /* 6 */
+ "waitpid", /* 7 */
+ "creat", /* 8 */
+ "link", /* 9 */
+ "unlink", /* 10 */
+ "execve", /* 11 */
+ "chdir", /* 12 */
+ "time", /* 13 */
+ "mknod", /* 14 */
+ "chmod", /* 15 */
+ "chown", /* 16 */
+ "break", /* 17 */
+ "oldstat", /* 18 */
+ "lseek", /* 19 */
+ "getpid", /* 20 */
+ "mount", /* 21 */
+ "umount", /* 22 */
+ "setuid", /* 23 */
+ "getuid", /* 24 */
+ "stime", /* 25 */
+ "ptrace", /* 26 */
+ "alarm", /* 27 */
+ "oldfstat", /* 28 */
+ "pause", /* 29 */
+ "utime", /* 30 */
+ "stty", /* 31 */
+ "gtty", /* 32 */
+ "access", /* 33 */
+ "nice", /* 34 */
+ "ftime", /* 35 */
+ "sync", /* 36 */
+ "kill", /* 37 */
+ "rename", /* 38 */
+ "mkdir", /* 39 */
+ "rmdir", /* 40 */
+ "dup", /* 41 */
+ "pipe", /* 42 */
+ "times", /* 43 */
+ "prof", /* 44 */
+ "brk", /* 45 */
+ "setgid", /* 46 */
+ "getgid", /* 47 */
+ "signal", /* 48 */
+ "geteuid", /* 49 */
+ "getegid", /* 50 */
+ "acct", /* 51 */
+ "umount2", /* 52 */
+ "lock", /* 53 */
+ "ioctl", /* 54 */
+ "fcntl", /* 55 */
+ "mpx", /* 56 */
+ "setpgid", /* 57 */
+ "ulimit", /* 58 */
+ "oldolduname", /* 59 */
+ "umask", /* 60 */
+ "chroot", /* 61 */
+ "ustat", /* 62 */
+ "dup2", /* 63 */
+ "getppid", /* 64 */
+ "getpgrp", /* 65 */
+ "setsid", /* 66 */
+ "sigaction", /* 67 */
+ "sgetmask", /* 68 */
+ "ssetmask", /* 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 */
+ "select", /* 82 */
+ "symlink", /* 83 */
+ "oldlstat", /* 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 */
+ "profil", /* 98 */
+ "statfs", /* 99 */
+ "fstatfs", /* 100 */
+ "ioperm", /* 101 */
+ "socketcall", /* 102 */
+ "syslog", /* 103 */
+ "setitimer", /* 104 */
+ "getitimer", /* 105 */
+ "stat", /* 106 */
+ "lstat", /* 107 */
+ "fstat", /* 108 */
+ "olduname", /* 109 */
+ "110", /* 110 */
+ "vhangup", /* 111 */
+ "112", /* 112 */
+ "113", /* 113 */
+ "wait4", /* 114 */
+ "swapoff", /* 115 */
+ "sysinfo", /* 116 */
+ "ipc", /* 117 */
+ "fsync", /* 118 */
+ "sigreturn", /* 119 */
+ "clone", /* 120 */
+ "setdomainname", /* 121 */
+ "uname", /* 122 */
+ "cacheflush", /* 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 */
+ "getpagesize", /* 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 */
+ "pread64", /* 180 */
+ "pwrite64", /* 181 */
+ "lchown", /* 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 */
+ "chown32", /* 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 */
+ "lchown32", /* 212 */
+ "setuid32", /* 213 */
+ "setgid32", /* 214 */
+ "setfsuid32", /* 215 */
+ "setfsgid32", /* 216 */
+ "pivot_root", /* 217 */
+ "218", /* 218 */
+ "219", /* 219 */
+ "getdents64", /* 220 */
+ "gettid", /* 221 */
+ "tkill", /* 222 */
+ "setxattr", /* 223 */
+ "lsetxattr", /* 224 */
+ "fsetxattr", /* 225 */
+ "getxattr", /* 226 */
+ "lgetxattr", /* 227 */
+ "fgetxattr", /* 228 */
+ "listxattr", /* 229 */
+ "llistxattr", /* 230 */
+ "flistxattr", /* 231 */
+ "removexattr", /* 232 */
+ "lremovexattr", /* 233 */
+ "fremovexattr", /* 234 */
+ "futex", /* 235 */
+ "sendfile64", /* 236 */
+ "mincore", /* 237 */
+ "madvise", /* 238 */
+ "fcntl64", /* 239 */
+ "readahead", /* 240 */
+ "io_setup", /* 241 */
+ "io_destroy", /* 242 */
+ "io_getevents", /* 243 */
+ "io_submit", /* 244 */
+ "io_cancel", /* 245 */
+ "fadvise64", /* 246 */
+ "exit_group", /* 247 */
+ "lookup_dcookie", /* 248 */
+ "epoll_create", /* 249 */
+ "epoll_ctl", /* 250 */
+ "epoll_wait", /* 251 */
+ "remap_file_pages", /* 252 */
+ "set_tid_address", /* 253 */
+ "timer_create", /* 254 */
+ "timer_settime", /* 255 */
+ "timer_gettime", /* 256 */
+ "timer_getoverrun", /* 257 */
+ "timer_delete", /* 258 */
+ "clock_settime", /* 259 */
+ "clock_gettime", /* 260 */
+ "clock_getres", /* 261 */
+ "clock_nanosleep", /* 262 */
+ "statfs64", /* 263 */
+ "fstatfs64", /* 264 */
+ "tgkill", /* 265 */
+ "utimes", /* 266 */
+ "fadvise64_64", /* 267 */
+ "mbind", /* 268 */
+ "get_mempolicy", /* 269 */
+ "set_mempolicy", /* 270 */
+ "mq_open", /* 271 */
+ "mq_unlink", /* 272 */
+ "mq_timedsend", /* 273 */
+ "mq_timedreceive", /* 274 */
+ "mq_notify", /* 275 */
+ "mq_getsetattr", /* 276 */
+ "waitid", /* 277 */
+ "vserver", /* 278 */
+ "add_key", /* 279 */
+ "request_key", /* 280 */
+ "keyctl", /* 281 */
diff --git a/sysdeps/linux-gnu/m68k/trace.c b/sysdeps/linux-gnu/m68k/trace.c
new file mode 100644
index 0000000..2f89fdf
--- /dev/null
+++ b/sysdeps/linux-gnu/m68k/trace.c
@@ -0,0 +1,89 @@
+#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"
+
+#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) {
+ int depth;
+
+ if (WIFSTOPPED(status)
+ && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
+ *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_ORIG_D0, 0);
+ if (*sysnum == -1)
+ return 0;
+ if (*sysnum >= 0) {
+ depth = proc->callstack_depth;
+ if (depth > 0 &&
+ proc->callstack[depth - 1].is_syscall &&
+ proc->callstack[depth - 1].c_un.syscall == *sysnum) {
+ return 2;
+ } else {
+ 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, 4 * PT_D0, 0);
+ }
+
+ if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
+ return ptrace(PTRACE_PEEKTEXT, proc->pid,
+ proc->stack_pointer + 4 * (arg_num + 1), 0);
+ } else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) {
+#if 0
+ switch (arg_num) {
+ case 0:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_D1, 0);
+ case 1:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_D2, 0);
+ case 2:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_D3, 0);
+ case 3:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_D4, 0);
+ case 4:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_D5, 0);
+ default:
+ fprintf(stderr,
+ "gimme_arg called with wrong arguments\n");
+ exit(2);
+ }
+#else
+ /* That hack works on m68k, too */
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num, 0);
+#endif
+ } else {
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(1);
+ }
+
+ return 0;
+}
+
+void
+save_register_args(enum tof type, Process *proc) {
+}
diff --git a/sysdeps/linux-gnu/mipsel/Doxyfile b/sysdeps/linux-gnu/mipsel/Doxyfile
new file mode 100644
index 0000000..b4f5eb2
--- /dev/null
+++ b/sysdeps/linux-gnu/mipsel/Doxyfile
@@ -0,0 +1,275 @@
+# Doxyfile 1.5.1
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = ltrace-mipsel
+PROJECT_NUMBER =
+OUTPUT_DIRECTORY =
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = NO
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH =
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP = NO
+INHERIT_DOCS = YES
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 8
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+BUILTIN_STL_SUPPORT = NO
+DISTRIBUTE_GROUP_DOC = NO
+SUBGROUPING = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = YES
+EXTRACT_LOCAL_METHODS = YES
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = YES
+SORT_BY_SCOPE_NAME = YES
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_DIRECTORIES = NO
+FILE_VERSION_FILTER =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = .
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.d \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.idl \
+ *.odl \
+ *.cs \
+ *.php \
+ *.php3 \
+ *.inc \
+ *.m \
+ *.mm \
+ *.dox \
+ *.py \
+ *.C \
+ *.CC \
+ *.C++ \
+ *.II \
+ *.I++ \
+ *.H \
+ *.HH \
+ *.H++ \
+ *.CS \
+ *.PHP \
+ *.PHP3 \
+ *.M \
+ *.MM \
+ *.PY
+RECURSIVE = NO
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS = *
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = YES
+INLINE_SOURCES = YES
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+REFERENCES_LINK_SOURCE = YES
+USE_HTAGS = NO
+VERBATIM_HEADERS = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = NO
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = NO
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED =
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = YES
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = YES
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = YES
+TEMPLATE_RELATIONS = YES
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = YES
+CALLER_GRAPH = YES
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+MAX_DOT_GRAPH_WIDTH = 1024
+MAX_DOT_GRAPH_HEIGHT = 1024
+MAX_DOT_GRAPH_DEPTH = 1000
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = NO
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
diff --git a/sysdeps/linux-gnu/mipsel/Makefile b/sysdeps/linux-gnu/mipsel/Makefile
new file mode 100644
index 0000000..44f4aae
--- /dev/null
+++ b/sysdeps/linux-gnu/mipsel/Makefile
@@ -0,0 +1,22 @@
+.PHONY: all deps clean docs
+
+OBJ = trace.o regs.o plt.o
+SRC=$(OBJ:.o=.c)
+
+all: arch.o
+
+deps:
+ $(CC) $(CFLAGS) $(CPPFLAGS) -M $(SRC) > .depends
+
+arch.o: $(OBJ) arch.h
+ $(CC) -nostdlib -r -o arch.o $(OBJ)
+
+clean:
+ -rm -f $(OBJ) arch.o
+ -rm -rf html
+
+docs:
+ doxygen
+
+
+-include .depends
diff --git a/sysdeps/linux-gnu/mipsel/arch.h b/sysdeps/linux-gnu/mipsel/arch.h
new file mode 100644
index 0000000..dd0ca35
--- /dev/null
+++ b/sysdeps/linux-gnu/mipsel/arch.h
@@ -0,0 +1,9 @@
+#define BREAKPOINT_VALUE { 0x0d, 0x00, 0x00, 0x00 }
+#define BREAKPOINT_LENGTH 4
+#define DECR_PC_AFTER_BREAK 0
+
+#define LT_ELFCLASS ELFCLASS32
+#define LT_ELF_MACHINE EM_MIPS
+
+#define PLTs_INIT_BY_HERE "_start"
+#define E_ENTRY_NAME "_start"
diff --git a/sysdeps/linux-gnu/mipsel/mipsel.h b/sysdeps/linux-gnu/mipsel/mipsel.h
new file mode 100644
index 0000000..a63cafd
--- /dev/null
+++ b/sysdeps/linux-gnu/mipsel/mipsel.h
@@ -0,0 +1,11 @@
+#ifndef MIPSEL_h
+#define MIPSEL_h
+// linux-2.4.30/arch/mips/kernel/ptrace.c for these offsets.
+#define off_v0 2
+#define off_pc 64
+#define off_a0 4
+#define off_a3 7
+#define off_lr 31
+#define off_sp 29
+
+#endif // MIPSEL_h
diff --git a/sysdeps/linux-gnu/mipsel/plt.c b/sysdeps/linux-gnu/mipsel/plt.c
new file mode 100644
index 0000000..003171b
--- /dev/null
+++ b/sysdeps/linux-gnu/mipsel/plt.c
@@ -0,0 +1,72 @@
+#include <debug.h>
+#include <gelf.h>
+#include <sys/ptrace.h>
+#include "common.h"
+
+/**
+ \addtogroup mipsel
+ @{
+ */
+
+/**
+ \param lte Structure containing link table entry information
+ \param ndx Index into .dynsym
+ \param rela Not used.
+ \return Address of GOT table entry
+
+ MIPS ABI Supplement:
+
+ DT_PLTGOT This member holds the address of the .got section.
+
+ DT_MIPS_SYMTABNO This member holds the number of entries in the
+ .dynsym section.
+
+ DT_MIPS_LOCAL_GOTNO This member holds the number of local global
+ offset table entries.
+
+ DT_MIPS_GOTSYM This member holds the index of the first dyamic
+ symbol table entry that corresponds to an entry in the gobal offset
+ table.
+
+ Called by read_elf when building the symbol table.
+
+ */
+GElf_Addr
+arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) {
+ debug(1,"plt_addr %x ndx %#x",lte->pltgot_addr, ndx);
+ return lte->pltgot_addr +
+ sizeof(void *) * (lte->mips_local_gotno + (ndx - lte->mips_gotsym));
+}
+/**
+ \param proc The process to work on.
+ \param sym The library symbol.
+ \return What is at the got table address
+
+ The return value should be the address to put the breakpoint at.
+
+ On the mips the library_symbol.enter_addr is the .got addr for the
+ symbol and the breakpoint.addr is the actual breakpoint address.
+
+ Other processors use a plt, the mips is "special" in that is uses
+ the .got for both function and data relocations. Prior to program
+ startup, return 0.
+
+ \warning MIPS relocations are lazy. This means that the breakpoint
+ may move after the first call. Ltrace dictionary routines don't
+ have a delete and symbol is one to one with breakpoint, so if the
+ breakpoint changes I just add a new breakpoint for the new address.
+ */
+void *
+sym2addr(Process *proc, struct library_symbol *sym) {
+ long ret;
+ if(!proc->pid){
+ return 0;
+ }
+ ret=ptrace(PTRACE_PEEKTEXT, proc->pid, sym->enter_addr, 0);
+ if(ret==-1){
+ ret =0;
+ }
+ return (void *)ret;;
+}
+
+/**@}*/
diff --git a/sysdeps/linux-gnu/mipsel/ptrace.h b/sysdeps/linux-gnu/mipsel/ptrace.h
new file mode 100644
index 0000000..c3cbcb6
--- /dev/null
+++ b/sysdeps/linux-gnu/mipsel/ptrace.h
@@ -0,0 +1 @@
+#include <sys/ptrace.h>
diff --git a/sysdeps/linux-gnu/mipsel/regs.c b/sysdeps/linux-gnu/mipsel/regs.c
new file mode 100644
index 0000000..a7a6de1
--- /dev/null
+++ b/sysdeps/linux-gnu/mipsel/regs.c
@@ -0,0 +1,76 @@
+#include "config.h"
+
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+#include <linux/user.h>
+
+#include "common.h"
+#include "mipsel.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
+
+/**
+ \addtogroup mipsel
+ @{
+ */
+
+
+/**
+ \param proc The process to work on.
+ \return The current instruction pointer.
+ */
+void *
+get_instruction_pointer(Process *proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0);
+}
+
+/**
+ \param proc The process to work on.
+ \param addr The address to set to.
+
+ Called by \c continue_after_breakpoint().
+
+ \todo Our mips kernel ptrace doesn't support PTRACE_SINGLESTEP, so
+ we \c continue_process() after a breakpoint. Check if this is OK.
+ */
+void
+set_instruction_pointer(Process *proc, void *addr) {
+ ptrace(PTRACE_POKEUSER, proc->pid, off_pc, addr);
+}
+
+/**
+ \param proc The process to work on.
+ \return The current stack pointer.
+ */
+void *
+get_stack_pointer(Process *proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_sp, 0);
+}
+
+/**
+ \param proc The process to work on.
+ \param stack_pointer The current stack pointer for proc
+ \return The current return address.
+
+ Called by \c handle_breakpoint().
+
+ Mips uses r31 for the return address, so the stack_pointer is
+ unused.
+ */
+void *
+get_return_addr(Process *proc, void *stack_pointer) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_lr, 0);
+}
+
+void
+set_return_addr(Process *proc, void *addr) {
+ ptrace(PTRACE_POKEUSER, proc->pid, off_lr, addr);
+}
diff --git a/sysdeps/linux-gnu/mipsel/signalent.h b/sysdeps/linux-gnu/mipsel/signalent.h
new file mode 100644
index 0000000..6bb1ff6
--- /dev/null
+++ b/sysdeps/linux-gnu/mipsel/signalent.h
@@ -0,0 +1,32 @@
+"SIG_0", /* 0 */
+ "SIGHUP", // 1 /* Hangup (POSIX). */
+ "SIGINT", // 2 /* Interrupt (ANSI). */
+ "SIGQUIT", // 3 /* Quit (POSIX). */
+ "SIGILL", // 4 /* Illegal instruction (ANSI). */
+ "SIGTRAP", // 5 /* Trace trap (POSIX). */
+ "SIGIOT", // 6 /* IOT trap (4.2 BSD). */
+ "SIGEMT", // 7
+ "SIGFPE", // 8 /* Floating-point exception (ANSI). */
+ "SIGKILL", // 9 /* Kill, unblockable (POSIX). */
+ "SIGBUS", // 10 /* BUS error (4.2 BSD). */
+ "SIGSEGV", // 11 /* Segmentation violation (ANSI). */
+ "SIGSYS", // 12
+ "SIGPIPE", // 13 /* Broken pipe (POSIX). */
+ "SIGALRM", // 14 /* Alarm clock (POSIX). */
+ "SIGTERM", // 15 /* Termination (ANSI). */
+ "SIGUSR1", // 16 /* User-defined signal 1 (POSIX). */
+ "SIGUSR2", // 17 /* User-defined signal 2 (POSIX). */
+ "SIGCHLD", // 18 /* Child status has changed (POSIX). */
+ "SIGPWR", // 19 /* Power failure restart (System V). */
+ "SIGWINCH", // 20 /* Window size change (4.3 BSD, Sun). */
+ "SIGURG", // 21 /* Urgent condition on socket (4.2 BSD). */
+ "SIGIO", // 22 /* I/O now possible (4.2 BSD). */
+ "SIGSTOP", // 23 /* Stop, unblockable (POSIX). */
+ "SIGTSTP", // 24 /* Keyboard stop (POSIX). */
+ "SIGCONT", // 25 /* Continue (POSIX). */
+ "SIGTTIN", // 26 /* Background read from tty (POSIX). */
+ "SIGTTOU", // 27 /* Background write to tty (POSIX). */
+ "SIGVTALRM", // 28 /* Virtual alarm clock (4.2 BSD). */
+ "SIGPROF", // 29 /* Profiling alarm clock (4.2 BSD). */
+ "SIGXCPU", // 30 /* CPU limit exceeded (4.2 BSD). */
+ "SIGXFSZ", // 31 /* File size limit exceeded (4.2 BSD). */
diff --git a/sysdeps/linux-gnu/mipsel/syscallent.h b/sysdeps/linux-gnu/mipsel/syscallent.h
new file mode 100644
index 0000000..bed43fe
--- /dev/null
+++ b/sysdeps/linux-gnu/mipsel/syscallent.h
@@ -0,0 +1,241 @@
+ "0", /*Linux + 0*/
+ "exit", /*Linux + 1*/
+ "fork", /*Linux + 2*/
+ "read", /*Linux + 3*/
+ "write", /*Linux + 4*/
+ "open", /*Linux + 5*/
+ "close", /*Linux + 6*/
+ "waitpid", /*Linux + 7*/
+ "creat", /*Linux + 8*/
+ "link", /*Linux + 9*/
+ "unlink", /*Linux + 10*/
+ "execve", /*Linux + 11*/
+ "chdir", /*Linux + 12*/
+ "time", /*Linux + 13*/
+ "mknod", /*Linux + 14*/
+ "chmod", /*Linux + 15*/
+ "lchown", /*Linux + 16*/
+ "break", /*Linux + 17*/
+ "unused18", /*Linux + 18*/
+ "lseek", /*Linux + 19*/
+ "getpid", /*Linux + 20*/
+ "mount", /*Linux + 21*/
+ "umount", /*Linux + 22*/
+ "setuid", /*Linux + 23*/
+ "getuid", /*Linux + 24*/
+ "stime", /*Linux + 25*/
+ "ptrace", /*Linux + 26*/
+ "alarm", /*Linux + 27*/
+ "unused28", /*Linux + 28*/
+ "pause", /*Linux + 29*/
+ "utime", /*Linux + 30*/
+ "stty", /*Linux + 31*/
+ "gtty", /*Linux + 32*/
+ "access", /*Linux + 33*/
+ "nice", /*Linux + 34*/
+ "ftime", /*Linux + 35*/
+ "sync", /*Linux + 36*/
+ "kill", /*Linux + 37*/
+ "rename", /*Linux + 38*/
+ "mkdir", /*Linux + 39*/
+ "rmdir", /*Linux + 40*/
+ "dup", /*Linux + 41*/
+ "pipe", /*Linux + 42*/
+ "times", /*Linux + 43*/
+ "prof", /*Linux + 44*/
+ "brk", /*Linux + 45*/
+ "setgid", /*Linux + 46*/
+ "getgid", /*Linux + 47*/
+ "signal", /*Linux + 48*/
+ "geteuid", /*Linux + 49*/
+ "getegid", /*Linux + 50*/
+ "acct", /*Linux + 51*/
+ "umount2", /*Linux + 52*/
+ "lock", /*Linux + 53*/
+ "ioctl", /*Linux + 54*/
+ "fcntl", /*Linux + 55*/
+ "mpx", /*Linux + 56*/
+ "setpgid", /*Linux + 57*/
+ "ulimit", /*Linux + 58*/
+ "unused59", /*Linux + 59*/
+ "umask", /*Linux + 60*/
+ "chroot", /*Linux + 61*/
+ "ustat", /*Linux + 62*/
+ "dup2", /*Linux + 63*/
+ "getppid", /*Linux + 64*/
+ "getpgrp", /*Linux + 65*/
+ "setsid", /*Linux + 66*/
+ "sigaction", /*Linux + 67*/
+ "sgetmask", /*Linux + 68*/
+ "ssetmask", /*Linux + 69*/
+ "setreuid", /*Linux + 70*/
+ "setregid", /*Linux + 71*/
+ "sigsuspend", /*Linux + 72*/
+ "sigpending", /*Linux + 73*/
+ "sethostname", /*Linux + 74*/
+ "setrlimit", /*Linux + 75*/
+ "getrlimit", /*Linux + 76*/
+ "getrusage", /*Linux + 77*/
+ "gettimeofday", /*Linux + 78*/
+ "settimeofday", /*Linux + 79*/
+ "getgroups", /*Linux + 80*/
+ "setgroups", /*Linux + 81*/
+ "reserved82", /*Linux + 82*/
+ "symlink", /*Linux + 83*/
+ "unused84", /*Linux + 84*/
+ "readlink", /*Linux + 85*/
+ "uselib", /*Linux + 86*/
+ "swapon", /*Linux + 87*/
+ "reboot", /*Linux + 88*/
+ "readdir", /*Linux + 89*/
+ "mmap", /*Linux + 90*/
+ "munmap", /*Linux + 91*/
+ "truncate", /*Linux + 92*/
+ "ftruncate", /*Linux + 93*/
+ "fchmod", /*Linux + 94*/
+ "fchown", /*Linux + 95*/
+ "getpriority", /*Linux + 96*/
+ "setpriority", /*Linux + 97*/
+ "profil", /*Linux + 98*/
+ "statfs", /*Linux + 99*/
+ "fstatfs", /*Linux + 100*/
+ "ioperm", /*Linux + 101*/
+ "socketcall", /*Linux + 102*/
+ "syslog", /*Linux + 103*/
+ "setitimer", /*Linux + 104*/
+ "getitimer", /*Linux + 105*/
+ "stat", /*Linux + 106*/
+ "lstat", /*Linux + 107*/
+ "fstat", /*Linux + 108*/
+ "unused109", /*Linux + 109*/
+ "iopl", /*Linux + 110*/
+ "vhangup", /*Linux + 111*/
+ "idle", /*Linux + 112*/
+ "vm86", /*Linux + 113*/
+ "wait4", /*Linux + 114*/
+ "swapoff", /*Linux + 115*/
+ "sysinfo", /*Linux + 116*/
+ "ipc", /*Linux + 117*/
+ "fsync", /*Linux + 118*/
+ "sigreturn", /*Linux + 119*/
+ "clone", /*Linux + 120*/
+ "setdomainname", /*Linux + 121*/
+ "uname", /*Linux + 122*/
+ "modify_ldt", /*Linux + 123*/
+ "adjtimex", /*Linux + 124*/
+ "mprotect", /*Linux + 125*/
+ "sigprocmask", /*Linux + 126*/
+ "create_module", /*Linux + 127*/
+ "init_module", /*Linux + 128*/
+ "delete_module", /*Linux + 129*/
+ "get_kernel_syms", /*Linux + 130*/
+ "quotactl", /*Linux + 131*/
+ "getpgid", /*Linux + 132*/
+ "fchdir", /*Linux + 133*/
+ "bdflush", /*Linux + 134*/
+ "sysfs", /*Linux + 135*/
+ "personality", /*Linux + 136*/
+ "afs_syscall", /*Linux + 137*/ /* Syscall for Andrew File System */
+ "setfsuid", /*Linux + 138*/
+ "setfsgid", /*Linux + 139*/
+ "_llseek", /*Linux + 140*/
+ "getdents", /*Linux + 141*/
+ "_newselect", /*Linux + 142*/
+ "flock", /*Linux + 143*/
+ "msync", /*Linux + 144*/
+ "readv", /*Linux + 145*/
+ "writev", /*Linux + 146*/
+ "cacheflush", /*Linux + 147*/
+ "cachectl", /*Linux + 148*/
+ "sysmips", /*Linux + 149*/
+ "unused150", /*Linux + 150*/
+ "getsid", /*Linux + 151*/
+ "fdatasync", /*Linux + 152*/
+ "_sysctl", /*Linux + 153*/
+ "mlock", /*Linux + 154*/
+ "munlock", /*Linux + 155*/
+ "mlockall", /*Linux + 156*/
+ "munlockall", /*Linux + 157*/
+ "sched_setparam", /*Linux + 158*/
+ "sched_getparam", /*Linux + 159*/
+ "sched_setscheduler", /*Linux + 160*/
+ "sched_getscheduler", /*Linux + 161*/
+ "sched_yield", /*Linux + 162*/
+ "sched_get_priority_max", /*Linux + 163*/
+ "sched_get_priority_min", /*Linux + 164*/
+ "sched_rr_get_interval", /*Linux + 165*/
+ "nanosleep", /*Linux + 166*/
+ "mremap", /*Linux + 167*/
+ "accept", /*Linux + 168*/
+ "bind", /*Linux + 169*/
+ "connect", /*Linux + 170*/
+ "getpeername", /*Linux + 171*/
+ "getsockname", /*Linux + 172*/
+ "getsockopt", /*Linux + 173*/
+ "listen", /*Linux + 174*/
+ "recv", /*Linux + 175*/
+ "recvfrom", /*Linux + 176*/
+ "recvmsg", /*Linux + 177*/
+ "send", /*Linux + 178*/
+ "sendmsg", /*Linux + 179*/
+ "sendto", /*Linux + 180*/
+ "setsockopt", /*Linux + 181*/
+ "shutdown", /*Linux + 182*/
+ "socket", /*Linux + 183*/
+ "socketpair", /*Linux + 184*/
+ "setresuid", /*Linux + 185*/
+ "getresuid", /*Linux + 186*/
+ "query_module", /*Linux + 187*/
+ "poll", /*Linux + 188*/
+ "nfsservctl", /*Linux + 189*/
+ "setresgid", /*Linux + 190*/
+ "getresgid", /*Linux + 191*/
+ "prctl", /*Linux + 192*/
+ "rt_sigreturn", /*Linux + 193*/
+ "rt_sigaction", /*Linux + 194*/
+ "rt_sigprocmask", /*Linux + 195*/
+ "rt_sigpending", /*Linux + 196*/
+ "rt_sigtimedwait", /*Linux + 197*/
+ "rt_sigqueueinfo", /*Linux + 198*/
+ "rt_sigsuspend", /*Linux + 199*/
+ "pread", /*Linux + 200*/
+ "pwrite", /*Linux + 201*/
+ "chown", /*Linux + 202*/
+ "getcwd", /*Linux + 203*/
+ "capget", /*Linux + 204*/
+ "capset", /*Linux + 205*/
+ "sigaltstack", /*Linux + 206*/
+ "sendfile", /*Linux + 207*/
+ "getpmsg", /*Linux + 208*/
+ "putpmsg", /*Linux + 209*/
+ "mmap2", /*Linux + 210*/
+ "truncate64", /*Linux + 211*/
+ "ftruncate64", /*Linux + 212*/
+ "stat64", /*Linux + 213*/
+ "lstat64", /*Linux + 214*/
+ "fstat64", /*Linux + 215*/
+ "pivot_root", /*Linux + 216*/
+ "mincore", /*Linux + 217*/
+ "madvise", /*Linux + 218*/
+ "getdents64", /*Linux + 219*/
+ "fcntl64", /*Linux + 220*/
+ "security", /*Linux + 221*/
+ "gettid", /*Linux + 222*/
+ "readahead", /*Linux + 223*/
+ "setxattr", /*Linux + 224*/
+ "lsetxattr", /*Linux + 225*/
+ "fsetxattr", /*Linux + 226*/
+ "getxattr", /*Linux + 227*/
+ "lgetxattr", /*Linux + 228*/
+ "fgetxattr", /*Linux + 229*/
+ "listxattr", /*Linux + 230*/
+ "llistxattr", /*Linux + 231*/
+ "flistxattr", /*Linux + 232*/
+ "removexattr", /*Linux + 233*/
+ "lremovexattr", /*Linux + 234*/
+ "fremovexattr", /*Linux + 235*/
+ "tkill", /*Linux + 236*/
+ "sendfile64", /*Linux + 237*/
+ "futex", /*Linux + 238*/
+ "sched_setaffinity", /*Linux + 239*/
+ "sched_getaffinity", /*Linux + 240*/
diff --git a/sysdeps/linux-gnu/mipsel/trace.c b/sysdeps/linux-gnu/mipsel/trace.c
new file mode 100644
index 0000000..ff94930
--- /dev/null
+++ b/sysdeps/linux-gnu/mipsel/trace.c
@@ -0,0 +1,167 @@
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+#include "debug.h"
+#include "common.h"
+#include "mipsel.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
+
+
+/**
+ \addtogroup mipsel Mipsel specific functions.
+
+ These are the functions that it looks like I need to implement in
+ order to get ltrace to work on our target.
+
+ @{
+ */
+
+/**
+ \param proc The process that had an event.
+
+ Called by \c next_event() right after the return from wait.
+
+ Most targets just return here. A couple use proc->arch_ptr for a
+ private data area.
+ */
+void
+get_arch_dep(Process *proc) {
+}
+
+/**
+ \param proc Process that had event.
+ \param status From \c wait()
+ \param sysnum 0-based syscall number.
+ \return 1 if syscall, 2 if sysret, 0 otherwise.
+
+ Called by \c next_event() after the call to get_arch_dep()
+
+ It seems that the ptrace call trips twice on a system call, once
+ just before the system call and once when it returns. Both times,
+ the pc points at the instruction just after the mipsel "syscall"
+ instruction.
+
+ There are several possiblities for system call sets, each is offset
+ by a base from the others. On our system, it looks like the base
+ for the system calls is 4000.
+ */
+int
+syscall_p(Process *proc, int status, int *sysnum) {
+ if (WIFSTOPPED(status)
+ && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
+ /* get the user's pc (plus 8) */
+ long pc = (long)get_instruction_pointer(proc);
+ /* fetch the SWI instruction */
+ int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 4, 0);
+ int num = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 8, 0);
+
+ /*
+ On a mipsel, syscall looks like:
+ 24040fa1 li v0, 0x0fa1 # 4001 --> _exit syscall
+ 0000000c syscall
+ */
+ if(insn!=0x0000000c){
+ return 0;
+ }
+
+ *sysnum = (num & 0xFFFF) - 4000;
+ /* if it is a syscall, return 1 or 2 */
+ 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) {
+ return 1;
+ }
+ }
+ return 0;
+}
+/**
+ \param type Function/syscall call or return.
+ \param proc The process that had an event.
+ \param arg_num -1 for return value,
+ \return The argument to fetch.
+
+ A couple of assumptions.
+
+- Type is LT_TOF_FUNCTIONR or LT_TOF_SYSCALLR if arg_num==-1. These
+ types are only used in calls for output_right(), which only uses -1
+ for arg_num.
+- Type is LT_TOF_FUNCTION or LT_TOF_SYSCALL for args 0...4.
+- I'm only displaying the first 4 args (Registers a0..a3). Good
+ enough for now.
+
+ Mipsel conventions seem to be:
+- syscall parameters: r4...r9
+- syscall return: if(!a3){ return v0;} else{ errno=v0;return -1;}
+- function call: r4..r7. Not sure how to get arg number 5.
+- function return: v0
+
+The argument registers are wiped by a call, so it is a mistake to ask
+for arguments on a return. If ltrace does this, we will need to cache
+arguments somewhere on the call.
+
+I'm not doing any floating point support here.
+
+*/
+long
+gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) {
+ long ret;
+ debug(2,"type %d arg %d",type,arg_num);
+ if (type == LT_TOF_FUNCTION || type == LT_TOF_SYSCALL){
+ if(arg_num <4){
+ ret=ptrace(PTRACE_PEEKUSER,proc->pid,off_a0+arg_num,0);
+ debug(2,"ret = %#lx",ret);
+ return ret;
+ } else {
+ // If we need this, I think we can look at [sp+16] for arg_num==4.
+ CP;
+ return 0;
+ }
+ }
+ if(arg_num>=0){
+ fprintf(stderr,"args on return?");
+ }
+ if(type == LT_TOF_FUNCTIONR) {
+ return ptrace(PTRACE_PEEKUSER,proc->pid,off_v0,0);
+ }
+ if (type == LT_TOF_SYSCALLR) {
+ unsigned a3=ptrace(PTRACE_PEEKUSER, proc->pid,off_a3,0);
+ unsigned v0=ptrace(PTRACE_PEEKUSER, proc->pid,off_v0,0);
+ if(!a3){
+ return v0;
+ }
+ return -1;
+ }
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ return 0;
+}
+
+/**
+ \param type Type of call/return
+ \param proc Process to work with.
+
+ Called by \c output_left(), which is called on a syscall or
+ function.
+
+ The other architectures stub this out, but seems to be the place to
+ stash off the arguments on a call so we have them on the return.
+
+*/
+void
+save_register_args(enum tof type, Process *proc) {
+}
+
+/**@}*/
diff --git a/sysdeps/linux-gnu/mksignalent b/sysdeps/linux-gnu/mksignalent
new file mode 100755
index 0000000..316d81f
--- /dev/null
+++ b/sysdeps/linux-gnu/mksignalent
@@ -0,0 +1,33 @@
+#!/usr/bin/awk -f
+
+# hack expression to generate arch/signalent.h from <asm/signal.h>
+# It reads from stdin and writes to stdout
+
+BEGIN {
+ max=0;
+}
+
+{
+ if (($1 ~ /^#define$/) && (!SIGNAL[$3]) && ($2 ~ /^SIG[A-Z]/) \
+ && ($2 !~ /^SIGRTMIN$/) && ($2 !~ /^SIGRTMAX$/) && ($2 !~ /^SIGSTKSZ$/) \
+ && ($3>=0) && ($3<=1000)) {
+ SIGNAL[$3]=$2;
+ if ($3 > max) {
+ max=$3;
+ }
+ }
+}
+
+END {
+ for(i=0; i<=max; i++) {
+ if (!SIGNAL[i]) {
+ SIGNAL[i] = "SIG_" i;
+ }
+ pad = 16 - length(SIGNAL[i]);
+ if (pad<1) {
+ pad=1;
+ }
+ printf("\t\"%s\",%*s/* %d */\n", SIGNAL[i], pad, "", i);
+ }
+}
+
diff --git a/sysdeps/linux-gnu/mksyscallent b/sysdeps/linux-gnu/mksyscallent
new file mode 100755
index 0000000..e0c3ec7
--- /dev/null
+++ b/sysdeps/linux-gnu/mksyscallent
@@ -0,0 +1,45 @@
+#!/usr/bin/awk -f
+
+# hack expression to generate arch/syscallent.h from <asm/unistd.h>
+# It reads from stdin and writes to stdout
+# It should work OK on i386,m68k,arm,ia64
+# It does NOT work in mips, s390
+# It is untested in other architectures
+
+BEGIN {
+ max=0;
+ FS="[ \t\n()+]+";
+}
+
+{
+ #debug
+ #printf("/%s/%s/%s/%s/\n", $1, $2, $3, $4);
+ if (($1 ~ /^#define$/) && ($2 ~ /^__NR_/)) {
+ #ia64 syscalls are > 1000 (lower for x86 compat)
+ if (($3>=0) && ($3<=2000)) {
+ SYSCALL[$3]=substr($2,6);
+ if ($3 > max) {
+ max=$3;
+ }
+ } else if (($3 ~ /^__NR_SYSCALL_BASE$/) && ($4>=0) && ($4<=1000)) {
+ SYSCALL[$4]=substr($2,6);
+ if ($4 > max) {
+ max=$4;
+ }
+ }
+ }
+}
+
+END {
+ for(i=0; i<=max; i++) {
+ if (!SYSCALL[i]) {
+ SYSCALL[i] = i;
+ }
+ pad = 32 - length(SYSCALL[i]);
+ if (pad<1) {
+ pad=1;
+ }
+ printf("\t\"%s\",%*s/* %d */\n", SYSCALL[i], pad, "", i);
+ }
+}
+
diff --git a/sysdeps/linux-gnu/mksyscallent_s390 b/sysdeps/linux-gnu/mksyscallent_s390
new file mode 100644
index 0000000..73416d9
--- /dev/null
+++ b/sysdeps/linux-gnu/mksyscallent_s390
@@ -0,0 +1,38 @@
+#!/usr/bin/perl
+#
+# Generate syscall table for s390/s390x
+#
+# Use this on arch/s390/kernel/syscall.s after removing the first few
+# nonsyscall lines.
+#
+# cat syscall.s | mksyscallent_s390 > syscalls31.h
+# cat syscall.s | mksyscallent_s390 -x > syscalls64.h
+#
+
+use Getopt::Std;
+use integer;
+getopts('x');
+$i = 0;
+$s390x = 0;
+$opt_x and $s390x = 1;
+
+while (<>) {
+ chomp;
+
+ if ($s390x==1) {
+ s/^SYSCALL\([^,]*,//;
+ } else {
+ s/^SYSCALL\(//;
+ }
+
+ s/,.*//;
+ s/^sys_//;
+ s/^s390[x]*_//;
+ s/_glue$//;
+ s/^ni_syscall.*/$i/i;
+ $len = 32 - length();
+ $tab = $len / 8;
+ $space = $len % 8;
+ print " \"$_\"," ," " x $space , "\t" x $tab, " \/* $i \*\/\n";
+ $i++;
+}
diff --git a/sysdeps/linux-gnu/ppc/Makefile b/sysdeps/linux-gnu/ppc/Makefile
new file mode 100644
index 0000000..60d7531
--- /dev/null
+++ b/sysdeps/linux-gnu/ppc/Makefile
@@ -0,0 +1,10 @@
+OBJ = trace.o regs.o plt.o
+
+all: arch.o
+
+arch.o: $(OBJ)
+ $(CC) -nostdlib -r -o arch.o $(OBJ)
+
+clean:
+ $(RM) $(OBJ) arch.o
+
diff --git a/sysdeps/linux-gnu/ppc/arch.h b/sysdeps/linux-gnu/ppc/arch.h
new file mode 100644
index 0000000..711b4a3
--- /dev/null
+++ b/sysdeps/linux-gnu/ppc/arch.h
@@ -0,0 +1,24 @@
+#define BREAKPOINT_VALUE { 0x7f, 0xe0, 0x00, 0x08 }
+#define BREAKPOINT_LENGTH 4
+#define DECR_PC_AFTER_BREAK 0
+
+#define LT_ELFCLASS ELFCLASS32
+#define LT_ELF_MACHINE EM_PPC
+
+#ifdef __powerpc64__ // Says 'ltrace' is 64 bits, says nothing about target.
+#define LT_ELFCLASS2 ELFCLASS64
+#define LT_ELF_MACHINE2 EM_PPC64
+#define ARCH_SUPPORTS_OPD
+#endif
+
+#define PLT_REINITALISATION_BP "_start"
+
+/* Start of arch-specific functions. */
+#define ARCH_HAVE_UMOVELONG
+
+#define PPC_NOP { 0x60, 0x00, 0x00, 0x00 }
+#define PPC_NOP_LENGTH 4
+
+#if (PPC_NOP_LENGTH != BREAKPOINT_LENGTH)
+#error "Length of the breakpoint value not equal to the length of a nop instruction"
+#endif
diff --git a/sysdeps/linux-gnu/ppc/plt.c b/sysdeps/linux-gnu/ppc/plt.c
new file mode 100644
index 0000000..31830fb
--- /dev/null
+++ b/sysdeps/linux-gnu/ppc/plt.c
@@ -0,0 +1,54 @@
+#include <gelf.h>
+#include "common.h"
+
+GElf_Addr
+arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) {
+ return rela->r_offset;
+}
+
+void *
+sym2addr(Process *proc, struct library_symbol *sym) {
+ void *addr = sym->enter_addr;
+ long pt_ret;
+
+ debug(3, 0);
+
+ if (sym->plt_type != LS_TOPLT_POINT) {
+ return addr;
+ }
+
+ if (proc->pid == 0) {
+ return 0;
+ }
+
+ if (options.debug >= 3) {
+ xinfdump(proc->pid, (void *)(((long)addr-32)&0xfffffff0),
+ sizeof(void*)*8);
+ }
+
+ // On a PowerPC-64 system, a plt is three 64-bit words: the first is the
+ // 64-bit address of the routine. Before the PLT has been initialized,
+ // this will be 0x0. In fact, the symbol table won't have the plt's
+ // address even. Ater the PLT has been initialized, but before it has
+ // been resolved, the first word will be the address of the function in
+ // the dynamic linker that will reslove the PLT. After the PLT is
+ // resolved, this will will be the address of the routine whose symbol
+ // is in the symbol table.
+
+ // On a PowerPC-32 system, there are two types of PLTs: secure (new) and
+ // non-secure (old). For the secure case, the PLT is simply a pointer
+ // and we can treat it much as we do for the PowerPC-64 case. For the
+ // non-secure case, the PLT is executable code and we can put the
+ // break-point right in the PLT.
+
+ pt_ret = ptrace(PTRACE_PEEKTEXT, proc->pid, addr, 0);
+
+ if (proc->mask_32bit) {
+ // Assume big-endian.
+ addr = (void *)((pt_ret >> 32) & 0xffffffff);
+ } else {
+ addr = (void *)pt_ret;
+ }
+
+ return addr;
+}
diff --git a/sysdeps/linux-gnu/ppc/ptrace.h b/sysdeps/linux-gnu/ppc/ptrace.h
new file mode 100644
index 0000000..c3cbcb6
--- /dev/null
+++ b/sysdeps/linux-gnu/ppc/ptrace.h
@@ -0,0 +1 @@
+#include <sys/ptrace.h>
diff --git a/sysdeps/linux-gnu/ppc/regs.c b/sysdeps/linux-gnu/ppc/regs.c
new file mode 100644
index 0000000..eca58ff
--- /dev/null
+++ b/sysdeps/linux-gnu/ppc/regs.c
@@ -0,0 +1,47 @@
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+
+#include "common.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(Process *proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long)*PT_NIP, 0);
+}
+
+void
+set_instruction_pointer(Process *proc, void *addr) {
+ ptrace(PTRACE_POKEUSER, proc->pid, sizeof(long)*PT_NIP, addr);
+}
+
+void *
+get_stack_pointer(Process *proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long)*PT_R1, 0);
+}
+
+void *
+get_return_addr(Process *proc, void *stack_pointer) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long)*PT_LNK, 0);
+}
+
+void
+set_return_addr(Process *proc, void *addr) {
+ ptrace(PTRACE_POKEUSER, proc->pid, sizeof(long)*PT_LNK, addr);
+}
+
+/* Grab the value of CTR registers. */
+void *
+get_count_register (Process *proc) {
+ return (void *) ptrace (PTRACE_PEEKUSER, proc->pid,
+ sizeof (long) * PT_CTR, 0);
+}
diff --git a/sysdeps/linux-gnu/ppc/signalent.h b/sysdeps/linux-gnu/ppc/signalent.h
new file mode 100644
index 0000000..d58a36c
--- /dev/null
+++ b/sysdeps/linux-gnu/ppc/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/ppc/syscallent.h b/sysdeps/linux-gnu/ppc/syscallent.h
new file mode 100644
index 0000000..5ce5739
--- /dev/null
+++ b/sysdeps/linux-gnu/ppc/syscallent.h
@@ -0,0 +1,272 @@
+"0", /* 0 */
+ "exit", /* 1 */
+ "fork", /* 2 */
+ "read", /* 3 */
+ "write", /* 4 */
+ "open", /* 5 */
+ "close", /* 6 */
+ "waitpid", /* 7 */
+ "creat", /* 8 */
+ "link", /* 9 */
+ "unlink", /* 10 */
+ "execve", /* 11 */
+ "chdir", /* 12 */
+ "time", /* 13 */
+ "mknod", /* 14 */
+ "chmod", /* 15 */
+ "lchown", /* 16 */
+ "break", /* 17 */
+ "oldstat", /* 18 */
+ "lseek", /* 19 */
+ "getpid", /* 20 */
+ "mount", /* 21 */
+ "umount", /* 22 */
+ "setuid", /* 23 */
+ "getuid", /* 24 */
+ "stime", /* 25 */
+ "ptrace", /* 26 */
+ "alarm", /* 27 */
+ "oldfstat", /* 28 */
+ "pause", /* 29 */
+ "utime", /* 30 */
+ "stty", /* 31 */
+ "gtty", /* 32 */
+ "access", /* 33 */
+ "nice", /* 34 */
+ "ftime", /* 35 */
+ "sync", /* 36 */
+ "kill", /* 37 */
+ "rename", /* 38 */
+ "mkdir", /* 39 */
+ "rmdir", /* 40 */
+ "dup", /* 41 */
+ "pipe", /* 42 */
+ "times", /* 43 */
+ "prof", /* 44 */
+ "brk", /* 45 */
+ "setgid", /* 46 */
+ "getgid", /* 47 */
+ "signal", /* 48 */
+ "geteuid", /* 49 */
+ "getegid", /* 50 */
+ "acct", /* 51 */
+ "umount2", /* 52 */
+ "lock", /* 53 */
+ "ioctl", /* 54 */
+ "fcntl", /* 55 */
+ "mpx", /* 56 */
+ "setpgid", /* 57 */
+ "ulimit", /* 58 */
+ "oldolduname", /* 59 */
+ "umask", /* 60 */
+ "chroot", /* 61 */
+ "ustat", /* 62 */
+ "dup2", /* 63 */
+ "getppid", /* 64 */
+ "getpgrp", /* 65 */
+ "setsid", /* 66 */
+ "sigaction", /* 67 */
+ "sgetmask", /* 68 */
+ "ssetmask", /* 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 */
+ "select", /* 82 */
+ "symlink", /* 83 */
+ "oldlstat", /* 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 */
+ "profil", /* 98 */
+ "statfs", /* 99 */
+ "fstatfs", /* 100 */
+ "ioperm", /* 101 */
+ "socketcall", /* 102 */
+ "syslog", /* 103 */
+ "setitimer", /* 104 */
+ "getitimer", /* 105 */
+ "stat", /* 106 */
+ "lstat", /* 107 */
+ "fstat", /* 108 */
+ "olduname", /* 109 */
+ "iopl", /* 110 */
+ "vhangup", /* 111 */
+ "idle", /* 112 */
+ "vm86", /* 113 */
+ "wait4", /* 114 */
+ "swapoff", /* 115 */
+ "sysinfo", /* 116 */
+ "ipc", /* 117 */
+ "fsync", /* 118 */
+ "sigreturn", /* 119 */
+ "clone", /* 120 */
+ "setdomainname", /* 121 */
+ "uname", /* 122 */
+ "modify_ldt", /* 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 */
+ "query_module", /* 166 */
+ "poll", /* 167 */
+ "nfsservctl", /* 168 */
+ "setresgid", /* 169 */
+ "getresgid", /* 170 */
+ "prctl", /* 171 */
+ "rt_sigreturn", /* 172 */
+ "rt_sigaction", /* 173 */
+ "rt_sigprocmask", /* 174 */
+ "rt_sigpending", /* 175 */
+ "rt_sigtimedwait", /* 176 */
+ "rt_sigqueueinfo", /* 177 */
+ "rt_sigsuspend", /* 178 */
+ "pread", /* 179 */
+ "pwrite", /* 180 */
+ "chown", /* 181 */
+ "getcwd", /* 182 */
+ "capget", /* 183 */
+ "capset", /* 184 */
+ "sigaltstack", /* 185 */
+ "sendfile", /* 186 */
+ "getpmsg", /* 187 */
+ "putpmsg", /* 188 */
+ "vfork", /* 189 */
+ "ugetrlimit", /* 190 */
+ "readahead", /* 191 */
+ "mmap2", /* 192 */
+ "truncate64", /* 193 */
+ "ftruncate64", /* 194 */
+ "stat64", /* 195 */
+ "lstat64", /* 196 */
+ "fstat64", /* 197 */
+ "pciconfig_read", /* 198 */
+ "pciconfig_write", /* 199 */
+ "pciconfig_iobase", /* 200 */
+ "multiplexer", /* 201 */
+ "getdents64", /* 202 */
+ "pivot_root", /* 203 */
+ "fcntl64", /* 204 */
+ "madvise", /* 205 */
+ "mincore", /* 206 */
+ "gettid", /* 207 */
+ "tkill", /* 208 */
+ "setxattr", /* 209 */
+ "lsetxattr", /* 210 */
+ "fsetxattr", /* 211 */
+ "getxattr", /* 212 */
+ "lgetxattr", /* 213 */
+ "fgetxattr", /* 214 */
+ "listxattr", /* 215 */
+ "llistxattr", /* 216 */
+ "flistxattr", /* 217 */
+ "removexattr", /* 218 */
+ "lremovexattr", /* 219 */
+ "fremovexattr", /* 220 */
+ "futex", /* 221 */
+ "sched_setaffinity", /* 222 */
+ "sched_getaffinity", /* 223 */
+ "224", /* 224 */
+ "tuxcall", /* 225 */
+ "sendfile64", /* 226 */
+ "io_setup", /* 227 */
+ "io_destroy", /* 228 */
+ "io_getevents", /* 229 */
+ "io_submit", /* 230 */
+ "io_cancel", /* 231 */
+ "set_tid_address", /* 232 */
+ "fadvise64", /* 233 */
+ "exit_group", /* 234 */
+ "lookup_dcookie", /* 235 */
+ "epoll_create", /* 236 */
+ "epoll_ctl", /* 237 */
+ "epoll_wait", /* 238 */
+ "remap_file_pages", /* 239 */
+ "timer_create", /* 240 */
+ "timer_settime", /* 241 */
+ "timer_gettime", /* 242 */
+ "timer_getoverrun", /* 243 */
+ "timer_delete", /* 244 */
+ "clock_settime", /* 245 */
+ "clock_gettime", /* 246 */
+ "clock_getres", /* 247 */
+ "clock_nanosleep", /* 248 */
+ "swapcontext", /* 249 */
+ "tgkill", /* 250 */
+ "utimes", /* 251 */
+ "statfs64", /* 252 */
+ "fstatfs64", /* 253 */
+ "fadvise64_64", /* 254 */
+ "rtas", /* 255 */
+ "mq_open", /* 262 */
+ "mq_unlink", /* 263 */
+ "mq_timedsend", /* 264 */
+ "mq_timedreceive", /* 265 */
+ "mq_notify", /* 266 */
+ "mq_getsetattr", /* 267 */
+ "kexec_load", /* 268 */
+ "add_key", /* 269 */
+ "request_key", /* 270 */
+ "keyctl", /* 271 */
+ "waitid", /* 272 */
+ "ioprio_set", /* 273 */
+ "ioprio_get", /* 274 */
+ "inotify_init", /* 275 */
+ "inotify_add_watch", /* 276 */
+ "inotify_rm_watch", /* 277 */
diff --git a/sysdeps/linux-gnu/ppc/trace.c b/sysdeps/linux-gnu/ppc/trace.c
new file mode 100644
index 0000000..81fb71d
--- /dev/null
+++ b/sysdeps/linux-gnu/ppc/trace.c
@@ -0,0 +1,155 @@
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+#include <elf.h>
+#include <errno.h>
+
+#include "common.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) {
+#ifdef __powerpc64__
+ if (proc->arch_ptr)
+ return;
+ proc->mask_32bit = (proc->e_machine == EM_PPC);
+ proc->arch_ptr = (void *)1;
+#endif
+}
+
+/* Returns 1 if syscall, 2 if sysret, 0 otherwise. */
+#define SYSCALL_INSN 0x44000002
+
+unsigned int greg = 3;
+unsigned int freg = 1;
+unsigned int vreg = 2;
+
+int
+syscall_p(Process *proc, int status, int *sysnum) {
+ if (WIFSTOPPED(status)
+ && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
+ long pc = (long)get_instruction_pointer(proc);
+ int insn =
+ (int)ptrace(PTRACE_PEEKTEXT, proc->pid, pc - sizeof(long),
+ 0);
+
+ if (insn == SYSCALL_INSN) {
+ *sysnum =
+ (int)ptrace(PTRACE_PEEKUSER, proc->pid,
+ sizeof(long) * PT_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;
+ }
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Grab functions arguments based on the PPC64 ABI. */
+long
+gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) {
+ long data;
+
+ if (type == LT_TOF_FUNCTIONR) {
+ if (info->type == ARGTYPE_FLOAT || info->type == ARGTYPE_DOUBLE)
+ return ptrace (PTRACE_PEEKUSER, proc->pid,
+ sizeof (long) * (PT_FPR0 + 1), 0);
+ else
+ return ptrace (PTRACE_PEEKUSER, proc->pid,
+ sizeof (long) * PT_R3, 0);
+ }
+
+ /* Check if we're entering a new function call to list parameters. If
+ so, initialize the register control variables to keep track of where
+ the parameters were stored. */
+ if (type == LT_TOF_FUNCTION && arg_num == 0) {
+ /* Initialize the set of registrers for parameter passing. */
+ greg = 3;
+ freg = 1;
+ vreg = 2;
+ }
+
+ if (info->type == ARGTYPE_FLOAT || info->type == ARGTYPE_DOUBLE) {
+ if (freg <= 13 || (proc->mask_32bit && freg <= 8)) {
+ data = ptrace (PTRACE_PEEKUSER, proc->pid,
+ sizeof (long) * (PT_FPR0 + freg), 0);
+
+ if (info->type == ARGTYPE_FLOAT) {
+ /* float values passed in FP registers are automatically
+ promoted to double. We need to convert it back to float
+ before printing. */
+ union { long val; float fval; double dval; } cvt;
+ cvt.val = data;
+ cvt.fval = (float) cvt.dval;
+ data = cvt.val;
+ }
+
+ freg++;
+ greg++;
+
+ return data;
+ }
+ }
+ else if (greg <= 10) {
+ data = ptrace (PTRACE_PEEKUSER, proc->pid,
+ sizeof (long) * greg, 0);
+ greg++;
+
+ return data;
+ }
+ else
+ return ptrace (PTRACE_PEEKDATA, proc->pid,
+ proc->stack_pointer + sizeof (long) *
+ (arg_num - 8), 0);
+
+ return 0;
+}
+
+void
+save_register_args(enum tof type, Process *proc) {
+}
+
+/* Read a single long from the process's memory address 'addr'. */
+int
+arch_umovelong (Process *proc, void *addr, long *result, arg_type_info *info) {
+ long pointed_to;
+
+ errno = 0;
+
+ pointed_to = ptrace (PTRACE_PEEKTEXT, proc->pid, addr, 0);
+
+ if (pointed_to == -1 && errno)
+ return -errno;
+
+ /* Since int's are 4-bytes (long is 8-bytes) in length for ppc64, we
+ need to shift the long values returned by ptrace to end up with
+ the correct value. */
+
+ if (info) {
+ if (info->type == ARGTYPE_INT || (proc->mask_32bit && (info->type == ARGTYPE_POINTER
+ || info->type == ARGTYPE_STRING))) {
+ pointed_to = pointed_to >> 32;
+
+ /* Make sure we have nothing in the upper word so we can
+ do a explicit cast from long to int later in the code. */
+ pointed_to &= 0x00000000ffffffff;
+ }
+ }
+
+ *result = pointed_to;
+ return 0;
+}
diff --git a/sysdeps/linux-gnu/proc.c b/sysdeps/linux-gnu/proc.c
new file mode 100644
index 0000000..4251c1d
--- /dev/null
+++ b/sysdeps/linux-gnu/proc.c
@@ -0,0 +1,36 @@
+#include "config.h"
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+
+/* /proc/pid doesn't exist just after the fork, and sometimes `ltrace'
+ * couldn't open it to find the executable. So it may be necessary to
+ * have a bit delay
+ */
+
+#define MAX_DELAY 100000 /* 100000 microseconds = 0.1 seconds */
+
+/*
+ * Returns a (malloc'd) file name corresponding to a running pid
+ */
+char *
+pid2name(pid_t pid) {
+ char proc_exe[1024];
+
+ if (!kill(pid, 0)) {
+ int delay = 0;
+
+ sprintf(proc_exe, "/proc/%d/exe", pid);
+
+ while (delay < MAX_DELAY) {
+ if (!access(proc_exe, F_OK)) {
+ return strdup(proc_exe);
+ }
+ delay += 1000; /* 1 milisecond */
+ }
+ }
+ return NULL;
+}
diff --git a/sysdeps/linux-gnu/s390/Makefile b/sysdeps/linux-gnu/s390/Makefile
new file mode 100644
index 0000000..cea1b45
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/Makefile
@@ -0,0 +1,13 @@
+#
+# S/390 version
+# Copyright (C) 2001 IBM Poughkeepsie, IBM Corporation
+#
+OBJ = trace.o regs.o plt.o
+
+all: arch.o
+
+arch.o: $(OBJ)
+ $(CC) -nostdlib -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..03690b8
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/arch.h
@@ -0,0 +1,18 @@
+/*
+** S/390 version
+** (C) Copyright 2001 IBM Poughkeepsie, IBM Corporation
+*/
+
+#define BREAKPOINT_VALUE { 0x00, 0x01 }
+#define BREAKPOINT_LENGTH 2
+#define DECR_PC_AFTER_BREAK 2
+
+#ifdef __s390x__
+#define LT_ELFCLASS ELFCLASS64
+#define LT_ELF_MACHINE EM_S390
+#define LT_ELFCLASS2 ELFCLASS32
+#define LT_ELF_MACHINE2 EM_S390
+#else
+#define LT_ELFCLASS ELFCLASS32
+#define LT_ELF_MACHINE EM_S390
+#endif
diff --git a/sysdeps/linux-gnu/s390/plt.c b/sysdeps/linux-gnu/s390/plt.c
new file mode 100644
index 0000000..85a1dd1
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/plt.c
@@ -0,0 +1,12 @@
+#include <gelf.h>
+#include "common.h"
+
+GElf_Addr
+arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) {
+ return lte->plt_addr + (ndx + 1) * 32;
+}
+
+void *
+sym2addr(Process *proc, struct library_symbol *sym) {
+ return sym->enter_addr;
+}
diff --git a/sysdeps/linux-gnu/s390/ptrace.h b/sysdeps/linux-gnu/s390/ptrace.h
new file mode 100644
index 0000000..c3cbcb6
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/ptrace.h
@@ -0,0 +1 @@
+#include <sys/ptrace.h>
diff --git a/sysdeps/linux-gnu/s390/regs.c b/sysdeps/linux-gnu/s390/regs.c
new file mode 100644
index 0000000..169893e
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/regs.c
@@ -0,0 +1,75 @@
+/*
+** S/390 version
+** Copyright (C) 2001 IBM Poughkeepsie, IBM Corporation
+*/
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+
+#include "common.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
+
+#ifdef __s390x__
+#define PSW_MASK 0xffffffffffffffff
+#define PSW_MASK31 0x7fffffff
+#else
+#define PSW_MASK 0x7fffffff
+#endif
+
+void *
+get_instruction_pointer(Process *proc) {
+ long ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_PSWADDR, 0) & PSW_MASK;
+#ifdef __s390x__
+ if (proc->mask_32bit)
+ ret &= PSW_MASK31;
+#endif
+ return (void *)ret;
+}
+
+void
+set_instruction_pointer(Process *proc, void *addr) {
+#ifdef __s390x__
+ if (proc->mask_32bit)
+ addr = (void *)((long)addr & PSW_MASK31);
+#endif
+ ptrace(PTRACE_POKEUSER, proc->pid, PT_PSWADDR, addr);
+}
+
+void *
+get_stack_pointer(Process *proc) {
+ long ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR15, 0) & PSW_MASK;
+#ifdef __s390x__
+ if (proc->mask_32bit)
+ ret &= PSW_MASK31;
+#endif
+ return (void *)ret;
+}
+
+void *
+get_return_addr(Process *proc, void *stack_pointer) {
+ long ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR14, 0) & PSW_MASK;
+#ifdef __s390x__
+ if (proc->mask_32bit)
+ ret &= PSW_MASK31;
+#endif
+ return (void *)ret;
+}
+
+void
+set_return_addr(Process *proc, void *addr) {
+#ifdef __s390x__
+ if (proc->mask_32bit)
+ addr = (void *)((long)addr & PSW_MASK31);
+#endif
+ ptrace(PTRACE_POKEUSER, proc->pid, PT_GPR14, addr);
+}
diff --git a/sysdeps/linux-gnu/s390/signalent.h b/sysdeps/linux-gnu/s390/signalent.h
new file mode 100644
index 0000000..35b74f1
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/signalent.h
@@ -0,0 +1,33 @@
+"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 */
+ "SIGUNUSED", /* 31 */
+ "SIGRTMIN", /* 32 */
diff --git a/sysdeps/linux-gnu/s390/signalent1.h b/sysdeps/linux-gnu/s390/signalent1.h
new file mode 100644
index 0000000..b5b6ca8
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/signalent1.h
@@ -0,0 +1 @@
+#include "s390/signalent.h"
diff --git a/sysdeps/linux-gnu/s390/syscallent.h b/sysdeps/linux-gnu/s390/syscallent.h
new file mode 100644
index 0000000..5a35d93
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/syscallent.h
@@ -0,0 +1,5 @@
+#ifdef __s390x__
+#include "s390/syscalls64.h"
+#else
+#include "s390/syscalls31.h"
+#endif
diff --git a/sysdeps/linux-gnu/s390/syscallent1.h b/sysdeps/linux-gnu/s390/syscallent1.h
new file mode 100644
index 0000000..c9fdc81
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/syscallent1.h
@@ -0,0 +1 @@
+#include "s390/syscalls31.h"
diff --git a/sysdeps/linux-gnu/s390/syscalls31.h b/sysdeps/linux-gnu/s390/syscalls31.h
new file mode 100644
index 0000000..42631eb
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/syscalls31.h
@@ -0,0 +1,310 @@
+ "0", /* 0 */
+ "exit", /* 1 */
+ "fork", /* 2 */
+ "read", /* 3 */
+ "write", /* 4 */
+ "open", /* 5 */
+ "close", /* 6 */
+ "restart_syscall", /* 7 */
+ "creat", /* 8 */
+ "link", /* 9 */
+ "unlink", /* 10 */
+ "execve", /* 11 */
+ "chdir", /* 12 */
+ "time", /* 13 */
+ "mknod", /* 14 */
+ "chmod", /* 15 */
+ "lchown16", /* 16 */
+ "17", /* 17 */
+ "18", /* 18 */
+ "lseek", /* 19 */
+ "getpid", /* 20 */
+ "mount", /* 21 */
+ "oldumount", /* 22 */
+ "setuid16", /* 23 */
+ "getuid16", /* 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 */
+ "setgid16", /* 46 */
+ "getgid16", /* 47 */
+ "signal", /* 48 */
+ "geteuid16", /* 49 */
+ "getegid16", /* 50 */
+ "acct", /* 51 */
+ "umount", /* 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 */
+ "setreuid16", /* 70 */
+ "setregid16", /* 71 */
+ "sigsuspend", /* 72 */
+ "sigpending", /* 73 */
+ "sethostname", /* 74 */
+ "setrlimit", /* 75 */
+ "old_getrlimit", /* 76 */
+ "getrusage", /* 77 */
+ "gettimeofday", /* 78 */
+ "settimeofday", /* 79 */
+ "getgroups16", /* 80 */
+ "setgroups16", /* 81 */
+ "82", /* 82 */
+ "symlink", /* 83 */
+ "84", /* 84 */
+ "readlink", /* 85 */
+ "uselib", /* 86 */
+ "swapon", /* 87 */
+ "reboot", /* 88 */
+ "89", /* 89 */
+ "old_mmap", /* 90 */
+ "munmap", /* 91 */
+ "truncate", /* 92 */
+ "ftruncate", /* 93 */
+ "fchmod", /* 94 */
+ "fchown16", /* 95 */
+ "getpriority", /* 96 */
+ "setpriority", /* 97 */
+ "98", /* 98 */
+ "statfs", /* 99 */
+ "fstatfs", /* 100 */
+ "101", /* 101 */
+ "socketcall", /* 102 */
+ "syslog", /* 103 */
+ "setitimer", /* 104 */
+ "getitimer", /* 105 */
+ "newstat", /* 106 */
+ "newlstat", /* 107 */
+ "newfstat", /* 108 */
+ "109", /* 109 */
+ "lookup_dcookie", /* 110 */
+ "vhangup", /* 111 */
+ "112", /* 112 */
+ "113", /* 113 */
+ "wait4", /* 114 */
+ "swapoff", /* 115 */
+ "sysinfo", /* 116 */
+ "ipc", /* 117 */
+ "fsync", /* 118 */
+ "sigreturn", /* 119 */
+ "clone", /* 120 */
+ "setdomainname", /* 121 */
+ "newuname", /* 122 */
+ "123", /* 123 */
+ "adjtimex", /* 124 */
+ "mprotect", /* 125 */
+ "sigprocmask", /* 126 */
+ "127", /* 127 */
+ "init_module", /* 128 */
+ "delete_module", /* 129 */
+ "130", /* 130 */
+ "quotactl", /* 131 */
+ "getpgid", /* 132 */
+ "fchdir", /* 133 */
+ "bdflush", /* 134 */
+ "sysfs", /* 135 */
+ "personality", /* 136 */
+ "137", /* 137 */
+ "setfsuid16", /* 138 */
+ "setfsgid16", /* 139 */
+ "llseek", /* 140 */
+ "getdents", /* 141 */
+ "select", /* 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 */
+ "setresuid16", /* 164 */
+ "getresuid16", /* 165 */
+ "166", /* 166 */
+ "167", /* 167 */
+ "poll", /* 168 */
+ "nfsservctl", /* 169 */
+ "setresgid16", /* 170 */
+ "getresgid16", /* 171 */
+ "prctl", /* 172 */
+ "rt_sigreturn", /* 173 */
+ "rt_sigaction", /* 174 */
+ "rt_sigprocmask", /* 175 */
+ "rt_sigpending", /* 176 */
+ "rt_sigtimedwait", /* 177 */
+ "rt_sigqueueinfo", /* 178 */
+ "rt_sigsuspend", /* 179 */
+ "pread64", /* 180 */
+ "pwrite64", /* 181 */
+ "chown16", /* 182 */
+ "getcwd", /* 183 */
+ "capget", /* 184 */
+ "capset", /* 185 */
+ "sigaltstack", /* 186 */
+ "sendfile", /* 187 */
+ "188", /* 188 */
+ "189", /* 189 */
+ "vfork", /* 190 */
+ "getrlimit", /* 191 */
+ "mmap2", /* 192 */
+ "truncate64", /* 193 */
+ "ftruncate64", /* 194 */
+ "stat64", /* 195 */
+ "lstat64", /* 196 */
+ "fstat64", /* 197 */
+ "lchown", /* 198 */
+ "getuid", /* 199 */
+ "getgid", /* 200 */
+ "geteuid", /* 201 */
+ "getegid", /* 202 */
+ "setreuid", /* 203 */
+ "setregid", /* 204 */
+ "getgroups", /* 205 */
+ "setgroups", /* 206 */
+ "fchown", /* 207 */
+ "setresuid", /* 208 */
+ "getresuid", /* 209 */
+ "setresgid", /* 210 */
+ "getresgid", /* 211 */
+ "chown", /* 212 */
+ "setuid", /* 213 */
+ "setgid", /* 214 */
+ "setfsuid", /* 215 */
+ "setfsgid", /* 216 */
+ "pivot_root", /* 217 */
+ "mincore", /* 218 */
+ "madvise", /* 219 */
+ "getdents64", /* 220 */
+ "fcntl64", /* 221 */
+ "readahead", /* 222 */
+ "sendfile64", /* 223 */
+ "setxattr", /* 224 */
+ "lsetxattr", /* 225 */
+ "fsetxattr", /* 226 */
+ "getxattr", /* 227 */
+ "lgetxattr", /* 228 */
+ "fgetxattr", /* 229 */
+ "listxattr", /* 230 */
+ "llistxattr", /* 231 */
+ "flistxattr", /* 232 */
+ "removexattr", /* 233 */
+ "lremovexattr", /* 234 */
+ "fremovexattr", /* 235 */
+ "gettid", /* 236 */
+ "tkill", /* 237 */
+ "futex", /* 238 */
+ "sched_setaffinity", /* 239 */
+ "sched_getaffinity", /* 240 */
+ "tgkill", /* 241 */
+ "242", /* 242 */
+ "io_setup", /* 243 */
+ "io_destroy", /* 244 */
+ "io_getevents", /* 245 */
+ "io_submit", /* 246 */
+ "io_cancel", /* 247 */
+ "exit_group", /* 248 */
+ "epoll_create", /* 249 */
+ "epoll_ctl", /* 250 */
+ "epoll_wait", /* 251 */
+ "set_tid_address", /* 252 */
+ "fadvise64", /* 253 */
+ "timer_create", /* 254 */
+ "timer_settime", /* 255 */
+ "timer_gettime", /* 256 */
+ "timer_getoverrun", /* 257 */
+ "timer_delete", /* 258 */
+ "clock_settime", /* 259 */
+ "clock_gettime", /* 260 */
+ "clock_getres", /* 261 */
+ "clock_nanosleep", /* 262 */
+ "263", /* 263 */
+ "fadvise64_64", /* 264 */
+ "statfs64", /* 265 */
+ "fstatfs64", /* 266 */
+ "remap_file_pages", /* 267 */
+ "268", /* 268 */
+ "269", /* 269 */
+ "270", /* 270 */
+ "mq_open", /* 271 */
+ "mq_unlink", /* 272 */
+ "mq_timedsend", /* 273 */
+ "mq_timedreceive", /* 274 */
+ "mq_notify", /* 275 */
+ "mq_getsetattr", /* 276 */
+ "kexec_load", /* 277 */
+ "add_key", /* 278 */
+ "request_key", /* 279 */
+ "keyctl", /* 280 */
+ "waitid", /* 281 */
+ "ioprio_set", /* 282 */
+ "ioprio_get", /* 283 */
+ "inotify_init", /* 284 */
+ "inotify_add_watch", /* 285 */
+ "inotify_rm_watch", /* 286 */
+ "287", /* 287 */
+ "openat", /* 288 */
+ "mkdirat", /* 289 */
+ "mknodat", /* 290 */
+ "fchownat", /* 291 */
+ "futimesat", /* 292 */
+ "fstatat64", /* 293 */
+ "unlinkat", /* 294 */
+ "renameat", /* 295 */
+ "linkat", /* 296 */
+ "symlinkat", /* 297 */
+ "readlinkat", /* 298 */
+ "fchmodat", /* 299 */
+ "faccessat", /* 300 */
+ "pselect6", /* 301 */
+ "ppoll", /* 302 */
+ "unshare", /* 303 */
+ "set_robust_list", /* 304 */
+ "get_robust_list", /* 305 */
+ "splice", /* 306 */
+ "sync_file_range", /* 307 */
+ "tee", /* 308 */
+ "vmsplice", /* 309 */
diff --git a/sysdeps/linux-gnu/s390/syscalls64.h b/sysdeps/linux-gnu/s390/syscalls64.h
new file mode 100644
index 0000000..97be52c
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/syscalls64.h
@@ -0,0 +1,310 @@
+ "0", /* 0 */
+ "exit", /* 1 */
+ "fork", /* 2 */
+ "read", /* 3 */
+ "write", /* 4 */
+ "open", /* 5 */
+ "close", /* 6 */
+ "restart_syscall", /* 7 */
+ "creat", /* 8 */
+ "link", /* 9 */
+ "unlink", /* 10 */
+ "execve", /* 11 */
+ "chdir", /* 12 */
+ "13", /* 13 */
+ "mknod", /* 14 */
+ "chmod", /* 15 */
+ "16", /* 16 */
+ "17", /* 17 */
+ "18", /* 18 */
+ "lseek", /* 19 */
+ "getpid", /* 20 */
+ "mount", /* 21 */
+ "oldumount", /* 22 */
+ "23", /* 23 */
+ "24", /* 24 */
+ "25", /* 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 */
+ "46", /* 46 */
+ "47", /* 47 */
+ "signal", /* 48 */
+ "49", /* 49 */
+ "50", /* 50 */
+ "acct", /* 51 */
+ "umount", /* 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 */
+ "70", /* 70 */
+ "71", /* 71 */
+ "sigsuspend", /* 72 */
+ "sigpending", /* 73 */
+ "sethostname", /* 74 */
+ "setrlimit", /* 75 */
+ "getrlimit", /* 76 */
+ "getrusage", /* 77 */
+ "gettimeofday", /* 78 */
+ "settimeofday", /* 79 */
+ "80", /* 80 */
+ "81", /* 81 */
+ "82", /* 82 */
+ "symlink", /* 83 */
+ "84", /* 84 */
+ "readlink", /* 85 */
+ "uselib", /* 86 */
+ "swapon", /* 87 */
+ "reboot", /* 88 */
+ "89", /* 89 */
+ "old_mmap", /* 90 */
+ "munmap", /* 91 */
+ "truncate", /* 92 */
+ "ftruncate", /* 93 */
+ "fchmod", /* 94 */
+ "95", /* 95 */
+ "getpriority", /* 96 */
+ "setpriority", /* 97 */
+ "98", /* 98 */
+ "statfs", /* 99 */
+ "fstatfs", /* 100 */
+ "101", /* 101 */
+ "socketcall", /* 102 */
+ "syslog", /* 103 */
+ "setitimer", /* 104 */
+ "getitimer", /* 105 */
+ "newstat", /* 106 */
+ "newlstat", /* 107 */
+ "newfstat", /* 108 */
+ "109", /* 109 */
+ "lookup_dcookie", /* 110 */
+ "vhangup", /* 111 */
+ "112", /* 112 */
+ "113", /* 113 */
+ "wait4", /* 114 */
+ "swapoff", /* 115 */
+ "sysinfo", /* 116 */
+ "ipc", /* 117 */
+ "fsync", /* 118 */
+ "sigreturn", /* 119 */
+ "clone", /* 120 */
+ "setdomainname", /* 121 */
+ "newuname", /* 122 */
+ "123", /* 123 */
+ "adjtimex", /* 124 */
+ "mprotect", /* 125 */
+ "sigprocmask", /* 126 */
+ "127", /* 127 */
+ "init_module", /* 128 */
+ "delete_module", /* 129 */
+ "130", /* 130 */
+ "quotactl", /* 131 */
+ "getpgid", /* 132 */
+ "fchdir", /* 133 */
+ "bdflush", /* 134 */
+ "sysfs", /* 135 */
+ "personality", /* 136 */
+ "137", /* 137 */
+ "138", /* 138 */
+ "139", /* 139 */
+ "llseek", /* 140 */
+ "getdents", /* 141 */
+ "select", /* 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 */
+ "164", /* 164 */
+ "165", /* 165 */
+ "166", /* 166 */
+ "167", /* 167 */
+ "poll", /* 168 */
+ "nfsservctl", /* 169 */
+ "170", /* 170 */
+ "171", /* 171 */
+ "prctl", /* 172 */
+ "rt_sigreturn", /* 173 */
+ "rt_sigaction", /* 174 */
+ "rt_sigprocmask", /* 175 */
+ "rt_sigpending", /* 176 */
+ "rt_sigtimedwait", /* 177 */
+ "rt_sigqueueinfo", /* 178 */
+ "rt_sigsuspend", /* 179 */
+ "pread64", /* 180 */
+ "pwrite64", /* 181 */
+ "182", /* 182 */
+ "getcwd", /* 183 */
+ "capget", /* 184 */
+ "capset", /* 185 */
+ "sigaltstack", /* 186 */
+ "sendfile64", /* 187 */
+ "188", /* 188 */
+ "189", /* 189 */
+ "vfork", /* 190 */
+ "getrlimit", /* 191 */
+ "mmap2", /* 192 */
+ "193", /* 193 */
+ "194", /* 194 */
+ "195", /* 195 */
+ "196", /* 196 */
+ "197", /* 197 */
+ "lchown", /* 198 */
+ "getuid", /* 199 */
+ "getgid", /* 200 */
+ "geteuid", /* 201 */
+ "getegid", /* 202 */
+ "setreuid", /* 203 */
+ "setregid", /* 204 */
+ "getgroups", /* 205 */
+ "setgroups", /* 206 */
+ "fchown", /* 207 */
+ "setresuid", /* 208 */
+ "getresuid", /* 209 */
+ "setresgid", /* 210 */
+ "getresgid", /* 211 */
+ "chown", /* 212 */
+ "setuid", /* 213 */
+ "setgid", /* 214 */
+ "setfsuid", /* 215 */
+ "setfsgid", /* 216 */
+ "pivot_root", /* 217 */
+ "mincore", /* 218 */
+ "madvise", /* 219 */
+ "getdents64", /* 220 */
+ "221", /* 221 */
+ "readahead", /* 222 */
+ "223", /* 223 */
+ "setxattr", /* 224 */
+ "lsetxattr", /* 225 */
+ "fsetxattr", /* 226 */
+ "getxattr", /* 227 */
+ "lgetxattr", /* 228 */
+ "fgetxattr", /* 229 */
+ "listxattr", /* 230 */
+ "llistxattr", /* 231 */
+ "flistxattr", /* 232 */
+ "removexattr", /* 233 */
+ "lremovexattr", /* 234 */
+ "fremovexattr", /* 235 */
+ "gettid", /* 236 */
+ "tkill", /* 237 */
+ "futex", /* 238 */
+ "sched_setaffinity", /* 239 */
+ "sched_getaffinity", /* 240 */
+ "tgkill", /* 241 */
+ "242", /* 242 */
+ "io_setup", /* 243 */
+ "io_destroy", /* 244 */
+ "io_getevents", /* 245 */
+ "io_submit", /* 246 */
+ "io_cancel", /* 247 */
+ "exit_group", /* 248 */
+ "epoll_create", /* 249 */
+ "epoll_ctl", /* 250 */
+ "epoll_wait", /* 251 */
+ "set_tid_address", /* 252 */
+ "fadvise64_64", /* 253 */
+ "timer_create", /* 254 */
+ "timer_settime", /* 255 */
+ "timer_gettime", /* 256 */
+ "timer_getoverrun", /* 257 */
+ "timer_delete", /* 258 */
+ "clock_settime", /* 259 */
+ "clock_gettime", /* 260 */
+ "clock_getres", /* 261 */
+ "clock_nanosleep", /* 262 */
+ "263", /* 263 */
+ "264", /* 264 */
+ "statfs64", /* 265 */
+ "fstatfs64", /* 266 */
+ "remap_file_pages", /* 267 */
+ "268", /* 268 */
+ "269", /* 269 */
+ "270", /* 270 */
+ "mq_open", /* 271 */
+ "mq_unlink", /* 272 */
+ "mq_timedsend", /* 273 */
+ "mq_timedreceive", /* 274 */
+ "mq_notify", /* 275 */
+ "mq_getsetattr", /* 276 */
+ "kexec_load", /* 277 */
+ "add_key", /* 278 */
+ "request_key", /* 279 */
+ "keyctl", /* 280 */
+ "waitid", /* 281 */
+ "ioprio_set", /* 282 */
+ "ioprio_get", /* 283 */
+ "inotify_init", /* 284 */
+ "inotify_add_watch", /* 285 */
+ "inotify_rm_watch", /* 286 */
+ "287", /* 287 */
+ "openat", /* 288 */
+ "mkdirat", /* 289 */
+ "mknodat", /* 290 */
+ "fchownat", /* 291 */
+ "futimesat", /* 292 */
+ "newfstatat", /* 293 */
+ "unlinkat", /* 294 */
+ "renameat", /* 295 */
+ "linkat", /* 296 */
+ "symlinkat", /* 297 */
+ "readlinkat", /* 298 */
+ "fchmodat", /* 299 */
+ "faccessat", /* 300 */
+ "pselect6", /* 301 */
+ "ppoll", /* 302 */
+ "unshare", /* 303 */
+ "set_robust_list", /* 304 */
+ "get_robust_list", /* 305 */
+ "splice", /* 306 */
+ "sync_file_range", /* 307 */
+ "tee", /* 308 */
+ "vmsplice", /* 309 */
diff --git a/sysdeps/linux-gnu/s390/trace.c b/sysdeps/linux-gnu/s390/trace.c
new file mode 100644
index 0000000..9df2437
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/trace.c
@@ -0,0 +1,198 @@
+/*
+** S390 specific part of trace.c
+**
+** Other routines are in ../trace.c and need to be combined
+** at link time with this code.
+**
+** Copyright (C) 2001,2005 IBM Corp.
+*/
+
+#include "config.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+
+#include "common.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) {
+#ifdef __s390x__
+ unsigned long psw;
+
+ if (proc->arch_ptr)
+ return;
+
+ psw = ptrace(PTRACE_PEEKUSER, proc->pid, PT_PSWMASK, 0);
+
+ if ((psw & 0x000000180000000) == 0x000000080000000) {
+ proc->mask_32bit = 1;
+ proc->personality = 1;
+ }
+
+ proc->arch_ptr = (void *)1;
+#endif
+}
+
+/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
+ */
+int
+syscall_p(Process *proc, int status, int *sysnum) {
+ long pc, opcode, offset_reg, scno, tmp;
+ void *svc_addr;
+ int gpr_offset[16] = { PT_GPR0, PT_GPR1, PT_ORIGGPR2, PT_GPR3,
+ PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
+ PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
+ PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15
+ };
+
+ if (WIFSTOPPED(status)
+ && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
+
+ /*
+ * If we have PTRACE_O_TRACESYSGOOD and we have the new style
+ * of passing the system call number to user space via PT_GPR2
+ * then the task is quite easy.
+ */
+
+ *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR2, 0);
+
+ if (proc->tracesysgood) {
+ /* System call was encountered... */
+ if (proc->callstack_depth > 0 &&
+ proc->callstack[proc->callstack_depth -
+ 1].is_syscall) {
+ /* syscall exit */
+ *sysnum =
+ proc->callstack[proc->callstack_depth -
+ 1].c_un.syscall;
+ return 2;
+ } else {
+ /* syscall enter */
+ if (*sysnum != -ENOSYS)
+ return 1;
+ }
+ }
+
+ /*
+ * At least one of the two requirements mentioned above is not
+ * met. Therefore the fun part starts here:
+ * We try to do some instruction decoding without even knowing
+ * the instruction code length of the last instruction executed.
+ * Needs to be done to get the system call number or to decide
+ * if we reached a breakpoint or even checking for a completely
+ * unrelated instruction.
+ * Just a heuristic that most of the time appears to work...
+ */
+
+ pc = ptrace(PTRACE_PEEKUSER, proc->pid, PT_PSWADDR, 0);
+ opcode = ptrace(PTRACE_PEEKTEXT, proc->pid,
+ (char *)(pc - sizeof(long)), 0);
+
+ if ((opcode & 0xffff) == 0x0001) {
+ /* Breakpoint */
+ return 0;
+ } else if ((opcode & 0xff00) == 0x0a00) {
+ /* SVC opcode */
+ scno = opcode & 0xff;
+ } else if ((opcode & 0xff000000) == 0x44000000) {
+ /* Instruction decoding of EXECUTE... */
+ svc_addr = (void *)(opcode & 0xfff);
+
+ offset_reg = (opcode & 0x000f0000) >> 16;
+ if (offset_reg)
+ svc_addr += ptrace(PTRACE_PEEKUSER, proc->pid,
+ gpr_offset[offset_reg], 0);
+
+ offset_reg = (opcode & 0x0000f000) >> 12;
+ if (offset_reg)
+ svc_addr += ptrace(PTRACE_PEEKUSER, proc->pid,
+ gpr_offset[offset_reg], 0);
+
+ scno = ptrace(PTRACE_PEEKTEXT, proc->pid, svc_addr, 0);
+#ifdef __s390x__
+ scno >>= 48;
+#else
+ scno >>= 16;
+#endif
+ if ((scno & 0xff00) != 0x0a000)
+ return 0;
+
+ tmp = 0;
+ offset_reg = (opcode & 0x00f00000) >> 20;
+ if (offset_reg)
+ tmp = ptrace(PTRACE_PEEKUSER, proc->pid,
+ gpr_offset[offset_reg], 0);
+
+ scno = (scno | tmp) & 0xff;
+ } else {
+ /* No opcode related to syscall handling */
+ return 0;
+ }
+
+ if (scno == 0)
+ scno = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR1, 0);
+
+ *sysnum = scno;
+
+ /* System call was encountered... */
+ if (proc->callstack_depth > 0 &&
+ proc->callstack[proc->callstack_depth - 1].is_syscall) {
+ return 2;
+ } else {
+ return 1;
+ }
+ }
+ /* Unknown status... */
+ return 0;
+}
+
+long
+gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) {
+ long ret;
+
+ switch (arg_num) {
+ case -1: /* return value */
+ ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR2, 0);
+ break;
+ case 0:
+ ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_ORIGGPR2, 0);
+ break;
+ case 1:
+ ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR3, 0);
+ break;
+ case 2:
+ ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR4, 0);
+ break;
+ case 3:
+ ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR5, 0);
+ break;
+ case 4:
+ ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR6, 0);
+ break;
+ default:
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(2);
+ }
+#ifdef __s390x__
+ if (proc->mask_32bit)
+ ret &= 0xffffffff;
+#endif
+ return ret;
+}
+
+void
+save_register_args(enum tof type, Process *proc) {
+}
diff --git a/sysdeps/linux-gnu/sparc/Makefile b/sysdeps/linux-gnu/sparc/Makefile
new file mode 100644
index 0000000..b3914e5
--- /dev/null
+++ b/sysdeps/linux-gnu/sparc/Makefile
@@ -0,0 +1,9 @@
+OBJ = regs.o trace.o plt.o
+
+all: arch.o
+
+arch.o: $(OBJ)
+ $(CC) -nostdlib -r -o arch.o $(OBJ)
+
+clean:
+ $(RM) $(OBJ) arch.o
diff --git a/sysdeps/linux-gnu/sparc/arch.h b/sysdeps/linux-gnu/sparc/arch.h
new file mode 100644
index 0000000..75251b8
--- /dev/null
+++ b/sysdeps/linux-gnu/sparc/arch.h
@@ -0,0 +1,8 @@
+#define BREAKPOINT_VALUE {0x91, 0xd0, 0x20, 0x01}
+#define BREAKPOINT_LENGTH 4
+#define DECR_PC_AFTER_BREAK 0
+
+#define LT_ELFCLASS ELFCLASS32
+#define LT_ELF_MACHINE EM_SPARC
+#define LT_ELFCLASS2 ELFCLASS32
+#define LT_ELF_MACHINE2 EM_SPARC32PLUS
diff --git a/sysdeps/linux-gnu/sparc/plt.c b/sysdeps/linux-gnu/sparc/plt.c
new file mode 100644
index 0000000..f9e6d80
--- /dev/null
+++ b/sysdeps/linux-gnu/sparc/plt.c
@@ -0,0 +1,12 @@
+#include <gelf.h>
+#include "common.h"
+
+GElf_Addr
+arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) {
+ return rela->r_offset + 4;
+}
+
+void *
+sym2addr(Process *proc, struct library_symbol *sym) {
+ return sym->enter_addr;
+}
diff --git a/sysdeps/linux-gnu/sparc/ptrace.h b/sysdeps/linux-gnu/sparc/ptrace.h
new file mode 100644
index 0000000..bbaf01a
--- /dev/null
+++ b/sysdeps/linux-gnu/sparc/ptrace.h
@@ -0,0 +1,21 @@
+#undef PTRACE_GETREGS
+#undef PTRACE_SETREGS
+#undef PTRACE_GETFPREGS
+#undef PTRACE_SETFPREGS
+#include <sys/ptrace.h>
+#ifndef PTRACE_SUNDETACH
+#define PTRACE_SUNDETACH 11
+#endif
+#undef PT_DETACH
+#undef PTRACE_DETACH
+#define PT_DETACH PTRACE_SUNDETACH
+#define PTRACE_DETACH PTRACE_SUNDETACH
+
+#include <asm/ptrace.h>
+
+typedef struct {
+ int valid;
+ struct pt_regs regs;
+ unsigned int func_arg[6];
+ unsigned int sysc_arg[6];
+} proc_archdep;
diff --git a/sysdeps/linux-gnu/sparc/regs.c b/sysdeps/linux-gnu/sparc/regs.c
new file mode 100644
index 0000000..49d2729
--- /dev/null
+++ b/sysdeps/linux-gnu/sparc/regs.c
@@ -0,0 +1,49 @@
+#include "config.h"
+
+#include <sys/types.h>
+#include "ptrace.h"
+#include "common.h"
+
+void *
+get_instruction_pointer(Process *proc) {
+ proc_archdep *a = (proc_archdep *) (proc->arch_ptr);
+ if (a->valid)
+ return (void *)a->regs.pc;
+ return (void *)-1;
+}
+
+void
+set_instruction_pointer(Process *proc, void *addr) {
+ proc_archdep *a = (proc_archdep *) (proc->arch_ptr);
+ if (a->valid)
+ a->regs.pc = (long)addr;
+}
+
+void *
+get_stack_pointer(Process *proc) {
+ proc_archdep *a = (proc_archdep *) (proc->arch_ptr);
+ if (a->valid)
+ return (void *)a->regs.u_regs[UREG_I5];
+ return (void *)-1;
+}
+
+void *
+get_return_addr(Process *proc, void *stack_pointer) {
+ proc_archdep *a = (proc_archdep *) (proc->arch_ptr);
+ unsigned int t;
+ if (!a->valid)
+ return (void *)-1;
+ /* Work around structure returns */
+ t = ptrace(PTRACE_PEEKTEXT, proc->pid, a->regs.u_regs[UREG_I6] + 8, 0);
+ if (t < 0x400000)
+ return (void *)a->regs.u_regs[UREG_I6] + 12;
+ return (void *)a->regs.u_regs[UREG_I6] + 8;
+}
+
+void
+set_return_addr(Process *proc, void *addr) {
+ proc_archdep *a = (proc_archdep *) (proc->arch_ptr);
+ if (!a->valid)
+ return;
+ ptrace(PTRACE_POKETEXT, proc->pid, a->regs.u_regs[UREG_I6] + 8, addr);
+}
diff --git a/sysdeps/linux-gnu/sparc/signalent.h b/sysdeps/linux-gnu/sparc/signalent.h
new file mode 100644
index 0000000..d30f69e
--- /dev/null
+++ b/sysdeps/linux-gnu/sparc/signalent.h
@@ -0,0 +1,32 @@
+"SIG_0", /* 0 */
+ "SIGHUP", /* 1 */
+ "SIGINT", /* 2 */
+ "SIGQUIT", /* 3 */
+ "SIGILL", /* 4 */
+ "SIGTRAP", /* 5 */
+ "SIGABRT", /* 6 */
+ "SIGEMT", /* 7 */
+ "SIGFPE", /* 8 */
+ "SIGKILL", /* 9 */
+ "SIGBUS", /* 10 */
+ "SIGSEGV", /* 11 */
+ "SIGSYS", /* 12 */
+ "SIGPIPE", /* 13 */
+ "SIGALRM", /* 14 */
+ "SIGTERM", /* 15 */
+ "SIGURG", /* 16 */
+ "SIGSTOP", /* 17 */
+ "SIGTSTP", /* 18 */
+ "SIGCONT", /* 19 */
+ "SIGCHLD", /* 20 */
+ "SIGTTIN", /* 21 */
+ "SIGTTOU", /* 22 */
+ "SIGIO", /* 23 */
+ "SIGXCPU", /* 24 */
+ "SIGXFSZ", /* 25 */
+ "SIGVTALRM", /* 26 */
+ "SIGPROF", /* 27 */
+ "SIGWINCH", /* 28 */
+ "SIGLOST", /* 29 */
+ "SIGUSR1", /* 30 */
+ "SIGUSR2", /* 31 */
diff --git a/sysdeps/linux-gnu/sparc/syscallent.h b/sysdeps/linux-gnu/sparc/syscallent.h
new file mode 100644
index 0000000..96eeec9
--- /dev/null
+++ b/sysdeps/linux-gnu/sparc/syscallent.h
@@ -0,0 +1,284 @@
+"0", /* 0 */
+ "exit", /* 1 */
+ "fork", /* 2 */
+ "read", /* 3 */
+ "write", /* 4 */
+ "open", /* 5 */
+ "close", /* 6 */
+ "wait4", /* 7 */
+ "creat", /* 8 */
+ "link", /* 9 */
+ "unlink", /* 10 */
+ "execv", /* 11 */
+ "chdir", /* 12 */
+ "chown", /* 13 */
+ "mknod", /* 14 */
+ "chmod", /* 15 */
+ "lchown", /* 16 */
+ "brk", /* 17 */
+ "perfctr", /* 18 */
+ "lseek", /* 19 */
+ "getpid", /* 20 */
+ "capget", /* 21 */
+ "capset", /* 22 */
+ "setuid", /* 23 */
+ "getuid", /* 24 */
+ "25", /* 25 */
+ "ptrace", /* 26 */
+ "alarm", /* 27 */
+ "sigaltstack", /* 28 */
+ "pause", /* 29 */
+ "utime", /* 30 */
+ "lchown32", /* 31 */
+ "fchown32", /* 32 */
+ "access", /* 33 */
+ "nice", /* 34 */
+ "chown32", /* 35 */
+ "sync", /* 36 */
+ "kill", /* 37 */
+ "stat", /* 38 */
+ "sendfile", /* 39 */
+ "lstat", /* 40 */
+ "dup", /* 41 */
+ "pipe", /* 42 */
+ "times", /* 43 */
+ "getuid32", /* 44 */
+ "umount2", /* 45 */
+ "setgid", /* 46 */
+ "getgid", /* 47 */
+ "signal", /* 48 */
+ "geteuid", /* 49 */
+ "getegid", /* 50 */
+ "acct", /* 51 */
+ "memory_ordering", /* 52 */
+ "getgid32", /* 53 */
+ "ioctl", /* 54 */
+ "reboot", /* 55 */
+ "mmap2", /* 56 */
+ "symlink", /* 57 */
+ "readlink", /* 58 */
+ "execve", /* 59 */
+ "umask", /* 60 */
+ "chroot", /* 61 */
+ "fstat", /* 62 */
+ "fstat64", /* 63 */
+ "getpagesize", /* 64 */
+ "msync", /* 65 */
+ "vfork", /* 66 */
+ "pread64", /* 67 */
+ "pwrite64", /* 68 */
+ "geteuid32", /* 69 */
+ "getegid32", /* 70 */
+ "mmap", /* 71 */
+ "setreuid32", /* 72 */
+ "munmap", /* 73 */
+ "mprotect", /* 74 */
+ "madvise", /* 75 */
+ "vhangup", /* 76 */
+ "truncate64", /* 77 */
+ "mincore", /* 78 */
+ "getgroups", /* 79 */
+ "setgroups", /* 80 */
+ "getpgrp", /* 81 */
+ "setgroups32", /* 82 */
+ "setitimer", /* 83 */
+ "ftruncate64", /* 84 */
+ "swapon", /* 85 */
+ "getitimer", /* 86 */
+ "setuid32", /* 87 */
+ "sethostname", /* 88 */
+ "setgid32", /* 89 */
+ "dup2", /* 90 */
+ "setfsuid32", /* 91 */
+ "fcntl", /* 92 */
+ "select", /* 93 */
+ "setfsgid32", /* 94 */
+ "fsync", /* 95 */
+ "setpriority", /* 96 */
+ "socket", /* 97 */
+ "connect", /* 98 */
+ "accept", /* 99 */
+ "getpriority", /* 100 */
+ "rt_sigreturn", /* 101 */
+ "rt_sigaction", /* 102 */
+ "rt_sigprocmask", /* 103 */
+ "rt_sigpending", /* 104 */
+ "rt_sigtimedwait", /* 105 */
+ "rt_sigqueueinfo", /* 106 */
+ "rt_sigsuspend", /* 107 */
+ "setresuid32", /* 108 */
+ "getresuid32", /* 109 */
+ "setresgid32", /* 110 */
+ "getresgid32", /* 111 */
+ "setregid32", /* 112 */
+ "recvmsg", /* 113 */
+ "sendmsg", /* 114 */
+ "getgroups32", /* 115 */
+ "gettimeofday", /* 116 */
+ "getrusage", /* 117 */
+ "getsockopt", /* 118 */
+ "getcwd", /* 119 */
+ "readv", /* 120 */
+ "writev", /* 121 */
+ "settimeofday", /* 122 */
+ "fchown", /* 123 */
+ "fchmod", /* 124 */
+ "recvfrom", /* 125 */
+ "setreuid", /* 126 */
+ "setregid", /* 127 */
+ "rename", /* 128 */
+ "truncate", /* 129 */
+ "ftruncate", /* 130 */
+ "flock", /* 131 */
+ "lstat64", /* 132 */
+ "sendto", /* 133 */
+ "shutdown", /* 134 */
+ "socketpair", /* 135 */
+ "mkdir", /* 136 */
+ "rmdir", /* 137 */
+ "utimes", /* 138 */
+ "stat64", /* 139 */
+ "sendfile64", /* 140 */
+ "getpeername", /* 141 */
+ "futex", /* 142 */
+ "gettid", /* 143 */
+ "getrlimit", /* 144 */
+ "setrlimit", /* 145 */
+ "pivot_root", /* 146 */
+ "prctl", /* 147 */
+ "pciconfig_read", /* 148 */
+ "pciconfig_write", /* 149 */
+ "getsockname", /* 150 */
+ "inotify_init", /* 151 */
+ "inotify_add_watch", /* 152 */
+ "poll", /* 153 */
+ "getdents64", /* 154 */
+ "fcntl64", /* 155 */
+ "inotify_rm_watch", /* 156 */
+ "statfs", /* 157 */
+ "fstatfs", /* 158 */
+ "umount", /* 159 */
+ "sched_set_affinity", /* 160 */
+ "sched_get_affinity", /* 161 */
+ "getdomainname", /* 162 */
+ "setdomainname", /* 163 */
+ "utrap_install", /* 164 */
+ "quotactl", /* 165 */
+ "set_tid_address", /* 166 */
+ "mount", /* 167 */
+ "ustat", /* 168 */
+ "setxattr", /* 169 */
+ "lsetxattr", /* 170 */
+ "fsetxattr", /* 171 */
+ "getxattr", /* 172 */
+ "lgetxattr", /* 173 */
+ "getdents", /* 174 */
+ "setsid", /* 175 */
+ "fchdir", /* 176 */
+ "fgetxattr", /* 177 */
+ "listxattr", /* 178 */
+ "llistxattr", /* 179 */
+ "flistxattr", /* 180 */
+ "removexattr", /* 181 */
+ "lremovexattr", /* 182 */
+ "sigpending", /* 183 */
+ "query_module", /* 184 */
+ "setpgid", /* 185 */
+ "fremovexattr", /* 186 */
+ "tkill", /* 187 */
+ "exit_group", /* 188 */
+ "uname", /* 189 */
+ "init_module", /* 190 */
+ "personality", /* 191 */
+ "remap_file_pages", /* 192 */
+ "epoll_create", /* 193 */
+ "epoll_ctl", /* 194 */
+ "epoll_wait", /* 195 */
+ "ioprio_set", /* 196 */
+ "getppid", /* 197 */
+ "sigaction", /* 198 */
+ "sgetmask", /* 199 */
+ "ssetmask", /* 200 */
+ "sigsuspend", /* 201 */
+ "oldlstat", /* 202 */
+ "uselib", /* 203 */
+ "readdir", /* 204 */
+ "readahead", /* 205 */
+ "socketcall", /* 206 */
+ "syslog", /* 207 */
+ "lookup_dcookie", /* 208 */
+ "fadvise64", /* 209 */
+ "fadvise64_64", /* 210 */
+ "tgkill", /* 211 */
+ "waitpid", /* 212 */
+ "swapoff", /* 213 */
+ "sysinfo", /* 214 */
+ "ipc", /* 215 */
+ "sigreturn", /* 216 */
+ "clone", /* 217 */
+ "ioprio_get", /* 218 */
+ "adjtimex", /* 219 */
+ "sigprocmask", /* 220 */
+ "create_module", /* 221 */
+ "delete_module", /* 222 */
+ "get_kernel_syms", /* 223 */
+ "getpgid", /* 224 */
+ "bdflush", /* 225 */
+ "sysfs", /* 226 */
+ "afs_syscall", /* 227 */
+ "setfsuid", /* 228 */
+ "setfsgid", /* 229 */
+ "_newselect", /* 230 */
+ "time", /* 231 */
+ "232", /* 232 */
+ "stime", /* 233 */
+ "statfs64", /* 234 */
+ "fstatfs64", /* 235 */
+ "_llseek", /* 236 */
+ "mlock", /* 237 */
+ "munlock", /* 238 */
+ "mlockall", /* 239 */
+ "munlockall", /* 240 */
+ "sched_setparam", /* 241 */
+ "sched_getparam", /* 242 */
+ "sched_setscheduler", /* 243 */
+ "sched_getscheduler", /* 244 */
+ "sched_yield", /* 245 */
+ "sched_get_priority_max", /* 246 */
+ "sched_get_priority_min", /* 247 */
+ "sched_rr_get_interval", /* 248 */
+ "nanosleep", /* 249 */
+ "mremap", /* 250 */
+ "_sysctl", /* 251 */
+ "getsid", /* 252 */
+ "fdatasync", /* 253 */
+ "nfsservctl", /* 254 */
+ "aplib", /* 255 */
+ "clock_settime", /* 256 */
+ "clock_gettime", /* 257 */
+ "clock_getres", /* 258 */
+ "clock_nanosleep", /* 259 */
+ "sched_getaffinity", /* 260 */
+ "sched_setaffinity", /* 261 */
+ "timer_settime", /* 262 */
+ "timer_gettime", /* 263 */
+ "timer_getoverrun", /* 264 */
+ "timer_delete", /* 265 */
+ "timer_create", /* 266 */
+ "vserver", /* 267 */
+ "io_setup", /* 268 */
+ "io_destroy", /* 269 */
+ "io_submit", /* 270 */
+ "io_cancel", /* 271 */
+ "io_getevents", /* 272 */
+ "mq_open", /* 273 */
+ "mq_unlink", /* 274 */
+ "mq_timedsend", /* 275 */
+ "mq_timedreceive", /* 276 */
+ "mq_notify", /* 277 */
+ "mq_getsetattr", /* 278 */
+ "waitid", /* 279 */
+ "setaltroot", /* 280 */
+ "add_key", /* 281 */
+ "request_key", /* 282 */
+ "keyctl", /* 283 */
diff --git a/sysdeps/linux-gnu/sparc/trace.c b/sysdeps/linux-gnu/sparc/trace.c
new file mode 100644
index 0000000..7f05b55
--- /dev/null
+++ b/sysdeps/linux-gnu/sparc/trace.c
@@ -0,0 +1,81 @@
+#include "config.h"
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <string.h>
+#include "ptrace.h"
+#include "common.h"
+
+void
+get_arch_dep(Process *proc) {
+ proc_archdep *a;
+ if (!proc->arch_ptr)
+ proc->arch_ptr = (void *)malloc(sizeof(proc_archdep));
+ a = (proc_archdep *) (proc->arch_ptr);
+ a->valid = (ptrace(PTRACE_GETREGS, proc->pid, &a->regs, 0) >= 0);
+}
+
+/* Returns syscall number if `pid' stopped because of a syscall.
+ * Returns -1 otherwise
+ */
+int
+syscall_p(Process *proc, int status, int *sysnum) {
+ if (WIFSTOPPED(status)
+ && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
+ void *ip = get_instruction_pointer(proc);
+ unsigned int insn;
+ if (ip == (void *)-1)
+ return 0;
+ insn = ptrace(PTRACE_PEEKTEXT, proc->pid, ip, 0);
+ if ((insn & 0xc1f8007f) == 0x81d00010) {
+ *sysnum = ((proc_archdep *) proc->arch_ptr)->regs.u_regs[UREG_G0];
+ 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;
+ } else if (*sysnum >= 0) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+long
+gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) {
+ proc_archdep *a = (proc_archdep *) proc->arch_ptr;
+ if (!a->valid) {
+ fprintf(stderr, "Could not get child registers\n");
+ exit(1);
+ }
+ if (arg_num == -1) /* return value */
+ return a->regs.u_regs[UREG_G7];
+
+ if (type == LT_TOF_FUNCTION || type == LT_TOF_SYSCALL || arg_num >= 6) {
+ if (arg_num < 6)
+ return ((int *)&a->regs.u_regs[UREG_G7])[arg_num];
+ return ptrace(PTRACE_PEEKTEXT, proc->pid,
+ proc->stack_pointer + 64 * (arg_num + 1));
+ } else if (type == LT_TOF_FUNCTIONR)
+ return a->func_arg[arg_num];
+ else if (type == LT_TOF_SYSCALLR)
+ return a->sysc_arg[arg_num];
+ else {
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(1);
+ }
+ return 0;
+}
+
+void
+save_register_args(enum tof type, Process *proc) {
+ proc_archdep *a = (proc_archdep *) proc->arch_ptr;
+ if (a->valid) {
+ if (type == LT_TOF_FUNCTION)
+ memcpy(a->func_arg, &a->regs.u_regs[UREG_G7], sizeof(a->func_arg));
+ else
+ memcpy(a->sysc_arg, &a->regs.u_regs[UREG_G7], sizeof(a->sysc_arg));
+ }
+}
diff --git a/sysdeps/linux-gnu/trace.c b/sysdeps/linux-gnu/trace.c
new file mode 100644
index 0000000..df5b090
--- /dev/null
+++ b/sysdeps/linux-gnu/trace.c
@@ -0,0 +1,193 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include "ptrace.h"
+#include <asm/unistd.h>
+
+#include "common.h"
+
+/* If the system headers did not provide the constants, hard-code the normal
+ values. */
+#ifndef PTRACE_EVENT_FORK
+
+#define PTRACE_OLDSETOPTIONS 21
+#define PTRACE_SETOPTIONS 0x4200
+#define PTRACE_GETEVENTMSG 0x4201
+
+/* options set using PTRACE_SETOPTIONS */
+#define PTRACE_O_TRACESYSGOOD 0x00000001
+#define PTRACE_O_TRACEFORK 0x00000002
+#define PTRACE_O_TRACEVFORK 0x00000004
+#define PTRACE_O_TRACECLONE 0x00000008
+#define PTRACE_O_TRACEEXEC 0x00000010
+#define PTRACE_O_TRACEVFORKDONE 0x00000020
+#define PTRACE_O_TRACEEXIT 0x00000040
+
+/* Wait extended result codes for the above trace options. */
+#define PTRACE_EVENT_FORK 1
+#define PTRACE_EVENT_VFORK 2
+#define PTRACE_EVENT_CLONE 3
+#define PTRACE_EVENT_EXEC 4
+#define PTRACE_EVENT_VFORK_DONE 5
+#define PTRACE_EVENT_EXIT 6
+
+#endif /* PTRACE_EVENT_FORK */
+
+#ifdef ARCH_HAVE_UMOVELONG
+extern int arch_umovelong (Process *, void *, long *, arg_type_info *);
+int
+umovelong (Process *proc, void *addr, long *result, arg_type_info *info) {
+ return arch_umovelong (proc, addr, result, info);
+}
+#else
+/* Read a single long from the process's memory address 'addr' */
+int
+umovelong (Process *proc, void *addr, long *result, arg_type_info *info) {
+ long pointed_to;
+
+ errno = 0;
+ pointed_to = ptrace (PTRACE_PEEKTEXT, proc->pid, addr, 0);
+ if (pointed_to == -1 && errno)
+ return -errno;
+
+ *result = pointed_to;
+ return 0;
+}
+#endif
+
+void
+trace_me(void) {
+ debug(DEBUG_PROCESS, "trace_me: pid=%d\n", getpid());
+ if (ptrace(PTRACE_TRACEME, 0, 1, 0) < 0) {
+ perror("PTRACE_TRACEME");
+ exit(1);
+ }
+}
+
+int
+trace_pid(pid_t pid) {
+ debug(DEBUG_PROCESS, "trace_pid: pid=%d\n", pid);
+ if (ptrace(PTRACE_ATTACH, pid, 1, 0) < 0) {
+ return -1;
+ }
+
+ /* man ptrace: PTRACE_ATTACH attaches to the process specified
+ in pid. The child is sent a SIGSTOP, but will not
+ necessarily have stopped by the completion of this call;
+ use wait() to wait for the child to stop. */
+ if (waitpid (pid, NULL, 0) != pid) {
+ perror ("trace_pid: waitpid");
+ exit (1);
+ }
+
+ return 0;
+}
+
+void
+trace_set_options(Process *proc, pid_t pid) {
+ if (proc->tracesysgood & 0x80)
+ return;
+
+ debug(DEBUG_PROCESS, "trace_set_options: pid=%d\n", pid);
+
+ long options = PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEFORK |
+ PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE |
+ PTRACE_O_TRACEEXEC;
+ if (ptrace(PTRACE_SETOPTIONS, pid, 0, options) < 0 &&
+ ptrace(PTRACE_OLDSETOPTIONS, pid, 0, options) < 0) {
+ perror("PTRACE_SETOPTIONS");
+ return;
+ }
+ proc->tracesysgood |= 0x80;
+}
+
+void
+untrace_pid(pid_t pid) {
+ debug(DEBUG_PROCESS, "untrace_pid: pid=%d\n", pid);
+ ptrace(PTRACE_DETACH, pid, 1, 0);
+}
+
+void
+continue_after_signal(pid_t pid, int signum) {
+ Process *proc;
+
+ debug(DEBUG_PROCESS, "continue_after_signal: pid=%d, signum=%d", pid, signum);
+
+ proc = pid2proc(pid);
+ if (proc && proc->breakpoint_being_enabled) {
+#if defined __sparc__ || defined __ia64___
+ ptrace(PTRACE_SYSCALL, pid, 0, signum);
+#else
+ ptrace(PTRACE_SINGLESTEP, pid, 0, signum);
+#endif
+ } else {
+ ptrace(PTRACE_SYSCALL, pid, 0, signum);
+ }
+}
+
+void
+continue_process(pid_t pid) {
+ /* We always trace syscalls to control fork(), clone(), execve()... */
+
+ debug(DEBUG_PROCESS, "continue_process: pid=%d", pid);
+
+ ptrace(PTRACE_SYSCALL, pid, 0, 0);
+}
+
+void
+continue_enabling_breakpoint(pid_t pid, Breakpoint *sbp) {
+ enable_breakpoint(pid, sbp);
+ continue_process(pid);
+}
+
+void
+continue_after_breakpoint(Process *proc, Breakpoint *sbp) {
+ if (sbp->enabled)
+ disable_breakpoint(proc->pid, sbp);
+ set_instruction_pointer(proc, sbp->addr);
+ if (sbp->enabled == 0) {
+ continue_process(proc->pid);
+ } else {
+ debug(DEBUG_PROCESS, "continue_after_breakpoint: pid=%d, addr=%p", proc->pid, sbp->addr);
+ proc->breakpoint_being_enabled = sbp;
+#if defined __sparc__ || defined __ia64___
+ /* we don't want to singlestep here */
+ continue_process(proc->pid);
+#else
+ ptrace(PTRACE_SINGLESTEP, proc->pid, 0, 0);
+#endif
+ }
+}
+
+/* Read a series of bytes starting at the process's memory address
+ 'addr' and continuing until a NUL ('\0') is seen or 'len' bytes
+ have been read.
+*/
+int
+umovestr(Process *proc, void *addr, int len, void *laddr) {
+ union {
+ long a;
+ char c[sizeof(long)];
+ } a;
+ int i;
+ int offset = 0;
+
+ while (offset < len) {
+ a.a = ptrace(PTRACE_PEEKTEXT, proc->pid, addr + offset, 0);
+ for (i = 0; i < sizeof(long); i++) {
+ if (a.c[i] && offset + (signed)i < len) {
+ *(char *)(laddr + offset + i) = a.c[i];
+ } else {
+ *(char *)(laddr + offset + i) = '\0';
+ return 0;
+ }
+ }
+ offset += sizeof(long);
+ }
+ *(char *)(laddr + offset) = '\0';
+ return 0;
+}
diff --git a/sysdeps/linux-gnu/x86_64/Makefile b/sysdeps/linux-gnu/x86_64/Makefile
new file mode 100644
index 0000000..0a19c97
--- /dev/null
+++ b/sysdeps/linux-gnu/x86_64/Makefile
@@ -0,0 +1,9 @@
+OBJ = trace.o regs.o plt.o
+
+all: arch.o
+
+arch.o: $(OBJ)
+ $(CC) -nostdlib -r -o arch.o $(OBJ)
+
+clean:
+ $(RM) $(OBJ) arch.o
diff --git a/sysdeps/linux-gnu/x86_64/arch.h b/sysdeps/linux-gnu/x86_64/arch.h
new file mode 100644
index 0000000..255395c
--- /dev/null
+++ b/sysdeps/linux-gnu/x86_64/arch.h
@@ -0,0 +1,12 @@
+#define BREAKPOINT_VALUE {0xcc}
+#define BREAKPOINT_LENGTH 1
+#define DECR_PC_AFTER_BREAK 1
+
+#define LT_ELFCLASS ELFCLASS64
+#define LT_ELF_MACHINE EM_X86_64
+#define LT_ELFCLASS2 ELFCLASS32
+#define LT_ELF_MACHINE2 EM_386
+
+/* __NR_fork, __NR_clone, __NR_clone2, __NR_vfork and __NR_execve
+ from asm-i386/unistd.h. */
+#define FORK_EXEC_SYSCALLS , { 2, 120, -1, 190, 11 }
diff --git a/sysdeps/linux-gnu/x86_64/ffcheck.c b/sysdeps/linux-gnu/x86_64/ffcheck.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sysdeps/linux-gnu/x86_64/ffcheck.c
diff --git a/sysdeps/linux-gnu/x86_64/plt.c b/sysdeps/linux-gnu/x86_64/plt.c
new file mode 100644
index 0000000..b53ff44
--- /dev/null
+++ b/sysdeps/linux-gnu/x86_64/plt.c
@@ -0,0 +1,12 @@
+#include <gelf.h>
+#include "common.h"
+
+GElf_Addr
+arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) {
+ return lte->plt_addr + (ndx + 1) * 16;
+}
+
+void *
+sym2addr(Process *proc, struct library_symbol *sym) {
+ return sym->enter_addr;
+}
diff --git a/sysdeps/linux-gnu/x86_64/ptrace.h b/sysdeps/linux-gnu/x86_64/ptrace.h
new file mode 100644
index 0000000..c3cbcb6
--- /dev/null
+++ b/sysdeps/linux-gnu/x86_64/ptrace.h
@@ -0,0 +1 @@
+#include <sys/ptrace.h>
diff --git a/sysdeps/linux-gnu/x86_64/regs.c b/sysdeps/linux-gnu/x86_64/regs.c
new file mode 100644
index 0000000..ed1f118
--- /dev/null
+++ b/sysdeps/linux-gnu/x86_64/regs.c
@@ -0,0 +1,54 @@
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/reg.h>
+
+#include "common.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(Process *proc) {
+ long int ret = ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RIP, 0);
+ if (proc->mask_32bit)
+ ret &= 0xffffffff;
+ return (void *)ret;
+}
+
+void
+set_instruction_pointer(Process *proc, void *addr) {
+ if (proc->mask_32bit)
+ addr = (void *)((long int)addr & 0xffffffff);
+ ptrace(PTRACE_POKEUSER, proc->pid, 8 * RIP, addr);
+}
+
+void *
+get_stack_pointer(Process *proc) {
+ long int ret = ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RSP, 0);
+ if (proc->mask_32bit)
+ ret &= 0xffffffff;
+ return (void *)ret;
+}
+
+void *
+get_return_addr(Process *proc, void *stack_pointer) {
+ unsigned long int ret;
+ ret = ptrace(PTRACE_PEEKTEXT, proc->pid, stack_pointer, 0);
+ if (proc->mask_32bit)
+ ret &= 0xffffffff;
+ return (void *)ret;
+}
+
+void
+set_return_addr(Process *proc, void *addr) {
+ if (proc->mask_32bit)
+ addr = (void *)((long int)addr & 0xffffffff);
+ ptrace(PTRACE_POKETEXT, proc->pid, proc->stack_pointer, addr);
+}
diff --git a/sysdeps/linux-gnu/x86_64/signalent.h b/sysdeps/linux-gnu/x86_64/signalent.h
new file mode 100644
index 0000000..d58a36c
--- /dev/null
+++ b/sysdeps/linux-gnu/x86_64/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/x86_64/signalent1.h b/sysdeps/linux-gnu/x86_64/signalent1.h
new file mode 100644
index 0000000..5ead946
--- /dev/null
+++ b/sysdeps/linux-gnu/x86_64/signalent1.h
@@ -0,0 +1 @@
+#include "i386/signalent.h"
diff --git a/sysdeps/linux-gnu/x86_64/syscallent.h b/sysdeps/linux-gnu/x86_64/syscallent.h
new file mode 100644
index 0000000..5e5f88a
--- /dev/null
+++ b/sysdeps/linux-gnu/x86_64/syscallent.h
@@ -0,0 +1,256 @@
+"read", /* 0 */
+ "write", /* 1 */
+ "open", /* 2 */
+ "close", /* 3 */
+ "stat", /* 4 */
+ "fstat", /* 5 */
+ "lstat", /* 6 */
+ "poll", /* 7 */
+ "lseek", /* 8 */
+ "mmap", /* 9 */
+ "mprotect", /* 10 */
+ "munmap", /* 11 */
+ "brk", /* 12 */
+ "rt_sigaction", /* 13 */
+ "rt_sigprocmask", /* 14 */
+ "rt_sigreturn", /* 15 */
+ "ioctl", /* 16 */
+ "pread", /* 17 */
+ "pwrite", /* 18 */
+ "readv", /* 19 */
+ "writev", /* 20 */
+ "access", /* 21 */
+ "pipe", /* 22 */
+ "select", /* 23 */
+ "sched_yield", /* 24 */
+ "mremap", /* 25 */
+ "msync", /* 26 */
+ "mincore", /* 27 */
+ "madvise", /* 28 */
+ "shmget", /* 29 */
+ "shmat", /* 30 */
+ "shmctl", /* 31 */
+ "dup", /* 32 */
+ "dup2", /* 33 */
+ "pause", /* 34 */
+ "nanosleep", /* 35 */
+ "getitimer", /* 36 */
+ "alarm", /* 37 */
+ "setitimer", /* 38 */
+ "getpid", /* 39 */
+ "sendfile", /* 40 */
+ "socket", /* 41 */
+ "connect", /* 42 */
+ "accept", /* 43 */
+ "sendto", /* 44 */
+ "recvfrom", /* 45 */
+ "sendmsg", /* 46 */
+ "recvmsg", /* 47 */
+ "shutdown", /* 48 */
+ "bind", /* 49 */
+ "listen", /* 50 */
+ "getsockname", /* 51 */
+ "getpeername", /* 52 */
+ "socketpair", /* 53 */
+ "setsockopt", /* 54 */
+ "getsockopt", /* 55 */
+ "clone", /* 56 */
+ "fork", /* 57 */
+ "vfork", /* 58 */
+ "execve", /* 59 */
+ "exit", /* 60 */
+ "wait4", /* 61 */
+ "kill", /* 62 */
+ "uname", /* 63 */
+ "semget", /* 64 */
+ "semop", /* 65 */
+ "semctl", /* 66 */
+ "shmdt", /* 67 */
+ "msgget", /* 68 */
+ "msgsnd", /* 69 */
+ "msgrcv", /* 70 */
+ "msgctl", /* 71 */
+ "fcntl", /* 72 */
+ "flock", /* 73 */
+ "fsync", /* 74 */
+ "fdatasync", /* 75 */
+ "truncate", /* 76 */
+ "ftruncate", /* 77 */
+ "getdents", /* 78 */
+ "getcwd", /* 79 */
+ "chdir", /* 80 */
+ "fchdir", /* 81 */
+ "rename", /* 82 */
+ "mkdir", /* 83 */
+ "rmdir", /* 84 */
+ "creat", /* 85 */
+ "link", /* 86 */
+ "unlink", /* 87 */
+ "symlink", /* 88 */
+ "readlink", /* 89 */
+ "chmod", /* 90 */
+ "fchmod", /* 91 */
+ "chown", /* 92 */
+ "fchown", /* 93 */
+ "lchown", /* 94 */
+ "umask", /* 95 */
+ "gettimeofday", /* 96 */
+ "getrlimit", /* 97 */
+ "getrusage", /* 98 */
+ "sysinfo", /* 99 */
+ "times", /* 100 */
+ "ptrace", /* 101 */
+ "getuid", /* 102 */
+ "syslog", /* 103 */
+ "getgid", /* 104 */
+ "setuid", /* 105 */
+ "setgid", /* 106 */
+ "geteuid", /* 107 */
+ "getegid", /* 108 */
+ "setpgid", /* 109 */
+ "getppid", /* 110 */
+ "getpgrp", /* 111 */
+ "setsid", /* 112 */
+ "setreuid", /* 113 */
+ "setregid", /* 114 */
+ "getgroups", /* 115 */
+ "setgroups", /* 116 */
+ "setresuid", /* 117 */
+ "getresuid", /* 118 */
+ "setresgid", /* 119 */
+ "getresgid", /* 120 */
+ "getpgid", /* 121 */
+ "setfsuid", /* 122 */
+ "setfsgid", /* 123 */
+ "getsid", /* 124 */
+ "capget", /* 125 */
+ "capset", /* 126 */
+ "rt_sigpending", /* 127 */
+ "rt_sigtimedwait", /* 128 */
+ "rt_sigqueueinfo", /* 129 */
+ "rt_sigsuspend", /* 130 */
+ "sigaltstack", /* 131 */
+ "utime", /* 132 */
+ "mknod", /* 133 */
+ "uselib", /* 134 */
+ "personality", /* 135 */
+ "ustat", /* 136 */
+ "statfs", /* 137 */
+ "fstatfs", /* 138 */
+ "sysfs", /* 139 */
+ "getpriority", /* 140 */
+ "setpriority", /* 141 */
+ "sched_setparam", /* 142 */
+ "sched_getparam", /* 143 */
+ "sched_setscheduler", /* 144 */
+ "sched_getscheduler", /* 145 */
+ "sched_get_priority_max", /* 146 */
+ "sched_get_priority_min", /* 147 */
+ "sched_rr_get_interval", /* 148 */
+ "mlock", /* 149 */
+ "munlock", /* 150 */
+ "mlockall", /* 151 */
+ "munlockall", /* 152 */
+ "vhangup", /* 153 */
+ "modify_ldt", /* 154 */
+ "pivot_root", /* 155 */
+ "_sysctl", /* 156 */
+ "prctl", /* 157 */
+ "arch_prctl", /* 158 */
+ "adjtimex", /* 159 */
+ "setrlimit", /* 160 */
+ "chroot", /* 161 */
+ "sync", /* 162 */
+ "acct", /* 163 */
+ "settimeofday", /* 164 */
+ "mount", /* 165 */
+ "umount2", /* 166 */
+ "swapon", /* 167 */
+ "swapoff", /* 168 */
+ "reboot", /* 169 */
+ "sethostname", /* 170 */
+ "setdomainname", /* 171 */
+ "iopl", /* 172 */
+ "ioperm", /* 173 */
+ "create_module", /* 174 */
+ "init_module", /* 175 */
+ "delete_module", /* 176 */
+ "get_kernel_syms", /* 177 */
+ "query_module", /* 178 */
+ "quotactl", /* 179 */
+ "nfsservctl", /* 180 */
+ "getpmsg", /* 181 */
+ "putpmsg", /* 182 */
+ "afs_syscall", /* 183 */
+ "tuxcall", /* 184 */
+ "security", /* 185 */
+ "gettid", /* 186 */
+ "readahead", /* 187 */
+ "setxattr", /* 188 */
+ "lsetxattr", /* 189 */
+ "fsetxattr", /* 190 */
+ "getxattr", /* 191 */
+ "lgetxattr", /* 192 */
+ "fgetxattr", /* 193 */
+ "listxattr", /* 194 */
+ "llistxattr", /* 195 */
+ "flistxattr", /* 196 */
+ "removexattr", /* 197 */
+ "lremovexattr", /* 198 */
+ "fremovexattr", /* 199 */
+ "tkill", /* 200 */
+ "time", /* 201 */
+ "futex", /* 202 */
+ "sched_setaffinity", /* 203 */
+ "sched_getaffinity", /* 204 */
+ "set_thread_area", /* 205 */
+ "io_setup", /* 206 */
+ "io_destroy", /* 207 */
+ "io_getevents", /* 208 */
+ "io_submit", /* 209 */
+ "io_cancel", /* 210 */
+ "get_thread_area", /* 211 */
+ "lookup_dcookie", /* 212 */
+ "epoll_create", /* 213 */
+ "epoll_ctl", /* 214 */
+ "epoll_wait", /* 215 */
+ "remap_file_pages", /* 216 */
+ "getdents64", /* 217 */
+ "set_tid_address", /* 218 */
+ "restart_syscall", /* 219 */
+ "semtimedop", /* 220 */
+ "fadvise64", /* 221 */
+ "timer_create", /* 222 */
+ "timer_settime", /* 223 */
+ "timer_gettime", /* 224 */
+ "timer_getoverrun", /* 225 */
+ "timer_delete", /* 226 */
+ "clock_settime", /* 227 */
+ "clock_gettime", /* 228 */
+ "clock_getres", /* 229 */
+ "clock_nanosleep", /* 230 */
+ "exit_group", /* 231 */
+ "epoll_wait", /* 232 */
+ "epoll_ctl", /* 233 */
+ "tgkill", /* 234 */
+ "utimes", /* 235 */
+ "vserver", /* 236 */
+ "mbind", /* 237 */
+ "set_mempolicy", /* 238 */
+ "get_mempolicy", /* 239 */
+ "mq_open", /* 240 */
+ "mq_unlink", /* 241 */
+ "mq_timedsend", /* 242 */
+ "mq_timedreceive", /* 243 */
+ "mq_notify", /* 244 */
+ "mq_getsetattr", /* 245 */
+ "kexec_load", /* 246 */
+ "waitid", /* 247 */
+ "add_key", /* 248 */
+ "request_key", /* 249 */
+ "keyctl", /* 250 */
+ "ioprio_set", /* 251 */
+ "ioprio_get", /* 252 */
+ "inotify_init", /* 253 */
+ "inotify_add_watch", /* 254 */
+ "inotify_rm_watch", /* 255 */
diff --git a/sysdeps/linux-gnu/x86_64/syscallent1.h b/sysdeps/linux-gnu/x86_64/syscallent1.h
new file mode 100644
index 0000000..d8dd9f7
--- /dev/null
+++ b/sysdeps/linux-gnu/x86_64/syscallent1.h
@@ -0,0 +1 @@
+#include "i386/syscallent.h"
diff --git a/sysdeps/linux-gnu/x86_64/trace.c b/sysdeps/linux-gnu/x86_64/trace.c
new file mode 100644
index 0000000..189734d
--- /dev/null
+++ b/sysdeps/linux-gnu/x86_64/trace.c
@@ -0,0 +1,144 @@
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <sys/ptrace.h>
+#include <sys/reg.h>
+
+#include "common.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) {
+ unsigned long cs;
+ if (proc->arch_ptr)
+ return;
+ cs = ptrace(PTRACE_PEEKUSER, proc->pid, 8 * CS, 0);
+ if (cs == 0x23) {
+ proc->mask_32bit = 1;
+ proc->personality = 1;
+ }
+ proc->arch_ptr = (void *)1;
+}
+
+/* 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)) {
+ *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 8 * ORIG_RAX, 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) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static unsigned int
+gimme_arg32(enum tof type, Process *proc, int arg_num) {
+ if (arg_num == -1) { /* return value */
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RAX, 0);
+ }
+
+ if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
+ return ptrace(PTRACE_PEEKTEXT, proc->pid,
+ proc->stack_pointer + 4 * (arg_num + 1), 0);
+ } else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) {
+ switch (arg_num) {
+ case 0:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RBX, 0);
+ case 1:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RCX, 0);
+ case 2:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RDX, 0);
+ case 3:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RSI, 0);
+ case 4:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RDI, 0);
+ case 5:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RBP, 0);
+ default:
+ fprintf(stderr,
+ "gimme_arg32 called with wrong arguments\n");
+ exit(2);
+ }
+ }
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(1);
+}
+
+long
+gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) {
+ if (proc->mask_32bit)
+ return (unsigned int)gimme_arg32(type, proc, arg_num);
+
+ if (arg_num == -1) { /* return value */
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RAX, 0);
+ }
+
+ if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
+ switch (arg_num) {
+ case 0:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RDI, 0);
+ case 1:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RSI, 0);
+ case 2:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RDX, 0);
+ case 3:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RCX, 0);
+ case 4:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * R8, 0);
+ case 5:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * R9, 0);
+ default:
+ return ptrace(PTRACE_PEEKTEXT, proc->pid,
+ proc->stack_pointer + 8 * (arg_num - 6 +
+ 1), 0);
+ }
+ } else if (type == LT_TOF_SYSCALL || LT_TOF_SYSCALLR) {
+ switch (arg_num) {
+ case 0:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RDI, 0);
+ case 1:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RSI, 0);
+ case 2:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RDX, 0);
+ case 3:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * R10, 0);
+ case 4:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * R8, 0);
+ case 5:
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * R9, 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;
+}
+
+void
+save_register_args(enum tof type, Process *proc) {
+}