91 Commits

Author SHA1 Message Date
Ami-zhang
12a154a94a
[libunwind] Unwind through loongarch64/Linux sigreturn frame (#123682)
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>
2025-02-08 09:48:41 +08:00
Jérôme Duval
3b904ae5ac
[libunwind][Haiku] Improve support (#115462)
* 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>
2024-12-04 10:40:28 -05:00
Xing Xue
dde26e361f
[libunwind][AIX] Call dlclose only when dlsym() fails (#112768)
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.
2024-10-19 18:41:06 -04:00
Xing Xue
2ef24e05de
[libunwind][AIX] Remove weak declaration "__xlcxx_personality_v0" (#112436)
`__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.
2024-10-17 13:07:18 -04:00
Daniel Kiss
710590e33d
[libunwind] Undefined behaviour pointer arithmetic with null pointer (#98648)
Fixes #91144
2024-08-05 11:16:51 +02:00
John Brawn
b32aac4358
[libunwind] Add GCS support for AArch64 (#99335)
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.
2024-08-04 13:27:12 +01:00
Xing Xue
d90fa61260
[libunwind][AIX] Fix the wrong traceback from signal handler (#101069)
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.
2024-07-30 06:28:59 -04:00
Azat Khuzhin
7b604cdf75
[libunwind] fix unwinding from signal handler (#92291)
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
2024-07-09 12:57:00 -07:00
Izaak Schroeder
495452e7da
[libunwind] Remove needless sys/uio.h (#97495)
No reference to `readv` or `writev`. This makes `libcxx` happy when
compiling against clang's `libc` as part of
https://github.com/llvm/llvm-project/issues/97191.
2024-07-03 09:25:43 -05:00
Xing Xue
42b5daba50
[libunwind][AIX] Cast NULL as type uintptr_t. (#93204)
Casting NULL as type `uintptr_t` to allow type checking in both 32-bit
and 64-bit mode.
2024-05-23 16:06:21 -04:00
Louis Dionne
c1a442462d
[libunwind] Move errno.h and signal.h includes under the block where they're needed (#78054)
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.
2024-01-16 10:31:01 -05:00
Jordan R AW
fc1c478709
[libunwind] Replace process_vm_readv with SYS_rt_sigprocmask (#74791)
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.
2024-01-05 12:56:02 -08:00
xingxue-ibm
7c651a1fc0
[libunwind][AIX] static_cast the value from getLR() to avoid the warning from -Wconversion (#69767)
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.
2023-10-24 11:55:22 -04:00
Xing Xue
45d1511380 [libunwind][AIX] Fix problem with stepping up from a leaf function when unwinding started in a signal handler
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
2023-10-16 12:24:05 -04:00
Feng Wang
f56ea14c29 [libunwind] Unwind through Linux riscv sigreturn trampoline
Similar to D90898 (Linux AArch64) and D124765 (SystemZ).

On an Arch Linux RISC-V (riscv64gc), the following code

```
#define _GNU_SOURCE
#include <dlfcn.h>
#include <libunwind.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

static void handler(int signo) {
  unw_context_t context;
  unw_cursor_t cursor;
  unw_getcontext(&context);
  unw_init_local(&cursor, &context);
  unw_word_t pc, sp;
  do {
    unw_get_reg(&cursor, UNW_REG_IP, &pc);
    unw_get_reg(&cursor, UNW_REG_SP, &sp);
    printf("pc=0x%016zx sp=0x%016zx", (size_t)pc, (size_t)sp);
    Dl_info info = {};
    if (dladdr((void *)pc, &info))
      printf(" %s:%s", info.dli_fname, info.dli_sname ? info.dli_sname : "");
    puts("");
  } while (unw_step(&cursor) > 0);
  exit(0);
}

int main() {
  signal(SIGUSR1, handler);
  raise(SIGUSR1);
  return 1;
}
```

linked with `-Wl,--export-dynamic` gives an output like
```
pc=0x0000000000010a82 sp=0x00007fffd8a0b910 ./b:
pc=0x00007fffa7e77800 sp=0x00007fffd8a0c520 linux-vdso.so.1:__vdso_rt_sigreturn
pc=0x00007fffa7d73bee sp=0x00007fffd8a0c960 /usr/lib/libc.so.6:
pc=0x00007fffa7d3ed66 sp=0x00007fffd8a0c9b0 /usr/lib/libc.so.6:gsignal
pc=0x0000000000010a3c sp=0x00007fffd8a0c9c0 ./b:main
pc=0x00007fffa7d2f1d4 sp=0x00007fffd8a0c9e0 /usr/lib/libc.so.6:
pc=0x00007fffa7d2f27c sp=0x00007fffd8a0cb10 /usr/lib/libc.so.6:__libc_start_main
pc=0x00000000000109a0 sp=0x00007fffd8a0cb60 ./b:_start
```

Co-Authored-By: Fangrui Song <i@maskray.me>

Reviewed By: #libunwind, MaskRay

Differential Revision: https://reviews.llvm.org/D148499
2023-05-06 11:17:02 -07:00
Martin Storsjö
f6320f5e0e [libunwind] [SEH] Clear DISPATCHER_CONTEXT when initializing a cursor
We only initialize a few fields in DISPATCHER_CONTEXT - don't leave
the rest in an uninitialized state; make sure the whole struct is
in a deterministic state.

This makes nondeterministic failures deterministic, for some cases
relating to forced unwinding on aarch64/arm (which requires filling
in parsing of the xdata for finding the exception handler and LSDA).

Differential Revision: https://reviews.llvm.org/D148660
2023-04-22 22:47:45 +03:00
Martin Storsjö
ebae5622d1 [libunwind] [SEH] Initialize _msContext with RtlCaptureContext
When we initialize the UnwindCursor (unw_cursor_t) based on
an existing Registers object (unw_context_t), we only initialize
a subset of the class.

Fill the struct properly for the current thread with RtlCaptureContext,
followed by overwriting of the subset of registers that we do have
available in the Registers class.

One might think that it's enough to initialize specifically the
registers that we signal availability for with ContextFlags,
however in practice, that's not enough.

This fixes crashes when restoring the context via RtlRestoreContext
(via UnwindCursor::jumpto), via __unw_resume.

Differential Revision: https://reviews.llvm.org/D147636
2023-04-13 12:03:35 +03:00
Martin Storsjö
5b9d969e7c [libunwind] [SEH] Allow setting/getting the register UNW_X86_64_RIP
This fixes libunwind_01.pass.cpp for x86_64 Windows.

Differential Revision: https://reviews.llvm.org/D147635
2023-04-13 12:03:35 +03:00
Martin Storsjö
87ca04033c [libunwind] [SEH] Sync LSDA and handler between unw_proc_info_t and DISPATCHER_CONTEXT
For normal C++ unwinding, we get _dispContext initialized by the
prepopulated DISPATCHER_CONTEXT in _GCC_specific_handler, which
we set with __unw_seh_set_disp_ctx.

When doing force unwinding, we step and populate the unw_proc_info_t
struct _info with getInfoFromSEH, but when we execute the handler
via the __libunwind_seh_personality wrapper function, we execute
the handler set in DISPATCHER_CONTEXT.

Whenever updating these fields in either _info or _dispContext,
sync them to the other one too.

This fixes one aspect of the libcxxabi force_unwind*.pass.cpp tests on
x86_64.

Differential Revision: https://reviews.llvm.org/D147637
2023-04-11 00:00:30 +03:00
zhanglimin
c507269512 [libunwind][LoongArch] Add 64-bit LoongArch support
Defines enums for the LoongArch registers.
Adds the register class implementation for LoongArch.
Adds save and restore context functionality.

This only supports 64 bits integer and float-point register
implementation.

Fix https://github.com/llvm/llvm-project/issues/55398

Reviewed By: SixWeining

Differential Revision: https://reviews.llvm.org/D137010
2022-11-15 14:37:00 +08:00
Florian Mayer
a3153381af [libunwind] Handle G in personality string
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-09-21 14:13:32 -07:00
Ryan Prichard
6332a00d69 [libunwind] Fix a few libunwind includes
In UnwindCursor.hpp, include config.h before checking _LIBUNWIND_SUPPORT_SEH_UNWIND.

Include libunwind_ext.h for UNW_STEP_SUCCESS.

Differential Revision: https://reviews.llvm.org/D86766
2022-09-07 22:18:09 -04:00
Gabriel Ravier
dad00daa7a [libunwind] Fixed a number of typos
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-08-20 18:09:03 -07:00
Xing Xue
cc8edbea7a [libunwind][AIX] Save/restore errno before/after system calls dlopen/dlsym/dlclose
Summary:
libunwind on AIX calls dlopen()/dlsym()/dlclose() to dynamically load libc++abi and get the personality for state table EH when it is running against the legacy xlcang++ compiler genereated applications. dlopen() sets errno to 0 when it is successful, which clobbers the value in errno from the user code. This seems to be an AIX bug that it should not set errno to 0 according to POSIX. We will open a bug report to AIX but in the mean time there won't be time line when AIX will have a fix and even AIX does fix it, it won't help earlier AIX releases in the field. This patch saves and restores errno before and after these calls so that user code can work as expected.

Reviewed by: compnerd, libunwind

Differential Revision: https://reviews.llvm.org/D131292
2022-08-08 17:21:30 -04:00
Ulrich Weigand
24ec521cd7 [libunwind][SystemZ] Use process_vm_readv to avoid potential segfaults
Fix potential crashes during unwind when checking for signal frames
and the current PC is invalid.

The same bug was fixed for aarch64 in https://reviews.llvm.org/D126343.

Reviewed by: MaskRay

Differential Revision: https://reviews.llvm.org/D129856
2022-07-18 16:54:48 +02:00
Martin Storsjö
08d30c602b [libunwind] Don't store a predecremented PC when using SEH
This fixes unwinding in boundary cases on ARM with SEH.

In the case of ARM/Thumb, disp->ControlPc points at the following
instruction, with the thumb bit set. Thus by decrementing 1,
it still points at the next instruction. To achieve the desired
effect of pointing at the previous instruction, one first has to strip
out the thumb bit, then do the decrement by 1 to reach the previous
instruction.

When libcxxabi looks for call site ranges, it already does
`_Unwind_GetIP(context) - 1` (in `scan_eh_tab` in
libcxxabi/src/cxa_personality.cpp), so we shouldn't do the
corresponding `- 1` multiple times.

In the case of libcxxabi on Thumb, `funcStart` (still in `scan_eh_tab`)
may have the thumb bit set. If the program counter address is
decremented both in libunwind (first removing the thumb bit, then
decremented), and then libcxxabi decrements it further, and compares
with a `funcStart` with the thumb bit set, it could point to one byte
before the start of the call site.

Thus: This modification makes libunwind with SEH work with libcxxabi
on Thumb, in settings where libunwind and libcxxabi worked fine with
Dwarf before.

For existing cases with libunwind with SEH (on x86_64 and aarch64),
this modification doesn't break any of my testcases.

Differential Revision: https://reviews.llvm.org/D126869
2022-06-06 23:25:24 +03:00
Martin Storsjö
64778c002a [libunwind] Remove unused ARM SEH placeholder code
There's no such corresponding code for ARM64 (which has been working
in production for years). The SEH version of the Unwind functions
(e.g. `_Unwind_GetLanguageSpecificData`) doesn't use these fields.

The `_Unwind_ForcedUnwind` function would need these bits though,
but that's not used in normal C++ exception unwinding.

Differential Revision: https://reviews.llvm.org/D126868
2022-06-06 23:24:22 +03:00
Martin Storsjö
7c0e93cb89 [libunwind] Fix SEH unwinding on ARM
Check `__SEH__` when checking if ARM EHABI should be implied,
similarly to 4a3722a2c3dff1fe885cc38bf43d3c095c9851e7 / D126866.

Fix a warning by using the right format specifier (PRIxPTR instead
of PRIx64), and add a double->float cast in a codepath that hasn't
been built so far.

This is enough to make SEH unwinding of itanium ABI exceptions on
ARM mostly work - one specific issue is fixed in a separate follow-up
patch.

Differential Revision: https://reviews.llvm.org/D126867
2022-06-06 23:23:35 +03:00
Shoaib Meenai
0be0a53df6 [libunwind] Use process_vm_readv to avoid potential segfaults
We've observed segfaults in libunwind when attempting to check for the
Linux aarch64 sigreturn frame, presumably because of bad unwind info
leading to an incorrect PC that we attempt to read from. Use
process_vm_readv to read the memory safely instead.

The s390x code path should likely follow suit, but I don't have the
hardware to be able to test that, so I didn't modify it here either.

Reviewed By: MaskRay, rprichard, #libunwind

Differential Revision: https://reviews.llvm.org/D126343
2022-05-26 09:12:51 -07:00
Shoaib Meenai
3d2b5b7b87 [libunwind] Factor out sigreturn check condition. NFC
Create a macro for this instead of duplicating the architecture checks
everywhere. (It's a little redundant to use it when we're checking for a
specific architecture, but I'm also applying it there for consistency.)

Reviewed By: rprichard, MaskRay, #libunwind

Differential Revision: https://reviews.llvm.org/D126342
2022-05-26 09:12:50 -07:00
Ulrich Weigand
71672375fe [libunwind][SystemZ] Unwind out of signal handlers
Unwinding out of signal handlers currently does not work since
the sigreturn trampoline is not annotated with CFI data.

Fix this by detecting the sigreturn trampoline during unwinding
and providing appropriate unwind data manually. This follows
closely the approach used by existing code for the AArch64 target.

Reviewed by: MaskRay

Differential Revision: https://reviews.llvm.org/D124765
2022-05-04 10:43:11 +02:00
Ulrich Weigand
364c5023d2 [libunwind] Add SystemZ support
Add support for the SystemZ (s390x) architecture to libunwind.

Support should be feature-complete with the exception of
unwinding from signal handlers (to be added later).

Reviewed by: MaskRay

Differential Revision: https://reviews.llvm.org/D124248
2022-05-02 14:35:29 +02:00
Daniel Kiss
f326df34bc [libunwind][AArch64] Fix _Unwind_ForcedUnwind via sigreturn.
When the sigreturn trampoline is found the unw_proc_info_t.end_ip need to be set to
indicate a stack frame is found.

Reviewed By: cjdb, #libunwind, MaskRay

Differential Revision: https://reviews.llvm.org/D124522
2022-04-28 18:41:38 +02:00
Xing Xue
a85da649b9 [libunwind][AIX] implementation of the unwinder for AIX
Summary:
This patch contains the implementation of the unwinder for IBM AIX.

AIX does not support the eh_frame section. Instead, the traceback table located at the end of each function provides the information for stack unwinding and EH. In this patch macro _LIBUNWIND_SUPPORT_TBTAB_UNWIND is used to guard code for AIX traceback table based unwinding. Function getInfoFromTBTable() and stepWithTBTable() are added to get the EH information from the traceback table and to step up the stack respectively.

There are two kinds of LSDA information for EH on AIX, the state table and the range table. The state table is used by the previous version of the IBM XL compiler, i.e., xlC and xlclang++. The DWARF based range table is used by AIX clang++. The traceback table has flags to differentiate these cases. For the range table, relative addresses are calculated using a base of DW_EH_PE_datarel, which is the TOC base of the module where the function of the current frame belongs.

Two personality routines are employed to handle these two different LSDAs, __xlcxx_personality_v0() for the state table and __xlcxx_personality_v1() for the range table. Since the traceback table does not have the information of the personality for the state table approach, its personality __xlcxx_personality_v0() is dynamically resolved as the handler for the state table. For the range table, the locations of the LSDA and its associated personality routine are found in the traceback table.

Assembly code for 32- and 64-bit PowerPC in UnwindRegistersRestore.S and UnwindRegistersSave.S are modified so that it can be consumed by the GNU flavor assembler and the AIX assembler. The restoration of vector registers does not check VRSAVE on AIX because VRSAVE is not used in the AIX ABI.

Reviewed by: MaskRay, compnerd, cebowleratibm, sfertile, libunwind

Differential Revision: https://reviews.llvm.org/D100132
2022-04-13 11:01:59 -04:00
Koakuma
2b9554b885 [libunwind] [sparc] Add SPARCv9 support
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-02-05 13:08:26 -08:00
Ties Stuij
e6d0b851f8 [ARM][libunwind] add PACBTI-M support for libunwind
This patch implements the following:

- Emit PACBTI-M build attributes in libunwind asm files

- Authenticate LR in DWARF32 using PACBTI

Use Armv8.1-M.Main PACBTI extension to authenticate the return address
(stored in the LR register) before moving it to the PC (IP) register.

The AUTG instruction is used with the candidate return address, the CFA,
and the authentication code that is retrieved from the saved
pseudo-register RA_AUTH_CODE.

- Authenticate LR in EHABI using PACBTI

Authenticate the contents of the LR register using Armv8.1-M.Main PACBTI
extension.

A new frame unwinding instruction is introduced (0xb4). This
instruction pops out of the stack the return address authentication
code, which is then used in conjunction with the SP and the next-to-be
instruction pointer to perform authentication.

This authentication code is popped into a new register,
UNW_ARM_PSEUDO_PAC, which is a pseudo-register.

This patch is part of a series that adds support for the PACBTI-M extension of
the Armv8.1-M architecture, as detailed here:

https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/armv8-1-m-pointer-authentication-and-branch-target-identification-extension

The PACBTI-M specification can be found in the Armv8-M Architecture Reference
Manual:

https://developer.arm.com/documentation/ddi0553/latest

The following people contributed to this patch:

- Momchil Velikov
- Victor Campos
- Ties Stuij

Reviewed By: #libunwind, danielkiss, mstorsjo

Differential Revision: https://reviews.llvm.org/D112430
2021-12-08 09:44:45 +00:00
Louis Dionne
eb8650a757 [runtimes][NFC] Remove filenames at the top of the license notice
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-11-17 16:30:52 -05:00
gejin
21b25a1fb3 [libunwind] Support stack unwind in CET environment
Control-flow Enforcement Technology (CET), published by Intel,
introduces shadow stack feature aiming to ensure a return from
a function is directed to where the function was called.
In a CET enabled system, each function call will push return
address into normal stack and shadow stack, when the function
returns, the address stored in shadow stack will be popped and
compared with the return address, program will fail if the 2
addresses don't match.
In exception handling, the control flow may skip some stack frames
and we must adjust shadow stack to avoid violating CET restriction.
In order to achieve this, we count the number of stack frames skipped
and adjust shadow stack by this number before jumping to landing pad.

Reviewed By: hjl.tools, compnerd, MaskRay
Differential Revision: https://reviews.llvm.org/D105968

Signed-off-by: gejin <ge.jin@intel.com>
2021-08-26 16:20:38 +08:00
Fangrui Song
9ae9dd3fcf [libunwind] Add UNW_AARCH64_* beside UNW_ARM64_*
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
2021-08-20 14:26:27 -07:00
Nico Weber
7cdd768ac9 [libunwind] reflow some debug logs for better greppability
"bad second level page" and "second level compressed unwind table"
can now be grepped for.

(Also remove one of the two spaces between "second" and "level"
in the second message.)
2021-07-04 17:52:23 -04:00
Ryan Prichard
c82deed676 [libunwind] Unwind through aarch64/Linux sigreturn frame
An AArch64 sigreturn trampoline frame can't currently be described
in a DWARF .eh_frame section, because the AArch64 DWARF spec currently
doesn't define a constant for the PC register. (PC and LR may need to
be restored to different values.)

Instead, use the same technique as libgcc or github.com/libunwind and
detect the sigreturn frame by looking for the sigreturn instructions:

    mov x8, #0x8b
    svc #0x0

If a sigreturn frame is detected, libunwind restores all the GPRs by
assuming that sp points at an rt_sigframe Linux kernel struct. This
behavior is a fallback mode that is only used if there is no ordinary
unwind info for sigreturn.

If libunwind can't find unwind info for a PC, it assumes that the PC is
readable, and would crash if it isn't. This could happen if:
 - The PC points at a function compiled without unwind info, and which
   is part of an execute-only mapping (e.g. using -Wl,--execute-only).
 - The PC is invalid and happens to point to unreadable or unmapped
   memory.

In the tests, ignore a failed dladdr call so that the tests can run on
user-mode qemu for AArch64, which uses a stack-allocated trampoline
instead of a vDSO.

Reviewed By: danielkiss, compnerd, #libunwind

Differential Revision: https://reviews.llvm.org/D90898
2021-01-13 16:38:36 -08:00
Ryan Prichard
fb1abe0063 [libunwind][DWARF] Fix end of .eh_frame calculation
* 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 19:00:57 -07:00
Ryan Prichard
09d492902f [libunwind] Bare-metal DWARF: set dso_base to 0
Previously, DwarfFDECache::findFDE used 0 as a special value meaning
"search the entire cache, including dynamically-registered FDEs".
Switch this special value to -1, which doesn't make sense as a DSO
base.

Fixes PR47335.

Reviewed By: compnerd, #libunwind

Differential Revision: https://reviews.llvm.org/D86748
2020-09-09 15:43:35 -07:00
Ryan Prichard
3071d5ffba [libunwind] Factor out getInfoFromFdeCie. NFCI.
Differential Revision: https://reviews.llvm.org/D86255
2020-08-26 18:22:06 -07:00
Martin Storsjö
542db87f1a [libunwind] Ensure enough alignment for unw_cursor_t for SEH build configurations
When built in SEH mode, UnwindCursor contains a CONTEXT struct,
which is aligned to 16 bytes in most configurations, causing the
whole UnwindCursor object to have 16 byte alignment.

This fixes backtraces using _Unwind_Backtrace on x86_64 mingw,
where an unw_cursor_t allocated on the stack was misaligned before.

This is an ABI break for this struct for this configuration, but very
few callers call libunwind directly (and even fewer directly allocate
an unw_cursor_t anyway).

Differential Revision: https://reviews.llvm.org/D86102
2020-08-22 22:48:57 +03:00
Louis Dionne
9b211a5076 [libunwind] Fix incorrect check for out-of-boundedness
If the personalityIndex (which is 0-based) is equal to the length of
the personality array, we should error out.

rdar://18013273
2020-08-11 15:37:57 -04:00
Louis Dionne
e8dac8b3db [libunwind][NFC] Fix typo in comment 2020-08-11 15:24:52 -04:00
Saleem Abdulrasool
2d865ccbd8 unwind: EHABISectionIterator operator!=, constify operator-
Add missing `operator!=` and make `operator-` const for
`EHABISectionIterator`.  This repairs the build of libunwind when
building with GCC.

Patch by Chad Duffin!

Reviewed By: compnerd, libunwind
Differential Revision: https://reviews.llvm.org/D81597
2020-06-18 08:54:34 -07:00
Brian Cain
9107594f37 [libunwind] add hexagon support 2020-04-10 04:24:10 -05:00
Sterling Augustine
71fbd6e406 Exit unwinding early when at the top of the stack and additional info won't be found.
Summary:
This patch follows libgcc's lead: When the return-address register is
zero, there won't be additional stack frames to examine, or gather
information about. Exit before spending time looking for something
known not to be found.

Subscribers: llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D77099
2020-04-02 10:52:25 -07:00