diff options
author | andrew <andrew@FreeBSD.org> | 2013-06-27 22:26:56 +0000 |
---|---|---|
committer | andrew <andrew@FreeBSD.org> | 2013-06-27 22:26:56 +0000 |
commit | b4606583056cfbefe7934774c4b8f98725c9b4a4 (patch) | |
tree | cfbf7259e48d36961fa176b39775d5fd130c4e8e /sys/arm | |
parent | c1207dc20cfb10830a48d20d77f7a913d7a96029 (diff) | |
download | FreeBSD-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.c | 19 |
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; |