mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-11-22 07:37:38 +01:00
eh_elf: fix a few more errors
This commit is contained in:
parent
7494efbb16
commit
bfd5b164fa
2 changed files with 49 additions and 19 deletions
|
@ -37,18 +37,24 @@ void eh_elf_clear() {
|
|||
}
|
||||
|
||||
static struct {
|
||||
unw_addr_space_t addr_space;
|
||||
unw_accessors_t *accessors;
|
||||
void* arg;
|
||||
struct cursor* cursor;
|
||||
int last_rc;
|
||||
} _fetch_state;
|
||||
|
||||
static uintptr_t fetchw_here(uintptr_t addr) {
|
||||
uintptr_t out;
|
||||
fetchw(_fetch_state.addr_space,
|
||||
_fetch_state.accessors,
|
||||
&addr,
|
||||
&out,
|
||||
_fetch_state.arg);
|
||||
int rv = _fetch_state.cursor->dwarf.as->acc.access_mem(
|
||||
_fetch_state.cursor->dwarf.as,
|
||||
addr,
|
||||
&out,
|
||||
0,
|
||||
_fetch_state.cursor->dwarf.as_arg);
|
||||
|
||||
if(rv != 0) {
|
||||
Debug(1, "dwarf_get error %d\n", rv);
|
||||
_fetch_state.last_rc = rv;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -64,6 +70,7 @@ int eh_elf_step_cursor(struct cursor *cursor) {
|
|||
// Check for the end of the call chain
|
||||
if(DWARF_IS_NULL_LOC(cursor->dwarf.loc[UNW_TDEP_IP]))
|
||||
return 0;
|
||||
|
||||
if(!DWARF_IS_NULL_LOC(cursor->dwarf.loc[UNW_TDEP_BP])) {
|
||||
uintptr_t bp;
|
||||
dwarf_get(&cursor->dwarf,
|
||||
|
@ -74,8 +81,10 @@ int eh_elf_step_cursor(struct cursor *cursor) {
|
|||
|
||||
// Retrieve memory map entry
|
||||
mmap_entry_t* mmap_entry = mmap_get_entry(ip);
|
||||
if(mmap_entry == NULL)
|
||||
if(mmap_entry == NULL) {
|
||||
Debug(3, "No such mmap entry :(\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Debug(5, "In memory map entry %lx-%lx (%s) - off %lx, ip %lx%s\n",
|
||||
mmap_entry->beg_ip,
|
||||
|
@ -94,19 +103,18 @@ int eh_elf_step_cursor(struct cursor *cursor) {
|
|||
// Setup an eh_elf context
|
||||
unwind_context_t eh_elf_context;
|
||||
eh_elf_context.rip = ip;
|
||||
dwarf_get(&cursor->dwarf,
|
||||
cursor->dwarf.loc[UNW_TDEP_SP], &eh_elf_context.rsp);
|
||||
eh_elf_context.rsp = cursor->dwarf.cfa;
|
||||
dwarf_get(&cursor->dwarf,
|
||||
cursor->dwarf.loc[UNW_TDEP_BP], &eh_elf_context.rbp);
|
||||
|
||||
// Set _fetch_state before passing fetchw_here
|
||||
_fetch_state.addr_space = cursor->dwarf.as;
|
||||
_fetch_state.accessors = &cursor->dwarf.as->acc;
|
||||
_fetch_state.arg = &cursor->dwarf.as_arg;
|
||||
_fetch_state.cursor = cursor;
|
||||
_fetch_state.last_rc = 0;
|
||||
|
||||
Debug(4, "Unwinding in mmap entry %s at position 0x%lx\n",
|
||||
Debug(4, "Unwinding in mmap entry %s at position 0x%lx (sp=%016lx)\n",
|
||||
mmap_entry->object_name,
|
||||
ip - mmap_entry->offset);
|
||||
ip - mmap_entry->offset,
|
||||
eh_elf_context.rsp);
|
||||
|
||||
// Call fde_func
|
||||
eh_elf_context = fde_func(
|
||||
|
@ -114,6 +122,11 @@ int eh_elf_step_cursor(struct cursor *cursor) {
|
|||
ip - mmap_entry->offset,
|
||||
fetchw_here);
|
||||
|
||||
if(_fetch_state.last_rc != 0) {
|
||||
// access_mem error
|
||||
return -4;
|
||||
}
|
||||
|
||||
if(eh_elf_context.rbp + 1 == 0
|
||||
&& eh_elf_context.rsp + 1 == 0
|
||||
&& eh_elf_context.rip + 1 == 0) {
|
||||
|
@ -122,6 +135,17 @@ int eh_elf_step_cursor(struct cursor *cursor) {
|
|||
return -3;
|
||||
}
|
||||
|
||||
if(eh_elf_context.rip < 10 || eh_elf_context.rsp < 10)
|
||||
return -5;
|
||||
|
||||
Debug(3, "EH_ELF: bp=%016lx sp=%016lx ip=%016lx\n",
|
||||
eh_elf_context.rbp,
|
||||
eh_elf_context.rsp,
|
||||
eh_elf_context.rip);
|
||||
Debug(3, "MMAP: %s %lx\n",
|
||||
mmap_entry->object_name,
|
||||
ip - mmap_entry->offset);
|
||||
|
||||
// Push back the data into libunwind's structures
|
||||
for (int i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
|
||||
cursor->dwarf.loc[i] = DWARF_NULL_LOC;
|
||||
|
@ -129,13 +153,13 @@ int eh_elf_step_cursor(struct cursor *cursor) {
|
|||
cursor->dwarf.loc[UNW_TDEP_BP] = of_eh_elf_loc(eh_elf_context.rbp);
|
||||
cursor->dwarf.loc[UNW_TDEP_SP] = of_eh_elf_loc(eh_elf_context.rsp);
|
||||
cursor->dwarf.loc[UNW_TDEP_IP] = of_eh_elf_loc(eh_elf_context.rip);
|
||||
cursor->dwarf.use_prev_instr = 1;
|
||||
cursor->dwarf.use_prev_instr = 0;
|
||||
|
||||
cursor->frame_info.frame_type = UNW_X86_64_FRAME_GUESSED;
|
||||
cursor->frame_info.cfa_reg_rsp = 0;
|
||||
cursor->frame_info.cfa_reg_offset = 16;
|
||||
cursor->frame_info.rbp_cfa_offset = -16;
|
||||
cursor->dwarf.cfa += 16;
|
||||
cursor->dwarf.cfa = eh_elf_context.rsp;
|
||||
cursor->dwarf.ip = eh_elf_context.rip;
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -28,6 +28,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|||
#include "unwind_i.h"
|
||||
#include "../eh_elf/eh_elf.h"
|
||||
#include <signal.h>
|
||||
#include "remote.h"
|
||||
|
||||
/* Recognise PLT entries such as:
|
||||
3bdf0: ff 25 e2 49 13 00 jmpq *0x1349e2(%rip)
|
||||
|
@ -67,6 +68,8 @@ unw_step (unw_cursor_t *cursor)
|
|||
Debug (1, "(cursor=%p, ip=0x%016lx, cfa=0x%016lx)\n",
|
||||
c, c->dwarf.ip, c->dwarf.cfa);
|
||||
|
||||
c->sigcontext_format = X86_64_SCF_NONE;
|
||||
|
||||
// Try eh_elf based unwinding...
|
||||
ret = eh_elf_step_cursor(c);
|
||||
|
||||
|
@ -79,7 +82,6 @@ unw_step (unw_cursor_t *cursor)
|
|||
}
|
||||
|
||||
/* Try DWARF-based unwinding... */
|
||||
c->sigcontext_format = X86_64_SCF_NONE;
|
||||
ret = dwarf_step (&c->dwarf);
|
||||
|
||||
#if CONSERVATIVE_CHECKS
|
||||
|
@ -102,6 +104,10 @@ unw_step (unw_cursor_t *cursor)
|
|||
c->dwarf.ip = 0;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
uintptr_t dbp;
|
||||
dwarf_get(&c->dwarf, c->dwarf.loc[RBP], &dbp);
|
||||
Debug (3, " DWARF: bp=%016lx sp=%016lx ip=%016lx\n", dbp, c->dwarf.cfa, c->dwarf.ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue