From: Omar Sandoval <osan...@fb.com> libdwfl can evaluate DWARF expressions in order to unwind the stack, but this functionality isn't exposed to clients of the library. Now that the pieces are in place, add dwfl_frame_eval_expr to provide this feature.
Signed-off-by: Omar Sandoval <osan...@fb.com> --- libdw/ChangeLog | 1 + libdw/libdw.map | 1 + libdwfl/ChangeLog | 2 ++ libdwfl/frame_unwind.c | 12 ++++++++++++ libdwfl/libdwfl.h | 6 ++++++ 5 files changed, 22 insertions(+) diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 1a712497..765d51ec 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -5,6 +5,7 @@ Add dwfl_detach_thread. Add dwfl_frame_module. Add dwfl_frame_dwarf_frame. + Add dwfl_frame_eval_expr. 2019-07-05 Omar Sandoval <osan...@fb.com> diff --git a/libdw/libdw.map b/libdw/libdw.map index c1469c4e..d06a29ed 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -376,4 +376,5 @@ ELFUTILS_0.178 { dwfl_detach_thread; dwfl_frame_module; dwfl_frame_dwarf_frame; + dwfl_frame_eval_expr; } ELFUTILS_0.177; diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index fdb517c9..3689ddd9 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -20,10 +20,12 @@ (__libdwfl_frame_unwind): Cache state->mod. (dwfl_frame_module): Add function. (dwfl_frame_dwarf_frame): Add function. + (dwfl_frame_eval_expr): Add function. * libdwfl.h (dwfl_attach_thread): Add definition. (dwfl_detach_thread): Add definition. (dwfl_frame_module): Add definition. (dwfl_frame_dwarf_frame): Add definition. + (dwfl_frame_eval_expr): Add definition. * libdwflP.h (struct Dwfl_Thread): Update comment for unwound member. Add mod, frame, and bias. diff --git a/libdwfl/frame_unwind.c b/libdwfl/frame_unwind.c index 9738ca72..4c2df837 100644 --- a/libdwfl/frame_unwind.c +++ b/libdwfl/frame_unwind.c @@ -787,3 +787,15 @@ dwfl_frame_dwarf_frame (Dwfl_Frame *state, Dwarf_Addr *bias) *bias = state->bias; return state->frame; } + +bool +dwfl_frame_eval_expr (Dwfl_Frame *state, const Dwarf_Op *ops, size_t nops, + Dwarf_Addr *result) +{ + if (state->frame == NULL) + { + __libdwfl_seterrno (DWFL_E_NO_DWARF); + return false; + } + return expr_eval (state, state->frame, ops, nops, result, state->bias); +} diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h index b450816b..90a3e103 100644 --- a/libdwfl/libdwfl.h +++ b/libdwfl/libdwfl.h @@ -829,6 +829,12 @@ int dwfl_getthread_frames (Dwfl *dwfl, pid_t tid, bool dwfl_frame_pc (Dwfl_Frame *state, Dwarf_Addr *pc, bool *isactivation) __nonnull_attribute__ (1, 2); +/* Evaluate a DWARF expression in the context of a frame. On success, returns + true and fills in *RESULT. On error, returns false. */ +bool dwfl_frame_eval_expr (Dwfl_Frame *state, const Dwarf_Op *ops, size_t nops, + Dwarf_Addr *result) + __nonnull_attribute__ (1, 2, 4); + #ifdef __cplusplus } #endif -- 2.23.0