aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/linux-gnu
diff options
context:
space:
mode:
authorJuan Cespedes <cespedes@debian.org>2004-04-04 01:31:38 +0200
committerJuan Cespedes <cespedes@debian.org>2004-04-04 01:31:38 +0200
commitefe85f0668a077b1e851df4b3f87a380cf2269fd (patch)
tree139d24d388a22b187c0230512460a1a27e7ed3b5 /sysdeps/linux-gnu
parent504a385858a49352bcfceca444ba4f1a7bfd20cd (diff)
downloadltrace-efe85f0668a077b1e851df4b3f87a380cf2269fd.tar.gz
Version 0.3.32
* Fixed wrong version number * Removed unused file "opt_c.c" * Remove error when tracing no calls and doing fork() * Clean-up of sysdeps/linux-gnu/s390/trace.c * Clean-up of sysdeps/linux-gnu/ppc/trace.c * Make `--library' option really work (closes: Bug#232321) * Merged several patches from SuSE: + Added some functions to ltrace.conf + Handle 64-big ELF files nicely + AMD64 support + Updated list of syscalls for S/390 + Improved some debugging statements Many thanks to Bernhard Kaindl <bk@suse.de> for his great work
Diffstat (limited to 'sysdeps/linux-gnu')
-rw-r--r--sysdeps/linux-gnu/arm/arch.h1
-rw-r--r--sysdeps/linux-gnu/breakpoint.c4
-rw-r--r--sysdeps/linux-gnu/ppc/arch.obin32104 -> 0 bytes
-rw-r--r--sysdeps/linux-gnu/ppc/regs.obin9608 -> 0 bytes
-rw-r--r--sysdeps/linux-gnu/ppc/trace.c13
-rw-r--r--sysdeps/linux-gnu/ppc/trace.obin23252 -> 0 bytes
-rw-r--r--sysdeps/linux-gnu/s390/Makefile4
-rw-r--r--sysdeps/linux-gnu/s390/regs.c2
-rw-r--r--sysdeps/linux-gnu/s390/syscallent.h26
-rw-r--r--sysdeps/linux-gnu/s390/trace.c41
-rw-r--r--sysdeps/linux-gnu/x86_64/Makefile9
-rw-r--r--sysdeps/linux-gnu/x86_64/arch.h6
-rw-r--r--sysdeps/linux-gnu/x86_64/ffcheck.c18
-rw-r--r--sysdeps/linux-gnu/x86_64/regs.c35
-rw-r--r--sysdeps/linux-gnu/x86_64/signalent.h32
-rw-r--r--sysdeps/linux-gnu/x86_64/syscallent.h203
-rw-r--r--sysdeps/linux-gnu/x86_64/trace.c77
17 files changed, 411 insertions, 60 deletions
diff --git a/sysdeps/linux-gnu/arm/arch.h b/sysdeps/linux-gnu/arm/arch.h
index 8a242e6..dc2a1d0 100644
--- a/sysdeps/linux-gnu/arm/arch.h
+++ b/sysdeps/linux-gnu/arm/arch.h
@@ -1,4 +1,3 @@
#define BREAKPOINT_VALUE { 0x01, 0x00, 0x9f, 0xef }
#define BREAKPOINT_LENGTH 4
-/* we don't need to decr the pc; the kernel does it for us! */
#define DECR_PC_AFTER_BREAK 0
diff --git a/sysdeps/linux-gnu/breakpoint.c b/sysdeps/linux-gnu/breakpoint.c
index e2bd6d7..da42556 100644
--- a/sysdeps/linux-gnu/breakpoint.c
+++ b/sysdeps/linux-gnu/breakpoint.c
@@ -14,7 +14,7 @@ enable_breakpoint(pid_t pid, struct breakpoint * sbp) {
int i,j;
if (opt_d>1) {
- output_line(0, "enable_breakpoint(%d,0x%08x)", pid, sbp->addr);
+ output_line(0, "enable_breakpoint(%d,%p)", pid, sbp->addr);
}
for(i=0; i < 1+((BREAKPOINT_LENGTH-1)/sizeof(long)); i++) {
@@ -34,7 +34,7 @@ disable_breakpoint(pid_t pid, const struct breakpoint * sbp) {
int i,j;
if (opt_d>1) {
- output_line(0, "disable_breakpoint(%d,0x%08x)", pid, sbp->addr);
+ output_line(0, "disable_breakpoint(%d,%p)", pid, sbp->addr);
}
for(i=0; i < 1+((BREAKPOINT_LENGTH-1)/sizeof(long)); i++) {
diff --git a/sysdeps/linux-gnu/ppc/arch.o b/sysdeps/linux-gnu/ppc/arch.o
deleted file mode 100644
index 312a4f8..0000000
--- a/sysdeps/linux-gnu/ppc/arch.o
+++ /dev/null
Binary files differ
diff --git a/sysdeps/linux-gnu/ppc/regs.o b/sysdeps/linux-gnu/ppc/regs.o
deleted file mode 100644
index c8cc474..0000000
--- a/sysdeps/linux-gnu/ppc/regs.o
+++ /dev/null
Binary files differ
diff --git a/sysdeps/linux-gnu/ppc/trace.c b/sysdeps/linux-gnu/ppc/trace.c
index 9634d1d..58218bb 100644
--- a/sysdeps/linux-gnu/ppc/trace.c
+++ b/sysdeps/linux-gnu/ppc/trace.c
@@ -43,17 +43,10 @@ long
gimme_arg(enum tof type, struct process * proc, int arg_num) {
if (arg_num==-1) { /* return value */
return ptrace(PTRACE_PEEKUSER, proc->pid, 4*PT_R3, 0);
- }
-
- if (type==LT_TOF_FUNCTION || type==LT_TOF_SYSCALL) {
- if (arg_num < 8) {
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4*(arg_num+PT_R3), 0);
- } else {
- return ptrace(PTRACE_PEEKDATA, proc->pid, proc->stack_pointer+8*(arg_num-8), 0);
- }
+ } else if (arg_num < 8) {
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4*(arg_num+PT_R3), 0);
} else {
- fprintf(stderr, "gimme_arg called with wrong arguments\n");
- exit(1);
+ return ptrace(PTRACE_PEEKDATA, proc->pid, proc->stack_pointer+8*(arg_num-8), 0);
}
return 0;
}
diff --git a/sysdeps/linux-gnu/ppc/trace.o b/sysdeps/linux-gnu/ppc/trace.o
deleted file mode 100644
index aafcf69..0000000
--- a/sysdeps/linux-gnu/ppc/trace.o
+++ /dev/null
Binary files differ
diff --git a/sysdeps/linux-gnu/s390/Makefile b/sysdeps/linux-gnu/s390/Makefile
index e4739d8..ffad176 100644
--- a/sysdeps/linux-gnu/s390/Makefile
+++ b/sysdeps/linux-gnu/s390/Makefile
@@ -1,6 +1,6 @@
#
-# S/390 version
-# (C) Copyright 2001 IBM Poughkeepsie, IBM Corporation
+# S/390 version
+# Copyright (C) 2001 IBM Poughkeepsie, IBM Corporation
#
OBJ = trace.o regs.o
diff --git a/sysdeps/linux-gnu/s390/regs.c b/sysdeps/linux-gnu/s390/regs.c
index 77bdb6d..171f1c9 100644
--- a/sysdeps/linux-gnu/s390/regs.c
+++ b/sysdeps/linux-gnu/s390/regs.c
@@ -1,6 +1,6 @@
/*
** S/390 version
-** (C) Copyright 2001 IBM Poughkeepsie, IBM Corporation
+** Copyright (C) 2001 IBM Poughkeepsie, IBM Corporation
*/
#if HAVE_CONFIG_H
diff --git a/sysdeps/linux-gnu/s390/syscallent.h b/sysdeps/linux-gnu/s390/syscallent.h
index bcc404c..6ee7829 100644
--- a/sysdeps/linux-gnu/s390/syscallent.h
+++ b/sysdeps/linux-gnu/s390/syscallent.h
@@ -220,19 +220,19 @@
"madvise", /* 219 */
"getdents64", /* 220 */
"fcntl64", /* 221 */
- "222", /* 222 */
+ "readahead", /* 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 */
+ "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 */
diff --git a/sysdeps/linux-gnu/s390/trace.c b/sysdeps/linux-gnu/s390/trace.c
index e15e89a..cdacfa3 100644
--- a/sysdeps/linux-gnu/s390/trace.c
+++ b/sysdeps/linux-gnu/s390/trace.c
@@ -5,7 +5,7 @@
** at link time with this code.
**
** S/390 version
-** (C) Copyright 2001 IBM Poughkeepsie, IBM Corporation
+** Copyright (C) 2001 IBM Poughkeepsie, IBM Corporation
*/
#if HAVE_CONFIG_H
@@ -73,37 +73,16 @@ syscall_p(struct process * proc, int status, int * sysnum) {
long
gimme_arg(enum tof type, struct process * proc, int arg_num) {
- if (arg_num==-1) { /* return value */
- return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR2, 0);
- }
-
- if (type==LT_TOF_FUNCTION) {
- switch(arg_num) {
- case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_ORIGGPR2, 0);
- case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR3, 0);
- case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR4, 0);
- case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR5, 0);
- case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR6, 0);
- default:
- fprintf(stderr, "gimme_arg called with wrong arguments\n");
- exit(2);
- }
-
- } else if (type==LT_TOF_SYSCALL) {
- switch(arg_num) {
- case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_ORIGGPR2, 0);
- case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR3, 0);
- case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR4, 0);
- case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR5, 0);
- case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR6, 0);
- default:
+ switch(arg_num) {
+ case -1: /* return value */
+ return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR2, 0);
+ case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_ORIGGPR2, 0);
+ case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR3, 0);
+ case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR4, 0);
+ case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR5, 0);
+ case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR6, 0);
+ default:
fprintf(stderr, "gimme_arg called with wrong arguments\n");
exit(2);
- }
- } else {
- fprintf(stderr, "gimme_arg called with wrong arguments\n");
- exit(1);
}
-
- return 0;
}
diff --git a/sysdeps/linux-gnu/x86_64/Makefile b/sysdeps/linux-gnu/x86_64/Makefile
new file mode 100644
index 0000000..0319ab0
--- /dev/null
+++ b/sysdeps/linux-gnu/x86_64/Makefile
@@ -0,0 +1,9 @@
+OBJ = trace.o regs.o ffcheck.o
+
+all: arch.o
+
+arch.o: $(OBJ)
+ $(LD) -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..aa61505
--- /dev/null
+++ b/sysdeps/linux-gnu/x86_64/arch.h
@@ -0,0 +1,6 @@
+#define BREAKPOINT_VALUE {0xcc}
+#define BREAKPOINT_LENGTH 1
+#define DECR_PC_AFTER_BREAK 1
+
+#define FILEFORMAT_CHECK 1
+#define ELFSIZE 64
diff --git a/sysdeps/linux-gnu/x86_64/ffcheck.c b/sysdeps/linux-gnu/x86_64/ffcheck.c
new file mode 100644
index 0000000..91dc855
--- /dev/null
+++ b/sysdeps/linux-gnu/x86_64/ffcheck.c
@@ -0,0 +1,18 @@
+#include <elf.h>
+
+int
+ffcheck (void *maddr)
+{
+ Elf64_Ehdr *ehdr=maddr;
+
+ if (! ehdr)
+ return 0;
+ if (
+ ehdr->e_type == 2 &&
+ ehdr->e_machine == 0x3e &&
+ ehdr->e_version == 1
+ )
+ return 1;
+
+ return 0;
+}
diff --git a/sysdeps/linux-gnu/x86_64/regs.c b/sysdeps/linux-gnu/x86_64/regs.c
new file mode 100644
index 0000000..b639322
--- /dev/null
+++ b/sysdeps/linux-gnu/x86_64/regs.c
@@ -0,0 +1,35 @@
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/reg.h>
+
+#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
+# define PTRACE_PEEKUSER PTRACE_PEEKUSR
+#endif
+
+#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR))
+# define PTRACE_POKEUSER PTRACE_POKEUSR
+#endif
+
+void *
+get_instruction_pointer(pid_t pid) {
+ return (void *)ptrace(PTRACE_PEEKUSER, pid, 8*RIP, 0);
+}
+
+void
+set_instruction_pointer(pid_t pid, long addr) {
+ ptrace(PTRACE_POKEUSER, pid, 8*RIP, addr);
+}
+
+void *
+get_stack_pointer(pid_t pid) {
+ return (void *)ptrace(PTRACE_PEEKUSER, pid, 8*RSP, 0);
+}
+
+void *
+get_return_addr(pid_t pid, void * stack_pointer) {
+ return (void *)ptrace(PTRACE_PEEKTEXT, pid, stack_pointer, 0);
+}
diff --git a/sysdeps/linux-gnu/x86_64/signalent.h b/sysdeps/linux-gnu/x86_64/signalent.h
new file mode 100644
index 0000000..5395f82
--- /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/syscallent.h b/sysdeps/linux-gnu/x86_64/syscallent.h
new file mode 100644
index 0000000..2b56c95
--- /dev/null
+++ b/sysdeps/linux-gnu/x86_64/syscallent.h
@@ -0,0 +1,203 @@
+ "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 */
diff --git a/sysdeps/linux-gnu/x86_64/trace.c b/sysdeps/linux-gnu/x86_64/trace.c
new file mode 100644
index 0000000..942670d
--- /dev/null
+++ b/sysdeps/linux-gnu/x86_64/trace.c
@@ -0,0 +1,77 @@
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <sys/ptrace.h>
+#include <sys/reg.h>
+
+#include "ltrace.h"
+
+#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
+# define PTRACE_PEEKUSER PTRACE_PEEKUSR
+#endif
+
+#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR))
+# define PTRACE_POKEUSER PTRACE_POKEUSR
+#endif
+
+/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
+ */
+int
+syscall_p(struct process * proc, int status, int * sysnum) {
+ if (WIFSTOPPED(status) && WSTOPSIG(status)==SIGTRAP) {
+ *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 8*ORIG_RAX, 0);
+
+ if (proc->callstack_depth > 0 &&
+ proc->callstack[proc->callstack_depth-1].is_syscall) {
+ return 2;
+ }
+
+ if (*sysnum>=0) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+long
+gimme_arg(enum tof type, struct process * proc, int arg_num) {
+ if (arg_num==-1) { /* return value */
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8*RAX, 0);
+ }
+
+ if (type==LT_TOF_FUNCTION) {
+ 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:
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(2);
+ }
+ } else if (type==LT_TOF_SYSCALL) {
+ switch(arg_num) {
+ case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, 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;
+}