1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-12-22 19:43:42 +01:00
Commit graph

3024 commits

Author SHA1 Message Date
Konstantin Baladurin
ac02808556 dwarf/Gparser: fix crash during unwinding (#44)
We should update locations of the registers after all of them will
be restored. Otherwise some locations will be incorrect.

For example if function stores ebp, edi, esi and ebx registers on
stack in its prologue, compiler can generate following unwind info:
DW_CFA_expression: r5 (ebp) (DW_OP_breg5 (ebp): 0)
DW_CFA_expression: r7 (edi) (DW_OP_breg5 (ebp): -4)
DW_CFA_expression: r6 (esi) (DW_OP_breg5 (ebp): -8)
DW_CFA_expression: r3 (ebx) (DW_OP_breg5 (ebp): -12)

In this case locations of the ebx and ebp will be calculated using
current ebp but locations of the esi and edi will be calculated using
previous (restored) one. Due to it their locations will be incorrect
and it could lead to crash if we will try to get esi or edi value.

This patch fixes this problem.
2017-10-17 11:27:53 -07:00
Dave Watson
5f354cb7b9 mips/tilegx: Add missing unwind_i.h header file
reported-by: John Knight <John.Knight@belkin.com>
2017-01-25 16:28:38 -08:00
Christopher Ferris
620d1c3b0b Add aarch64 getcontext functionality.
Change-Id: I32912a85c0fd02bb5e45a9eb7deb2410ded352a9
2017-01-25 16:28:29 -08:00
Dave Watson
cc247fc0a2 Bump version to 1.2 2017-01-13 08:02:53 -08:00
Ulrich Weigand
c56fb8f99e ppc64: Fix serious regression (many crashes in test suite)
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>
2015-12-06 11:10:10 -08:00
Keno Fischer
8afc33ce9f Add an option to have start_ip_offset be relative to start_ip
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.
2015-09-15 12:18:30 -07:00
Alexander Esilevich
d1a8ca6d84 powerpc64 implementation 2015-09-07 18:08:26 -07:00
Arun Sharma
923fa78e79 Revert parts of 68a2910
The check breaks a few tests when used with gold.
2015-09-07 17:59:27 -07:00
Arun Sharma
396b6c7ab7 Invalid dwarf opcodes can cause references beyond the end of the array. 2015-06-19 19:47:22 -07:00
Milian Wolff
b2db825e8a Update README to use autogen.sh 2015-06-07 12:23:42 -07:00
Vyacheslav Barinov
7701522688 arm: Validate memory before access
Prevent SIGSEGV due to accessing addresses now mapped to current process

Signed-off-by: Vyacheslav Barinov <v.barinov@samsung.com>
2015-06-07 12:17:40 -07:00
Faraz Shahbazker
16bf4e5e49 Stack-unwinding through signal frames on mips
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.
2015-04-02 11:20:33 -07:00
Andreas Schwab
544cdb3b43 tests/Gtest-trace.c: show differing addresses 2015-03-22 00:05:14 -07:00
Gregory Fong
0bed10aa21 Mark run-ptrace-mapper and run-ptrace-misc as XFAIL on ARM
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>
2015-02-21 13:00:34 -08:00
Peter Wu
68a2910bae Check that the CIE is within the segment
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>
2014-12-05 23:39:48 -08:00
Olivier Fourdan
6e3254ea6e [PATCH] Fix build from scratch
- 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>
2014-12-04 00:12:00 -08:00
Victor Kamensky
16e98c8cf3 aarch64: fix wrong big_endian flag in aarch64_be case
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>
2014-12-03 23:28:07 -08:00
Victor Kamensky
743668f669 aarch64: introduce build support for aarch64_be target
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>
2014-12-03 23:26:27 -08:00
C. Bergström
3babc1d148 aarch64: Restore x0, x1, x2 and x3
These registers contain the exception pointer and selector.
2014-10-24 22:40:19 -07:00
Simon Atanasyan
c90a2e02b3 Mark run-ptrace-mapper and run-ptrace-misc as XFAIL on MIPS
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>
2014-10-24 22:31:05 -07:00
Paul Pluzhnikov
1bca6eb8ea Remove unnecessary calls to labs()
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
2014-10-24 22:29:15 -07:00
Simon Atanasyan
5b37b3cff1 Fix intermittent failures of Lrs-race test case
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>
2014-10-24 22:05:46 -07:00
Arun Sharma
44b867c650 Store location type in local unwinding mode for x86_64
Helps support DW_CFA_val_expression
2014-10-04 09:04:08 -07:00
Arun Sharma
781d5d5263 One time whitespace fixup.
for f in $(find src include -name '*.[ch]'); do
  expand -t 8 $f > $tmp; mv $tmp $f;
done
2014-09-27 09:47:23 -07:00
Arun Sharma
06e608d043 Merge branch 'fast-stack-trace-arm' of https://github.com/fillexen/libunwind 2014-09-20 08:09:55 -07:00
Arun Sharma
6046c87d8e Merge branch 'fast-stack-trace-aarch64' of https://github.com/fillexen/libunwind 2014-09-20 08:09:35 -07:00
Arun Sharma
5d79a12ec0 Merge https://github.com/zliu2014/libunwind-tilegx 2014-09-20 00:47:23 -07:00
Zhi-Gang Liu
790be1e40d Add TileGx platform support to libunwind.
"make check" passed.
======================================================
All 34 tests behaved as expected (2 expected failures)
======================================================
Zhi-Gang Liu @ Tilera
2014-09-08 16:21:53 -04:00
Arun Sharma
0808aa6737 Stop unwinding on undefined return address
Milian Wolff <mail@milianw.de> reported that this greatly
improved unwinding perf on some his apps.
2014-09-07 03:32:57 -07:00
Arun Sharma
4791a76d26 Fix compiler warnings when UNW_DEBUG is enabled
Newer versions of gcc complain when ALWAYS_INLINE is used without
inline.
2014-08-19 07:53:57 -07:00
Лежанкин Иван
9e0d6b1e08 Fix empty structs in libunwind-x86_64.h
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:
2014-08-19 07:42:48 -07:00
Paul Pluzhnikov
e63cadf76d Remove unnecessary calls to labs()
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
2014-08-15 13:01:47 -07:00
Konstantin Belousov
dbce594d33 Correct name returned by get_proc_name() for some frames.
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.
2014-08-15 13:01:40 -07:00
Konstantin Belousov
3723511003 Adjust use_prev_instr for syscall and frame-chain frames.
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.
2014-08-15 13:01:36 -07:00
Konstantin Belousov
85946d9766 Use helper to walk past the syscall frames on FreeBSD/x86, similar to FreeBSD/x86_64.
The syscall trampolines in FreeBSD libc do not have unwind annotations.
2014-08-15 13:01:33 -07:00
Thierry Reding
f1684379df Link libunwind to libgcc_s rather than libgcc
For some architectures, -lgcc and -lgcc_s are not equivalent. On ARM for
example, libgcc_s.so.1 contains some symbols needed by libunwind which
are not present in libgcc.

This causes the following link error when building the X.Org X server
with libunwind support:

	  CCLD     Xorg
	/usr/lib/libunwind.so: undefined reference to `__aeabi_unwind_cpp_pr0'
	/usr/lib/libunwind.so: undefined reference to `__aeabi_unwind_cpp_pr1'

Linking against libgcc_s explicitly solves this problem.

Signed-off-by: Thierry Reding <treding@nvidia.com>
2014-08-15 13:01:29 -07:00
Filip Nyback
93d8272481 Add fast stack trace on AArch64.
Port of the fast stack trace feature to AArch64.
2014-07-30 14:34:31 +03:00
Filip Nyback
e1804829ca Add fast stack trace on ARM.
Port of the fast stack trace feature to ARM.
2014-07-30 14:25:14 +03:00
Martin Milata
65ac867416 Do not compute load offset for MiniDebugInfo
We already have the value computed based on the executable. Furthermore,
debuginfo need not have valid program header table, thus the result
might be bogus.

Signed-off-by: Martin Milata <mmilata@redhat.com>
2014-06-07 18:07:06 -07:00
Kevin Modzelewski
4509adb853 x86_64: Handle edge conditions with zero length frames
When JITs generate code without unwind information, it may be possible
to continue unwinding via RBP chaining. However, we currently disallow
RBP==RSP condition even though we can make forward progress.

Relax the check a bit in the code where we switch from one type of
unwinding to another to handle this situation. JIT authors
are encouraged to use the dynamic unwind info registration API when
the underlying platform supports it.

Signed-off-by: Kevin Modzelewski <kmod@dropbox.com>
2014-05-18 19:39:26 -07:00
Christopher Ferris
2cb00c1eac AARCH64: Change Debug calls to use %lx instead of %x.
The attached patch simply modifies the Debug statements for aarch64 to use
%lx instead of %x. Tested by compiling for aarch64 using a cross-compiler.

Signed-off-by: Christopher Ferris <cferris@google.com>
2014-03-07 22:52:24 -08:00
Mike Frysinger
385c19f335 link sublibs against liblzma as needed
The coredump/elf32/elf64/elfxx libs use lzma funcs but don't link against
it.  This produces sub-shared libs that don't link against lzma and can
make the linker angry due to underlinking like so:

libtool: link: x86_64-pc-linux-gnu-gcc -O2 -march=amdfam10 -pipe -g \
	-frecord-gcc-switches -Wimplicit-function-declaration -fexceptions \
	-Wall -Wsign-compare -Wl,-O1 -Wl,--hash-style=gnu \
	-o .libs/test-coredump-unwind test-coredump-unwind.o  \
	../src/.libs/libunwind-coredump.so ../src/.libs/libunwind-x86_64.so
../src/.libs/libunwind-coredump.so: error: undefined reference to 'lzma_stream_footer_decode'
../src/.libs/libunwind-coredump.so: error: undefined reference to 'lzma_index_buffer_decode'
../src/.libs/libunwind-coredump.so: error: undefined reference to 'lzma_index_size'
../src/.libs/libunwind-coredump.so: error: undefined reference to 'lzma_index_end'
../src/.libs/libunwind-coredump.so: error: undefined reference to 'lzma_index_uncompressed_size'
../src/.libs/libunwind-coredump.so: error: undefined reference to 'lzma_stream_buffer_decode'
collect2: error: ld returned 1 exit status

So add LIBLZMA to the right LIBADD for each of these libraries.

URL: https://bugs.gentoo.org/444050
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
2014-02-22 10:53:39 -08:00
Tim Deegan
4eb880e1b5 Implement DWARF DW_CFA_val_expression for x86_64
Ubuntu's libc-bin (2.15-0ubuntu20.2) on x86_64 uses DW_CFA_val_expression
in describing the pthread spinlock operations __lll_unlock_wake() and
__lll_lock_wait().  libunwind 1.1 doesn't understand that opcode and
so backtraces from those operations are truncated.

This changeset adds basic support for it, by adding a new type to
dwarf_loc_t that describes the register's actual contents rather than
its location.  I've only implemented the new type for x86_64, and
stubbed it out for all other architectures -- it looks like a lot
of that code is duplicated so oughtn't to be that hard, but I don't
have test cases for them.

Tested that DW_CFA_val_expression works on x86_64 (by using
https://code.google.com/p/gperftools/ on a lock-heavy program).
Build-tested on x86, x86_64 and arm.  The unit tests don't pass for me
on any of those archs, but this cset doesn't break anything that was
passing before.

Signed-off-by: Tim Deegan <tjd@phlegethon.org>
2014-02-08 20:19:20 -08:00
Tim Deegan
11a7d98e39 Missing header in dist tarball.
Signed-off-by: Tim Deegan <tjd@phlegethon.org>
2014-02-08 19:47:17 -08:00
Ulrich Weigand
da0b1a146f Support powerpc64le-linux platform
This patch adds support for the powerpc64le-linux platform.  It consists
of two main features:

- Support little-endian byte order
  This is done via a "big_endian" member of struct unw_addr_space,
  which is evaluated by common code via the dwarf_is_big_endian
  macro, and also in endian-aware code in unw_is_signal_frame.

- Support the ELFv2 ABI
  This is done via an "abi" member of struct unw_addr_space.  This
  is currently only needed in tdep_get_func_addr, since the ELFv2
  ABI does not use function descriptors.

Both new members are initialized in unw_create_addr_space and
ppc64_local_addr_space_init, following the mips precedent.

Since ppc32 and ppc64 now no longer share the unw_create_addr_space
implementation, the file is duplicated from the ppc directory into
ppc32/ppc64.

Tested on powerpc64-linux and powerpc64le-linux.  Support on LE
seems to be as good as existing BE support; I have not attempted to
fix the existing shortcomings of PPC support that already cause a
number to tests to fail due to unimplemented features.

Signed-off-by: Ulrich Weigand <uweigand@de.ibm.com>
2013-12-27 07:09:06 -08:00
Ulrich Weigand
4c62c4a955 Fix test case link failure on PowerPC systems with Altivec
On systems where the system compiler supports Altivec by default,
the libunwind Makefile will attempt to build an extra test case
ppc64-test-altivec.  Unfortunately, the link step will fail since
the Makefile does not actually link against the libunwind library.

Fixed by adding the appropriate LDADD macro.

Signed-off-by: Ulrich Weigand <uweigand@de.ibm.com>
2013-12-27 07:08:50 -08:00
Ulrich Weigand
844f1b84cc Pass relocated address to tdep_get_func_addr
The ppc64 implementation of tdep_get_func_addr would crash when
attempting to retrieve the address of a function in a shared
library.  The problem was that it needs to dereference the
function descriptor, but common code was passing the *unrelocated*
adddress of the descriptor to the tdep_get_func_addr routine.

Instead, common code would attempt to relocate the *result* of
tdep_get_func_addr, which is also wrong: the ppc64 implementation
reads the function address from the in-memory copy of the
descriptor, which is already relocation and contains the final
address.

This patch fixes the problem by relocating the descriptor address
before passing it to tdep_get_func_addr, instead of relocating
the result of tdep_get_func_addr.  Since ppc64 is the only
non-trivial implementation of tdep_get_func_addr, this cannot
affect any other platform.

Signed-off-by: Ulrich Weigand <uweigand@de.ibm.com>
2013-12-27 07:08:43 -08:00
Ulrich Weigand
5710c98fbf Fix undefined behavior in dwarf_eval_expr
The dwarf_eval_expr routine uses macros push, pop, and pick to
manipulate the DWARF expression stack.  When these macros are
nested, e.g. in the implementation of DW_OP_dup:
          push (pick (0));
the combination can lead to unfortunate results.

In particular, when substituting into:
do {
  if (tos >= MAX_EXPR_STACK_SIZE)
    {
      Debug (1, "Stack overflow\n");
      return -UNW_EINVAL;
    }
  stack[tos++] = (x);
} while (0)
a value of "x" that makes use of "tos" (as instances of the
pick or pop macros do), the resulting expression will both
use and modify tos without an intervening sequence point,
which is undefined behavior according to the C standard.

And in fact with current GCC on PowerPC, this leads to a
miscompilation of the DW_OP_dup implementation.

This patch fixes the problem by assigning "x" to a
temporary variable before modifying tos.

Signed-off-by: Ulrich Weigand <uweigand@de.ibm.com>
2013-12-27 07:07:48 -08:00
Arun Sharma
85ce920cff Use adaptive mutexes when available. 2013-11-17 20:33:33 -08:00
Masatake YAMATO
2c3444d0f4 Remove one of duplicated declarations of `get_proc_name'
Declarations of `get_proc_name' of is duplicated.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
2013-09-25 07:39:16 -07:00