1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-29 18:27:37 +01:00
Commit graph

1836 commits

Author SHA1 Message Date
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
4184bb478a Restore a dwarf-free "apply_reg_state" function. 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
06d230d732 Merge dwarf_find_save_locs into dwarf_step. 2017-05-12 22:24:00 -05:00
Doug Moore
1602987b5f Extract 'find_reg_state' from dwarf_find_save_locs. 2017-05-12 22:23:59 -05:00
Doug Moore
04db2b7cea The call to put_unwind_info is what makes pi invalid, so clear the
valid bit here, and soon stop bothering to clear it in other places.
2017-05-12 22:23:59 -05:00
Doug Moore
1c76d41939 Pass in a pointer to the address where run_cfi_program will start,
or resume, its decoding, rather than always starting at the procedure
start, so that resuming a cfi_program becomes possible.
2017-05-12 22:23:59 -05:00
Doug Moore
7a962b951b Create setup_fde, and put all the one-time parts of fde processing there. 2017-05-12 22:23:59 -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
Doug Moore
3775cdd997 dwarf: Avoid a leak for a no-cache failure in create_state_record_for.
Avoid a duplicate copy for a cache miss.
2017-04-28 09:58:40 -07:00
Doug Moore
24ac32b480 run_cfi patch for libunwind
dwarf: If the dwarf_readu8 call to set op fails, and if there are register
states pushed onto the stack, the stack is not emptied before the function
returns. This change addresses that.

Most of the rest is eliminating ‘goto fail’ from the code.
2017-04-26 08:11:34 -07:00
Doug Moore
24f27f02ac dwarf: error in unmap size arguments
This patch fixes an error in the unmapping of
hash table memory when the dwarf hash table is resized.
2017-04-17 10:28:48 -07:00
Doug Moore
0f24c6dec8 dwarf: Cleanup dwarf cache hint
0-valued hints are used when they are just initial values with no use as
hints. And I think there were some other problems as well.
This patch cleans up and stores hint values with 1 added, so that 0-valued
hints can be ignored.
2017-04-14 08:02:10 -07:00
Dave Watson
aee8bbe795 dwarf: fix unw_get_proc_info
unw_get_proc_info must always load the unwind info so that unw_resume
works with GNU_args_size expressions, but must not update
use_prev_expr unless we are unw_step()ing.

blame rev: 4b63a536ee

reported-by: Doug Moore <dougm@rice.edu>
2017-04-04 11:15:23 -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
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
Dave Watson
54a970079d elf: Follow .gnu_debuglink when resolving function names
Centralize gnu_debuglink logic in elfxx.  Remove previous duplicated logic
from Gfind_proc_info and os-linux.

Logic is roughly the same as previous load_debug_frame, but uses VLAs
instead of malloc.
2017-03-02 08:02:14 -08:00
Mike Frysinger
f3f456c0d1 coredump: simplify bad regnum checks a little
We always want to reject negative regnums since we use it as an index,
so make it a common check at the top for all arches.
2017-02-14 08:23:38 -08:00
Королев Сергей
00cca00716 mips/Gstep.c: unw_handle_signal_frame: remove unused 'sp' variable
This fixes GCC 4.9.3 warnings (Linux/mipsel):

mips/Gstep.c: In function '_Umips_handle_signal_frame':
mips/Gstep.c:33:23: warning: unused variable 'sp' [-Wunused-variable]
   unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa;
                       ^
2017-02-14 08:22:00 -08:00
Королев Сергей
b5de17183c mips[el]: fix cast from pointer to integer of different size
This fixes GCC 4.9.3 warnings (Linux/mipsel):

In file included from dwarf/Lfind_unwind_table.c:4:0:
dwarf/Gfind_unwind_table.c: In function '_ULmips_dwarf_find_unwind_table':
dwarf/Gfind_unwind_table.c:140:14: warning: cast from pointer to integer of
different size [-Wpointer-to-int-cast]
       addr = (unw_word_t) (hdr + 1);
              ^
