Update ltrace to ltrace-0.5 + fixes from Debian ltrace-0.5-3.1.
author"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Tue Nov 04 18:52:59 2008 +0000 (2008-11-04)
changeset 103606aecfa2c355
parent 1035 4e94b43c56ed
child 1037 f30de763bcce
Update ltrace to ltrace-0.5 + fixes from Debian ltrace-0.5-3.1.

/trunk/patches/ltrace/0.5/130-fixes-by-debian.patch | 812 812 0 0 +++++++++++++++++++++++
/trunk/patches/ltrace/0.5/110-allow-cross-compile.patch | 26 13 13 0
/trunk/config/debug/ltrace.in | 5 5 0 0 +
3 files changed, 830 insertions(+), 13 deletions(-)
config/debug/ltrace.in
patches/ltrace/0.5/100-fix-build-with-exotic-linux-host-OS.patch
patches/ltrace/0.5/110-allow-cross-compile.patch
patches/ltrace/0.5/120-alpha-support.patch
patches/ltrace/0.5/130-fixes-by-debian.patch
     1.1 --- a/config/debug/ltrace.in	Tue Nov 04 18:31:07 2008 +0000
     1.2 +++ b/config/debug/ltrace.in	Tue Nov 04 18:52:59 2008 +0000
     1.3 @@ -16,6 +16,10 @@
     1.4      bool
     1.5      prompt "0.4"
     1.6  
     1.7 +config LTRACE_V_0_5
     1.8 +    bool
     1.9 +    prompt "0.5"
    1.10 +
    1.11  # CT_INSERT_VERSION_ABOVE
    1.12  # Don't remove above line!
    1.13  endchoice
    1.14 @@ -23,5 +27,6 @@
    1.15  config LTRACE_VERSION
    1.16      string
    1.17      default "0.4" if LTRACE_V_0_4
    1.18 +    default "0.5" if LTRACE_V_0_5
    1.19  # CT_INSERT_VERSION_STRING_ABOVE
    1.20  # # Don't remove above line!
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/patches/ltrace/0.5/100-fix-build-with-exotic-linux-host-OS.patch	Tue Nov 04 18:52:59 2008 +0000
     2.3 @@ -0,0 +1,26 @@
     2.4 +diff -durN ltrace-0.4.orig/configure ltrace-0.4/configure
     2.5 +--- ltrace-0.4.orig/configure	2008-10-23 23:19:38.000000000 +0200
     2.6 ++++ ltrace-0.4/configure	2008-10-23 23:19:06.000000000 +0200
     2.7 +@@ -1392,6 +1392,9 @@
     2.8 + 
     2.9 + 
    2.10 + HOST_OS="$host_os"
    2.11 ++case "${HOST_OS}" in
    2.12 ++  linux-*) HOST_OS=linux-gnu;;
    2.13 ++esac
    2.14 + 
    2.15 + 
    2.16 + ac_ext=c
    2.17 +diff -durN ltrace-0.4.orig/configure.ac ltrace-0.4/configure.ac
    2.18 +--- ltrace-0.4.orig/configure.ac	2008-10-23 23:19:43.000000000 +0200
    2.19 ++++ ltrace-0.4/configure.ac	2008-10-23 23:18:44.000000000 +0200
    2.20 +@@ -7,6 +7,9 @@
    2.21 + dnl Check host system type
    2.22 + AC_CANONICAL_HOST
    2.23 + HOST_OS="$host_os"
    2.24 ++case "${HOST_OS}" in
    2.25 ++  linux-*) HOST_OS=linux-gnu;;
    2.26 ++esac
    2.27 + AC_SUBST(HOST_OS)
    2.28 + 
    2.29 + dnl Checks for programs.
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/patches/ltrace/0.5/110-allow-cross-compile.patch	Tue Nov 04 18:52:59 2008 +0000
     3.3 @@ -0,0 +1,89 @@
     3.4 +diff -durN ltrace-0.5.orig/Makefile.in ltrace-0.5/Makefile.in
     3.5 +--- ltrace-0.5.orig/Makefile.in	2006-03-14 00:12:01.000000000 +0100
     3.6 ++++ ltrace-0.5/Makefile.in	2008-11-04 19:23:05.000000000 +0100
     3.7 +@@ -2,8 +2,14 @@
     3.8 + # ltrace's Makefile.in
     3.9 + #
    3.10 + 
    3.11 +-#OS		:= $(shell uname -s)
    3.12 + OS		:= @HOST_OS@
    3.13 ++ARCH		:= $(shell echo "@HOST_ARCH@" |sed -e s/i.86/i386/      \
    3.14 ++						   -e s/sun4u/sparc64/  \
    3.15 ++						   -e s/arm.*/arm/      \
    3.16 ++						   -e s/sa110/arm/      \
    3.17 ++						   -e s/ppc64/ppc/      \
    3.18 ++						   -e s/s390x/s390/)
    3.19 ++export ARCH
    3.20 + 
    3.21 + TOPDIR		= $(shell pwd)
    3.22 + 
    3.23 +@@ -20,10 +26,10 @@
    3.24 + LIBS		=	@LIBS@
    3.25 + 
    3.26 + INSTALL		=	@INSTALL@
    3.27 +-INSTALL_FILE	=	$(INSTALL) -p    -o root -g root  -m  644
    3.28 +-INSTALL_PROGRAM	=	$(INSTALL) -p    -o root -g root  -m  755
    3.29 +-INSTALL_SCRIPT	=	$(INSTALL) -p    -o root -g root  -m  755
    3.30 +-INSTALL_DIR	=	$(INSTALL) -p -d -o root -g root  -m  755
    3.31 ++INSTALL_FILE	=	$(INSTALL) -p    -m  644
    3.32 ++INSTALL_PROGRAM	=	$(INSTALL) -p    -m  755
    3.33 ++INSTALL_SCRIPT	=	$(INSTALL) -p    -m  755
    3.34 ++INSTALL_DIR	=	$(INSTALL) -p -d -m  755
    3.35 + 
    3.36 + OBJ	=	ltrace.o options.o elf.o output.o read_config_file.o	\
    3.37 + 		execute_program.o wait_for_something.o process_event.o	\
    3.38 +diff -durN ltrace-0.5.orig/configure ltrace-0.5/configure
    3.39 +--- ltrace-0.5.orig/configure	2008-11-04 19:23:00.000000000 +0100
    3.40 ++++ ltrace-0.5/configure	2008-11-04 19:23:05.000000000 +0100
    3.41 +@@ -311,7 +311,7 @@
    3.42 + # include <unistd.h>
    3.43 + #endif"
    3.44 + 
    3.45 +-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os HOST_OS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CPP EGREP iquote iquoteend LIBOBJS LTLIBOBJS'
    3.46 ++ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os HOST_ARCH HOST_OS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CPP EGREP iquote iquoteend LIBOBJS LTLIBOBJS'
    3.47 + ac_subst_files=''
    3.48 + 
    3.49 + # Initialize some variables set by options.
    3.50 +@@ -1390,7 +1390,7 @@
    3.51 + host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
    3.52 + host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
    3.53 + 
    3.54 +-
    3.55 ++HOST_ARCH="$host_cpu"
    3.56 + HOST_OS="$host_os"
    3.57 + case "${HOST_OS}" in
    3.58 +   linux-*) HOST_OS=linux-gnu;;
    3.59 +@@ -4846,6 +4846,7 @@
    3.60 + s,@host_cpu@,$host_cpu,;t t
    3.61 + s,@host_vendor@,$host_vendor,;t t
    3.62 + s,@host_os@,$host_os,;t t
    3.63 ++s,@HOST_ARCH@,$HOST_ARCH,;t t
    3.64 + s,@HOST_OS@,$HOST_OS,;t t
    3.65 + s,@CC@,$CC,;t t
    3.66 + s,@CFLAGS@,$CFLAGS,;t t
    3.67 +diff -durN ltrace-0.5.orig/configure.ac ltrace-0.5/configure.ac
    3.68 +--- ltrace-0.5.orig/configure.ac	2008-11-04 19:23:00.000000000 +0100
    3.69 ++++ ltrace-0.5/configure.ac	2008-11-04 19:23:05.000000000 +0100
    3.70 +@@ -6,10 +6,12 @@
    3.71 + 
    3.72 + dnl Check host system type
    3.73 + AC_CANONICAL_HOST
    3.74 ++HOST_ARCH="$host_cpu"
    3.75 + HOST_OS="$host_os"
    3.76 + case "${HOST_OS}" in
    3.77 +   linux-*) HOST_OS=linux-gnu;;
    3.78 + esac
    3.79 ++AC_SUBST(HOST_ARCH)
    3.80 + AC_SUBST(HOST_OS)
    3.81 + 
    3.82 + dnl Checks for programs.
    3.83 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/Makefile ltrace-0.5/sysdeps/linux-gnu/Makefile
    3.84 +--- ltrace-0.5.orig/sysdeps/linux-gnu/Makefile	2006-02-20 22:44:45.000000000 +0100
    3.85 ++++ ltrace-0.5/sysdeps/linux-gnu/Makefile	2008-11-04 19:23:05.000000000 +0100
    3.86 +@@ -1,6 +1,3 @@
    3.87 +-ARCH		:=	$(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
    3.88 +-			-e s/arm.*/arm/ -e s/sa110/arm/ -e s/ppc64/ppc/ -e s/s390x/s390/)
    3.89 +-
    3.90 + CPPFLAGS	+=	-I$(TOPDIR)/sysdeps/linux-gnu/$(ARCH)
    3.91 + 
    3.92 + OBJ		=	trace.o proc.o breakpoint.o
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/patches/ltrace/0.5/120-alpha-support.patch	Tue Nov 04 18:52:59 2008 +0000
     4.3 @@ -0,0 +1,11 @@
     4.4 +diff -durN ltrace-0.4.orig/Makefile.in ltrace-0.4/Makefile.in
     4.5 +--- ltrace-0.4.orig/Makefile.in	2008-10-26 15:34:21.000000000 +0100
     4.6 ++++ ltrace-0.4/Makefile.in	2008-10-26 15:37:40.000000000 +0100
     4.7 +@@ -5,6 +5,7 @@
     4.8 + OS		:= @HOST_OS@
     4.9 + ARCH		:= $(shell echo "@HOST_ARCH@" |sed -e s/i.86/i386/      \
    4.10 + 						   -e s/sun4u/sparc64/  \
    4.11 ++						   -e s/alpha.*/alpha/  \
    4.12 + 						   -e s/arm.*/arm/      \
    4.13 + 						   -e s/sa110/arm/      \
    4.14 + 						   -e s/ppc64/ppc/      \
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/patches/ltrace/0.5/130-fixes-by-debian.patch	Tue Nov 04 18:52:59 2008 +0000
     5.3 @@ -0,0 +1,812 @@
     5.4 +This patch was vampirised from the 0.5-3.1 Debian-packaged version of ltrace,
     5.5 +and contains the following fixes (exerpt from the Debian changelog). Moreover,
     5.6 +you will also find an exerpt of the Debian copyright file with proper
     5.7 +attribution.
     5.8 +
     5.9 +================ Debian changelog exerpt ================
    5.10 +ltrace (0.5-3.1) unstable; urgency=low
    5.11 +
    5.12 +  * Non-maintainer upload.
    5.13 +  * Big thanks for Anderson Lizardo for providing patches!
    5.14 +  * Add generic support for arm targets, Closes: #176413
    5.15 +  * Save funtion arguments on arm, Closes: #462530
    5.16 +  * Add thumb instruction support, Closes: #462531
    5.17 +  * Add basic arm/eabi support, Closes: #450931
    5.18 +  * fix exec() testcase cleanup, Closes: #462532
    5.19 +  * fix memory corruption in clone() test, Closes: #462533
    5.20 +  * fix tracing child with "-p" option, Closes: #462535
    5.21 +  * Update standard, no changes
    5.22 +
    5.23 + -- Riku Voipio <riku.voipio@iki.fi>  Tue, 29 Jan 2008 00:26:50 +0200
    5.24 +
    5.25 +ltrace (0.5-3) unstable; urgency=low
    5.26 +
    5.27 +  * Really fix compilation problems in ppc (!)
    5.28 +
    5.29 + -- Juan Cespedes <cespedes@debian.org>  Fri, 31 Aug 2007 19:04:03 +0200
    5.30 +
    5.31 +ltrace (0.5-2) unstable; urgency=low
    5.32 +
    5.33 +  * Fixed compilation issue in ppc
    5.34 +
    5.35 + -- Juan Cespedes <cespedes@debian.org>  Fri, 31 Aug 2007 13:53:27 +0200
    5.36 +
    5.37 +ltrace (0.5-1) unstable; urgency=low
    5.38 +
    5.39 +  * New upstream version
    5.40 +  * Remove some unneeded files in /usr/share/doc (ChangeLog, COPYING...)
    5.41 +  * Fix several typos (closes: Bug#372928)
    5.42 +  * Added more system calls to ltrace.conf
    5.43 +
    5.44 + -- Juan Cespedes <cespedes@debian.org>  Thu, 30 Aug 2007 14:54:44 +0200
    5.45 +============== End Debian changelog exerpt ==============
    5.46 +
    5.47 +================ Debian copyright exerpt ================
    5.48 +Copyrights
    5.49 +----------
    5.50 +Copyright (C) 1997-2007 Juan Cespedes <cespedes@debian.org>
    5.51 +
    5.52 +ARMLinux port: Copyright (C) 1998 Pat Beirne <pbeirne@home.com>
    5.53 +m68k port: Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
    5.54 +Misc fixes: Copyright (C) 1999 Morten Eriksen <mortene@sim.no>
    5.55 +s390 port: Copyright (C) 2001 IBM Poughkeepsie, IBM Cororation <slate@us.ibm.com>
    5.56 +ELF hacking: Copyright (C) 1999 Silvio Cesare <silvio@big.net.au>
    5.57 +PowerPC port: Copyright (C) 2001-2002 Anton Blanchard <anton@samba.org>
    5.58 +SPARC port: Copyright (C) 1999 Jakub Jelinek <jakub@redhat.com>
    5.59 +
    5.60 +Autoconf stuff: Copyright 1992-1996 Free Software Foundation, Inc.
    5.61 +install-sh: Copyright 1991 by the Massachusetts Institute of Technology
    5.62 +C++ demangle: Copyright 1989-1997 Free Software Foundation, Inc.
    5.63 +============== End Debian copyright exerpt ==============
    5.64 +
    5.65 +diff -durN ltrace-0.5.orig/breakpoints.c ltrace-0.5/breakpoints.c
    5.66 +--- ltrace-0.5.orig/breakpoints.c	2006-06-14 06:55:21.000000000 +0200
    5.67 ++++ ltrace-0.5/breakpoints.c	2008-11-04 19:25:50.000000000 +0100
    5.68 +@@ -53,6 +53,10 @@
    5.69 + 		if (libsym)
    5.70 + 			libsym->brkpnt = sbp;
    5.71 + 	}
    5.72 ++#ifdef __arm__
    5.73 ++	sbp->thumb_mode = proc->thumb_mode;
    5.74 ++	proc->thumb_mode = 0;
    5.75 ++#endif
    5.76 + 	sbp->enabled++;
    5.77 + 	if (sbp->enabled == 1 && proc->pid)
    5.78 + 		enable_breakpoint(proc->pid, sbp);
    5.79 +diff -durN ltrace-0.5.orig/elf.c ltrace-0.5/elf.c
    5.80 +--- ltrace-0.5.orig/elf.c	2006-06-14 06:55:21.000000000 +0200
    5.81 ++++ ltrace-0.5/elf.c	2008-11-04 19:25:50.000000000 +0100
    5.82 +@@ -464,8 +464,7 @@
    5.83 + 			if (strcmp(xptr->name, PLTs_initialized_by_here) == 0) {
    5.84 + 				if (lte->ehdr.e_entry) {
    5.85 + 					add_library_symbol (
    5.86 +-						elf_plt2addr (lte, (void*)(long)
    5.87 +-							lte->ehdr.e_entry),
    5.88 ++						opd2addr (lte, lte->ehdr.e_entry),
    5.89 + 						PLTs_initialized_by_here,
    5.90 + 						lib_tail, 1, 0);
    5.91 + 					fprintf (stderr, "WARNING: Using e_ent"
    5.92 +diff -durN ltrace-0.5.orig/etc/ltrace.conf ltrace-0.5/etc/ltrace.conf
    5.93 +--- ltrace-0.5.orig/etc/ltrace.conf	2006-02-20 22:55:47.000000000 +0100
    5.94 ++++ ltrace-0.5/etc/ltrace.conf	2008-11-04 19:25:50.000000000 +0100
    5.95 +@@ -444,3 +444,81 @@
    5.96 + int   SYS_removexattr(string,string);
    5.97 + int   SYS_lremovexattr(string,string);
    5.98 + int   SYS_fremovexattr(int,string);
    5.99 ++int   SYS_chdir(string);
   5.100 ++int   SYS_fchdir(int);
   5.101 ++int   SYS_chmod(string,octal);
   5.102 ++int   SYS_fchmod(int,octal);
   5.103 ++int   SYS_chown(string,int,int);
   5.104 ++int   SYS_fchown(int,int,int);
   5.105 ++int   SYS_lchown(string,int,int);
   5.106 ++int   SYS_chroot(string);
   5.107 ++int   SYS_dup(int);
   5.108 ++int   SYS_dup2(int,int);
   5.109 ++int   SYS_fdatasync(int);
   5.110 ++int   SYS_fsync(int);
   5.111 ++int   SYS_getpriority(int,int);
   5.112 ++int   SYS_setpriority(int,int,int);
   5.113 ++int   SYS_getrlimit(int,addr);
   5.114 ++int   SYS_setrlimit(int,addr);
   5.115 ++int   SYS_gettimeofday(addr,addr);
   5.116 ++int   SYS_settimeofday(addr,addr);
   5.117 ++int   SYS_setfsgid(int);
   5.118 ++int   SYS_setfsuid(int);
   5.119 ++int   SYS_getuid(void);
   5.120 ++int   SYS_setuid(int);
   5.121 ++int   SYS_getgid(void);
   5.122 ++int   SYS_setgid(int);
   5.123 ++int   SYS_getsid(int);
   5.124 ++int   SYS_setsid(int);
   5.125 ++int   SYS_setreuid(int,int);
   5.126 ++int   SYS_setregid(int,int);
   5.127 ++int   SYS_geteuid(void);
   5.128 ++int   SYS_getegid(void);
   5.129 ++int   SYS_setpgid(int,int);
   5.130 ++int   SYS_getresuid(addr,addr,addr);
   5.131 ++int   SYS_setresuid(int,int,int);
   5.132 ++int   SYS_getresgid(addr,addr,addr);
   5.133 ++int   SYS_setresgid(int,int,int);
   5.134 ++int   SYS_kill(int,int);
   5.135 ++int   SYS_link(string,string);
   5.136 ++int   SYS_madvise(addr,ulong,int);
   5.137 ++int   SYS_mkdir(string,octal);
   5.138 ++int   SYS_mknod(string,octal,int);
   5.139 ++int   SYS_msync(addr,ulong,int);
   5.140 ++int   SYS_nice(int);
   5.141 ++int   SYS_poll(addr,uint,int);
   5.142 ++int   SYS_readdir(uint,addr,uint);
   5.143 ++int   SYS_readlink(string,string,ulong);
   5.144 ++int   SYS_reboot(int,int,int,addr);
   5.145 ++int   SYS_rename(string,string);
   5.146 ++int   SYS_rmdir(string);
   5.147 ++int   SYS_sigaltstack(addr,addr);
   5.148 ++int   SYS_statfs(string,addr);
   5.149 ++int   SYS_fstatfs(int,addr);
   5.150 ++int   SYS_fstat(int,addr);
   5.151 ++int   SYS_lstat(string,addr);
   5.152 ++int   SYS_stime(addr);
   5.153 ++int   SYS_symlink(string, string);
   5.154 ++int   SYS_sysinfo(addr);
   5.155 ++int   SYS_syslog(int,string,int);
   5.156 ++int   SYS_truncate(string,long);
   5.157 ++int   SYS_ftruncate(int,long);
   5.158 ++int   SYS_mount(string,string,string,ulong,addr);
   5.159 ++int   SYS_umount(string);
   5.160 ++int   SYS_umount2(string,int);
   5.161 ++int   SYS_unlink(string);
   5.162 ++int   SYS_utime(string,addr);
   5.163 ++long  SYS_lseek(int,long,int);
   5.164 ++addr  SYS_signal(int,addr);
   5.165 ++int   SYS_sigaction(int,addr,addr);
   5.166 ++int   SYS_pause(void);
   5.167 ++int   SYS_sigpending(addr);
   5.168 ++int   SYS_sigprocmask(int,addr,addr);
   5.169 ++int   SYS_sigqueue(int,int,addr);
   5.170 ++int   SYS_sigsuspend(addr);
   5.171 ++int   SYS_wait(addr);
   5.172 ++int   SYS_waitpid(int,addr,int);
   5.173 ++ulong SYS_readv(int,addr,int);
   5.174 ++ulong SYS_writev(int,addr,int);
   5.175 ++int   SYS_mprotect(addr,int,int);
   5.176 ++int   SYS_access(string,octal);
   5.177 +diff -durN ltrace-0.5.orig/ltrace.1 ltrace-0.5/ltrace.1
   5.178 +--- ltrace-0.5.orig/ltrace.1	2006-06-16 03:15:18.000000000 +0200
   5.179 ++++ ltrace-0.5/ltrace.1	2008-11-04 19:25:50.000000000 +0100
   5.180 +@@ -30,7 +30,7 @@
   5.181 + .TP
   5.182 + .I \-C, \-\-demangle
   5.183 + Decode (demangle) low-level symbol names into user-level names.
   5.184 +-Besides removing any initial underscore prepended by the system,
   5.185 ++Besides removing any initial underscore prefix used by the system,
   5.186 + this makes C++ function names readable.
   5.187 + .TP
   5.188 + .I \-d, \-\-debug
   5.189 +diff -durN ltrace-0.5.orig/ltrace.c ltrace-0.5/ltrace.c
   5.190 +--- ltrace-0.5.orig/ltrace.c	2006-02-20 22:48:07.000000000 +0100
   5.191 ++++ ltrace-0.5/ltrace.c	2008-11-04 19:25:50.000000000 +0100
   5.192 +@@ -54,6 +54,9 @@
   5.193 + {
   5.194 + 	exiting = 1;
   5.195 + 	debug(1, "Received interrupt signal; exiting...");
   5.196 ++	if (opt_o) {
   5.197 ++		fclose(output);
   5.198 ++	}
   5.199 + 	signal(SIGINT, SIG_IGN);
   5.200 + 	signal(SIGTERM, SIG_IGN);
   5.201 + 	signal(SIGALRM, signal_alarm);
   5.202 +@@ -74,6 +77,9 @@
   5.203 + 	if (opt_c) {
   5.204 + 		show_summary();
   5.205 + 	}
   5.206 ++	if (opt_o) {
   5.207 ++		fclose(output);
   5.208 ++	}
   5.209 + }
   5.210 + 
   5.211 + static void guess_cols(void)
   5.212 +diff -durN ltrace-0.5.orig/ltrace.h ltrace-0.5/ltrace.h
   5.213 +--- ltrace-0.5.orig/ltrace.h	2006-06-14 06:55:21.000000000 +0200
   5.214 ++++ ltrace-0.5/ltrace.h	2008-11-04 19:25:50.000000000 +0100
   5.215 +@@ -26,6 +26,9 @@
   5.216 + 	unsigned char orig_value[BREAKPOINT_LENGTH];
   5.217 + 	int enabled;
   5.218 + 	struct library_symbol *libsym;
   5.219 ++#ifdef __arm__
   5.220 ++	int thumb_mode;
   5.221 ++#endif
   5.222 + };
   5.223 + 
   5.224 + enum arg_type {
   5.225 +@@ -119,6 +122,9 @@
   5.226 + 	void *arch_ptr;
   5.227 + 	short e_machine;
   5.228 + 	short need_to_reinitialize_breakpoints;
   5.229 ++#ifdef __arm__
   5.230 ++	int thumb_mode; /* ARM execution mode: 0: ARM mode, 1: Thumb mode */
   5.231 ++#endif
   5.232 + 
   5.233 + 	/* output: */
   5.234 + 	enum tof type_being_displayed;
   5.235 +@@ -136,12 +142,14 @@
   5.236 + 		LT_EV_EXIT_SIGNAL,
   5.237 + 		LT_EV_SYSCALL,
   5.238 + 		LT_EV_SYSRET,
   5.239 ++		LT_EV_ARCH_SYSCALL,
   5.240 ++		LT_EV_ARCH_SYSRET,
   5.241 + 		LT_EV_BREAKPOINT
   5.242 + 	} thing;
   5.243 + 	union {
   5.244 + 		int ret_val;	/* _EV_EXIT */
   5.245 + 		int signum;	/* _EV_SIGNAL, _EV_EXIT_SIGNAL */
   5.246 +-		int sysnum;	/* _EV_SYSCALL, _EV_SYSRET */
   5.247 ++		int sysnum;	/* _EV_SYSCALL, _EV_SYSRET, _EV_ARCH_SYSCALL, _EV_ARCH_SYSRET */
   5.248 + 		void *brk_addr;	/* _EV_BREAKPOINT */
   5.249 + 	} e_un;
   5.250 + };
   5.251 +diff -durN ltrace-0.5.orig/options.c ltrace-0.5/options.c
   5.252 +--- ltrace-0.5.orig/options.c	2006-04-24 22:06:23.000000000 +0200
   5.253 ++++ ltrace-0.5/options.c	2008-11-04 19:25:50.000000000 +0100
   5.254 +@@ -42,6 +42,7 @@
   5.255 + #endif
   5.256 + int opt_n = 0;			/* indent trace output according to program flow */
   5.257 + int opt_T = 0;			/* show the time spent inside each call */
   5.258 ++int opt_o = 0;			/* output to a specific file */
   5.259 + 
   5.260 + /* List of pids given to option -p: */
   5.261 + struct opt_p_t *opt_p = NULL;	/* attach to process with a given pid */
   5.262 +@@ -274,6 +275,7 @@
   5.263 + 			opt_n = atoi(optarg);
   5.264 + 			break;
   5.265 + 		case 'o':
   5.266 ++			opt_o++;
   5.267 + 			output = fopen(optarg, "w");
   5.268 + 			if (!output) {
   5.269 + 				fprintf(stderr,
   5.270 +diff -durN ltrace-0.5.orig/options.h ltrace-0.5/options.h
   5.271 +--- ltrace-0.5.orig/options.h	2006-03-13 18:43:13.000000000 +0100
   5.272 ++++ ltrace-0.5/options.h	2008-11-04 19:25:50.000000000 +0100
   5.273 +@@ -20,6 +20,7 @@
   5.274 + extern int opt_C;		/* Demanglelow-level symbol names into user-level names */
   5.275 + extern int opt_n;		/* indent trace output according to program flow */
   5.276 + extern int opt_T;		/* show the time spent inside each call */
   5.277 ++extern int opt_o;		/* output to a specific file */
   5.278 + 
   5.279 + struct opt_p_t {
   5.280 + 	pid_t pid;
   5.281 +diff -durN ltrace-0.5.orig/process_event.c ltrace-0.5/process_event.c
   5.282 +--- ltrace-0.5.orig/process_event.c	2006-06-14 06:55:21.000000000 +0200
   5.283 ++++ ltrace-0.5/process_event.c	2008-11-04 19:25:50.000000000 +0100
   5.284 +@@ -24,7 +24,9 @@
   5.285 + static void process_exit(struct event *event);
   5.286 + static void process_exit_signal(struct event *event);
   5.287 + static void process_syscall(struct event *event);
   5.288 ++static void process_arch_syscall(struct event *event);
   5.289 + static void process_sysret(struct event *event);
   5.290 ++static void process_arch_sysret(struct event *event);
   5.291 + static void process_breakpoint(struct event *event);
   5.292 + static void remove_proc(struct process *proc);
   5.293 + 
   5.294 +@@ -81,6 +83,24 @@
   5.295 + 	}
   5.296 + }
   5.297 + 
   5.298 ++static char *arch_sysname(struct process *proc, int sysnum)
   5.299 ++{
   5.300 ++	static char result[128];
   5.301 ++	static char *arch_syscalent[] = {
   5.302 ++#include "arch_syscallent.h"
   5.303 ++	};
   5.304 ++	int nsyscals = sizeof arch_syscalent / sizeof arch_syscalent[0];
   5.305 ++
   5.306 ++	if (sysnum < 0 || sysnum >= nsyscals) {
   5.307 ++		sprintf(result, "ARCH_%d", sysnum);
   5.308 ++		return result;
   5.309 ++	} else {
   5.310 ++		sprintf(result, "ARCH_%s",
   5.311 ++			arch_syscalent[sysnum]);
   5.312 ++		return result;
   5.313 ++	}
   5.314 ++}
   5.315 ++
   5.316 + void process_event(struct event *event)
   5.317 + {
   5.318 + 	switch (event->thing) {
   5.319 +@@ -115,6 +135,18 @@
   5.320 + 		      event->e_un.sysnum);
   5.321 + 		process_sysret(event);
   5.322 + 		return;
   5.323 ++	case LT_EV_ARCH_SYSCALL:
   5.324 ++		debug(1, "event: arch_syscall (%s [%d])",
   5.325 ++		      arch_sysname(event->proc, event->e_un.sysnum),
   5.326 ++		      event->e_un.sysnum);
   5.327 ++		process_arch_syscall(event);
   5.328 ++		return;
   5.329 ++	case LT_EV_ARCH_SYSRET:
   5.330 ++		debug(1, "event: arch_sysret (%s [%d])",
   5.331 ++		      arch_sysname(event->proc, event->e_un.sysnum),
   5.332 ++		      event->e_un.sysnum);
   5.333 ++		process_arch_sysret(event);
   5.334 ++		return;
   5.335 + 	case LT_EV_BREAKPOINT:
   5.336 + 		debug(1, "event: breakpoint");
   5.337 + 		process_breakpoint(event);
   5.338 +@@ -195,6 +227,19 @@
   5.339 + 	continue_process(event->proc->pid);
   5.340 + }
   5.341 + 
   5.342 ++static void process_arch_syscall(struct event *event)
   5.343 ++{
   5.344 ++	if (opt_S) {
   5.345 ++		output_left(LT_TOF_SYSCALL, event->proc,
   5.346 ++			    arch_sysname(event->proc, event->e_un.sysnum));
   5.347 ++	}
   5.348 ++	if (event->proc->breakpoints_enabled == 0) {
   5.349 ++		enable_all_breakpoints(event->proc);
   5.350 ++	}
   5.351 ++	callstack_push_syscall(event->proc, 0xf0000 + event->e_un.sysnum);
   5.352 ++	continue_process(event->proc->pid);
   5.353 ++}
   5.354 ++
   5.355 + struct timeval current_time_spent;
   5.356 + 
   5.357 + static void calc_time_spent(struct process *proc)
   5.358 +@@ -257,6 +302,19 @@
   5.359 + 	continue_process(event->proc->pid);
   5.360 + }
   5.361 + 
   5.362 ++static void process_arch_sysret(struct event *event)
   5.363 ++{
   5.364 ++	if (opt_T || opt_c) {
   5.365 ++		calc_time_spent(event->proc);
   5.366 ++	}
   5.367 ++	callstack_pop(event->proc);
   5.368 ++	if (opt_S) {
   5.369 ++		output_right(LT_TOF_SYSCALLR, event->proc,
   5.370 ++			     arch_sysname(event->proc, event->e_un.sysnum));
   5.371 ++	}
   5.372 ++	continue_process(event->proc->pid);
   5.373 ++}
   5.374 ++
   5.375 + static void process_breakpoint(struct event *event)
   5.376 + {
   5.377 + 	int i, j;
   5.378 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/Makefile ltrace-0.5/sysdeps/linux-gnu/Makefile
   5.379 +--- ltrace-0.5.orig/sysdeps/linux-gnu/Makefile	2008-11-04 19:25:11.000000000 +0100
   5.380 ++++ ltrace-0.5/sysdeps/linux-gnu/Makefile	2008-11-04 19:25:50.000000000 +0100
   5.381 +@@ -2,7 +2,7 @@
   5.382 + 
   5.383 + OBJ		=	trace.o proc.o breakpoint.o
   5.384 + 
   5.385 +-all:		sysdep.h signalent.h syscallent.h signalent1.h syscallent1.h ../sysdep.o
   5.386 ++all:		sysdep.h signalent.h syscallent.h arch_syscallent.h signalent1.h syscallent1.h ../sysdep.o
   5.387 + 
   5.388 + sysdep.h:	$(ARCH)/arch.h
   5.389 + 		cat $(ARCH)/arch.h > sysdep.h
   5.390 +@@ -26,6 +26,13 @@
   5.391 + 			> syscallent1.h; \
   5.392 + 		fi
   5.393 + 
   5.394 ++arch_syscallent.h:
   5.395 ++		if [ -f $(ARCH)/arch_syscallent.h ]; then \
   5.396 ++			cp $(ARCH)/arch_syscallent.h arch_syscallent.h; \
   5.397 ++		else \
   5.398 ++			> arch_syscallent.h; \
   5.399 ++		fi
   5.400 ++
   5.401 + ../sysdep.o:	os.o $(ARCH)/arch.o
   5.402 + 		$(CC) -nostdlib -r -o ../sysdep.o os.o $(ARCH)/arch.o
   5.403 + 
   5.404 +@@ -37,7 +44,7 @@
   5.405 + 
   5.406 + clean:
   5.407 + 		$(MAKE) -C $(ARCH) clean
   5.408 +-		rm -f $(OBJ) sysdep.h signalent.h signalent1.h syscallent.h
   5.409 ++		rm -f $(OBJ) sysdep.h signalent.h signalent1.h syscallent.h arch_syscallent.h
   5.410 + 		rm -f syscallent1.h os.o sysdep.o ../sysdep.o
   5.411 + 
   5.412 + dummy:
   5.413 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arch_mksyscallent ltrace-0.5/sysdeps/linux-gnu/arch_mksyscallent
   5.414 +--- ltrace-0.5.orig/sysdeps/linux-gnu/arch_mksyscallent	1970-01-01 01:00:00.000000000 +0100
   5.415 ++++ ltrace-0.5/sysdeps/linux-gnu/arch_mksyscallent	2008-11-04 19:25:50.000000000 +0100
   5.416 +@@ -0,0 +1,43 @@
   5.417 ++#!/usr/bin/awk -f
   5.418 ++
   5.419 ++# hack expression to generate arch_syscallent.h from <asm/unistd.h>
   5.420 ++# It reads from stdin and writes to stdout
   5.421 ++# Currently (linux-2.6.16), it works OK on arm
   5.422 ++# It is untested in other architectures
   5.423 ++
   5.424 ++BEGIN {
   5.425 ++	max=0;
   5.426 ++	FS="[ \t\n()+]+";
   5.427 ++}
   5.428 ++
   5.429 ++{
   5.430 ++#	printf("/%s/%s/%s/%s/\n", $1, $2, $3, $4);
   5.431 ++	if (($1 ~ /^#define$/) && ($2 ~ /^__[A-Z]+_NR_/)) {
   5.432 ++		sub(/^__[A-Z]+_NR_/,"",$2);
   5.433 ++		if (($3>=0) && ($3<=1000)) {
   5.434 ++			SYSCALL[$3]=$2;
   5.435 ++			if ($3 > max) {
   5.436 ++				max=$3;
   5.437 ++			}
   5.438 ++		} else if (($3 ~ /^__[A-Z]+_NR_BASE$/) && ($4>=0) && ($4<=1000)) {
   5.439 ++			SYSCALL[$4]=$2;
   5.440 ++			if ($4 > max) {
   5.441 ++				max=$4;
   5.442 ++			}
   5.443 ++		}
   5.444 ++	}
   5.445 ++}
   5.446 ++
   5.447 ++END {
   5.448 ++	for(i=0; i<=max; i++) {
   5.449 ++		if (!SYSCALL[i]) {
   5.450 ++			SYSCALL[i] = i;
   5.451 ++		}
   5.452 ++		pad = 32 - length(SYSCALL[i]);
   5.453 ++		if (pad<1) {
   5.454 ++			pad=1;
   5.455 ++		}
   5.456 ++		printf("\t\"%s\",%*s/* %d */\n", SYSCALL[i], pad, "", i);
   5.457 ++	}
   5.458 ++}
   5.459 ++
   5.460 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/Makefile ltrace-0.5/sysdeps/linux-gnu/arm/Makefile
   5.461 +--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/Makefile	2006-02-20 22:44:45.000000000 +0100
   5.462 ++++ ltrace-0.5/sysdeps/linux-gnu/arm/Makefile	2008-11-04 19:25:50.000000000 +0100
   5.463 +@@ -1,4 +1,4 @@
   5.464 +-OBJ	=	trace.o regs.o plt.o
   5.465 ++OBJ	=	trace.o regs.o plt.o breakpoint.o
   5.466 + 
   5.467 + all:		arch.o
   5.468 + 
   5.469 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/arch.h ltrace-0.5/sysdeps/linux-gnu/arm/arch.h
   5.470 +--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/arch.h	2006-04-24 22:06:23.000000000 +0200
   5.471 ++++ ltrace-0.5/sysdeps/linux-gnu/arm/arch.h	2008-11-04 19:25:50.000000000 +0100
   5.472 +@@ -1,5 +1,10 @@
   5.473 +-#define BREAKPOINT_VALUE { 0x01, 0x00, 0x9f, 0xef }
   5.474 ++#define ARCH_HAVE_ENABLE_BREAKPOINT 1
   5.475 ++#define ARCH_HAVE_DISABLE_BREAKPOINT 1
   5.476 ++
   5.477 ++#define BREAKPOINT_VALUE { 0xf0, 0x01, 0xf0, 0xe7 }
   5.478 + #define BREAKPOINT_LENGTH 4
   5.479 ++#define THUMB_BREAKPOINT_VALUE { 0x01, 0xde }
   5.480 ++#define THUMB_BREAKPOINT_LENGTH 2
   5.481 + #define DECR_PC_AFTER_BREAK 0
   5.482 + 
   5.483 + #define LT_ELFCLASS	ELFCLASS32
   5.484 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/arch_syscallent.h ltrace-0.5/sysdeps/linux-gnu/arm/arch_syscallent.h
   5.485 +--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/arch_syscallent.h	1970-01-01 01:00:00.000000000 +0100
   5.486 ++++ ltrace-0.5/sysdeps/linux-gnu/arm/arch_syscallent.h	2008-11-04 19:25:50.000000000 +0100
   5.487 +@@ -0,0 +1,6 @@
   5.488 ++	"0",                               /* 0 */
   5.489 ++	"breakpoint",                      /* 1 */
   5.490 ++	"cacheflush",                      /* 2 */
   5.491 ++	"usr26",                           /* 3 */
   5.492 ++	"usr32",                           /* 4 */
   5.493 ++	"set_tls",                         /* 5 */
   5.494 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/breakpoint.c ltrace-0.5/sysdeps/linux-gnu/arm/breakpoint.c
   5.495 +--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/breakpoint.c	1970-01-01 01:00:00.000000000 +0100
   5.496 ++++ ltrace-0.5/sysdeps/linux-gnu/arm/breakpoint.c	2008-11-04 19:25:50.000000000 +0100
   5.497 +@@ -0,0 +1,86 @@
   5.498 ++/*
   5.499 ++ * This file is part of ltrace.
   5.500 ++ *
   5.501 ++ * Copyright (C) 2007 by Instituto Nokia de Tecnologia (INdT)
   5.502 ++ *
   5.503 ++ * Author: Anderson Lizardo <anderson.lizardo@indt.org.br>
   5.504 ++ *
   5.505 ++ * This program is free software; you can redistribute it and/or
   5.506 ++ * modify it under the terms of the GNU General Public License
   5.507 ++ * version 2 as published by the Free Software Foundation.
   5.508 ++ *
   5.509 ++ * This program is distributed in the hope that it will be useful, but
   5.510 ++ * WITHOUT ANY WARRANTY; without even the implied warranty of
   5.511 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   5.512 ++ * General Public License for more details.
   5.513 ++ *
   5.514 ++ * You should have received a copy of the GNU General Public License
   5.515 ++ * along with this program; if not, write to the Free Software
   5.516 ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   5.517 ++ * 02110-1301 USA
   5.518 ++ *
   5.519 ++ * Modified from sysdeps/linux-gnu/breakpoint.c and added ARM Thumb support.
   5.520 ++*/
   5.521 ++
   5.522 ++#include <sys/ptrace.h>
   5.523 ++#include "config.h"
   5.524 ++#include "arch.h"
   5.525 ++#include "options.h"
   5.526 ++#include "output.h"
   5.527 ++#include "debug.h"
   5.528 ++
   5.529 ++void arch_enable_breakpoint(pid_t pid, struct breakpoint *sbp)
   5.530 ++{
   5.531 ++	unsigned int i, j;
   5.532 ++	const unsigned char break_insn[] = BREAKPOINT_VALUE;
   5.533 ++	const unsigned char thumb_break_insn[] = THUMB_BREAKPOINT_VALUE;
   5.534 ++
   5.535 ++	debug(1, "arch_enable_breakpoint(%d,%p)", pid, sbp->addr);
   5.536 ++
   5.537 ++	for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
   5.538 ++		long a =
   5.539 ++		    ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
   5.540 ++			   0);
   5.541 ++		unsigned char *bytes = (unsigned char *)&a;
   5.542 ++
   5.543 ++		debug(2, "current = 0x%lx, orig_value = 0x%lx, thumb_mode = %d", a, *(long *)&sbp->orig_value, sbp->thumb_mode);
   5.544 ++		for (j = 0;
   5.545 ++		     j < sizeof(long)
   5.546 ++		     && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
   5.547 ++
   5.548 ++			sbp->orig_value[i * sizeof(long) + j] = bytes[j];
   5.549 ++			if (!sbp->thumb_mode) {
   5.550 ++				bytes[j] = break_insn[i * sizeof(long) + j];
   5.551 ++			}
   5.552 ++			else if (j < THUMB_BREAKPOINT_LENGTH) {
   5.553 ++				bytes[j] = thumb_break_insn[i * sizeof(long) + j];
   5.554 ++			}
   5.555 ++		}
   5.556 ++		ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
   5.557 ++	}
   5.558 ++}
   5.559 ++
   5.560 ++void arch_disable_breakpoint(pid_t pid, const struct breakpoint *sbp)
   5.561 ++{
   5.562 ++	unsigned int i, j;
   5.563 ++	const unsigned char break_insn[] = BREAKPOINT_VALUE;
   5.564 ++	const unsigned char thumb_break_insn[] = THUMB_BREAKPOINT_VALUE;
   5.565 ++
   5.566 ++	debug(1, "arch_disable_breakpoint(%d,%p)", pid, sbp->addr);
   5.567 ++
   5.568 ++	for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
   5.569 ++		long a =
   5.570 ++		    ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
   5.571 ++			   0);
   5.572 ++		unsigned char *bytes = (unsigned char *)&a;
   5.573 ++
   5.574 ++		debug(2, "current = 0x%lx, orig_value = 0x%lx, thumb_mode = %d", a, *(long *)&sbp->orig_value, sbp->thumb_mode);
   5.575 ++		for (j = 0;
   5.576 ++		     j < sizeof(long)
   5.577 ++		     && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
   5.578 ++
   5.579 ++			bytes[j] = sbp->orig_value[i * sizeof(long) + j];
   5.580 ++		}
   5.581 ++		ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
   5.582 ++	}
   5.583 ++}
   5.584 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/ptrace.h ltrace-0.5/sysdeps/linux-gnu/arm/ptrace.h
   5.585 +--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/ptrace.h	2006-02-20 22:44:45.000000000 +0100
   5.586 ++++ ltrace-0.5/sysdeps/linux-gnu/arm/ptrace.h	2008-11-04 19:25:50.000000000 +0100
   5.587 +@@ -1 +1,9 @@
   5.588 + #include <sys/ptrace.h>
   5.589 ++#include <asm/ptrace.h>
   5.590 ++
   5.591 ++typedef struct {
   5.592 ++	int valid;
   5.593 ++	struct pt_regs regs;
   5.594 ++	long func_arg[5];
   5.595 ++	long sysc_arg[5];
   5.596 ++} proc_archdep;
   5.597 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/regs.c ltrace-0.5/sysdeps/linux-gnu/arm/regs.c
   5.598 +--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/regs.c	2006-02-20 22:48:07.000000000 +0100
   5.599 ++++ ltrace-0.5/sysdeps/linux-gnu/arm/regs.c	2008-11-04 19:25:50.000000000 +0100
   5.600 +@@ -39,5 +39,10 @@
   5.601 +  * a CISC architecture; in our case, we don't need that */
   5.602 + void *get_return_addr(struct process *proc, void *stack_pointer)
   5.603 + {
   5.604 +-	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_lr, 0);
   5.605 ++	long addr = ptrace(PTRACE_PEEKUSER, proc->pid, off_lr, 0);
   5.606 ++
   5.607 ++	proc->thumb_mode = addr & 1;
   5.608 ++	if (proc->thumb_mode)
   5.609 ++		addr &= ~1;
   5.610 ++	return (void *)addr;
   5.611 + }
   5.612 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/trace.c ltrace-0.5/sysdeps/linux-gnu/arm/trace.c
   5.613 +--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/trace.c	2006-02-20 22:48:07.000000000 +0100
   5.614 ++++ ltrace-0.5/sysdeps/linux-gnu/arm/trace.c	2008-11-04 19:25:50.000000000 +0100
   5.615 +@@ -2,6 +2,7 @@
   5.616 + #include "config.h"
   5.617 + #endif
   5.618 + 
   5.619 ++#include <string.h>
   5.620 + #include <sys/types.h>
   5.621 + #include <sys/wait.h>
   5.622 + #include <signal.h>
   5.623 +@@ -9,6 +10,8 @@
   5.624 + #include <asm/ptrace.h>
   5.625 + 
   5.626 + #include "ltrace.h"
   5.627 ++#include "output.h"
   5.628 ++#include "ptrace.h"
   5.629 + 
   5.630 + #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
   5.631 + # define PTRACE_PEEKUSER PTRACE_PEEKUSR
   5.632 +@@ -18,19 +21,25 @@
   5.633 + # define PTRACE_POKEUSER PTRACE_POKEUSR
   5.634 + #endif
   5.635 + 
   5.636 +-/* syscall tracing protocol: ArmLinux
   5.637 +- on the way in, ip is 0
   5.638 +- on the way out, ip is non-zero
   5.639 +-*/
   5.640 + #define off_r0 0
   5.641 ++#define off_r7 28
   5.642 + #define off_ip 48
   5.643 + #define off_pc 60
   5.644 + 
   5.645 + void get_arch_dep(struct process *proc)
   5.646 + {
   5.647 ++	proc_archdep *a;
   5.648 ++
   5.649 ++	if (!proc->arch_ptr)
   5.650 ++		proc->arch_ptr = (void *)malloc(sizeof(proc_archdep));
   5.651 ++	a = (proc_archdep *) (proc->arch_ptr);
   5.652 ++	a->valid = (ptrace(PTRACE_GETREGS, proc->pid, 0, &a->regs) >= 0);
   5.653 + }
   5.654 + 
   5.655 +-/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
   5.656 ++/* Returns 0 if not a syscall,
   5.657 ++ *         1 if syscall entry, 2 if syscall exit,
   5.658 ++ *         3 if arch-specific syscall entry, 4 if arch-specific syscall exit,
   5.659 ++ *         -1 on error.
   5.660 +  */
   5.661 + int syscall_p(struct process *proc, int status, int *sysnum)
   5.662 + {
   5.663 +@@ -40,19 +49,39 @@
   5.664 + 		int pc = ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0);
   5.665 + 		/* fetch the SWI instruction */
   5.666 + 		int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 4, 0);
   5.667 ++		int ip = ptrace(PTRACE_PEEKUSER, proc->pid, off_ip, 0);
   5.668 + 
   5.669 +-		*sysnum = insn & 0xFFFF;
   5.670 +-		/* if it is a syscall, return 1 or 2 */
   5.671 +-		if ((insn & 0xFFFF0000) == 0xef900000) {
   5.672 +-			return ptrace(PTRACE_PEEKUSER, proc->pid, off_ip,
   5.673 +-				      0) ? 2 : 1;
   5.674 ++		if (insn == 0xef000000 || insn == 0x0f000000) {
   5.675 ++			/* EABI syscall */
   5.676 ++			*sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, off_r7, 0);
   5.677 ++		} else if ((insn & 0xfff00000) == 0xef900000) {
   5.678 ++			/* old ABI syscall */
   5.679 ++			*sysnum = insn & 0xfffff;
   5.680 ++		} else {
   5.681 ++			/* TODO: handle swi<cond> variations */
   5.682 ++			/* one possible reason for getting in here is that we
   5.683 ++			 * are coming from a signal handler, so the current
   5.684 ++			 * PC does not point to the instruction just after the
   5.685 ++			 * "swi" one. */
   5.686 ++			output_line(proc, "unexpected instruction 0x%x at %p", insn, pc - 4);
   5.687 ++			return -1;
   5.688 ++		}
   5.689 ++		if ((*sysnum & 0xf0000) == 0xf0000) {
   5.690 ++			/* arch-specific syscall */
   5.691 ++			*sysnum &= ~0xf0000;
   5.692 ++			return ip ? 4 : 3;
   5.693 + 		}
   5.694 ++		/* ARM syscall convention: on syscall entry, ip is zero;
   5.695 ++		 * on syscall exit, ip is non-zero */
   5.696 ++		return ip ? 2 : 1;
   5.697 + 	}
   5.698 + 	return 0;
   5.699 + }
   5.700 + 
   5.701 + long gimme_arg(enum tof type, struct process *proc, int arg_num)
   5.702 + {
   5.703 ++	proc_archdep *a = (proc_archdep *) proc->arch_ptr;
   5.704 ++
   5.705 + 	if (arg_num == -1) {	/* return value */
   5.706 + 		return ptrace(PTRACE_PEEKUSER, proc->pid, off_r0, 0);
   5.707 + 	}
   5.708 +@@ -60,6 +89,10 @@
   5.709 + 	/* deal with the ARM calling conventions */
   5.710 + 	if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
   5.711 + 		if (arg_num < 4) {
   5.712 ++			if (a->valid && type == LT_TOF_FUNCTION)
   5.713 ++				return a->regs.uregs[arg_num];
   5.714 ++			if (a->valid && type == LT_TOF_FUNCTIONR)
   5.715 ++				return a->func_arg[arg_num];
   5.716 + 			return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num,
   5.717 + 				      0);
   5.718 + 		} else {
   5.719 +@@ -69,6 +102,10 @@
   5.720 + 		}
   5.721 + 	} else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) {
   5.722 + 		if (arg_num < 5) {
   5.723 ++			if (a->valid && type == LT_TOF_SYSCALL)
   5.724 ++				return a->regs.uregs[arg_num];
   5.725 ++			if (a->valid && type == LT_TOF_SYSCALLR)
   5.726 ++				return a->sysc_arg[arg_num];
   5.727 + 			return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num,
   5.728 + 				      0);
   5.729 + 		} else {
   5.730 +@@ -86,4 +123,11 @@
   5.731 + 
   5.732 + void save_register_args(enum tof type, struct process *proc)
   5.733 + {
   5.734 ++	proc_archdep *a = (proc_archdep *) proc->arch_ptr;
   5.735 ++	if (a->valid) {
   5.736 ++		if (type == LT_TOF_FUNCTION)
   5.737 ++			memcpy(a->func_arg, a->regs.uregs, sizeof(a->func_arg));
   5.738 ++		else
   5.739 ++			memcpy(a->sysc_arg, a->regs.uregs, sizeof(a->sysc_arg));
   5.740 ++	}
   5.741 + }
   5.742 +diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/ppc/arch.h ltrace-0.5/sysdeps/linux-gnu/ppc/arch.h
   5.743 +--- ltrace-0.5.orig/sysdeps/linux-gnu/ppc/arch.h	2006-06-14 06:55:21.000000000 +0200
   5.744 ++++ ltrace-0.5/sysdeps/linux-gnu/ppc/arch.h	2008-11-04 19:25:50.000000000 +0100
   5.745 +@@ -4,9 +4,12 @@
   5.746 + 
   5.747 + #define LT_ELFCLASS	ELFCLASS32
   5.748 + #define LT_ELF_MACHINE	EM_PPC
   5.749 ++
   5.750 + #ifdef __powerpc64__ // Says 'ltrace' is 64 bits, says nothing about target.
   5.751 + #define LT_ELFCLASS2	ELFCLASS64
   5.752 + #define LT_ELF_MACHINE2	EM_PPC64
   5.753 ++#define ARCH_SUPPORTS_OPD
   5.754 ++#endif
   5.755 + 
   5.756 + #define PLT_REINITALISATION_BP    "_start"
   5.757 + 
   5.758 +@@ -16,6 +19,3 @@
   5.759 + #if (PPC_NOP_LENGTH != BREAKPOINT_LENGTH)
   5.760 + #error "Length of the breakpoint value not equal to the length of a nop instruction"
   5.761 + #endif
   5.762 +-
   5.763 +-
   5.764 +-#endif
   5.765 +diff -durN ltrace-0.5.orig/testsuite/ltrace.minor/Makefile.in ltrace-0.5/testsuite/ltrace.minor/Makefile.in
   5.766 +--- ltrace-0.5.orig/testsuite/ltrace.minor/Makefile.in	2006-03-14 00:12:01.000000000 +0100
   5.767 ++++ ltrace-0.5/testsuite/ltrace.minor/Makefile.in	2008-11-04 19:25:50.000000000 +0100
   5.768 +@@ -19,7 +19,7 @@
   5.769 + 
   5.770 + .SUFFIXES:	
   5.771 + clean:
   5.772 +-	-rm -f demangle trace-fork trace-clone 
   5.773 ++	-rm -f demangle trace-fork trace-clone trace-exec trace-exec1
   5.774 + 	-rm -f time-record-tt time-record-ttt time-record-T
   5.775 + 	-rm -f attach-process count-record
   5.776 + 	-rm -f print-instruction-pointer
   5.777 +diff -durN ltrace-0.5.orig/testsuite/ltrace.minor/trace-clone.c ltrace-0.5/testsuite/ltrace.minor/trace-clone.c
   5.778 +--- ltrace-0.5.orig/testsuite/ltrace.minor/trace-clone.c	2006-03-16 01:38:47.000000000 +0100
   5.779 ++++ ltrace-0.5/testsuite/ltrace.minor/trace-clone.c	2008-11-04 19:25:50.000000000 +0100
   5.780 +@@ -21,11 +21,11 @@
   5.781 + int main ()
   5.782 + {
   5.783 +   pid_t pid;
   5.784 +-  static char stack[STACK_SIZE];
   5.785 ++  char stack[STACK_SIZE];
   5.786 + #ifdef __ia64__
   5.787 +   pid = __clone2((myfunc)&child, stack, STACK_SIZE, CLONE_FS, NULL);
   5.788 + #else
   5.789 +-  pid = clone((myfunc)&child, stack,CLONE_FS, NULL );
   5.790 ++  pid = clone((myfunc)&child, stack + STACK_SIZE,CLONE_FS, NULL );
   5.791 + #endif
   5.792 +   if (pid < 0)
   5.793 +     {
   5.794 +diff -durN ltrace-0.5.orig/wait_for_something.c ltrace-0.5/wait_for_something.c
   5.795 +--- ltrace-0.5.orig/wait_for_something.c	2006-02-20 22:48:07.000000000 +0100
   5.796 ++++ ltrace-0.5/wait_for_something.c	2008-11-04 19:25:50.000000000 +0100
   5.797 +@@ -71,6 +71,18 @@
   5.798 + 		event.thing = LT_EV_SYSRET;
   5.799 + 		event.e_un.sysnum = tmp;
   5.800 + 		return &event;
   5.801 ++	case 3:
   5.802 ++		event.thing = LT_EV_ARCH_SYSCALL;
   5.803 ++		event.e_un.sysnum = tmp;
   5.804 ++		return &event;
   5.805 ++	case 4:
   5.806 ++		event.thing = LT_EV_ARCH_SYSRET;
   5.807 ++		event.e_un.sysnum = tmp;
   5.808 ++		return &event;
   5.809 ++	case -1:
   5.810 ++		event.thing = LT_EV_NONE;
   5.811 ++		continue_process(event.proc->pid);
   5.812 ++		return &event;
   5.813 + 	}
   5.814 + 	if (WIFEXITED(status)) {
   5.815 + 		event.thing = LT_EV_EXIT;