1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/patches/ltrace/0.5/130-fixes-by-debian.patch Mon Aug 02 21:38:32 2010 +0200
1.3 @@ -0,0 +1,812 @@
1.4 +This patch was vampirised from the 0.5-3.1 Debian-packaged version of ltrace,
1.5 +and contains the following fixes (exerpt from the Debian changelog). Moreover,
1.6 +you will also find an exerpt of the Debian copyright file with proper
1.7 +attribution.
1.8 +
1.9 +================ Debian changelog exerpt ================
1.10 +ltrace (0.5-3.1) unstable; urgency=low
1.11 +
1.12 + * Non-maintainer upload.
1.13 + * Big thanks for Anderson Lizardo for providing patches!
1.14 + * Add generic support for arm targets, Closes: #176413
1.15 + * Save funtion arguments on arm, Closes: #462530
1.16 + * Add thumb instruction support, Closes: #462531
1.17 + * Add basic arm/eabi support, Closes: #450931
1.18 + * fix exec() testcase cleanup, Closes: #462532
1.19 + * fix memory corruption in clone() test, Closes: #462533
1.20 + * fix tracing child with "-p" option, Closes: #462535
1.21 + * Update standard, no changes
1.22 +
1.23 + -- Riku Voipio <riku.voipio@iki.fi> Tue, 29 Jan 2008 00:26:50 +0200
1.24 +
1.25 +ltrace (0.5-3) unstable; urgency=low
1.26 +
1.27 + * Really fix compilation problems in ppc (!)
1.28 +
1.29 + -- Juan Cespedes <cespedes@debian.org> Fri, 31 Aug 2007 19:04:03 +0200
1.30 +
1.31 +ltrace (0.5-2) unstable; urgency=low
1.32 +
1.33 + * Fixed compilation issue in ppc
1.34 +
1.35 + -- Juan Cespedes <cespedes@debian.org> Fri, 31 Aug 2007 13:53:27 +0200
1.36 +
1.37 +ltrace (0.5-1) unstable; urgency=low
1.38 +
1.39 + * New upstream version
1.40 + * Remove some unneeded files in /usr/share/doc (ChangeLog, COPYING...)
1.41 + * Fix several typos (closes: Bug#372928)
1.42 + * Added more system calls to ltrace.conf
1.43 +
1.44 + -- Juan Cespedes <cespedes@debian.org> Thu, 30 Aug 2007 14:54:44 +0200
1.45 +============== End Debian changelog exerpt ==============
1.46 +
1.47 +================ Debian copyright exerpt ================
1.48 +Copyrights
1.49 +----------
1.50 +Copyright (C) 1997-2007 Juan Cespedes <cespedes@debian.org>
1.51 +
1.52 +ARMLinux port: Copyright (C) 1998 Pat Beirne <pbeirne@home.com>
1.53 +m68k port: Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
1.54 +Misc fixes: Copyright (C) 1999 Morten Eriksen <mortene@sim.no>
1.55 +s390 port: Copyright (C) 2001 IBM Poughkeepsie, IBM Cororation <slate@us.ibm.com>
1.56 +ELF hacking: Copyright (C) 1999 Silvio Cesare <silvio@big.net.au>
1.57 +PowerPC port: Copyright (C) 2001-2002 Anton Blanchard <anton@samba.org>
1.58 +SPARC port: Copyright (C) 1999 Jakub Jelinek <jakub@redhat.com>
1.59 +
1.60 +Autoconf stuff: Copyright 1992-1996 Free Software Foundation, Inc.
1.61 +install-sh: Copyright 1991 by the Massachusetts Institute of Technology
1.62 +C++ demangle: Copyright 1989-1997 Free Software Foundation, Inc.
1.63 +============== End Debian copyright exerpt ==============
1.64 +
1.65 +diff -durN ltrace-0.5.orig/breakpoints.c ltrace-0.5/breakpoints.c
1.66 +--- ltrace-0.5.orig/breakpoints.c 2006-06-14 06:55:21.000000000 +0200
1.67 ++++ ltrace-0.5/breakpoints.c 2008-11-04 19:25:50.000000000 +0100
1.68 +@@ -53,6 +53,10 @@
1.69 + if (libsym)
1.70 + libsym->brkpnt = sbp;
1.71 + }
1.72 ++#ifdef __arm__
1.73 ++ sbp->thumb_mode = proc->thumb_mode;
1.74 ++ proc->thumb_mode = 0;
1.75 ++#endif
1.76 + sbp->enabled++;
1.77 + if (sbp->enabled == 1 && proc->pid)
1.78 + enable_breakpoint(proc->pid, sbp);
1.79 +diff -durN ltrace-0.5.orig/elf.c ltrace-0.5/elf.c
1.80 +--- ltrace-0.5.orig/elf.c 2006-06-14 06:55:21.000000000 +0200
1.81 ++++ ltrace-0.5/elf.c 2008-11-04 19:25:50.000000000 +0100
1.82 +@@ -464,8 +464,7 @@
1.83 + if (strcmp(xptr->name, PLTs_initialized_by_here) == 0) {
1.84 + if (lte->ehdr.e_entry) {
1.85 + add_library_symbol (
1.86 +- elf_plt2addr (lte, (void*)(long)
1.87 +- lte->ehdr.e_entry),
1.88 ++ opd2addr (lte, lte->ehdr.e_entry),
1.89 + PLTs_initialized_by_here,
1.90 + lib_tail, 1, 0);
1.91 + fprintf (stderr, "WARNING: Using e_ent"
1.92 +diff -durN ltrace-0.5.orig/etc/ltrace.conf ltrace-0.5/etc/ltrace.conf
1.93 +--- ltrace-0.5.orig/etc/ltrace.conf 2006-02-20 22:55:47.000000000 +0100
1.94 ++++ ltrace-0.5/etc/ltrace.conf 2008-11-04 19:25:50.000000000 +0100
1.95 +@@ -444,3 +444,81 @@
1.96 + int SYS_removexattr(string,string);
1.97 + int SYS_lremovexattr(string,string);
1.98 + int SYS_fremovexattr(int,string);
1.99 ++int SYS_chdir(string);
1.100 ++int SYS_fchdir(int);
1.101 ++int SYS_chmod(string,octal);
1.102 ++int SYS_fchmod(int,octal);
1.103 ++int SYS_chown(string,int,int);
1.104 ++int SYS_fchown(int,int,int);
1.105 ++int SYS_lchown(string,int,int);
1.106 ++int SYS_chroot(string);
1.107 ++int SYS_dup(int);
1.108 ++int SYS_dup2(int,int);
1.109 ++int SYS_fdatasync(int);
1.110 ++int SYS_fsync(int);
1.111 ++int SYS_getpriority(int,int);
1.112 ++int SYS_setpriority(int,int,int);
1.113 ++int SYS_getrlimit(int,addr);
1.114 ++int SYS_setrlimit(int,addr);
1.115 ++int SYS_gettimeofday(addr,addr);
1.116 ++int SYS_settimeofday(addr,addr);
1.117 ++int SYS_setfsgid(int);
1.118 ++int SYS_setfsuid(int);
1.119 ++int SYS_getuid(void);
1.120 ++int SYS_setuid(int);
1.121 ++int SYS_getgid(void);
1.122 ++int SYS_setgid(int);
1.123 ++int SYS_getsid(int);
1.124 ++int SYS_setsid(int);
1.125 ++int SYS_setreuid(int,int);
1.126 ++int SYS_setregid(int,int);
1.127 ++int SYS_geteuid(void);
1.128 ++int SYS_getegid(void);
1.129 ++int SYS_setpgid(int,int);
1.130 ++int SYS_getresuid(addr,addr,addr);
1.131 ++int SYS_setresuid(int,int,int);
1.132 ++int SYS_getresgid(addr,addr,addr);
1.133 ++int SYS_setresgid(int,int,int);
1.134 ++int SYS_kill(int,int);
1.135 ++int SYS_link(string,string);
1.136 ++int SYS_madvise(addr,ulong,int);
1.137 ++int SYS_mkdir(string,octal);
1.138 ++int SYS_mknod(string,octal,int);
1.139 ++int SYS_msync(addr,ulong,int);
1.140 ++int SYS_nice(int);
1.141 ++int SYS_poll(addr,uint,int);
1.142 ++int SYS_readdir(uint,addr,uint);
1.143 ++int SYS_readlink(string,string,ulong);
1.144 ++int SYS_reboot(int,int,int,addr);
1.145 ++int SYS_rename(string,string);
1.146 ++int SYS_rmdir(string);
1.147 ++int SYS_sigaltstack(addr,addr);
1.148 ++int SYS_statfs(string,addr);
1.149 ++int SYS_fstatfs(int,addr);
1.150 ++int SYS_fstat(int,addr);
1.151 ++int SYS_lstat(string,addr);
1.152 ++int SYS_stime(addr);
1.153 ++int SYS_symlink(string, string);
1.154 ++int SYS_sysinfo(addr);
1.155 ++int SYS_syslog(int,string,int);
1.156 ++int SYS_truncate(string,long);
1.157 ++int SYS_ftruncate(int,long);
1.158 ++int SYS_mount(string,string,string,ulong,addr);
1.159 ++int SYS_umount(string);
1.160 ++int SYS_umount2(string,int);
1.161 ++int SYS_unlink(string);
1.162 ++int SYS_utime(string,addr);
1.163 ++long SYS_lseek(int,long,int);
1.164 ++addr SYS_signal(int,addr);
1.165 ++int SYS_sigaction(int,addr,addr);
1.166 ++int SYS_pause(void);
1.167 ++int SYS_sigpending(addr);
1.168 ++int SYS_sigprocmask(int,addr,addr);
1.169 ++int SYS_sigqueue(int,int,addr);
1.170 ++int SYS_sigsuspend(addr);
1.171 ++int SYS_wait(addr);
1.172 ++int SYS_waitpid(int,addr,int);
1.173 ++ulong SYS_readv(int,addr,int);
1.174 ++ulong SYS_writev(int,addr,int);
1.175 ++int SYS_mprotect(addr,int,int);
1.176 ++int SYS_access(string,octal);
1.177 +diff -durN ltrace-0.5.orig/ltrace.1 ltrace-0.5/ltrace.1
1.178 +--- ltrace-0.5.orig/ltrace.1 2006-06-16 03:15:18.000000000 +0200
1.179 ++++ ltrace-0.5/ltrace.1 2008-11-04 19:25:50.000000000 +0100
1.180 +@@ -30,7 +30,7 @@
1.181 + .TP
1.182 + .I \-C, \-\-demangle
1.183 + Decode (demangle) low-level symbol names into user-level names.
1.184 +-Besides removing any initial underscore prepended by the system,
1.185 ++Besides removing any initial underscore prefix used by the system,
1.186 + this makes C++ function names readable.
1.187 + .TP
1.188 + .I \-d, \-\-debug
1.189 +diff -durN ltrace-0.5.orig/ltrace.c ltrace-0.5/ltrace.c
1.190 +--- ltrace-0.5.orig/ltrace.c 2006-02-20 22:48:07.000000000 +0100
1.191 ++++ ltrace-0.5/ltrace.c 2008-11-04 19:25:50.000000000 +0100
1.192 +@@ -54,6 +54,9 @@
1.193 + {
1.194 + exiting = 1;
1.195 + debug(1, "Received interrupt signal; exiting...");
1.196 ++ if (opt_o) {
1.197 ++ fclose(output);
1.198 ++ }
1.199 + signal(SIGINT, SIG_IGN);
1.200 + signal(SIGTERM, SIG_IGN);
1.201 + signal(SIGALRM, signal_alarm);
1.202 +@@ -74,6 +77,9 @@
1.203 + if (opt_c) {
1.204 + show_summary();
1.205 + }
1.206 ++ if (opt_o) {
1.207 ++ fclose(output);
1.208 ++ }
1.209 + }
1.210 +
1.211 + static void guess_cols(void)
1.212 +diff -durN ltrace-0.5.orig/ltrace.h ltrace-0.5/ltrace.h
1.213 +--- ltrace-0.5.orig/ltrace.h 2006-06-14 06:55:21.000000000 +0200
1.214 ++++ ltrace-0.5/ltrace.h 2008-11-04 19:25:50.000000000 +0100
1.215 +@@ -26,6 +26,9 @@
1.216 + unsigned char orig_value[BREAKPOINT_LENGTH];
1.217 + int enabled;
1.218 + struct library_symbol *libsym;
1.219 ++#ifdef __arm__
1.220 ++ int thumb_mode;
1.221 ++#endif
1.222 + };
1.223 +
1.224 + enum arg_type {
1.225 +@@ -119,6 +122,9 @@
1.226 + void *arch_ptr;
1.227 + short e_machine;
1.228 + short need_to_reinitialize_breakpoints;
1.229 ++#ifdef __arm__
1.230 ++ int thumb_mode; /* ARM execution mode: 0: ARM mode, 1: Thumb mode */
1.231 ++#endif
1.232 +
1.233 + /* output: */
1.234 + enum tof type_being_displayed;
1.235 +@@ -136,12 +142,14 @@
1.236 + LT_EV_EXIT_SIGNAL,
1.237 + LT_EV_SYSCALL,
1.238 + LT_EV_SYSRET,
1.239 ++ LT_EV_ARCH_SYSCALL,
1.240 ++ LT_EV_ARCH_SYSRET,
1.241 + LT_EV_BREAKPOINT
1.242 + } thing;
1.243 + union {
1.244 + int ret_val; /* _EV_EXIT */
1.245 + int signum; /* _EV_SIGNAL, _EV_EXIT_SIGNAL */
1.246 +- int sysnum; /* _EV_SYSCALL, _EV_SYSRET */
1.247 ++ int sysnum; /* _EV_SYSCALL, _EV_SYSRET, _EV_ARCH_SYSCALL, _EV_ARCH_SYSRET */
1.248 + void *brk_addr; /* _EV_BREAKPOINT */
1.249 + } e_un;
1.250 + };
1.251 +diff -durN ltrace-0.5.orig/options.c ltrace-0.5/options.c
1.252 +--- ltrace-0.5.orig/options.c 2006-04-24 22:06:23.000000000 +0200
1.253 ++++ ltrace-0.5/options.c 2008-11-04 19:25:50.000000000 +0100
1.254 +@@ -42,6 +42,7 @@
1.255 + #endif
1.256 + int opt_n = 0; /* indent trace output according to program flow */
1.257 + int opt_T = 0; /* show the time spent inside each call */
1.258 ++int opt_o = 0; /* output to a specific file */
1.259 +
1.260 + /* List of pids given to option -p: */
1.261 + struct opt_p_t *opt_p = NULL; /* attach to process with a given pid */
1.262 +@@ -274,6 +275,7 @@
1.263 + opt_n = atoi(optarg);
1.264 + break;
1.265 + case 'o':
1.266 ++ opt_o++;
1.267 + output = fopen(optarg, "w");
1.268 + if (!output) {
1.269 + fprintf(stderr,
1.270 +diff -durN ltrace-0.5.orig/options.h ltrace-0.5/options.h
1.271 +--- ltrace-0.5.orig/options.h 2006-03-13 18:43:13.000000000 +0100
1.272 ++++ ltrace-0.5/options.h 2008-11-04 19:25:50.000000000 +0100
1.273 +@@ -20,6 +20,7 @@
1.274 + extern int opt_C; /* Demanglelow-level symbol names into user-level names */
1.275 + extern int opt_n; /* indent trace output according to program flow */
1.276 + extern int opt_T; /* show the time spent inside each call */
1.277 ++extern int opt_o; /* output to a specific file */
1.278 +
1.279 + struct opt_p_t {
1.280 + pid_t pid;
1.281 +diff -durN ltrace-0.5.orig/process_event.c ltrace-0.5/process_event.c
1.282 +--- ltrace-0.5.orig/process_event.c 2006-06-14 06:55:21.000000000 +0200
1.283 ++++ ltrace-0.5/process_event.c 2008-11-04 19:25:50.000000000 +0100
1.284 +@@ -24,7 +24,9 @@
1.285 + static void process_exit(struct event *event);
1.286 + static void process_exit_signal(struct event *event);
1.287 + static void process_syscall(struct event *event);
1.288 ++static void process_arch_syscall(struct event *event);
1.289 + static void process_sysret(struct event *event);
1.290 ++static void process_arch_sysret(struct event *event);
1.291 + static void process_breakpoint(struct event *event);
1.292 + static void remove_proc(struct process *proc);
1.293 +
1.294 +@@ -81,6 +83,24 @@
1.295 + }
1.296 + }
1.297 +
1.298 ++static char *arch_sysname(struct process *proc, int sysnum)
1.299 ++{
1.300 ++ static char result[128];
1.301 ++ static char *arch_syscalent[] = {
1.302 ++#include "arch_syscallent.h"
1.303 ++ };
1.304 ++ int nsyscals = sizeof arch_syscalent / sizeof arch_syscalent[0];
1.305 ++
1.306 ++ if (sysnum < 0 || sysnum >= nsyscals) {
1.307 ++ sprintf(result, "ARCH_%d", sysnum);
1.308 ++ return result;
1.309 ++ } else {
1.310 ++ sprintf(result, "ARCH_%s",
1.311 ++ arch_syscalent[sysnum]);
1.312 ++ return result;
1.313 ++ }
1.314 ++}
1.315 ++
1.316 + void process_event(struct event *event)
1.317 + {
1.318 + switch (event->thing) {
1.319 +@@ -115,6 +135,18 @@
1.320 + event->e_un.sysnum);
1.321 + process_sysret(event);
1.322 + return;
1.323 ++ case LT_EV_ARCH_SYSCALL:
1.324 ++ debug(1, "event: arch_syscall (%s [%d])",
1.325 ++ arch_sysname(event->proc, event->e_un.sysnum),
1.326 ++ event->e_un.sysnum);
1.327 ++ process_arch_syscall(event);
1.328 ++ return;
1.329 ++ case LT_EV_ARCH_SYSRET:
1.330 ++ debug(1, "event: arch_sysret (%s [%d])",
1.331 ++ arch_sysname(event->proc, event->e_un.sysnum),
1.332 ++ event->e_un.sysnum);
1.333 ++ process_arch_sysret(event);
1.334 ++ return;
1.335 + case LT_EV_BREAKPOINT:
1.336 + debug(1, "event: breakpoint");
1.337 + process_breakpoint(event);
1.338 +@@ -195,6 +227,19 @@
1.339 + continue_process(event->proc->pid);
1.340 + }
1.341 +
1.342 ++static void process_arch_syscall(struct event *event)
1.343 ++{
1.344 ++ if (opt_S) {
1.345 ++ output_left(LT_TOF_SYSCALL, event->proc,
1.346 ++ arch_sysname(event->proc, event->e_un.sysnum));
1.347 ++ }
1.348 ++ if (event->proc->breakpoints_enabled == 0) {
1.349 ++ enable_all_breakpoints(event->proc);
1.350 ++ }
1.351 ++ callstack_push_syscall(event->proc, 0xf0000 + event->e_un.sysnum);
1.352 ++ continue_process(event->proc->pid);
1.353 ++}
1.354 ++
1.355 + struct timeval current_time_spent;
1.356 +
1.357 + static void calc_time_spent(struct process *proc)
1.358 +@@ -257,6 +302,19 @@
1.359 + continue_process(event->proc->pid);
1.360 + }
1.361 +
1.362 ++static void process_arch_sysret(struct event *event)
1.363 ++{
1.364 ++ if (opt_T || opt_c) {
1.365 ++ calc_time_spent(event->proc);
1.366 ++ }
1.367 ++ callstack_pop(event->proc);
1.368 ++ if (opt_S) {
1.369 ++ output_right(LT_TOF_SYSCALLR, event->proc,
1.370 ++ arch_sysname(event->proc, event->e_un.sysnum));
1.371 ++ }
1.372 ++ continue_process(event->proc->pid);
1.373 ++}
1.374 ++
1.375 + static void process_breakpoint(struct event *event)
1.376 + {
1.377 + int i, j;
1.378 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/Makefile ltrace-0.5/sysdeps/linux-gnu/Makefile
1.379 +--- ltrace-0.5.orig/sysdeps/linux-gnu/Makefile 2008-11-04 19:25:11.000000000 +0100
1.380 ++++ ltrace-0.5/sysdeps/linux-gnu/Makefile 2008-11-04 19:25:50.000000000 +0100
1.381 +@@ -2,7 +2,7 @@
1.382 +
1.383 + OBJ = trace.o proc.o breakpoint.o
1.384 +
1.385 +-all: sysdep.h signalent.h syscallent.h signalent1.h syscallent1.h ../sysdep.o
1.386 ++all: sysdep.h signalent.h syscallent.h arch_syscallent.h signalent1.h syscallent1.h ../sysdep.o
1.387 +
1.388 + sysdep.h: $(ARCH)/arch.h
1.389 + cat $(ARCH)/arch.h > sysdep.h
1.390 +@@ -26,6 +26,13 @@
1.391 + > syscallent1.h; \
1.392 + fi
1.393 +
1.394 ++arch_syscallent.h:
1.395 ++ if [ -f $(ARCH)/arch_syscallent.h ]; then \
1.396 ++ cp $(ARCH)/arch_syscallent.h arch_syscallent.h; \
1.397 ++ else \
1.398 ++ > arch_syscallent.h; \
1.399 ++ fi
1.400 ++
1.401 + ../sysdep.o: os.o $(ARCH)/arch.o
1.402 + $(CC) -nostdlib -r -o ../sysdep.o os.o $(ARCH)/arch.o
1.403 +
1.404 +@@ -37,7 +44,7 @@
1.405 +
1.406 + clean:
1.407 + $(MAKE) -C $(ARCH) clean
1.408 +- rm -f $(OBJ) sysdep.h signalent.h signalent1.h syscallent.h
1.409 ++ rm -f $(OBJ) sysdep.h signalent.h signalent1.h syscallent.h arch_syscallent.h
1.410 + rm -f syscallent1.h os.o sysdep.o ../sysdep.o
1.411 +
1.412 + dummy:
1.413 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arch_mksyscallent ltrace-0.5/sysdeps/linux-gnu/arch_mksyscallent
1.414 +--- ltrace-0.5.orig/sysdeps/linux-gnu/arch_mksyscallent 1970-01-01 01:00:00.000000000 +0100
1.415 ++++ ltrace-0.5/sysdeps/linux-gnu/arch_mksyscallent 2008-11-04 19:25:50.000000000 +0100
1.416 +@@ -0,0 +1,43 @@
1.417 ++#!/usr/bin/awk -f
1.418 ++
1.419 ++# hack expression to generate arch_syscallent.h from <asm/unistd.h>
1.420 ++# It reads from stdin and writes to stdout
1.421 ++# Currently (linux-2.6.16), it works OK on arm
1.422 ++# It is untested in other architectures
1.423 ++
1.424 ++BEGIN {
1.425 ++ max=0;
1.426 ++ FS="[ \t\n()+]+";
1.427 ++}
1.428 ++
1.429 ++{
1.430 ++# printf("/%s/%s/%s/%s/\n", $1, $2, $3, $4);
1.431 ++ if (($1 ~ /^#define$/) && ($2 ~ /^__[A-Z]+_NR_/)) {
1.432 ++ sub(/^__[A-Z]+_NR_/,"",$2);
1.433 ++ if (($3>=0) && ($3<=1000)) {
1.434 ++ SYSCALL[$3]=$2;
1.435 ++ if ($3 > max) {
1.436 ++ max=$3;
1.437 ++ }
1.438 ++ } else if (($3 ~ /^__[A-Z]+_NR_BASE$/) && ($4>=0) && ($4<=1000)) {
1.439 ++ SYSCALL[$4]=$2;
1.440 ++ if ($4 > max) {
1.441 ++ max=$4;
1.442 ++ }
1.443 ++ }
1.444 ++ }
1.445 ++}
1.446 ++
1.447 ++END {
1.448 ++ for(i=0; i<=max; i++) {
1.449 ++ if (!SYSCALL[i]) {
1.450 ++ SYSCALL[i] = i;
1.451 ++ }
1.452 ++ pad = 32 - length(SYSCALL[i]);
1.453 ++ if (pad<1) {
1.454 ++ pad=1;
1.455 ++ }
1.456 ++ printf("\t\"%s\",%*s/* %d */\n", SYSCALL[i], pad, "", i);
1.457 ++ }
1.458 ++}
1.459 ++
1.460 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/Makefile ltrace-0.5/sysdeps/linux-gnu/arm/Makefile
1.461 +--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/Makefile 2006-02-20 22:44:45.000000000 +0100
1.462 ++++ ltrace-0.5/sysdeps/linux-gnu/arm/Makefile 2008-11-04 19:25:50.000000000 +0100
1.463 +@@ -1,4 +1,4 @@
1.464 +-OBJ = trace.o regs.o plt.o
1.465 ++OBJ = trace.o regs.o plt.o breakpoint.o
1.466 +
1.467 + all: arch.o
1.468 +
1.469 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/arch.h ltrace-0.5/sysdeps/linux-gnu/arm/arch.h
1.470 +--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/arch.h 2006-04-24 22:06:23.000000000 +0200
1.471 ++++ ltrace-0.5/sysdeps/linux-gnu/arm/arch.h 2008-11-04 19:25:50.000000000 +0100
1.472 +@@ -1,5 +1,10 @@
1.473 +-#define BREAKPOINT_VALUE { 0x01, 0x00, 0x9f, 0xef }
1.474 ++#define ARCH_HAVE_ENABLE_BREAKPOINT 1
1.475 ++#define ARCH_HAVE_DISABLE_BREAKPOINT 1
1.476 ++
1.477 ++#define BREAKPOINT_VALUE { 0xf0, 0x01, 0xf0, 0xe7 }
1.478 + #define BREAKPOINT_LENGTH 4
1.479 ++#define THUMB_BREAKPOINT_VALUE { 0x01, 0xde }
1.480 ++#define THUMB_BREAKPOINT_LENGTH 2
1.481 + #define DECR_PC_AFTER_BREAK 0
1.482 +
1.483 + #define LT_ELFCLASS ELFCLASS32
1.484 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/arch_syscallent.h ltrace-0.5/sysdeps/linux-gnu/arm/arch_syscallent.h
1.485 +--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/arch_syscallent.h 1970-01-01 01:00:00.000000000 +0100
1.486 ++++ ltrace-0.5/sysdeps/linux-gnu/arm/arch_syscallent.h 2008-11-04 19:25:50.000000000 +0100
1.487 +@@ -0,0 +1,6 @@
1.488 ++ "0", /* 0 */
1.489 ++ "breakpoint", /* 1 */
1.490 ++ "cacheflush", /* 2 */
1.491 ++ "usr26", /* 3 */
1.492 ++ "usr32", /* 4 */
1.493 ++ "set_tls", /* 5 */
1.494 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/breakpoint.c ltrace-0.5/sysdeps/linux-gnu/arm/breakpoint.c
1.495 +--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/breakpoint.c 1970-01-01 01:00:00.000000000 +0100
1.496 ++++ ltrace-0.5/sysdeps/linux-gnu/arm/breakpoint.c 2008-11-04 19:25:50.000000000 +0100
1.497 +@@ -0,0 +1,86 @@
1.498 ++/*
1.499 ++ * This file is part of ltrace.
1.500 ++ *
1.501 ++ * Copyright (C) 2007 by Instituto Nokia de Tecnologia (INdT)
1.502 ++ *
1.503 ++ * Author: Anderson Lizardo <anderson.lizardo@indt.org.br>
1.504 ++ *
1.505 ++ * This program is free software; you can redistribute it and/or
1.506 ++ * modify it under the terms of the GNU General Public License
1.507 ++ * version 2 as published by the Free Software Foundation.
1.508 ++ *
1.509 ++ * This program is distributed in the hope that it will be useful, but
1.510 ++ * WITHOUT ANY WARRANTY; without even the implied warranty of
1.511 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1.512 ++ * General Public License for more details.
1.513 ++ *
1.514 ++ * You should have received a copy of the GNU General Public License
1.515 ++ * along with this program; if not, write to the Free Software
1.516 ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
1.517 ++ * 02110-1301 USA
1.518 ++ *
1.519 ++ * Modified from sysdeps/linux-gnu/breakpoint.c and added ARM Thumb support.
1.520 ++*/
1.521 ++
1.522 ++#include <sys/ptrace.h>
1.523 ++#include "config.h"
1.524 ++#include "arch.h"
1.525 ++#include "options.h"
1.526 ++#include "output.h"
1.527 ++#include "debug.h"
1.528 ++
1.529 ++void arch_enable_breakpoint(pid_t pid, struct breakpoint *sbp)
1.530 ++{
1.531 ++ unsigned int i, j;
1.532 ++ const unsigned char break_insn[] = BREAKPOINT_VALUE;
1.533 ++ const unsigned char thumb_break_insn[] = THUMB_BREAKPOINT_VALUE;
1.534 ++
1.535 ++ debug(1, "arch_enable_breakpoint(%d,%p)", pid, sbp->addr);
1.536 ++
1.537 ++ for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
1.538 ++ long a =
1.539 ++ ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
1.540 ++ 0);
1.541 ++ unsigned char *bytes = (unsigned char *)&a;
1.542 ++
1.543 ++ debug(2, "current = 0x%lx, orig_value = 0x%lx, thumb_mode = %d", a, *(long *)&sbp->orig_value, sbp->thumb_mode);
1.544 ++ for (j = 0;
1.545 ++ j < sizeof(long)
1.546 ++ && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
1.547 ++
1.548 ++ sbp->orig_value[i * sizeof(long) + j] = bytes[j];
1.549 ++ if (!sbp->thumb_mode) {
1.550 ++ bytes[j] = break_insn[i * sizeof(long) + j];
1.551 ++ }
1.552 ++ else if (j < THUMB_BREAKPOINT_LENGTH) {
1.553 ++ bytes[j] = thumb_break_insn[i * sizeof(long) + j];
1.554 ++ }
1.555 ++ }
1.556 ++ ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
1.557 ++ }
1.558 ++}
1.559 ++
1.560 ++void arch_disable_breakpoint(pid_t pid, const struct breakpoint *sbp)
1.561 ++{
1.562 ++ unsigned int i, j;
1.563 ++ const unsigned char break_insn[] = BREAKPOINT_VALUE;
1.564 ++ const unsigned char thumb_break_insn[] = THUMB_BREAKPOINT_VALUE;
1.565 ++
1.566 ++ debug(1, "arch_disable_breakpoint(%d,%p)", pid, sbp->addr);
1.567 ++
1.568 ++ for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
1.569 ++ long a =
1.570 ++ ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
1.571 ++ 0);
1.572 ++ unsigned char *bytes = (unsigned char *)&a;
1.573 ++
1.574 ++ debug(2, "current = 0x%lx, orig_value = 0x%lx, thumb_mode = %d", a, *(long *)&sbp->orig_value, sbp->thumb_mode);
1.575 ++ for (j = 0;
1.576 ++ j < sizeof(long)
1.577 ++ && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
1.578 ++
1.579 ++ bytes[j] = sbp->orig_value[i * sizeof(long) + j];
1.580 ++ }
1.581 ++ ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
1.582 ++ }
1.583 ++}
1.584 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/ptrace.h ltrace-0.5/sysdeps/linux-gnu/arm/ptrace.h
1.585 +--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/ptrace.h 2006-02-20 22:44:45.000000000 +0100
1.586 ++++ ltrace-0.5/sysdeps/linux-gnu/arm/ptrace.h 2008-11-04 19:25:50.000000000 +0100
1.587 +@@ -1 +1,9 @@
1.588 + #include <sys/ptrace.h>
1.589 ++#include <asm/ptrace.h>
1.590 ++
1.591 ++typedef struct {
1.592 ++ int valid;
1.593 ++ struct pt_regs regs;
1.594 ++ long func_arg[5];
1.595 ++ long sysc_arg[5];
1.596 ++} proc_archdep;
1.597 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/regs.c ltrace-0.5/sysdeps/linux-gnu/arm/regs.c
1.598 +--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/regs.c 2006-02-20 22:48:07.000000000 +0100
1.599 ++++ ltrace-0.5/sysdeps/linux-gnu/arm/regs.c 2008-11-04 19:25:50.000000000 +0100
1.600 +@@ -39,5 +39,10 @@
1.601 + * a CISC architecture; in our case, we don't need that */
1.602 + void *get_return_addr(struct process *proc, void *stack_pointer)
1.603 + {
1.604 +- return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_lr, 0);
1.605 ++ long addr = ptrace(PTRACE_PEEKUSER, proc->pid, off_lr, 0);
1.606 ++
1.607 ++ proc->thumb_mode = addr & 1;
1.608 ++ if (proc->thumb_mode)
1.609 ++ addr &= ~1;
1.610 ++ return (void *)addr;
1.611 + }
1.612 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/trace.c ltrace-0.5/sysdeps/linux-gnu/arm/trace.c
1.613 +--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/trace.c 2006-02-20 22:48:07.000000000 +0100
1.614 ++++ ltrace-0.5/sysdeps/linux-gnu/arm/trace.c 2008-11-04 19:25:50.000000000 +0100
1.615 +@@ -2,6 +2,7 @@
1.616 + #include "config.h"
1.617 + #endif
1.618 +
1.619 ++#include <string.h>
1.620 + #include <sys/types.h>
1.621 + #include <sys/wait.h>
1.622 + #include <signal.h>
1.623 +@@ -9,6 +10,8 @@
1.624 + #include <asm/ptrace.h>
1.625 +
1.626 + #include "ltrace.h"
1.627 ++#include "output.h"
1.628 ++#include "ptrace.h"
1.629 +
1.630 + #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
1.631 + # define PTRACE_PEEKUSER PTRACE_PEEKUSR
1.632 +@@ -18,19 +21,25 @@
1.633 + # define PTRACE_POKEUSER PTRACE_POKEUSR
1.634 + #endif
1.635 +
1.636 +-/* syscall tracing protocol: ArmLinux
1.637 +- on the way in, ip is 0
1.638 +- on the way out, ip is non-zero
1.639 +-*/
1.640 + #define off_r0 0
1.641 ++#define off_r7 28
1.642 + #define off_ip 48
1.643 + #define off_pc 60
1.644 +
1.645 + void get_arch_dep(struct process *proc)
1.646 + {
1.647 ++ proc_archdep *a;
1.648 ++
1.649 ++ if (!proc->arch_ptr)
1.650 ++ proc->arch_ptr = (void *)malloc(sizeof(proc_archdep));
1.651 ++ a = (proc_archdep *) (proc->arch_ptr);
1.652 ++ a->valid = (ptrace(PTRACE_GETREGS, proc->pid, 0, &a->regs) >= 0);
1.653 + }
1.654 +
1.655 +-/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
1.656 ++/* Returns 0 if not a syscall,
1.657 ++ * 1 if syscall entry, 2 if syscall exit,
1.658 ++ * 3 if arch-specific syscall entry, 4 if arch-specific syscall exit,
1.659 ++ * -1 on error.
1.660 + */
1.661 + int syscall_p(struct process *proc, int status, int *sysnum)
1.662 + {
1.663 +@@ -40,19 +49,39 @@
1.664 + int pc = ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0);
1.665 + /* fetch the SWI instruction */
1.666 + int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 4, 0);
1.667 ++ int ip = ptrace(PTRACE_PEEKUSER, proc->pid, off_ip, 0);
1.668 +
1.669 +- *sysnum = insn & 0xFFFF;
1.670 +- /* if it is a syscall, return 1 or 2 */
1.671 +- if ((insn & 0xFFFF0000) == 0xef900000) {
1.672 +- return ptrace(PTRACE_PEEKUSER, proc->pid, off_ip,
1.673 +- 0) ? 2 : 1;
1.674 ++ if (insn == 0xef000000 || insn == 0x0f000000) {
1.675 ++ /* EABI syscall */
1.676 ++ *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, off_r7, 0);
1.677 ++ } else if ((insn & 0xfff00000) == 0xef900000) {
1.678 ++ /* old ABI syscall */
1.679 ++ *sysnum = insn & 0xfffff;
1.680 ++ } else {
1.681 ++ /* TODO: handle swi<cond> variations */
1.682 ++ /* one possible reason for getting in here is that we
1.683 ++ * are coming from a signal handler, so the current
1.684 ++ * PC does not point to the instruction just after the
1.685 ++ * "swi" one. */
1.686 ++ output_line(proc, "unexpected instruction 0x%x at %p", insn, pc - 4);
1.687 ++ return -1;
1.688 ++ }
1.689 ++ if ((*sysnum & 0xf0000) == 0xf0000) {
1.690 ++ /* arch-specific syscall */
1.691 ++ *sysnum &= ~0xf0000;
1.692 ++ return ip ? 4 : 3;
1.693 + }
1.694 ++ /* ARM syscall convention: on syscall entry, ip is zero;
1.695 ++ * on syscall exit, ip is non-zero */
1.696 ++ return ip ? 2 : 1;
1.697 + }
1.698 + return 0;
1.699 + }
1.700 +
1.701 + long gimme_arg(enum tof type, struct process *proc, int arg_num)
1.702 + {
1.703 ++ proc_archdep *a = (proc_archdep *) proc->arch_ptr;
1.704 ++
1.705 + if (arg_num == -1) { /* return value */
1.706 + return ptrace(PTRACE_PEEKUSER, proc->pid, off_r0, 0);
1.707 + }
1.708 +@@ -60,6 +89,10 @@
1.709 + /* deal with the ARM calling conventions */
1.710 + if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
1.711 + if (arg_num < 4) {
1.712 ++ if (a->valid && type == LT_TOF_FUNCTION)
1.713 ++ return a->regs.uregs[arg_num];
1.714 ++ if (a->valid && type == LT_TOF_FUNCTIONR)
1.715 ++ return a->func_arg[arg_num];
1.716 + return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num,
1.717 + 0);
1.718 + } else {
1.719 +@@ -69,6 +102,10 @@
1.720 + }
1.721 + } else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) {
1.722 + if (arg_num < 5) {
1.723 ++ if (a->valid && type == LT_TOF_SYSCALL)
1.724 ++ return a->regs.uregs[arg_num];
1.725 ++ if (a->valid && type == LT_TOF_SYSCALLR)
1.726 ++ return a->sysc_arg[arg_num];
1.727 + return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num,
1.728 + 0);
1.729 + } else {
1.730 +@@ -86,4 +123,11 @@
1.731 +
1.732 + void save_register_args(enum tof type, struct process *proc)
1.733 + {
1.734 ++ proc_archdep *a = (proc_archdep *) proc->arch_ptr;
1.735 ++ if (a->valid) {
1.736 ++ if (type == LT_TOF_FUNCTION)
1.737 ++ memcpy(a->func_arg, a->regs.uregs, sizeof(a->func_arg));
1.738 ++ else
1.739 ++ memcpy(a->sysc_arg, a->regs.uregs, sizeof(a->sysc_arg));
1.740 ++ }
1.741 + }
1.742 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/ppc/arch.h ltrace-0.5/sysdeps/linux-gnu/ppc/arch.h
1.743 +--- ltrace-0.5.orig/sysdeps/linux-gnu/ppc/arch.h 2006-06-14 06:55:21.000000000 +0200
1.744 ++++ ltrace-0.5/sysdeps/linux-gnu/ppc/arch.h 2008-11-04 19:25:50.000000000 +0100
1.745 +@@ -4,9 +4,12 @@
1.746 +
1.747 + #define LT_ELFCLASS ELFCLASS32
1.748 + #define LT_ELF_MACHINE EM_PPC
1.749 ++
1.750 + #ifdef __powerpc64__ // Says 'ltrace' is 64 bits, says nothing about target.
1.751 + #define LT_ELFCLASS2 ELFCLASS64
1.752 + #define LT_ELF_MACHINE2 EM_PPC64
1.753 ++#define ARCH_SUPPORTS_OPD
1.754 ++#endif
1.755 +
1.756 + #define PLT_REINITALISATION_BP "_start"
1.757 +
1.758 +@@ -16,6 +19,3 @@
1.759 + #if (PPC_NOP_LENGTH != BREAKPOINT_LENGTH)
1.760 + #error "Length of the breakpoint value not equal to the length of a nop instruction"
1.761 + #endif
1.762 +-
1.763 +-
1.764 +-#endif
1.765 +diff -durN ltrace-0.5.orig/testsuite/ltrace.minor/Makefile.in ltrace-0.5/testsuite/ltrace.minor/Makefile.in
1.766 +--- ltrace-0.5.orig/testsuite/ltrace.minor/Makefile.in 2006-03-14 00:12:01.000000000 +0100
1.767 ++++ ltrace-0.5/testsuite/ltrace.minor/Makefile.in 2008-11-04 19:25:50.000000000 +0100
1.768 +@@ -19,7 +19,7 @@
1.769 +
1.770 + .SUFFIXES:
1.771 + clean:
1.772 +- -rm -f demangle trace-fork trace-clone
1.773 ++ -rm -f demangle trace-fork trace-clone trace-exec trace-exec1
1.774 + -rm -f time-record-tt time-record-ttt time-record-T
1.775 + -rm -f attach-process count-record
1.776 + -rm -f print-instruction-pointer
1.777 +diff -durN ltrace-0.5.orig/testsuite/ltrace.minor/trace-clone.c ltrace-0.5/testsuite/ltrace.minor/trace-clone.c
1.778 +--- ltrace-0.5.orig/testsuite/ltrace.minor/trace-clone.c 2006-03-16 01:38:47.000000000 +0100
1.779 ++++ ltrace-0.5/testsuite/ltrace.minor/trace-clone.c 2008-11-04 19:25:50.000000000 +0100
1.780 +@@ -21,11 +21,11 @@
1.781 + int main ()
1.782 + {
1.783 + pid_t pid;
1.784 +- static char stack[STACK_SIZE];
1.785 ++ char stack[STACK_SIZE];
1.786 + #ifdef __ia64__
1.787 + pid = __clone2((myfunc)&child, stack, STACK_SIZE, CLONE_FS, NULL);
1.788 + #else
1.789 +- pid = clone((myfunc)&child, stack,CLONE_FS, NULL );
1.790 ++ pid = clone((myfunc)&child, stack + STACK_SIZE,CLONE_FS, NULL );
1.791 + #endif
1.792 + if (pid < 0)
1.793 + {
1.794 +diff -durN ltrace-0.5.orig/wait_for_something.c ltrace-0.5/wait_for_something.c
1.795 +--- ltrace-0.5.orig/wait_for_something.c 2006-02-20 22:48:07.000000000 +0100
1.796 ++++ ltrace-0.5/wait_for_something.c 2008-11-04 19:25:50.000000000 +0100
1.797 +@@ -71,6 +71,18 @@
1.798 + event.thing = LT_EV_SYSRET;
1.799 + event.e_un.sysnum = tmp;
1.800 + return &event;
1.801 ++ case 3:
1.802 ++ event.thing = LT_EV_ARCH_SYSCALL;
1.803 ++ event.e_un.sysnum = tmp;
1.804 ++ return &event;
1.805 ++ case 4:
1.806 ++ event.thing = LT_EV_ARCH_SYSRET;
1.807 ++ event.e_un.sysnum = tmp;
1.808 ++ return &event;
1.809 ++ case -1:
1.810 ++ event.thing = LT_EV_NONE;
1.811 ++ continue_process(event.proc->pid);
1.812 ++ return &event;
1.813 + }
1.814 + if (WIFEXITED(status)) {
1.815 + event.thing = LT_EV_EXIT;