summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
authorandrew <andrew@FreeBSD.org>2013-06-27 22:26:56 +0000
committerandrew <andrew@FreeBSD.org>2013-06-27 22:26:56 +0000
commitb4606583056cfbefe7934774c4b8f98725c9b4a4 (patch)
treecfbf7259e48d36961fa176b39775d5fd130c4e8e /sys/arm
parentc1207dc20cfb10830a48d20d77f7a913d7a96029 (diff)
downloadFreeBSD-src-b4606583056cfbefe7934774c4b8f98725c9b4a4.zip
FreeBSD-src-b4606583056cfbefe7934774c4b8f98725c9b4a4.tar.gz
Support reading registers r0-r3 when unwinding. There is a seperate
instruction to load these. We only hit it when unwinding past an trap frame as in C r0-r3 would never have been saved onto the stack.
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/arm/db_trace.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/sys/arm/arm/db_trace.c b/sys/arm/arm/db_trace.c
index 7f16028..6b72cde 100644
--- a/sys/arm/arm/db_trace.c
+++ b/sys/arm/arm/db_trace.c
@@ -108,6 +108,7 @@ extern int extab_start, extab_end, exidx_start, exidx_end;
#define INSN_VSP_REG 0x90
#define INSN_POP_COUNT 0xa0
#define INSN_FINISH 0xb0
+#define INSN_POP_REGS 0xb1
#define INSN_VSP_LARGE_INC 0xb2
/* An item in the exception index table */
@@ -268,6 +269,24 @@ db_unwind_exec_insn(struct unwind_state *state)
/* Stop processing */
state->entries = 0;
+ } else if ((insn == INSN_POP_REGS)) {
+ unsigned int mask, reg;
+
+ mask = db_unwind_exec_read_byte(state);
+ if (mask == 0 || (mask & 0xf0) != 0)
+ return 1;
+
+ /* Update SP */
+ update_vsp = 1;
+
+ /* Load the registers */
+ for (reg = 0; mask && reg < 4; mask >>= 1, reg++) {
+ if (mask & 1) {
+ state->registers[reg] = *vsp++;
+ state->update_mask |= 1 << reg;
+ }
+ }
+
} else if ((insn & INSN_VSP_LARGE_INC_MASK) == INSN_VSP_LARGE_INC) {
unsigned int uleb128;
OpenPOWER on IntegriCloud