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;
|
||||
|
||||
/** Describes a line in the memory map (which SO is loaded where) */
|
||||
struct MemoryMapEntry {
|
||||
MemoryMapEntry():
|
||||
beg(0), end(0), offset(0), obj_path(), eh_dl_handle(nullptr)
|
||||
|
@ -24,11 +25,18 @@ struct MemoryMapEntry {
|
|||
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;
|
||||
|
||||
|
||||
/** Equivalent to a shell command `readlink -f` */
|
||||
std::string readlink_rec(const char* path) {
|
||||
char buf[2][1024];
|
||||
int parity = 1;
|
||||
|
@ -46,6 +54,7 @@ std::string readlink_rec(const char* path) {
|
|||
return std::string(buf[1 - parity]);
|
||||
}
|
||||
|
||||
/** Called by `dl_iterate_phdr` later, initializes `memory_map` */
|
||||
int fill_memory_map_callback(
|
||||
struct dl_phdr_info* info,
|
||||
size_t /*size*/,
|
||||
|
@ -100,6 +109,7 @@ bool stack_walker_init() {
|
|||
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) {
|
||||
auto& mmap_entry = mmap_entry_pair.second;
|
||||
|
||||
|
@ -144,6 +154,34 @@ unwind_context_t get_context() {
|
|||
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) {
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue