Tags: patch

Changelog:

2008-01-25  Anderson Lizardo  <[EMAIL PROTECTED]>
        * sysdeps/linux-gnu/arm/trace.c: add ARM EABI support.

-- 
Anderson Lizardo
Instituto Nokia de Tecnologia
Manaus - Brazil
ARM EABI fixes:

* Modify breakpoint value to an undefined instruction so that breakpoints work
  on "pure" EABI systems.
* Force Makefile to look into "linux-gnu" directory instead of "linux-gnueabi".
* Add EABI syscall detection to syscall_p() and add proper error handling for
  unexpected swi instruction variations.

Signed-off-by: Anderson Lizardo <[EMAIL PROTECTED]>
Signed-off-by: Bruna Moreira <[EMAIL PROTECTED]>

Index: ltrace-indt/sysdeps/linux-gnu/arm/arch.h
===================================================================
--- ltrace-indt.orig/sysdeps/linux-gnu/arm/arch.h	2007-12-18 21:10:24.000000000 -0400
+++ ltrace-indt/sysdeps/linux-gnu/arm/arch.h	2007-12-18 21:10:24.000000000 -0400
@@ -1,4 +1,4 @@
-#define BREAKPOINT_VALUE { 0x01, 0x00, 0x9f, 0xef }
+#define BREAKPOINT_VALUE { 0xf0, 0x01, 0xf0, 0xe7 }
 #define BREAKPOINT_LENGTH 4
 #define DECR_PC_AFTER_BREAK 0
 
Index: ltrace-indt/Makefile.in
===================================================================
--- ltrace-indt.orig/Makefile.in	2007-12-18 21:10:24.000000000 -0400
+++ ltrace-indt/Makefile.in	2007-12-18 21:10:24.000000000 -0400
@@ -5,6 +5,10 @@
 #OS		:= $(shell uname -s)
 OS		:= @HOST_OS@
 
+ifeq ($(OS),linux-gnueabi)
+OS = linux-gnu
+endif
+
 TOPDIR		= $(shell pwd)
 
 prefix		= @prefix@
Index: ltrace-indt/sysdeps/linux-gnu/arm/trace.c
===================================================================
--- ltrace-indt.orig/sysdeps/linux-gnu/arm/trace.c	2007-12-18 21:10:24.000000000 -0400
+++ ltrace-indt/sysdeps/linux-gnu/arm/trace.c	2007-12-18 21:10:24.000000000 -0400
@@ -9,6 +9,7 @@
 #include <asm/ptrace.h>
 
 #include "ltrace.h"
+#include "output.h"
 
 #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
 # define PTRACE_PEEKUSER PTRACE_PEEKUSR
@@ -18,11 +19,8 @@
 # define PTRACE_POKEUSER PTRACE_POKEUSR
 #endif
 
-/* syscall tracing protocol: ArmLinux
- on the way in, ip is 0
- on the way out, ip is non-zero
-*/
 #define off_r0 0
+#define off_r7 28
 #define off_ip 48
 #define off_pc 60
 
@@ -30,7 +28,7 @@ void get_arch_dep(struct process *proc)
 {
 }
 
-/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
+/* Returns 0 if not a syscall, 1 if syscall entry, 2 if syscall exit, -1 on error.
  */
 int syscall_p(struct process *proc, int status, int *sysnum)
 {
@@ -40,13 +38,26 @@ int syscall_p(struct process *proc, int 
 		int pc = ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0);
 		/* fetch the SWI instruction */
 		int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 4, 0);
+		int ip = ptrace(PTRACE_PEEKUSER, proc->pid, off_ip, 0);
 
-		*sysnum = insn & 0xFFFF;
-		/* if it is a syscall, return 1 or 2 */
-		if ((insn & 0xFFFF0000) == 0xef900000) {
-			return ptrace(PTRACE_PEEKUSER, proc->pid, off_ip,
-				      0) ? 2 : 1;
+		if (insn == 0xef000000 || insn == 0x0f000000) {
+			/* EABI syscall */
+			*sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, off_r7, 0);
+		} else if ((insn & 0xfff00000) == 0xef900000) {
+			/* old ABI syscall */
+			*sysnum = insn & 0xfffff;
+		} else {
+			/* TODO: handle swi<cond> variations */
+			/* one possible reason for getting in here is that we
+			 * are coming from a signal handler, so the current
+			 * PC does not point to the instruction just after the
+			 * "swi" one. */
+			output_line(proc, "unexpected instruction 0x%x at %p", insn, pc - 4);
+			return -1;
 		}
+		/* ARM syscall convention: on syscall entry, ip is zero;
+		 * on syscall exit, ip is non-zero */
+		return ip ? 2 : 1;
 	}
 	return 0;
 }
Index: ltrace-indt/wait_for_something.c
===================================================================
--- ltrace-indt.orig/wait_for_something.c	2007-12-18 21:10:24.000000000 -0400
+++ ltrace-indt/wait_for_something.c	2007-12-18 21:10:24.000000000 -0400
@@ -72,6 +72,10 @@ struct event *wait_for_something(void)
 		event.thing = LT_EV_SYSRET;
 		event.e_un.sysnum = tmp;
 		return &event;
+	case -1:
+		event.thing = LT_EV_NONE;
+		continue_process(event.proc->pid);
+		return &event;
 	}
 	if (WIFEXITED(status)) {
 		event.thing = LT_EV_EXIT;

Reply via email to