dwarf/Gfind_unwind_table.c:196:50: warning: cast from pointer to integer of
different size [-Wpointer-to-int-cast]
                                        + (addr - (unw_word_t) edi->ei.image
                                                  ^
dwarf/Gfind_unwind_table.c:202:40: warning: cast from pointer to integer of
different size [-Wpointer-to-int-cast]
                                     + ((unw_word_t) hdr - (unw_word_t)
edi->ei.image
                                        ^
dwarf/Gfind_unwind_table.c:202:59: warning: cast from pointer to integer of
different size [-Wpointer-to-int-cast]
                                     + ((unw_word_t) hdr - (unw_word_t)
edi->ei.image
                                                           ^
2017-02-14 08:21:49 -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
Bert Wesarg
b15e74a884 dwarf: Utilize ELFs find_section to find the eh_frame.
Makes it thread-safe.
2017-02-02 08:29:17 -08:00
Bert Wesarg
1b960e54e9 elfxx: Add helper to find a section in ELF image. 2017-02-02 08:29:17 -08:00
Dave Watson
316a34a36e mips/tilegx: Add missing unwind_i.h header file
reported-by: John Knight <John.Knight@belkin.com>
2017-01-25 16:23:59 -08:00
Bert Wesarg
2e60ca34d2 dwarf: Fix warning about -Wmaybe-uninitialized.
```
src/dwarf/Gfind_proc_info-lsb.c:536:16: warning: 'eh_frame' may be used uninitialized in this function [-Wmaybe-uninitialized]
   Elf_W (Addr) eh_frame;
                ^
```

Introduced-in: 25413c729a
2017-01-24 11:09:25 -08:00
Bert Wesarg
4dea379ad9 x84_64: It's only 'mcontext_t'.
Fixes warning:
```
src/x86_64/Gos-linux.c:141:36: warning: initialization from incompatible pointer type
   struct mcontext_t *sc_mcontext = &((struct ucontext*)sc)->uc_mcontext;
                                    ^
```

Introduced-in: 29483327be
2017-01-24 11:09:14 -08:00
Saleem Abdulrasool
e9e8ed73e3 dwarf: Account for multiple CFA for args_size
It is possible to have multiple CFA_args_size adjustments for a single
frame.  If the CFA_args_size adjustment is immediately following the
return from a function which can raise an exception, it is possible to
incorrectly adjust the stack pointer.  Consider the following:

  ...
  .cfi_escape 0x2e, 0x00
  call f
.Ltmp:
  .cfi_escape 0x2e, 0x10
  lea label@GOTOFF(%ebx), %eax
  ...

Because we process the CFI program up to and *INCLUDING* IP, where the
IP is the RA, we would process the associated DW_CFA_GNU_args_size for
the post-call instruction.  The result would be a DW_CFA_GNU_args_size
of 0x10 rather than 0x00, resulting in an incorrect stack adjustment.
Handle this by processing the CFI operation but not adjusting the state
record unless we are below the current IP.
2017-01-19 10:07:53 -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
Vitaly Kuzmichev
7885596b9c arm: ptrace: Fix order of probing unwind tables
Commit 92327a3 "ARM: prefer to unwind using DWARF info"
changes order of unwind info searching to prefer DWARF (.debug_frame)
section in prior to ARM specific (.ARM.exidx). This patch only affects
local process unwinding. Now the same is done for remote unwinding.

Sometimes probing .ARM.exidx first causes backtrace truncation
after __aeabi_ldiv0 (division by 0 handler that generates SIGFPE),
because it hits [cantunwind] generated by cross-gcc for __divsi3
function copied with __aeabi_ldiv0 from libgcc.a. Perhaps, lack of
debug info for __divsi3 causes [cantunwind], or there is a problem
converting DWARF to ARM unwind tables, but when unwinding using
DWARF, it hits proper entry, and backtrace is shown correctly.

Reported-by: Frederic Berat <fberat@de.adit-jv.com>
Signed-off-by: Vitaly Kuzmichev <Vitaly_Kuzmichev@mentor.com>
2017-01-19 10:06:24 -08:00
Saleem Abdulrasool
11a053f5ca use target dependent names for stack registers
When adjusting the stack for a DW_CFA_arg_size adjustment, ensure that
we use the target dependent register name as the generic name does not
necessarily map to the same register.  For example, on x86, ESP maps to
the eip register, which results in the wrong stack adjustment being
applied.
2017-01-18 10:17:15 -08:00
Konstantin Belousov
09a598a3da Make the code compile on FreeBSD. 2017-01-18 09:18:29 -08:00
Guy Menanteau
7c079200d0 ppc64: Make access_fpreg function accept fp and v registers 2017-01-13 08:41:45 -08:00
Martin Dorey
1f4929c05d linux: Add /usr/lib/debug symbol path checking
Debian likes to hive off symbol information to separate -dbg packages,
installing the debug information in a parallel tree rooted at /usr/lib/debug.
libunwind doesn't know how to find these files but it's easy, per the tested,
attached patch, to make it so. I don't see /usr/lib/debug at
http://www.pathname.com/fhs/pub/fhs-2.3.html#USRLIBLIBRARIESFORPROGRAMMINGANDPA
but
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Debugging_with_gdb/separate-debug-files.html
says it's not just Debian and hints it might be driven by gdb. I do see mention
of /usr/lib/debug in libunwind already, but only in a DWARF-specific part of
the code.  A minor concern might be checking errno to see if the problem is
ENOENT before trying the alternate path. That might be better than flogging a
mmap problem or being out of file handles or whatever.
2017-01-13 08:36:37 -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
29483327be x86_64: Use sigprocmask from signal frames
Currently setcontext for x86_64 restores the signal mask, even
though it is never saved anywhere.  This means the signal mask
is often garbage after an unw_resume.

(changed in commit f8a15e9679)

It looks like this was a fix for the Gtest-resume-sig function -
testing if signal masks are restored across signal frames.  The
root issue looks like that x86_64 only uses sigreturn for the exact
signal frame, and not for any decedant frames as well (as i64 does).

Instead, modify Gresume to use sigreturn if *any* frame on the stack
is a signal frame, so that we correct fixup the signal mask and any
sigaltstacks.  The sigreturn os-specific functions are changed slightly
to copy in the saved ucontext structure if we are jumping farther
up the stack.

This should fix sigprocmask reported issues such as
https://github.com/dropbox/pyston/blob/master/libunwind_patches/0002-pyston-stop-x86_64-setcontext-restoring-uninitialize.patch

Tests pass on freebsd, linux
2017-01-13 08:28:22 -08:00
Dave Watson
4b63a536ee dwarf: Correct handling of DW_CFA_GNU_args_size
When resuming execution, DW_CFA_GNU_args_size from the current frame
must be added back to the stack pointer.  Clang now generates these frequently
at -O3.  A simple repro for x86_64, that will crash with clang ~3.9 or newer:

void f(int, int,int,int,int,int,int,int,int);

int main() {
  try {
    f(0,1,2,3,4,5,6,7,8);
  } catch (int) {
    return 0;
  }
  return 1;
}

Where f is something that throws an int, but in a different translation unit to
prevent optimization.

This results in cfi instructions before the call:
 .cfi_escape 0x2e, 0x20

Grabbing the args_size means fully parsing the cfi in the current frame, which
is unfortunate because it means nearly twice the work at each step.  The logic
to grab args_size can be in unw_step or get_proc_info (since this is always
called before resuming in stack unwinding).  Putting it in get_proc_info allows
the more common unw_step code to remain fast.

It would potentially fit in nicely with a proc info cache (as mentioned in the
if0 comment block)
2017-01-13 08:28:21 -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
Jan Willeke
e5fe9034ad coredump: align coredump description pointer
next = inote.descdata + align_power (inote.descsz, 2);

this align is missing, leading to parsing errors. In one case
libunwind only found 1 thread out of 4.
2017-01-13 08:28:21 -08:00
Jonathan Byrd
25413c729a dwarf: Improve support for binaries missing the GNU_EH_FRAME segment
Improves support for binaries missing the GNU_EH_FRAME segment
(.eh_frame_hdr section) by adding a function
'dwarf_find_eh_frame_section' that can create a synthetic one.
2017-01-13 08:28:21 -08:00
Королев Сергей
fd44f596b2 tdep_uc_addr: use +4 offset for UNW_MIPS_PC on MIPS (be)
According to mcontext_t definition its "pc" field
is also 64 bit wide and thus requires 4 byte offset
on MIPS32 (be).
2017-01-13 08:27:40 -08:00
Chris Redmon
cf2bc87561 Fixup invalid return code checks of unw_is_signal_frame()
unw_is_signal_frame() returns <= 0 if not a signal frame. Several places in
code were only checking for a "if (unw_is_signal_frame())", or
"if (!unw_is_signal_frame())".
2017-01-13 08:27:40 -08:00
Королев Сергей
ad0d7633bc dwarf: check maps_init result
This fixes GCC 4.9.3 warnings (Linux/mipsel):

dwarf/Gfind_proc_info-lsb.c: In function 'locate_debug_info':
dwarf/Gfind_proc_info-lsb.c:244:23: warning: 'mi.buf_end' may be used
uninitialized in this function [-Wmaybe-uninitialized]
   struct map_iterator mi;
                       ^
dwarf/Gfind_proc_info-lsb.c:244:23: warning: 'mi.buf' may be used
uninitialized in this function [-Wmaybe-uninitialized]
In file included from dwarf/Gfind_proc_info-lsb.c:46:0:
./os-linux.h:292:27: warning: 'mi.buf_size' may be used uninitialized in
this function [-Wmaybe-uninitialized]
       munmap (mi->buf_end - mi->buf_size, mi->buf_size);
                           ^
dwarf/Gfind_proc_info-lsb.c:244:23: note: 'mi.buf_size' was declared here
   struct map_iterator mi;
                       ^
2017-01-13 08:27:39 -08:00
Giuseppe Ottaviano
bc8698fd7e [PATCH] x86_64: fix mincore_validate
The detection logic introduced in 28f33c8ce0 is
broken, because it tests mincore using an address that is almost certainly not
page-aligned. straces confirms that msync is used all the time.

This patch fixes the logic by page-aligning the test pointer. strace now shows
that mincore is actually used. Furthermore, the return value of mincore is not
sufficient to assess whether the address can be safely dereferenced: we should
also check that the pages are mapped, through the passed mvec array. This patch
also adds this verification.

Tested on a system where unwinding a stack across a JNI boundary would cause
sporadic segfaults; no more crashes were observed after the patch.
2016-02-29 11:05:42 -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