summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libdwfl/ChangeLog7
-rw-r--r--libdwfl/dwfl_frame.c2
-rw-r--r--libdwfl/frame_unwind.c9
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);
}