| author | |
| committer | |
| log | 26ddfabba4611231fa486322b9ba11b1057a2053 |
| tree | b083f47f7a7f578da30d39605fece3ffaa7ce07e |
| parent | dc14434c0aed409a9152a05e4741623e0e99f32a |
10 files changed, 118 insertions(+), 23 deletions(-)
lib/libunwind/include/__libunwind_config.h+4| ... | ... | @@ -180,6 +180,10 @@ |
| 180 | 180 | #endif |
| 181 | 181 | #define _LIBUNWIND_HIGHEST_DWARF_REGISTER \ |
| 182 | 182 | _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH |
| 183 | #elif defined(__wasm__) | |
| 184 | // Unused | |
| 185 | #define _LIBUNWIND_CONTEXT_SIZE 0 | |
| 186 | #define _LIBUNWIND_CURSOR_SIZE 0 | |
| 183 | 187 | # else |
| 184 | 188 | # error "Unsupported architecture." |
| 185 | 189 | # endif |
lib/libunwind/src/Registers.hpp+7| ... | ... | @@ -1815,6 +1815,13 @@ inline const char *Registers_ppc64::getRegisterName(int regNum) { |
| 1815 | 1815 | /// process. |
| 1816 | 1816 | class _LIBUNWIND_HIDDEN Registers_arm64; |
| 1817 | 1817 | extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *); |
| 1818 | ||
| 1819 | #if defined(_LIBUNWIND_USE_GCS) | |
| 1820 | extern "C" void *__libunwind_cet_get_jump_target() { | |
| 1821 | return reinterpret_cast<void *>(&__libunwind_Registers_arm64_jumpto); | |
| 1822 | } | |
| 1823 | #endif | |
| 1824 | ||
| 1818 | 1825 | class _LIBUNWIND_HIDDEN Registers_arm64 { |
| 1819 | 1826 | public: |
| 1820 | 1827 | Registers_arm64(); |
lib/libunwind/src/Unwind-wasm.c+2-2| ... | ... | @@ -14,7 +14,7 @@ |
| 14 | 14 | |
| 15 | 15 | #include "config.h" |
| 16 | 16 | |
| 17 | #ifdef __USING_WASM_EXCEPTIONS__ | |
| 17 | #ifdef __WASM_EXCEPTIONS__ | |
| 18 | 18 | |
| 19 | 19 | #include "unwind.h" |
| 20 | 20 | #include <threads.h> |
| ... | ... | @@ -120,4 +120,4 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) { |
| 120 | 120 | return 0; |
| 121 | 121 | } |
| 122 | 122 | |
| 123 | #endif // defined(__USING_WASM_EXCEPTIONS__) | |
| 123 | #endif // defined(__WASM_EXCEPTIONS__) |
lib/libunwind/src/UnwindCursor.hpp+13-5| ... | ... | @@ -36,7 +36,6 @@ |
| 36 | 36 | #include <errno.h> |
| 37 | 37 | #include <signal.h> |
| 38 | 38 | #include <sys/syscall.h> |
| 39 | #include <sys/uio.h> | |
| 40 | 39 | #include <unistd.h> |
| 41 | 40 | #define _LIBUNWIND_CHECK_LINUX_SIGRETURN 1 |
| 42 | 41 | #endif |
| ... | ... | @@ -472,7 +471,7 @@ public: |
| 472 | 471 | } |
| 473 | 472 | #endif |
| 474 | 473 | |
| 475 | #if defined(_LIBUNWIND_USE_CET) | |
| 474 | #if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS) | |
| 476 | 475 | virtual void *get_registers() { |
| 477 | 476 | _LIBUNWIND_ABORT("get_registers not implemented"); |
| 478 | 477 | } |
| ... | ... | @@ -955,7 +954,7 @@ public: |
| 955 | 954 | virtual uintptr_t getDataRelBase(); |
| 956 | 955 | #endif |
| 957 | 956 | |
| 958 | #if defined(_LIBUNWIND_USE_CET) | |
| 957 | #if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS) | |
| 959 | 958 | virtual void *get_registers() { return &_registers; } |
| 960 | 959 | #endif |
| 961 | 960 | |
| ... | ... | @@ -2416,7 +2415,7 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable, |
| 2416 | 2415 | } |
| 2417 | 2416 | |
| 2418 | 2417 | // Reset LR in the current context. |
| 2419 | newRegisters.setLR(NULL); | |
| 2418 | newRegisters.setLR(static_cast<uintptr_t>(NULL)); | |
| 2420 | 2419 | |
| 2421 | 2420 | _LIBUNWIND_TRACE_UNWINDING( |
| 2422 | 2421 | "Extract info from lastStack=%p, returnAddress=%p", |
| ... | ... | @@ -2590,6 +2589,15 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) { |
| 2590 | 2589 | --pc; |
| 2591 | 2590 | #endif |
| 2592 | 2591 | |
| 2592 | #if !(defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && defined(_WIN32)) && \ | |
| 2593 | !defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND) | |
| 2594 | // In case of this is frame of signal handler, the IP saved in the signal | |
| 2595 | // handler points to first non-executed instruction, while FDE/CIE expects IP | |
| 2596 | // to be after the first non-executed instruction. | |
| 2597 | if (_isSignalFrame) | |
| 2598 | ++pc; | |
| 2599 | #endif | |
| 2600 | ||
| 2593 | 2601 | // Ask address space object to find unwind sections for this pc. |
| 2594 | 2602 | UnwindInfoSections sects; |
| 2595 | 2603 | if (_addressSpace.findUnwindSections(pc, sects)) { |
| ... | ... | @@ -2997,7 +3005,7 @@ bool UnwindCursor<A, R>::isReadableAddr(const pint_t addr) const { |
| 2997 | 3005 | } |
| 2998 | 3006 | #endif |
| 2999 | 3007 | |
| 3000 | #if defined(_LIBUNWIND_USE_CET) | |
| 3008 | #if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS) | |
| 3001 | 3009 | extern "C" void *__libunwind_cet_get_registers(unw_cursor_t *cursor) { |
| 3002 | 3010 | AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; |
| 3003 | 3011 | return co->get_registers(); |
lib/libunwind/src/UnwindLevel1.c+30-4| ... | ... | @@ -31,7 +31,8 @@ |
| 31 | 31 | #include "libunwind_ext.h" |
| 32 | 32 | #include "unwind.h" |
| 33 | 33 | |
| 34 | #if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__) | |
| 34 | #if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__) && \ | |
| 35 | !defined(__wasm__) | |
| 35 | 36 | |
| 36 | 37 | #ifndef _LIBUNWIND_SUPPORT_SEH_UNWIND |
| 37 | 38 | |
| ... | ... | @@ -43,7 +44,7 @@ |
| 43 | 44 | // _LIBUNWIND_POP_CET_SSP is used to adjust CET shadow stack pointer and we |
| 44 | 45 | // directly jump to __libunwind_Registers_x86/x86_64_jumpto instead of using |
| 45 | 46 | // a regular function call to avoid pushing to CET shadow stack again. |
| 46 | #if !defined(_LIBUNWIND_USE_CET) | |
| 47 | #if !defined(_LIBUNWIND_USE_CET) && !defined(_LIBUNWIND_USE_GCS) | |
| 47 | 48 | #define __unw_phase2_resume(cursor, fn) \ |
| 48 | 49 | do { \ |
| 49 | 50 | (void)fn; \ |
| ... | ... | @@ -71,6 +72,19 @@ |
| 71 | 72 | __asm__ volatile("jmpq *%%rdx\n\t" :: "D"(cetRegContext), \ |
| 72 | 73 | "d"(cetJumpAddress)); \ |
| 73 | 74 | } while (0) |
| 75 | #elif defined(_LIBUNWIND_TARGET_AARCH64) | |
| 76 | #define __cet_ss_step_size 8 | |
| 77 | #define __unw_phase2_resume(cursor, fn) \ | |
| 78 | do { \ | |
| 79 | _LIBUNWIND_POP_CET_SSP((fn)); \ | |
| 80 | void *cetRegContext = __libunwind_cet_get_registers((cursor)); \ | |
| 81 | void *cetJumpAddress = __libunwind_cet_get_jump_target(); \ | |
| 82 | __asm__ volatile("mov x0, %0\n\t" \ | |
| 83 | "br %1\n\t" \ | |
| 84 | : \ | |
| 85 | : "r"(cetRegContext), "r"(cetJumpAddress) \ | |
| 86 | : "x0"); \ | |
| 87 | } while (0) | |
| 74 | 88 | #endif |
| 75 | 89 | |
| 76 | 90 | static _Unwind_Reason_Code |
| ... | ... | @@ -169,6 +183,10 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except |
| 169 | 183 | } |
| 170 | 184 | extern int __unw_step_stage2(unw_cursor_t *); |
| 171 | 185 | |
| 186 | #if defined(_LIBUNWIND_USE_GCS) | |
| 187 | // Enable the GCS target feature to permit gcspop instructions to be used. | |
| 188 | __attribute__((target("gcs"))) | |
| 189 | #endif | |
| 172 | 190 | static _Unwind_Reason_Code |
| 173 | 191 | unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) { |
| 174 | 192 | __unw_init_local(cursor, uc); |
| ... | ... | @@ -179,8 +197,12 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except |
| 179 | 197 | // uc is initialized by __unw_getcontext in the parent frame. The first stack |
| 180 | 198 | // frame walked is unwind_phase2. |
| 181 | 199 | unsigned framesWalked = 1; |
| 182 | #ifdef _LIBUNWIND_USE_CET | |
| 200 | #if defined(_LIBUNWIND_USE_CET) | |
| 183 | 201 | unsigned long shadowStackTop = _get_ssp(); |
| 202 | #elif defined(_LIBUNWIND_USE_GCS) | |
| 203 | unsigned long shadowStackTop = 0; | |
| 204 | if (__chkfeat(_CHKFEAT_GCS)) | |
| 205 | shadowStackTop = (unsigned long)__gcspr(); | |
| 184 | 206 | #endif |
| 185 | 207 | // Walk each frame until we reach where search phase said to stop. |
| 186 | 208 | while (true) { |
| ... | ... | @@ -237,7 +259,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except |
| 237 | 259 | // against return address stored in CET shadow stack, if the 2 addresses don't |
| 238 | 260 | // match, it means return address in normal stack has been corrupted, we return |
| 239 | 261 | // _URC_FATAL_PHASE2_ERROR. |
| 240 | #ifdef _LIBUNWIND_USE_CET | |
| 262 | #if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS) | |
| 241 | 263 | if (shadowStackTop != 0) { |
| 242 | 264 | unw_word_t retInNormalStack; |
| 243 | 265 | __unw_get_reg(cursor, UNW_REG_IP, &retInNormalStack); |
| ... | ... | @@ -305,6 +327,10 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except |
| 305 | 327 | return _URC_FATAL_PHASE2_ERROR; |
| 306 | 328 | } |
| 307 | 329 | |
| 330 | #if defined(_LIBUNWIND_USE_GCS) | |
| 331 | // Enable the GCS target feature to permit gcspop instructions to be used. | |
| 332 | __attribute__((target("gcs"))) | |
| 333 | #endif | |
| 308 | 334 | static _Unwind_Reason_Code |
| 309 | 335 | unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, |
| 310 | 336 | _Unwind_Exception *exception_object, |
lib/libunwind/src/UnwindRegistersRestore.S+16-2| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | .text |
| 21 | 21 | #endif |
| 22 | 22 | |
| 23 | #if !defined(__USING_SJLJ_EXCEPTIONS__) | |
| 23 | #if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__) | |
| 24 | 24 | |
| 25 | 25 | #if defined(__i386__) |
| 26 | 26 | DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_jumpto) |
| ... | ... | @@ -629,6 +629,10 @@ Lnovec: |
| 629 | 629 | |
| 630 | 630 | #elif defined(__aarch64__) |
| 631 | 631 | |
| 632 | #if defined(__ARM_FEATURE_GCS_DEFAULT) | |
| 633 | .arch_extension gcs | |
| 634 | #endif | |
| 635 | ||
| 632 | 636 | // |
| 633 | 637 | // extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *); |
| 634 | 638 | // |
| ... | ... | @@ -680,6 +684,16 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto) |
| 680 | 684 | ldr x16, [x0, #0x0F8] |
| 681 | 685 | ldp x0, x1, [x0, #0x000] // restore x0,x1 |
| 682 | 686 | mov sp,x16 // restore sp |
| 687 | #if defined(__ARM_FEATURE_GCS_DEFAULT) | |
| 688 | // If GCS is enabled we need to push the address we're returning to onto the | |
| 689 | // GCS stack. We can't just return using br, as there won't be a BTI landing | |
| 690 | // pad instruction at the destination. | |
| 691 | mov x16, #1 | |
| 692 | chkfeat x16 | |
| 693 | cbnz x16, Lnogcs | |
| 694 | gcspushm x30 | |
| 695 | Lnogcs: | |
| 696 | #endif | |
| 683 | 697 | ret x30 // jump to pc |
| 684 | 698 | |
| 685 | 699 | #elif defined(__arm__) && !defined(__APPLE__) |
| ... | ... | @@ -1232,7 +1246,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind19Registers_loongarch6jumptoEv) |
| 1232 | 1246 | |
| 1233 | 1247 | #endif |
| 1234 | 1248 | |
| 1235 | #endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */ | |
| 1249 | #endif /* !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__) */ | |
| 1236 | 1250 | |
| 1237 | 1251 | NO_EXEC_STACK_DIRECTIVE |
| 1238 | 1252 |
lib/libunwind/src/UnwindRegistersSave.S+2-2| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | .text |
| 21 | 21 | #endif |
| 22 | 22 | |
| 23 | #if !defined(__USING_SJLJ_EXCEPTIONS__) | |
| 23 | #if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__) | |
| 24 | 24 | |
| 25 | 25 | #if defined(__i386__) |
| 26 | 26 | |
| ... | ... | @@ -1177,6 +1177,6 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) |
| 1177 | 1177 | |
| 1178 | 1178 | WEAK_ALIAS(__unw_getcontext, unw_getcontext) |
| 1179 | 1179 | |
| 1180 | #endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */ | |
| 1180 | #endif /* !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__) */ | |
| 1181 | 1181 | |
| 1182 | 1182 | NO_EXEC_STACK_DIRECTIVE |
lib/libunwind/src/assembly.h+20-5| ... | ... | @@ -82,7 +82,22 @@ |
| 82 | 82 | #define PPC64_OPD2 |
| 83 | 83 | #endif |
| 84 | 84 | |
| 85 | #if defined(__aarch64__) && defined(__ARM_FEATURE_BTI_DEFAULT) | |
| 85 | #if defined(__aarch64__) | |
| 86 | #if defined(__ARM_FEATURE_GCS_DEFAULT) && defined(__ARM_FEATURE_BTI_DEFAULT) | |
| 87 | // Set BTI, PAC, and GCS gnu property bits | |
| 88 | #define GNU_PROPERTY 7 | |
| 89 | // We indirectly branch to __libunwind_Registers_arm64_jumpto from | |
| 90 | // __unw_phase2_resume, so we need to use bti jc. | |
| 91 | #define AARCH64_BTI bti jc | |
| 92 | #elif defined(__ARM_FEATURE_GCS_DEFAULT) | |
| 93 | // Set GCS gnu property bit | |
| 94 | #define GNU_PROPERTY 4 | |
| 95 | #elif defined(__ARM_FEATURE_BTI_DEFAULT) | |
| 96 | // Set BTI and PAC gnu property bits | |
| 97 | #define GNU_PROPERTY 3 | |
| 98 | #define AARCH64_BTI bti c | |
| 99 | #endif | |
| 100 | #ifdef GNU_PROPERTY | |
| 86 | 101 | .pushsection ".note.gnu.property", "a" SEPARATOR \ |
| 87 | 102 | .balign 8 SEPARATOR \ |
| 88 | 103 | .long 4 SEPARATOR \ |
| ... | ... | @@ -91,12 +106,12 @@ |
| 91 | 106 | .asciz "GNU" SEPARATOR \ |
| 92 | 107 | .long 0xc0000000 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ \ |
| 93 | 108 | .long 4 SEPARATOR \ |
| 94 | .long 3 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_BTI AND */ \ | |
| 95 | /* GNU_PROPERTY_AARCH64_FEATURE_1_PAC */ \ | |
| 109 | .long GNU_PROPERTY SEPARATOR \ | |
| 96 | 110 | .long 0 SEPARATOR \ |
| 97 | 111 | .popsection SEPARATOR |
| 98 | #define AARCH64_BTI bti c | |
| 99 | #else | |
| 112 | #endif | |
| 113 | #endif | |
| 114 | #if !defined(AARCH64_BTI) | |
| 100 | 115 | #define AARCH64_BTI |
| 101 | 116 | #endif |
| 102 | 117 |
lib/libunwind/src/cet_unwind.h+22| ... | ... | @@ -35,6 +35,28 @@ |
| 35 | 35 | } while (0) |
| 36 | 36 | #endif |
| 37 | 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 | ||
| 38 | 60 | extern void *__libunwind_cet_get_registers(unw_cursor_t *); |
| 39 | 61 | extern void *__libunwind_cet_get_jump_target(void); |
| 40 | 62 |
lib/libunwind/src/libunwind.cpp+2-3| ... | ... | @@ -26,7 +26,7 @@ |
| 26 | 26 | #include <sanitizer/asan_interface.h> |
| 27 | 27 | #endif |
| 28 | 28 | |
| 29 | #if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__USING_WASM_EXCEPTIONS__) | |
| 29 | #if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__) | |
| 30 | 30 | #include "AddressSpace.hpp" |
| 31 | 31 | #include "UnwindCursor.hpp" |
| 32 | 32 | |
| ... | ... | @@ -347,8 +347,7 @@ void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start) { |
| 347 | 347 | } |
| 348 | 348 | |
| 349 | 349 | #endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) |
| 350 | #endif // !defined(__USING_SJLJ_EXCEPTIONS__) && | |
| 351 | // !defined(__USING_WASM_EXCEPTIONS__) | |
| 350 | #endif // !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__) | |
| 352 | 351 | |
| 353 | 352 | #ifdef __APPLE__ |
| 354 | 353 |