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;