mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2025-04-03 20:42:17 +02:00
Leave ret_addr_column out of the data that gets copied when pushing/popping
data on/off the register state stack.
This commit is contained in:
parent
c66661f73c
commit
27f5f9fa0b
6 changed files with 125 additions and 117 deletions
include
src
tests
|
@ -249,18 +249,24 @@ dwarf_where_t;
|
||||||
#define DWARF_CFA_REG_COLUMN DWARF_NUM_PRESERVED_REGS
|
#define DWARF_CFA_REG_COLUMN DWARF_NUM_PRESERVED_REGS
|
||||||
#define DWARF_CFA_OFF_COLUMN (DWARF_NUM_PRESERVED_REGS + 1)
|
#define DWARF_CFA_OFF_COLUMN (DWARF_NUM_PRESERVED_REGS + 1)
|
||||||
|
|
||||||
|
typedef struct dwarf_reg_only_state
|
||||||
|
{
|
||||||
|
char where[DWARF_NUM_PRESERVED_REGS + 2]; /* how is the register saved? */
|
||||||
|
unw_word_t val[DWARF_NUM_PRESERVED_REGS + 2]; /* where it's saved */
|
||||||
|
}
|
||||||
|
dwarf_reg_only_state_t;
|
||||||
|
|
||||||
typedef struct dwarf_reg_state
|
typedef struct dwarf_reg_state
|
||||||
{
|
{
|
||||||
unw_word_t ret_addr_column; /* which column in rule table represents return address */
|
unw_word_t ret_addr_column; /* which column in rule table represents return address */
|
||||||
char where[DWARF_NUM_PRESERVED_REGS + 2]; /* how is the register saved? */
|
dwarf_reg_only_state_t reg;
|
||||||
unw_word_t val[DWARF_NUM_PRESERVED_REGS + 2]; /* where it's saved */
|
|
||||||
}
|
}
|
||||||
dwarf_reg_state_t;
|
dwarf_reg_state_t;
|
||||||
|
|
||||||
typedef struct dwarf_stackable_reg_state
|
typedef struct dwarf_stackable_reg_state
|
||||||
{
|
{
|
||||||
struct dwarf_stackable_reg_state *next; /* for rs_stack */
|
struct dwarf_stackable_reg_state *next; /* for rs_stack */
|
||||||
dwarf_reg_state_t state;
|
dwarf_reg_only_state_t state;
|
||||||
}
|
}
|
||||||
dwarf_stackable_reg_state_t;
|
dwarf_stackable_reg_state_t;
|
||||||
|
|
||||||
|
|
|
@ -36,13 +36,13 @@ tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs)
|
||||||
" ra=0x%lx fp [where=%d val=%ld @0x%lx] lr [where=%d val=%ld @0x%lx] "
|
" ra=0x%lx fp [where=%d val=%ld @0x%lx] lr [where=%d val=%ld @0x%lx] "
|
||||||
"sp [where=%d val=%ld @0x%lx]\n",
|
"sp [where=%d val=%ld @0x%lx]\n",
|
||||||
d->ip, d->cfa, f->frame_type,
|
d->ip, d->cfa, f->frame_type,
|
||||||
rs->where[DWARF_CFA_REG_COLUMN],
|
rs->reg.where[DWARF_CFA_REG_COLUMN],
|
||||||
rs->val[DWARF_CFA_REG_COLUMN],
|
rs->reg.val[DWARF_CFA_REG_COLUMN],
|
||||||
rs->val[DWARF_CFA_OFF_COLUMN],
|
rs->reg.val[DWARF_CFA_OFF_COLUMN],
|
||||||
DWARF_GET_LOC(d->loc[rs->ret_addr_column]),
|
DWARF_GET_LOC(d->loc[rs->ret_addr_column]),
|
||||||
rs->where[FP], rs->val[FP], DWARF_GET_LOC(d->loc[FP]),
|
rs->reg.where[FP], rs->reg.val[FP], DWARF_GET_LOC(d->loc[FP]),
|
||||||
rs->where[LR], rs->val[LR], DWARF_GET_LOC(d->loc[LR]),
|
rs->reg.where[LR], rs->reg.val[LR], DWARF_GET_LOC(d->loc[LR]),
|
||||||
rs->where[SP], rs->val[SP], DWARF_GET_LOC(d->loc[SP]));
|
rs->reg.where[SP], rs->reg.val[SP], DWARF_GET_LOC(d->loc[SP]));
|
||||||
|
|
||||||
/* A standard frame is defined as:
|
/* A standard frame is defined as:
|
||||||
- CFA is register-relative offset off FP or SP;
|
- CFA is register-relative offset off FP or SP;
|
||||||
|
@ -51,37 +51,37 @@ tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs)
|
||||||
- LR is unsaved or saved at CFA+offset, offset != -1;
|
- LR is unsaved or saved at CFA+offset, offset != -1;
|
||||||
- SP is unsaved or saved at CFA+offset, offset != -1. */
|
- SP is unsaved or saved at CFA+offset, offset != -1. */
|
||||||
if (f->frame_type == UNW_AARCH64_FRAME_OTHER
|
if (f->frame_type == UNW_AARCH64_FRAME_OTHER
|
||||||
&& (rs->where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_REG)
|
&& (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_REG)
|
||||||
&& (rs->val[DWARF_CFA_REG_COLUMN] == FP
|
&& (rs->reg.val[DWARF_CFA_REG_COLUMN] == FP
|
||||||
|| rs->val[DWARF_CFA_REG_COLUMN] == SP)
|
|| rs->reg.val[DWARF_CFA_REG_COLUMN] == SP)
|
||||||
&& labs(rs->val[DWARF_CFA_OFF_COLUMN]) < (1 << 29)
|
&& labs(rs->reg.val[DWARF_CFA_OFF_COLUMN]) < (1 << 29)
|
||||||
&& rs->ret_addr_column == LR
|
&& rs->ret_addr_column == LR
|
||||||
&& (rs->where[FP] == DWARF_WHERE_UNDEF
|
&& (rs->reg.where[FP] == DWARF_WHERE_UNDEF
|
||||||
|| rs->where[FP] == DWARF_WHERE_SAME
|
|| rs->reg.where[FP] == DWARF_WHERE_SAME
|
||||||
|| (rs->where[FP] == DWARF_WHERE_CFAREL
|
|| (rs->reg.where[FP] == DWARF_WHERE_CFAREL
|
||||||
&& labs(rs->val[FP]) < (1 << 29)
|
&& labs(rs->reg.val[FP]) < (1 << 29)
|
||||||
&& rs->val[FP]+1 != 0))
|
&& rs->reg.val[FP]+1 != 0))
|
||||||
&& (rs->where[LR] == DWARF_WHERE_UNDEF
|
&& (rs->reg.where[LR] == DWARF_WHERE_UNDEF
|
||||||
|| rs->where[LR] == DWARF_WHERE_SAME
|
|| rs->reg.where[LR] == DWARF_WHERE_SAME
|
||||||
|| (rs->where[LR] == DWARF_WHERE_CFAREL
|
|| (rs->reg.where[LR] == DWARF_WHERE_CFAREL
|
||||||
&& labs(rs->val[LR]) < (1 << 29)
|
&& labs(rs->reg.val[LR]) < (1 << 29)
|
||||||
&& rs->val[LR]+1 != 0))
|
&& rs->reg.val[LR]+1 != 0))
|
||||||
&& (rs->where[SP] == DWARF_WHERE_UNDEF
|
&& (rs->reg.where[SP] == DWARF_WHERE_UNDEF
|
||||||
|| rs->where[SP] == DWARF_WHERE_SAME
|
|| rs->reg.where[SP] == DWARF_WHERE_SAME
|
||||||
|| (rs->where[SP] == DWARF_WHERE_CFAREL
|
|| (rs->reg.where[SP] == DWARF_WHERE_CFAREL
|
||||||
&& labs(rs->val[SP]) < (1 << 29)
|
&& labs(rs->reg.val[SP]) < (1 << 29)
|
||||||
&& rs->val[SP]+1 != 0)))
|
&& rs->reg.val[SP]+1 != 0)))
|
||||||
{
|
{
|
||||||
/* Save information for a standard frame. */
|
/* Save information for a standard frame. */
|
||||||
f->frame_type = UNW_AARCH64_FRAME_STANDARD;
|
f->frame_type = UNW_AARCH64_FRAME_STANDARD;
|
||||||
f->cfa_reg_sp = (rs->val[DWARF_CFA_REG_COLUMN] == SP);
|
f->cfa_reg_sp = (rs->reg.val[DWARF_CFA_REG_COLUMN] == SP);
|
||||||
f->cfa_reg_offset = rs->val[DWARF_CFA_OFF_COLUMN];
|
f->cfa_reg_offset = rs->reg.val[DWARF_CFA_OFF_COLUMN];
|
||||||
if (rs->where[FP] == DWARF_WHERE_CFAREL)
|
if (rs->reg.where[FP] == DWARF_WHERE_CFAREL)
|
||||||
f->fp_cfa_offset = rs->val[FP];
|
f->fp_cfa_offset = rs->reg.val[FP];
|
||||||
if (rs->where[LR] == DWARF_WHERE_CFAREL)
|
if (rs->reg.where[LR] == DWARF_WHERE_CFAREL)
|
||||||
f->lr_cfa_offset = rs->val[LR];
|
f->lr_cfa_offset = rs->reg.val[LR];
|
||||||
if (rs->where[SP] == DWARF_WHERE_CFAREL)
|
if (rs->reg.where[SP] == DWARF_WHERE_CFAREL)
|
||||||
f->sp_cfa_offset = rs->val[SP];
|
f->sp_cfa_offset = rs->reg.val[SP];
|
||||||
Debug (4, " standard frame\n");
|
Debug (4, " standard frame\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -36,13 +36,13 @@ tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs)
|
||||||
" ra=0x%x r7 [where=%d val=%d @0x%x] lr [where=%d val=%d @0x%x] "
|
" ra=0x%x r7 [where=%d val=%d @0x%x] lr [where=%d val=%d @0x%x] "
|
||||||
"sp [where=%d val=%d @0x%x]\n",
|
"sp [where=%d val=%d @0x%x]\n",
|
||||||
d->ip, d->cfa, f->frame_type,
|
d->ip, d->cfa, f->frame_type,
|
||||||
rs->where[DWARF_CFA_REG_COLUMN],
|
rs->reg.where[DWARF_CFA_REG_COLUMN],
|
||||||
rs->val[DWARF_CFA_REG_COLUMN],
|
rs->reg.val[DWARF_CFA_REG_COLUMN],
|
||||||
rs->val[DWARF_CFA_OFF_COLUMN],
|
rs->reg.val[DWARF_CFA_OFF_COLUMN],
|
||||||
DWARF_GET_LOC(d->loc[rs->ret_addr_column]),
|
DWARF_GET_LOC(d->loc[rs->ret_addr_column]),
|
||||||
rs->where[R7], rs->val[R7], DWARF_GET_LOC(d->loc[R7]),
|
rs->reg.where[R7], rs->reg.val[R7], DWARF_GET_LOC(d->loc[R7]),
|
||||||
rs->where[LR], rs->val[LR], DWARF_GET_LOC(d->loc[LR]),
|
rs->reg.where[LR], rs->reg.val[LR], DWARF_GET_LOC(d->loc[LR]),
|
||||||
rs->where[SP], rs->val[SP], DWARF_GET_LOC(d->loc[SP]));
|
rs->reg.where[SP], rs->reg.val[SP], DWARF_GET_LOC(d->loc[SP]));
|
||||||
|
|
||||||
/* A standard frame is defined as:
|
/* A standard frame is defined as:
|
||||||
- CFA is register-relative offset off R7 or SP;
|
- CFA is register-relative offset off R7 or SP;
|
||||||
|
@ -51,37 +51,37 @@ tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs)
|
||||||
- LR is unsaved or saved at CFA+offset, offset != -1;
|
- LR is unsaved or saved at CFA+offset, offset != -1;
|
||||||
- SP is unsaved or saved at CFA+offset, offset != -1. */
|
- SP is unsaved or saved at CFA+offset, offset != -1. */
|
||||||
if (f->frame_type == UNW_ARM_FRAME_OTHER
|
if (f->frame_type == UNW_ARM_FRAME_OTHER
|
||||||
&& (rs->where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_REG)
|
&& (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_REG)
|
||||||
&& (rs->val[DWARF_CFA_REG_COLUMN] == R7
|
&& (rs->reg.val[DWARF_CFA_REG_COLUMN] == R7
|
||||||
|| rs->val[DWARF_CFA_REG_COLUMN] == SP)
|
|| rs->reg.val[DWARF_CFA_REG_COLUMN] == SP)
|
||||||
&& labs(rs->val[DWARF_CFA_OFF_COLUMN]) < (1 << 29)
|
&& labs(rs->reg.val[DWARF_CFA_OFF_COLUMN]) < (1 << 29)
|
||||||
&& rs->ret_addr_column == LR
|
&& rs->ret_addr_column == LR
|
||||||
&& (rs->where[R7] == DWARF_WHERE_UNDEF
|
&& (rs->reg.where[R7] == DWARF_WHERE_UNDEF
|
||||||
|| rs->where[R7] == DWARF_WHERE_SAME
|
|| rs->reg.where[R7] == DWARF_WHERE_SAME
|
||||||
|| (rs->where[R7] == DWARF_WHERE_CFAREL
|
|| (rs->reg.where[R7] == DWARF_WHERE_CFAREL
|
||||||
&& labs(rs->val[R7]) < (1 << 29)
|
&& labs(rs->reg.val[R7]) < (1 << 29)
|
||||||
&& rs->val[R7]+1 != 0))
|
&& rs->reg.val[R7]+1 != 0))
|
||||||
&& (rs->where[LR] == DWARF_WHERE_UNDEF
|
&& (rs->reg.where[LR] == DWARF_WHERE_UNDEF
|
||||||
|| rs->where[LR] == DWARF_WHERE_SAME
|
|| rs->reg.where[LR] == DWARF_WHERE_SAME
|
||||||
|| (rs->where[LR] == DWARF_WHERE_CFAREL
|
|| (rs->reg.where[LR] == DWARF_WHERE_CFAREL
|
||||||
&& labs(rs->val[LR]) < (1 << 29)
|
&& labs(rs->reg.val[LR]) < (1 << 29)
|
||||||
&& rs->val[LR]+1 != 0))
|
&& rs->reg.val[LR]+1 != 0))
|
||||||
&& (rs->where[SP] == DWARF_WHERE_UNDEF
|
&& (rs->reg.where[SP] == DWARF_WHERE_UNDEF
|
||||||
|| rs->where[SP] == DWARF_WHERE_SAME
|
|| rs->reg.where[SP] == DWARF_WHERE_SAME
|
||||||
|| (rs->where[SP] == DWARF_WHERE_CFAREL
|
|| (rs->reg.where[SP] == DWARF_WHERE_CFAREL
|
||||||
&& labs(rs->val[SP]) < (1 << 29)
|
&& labs(rs->reg.val[SP]) < (1 << 29)
|
||||||
&& rs->val[SP]+1 != 0)))
|
&& rs->reg.val[SP]+1 != 0)))
|
||||||
{
|
{
|
||||||
/* Save information for a standard frame. */
|
/* Save information for a standard frame. */
|
||||||
f->frame_type = UNW_ARM_FRAME_STANDARD;
|
f->frame_type = UNW_ARM_FRAME_STANDARD;
|
||||||
f->cfa_reg_sp = (rs->val[DWARF_CFA_REG_COLUMN] == SP);
|
f->cfa_reg_sp = (rs->reg.val[DWARF_CFA_REG_COLUMN] == SP);
|
||||||
f->cfa_reg_offset = rs->val[DWARF_CFA_OFF_COLUMN];
|
f->cfa_reg_offset = rs->reg.val[DWARF_CFA_OFF_COLUMN];
|
||||||
if (rs->where[R7] == DWARF_WHERE_CFAREL)
|
if (rs->reg.where[R7] == DWARF_WHERE_CFAREL)
|
||||||
f->r7_cfa_offset = rs->val[R7];
|
f->r7_cfa_offset = rs->reg.val[R7];
|
||||||
if (rs->where[LR] == DWARF_WHERE_CFAREL)
|
if (rs->reg.where[LR] == DWARF_WHERE_CFAREL)
|
||||||
f->lr_cfa_offset = rs->val[LR];
|
f->lr_cfa_offset = rs->reg.val[LR];
|
||||||
if (rs->where[SP] == DWARF_WHERE_CFAREL)
|
if (rs->reg.where[SP] == DWARF_WHERE_CFAREL)
|
||||||
f->sp_cfa_offset = rs->val[SP];
|
f->sp_cfa_offset = rs->reg.val[SP];
|
||||||
Debug (4, " standard frame\n");
|
Debug (4, " standard frame\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -55,8 +55,8 @@ static inline void
|
||||||
set_reg (dwarf_state_record_t *sr, unw_word_t regnum, dwarf_where_t where,
|
set_reg (dwarf_state_record_t *sr, unw_word_t regnum, dwarf_where_t where,
|
||||||
unw_word_t val)
|
unw_word_t val)
|
||||||
{
|
{
|
||||||
sr->rs_current.where[regnum] = where;
|
sr->rs_current.reg.where[regnum] = where;
|
||||||
sr->rs_current.val[regnum] = val;
|
sr->rs_current.reg.val[regnum] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
|
@ -218,8 +218,8 @@ run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr,
|
||||||
ret = -UNW_EINVAL;
|
ret = -UNW_EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sr->rs_current.where[regnum] = sr->rs_initial.where[regnum];
|
sr->rs_current.reg.where[regnum] = sr->rs_initial.reg.where[regnum];
|
||||||
sr->rs_current.val[regnum] = sr->rs_initial.val[regnum];
|
sr->rs_current.reg.val[regnum] = sr->rs_initial.reg.val[regnum];
|
||||||
Debug (15, "CFA_restore r%lu\n", (long) regnum);
|
Debug (15, "CFA_restore r%lu\n", (long) regnum);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -233,8 +233,8 @@ run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr,
|
||||||
ret = -UNW_EINVAL;
|
ret = -UNW_EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sr->rs_current.where[regnum] = sr->rs_initial.where[regnum];
|
sr->rs_current.reg.where[regnum] = sr->rs_initial.reg.where[regnum];
|
||||||
sr->rs_current.val[regnum] = sr->rs_initial.val[regnum];
|
sr->rs_current.reg.val[regnum] = sr->rs_initial.reg.val[regnum];
|
||||||
Debug (15, "CFA_restore_extended r%lu\n", (long) regnum);
|
Debug (15, "CFA_restore_extended r%lu\n", (long) regnum);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -785,32 +785,32 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs)
|
||||||
/* Evaluate the CFA first, because it may be referred to by other
|
/* Evaluate the CFA first, because it may be referred to by other
|
||||||
expressions. */
|
expressions. */
|
||||||
|
|
||||||
if (rs->where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_REG)
|
if (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_REG)
|
||||||
{
|
{
|
||||||
/* CFA is equal to [reg] + offset: */
|
/* CFA is equal to [reg] + offset: */
|
||||||
|
|
||||||
/* As a special-case, if the stack-pointer is the CFA and the
|
/* As a special-case, if the stack-pointer is the CFA and the
|
||||||
stack-pointer wasn't saved, popping the CFA implicitly pops
|
stack-pointer wasn't saved, popping the CFA implicitly pops
|
||||||
the stack-pointer as well. */
|
the stack-pointer as well. */
|
||||||
if ((rs->val[DWARF_CFA_REG_COLUMN] == UNW_TDEP_SP)
|
if ((rs->reg.val[DWARF_CFA_REG_COLUMN] == UNW_TDEP_SP)
|
||||||
&& (UNW_TDEP_SP < ARRAY_SIZE(rs->val))
|
&& (UNW_TDEP_SP < ARRAY_SIZE(rs->reg.val))
|
||||||
&& (rs->where[UNW_TDEP_SP] == DWARF_WHERE_SAME))
|
&& (rs->reg.where[UNW_TDEP_SP] == DWARF_WHERE_SAME))
|
||||||
cfa = c->cfa;
|
cfa = c->cfa;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
regnum = dwarf_to_unw_regnum (rs->val[DWARF_CFA_REG_COLUMN]);
|
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 ((unw_cursor_t *) c, regnum, &cfa)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
cfa += rs->val[DWARF_CFA_OFF_COLUMN];
|
cfa += rs->reg.val[DWARF_CFA_OFF_COLUMN];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* CFA is equal to EXPR: */
|
/* CFA is equal to EXPR: */
|
||||||
|
|
||||||
assert (rs->where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_EXPR);
|
assert (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_EXPR);
|
||||||
|
|
||||||
addr = rs->val[DWARF_CFA_REG_COLUMN];
|
addr = rs->reg.val[DWARF_CFA_REG_COLUMN];
|
||||||
if ((ret = eval_location_expr (c, as, a, addr, &cfa_loc, arg)) < 0)
|
if ((ret = eval_location_expr (c, as, a, addr, &cfa_loc, arg)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
/* the returned location better be a memory location... */
|
/* the returned location better be a memory location... */
|
||||||
|
@ -821,7 +821,7 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs)
|
||||||
|
|
||||||
for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
|
for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
|
||||||
{
|
{
|
||||||
switch ((dwarf_where_t) rs->where[i])
|
switch ((dwarf_where_t) rs->reg.where[i])
|
||||||
{
|
{
|
||||||
case DWARF_WHERE_UNDEF:
|
case DWARF_WHERE_UNDEF:
|
||||||
c->loc[i] = DWARF_NULL_LOC;
|
c->loc[i] = DWARF_NULL_LOC;
|
||||||
|
@ -831,21 +831,21 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DWARF_WHERE_CFAREL:
|
case DWARF_WHERE_CFAREL:
|
||||||
c->loc[i] = DWARF_MEM_LOC (c, cfa + rs->val[i]);
|
c->loc[i] = DWARF_MEM_LOC (c, cfa + rs->reg.val[i]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DWARF_WHERE_REG:
|
case DWARF_WHERE_REG:
|
||||||
c->loc[i] = DWARF_REG_LOC (c, dwarf_to_unw_regnum (rs->val[i]));
|
c->loc[i] = DWARF_REG_LOC (c, dwarf_to_unw_regnum (rs->reg.val[i]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DWARF_WHERE_EXPR:
|
case DWARF_WHERE_EXPR:
|
||||||
addr = rs->val[i];
|
addr = rs->reg.val[i];
|
||||||
if ((ret = eval_location_expr (c, as, a, addr, c->loc + i, arg)) < 0)
|
if ((ret = eval_location_expr (c, as, a, addr, c->loc + i, arg)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DWARF_WHERE_VAL_EXPR:
|
case DWARF_WHERE_VAL_EXPR:
|
||||||
addr = rs->val[i];
|
addr = rs->reg.val[i];
|
||||||
if ((ret = eval_location_expr (c, as, a, addr, c->loc + i, arg)) < 0)
|
if ((ret = eval_location_expr (c, as, a, addr, c->loc + i, arg)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
c->loc[i] = DWARF_VAL_LOC (c, DWARF_GET_LOC (c->loc[i]));
|
c->loc[i] = DWARF_VAL_LOC (c, DWARF_GET_LOC (c->loc[i]));
|
||||||
|
|
|
@ -34,20 +34,20 @@ tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs)
|
||||||
Debug (4, "ip=0x%lx cfa=0x%lx type %d cfa [where=%d val=%ld] cfaoff=%ld"
|
Debug (4, "ip=0x%lx cfa=0x%lx type %d cfa [where=%d val=%ld] cfaoff=%ld"
|
||||||
" ra=0x%lx rbp [where=%d val=%ld @0x%lx] rsp [where=%d val=%ld @0x%lx]\n",
|
" ra=0x%lx rbp [where=%d val=%ld @0x%lx] rsp [where=%d val=%ld @0x%lx]\n",
|
||||||
d->ip, d->cfa, f->frame_type,
|
d->ip, d->cfa, f->frame_type,
|
||||||
rs->where[DWARF_CFA_REG_COLUMN],
|
rs->reg.where[DWARF_CFA_REG_COLUMN],
|
||||||
rs->val[DWARF_CFA_REG_COLUMN],
|
rs->reg.val[DWARF_CFA_REG_COLUMN],
|
||||||
rs->val[DWARF_CFA_OFF_COLUMN],
|
rs->reg.val[DWARF_CFA_OFF_COLUMN],
|
||||||
DWARF_GET_LOC(d->loc[rs->ret_addr_column]),
|
DWARF_GET_LOC(d->loc[rs->ret_addr_column]),
|
||||||
rs->where[RBP], rs->val[RBP], DWARF_GET_LOC(d->loc[RBP]),
|
rs->reg.where[RBP], rs->reg.val[RBP], DWARF_GET_LOC(d->loc[RBP]),
|
||||||
rs->where[RSP], rs->val[RSP], DWARF_GET_LOC(d->loc[RSP]));
|
rs->reg.where[RSP], rs->reg.val[RSP], DWARF_GET_LOC(d->loc[RSP]));
|
||||||
|
|
||||||
if (rs->where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_EXPR &&
|
if (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_EXPR &&
|
||||||
rs->where[RBP] == DWARF_WHERE_EXPR) {
|
rs->reg.where[RBP] == DWARF_WHERE_EXPR) {
|
||||||
/* Check for GCC generated alignment frame for rsp. A simple
|
/* Check for GCC generated alignment frame for rsp. A simple
|
||||||
* def_cfa_expr that loads a constant offset from rbp, where the
|
* def_cfa_expr that loads a constant offset from rbp, where the
|
||||||
* addres of the rip was pushed on the stack */
|
* addres of the rip was pushed on the stack */
|
||||||
unw_word_t cfa_addr = rs->val[DWARF_CFA_REG_COLUMN];
|
unw_word_t cfa_addr = rs->reg.val[DWARF_CFA_REG_COLUMN];
|
||||||
unw_word_t rbp_addr = rs->val[RBP];
|
unw_word_t rbp_addr = rs->reg.val[RBP];
|
||||||
unw_word_t cfa_offset;
|
unw_word_t cfa_offset;
|
||||||
|
|
||||||
int ret = dwarf_stack_aligned(d, cfa_addr, rbp_addr, &cfa_offset);
|
int ret = dwarf_stack_aligned(d, cfa_addr, rbp_addr, &cfa_offset);
|
||||||
|
@ -64,30 +64,30 @@ tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs)
|
||||||
- RBP is unsaved or saved at CFA+offset, offset != -1;
|
- RBP is unsaved or saved at CFA+offset, offset != -1;
|
||||||
- RSP is unsaved or saved at CFA+offset, offset != -1. */
|
- RSP is unsaved or saved at CFA+offset, offset != -1. */
|
||||||
if (f->frame_type == UNW_X86_64_FRAME_OTHER
|
if (f->frame_type == UNW_X86_64_FRAME_OTHER
|
||||||
&& (rs->where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_REG)
|
&& (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_REG)
|
||||||
&& (rs->val[DWARF_CFA_REG_COLUMN] == RBP
|
&& (rs->reg.val[DWARF_CFA_REG_COLUMN] == RBP
|
||||||
|| rs->val[DWARF_CFA_REG_COLUMN] == RSP)
|
|| rs->reg.val[DWARF_CFA_REG_COLUMN] == RSP)
|
||||||
&& labs((long) rs->val[DWARF_CFA_OFF_COLUMN]) < (1 << 28)
|
&& labs((long) rs->reg.val[DWARF_CFA_OFF_COLUMN]) < (1 << 28)
|
||||||
&& DWARF_GET_LOC(d->loc[rs->ret_addr_column]) == d->cfa-8
|
&& DWARF_GET_LOC(d->loc[rs->ret_addr_column]) == d->cfa-8
|
||||||
&& (rs->where[RBP] == DWARF_WHERE_UNDEF
|
&& (rs->reg.where[RBP] == DWARF_WHERE_UNDEF
|
||||||
|| rs->where[RBP] == DWARF_WHERE_SAME
|
|| rs->reg.where[RBP] == DWARF_WHERE_SAME
|
||||||
|| (rs->where[RBP] == DWARF_WHERE_CFAREL
|
|| (rs->reg.where[RBP] == DWARF_WHERE_CFAREL
|
||||||
&& labs((long) rs->val[RBP]) < (1 << 14)
|
&& labs((long) rs->reg.val[RBP]) < (1 << 14)
|
||||||
&& rs->val[RBP]+1 != 0))
|
&& rs->reg.val[RBP]+1 != 0))
|
||||||
&& (rs->where[RSP] == DWARF_WHERE_UNDEF
|
&& (rs->reg.where[RSP] == DWARF_WHERE_UNDEF
|
||||||
|| rs->where[RSP] == DWARF_WHERE_SAME
|
|| rs->reg.where[RSP] == DWARF_WHERE_SAME
|
||||||
|| (rs->where[RSP] == DWARF_WHERE_CFAREL
|
|| (rs->reg.where[RSP] == DWARF_WHERE_CFAREL
|
||||||
&& labs((long) rs->val[RSP]) < (1 << 14)
|
&& labs((long) rs->reg.val[RSP]) < (1 << 14)
|
||||||
&& rs->val[RSP]+1 != 0)))
|
&& rs->reg.val[RSP]+1 != 0)))
|
||||||
{
|
{
|
||||||
/* Save information for a standard frame. */
|
/* Save information for a standard frame. */
|
||||||
f->frame_type = UNW_X86_64_FRAME_STANDARD;
|
f->frame_type = UNW_X86_64_FRAME_STANDARD;
|
||||||
f->cfa_reg_rsp = (rs->val[DWARF_CFA_REG_COLUMN] == RSP);
|
f->cfa_reg_rsp = (rs->reg.val[DWARF_CFA_REG_COLUMN] == RSP);
|
||||||
f->cfa_reg_offset = rs->val[DWARF_CFA_OFF_COLUMN];
|
f->cfa_reg_offset = rs->reg.val[DWARF_CFA_OFF_COLUMN];
|
||||||
if (rs->where[RBP] == DWARF_WHERE_CFAREL)
|
if (rs->reg.where[RBP] == DWARF_WHERE_CFAREL)
|
||||||
f->rbp_cfa_offset = rs->val[RBP];
|
f->rbp_cfa_offset = rs->reg.val[RBP];
|
||||||
if (rs->where[RSP] == DWARF_WHERE_CFAREL)
|
if (rs->reg.where[RSP] == DWARF_WHERE_CFAREL)
|
||||||
f->rsp_cfa_offset = rs->val[RSP];
|
f->rsp_cfa_offset = rs->reg.val[RSP];
|
||||||
Debug (4, " standard frame\n");
|
Debug (4, " standard frame\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ void handler(int num, siginfo_t* info, void* ucontext) {
|
||||||
int ucontext_steps = stepper(&c);
|
int ucontext_steps = stepper(&c);
|
||||||
|
|
||||||
ret = unw_init_local(&c, &context);
|
ret = unw_init_local(&c, &context);
|
||||||
|
(void)ret;
|
||||||
assert(!ret);
|
assert(!ret);
|
||||||
int getcontext_steps = stepper(&c);
|
int getcontext_steps = stepper(&c);
|
||||||
if (ucontext_steps == getcontext_steps - 2) {
|
if (ucontext_steps == getcontext_steps - 2) {
|
||||||
|
@ -54,4 +55,5 @@ int main(){
|
||||||
sigaction(SIGSEGV, &a, NULL);
|
sigaction(SIGSEGV, &a, NULL);
|
||||||
|
|
||||||
foo(NULL);
|
foo(NULL);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue