A recent commit added code to override the unwind location for the
TOC pointer register r2:
unsigned int *inst = (unw_word_t*)c->dwarf.ip;
if (*inst == (0xE8410000 + 24)) {
// @plt call, restoring R2 from CFA+24
c->dwarf.loc[UNW_PPC64_R2] = DWARF_LOC(c->dwarf.cfa + 24, 0);
}
It is correct that such code is needed, since DWARF CFI does not
describe the unwind location for r2 on PowerPC. However, this
particular bit of code has a number of issues, which are fixed
in this patch.
First of all, the location CFA+24 is correct only for the ELFv2
ABI. In the ELFv1 ABI, the TOC location is actually CFA+40.
More problematically, attempting to read the current instruction
by just dereferencing the address in c->dwarf.ip is wrong, and
may often lead to crashes. In particular:
- During remote unwinding, this is always wrong since we're in
the wrong address space. I've used the fetch32 helper from
remote.h to use the proper access_mem under the covers.
- c->dwarf.ip may be NULL if we've reached the end-of-stack.
I've fixed this by moving the c->dwarf.ip == 0 check down
to after unwinding (instead of before), just like all other
platforms do.
- Even so, c->dwarf.ip may point to some random location if
we've gotten confused during unwinding earlier. One likely
cause for such confusion is that we did not find DWARF CFI
for some earlier frame and attempted to use the stack
backchain. The problem is that this code currently claims
all registers remain unchanges in such a frame, which is
generally wrong. In particular if the function actually
saves and modifies r31, and this is used as frame pointer
by a later frame, things will likely go quite wrong. While
it is not really possibly to completely fix this, I've at
least marked all registers as unavailable after unwinding
a frame via stack backchain.
Tested on powerpc64-linux and powerpc64le-linux. The patch fixes
about a dozen test cases that were crashing before.
Signed-off-by: Ulrich Weigand <ulrich.weigand@de.ibm.com>
By default, the start_ip_offset in libunwind's table_entry struct is
relative to the unw_dyn_info_t's segbase. This presents a problem
for us in conjunction with using LLVM's MCJIT because it likes to
spread text sections and the corresponding eh_frame sections quite
far apart. This represents my attempt to support this use case in the
simplest manner that is backwards compatible, by adding a new format
kind (UNW_INFO_FORMAT_REMOTE_TABLE2) that indicates that the
`start_ip_offset` should be interpreted as relative to `start_ip`
rather than segbase.
Detect if current frame is a signal frame by checking for preceeding
syscall instruction. For signal frames, update the cursor correctly
from user context before calling dwarf_step.
This is similar to commit c90a2e02b3
"Mark run-ptrace-mapper and run-ptrace-misc as XFAIL on MIPS".
Starting with 2.6.39, ARM Linux returns -EIO for PTRACE_SINGLESTEP, so
we need to mark this as XFAIL for ARM too.
The Linux commit that changed this is
commit 425fc47adb5bb69f76285be77a09a3341a30799e
Author: Will Deacon <will.deacon@arm.com>
Date: Mon Feb 14 14:31:09 2011 +0100
ARM: 6668/1: ptrace: remove single-step emulation code
see: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=425fc47adb5bb69f76285be77a09a3341a30799e
Signed-off-by: Gregory Fong <gregory.0xf0@gmail.com>
Due to a bug in the gold linker[1], the .eh_frame and .eh_frame_hdr
sections contains garbage. When dwarf_extract_proc_info_from_fde tried
to look up the begin of the CIE subsection, it would underflow the
.eh_frame segment, resulting in a crash[2].
This patch avoids that crash by checking whether the CIE pointer is
located after the begin of the .eh_frame section. The variable "base"
was misused in various places as a boolean (decode as .debug_frame or
decode as .eh_frame). These instances have been renamed to
is_debug_frame where applicable.
Tested on Linux x86_64.
[1]: https://sourceware.org/bugzilla/show_bug.cgi?id=17639
[2]: http://lists.nongnu.org/archive/html/libunwind-devel/2014-11/msg00009.html
Signed-off-by: Peter Wu <peter@lekensteyn.nl>
- Add autogen.sh to bootstrap autotools generation
- Make generation of man pages optional, and check for
availibity of latex2man if documentation is requested.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Arun Sharma <asharma@fb.com>
Set local_addr_space.big_endian flag according to current target
endianness. Before it was set by memset to 0, which corresponds
to little endian and it worked perfectly fine for aarch64.
But it breaks aarch64_be because dwarf_readu16, dwarf_readu32,
etc functions do not read values correctly since they operate
with wrong idea about current target endianness.
Signed-off-by: Victor Kamensky <victor.kamensky@linaro.org>
Introduce support for aarch64_be, aarch64 big endian, target.
We would like to reuse all code that was done for aarch64
(little endian) target. So we do similar thing that is done
for ARM v7 (arm) target for any aarch64* arch we set it
just to aarch64.
Signed-off-by: Victor Kamensky <victor.kamensky@linaro.org>
Though PTRACE_SINGLESTEP is defined on MIPS Linux, the kernel does
not support that kind of request. The ptrace call failed and sets
errno to EIO and paused process is not resumed. In case of
run-ptrace-mapper and run-ptrace-misc this leads to hanged execution
because next call to wait4 never returns.
This change adds run-ptrace-mapper and run-ptrace-misc to the list
of 'expected failed' tests on MIPS targets.
Signed-off-by: Simon Atanasyan <simon@atanasyan.com>
We've just traced a large memory increase to that patch (Google ref:
b/18069427).
It appears that labs() was there for a good reason.
Sorry about that :-(
For the curious:
unsigned long u1 = ~0UL;
unsigned long u2 = labs(u1);
assert(u1 != u2); // labs on unsigned *may* have an effect, despite
what Clang says.
Attached patch suppresses the Clang warning, while still keeping the
original behavior (which I believe to be correct).
Thanks,
--
Paul Pluzhnikov
After the following change the Lrs-race test case starts to intermittently
fails:
eac65dc Add basic support for the QNX operating system
When we include "config.h" into the "libunwind_i.h" we undefine
the HAVE___THREAD macro in a few lines below in #include "config.h"
pragma. The change eac65dc includes "config.h" into the "dwarf.h"
but forgets to undefine HAVE___THREAD. So now this macro has inconsistent
state among the code. Somewhere it is defined, somewhere not. In particular
it becomes defined in the mi/Gset_caching_policy.c and we do not replace
UNW_CACHE_PER_THREAD caching policy by the UNW_CACHE_GLOBAL.
The fix is rather dirty. It adds the code to undefine HAVE___THREAD in
the "dwarf.h" like we do that in the "libunwind_i.h". Probably the ideal
solution should fix per-thread caching implementation or turned it off
at all on platforms where it is not completely and correctly supported.
Signed-off-by: Simon Atanasyan <simon@atanasyan.com>
Hi,
there is a compilation issue with Clang and latest libunwind - It's
about "typedef struct unw_tdep_save_loc" and one more struct:
include/libunwind-x86_64.h:111:9: error: empty struct has size 0 in C,
size 1 in C++ [-Werror,-Wextern-c-compat]
The solution is very simple:
Greetings,
Roman reports that Clang warns on unnecessary calls to labs():
taking the absolute value of unsigned type 'unw_word_t' (aka
'unsigned long') has no effect [-Werror,-Wabsolute-value]
Since rs->reg[...].val is unw_word_t and unsigned on all platforms,
this patch removes the unnecessary calls to labs().
Tested on Linux x86_64, no regressions.
Thanks,
--
Paul Pluzhnikov
Fix returning the name of the function containing the frame PC,
for the non-interrupted frames. The symbol lookup code should
take use_prev_instr value into account, otherwise it could return
the name of the function adjacent to the caller.
Mark frames which are unwound with the frame-chain walker or
syscall frame code, as non-interrupted. The return PC in the frame
points to the instruction after the call.