Skip to content

Commit

Permalink
Update libunwind to LLVM 19.1.4 (#22934)
Browse files Browse the repository at this point in the history
Other than these two PRs I submitted to upstream LLVM, all other changes
are unrelated upstream changes.
llvm/llvm-project#92192
llvm/llvm-project#92840

This PR was created by running
https://github.com/emscripten-core/emscripten/blob/main/system/lib/update_libunwind.py
script.
  • Loading branch information
aheejin authored Nov 20, 2024
1 parent f03605d commit 119a427
Show file tree
Hide file tree
Showing 12 changed files with 120 additions and 28 deletions.
1 change: 1 addition & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ See docs/process.md for more on how version tagging works.

3.1.73 (in development)
-----------------------
- libunwind was updated to LLVM 19.1.4. (#22394)

3.1.72 - 11/19/24
-----------------
Expand Down
4 changes: 4 additions & 0 deletions system/lib/libunwind/include/__libunwind_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@
#endif
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER \
_LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH
#elif defined(__wasm__)
// Unused
#define _LIBUNWIND_CONTEXT_SIZE 0
#define _LIBUNWIND_CURSOR_SIZE 0
# else
# error "Unsupported architecture."
# endif
Expand Down

This file was deleted.

6 changes: 3 additions & 3 deletions system/lib/libunwind/readme.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
llvm's libunwind
----------------

These files are from the llvm-project based on release 17.0.4.
These files are from the llvm-project based on release 19.1.4.

We maintain a local fork of llvm-project that contains any emscripten
specific patches:

https://github.com/emscripten-core/llvm-project

The current patch is based on the emscripten-libs-17 branch.
The current patch is based on the emscripten-libs-19 branch.

Update Instructions
-------------------
Expand All @@ -20,4 +20,4 @@ Modifications

For a list of changes from upstream see the libunwind files that are part of:

https://github.com/llvm/llvm-project/compare/llvmorg-17.0.4...emscripten-core:emscripten-libs-17
https://github.com/llvm/llvm-project/compare/llvmorg-19.1.4...emscripten-core:emscripten-libs-19
7 changes: 7 additions & 0 deletions system/lib/libunwind/src/Registers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1815,6 +1815,13 @@ inline const char *Registers_ppc64::getRegisterName(int regNum) {
/// process.
class _LIBUNWIND_HIDDEN Registers_arm64;
extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);

#if defined(_LIBUNWIND_USE_GCS)
extern "C" void *__libunwind_cet_get_jump_target() {
return reinterpret_cast<void *>(&__libunwind_Registers_arm64_jumpto);
}
#endif

class _LIBUNWIND_HIDDEN Registers_arm64 {
public:
Registers_arm64();
Expand Down
18 changes: 13 additions & 5 deletions system/lib/libunwind/src/UnwindCursor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
#include <errno.h>
#include <signal.h>
#include <sys/syscall.h>
#include <sys/uio.h>
#include <unistd.h>
#define _LIBUNWIND_CHECK_LINUX_SIGRETURN 1
#endif
Expand Down Expand Up @@ -472,7 +471,7 @@ class _LIBUNWIND_HIDDEN AbstractUnwindCursor {
}
#endif

#if defined(_LIBUNWIND_USE_CET)
#if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS)
virtual void *get_registers() {
_LIBUNWIND_ABORT("get_registers not implemented");
}
Expand Down Expand Up @@ -955,7 +954,7 @@ class UnwindCursor : public AbstractUnwindCursor{
virtual uintptr_t getDataRelBase();
#endif

#if defined(_LIBUNWIND_USE_CET)
#if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS)
virtual void *get_registers() { return &_registers; }
#endif

Expand Down Expand Up @@ -2416,7 +2415,7 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
}

// Reset LR in the current context.
newRegisters.setLR(NULL);
newRegisters.setLR(static_cast<uintptr_t>(NULL));

_LIBUNWIND_TRACE_UNWINDING(
"Extract info from lastStack=%p, returnAddress=%p",
Expand Down Expand Up @@ -2590,6 +2589,15 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
--pc;
#endif

#if !(defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && defined(_WIN32)) && \
!defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
// In case of this is frame of signal handler, 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.
if (_isSignalFrame)
++pc;
#endif

// Ask address space object to find unwind sections for this pc.
UnwindInfoSections sects;
if (_addressSpace.findUnwindSections(pc, sects)) {
Expand Down Expand Up @@ -2997,7 +3005,7 @@ bool UnwindCursor<A, R>::isReadableAddr(const pint_t addr) const {
}
#endif

#if defined(_LIBUNWIND_USE_CET)
#if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS)
extern "C" void *__libunwind_cet_get_registers(unw_cursor_t *cursor) {
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
return co->get_registers();
Expand Down
34 changes: 30 additions & 4 deletions system/lib/libunwind/src/UnwindLevel1.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
#include "libunwind_ext.h"
#include "unwind.h"

#if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__)
#if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__) && \
!defined(__wasm__)

#ifndef _LIBUNWIND_SUPPORT_SEH_UNWIND

Expand All @@ -43,7 +44,7 @@
// _LIBUNWIND_POP_CET_SSP is used to adjust CET shadow stack pointer and we
// directly jump to __libunwind_Registers_x86/x86_64_jumpto instead of using
// a regular function call to avoid pushing to CET shadow stack again.
#if !defined(_LIBUNWIND_USE_CET)
#if !defined(_LIBUNWIND_USE_CET) && !defined(_LIBUNWIND_USE_GCS)
#define __unw_phase2_resume(cursor, fn) \
do { \
(void)fn; \
Expand Down Expand Up @@ -71,6 +72,19 @@
__asm__ volatile("jmpq *%%rdx\n\t" :: "D"(cetRegContext), \
"d"(cetJumpAddress)); \
} while (0)
#elif defined(_LIBUNWIND_TARGET_AARCH64)
#define __cet_ss_step_size 8
#define __unw_phase2_resume(cursor, fn) \
do { \
_LIBUNWIND_POP_CET_SSP((fn)); \
void *cetRegContext = __libunwind_cet_get_registers((cursor)); \
void *cetJumpAddress = __libunwind_cet_get_jump_target(); \
__asm__ volatile("mov x0, %0\n\t" \
"br %1\n\t" \
: \
: "r"(cetRegContext), "r"(cetJumpAddress) \
: "x0"); \
} while (0)
#endif

static _Unwind_Reason_Code
Expand Down Expand Up @@ -169,6 +183,10 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
}
extern int __unw_step_stage2(unw_cursor_t *);

#if defined(_LIBUNWIND_USE_GCS)
// Enable the GCS target feature to permit gcspop instructions to be used.
__attribute__((target("gcs")))
#endif
static _Unwind_Reason_Code
unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
__unw_init_local(cursor, uc);
Expand All @@ -179,8 +197,12 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
// uc is initialized by __unw_getcontext in the parent frame. The first stack
// frame walked is unwind_phase2.
unsigned framesWalked = 1;
#ifdef _LIBUNWIND_USE_CET
#if defined(_LIBUNWIND_USE_CET)
unsigned long shadowStackTop = _get_ssp();
#elif defined(_LIBUNWIND_USE_GCS)
unsigned long shadowStackTop = 0;
if (__chkfeat(_CHKFEAT_GCS))
shadowStackTop = (unsigned long)__gcspr();
#endif
// Walk each frame until we reach where search phase said to stop.
while (true) {
Expand Down Expand Up @@ -237,7 +259,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
// against return address stored in CET shadow stack, if the 2 addresses don't
// match, it means return address in normal stack has been corrupted, we return
// _URC_FATAL_PHASE2_ERROR.
#ifdef _LIBUNWIND_USE_CET
#if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS)
if (shadowStackTop != 0) {
unw_word_t retInNormalStack;
__unw_get_reg(cursor, UNW_REG_IP, &retInNormalStack);
Expand Down Expand Up @@ -305,6 +327,10 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
return _URC_FATAL_PHASE2_ERROR;
}

#if defined(_LIBUNWIND_USE_GCS)
// Enable the GCS target feature to permit gcspop instructions to be used.
__attribute__((target("gcs")))
#endif
static _Unwind_Reason_Code
unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
_Unwind_Exception *exception_object,
Expand Down
18 changes: 16 additions & 2 deletions system/lib/libunwind/src/UnwindRegistersRestore.S
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
.text
#endif

#if !defined(__USING_SJLJ_EXCEPTIONS__)
#if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__)

#if defined(__i386__)
DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_jumpto)
Expand Down Expand Up @@ -629,6 +629,10 @@ Lnovec:

#elif defined(__aarch64__)

#if defined(__ARM_FEATURE_GCS_DEFAULT)
.arch_extension gcs
#endif

//
// extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);
//
Expand Down Expand Up @@ -680,6 +684,16 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
ldr x16, [x0, #0x0F8]
ldp x0, x1, [x0, #0x000] // restore x0,x1
mov sp,x16 // restore sp
#if defined(__ARM_FEATURE_GCS_DEFAULT)
// If GCS is enabled we need to push the address we're returning to onto the
// GCS stack. We can't just return using br, as there won't be a BTI landing
// pad instruction at the destination.
mov x16, #1
chkfeat x16
cbnz x16, Lnogcs
gcspushm x30
Lnogcs:
#endif
ret x30 // jump to pc

#elif defined(__arm__) && !defined(__APPLE__)
Expand Down Expand Up @@ -1232,7 +1246,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind19Registers_loongarch6jumptoEv)

#endif

#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */
#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__) */

NO_EXEC_STACK_DIRECTIVE

4 changes: 2 additions & 2 deletions system/lib/libunwind/src/UnwindRegistersSave.S
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
.text
#endif

#if !defined(__USING_SJLJ_EXCEPTIONS__)
#if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__)

#if defined(__i386__)

Expand Down Expand Up @@ -1177,6 +1177,6 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)

WEAK_ALIAS(__unw_getcontext, unw_getcontext)

#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */
#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__) */

NO_EXEC_STACK_DIRECTIVE
25 changes: 20 additions & 5 deletions system/lib/libunwind/src/assembly.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,22 @@
#define PPC64_OPD2
#endif

#if defined(__aarch64__) && defined(__ARM_FEATURE_BTI_DEFAULT)
#if defined(__aarch64__)
#if defined(__ARM_FEATURE_GCS_DEFAULT) && defined(__ARM_FEATURE_BTI_DEFAULT)
// Set BTI, PAC, and GCS gnu property bits
#define GNU_PROPERTY 7
// We indirectly branch to __libunwind_Registers_arm64_jumpto from
// __unw_phase2_resume, so we need to use bti jc.
#define AARCH64_BTI bti jc
#elif defined(__ARM_FEATURE_GCS_DEFAULT)
// Set GCS gnu property bit
#define GNU_PROPERTY 4
#elif defined(__ARM_FEATURE_BTI_DEFAULT)
// Set BTI and PAC gnu property bits
#define GNU_PROPERTY 3
#define AARCH64_BTI bti c
#endif
#ifdef GNU_PROPERTY
.pushsection ".note.gnu.property", "a" SEPARATOR \
.balign 8 SEPARATOR \
.long 4 SEPARATOR \
Expand All @@ -91,12 +106,12 @@
.asciz "GNU" SEPARATOR \
.long 0xc0000000 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ \
.long 4 SEPARATOR \
.long 3 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_BTI AND */ \
/* GNU_PROPERTY_AARCH64_FEATURE_1_PAC */ \
.long GNU_PROPERTY SEPARATOR \
.long 0 SEPARATOR \
.popsection SEPARATOR
#define AARCH64_BTI bti c
#else
#endif
#endif
#if !defined(AARCH64_BTI)
#define AARCH64_BTI
#endif

Expand Down
22 changes: 22 additions & 0 deletions system/lib/libunwind/src/cet_unwind.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,28 @@
} while (0)
#endif

// On AArch64 we use _LIBUNWIND_USE_GCS to indicate that GCS is supported. We
// need to guard any use of GCS instructions with __chkfeat though, as GCS may
// not be enabled.
#if defined(_LIBUNWIND_TARGET_AARCH64) && defined(__ARM_FEATURE_GCS_DEFAULT)
#include <arm_acle.h>

// We can only use GCS if arm_acle.h defines the GCS intrinsics.
#ifdef _CHKFEAT_GCS
#define _LIBUNWIND_USE_GCS 1
#endif

#define _LIBUNWIND_POP_CET_SSP(x) \
do { \
if (__chkfeat(_CHKFEAT_GCS)) { \
unsigned tmp = (x); \
while (tmp--) \
__gcspopm(); \
} \
} while (0)

#endif

extern void *__libunwind_cet_get_registers(unw_cursor_t *);
extern void *__libunwind_cet_get_jump_target(void);

Expand Down
5 changes: 2 additions & 3 deletions system/lib/libunwind/src/libunwind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#include <sanitizer/asan_interface.h>
#endif

#if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__WASM_EXCEPTIONS__)
#if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__)
#include "AddressSpace.hpp"
#include "UnwindCursor.hpp"

Expand Down Expand Up @@ -347,8 +347,7 @@ void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start) {
}

#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
#endif // !defined(__USING_SJLJ_EXCEPTIONS__) &&
// !defined(__WASM_EXCEPTIONS__)
#endif // !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__)

#ifdef __APPLE__

Expand Down

0 comments on commit 119a427

Please sign in to comment.