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.
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.
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.
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>
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]
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.
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.
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
^
```
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
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.