summaryrefslogtreecommitdiff
path: root/libunwind/src/DwarfParser.hpp
AgeCommit message (Collapse)Author
2025-10-29[libunwind][PAuthLR] Remove PC offset when using FEAT_PAuthLR (#164224)Jack Styles
When originally introduced to libunwind as part of #112171, FEAT_PAuthLR had its Call Frame Instruction's (CFI's) in a different location to other Signing Authentication methods. To incorporate this in libunwind, a 4 byte offset was introduced to work with this. However, this design was reversed in #121551 so the CFI's are emitted in the same location as other methods. When making this change, the offset in libunwind was not removed, so libunwind's PC value would be incorrect. As the 4 byte offset is no longer needed, that adjustment can be removed. results->ptrAuthDiversifier will still be set.
2025-10-20[runtimes][PAC] Harden unwinding when possible (#143230)Oliver Hunt
This hardens the unwinding logic and datastructures on systems that support pointer authentication. The approach taken to hardening is to harden the schemas of as many high value fields in the myriad structs as possible, and then also explicitly qualify local variables referencing privileged or security critical values. This does introduce ABI linkage between libcxx, libcxxabi, and libunwind but those are in principle separate from the OS itself so we've kept the schema definitions in the library specific headers rather than ptrauth.h
2025-09-01[libunwind] fix pc range condition check bug (#154902)Wu Yingcong
There is an off-by-one error with current condition check for PC fallen into the range or not. There is another check within libunwind that use the correct checks in https://github.com/llvm/llvm-project/blob/5050da7ba18fc876f80fbeaaca3564d3b4483bb8/libunwind/src/UnwindCursor.hpp#L2757 ``` if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd)) ```
2024-10-28[AArch64][Libunwind] Add Support for FEAT_PAuthLR DWARF Instruction (#112171)Jack Styles
As part of FEAT_PAuthLR, a new DWARF Frame Instruction was introduced, `DW_CFA_AARCH64_negate_ra_state_with_pc`. This instructs Libunwind that the PC has been used with the signing instruction. This change includes three commits - Libunwind support for the newly introduced DWARF Instruction - CodeGen Support for the DWARF Instructions - Reversing the changes made in #96377. Due to `DW_CFA_AARCH64_negate_ra_state_with_pc`'s requirements to be placed immediately after the signing instruction, this would mean the CFI Instruction location was not consistent with the generated location when not using FEAT_PAuthLR. The commit reverses the changes and makes the location consistent across the different branch protection options. While this does have a code size effect, this is a negligible one. For the ABI information, see here: https://github.com/ARM-software/abi-aa/blob/853286c7ab66048e4b819682ce17f567b77a0291/aadwarf64/aadwarf64.rst#id23
2022-09-21[libunwind] Handle G in personality stringFlorian Mayer
Tested with the following program: ``` static volatile int* x = nullptr; void throws() __attribute__((noinline)) { if (getpid() == 0) return; throw "error"; } void maybe_throws() __attribute__((noinline)) { volatile int y = 1; x = &y; throws(); y = 2; } int main(int argc, char** argv) { int y; try { maybe_throws(); } catch (const char* e) { //printf("Caught\n"); } y = *x; printf("%d\n", y); // should be MTE failure. return 0; } ``` Built using `clang++ -c -O2 -target aarch64-linux -fexceptions -march=armv8-a+memtag -fsanitize=memtag-heap,memtag-stack` Currently only Android implements runtime support for MTE stack tagging. Without this change, we crash on `__cxa_get_globals` when trying to catch the exception (because the stack frame __cxa_get_globals frame will fail due to tags left behind on the stack). With this change, we crash on the `y = *x;` as expected, because the stack frame has been untagged, but the pointer hasn't. Reviewed By: #libunwind, compnerd, MaskRay Differential Revision: https://reviews.llvm.org/D128998
2022-08-20[libunwind] Fixed a number of typosGabriel Ravier
I went over the output of the following mess of a command: `(ulimit -m 2000000; ulimit -v 2000000; git ls-files -z | parallel --xargs -0 cat | aspell list --mode=none --ignore-case | grep -E '^[A-Za-z][a-z]*$' | sort | uniq -c | sort -n | grep -vE '.{25}' | aspell pipe -W3 | grep : | cut -d' ' -f2 | less)` and proceeded to spend a few days looking at it to find probable typos and fixed a few hundred of them in all of the llvm project (note, the ones I found are not anywhere near all of them, but it seems like a good start). Reviewed By: #libunwind, MaskRay Differential Revision: https://reviews.llvm.org/D130948
2022-02-05[libunwind] [sparc] Add SPARCv9 supportKoakuma
Adds libunwind support for SPARCv9 (aka sparc64). This is a rebase of @kettenis' patch D32450, which I created (with his permission) because the original review has become inactive. The changes are of a cosmetic nature to make it fit better with the new code style, and to reuse the existing SPARCv8 code, whenever possible. Please let me know if I posted this on the wrong place. Also, the summary of the original review is reproduced below: > This adds unwinder support for 64-bit SPARC (aka SPARCv9). The implementation was done on OpenBSD/sparc64, so it takes StackGhost into account: > > https://www.usenix.org/legacy/publications/library/proceedings/sec01/full_papers/frantzen/frantzen_html/index.html > > Since StackGhost xor's return addresses with a random cookie before storing them on the stack, the unwinder has to do some extra work to recover those. This is done by introducing a new kRegisterInCFADecrypt "location" type that is used to implement the DW_CFA_GNU_window_save opcode. That implementation is SPARC-specific, but should work for 32-bit SPARC as well. DW_CFA_GNU_window_save is only ever generated on SPARC as far as I know. Co-authored-by: Mark Kettenis Reviewed By: #libunwind, thesamesam, MaskRay, Arfrever Differential Revision: https://reviews.llvm.org/D116857
2022-01-19[NFC][libunwind] Fix uintptr_t vs size_t confusion for lengthsJessica Clarke
These two are not conceptually the same; the former is a pointer shoved in an integer, the latter is an offset or length. On the architectures supported by libunwind, these two have the same underlying type, namely unsigned int on ILP32, unsigned long on LP64 and unsigned long long on LLP64. However, on CHERI, and thus Arm's Morello, they are not the same, as pointers are hardware capabilities that carry additional metadata including bounds and permissions, which is preserved in uintptr_t but not in size_t. Thus, fix all length variables to be of type size_t not uintptr_t, as we have done downstream for a while in CHERI LLVM but did not get round to upstreaming. Note that dyld_unwind_sections is currently defined in Apple's headers as genuinely using uintptr_t to represent lengths. This is a bad API and should be fixed, which would be totally API and ABI compatible due to size_t and uintptr_t being the same type on all supported Apple systems, but our definition is left matching theirs until such a time as they fix their bogus types. This is intended to be an NFC change on all architectures supported by LLVM upstream, only being a functional change for CHERI downstream in CHERI LLVM.
2021-11-18[libunwind] Add an interface for dynamic .eh_frame registrationPeter S. Housel
The libgcc runtime library provides __register_frame and __deregister_frame functions, which can be used by dynamic code generators to register an .eh_frame section, which contains one or more Call Frame Information records, each consisting of a Common Information Entry record followed by one or more Frame Description Entry records. This libunwind library also provides __register_frame and __deregister_frame functions, but they are aliases for __unw_add_dynamic_fde and __unw_remove_dynamic_fde and thus can only take a single FDE. This patch adds __unw_add_dynamic_eh_frame_section and __unw_remove_dynamic_eh_frame_section functions which explicitly use the .eh_frame format. Clients such as the ORCv2 platform and runtime can check for these functions and use them if unwinding is being provided by libunwind, or fall back to __register_frame and __deregister_frame if unwinding is provided by libgcc. Reviewed By: lhames Differential Revision: https://reviews.llvm.org/D111863
2021-11-17[runtimes][NFC] Remove filenames at the top of the license noticeLouis Dionne
We've stopped doing it in libc++ for a while now because these names would end up rotting as we move things around and copy/paste stuff. This cleans up all the existing files so as to stop the spreading as people copy-paste headers around.
2021-08-20[libunwind] Add UNW_AARCH64_* beside UNW_ARM64_*Fangrui Song
The original libunwind project defines UNW_AARCH64_* instead of UNW_ARM64_*. Rename the enum members to match. This allows some applications with simple `unw_init_local` usage to migrate to llvm-project libunwind. Note: the canonical names of `UNW_ARM_D{0..31}` are now `UNW_AARCH64_V{0..31}`, to match the original libunwind. UNW_ARM64_* are kept for now for compatibility. Some may be unneeded and can be cleaned up in the future. Reviewed By: #libunwind, compnerd Differential Revision: https://reviews.llvm.org/D107996
2020-11-09[libunwind] Delete unused ↵Fangrui Song
codeOffsetAtStackDecrement/registersInOtherRegisters/sameValueUsed ld64 uses them to create compact unwind from DWARF call frame information. When the code was ported to libunwind, the variables were not deleted. Reviewed By: #libunwind, compnerd Differential Revision: https://reviews.llvm.org/D91039
2020-10-30[libunwind] Support DW_CFA_remember/restore_state without heap allocation.Daniel Kiss
This patch just reorganises the code to make possible to use alloca instead of malloc. This makes possible to use `.cfi_remember_state`/`.cfi_restore_state` on platforms without heap allocation. Also it will be safe to backtrace/unwind faults related to the allocator behind malloc. `_LIBUNWIND_REMEMBER_HEAP_ALLOC ` option reenables the heap usage for `.cfi_remember_state`/`.cfi_restore_state`. Define _LIBUNWIND_REMEMBER_STACK_ALLOC to force stack allocation. Reviewed By: #libunwind, mstorsjo Differential Revision: https://reviews.llvm.org/D85005
2020-09-18[libunwind] Support for leaf function unwinding.Daniel Kiss
Unwinding leaf function is useful in cases when the backtrace finds a leaf function for example when it caused a signal. This patch also add the support for the DW_CFA_undefined because it marks the end of the frames. Ryan Prichard provided code for the tests. Reviewed By: #libunwind, mstorsjo Differential Revision: https://reviews.llvm.org/D83573 Reland with limit the test to the x86_64-linux target.
2020-09-18Revert "[libunwind] Support for leaf function unwinding."Daniel Kiss
This reverts commit 23bef7ee9923b1262326981960397e8cd95d6923.
2020-09-16[libunwind][DWARF] Fix end of .eh_frame calculationRyan Prichard
* When .eh_frame is located using .eh_frame_hdr (PT_GNU_EH_FRAME), the start of .eh_frame is known, but not the size. In this case, the unwinder must rely on a terminator present at the end of .eh_frame. Set dwarf_section_length to UINTPTR_MAX to indicate this. * Add a new field, text_segment_length, that the FrameHeaderCache uses to track the size of the PT_LOAD segment indicated by dso_base. * Compute ehSectionEnd by adding sectionLength to ehSectionStart, never to fdeHint. Fixes PR46829. Differential Revision: https://reviews.llvm.org/D87750
2020-09-16[libunwind] Support for leaf function unwinding.Daniel Kiss
Unwinding leaf function is useful in cases when the backtrace finds a leaf function for example when it caused a signal. This patch also add the support for the DW_CFA_undefined because it marks the end of the frames. Ryan Prichard provided code for the tests. Reviewed By: #libunwind, mstorsjo Differential Revision: https://reviews.llvm.org/D83573
2020-07-15[libunwind] Fix CIE v1 return address parsingRyan Prichard
- For CIE version 1 (e.g. in DWARF 2.0.0), the return_address_register field is a ubyte [0..255]. - For CIE version 3 (e.g. in DWARF 3), the field is instead a ULEB128 constant. Previously, libunwind accepted a CIE version of 1 or 3, but always parsed the field as ULEB128. Clang always outputs CIE version 1 into .eh_frame. (It can output CIE version 3 or 4, but only into .debug_frame.) Differential Revision: https://reviews.llvm.org/D83741
2020-05-15unwind: fix unwind build without heapSaleem Abdulrasool
Add a missing guard for `_LIBUNWIND_NO_HEAP` around code dealing with the `.cfi_remember_state` and `.cfi_restore_state` instructions. Patch by Amanieu d'Antras!
2020-03-11Lazily save initialState of registers during unwind.Sterling Augustine
Summary: Copying all of the saved register state on every entry to parseInstruction is a severe performance contraint, especially because most of this saved state is never used. On x86 linux this is about 560 bytes, and will be more on other platforms. When performance testing libunwind, this memcpy appears at the top of nearly all our tests. By only saving this state as needed, we see increasing in performance of around 2.5% for the ctak test here. https://github.com/clasp-developers/ctak Certain internal extremely exception-heavy tasks run in about 2/3 the time. Note that by stashing the new boolean inside what had been padding in the original structure, this uses no additional memory. Subscribers: fedor.sergeev, libcxx-commits Tags: #libc Differential Revision: https://reviews.llvm.org/D75692
2020-02-18[libunwind] Fix memory leak in handling of DW_CFA_remember_state and ↵Jorge Gorbe Moya
DW_CFA_restore_state parseInstructions() doesn't always process the whole set of DWARF instructions for a frame. It will stop once the target PC is reached, or if malformed instructions are found. So, for example, if we have an instruction sequence like this: ``` <start> ... DW_CFA_remember_state ... DW_CFA_advance_loc past the location we're unwinding at (pcoffset in parseInstructions() main loop) ... DW_CFA_restore_state <end> ``` ... the saved state will never be freed, even though the DW_CFA_remember_state opcode has a matching DW_CFA_restore_state later in the sequence. This change adds code to free whatever is left on rememberStack after parsing the CIE and the FDE instructions. Differential Revision: https://reviews.llvm.org/D66904
2019-01-19Update more file headers across all of the LLVM projects in the monorepoChandler Carruth
to reflect the new license. These used slightly different spellings that defeated my regular expressions. We understand that people may be surprised that we're moving the header entirely to discuss the new license. We checked this carefully with the Foundation's lawyer and we believe this is the correct approach. Essentially, all code in the project is now made available by the LLVM project under our new license, so you will see that the license headers include that license only. Some of our contributors have contributed code under our old license, and accordingly, we have retained a copy of our old license notice in the top-level files in each project and repository. llvm-svn: 351648
2019-01-14[Sparc] Add Sparc V8 supportDaniel Cederman
Summary: Adds the register class implementation for Sparc. Adds support for DW_CFA_GNU_window_save. Adds save and restore context functionality. Adds getArch() function to each Registers_ class to be able to separate between DW_CFA_AARCH64_negate_ra_state and DW_CFA_GNU_window_save which are both represented by the same constant. On Sparc the return address is the address of the call instruction, so an offset needs to be added when returning to skip the call instruction and its delay slot. If the function returns a struct it is also necessary to skip one extra instruction on Sparc V8. Reviewers: jyknight, mclow.lists, mstorsjo, compnerd Reviewed By: jyknight, compnerd Subscribers: jgorbe, mgorny, christof, llvm-commits, fedor.sergeev, JDevlieghere, ldionne, libcxx-commits Differential Revision: https://reviews.llvm.org/D55763 llvm-svn: 351044
2019-01-10Revert "[Sparc] Add Sparc V8 support"Jorge Gorbe Moya
This reverts commit r350705. llvm-svn: 350787
2019-01-09[Sparc] Add Sparc V8 supportDaniel Cederman
Summary: Adds the register class implementation for Sparc. Adds support for DW_CFA_GNU_window_save. Adds save and restore context functionality. On Sparc the return address is the address of the call instruction, so an offset needs to be added when returning to skip the call instruction and its delay slot. If the function returns a struct it is also necessary to skip one extra instruction. Reviewers: jyknight, mclow.lists, mstorsjo, compnerd Reviewed By: compnerd Subscribers: fedor.sergeev, JDevlieghere, ldionne, libcxx-commits Differential Revision: https://reviews.llvm.org/D55763 llvm-svn: 350705
2018-12-17[AArch64][libunwind] Unwinding support for return address signing with B KeyLuke Cheeseman
- Support for the case where the return address has been signed with the B key - When the B key is used, a 'B' character is present in the augmentation string of CIE associated with the FDE for the function. Differential Revision: https://reviews.llvm.org/D55704 llvm-svn: 349339
2018-12-14[AArch64][libunwind] Unwinding support for return address signingLuke Cheeseman
- Follow up to revision r342895 - gcc would not build libunwind with the earlier patch as the autia1716 instruction wasn't allowed to be assembled for pre armv8.3a targets - The autia1716 instruction lives in the hint space encodings so is a valid instruction for all armv8a targets - To work around this I have swapped out the autia1716 instruction for the hint instruction Differential Revision: https://reviews.llvm.org/D55700 llvm-svn: 349140
2018-09-24Reverting r342895Luke Cheeseman
- The used builtins do not compile for pre arm v8.3a targets with gcc llvm-svn: 342901
2018-09-24[AArch64] Unwinding support for return address signingLuke Cheeseman
- When return address signing is enabled, the LR may be signed on function entry - When an exception is thrown the return address is inspected used to unwind the call stack - Before this happens, the return address must be correctly authenticated to avoid causing an abort by dereferencing the signed pointer Differential Revision: https://reviews.llvm.org/D51432 llvm-svn: 342895
2017-12-25[libunwind] Remove dubious template function. NFC.whitequark
Per review by Don Hinton. llvm-svn: 321448
2017-12-25[libunwind] Unbreak debug builds after r321440.whitequark
llvm-svn: 321446
2017-12-25[libunwind] fix a typo in r321441.whitequark
llvm-svn: 321442
2017-12-25[libunwind] convert error logs to _LIBUNWIND_LOG/_LIBUNWIND_LOG0.whitequark
Use the `_LIBUNWIND_LOG` and `_LIBUNWIND_LOG0` macros instead of the explicit `fprintf` call. This was previously done in r292721 as a cleanup and then reverted in r293257 because the implementation in r292721 relied on a GNU extension. This implementation avoids the use of an extension by using a second macro instead, and allows to avoid the dependency on fprintf if _LIBUNWIND_BARE_METAL is defined. llvm-svn: 321441
2017-12-25[libunwind] Avoid using C++ headers.whitequark
This is useful for building libunwind on libcxx-free systems. llvm-svn: 321440
2017-10-27Express Registers_*::lastDwarfReg using _LIBUNWIND_HIGHEST_DWARF_REGISTERMartin Storsjo
This avoids having to keep the same information duplicated in multiple places. Adjust _LIBUNWIND_HIGHEST_DWARF_REGISTER to actually have the value of the highest used register and only use the value _LIBUNWIND_HIGHEST_DWARF_REGISTER + 1 (kMaxRegisterNumber + 1) for allocating the savedRegisters array. Differential Revision: https://reviews.llvm.org/D39281 llvm-svn: 316745
2017-10-24Add missing checks for register numberMartin Storsjo
Most other cases that touch savedRegisters[reg] have got this check, but these three seemed to lack it. Differential Revision: https://reviews.llvm.org/D39206 llvm-svn: 316415
2017-03-14DarwinParser: include limitsSaleem Abdulrasool
In debug mode, we have assertions that the values do not exceed the limits of the type holding them. In order to account for the type being derived from the AddressSpace and thus a typedef, we use `std::numeric_limits`. Include the appropriate header. Thanks to Marshal Clow for pointing out the missing include! llvm-svn: 297744
2017-03-09Fix up the places where AddressSpace.hpp is included.Ed Schouten
The AddressSpace.hpp header declares two classes: LocalAddressSpace and RemoteAddressSpace. These classes are only used in a very small number of source files, but passed in as template arguments to many other classes. Let's go ahead and only include AddressSpace.hpp in source files where at least one of these two classes is mentioned. This gets rid of a cyclic header dependency that was already present, but only caused breakage on macOS until recently. Reported by: Marshall Clow llvm-svn: 297364
2017-03-08DARWF: silence some warnings about conversionsSaleem Abdulrasool
Add a check for an overflow and explicitly cast the value. We would have silently overflowed previously. llvm-svn: 297291
2017-01-27Revert "DWARF: convert error logs to _LIBUNWIND_LOG"Saleem Abdulrasool
This reverts SVN r292721. Avoid the use of the GNU extension as the preprocessor in C++11 mode requires at least one argument, and this warning cannot be disabled, resulting in failing -Werror builds. llvm-svn: 293257
2017-01-25DWARF: fix -Asserts buildsSaleem Abdulrasool
no-op the DWARF tracing macros in non-debug builds. llvm-svn: 293008
2017-01-21DWARF: correct cast (NFC)Saleem Abdulrasool
Change the case of a PRIu64 value from `long` to `uint64_t`. NFC. llvm-svn: 292728
2017-01-21DWARF: allow enabling tracing at runtimeSaleem Abdulrasool
Introduce `logDWARF` and the associated environment variable `LIBUNWIND_PRINT_DWARF` to trace the CFI instructions. llvm-svn: 292722
2017-01-21DWARF: convert error logs to _LIBUNWIND_LOGSaleem Abdulrasool
Use the `_LIBUNWIND_LOG` macro instead of the explicit `fprintf` call. NFC. llvm-svn: 292721
2016-07-20libunwind: limit stack usage in unwind cursorEd Maste
Obtained from FreeBSD SVN r302475 Differential Revision: https://reviews.llvm.org/D22570 llvm-svn: 276128
2016-07-19libunwind: sync some coments with NetBSD's versionEd Maste
NetBSD's system unwinder is a modified version of LLVM's libunwind. Slightly reduce diffs by updating comments to match theirs where appropriate. llvm-svn: 275997
2016-07-19libunwind: Use conventional DWARF capitalization in comments and errorsEd Maste
llvm-svn: 275996
2015-11-09Make it possible to use libunwind without heap.Peter Zotov
This patch allows to use libunwind on bare-metal systems that do not include malloc/free by conditionally turning off nonessential functionality that requires these functions. The disabled functionality includes: * the .cfi_remember_state and .cfi_restore_state instructions; * the DWARF FDE cache. The .cfi_{remember,restore}_state instructions don't seem to be used by contemporary compilers. None of the LLVM backends emit it. The DWARF FDE cache is bypassed if _LIBUNWIND_NO_HEAP is defined. Specifically, entries are never added to it, so the search begins and ends at the statically allocated, empty initial cache. Such heap-less libunwind on a bare metal system is successfully used in the ARTIQ project[1], and it is my hope that it will be useful elsewhere. [1]: http://m-labs.hk/artiq Differential Revision: http://reviews.llvm.org/D11897 llvm-svn: 252452
2015-08-27[libunwind] Remove unused includes.Peter Zotov
llvm-svn: 246143
2015-04-24unwind: move src/Unwind, include/, and test/ unwind contentSaleem Abdulrasool
This moves the majority of the unwind sources into the new project layout for libunwind. This was previously discussed on llvmdev at [1]. This is a purely movement related change, with the build infrastructure currently still residing in the libc++abi repository. [1] http://lists.cs.uiuc.edu/pipermail/llvmdev/2015-January/081507.html llvm-svn: 235758