Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2013-08-23 19:52:34 +0000
committerEugene Tarassov2013-08-23 19:52:34 +0000
commit1bbb436cdf19d40441abafc2ff5f6f1e09db6502 (patch)
tree6f55ff1f0a60493978dd04d05535815b860cfad5
parentedf7bcb5bee0b187a51b1edc4a4466eb2a0ef6b4 (diff)
downloadorg.eclipse.tcf.agent-1bbb436cdf19d40441abafc2ff5f6f1e09db6502.tar.gz
org.eclipse.tcf.agent-1bbb436cdf19d40441abafc2ff5f6f1e09db6502.tar.xz
org.eclipse.tcf.agent-1bbb436cdf19d40441abafc2ff5f6f1e09db6502.zip
TCF Agent: ARM stack crawl: better handling of return from exception instructions
-rw-r--r--agent/machine/arm/tcf/stack-crawl-arm.c41
1 files changed, 23 insertions, 18 deletions
diff --git a/agent/machine/arm/tcf/stack-crawl-arm.c b/agent/machine/arm/tcf/stack-crawl-arm.c
index 52ce9308..91ae1508 100644
--- a/agent/machine/arm/tcf/stack-crawl-arm.c
+++ b/agent/machine/arm/tcf/stack-crawl-arm.c
@@ -866,6 +866,25 @@ static int is_data_processing_instr(uint32_t instr) {
return 1;
}
+static void return_from_exception(void) {
+ /* Return from exception - copies the SPSR to the CPSR */
+ RegisterDefinition * def;
+ for (def = get_reg_definitions(stk_ctx); def->name; def++) {
+ int r = is_banked_reg_visible(def, spsr_data.v & 0x1f);
+ if (r >= 0 && r != is_banked_reg_visible(def, cpsr_data.v & 0x1f)) {
+ uint64_t v = 0;
+ if (search_reg_value(stk_frame, def, &v) < 0) {
+ reg_data[r].o = 0;
+ }
+ else {
+ reg_data[r].v = (uint32_t)v;
+ reg_data[r].o = REG_VAL_OTHER;
+ }
+ }
+ }
+ cpsr_data = spsr_data;
+}
+
static int trace_arm_bx(uint32_t instr) {
uint8_t rn = instr & 0xf;
@@ -1403,22 +1422,7 @@ static void trace_arm_data_processing_instr(uint32_t instr) {
}
if (rd == 15 && (instr & (1 << 20)) != 0) {
- /* Return from exception - copies the SPSR to the CPSR */
- RegisterDefinition * def;
- for (def = get_reg_definitions(stk_ctx); def->name; def++) {
- int r = is_banked_reg_visible(def, spsr_data.v & 0x1f);
- if (r >= 0 && r != is_banked_reg_visible(def, cpsr_data.v & 0x1f)) {
- uint64_t v = 0;
- if (search_reg_value(stk_frame, def, &v) < 0) {
- reg_data[r].o = 0;
- }
- else {
- reg_data[r].v = (uint32_t)v;
- reg_data[r].o = REG_VAL_OTHER;
- }
- }
- }
- cpsr_data = spsr_data;
+ return_from_exception();
}
}
@@ -1433,6 +1437,7 @@ static int trace_arm_ldm_stm(uint32_t instr) {
uint16_t regs = (instr & 0x0000ffff);
uint32_t addr = 0;
int addr_valid = 0;
+ uint32_t rn_bank = cpsr_data.v & 0x1f;
unsigned banked = 0;
uint8_t r;
@@ -1446,7 +1451,7 @@ static int trace_arm_ldm_stm(uint32_t instr) {
*/
if (S) {
if (L && (regs & (1 << 15)) != 0) {
- cpsr_data = spsr_data;
+ return_from_exception();
}
else {
switch (cpsr_data.v & 0x1f) {
@@ -1516,7 +1521,7 @@ static int trace_arm_ldm_stm(uint32_t instr) {
}
/* Check the writeback bit */
- if (addr_valid && W) {
+ if (addr_valid && W && rn_bank == (cpsr_data.v & 0x1f)) {
reg_data[rn].o = cond == 14 ? REG_VAL_OTHER : 0;
reg_data[rn].v = addr;
}

Back to the top