Skip to content
Merged
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
3 changes: 1 addition & 2 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ See docs/process.md for more on how version tagging works.
FS-backend handler signature changed from `poll(stream, timeout)` to
`poll(stream)` returning the current readiness mask; out-of-tree custom FS
backends with a `poll` handler must update. (#27226)
- compiler-rt was updated to LLVM 22.1.8. (#27245)
- compiler-rt and libunwind were updated to LLVM 22.1.8. (#27245, #27246)

6.0.2 - 07/01/26
----------------
Expand Down Expand Up @@ -272,7 +272,6 @@ See docs/process.md for more on how version tagging works.
21.1.8. (#26036, #26045, #26058, and #26151)
- Calling pthread_create in a single-threaded build will now return ENOTSUP
rather then EAGAIN. (#26105)
- compiler-rt and libunwind were updated to LLVM 21.1.8. (#26036 and #26045)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drive-by fix: This was also in line 271 so not necessary

- A new `-sEXECUTABLE` setting was added which adds a #! line to the resulting
JavaScript and makes it executable. This setting defaults to true when the
output filename has no extension, or ends in `.out` (e.g. `a.out`) (#26085)
Expand Down
13 changes: 11 additions & 2 deletions system/lib/libunwind/include/__libunwind_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC
# elif defined(__aarch64__)
# define _LIBUNWIND_TARGET_AARCH64 1
# define _LIBUNWIND_CONTEXT_SIZE 66
#define _LIBUNWIND_CONTEXT_SIZE 67
# if defined(__SEH__)
# define _LIBUNWIND_CURSOR_SIZE 164
# else
# define _LIBUNWIND_CURSOR_SIZE 78
#define _LIBUNWIND_CURSOR_SIZE 79
# endif
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64
# elif defined(__arm__)
Expand Down Expand Up @@ -212,4 +212,13 @@
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287
#endif // _LIBUNWIND_IS_NATIVE_ONLY

#if defined(__has_feature)
# if __has_feature(ptrauth_calls) && __has_feature(ptrauth_returns)
# define _LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING 1
# elif __has_feature(ptrauth_calls) != __has_feature(ptrauth_returns)
# error "Either both or none of ptrauth_calls and ptrauth_returns "\
"is allowed to be enabled"
# endif
#endif

#endif // ____LIBUNWIND_CONFIG_H__
128 changes: 117 additions & 11 deletions system/lib/libunwind/include/libunwind.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,109 @@
#define LIBUNWIND_AVAIL
#endif

#if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)

#include <ptrauth.h>

// `__ptrauth_restricted_intptr` is a feature of apple clang that predates
// support for direct application of `__ptrauth` to integer types. This
// guard is necessary to support compilation with those compiler.
#if __has_extension(ptrauth_restricted_intptr_qualifier)
#define __unwind_ptrauth_restricted_intptr(...) \
__ptrauth_restricted_intptr(__VA_ARGS__)
#else
#define __unwind_ptrauth_restricted_intptr(...) \
__ptrauth(__VA_ARGS__)
#endif

// ptrauth_string_discriminator("unw_proc_info_t::handler") == 0x7405
#define __ptrauth_unwind_upi_handler_disc 0x7405

#define __ptrauth_unwind_upi_handler \
__ptrauth(ptrauth_key_function_pointer, 1, __ptrauth_unwind_upi_handler_disc)

#define __ptrauth_unwind_upi_handler_intptr \
__unwind_ptrauth_restricted_intptr(ptrauth_key_function_pointer, 1,\
__ptrauth_unwind_upi_handler_disc)

// ptrauth_string_discriminator("unw_proc_info_t::start_ip") == 0xCA2C
#define __ptrauth_unwind_upi_startip \
__unwind_ptrauth_restricted_intptr(ptrauth_key_process_independent_code, 1, 0xCA2C)

// ptrauth_string_discriminator("unw_proc_info_t::end_ip") == 0xE183
#define __ptrauth_unwind_upi_endip \
__unwind_ptrauth_restricted_intptr(ptrauth_key_process_independent_code, 1, 0xE183)

// ptrauth_string_discriminator("unw_proc_info_t::lsda") == 0x83DE
#define __ptrauth_unwind_upi_lsda \
__unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, 0x83DE)

// ptrauth_string_discriminator("unw_proc_info_t::flags") == 0x79A1
#define __ptrauth_unwind_upi_flags \
__unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, 0x79A1)

// ptrauth_string_discriminator("unw_proc_info_t::unwind_info") == 0xC20C
#define __ptrauth_unwind_upi_info \
__unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, 0xC20C)

// ptrauth_string_discriminator("unw_proc_info_t::extra") == 0x03DF
#define __ptrauth_unwind_upi_extra \
__unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, 0x03DF)

// ptrauth_string_discriminator("Registers_arm64::link_reg_t") == 0x8301
#define __ptrauth_unwind_registers_arm64_link_reg \
__unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_code, 1, 0x8301)

// ptrauth_string_discriminator("UnwindInfoSections::dso_base") == 0x4FF5
#define __ptrauth_unwind_uis_dso_base \
__unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, 0x4FF5)

// ptrauth_string_discriminator("UnwindInfoSections::dwarf_section") == 0x4974
#define __ptrauth_unwind_uis_dwarf_section \
__unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, 0x4974)

