1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-14 04:18:11 +01:00

Pass in a pointer to the address where run_cfi_program will start,

or resume, its decoding, rather than always starting at the procedure
start, so that resuming a cfi_program becomes possible.
This commit is contained in:
Doug Moore 2017-05-08 18:56:45 -05:00
parent 7a962b951b
commit 1c76d41939

View file

@ -83,10 +83,10 @@ pop_rstate_stack(dwarf_reg_state_t **rs_stack)
/* Run a CFI program to update the register state. */
static int
run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr,
unw_word_t ip, unw_word_t *addr, unw_word_t end_addr,
unw_word_t *ip, unw_word_t end_ip,
unw_word_t *addr, unw_word_t end_addr,
struct dwarf_cie_info *dci)
{
unw_word_t curr_ip = c->pi.start_ip;
dwarf_reg_state_t *rs_stack = NULL;
unw_addr_space_t as;
void *arg;
@ -105,10 +105,10 @@ run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr,
unw_accessors_t *a = unw_get_accessors (as);
int ret = 0;
/* Process everything up to and including the current 'ip',
/* Process everything up to and including the current 'end_ip',
including all the DW_CFA_advance_loc instructions. See
'c->use_prev_instr' use in 'fetch_proc_info' for details. */
while (curr_ip <= ip && *addr < end_addr && ret >= 0)
while (*ip <= end_ip && *addr < end_addr && ret >= 0)
{
unw_word_t operand = 0, regnum, val, len;
uint8_t u8, op;
@ -126,29 +126,29 @@ run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr,
switch ((dwarf_cfa_t) op)
{
case DW_CFA_advance_loc:
curr_ip += operand * dci->code_align;
Debug (15, "CFA_advance_loc to 0x%lx\n", (long) curr_ip);
*ip += operand * dci->code_align;
Debug (15, "CFA_advance_loc to 0x%lx\n", (long) *ip);
break;
case DW_CFA_advance_loc1:
if ((ret = dwarf_readu8 (as, a, addr, &u8, arg)) < 0)
break;
curr_ip += u8 * dci->code_align;
Debug (15, "CFA_advance_loc1 to 0x%lx\n", (long) curr_ip);
*ip += u8 * dci->code_align;
Debug (15, "CFA_advance_loc1 to 0x%lx\n", (long) *ip);
break;
case DW_CFA_advance_loc2:
if ((ret = dwarf_readu16 (as, a, addr, &u16, arg)) < 0)
break;
curr_ip += u16 * dci->code_align;
Debug (15, "CFA_advance_loc2 to 0x%lx\n", (long) curr_ip);
*ip += u16 * dci->code_align;
Debug (15, "CFA_advance_loc2 to 0x%lx\n", (long) *ip);
break;
case DW_CFA_advance_loc4:
if ((ret = dwarf_readu32 (as, a, addr, &u32, arg)) < 0)
break;
curr_ip += u32 * dci->code_align;
Debug (15, "CFA_advance_loc4 to 0x%lx\n", (long) curr_ip);
*ip += u32 * dci->code_align;
Debug (15, "CFA_advance_loc4 to 0x%lx\n", (long) *ip);
break;
case DW_CFA_MIPS_advance_loc8:
@ -158,7 +158,7 @@ run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr,
if ((ret = dwarf_readu64 (as, a, addr, &u64, arg)) < 0)
break;
curr_ip += u64 * dci->code_align;
*ip += u64 * dci->code_align;
Debug (15, "CFA_MIPS_advance_loc8\n");
break;
}
@ -234,10 +234,10 @@ run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr,
case DW_CFA_set_loc:
if ((ret = dwarf_read_encoded_pointer (as, a, addr, dci->fde_encoding,
&c->pi, &curr_ip,
&c->pi, ip,
arg)) < 0)
break;
Debug (15, "CFA_set_loc to 0x%lx\n", (long) curr_ip);
Debug (15, "CFA_set_loc to 0x%lx\n", (long) *ip);
break;
case DW_CFA_undefined:
@ -373,7 +373,7 @@ run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr,
case DW_CFA_GNU_args_size:
if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
break;
if (curr_ip < ip)
if (*ip < end_ip)
{
sr->args_size = val;
Debug (15, "CFA_GNU_args_size %lu\n", (long) val);
@ -515,7 +515,8 @@ setup_fde (struct dwarf_cursor *c, dwarf_state_record_t *sr)
struct dwarf_cie_info *dci = c->pi.unwind_info;
c->ret_addr_column = dci->ret_addr_column;
unw_word_t addr = dci->cie_instr_start;
if ((ret = run_cfi_program (c, sr, ~(unw_word_t) 0, &addr,
unw_word_t curr_ip = 0;
if ((ret = run_cfi_program (c, sr, &curr_ip, ~(unw_word_t) 0, &addr,
dci->cie_instr_end, dci)) < 0)
return ret;
@ -529,7 +530,8 @@ parse_fde (struct dwarf_cursor *c, unw_word_t ip, dwarf_state_record_t *sr)
int ret;
struct dwarf_cie_info *dci = c->pi.unwind_info;
unw_word_t addr = dci->fde_instr_start;
if ((ret = run_cfi_program (c, sr, ip, &addr, dci->fde_instr_end, dci)) < 0)
unw_word_t curr_ip = c->pi.start_ip;
if ((ret = run_cfi_program (c, sr, &curr_ip, ip, &addr, dci->fde_instr_end, dci)) < 0)
return ret;
return 0;