mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-11-22 07:37:38 +01:00
Cache _fde_func
This commit is contained in:
parent
a73203b9bb
commit
11cce868c6
4 changed files with 34 additions and 19 deletions
|
@ -1,5 +1,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
UNWF_RIP=0,
|
UNWF_RIP=0,
|
||||||
UNWF_RSP=1,
|
UNWF_RSP=1,
|
||||||
|
|
|
@ -120,12 +120,6 @@ int eh_elf_step_cursor(struct cursor *cursor) {
|
||||||
ip - mmap_entry->offset,
|
ip - mmap_entry->offset,
|
||||||
mmap_entry->eh_elf == NULL ? " [MISSING EH_ELF]" : "");
|
mmap_entry->eh_elf == NULL ? " [MISSING EH_ELF]" : "");
|
||||||
|
|
||||||
// Retrieve a pointer to the eh_elf function
|
|
||||||
_fde_func_with_deref_t fde_func =
|
|
||||||
(_fde_func_with_deref_t) (dlsym(mmap_entry->eh_elf, "_eh_elf"));
|
|
||||||
if(fde_func == NULL)
|
|
||||||
return -2;
|
|
||||||
|
|
||||||
// Setup an eh_elf context
|
// Setup an eh_elf context
|
||||||
unwind_context_t eh_elf_context;
|
unwind_context_t eh_elf_context;
|
||||||
eh_elf_context.rip = ip;
|
eh_elf_context.rip = ip;
|
||||||
|
@ -149,7 +143,7 @@ int eh_elf_step_cursor(struct cursor *cursor) {
|
||||||
|
|
||||||
eh_elf_context.flags = 0;
|
eh_elf_context.flags = 0;
|
||||||
// Call fde_func
|
// Call fde_func
|
||||||
eh_elf_context = fde_func(
|
eh_elf_context = mmap_entry->fde_func(
|
||||||
eh_elf_context,
|
eh_elf_context,
|
||||||
ip - mmap_entry->offset,
|
ip - mmap_entry->offset,
|
||||||
fetchw_here);
|
fetchw_here);
|
||||||
|
|
|
@ -18,9 +18,6 @@ int mmap_init_procdir(const char* procdir);
|
||||||
/// memory region
|
/// memory region
|
||||||
static int mmap_order_entries(mmap_entry_t* entries, size_t count);
|
static int mmap_order_entries(mmap_entry_t* entries, size_t count);
|
||||||
|
|
||||||
/// `dlopen` a new list entry, or fetch it
|
|
||||||
static dl_obj_t mmap_dlopen_eh_elf(const char* obj_name);
|
|
||||||
|
|
||||||
/// `dlopen`s the corresponding eh_elf for each entry in `entries`.
|
/// `dlopen`s the corresponding eh_elf for each entry in `entries`.
|
||||||
static int mmap_dlopen_eh_elfs(mmap_entry_t* entries, size_t count);
|
static int mmap_dlopen_eh_elfs(mmap_entry_t* entries, size_t count);
|
||||||
|
|
||||||
|
@ -181,20 +178,20 @@ static int mmap_order_entries(mmap_entry_t* entries, size_t count) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dl_obj_t mmap_dlopen_eh_elf(const char* obj_name) {
|
/// `dlopen` a new list entry, or fetch it
|
||||||
|
static dl_obj_list_t* mmap_dlopen_eh_elf(const char* obj_name) {
|
||||||
dl_obj_list_t *cur_elt = _dl_obj_list;
|
dl_obj_list_t *cur_elt = _dl_obj_list;
|
||||||
|
|
||||||
Debug(1, "Obj_name: %s\n", obj_name);
|
|
||||||
while(cur_elt != NULL) {
|
while(cur_elt != NULL) {
|
||||||
Debug(1, "Cur_elt: %s\n", cur_elt->object_name);
|
|
||||||
if(strcmp(cur_elt->object_name, obj_name) == 0) {
|
if(strcmp(cur_elt->object_name, obj_name) == 0) {
|
||||||
Debug(4, "Reusing previous eh_elf %s\n", obj_name);
|
Debug(4, "Reusing previous eh_elf %s\n", obj_name);
|
||||||
return cur_elt->eh_elf;
|
return cur_elt;
|
||||||
}
|
}
|
||||||
cur_elt = cur_elt->next;
|
cur_elt = cur_elt->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wasn't previously opened
|
// Wasn't previously opened
|
||||||
|
// Open the DL object
|
||||||
dl_obj_list_t* new_elt = malloc(sizeof(dl_obj_list_t));
|
dl_obj_list_t* new_elt = malloc(sizeof(dl_obj_list_t));
|
||||||
new_elt->object_name = malloc(sizeof(char) * (strlen(obj_name) + 1));
|
new_elt->object_name = malloc(sizeof(char) * (strlen(obj_name) + 1));
|
||||||
new_elt->next = NULL;
|
new_elt->next = NULL;
|
||||||
|
@ -207,8 +204,25 @@ static dl_obj_t mmap_dlopen_eh_elf(const char* obj_name) {
|
||||||
sprintf(eh_elf_path, "%s.eh_elf.so", obj_basename);
|
sprintf(eh_elf_path, "%s.eh_elf.so", obj_basename);
|
||||||
new_elt->eh_elf = dlopen(eh_elf_path, RTLD_LAZY);
|
new_elt->eh_elf = dlopen(eh_elf_path, RTLD_LAZY);
|
||||||
free(obj_name_cpy);
|
free(obj_name_cpy);
|
||||||
if(new_elt->eh_elf == NULL)
|
if(new_elt->eh_elf == NULL) {
|
||||||
|
// Failed, cleanup everything
|
||||||
|
Debug(3, "Could not open eh_elf.so %s\n", eh_elf_path);
|
||||||
|
free(new_elt->object_name);
|
||||||
|
free(new_elt);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the fde function
|
||||||
|
new_elt->fde_func =
|
||||||
|
(_fde_func_with_deref_t) (dlsym(new_elt->eh_elf, "_eh_elf"));
|
||||||
|
if(new_elt->fde_func == NULL) {
|
||||||
|
// Failed, cleanup everything
|
||||||
|
Debug(3, "Could not find _eh_elf in %s\n", eh_elf_path);
|
||||||
|
free(new_elt->object_name);
|
||||||
|
dlclose(new_elt->eh_elf);
|
||||||
|
free(new_elt);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
char opened_file[256];
|
char opened_file[256];
|
||||||
dlinfo(new_elt->eh_elf, RTLD_DI_ORIGIN, opened_file);
|
dlinfo(new_elt->eh_elf, RTLD_DI_ORIGIN, opened_file);
|
||||||
|
@ -218,16 +232,18 @@ static dl_obj_t mmap_dlopen_eh_elf(const char* obj_name) {
|
||||||
new_elt->next = _dl_obj_list;
|
new_elt->next = _dl_obj_list;
|
||||||
_dl_obj_list = new_elt;
|
_dl_obj_list = new_elt;
|
||||||
|
|
||||||
return new_elt->eh_elf;
|
return new_elt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `dlopen` the needed eh_elf objects.
|
/// `dlopen` the needed eh_elf objects.
|
||||||
static int mmap_dlopen_eh_elfs(mmap_entry_t* entries, size_t count) {
|
static int mmap_dlopen_eh_elfs(mmap_entry_t* entries, size_t count) {
|
||||||
for(size_t id = 0; id < count; ++id) {
|
for(size_t id = 0; id < count; ++id) {
|
||||||
dl_obj_t eh_elf = mmap_dlopen_eh_elf(entries[id].object_name);
|
dl_obj_list_t* eh_elf_elt =
|
||||||
if(eh_elf == NULL)
|
mmap_dlopen_eh_elf(entries[id].object_name);
|
||||||
|
if(eh_elf_elt == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
entries[id].eh_elf = eh_elf;
|
entries[id].eh_elf = eh_elf_elt->eh_elf;
|
||||||
|
entries[id].fde_func = eh_elf_elt->fde_func;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#include "libunwind.h"
|
#include "libunwind.h"
|
||||||
|
#include "context_struct.h"
|
||||||
|
|
||||||
/// A type representing a dlopen handle
|
/// A type representing a dlopen handle
|
||||||
typedef void* dl_obj_t;
|
typedef void* dl_obj_t;
|
||||||
|
@ -27,6 +28,7 @@ typedef void* dl_obj_t;
|
||||||
typedef struct dl_obj_list {
|
typedef struct dl_obj_list {
|
||||||
char* object_name; ///< Name of the object mapped here
|
char* object_name; ///< Name of the object mapped here
|
||||||
dl_obj_t eh_elf; ///< Corresponding eh_elf file, dlopen'd
|
dl_obj_t eh_elf; ///< Corresponding eh_elf file, dlopen'd
|
||||||
|
_fde_func_with_deref_t fde_func; ///< Fde deref function, directly
|
||||||
struct dl_obj_list* next; ///< Next item in the list
|
struct dl_obj_list* next; ///< Next item in the list
|
||||||
} dl_obj_list_t;
|
} dl_obj_list_t;
|
||||||
|
|
||||||
|
@ -38,6 +40,7 @@ typedef struct {
|
||||||
char* object_name; ///< Name of the object mapped here
|
char* object_name; ///< Name of the object mapped here
|
||||||
uintptr_t beg_ip, end_ip; ///< Start and end IP of this object in memory
|
uintptr_t beg_ip, end_ip; ///< Start and end IP of this object in memory
|
||||||
dl_obj_t eh_elf; ///< Corresponding eh_elf file, dlopen'd
|
dl_obj_t eh_elf; ///< Corresponding eh_elf file, dlopen'd
|
||||||
|
_fde_func_with_deref_t fde_func; ///< Fde deref function, directly
|
||||||
} mmap_entry_t;
|
} mmap_entry_t;
|
||||||
|
|
||||||
/// Dealloc all allocated memory and reset internal state
|
/// Dealloc all allocated memory and reset internal state
|
||||||
|
|
Loading…
Reference in a new issue