// ptrauth_string_discriminator("UnwindInfoSections::dwarf_section_length") == 0x2A9A
#define __ptrauth_unwind_uis_dwarf_section_length \
__unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, 0x2A9A)

// ptrauth_string_discriminator("UnwindInfoSections::compact_unwind_section") == 0xA27B
#define __ptrauth_unwind_uis_compact_unwind_section \
__unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, 0xA27B)

// ptrauth_string_discriminator("UnwindInfoSections::compact_unwind_section_length") == 0x5D0A
#define __ptrauth_unwind_uis_compact_unwind_section_length \
__unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, 0x5D0A)

// ptrauth_string_discriminator("CIE_Info::personality") == 0x6A40
#define __ptrauth_unwind_cie_info_personality_disc 0x6A40
#define __ptrauth_unwind_cie_info_personality \
__unwind_ptrauth_restricted_intptr(ptrauth_key_function_pointer, 1, \
__ptrauth_unwind_cie_info_personality_disc)

// ptrauth_string_discriminator("personality") == 0x7EAD)
#define __ptrauth_unwind_pauthtest_personality_disc 0x7EAD

#else

#define __unwind_ptrauth_restricted_intptr(...)
#define __ptrauth_unwind_upi_handler
#define __ptrauth_unwind_upi_handler_intptr
#define __ptrauth_unwind_upi_startip
#define __ptrauth_unwind_upi_endip
#define __ptrauth_unwind_upi_lsda
#define __ptrauth_unwind_upi_flags
#define __ptrauth_unwind_upi_info
#define __ptrauth_unwind_upi_extra
#define __ptrauth_unwind_registers_arm64_link_reg
#define __ptrauth_unwind_uis_dso_base
#define __ptrauth_unwind_uis_dwarf_section
#define __ptrauth_unwind_uis_dwarf_section_length
#define __ptrauth_unwind_uis_compact_unwind_section
#define __ptrauth_unwind_uis_compact_unwind_section_length
#define __ptrauth_unwind_cie_info_personality

#endif

#if defined(_WIN32) && defined(__SEH__)
#define LIBUNWIND_CURSOR_ALIGNMENT_ATTR __attribute__((__aligned__(16)))
#else
Expand Down Expand Up @@ -88,17 +191,18 @@ typedef double unw_fpreg_t;
#endif

struct unw_proc_info_t {
unw_word_t start_ip; /* start address of function */
unw_word_t end_ip; /* address after end of function */
unw_word_t lsda; /* address of language specific data area, */
/* or zero if not used */
unw_word_t handler; /* personality routine, or zero if not used */
unw_word_t gp; /* not used */
unw_word_t flags; /* not used */
uint32_t format; /* compact unwind encoding, or zero if none */
uint32_t unwind_info_size; /* size of DWARF unwind info, or zero if none */
unw_word_t unwind_info; /* address of DWARF unwind info, or zero */
unw_word_t extra; /* mach_header of mach-o image containing func */
unw_word_t __ptrauth_unwind_upi_startip start_ip; /* start address of function */
unw_word_t __ptrauth_unwind_upi_endip end_ip; /* address after end of function */
unw_word_t __ptrauth_unwind_upi_lsda lsda; /* address of language specific data area, */
/* or zero if not used */

unw_word_t __ptrauth_unwind_upi_handler_intptr handler;
unw_word_t gp; /* not used */
unw_word_t __ptrauth_unwind_upi_flags flags; /* not used */
uint32_t format; /* compact unwind encoding, or zero if none */
uint32_t unwind_info_size; /* size of DWARF unwind info, or zero if none */
unw_word_t __ptrauth_unwind_upi_info unwind_info; /* address of DWARF unwind info, or zero */
unw_word_t __ptrauth_unwind_upi_extra extra; /* mach_header of mach-o image containing func */
};
typedef struct unw_proc_info_t unw_proc_info_t;

Expand Down Expand Up @@ -130,6 +234,7 @@ extern int unw_is_fpreg(unw_cursor_t *, unw_regnum_t) LIBUNWIND_AVAIL;
extern int unw_is_signal_frame(unw_cursor_t *) LIBUNWIND_AVAIL;
extern int unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *) LIBUNWIND_AVAIL;
//extern int unw_get_save_loc(unw_cursor_t*, int, unw_save_loc_t*);
extern const char *unw_strerror(int) LIBUNWIND_AVAIL;

extern unw_addr_space_t unw_local_addr_space;

Expand Down Expand Up @@ -532,6 +637,7 @@ enum {
UNW_AARCH64_X31 = 31,
UNW_AARCH64_SP = 31,
UNW_AARCH64_PC = 32,
UNW_AARCH64_VG = 46,

// reserved block
UNW_AARCH64_RA_SIGN_STATE = 34,
Expand Down
5 changes: 4 additions & 1 deletion system/lib/libunwind/include/unwind_arm_ehabi.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,11 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
uint32_t discriminator,
_Unwind_VRS_DataRepresentation representation);

extern _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Exception *,
_Unwind_Context *);

#if defined(_LIBUNWIND_UNWIND_LEVEL1_EXTERNAL_LINKAGE)
#define _LIBUNWIND_EXPORT_UNWIND_LEVEL1 extern
#define _LIBUNWIND_EXPORT_UNWIND_LEVEL1 extern __inline__
#else
#define _LIBUNWIND_EXPORT_UNWIND_LEVEL1 static __inline__
#endif
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 21.1.8.
These files are from the llvm-project based on release 22.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-21 branch.
The current patch is based on the emscripten-libs-22 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-21.1.8...emscripten-core:emscripten-libs-21
https://github.com/llvm/llvm-project/compare/llvmorg-22.1.8...emscripten-core:emscripten-libs-22
61 changes: 41 additions & 20 deletions system/lib/libunwind/src/AddressSpace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,22 +129,27 @@ struct UnwindInfoSections {
defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) || \
defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
// No dso_base for SEH.
uintptr_t dso_base;
uintptr_t __ptrauth_unwind_uis_dso_base
dso_base = 0;
#endif
#if defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
size_t text_segment_length;
#endif
#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
uintptr_t dwarf_section;
size_t dwarf_section_length;
uintptr_t __ptrauth_unwind_uis_dwarf_section
dwarf_section = 0;
size_t __ptrauth_unwind_uis_dwarf_section_length
dwarf_section_length = 0;
#endif
#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
uintptr_t dwarf_index_section;
size_t dwarf_index_section_length;
#endif
#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
uintptr_t compact_unwind_section;
size_t compact_unwind_section_length;
uintptr_t __ptrauth_unwind_uis_compact_unwind_section
compact_unwind_section = 0;
size_t __ptrauth_unwind_uis_compact_unwind_section_length
compact_unwind_section_length = 0;
#endif
#if defined(_LIBUNWIND_ARM_EHABI)
uintptr_t arm_section;
Expand Down Expand Up @@ -196,11 +201,16 @@ class _LIBUNWIND_HIDDEN LocalAddressSpace {
static int64_t getSLEB128(pint_t &addr, pint_t end);

pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
pint_t datarelBase = 0);
bool findFunctionName(pint_t addr, char *buf, size_t bufLen,
unw_word_t *offset);
bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info);
bool findOtherFDE(pint_t targetAddr, pint_t &fde);
pint_t datarelBase = 0, pint_t *resultAddr = nullptr);
template <typename R>
bool findFunctionName(typename R::link_hardened_reg_arg_t addr, char *buf,
size_t bufLen, unw_word_t *offset);
template <typename R>
bool findUnwindSections(typename R::link_hardened_reg_arg_t targetAddr,
UnwindInfoSections &info);
template <typename R>
bool findOtherFDE(typename R::link_hardened_reg_arg_t targetAddr,
pint_t &fde);

static LocalAddressSpace sThisAddressSpace;
};
Expand Down Expand Up @@ -269,7 +279,7 @@ inline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) {

inline LocalAddressSpace::pint_t
LocalAddressSpace::getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
pint_t datarelBase) {
pint_t datarelBase, pint_t *resultAddr) {
pint_t startAddr = addr;
const uint8_t *p = (uint8_t *)addr;
pint_t result;
Expand Down Expand Up @@ -353,8 +363,14 @@ LocalAddressSpace::getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
break;
}

if (encoding & DW_EH_PE_indirect)
if (encoding & DW_EH_PE_indirect) {
if (resultAddr)
*resultAddr = result;
result = getP(result);
} else {
if (resultAddr)
*resultAddr = startAddr;
}

return result;
}
Expand Down Expand Up @@ -486,9 +502,9 @@ static int findUnwindSectionsByPhdr(struct dl_phdr_info *pinfo,

#endif // defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)


inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
UnwindInfoSections &info) {
template <typename R>
inline bool LocalAddressSpace::findUnwindSections(
typename R::link_hardened_reg_arg_t targetAddr, UnwindInfoSections &info) {
#ifdef __APPLE__
dyld_unwind_sections dyldInfo;
if (_dyld_find_unwind_sections((void *)targetAddr, &dyldInfo)) {
Expand Down Expand Up @@ -650,24 +666,29 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
return true;
}
#endif
dl_iterate_cb_data cb_data = {this, &info, targetAddr};
dl_iterate_cb_data cb_data = {this, &info, static_cast<pint_t>(targetAddr)};
int found = dl_iterate_phdr(findUnwindSectionsByPhdr, &cb_data);
return static_cast<bool>(found);
#endif

return false;
}

inline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) {
template <typename R>
inline bool
LocalAddressSpace::findOtherFDE(typename R::link_hardened_reg_arg_t targetAddr,
pint_t &fde) {
// TO DO: if OS has way to dynamically register FDEs, check that.
(void)targetAddr;
(void)fde;
return false;
}

inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf,
size_t bufLen,
unw_word_t *offset) {
template <typename R>
inline bool
LocalAddressSpace::findFunctionName(typename R::link_hardened_reg_arg_t addr,
char *buf, size_t bufLen,
unw_word_t *offset) {
#if _LIBUNWIND_USE_DLADDR
Dl_info dyldInfo;
if (dladdr((void *)addr, &dyldInfo)) {
Expand Down
Loading