aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorPetr Machata <pmachata@redhat.com>2013-02-06 20:01:53 +0100
committerPetr Machata <pmachata@redhat.com>2013-03-12 00:08:53 +0100
commitf25af517a06521f69fbc53eaf3c245a7a2298c75 (patch)
tree67234374eb1632f7880ccfd4ef1321a1a96fb10f /sysdeps
parent8a7a9f59e75c8605ca8206294b7729d0fd70f11f (diff)
downloadltrace-f25af517a06521f69fbc53eaf3c245a7a2298c75.tar.gz
ARM cleanups
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/linux-gnu/arm/regs.c36
-rw-r--r--sysdeps/linux-gnu/arm/regs.h2
-rw-r--r--sysdeps/linux-gnu/arm/trace.c21
3 files changed, 34 insertions, 25 deletions
diff --git a/sysdeps/linux-gnu/arm/regs.c b/sysdeps/linux-gnu/arm/regs.c
index bd86370..e9e825e 100644
--- a/sysdeps/linux-gnu/arm/regs.c
+++ b/sysdeps/linux-gnu/arm/regs.c
@@ -39,9 +39,6 @@
# define PTRACE_POKEUSER PTRACE_POKEUSR
#endif
-#define off_pc ((void *)60)
-#define off_sp ((void *)52)
-
int
arm_get_register(struct process *proc, enum arm_register reg, uint32_t *lp)
{
@@ -54,6 +51,13 @@ arm_get_register(struct process *proc, enum arm_register reg, uint32_t *lp)
}
int
+arm_set_register(struct process *proc, enum arm_register reg, uint32_t lp)
+{
+ return ptrace(PTRACE_PEEKUSER, proc->pid,
+ (void *)(reg * 4L), (void *)lp);
+}
+
+int
arm_get_register_offpc(struct process *proc, enum arm_register reg,
uint32_t *lp)
{
@@ -116,36 +120,38 @@ arm_get_shifted_register(struct process *proc, uint32_t inst, int carry,
return 0;
}
-arch_addr_t
-get_instruction_pointer(struct process *proc)
+static arch_addr_t
+get_register_nocheck(struct process *proc, enum arm_register r)
{
uint32_t reg;
- if (arm_get_register(proc, ARM_REG_PC, &reg) < 0)
+ if (arm_get_register(proc, r, &reg) < 0)
/* XXX double cast. */
return (arch_addr_t)-1;
/* XXX double cast. */
return (arch_addr_t)(uintptr_t)reg;
}
+arch_addr_t
+get_instruction_pointer(struct process *proc)
+{
+ return get_register_nocheck(proc, ARM_REG_PC);
+}
+
void
-set_instruction_pointer(struct process *proc, void *addr)
+set_instruction_pointer(struct process *proc, arch_addr_t addr)
{
- ptrace(PTRACE_POKEUSER, proc->pid, off_pc, addr);
+ /* XXX double cast. */
+ arm_set_register(proc, ARM_REG_PC, (uint32_t)addr);
}
void *
get_stack_pointer(struct process *proc)
{
- return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_sp, 0);
+ return get_register_nocheck(proc, ARM_REG_SP);
}
arch_addr_t
get_return_addr(struct process *proc, arch_addr_t stack_pointer)
{
- uint32_t reg;
- if (arm_get_register(proc, ARM_REG_LR, &reg) < 0)
- /* XXX double cast. */
- return (arch_addr_t)-1;
- /* XXX double cast. */
- return (arch_addr_t)(uintptr_t)reg;
+ return get_register_nocheck(proc, ARM_REG_LR);
}
diff --git a/sysdeps/linux-gnu/arm/regs.h b/sysdeps/linux-gnu/arm/regs.h
index 1566f92..f9a5a86 100644
--- a/sysdeps/linux-gnu/arm/regs.h
+++ b/sysdeps/linux-gnu/arm/regs.h
@@ -25,6 +25,8 @@
((long) (BITS(obj,st,fn) | ((long) BIT(obj,fn) * ~ SUBMASK(fn - st))))
enum arm_register {
+ ARM_REG_R7 = 7,
+ ARM_REG_IP = 12,
ARM_REG_SP = 13,
ARM_REG_LR = 14,
ARM_REG_PC = 15,
diff --git a/sysdeps/linux-gnu/arm/trace.c b/sysdeps/linux-gnu/arm/trace.c
index a4d82ac..5e51e91 100644
--- a/sysdeps/linux-gnu/arm/trace.c
+++ b/sysdeps/linux-gnu/arm/trace.c
@@ -35,6 +35,7 @@
#include "output.h"
#include "ptrace.h"
#include "regs.h"
+#include "type.h"
#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
# define PTRACE_PEEKUSER PTRACE_PEEKUSR
@@ -44,12 +45,6 @@
# define PTRACE_POKEUSER PTRACE_POKEUSR
#endif
-#define off_r0 ((void *)0)
-#define off_r7 ((void *)28)
-#define off_ip ((void *)48)
-#define off_pc ((void *)60)
-#define off_cpsr ((void *)64)
-
void
get_arch_dep(struct process *proc)
{
@@ -71,18 +66,24 @@ syscall_p(struct process *proc, int status, int *sysnum)
{
if (WIFSTOPPED(status)
&& WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
- /* get the user's pc (plus 8) */
- unsigned pc = ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0);
+ uint32_t pc, ip;
+ if (arm_get_register(proc, ARM_REG_PC, &pc) < 0
+ || arm_get_register(proc, ARM_REG_IP, &ip) < 0)
+ return -1;
+
pc = pc - 4;
+
/* fetch the SWI instruction */
unsigned insn = ptrace(PTRACE_PEEKTEXT, proc->pid,
(void *)pc, 0);
- int ip = ptrace(PTRACE_PEEKUSER, proc->pid, off_ip, 0);
if (insn == 0xef000000 || insn == 0x0f000000
|| (insn & 0xffff0000) == 0xdf000000) {
/* EABI syscall */
- *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, off_r7, 0);
+ uint32_t r7;
+ if (arm_get_register(proc, ARM_REG_R7, &r7) < 0)
+ return -1;
+ *sysnum = r7;
} else if ((insn & 0xfff00000) == 0xef900000) {
/* old ABI syscall */
*sysnum = insn & 0xfffff;