]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdwfl: make the unwinder aware of the backend defined ra_offset.
authorJose E. Marchesi <jose.marchesi@oracle.com>
Tue, 8 Dec 2015 18:10:41 +0000 (19:10 +0100)
committerMark Wielaard <mjw@redhat.com>
Sun, 3 Jan 2016 09:31:41 +0000 (10:31 +0100)
Ebl backends can define an offset that must be applied to the value of
the "return address register" defined in the CFI ABI information.
This patch makes the unwinder to use that offset when reading the RA
CFI register.

Signed-off-by: Jose E. Marchesi <jose.marchesi@oracle.com>
libdwfl/ChangeLog
libdwfl/dwfl_frame.c
libdwfl/frame_unwind.c

index d815f3e5c694518bd850044cc573347133e9fdb9..8657da45a8525cab5df9e2c7dcb7a69de3a75db1 100644 (file)
@@ -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
index a91a1d6831d4d8f07b57de613a1f41a513d61d58..d63993983078c9caa9558217a1221232041efee5 100644 (file)
@@ -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;
index 39509b70e6cc06088a7e33236ded1bb952d5ec5a..0e470b97ffc531730ab5bab95fd01a7bc635dd5d 100644 (file)
@@ -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);
 }