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;