diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arm/Gex_tables.c | 4 | ||||
-rw-r--r-- | src/arm/Gget_save_loc.c | 19 | ||||
-rw-r--r-- | src/arm/Ginit.c | 2 | ||||
-rw-r--r-- | src/arm/Gregs.c | 33 | ||||
-rw-r--r-- | src/arm/init.h | 19 |
5 files changed, 73 insertions, 4 deletions
diff --git a/src/arm/Gex_tables.c b/src/arm/Gex_tables.c index 083d2b2f..40cd1534 100644 --- a/src/arm/Gex_tables.c +++ b/src/arm/Gex_tables.c @@ -119,10 +119,12 @@ arm_exidx_apply_cmd (struct arm_exbuf_data *edata, struct dwarf_cursor *c) dwarf_get (c, c->loc[UNW_ARM_R13], &c->cfa); break; case ARM_EXIDX_CMD_VFP_POP: - /* Skip VFP registers, but be sure to adjust stack */ for (i = ARM_EXBUF_START (edata->data); i <= ARM_EXBUF_END (edata->data); i++) + { + c->loc[UNW_ARM_S0 + i] = DWARF_LOC (c->cfa, 0); c->cfa += 8; + } if (!(edata->data & ARM_EXIDX_VFP_DOUBLE)) c->cfa += 4; break; diff --git a/src/arm/Gget_save_loc.c b/src/arm/Gget_save_loc.c index 9fb07048..906c5b18 100644 --- a/src/arm/Gget_save_loc.c +++ b/src/arm/Gget_save_loc.c @@ -53,6 +53,25 @@ unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) loc = c->dwarf.loc[reg - UNW_ARM_R0]; break; + case UNW_ARM_D0: + case UNW_ARM_D1: + case UNW_ARM_D2: + case UNW_ARM_D3: + case UNW_ARM_D4: + case UNW_ARM_D5: + case UNW_ARM_D6: + case UNW_ARM_D7: + case UNW_ARM_D8: + case UNW_ARM_D9: + case UNW_ARM_D10: + case UNW_ARM_D11: + case UNW_ARM_D12: + case UNW_ARM_D13: + case UNW_ARM_D14: + case UNW_ARM_D15: + loc = c->dwarf.loc[UNW_ARM_S0 + (reg - UNW_ARM_D0)]; + break; + default: break; } diff --git a/src/arm/Ginit.c b/src/arm/Ginit.c index bce52dc3..680b2d47 100644 --- a/src/arm/Ginit.c +++ b/src/arm/Ginit.c @@ -43,6 +43,8 @@ uc_addr (unw_tdep_context_t *uc, int reg) { if (reg >= UNW_ARM_R0 && reg < UNW_ARM_R0 + 16) return &uc->regs[reg - UNW_ARM_R0]; + else if (reg >= UNW_ARM_D0 && reg <= UNW_ARM_D15) + return &uc->fpregs[reg - UNW_ARM_D0]; else return NULL; } diff --git a/src/arm/Gregs.c b/src/arm/Gregs.c index 0d52f0b2..30720631 100644 --- a/src/arm/Gregs.c +++ b/src/arm/Gregs.c @@ -78,6 +78,35 @@ HIDDEN int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, int write) { - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; + dwarf_loc_t loc = DWARF_NULL_LOC; + switch (reg) + { + case UNW_ARM_D0: + case UNW_ARM_D1: + case UNW_ARM_D2: + case UNW_ARM_D3: + case UNW_ARM_D4: + case UNW_ARM_D5: + case UNW_ARM_D6: + case UNW_ARM_D7: + case UNW_ARM_D8: + case UNW_ARM_D9: + case UNW_ARM_D10: + case UNW_ARM_D11: + case UNW_ARM_D12: + case UNW_ARM_D13: + case UNW_ARM_D14: + case UNW_ARM_D15: + loc = c->dwarf.loc[UNW_ARM_S0 + (reg - UNW_ARM_D0)]; + break; + + default: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_putfp (&c->dwarf, loc, *valp); + else + return dwarf_getfp (&c->dwarf, loc, valp); } diff --git a/src/arm/init.h b/src/arm/init.h index 7d765ecf..44cf7c22 100644 --- a/src/arm/init.h +++ b/src/arm/init.h @@ -45,7 +45,24 @@ common_init (struct cursor *c, unsigned use_prev_instr) c->dwarf.loc[UNW_ARM_R13] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R13); c->dwarf.loc[UNW_ARM_R14] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R14); c->dwarf.loc[UNW_ARM_R15] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_R15); - for (i = UNW_ARM_R15 + 1; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[UNW_ARM_S0] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_S0); + c->dwarf.loc[UNW_ARM_S1] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_S1); + c->dwarf.loc[UNW_ARM_S2] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_S2); + c->dwarf.loc[UNW_ARM_S3] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_S3); + c->dwarf.loc[UNW_ARM_S4] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_S4); + c->dwarf.loc[UNW_ARM_S5] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_S5); + c->dwarf.loc[UNW_ARM_S6] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_S6); + c->dwarf.loc[UNW_ARM_S7] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_S7); + c->dwarf.loc[UNW_ARM_S8] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_S8); + c->dwarf.loc[UNW_ARM_S9] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_S9); + c->dwarf.loc[UNW_ARM_S10] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_S10); + c->dwarf.loc[UNW_ARM_S11] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_S11); + c->dwarf.loc[UNW_ARM_S12] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_S12); + c->dwarf.loc[UNW_ARM_S13] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_S13); + c->dwarf.loc[UNW_ARM_S14] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_S14); + c->dwarf.loc[UNW_ARM_S15] = DWARF_REG_LOC (&c->dwarf, UNW_ARM_S15); + + for (i = UNW_ARM_S15 + 1; i < DWARF_NUM_PRESERVED_REGS; ++i) c->dwarf.loc[i] = DWARF_NULL_LOC; ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_ARM_R15], &c->dwarf.ip); |