summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arm/Gex_tables.c4
-rw-r--r--src/arm/Gget_save_loc.c19
-rw-r--r--src/arm/Ginit.c2
-rw-r--r--src/arm/Gregs.c33
-rw-r--r--src/arm/init.h19
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);