patches/ltrace/0.5/130-fixes-by-debian.patch
author "Benoît THÉBAUDEAU" <benoit.thebaudeau@advansee.com>
Thu Aug 18 16:05:48 2011 +0200 (2011-08-18)
changeset 2612 a52574521bea
permissions -rw-r--r--
debug/gdb: update GDB revisions

Update GDB with the latest available revisions.

Signed-off-by: "Benoît THÉBAUDEAU" <benoit.thebaudeau@advansee.com>
     1 This patch was vampirised from the 0.5-3.1 Debian-packaged version of ltrace,
     2 and contains the following fixes (exerpt from the Debian changelog). Moreover,
     3 you will also find an exerpt of the Debian copyright file with proper
     4 attribution.
     5 
     6 ================ Debian changelog exerpt ================
     7 ltrace (0.5-3.1) unstable; urgency=low
     8 
     9   * Non-maintainer upload.
    10   * Big thanks for Anderson Lizardo for providing patches!
    11   * Add generic support for arm targets, Closes: #176413
    12   * Save funtion arguments on arm, Closes: #462530
    13   * Add thumb instruction support, Closes: #462531
    14   * Add basic arm/eabi support, Closes: #450931
    15   * fix exec() testcase cleanup, Closes: #462532
    16   * fix memory corruption in clone() test, Closes: #462533
    17   * fix tracing child with "-p" option, Closes: #462535
    18   * Update standard, no changes
    19 
    20  -- Riku Voipio <riku.voipio@iki.fi>  Tue, 29 Jan 2008 00:26:50 +0200
    21 
    22 ltrace (0.5-3) unstable; urgency=low
    23 
    24   * Really fix compilation problems in ppc (!)
    25 
    26  -- Juan Cespedes <cespedes@debian.org>  Fri, 31 Aug 2007 19:04:03 +0200
    27 
    28 ltrace (0.5-2) unstable; urgency=low
    29 
    30   * Fixed compilation issue in ppc
    31 
    32  -- Juan Cespedes <cespedes@debian.org>  Fri, 31 Aug 2007 13:53:27 +0200
    33 
    34 ltrace (0.5-1) unstable; urgency=low
    35 
    36   * New upstream version
    37   * Remove some unneeded files in /usr/share/doc (ChangeLog, COPYING...)
    38   * Fix several typos (closes: Bug#372928)
    39   * Added more system calls to ltrace.conf
    40 
    41  -- Juan Cespedes <cespedes@debian.org>  Thu, 30 Aug 2007 14:54:44 +0200
    42 ============== End Debian changelog exerpt ==============
    43 
    44 ================ Debian copyright exerpt ================
    45 Copyrights
    46 ----------
    47 Copyright (C) 1997-2007 Juan Cespedes <cespedes@debian.org>
    48 
    49 ARMLinux port: Copyright (C) 1998 Pat Beirne <pbeirne@home.com>
    50 m68k port: Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
    51 Misc fixes: Copyright (C) 1999 Morten Eriksen <mortene@sim.no>
    52 s390 port: Copyright (C) 2001 IBM Poughkeepsie, IBM Cororation <slate@us.ibm.com>
    53 ELF hacking: Copyright (C) 1999 Silvio Cesare <silvio@big.net.au>
    54 PowerPC port: Copyright (C) 2001-2002 Anton Blanchard <anton@samba.org>
    55 SPARC port: Copyright (C) 1999 Jakub Jelinek <jakub@redhat.com>
    56 
    57 Autoconf stuff: Copyright 1992-1996 Free Software Foundation, Inc.
    58 install-sh: Copyright 1991 by the Massachusetts Institute of Technology
    59 C++ demangle: Copyright 1989-1997 Free Software Foundation, Inc.
    60 ============== End Debian copyright exerpt ==============
    61 
    62 diff -durN ltrace-0.5.orig/breakpoints.c ltrace-0.5/breakpoints.c
    63 --- ltrace-0.5.orig/breakpoints.c	2006-06-14 06:55:21.000000000 +0200
    64 +++ ltrace-0.5/breakpoints.c	2008-11-04 19:25:50.000000000 +0100
    65 @@ -53,6 +53,10 @@
    66  		if (libsym)
    67  			libsym->brkpnt = sbp;
    68  	}
    69 +#ifdef __arm__
    70 +	sbp->thumb_mode = proc->thumb_mode;
    71 +	proc->thumb_mode = 0;
    72 +#endif
    73  	sbp->enabled++;
    74  	if (sbp->enabled == 1 && proc->pid)
    75  		enable_breakpoint(proc->pid, sbp);
    76 diff -durN ltrace-0.5.orig/elf.c ltrace-0.5/elf.c
    77 --- ltrace-0.5.orig/elf.c	2006-06-14 06:55:21.000000000 +0200
    78 +++ ltrace-0.5/elf.c	2008-11-04 19:25:50.000000000 +0100
    79 @@ -464,8 +464,7 @@
    80  			if (strcmp(xptr->name, PLTs_initialized_by_here) == 0) {
    81  				if (lte->ehdr.e_entry) {
    82  					add_library_symbol (
    83 -						elf_plt2addr (lte, (void*)(long)
    84 -							lte->ehdr.e_entry),
    85 +						opd2addr (lte, lte->ehdr.e_entry),
    86  						PLTs_initialized_by_here,
    87  						lib_tail, 1, 0);
    88  					fprintf (stderr, "WARNING: Using e_ent"
    89 diff -durN ltrace-0.5.orig/etc/ltrace.conf ltrace-0.5/etc/ltrace.conf
    90 --- ltrace-0.5.orig/etc/ltrace.conf	2006-02-20 22:55:47.000000000 +0100
    91 +++ ltrace-0.5/etc/ltrace.conf	2008-11-04 19:25:50.000000000 +0100
    92 @@ -444,3 +444,81 @@
    93  int   SYS_removexattr(string,string);
    94  int   SYS_lremovexattr(string,string);
    95  int   SYS_fremovexattr(int,string);
    96 +int   SYS_chdir(string);
    97 +int   SYS_fchdir(int);
    98 +int   SYS_chmod(string,octal);
    99 +int   SYS_fchmod(int,octal);
   100 +int   SYS_chown(string,int,int);
   101 +int   SYS_fchown(int,int,int);
   102 +int   SYS_lchown(string,int,int);
   103 +int   SYS_chroot(string);
   104 +int   SYS_dup(int);
   105 +int   SYS_dup2(int,int);
   106 +int   SYS_fdatasync(int);
   107 +int   SYS_fsync(int);
   108 +int   SYS_getpriority(int,int);
   109 +int   SYS_setpriority(int,int,int);
   110 +int   SYS_getrlimit(int,addr);
   111 +int   SYS_setrlimit(int,addr);
   112 +int   SYS_gettimeofday(addr,addr);
   113 +int   SYS_settimeofday(addr,addr);
   114 +int   SYS_setfsgid(int);
   115 +int   SYS_setfsuid(int);
   116 +int   SYS_getuid(void);
   117 +int   SYS_setuid(int);
   118 +int   SYS_getgid(void);
   119 +int   SYS_setgid(int);
   120 +int   SYS_getsid(int);
   121 +int   SYS_setsid(int);
   122 +int   SYS_setreuid(int,int);
   123 +int   SYS_setregid(int,int);
   124 +int   SYS_geteuid(void);
   125 +int   SYS_getegid(void);
   126 +int   SYS_setpgid(int,int);
   127 +int   SYS_getresuid(addr,addr,addr);
   128 +int   SYS_setresuid(int,int,int);
   129 +int   SYS_getresgid(addr,addr,addr);
   130 +int   SYS_setresgid(int,int,int);
   131 +int   SYS_kill(int,int);
   132 +int   SYS_link(string,string);
   133 +int   SYS_madvise(addr,ulong,int);
   134 +int   SYS_mkdir(string,octal);
   135 +int   SYS_mknod(string,octal,int);
   136 +int   SYS_msync(addr,ulong,int);
   137 +int   SYS_nice(int);
   138 +int   SYS_poll(addr,uint,int);
   139 +int   SYS_readdir(uint,addr,uint);
   140 +int   SYS_readlink(string,string,ulong);
   141 +int   SYS_reboot(int,int,int,addr);
   142 +int   SYS_rename(string,string);
   143 +int   SYS_rmdir(string);
   144 +int   SYS_sigaltstack(addr,addr);
   145 +int   SYS_statfs(string,addr);
   146 +int   SYS_fstatfs(int,addr);
   147 +int   SYS_fstat(int,addr);
   148 +int   SYS_lstat(string,addr);
   149 +int   SYS_stime(addr);
   150 +int   SYS_symlink(string, string);
   151 +int   SYS_sysinfo(addr);
   152 +int   SYS_syslog(int,string,int);
   153 +int   SYS_truncate(string,long);
   154 +int   SYS_ftruncate(int,long);
   155 +int   SYS_mount(string,string,string,ulong,addr);
   156 +int   SYS_umount(string);
   157 +int   SYS_umount2(string,int);
   158 +int   SYS_unlink(string);
   159 +int   SYS_utime(string,addr);
   160 +long  SYS_lseek(int,long,int);
   161 +addr  SYS_signal(int,addr);
   162 +int   SYS_sigaction(int,addr,addr);
   163 +int   SYS_pause(void);
   164 +int   SYS_sigpending(addr);
   165 +int   SYS_sigprocmask(int,addr,addr);
   166 +int   SYS_sigqueue(int,int,addr);
   167 +int   SYS_sigsuspend(addr);
   168 +int   SYS_wait(addr);
   169 +int   SYS_waitpid(int,addr,int);
   170 +ulong SYS_readv(int,addr,int);
   171 +ulong SYS_writev(int,addr,int);
   172 +int   SYS_mprotect(addr,int,int);
   173 +int   SYS_access(string,octal);
   174 diff -durN ltrace-0.5.orig/ltrace.1 ltrace-0.5/ltrace.1
   175 --- ltrace-0.5.orig/ltrace.1	2006-06-16 03:15:18.000000000 +0200
   176 +++ ltrace-0.5/ltrace.1	2008-11-04 19:25:50.000000000 +0100
   177 @@ -30,7 +30,7 @@
   178  .TP
   179  .I \-C, \-\-demangle
   180  Decode (demangle) low-level symbol names into user-level names.
   181 -Besides removing any initial underscore prepended by the system,
   182 +Besides removing any initial underscore prefix used by the system,
   183  this makes C++ function names readable.
   184  .TP
   185  .I \-d, \-\-debug
   186 diff -durN ltrace-0.5.orig/ltrace.c ltrace-0.5/ltrace.c
   187 --- ltrace-0.5.orig/ltrace.c	2006-02-20 22:48:07.000000000 +0100
   188 +++ ltrace-0.5/ltrace.c	2008-11-04 19:25:50.000000000 +0100
   189 @@ -54,6 +54,9 @@
   190  {
   191  	exiting = 1;
   192  	debug(1, "Received interrupt signal; exiting...");
   193 +	if (opt_o) {
   194 +		fclose(output);
   195 +	}
   196  	signal(SIGINT, SIG_IGN);
   197  	signal(SIGTERM, SIG_IGN);
   198  	signal(SIGALRM, signal_alarm);
   199 @@ -74,6 +77,9 @@
   200  	if (opt_c) {
   201  		show_summary();
   202  	}
   203 +	if (opt_o) {
   204 +		fclose(output);
   205 +	}
   206  }
   207  
   208  static void guess_cols(void)
   209 diff -durN ltrace-0.5.orig/ltrace.h ltrace-0.5/ltrace.h
   210 --- ltrace-0.5.orig/ltrace.h	2006-06-14 06:55:21.000000000 +0200
   211 +++ ltrace-0.5/ltrace.h	2008-11-04 19:25:50.000000000 +0100
   212 @@ -26,6 +26,9 @@
   213  	unsigned char orig_value[BREAKPOINT_LENGTH];
   214  	int enabled;
   215  	struct library_symbol *libsym;
   216 +#ifdef __arm__
   217 +	int thumb_mode;
   218 +#endif
   219  };
   220  
   221  enum arg_type {
   222 @@ -119,6 +122,9 @@
   223  	void *arch_ptr;
   224  	short e_machine;
   225  	short need_to_reinitialize_breakpoints;
   226 +#ifdef __arm__
   227 +	int thumb_mode; /* ARM execution mode: 0: ARM mode, 1: Thumb mode */
   228 +#endif
   229  
   230  	/* output: */
   231  	enum tof type_being_displayed;
   232 @@ -136,12 +142,14 @@
   233  		LT_EV_EXIT_SIGNAL,
   234  		LT_EV_SYSCALL,
   235  		LT_EV_SYSRET,
   236 +		LT_EV_ARCH_SYSCALL,
   237 +		LT_EV_ARCH_SYSRET,
   238  		LT_EV_BREAKPOINT
   239  	} thing;
   240  	union {
   241  		int ret_val;	/* _EV_EXIT */
   242  		int signum;	/* _EV_SIGNAL, _EV_EXIT_SIGNAL */
   243 -		int sysnum;	/* _EV_SYSCALL, _EV_SYSRET */
   244 +		int sysnum;	/* _EV_SYSCALL, _EV_SYSRET, _EV_ARCH_SYSCALL, _EV_ARCH_SYSRET */
   245  		void *brk_addr;	/* _EV_BREAKPOINT */
   246  	} e_un;
   247  };
   248 diff -durN ltrace-0.5.orig/options.c ltrace-0.5/options.c
   249 --- ltrace-0.5.orig/options.c	2006-04-24 22:06:23.000000000 +0200
   250 +++ ltrace-0.5/options.c	2008-11-04 19:25:50.000000000 +0100
   251 @@ -42,6 +42,7 @@
   252  #endif
   253  int opt_n = 0;			/* indent trace output according to program flow */
   254  int opt_T = 0;			/* show the time spent inside each call */
   255 +int opt_o = 0;			/* output to a specific file */
   256  
   257  /* List of pids given to option -p: */
   258  struct opt_p_t *opt_p = NULL;	/* attach to process with a given pid */
   259 @@ -274,6 +275,7 @@
   260  			opt_n = atoi(optarg);
   261  			break;
   262  		case 'o':
   263 +			opt_o++;
   264  			output = fopen(optarg, "w");
   265  			if (!output) {
   266  				fprintf(stderr,
   267 diff -durN ltrace-0.5.orig/options.h ltrace-0.5/options.h
   268 --- ltrace-0.5.orig/options.h	2006-03-13 18:43:13.000000000 +0100
   269 +++ ltrace-0.5/options.h	2008-11-04 19:25:50.000000000 +0100
   270 @@ -20,6 +20,7 @@
   271  extern int opt_C;		/* Demanglelow-level symbol names into user-level names */
   272  extern int opt_n;		/* indent trace output according to program flow */
   273  extern int opt_T;		/* show the time spent inside each call */
   274 +extern int opt_o;		/* output to a specific file */
   275  
   276  struct opt_p_t {
   277  	pid_t pid;
   278 diff -durN ltrace-0.5.orig/process_event.c ltrace-0.5/process_event.c
   279 --- ltrace-0.5.orig/process_event.c	2006-06-14 06:55:21.000000000 +0200
   280 +++ ltrace-0.5/process_event.c	2008-11-04 19:25:50.000000000 +0100
   281 @@ -24,7 +24,9 @@
   282  static void process_exit(struct event *event);
   283  static void process_exit_signal(struct event *event);
   284  static void process_syscall(struct event *event);
   285 +static void process_arch_syscall(struct event *event);
   286  static void process_sysret(struct event *event);
   287 +static void process_arch_sysret(struct event *event);
   288  static void process_breakpoint(struct event *event);
   289  static void remove_proc(struct process *proc);
   290  
   291 @@ -81,6 +83,24 @@
   292  	}
   293  }
   294  
   295 +static char *arch_sysname(struct process *proc, int sysnum)
   296 +{
   297 +	static char result[128];
   298 +	static char *arch_syscalent[] = {
   299 +#include "arch_syscallent.h"
   300 +	};
   301 +	int nsyscals = sizeof arch_syscalent / sizeof arch_syscalent[0];
   302 +
   303 +	if (sysnum < 0 || sysnum >= nsyscals) {
   304 +		sprintf(result, "ARCH_%d", sysnum);
   305 +		return result;
   306 +	} else {
   307 +		sprintf(result, "ARCH_%s",
   308 +			arch_syscalent[sysnum]);
   309 +		return result;
   310 +	}
   311 +}
   312 +
   313  void process_event(struct event *event)
   314  {
   315  	switch (event->thing) {
   316 @@ -115,6 +135,18 @@
   317  		      event->e_un.sysnum);
   318  		process_sysret(event);
   319  		return;
   320 +	case LT_EV_ARCH_SYSCALL:
   321 +		debug(1, "event: arch_syscall (%s [%d])",
   322 +		      arch_sysname(event->proc, event->e_un.sysnum),
   323 +		      event->e_un.sysnum);
   324 +		process_arch_syscall(event);
   325 +		return;
   326 +	case LT_EV_ARCH_SYSRET:
   327 +		debug(1, "event: arch_sysret (%s [%d])",
   328 +		      arch_sysname(event->proc, event->e_un.sysnum),
   329 +		      event->e_un.sysnum);
   330 +		process_arch_sysret(event);
   331 +		return;
   332  	case LT_EV_BREAKPOINT:
   333  		debug(1, "event: breakpoint");
   334  		process_breakpoint(event);
   335 @@ -195,6 +227,19 @@
   336  	continue_process(event->proc->pid);
   337  }
   338  
   339 +static void process_arch_syscall(struct event *event)
   340 +{
   341 +	if (opt_S) {
   342 +		output_left(LT_TOF_SYSCALL, event->proc,
   343 +			    arch_sysname(event->proc, event->e_un.sysnum));
   344 +	}
   345 +	if (event->proc->breakpoints_enabled == 0) {
   346 +		enable_all_breakpoints(event->proc);
   347 +	}
   348 +	callstack_push_syscall(event->proc, 0xf0000 + event->e_un.sysnum);
   349 +	continue_process(event->proc->pid);
   350 +}
   351 +
   352  struct timeval current_time_spent;
   353  
   354  static void calc_time_spent(struct process *proc)
   355 @@ -257,6 +302,19 @@
   356  	continue_process(event->proc->pid);
   357  }
   358  
   359 +static void process_arch_sysret(struct event *event)
   360 +{
   361 +	if (opt_T || opt_c) {
   362 +		calc_time_spent(event->proc);
   363 +	}
   364 +	callstack_pop(event->proc);
   365 +	if (opt_S) {
   366 +		output_right(LT_TOF_SYSCALLR, event->proc,
   367 +			     arch_sysname(event->proc, event->e_un.sysnum));
   368 +	}
   369 +	continue_process(event->proc->pid);
   370 +}
   371 +
   372  static void process_breakpoint(struct event *event)
   373  {
   374  	int i, j;
   375 diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/Makefile ltrace-0.5/sysdeps/linux-gnu/Makefile
   376 --- ltrace-0.5.orig/sysdeps/linux-gnu/Makefile	2008-11-04 19:25:11.000000000 +0100
   377 +++ ltrace-0.5/sysdeps/linux-gnu/Makefile	2008-11-04 19:25:50.000000000 +0100
   378 @@ -2,7 +2,7 @@
   379  
   380  OBJ		=	trace.o proc.o breakpoint.o
   381  
   382 -all:		sysdep.h signalent.h syscallent.h signalent1.h syscallent1.h ../sysdep.o
   383 +all:		sysdep.h signalent.h syscallent.h arch_syscallent.h signalent1.h syscallent1.h ../sysdep.o
   384  
   385  sysdep.h:	$(ARCH)/arch.h
   386  		cat $(ARCH)/arch.h > sysdep.h
   387 @@ -26,6 +26,13 @@
   388  			> syscallent1.h; \
   389  		fi
   390  
   391 +arch_syscallent.h:
   392 +		if [ -f $(ARCH)/arch_syscallent.h ]; then \
   393 +			cp $(ARCH)/arch_syscallent.h arch_syscallent.h; \
   394 +		else \
   395 +			> arch_syscallent.h; \
   396 +		fi
   397 +
   398  ../sysdep.o:	os.o $(ARCH)/arch.o
   399  		$(CC) -nostdlib -r -o ../sysdep.o os.o $(ARCH)/arch.o
   400  
   401 @@ -37,7 +44,7 @@
   402  
   403  clean:
   404  		$(MAKE) -C $(ARCH) clean
   405 -		rm -f $(OBJ) sysdep.h signalent.h signalent1.h syscallent.h
   406 +		rm -f $(OBJ) sysdep.h signalent.h signalent1.h syscallent.h arch_syscallent.h
   407  		rm -f syscallent1.h os.o sysdep.o ../sysdep.o
   408  
   409  dummy:
   410 diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arch_mksyscallent ltrace-0.5/sysdeps/linux-gnu/arch_mksyscallent
   411 --- ltrace-0.5.orig/sysdeps/linux-gnu/arch_mksyscallent	1970-01-01 01:00:00.000000000 +0100
   412 +++ ltrace-0.5/sysdeps/linux-gnu/arch_mksyscallent	2008-11-04 19:25:50.000000000 +0100
   413 @@ -0,0 +1,43 @@
   414 +#!/usr/bin/awk -f
   415 +
   416 +# hack expression to generate arch_syscallent.h from <asm/unistd.h>
   417 +# It reads from stdin and writes to stdout
   418 +# Currently (linux-2.6.16), it works OK on arm
   419 +# It is untested in other architectures
   420 +
   421 +BEGIN {
   422 +	max=0;
   423 +	FS="[ \t\n()+]+";
   424 +}
   425 +
   426 +{
   427 +#	printf("/%s/%s/%s/%s/\n", $1, $2, $3, $4);
   428 +	if (($1 ~ /^#define$/) && ($2 ~ /^__[A-Z]+_NR_/)) {
   429 +		sub(/^__[A-Z]+_NR_/,"",$2);
   430 +		if (($3>=0) && ($3<=1000)) {
   431 +			SYSCALL[$3]=$2;
   432 +			if ($3 > max) {
   433 +				max=$3;
   434 +			}
   435 +		} else if (($3 ~ /^__[A-Z]+_NR_BASE$/) && ($4>=0) && ($4<=1000)) {
   436 +			SYSCALL[$4]=$2;
   437 +			if ($4 > max) {
   438 +				max=$4;
   439 +			}
   440 +		}
   441 +	}
   442 +}
   443 +
   444 +END {
   445 +	for(i=0; i<=max; i++) {
   446 +		if (!SYSCALL[i]) {
   447 +			SYSCALL[i] = i;
   448 +		}
   449 +		pad = 32 - length(SYSCALL[i]);
   450 +		if (pad<1) {
   451 +			pad=1;
   452 +		}
   453 +		printf("\t\"%s\",%*s/* %d */\n", SYSCALL[i], pad, "", i);
   454 +	}
   455 +}
   456 +
   457 diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/Makefile ltrace-0.5/sysdeps/linux-gnu/arm/Makefile
   458 --- ltrace-0.5.orig/sysdeps/linux-gnu/arm/Makefile	2006-02-20 22:44:45.000000000 +0100
   459 +++ ltrace-0.5/sysdeps/linux-gnu/arm/Makefile	2008-11-04 19:25:50.000000000 +0100
   460 @@ -1,4 +1,4 @@
   461 -OBJ	=	trace.o regs.o plt.o
   462 +OBJ	=	trace.o regs.o plt.o breakpoint.o
   463  
   464  all:		arch.o
   465  
   466 diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/arch.h ltrace-0.5/sysdeps/linux-gnu/arm/arch.h
   467 --- ltrace-0.5.orig/sysdeps/linux-gnu/arm/arch.h	2006-04-24 22:06:23.000000000 +0200
   468 +++ ltrace-0.5/sysdeps/linux-gnu/arm/arch.h	2008-11-04 19:25:50.000000000 +0100
   469 @@ -1,5 +1,10 @@
   470 -#define BREAKPOINT_VALUE { 0x01, 0x00, 0x9f, 0xef }
   471 +#define ARCH_HAVE_ENABLE_BREAKPOINT 1
   472 +#define ARCH_HAVE_DISABLE_BREAKPOINT 1
   473 +
   474 +#define BREAKPOINT_VALUE { 0xf0, 0x01, 0xf0, 0xe7 }
   475  #define BREAKPOINT_LENGTH 4
   476 +#define THUMB_BREAKPOINT_VALUE { 0x01, 0xde }
   477 +#define THUMB_BREAKPOINT_LENGTH 2
   478  #define DECR_PC_AFTER_BREAK 0
   479  
   480  #define LT_ELFCLASS	ELFCLASS32
   481 diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/arch_syscallent.h ltrace-0.5/sysdeps/linux-gnu/arm/arch_syscallent.h
   482 --- ltrace-0.5.orig/sysdeps/linux-gnu/arm/arch_syscallent.h	1970-01-01 01:00:00.000000000 +0100
   483 +++ ltrace-0.5/sysdeps/linux-gnu/arm/arch_syscallent.h	2008-11-04 19:25:50.000000000 +0100
   484 @@ -0,0 +1,6 @@
   485 +	"0",                               /* 0 */
   486 +	"breakpoint",                      /* 1 */
   487 +	"cacheflush",                      /* 2 */
   488 +	"usr26",                           /* 3 */
   489 +	"usr32",                           /* 4 */
   490 +	"set_tls",                         /* 5 */
   491 diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/breakpoint.c ltrace-0.5/sysdeps/linux-gnu/arm/breakpoint.c
   492 --- ltrace-0.5.orig/sysdeps/linux-gnu/arm/breakpoint.c	1970-01-01 01:00:00.000000000 +0100
   493 +++ ltrace-0.5/sysdeps/linux-gnu/arm/breakpoint.c	2008-11-04 19:25:50.000000000 +0100
   494 @@ -0,0 +1,86 @@
   495 +/*
   496 + * This file is part of ltrace.
   497 + *
   498 + * Copyright (C) 2007 by Instituto Nokia de Tecnologia (INdT)
   499 + *
   500 + * Author: Anderson Lizardo <anderson.lizardo@indt.org.br>
   501 + *
   502 + * This program is free software; you can redistribute it and/or
   503 + * modify it under the terms of the GNU General Public License
   504 + * version 2 as published by the Free Software Foundation.
   505 + *
   506 + * This program is distributed in the hope that it will be useful, but
   507 + * WITHOUT ANY WARRANTY; without even the implied warranty of
   508 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   509 + * General Public License for more details.
   510 + *
   511 + * You should have received a copy of the GNU General Public License
   512 + * along with this program; if not, write to the Free Software
   513 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   514 + * 02110-1301 USA
   515 + *
   516 + * Modified from sysdeps/linux-gnu/breakpoint.c and added ARM Thumb support.
   517 +*/
   518 +
   519 +#include <sys/ptrace.h>
   520 +#include "config.h"
   521 +#include "arch.h"
   522 +#include "options.h"
   523 +#include "output.h"
   524 +#include "debug.h"
   525 +
   526 +void arch_enable_breakpoint(pid_t pid, struct breakpoint *sbp)
   527 +{
   528 +	unsigned int i, j;
   529 +	const unsigned char break_insn[] = BREAKPOINT_VALUE;
   530 +	const unsigned char thumb_break_insn[] = THUMB_BREAKPOINT_VALUE;
   531 +
   532 +	debug(1, "arch_enable_breakpoint(%d,%p)", pid, sbp->addr);
   533 +
   534 +	for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
   535 +		long a =
   536 +		    ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
   537 +			   0);
   538 +		unsigned char *bytes = (unsigned char *)&a;
   539 +
   540 +		debug(2, "current = 0x%lx, orig_value = 0x%lx, thumb_mode = %d", a, *(long *)&sbp->orig_value, sbp->thumb_mode);
   541 +		for (j = 0;
   542 +		     j < sizeof(long)
   543 +		     && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
   544 +
   545 +			sbp->orig_value[i * sizeof(long) + j] = bytes[j];
   546 +			if (!sbp->thumb_mode) {
   547 +				bytes[j] = break_insn[i * sizeof(long) + j];
   548 +			}
   549 +			else if (j < THUMB_BREAKPOINT_LENGTH) {
   550 +				bytes[j] = thumb_break_insn[i * sizeof(long) + j];
   551 +			}
   552 +		}
   553 +		ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
   554 +	}
   555 +}
   556 +
   557 +void arch_disable_breakpoint(pid_t pid, const struct breakpoint *sbp)
   558 +{
   559 +	unsigned int i, j;
   560 +	const unsigned char break_insn[] = BREAKPOINT_VALUE;
   561 +	const unsigned char thumb_break_insn[] = THUMB_BREAKPOINT_VALUE;
   562 +
   563 +	debug(1, "arch_disable_breakpoint(%d,%p)", pid, sbp->addr);
   564 +
   565 +	for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
   566 +		long a =
   567 +		    ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
   568 +			   0);
   569 +		unsigned char *bytes = (unsigned char *)&a;
   570 +
   571 +		debug(2, "current = 0x%lx, orig_value = 0x%lx, thumb_mode = %d", a, *(long *)&sbp->orig_value, sbp->thumb_mode);
   572 +		for (j = 0;
   573 +		     j < sizeof(long)
   574 +		     && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
   575 +
   576 +			bytes[j] = sbp->orig_value[i * sizeof(long) + j];
   577 +		}
   578 +		ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
   579 +	}
   580 +}
   581 diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/ptrace.h ltrace-0.5/sysdeps/linux-gnu/arm/ptrace.h
   582 --- ltrace-0.5.orig/sysdeps/linux-gnu/arm/ptrace.h	2006-02-20 22:44:45.000000000 +0100
   583 +++ ltrace-0.5/sysdeps/linux-gnu/arm/ptrace.h	2008-11-04 19:25:50.000000000 +0100
   584 @@ -1 +1,9 @@
   585  #include <sys/ptrace.h>
   586 +#include <asm/ptrace.h>
   587 +
   588 +typedef struct {
   589 +	int valid;
   590 +	struct pt_regs regs;
   591 +	long func_arg[5];
   592 +	long sysc_arg[5];
   593 +} proc_archdep;
   594 diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/regs.c ltrace-0.5/sysdeps/linux-gnu/arm/regs.c
   595 --- ltrace-0.5.orig/sysdeps/linux-gnu/arm/regs.c	2006-02-20 22:48:07.000000000 +0100
   596 +++ ltrace-0.5/sysdeps/linux-gnu/arm/regs.c	2008-11-04 19:25:50.000000000 +0100
   597 @@ -39,5 +39,10 @@
   598   * a CISC architecture; in our case, we don't need that */
   599  void *get_return_addr(struct process *proc, void *stack_pointer)
   600  {
   601 -	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_lr, 0);
   602 +	long addr = ptrace(PTRACE_PEEKUSER, proc->pid, off_lr, 0);
   603 +
   604 +	proc->thumb_mode = addr & 1;
   605 +	if (proc->thumb_mode)
   606 +		addr &= ~1;
   607 +	return (void *)addr;
   608  }
   609 diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/trace.c ltrace-0.5/sysdeps/linux-gnu/arm/trace.c
   610 --- ltrace-0.5.orig/sysdeps/linux-gnu/arm/trace.c	2006-02-20 22:48:07.000000000 +0100
   611 +++ ltrace-0.5/sysdeps/linux-gnu/arm/trace.c	2008-11-04 19:25:50.000000000 +0100
   612 @@ -2,6 +2,7 @@
   613  #include "config.h"
   614  #endif
   615  
   616 +#include <string.h>
   617  #include <sys/types.h>
   618  #include <sys/wait.h>
   619  #include <signal.h>
   620 @@ -9,6 +10,8 @@
   621  #include <asm/ptrace.h>
   622  
   623  #include "ltrace.h"
   624 +#include "output.h"
   625 +#include "ptrace.h"
   626  
   627  #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
   628  # define PTRACE_PEEKUSER PTRACE_PEEKUSR
   629 @@ -18,19 +21,25 @@
   630  # define PTRACE_POKEUSER PTRACE_POKEUSR
   631  #endif
   632  
   633 -/* syscall tracing protocol: ArmLinux
   634 - on the way in, ip is 0
   635 - on the way out, ip is non-zero
   636 -*/
   637  #define off_r0 0
   638 +#define off_r7 28
   639  #define off_ip 48
   640  #define off_pc 60
   641  
   642  void get_arch_dep(struct process *proc)
   643  {
   644 +	proc_archdep *a;
   645 +
   646 +	if (!proc->arch_ptr)
   647 +		proc->arch_ptr = (void *)malloc(sizeof(proc_archdep));
   648 +	a = (proc_archdep *) (proc->arch_ptr);
   649 +	a->valid = (ptrace(PTRACE_GETREGS, proc->pid, 0, &a->regs) >= 0);
   650  }
   651  
   652 -/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
   653 +/* Returns 0 if not a syscall,
   654 + *         1 if syscall entry, 2 if syscall exit,
   655 + *         3 if arch-specific syscall entry, 4 if arch-specific syscall exit,
   656 + *         -1 on error.
   657   */
   658  int syscall_p(struct process *proc, int status, int *sysnum)
   659  {
   660 @@ -40,19 +49,39 @@
   661  		int pc = ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0);
   662  		/* fetch the SWI instruction */
   663  		int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 4, 0);
   664 +		int ip = ptrace(PTRACE_PEEKUSER, proc->pid, off_ip, 0);
   665  
   666 -		*sysnum = insn & 0xFFFF;
   667 -		/* if it is a syscall, return 1 or 2 */
   668 -		if ((insn & 0xFFFF0000) == 0xef900000) {
   669 -			return ptrace(PTRACE_PEEKUSER, proc->pid, off_ip,
   670 -				      0) ? 2 : 1;
   671 +		if (insn == 0xef000000 || insn == 0x0f000000) {
   672 +			/* EABI syscall */
   673 +			*sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, off_r7, 0);
   674 +		} else if ((insn & 0xfff00000) == 0xef900000) {
   675 +			/* old ABI syscall */
   676 +			*sysnum = insn & 0xfffff;
   677 +		} else {
   678 +			/* TODO: handle swi<cond> variations */
   679 +			/* one possible reason for getting in here is that we
   680 +			 * are coming from a signal handler, so the current
   681 +			 * PC does not point to the instruction just after the
   682 +			 * "swi" one. */
   683 +			output_line(proc, "unexpected instruction 0x%x at %p", insn, pc - 4);
   684 +			return -1;
   685 +		}
   686 +		if ((*sysnum & 0xf0000) == 0xf0000) {
   687 +			/* arch-specific syscall */
   688 +			*sysnum &= ~0xf0000;
   689 +			return ip ? 4 : 3;
   690  		}
   691 +		/* ARM syscall convention: on syscall entry, ip is zero;
   692 +		 * on syscall exit, ip is non-zero */
   693 +		return ip ? 2 : 1;
   694  	}
   695  	return 0;
   696  }
   697  
   698  long gimme_arg(enum tof type, struct process *proc, int arg_num)
   699  {
   700 +	proc_archdep *a = (proc_archdep *) proc->arch_ptr;
   701 +
   702  	if (arg_num == -1) {	/* return value */
   703  		return ptrace(PTRACE_PEEKUSER, proc->pid, off_r0, 0);
   704  	}
   705 @@ -60,6 +89,10 @@
   706  	/* deal with the ARM calling conventions */
   707  	if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
   708  		if (arg_num < 4) {
   709 +			if (a->valid && type == LT_TOF_FUNCTION)
   710 +				return a->regs.uregs[arg_num];
   711 +			if (a->valid && type == LT_TOF_FUNCTIONR)
   712 +				return a->func_arg[arg_num];
   713  			return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num,
   714  				      0);
   715  		} else {
   716 @@ -69,6 +102,10 @@
   717  		}
   718  	} else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) {
   719  		if (arg_num < 5) {
   720 +			if (a->valid && type == LT_TOF_SYSCALL)
   721 +				return a->regs.uregs[arg_num];
   722 +			if (a->valid && type == LT_TOF_SYSCALLR)
   723 +				return a->sysc_arg[arg_num];
   724  			return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num,
   725  				      0);
   726  		} else {
   727 @@ -86,4 +123,11 @@
   728  
   729  void save_register_args(enum tof type, struct process *proc)
   730  {
   731 +	proc_archdep *a = (proc_archdep *) proc->arch_ptr;
   732 +	if (a->valid) {
   733 +		if (type == LT_TOF_FUNCTION)
   734 +			memcpy(a->func_arg, a->regs.uregs, sizeof(a->func_arg));
   735 +		else
   736 +			memcpy(a->sysc_arg, a->regs.uregs, sizeof(a->sysc_arg));
   737 +	}
   738  }
   739 diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/ppc/arch.h ltrace-0.5/sysdeps/linux-gnu/ppc/arch.h
   740 --- ltrace-0.5.orig/sysdeps/linux-gnu/ppc/arch.h	2006-06-14 06:55:21.000000000 +0200
   741 +++ ltrace-0.5/sysdeps/linux-gnu/ppc/arch.h	2008-11-04 19:25:50.000000000 +0100
   742 @@ -4,9 +4,12 @@
   743  
   744  #define LT_ELFCLASS	ELFCLASS32
   745  #define LT_ELF_MACHINE	EM_PPC
   746 +
   747  #ifdef __powerpc64__ // Says 'ltrace' is 64 bits, says nothing about target.
   748  #define LT_ELFCLASS2	ELFCLASS64
   749  #define LT_ELF_MACHINE2	EM_PPC64
   750 +#define ARCH_SUPPORTS_OPD
   751 +#endif
   752  
   753  #define PLT_REINITALISATION_BP    "_start"
   754  
   755 @@ -16,6 +19,3 @@
   756  #if (PPC_NOP_LENGTH != BREAKPOINT_LENGTH)
   757  #error "Length of the breakpoint value not equal to the length of a nop instruction"
   758  #endif
   759 -
   760 -
   761 -#endif
   762 diff -durN ltrace-0.5.orig/testsuite/ltrace.minor/Makefile.in ltrace-0.5/testsuite/ltrace.minor/Makefile.in
   763 --- ltrace-0.5.orig/testsuite/ltrace.minor/Makefile.in	2006-03-14 00:12:01.000000000 +0100
   764 +++ ltrace-0.5/testsuite/ltrace.minor/Makefile.in	2008-11-04 19:25:50.000000000 +0100
   765 @@ -19,7 +19,7 @@
   766  
   767  .SUFFIXES:	
   768  clean:
   769 -	-rm -f demangle trace-fork trace-clone 
   770 +	-rm -f demangle trace-fork trace-clone trace-exec trace-exec1
   771  	-rm -f time-record-tt time-record-ttt time-record-T
   772  	-rm -f attach-process count-record
   773  	-rm -f print-instruction-pointer
   774 diff -durN ltrace-0.5.orig/testsuite/ltrace.minor/trace-clone.c ltrace-0.5/testsuite/ltrace.minor/trace-clone.c
   775 --- ltrace-0.5.orig/testsuite/ltrace.minor/trace-clone.c	2006-03-16 01:38:47.000000000 +0100
   776 +++ ltrace-0.5/testsuite/ltrace.minor/trace-clone.c	2008-11-04 19:25:50.000000000 +0100
   777 @@ -21,11 +21,11 @@
   778  int main ()
   779  {
   780    pid_t pid;
   781 -  static char stack[STACK_SIZE];
   782 +  char stack[STACK_SIZE];
   783  #ifdef __ia64__
   784    pid = __clone2((myfunc)&child, stack, STACK_SIZE, CLONE_FS, NULL);
   785  #else
   786 -  pid = clone((myfunc)&child, stack,CLONE_FS, NULL );
   787 +  pid = clone((myfunc)&child, stack + STACK_SIZE,CLONE_FS, NULL );
   788  #endif
   789    if (pid < 0)
   790      {
   791 diff -durN ltrace-0.5.orig/wait_for_something.c ltrace-0.5/wait_for_something.c
   792 --- ltrace-0.5.orig/wait_for_something.c	2006-02-20 22:48:07.000000000 +0100
   793 +++ ltrace-0.5/wait_for_something.c	2008-11-04 19:25:50.000000000 +0100
   794 @@ -71,6 +71,18 @@
   795  		event.thing = LT_EV_SYSRET;
   796  		event.e_un.sysnum = tmp;
   797  		return &event;
   798 +	case 3:
   799 +		event.thing = LT_EV_ARCH_SYSCALL;
   800 +		event.e_un.sysnum = tmp;
   801 +		return &event;
   802 +	case 4:
   803 +		event.thing = LT_EV_ARCH_SYSRET;
   804 +		event.e_un.sysnum = tmp;
   805 +		return &event;
   806 +	case -1:
   807 +		event.thing = LT_EV_NONE;
   808 +		continue_process(event.proc->pid);
   809 +		return &event;
   810  	}
   811  	if (WIFEXITED(status)) {
   812  		event.thing = LT_EV_EXIT;