1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-07-04 14:35:34 +02: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. */ /* Run a CFI program to update the register state. */
static int static int
run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr, 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) struct dwarf_cie_info *dci)
{ {
unw_word_t curr_ip = c->pi.start_ip;
dwarf_reg_state_t *rs_stack = NULL; dwarf_reg_state_t *rs_stack = NULL;
unw_addr_space_t as; unw_addr_space_t as;
void *arg; 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); unw_accessors_t *a = unw_get_accessors (as);
int ret = 0; 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 including all the DW_CFA_advance_loc instructions. See
'c->use_prev_instr' use in 'fetch_proc_info' for details. */ '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; unw_word_t operand = 0, regnum, val, len;
uint8_t u8, op; 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) switch ((dwarf_cfa_t) op)
{ {
case DW_CFA_advance_loc: case DW_CFA_advance_loc:
curr_ip += operand * dci->code_align; *ip += operand * dci->code_align;
Debug (15, "CFA_advance_loc to 0x%lx\n", (long) curr_ip); Debug (15, "CFA_advance_loc to 0x%lx\n", (long) *ip);
break; break;
case DW_CFA_advance_loc1: case DW_CFA_advance_loc1:
if ((ret = dwarf_readu8 (as, a, addr, &u8, arg)) < 0) if ((ret = dwarf_readu8 (as, a, addr, &u8, arg)) < 0)
break; break;
curr_ip += u8 * dci->code_align; *ip += u8 * dci->code_align;
Debug (15, "CFA_advance_loc1 to 0x%lx\n", (long) curr_ip); Debug (15, "CFA_advance_loc1 to 0x%lx\n", (long) *ip);
break; break;
case DW_CFA_advance_loc2: case DW_CFA_advance_loc2:
if ((ret = dwarf_readu16 (as, a, addr, &u16, arg)) < 0) if ((ret = dwarf_readu16 (as, a, addr, &u16, arg)) < 0)
break; break;
curr_ip += u16 * dci->code_align; *ip += u16 * dci->code_align;
Debug (15, "CFA_advance_loc2 to 0x%lx\n", (long) curr_ip); Debug (15, "CFA_advance_loc2 to 0x%lx\n", (long) *ip);
break; break;
case DW_CFA_advance_loc4: case DW_CFA_advance_loc4:
if ((ret = dwarf_readu32 (as, a, addr, &u32, arg)) < 0) if ((ret = dwarf_readu32 (as, a, addr, &u32, arg)) < 0)
break; break;
curr_ip += u32 * dci->code_align; *ip += u32 * dci->code_align;
Debug (15, "CFA_advance_loc4 to 0x%lx\n", (long) curr_ip); Debug (15, "CFA_advance_loc4 to 0x%lx\n", (long) *ip);
break; break;
case DW_CFA_MIPS_advance_loc8: 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) if ((ret = dwarf_readu64 (as, a, addr, &u64, arg)) < 0)
break; break;
curr_ip += u64 * dci->code_align; *ip += u64 * dci->code_align;
Debug (15, "CFA_MIPS_advance_loc8\n"); Debug (15, "CFA_MIPS_advance_loc8\n");
break; break;
} }
@ -234,10 +234,10 @@ run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr,
case DW_CFA_set_loc: case DW_CFA_set_loc:
if ((ret = dwarf_read_encoded_pointer (as, a, addr, dci->fde_encoding, if ((ret = dwarf_read_encoded_pointer (as, a, addr, dci->fde_encoding,
&c->pi, &curr_ip, &c->pi, ip,
arg)) < 0) arg)) < 0)
break; 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; break;
case DW_CFA_undefined: 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: case DW_CFA_GNU_args_size:
if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
break; break;
if (curr_ip < ip) if (*ip < end_ip)
{ {
sr->args_size = val; sr->args_size = val;
Debug (15, "CFA_GNU_args_size %lu\n", (long) 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; struct dwarf_cie_info *dci = c->pi.unwind_info;
c->ret_addr_column = dci->ret_addr_column; c->ret_addr_column = dci->ret_addr_column;
unw_word_t addr = dci->cie_instr_start; 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) dci->cie_instr_end, dci)) < 0)
return ret; return ret;
@ -529,7 +530,8 @@ parse_fde (struct dwarf_cursor *c, unw_word_t ip, dwarf_state_record_t *sr)
int ret; int ret;
struct dwarf_cie_info *dci = c->pi.unwind_info; struct dwarf_cie_info *dci = c->pi.unwind_info;
unw_word_t addr = dci->fde_instr_start; 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 ret;
return 0; return 0;