authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-07-16 10:55:09+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-08-30 06:36:41+02:00
log85438e75e04b356ca319051c33e0987a9958ad4a
tree985baaa5543044d8ac252427e97ba4e1463975db
parentc34fc8f19884ebe551b1dea9b8061efd3680848a
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

libunwind: update to LLVM 21


10 files changed, 430 insertions(+), 167 deletions(-)

lib/libunwind/src/Registers.hpp+5-5
...@@ -15,9 +15,9 @@...@@ -15,9 +15,9 @@
15#include <stdint.h>15#include <stdint.h>
16#include <string.h>16#include <string.h>
1717
18#include "cet_unwind.h"
19#include "config.h"18#include "config.h"
20#include "libunwind.h"19#include "libunwind.h"
20#include "shadow_stack_unwind.h"
2121
22namespace libunwind {22namespace libunwind {
2323
...@@ -48,7 +48,7 @@ class _LIBUNWIND_HIDDEN Registers_x86;...@@ -48,7 +48,7 @@ class _LIBUNWIND_HIDDEN Registers_x86;
48extern "C" void __libunwind_Registers_x86_jumpto(Registers_x86 *);48extern "C" void __libunwind_Registers_x86_jumpto(Registers_x86 *);
4949
50#if defined(_LIBUNWIND_USE_CET)50#if defined(_LIBUNWIND_USE_CET)
51extern "C" void *__libunwind_cet_get_jump_target() {51extern "C" void *__libunwind_shstk_get_jump_target() {
52 return reinterpret_cast<void *>(&__libunwind_Registers_x86_jumpto);52 return reinterpret_cast<void *>(&__libunwind_Registers_x86_jumpto);
53}53}
54#endif54#endif
...@@ -268,7 +268,7 @@ class _LIBUNWIND_HIDDEN Registers_x86_64;...@@ -268,7 +268,7 @@ class _LIBUNWIND_HIDDEN Registers_x86_64;
268extern "C" void __libunwind_Registers_x86_64_jumpto(Registers_x86_64 *);268extern "C" void __libunwind_Registers_x86_64_jumpto(Registers_x86_64 *);
269269
270#if defined(_LIBUNWIND_USE_CET)270#if defined(_LIBUNWIND_USE_CET)
271extern "C" void *__libunwind_cet_get_jump_target() {271extern "C" void *__libunwind_shstk_get_jump_target() {
272 return reinterpret_cast<void *>(&__libunwind_Registers_x86_64_jumpto);272 return reinterpret_cast<void *>(&__libunwind_Registers_x86_64_jumpto);
273}273}
274#endif274#endif
...@@ -1817,7 +1817,7 @@ class _LIBUNWIND_HIDDEN Registers_arm64;...@@ -1817,7 +1817,7 @@ class _LIBUNWIND_HIDDEN Registers_arm64;
1817extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);1817extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);
18181818
1819#if defined(_LIBUNWIND_USE_GCS)1819#if defined(_LIBUNWIND_USE_GCS)
1820extern "C" void *__libunwind_cet_get_jump_target() {1820extern "C" void *__libunwind_shstk_get_jump_target() {
1821 return reinterpret_cast<void *>(&__libunwind_Registers_arm64_jumpto);1821 return reinterpret_cast<void *>(&__libunwind_Registers_arm64_jumpto);
1822}1822}
1823#endif1823#endif
...@@ -4126,7 +4126,7 @@ inline reg_t Registers_riscv::getRegister(int regNum) const {...@@ -4126,7 +4126,7 @@ inline reg_t Registers_riscv::getRegister(int regNum) const {
4126 return _registers[regNum];4126 return _registers[regNum];
4127 if (regNum == UNW_RISCV_VLENB) {4127 if (regNum == UNW_RISCV_VLENB) {
4128 reg_t vlenb;4128 reg_t vlenb;
4129 __asm__("csrr %0, 0xC22" : "=r"(vlenb));4129 __asm__ volatile("csrr %0, 0xC22" : "=r"(vlenb));
4130 return vlenb;4130 return vlenb;
4131 }4131 }
4132 _LIBUNWIND_ABORT("unsupported riscv register");4132 _LIBUNWIND_ABORT("unsupported riscv register");
lib/libunwind/src/Unwind-seh.cpp+41
...@@ -51,6 +51,32 @@ static DISPATCHER_CONTEXT *__unw_seh_get_disp_ctx(unw_cursor_t *cursor);...@@ -51,6 +51,32 @@ static DISPATCHER_CONTEXT *__unw_seh_get_disp_ctx(unw_cursor_t *cursor);
51static void __unw_seh_set_disp_ctx(unw_cursor_t *cursor,51static void __unw_seh_set_disp_ctx(unw_cursor_t *cursor,
52 DISPATCHER_CONTEXT *disp);52 DISPATCHER_CONTEXT *disp);
5353
54#pragma clang diagnostic push
55#pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
56// Local redefinition of this type; mingw-w64 headers lack the
57// DISPATCHER_CONTEXT_NONVOLREG_ARM64 type as of May 2025, so locally redefine
58// it and use that definition, to avoid needing to test/guess whether the real
59// type is available of not.
60union LOCAL_DISPATCHER_CONTEXT_NONVOLREG_ARM64 {
61 BYTE Buffer[11 * sizeof(DWORD64) + 8 * sizeof(double)];
62
63 struct {
64 DWORD64 GpNvRegs[11];
65 double FpNvRegs[8];
66 };
67};
68
69// Custom data type definition; this type is not defined in WinSDK.
70union LOCAL_DISPATCHER_CONTEXT_NONVOLREG_ARM {
71 BYTE Buffer[8 * sizeof(DWORD) + 8 * sizeof(double)];
72
73 struct {
74 DWORD GpNvRegs[8];
75 double FpNvRegs[8];
76 };
77};
78#pragma clang diagnostic pop
79
54/// Common implementation of SEH-style handler functions used by Itanium-80/// Common implementation of SEH-style handler functions used by Itanium-
55/// style frames. Depending on how and why it was called, it may do one of:81/// style frames. Depending on how and why it was called, it may do one of:
56/// a) Delegate to the given Itanium-style personality function; or82/// a) Delegate to the given Itanium-style personality function; or
...@@ -212,6 +238,21 @@ __libunwind_seh_personality(int version, _Unwind_Action state,...@@ -212,6 +238,21 @@ __libunwind_seh_personality(int version, _Unwind_Action state,
212 ms_exc.ExceptionInformation[2] = state;238 ms_exc.ExceptionInformation[2] = state;
213 DISPATCHER_CONTEXT *disp_ctx =239 DISPATCHER_CONTEXT *disp_ctx =
214 __unw_seh_get_disp_ctx((unw_cursor_t *)context);240 __unw_seh_get_disp_ctx((unw_cursor_t *)context);
241#if defined(__aarch64__)
242 LOCAL_DISPATCHER_CONTEXT_NONVOLREG_ARM64 nonvol;
243 memcpy(&nonvol.GpNvRegs, &disp_ctx->ContextRecord->X19,
244 sizeof(nonvol.GpNvRegs));
245 for (int i = 0; i < 8; i++)
246 nonvol.FpNvRegs[i] = disp_ctx->ContextRecord->V[i + 8].D[0];
247 disp_ctx->NonVolatileRegisters = nonvol.Buffer;
248#elif defined(__arm__)
249 LOCAL_DISPATCHER_CONTEXT_NONVOLREG_ARM nonvol;
250 memcpy(&nonvol.GpNvRegs, &disp_ctx->ContextRecord->R4,
251 sizeof(nonvol.GpNvRegs));
252 memcpy(&nonvol.FpNvRegs, &disp_ctx->ContextRecord->D[8],
253 sizeof(nonvol.FpNvRegs));
254 disp_ctx->NonVolatileRegisters = nonvol.Buffer;
255#endif
215 _LIBUNWIND_TRACE_UNWINDING("__libunwind_seh_personality() calling "256 _LIBUNWIND_TRACE_UNWINDING("__libunwind_seh_personality() calling "
216 "LanguageHandler %p(%p, %p, %p, %p)",257 "LanguageHandler %p(%p, %p, %p, %p)",
217 (void *)disp_ctx->LanguageHandler, (void *)&ms_exc,258 (void *)disp_ctx->LanguageHandler, (void *)&ms_exc,
lib/libunwind/src/Unwind-wasm.c+2-4
...@@ -102,8 +102,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {...@@ -102,8 +102,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
102}102}
103103
104/// Not used in Wasm.104/// Not used in Wasm.
105_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,105_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t) {}
106 uintptr_t value) {}
107106
108/// Called by personality handler to get LSDA for current frame.107/// Called by personality handler to get LSDA for current frame.
109_LIBUNWIND_EXPORT uintptr_t108_LIBUNWIND_EXPORT uintptr_t
...@@ -115,8 +114,7 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {...@@ -115,8 +114,7 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
115}114}
116115
117/// Not used in Wasm.116/// Not used in Wasm.
118_LIBUNWIND_EXPORT uintptr_t117_LIBUNWIND_EXPORT uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *) {
119_Unwind_GetRegionStart(struct _Unwind_Context *context) {
120 return 0;118 return 0;
121}119}
122120
lib/libunwind/src/UnwindCursor.hpp+228-58
...@@ -11,7 +11,7 @@...@@ -11,7 +11,7 @@
11#ifndef __UNWINDCURSOR_HPP__11#ifndef __UNWINDCURSOR_HPP__
12#define __UNWINDCURSOR_HPP__12#define __UNWINDCURSOR_HPP__
1313
14#include "cet_unwind.h"14#include "shadow_stack_unwind.h"
15#include <stdint.h>15#include <stdint.h>
16#include <stdio.h>16#include <stdio.h>
17#include <stdlib.h>17#include <stdlib.h>
...@@ -31,8 +31,9 @@...@@ -31,8 +31,9 @@
31#endif31#endif
3232
33#if defined(_LIBUNWIND_TARGET_LINUX) && \33#if defined(_LIBUNWIND_TARGET_LINUX) && \
34 (defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_RISCV) || \34 (defined(_LIBUNWIND_TARGET_AARCH64) || \
35 defined(_LIBUNWIND_TARGET_S390X))35 defined(_LIBUNWIND_TARGET_LOONGARCH) || \
36 defined(_LIBUNWIND_TARGET_RISCV) || defined(_LIBUNWIND_TARGET_S390X))
36#include <errno.h>37#include <errno.h>
37#include <signal.h>38#include <signal.h>
38#include <sys/syscall.h>39#include <sys/syscall.h>
...@@ -40,6 +41,12 @@...@@ -40,6 +41,12 @@
40#define _LIBUNWIND_CHECK_LINUX_SIGRETURN 141#define _LIBUNWIND_CHECK_LINUX_SIGRETURN 1
41#endif42#endif
4243
44#if defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64)
45#include <OS.h>
46#include <signal.h>
47#define _LIBUNWIND_CHECK_HAIKU_SIGRETURN 1
48#endif
49
43#include "AddressSpace.hpp"50#include "AddressSpace.hpp"
44#include "CompactUnwinder.hpp"51#include "CompactUnwinder.hpp"
45#include "config.h"52#include "config.h"
...@@ -82,6 +89,22 @@ struct UNWIND_INFO {...@@ -82,6 +89,22 @@ struct UNWIND_INFO {
82 uint16_t UnwindCodes[2];89 uint16_t UnwindCodes[2];
83};90};
8491
92#pragma clang diagnostic push
93#pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
94union UNWIND_INFO_ARM {
95 DWORD HeaderData;
96 struct {
97 DWORD FunctionLength : 18;
98 DWORD Version : 2;
99 DWORD ExceptionDataPresent : 1;
100 DWORD EpilogInHeader : 1;
101 DWORD FunctionFragment : 1;
102 DWORD EpilogCount : 5;
103 DWORD CodeWords : 4;
104 };
105};
106#pragma clang diagnostic pop
107
85extern "C" _Unwind_Reason_Code __libunwind_seh_personality(108extern "C" _Unwind_Reason_Code __libunwind_seh_personality(
86 int, _Unwind_Action, uint64_t, _Unwind_Exception *,109 int, _Unwind_Action, uint64_t, _Unwind_Exception *,
87 struct _Unwind_Context *);110 struct _Unwind_Context *);
...@@ -150,7 +173,7 @@ bool DwarfFDECache<A>::_registeredForDyldUnloads = false;...@@ -150,7 +173,7 @@ bool DwarfFDECache<A>::_registeredForDyldUnloads = false;
150#endif173#endif
151174
152template <typename A>175template <typename A>
153typename DwarfFDECache<A>::pint_t DwarfFDECache<A>::findFDE(pint_t mh, pint_t pc) {176typename A::pint_t DwarfFDECache<A>::findFDE(pint_t mh, pint_t pc) {
154 pint_t result = 0;177 pint_t result = 0;
155 _LIBUNWIND_LOG_IF_FALSE(_lock.lock_shared());178 _LIBUNWIND_LOG_IF_FALSE(_lock.lock_shared());
156 for (entry *p = _buffer; p < _bufferUsed; ++p) {179 for (entry *p = _buffer; p < _bufferUsed; ++p) {
...@@ -996,6 +1019,10 @@ private:...@@ -996,6 +1019,10 @@ private:
996 bool setInfoForSigReturn(Registers_arm64 &);1019 bool setInfoForSigReturn(Registers_arm64 &);
997 int stepThroughSigReturn(Registers_arm64 &);1020 int stepThroughSigReturn(Registers_arm64 &);
998#endif1021#endif
1022#if defined(_LIBUNWIND_TARGET_LOONGARCH)
1023 bool setInfoForSigReturn(Registers_loongarch &);
1024 int stepThroughSigReturn(Registers_loongarch &);
1025#endif
999#if defined(_LIBUNWIND_TARGET_RISCV)1026#if defined(_LIBUNWIND_TARGET_RISCV)
1000 bool setInfoForSigReturn(Registers_riscv &);1027 bool setInfoForSigReturn(Registers_riscv &);
1001 int stepThroughSigReturn(Registers_riscv &);1028 int stepThroughSigReturn(Registers_riscv &);
...@@ -1010,7 +1037,7 @@ private:...@@ -1010,7 +1037,7 @@ private:
1010 template <typename Registers> int stepThroughSigReturn(Registers &) {1037 template <typename Registers> int stepThroughSigReturn(Registers &) {
1011 return UNW_STEP_END;1038 return UNW_STEP_END;
1012 }1039 }
1013#elif defined(_LIBUNWIND_TARGET_HAIKU)1040#elif defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN)
1014 bool setInfoForSigReturn();1041 bool setInfoForSigReturn();
1015 int stepThroughSigReturn();1042 int stepThroughSigReturn();
1016#endif1043#endif
...@@ -2013,6 +2040,61 @@ bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) {...@@ -2013,6 +2040,61 @@ bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) {
2013 _info.handler = 0;2040 _info.handler = 0;
2014 }2041 }
2015 }2042 }
2043#elif defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_ARM)
2044
2045#if defined(_LIBUNWIND_TARGET_AARCH64)
2046#define FUNC_LENGTH_UNIT 4
2047#define XDATA_TYPE IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA
2048#else
2049#define FUNC_LENGTH_UNIT 2
2050#define XDATA_TYPE UNWIND_INFO_ARM
2051#endif
2052 if (unwindEntry->Flag != 0) { // Packed unwind info
2053 _info.end_ip =
2054 _info.start_ip + unwindEntry->FunctionLength * FUNC_LENGTH_UNIT;
2055 // Only fill in the handler and LSDA if they're stale.
2056 if (pc != getLastPC()) {
2057 // Packed unwind info doesn't have an exception handler.
2058 _info.lsda = 0;
2059 _info.handler = 0;
2060 }
2061 } else {
2062 XDATA_TYPE *xdata =
2063 reinterpret_cast<XDATA_TYPE *>(base + unwindEntry->UnwindData);
2064 _info.end_ip = _info.start_ip + xdata->FunctionLength * FUNC_LENGTH_UNIT;
2065 // Only fill in the handler and LSDA if they're stale.
2066 if (pc != getLastPC()) {
2067 if (xdata->ExceptionDataPresent) {
2068 uint32_t offset = 1; // The main xdata
2069 uint32_t codeWords = xdata->CodeWords;
2070 uint32_t epilogScopes = xdata->EpilogCount;
2071 if (xdata->EpilogCount == 0 && xdata->CodeWords == 0) {
2072 // The extension word has got the same layout for both ARM and ARM64
2073 uint32_t extensionWord = reinterpret_cast<uint32_t *>(xdata)[1];
2074 codeWords = (extensionWord >> 16) & 0xff;
2075 epilogScopes = extensionWord & 0xffff;
2076 offset++;
2077 }
2078 if (!xdata->EpilogInHeader)
2079 offset += epilogScopes;
2080 offset += codeWords;
2081 uint32_t *exceptionHandlerInfo =
2082 reinterpret_cast<uint32_t *>(xdata) + offset;
2083 _dispContext.HandlerData = &exceptionHandlerInfo[1];
2084 _dispContext.LanguageHandler = reinterpret_cast<EXCEPTION_ROUTINE *>(
2085 base + exceptionHandlerInfo[0]);
2086 _info.lsda = reinterpret_cast<unw_word_t>(_dispContext.HandlerData);
2087 if (exceptionHandlerInfo[0])
2088 _info.handler =
2089 reinterpret_cast<unw_word_t>(__libunwind_seh_personality);
2090 else
2091 _info.handler = 0;
2092 } else {
2093 _info.lsda = 0;
2094 _info.handler = 0;
2095 }
2096 }
2097 }
2016#endif2098#endif
2017 setLastPC(pc);2099 setLastPC(pc);
2018 return true;2100 return true;
...@@ -2554,7 +2636,7 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,...@@ -2554,7 +2636,7 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
2554template <typename A, typename R>2636template <typename A, typename R>
2555void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {2637void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
2556#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \2638#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \
2557 defined(_LIBUNWIND_TARGET_HAIKU)2639 defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN)
2558 _isSigReturn = false;2640 _isSigReturn = false;
2559#endif2641#endif
25602642
...@@ -2679,7 +2761,7 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {...@@ -2679,7 +2761,7 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
2679#endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)2761#endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
26802762
2681#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \2763#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \
2682 defined(_LIBUNWIND_TARGET_HAIKU)2764 defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN)
2683 if (setInfoForSigReturn())2765 if (setInfoForSigReturn())
2684 return;2766 return;
2685#endif2767#endif
...@@ -2755,65 +2837,63 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) {...@@ -2755,65 +2837,63 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) {
2755 _isSignalFrame = true;2837 _isSignalFrame = true;
2756 return UNW_STEP_SUCCESS;2838 return UNW_STEP_SUCCESS;
2757}2839}
2840#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
2841 // defined(_LIBUNWIND_TARGET_AARCH64)
27582842
2759#elif defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64)2843#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \
2760#include <commpage_defs.h>2844 defined(_LIBUNWIND_TARGET_LOONGARCH)
2761#include <signal.h>2845template <typename A, typename R>
2846bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_loongarch &) {
2847 const pint_t pc = static_cast<pint_t>(getReg(UNW_REG_IP));
2848 // The PC might contain an invalid address if the unwind info is bad, so
2849 // directly accessing it could cause a SIGSEGV.
2850 if (!isReadableAddr(pc))
2851 return false;
2852 const auto *instructions = reinterpret_cast<const uint32_t *>(pc);
2853 // Look for the two instructions used in the sigreturn trampoline
2854 // __vdso_rt_sigreturn:
2855 //
2856 // 0x03822c0b li a7,0x8b
2857 // 0x002b0000 syscall 0
2858 if (instructions[0] != 0x03822c0b || instructions[1] != 0x002b0000)
2859 return false;
27622860
2763extern "C" {2861 _info = {};
2764extern void *__gCommPageAddress;2862 _info.start_ip = pc;
2863 _info.end_ip = pc + 4;
2864 _isSigReturn = true;
2865 return true;
2765}2866}
27662867
2767template <typename A, typename R>2868template <typename A, typename R>
2768bool UnwindCursor<A, R>::setInfoForSigReturn() {2869int UnwindCursor<A, R>::stepThroughSigReturn(Registers_loongarch &) {
2769#if defined(_LIBUNWIND_TARGET_X86_64)2870 // In the signal trampoline frame, sp points to an rt_sigframe[1], which is:
2770 addr_t signal_handler =2871 // - 128-byte siginfo struct
2771 (((addr_t *)__gCommPageAddress)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER] +2872 // - ucontext_t struct:
2772 (addr_t)__gCommPageAddress);2873 // - 8-byte long (__uc_flags)
2773 addr_t signal_handler_ret = signal_handler + 45;2874 // - 8-byte pointer (*uc_link)
2774#endif2875 // - 24-byte uc_stack
2775 pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));2876 // - 8-byte uc_sigmask
2776 if (pc == signal_handler_ret) {2877 // - 120-byte of padding to allow sigset_t to be expanded in the future
2777 _info = {};2878 // - 8 bytes of padding because sigcontext has 16-byte alignment
2778 _info.start_ip = signal_handler;2879 // - struct sigcontext uc_mcontext
2779 _info.end_ip = signal_handler_ret;2880 // [1]
2780 _isSigReturn = true;2881 // https://github.com/torvalds/linux/blob/master/arch/loongarch/kernel/signal.c
2781 return true;2882 const pint_t kOffsetSpToSigcontext = 128 + 8 + 8 + 24 + 8 + 128;
2782 }
2783 return false;
2784}
27852883
2786template <typename A, typename R>2884 const pint_t sigctx = _registers.getSP() + kOffsetSpToSigcontext;
2787int UnwindCursor<A, R>::stepThroughSigReturn() {2885 _registers.setIP(_addressSpace.get64(sigctx));
2886 for (int i = UNW_LOONGARCH_R1; i <= UNW_LOONGARCH_R31; ++i) {
2887 // skip R0
2888 uint64_t value =
2889 _addressSpace.get64(sigctx + static_cast<pint_t>((i + 1) * 8));
2890 _registers.setRegister(i, value);
2891 }
2788 _isSignalFrame = true;2892 _isSignalFrame = true;
2789 pint_t sp = _registers.getSP();
2790#if defined(_LIBUNWIND_TARGET_X86_64)
2791 vregs *regs = (vregs *)(sp + 0x70);
2792
2793 _registers.setRegister(UNW_REG_IP, regs->rip);
2794 _registers.setRegister(UNW_REG_SP, regs->rsp);
2795 _registers.setRegister(UNW_X86_64_RAX, regs->rax);
2796 _registers.setRegister(UNW_X86_64_RDX, regs->rdx);
2797 _registers.setRegister(UNW_X86_64_RCX, regs->rcx);
2798 _registers.setRegister(UNW_X86_64_RBX, regs->rbx);
2799 _registers.setRegister(UNW_X86_64_RSI, regs->rsi);
2800 _registers.setRegister(UNW_X86_64_RDI, regs->rdi);
2801 _registers.setRegister(UNW_X86_64_RBP, regs->rbp);
2802 _registers.setRegister(UNW_X86_64_R8, regs->r8);
2803 _registers.setRegister(UNW_X86_64_R9, regs->r9);
2804 _registers.setRegister(UNW_X86_64_R10, regs->r10);
2805 _registers.setRegister(UNW_X86_64_R11, regs->r11);
2806 _registers.setRegister(UNW_X86_64_R12, regs->r12);
2807 _registers.setRegister(UNW_X86_64_R13, regs->r13);
2808 _registers.setRegister(UNW_X86_64_R14, regs->r14);
2809 _registers.setRegister(UNW_X86_64_R15, regs->r15);
2810 // TODO: XMM
2811#endif
2812
2813 return UNW_STEP_SUCCESS;2893 return UNW_STEP_SUCCESS;
2814}2894}
2815#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&2895#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
2816 // defined(_LIBUNWIND_TARGET_AARCH64)2896 // defined(_LIBUNWIND_TARGET_LOONGARCH)
28172897
2818#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \2898#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \
2819 defined(_LIBUNWIND_TARGET_RISCV)2899 defined(_LIBUNWIND_TARGET_RISCV)
...@@ -2972,6 +3052,96 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_s390x &) {...@@ -2972,6 +3052,96 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_s390x &) {
2972#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&3052#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
2973 // defined(_LIBUNWIND_TARGET_S390X)3053 // defined(_LIBUNWIND_TARGET_S390X)
29743054
3055#if defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN)
3056template <typename A, typename R>
3057bool UnwindCursor<A, R>::setInfoForSigReturn() {
3058 Dl_info dlinfo;
3059 const auto isSignalHandler = [&](pint_t addr) {
3060 if (!dladdr(reinterpret_cast<void *>(addr), &dlinfo))
3061 return false;
3062 if (strcmp(dlinfo.dli_fname, "commpage"))
3063 return false;
3064 if (dlinfo.dli_sname == NULL ||
3065 strcmp(dlinfo.dli_sname, "commpage_signal_handler"))
3066 return false;
3067 return true;
3068 };
3069
3070 pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
3071 if (!isSignalHandler(pc))
3072 return false;
3073
3074 pint_t start = reinterpret_cast<pint_t>(dlinfo.dli_saddr);
3075
3076 static size_t signalHandlerSize = 0;
3077 if (signalHandlerSize == 0) {
3078 size_t boundLow = 0;
3079 size_t boundHigh = static_cast<size_t>(-1);
3080
3081 area_info areaInfo;
3082 if (get_area_info(area_for(dlinfo.dli_saddr), &areaInfo) == B_OK)
3083 boundHigh = areaInfo.size;
3084
3085 while (boundLow < boundHigh) {
3086 size_t boundMid = boundLow + ((boundHigh - boundLow) / 2);
3087 pint_t test = start + boundMid;
3088 if (test >= start && isSignalHandler(test))
3089 boundLow = boundMid + 1;
3090 else
3091 boundHigh = boundMid;
3092 }
3093
3094 signalHandlerSize = boundHigh;
3095 }
3096
3097 _info = {};
3098 _info.start_ip = start;
3099 _info.end_ip = start + signalHandlerSize;
3100 _isSigReturn = true;
3101
3102 return true;
3103}
3104
3105template <typename A, typename R>
3106int UnwindCursor<A, R>::stepThroughSigReturn() {
3107 _isSignalFrame = true;
3108
3109#if defined(_LIBUNWIND_TARGET_X86_64)
3110 // Layout of the stack before function call:
3111 // - signal_frame_data
3112 // + siginfo_t (public struct, fairly stable)
3113 // + ucontext_t (public struct, fairly stable)
3114 // - mcontext_t -> Offset 0x70, this is what we want.
3115 // - frame->ip (8 bytes)
3116 // - frame->bp (8 bytes). Not written by the kernel,
3117 // but the signal handler has a "push %rbp" instruction.
3118 pint_t bp = this->getReg(UNW_X86_64_RBP);
3119 vregs *regs = (vregs *)(bp + 0x70);
3120
3121 _registers.setRegister(UNW_REG_IP, regs->rip);
3122 _registers.setRegister(UNW_REG_SP, regs->rsp);
3123 _registers.setRegister(UNW_X86_64_RAX, regs->rax);
3124 _registers.setRegister(UNW_X86_64_RDX, regs->rdx);
3125 _registers.setRegister(UNW_X86_64_RCX, regs->rcx);
3126 _registers.setRegister(UNW_X86_64_RBX, regs->rbx);
3127 _registers.setRegister(UNW_X86_64_RSI, regs->rsi);
3128 _registers.setRegister(UNW_X86_64_RDI, regs->rdi);
3129 _registers.setRegister(UNW_X86_64_RBP, regs->rbp);
3130 _registers.setRegister(UNW_X86_64_R8, regs->r8);
3131 _registers.setRegister(UNW_X86_64_R9, regs->r9);
3132 _registers.setRegister(UNW_X86_64_R10, regs->r10);
3133 _registers.setRegister(UNW_X86_64_R11, regs->r11);
3134 _registers.setRegister(UNW_X86_64_R12, regs->r12);
3135 _registers.setRegister(UNW_X86_64_R13, regs->r13);
3136 _registers.setRegister(UNW_X86_64_R14, regs->r14);
3137 _registers.setRegister(UNW_X86_64_R15, regs->r15);
3138 // TODO: XMM
3139#endif // defined(_LIBUNWIND_TARGET_X86_64)
3140
3141 return UNW_STEP_SUCCESS;
3142}
3143#endif // defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN)
3144
2975template <typename A, typename R> int UnwindCursor<A, R>::step(bool stage2) {3145template <typename A, typename R> int UnwindCursor<A, R>::step(bool stage2) {
2976 (void)stage2;3146 (void)stage2;
2977 // Bottom of stack is defined is when unwind info cannot be found.3147 // Bottom of stack is defined is when unwind info cannot be found.
...@@ -2981,7 +3151,7 @@ template <typename A, typename R> int UnwindCursor<A, R>::step(bool stage2) {...@@ -2981,7 +3151,7 @@ template <typename A, typename R> int UnwindCursor<A, R>::step(bool stage2) {
2981 // Use unwinding info to modify register set as if function returned.3151 // Use unwinding info to modify register set as if function returned.
2982 int result;3152 int result;
2983#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \3153#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \
2984 defined(_LIBUNWIND_TARGET_HAIKU)3154 defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN)
2985 if (_isSigReturn) {3155 if (_isSigReturn) {
2986 result = this->stepThroughSigReturn();3156 result = this->stepThroughSigReturn();
2987 } else3157 } else
...@@ -3062,7 +3232,7 @@ bool UnwindCursor<A, R>::isReadableAddr(const pint_t addr) const {...@@ -3062,7 +3232,7 @@ bool UnwindCursor<A, R>::isReadableAddr(const pint_t addr) const {
3062#endif3232#endif
30633233
3064#if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS)3234#if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS)
3065extern "C" void *__libunwind_cet_get_registers(unw_cursor_t *cursor) {3235extern "C" void *__libunwind_shstk_get_registers(unw_cursor_t *cursor) {
3066 AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;3236 AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
3067 return co->get_registers();3237 return co->get_registers();
3068}3238}
lib/libunwind/src/UnwindLevel1.c+39-36
...@@ -25,10 +25,10 @@...@@ -25,10 +25,10 @@
25#include <stdio.h>25#include <stdio.h>
26#include <string.h>26#include <string.h>
2727
28#include "cet_unwind.h"
29#include "config.h"28#include "config.h"
30#include "libunwind.h"29#include "libunwind.h"
31#include "libunwind_ext.h"30#include "libunwind_ext.h"
31#include "shadow_stack_unwind.h"
32#include "unwind.h"32#include "unwind.h"
3333
34#if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__) && \34#if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__) && \
...@@ -36,14 +36,17 @@...@@ -36,14 +36,17 @@
3636
37#ifndef _LIBUNWIND_SUPPORT_SEH_UNWIND37#ifndef _LIBUNWIND_SUPPORT_SEH_UNWIND
3838
39// When CET is enabled, each "call" instruction will push return address to39// When shadow stack is enabled, a separate stack containing only return
40// CET shadow stack, each "ret" instruction will pop current CET shadow stack40// addresses would be maintained. On function return, the return address would
41// top and compare it with target address which program will return.41// be compared to the popped address from shadow stack to ensure the return
42// In exception handing, some stack frames will be skipped before jumping to42// target is not tempered with. When unwinding, we're skipping the normal return
43// landing pad and we must adjust CET shadow stack accordingly.43// procedure for multiple frames and thus need to pop the return addresses of
44// _LIBUNWIND_POP_CET_SSP is used to adjust CET shadow stack pointer and we44// the skipped frames from shadow stack to avoid triggering an exception (using
45// directly jump to __libunwind_Registers_x86/x86_64_jumpto instead of using45// `_LIBUNWIND_POP_SHSTK_SSP()`). Also, some architectures, like the x86-family
46// a regular function call to avoid pushing to CET shadow stack again.46// CET, push the return adddresses onto shadow stack with common call
47// instructions, so for these architectures, normal function calls should be
48// avoided when invoking the `jumpto()` function. To do this, we use inline
49// assemblies to "goto" the `jumpto()` for these architectures.
47#if !defined(_LIBUNWIND_USE_CET) && !defined(_LIBUNWIND_USE_GCS)50#if !defined(_LIBUNWIND_USE_CET) && !defined(_LIBUNWIND_USE_GCS)
48#define __unw_phase2_resume(cursor, fn) \51#define __unw_phase2_resume(cursor, fn) \
49 do { \52 do { \
...@@ -51,38 +54,38 @@...@@ -51,38 +54,38 @@
51 __unw_resume((cursor)); \54 __unw_resume((cursor)); \
52 } while (0)55 } while (0)
53#elif defined(_LIBUNWIND_TARGET_I386)56#elif defined(_LIBUNWIND_TARGET_I386)
54#define __cet_ss_step_size 457#define __shstk_step_size (4)
55#define __unw_phase2_resume(cursor, fn) \58#define __unw_phase2_resume(cursor, fn) \
56 do { \59 do { \
57 _LIBUNWIND_POP_CET_SSP((fn)); \60 _LIBUNWIND_POP_SHSTK_SSP((fn)); \
58 void *cetRegContext = __libunwind_cet_get_registers((cursor)); \61 void *shstkRegContext = __libunwind_shstk_get_registers((cursor)); \
59 void *cetJumpAddress = __libunwind_cet_get_jump_target(); \62 void *shstkJumpAddress = __libunwind_shstk_get_jump_target(); \
60 __asm__ volatile("push %%edi\n\t" \63 __asm__ volatile("push %%edi\n\t" \
61 "sub $4, %%esp\n\t" \64 "sub $4, %%esp\n\t" \
62 "jmp *%%edx\n\t" :: "D"(cetRegContext), \65 "jmp *%%edx\n\t" ::"D"(shstkRegContext), \
63 "d"(cetJumpAddress)); \66 "d"(shstkJumpAddress)); \
64 } while (0)67 } while (0)
65#elif defined(_LIBUNWIND_TARGET_X86_64)68#elif defined(_LIBUNWIND_TARGET_X86_64)
66#define __cet_ss_step_size 869#define __shstk_step_size (8)
67#define __unw_phase2_resume(cursor, fn) \70#define __unw_phase2_resume(cursor, fn) \
68 do { \71 do { \
69 _LIBUNWIND_POP_CET_SSP((fn)); \72 _LIBUNWIND_POP_SHSTK_SSP((fn)); \
70 void *cetRegContext = __libunwind_cet_get_registers((cursor)); \73 void *shstkRegContext = __libunwind_shstk_get_registers((cursor)); \
71 void *cetJumpAddress = __libunwind_cet_get_jump_target(); \74 void *shstkJumpAddress = __libunwind_shstk_get_jump_target(); \
72 __asm__ volatile("jmpq *%%rdx\n\t" :: "D"(cetRegContext), \75 __asm__ volatile("jmpq *%%rdx\n\t" ::"D"(shstkRegContext), \
73 "d"(cetJumpAddress)); \76 "d"(shstkJumpAddress)); \
74 } while (0)77 } while (0)
75#elif defined(_LIBUNWIND_TARGET_AARCH64)78#elif defined(_LIBUNWIND_TARGET_AARCH64)
76#define __cet_ss_step_size 879#define __shstk_step_size (8)
77#define __unw_phase2_resume(cursor, fn) \80#define __unw_phase2_resume(cursor, fn) \
78 do { \81 do { \
79 _LIBUNWIND_POP_CET_SSP((fn)); \82 _LIBUNWIND_POP_SHSTK_SSP((fn)); \
80 void *cetRegContext = __libunwind_cet_get_registers((cursor)); \83 void *shstkRegContext = __libunwind_shstk_get_registers((cursor)); \
81 void *cetJumpAddress = __libunwind_cet_get_jump_target(); \84 void *shstkJumpAddress = __libunwind_shstk_get_jump_target(); \
82 __asm__ volatile("mov x0, %0\n\t" \85 __asm__ volatile("mov x0, %0\n\t" \
83 "br %1\n\t" \86 "br %1\n\t" \
84 : \87 : \
85 : "r"(cetRegContext), "r"(cetJumpAddress) \88 : "r"(shstkRegContext), "r"(shstkJumpAddress) \
86 : "x0"); \89 : "x0"); \
87 } while (0)90 } while (0)
88#endif91#endif
...@@ -185,10 +188,11 @@ extern int __unw_step_stage2(unw_cursor_t *);...@@ -185,10 +188,11 @@ extern int __unw_step_stage2(unw_cursor_t *);
185188
186#if defined(_LIBUNWIND_USE_GCS)189#if defined(_LIBUNWIND_USE_GCS)
187// Enable the GCS target feature to permit gcspop instructions to be used.190// Enable the GCS target feature to permit gcspop instructions to be used.
188__attribute__((target("gcs")))191__attribute__((target("+gcs")))
189#endif192#endif
190static _Unwind_Reason_Code193static _Unwind_Reason_Code
191unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {194unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor,
195 _Unwind_Exception *exception_object) {
192 __unw_init_local(cursor, uc);196 __unw_init_local(cursor, uc);
193197
194 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_obj=%p)",198 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_obj=%p)",
...@@ -255,16 +259,16 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except...@@ -255,16 +259,16 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
255 }259 }
256#endif260#endif
257261
258// In CET enabled environment, we check return address stored in normal stack262// In shadow stack enabled environment, we check return address stored in normal
259// against return address stored in CET shadow stack, if the 2 addresses don't263// stack against return address stored in shadow stack, if the 2 addresses don't
260// match, it means return address in normal stack has been corrupted, we return264// match, it means return address in normal stack has been corrupted, we return
261// _URC_FATAL_PHASE2_ERROR.265// _URC_FATAL_PHASE2_ERROR.
262#if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS)266#if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS)
263 if (shadowStackTop != 0) {267 if (shadowStackTop != 0) {
264 unw_word_t retInNormalStack;268 unw_word_t retInNormalStack;
265 __unw_get_reg(cursor, UNW_REG_IP, &retInNormalStack);269 __unw_get_reg(cursor, UNW_REG_IP, &retInNormalStack);
266 unsigned long retInShadowStack = *(270 unsigned long retInShadowStack =
267 unsigned long *)(shadowStackTop + __cet_ss_step_size * framesWalked);271 *(unsigned long *)(shadowStackTop + __shstk_step_size * framesWalked);
268 if (retInNormalStack != retInShadowStack)272 if (retInNormalStack != retInShadowStack)
269 return _URC_FATAL_PHASE2_ERROR;273 return _URC_FATAL_PHASE2_ERROR;
270 }274 }
...@@ -329,12 +333,12 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except...@@ -329,12 +333,12 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
329333
330#if defined(_LIBUNWIND_USE_GCS)334#if defined(_LIBUNWIND_USE_GCS)
331// Enable the GCS target feature to permit gcspop instructions to be used.335// Enable the GCS target feature to permit gcspop instructions to be used.
332__attribute__((target("gcs")))336__attribute__((target("+gcs")))
333#endif337#endif
334static _Unwind_Reason_Code338static _Unwind_Reason_Code
335unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,339unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
336 _Unwind_Exception *exception_object,340 _Unwind_Exception *exception_object, _Unwind_Stop_Fn stop,
337 _Unwind_Stop_Fn stop, void *stop_parameter) {341 void *stop_parameter) {
338 __unw_init_local(cursor, uc);342 __unw_init_local(cursor, uc);
339343
340 // uc is initialized by __unw_getcontext in the parent frame. The first stack344 // uc is initialized by __unw_getcontext in the parent frame. The first stack
...@@ -440,7 +444,6 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,...@@ -440,7 +444,6 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
440 return _URC_FATAL_PHASE2_ERROR;444 return _URC_FATAL_PHASE2_ERROR;
441}445}
442446
443
444/// Called by __cxa_throw. Only returns if there is a fatal error.447/// Called by __cxa_throw. Only returns if there is a fatal error.
445_LIBUNWIND_EXPORT _Unwind_Reason_Code448_LIBUNWIND_EXPORT _Unwind_Reason_Code
446_Unwind_RaiseException(_Unwind_Exception *exception_object) {449_Unwind_RaiseException(_Unwind_Exception *exception_object) {
lib/libunwind/src/UnwindRegistersRestore.S+1-1
...@@ -66,7 +66,7 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_jumpto)...@@ -66,7 +66,7 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_jumpto)
66 # skip fs66 # skip fs
67 # skip gs67 # skip gs
6868
69#elif defined(__x86_64__)69#elif defined(__x86_64__) && !defined(__arm64ec__)
7070
71DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_64_jumpto)71DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_64_jumpto)
72#72#
lib/libunwind/src/UnwindRegistersSave.S+49
...@@ -65,6 +65,47 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)...@@ -65,6 +65,47 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
65 xorl %eax, %eax # return UNW_ESUCCESS65 xorl %eax, %eax # return UNW_ESUCCESS
66 ret66 ret
6767
68#elif defined(__arm64ec__)
69
70//
71// extern int __unw_getcontext(unw_context_t* thread_state)
72//
73// On entry:
74// thread_state pointer is in x0
75//
76 .section .text,"xr",discard,"#__unw_getcontext"
77 .p2align 2
78DEFINE_LIBUNWIND_FUNCTION("#__unw_getcontext")
79 stp x8, x27, [x0, #0x000] // rax, rbx
80 stp x0, x1, [x0, #0x010] // rcx, rdx
81 stp x26,x25, [x0, #0x020] // rdi, rsi
82 mov x1, sp
83 stp fp, x1, [x0, #0x030] // rbp, rsp
84 stp x2, x3, [x0, #0x040] // r8, r9
85 stp x4, x5, [x0, #0x050] // r10, r11
86 stp x19,x20, [x0, #0x060] // r12, r13
87 stp x21,x22, [x0, #0x070] // r14, r15
88 str x30, [x0, #0x080] // store return address as pc
89 stp q0, q1, [x0, #0x0b0] // xmm0, xmm1
90 stp q2, q3, [x0, #0x0d0] // xmm2, xmm3
91 stp q4, q5, [x0, #0x0f0] // xmm4, xmm5
92 stp q6, q7, [x0, #0x110] // xmm6, xmm7
93 stp q8, q9, [x0, #0x130] // xmm8, xmm9
94 stp q10,q11, [x0, #0x150] // xmm10,xmm11
95 stp q12,q13, [x0, #0x170] // xmm12,xmm13
96 stp q14,q15, [x0, #0x190] // xmm14,xmm15
97 mov x0, #0 // return UNW_ESUCCESS
98 ret
99
100 .weak_anti_dep __unw_getcontext
101 .set __unw_getcontext, "#__unw_getcontext"
102
103 .section .hybmp$x,"yi"
104 .symidx "#__unw_getcontext"
105 .symidx $ientry_thunk$cdecl$i8$i8
106 .word 1
107 .text
108
68#elif defined(__x86_64__)109#elif defined(__x86_64__)
69110
70#111#
...@@ -1181,7 +1222,15 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)...@@ -1181,7 +1222,15 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
11811222
1182#endif1223#endif
11831224
1225#ifdef __arm64ec__
1226 .globl "#unw_getcontext"
1227 .set "#unw_getcontext", "#__unw_getcontext"
1228 .weak_anti_dep unw_getcontext
1229 .set unw_getcontext, "#unw_getcontext"
1230 EXPORT_SYMBOL(unw_getcontext)
1231#else
1184 WEAK_ALIAS(__unw_getcontext, unw_getcontext)1232 WEAK_ALIAS(__unw_getcontext, unw_getcontext)
1233#endif
11851234
1186#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__) */1235#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__) */
11871236
lib/libunwind/src/cet_unwind.h deleted-63
...@@ -1,63 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LIBUNWIND_CET_UNWIND_H
11#define LIBUNWIND_CET_UNWIND_H
12
13#include "libunwind.h"
14
15// Currently, CET is implemented on Linux x86 platforms.
16#if defined(_LIBUNWIND_TARGET_LINUX) && defined(__CET__) && defined(__SHSTK__)
17#define _LIBUNWIND_USE_CET 1
18#endif
19
20#if defined(_LIBUNWIND_USE_CET)
21#include <cet.h>
22#include <immintrin.h>
23
24#define _LIBUNWIND_POP_CET_SSP(x) \
25 do { \
26 unsigned long ssp = _get_ssp(); \
27 if (ssp != 0) { \
28 unsigned int tmp = (x); \
29 while (tmp > 255) { \
30 _inc_ssp(255); \
31 tmp -= 255; \
32 } \
33 _inc_ssp(tmp); \
34 } \
35 } while (0)
36#endif
37
38// On AArch64 we use _LIBUNWIND_USE_GCS to indicate that GCS is supported. We
39// need to guard any use of GCS instructions with __chkfeat though, as GCS may
40// not be enabled.
41#if defined(_LIBUNWIND_TARGET_AARCH64) && defined(__ARM_FEATURE_GCS_DEFAULT)
42#include <arm_acle.h>
43
44// We can only use GCS if arm_acle.h defines the GCS intrinsics.
45#ifdef _CHKFEAT_GCS
46#define _LIBUNWIND_USE_GCS 1
47#endif
48
49#define _LIBUNWIND_POP_CET_SSP(x) \
50 do { \
51 if (__chkfeat(_CHKFEAT_GCS)) { \
52 unsigned tmp = (x); \
53 while (tmp--) \
54 __gcspopm(); \
55 } \
56 } while (0)
57
58#endif
59
60extern void *__libunwind_cet_get_registers(unw_cursor_t *);
61extern void *__libunwind_cet_get_jump_target(void);
62
63#endif
lib/libunwind/src/gcc_personality_v0.c+2
...@@ -6,6 +6,7 @@...@@ -6,6 +6,7 @@
6//6//
7//===----------------------------------------------------------------------===//7//===----------------------------------------------------------------------===//
88
9/* zig patch: remove compiler-rt int_lib.h dependency */
9#if __ARM_EABI__10#if __ARM_EABI__
10#ifdef COMPILER_RT_ARMHF_TARGET11#ifdef COMPILER_RT_ARMHF_TARGET
11#define COMPILER_RT_ABI12#define COMPILER_RT_ABI
...@@ -19,6 +20,7 @@...@@ -19,6 +20,7 @@
19#define compilerrt_abort() __builtin_unreachable()20#define compilerrt_abort() __builtin_unreachable()
2021
21#include <unwind.h>22#include <unwind.h>
23/* zig patch: remove unwind-ehabi-helpers.h dependency */
2224
23#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)25#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
24#include <windows.h>26#include <windows.h>
lib/libunwind/src/shadow_stack_unwind.h created+63
...@@ -0,0 +1,63 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LIBUNWIND_SHADOW_STACK_UNWIND_H
11#define LIBUNWIND_SHADOW_STACK_UNWIND_H
12
13#include "libunwind.h"
14
15// Currently, CET is implemented on Linux x86 platforms.
16#if defined(_LIBUNWIND_TARGET_LINUX) && defined(__CET__) && defined(__SHSTK__)
17#define _LIBUNWIND_USE_CET 1
18#endif
19
20#if defined(_LIBUNWIND_USE_CET)
21#include <cet.h>
22#include <immintrin.h>
23
24#define _LIBUNWIND_POP_SHSTK_SSP(x) \
25 do { \
26 unsigned long ssp = _get_ssp(); \
27 if (ssp != 0) { \
28 unsigned int tmp = (x); \
29 while (tmp > 255) { \
30 _inc_ssp(255); \
31 tmp -= 255; \
32 } \
33 _inc_ssp(tmp); \
34 } \
35 } while (0)
36#endif
37
38// On AArch64 we use _LIBUNWIND_USE_GCS to indicate that GCS is supported. We
39// need to guard any use of GCS instructions with __chkfeat though, as GCS may
40// not be enabled.
41#if defined(_LIBUNWIND_TARGET_AARCH64) && defined(__ARM_FEATURE_GCS_DEFAULT)
42#include <arm_acle.h>
43
44// We can only use GCS if arm_acle.h defines the GCS intrinsics.
45#ifdef _CHKFEAT_GCS
46#define _LIBUNWIND_USE_GCS 1
47#endif
48
49#define _LIBUNWIND_POP_SHSTK_SSP(x) \
50 do { \
51 if (__chkfeat(_CHKFEAT_GCS)) { \
52 unsigned tmp = (x); \
53 while (tmp--) \
54 __gcspopm(); \
55 } \
56 } while (0)
57
58#endif
59
60extern void *__libunwind_shstk_get_registers(unw_cursor_t *);
61extern void *__libunwind_shstk_get_jump_target(void);
62
63#endif