Adapt to use DwarfInterpret as unwinder
This commit is contained in:
parent
77bd72cbf8
commit
48e08d0eda
1 changed files with 68 additions and 7 deletions
|
@ -10,6 +10,9 @@
|
|||
#include <cassert>
|
||||
#include <functional>
|
||||
|
||||
// Cf. https://git.tobast.fr/m2-internship/dwarfinterpret
|
||||
#include <DwarfInterpret.hpp>
|
||||
|
||||
/* How can we "compile" the DWARF CFA instructions into C++ code?
|
||||
* Perhaps the right thing to do is expand into "table" form first.
|
||||
* Compiled code just needs to
|
||||
|
@ -212,6 +215,17 @@ struct mcursor
|
|||
long long int& rbp() { return state.gregs[REG_RBP]; }
|
||||
};
|
||||
|
||||
struct UnwContext {
|
||||
UnwContext(): valid(true) {}
|
||||
|
||||
bool valid;
|
||||
DwarfInterpret::UnwindContext ctx;
|
||||
|
||||
long long int rip() { return ctx.rip; }
|
||||
long long int rsp() { return ctx.rsp; }
|
||||
long long int rbp() { return ctx.rbp; }
|
||||
};
|
||||
|
||||
template <unsigned CacheSize, typename Cursor, typename StepRoutine, typename ValidityCheck, typename Dispatcher, typename Action>
|
||||
struct caching_stack_walker
|
||||
{
|
||||
|
@ -306,6 +320,10 @@ struct blind_frame_pointer_validity_checker
|
|||
static bool check(mcursor& c) { return true; }
|
||||
};
|
||||
|
||||
struct dwarf_frame_pointer_validity_checker {
|
||||
static bool check(UnwContext& c) { return c.valid; }
|
||||
};
|
||||
|
||||
struct blind_frame_pointer_dispatcher; // see below
|
||||
|
||||
struct blind_frame_pointer_stepper
|
||||
|
@ -389,6 +407,25 @@ struct blind_frame_pointer_stepper
|
|||
#undef SANE_BP_OR_NULL
|
||||
};
|
||||
|
||||
struct dwarf_frame_pointer_stepper {
|
||||
template <typename Action>
|
||||
static int step(const Action& a, UnwContext& c) {
|
||||
DwarfInterpret& dw = DwarfInterpret::acquire();
|
||||
try {
|
||||
c.ctx = dw.unwind_context(c.ctx);
|
||||
} catch(const DwarfInterpret::FirstUnwindFrame& e) {
|
||||
c.valid = false;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int initcontext(UnwContext& c) {
|
||||
c.ctx = DwarfInterpret::get_current_unwind_context();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct blind_frame_pointer_dispatcher
|
||||
{
|
||||
// typedef int (*walker_fn)(Cursor&, const Action&);
|
||||
|
@ -412,9 +449,33 @@ struct blind_frame_pointer_dispatcher
|
|||
}
|
||||
};
|
||||
|
||||
struct dwarf_frame_pointer_dispatcher
|
||||
{
|
||||
// typedef int (*walker_fn)(Cursor&, const Action&);
|
||||
template <typename Action, typename Cursor>
|
||||
static
|
||||
//std::function<int(Cursor&, const Action&)>
|
||||
int
|
||||
(*lookup (const Action& a, Cursor &c, void **out_lower, void **out_upper))
|
||||
(Cursor&, const Action&)
|
||||
{
|
||||
*out_lower = nullptr;
|
||||
*out_upper = nullptr;
|
||||
return &caching_stack_walker<
|
||||
1u /* CacheSize */,
|
||||
Cursor,
|
||||
dwarf_frame_pointer_stepper /* StepRoutine */,
|
||||
dwarf_frame_pointer_validity_checker /* ValidityCheck */,
|
||||
dwarf_frame_pointer_dispatcher /* Dispatcher */,
|
||||
Action
|
||||
>::walk_stack;
|
||||
}
|
||||
};
|
||||
|
||||
struct print_frame_action
|
||||
{
|
||||
int act(mcursor& c) const
|
||||
template <typename Cursor>
|
||||
int act(Cursor& c) const
|
||||
{
|
||||
Dl_info i;
|
||||
int success = dladdr((void *) c.rip(), &i);
|
||||
|
@ -445,16 +506,16 @@ int g(int x)
|
|||
// print_frame_action /* Action */
|
||||
//>::walk_stack(c);
|
||||
|
||||
mcursor c_2;
|
||||
UnwContext c_2;
|
||||
ret = x;
|
||||
ret = blind_frame_pointer_stepper::initcontext(c_2);
|
||||
ret = dwarf_frame_pointer_stepper::initcontext(c_2);
|
||||
if (ret) abort();
|
||||
return
|
||||
stack_walker<
|
||||
mcursor,
|
||||
blind_frame_pointer_stepper /* StepRoutine */,
|
||||
blind_frame_pointer_validity_checker /* ValidityCheck */,
|
||||
blind_frame_pointer_dispatcher /* Dispatcher */,
|
||||
UnwContext,
|
||||
dwarf_frame_pointer_stepper /* StepRoutine */,
|
||||
dwarf_frame_pointer_validity_checker /* ValidityCheck */,
|
||||
dwarf_frame_pointer_dispatcher /* Dispatcher */,
|
||||
print_frame_action /* Action */
|
||||
>::walk_stack(c_2);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue