Skip to content

Commit ee88173

Browse files
authored
Update libunwind to LLVM 17.0.4 (#20705)
1 parent 165c1a3 commit ee88173

File tree

12 files changed

+281
-131
lines changed

12 files changed

+281
-131
lines changed

system/lib/libunwind/include/__libunwind_config.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,9 @@
196196
# define _LIBUNWIND_TARGET_RISCV 1
197197
# define _LIBUNWIND_TARGET_VE 1
198198
# define _LIBUNWIND_TARGET_S390X 1
199-
#define _LIBUNWIND_TARGET_LOONGARCH 1
199+
#define _LIBUNWIND_TARGET_LOONGARCH 1
200200
# define _LIBUNWIND_CONTEXT_SIZE 167
201-
# define _LIBUNWIND_CURSOR_SIZE 179
201+
# define _LIBUNWIND_CURSOR_SIZE 204
202202
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287
203203
#endif // _LIBUNWIND_IS_NATIVE_ONLY
204204

system/lib/libunwind/readme.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
llvm's libunwind
22
----------------
33

4-
These files are from the llvm-project based on release 16.0.6.
4+
These files are from the llvm-project based on release 17.0.4.
55

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

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

11-
The current patch is based on the emscripten-libs-16 branch.
11+
The current patch is based on the emscripten-libs-17 branch.
1212

1313
Update Instructions
1414
-------------------
@@ -20,4 +20,4 @@ Modifications
2020

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

23-
https://github.com/llvm/llvm-project/compare/llvmorg-16.0.6...emscripten-core:emscripten-libs-16
23+
https://github.com/llvm/llvm-project/compare/llvmorg-17.0.4...emscripten-core:emscripten-libs-17

system/lib/libunwind/src/AddressSpace.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ char *getFuncNameFromTBTable(uintptr_t pc, uint16_t &NameLen,
6666
// In 10.7.0 or later, libSystem.dylib implements this function.
6767
extern "C" bool _dyld_find_unwind_sections(void *, dyld_unwind_sections *);
6868

69+
namespace libunwind {
70+
bool findDynamicUnwindSections(void *, unw_dynamic_unwind_sections *);
71+
}
72+
6973
#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL)
7074

7175
// When statically linked on bare-metal, the symbols for the EH table are looked
@@ -497,6 +501,22 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
497501
info.compact_unwind_section_length = (size_t)dyldInfo.compact_unwind_section_length;
498502
return true;
499503
}
504+
505+
unw_dynamic_unwind_sections dynamicUnwindSectionInfo;
506+
if (findDynamicUnwindSections((void *)targetAddr,
507+
&dynamicUnwindSectionInfo)) {
508+
info.dso_base = dynamicUnwindSectionInfo.dso_base;
509+
#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
510+
info.dwarf_section = (uintptr_t)dynamicUnwindSectionInfo.dwarf_section;
511+
info.dwarf_section_length = dynamicUnwindSectionInfo.dwarf_section_length;
512+
#endif
513+
info.compact_unwind_section =
514+
(uintptr_t)dynamicUnwindSectionInfo.compact_unwind_section;
515+
info.compact_unwind_section_length =
516+
dynamicUnwindSectionInfo.compact_unwind_section_length;
517+
return true;
518+
}
519+
500520
#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL)
501521
info.dso_base = 0;
502522
// Bare metal is statically linked, so no need to ask the dynamic loader

system/lib/libunwind/src/Unwind-EHABI.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
709709
// Update info about this frame.
710710
unw_proc_info_t frameInfo;
711711
if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
712-
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_step "
712+
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_get_proc_info "
713713
"failed => _URC_END_OF_STACK",
714714
(void *)exception_object);
715715
return _URC_FATAL_PHASE2_ERROR;
@@ -885,8 +885,11 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
885885
return result;
886886
}
887887

888-
static uint64_t ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation,
889-
void* valuep) {
888+
// Only used in _LIBUNWIND_TRACE_API, which is a no-op when assertions are
889+
// disabled.
890+
[[gnu::unused]] static uint64_t
891+
ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation,
892+
const void *valuep) {
890893
uint64_t value = 0;
891894
switch (representation) {
892895
case _UVRSD_UINT32:

system/lib/libunwind/src/Unwind-seh.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,20 @@ __libunwind_seh_personality(int version, _Unwind_Action state,
212212
ms_exc.ExceptionInformation[2] = state;
213213
DISPATCHER_CONTEXT *disp_ctx =
214214
__unw_seh_get_disp_ctx((unw_cursor_t *)context);
215+
_LIBUNWIND_TRACE_UNWINDING("__libunwind_seh_personality() calling "
216+
"LanguageHandler %p(%p, %p, %p, %p)",
217+
(void *)disp_ctx->LanguageHandler, (void *)&ms_exc,
218+
(void *)disp_ctx->EstablisherFrame,
219+
(void *)disp_ctx->ContextRecord, (void *)disp_ctx);
215220
EXCEPTION_DISPOSITION ms_act = disp_ctx->LanguageHandler(&ms_exc,
216221
(PVOID)disp_ctx->EstablisherFrame,
217222
disp_ctx->ContextRecord,
218223
disp_ctx);
224+
_LIBUNWIND_TRACE_UNWINDING("__libunwind_seh_personality() LanguageHandler "
225+
"returned %d",
226+
(int)ms_act);
219227
switch (ms_act) {
228+
case ExceptionContinueExecution: return _URC_END_OF_STACK;
220229
case ExceptionContinueSearch: return _URC_CONTINUE_UNWIND;
221230
case 4 /*ExceptionExecuteHandler*/:
222231
return phase2 ? _URC_INSTALL_CONTEXT : _URC_HANDLER_FOUND;
@@ -238,7 +247,7 @@ unwind_phase2_forced(unw_context_t *uc,
238247
// Update info about this frame.
239248
unw_proc_info_t frameInfo;
240249
if (__unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) {
241-
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_step "
250+
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_get_proc_info "
242251
"failed => _URC_END_OF_STACK",
243252
(void *)exception_object);
244253
return _URC_FATAL_PHASE2_ERROR;
@@ -304,6 +313,12 @@ unwind_phase2_forced(unw_context_t *uc,
304313
// We may get control back if landing pad calls _Unwind_Resume().
305314
__unw_resume(&cursor2);
306315
break;
316+
case _URC_END_OF_STACK:
317+
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
318+
"personality returned "
319+
"_URC_END_OF_STACK",
320+
(void *)exception_object);
321+
break;
307322
default:
308323
// Personality routine returned an unknown result code.
309324
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
@@ -312,6 +327,8 @@ unwind_phase2_forced(unw_context_t *uc,
312327
(void *)exception_object, personalityResult);
313328
return _URC_FATAL_PHASE2_ERROR;
314329
}
330+
if (personalityResult == _URC_END_OF_STACK)
331+
break;
315332
}
316333
}
317334

system/lib/libunwind/src/UnwindCursor.hpp

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
#endif
3232

3333
#if defined(_LIBUNWIND_TARGET_LINUX) && \
34-
(defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_S390X))
34+
(defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_RISCV) || \
35+
defined(_LIBUNWIND_TARGET_S390X))
3536
#include <sys/syscall.h>
3637
#include <sys/uio.h>
3738
#include <unistd.h>
@@ -506,7 +507,14 @@ class UnwindCursor : public AbstractUnwindCursor {
506507
#endif
507508

508509
DISPATCHER_CONTEXT *getDispatcherContext() { return &_dispContext; }
509-
void setDispatcherContext(DISPATCHER_CONTEXT *disp) { _dispContext = *disp; }
510+
void setDispatcherContext(DISPATCHER_CONTEXT *disp) {
511+
_dispContext = *disp;
512+
_info.lsda = reinterpret_cast<unw_word_t>(_dispContext.HandlerData);
513+
if (_dispContext.LanguageHandler) {
514+
_info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality);
515+
} else
516+
_info.handler = 0;
517+
}
510518

