authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-04-26 14:40:08-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-05-08 19:37:29-07:00
log6295415da72eb17b263494a070fdf957e89460fb
tree308c2c6341b137085dd9dc20168e2509572c2216
parenta6856ef6d21635641320761a8f17205fd6e99fa9

libunwind: update to LLVM 18

release/18.x branch, commit 78b99c73ee4b96fe9ce0e294d4632326afb2db42

17 files changed, 389 insertions(+), 128 deletions(-)

lib/libunwind/include/__libunwind_config.h+4-1
......@@ -36,6 +36,9 @@
3636# if defined(__linux__)
3737# define _LIBUNWIND_TARGET_LINUX 1
3838# endif
39# if defined(__HAIKU__)
40# define _LIBUNWIND_TARGET_HAIKU 1
41# endif
3942# if defined(__i386__)
4043# define _LIBUNWIND_TARGET_I386
4144# define _LIBUNWIND_CONTEXT_SIZE 8
......@@ -196,7 +199,7 @@
196199# define _LIBUNWIND_TARGET_RISCV 1
197200# define _LIBUNWIND_TARGET_VE 1
198201# define _LIBUNWIND_TARGET_S390X 1
199 #define _LIBUNWIND_TARGET_LOONGARCH 1
202# define _LIBUNWIND_TARGET_LOONGARCH 1
200203# define _LIBUNWIND_CONTEXT_SIZE 167
201204# define _LIBUNWIND_CURSOR_SIZE 204
202205# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287
lib/libunwind/include/libunwind.h+3
......@@ -876,6 +876,9 @@ enum {
876876 UNW_MIPS_F29 = 61,
877877 UNW_MIPS_F30 = 62,
878878 UNW_MIPS_F31 = 63,
879 // HI,LO have been dropped since r6, we keep them here.
880 // So, when we add DSP/MSA etc, we can use the same register indexes
881 // for r6 and pre-r6.
879882 UNW_MIPS_HI = 64,
880883 UNW_MIPS_LO = 65,
881884};
lib/libunwind/include/mach-o/compact_unwind_encoding.h+40-40
......@@ -108,7 +108,7 @@ enum {
108108// are encoded in the UNWIND_X86_EBP_FRAME_REGISTERS bits as five 3-bit entries.
109109// Each entry contains which register to restore.
110110// UNWIND_X86_MODE_STACK_IMMD:
111// A "frameless" (EBP not used as frame pointer) function with a small
111// A "frameless" (EBP not used as frame pointer) function with a small
112112// constant stack size. To return, a constant (encoded in the compact
113113// unwind encoding) is added to the ESP. Then the return is done by
114114// popping the stack into the pc.
......@@ -119,16 +119,16 @@ enum {
119119// UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION contains which registers were
120120// saved and their order.
121121// UNWIND_X86_MODE_STACK_IND:
122// A "frameless" (EBP not used as frame pointer) function large constant
122// A "frameless" (EBP not used as frame pointer) function large constant
123123// stack size. This case is like the previous, except the stack size is too
124// large to encode in the compact unwind encoding. Instead it requires that
125// the function contains "subl $nnnnnnnn,ESP" in its prolog. The compact
124// large to encode in the compact unwind encoding. Instead it requires that
125// the function contains "subl $nnnnnnnn,ESP" in its prolog. The compact
126126// encoding contains the offset to the nnnnnnnn value in the function in
127// UNWIND_X86_FRAMELESS_STACK_SIZE.
127// UNWIND_X86_FRAMELESS_STACK_SIZE.
128128// UNWIND_X86_MODE_DWARF:
129129// No compact unwind encoding is available. Instead the low 24-bits of the
130130// compact encoding is the offset of the DWARF FDE in the __eh_frame section.
131// This mode is never used in object files. It is only generated by the
131// This mode is never used in object files. It is only generated by the
132132// linker in final linked images which have only DWARF unwind info for a
133133// function.
134134//
......@@ -233,36 +233,36 @@ enum {
233233// For x86_64 there are four modes for the compact unwind encoding:
234234// UNWIND_X86_64_MODE_RBP_FRAME:
235235// RBP based frame where RBP is push on stack immediately after return address,
236// then RSP is moved to RBP. Thus, to unwind RSP is restored with the current
237// EPB value, then RBP is restored by popping off the stack, and the return
236// then RSP is moved to RBP. Thus, to unwind RSP is restored with the current
237// EPB value, then RBP is restored by popping off the stack, and the return
238238// is done by popping the stack once more into the pc.
239239// All non-volatile registers that need to be restored must have been saved
240// in a small range in the stack that starts RBP-8 to RBP-2040. The offset/8
240// in a small range in the stack that starts RBP-8 to RBP-2040. The offset/8
241241// is encoded in the UNWIND_X86_64_RBP_FRAME_OFFSET bits. The registers saved
242242// are encoded in the UNWIND_X86_64_RBP_FRAME_REGISTERS bits as five 3-bit entries.
243// Each entry contains which register to restore.
243// Each entry contains which register to restore.
244244// UNWIND_X86_64_MODE_STACK_IMMD:
245// A "frameless" (RBP not used as frame pointer) function with a small
246// constant stack size. To return, a constant (encoded in the compact
247// unwind encoding) is added to the RSP. Then the return is done by
245// A "frameless" (RBP not used as frame pointer) function with a small
246// constant stack size. To return, a constant (encoded in the compact
247// unwind encoding) is added to the RSP. Then the return is done by
248248// popping the stack into the pc.
249249// All non-volatile registers that need to be restored must have been saved
250250// on the stack immediately after the return address. The stack_size/8 is
251251// encoded in the UNWIND_X86_64_FRAMELESS_STACK_SIZE (max stack size is 2048).
252252// The number of registers saved is encoded in UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT.
253253// UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION contains which registers were
254// saved and their order.
254// saved and their order.
255255// UNWIND_X86_64_MODE_STACK_IND:
256// A "frameless" (RBP not used as frame pointer) function large constant
256// A "frameless" (RBP not used as frame pointer) function large constant
257257// stack size. This case is like the previous, except the stack size is too
258// large to encode in the compact unwind encoding. Instead it requires that
259// the function contains "subq $nnnnnnnn,RSP" in its prolog. The compact
258// large to encode in the compact unwind encoding. Instead it requires that
259// the function contains "subq $nnnnnnnn,RSP" in its prolog. The compact
260260// encoding contains the offset to the nnnnnnnn value in the function in
261// UNWIND_X86_64_FRAMELESS_STACK_SIZE.
261// UNWIND_X86_64_FRAMELESS_STACK_SIZE.
262262// UNWIND_X86_64_MODE_DWARF:
263263// No compact unwind encoding is available. Instead the low 24-bits of the
264264// compact encoding is the offset of the DWARF FDE in the __eh_frame section.
265// This mode is never used in object files. It is only generated by the
265// This mode is never used in object files. It is only generated by the
266266// linker in final linked images which have only DWARF unwind info for a
267267// function.
268268//
......@@ -307,20 +307,20 @@ enum {
307307// This is a standard arm64 prolog where FP/LR are immediately pushed on the
308308// stack, then SP is copied to FP. If there are any non-volatile registers
309309// saved, then are copied into the stack frame in pairs in a contiguous
310// range right below the saved FP/LR pair. Any subset of the five X pairs
310// range right below the saved FP/LR pair. Any subset of the five X pairs
311311// and four D pairs can be saved, but the memory layout must be in register
312// number order.
312// number order.
313313// UNWIND_ARM64_MODE_FRAMELESS:
314// A "frameless" leaf function, where FP/LR are not saved. The return address
314// A "frameless" leaf function, where FP/LR are not saved. The return address
315315// remains in LR throughout the function. If any non-volatile registers
316316// are saved, they must be pushed onto the stack before any stack space is
317317// allocated for local variables. The stack sized (including any saved
318// non-volatile registers) divided by 16 is encoded in the bits
318// non-volatile registers) divided by 16 is encoded in the bits
319319// UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK.
320320// UNWIND_ARM64_MODE_DWARF:
321321// No compact unwind encoding is available. Instead the low 24-bits of the
322322// compact encoding is the offset of the DWARF FDE in the __eh_frame section.
323// This mode is never used in object files. It is only generated by the
323// This mode is never used in object files. It is only generated by the
324324// linker in final linked images which have only DWARF unwind info for a
325325// function.
326326//
......@@ -337,19 +337,19 @@ enum {
337337
338338//
339339// A compiler can generated compact unwind information for a function by adding
340// a "row" to the __LD,__compact_unwind section. This section has the
341// S_ATTR_DEBUG bit set, so the section will be ignored by older linkers.
342// It is removed by the new linker, so never ends up in final executables.
343// This section is a table, initially with one row per function (that needs
340// a "row" to the __LD,__compact_unwind section. This section has the
341// S_ATTR_DEBUG bit set, so the section will be ignored by older linkers.
342// It is removed by the new linker, so never ends up in final executables.
343// This section is a table, initially with one row per function (that needs
344344// unwind info). The table columns and some conceptual entries are:
345345//
346346// range-start pointer to start of function/range
347// range-length
348// compact-unwind-encoding 32-bit encoding
347// range-length
348// compact-unwind-encoding 32-bit encoding
349349// personality-function or zero if no personality function
350350// lsda or zero if no LSDA data
351351//
352// The length and encoding fields are 32-bits. The other are all pointer sized.
352// The length and encoding fields are 32-bits. The other are all pointer sized.
353353//
354354// In x86_64 assembly, these entry would look like:
355355//
......@@ -372,23 +372,23 @@ enum {
372372// .quad except_tab1
373373//
374374//
375// Notes: There is no need for any labels in the the __compact_unwind section.
376// The use of the .set directive is to force the evaluation of the
375// Notes: There is no need for any labels in the __compact_unwind section.
376// The use of the .set directive is to force the evaluation of the
377377// range-length at assembly time, instead of generating relocations.
378378//
379// To support future compiler optimizations where which non-volatile registers
379// To support future compiler optimizations where which non-volatile registers
380380// are saved changes within a function (e.g. delay saving non-volatiles until
381381// necessary), there can by multiple lines in the __compact_unwind table for one
382// function, each with a different (non-overlapping) range and each with
383// different compact unwind encodings that correspond to the non-volatiles
382// function, each with a different (non-overlapping) range and each with
383// different compact unwind encodings that correspond to the non-volatiles
384384// saved at that range of the function.
385385//
386386// If a particular function is so wacky that there is no compact unwind way
387// to encode it, then the compiler can emit traditional DWARF unwind info.
387// to encode it, then the compiler can emit traditional DWARF unwind info.
388388// The runtime will use which ever is available.
389389//
390// Runtime support for compact unwind encodings are only available on 10.6
391// and later. So, the compiler should not generate it when targeting pre-10.6.
390// Runtime support for compact unwind encodings are only available on 10.6
391// and later. So, the compiler should not generate it when targeting pre-10.6.
392392
393393
394394
......@@ -402,7 +402,7 @@ enum {
402402//
403403// The __TEXT,__unwind_info section is laid out for an efficient two level lookup.
404404// The header of the section contains a coarse index that maps function address
405// to the page (4096 byte block) containing the unwind info for that function.
405// to the page (4096 byte block) containing the unwind info for that function.
406406//
407407
408408#define UNWIND_SECTION_VERSION 1
lib/libunwind/src/AddressSpace.hpp+4-3
......@@ -414,8 +414,8 @@ static bool checkForUnwindInfoSegment(const Elf_Phdr *phdr, size_t image_base,
414414 cbdata->sects->dwarf_index_section = eh_frame_hdr_start;
415415 cbdata->sects->dwarf_index_section_length = phdr->p_memsz;
416416 if (EHHeaderParser<LocalAddressSpace>::decodeEHHdr(
417 *cbdata->addressSpace, eh_frame_hdr_start, phdr->p_memsz,
418 hdrInfo)) {
417 *cbdata->addressSpace, eh_frame_hdr_start,
418 eh_frame_hdr_start + phdr->p_memsz, hdrInfo)) {
419419 // .eh_frame_hdr records the start of .eh_frame, but not its size.
420420 // Rely on a zero terminator to find the end of the section.
421421 cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr;
......@@ -638,7 +638,8 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
638638 info.dwarf_index_section_length = SIZE_MAX;
639639 EHHeaderParser<LocalAddressSpace>::EHHeaderInfo hdrInfo;
640640 if (!EHHeaderParser<LocalAddressSpace>::decodeEHHdr(
641 *this, info.dwarf_index_section, info.dwarf_index_section_length,
641 *this, info.dwarf_index_section,
642 info.dwarf_index_section + info.dwarf_index_section_length,
642643 hdrInfo)) {
643644 return false;
644645 }
lib/libunwind/src/DwarfInstructions.hpp+1-1
......@@ -68,7 +68,7 @@ private:
6868 return (pint_t)((sint_t)registers.getRegister((int)prolog.cfaRegister) +
6969 prolog.cfaRegisterOffset);
7070 if (prolog.cfaExpression != 0)
71 return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace,
71 return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace,
7272 registers, 0);
7373 assert(0 && "getCFA(): unknown location");
7474 __builtin_unreachable();
lib/libunwind/src/EHHeaderParser.hpp+13
......@@ -55,6 +55,19 @@ template <typename A>
5555bool EHHeaderParser<A>::decodeEHHdr(A &addressSpace, pint_t ehHdrStart,
5656 pint_t ehHdrEnd, EHHeaderInfo &ehHdrInfo) {
5757 pint_t p = ehHdrStart;
58
59 // Ensure that we don't read data beyond the end of .eh_frame_hdr
60 if (ehHdrEnd - ehHdrStart < 4) {
61 // Don't print a message for an empty .eh_frame_hdr (this can happen if
62 // the linker script defines symbols for it even in the empty case).
63 if (ehHdrEnd == ehHdrStart)
64 return false;
65 _LIBUNWIND_LOG("unsupported .eh_frame_hdr at %" PRIx64
66 ": need at least 4 bytes of data but only got %zd",
67 static_cast<uint64_t>(ehHdrStart),
68 static_cast<size_t>(ehHdrEnd - ehHdrStart));
69 return false;
70 }
5871 uint8_t version = addressSpace.get8(p++);
5972 if (version != 1) {
6073 _LIBUNWIND_LOG("unsupported .eh_frame_hdr version: %" PRIu8 " at %" PRIx64,
lib/libunwind/src/FrameHeaderCache.hpp+3-3
......@@ -31,8 +31,8 @@
3131
3232class _LIBUNWIND_HIDDEN FrameHeaderCache {
3333 struct CacheEntry {
34 uintptr_t LowPC() { return Info.dso_base; };
35 uintptr_t HighPC() { return Info.dso_base + Info.text_segment_length; };
34 uintptr_t LowPC() { return Info.dso_base; }
35 uintptr_t HighPC() { return Info.dso_base + Info.text_segment_length; }
3636 UnwindInfoSections Info;
3737 CacheEntry *Next;
3838 };
......@@ -41,7 +41,7 @@ class _LIBUNWIND_HIDDEN FrameHeaderCache {
4141
4242 // Can't depend on the C++ standard library in libunwind, so use an array to
4343 // allocate the entries, and two linked lists for ordering unused and recently
44 // used entries. FIXME: Would the the extra memory for a doubly-linked list
44 // used entries. FIXME: Would the extra memory for a doubly-linked list
4545 // be better than the runtime cost of traversing a very short singly-linked
4646 // list on a cache miss? The entries themselves are all small and consecutive,
4747 // so unlikely to cause page faults when following the pointers. The memory
lib/libunwind/src/Registers.hpp+18-2
......@@ -619,6 +619,8 @@ public:
619619 void setIP(uint32_t value) { _registers.__srr0 = value; }
620620 uint64_t getCR() const { return _registers.__cr; }
621621 void setCR(uint32_t value) { _registers.__cr = value; }
622 uint64_t getLR() const { return _registers.__lr; }
623 void setLR(uint32_t value) { _registers.__lr = value; }
622624
623625private:
624626 struct ppc_thread_state_t {
......@@ -1189,6 +1191,8 @@ public:
11891191 void setIP(uint64_t value) { _registers.__srr0 = value; }
11901192 uint64_t getCR() const { return _registers.__cr; }
11911193 void setCR(uint64_t value) { _registers.__cr = value; }
1194 uint64_t getLR() const { return _registers.__lr; }
1195 void setLR(uint64_t value) { _registers.__lr = value; }
11921196
11931197private:
11941198 struct ppc64_thread_state_t {
......@@ -2869,7 +2873,7 @@ inline bool Registers_mips_o32::validRegister(int regNum) const {
28692873 return false;
28702874 if (regNum <= UNW_MIPS_R31)
28712875 return true;
2872#if __mips_isa_rev != 6
2876#if __mips_isa_rev < 6
28732877 if (regNum == UNW_MIPS_HI)
28742878 return true;
28752879 if (regNum == UNW_MIPS_LO)
......@@ -2903,10 +2907,12 @@ inline uint32_t Registers_mips_o32::getRegister(int regNum) const {
29032907 return _registers.__pc;
29042908 case UNW_REG_SP:
29052909 return _registers.__r[29];
2910#if __mips_isa_rev < 6
29062911 case UNW_MIPS_HI:
29072912 return _registers.__hi;
29082913 case UNW_MIPS_LO:
29092914 return _registers.__lo;
2915#endif
29102916 }
29112917 _LIBUNWIND_ABORT("unsupported mips_o32 register");
29122918}
......@@ -2936,11 +2942,13 @@ inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) {
29362942 case UNW_REG_SP:
29372943 _registers.__r[29] = value;
29382944 return;
2945#if __mips_isa_rev < 6
29392946 case UNW_MIPS_HI:
29402947 _registers.__hi = value;
29412948 return;
29422949 case UNW_MIPS_LO:
29432950 _registers.__lo = value;
2951#endif
29442952 return;
29452953 }
29462954 _LIBUNWIND_ABORT("unsupported mips_o32 register");
......@@ -3120,10 +3128,12 @@ inline const char *Registers_mips_o32::getRegisterName(int regNum) {
31203128 return "$f30";
31213129 case UNW_MIPS_F31:
31223130 return "$f31";
3131#if __mips_isa_rev < 6
31233132 case UNW_MIPS_HI:
31243133 return "$hi";
31253134 case UNW_MIPS_LO:
31263135 return "$lo";
3136#endif
31273137 default:
31283138 return "unknown register";
31293139 }
......@@ -3193,7 +3203,7 @@ inline bool Registers_mips_newabi::validRegister(int regNum) const {
31933203 return false;
31943204 if (regNum <= UNW_MIPS_R31)
31953205 return true;
3196#if __mips_isa_rev != 6
3206#if __mips_isa_rev < 6
31973207 if (regNum == UNW_MIPS_HI)
31983208 return true;
31993209 if (regNum == UNW_MIPS_LO)
......@@ -3212,10 +3222,12 @@ inline uint64_t Registers_mips_newabi::getRegister(int regNum) const {
32123222 return _registers.__pc;
32133223 case UNW_REG_SP:
32143224 return _registers.__r[29];
3225#if __mips_isa_rev < 6
32153226 case UNW_MIPS_HI:
32163227 return _registers.__hi;
32173228 case UNW_MIPS_LO:
32183229 return _registers.__lo;
3230#endif
32193231 }
32203232 _LIBUNWIND_ABORT("unsupported mips_newabi register");
32213233}
......@@ -3233,12 +3245,14 @@ inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) {
32333245 case UNW_REG_SP:
32343246 _registers.__r[29] = value;
32353247 return;
3248#if __mips_isa_rev < 6
32363249 case UNW_MIPS_HI:
32373250 _registers.__hi = value;
32383251 return;
32393252 case UNW_MIPS_LO:
32403253 _registers.__lo = value;
32413254 return;
3255#endif
32423256 }
32433257 _LIBUNWIND_ABORT("unsupported mips_newabi register");
32443258}
......@@ -3417,10 +3431,12 @@ inline const char *Registers_mips_newabi::getRegisterName(int regNum) {
34173431 return "$f30";
34183432 case UNW_MIPS_F31:
34193433 return "$f31";
3434#if __mips_isa_rev < 6
34203435 case UNW_MIPS_HI:
34213436 return "$hi";
34223437 case UNW_MIPS_LO:
34233438 return "$lo";
3439#endif
34243440 default:
34253441 return "unknown register";
34263442 }
lib/libunwind/src/Unwind-sjlj.c+6-5
......@@ -82,7 +82,8 @@ struct _Unwind_FunctionContext {
8282static _LIBUNWIND_THREAD_LOCAL struct _Unwind_FunctionContext *stack = NULL;
8383#endif
8484
85static struct _Unwind_FunctionContext *__Unwind_SjLj_GetTopOfFunctionStack() {
85static struct _Unwind_FunctionContext *
86__Unwind_SjLj_GetTopOfFunctionStack(void) {
8687#if defined(__APPLE__)
8788 return _pthread_getspecific_direct(__PTK_LIBC_DYLD_Unwind_SjLj_Key);
8889#else
......@@ -426,7 +427,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetGR(struct _Unwind_Context *context,
426427/// Called by personality handler during phase 2 to alter register values.
427428_LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index,
428429 uintptr_t new_value) {
429 _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%" PRIuPTR
430 _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%" PRIxPTR
430431 ")",
431432 (void *)context, index, new_value);
432433 _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context;
......@@ -437,7 +438,7 @@ _LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index,
437438/// Called by personality handler during phase 2 to get instruction pointer.
438439_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
439440 _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context;
440 _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIu32,
441 _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIxPTR,
441442 (void *)context, ufc->resumeLocation + 1);
442443 return ufc->resumeLocation + 1;
443444}
......@@ -450,7 +451,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context,
450451 int *ipBefore) {
451452 _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context;
452453 *ipBefore = 0;
453 _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p, %p) => 0x%" PRIu32,
454 _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p, %p) => 0x%" PRIxPTR,
454455 (void *)context, (void *)ipBefore,
455456 ufc->resumeLocation + 1);
456457 return ufc->resumeLocation + 1;
......@@ -460,7 +461,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context,
460461/// Called by personality handler during phase 2 to alter instruction pointer.
461462_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
462463 uintptr_t new_value) {
463 _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%" PRIuPTR ")",
464 _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%" PRIxPTR ")",
464465 (void *)context, new_value);
465466 _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context;
466467 ufc->resumeLocation = new_value - 1;
lib/libunwind/src/Unwind-wasm.c created+123
......@@ -0,0 +1,123 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//
8// Implements Wasm exception handling proposal
9// (https://github.com/WebAssembly/exception-handling) based C++ exceptions
10//
11//===----------------------------------------------------------------------===//
12
13#include <stdbool.h>
14
15#include "config.h"
16
17#ifdef __USING_WASM_EXCEPTIONS__
18
19#include "unwind.h"
20#include <threads.h>
21
22_Unwind_Reason_Code __gxx_personality_wasm0(int version, _Unwind_Action actions,
23 uint64_t exceptionClass,
24 _Unwind_Exception *unwind_exception,
25 _Unwind_Context *context);
26
27struct _Unwind_LandingPadContext {
28 // Input information to personality function
29 uintptr_t lpad_index; // landing pad index
30 uintptr_t lsda; // LSDA address
31
32 // Output information computed by personality function
33 uintptr_t selector; // selector value
34};
35
36// Communication channel between compiler-generated user code and personality
37// function
38thread_local struct _Unwind_LandingPadContext __wasm_lpad_context;
39
40/// Calls to this function is in landing pads in compiler-generated user code.
41/// In other EH schemes, stack unwinding is done by libunwind library, which
42/// calls the personality function for each each frame it lands. On the other
43/// hand, WebAssembly stack unwinding process is performed by a VM, and the
44/// personality function cannot be called from there. So the compiler inserts
45/// a call to this function in landing pads in the user code, which in turn
46/// calls the personality function.
47_Unwind_Reason_Code _Unwind_CallPersonality(void *exception_ptr) {
48 struct _Unwind_Exception *exception_object =
49 (struct _Unwind_Exception *)exception_ptr;
50 _LIBUNWIND_TRACE_API("_Unwind_CallPersonality(exception_object=%p)",
51 (void *)exception_object);
52
53 // Reset the selector.
54 __wasm_lpad_context.selector = 0;
55
56 // Call personality function. Wasm does not have two-phase unwinding, so we
57 // only do the cleanup phase.
58 return __gxx_personality_wasm0(
59 1, _UA_SEARCH_PHASE, exception_object->exception_class, exception_object,
60 (struct _Unwind_Context *)&__wasm_lpad_context);
61}
62
63/// Called by __cxa_throw.
64_LIBUNWIND_EXPORT _Unwind_Reason_Code
65_Unwind_RaiseException(_Unwind_Exception *exception_object) {
66 _LIBUNWIND_TRACE_API("_Unwind_RaiseException(exception_object=%p)",
67 (void *)exception_object);
68 // Use Wasm EH's 'throw' instruction.
69 __builtin_wasm_throw(0, exception_object);
70}
71
72/// Called by __cxa_end_catch.
73_LIBUNWIND_EXPORT void
74_Unwind_DeleteException(_Unwind_Exception *exception_object) {
75 _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)",
76 (void *)(exception_object));
77 if (exception_object->exception_cleanup != NULL)
78 (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT,
79 exception_object);
80}
81
82/// Called by personality handler to alter register values.
83_LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index,
84 uintptr_t value) {
85 _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, index=%d, value=%lu)",
86 (void *)context, index, value);
87 // We only use this function to set __wasm_lpad_context.selector field, which
88 // is index 1 in the personality function.
89 if (index == 1)
90 ((struct _Unwind_LandingPadContext *)context)->selector = value;
91}
92
93/// Called by personality handler to get instruction pointer.
94_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
95 // The result will be used as an 1-based index after decrementing 1, so we
96 // increment 2 here
97 uintptr_t result =
98 ((struct _Unwind_LandingPadContext *)context)->lpad_index + 2;
99 _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => %lu", (void *)context,
100 result);
101 return result;
102}
103
104/// Not used in Wasm.
105_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
106 uintptr_t value) {}
107
108/// Called by personality handler to get LSDA for current frame.
109_LIBUNWIND_EXPORT uintptr_t
110_Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
111 uintptr_t result = ((struct _Unwind_LandingPadContext *)context)->lsda;
112 _LIBUNWIND_TRACE_API("_Unwind_GetLanguageSpecificData(context=%p) => 0x%lx",
113 (void *)context, result);
114 return result;
115}
116
117/// Not used in Wasm.
118_LIBUNWIND_EXPORT uintptr_t
119_Unwind_GetRegionStart(struct _Unwind_Context *context) {
120 return 0;
121}
122
123#endif // defined(__USING_WASM_EXCEPTIONS__)
lib/libunwind/src/UnwindCursor.hpp+114-59
......@@ -33,6 +33,8 @@
3333#if defined(_LIBUNWIND_TARGET_LINUX) && \
3434 (defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_RISCV) || \
3535 defined(_LIBUNWIND_TARGET_S390X))
36#include <errno.h>
37#include <signal.h>
3638#include <sys/syscall.h>
3739#include <sys/uio.h>
3840#include <unistd.h>
......@@ -990,6 +992,7 @@ private:
990992 R dummy;
991993 return stepThroughSigReturn(dummy);
992994 }
995 bool isReadableAddr(const pint_t addr) const;
993996#if defined(_LIBUNWIND_TARGET_AARCH64)
994997 bool setInfoForSigReturn(Registers_arm64 &);
995998 int stepThroughSigReturn(Registers_arm64 &);
......@@ -2301,27 +2304,39 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
23012304 if (!getFunctionName(functionBuf, sizeof(functionBuf), &offset)) {
23022305 functionName = ".anonymous.";
23032306 }
2304 _LIBUNWIND_TRACE_UNWINDING("%s: Look up traceback table of func=%s at %p",
2305 __func__, functionName,
2306 reinterpret_cast<void *>(TBTable));
2307 _LIBUNWIND_TRACE_UNWINDING(
2308 "%s: Look up traceback table of func=%s at %p, pc=%p, "
2309 "SP=%p, saves_lr=%d, stores_bc=%d",
2310 __func__, functionName, reinterpret_cast<void *>(TBTable),
2311 reinterpret_cast<void *>(pc),
2312 reinterpret_cast<void *>(registers.getSP()), TBTable->tb.saves_lr,
2313 TBTable->tb.stores_bc);
23072314 }
23082315
23092316#if defined(__powerpc64__)
2310 // Instruction to reload TOC register "l r2,40(r1)"
2317 // Instruction to reload TOC register "ld r2,40(r1)"
23112318 const uint32_t loadTOCRegInst = 0xe8410028;
23122319 const int32_t unwPPCF0Index = UNW_PPC64_F0;
23132320 const int32_t unwPPCV0Index = UNW_PPC64_V0;
23142321#else
2315 // Instruction to reload TOC register "l r2,20(r1)"
2322 // Instruction to reload TOC register "lwz r2,20(r1)"
23162323 const uint32_t loadTOCRegInst = 0x80410014;
23172324 const int32_t unwPPCF0Index = UNW_PPC_F0;
23182325 const int32_t unwPPCV0Index = UNW_PPC_V0;
23192326#endif
23202327
2328 // lastStack points to the stack frame of the next routine up.
2329 pint_t curStack = static_cast<pint_t>(registers.getSP());
2330 pint_t lastStack = *reinterpret_cast<pint_t *>(curStack);
2331
2332 if (lastStack == 0)
2333 return UNW_STEP_END;
2334
23212335 R newRegisters = registers;
23222336
2323 // lastStack points to the stack frame of the next routine up.
2324 pint_t lastStack = *(reinterpret_cast<pint_t *>(registers.getSP()));
2337 // If backchain is not stored, use the current stack frame.
2338 if (!TBTable->tb.stores_bc)
2339 lastStack = curStack;
23252340
23262341 // Return address is the address after call site instruction.
23272342 pint_t returnAddress;
......@@ -2331,33 +2346,41 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
23312346 reinterpret_cast<void *>(lastStack));
23322347
23332348 sigcontext *sigContext = reinterpret_cast<sigcontext *>(
2334 reinterpret_cast<char *>(lastStack) + STKMIN);
2349 reinterpret_cast<char *>(lastStack) + STKMINALIGN);
23352350 returnAddress = sigContext->sc_jmpbuf.jmp_context.iar;
23362351
2337 _LIBUNWIND_TRACE_UNWINDING("From sigContext=%p, returnAddress=%p\n",
2338 reinterpret_cast<void *>(sigContext),
2339 reinterpret_cast<void *>(returnAddress));
2340
2352 bool useSTKMIN = false;
23412353 if (returnAddress < 0x10000000) {
2342 // Try again using STKMINALIGN
2354 // Try again using STKMIN.
23432355 sigContext = reinterpret_cast<sigcontext *>(
2344 reinterpret_cast<char *>(lastStack) + STKMINALIGN);
2356 reinterpret_cast<char *>(lastStack) + STKMIN);
23452357 returnAddress = sigContext->sc_jmpbuf.jmp_context.iar;
23462358 if (returnAddress < 0x10000000) {
2347 _LIBUNWIND_TRACE_UNWINDING("Bad returnAddress=%p\n",
2348 reinterpret_cast<void *>(returnAddress));
2359 _LIBUNWIND_TRACE_UNWINDING("Bad returnAddress=%p from sigcontext=%p",
2360 reinterpret_cast<void *>(returnAddress),
2361 reinterpret_cast<void *>(sigContext));
23492362 return UNW_EBADFRAME;
2350 } else {
2351 _LIBUNWIND_TRACE_UNWINDING("Tried again using STKMINALIGN: "
2352 "sigContext=%p, returnAddress=%p. "
2353 "Seems to be a valid address\n",
2354 reinterpret_cast<void *>(sigContext),
2355 reinterpret_cast<void *>(returnAddress));
23562363 }
2364 useSTKMIN = true;
23572365 }
2366 _LIBUNWIND_TRACE_UNWINDING("Returning from a signal handler %s: "
2367 "sigContext=%p, returnAddress=%p. "
2368 "Seems to be a valid address",
2369 useSTKMIN ? "STKMIN" : "STKMINALIGN",
2370 reinterpret_cast<void *>(sigContext),
2371 reinterpret_cast<void *>(returnAddress));
2372
23582373 // Restore the condition register from sigcontext.
23592374 newRegisters.setCR(sigContext->sc_jmpbuf.jmp_context.cr);
23602375
2376 // Save the LR in sigcontext for stepping up when the function that
2377 // raised the signal is a leaf function. This LR has the return address
2378 // to the caller of the leaf function.
2379 newRegisters.setLR(sigContext->sc_jmpbuf.jmp_context.lr);
2380 _LIBUNWIND_TRACE_UNWINDING(
2381 "Save LR=%p from sigcontext",
2382 reinterpret_cast<void *>(sigContext->sc_jmpbuf.jmp_context.lr));
2383
23612384 // Restore GPRs from sigcontext.
23622385 for (int i = 0; i < 32; ++i)
23632386 newRegisters.setRegister(i, sigContext->sc_jmpbuf.jmp_context.gpr[i]);
......@@ -2380,13 +2403,26 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
23802403 }
23812404 } else {
23822405 // Step up a normal frame.
2383 returnAddress = reinterpret_cast<pint_t *>(lastStack)[2];
23842406
2385 _LIBUNWIND_TRACE_UNWINDING("Extract info from lastStack=%p, "
2386 "returnAddress=%p\n",
2387 reinterpret_cast<void *>(lastStack),
2388 reinterpret_cast<void *>(returnAddress));
2389 _LIBUNWIND_TRACE_UNWINDING("fpr_regs=%d, gpr_regs=%d, saves_cr=%d\n",
2407 if (!TBTable->tb.saves_lr && registers.getLR()) {
2408 // This case should only occur if we were called from a signal handler
2409 // and the signal occurred in a function that doesn't save the LR.
2410 returnAddress = static_cast<pint_t>(registers.getLR());
2411 _LIBUNWIND_TRACE_UNWINDING("Use saved LR=%p",
2412 reinterpret_cast<void *>(returnAddress));
2413 } else {
2414 // Otherwise, use the LR value in the stack link area.
2415 returnAddress = reinterpret_cast<pint_t *>(lastStack)[2];
2416 }
2417
2418 // Reset LR in the current context.
2419 newRegisters.setLR(NULL);
2420
2421 _LIBUNWIND_TRACE_UNWINDING(
2422 "Extract info from lastStack=%p, returnAddress=%p",
2423 reinterpret_cast<void *>(lastStack),
2424 reinterpret_cast<void *>(returnAddress));
2425 _LIBUNWIND_TRACE_UNWINDING("fpr_regs=%d, gpr_regs=%d, saves_cr=%d",
23902426 TBTable->tb.fpr_saved, TBTable->tb.gpr_saved,
23912427 TBTable->tb.saves_cr);
23922428
......@@ -2450,7 +2486,7 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
24502486
24512487 struct vec_ext *vec_ext = reinterpret_cast<struct vec_ext *>(charPtr);
24522488
2453 _LIBUNWIND_TRACE_UNWINDING("vr_saved=%d\n", vec_ext->vr_saved);
2489 _LIBUNWIND_TRACE_UNWINDING("vr_saved=%d", vec_ext->vr_saved);
24542490
24552491 // Restore vector register(s) if saved on the stack.
24562492 if (vec_ext->vr_saved) {
......@@ -2480,11 +2516,11 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
24802516
24812517 // Do we need to set the TOC register?
24822518 _LIBUNWIND_TRACE_UNWINDING(
2483 "Current gpr2=%p\n",
2519 "Current gpr2=%p",
24842520 reinterpret_cast<void *>(newRegisters.getRegister(2)));
24852521 if (firstInstruction == loadTOCRegInst) {
24862522 _LIBUNWIND_TRACE_UNWINDING(
2487 "Set gpr2=%p from frame\n",
2523 "Set gpr2=%p from frame",
24882524 reinterpret_cast<void *>(reinterpret_cast<pint_t *>(lastStack)[5]));
24892525 newRegisters.setRegister(2, reinterpret_cast<pint_t *>(lastStack)[5]);
24902526 }
......@@ -2516,7 +2552,6 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
25162552 } else {
25172553 isSignalFrame = false;
25182554 }
2519
25202555 return UNW_STEP_SUCCESS;
25212556}
25222557#endif // defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
......@@ -2668,20 +2703,12 @@ bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_arm64 &) {
26682703 // [1] https://github.com/torvalds/linux/blob/master/arch/arm64/kernel/vdso/sigreturn.S
26692704 const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
26702705 // The PC might contain an invalid address if the unwind info is bad, so
2671 // directly accessing it could cause a segfault. Use process_vm_readv to read
2672 // the memory safely instead. process_vm_readv was added in Linux 3.2, and
2673 // AArch64 supported was added in Linux 3.7, so the syscall is guaranteed to
2674 // be present. Unfortunately, there are Linux AArch64 environments where the
2675 // libc wrapper for the syscall might not be present (e.g. Android 5), so call
2676 // the syscall directly instead.
2677 uint32_t instructions[2];
2678 struct iovec local_iov = {&instructions, sizeof instructions};
2679 struct iovec remote_iov = {reinterpret_cast<void *>(pc), sizeof instructions};
2680 long bytesRead =
2681 syscall(SYS_process_vm_readv, getpid(), &local_iov, 1, &remote_iov, 1, 0);
2706 // directly accessing it could cause a SIGSEGV.
2707 if (!isReadableAddr(pc))
2708 return false;
2709 auto *instructions = reinterpret_cast<const uint32_t *>(pc);
26822710 // Look for instructions: mov x8, #0x8b; svc #0x0
2683 if (bytesRead != sizeof instructions || instructions[0] != 0xd2801168 ||
2684 instructions[1] != 0xd4000001)
2711 if (instructions[0] != 0xd2801168 || instructions[1] != 0xd4000001)
26852712 return false;
26862713
26872714 _info = {};
......@@ -2730,18 +2757,17 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) {
27302757template <typename A, typename R>
27312758bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_riscv &) {
27322759 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);
2760 // The PC might contain an invalid address if the unwind info is bad, so
2761 // directly accessing it could cause a SIGSEGV.
2762 if (!isReadableAddr(pc))
2763 return false;
2764 const auto *instructions = reinterpret_cast<const uint32_t *>(pc);
27382765 // Look for the two instructions used in the sigreturn trampoline
27392766 // __vdso_rt_sigreturn:
27402767 //
27412768 // 0x08b00893 li a7,0x8b
27422769 // 0x00000073 ecall
2743 if (bytesRead != sizeof instructions || instructions[0] != 0x08b00893 ||
2744 instructions[1] != 0x00000073)
2770 if (instructions[0] != 0x08b00893 || instructions[1] != 0x00000073)
27452771 return false;
27462772
27472773 _info = {};
......@@ -2790,13 +2816,11 @@ bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_s390x &) {
27902816 // onto the stack.
27912817 const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
27922818 // The PC might contain an invalid address if the unwind info is bad, so
2793 // directly accessing it could cause a segfault. Use process_vm_readv to
2794 // read the memory safely instead.
2795 uint16_t inst;
2796 struct iovec local_iov = {&inst, sizeof inst};
2797 struct iovec remote_iov = {reinterpret_cast<void *>(pc), sizeof inst};
2798 long bytesRead = process_vm_readv(getpid(), &local_iov, 1, &remote_iov, 1, 0);
2799 if (bytesRead == sizeof inst && (inst == 0x0a77 || inst == 0x0aad)) {
2819 // directly accessing it could cause a SIGSEGV.
2820 if (!isReadableAddr(pc))
2821 return false;
2822 const auto inst = *reinterpret_cast<const uint16_t *>(pc);
2823 if (inst == 0x0a77 || inst == 0x0aad) {
28002824 _info = {};
28012825 _info.start_ip = pc;
28022826 _info.end_ip = pc + 2;
......@@ -2942,6 +2966,37 @@ bool UnwindCursor<A, R>::getFunctionName(char *buf, size_t bufLen,
29422966 buf, bufLen, offset);
29432967}
29442968
2969#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
2970template <typename A, typename R>
2971bool UnwindCursor<A, R>::isReadableAddr(const pint_t addr) const {
2972 // We use SYS_rt_sigprocmask, inspired by Abseil's AddressIsReadable.
2973
2974 const auto sigsetAddr = reinterpret_cast<sigset_t *>(addr);
2975 // We have to check that addr is nullptr because sigprocmask allows that
2976 // as an argument without failure.
2977 if (!sigsetAddr)
2978 return false;
2979 const auto saveErrno = errno;
2980 // We MUST use a raw syscall here, as wrappers may try to access
2981 // sigsetAddr which may cause a SIGSEGV. A raw syscall however is
2982 // safe. Additionally, we need to pass the kernel_sigset_size, which is
2983 // different from libc sizeof(sigset_t). For the majority of architectures,
2984 // it's 64 bits (_NSIG), and libc NSIG is _NSIG + 1.
2985 const auto kernelSigsetSize = NSIG / 8;
2986 [[maybe_unused]] const int Result = syscall(
2987 SYS_rt_sigprocmask, /*how=*/~0, sigsetAddr, nullptr, kernelSigsetSize);
2988 // Because our "how" is invalid, this syscall should always fail, and our
2989 // errno should always be EINVAL or an EFAULT. This relies on the Linux
2990 // kernel to check copy_from_user before checking if the "how" argument is
2991 // invalid.
2992 assert(Result == -1);
2993 assert(errno == EFAULT || errno == EINVAL);
2994 const auto readable = errno != EFAULT;
2995 errno = saveErrno;
2996 return readable;
2997}
2998#endif
2999
29453000#if defined(_LIBUNWIND_USE_CET)
29463001extern "C" void *__libunwind_cet_get_registers(unw_cursor_t *cursor) {
29473002 AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
lib/libunwind/src/UnwindLevel1-gcc-ext.c+1-1
......@@ -143,7 +143,7 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) {
143143 // Create a mock exception object for force unwinding.
144144 _Unwind_Exception ex;
145145 memset(&ex, '\0', sizeof(ex));
146 strcpy((char *)&ex.exception_class, "CLNGUNW");
146 memcpy(&ex.exception_class, "CLNGUNW", sizeof(ex.exception_class));
147147#endif
148148
149149 // walk each frame
lib/libunwind/src/UnwindRegistersRestore.S+5-1
......@@ -673,7 +673,7 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
673673 ldr d30, [x0, #0x200]
674674 ldr d31, [x0, #0x208]
675675
676 // Finally, restore sp. This must be done after the the last read from the
676 // Finally, restore sp. This must be done after the last read from the
677677 // context struct, because it is allocated on the stack, and an exception
678678 // could clobber the de-allocated portion of the stack after sp has been
679679 // restored.
......@@ -993,11 +993,13 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind18Registers_mips_o326jumptoEv)
993993 ldc1 $f31, (4 * 36 + 8 * 31)($4)
994994#endif
995995#endif
996#if __mips_isa_rev < 6
996997 // restore hi and lo
997998 lw $8, (4 * 33)($4)
998999 mthi $8
9991000 lw $8, (4 * 34)($4)
10001001 mtlo $8
1002#endif
10011003 // r0 is zero
10021004 lw $1, (4 * 1)($4)
10031005 lw $2, (4 * 2)($4)
......@@ -1054,11 +1056,13 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv)
10541056 ldc1 $f\i, (280+8*\i)($4)
10551057 .endr
10561058#endif
1059#if __mips_isa_rev < 6
10571060 // restore hi and lo
10581061 ld $8, (8 * 33)($4)
10591062 mthi $8
10601063 ld $8, (8 * 34)($4)
10611064 mtlo $8
1065#endif
10621066 // r0 is zero
10631067 ld $1, (8 * 1)($4)
10641068 ld $2, (8 * 2)($4)
lib/libunwind/src/UnwindRegistersSave.S+41-3
......@@ -174,11 +174,13 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
174174 sw $31, (4 * 31)($4)
175175 # Store return address to pc
176176 sw $31, (4 * 32)($4)
177#if __mips_isa_rev < 6
177178 # hi and lo
178179 mfhi $8
179180 sw $8, (4 * 33)($4)
180181 mflo $8
181182 sw $8, (4 * 34)($4)
183#endif
182184#ifdef __mips_hard_float
183185#if __mips_fpr != 64
184186 sdc1 $f0, (4 * 36 + 8 * 0)($4)
......@@ -255,11 +257,13 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
255257 .endr
256258 # Store return address to pc
257259 sd $31, (8 * 32)($4)
260#if __mips_isa_rev < 6
258261 # hi and lo
259262 mfhi $8
260263 sd $8, (8 * 33)($4)
261264 mflo $8
262265 sd $8, (8 * 34)($4)
266#endif
263267#ifdef __mips_hard_float
264268 .irp i,FROM_0_TO_31
265269 sdc1 $f\i, (280+8*\i)($4)
......@@ -301,9 +305,21 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
301305 mflr 0
302306 std 0, PPC64_OFFS_SRR0(3) // store lr as ssr0
303307 PPC64_STR(1)
308 PPC64_STR(4) // Save r4 first since it will be used for fixing r2.
309#if defined(_AIX)
310 // The TOC register (r2) was changed by the glue code if unw_getcontext
311 // is called from a different module. Save the original TOC register
312 // in the context if this is the case.
313 mflr 4
314 lwz 4, 0(4) // Get the first instruction at the return address.
315 xoris 0, 4, 0xe841 // Is it reloading the TOC register "ld 2,40(1)"?
316 cmplwi 0, 0x28
317 bne 0, LnoR2Fix // No need to fix up r2 if it is not.
318 ld 2, 40(1) // Use the saved TOC register in the stack.
319LnoR2Fix:
320#endif
304321 PPC64_STR(2)
305322 PPC64_STR(3)
306 PPC64_STR(4)
307323 PPC64_STR(5)
308324 PPC64_STR(6)
309325 PPC64_STR(7)
......@@ -336,7 +352,12 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
336352 std 0, PPC64_OFFS_CR(3)
337353 mfxer 0
338354 std 0, PPC64_OFFS_XER(3)
355#if defined(_AIX)
356 // LR value saved from the register is not used, initialize it to 0.
357 li 0, 0
358#else
339359 mflr 0
360#endif
340361 std 0, PPC64_OFFS_LR(3)
341362 mfctr 0
342363 std 0, PPC64_OFFS_CTR(3)
......@@ -543,9 +564,21 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
543564 mflr 0
544565 stw 0, 0(3) // store lr as ssr0
545566 stw 1, 12(3)
567 stw 4, 24(3) // Save r4 first since it will be used for fixing r2.
568#if defined(_AIX)
569 // The TOC register (r2) was changed by the glue code if unw_getcontext
570 // is called from a different module. Save the original TOC register
571 // in the context if this is the case.
572 mflr 4
573 lwz 4, 0(4) // Get the instruction at the return address.
574 xoris 0, 4, 0x8041 // Is it reloading the TOC register "lwz 2,20(1)"?
575 cmplwi 0, 0x14
576 bne 0, LnoR2Fix // No need to fix up r2 if it is not.
577 lwz 2, 20(1) // Use the saved TOC register in the stack.
578LnoR2Fix:
579#endif
546580 stw 2, 16(3)
547581 stw 3, 20(3)
548 stw 4, 24(3)
549582 stw 5, 28(3)
550583 stw 6, 32(3)
551584 stw 7, 36(3)
......@@ -582,6 +615,11 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
582615 // save CR registers
583616 mfcr 0
584617 stw 0, 136(3)
618#if defined(_AIX)
619 // LR value from the register is not used, initialize it to 0.
620 li 0, 0
621 stw 0, 144(3)
622#endif
585623 // save CTR register
586624 mfctr 0
587625 stw 0, 148(3)
......@@ -742,7 +780,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
742780@
743781@ On entry:
744782@ thread_state pointer is in r0
745@
783@
746784@ Per EHABI #4.7 this only saves the core integer registers.
747785@ EHABI #7.4.5 notes that in general all VRS registers should be restored
748786@ however this is very hard to do for VFP registers because it is unknown
lib/libunwind/src/config.h+8-6
......@@ -46,6 +46,12 @@
4646#elif defined(_AIX)
4747// The traceback table at the end of each function is used for unwinding.
4848#define _LIBUNWIND_SUPPORT_TBTAB_UNWIND 1
49#elif defined(__HAIKU__)
50 #if defined(_LIBUNWIND_USE_HAIKU_BSD_LIB)
51 #define _LIBUNWIND_USE_DL_ITERATE_PHDR 1
52 #endif
53 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
54 #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1
4955#else
5056 // Assume an ELF system with a dl_iterate_phdr function.
5157 #define _LIBUNWIND_USE_DL_ITERATE_PHDR 1
......@@ -83,7 +89,7 @@
8389 __asm__(".globl " SYMBOL_NAME(aliasname)); \
8490 __asm__(SYMBOL_NAME(aliasname) " = " SYMBOL_NAME(name)); \
8591 _LIBUNWIND_ALIAS_VISIBILITY(SYMBOL_NAME(aliasname))
86#elif defined(__ELF__) || defined(_AIX)
92#elif defined(__ELF__) || defined(_AIX) || defined(__wasm__)
8793#define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \
8894 extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname \
8995 __attribute__((weak, alias(#name)));
......@@ -108,10 +114,6 @@
108114#define _LIBUNWIND_BUILD_SJLJ_APIS
109115#endif
110116
111#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__)
112#define _LIBUNWIND_SUPPORT_FRAME_APIS
113#endif
114
115117#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || \
116118 (!defined(__APPLE__) && defined(__arm__)) || defined(__aarch64__) || \
117119 defined(__mips__) || defined(__riscv) || defined(__hexagon__) || \
......@@ -125,7 +127,7 @@
125127#if defined(_LIBUNWIND_REMEMBER_STACK_ALLOC) || defined(__APPLE__) || \
126128 defined(__linux__) || defined(__ANDROID__) || defined(__MINGW32__) || \
127129 defined(_LIBUNWIND_IS_BAREMETAL)
128#define _LIBUNWIND_REMEMBER_ALLOC(_size) alloca(_size)
130#define _LIBUNWIND_REMEMBER_ALLOC(_size) __builtin_alloca(_size)
129131#define _LIBUNWIND_REMEMBER_FREE(_ptr) \
130132 do { \
131133 } while (0)
lib/libunwind/src/libunwind.cpp+4-3
......@@ -26,7 +26,7 @@
2626#include <sanitizer/asan_interface.h>
2727#endif
2828
29#if !defined(__USING_SJLJ_EXCEPTIONS__)
29#if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__USING_WASM_EXCEPTIONS__)
3030#include "AddressSpace.hpp"
3131#include "UnwindCursor.hpp"
3232
......@@ -324,7 +324,7 @@ void __unw_add_dynamic_eh_frame_section(unw_word_t eh_frame_start) {
324324 CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
325325 CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
326326 auto p = (LocalAddressSpace::pint_t)eh_frame_start;
327 while (true) {
327 while (LocalAddressSpace::sThisAddressSpace.get32(p)) {
328328 if (CFI_Parser<LocalAddressSpace>::decodeFDE(
329329 LocalAddressSpace::sThisAddressSpace, p, &fdeInfo, &cieInfo,
330330 true) == NULL) {
......@@ -347,7 +347,8 @@ void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start) {
347347}
348348
349349#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
350#endif // !defined(__USING_SJLJ_EXCEPTIONS__)
350#endif // !defined(__USING_SJLJ_EXCEPTIONS__) &&
351 // !defined(__USING_WASM_EXCEPTIONS__)
351352
352353#ifdef __APPLE__
353354
src/libunwind.zig+1
......@@ -164,6 +164,7 @@ const unwind_src_list = [_][]const u8{
164164 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindLevel1.c",
165165 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindLevel1-gcc-ext.c",
166166 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-sjlj.c",
167 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-wasm.c",
167168 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersRestore.S",
168169 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersSave.S",
169170 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind_AIXExtras.cpp",