Compare commits

...

3 commits

3 changed files with 32 additions and 9 deletions

View file

@ -107,6 +107,9 @@ class DwarfInterpret {
uintptr_t rip;
uintptr_t rsp;
uintptr_t rbp;
/// This context's `RIP` minus its ELF file load offset
uintptr_t elf_local_rip() const;
};
public: // methods
@ -180,6 +183,12 @@ class DwarfInterpret {
*/
UnwindContext unwind_context(const UnwindContext& ctx);
/** Get the offset for the instruction pointer.
*
* This offset is such that `actual_rip - pc_offset` is the ELF-local
* PC (ie. what readelf gives). */
uintptr_t get_pc_offset() const { return pc_offset; }
private:
DwarfInterpret(const MemoryMap::MapEntry& memory_object);

View file

@ -36,6 +36,11 @@ using namespace dwarf;
MemoryMap DwarfInterpret::memory_map;
map<int, unique_ptr<DwarfInterpret> > DwarfInterpret::instances;
uintptr_t DwarfInterpret::UnwindContext::elf_local_rip() const {
return rip - DwarfInterpret::acquire(rip).get_pc_offset();
}
DwarfInterpret::DwarfInterpret(const MemoryMap::MapEntry& memory_object)
: map_entry(memory_object)
{
@ -205,13 +210,17 @@ DwarfInterpret::UnwindContext DwarfInterpret::unwind_context(
// An undefined RA means we've reached the end of the call stack
throw FirstUnwindFrame();
}
new_context.rbp = interpret_dw_register(
cur_row,
lib::DWARF_X86_64_RBP,
ctx);
if(new_context.rbp == 0) {
// A null rbp means we've reached the end of the call stack
throw FirstUnwindFrame();
try {
new_context.rbp = interpret_dw_register(
cur_row,
lib::DWARF_X86_64_RBP,
ctx);
if(new_context.rbp == 0) {
// A null rbp means we've reached the end of the call stack
throw FirstUnwindFrame();
}
} catch(const std::out_of_range& e) {
new_context.rbp = 0; // The base pointer does not exist
}
new_context.rsp = interpret_dw_register(

View file

@ -28,7 +28,11 @@ void dump_my_stack() {
(dl_rc && dl_inf.dli_sname) ? dl_inf.dli_sname : "(no symbol)",
cur_map_entry.pathname.c_str());
fflush(stdout);
unw_context = dw.unwind_context(unw_context);
try {
unw_context = dw.unwind_context(unw_context);
} catch(const DwarfInterpret::FirstUnwindFrame& exn) {
return;
}
}
}
@ -36,7 +40,8 @@ void fill_my_stack(int stack_depth) {
if(stack_depth == 0)
dump_my_stack();
fill_my_stack(stack_depth - 1);
else
fill_my_stack(stack_depth - 1);
}
int main(int argc, char** argv) {