mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-12-23 03:53:43 +01:00
eh_elf: Implement step_cursor
This commit is contained in:
parent
7f70295713
commit
e0efd00acd
3 changed files with 85 additions and 9 deletions
13
src/eh_elf/context_struct.h
Normal file
13
src/eh_elf/context_struct.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uintptr_t rip, rsp, rbp;
|
||||
} unwind_context_t;
|
||||
|
||||
typedef uintptr_t (*deref_func_t)(uintptr_t);
|
||||
|
||||
typedef unwind_context_t (*_fde_func_t)(unwind_context_t, uintptr_t);
|
||||
typedef unwind_context_t (*_fde_func_with_deref_t)(
|
||||
unwind_context_t,
|
||||
uintptr_t,
|
||||
deref_func_t);
|
|
@ -13,6 +13,10 @@
|
|||
************************************************/
|
||||
|
||||
#include "eh_elf.h"
|
||||
#include "context_struct.h"
|
||||
#include "libunwind.h"
|
||||
#include "memory_map.h"
|
||||
#include "remote.h"
|
||||
|
||||
int eh_elf_init_local() {
|
||||
return mmap_init_local();
|
||||
|
@ -26,7 +30,70 @@ void eh_elf_clear() {
|
|||
mmap_clear();
|
||||
}
|
||||
|
||||
int eh_elf_step_cursor(struct cursor *cursor) {
|
||||
// TODO implement
|
||||
return 0;
|
||||
static struct {
|
||||
unw_addr_space_t addr_space;
|
||||
unw_accessors_t *accessors;
|
||||
void* arg;
|
||||
} _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);
|
||||
return out;
|
||||
}
|
||||
|
||||
int eh_elf_step_cursor(struct cursor *cursor) {
|
||||
uintptr_t ip = cursor->dwarf.ip;
|
||||
|
||||
// Retrieve memory map entry
|
||||
mmap_entry_t* mmap_entry = mmap_get_entry(ip);
|
||||
if(mmap_entry == NULL)
|
||||
return -1;
|
||||
|
||||
// Retrieve a pointer to the eh_elf function
|
||||
_fde_func_with_deref_t fde_func =
|
||||
(_fde_func_t) (dlsym(mmap_entry->eh_elf, "_eh_elf"));
|
||||
if(fde_func == NULL)
|
||||
return -2;
|
||||
|
||||
// Setup an eh_elf context
|
||||
unwind_context_t eh_elf_context;
|
||||
eh_elf_context.rip = ip;
|
||||
eh_elf_context.rsp = cursor->dwarf.loc[UNW_TDEP_SP].val;
|
||||
eh_elf_context.rbp = cursor->dwarf.loc[UNW_TDEP_BP].val;
|
||||
|
||||
// Set _fetch_state before passing fetchw_here
|
||||
_fetch_state.addr_space = cursor->dwarf.as;
|
||||
_fetch_state.accessors = &cursor->dwarf.as->acc;
|
||||
|
||||
// Call fde_func
|
||||
eh_elf_context = fde_func(
|
||||
eh_elf_context,
|
||||
ip - mmap_entry->offset,
|
||||
fetchw_here);
|
||||
|
||||
// Check for the end of the call chain
|
||||
if(eh_elf_context.rbp == 0 || eh_elf_context.rip + 1 == 0)
|
||||
return 0;
|
||||
|
||||
// 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;
|
||||
|
||||
cursor->dwarf.loc[UNW_TDEP_BP].val = eh_elf_context.rbp;
|
||||
cursor->dwarf.loc[UNW_TDEP_SP].val = eh_elf_context.rsp;
|
||||
cursor->dwarf.loc[UNW_TDEP_IP].val = eh_elf_context.rip;
|
||||
cursor->dwarf.use_prev_instr = 1;
|
||||
|
||||
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;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -17,11 +17,6 @@
|
|||
#include <sys/types.h>
|
||||
#include "libunwind_i.h"
|
||||
|
||||
/// Store the necessary data for a single eh_elf
|
||||
typedef struct {
|
||||
// TODO
|
||||
} eh_elf_handle_t;
|
||||
|
||||
/** Initialize everything for local memory analysis
|
||||
* @return 0 on success, or a negative value upon failure
|
||||
**/
|
||||
|
@ -37,6 +32,7 @@ void eh_elf_clear();
|
|||
|
||||
/** Step the cursor using eh_elf mechanisms.
|
||||
*
|
||||
* Return 0 if everything went fine, otherwise, return a negative value.
|
||||
* @return a positive value upon success, 0 if the frame before this unwinding
|
||||
* was the last one, or a negative value upon failure.
|
||||
**/
|
||||
int eh_elf_step_cursor(struct cursor *cursor);
|
||||
|
|
Loading…
Reference in a new issue