forked from rpms/elfutils
129 lines
5.0 KiB
Diff
129 lines
5.0 KiB
Diff
commit c049419d96d82e4f5834133d5f68f6054e46f789
|
|
Author: Mark Wielaard <mark@klomp.org>
|
|
Date: Tue Apr 10 16:13:34 2018 +0200
|
|
|
|
libdwfl: Handle unwind frame when the return address register isn't set.
|
|
|
|
When we have unwound the frame and then cannot set the return address
|
|
we wouldn't set any error. That meant that a dwfl_thread_getframes ()
|
|
call could end in an error, but without any dwfl_errno set, producing
|
|
the "no error" error message.
|
|
|
|
If we cannot set the return address at the end of unwinding the frame
|
|
that means that either the return address register is bogus (error),
|
|
or that the return address is undefined (end of the call stack).
|
|
|
|
This fixes the run-backtrace-native-biarch.sh testcase for me on an
|
|
i386 on x86_64 setup with gcc 7.2.1 and glibc 2.17.
|
|
|
|
Signed-off-by: Mark Wielaard <mark@klomp.org>
|
|
|
|
diff --git a/libdwfl/frame_unwind.c b/libdwfl/frame_unwind.c
|
|
index eaea495..8da691e 100644
|
|
--- a/libdwfl/frame_unwind.c
|
|
+++ b/libdwfl/frame_unwind.c
|
|
@@ -632,24 +632,38 @@ handle_cfi (Dwfl_Frame *state, Dwarf_Addr pc, Dwarf_CFI *cfi, Dwarf_Addr bias)
|
|
ra_set = true;
|
|
}
|
|
}
|
|
- if (unwound->pc_state == DWFL_FRAME_STATE_ERROR
|
|
- && __libdwfl_frame_reg_get (unwound,
|
|
- frame->fde->cie->return_address_register,
|
|
- &unwound->pc))
|
|
+ if (unwound->pc_state == DWFL_FRAME_STATE_ERROR)
|
|
{
|
|
- /* PPC32 __libc_start_main properly CFI-unwinds PC as zero. Currently
|
|
- none of the archs supported for unwinding have zero as a valid PC. */
|
|
- if (unwound->pc == 0)
|
|
- unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
|
|
+ if (__libdwfl_frame_reg_get (unwound,
|
|
+ frame->fde->cie->return_address_register,
|
|
+ &unwound->pc))
|
|
+ {
|
|
+ /* PPC32 __libc_start_main properly CFI-unwinds PC as zero.
|
|
+ Currently none of the archs supported for unwinding have
|
|
+ zero as a valid PC. */
|
|
+ if (unwound->pc == 0)
|
|
+ unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
|
|
+ else
|
|
+ {
|
|
+ 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);
|
|
+ }
|
|
+ }
|
|
else
|
|
- {
|
|
- 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);
|
|
- }
|
|
+ {
|
|
+ /* We couldn't set the return register, either it was bogus,
|
|
+ or the return pc is undefined, maybe end of call stack. */
|
|
+ unsigned pcreg = frame->fde->cie->return_address_register;
|
|
+ if (! ebl_dwarf_to_regno (ebl, &pcreg)
|
|
+ || pcreg >= ebl_frame_nregs (ebl))
|
|
+ __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
|
|
+ else
|
|
+ unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
|
|
+ }
|
|
}
|
|
free (frame);
|
|
}
|
|
|
|
commit 7be459fa531b1284408bf16616422b8dbf193278
|
|
Author: Mark Wielaard <mark@klomp.org>
|
|
Date: Wed Apr 11 10:37:45 2018 +0200
|
|
|
|
aarch64: Add default cfi rule to restore SP from CFA address.
|
|
|
|
The CFA is set by default to the stack pointer of the previous frame.
|
|
So that is also how we can always restore the SP. This default aarch64
|
|
CFI rule is necessary on Fedora 28 with GCC8 to make the run-deleted.sh
|
|
and run-backtrace-dwarf.sh testcases work.
|
|
|
|
Signed-off-by: Mark Wielaard <mark@klomp.org>
|
|
|
|
diff --git a/backends/aarch64_cfi.c b/backends/aarch64_cfi.c
|
|
index acbb9b6..a5579ab 100644
|
|
--- a/backends/aarch64_cfi.c
|
|
+++ b/backends/aarch64_cfi.c
|
|
@@ -1,5 +1,5 @@
|
|
-/* arm ABI-specified defaults for DWARF CFI.
|
|
- Copyright (C) 2013 Red Hat, Inc.
|
|
+/* arm64 ABI-specified defaults for DWARF CFI.
|
|
+ Copyright (C) 2013, 2018 Red Hat, Inc.
|
|
This file is part of elfutils.
|
|
|
|
This file is free software; you can redistribute it and/or modify
|
|
@@ -62,6 +62,9 @@ aarch64_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info)
|
|
/* The Frame Pointer (FP, r29) and Link Register (LR, r30). */
|
|
SV (29), SV (30),
|
|
|
|
+ /* The Stack Pointer (r31) is restored from CFA address by default. */
|
|
+ DW_CFA_val_offset, ULEB128_7 (31), ULEB128_7 (0),
|
|
+
|
|
/* Callee-saved fpregs v8-v15. v0 == 64. */
|
|
SV (72), SV (73), SV (74), SV (75),
|
|
SV (76), SV (77), SV (78), SV (79),
|
|
diff --git a/tests/run-addrcfi.sh b/tests/run-addrcfi.sh
|
|
index 376a6dc..fd89d02 100755
|
|
--- a/tests/run-addrcfi.sh
|
|
+++ b/tests/run-addrcfi.sh
|
|
@@ -3637,7 +3637,7 @@ dwarf_cfi_addrframe (.eh_frame): no matching address range
|
|
integer reg28 (x28): same_value
|
|
integer reg29 (x29): same_value
|
|
integer reg30 (x30): same_value
|
|
- integer reg31 (sp): undefined
|
|
+ integer reg31 (sp): location expression: call_frame_cfa stack_value
|
|
integer reg33 (elr): undefined
|
|
FP/SIMD reg64 (v0): undefined
|
|
FP/SIMD reg65 (v1): undefined
|