patches/ltrace/0.5/130-fixes-by-debian.patch
changeset 1036 06aecfa2c355
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/patches/ltrace/0.5/130-fixes-by-debian.patch	Tue Nov 04 18:52:59 2008 +0000
     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;