]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdwfl: Only skip reset of return register for non-CIE-return regno (ppc64). elfutils-0.158
authorMark Wielaard <mjw@redhat.com>
Sun, 5 Jan 2014 19:37:30 +0000 (20:37 +0100)
committerMark Wielaard <mjw@redhat.com>
Sun, 5 Jan 2014 19:49:24 +0000 (20:49 +0100)
For PPC64 we skip resetting the return register if it is already set.
This is because on PPC64 there are two DWARF registers numbers that can
represent the same register. Setting the return address again confuses
the unwinder. But we do want to reset it if the register number
(non-translated by the ppc64 ebl) is equal to the actual register number
as set in the CIE as return address. This happens on older toolchains in
.debug_frame where the return address is set to 108, but the ebl abi_cfi
also sets register number 65.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
libdwfl/ChangeLog
libdwfl/frame_unwind.c

index 766fb18ac222d874111e4734a93bd44065d9e532..55980a5728025eeb7cd983b815e19d1265884f76 100644 (file)
@@ -1,3 +1,8 @@
+2014-01-05  Mark Wielaard  <mjw@redhat.com>
+
+       * frame_unwind.c (handle_cfi): Only skip resetting return register
+       if the regno is not the actual CIE return address register.
+
 2014-01-02  Mark Wielaard  <mjw@redhat.com>
 
        * linux-pid-attach.c (dwfl_linux_proc_attach): Use strtol, not atoi.
index 3ce45479b8c7a964f7ee514f12b1a2e4cfa31a4a..dc99e40b6f130851e83e3198a9ad5d8b616a50fb 100644 (file)
@@ -585,8 +585,9 @@ handle_cfi (Dwfl_Frame *state, Dwarf_Addr pc, Dwarf_CFI *cfi, Dwarf_Addr bias)
       /* This is another strange PPC[64] case.  There are two
         registers numbers that can represent the same DWARF return
         register number.  We only want one to actually set the return
-        register value.  */
-      if (ra_set)
+        register value.  But we always want to override the value if
+        the register is the actual CIE return address register.  */
+      if (ra_set && regno != frame->fde->cie->return_address_register)
        {
          unsigned r = regno;
          if (ebl_dwarf_to_regno (ebl, &r) && r == ra)