Add fde_handler_for_pc (untested)
This is an abstraction function to get the _fde_yyy function out of the eh_elf for a given PC
This commit is contained in:
parent
4ab7d0a594
commit
69e6c10c36
1 changed files with 39 additions and 1 deletions
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
typedef void* dl_handle_t;
|
typedef void* dl_handle_t;
|
||||||
|
|
||||||
|
/** Describes a line in the memory map (which SO is loaded where) */
|
||||||
struct MemoryMapEntry {
|
struct MemoryMapEntry {
|
||||||
MemoryMapEntry():
|
MemoryMapEntry():
|
||||||
beg(0), end(0), offset(0), obj_path(), eh_dl_handle(nullptr)
|
beg(0), end(0), offset(0), obj_path(), eh_dl_handle(nullptr)
|
||||||
|
@ -24,11 +25,18 @@ struct MemoryMapEntry {
|
||||||
dl_handle_t eh_dl_handle;
|
dl_handle_t eh_dl_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<uintptr_t, MemoryMapEntry> MemoryMap;
|
/** `MemoryMapEntry`es mapped by their `beg` */
|
||||||
|
typedef std::map<
|
||||||
|
uintptr_t,
|
||||||
|
MemoryMapEntry,
|
||||||
|
std::greater<uintptr_t> > MemoryMap;
|
||||||
|
// here, std::greater is used because it allows easy access to the
|
||||||
|
// corresponding segment by using lower_bound
|
||||||
|
|
||||||
static MemoryMap memory_map;
|
static MemoryMap memory_map;
|
||||||
|
|
||||||
|
|
||||||
|
/** Equivalent to a shell command `readlink -f` */
|
||||||
std::string readlink_rec(const char* path) {
|
std::string readlink_rec(const char* path) {
|
||||||
char buf[2][1024];
|
char buf[2][1024];
|
||||||
int parity = 1;
|
int parity = 1;
|
||||||
|
@ -46,6 +54,7 @@ std::string readlink_rec(const char* path) {
|
||||||
return std::string(buf[1 - parity]);
|
return std::string(buf[1 - parity]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Called by `dl_iterate_phdr` later, initializes `memory_map` */
|
||||||
int fill_memory_map_callback(
|
int fill_memory_map_callback(
|
||||||
struct dl_phdr_info* info,
|
struct dl_phdr_info* info,
|
||||||
size_t /*size*/,
|
size_t /*size*/,
|
||||||
|
@ -100,6 +109,7 @@ bool stack_walker_init() {
|
||||||
mmap_entry.second.obj_path.c_str());
|
mmap_entry.second.obj_path.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call `dlopen` on the `eh_elf.so` maching every entry in `memory_map`
|
||||||
for(auto& mmap_entry_pair: memory_map) {
|
for(auto& mmap_entry_pair: memory_map) {
|
||||||
auto& mmap_entry = mmap_entry_pair.second;
|
auto& mmap_entry = mmap_entry_pair.second;
|
||||||
|
|
||||||
|
@ -144,6 +154,34 @@ unwind_context_t get_context() {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Get the `fde_func_t` function handling the given program counter — it may
|
||||||
|
* be by calling a lookup function, or by directly looking into the ELF
|
||||||
|
* symbols, depending on the state of the experiment. This is an abstraction
|
||||||
|
* function. */
|
||||||
|
_fde_func_t fde_handler_for_pc(uintptr_t pc) {
|
||||||
|
// Get the memory_map entry
|
||||||
|
auto mmap_entry_it = memory_map.lower_bound(pc);
|
||||||
|
if(mmap_entry_it == memory_map.end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
MemoryMapEntry& mmap_entry = mmap_entry_it->second;
|
||||||
|
if(!(mmap_entry.beg <= pc && pc <= mmap_entry.end))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// Get the lookup function
|
||||||
|
_fde_func_t (*lookup)(uintptr_t) =
|
||||||
|
(_fde_func_t (*)(uintptr_t)) (
|
||||||
|
dlsym(mmap_entry.eh_dl_handle, "_fde_lookup"));
|
||||||
|
|
||||||
|
// Get the translated pc
|
||||||
|
uintptr_t tr_pc = pc - mmap_entry.beg;
|
||||||
|
|
||||||
|
// Get the actual function
|
||||||
|
_fde_func_t rfunc = lookup(tr_pc);
|
||||||
|
|
||||||
|
return rfunc;
|
||||||
|
}
|
||||||
|
|
||||||
bool unwind_context(unwind_context_t& ctx) {
|
bool unwind_context(unwind_context_t& ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue