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

3021 commits

Author SHA1 Message Date
Tommi Rantala
ee06b32975 Fix IA64 separate builddir cursor generation
IA64 build was failing when using a separate build directory. Refer to
the source files with `$srcdir' to fix the build.
2012-09-04 14:58:38 +03:00
Tommi Rantala
a6f2a7a2a8 Fix incorrect .debug_frame lookup with non-zero text segment vaddr
Unwinding over ptrace and unwinding coredump fail to lookup the
.debug_frame dwarf data when the ELF file text segment virtual address
is non-zero. Looking at some binaries, the virtual address is non-zero
for non-pie binaries, and zero for PIC shared libraries and PIE
executables.

The core dump unwinder can be used for demonstrating the bug. Without
this patch, the unwinding fails badly (testing with a ARM qemu image):

 $ UNW_ARM_UNWIND_METHOD=1 ./test-coredump-unwind core `cat backing_files`
 test-coredump-unwind: unw_get_proc_info(ip=0x86d8) failed: ret=-10

After applying this patch, we can unwind all the way until running out
of dwarf data:

 $ UNW_ARM_UNWIND_METHOD=1 ./test-coredump-unwind core `cat backing_files`
     ip=0x000086d8 proc=000086d4-000086dc handler=0x00000000 lsda=0x00000000
 test-coredump-unwind: step
 test-coredump-unwind: step done:1
     ip=0x000086ef proc=000086dc-000086f2 handler=0x00000000 lsda=0x00000000
 test-coredump-unwind: step
 test-coredump-unwind: step done:1
     ip=0x000086e7 proc=000086dc-000086f2 handler=0x00000000 lsda=0x00000000
 test-coredump-unwind: step
 test-coredump-unwind: step done:1
     ip=0x00008597 proc=00008584-0000859a handler=0x00000000 lsda=0x00000000
 test-coredump-unwind: step
 test-coredump-unwind: step done:1
     ip=0x76eacc3b proc=76eacba0-76eaccec handler=0x00000000 lsda=0x00000000
 test-coredump-unwind: step
 test-coredump-unwind: step done:1
 test-coredump-unwind: unw_get_proc_info(ip=0x85c3) failed: ret=-10

Note how the binary itself is mapped to address 0x8000, the virtual
address for the text segment is 0x8000, and the .debug_frame program
counter values are relative to 0:

$ tr ' ' '\n' < backing_files
0x8000:/home/user/tests/crasher
0x76e96000:/lib/arm-linux-gnueabi/libc-2.13.so
0x76f77000:/lib/arm-linux-gnueabi/libgcc_s.so.1
0x76f88000:/lib/arm-linux-gnueabi/ld-2.13.so

$ readelf -l crasher
Elf file type is EXEC (Executable file)
Entry point 0x859d
There are 9 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  EXIDX          0x0007b0 0x000087b0 0x000087b0 0x00030 0x00030 R   0x4
  PHDR           0x000034 0x00008034 0x00008034 0x00120 0x00120 R E 0x4
  INTERP         0x000154 0x00008154 0x00008154 0x00013 0x00013 R   0x1
      [Requesting program interpreter: /lib/ld-linux.so.3]
  LOAD           0x000000 0x00008000 0x00008000 0x007e4 0x007e4 R E 0x8000
  LOAD           0x000efc 0x00010efc 0x00010efc 0x00148 0x00154 RW 0x8000
  DYNAMIC        0x000f08 0x00010f08 0x00010f08 0x000f8 0x000f8 RW  0x4
  NOTE           0x000168 0x00008168 0x00008168 0x00044 0x00044 R   0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x4
  GNU_RELRO      0x000efc 0x00010efc 0x00010efc 0x00104 0x00104 R   0x1

$ readelf --debug-dump=frames crasher | grep FDE
00000010 00000024 00000000 FDE cie=00000000 pc=00008614..000086d4
00000038 0000000c 00000000 FDE cie=00000000 pc=000086d4..000086dc
00000048 00000014 00000000 FDE cie=00000000 pc=000086dc..000086f2
00000060 00000014 00000000 FDE cie=00000000 pc=00008584..0000859a
2012-09-04 14:58:38 +03:00
Tommi Rantala
2aea391d6a ARM: invalidate proc info after non-dwarf unw_step()
After successfully stepping the cursor on ARM, the proc info is
invalidated only in dwarf_step(). Invalidate the proc info also when
stepping with the non-dwarf based methods. This fixes
unw_get_proc_info() returning stale data.

The core dump unwinder can be used for demonstrating the bug. When
unwinding based only on DWARF data, the proc info is correct:

$ UNW_ARM_UNWIND_METHOD=1 ./test-coredump-unwind core `cat backing_files` 2>/dev/null
    ip=0x000086d8 proc=000086d4-000086dc handler=0x00000000 lsda=0x00000000
    ip=0x000086ef proc=000086dc-000086f2 handler=0x00000000 lsda=0x00000000
    ip=0x000086e7 proc=000086dc-000086f2 handler=0x00000000 lsda=0x00000000
    ip=0x00008597 proc=00008584-0000859a handler=0x00000000 lsda=0x00000000
    ip=0x76e3ac3b proc=76e3aba0-76e3acec handler=0x00000000 lsda=0x00000000

When unwinding based only on the exidx method, we see the proc info
lagging behind:

$ UNW_ARM_UNWIND_METHOD=4 ./test-coredump-unwind core `cat backing_files` 2>/dev/null
    ip=0x000086d8 proc=000086d4-000086db handler=0x00000000 lsda=0x00000000
    ip=0x000086ef proc=000086d4-000086db handler=0x00000000 lsda=0x00000000
    ip=0x000086e7 proc=000086dc-000086f3 handler=0x00000000 lsda=0x00000000
    ip=0x00008597 proc=000086dc-000086f3 handler=0x00000000 lsda=0x00000000
    ip=0x76e3ac3b proc=00008584-0000859b handler=0x00000000 lsda=0x00000000
    ip=0x000085c3 proc=76e3aba0-76e3ae4b handler=0x00000000 lsda=0x00000000

Finally, with this patch applied, we get the desired proc info also with
the exidx unwinder:

$ UNW_ARM_UNWIND_METHOD=4 ./test-coredump-unwind core `cat backing_files` 2>/dev/null
    ip=0x000086d8 proc=000086d4-000086db handler=0x00000000 lsda=0x00000000
    ip=0x000086ef proc=000086dc-000086f3 handler=0x00000000 lsda=0x00000000
    ip=0x000086e7 proc=000086dc-000086f3 handler=0x00000000 lsda=0x00000000
    ip=0x00008597 proc=00008584-0000859b handler=0x00000000 lsda=0x00000000
    ip=0x76e3ac3b proc=76e3aba0-76e3ae4b handler=0x00000000 lsda=0x00000000
    ip=0x000085c3 proc=0000859c-00008613 handler=0x00000000 lsda=0x00000000
2012-09-04 14:58:38 +03:00
Tommi Rantala
21ad2c19ea Implement _UCD_access_reg() for ARM
Implement the Linux version of _UCD_access_reg() for ARM. We can
sidestep the register number remapping, as the libunwind register
numbers match one-to-one to the ELF core file register numbers.
2012-09-04 14:58:38 +03:00
Tommi Rantala
24a0c1f265 Provide manual page for `unw_backtrace()' 2012-09-04 14:58:38 +03:00
Tommi Rantala
eca102fd50 Remove AC_FUNC_MEMCMP check from configure.in
As far as I can tell, AC_FUNC_MEMCMP is useless for us. It checks for
some obscure `memcmp' bugs on some ancient systems, and gives us a
chance to provide a working `memcmp'. Since we're not shipping with a
local copy of a `memcmp', it makes no difference whether or not the test
fails. And when cross-compiling, the test automatically fails, as it
tries to compile and run a test program:

    checking for working memcmp... no

Quoting autoconf docs: ``This macro is obsolescent, as current systems
have a working memcmp. New programs need not use this macro.''
2012-09-04 14:58:38 +03:00
Tommi Rantala
f93e1e93be Avoid LLVM -Wunused-value warning in src/dwarf/Gexpr.c
src/dwarf/Gexpr.c:434:4: warning: expression result unused [-Wunused-value]
          pop ();
          ^~~~~~
src/dwarf/Gexpr.c:211:14: note: expanded from:
  stack[--tos];                                 \
  ~~~~~ ~~~~~^
2012-09-04 14:58:38 +03:00
Tommi Rantala
1c1dbbe296 Do not print garbage proc info in tests/Gtest-bt.c
Check the return value of the unw_get_proc_info() call to avoid printing
garbage if the call fails.
2012-09-04 14:58:38 +03:00
Tommi Rantala
8203c955c8 Change test-varargs to check libunwind backtracing
test-varargs is checking how `backtrace()' provided by the system
behaves when varargs are used. Let's make the test more useful by
changing it to test the `backtrace()' provided by libunwind.

Change the testcase to return 0/1 for success/failure, and add it to the
set of checks, so that it gets run on `make check'. Also call
`unw_backtrace()' explicitly so that we do not need to bother with
`execinfo.h' and `backtrace()' prototype.
2012-09-04 14:58:38 +03:00
Tommi Rantala
ffbe29940e Check correct variable for offset in tests/Gtest-init.cxx
Checking `off' for positiveness does not make any sense, check `offset'
instead.
2012-09-04 14:58:37 +03:00
Tommi Rantala
6470a67461 Rename backtrace' to do_backtrace' in tests/Gtest-init.cxx
Rename `backtrace' to `do_backtrace' in tests/Gtest-init.cxx for sanity;
the `backtrace' name is already defined in various other places.
2012-09-04 14:58:37 +03:00
Tommi Rantala
fce25d74c9 Eliminate one heap allocation in dwarf_find_debug_frame()
Allocate `tab' from stack in dwarf_find_debug_frame(), as it's only a
few members and we only need it locally in the function.
2012-09-04 14:58:37 +03:00
Tommi Rantala
90d7baea35 Remove free() NULL pointer checks in load_debug_frame() error path
Just pass potentially NULL pointers to free() in the error path in
load_debug_frame(). Saved 40 bytes of code in libunwind.so on ARM -O2
thumb build at the expense of slightly slower execution.
2012-09-04 14:58:24 +03:00
Tommi Rantala
a745ac2f60 PPC: return failure from the unw_get_proc_info() stub
Stop pretending that unw_get_proc_info() works on PPC, and instead give
an error back to the caller. As far as I can tell, none of the libunwind
tests clear out the `unw_proc_info_t' before passing it to
unw_get_proc_info(), so they would end up working on garbage data.
2012-09-04 13:26:13 +03:00
Tommi Rantala
8f94f1e6c0 PPC: add missing debug level in Debug() calls in Gstep.c
ppc32/Gstep.c:116: warning: comparison between pointer and integer
ppc32/Gstep.c:116: warning: comparison with string literal results in unspecified behavior
ppc32/Gstep.c:116: warning: initialization makes integer from pointer without a cast
ppc32/Gstep.c:116: warning: passing argument 2 of 'fprintf' makes pointer from integer without a cast
/usr/powerpc-linux-gnu/include/stdio.h:333: note: expected 'const char *__restrict__' but argument is of type 'int'
2012-09-04 13:26:13 +03:00
Tommi Rantala
7feb6b8575 HPPA: fix common_init() bitrot
Fix bitrot in HPPA common_init(). This has only been compile tested.

hppa/init.h: In function 'common_init':
hppa/init.h:33: error: 'struct cursor' has no member named 'ip_loc'
hppa/init.h:33: warning: implicit declaration of function 'HPPA_REG_LOC'
hppa/init.h:34: error: 'struct cursor' has no member named 'sp_loc'
hppa/init.h:36: warning: implicit declaration of function 'hppa_get'
hppa/init.h:36: error: 'struct cursor' has no member named 'ip_loc'
hppa/init.h:36: error: 'struct cursor' has no member named 'ip'
hppa/init.h:40: error: 'struct cursor' has no member named 'sp'
2012-09-04 13:26:13 +03:00
Tommi Rantala
aed6c8b994 Check __builtin___clear_cache() at configuration time
Fixup commit 39b83981 ("Flush icache with __builtin___clear_cache() in
tests when compiling with GCC") to fix compilation with older GCC
versions that do not provide __builtin___clear_cache().
2012-09-04 13:26:13 +03:00
Tommi Rantala
a15874f2cb Annotate unused argument in mark_as_used() to avoid -Wextra compiler noise
include/libunwind_i.h: In function 'mark_as_used':
include/libunwind_i.h:187:39: warning: unused parameter 'v' [-Wunused-parameter]
2012-09-04 12:59:11 +03:00
Tommi Rantala
7e5cab6dac Add missing newline to debug message in _UCD_access_reg_linux.c 2012-08-21 23:04:07 +03:00
Tommi Rantala
e61c6f69c3 Fix function name duplication in Debug() output
Fix function name duplication in Debug() output that was caused by
manually prepending the debug message with the function name.
2012-08-21 23:04:07 +03:00
Tommi Rantala
18c26d4a7e Place `inline' at beginning of declaration of invalidate_edi()
../include/libunwind_i.h:319:1: warning: 'inline' is not at beginning of declaration [-Wold-style-declaration]
2012-08-21 22:33:57 +03:00
Tommi Rantala
39b8398159 Flush icache with __builtin___clear_cache() in tests when compiling with GCC
When compiling with GCC, use the builtin instruction cache flushing
mechanism in all tests where it is needed.

