minor dwarf improvments

This commit is contained in:
Stefani Seibold 2018-04-17 14:57:49 +02:00
parent 98a3c4a942
commit 6ac727d143

42
dwarf.c
View File

@ -969,18 +969,18 @@ static int dwarf_access_reg(struct dwarf_addr_space *as, unsigned int reg, arch_
int dwarf_get(struct dwarf_addr_space *as, struct dwarf_loc loc, arch_addr_t *valp) int dwarf_get(struct dwarf_addr_space *as, struct dwarf_loc loc, arch_addr_t *valp)
{ {
arch_addr_t val = DWARF_GET_LOC(loc); arch_addr_t addr = DWARF_GET_LOC(loc);
if (DWARF_IS_REG_LOC(loc)) if (DWARF_IS_REG_LOC(loc))
return dwarf_access_reg(as, val, valp); return dwarf_access_reg(as, addr, valp);
if (!as->is_64bit) if (!as->is_64bit)
val &= 0xffffffff; addr &= 0xffffffff;
if (DWARF_IS_MEM_LOC(loc)) if (DWARF_IS_MEM_LOC(loc))
return dwarf_readw(as, &val, valp, as->is_64bit); return dwarf_readw(as, &addr, valp, as->is_64bit);
*valp = val; *valp = addr;
return 0; return 0;
} }
@ -1049,10 +1049,9 @@ static int run_cfi_program(struct dwarf_addr_space *as, struct dwarf_reg_state *
struct dwarf_cursor *c = &as->cursor; struct dwarf_cursor *c = &as->cursor;
struct dwarf_cie_info *dci = &c->dci; struct dwarf_cie_info *dci = &c->dci;
unsigned int num_regs = as->num_regs; unsigned int num_regs = as->num_regs;
struct dwarf_reg_stack { unsigned int reg_stack_ptr = 0;
struct dwarf_reg_stack *next; /* for reg state stack */ unsigned int reg_stack_entry_len = regs_size(as);
struct dwarf_reg_state store; unsigned char reg_stack[16 * reg_stack_entry_len];
} *rs_stack = NULL, *rs_tmp;
curr_ip = dci->start_ip; curr_ip = dci->start_ip;
@ -1161,21 +1160,22 @@ static int run_cfi_program(struct dwarf_addr_space *as, struct dwarf_reg_state *
set_reg(rs_current, regnum, DWARF_WHERE_REG, n); set_reg(rs_current, regnum, DWARF_WHERE_REG, n);
break; break;
case DW_CFA_remember_state: case DW_CFA_remember_state:
rs_tmp = malloc(sizeof(struct dwarf_reg_stack) + regs_size(as)); if (unlikely(sizeof(reg_stack) - reg_stack_ptr < reg_stack_entry_len)) {
memcpy(&rs_tmp->store, rs_current, regs_size(as)); debug(DEBUG_DWARF, "register-state stack overflow");
rs_tmp->next = rs_stack; ret = -DWARF_EINVAL;
rs_stack = rs_tmp; goto fail;
}
memcpy(reg_stack + reg_stack_ptr, rs_current, reg_stack_entry_len);
reg_stack_ptr += reg_stack_entry_len;
break; break;
case DW_CFA_restore_state: case DW_CFA_restore_state:
if (unlikely(!rs_stack)) { if (unlikely(!reg_stack_ptr)) {
debug(DEBUG_DWARF, "register-state stack underflow"); debug(DEBUG_DWARF, "register-state stack underflow");
ret = -DWARF_EINVAL; ret = -DWARF_EINVAL;
goto fail; goto fail;
} }
rs_tmp = rs_stack; reg_stack_ptr -= reg_stack_entry_len;
memcpy(rs_current, &rs_tmp->store, regs_size(as)); memcpy(rs_current, reg_stack + reg_stack_ptr, reg_stack_entry_len);
rs_stack = rs_tmp->next;
free(rs_tmp);
break; break;
case DW_CFA_def_cfa: case DW_CFA_def_cfa:
if ((unlikely((ret = read_regnum(num_regs, addr, &regnum)) < 0) if ((unlikely((ret = read_regnum(num_regs, addr, &regnum)) < 0)
@ -1264,12 +1264,6 @@ static int run_cfi_program(struct dwarf_addr_space *as, struct dwarf_reg_state *
ret = 0; ret = 0;
fail: fail:
/* Free the register-state stack, if not empty already. */
while (rs_stack) {
rs_tmp = rs_stack;
rs_stack = rs_stack->next;
free(rs_tmp);
}
return ret; return ret;
} }