1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-12-01 18:57:38 +01:00
Commit graph

416 commits

Author SHA1 Message Date
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
Tommi Rantala
ee8df26288 Constify `dwarf_to_unw_regnum_map' 2012-09-28 14:50:03 +03:00
Tommi Rantala
fca254a9b4 IA64: give prototype for `ia64_find_unwind_table()'
src/ptrace/_UPT_find_proc_info.c: In function 'get_unwind_info':
src/ptrace/_UPT_find_proc_info.c:67: warning: implicit declaration of function 'ia64_find_unwind_table'
2012-09-28 14:50:03 +03:00
Tommi Rantala
8d5b1aeeff SuperH port
Add support for the 32bit SuperH architecture running Linux.
Specifically, support is added for SH4, and support for earlier SH
versions and to the 64bit SH5 are left out. This was tested in qemu with
a little-endian SH4 debian image & GCC 4.7 cross compiler.
2012-09-28 14:50:03 +03:00
Tommi Rantala
79c2c254a7 MIPS coredump support
Add MIPS support to the coredump library. Explicit support for the MIPS
program counter register is added so that we can start backtracing from
the program counter value we read from a core dump. The PC register
support was not strictly required for local backtracing, and we will in
fact just plug the return address to the PC register in getcontext().

I have only tested the 32bit "OABI" paths.
2012-09-28 14:50:03 +03:00
Tommi Rantala
5d0f376b08 Invert tdep_init() flag logic
Invert the flag that signals that tdep_init() was called, to move the
symbol from data to BSS.
2012-09-28 14:06:07 +03:00