summaryrefslogtreecommitdiffstats
path: root/debuggerd/arm
diff options
context:
space:
mode:
Diffstat (limited to 'debuggerd/arm')
-rw-r--r--debuggerd/arm/crashglue.S42
-rw-r--r--debuggerd/arm/machine.cpp136
2 files changed, 67 insertions, 111 deletions
diff --git a/debuggerd/arm/crashglue.S b/debuggerd/arm/crashglue.S
index eb9d0e3..4fbfd6e 100644
--- a/debuggerd/arm/crashglue.S
+++ b/debuggerd/arm/crashglue.S
@@ -1,8 +1,5 @@
.globl crash1
.type crash1, %function
-.globl crashnostack
-.type crashnostack, %function
-
crash1:
ldr r0, =0xa5a50000
ldr r1, =0xa5a50001
@@ -18,11 +15,48 @@ crash1:
ldr r11, =0xa5a50011
ldr r12, =0xa5a50012
+
+ fconstd d0, #0
+ fconstd d1, #1
+ fconstd d2, #2
+ fconstd d3, #3
+ fconstd d4, #4
+ fconstd d5, #5
+ fconstd d6, #6
+ fconstd d7, #7
+ fconstd d8, #8
+ fconstd d9, #9
+ fconstd d10, #10
+ fconstd d11, #11
+ fconstd d12, #12
+ fconstd d13, #13
+ fconstd d14, #14
+ fconstd d15, #15
+#if defined(HAS_VFP_D32)
+ fconstd d16, #16
+ fconstd d17, #17
+ fconstd d18, #18
+ fconstd d19, #19
+ fconstd d20, #20
+ fconstd d21, #21
+ fconstd d22, #22
+ fconstd d23, #23
+ fconstd d24, #24
+ fconstd d25, #25
+ fconstd d26, #26
+ fconstd d27, #27
+ fconstd d28, #28
+ fconstd d29, #29
+ fconstd d30, #30
+ fconstd d31, #31
+#endif
+
mov lr, #0
ldr lr, [lr]
b .
-
+.globl crashnostack
+.type crashnostack, %function
crashnostack:
mov sp, #0
mov r0, #0
diff --git a/debuggerd/arm/machine.cpp b/debuggerd/arm/machine.cpp
index 3fba6db..8270066 100644
--- a/debuggerd/arm/machine.cpp
+++ b/debuggerd/arm/machine.cpp
@@ -27,146 +27,68 @@
#include "../utility.h"
#include "../machine.h"
-// enable to dump memory pointed to by every register
-#define DUMP_MEMORY_FOR_ALL_REGISTERS 1
-
-#ifdef WITH_VFP
-#ifdef WITH_VFP_D32
-#define NUM_VFP_REGS 32
-#else
-#define NUM_VFP_REGS 16
-#endif
-#endif
-
-static void dump_memory(log_t* log, pid_t tid, uintptr_t addr, int scope_flags) {
- char code_buffer[64]; // actual 8+1+((8+1)*4) + 1 == 45
- char ascii_buffer[32]; // actual 16 + 1 == 17
- uintptr_t p, end;
-
- p = addr & ~3;
- p -= 32;
- if (p > addr) {
- // catch underflow
- p = 0;
- }
- // Dump more memory content for the crashing thread.
- end = p + 256;
- // catch overflow; 'end - p' has to be multiples of 16
- while (end < p)
- end -= 16;
-
- // Dump the code around PC as:
- // addr contents ascii
- // 00008d34 ef000000 e8bd0090 e1b00000 512fff1e ............../Q
- // 00008d44 ea00b1f9 e92d0090 e3a070fc ef000000 ......-..p......
- while (p < end) {
- char* asc_out = ascii_buffer;
-
- sprintf(code_buffer, "%08x ", p);
-
- int i;
- for (i = 0; i < 4; i++) {
- // If we see (data == -1 && errno != 0), we know that the ptrace
- // call failed, probably because we're dumping memory in an
- // unmapped or inaccessible page. I don't know if there's
- // value in making that explicit in the output -- it likely
- // just complicates parsing and clarifies nothing for the
- // enlightened reader.
- long data = ptrace(PTRACE_PEEKTEXT, tid, reinterpret_cast<void*>(p), NULL);
- sprintf(code_buffer + strlen(code_buffer), "%08lx ", data);
-
- // Enable the following code blob to dump ASCII values
-#if 0
- int j;
- for (j = 0; j < 4; j++) {
- // Our isprint() allows high-ASCII characters that display
- // differently (often badly) in different viewers, so we
- // just use a simpler test.
- char val = (data >> (j*8)) & 0xff;
- if (val >= 0x20 && val < 0x7f) {
- *asc_out++ = val;
- } else {
- *asc_out++ = '.';
- }
- }
-#endif
- p += 4;
- }
- *asc_out = '\0';
- _LOG(log, scope_flags, " %s %s\n", code_buffer, ascii_buffer);
- }
-}
-
-// If configured to do so, dump memory around *all* registers
-// for the crashing thread.
-void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) {
- struct pt_regs regs;
+void dump_memory_and_code(log_t* log, pid_t tid) {
+ pt_regs regs;
if (ptrace(PTRACE_GETREGS, tid, 0, &regs)) {
return;
}
- if (IS_AT_FAULT(scope_flags) && DUMP_MEMORY_FOR_ALL_REGISTERS) {
- static const char REG_NAMES[] = "r0r1r2r3r4r5r6r7r8r9slfpipsp";
+ static const char REG_NAMES[] = "r0r1r2r3r4r5r6r7r8r9slfpipsp";
- for (int reg = 0; reg < 14; reg++) {
- // this may not be a valid way to access, but it'll do for now
- uintptr_t addr = regs.uregs[reg];
+ for (int reg = 0; reg < 14; reg++) {
+ // this may not be a valid way to access, but it'll do for now
+ uintptr_t addr = regs.uregs[reg];
- // Don't bother if it looks like a small int or ~= null, or if
- // it's in the kernel area.
- if (addr < 4096 || addr >= 0xc0000000) {
- continue;
- }
-
- _LOG(log, scope_flags | SCOPE_SENSITIVE, "\nmemory near %.2s:\n", &REG_NAMES[reg * 2]);
- dump_memory(log, tid, addr, scope_flags | SCOPE_SENSITIVE);
+ // Don't bother if it looks like a small int or ~= null, or if
+ // it's in the kernel area.
+ if (addr < 4096 || addr >= 0xc0000000) {
+ continue;
}
+
+ _LOG(log, logtype::MEMORY, "\nmemory near %.2s:\n", &REG_NAMES[reg * 2]);
+ dump_memory(log, tid, addr);
}
// explicitly allow upload of code dump logging
- _LOG(log, scope_flags, "\ncode around pc:\n");
- dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_pc), scope_flags);
+ _LOG(log, logtype::MEMORY, "\ncode around pc:\n");
+ dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_pc));
if (regs.ARM_pc != regs.ARM_lr) {
- _LOG(log, scope_flags, "\ncode around lr:\n");
- dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_lr), scope_flags);
+ _LOG(log, logtype::MEMORY, "\ncode around lr:\n");
+ dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_lr));
}
}
-void dump_registers(log_t* log, pid_t tid, int scope_flags) {
- struct pt_regs r;
+void dump_registers(log_t* log, pid_t tid) {
+ pt_regs r;
if (ptrace(PTRACE_GETREGS, tid, 0, &r)) {
- _LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno));
+ _LOG(log, logtype::REGISTERS, "cannot get registers: %s\n", strerror(errno));
return;
}
- _LOG(log, scope_flags, " r0 %08x r1 %08x r2 %08x r3 %08x\n",
+ _LOG(log, logtype::REGISTERS, " r0 %08x r1 %08x r2 %08x r3 %08x\n",
static_cast<uint32_t>(r.ARM_r0), static_cast<uint32_t>(r.ARM_r1),
static_cast<uint32_t>(r.ARM_r2), static_cast<uint32_t>(r.ARM_r3));
- _LOG(log, scope_flags, " r4 %08x r5 %08x r6 %08x r7 %08x\n",
+ _LOG(log, logtype::REGISTERS, " r4 %08x r5 %08x r6 %08x r7 %08x\n",
static_cast<uint32_t>(r.ARM_r4), static_cast<uint32_t>(r.ARM_r5),
static_cast<uint32_t>(r.ARM_r6), static_cast<uint32_t>(r.ARM_r7));
- _LOG(log, scope_flags, " r8 %08x r9 %08x sl %08x fp %08x\n",
+ _LOG(log, logtype::REGISTERS, " r8 %08x r9 %08x sl %08x fp %08x\n",
static_cast<uint32_t>(r.ARM_r8), static_cast<uint32_t>(r.ARM_r9),
static_cast<uint32_t>(r.ARM_r10), static_cast<uint32_t>(r.ARM_fp));
- _LOG(log, scope_flags, " ip %08x sp %08x lr %08x pc %08x cpsr %08x\n",
+ _LOG(log, logtype::REGISTERS, " ip %08x sp %08x lr %08x pc %08x cpsr %08x\n",
static_cast<uint32_t>(r.ARM_ip), static_cast<uint32_t>(r.ARM_sp),
static_cast<uint32_t>(r.ARM_lr), static_cast<uint32_t>(r.ARM_pc),
static_cast<uint32_t>(r.ARM_cpsr));
-#ifdef WITH_VFP
- struct user_vfp vfp_regs;
- int i;
-
+ user_vfp vfp_regs;
if (ptrace(PTRACE_GETVFPREGS, tid, 0, &vfp_regs)) {
- _LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno));
+ _LOG(log, logtype::REGISTERS, "cannot get registers: %s\n", strerror(errno));
return;
}
- for (i = 0; i < NUM_VFP_REGS; i += 2) {
- _LOG(log, scope_flags, " d%-2d %016llx d%-2d %016llx\n",
+ for (size_t i = 0; i < 32; i += 2) {
+ _LOG(log, logtype::REGISTERS, " d%-2d %016llx d%-2d %016llx\n",
i, vfp_regs.fpregs[i], i+1, vfp_regs.fpregs[i+1]);
}
- _LOG(log, scope_flags, " scr %08lx\n", vfp_regs.fpscr);
-#endif
+ _LOG(log, logtype::REGISTERS, " scr %08lx\n", vfp_regs.fpscr);
}