summaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* mips: make _step_n64 as a static functionv1.4-stablesnyh2019-04-111-50/+56
| | | | | | | | | | | 1. hidden _step_n64 to avoid a strange bug which will reproduce under `perf report`. The value `tdep_init_done` of suddenly be changed to zero when entering `_step_n64` from `unw_step`. 2. refactor code to improve the readability. use `FP_REG`, `SP_REG` and `RA_REG` to abstract the guessing logical.
* x86_64: Fix tdep_init_done when built with libatomic_opsDave Watson2019-04-112-1/+9
| | | | Use correct size variable.
* Tsan (#109)Dave Watson2019-04-034-9/+17
| | | x86_64: tsan clean
* dwarf: clang doesn't respect the static alias (#102)Dave Watson2019-01-091-0/+5
| | | | | Clang doesn't respect the static alias, resulting in global instead of local symbols, and name collisions. Work around for clang by always going through the PLT (at a small perf hit)
* Bump to 1.4-rc1v1.4-rc1Dave Watson2019-01-072-2/+2
|
* mips: Handle Gstep according the N64/N32 ABI if Dwarf way failed (#100)xiabin2018-12-122-7/+96
| | | | | - gp at 8(sp) - fp at 16(sp) - ra at 24(sp)
* Convert the README to markdown syntax (#96)Alex Arslan2018-12-111-105/+99
| | | | | | | | | | | | Currently the README's formatting shows up rather poorly on GitHub, as the file isn't written as a Markdown document but GitHub tries to render it as one due to the symlink from README.md to README. This commit reformats the file as a Markdown document, preserving the original content with two exceptions: 1. The platform support list has been converted to a Markdown table. 2. The severely outdated information regarding libexecinfo on FreeBSD has been amended and the note about FreeBSD 8.0 removed.
* dwarf: Push correct CFA onto stack for dwarf expression evaluation. (#93)Stephen Roberts2018-11-138-12/+190
| | | | | | | | dwarf: Push correct CFA onto stack for dwarf expression evaluation. This change fixes a bug where stale CFAs were pushed onto the dwarf expression stack before expression evaluation. Some optimising compilers emit CFI which relies on this being correct.
* dwarf: Add missing opcodes to the operands table in Gexpr.cStephen Roberts2018-10-121-0/+2
| | | This patch adds two opcodes to the operands table in Gexpr.c, which is a mapping between opcodes and the number and types of the operands for those opcodes. Two opcodes, DW_OP_constu and DW_OP_consts are missing from this table, which caused failures later in the CFI expression parsing logic. This patch adds the missing information into the table, and thus allows correct parsing of CFA_def_cfa_expression, CFA_expression and CFA_val_expression expressions which contain the offending opcodes.
* aarch64: Use __asm__ instead of asm (#89)Guido Günther2018-10-121-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Otherwise this fails to compile with -stc=c99 like: $ cat <<EOF > bla.c #include <libunwind.h> int main() { unw_tdep_context_t *uc = NULL; unw_tdep_getcontext(uc); } EOF # This works $ gcc bla.c # This does not $ gcc -std=c99 bla.c In file included from /usr/include/aarch64-linux-gnu/libunwind.h:7, from bla.c:1: bla.c: In function ‘main’: bla.c:6:5: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘asm’ unw_tdep_getcontext(uc); ^~~~~~~~~~~~~~~~~~~ bla.c:6:5: error: ‘mcontext_t’ {aka ‘struct <anonymous>’} has no member named ‘regs’; did you mean ‘__regs’? unw_tdep_getcontext(uc); ^~~~~~~~~~~~~~~~~~~ bla.c:6:5: error: ‘unw_base’ undeclared (first use in this function); did you mean ‘unw_ctx’? unw_tdep_getcontext(uc); ^~~~~~~~~~~~~~~~~~~ bla.c:6:5: note: each undeclared identifier is reported only once for each function it appears in bla.c:6:5: error: invalid lvalue in asm output 0 unw_tdep_getcontext(uc); ^~~~~~~~~~~~~~~~~~~ See https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html: The asm keyword is a GNU extension. When writing code that can be compiled with -ansi and the various -std options, use __asm__ instead of asm (see Alternate Keywords).
* Adopt two changes by Sergey Korolev to use mmap and a shell sort, ratherDoug Moore2018-09-282-158/+162
| | | | | than malloc and qsort, to process debug frames and reduce problems with non signal-safe functions in supposedly signal-safe libunwind procedures.
* aarch: [v2] aarch64 PLT entry recognition & fixes (#86)Dave Watson2018-09-281-1/+1
| | | | | Fix missing Gparser.c changes from patchset 'aarch64 PLT entry recognition & fixes'
* aarch64: fix freebsd supportmyfreeweb2018-08-074-1/+39
| | | implement _UPT_access_fpreg, _UCD_access_reg_freebsd for aarch64, and add a unw_fpsimd_context_t instead of using the one from the linux headers.
* arm: More verbose debug messages in arm_step() (#85)steelman2018-08-071-6/+14
| | | | | Compose debug messages depending on selected unwind methods. Fix indentation.
* Update README (#84)Kevin Mooney2018-08-071-1/+1
| | | readme: fix typo
* Fix after "dwarf: do not allocate in load_debug_frame (#72)".Dave Watson2018-06-201-7/+10
| | | | This patch also adds munmap() for unw_debug_frame_list elements.
* s390x: fix build when long double is more than 64 bitsMichael Munday2018-06-202-5/+5
| | | | | | | | The floating point registers on s390x are 64-bits wide so type them as double precision rather than long double. Also, GCC on Ubuntu 18.04 complains about the sizeof calls so fix those too.
* Also define NLGA when we build with atomic ops (#80)Milian Wolff2018-05-311-6/+1
| | | | | | | | | This uncovered the use of NLGA to guard the initializaition of the valid mem cache. This code is removed, as it isn't working properly for a per-thread cache anyways. What's more, it shouldn't be required anyways since static data is guaranteed to be initialized to zero anyways. Fixes https://github.com/libunwind/libunwind/issues/79
* Optionally use a thread-local cache for valid memoryMilian Wolff2018-05-071-1/+39
| | | | | When libunwind is compiled with per-thread-caches, then also make the cache of valid memory addresses thread-local.
* Fix race conditions in validate_mem via atomicsMilian Wolff2018-05-071-21/+50
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When atomics are not available, the address cache is disabled. Fixes data race found by TSAN: WARNING: ThreadSanitizer: data race (pid=17824) Read of size 8 at 0x7f4dac484140 by thread T3: #0 validate_mem ../../src/x86_64/Ginit.c:201 (libunwind.so. 8+0x00000001f836) #1 access_mem ../../src/x86_64/Ginit.c:242 (libunwind.so.8+0x00000001fe06) #2 dwarf_get ../../include/tdep-x86_64/libunwind_i.h:168 (libunwind.so. 8+0x0000000221cf) #3 _ULx86_64_access_reg ../../src/x86_64/Gregs.c:130 (libunwind.so. 8+0x000000022e99) #4 _ULx86_64_get_reg ../../src/mi/Gget_reg.c:40 (libunwind.so. 8+0x00000001e5bc) #5 apply_reg_state ../../src/dwarf/Gparser.c:796 (libunwind.so. 8+0x000000038209) #6 _ULx86_64_dwarf_step ../../src/dwarf/Gparser.c:961 (libunwind.so. 8+0x000000039dbc) #7 _ULx86_64_step ../../src/x86_64/Gstep.c:71 (libunwind.so. 8+0x00000002481f) #8 trace_init_addr ../../src/x86_64/Gtrace.c:248 (libunwind.so. 8+0x000000026f0e) #9 trace_lookup ../../src/x86_64/Gtrace.c:330 (libunwind.so. 8+0x000000027429) #10 _ULx86_64_tdep_trace ../../src/x86_64/Gtrace.c:447 (libunwind.so. 8+0x00000002789a) #11 unw_backtrace ../../src/mi/backtrace.c:69 (libunwind.so. 8+0x00000001cb07) Previous write of size 8 at 0x7f4dac484140 by thread T2: #0 validate_mem ../../src/x86_64/Ginit.c:220 (libunwind.so. 8+0x00000001fc54) #1 access_mem ../../src/x86_64/Ginit.c:242 (libunwind.so.8+0x00000001fe06) #2 dwarf_get ../../include/tdep-x86_64/libunwind_i.h:168 (libunwind.so. 8+0x0000000221cf) #3 _ULx86_64_access_reg ../../src/x86_64/Gregs.c:130 (libunwind.so. 8+0x000000022e99) #4 _ULx86_64_get_reg ../../src/mi/Gget_reg.c:40 (libunwind.so. 8+0x00000001e5bc) #5 apply_reg_state ../../src/dwarf/Gparser.c:796 (libunwind.so. 8+0x000000038209) #6 _ULx86_64_dwarf_step ../../src/dwarf/Gparser.c:961 (libunwind.so. 8+0x000000039dbc) #7 _ULx86_64_step ../../src/x86_64/Gstep.c:71 (libunwind.so. 8+0x00000002481f) #8 trace_init_addr ../../src/x86_64/Gtrace.c:248 (libunwind.so. 8+0x000000026f0e) #9 trace_lookup ../../src/x86_64/Gtrace.c:330 (libunwind.so. 8+0x000000027429) #10 _ULx86_64_tdep_trace ../../src/x86_64/Gtrace.c:447 (libunwind.so. 8+0x00000002789a) #11 unw_backtrace ../../src/mi/backtrace.c:69 (libunwind.so. 8+0x00000001cb07) Location is global 'last_good_addr' of size 32 at 0x7f4dac484140 (libunwind.so.8+0x000000273140)
* Cleanup: remove unused variableMilian Wolff2018-05-041-1/+0
|
* Do not try to close invalid fdsMilian Wolff2018-05-041-3/+4
| | | | | | | | | | | This was found by Valgrind: ==8330== Warning: invalid file descriptor -1 in syscall close() ==8330== at 0x504B9F4: close (in /usr/lib/libpthread-2.26.so) ==8330== by 0x40914DA: open_pipe (Ginit.c:82) ==8330== by 0x40914DA: _ULx86_64_init_mem_validate (Ginit.c:154) ==8330== by 0x4090CFE: _ULx86_64_init (Gglobal.c:93) ==8330== by 0x4090A8C: _ULx86_64_set_caching_policy (Gset_caching_policy.c:32)
* Fix data race on cache hints in find_reg_stateMilian Wolff2018-05-041-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This can be reproduced by using libunwind from multiple threads with UNW_CACHE_GLOBAL cache policy, as e.g. happens by default or when libunwind wasn't build with --enable-per-thread-cache. The call to put_rs_cache unlocks the cache, but we used to access data that needs to be guarded still. So move the call to put_rs_cache down to protect the data properly. Fixes the following data race reported by TSAN: WARNING: ThreadSanitizer: data race (pid=16551) Read of size 2 at 0x7f7dda69ed7a by thread T2: #0 find_reg_state ../../src/dwarf/Gparser.c:939 (libunwind.so. 8+0x000000037254) #1 _ULx86_64_dwarf_step ../../src/dwarf/Gparser.c:958 (libunwind.so. 8+0x000000037543) #2 _ULx86_64_step ../../src/x86_64/Gstep.c:71 (libunwind.so. 8+0x000000021fdd) #3 trace_init_addr ../../src/x86_64/Gtrace.c:248 (libunwind.so. 8+0x0000000246cc) #4 trace_lookup ../../src/x86_64/Gtrace.c:330 (libunwind.so. 8+0x000000024be7) #5 _ULx86_64_tdep_trace ../../src/x86_64/Gtrace.c:447 (libunwind.so. 8+0x000000025058) #6 unw_backtrace ../../src/mi/backtrace.c:69 (libunwind.so. 8+0x00000001a6e7) Previous write of size 2 at 0x7f7dda69ed7a by thread T3: #0 find_reg_state ../../src/dwarf/Gparser.c:940 (libunwind.so. 8+0x000000037383) #1 _ULx86_64_dwarf_step ../../src/dwarf/Gparser.c:958 (libunwind.so. 8+0x000000037543) #2 _ULx86_64_step ../../src/x86_64/Gstep.c:71 (libunwind.so. 8+0x000000021fdd) #3 trace_init_addr ../../src/x86_64/Gtrace.c:248 (libunwind.so. 8+0x0000000246cc) #4 trace_lookup ../../src/x86_64/Gtrace.c:330 (libunwind.so. 8+0x000000024be7) #5 _ULx86_64_tdep_trace ../../src/x86_64/Gtrace.c:447 (libunwind.so. 8+0x000000025058) #6 unw_backtrace ../../src/mi/backtrace.c:69 (libunwind.so. 8+0x00000001a6e7) Location is global 'local_addr_space' of size 26296 at 0x7f7dda698c60 (libunwind.so.8+0x000000268d7a)
* mipsN32: A modification suggestion to support mips N32Deng, Yimin (NSB - CN/Shanghai)2018-04-244-2/+19
|
* tests: Include wait-related headers for Ltest-mem-validate (#74)Alex Arslan2018-04-121-0/+2
| | | | Without these, I was getting errors from this test set claiming that wait, WIFCONTINUED, et al. were undefined on FreeBSD 11.1.
* aarch64: tune down size of unw_context_t and unw_cursor_t (#71)Dave Watson2018-04-103-9/+33
| | | | | | aarch64 defines a huge __reserved field in sigcontext. Cut it down to only the used FP fields. unw_cursor_t can also be cut down a bit, while still maintaining some reserved space.
* dwarf: do not allocate in load_debug_frame (#72)Dave Watson2018-04-101-2/+2
| | | | | | | load_debug_frame calls malloc() in a couple spots, use mmap via GET_MEMORY instead. These call paths are infrequent, and are never freed. Found by running tcmalloc unit tests on aarch64, when DEBUG_FRAME support is on.
* dwarf: make dwarf_find_debug_frame publicDave Watson2018-04-031-1/+1
| | | | | | | linux kernel's perf tool depends on this being public. reported-by: Luke Diamand <luke@diamand.org> blame: b56e4cb88989f82988a6a70acb32e187e88b5cac ("ALIAS dwarf symbols")
* Remove unw_handle_signal_frame from header. (#70)Bert Wesarg2018-04-021-2/+0
|
* Fix crasher test for gcc >= 8 when using -O2 or -O3. (#67)Romain Geissler @ Amadeus2018-03-061-0/+5
|
* x86_64: support for RIP in unw_get_save_loc (#66)laiwei-rice2018-03-061-0/+1
| | | Returns the location of RIP through unw_get_save_loc().
* Don't check if the memory is in core (#64)ShutterQuick2018-02-091-6/+1
| | | | | | | libunwind uses mincore() to validate that memory is mapped and available to the process. For this purpose, checking the return value of mincore() is sufficient. The result array tells us if the kernel has swapped out the page or not. We don't care about this, and the check leads to failure in those cases where the kernel has swapped out the page.
* Use syscall directly in write_validate to avoid ASAN errorsDave Watson2018-01-172-2/+6
| | | | | | | | | | | ASAN will complain about this write call with the following error: ERROR: AddressSanitizer: stack-buffer-underflow on address HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext This is similar to what google's abseil does to work around the issue. Reported-by: qiwang@fb.com
* s390x: remove unw_handle_signal_frame from public API. (#62)Michael Munday2018-01-111-3/+3
| | | Ports e287b69 to s390x and fixes the namespace check.
* s390x: remove PROTECTED visibilityDave Watson2018-01-0913-17/+17
|
* Add port to Linux on IBM Z (s390x)Michael Munday2018-01-0945-1/+2400
| | | | | | | | | | | | | | | | | | | | | | | | This adds a port to Linux on the IBM Z platform (a.k.a s390x). It only supports the 64-bit ABI. Most functionality is working and all the tests pass with the exception of the coredump tests*. Unwinding is only supported if DWARF unwind information is present. libunwind can't currently make use of the backchain (if present). The getcontext/setcontext functions only preserve/restore a subset of registers. Currently this only consists of callee-saved registers and some parameter registers. Vector registers and access registers are not saved (and aren't callee- saved) by getcontext and cannot currently be modified. They will however be restored unmodified after resuming a context from a signal handler. There is no special libunwind support for setjmp, the functionality is emulated using glibc (I think all the ports do this for modern Linux kernels). * Unwinding on s390x requires floating point register access which the coredump library doesn't currently support.
* ALIAS unwind_get_accessorsDave Watson2017-12-2826-32/+40
|
* ALIAS dwarf symbolsDave Watson2017-12-283-6/+14
|
* Remove unw_handle_signal_frame from public API.Dave Watson2017-12-2820-31/+38
|
* Remove PROTECTED visibilityDave Watson2017-12-28185-235/+232
| | | | This only works on bfd ld, not lld or gold.
* dwarf: Fix size of state to avoid corrupting rs_stackMichael Munday2017-11-282-3/+3
| | | | | | | | | | DW_CFA_remember_state used memcpy to overwrite state with the value of rs_current. Unfortunately rs_current was slightly larger than state, possibly resulting in rs_stack->next being overwritten. Fix this by making the type of state match the type of rs_current and using an assigment to perform the copy rather than memcpy. This should ensure that the types match in future.
* Bump version to 1.3-rc1v1.3-rc1Dave Watson2017-11-223-6/+24
|
* Default to --enable-debug-frame also on aarch64Adrian Bunk2017-11-211-0/+1
| | | | This is required for perf to show call graphs.
* elfxx: store elf image pointer and size after mapping imageHans-Christian Noren Egtvedt2017-11-091-2/+5
| | | | | | | | | | | If loading debug link is not successful, the initial NULL pointer for ei->image will eventually be restored, causing segfault during a later call to valid_object. Move populating the prev_image and prev_size to after elf_map_image() to fix this. Signed-off-by: Hans-Christian Noren Egtvedt <hegtvedt@cisco.com>
* dwarf: Fix incorrect cfi execution (#54)Yichao Yu2017-11-011-42/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | During unwinding/resuming execution of a normal call frame, it is not only necessary to use the previous instruction to lookup the unwind info but also when executing the cfi program. Although the call usually don't modify any unwinding state, it can happen for noreturn call or when the callee cleanup the stack. In these cases, the next instruction after the call may have a cfi adjusting the state (e.g. stack pointer) and such instruction should be executed. 3d9a694de85f2ba10368b4fbc2aff1c6b8b76f58 worked around this issue by treating `cfi_restore_state` specially. It works when the compiler use that instruction to restore the state, i.e. ``` .cfi_remember_state je .L0 push ... .cfi_def_cfi_offset <new_value> call noreturn .L0 .cfi_restore_state ``` which is what GCC ususally does. However, it is not necessarily the case and clang/LLVM doesn't do that. Instead LLVM emits the following unwind info which is also perfectly valid but is not handled by the special case. ``` je .L0 push ... .cfi_def_cfi_offset <new_value> call noreturn .L0 .cfi_def_cfi_offset <old_value> ``` e9e8ed73e34a2d65c7ec71c296156637763ffd5c also worked around this issue for another special case. This patch fix this issue for all cfi types by adjusting the `end_ip` based on the type of the current frame instead, similar to what's done in `fetch_proc_info`. Since this requires using the same `use_prev_instr` value after `fetch_proc_info` returns, the patch also remove the `need_unwind_info` parameter to the function and move the code updating `use_prev_instr` after all use of the old value are done.
* dwarf: Allow DWARF version both 3 and 4 (#56)Yichao Yu2017-10-312-4/+6
|
* arm: Handle non-signal frame unwind info lookup in ARM exidx unwinder (#55)Yichao Yu2017-10-311-2/+5
|
* Fix intermittent test failure in test-resume-sig (#51)Yichao Yu2017-10-311-0/+8
| | | | | | | | | | | | | | | | | (At least on x86(_32),) `unw_resume` will call `setcontext` which will modify the signal masks based on the value in the context. Since the signal mask is not being initialized by `unw_getcontext`, this cause the signal mask to be set to a random (uninitialized) value after `unw_resume` which cause the test to fail since it relies on the signal mask for SIGUSR2 being cleared. The proper fix is likely to either make `unw_resume` not touch the signal mask if the context wasn't initialized with a signal ucontext, or to make `unw_getcontext` record the signal mask too. It's unclear to me which approach should be taken... In the mean time, the intermittent failure can be fixed simply by zero initialing the context first which would clear all the signal masks. When siginfo is available, a more reliable way is to use the `ucontext` passed in to the signal handler directly and rely on `sigreturn` to reset it. Unfortunately, this is currently not implemented on all archs either.
* Ignore tests/Ltest-mem-validate (#52)Yichao Yu2017-10-311-0/+1
|
* Fix init-local-signal test (#50)Yichao Yu2017-10-312-2/+3
| | | | | | | | | * Add `SA_SIGINFO` flag This is needed to guarantee the availability of the `ucontext` argument * Mark the `NULL` pointer load as `volatile` Further prevent any compiler optimization on the load.