Skip to content

Commit

Permalink
Apply libunwind changes from 1b5719c
Browse files Browse the repository at this point in the history
Co-authored-by: Jan Vorlicek <janvorli@microsoft.com>
  • Loading branch information
am11 and janvorli committed Dec 10, 2021
1 parent 6a946e7 commit 231b456
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 32 deletions.
58 changes: 30 additions & 28 deletions src/coreclr/pal/src/libunwind/include/libunwind-arm.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ unw_tdep_save_loc_t;
typedef struct unw_tdep_context
{
unsigned long regs[16];
unsigned long long fpregs[16];
}
unw_tdep_context_t;

Expand All @@ -273,36 +274,37 @@ unw_tdep_context_t;
In thumb mode, we return directly back to thumb mode on return (with bx), to
avoid altering any registers after unw_resume. */
#ifndef __thumb__
#define unw_tdep_getcontext(uc) ({ \
unw_tdep_context_t *unw_ctx = (uc); \
register unsigned long *r0 __asm__ ("r0"); \
unsigned long *unw_base = unw_ctx->regs; \
__asm__ __volatile__ ( \
"mov r0, #0\n" \
"stmia %[base], {r0-r15}\n" \
"nop\n" /* align return address to value stored by stmia */ \
: [r0] "=r" (r0) : [base] "r" (unw_base) : "memory"); \
#define unw_tdep_getcontext(uc) ({ \
unw_tdep_context_t *unw_ctx = (uc); \
register unsigned long *r0 __asm__ ("r0"); \
register unsigned long *unw_base __asm__ ("r1") = unw_ctx->regs; \
__asm__ __volatile__ ( \
"mov r0, #0\n" \
"stmia %[base]!, {r0-r15}\n" \
"vstmia %[base], {d0-d15}\n" /* this also aligns return address to value stored by stmia */ \
: [r0] "=r" (r0) : [base] "r" (unw_base) : "memory"); \
(int)r0; })
#else /* __thumb__ */
#define unw_tdep_getcontext(uc) ({ \
unw_tdep_context_t *unw_ctx = (uc); \
register unsigned long *r0 __asm__ ("r0"); \
unsigned long *unw_base = unw_ctx->regs; \
__asm__ __volatile__ ( \
".align 2\n" \
"bx pc\n" \
"nop\n" \
".code 32\n" \
"mov r0, #0\n" \
"stmia %[base], {r0-r14}\n" \
"adr r0, ret%=+1\n" \
"str r0, [%[base], #60]\n" \
"orr r0, pc, #1\n" \
"bx r0\n" \
".code 16\n" \
"mov r0, #0\n" \
"ret%=:\n" \
: [r0] "=r" (r0) : [base] "r" (unw_base) : "memory", "cc"); \
#define unw_tdep_getcontext(uc) ({ \
unw_tdep_context_t *unw_ctx = (uc); \
register unsigned long *r0 __asm__ ("r0"); \
register unsigned long *unw_base __asm__ ("r1") = unw_ctx->regs; \
__asm__ __volatile__ ( \
".align 2\n" \
"bx pc\n" \
"nop\n" \
".code 32\n" \
"mov r0, #0\n" \
"stmia %[base], {r0-r14}\n" \
"adr r0, ret%=+1\n" \
"stmia %[base]!, {r0}\n" \
"vstmia %[base], {d0-d15}\n" \
"orr r0, pc, #1\n" \
"bx r0\n" \
".code 16\n" \
"mov r0, #0\n" \
"ret%=:\n" \
: [r0] "=r" (r0) : [base] "r" (unw_base) : "memory", "cc"); \
(int)r0; })
#endif

Expand Down
4 changes: 3 additions & 1 deletion src/coreclr/pal/src/libunwind/src/arm/Gex_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
19 changes: 19 additions & 0 deletions src/coreclr/pal/src/libunwind/src/arm/Gget_save_loc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/pal/src/libunwind/src/arm/Ginit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
33 changes: 31 additions & 2 deletions src/coreclr/pal/src/libunwind/src/arm/Gregs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
19 changes: 18 additions & 1 deletion src/coreclr/pal/src/libunwind/src/arm/init.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 231b456

Please sign in to comment.