1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-25 16:47:38 +01:00

Keep .eh_elf.so files opened

This commit is contained in:
Théophile Bastian 2018-06-27 11:39:20 +02:00
parent e8941a4c73
commit b5e2c60ec7
2 changed files with 64 additions and 7 deletions

View file

@ -9,6 +9,7 @@
static mmap_entry_t* _memory_map = NULL; static mmap_entry_t* _memory_map = NULL;
static size_t _memory_map_size = 0; static size_t _memory_map_size = 0;
static int _mmap_init_done = 0; static int _mmap_init_done = 0;
static dl_obj_list_t* _dl_obj_list = NULL;
/// Init the memory map with a given /proc/XX/ argument /// Init the memory map with a given /proc/XX/ argument
int mmap_init_procdir(const char* procdir); int mmap_init_procdir(const char* procdir);
@ -17,10 +18,12 @@ 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);
static int compare_mmap_entry(const void* _e1, const void* _e2) { static int compare_mmap_entry(const void* _e1, const void* _e2) {
// We can't return e1->beg_ip - e2->beg_ip because of int overflows // We can't return e1->beg_ip - e2->beg_ip because of int overflows
const mmap_entry_t *e1 = _e1, const mmap_entry_t *e1 = _e1,
@ -178,29 +181,76 @@ 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) {
dl_obj_list_t *cur_elt = _dl_obj_list;
Debug(1, "Obj_name: %s\n", obj_name);
while(cur_elt != NULL) {
Debug(1, "Cur_elt: %s\n", cur_elt->object_name);
if(strcmp(cur_elt->object_name, obj_name) == 0) {
Debug(4, "Reusing previous eh_elf %s\n", obj_name);
return cur_elt->eh_elf;
}
cur_elt = cur_elt->next;
}
// Wasn't previously opened
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->next = NULL;
strcpy(new_elt->object_name, obj_name);
char eh_elf_path[256];
char *obj_name_cpy = malloc(strlen(obj_name) + 1);
strcpy(obj_name_cpy, obj_name);
char* obj_basename = basename(obj_name_cpy);
sprintf(eh_elf_path, "%s.eh_elf.so", obj_basename);
new_elt->eh_elf = dlopen(eh_elf_path, RTLD_LAZY);
free(obj_name_cpy);
if(new_elt->eh_elf == NULL)
return NULL;
char opened_file[256];
dlinfo(new_elt->eh_elf, RTLD_DI_ORIGIN, opened_file);
Debug(4, "Opened %s/%s\n", opened_file, eh_elf_path);
// Linking, prepending
new_elt->next = _dl_obj_list;
_dl_obj_list = new_elt;
return new_elt->eh_elf;
}
/// `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) {
char eh_elf_path[256]; dl_obj_t eh_elf = mmap_dlopen_eh_elf(entries[id].object_name);
char* obj_basename = basename(entries[id].object_name); if(eh_elf == NULL)
sprintf(eh_elf_path, "%s.eh_elf.so", obj_basename);
entries[id].eh_elf = dlopen(eh_elf_path, RTLD_LAZY);
if(entries[id].eh_elf == NULL)
return -1; return -1;
entries[id].eh_elf = eh_elf;
} }
return 0; return 0;
} }
void mmap_clear() { void mmap_clear() {
_mmap_init_done = 0; _mmap_init_done = 0;
// dl_obj_list_t* dl_obj_list = _dl_obj_list;
if(_memory_map != NULL) { if(_memory_map != NULL) {
for(size_t pos=0; pos < _memory_map_size; ++pos) { for(size_t pos=0; pos < _memory_map_size; ++pos) {
free(_memory_map[pos].object_name); free(_memory_map[pos].object_name);
dlclose(_memory_map[pos].eh_elf);
} }
free(_memory_map); free(_memory_map);
} }
// while(dl_obj_list != NULL) {
// dlclose(dl_obj_list->eh_elf);
// free(dl_obj_list->object_name);
//
// dl_obj_list_t* prev = dl_obj_list;
// dl_obj_list = dl_obj_list->next;
// free(prev);
// }
// _dl_obj_list = NULL;
} }
static int bsearch_compar_mmap_entry(const void* vkey, const void* vmmap_elt) { static int bsearch_compar_mmap_entry(const void* vkey, const void* vmmap_elt) {

View file

@ -23,6 +23,13 @@
/// A type representing a dlopen handle /// A type representing a dlopen handle
typedef void* dl_obj_t; typedef void* dl_obj_t;
/// A linked list of dl_obj_t
typedef struct dl_obj_list {
char* object_name; ///< Name of the object mapped here
dl_obj_t eh_elf; ///< Corresponding eh_elf file, dlopen'd
struct dl_obj_list* next; ///< Next item in the list
} dl_obj_list_t;
/// A structure containing the informations gathererd about a line in the /// A structure containing the informations gathererd about a line in the
/// memory map /// memory map
typedef struct { typedef struct {