diff options
Diffstat (limited to 'src/dwarf/Gparser.c')
-rw-r--r-- | src/dwarf/Gparser.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/src/dwarf/Gparser.c b/src/dwarf/Gparser.c index da170d4b..70a62c50 100644 --- a/src/dwarf/Gparser.c +++ b/src/dwarf/Gparser.c @@ -508,6 +508,9 @@ setup_fde (struct dwarf_cursor *c, dwarf_state_record_t *sr) for (i = 0; i < DWARF_NUM_PRESERVED_REGS + 2; ++i) set_reg (sr, i, DWARF_WHERE_SAME, 0); + // SP defaults to CFA (but is overridable) + set_reg (sr, TDEP_DWARF_SP, DWARF_WHERE_CFA, 0); + struct dwarf_cie_info *dci = c->pi.unwind_info; sr->rs_current.ret_addr_column = dci->ret_addr_column; unw_word_t addr = dci->cie_instr_start; @@ -792,14 +795,14 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) /* As a special-case, if the stack-pointer is the CFA and the stack-pointer wasn't saved, popping the CFA implicitly pops the stack-pointer as well. */ - if ((rs->reg.val[DWARF_CFA_REG_COLUMN] == UNW_TDEP_SP) - && (UNW_TDEP_SP < ARRAY_SIZE(rs->reg.val)) - && (rs->reg.where[UNW_TDEP_SP] == DWARF_WHERE_SAME)) + if ((rs->reg.val[DWARF_CFA_REG_COLUMN] == TDEP_DWARF_SP) + && (TDEP_DWARF_SP < ARRAY_SIZE(rs->reg.val)) + && (DWARF_IS_NULL_LOC(c->loc[TDEP_DWARF_SP]))) cfa = c->cfa; else { regnum = dwarf_to_unw_regnum (rs->reg.val[DWARF_CFA_REG_COLUMN]); - if ((ret = unw_get_reg ((unw_cursor_t *) c, regnum, &cfa)) < 0) + if ((ret = unw_get_reg (dwarf_to_cursor(c), regnum, &cfa)) < 0) return ret; } cfa += rs->reg.val[DWARF_CFA_OFF_COLUMN]; @@ -836,6 +839,10 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) case DWARF_WHERE_SAME: break; + case DWARF_WHERE_CFA: + new_loc[i] = DWARF_VAL_LOC (c, cfa); + break; + case DWARF_WHERE_CFAREL: new_loc[i] = DWARF_MEM_LOC (c, cfa + rs->reg.val[i]); break; |