Quoting GCC docs: ''If the target does not require instruction cache
flushes, __builtin___clear_cache has no effect. Otherwise either
instructions are emitted in-line to clear the instruction cache or a
call to the __clear_cache function in libgcc is made.''.
2012-08-21 22:33:56 +03:00
Tommi Rantala
5fedf3407c Avoid -Wunused-value warning in tests/Gtest-exc.c
Gtest-exc.c: In function 'a':
Gtest-exc.c💯15: warning: value computed is not used [-Wunused-value]
2012-08-21 22:33:56 +03:00
Tommi Rantala
5b55e556ca test-resume-sig-rt: test unw_resume() in presence of "realtime" signal frame
Introduce a new test case that is derived from test-resume-sig, but
using the SA_SIGINFO sigaction() flag. This case is referred in the
linux kernel sources as "realtime" signal handler, and is handled
differently in the kernel on many architectures and in libunwind as
well.
2012-08-21 22:33:56 +03:00
Tommi Rantala
5738bac171 ARM: fix with-signal-frame local unw_resume()
Make sure that the `sigcontext_addr' cursor member is pointing to the
`struct sigcontext' as expected in arm_local_resume().
2012-08-21 22:33:56 +03:00
Tommi Rantala
14fc15928b ARM: fix non-signal-frame local unw_resume() due to compiler optimization cleverness
When cross-compiling libunwind with optimizations (-O1 or higher),
gcc-4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) optimizes away the memory
writes prior to the inline asm() statement in arm_local_resume() in the
non-signal-frame path, causing the `regs' array to be only allocated on
the stack, but not populated. This means that we are restoring garbage
to the registers.

As suggested in the GCC docs, add a fixed size input memory constraint
for the array content. This is enough to get the desired code to be
generated.

Adding __builtin_unreachable() to the point that we should never reach
was also in itself enough to inhibit the optimization. It also reduces
the function size by a few instructions.
2012-08-21 22:33:56 +03:00
Tommi Rantala
5fef17c05d Fix memory leaks in unw_create_addr_space() wrong-endian error paths
Check the endianness earlier in unw_create_addr_space() on all
architectures to avoid leaking the dynamically allocated address space
struct.

This was already fixed for ARM in commit cf6a998796 ("Fix memory leak
in ARM unw_create_addr_space()"). Move the endianness check also on ARM
to avoid malloc() & free() in the error case.
2012-08-21 22:33:29 +03:00
Tommi Rantala
ff0c6ccf6b Remove unneeded length modifier from suppressed match in sscanf() format in tests/crasher.c
GCC is complaining about the `%*jx' match in sscanf() format string.
Replace it with `%*x'; sscanf() will identically match an unsigned
hexadecimal integer without the length modifier.

crasher.c: In function 'write_maps':
crasher.c:30:9: warning: use of assignment suppression and length modifier together in gnu_scanf format [-Wformat]
2012-08-21 22:30:47 +03:00
Tommi Rantala
2d750952a5 Use constants for ELF magic bytes in _UCD_create.c 2012-08-21 22:30:47 +03:00
Tommi Rantala
9a6d921230 Fix plain return from main() in tests/test-async-sig.c
test-async-sig.c: In function 'main':
test-async-sig.c:185:4: warning: 'return' with no value, in function returning non-void [-Wreturn-type]
2012-08-21 22:30:46 +03:00
Tommi Rantala
7b81113721 MIPS: implement dwarf_to_unw_regnum() macro without table 2012-08-21 22:30:46 +03:00
Tommi Rantala
1dc66bd181 ARM: implement dwarf_to_unw_regnum() macro without table 2012-08-21 22:30:46 +03:00
Tommi Rantala
6a5da54b8a Allow for architecture specific dwarf_to_unw_regnum()
For a few of the supported architectures we can use one-to-one mapping
from the dwarf to the libunwind register numbers. Allow the
architectures to define their own dwarf_to_unw_regnum() macro to do this
easily.
2012-08-21 22:30:46 +03:00
Tommi Rantala
54a096a5af PPC: do not export dwarf_to_unw_regnum_map
dwarf_to_unw_regnum_map is internal to libunwind, and should not be
exported.
2012-08-21 22:30:46 +03:00
Tommi Rantala
80fc285599 MIPS: fix symbol naming for mips_lock', mips_local_resume', and `mips_local_addr_space_init'
Properly export the symbol names also on MIPS. `make check' was
complaining:

src/.libs/libunwind.a(Linit.o): In function `mips_local_addr_space_init':
src/mips/Ginit.c:183: multiple definition of `mips_local_addr_space_init'
../src/.libs/libunwind-mips.a(Ginit.o):src/mips/Ginit.c:183: first defined here

src/.libs/libunwind.a(Lglobal.o): In function `_ULmips_init':
src/mips/Gglobal.c:42: multiple definition of `mips_lock'
../src/.libs/libunwind-mips.a(Gglobal.o):src/mips/Gglobal.c:42: first defined here

collect2: ld returned 1 exit status
2012-08-21 22:30:46 +03:00
Tommi Rantala
56f07a8e55 Stop using nonportable echo arguments in tests
echo arguments are not portable, so use printf when we need to print
tabs or newlines.
2012-08-21 22:30:46 +03:00
Tommi Rantala
96cc0e8316 Run autoupdate' to stop using obsoleted macros in configure.in' 2012-08-21 22:30:46 +03:00
Tommi Rantala
757c81cca9 Update .gitignore 2012-08-21 22:30:46 +03:00
Tommi Rantala
f42a8de0fa Annotate unused parameters in tests
Compiling the tests with -Wextra results to lots of warnings for unused
parameters. Annotate these cases with the `unused' attribute to avoid
the warnings.
2012-08-21 22:30:46 +03:00
Tommi Rantala
47a99b6f00 Eliminate unused parameters in tests 2012-08-21 22:30:41 +03:00
Tommi Rantala
6f374ccb5a Ignore _fbss, _fdata, _ftext and _gp symbols on MIPS 2012-08-20 08:46:47 +03:00
Tommi Rantala
a63c209fed Add PPC namespace checking
PPC is the only architecture that has the get_func_addr() symbol
exported, so add specific checks for this architecture.
2012-08-20 08:46:46 +03:00
Tommi Rantala
d139d7e78e HPPA: include mempool.h' in libunwind_i.h'
dwarf/Gfde.c: In function '_Uhppa_dwarf_extract_proc_info_from_fde':
dwarf/Gfde.c:335: warning: implicit declaration of function 'mempool_alloc'
2012-08-20 08:46:46 +03:00
Tommi Rantala
d1e4614995 HPPA: add `global_cache' member to unw_addr_space struct
dwarf/Gparser.c: In function 'get_rs_cache':
dwarf/Gparser.c:522: error: 'struct unw_addr_space' has no member named 'global_cache'
2012-08-20 08:46:46 +03:00
Tommi Rantala
971216f8d4 HPPA: fix tdep_put_unwind_info() macro
In file included from mi/Lput_dynamic_unwind_info.c:4:
mi/Gput_dynamic_unwind_info.c:48:40: error: macro "tdep_put_unwind_info" passed 3 arguments, but takes just 2
2012-08-20 08:46:46 +03:00
Arun Sharma
201bb8733d Use libtool to build libunwind-ptrace 2012-08-18 12:41:21 -07:00
Konstantin Belousov
04c77cced4 Fix for test suite build in the separate directory.
Avoid manually coding the rule to build crasher, instead fuddle
the compiler so that even -O2 optimization does not eliminate call
to b().

First, put calls to both a() and b() in the b() into non-tail-recursive
position. Second, as recommended in gcc manual, use asm volatile("");
to prevent further prevent inlining, besides attribute((noinline).
And third, call b() by alias, which current gcc optimizer cannot see
through.

Also, do not dereference NULL in a, and mark the memory access as volatile.
[ Minor portability improvements: asharma@fb.com ]
2012-08-11 22:02:55 -07:00
Arun Sharma
538f63d796 Fix test-ptrace in automated mode
Tested via:
./test-ptrace
./test-ptrace -v /bin/ls /usr
2012-08-11 21:21:54 -07:00
Martin Milata
3d5e6c1ddd Search MiniDebugInfo for procedure names
After searching the normal symbol table, look if the binary contains
.gnu_debugdata section. If it does, run LZMA decompression on it, load
the resulting ELF image into memory and call lookup_symbol() on it
again.

lookup_symbol() is modified so that it takes min_dist as a parameter and
only returns a symbol when it finds one that is closer than indicated by
the parameter.

Signed-off-by: Martin Milata <mmilata@redhat.com>
2012-08-10 15:29:07 +02:00
Martin Milata
71c1fffc35 Refactor parts of elfxx.c to allow reusing code
Signed-off-by: Martin Milata <mmilata@redhat.com>
2012-08-10 15:29:07 +02:00