Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.

4.0.23 (in development)
-----------------------
- libunwind was updated to LLVM 21.1.8. (#26035)
- The inconsistency of incrementing / decrementing refcounts between Wasm EH and
Emscripten EH has been fixed. See `test_EXPORT_EXCEPTION_HANDLING_HELPERS` in
`test_core.py` to see the usage. (#25988)
Expand Down
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 20.1.8.
These files are from the llvm-project based on release 21.1.8.

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-20 branch.
The current patch is based on the emscripten-libs-21 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-20.1.8...emscripten-core:emscripten-libs-20
https://github.com/llvm/llvm-project/compare/llvmorg-21.1.8...emscripten-core:emscripten-libs-21
10 changes: 5 additions & 5 deletions system/lib/libunwind/src/Registers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
#include <stdint.h>
#include <string.h>

#include "cet_unwind.h"
#include "config.h"
#include "libunwind.h"
#include "shadow_stack_unwind.h"

namespace libunwind {

Expand Down Expand Up @@ -48,7 +48,7 @@ class _LIBUNWIND_HIDDEN Registers_x86;
extern "C" void __libunwind_Registers_x86_jumpto(Registers_x86 *);

#if defined(_LIBUNWIND_USE_CET)
extern "C" void *__libunwind_cet_get_jump_target() {
extern "C" void *__libunwind_shstk_get_jump_target() {
return reinterpret_cast<void *>(&__libunwind_Registers_x86_jumpto);
}
#endif
Expand Down Expand Up @@ -268,7 +268,7 @@ class _LIBUNWIND_HIDDEN Registers_x86_64;
extern "C" void __libunwind_Registers_x86_64_jumpto(Registers_x86_64 *);

#if defined(_LIBUNWIND_USE_CET)
extern "C" void *__libunwind_cet_get_jump_target() {
extern "C" void *__libunwind_shstk_get_jump_target() {
return reinterpret_cast<void *>(&__libunwind_Registers_x86_64_jumpto);
}
#endif
Expand Down Expand Up @@ -1817,7 +1817,7 @@ 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() {
extern "C" void *__libunwind_shstk_get_jump_target() {
return reinterpret_cast<void *>(&__libunwind_Registers_arm64_jumpto);
}
#endif
Expand Down Expand Up @@ -4126,7 +4126,7 @@ inline reg_t Registers_riscv::getRegister(int regNum) const {
return _registers[regNum];
if (regNum == UNW_RISCV_VLENB) {
reg_t vlenb;
__asm__("csrr %0, 0xC22" : "=r"(vlenb));
__asm__ volatile("csrr %0, 0xC22" : "=r"(vlenb));
return vlenb;
}
_LIBUNWIND_ABORT("unsupported riscv register");
Expand Down
44 changes: 43 additions & 1 deletion system/lib/libunwind/src/Unwind-seh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,32 @@ static DISPATCHER_CONTEXT *__unw_seh_get_disp_ctx(unw_cursor_t *cursor);
static void __unw_seh_set_disp_ctx(unw_cursor_t *cursor,
DISPATCHER_CONTEXT *disp);

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
// Local redefinition of this type; mingw-w64 headers lack the
// DISPATCHER_CONTEXT_NONVOLREG_ARM64 type as of May 2025, so locally redefine
// it and use that definition, to avoid needing to test/guess whether the real
// type is available of not.
union LOCAL_DISPATCHER_CONTEXT_NONVOLREG_ARM64 {
BYTE Buffer[11 * sizeof(DWORD64) + 8 * sizeof(double)];

struct {
DWORD64 GpNvRegs[11];
double FpNvRegs[8];
};
};

// Custom data type definition; this type is not defined in WinSDK.
union LOCAL_DISPATCHER_CONTEXT_NONVOLREG_ARM {
BYTE Buffer[8 * sizeof(DWORD) + 8 * sizeof(double)];

struct {
DWORD GpNvRegs[8];
double FpNvRegs[8];
};
};
#pragma clang diagnostic pop

/// Common implementation of SEH-style handler functions used by Itanium-
/// style frames. Depending on how and why it was called, it may do one of:
/// a) Delegate to the given Itanium-style personality function; or
Expand Down Expand Up @@ -148,7 +174,8 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx,
}
// FIXME: Indicate target frame in foreign case!
// phase 2: the clean up phase
RtlUnwindEx(frame, (PVOID)disp->ControlPc, ms_exc, exc, ms_ctx, disp->HistoryTable);
RtlUnwindEx(frame, (PVOID)disp->ControlPc, ms_exc, exc, disp->ContextRecord,
disp->HistoryTable);
_LIBUNWIND_ABORT("RtlUnwindEx() failed");
case _URC_INSTALL_CONTEXT: {
// If we were called by __libunwind_seh_personality(), indicate that
Expand Down Expand Up @@ -212,6 +239,21 @@ __libunwind_seh_personality(int version, _Unwind_Action state,
ms_exc.ExceptionInformation[2] = state;
DISPATCHER_CONTEXT *disp_ctx =
__unw_seh_get_disp_ctx((unw_cursor_t *)context);
#if defined(__aarch64__)
LOCAL_DISPATCHER_CONTEXT_NONVOLREG_ARM64 nonvol;
memcpy(&nonvol.GpNvRegs, &disp_ctx->ContextRecord->X19,
sizeof(nonvol.GpNvRegs));
for (int i = 0; i < 8; i++)
nonvol.FpNvRegs[i] = disp_ctx->ContextRecord->V[i + 8].D[0];
disp_ctx->NonVolatileRegisters = nonvol.Buffer;
#elif defined(__arm__)
LOCAL_DISPATCHER_CONTEXT_NONVOLREG_ARM nonvol;
memcpy(&nonvol.GpNvRegs, &disp_ctx->ContextRecord->R4,
sizeof(nonvol.GpNvRegs));
memcpy(&nonvol.FpNvRegs, &disp_ctx->ContextRecord->D[8],
sizeof(nonvol.FpNvRegs));
disp_ctx->NonVolatileRegisters = nonvol.Buffer;
#endif
_LIBUNWIND_TRACE_UNWINDING("__libunwind_seh_personality() calling "
"LanguageHandler %p(%p, %p, %p, %p)",
(void *)disp_ctx->LanguageHandler, (void *)&ms_exc,
Expand Down
6 changes: 2 additions & 4 deletions system/lib/libunwind/src/Unwind-wasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
}

/// Not used in Wasm.
_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
uintptr_t value) {}
_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t) {}

/// Called by personality handler to get LSDA for current frame.
_LIBUNWIND_EXPORT uintptr_t
Expand All @@ -115,8 +114,7 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
}

/// Not used in Wasm.
_LIBUNWIND_EXPORT uintptr_t
_Unwind_GetRegionStart(struct _Unwind_Context *context) {
_LIBUNWIND_EXPORT uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *) {
return 0;
}

Expand Down
Loading