Compiling with `O3`, the `early-machinelicm` pass hoisted the asm
statement to a path that has been executed unconditionally during stack
unwinding. On hardware without vector extension support, this resulted
in reading a nonexistent register.
libunwind currently supports shadow stack based on the Intel CET and
AArch64 GCS technology, but throughout related codes, the Intel-specific
keyword, "CET", is used to refer to the generic concept of control-flow
integrity/shadow stack. This patch replaces such wordings with
architecture-neutral term "shadow stack" (abbr. "shstk") to allow future
implementation to avoid using the Intel-specific "CET" term.
Similar to D90898 (Linux AArch64), D124765 (SystemZ), and D148499
(RISCV).
In this commit, I enabled two test cases, while zhuqizheng supported
with the source code development.
Co-Authored-By: zhuqizheng <zhuqizheng@loongson.cn>
Co-authored-by: zhuqizheng <zhuqizheng@loongson.cn>
When building libunwind with LTO, we found that routines, like
_Unwind_RaiseException were marked `nounwind`. This causes problems when
libunwind is then used with exception throwing code, since many of the
routines are marked `nounwind` and the compiler infers that something
like a try/catch block cannot throw resulting in a miscompile
(see #120657). Similarly, in #56825, it was pointed out that marking
_Unwind_Resume as `nounwind` causes bad exception table generation.
This patch adds the `-fexceptions` flag to the build of the C files that
define these routines, as proposed in #56825.
Fixes#56825#120657
---------
Co-authored-by: Petr Hosek <phosek@google.com>
* Signal frame unwinding on x86_64 from X512
* Header search for commpage_defs.h on non-standard paths
Unwind supported tests pass on Haiku x86_64
---------
Co-authored-by: Trung Nguyen <trungnt282910@gmail.com>
These two libraries don't build for `-march=armv8-a+nofp
-mabi=aapcs-soft` as a couple of uses of floating point instructions and
registers have crept in.
In libunwind, skip save/restore of FPU registers on targets without them.
In compiler-rt, fall back to the old C implementation of __arm_sc_memset when
the target doesn't have an FPU.
---------
Signed-off-by: Keith Packard <keithp@keithp.com>
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:
853286c7ab/aadwarf64/aadwarf64.rst (id23)
While these flags semantically are relevant only for C++, we do add them
to CMAKE_REQUIRED_FLAGS if they are detected. All flags in that variable
are used both when testing compilation of C and C++ (and for detecting
libraries, which uses the C compiler driver).
Therefore, to be sure we safely can add the flags to
CMAKE_REQUIRED_FLAGS, test for the option with the C language.
This should fix compilation with GCC; newer versions of GCC do support
the -nostdlib++ option, but it's only supported by the C++ compiler
driver, not the C driver. (However, many builds of GCC also do accept
the option with the C driver, if GCC was compiled with Ada support
enabled, see [1]. That's why this issue isn't noticed in all
configurations with GCC.)
Clang does support these options in both C and C++ driver modes.
This should fix#90332.
[1]
https://github.com/llvm/llvm-project/issues/90332#issuecomment-2325099254
The personality routine `__xlcxx_personality_v0` in `libc++abi` is
hard-coded in the unwinder as the handler for EH in applications
generated by the legacy IBM C++ compiler. The symbol is resolved
dynamically using `dlopen` to avoid a hard dependency of `libunwind` on
`libc++abi` for cases such as non-C++ applications. However, `dlclose`
was incorrectly called after `dlsym` succeeded, potentially invalidating
the function pointer obtained from `dlsym` when the memory allocated for
the `dlopen` is reclaimed. This PR changes to call `dlclose` only when
`dlsym` fails.
`__xlcxx_personality_v0` is the personality routine in `libc++abi` for
the EH of applications generated by the legacy IBM C++ compiler. Since
the EH info generated by the legacy compiler does not provide the
location of the personality routine, this routine is hard-coded as the
handler for legacy EH in the unwinder. The symbol is resolved
dynamically using `dlopen()` to avoid a hard dependency of `libunwind`
on `libc++abi` for cases such as non-C++ applications. The weak
declaration of `__xlcxx_personality_v0` was originally intended to
bypass `dlopen()` if the C++ application generated by the legacy
compiler is statically linked with the new LLVM C++ compiler.
Unfortunately, this causes problems with runtime linking for
Clang-compiled code using the unwinder that does not link with
`libc++abi`.
On the other hand, the C++ runtime libraries shipped for AIX are
actually stripped and statically linking is not supported. So, we can
fix the problem by removing the `__xlcxx_personality_v0` weak
declaration. Besides, `dlopen()` would work as long as the libc++abi
shared library is available.
This is a purely mechanical commit for fixing the indentation of the
runtimes' CMakeLists files after #80007. That PR didn't update the
indentation in order to make the diff easier to review and for merge
conflicts to be easier to resolve (for downstream changes).
This doesn't change any code, it only reindents it.
This patch always defines the cxx_shared, cxx_static & other top-level
targets. However, they are marked as EXCLUDE_FROM_ALL when we don't want
to build them. Simply declaring the targets should be of no harm, and it
allows other projects to mention these targets regardless of whether
they end up being built or not.
This patch basically moves the definition of e.g. cxx_shared out of the
`if (LIBCXX_ENABLE_SHARED)` and instead marks it as EXCLUDE_FROM_ALL
conditionally on whether LIBCXX_ENABLE_SHARED is passed. It then does
the same for libunwind and libc++abi targets. I purposefully avoided to
reformat the files (which now has inconsistent indentation) because I
wanted to keep the diff minimal, and I know this is an area of the code
where folks may have downstream diffs. I will re-indent the code
separately once this patch lands.
This is a reapplication of 79ee0342dbf0, which was reverted in
a3539090884c because it broke the TSAN and the Fuchsia builds.
Resolves#77654
Differential Revision: https://reviews.llvm.org/D134221
This patch introduces the LIBUNWIND_LIBRARY_VERSION setting to control
the dylib version of libunwind. This allows expressing the dylib version
in CMake instead of adding custom compiler flags.
As a drive-by, also remove some outdated Apple flags that are not
relevant anymore.
The libunwind assembly files need adjustment in order to work correctly
when both BTI and GCS are both enabled (which will be the case when
using -mbranch-protection=standard):
* __libunwind_Registers_arm64_jumpto can't use br to jump to the return
location, instead we need to use gcspush then ret.
* Because we indirectly call __libunwind_Registers_arm64_jumpto it needs
to start with bti jc.
* We need to set the GCS GNU property bit when it's enabled.
---------
Co-authored-by: Daniel Kiss <daniel.kristof.kiss@gmail.com>
We need both GCS to be enabled by the compiler (which we do by checking
if __ARM_FEATURE_GCS_DEFAULT is defined) and for arm_acle.h to define
the GCS intrinsics. Check the latter by checking if _CHKFEAT_GCS is
defined.
AArch64 GCS (Guarded Control Stack) is similar enough to CET that we can
re-use the existing code that is guarded by _LIBUNWIND_USE_CET, so long
as we also add defines to locate the GCS stack and pop the entries from
it. We also need the jumpto function to exit using br instead of ret, to
prevent it from popping the GCS stack.
GCS support is enabled using the LIBUNWIND_ENABLE_GCS cmake option. This
enables -mbranch-protection=standard, which enables GCS. For the places
we need to use GCS instructions we use the target attribute, as there's
not a command-line option to enable a specific architecture extension.
Don't try to save x16-x31 when using rv32e ISA
Note that I haven't actually tested yet whether or not unwinding
actually works on rv32e, but the code as-is doesn't even build.
Patch [llvm#92291](https://github.com/llvm/llvm-project/pull/92291)
causes wrong traceback from a signal handler for AIX because the AIX
unwinder uses the traceback table at the end of each function instead of
FDE/CIE for unwinding. This patch adds a condition to exclude traceback
table based unwinding from the code added by the patch.
In case of this is frame of signal handler, the IP should be
incremented, because the IP saved in the signal handler points to first
non-executed instruction, while FDE/CIE expects IP to be after the first
non-executed instruction.
Refs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=26208
This tries to make Wasm compilable in LLVM tree with CMake for
non-Emscripten platform.
This
- Adds `-D__USING_WASM_EXCEPTIONS__` when you compile with
`-fwasm-exceptions` (like other EH options) in Clang
- Exclude `UnwindLevel1.c`, `UnwindRegistersSave.S`, and
`UnwindRegistersRestore.S` when compiling with Wasm
- Changed some `__USING_WASM_EXCEPTIONS__` to `__wasm__`; they should be
applied when compiling with Wasm w/o exceptions.
- Define some unused macros to make it compile
Fixes#72771.
27ce26b06655cfece3d54b30e442ef93d3e78ac7 added the new option
-fvisibility-global-new-delete=, where -fvisibility-global-new-delete=force-hidden
is equivalent to the old option -fvisibility-global-new-delete-hidden.
At the same time, the old option was deprecated.
Test for and use the new option form first; if unsupported, try
using the old form.
This avoids warnings in the MinGW builds, if built with Clang 18 or
newer.
Commit fc1c478709e3 added includes of <signal.h> and <errno.h> to
UnwindCursor.hpp. The library previously built on platforms where these
headers are not provided. These headers should be included only in the
case where they are actually needed, i.e. on Linux.
Fix this issue
[#76957](https://github.com/llvm/llvm-project/issues/76957)
Libgcc provides __register_frame to register a dynamic .eh_frame
section, while __unw_add_dynamic_eh_frame_section can be used to do the
same in libunwind. However, the address after dynamic .eh_frame are
padding with 0 value, it will be identified as
legal CIE. And __unw_add_dynamic_eh_frame_section will continue to parse
subsequent addresses until illegal memory or other sections are
accessed.
This patch adds length formal parameter for dynamic registration.
process_vm_readv is generally considered dangerous from a syscall
perspective, and is frequently blanket banned in seccomp filters such as
those in Chromium and ChromiumOS. We can get the same behaviour during
the invalid PC address case with the raw SYS_rt_sigprocmask syscall.
Testing to ensure that process_vm_readv does not appear, I ran the
output of check-unwind on an ARM64 device under strace. Previously,
bad_unwind_info in particular would use process_vm_readv, but with this
commit, it now no longer uses it:
```
strace test/Output/bad_unwind_info.pass.cpp.dir/t.tmp.exe \
|& grep process_vm_readv
```
The libunwind unittests were also tested on ARM64 ChromeOS (Gentoo
Linux) devices.
libunwind uses C-style and low-level C++, so the language standard
doesn't matter that much, but bumping to C++17 aligns with the rest of
LLVM and enables some features that would cause pedantic warnings in
C++11 (e.g. -Wc++17-attribute-extensions for [[fallthrough]]/
[[nodiscard]]/[[maybe_unused]]). (Contributors might use these features
unaware of the pedantic warnings).
Suggested-by: Christopher Di Bella <cjdb@google.com>
libunwind uses a minimal set of necessary standard library functions,
basically just `memset` and `memcpy`. There is a single use of `strcpy`
to copy the bytes `"CLNGUNW"` into a `uint64_t` object. This is both an
arguably odd use of the `strcpy` function as well as it unnecessarily
widens the set of library functions that must be available to build
libunwind, which can be an obstacle in baremetal scenarios. This change
simply replaces this one `strcpy` with the more fundamental `memcpy`.
This PR adds `static_cast` to the value returned from `getLR()` in the
AIX unwinder to avoid warning in case `-Wconversion` is specified to
build in 32-bit mode.
Summary:
The implementation of AIX unwinder gets the return address from the link area of the stack frame of a function and uses the return address to walk up functions. However, when unwinding starts from a signal handler and the function that raised the signal happens to be a leaf function and it does not have its own stack frame, the return address of the stack frame of the leaf function points to the caller of the function that calls the leaf function because the leaf function and its caller share the same stack frame. As a result, the caller of the leaf function is skipped. This patch fixes the problem by saving the LR value in sigcontext when the unwinder hits the signal handler trampoline frame and using it as the return address of the leaf function. The LR value from sigcontext is saved in the unwinding context slot for LR currently unused.
Reviewed by: stephenpeckham
Differential Revision: https://reviews.llvm.org/D158655
I was running the tests with baremetal picolibc which has a linker
script that __eh_frame_start==__eh_frame_end (not equal to zero) in
case there is no .eh_frame_hdr.
I noticed that libunwind was trying to read nonsense data because it
was printing messages such as
`libunwind: unsupported .eh_frame_hdr version: 20 at
8000d30814`
This change adds a ehHdr size check to avoid reading this out-of-bounds
data and potentially crashing.
All but one callsite were actually passing start+length arguments.
This should not have any functional change since the end argument is
almost always ignored.
I noticed this while debugging some incorrect error messages being
printed while running the testsuite baremetal (using binaries that did
not have a valid eh_frame_hdr section): the tests print
`libunwind: unsupported .eh_frame_hdr version: 20 at
8000d30814`
because
libunwind is reading nonsense data for .eh_frame_hdr.
Change PRIu32 to PRIxPTR to avoid type warning of debug printf since VE
uses 64 bits SjLj. I don't use PRIuPTR since the print message has
0x-prefix from the beginning. I also change related PRIuPTR to PRIxPTR
since those uses 0x-prefix too.
Avoid following prototype related warning.
Unwind-sjlj.c:85:75: warning: a function declaration without a prototype
is deprecated in all versions of C [-Wstrict-prototypes]
This adds Wasm-specific libunwind port to support Wasm exception
handling (https://github.com/WebAssembly/exception-handling).
Wasm EH requires `__USING_WASM_EXCEPTIONS__` to be defined. This adds
`Unwind-wasm.c`, which defines libunwind APIs for Wasm. This also adds a
`thread_local` struct of type `_Unwind_LandingPadContext`, which serves
as a medium for input/output data between the user code and the
personality function. How all these work is explained in
https://github.com/WebAssembly/tool-conventions/blob/main/EHScheme.md.
(The doc is old and "You Shouldn't Prune Unreachable Resumes" section
doesn't apply anymore, but otherwise it should be good)
The bulk of these changes was added back in Mar 2020 in
https://github.com/emscripten-core/emscripten/pull/10577 to emscripten
repo and has been used ever since. Now we'd like to upstream this so
that other toolchains that don't use emscripten libraries, e.g., WASI,
can use this too.
Companion patch: D158918
Reviewed By: dschuff, #libunwind, phosek
Differential Revision: https://reviews.llvm.org/D158919
On Apple platforms, we always support the -nostdlib++ flag. Hence, it is
not necessary to manually link against system libraries. In fact, doing
so causes us to link against libSystem explicitly, which messes up with
the order of libraries we should use. Indeed:
Before patch, using the system unwinder (LIBCXXABI_USE_LLVM_UNWINDER = OFF)
===========================================================================
$ otool -L lib/{libc++.1.dylib,libc++abi.1.dylib,libunwind.1.dylib}
lib/libc++.1.dylib:
@rpath/libc++.1.dylib
/usr/lib/libSystem.B.dylib
@rpath/libc++abi.1.dylib
lib/libc++abi.1.dylib:
@rpath/libc++abi.1.dylib
/usr/lib/libSystem.B.dylib
lib/libunwind.1.dylib:
@rpath/libunwind.1.dylib
/usr/lib/libSystem.B.dylib
After patch, using the system unwinder (LIBCXXABI_USE_LLVM_UNWINDER = OFF)
===========================================================================
$ otool -L lib/{libc++.1.dylib,libc++abi.1.dylib,libunwind.1.dylib}
lib/libc++.1.dylib:
@rpath/libc++.1.dylib
@rpath/libc++abi.1.dylib
/usr/lib/libSystem.B.dylib
lib/libc++abi.1.dylib:
@rpath/libc++abi.1.dylib
/usr/lib/libSystem.B.dylib
lib/libunwind.1.dylib:
@rpath/libunwind.1.dylib
/usr/lib/libSystem.B.dylib
Before patch, with the LLVM unwinder (LIBCXXABI_USE_LLVM_UNWINDER = ON)
=======================================================================
$ otool -L lib/{libc++.1.dylib,libc++abi.1.dylib,libunwind.1.dylib}
lib/libc++.1.dylib:
@rpath/libc++.1.dylib
/usr/lib/libSystem.B.dylib
@rpath/libc++abi.1.dylib
@rpath/libunwind.1.dylib
lib/libc++abi.1.dylib:
@rpath/libc++abi.1.dylib
/usr/lib/libSystem.B.dylib
@rpath/libunwind.1.dylib
lib/libunwind.1.dylib:
@rpath/libunwind.1.dylib
/usr/lib/libSystem.B.dylib
After patch, with the LLVM unwinder (LIBCXXABI_USE_LLVM_UNWINDER = ON)
======================================================================
$ otool -L lib/{libc++.1.dylib,libc++abi.1.dylib,libunwind.1.dylib}
lib/libc++.1.dylib:
@rpath/libc++.1.dylib
@rpath/libc++abi.1.dylib
@rpath/libunwind.1.dylib
/usr/lib/libSystem.B.dylib
lib/libc++abi.1.dylib:
@rpath/libc++abi.1.dylib
@rpath/libunwind.1.dylib
/usr/lib/libSystem.B.dylib
lib/libunwind.1.dylib:
@rpath/libunwind.1.dylib
/usr/lib/libSystem.B.dylib
As we can see, libSystem appears before the just-built libraries before
the patch, which causes the libunwind.dylib bundled in libSystem.dylib
to be used instead of the just-built libunwind.dylib.
We didn't notice the issue until recently when I tried to update the
macOS CI builders to macOS 13.5, where it is necessary to use the right
libunwind library (the exact reason still needs to be investigated).
`unw_getcontext` saves the caller's registers in the context. However,
if the caller of `unw_getcontext` is in a different module, the glue
code of `unw_getcontext` sets the TOC register (r2) with the new TOC
base and saves the original TOC register value in the stack frame. This
causes the incorrect TOC value is used when the caller steps up frames,
which fails libunwind LIT test case `unw_resume.pass.cpp`. This PR fixes
the problem by using the original TOC register value saved in the stack
if the caller is in a different module and enables `unw_resume.pass.cpp`
on AIX.