Package: ltrace
Version: 0.5-3
Severity: important
User: [EMAIL PROTECTED]
Tags: patch
Registers used in function call arguments can be overwritten during the call
execution. This patch adds support for saving the first 5 registers so the
arguments can be printed correctly later. Idea borrowed from the SPARC port.
Changelog:
2008-01-25 Anderson Lizardo <[EMAIL PROTECTED]>
* sysdeps/linux-gnu/arm/trace.c, sysdeps/linux-gnu/arm/ptrace.h: save
function argument registers that may be overwritten during function
call.
--
Anderson Lizardo
Instituto Nokia de Tecnologia
Manaus - Brazil
Registers used in function call arguments can be overwritten during the call
execution. This patch adds support for saving the first 5 registers so the
arguments can be printed correctly later. Idea borrowed from the SPARC port.
Signed-off-by: Anderson Lizardo <[EMAIL PROTECTED]>
Signed-off-by: Bruna Moreira <[EMAIL PROTECTED]>
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:25.000000000 -0400
@@ -2,6 +2,7 @@
#include "config.h"
#endif
+#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
@@ -10,6 +11,7 @@
#include "ltrace.h"
#include "output.h"
+#include "ptrace.h"
#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
# define PTRACE_PEEKUSER PTRACE_PEEKUSR
@@ -26,6 +28,12 @@
void get_arch_dep(struct process *proc)
{
+ proc_archdep *a;
+
+ if (!proc->arch_ptr)
+ proc->arch_ptr = (void *)malloc(sizeof(proc_archdep));
+ a = (proc_archdep *) (proc->arch_ptr);
+ a->valid = (ptrace(PTRACE_GETREGS, proc->pid, 0, &a->regs) >= 0);
}
/* Returns 0 if not a syscall,
@@ -72,6 +80,8 @@ int syscall_p(struct process *proc, int
long gimme_arg(enum tof type, struct process *proc, int arg_num, arg_type_info *info)
{
+ proc_archdep *a = (proc_archdep *) proc->arch_ptr;
+
if (arg_num == -1) { /* return value */
return ptrace(PTRACE_PEEKUSER, proc->pid, off_r0, 0);
}
@@ -79,6 +89,10 @@ long gimme_arg(enum tof type, struct pro
/* deal with the ARM calling conventions */
if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
if (arg_num < 4) {
+ if (a->valid && type == LT_TOF_FUNCTION)
+ return a->regs.uregs[arg_num];
+ if (a->valid && type == LT_TOF_FUNCTIONR)
+ return a->func_arg[arg_num];
return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num,
0);
} else {
@@ -88,6 +102,10 @@ long gimme_arg(enum tof type, struct pro
}
} else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) {
if (arg_num < 5) {
+ if (a->valid && type == LT_TOF_SYSCALL)
+ return a->regs.uregs[arg_num];
+ if (a->valid && type == LT_TOF_SYSCALLR)
+ return a->sysc_arg[arg_num];
return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num,
0);
} else {
@@ -105,4 +123,11 @@ long gimme_arg(enum tof type, struct pro
void save_register_args(enum tof type, struct process *proc)
{
+ proc_archdep *a = (proc_archdep *) proc->arch_ptr;
+ if (a->valid) {
+ if (type == LT_TOF_FUNCTION)
+ memcpy(a->func_arg, a->regs.uregs, sizeof(a->func_arg));
+ else
+ memcpy(a->sysc_arg, a->regs.uregs, sizeof(a->sysc_arg));
+ }
}
Index: ltrace-indt/sysdeps/linux-gnu/arm/ptrace.h
===================================================================
--- ltrace-indt.orig/sysdeps/linux-gnu/arm/ptrace.h 2007-12-18 21:10:24.000000000 -0400
+++ ltrace-indt/sysdeps/linux-gnu/arm/ptrace.h 2007-12-18 21:10:25.000000000 -0400
@@ -1 +1,9 @@
#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+
+typedef struct {
+ int valid;
+ struct pt_regs regs;
+ long func_arg[5];
+ long sysc_arg[5];
+} proc_archdep;