diff options
-rw-r--r-- | libdwfl/ChangeLog | 7 | ||||
-rw-r--r-- | libdwfl/dwfl_frame.c | 2 | ||||
-rw-r--r-- | libdwfl/frame_unwind.c | 9 |
3 files changed, 16 insertions, 2 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index d815f3e5..8657da45 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,10 @@ +2015-12-08 Jose E. Marchesi <jose.marchesi@oracle.com> + + * dwfl_frame.c (state_fetch_pc): Add a backend-defined offset to + the value of the return address register as defined by the CFI + abi. + * frame_unwind.c (handle_cfi): Likewise. + 2015-12-01 Mark Wielaard <mjw@redhat.com> * link_map.c (dwfl_link_map_report): Track whether in.d_buf comes diff --git a/libdwfl/dwfl_frame.c b/libdwfl/dwfl_frame.c index a91a1d68..d6399398 100644 --- a/libdwfl/dwfl_frame.c +++ b/libdwfl/dwfl_frame.c @@ -57,7 +57,7 @@ state_fetch_pc (Dwfl_Frame *state) __libdwfl_seterrno (DWFL_E_LIBEBL_BAD); return false; } - state->pc = state->regs[ra]; + state->pc = state->regs[ra] + ebl_ra_offset (ebl); state->pc_state = DWFL_FRAME_STATE_PC_SET; } return true; diff --git a/libdwfl/frame_unwind.c b/libdwfl/frame_unwind.c index 39509b70..0e470b97 100644 --- a/libdwfl/frame_unwind.c +++ b/libdwfl/frame_unwind.c @@ -637,7 +637,14 @@ handle_cfi (Dwfl_Frame *state, Dwarf_Addr pc, Dwarf_CFI *cfi, Dwarf_Addr bias) if (unwound->pc == 0) unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED; else - unwound->pc_state = DWFL_FRAME_STATE_PC_SET; + { + unwound->pc_state = DWFL_FRAME_STATE_PC_SET; + /* In SPARC the return address register actually contains + the address of the call instruction instead of the return + address. Therefore we add here an offset defined by the + backend. Most likely 0. */ + unwound->pc += ebl_ra_offset (ebl); + } } free (frame); } |