1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-07-02 13:41:46 +02:00
Commit graph

421 commits

Author SHA1 Message Date
Stephen Chen 2934cf4052 aarch64: reduce UNW_TDEP_CURSOR_LEN to 512 on aarch64.
This allows libunwind to work in situations with limited stack size (ie. fibers). 512 is still more than enough for storing the cursor with some slack. (#25)
2017-06-20 09:49:16 -07:00
Doug Moore 0e74e583ae arm: Use dwarf_find_proc_info for arm dwarf processing
Rather than using a copy of dwarf_find_proc_info that differs from it slightly.
By using dwarf_find_proc_info, a potential search of the di table is
allowed, where it is omitted now.  Also, for ARM, avoid runtime
checks about which kind of unwind table search to use after dl_iterate_phdr.

A couple of Debug() warnings about ip lookup failure are lost here.
The dwarf callback struct defintion is moved to Gfind_proc_info-lsb.c,
which becomes the only source file that needs it.
2017-06-20 09:47:54 -07:00
Doug Moore 0b51f5892d Dwarf cache nodes are allocated in a round-robin fashion, despite the
'lru' prefix used in several data fields.  Drop the unnecessary fields,
and just use a simple counter to track the next cache entry to be recycled.
2017-06-16 08:53:36 -07:00
Doug Moore 27f5f9fa0b Leave ret_addr_column out of the data that gets copied when pushing/popping
data on/off the register state stack.
2017-05-20 14:36:25 -05:00
Doug Moore c66661f73c Drop reference to dwarf.ret_addr_column. 2017-05-19 19:19:12 -05:00
Doug Moore ec1a021243 Move the ret_addr_column field from dwarf_reg_cache_entry to dwarf_reg_state,
so that it will get saved and restored with the register state.  Initialize
the rs_state version of ret_addr_column at the some time the dwarf_cursor
version is initialized, and don't bother copying ret_addr_column explicitly
from cursor to cache since it's copied implicitly as part of reg_state.
Use the reg_state version in apply_reg_state, instead of the cursor version.

Which brings up the question: why do we have ret_addr_column in the dwarf_cursor?
We call find_reg_state before calling apply_reg_state, so the value of ret_addr_column
in the cursor when dwarf_step gets called gets overwritten before it is used.  So
it's initial value doesn't matter.  But some architectures do funky things with
cursor->ret_addr_column, even though I don't see how they matter.

So I'm not deleting dwarf_cursor->ret_addr_column, even though I suspect this
patch makes it useless.
2017-05-16 22:00:38 -05:00
Doug Moore 028a60f064 Change dwarf_reg_state from an array of pairs of differently-sized objects
to a pair of arrays, to reduce internal fragmentation.  Reduces storage
use by 37.5% on x86_64.
2017-05-16 17:40:58 -05:00
Doug Moore bb61e0bc2b Bury the last_ip field until it can reappear in version 2.0. 2017-05-12 23:45:56 -05:00
Doug Moore fef5de6c45 Move ret_addr_column and signal_frame from dwarf_reg_state to
dwarf_reg_cache_entry, leaving in dwarf_reg_state only what
apply_reg_state needs.
2017-05-12 22:24:00 -05:00
Doug Moore a7c65f5c3e Remove next field from dwarf_reg_state. Create new struct
that includes next field and dwarf_reg_state, and use that
strictly for stack push/pop in run_cfi_program.
2017-05-12 22:24:00 -05:00
Doug Moore 3888b2bbcb In dwarf_apply_reg_state change from dewarf_reg_state_t back to struct dwarf_reg_state. 2017-05-12 22:24:00 -05:00
Doug Moore 502ba27753 Add a function to capture the dwarf_reg_states that occur in processing
the dwarf code for a procedure, and a function to apply a captured
dwarf_reg_state later.
2017-05-12 22:24:00 -05:00
Doug Moore bbdc4b12da Capture the address of the first byte after the instructionless gap
that follows the procedure.
2017-05-12 22:24:00 -05:00
Doug Moore 50a457abb0 Pull cache-related fields out of reg_state, and put them into reg_cache struct. 2017-05-12 22:23:59 -05:00
Doug Moore 59ecb24ca2 dwarf:Drop dwarf_create_state_record.
In dwarf_make_proc_info, fix a leak in the case that create_state_record fails.
2017-04-28 09:59:22 -07:00
Paul Pluzhnikov f819f1b87c ppc: fix inverted check 2017-04-05 12:00:21 -07:00
Paul Pluzhnikov 7a7833ee0a ppc: return UNW_INVALID instead of assert on unaligned addresses
In src/ppc64/Gstep.c, we use fetch32 to fetch instruction from the
inferior process. In  UNW_REMOTE case, fetch32 asserts that the
address we are fetching from is aligned.

But if the inferior is corrupt, we can get unaligned IP, and hit the assert.

Attached patch removes the assert, and makes fetch32 (and fetch16)
return -UNW_EINVAL instead.
2017-04-05 11:14:04 -07:00
Doug Moore 14c48b3d51 unw_init_local_signal
init_local, but *not* setting use_prev_instr.
This is necessary to correctly unwind using ucontext argument to signal handlers.
2017-04-03 14:44:40 -07:00
Vicente Olivert Riera d9a8b23a35 mips: support MIPS64 n32 mode
The attached patch fixes a problem with Xorg on MIPS64 n32 which is explained here:
https://bugs.freedesktop.org/show_bug.cgi?id=79939

Basically, libunwind is using a word size of 64-bit for all MIPS variants.
Then, Xorg does a casting to (void *) of a 64-bit variable provided by
libunwind. Given that the size of the pointers in MIPS64 n32 is 32-bit wide,
that casting causes an error like this one:

backtrace.c:90:20: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
2017-03-02 08:02:50 -08:00
Rene Nielsen 2a5d1a6296 mips: remote unwind support
libunwind already had support for local unwind on a MIPS. This patch makes
support for remote unwinding on a MIPS.

I should add a few words to the changes to _UPT_access_mem.c: On MIPS, an
unw_word_t is defined as a 64-bit integer whether it's compiled for a 32- or a
64-bit MIPS.

When doing remote unwinding using the default _UPT_accessors, dwarf_readu8()
therefore expects _UPT_access_mem() to return a 64-bit integer. However, if
compiled on a 32-bit MIPS, only 32 bits are valid upon return from
_UPT_access_mem(). The patch detects this and will in this case perform two
calls to ptrace(PTRACE_POKE/PEEK_DATA) and organize the return value according
to endianness.
2017-03-02 08:02:41 -08:00
Rene Nielsen cfd4306cc7 mips: fix compiler warnings
This fixes a number of compiler warnings I got when compiling for mips32el with
gcc 5.3.0.
2017-02-14 08:18:49 -08:00
Christopher Ferris cf6382643e Add aarch64 getcontext functionality.
Change-Id: I32912a85c0fd02bb5e45a9eb7deb2410ded352a9
2017-01-24 11:08:28 -08:00
Konstantin Belousov 9e97c9b17a dwarf: Make binary path calculation os-specific.
/proc/self/exe only works on Linux, move path computation to os-* files
2017-01-19 10:07:13 -08:00
Dave Watson a51cf49031 dwarf: Configurable cache size
Add interface for configurable dwarf cache size

* Use item size and round up to nearest power of 2.
* Initial cache still exists in BSS.  Without this, it means we would fail
  backtrace when out of memory.  The test-mem test fails without this
2017-01-13 08:36:33 -08:00
Dave Watson f7fe1c9a7e x86_64: Add stack alignment prologue tdep_trace fastpath
GCC versions 4.9~current will often generate stack alignment prologues like:

lea 0x8(%rsp),%r10
and $0xfffffffffffffff0,%rsp
...
push %rbp
mov %rsp, %rbp
push %r10

resulting in dwarf expressions:
DW_CFA_def_cfa_expression (DW_OP_breg6: -8; DW_OP_deref)
DW_CFA_expression: r6 (rbp) (DW_OP_breg6: 0)

These prologues seem to be generated for SSE/AVX code, but sometimes
other times as well.

tdep_trace fastpath currently falls back to the slow dwarf parsing path
if it encounters any cfa_expressions. Unfortunately this is happening
often enough in our codebase to cause perf issues.  We could also fix the
fallback path (make the rs cache bigger, lock-free instead of locking, etc),
but that seems like a separate issue, and it will ever be as fast as the tracing
code.   Our binaries each have at least ~100 functions in them like this.

This patch teaches the tdep_trace about the two specific cfa_expressions,
which really just result in a single extra memory dereference of the stack
at a fixed offset from rbp.
2017-01-13 08:28:21 -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 396b6c7ab7 Invalid dwarf opcodes can cause references beyond the end of the array. 2015-06-19 19:47:22 -07: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
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
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 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
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
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
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
Arun Sharma 85ce920cff Use adaptive mutexes when available. 2013-11-17 20:33:33 -08:00
Matt Fischer eac65dc9b8 Add basic support for the QNX operating system
This change adds some special cases to allow libunwind to compile
for QNX.

* QNX's copy of <elf.h> and <link.h> reside in sys/ instead.  To deal
  with this, an AC_CHECK_HEADERS() was added to check for the files
  in both locations.
* Similarly, QNX does not have <endian.h>.  In cases where the file is
  not found, logic was added to refer to QNX-specific macros to determine
  endianness.
* The QCC compiler, which is a wrapper around GCC, cannot handle some
  standard GCC options.  Therefore, logic was added to check for QCC,
  and when it is found, to suppress the use of -lgcc, and to express the
  option -nostartfiles as -Wc,-nostartfiles instead, which is correctly
  passed on to the underlying GCC.
* Finally, the support file os-qnx.c was added, patterned after the existing
  os-*.c files.  Only local image lookup is currently supported (see the
  comments for more information), but this is sufficient for QNX, since
  ptrace is not supported there anyway, and that is the only case where the
  function is required to do remote image lookup.

Change-Id: Ie7934f94a7317bdde59335f2acd4c3a97c0384c1
2013-05-13 10:50:17 -05:00
Yvan Roux ac6c0a6535 [PATCH] AArch64 port. 2013-05-11 09:20:28 -06:00
Dave Lerner becfc23123 Fix the UNW_TDEP_CURSOR_LEN for ppc32 to fix assert failure
When libunwind is built for a ppc32 target, for example the yocto distro
for qemuppc, and configured with options --enable-debug-frame and
--enable-debug, then the shortfall in the size of the 'opaque' member
of the unw_cursor_t type throws an assert in mi_init().

The calculations for the ppc32 target size of UNW_TDEP_CURSOR_LEN in
the comment block based on the register count plus overhead sum to 280
words. However, that value is not reflected in the ppc32 header, which
defines the size as 200.  Fixing the ppc32 header value to 280 makes the
unw_cursor_t type larger than struct cursor type and the assert tests
true at run-time in mi_init().

Signed-off-by Dave Lerner <dave.lerner@windriver.com>
2013-04-13 11:47:18 -07:00
Ladislav Michl 10b064ffe9 Support building with older compilers.
Add a check for __builtin_unreachable.
2012-11-24 21:37:07 -08:00
Tommi Rantala 890e23eb9d Prefer NULL over zero 2012-09-28 14:51:21 +03:00
Tommi Rantala 7d471b1440 Define and use `CONST_ATTR' 2012-09-28 14:51:21 +03:00
Tommi Rantala e0653f9e3a Define and use `WEAK' 2012-09-28 14:51:21 +03:00
Tommi Rantala e3e49dc28a Define and use `NOINLINE' 2012-09-28 14:51:19 +03:00