511519
// libunwind does not and should not depend on C++ library which means that we
512520
// need our own definition of inline placement new.
@@ -568,10 +576,12 @@ UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
568576
"UnwindCursor<> requires more alignment than unw_cursor_t");
569577
memset(&_info, 0, sizeof(_info));
570578
memset(&_histTable, 0, sizeof(_histTable));
579+
memset(&_dispContext, 0, sizeof(_dispContext));
571580
_dispContext.ContextRecord = &_msContext;
572581
_dispContext.HistoryTable = &_histTable;
573582
// Initialize MS context from ours.
574583
R r(context);
584+
RtlCaptureContext(&_msContext);
575585
_msContext.ContextFlags = CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_FLOATING_POINT;
576586
#if defined(_LIBUNWIND_TARGET_X86_64)
577587
_msContext.Rax = r.getRegister(UNW_X86_64_RAX);
@@ -669,6 +679,7 @@ UnwindCursor<A, R>::UnwindCursor(CONTEXT *context, A &as)
669679
"UnwindCursor<> does not fit in unw_cursor_t");
670680
memset(&_info, 0, sizeof(_info));
671681
memset(&_histTable, 0, sizeof(_histTable));
682+
memset(&_dispContext, 0, sizeof(_dispContext));
672683
_dispContext.ContextRecord = &_msContext;
673684
_dispContext.HistoryTable = &_histTable;
674685
_msContext = *context;
@@ -679,7 +690,7 @@ template <typename A, typename R>
679690
bool UnwindCursor<A, R>::validReg(int regNum) {
680691
if (regNum == UNW_REG_IP || regNum == UNW_REG_SP) return true;
681692
#if defined(_LIBUNWIND_TARGET_X86_64)
682-
if (regNum >= UNW_X86_64_RAX && regNum <= UNW_X86_64_R15) return true;
693+
if (regNum >= UNW_X86_64_RAX && regNum <= UNW_X86_64_RIP) return true;
683694
#elif defined(_LIBUNWIND_TARGET_ARM)
684695
if ((regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15) ||
685696
regNum == UNW_ARM_RA_AUTH_CODE)
@@ -694,6 +705,7 @@ template <typename A, typename R>
694705
unw_word_t UnwindCursor<A, R>::getReg(int regNum) {
695706
switch (regNum) {
696707
#if defined(_LIBUNWIND_TARGET_X86_64)
708+
case UNW_X86_64_RIP:
697709
case UNW_REG_IP: return _msContext.Rip;
698710
case UNW_X86_64_RAX: return _msContext.Rax;
699711
case UNW_X86_64_RDX: return _msContext.Rdx;
@@ -744,6 +756,7 @@ template <typename A, typename R>
744756
void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) {
745757
switch (regNum) {
746758
#if defined(_LIBUNWIND_TARGET_X86_64)
759+
case UNW_X86_64_RIP:
747760
case UNW_REG_IP: _msContext.Rip = value; break;
748761
case UNW_X86_64_RAX: _msContext.Rax = value; break;
749762
case UNW_X86_64_RDX: _msContext.Rdx = value; break;
@@ -981,6 +994,10 @@ class UnwindCursor : public AbstractUnwindCursor{
981994
bool setInfoForSigReturn(Registers_arm64 &);
982995
int stepThroughSigReturn(Registers_arm64 &);
983996
#endif
997+
#if defined(_LIBUNWIND_TARGET_RISCV)
998+
bool setInfoForSigReturn(Registers_riscv &);
999+
int stepThroughSigReturn(Registers_riscv &);
1000+
#endif
9841001
#if defined(_LIBUNWIND_TARGET_S390X)
9851002
bool setInfoForSigReturn(Registers_s390x &);
9861003
int stepThroughSigReturn(Registers_s390x &);
@@ -1978,6 +1995,9 @@ bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) {
19781995
uint32_t lastcode = (xdata->CountOfCodes + 1) & ~1;
19791996
const uint32_t *handler = reinterpret_cast<uint32_t *>(&xdata->UnwindCodes[lastcode]);
19801997
_info.lsda = reinterpret_cast<unw_word_t>(handler+1);
1998+
_dispContext.HandlerData = reinterpret_cast<void *>(_info.lsda);
1999+
_dispContext.LanguageHandler =
2000+
reinterpret_cast<EXCEPTION_ROUTINE *>(base + *handler);
19812001
if (*handler) {
19822002
_info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality);
19832003
} else
@@ -2705,6 +2725,60 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) {
27052725
#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
27062726
// defined(_LIBUNWIND_TARGET_AARCH64)
27072727

2728+
#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \
2729+
defined(_LIBUNWIND_TARGET_RISCV)
2730+
template <typename A, typename R>
2731+
bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_riscv &) {
2732+
const pint_t pc = static_cast<pint_t>(getReg(UNW_REG_IP));
2733+
uint32_t instructions[2];
2734+
struct iovec local_iov = {&instructions, sizeof instructions};
2735+
struct iovec remote_iov = {reinterpret_cast<void *>(pc), sizeof instructions};
2736+
long bytesRead =
2737+
syscall(SYS_process_vm_readv, getpid(), &local_iov, 1, &remote_iov, 1, 0);
2738+
// Look for the two instructions used in the sigreturn trampoline
2739+
// __vdso_rt_sigreturn:
2740+
//
2741+
// 0x08b00893 li a7,0x8b
2742+
// 0x00000073 ecall
2743+
if (bytesRead != sizeof instructions || instructions[0] != 0x08b00893 ||
2744+
instructions[1] != 0x00000073)
2745+
return false;
2746+
2747+
_info = {};
2748+
_info.start_ip = pc;
2749+
_info.end_ip = pc + 4;
2750+
_isSigReturn = true;
2751+
return true;
2752+
}
2753+
2754+
template <typename A, typename R>
2755+
int UnwindCursor<A, R>::stepThroughSigReturn(Registers_riscv &) {
2756+
// In the signal trampoline frame, sp points to an rt_sigframe[1], which is:
2757+
// - 128-byte siginfo struct
2758+
// - ucontext_t struct:
2759+
// - 8-byte long (__uc_flags)
2760+
// - 8-byte pointer (*uc_link)
2761+
// - 24-byte uc_stack
2762+
// - 8-byte uc_sigmask
2763+
// - 120-byte of padding to allow sigset_t to be expanded in the future
2764+
// - 8 bytes of padding because sigcontext has 16-byte alignment
2765+
// - struct sigcontext uc_mcontext
2766+
// [1]
2767+
// https://github.com/torvalds/linux/blob/master/arch/riscv/kernel/signal.c
2768+
const pint_t kOffsetSpToSigcontext = 128 + 8 + 8 + 24 + 8 + 128;
2769+
2770+
const pint_t sigctx = _registers.getSP() + kOffsetSpToSigcontext;
2771+
_registers.setIP(_addressSpace.get64(sigctx));
2772+
for (int i = UNW_RISCV_X1; i <= UNW_RISCV_X31; ++i) {
2773+
uint64_t value = _addressSpace.get64(sigctx + static_cast<pint_t>(i * 8));
2774+
_registers.setRegister(i, value);
2775+
}
2776+
_isSignalFrame = true;
2777+
return UNW_STEP_SUCCESS;
2778+
}
2779+
#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
2780+
// defined(_LIBUNWIND_TARGET_RISCV)
2781+
27082782
#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \
27092783
defined(_LIBUNWIND_TARGET_S390X)
27102784
template <typename A, typename R>

system/lib/libunwind/src/UnwindLevel1-gcc-ext.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) {
167167
}
168168

169169
// Update the pr_cache in the mock exception object.
170-
const uint32_t* unwindInfo = (uint32_t *) frameInfo.unwind_info;
170+
uint32_t *unwindInfo = (uint32_t *)frameInfo.unwind_info;
171171
ex.pr_cache.fnstart = frameInfo.start_ip;
172172
ex.pr_cache.ehtp = (_Unwind_EHT_Header *) unwindInfo;
173173
ex.pr_cache.additional= frameInfo.flags;

system/lib/libunwind/src/UnwindLevel1.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
321321
unw_proc_info_t frameInfo;
322322
if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
323323
_LIBUNWIND_TRACE_UNWINDING(
324-
"unwind_phase2_forced(ex_obj=%p): __unw_step_stage2 "
324+
"unwind_phase2_forced(ex_obj=%p): __unw_get_proc_info "
325325
"failed => _URC_END_OF_STACK",
326326
(void *)exception_object);
327327
return _URC_FATAL_PHASE2_ERROR;

0 commit comments

Comments
 (0)