Browse Source

Update contrib/libs/libunwind to 18.1.0-rc1

dtorilov 1 year ago
parent
commit
ac6be7a860

+ 26 - 2
contrib/libs/libunwind/include/__libunwind_config.h

@@ -9,8 +9,10 @@
 #ifndef ____LIBUNWIND_CONFIG_H__
 #define ____LIBUNWIND_CONFIG_H__
 
+#define _LIBUNWIND_VERSION 15000
+
 #if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \
-    !defined(__ARM_DWARF_EH__)
+    !defined(__ARM_DWARF_EH__) && !defined(__SEH__)
 #define _LIBUNWIND_ARM_EHABI
 #endif
 
@@ -27,11 +29,16 @@
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON   34
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV     64
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE        143
+#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X     83
+#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH 64
 
 #if defined(_LIBUNWIND_IS_NATIVE_ONLY)
 # if defined(__linux__)
 #  define _LIBUNWIND_TARGET_LINUX 1
 # endif
+# if defined(__HAIKU__)
+#  define _LIBUNWIND_TARGET_HAIKU 1
+# endif
 # if defined(__i386__)
 #  define _LIBUNWIND_TARGET_I386
 #  define _LIBUNWIND_CONTEXT_SIZE 8
@@ -158,6 +165,21 @@
 #  define _LIBUNWIND_CONTEXT_SIZE 67
 #  define _LIBUNWIND_CURSOR_SIZE 79
 #  define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE
+# elif defined(__s390x__)
+#  define _LIBUNWIND_TARGET_S390X 1
+#  define _LIBUNWIND_CONTEXT_SIZE 34
+#  define _LIBUNWIND_CURSOR_SIZE 46
+#  define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X
+#elif defined(__loongarch__)
+#define _LIBUNWIND_TARGET_LOONGARCH 1
+#if __loongarch_grlen == 64
+#define _LIBUNWIND_CONTEXT_SIZE 65
+#define _LIBUNWIND_CURSOR_SIZE 77
+#else
+#error "Unsupported LoongArch ABI"
+#endif
+#define _LIBUNWIND_HIGHEST_DWARF_REGISTER                                      \
+  _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH
 # else
 #  error "Unsupported architecture."
 # endif
@@ -176,8 +198,10 @@
 # define _LIBUNWIND_TARGET_HEXAGON 1
 # define _LIBUNWIND_TARGET_RISCV 1
 # define _LIBUNWIND_TARGET_VE 1
+# define _LIBUNWIND_TARGET_S390X 1
+# define _LIBUNWIND_TARGET_LOONGARCH 1
 # define _LIBUNWIND_CONTEXT_SIZE 167
-# define _LIBUNWIND_CURSOR_SIZE 179
+# define _LIBUNWIND_CURSOR_SIZE 204
 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287
 #endif // _LIBUNWIND_IS_NATIVE_ONLY
 

+ 127 - 1
contrib/libs/libunwind/include/libunwind.h

@@ -81,7 +81,7 @@ typedef struct unw_addr_space *unw_addr_space_t;
 
 typedef int unw_regnum_t;
 typedef uintptr_t unw_word_t;
-#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
+#if defined(__arm__) && !defined(__ARM_DWARF_EH__) && !defined(__SEH__)
 typedef uint64_t unw_fpreg_t;
 #else
 typedef double unw_fpreg_t;
@@ -120,6 +120,9 @@ extern int unw_resume(unw_cursor_t *) LIBUNWIND_AVAIL;
 extern void unw_save_vfp_as_X(unw_cursor_t *) LIBUNWIND_AVAIL;
 #endif
 
+#ifdef _AIX
+extern uintptr_t unw_get_data_rel_base(unw_cursor_t *) LIBUNWIND_AVAIL;
+#endif
 
 extern const char *unw_regname(unw_cursor_t *, unw_regnum_t) LIBUNWIND_AVAIL;
 extern int unw_get_proc_info(unw_cursor_t *, unw_proc_info_t *) LIBUNWIND_AVAIL;
@@ -873,6 +876,9 @@ enum {
   UNW_MIPS_F29 = 61,
   UNW_MIPS_F30 = 62,
   UNW_MIPS_F31 = 63,
+  // HI,LO have been dropped since r6, we keep them here.
+  // So, when we add DSP/MSA etc, we can use the same register indexes
+  // for r6 and pre-r6.
   UNW_MIPS_HI = 64,
   UNW_MIPS_LO = 65,
 };
@@ -1020,6 +1026,16 @@ enum {
   UNW_RISCV_F29 = 61,
   UNW_RISCV_F30 = 62,
   UNW_RISCV_F31 = 63,
+  // 65-95 -- Reserved for future standard extensions
+  // 96-127 -- v0-v31 (Vector registers)
+  // 128-3071 -- Reserved for future standard extensions
+  // 3072-4095 -- Reserved for custom extensions
+  // 4096-8191 -- CSRs
+  //
+  // VLENB CSR number: 0xC22 -- defined by section 3 of v-spec:
+  // https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#3-vector-extension-programmers-model
+  // VLENB DWARF number: 0x1000 + 0xC22
+  UNW_RISCV_VLENB = 0x1C22,
 };
 
 // VE register numbers
@@ -1174,4 +1190,114 @@ enum {
   UNW_VE_VL   = 145,
 };
 
+// s390x register numbers
+enum {
+  UNW_S390X_R0      = 0,
+  UNW_S390X_R1      = 1,
+  UNW_S390X_R2      = 2,
+  UNW_S390X_R3      = 3,
+  UNW_S390X_R4      = 4,
+  UNW_S390X_R5      = 5,
+  UNW_S390X_R6      = 6,
+  UNW_S390X_R7      = 7,
+  UNW_S390X_R8      = 8,
+  UNW_S390X_R9      = 9,
+  UNW_S390X_R10     = 10,
+  UNW_S390X_R11     = 11,
+  UNW_S390X_R12     = 12,
+  UNW_S390X_R13     = 13,
+  UNW_S390X_R14     = 14,
+  UNW_S390X_R15     = 15,
+  UNW_S390X_F0      = 16,
+  UNW_S390X_F2      = 17,
+  UNW_S390X_F4      = 18,
+  UNW_S390X_F6      = 19,
+  UNW_S390X_F1      = 20,
+  UNW_S390X_F3      = 21,
+  UNW_S390X_F5      = 22,
+  UNW_S390X_F7      = 23,
+  UNW_S390X_F8      = 24,
+  UNW_S390X_F10     = 25,
+  UNW_S390X_F12     = 26,
+  UNW_S390X_F14     = 27,
+  UNW_S390X_F9      = 28,
+  UNW_S390X_F11     = 29,
+  UNW_S390X_F13     = 30,
+  UNW_S390X_F15     = 31,
+  // 32-47 Control Registers
+  // 48-63 Access Registers
+  UNW_S390X_PSWM    = 64,
+  UNW_S390X_PSWA    = 65,
+  // 66-67 Reserved
+  // 68-83 Vector Registers %v16-%v31
+};
+
+// LoongArch registers.
+enum {
+  UNW_LOONGARCH_R0 = 0,
+  UNW_LOONGARCH_R1 = 1,
+  UNW_LOONGARCH_R2 = 2,
+  UNW_LOONGARCH_R3 = 3,
+  UNW_LOONGARCH_R4 = 4,
+  UNW_LOONGARCH_R5 = 5,
+  UNW_LOONGARCH_R6 = 6,
+  UNW_LOONGARCH_R7 = 7,
+  UNW_LOONGARCH_R8 = 8,
+  UNW_LOONGARCH_R9 = 9,
+  UNW_LOONGARCH_R10 = 10,
+  UNW_LOONGARCH_R11 = 11,
+  UNW_LOONGARCH_R12 = 12,
+  UNW_LOONGARCH_R13 = 13,
+  UNW_LOONGARCH_R14 = 14,
+  UNW_LOONGARCH_R15 = 15,
+  UNW_LOONGARCH_R16 = 16,
+  UNW_LOONGARCH_R17 = 17,
+  UNW_LOONGARCH_R18 = 18,
+  UNW_LOONGARCH_R19 = 19,
+  UNW_LOONGARCH_R20 = 20,
+  UNW_LOONGARCH_R21 = 21,
+  UNW_LOONGARCH_R22 = 22,
+  UNW_LOONGARCH_R23 = 23,
+  UNW_LOONGARCH_R24 = 24,
+  UNW_LOONGARCH_R25 = 25,
+  UNW_LOONGARCH_R26 = 26,
+  UNW_LOONGARCH_R27 = 27,
+  UNW_LOONGARCH_R28 = 28,
+  UNW_LOONGARCH_R29 = 29,
+  UNW_LOONGARCH_R30 = 30,
+  UNW_LOONGARCH_R31 = 31,
+  UNW_LOONGARCH_F0 = 32,
+  UNW_LOONGARCH_F1 = 33,
+  UNW_LOONGARCH_F2 = 34,
+  UNW_LOONGARCH_F3 = 35,
+  UNW_LOONGARCH_F4 = 36,
+  UNW_LOONGARCH_F5 = 37,
+  UNW_LOONGARCH_F6 = 38,
+  UNW_LOONGARCH_F7 = 39,
+  UNW_LOONGARCH_F8 = 40,
+  UNW_LOONGARCH_F9 = 41,
+  UNW_LOONGARCH_F10 = 42,
+  UNW_LOONGARCH_F11 = 43,
+  UNW_LOONGARCH_F12 = 44,
+  UNW_LOONGARCH_F13 = 45,
+  UNW_LOONGARCH_F14 = 46,
+  UNW_LOONGARCH_F15 = 47,
+  UNW_LOONGARCH_F16 = 48,
+  UNW_LOONGARCH_F17 = 49,
+  UNW_LOONGARCH_F18 = 50,
+  UNW_LOONGARCH_F19 = 51,
+  UNW_LOONGARCH_F20 = 52,
+  UNW_LOONGARCH_F21 = 53,
+  UNW_LOONGARCH_F22 = 54,
+  UNW_LOONGARCH_F23 = 55,
+  UNW_LOONGARCH_F24 = 56,
+  UNW_LOONGARCH_F25 = 57,
+  UNW_LOONGARCH_F26 = 58,
+  UNW_LOONGARCH_F27 = 59,
+  UNW_LOONGARCH_F28 = 60,
+  UNW_LOONGARCH_F29 = 61,
+  UNW_LOONGARCH_F30 = 62,
+  UNW_LOONGARCH_F31 = 63,
+};
+
 #endif

+ 43 - 43
contrib/libs/libunwind/include/mach-o/compact_unwind_encoding.h

@@ -33,7 +33,7 @@
 
 
 //
-// The compact unwind endoding is a 32-bit value which encoded in an
+// The compact unwind encoding is a 32-bit value which encoded in an
 // architecture specific way, which registers to restore from where, and how
 // to unwind out of the function.
 //
@@ -108,7 +108,7 @@ enum {
 //    are encoded in the UNWIND_X86_EBP_FRAME_REGISTERS bits as five 3-bit entries.
 //    Each entry contains which register to restore.
 // UNWIND_X86_MODE_STACK_IMMD:
-//    A "frameless" (EBP not used as frame pointer) function with a small 
+//    A "frameless" (EBP not used as frame pointer) function with a small
 //    constant stack size.  To return, a constant (encoded in the compact
 //    unwind encoding) is added to the ESP. Then the return is done by
 //    popping the stack into the pc.
@@ -116,19 +116,19 @@ enum {
 //    on the stack immediately after the return address.  The stack_size/4 is
 //    encoded in the UNWIND_X86_FRAMELESS_STACK_SIZE (max stack size is 1024).
 //    The number of registers saved is encoded in UNWIND_X86_FRAMELESS_STACK_REG_COUNT.
-//    UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION constains which registers were
+//    UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION contains which registers were
 //    saved and their order.
 // UNWIND_X86_MODE_STACK_IND:
-//    A "frameless" (EBP not used as frame pointer) function large constant 
+//    A "frameless" (EBP not used as frame pointer) function large constant
 //    stack size.  This case is like the previous, except the stack size is too
-//    large to encode in the compact unwind encoding.  Instead it requires that 
-//    the function contains "subl $nnnnnnnn,ESP" in its prolog.  The compact 
+//    large to encode in the compact unwind encoding.  Instead it requires that
+//    the function contains "subl $nnnnnnnn,ESP" in its prolog.  The compact
 //    encoding contains the offset to the nnnnnnnn value in the function in
-//    UNWIND_X86_FRAMELESS_STACK_SIZE.  
+//    UNWIND_X86_FRAMELESS_STACK_SIZE.
 // UNWIND_X86_MODE_DWARF:
 //    No compact unwind encoding is available.  Instead the low 24-bits of the
 //    compact encoding is the offset of the DWARF FDE in the __eh_frame section.
-//    This mode is never used in object files.  It is only generated by the 
+//    This mode is never used in object files.  It is only generated by the
 //    linker in final linked images which have only DWARF unwind info for a
 //    function.
 //
@@ -233,36 +233,36 @@ enum {
 // For x86_64 there are four modes for the compact unwind encoding:
 // UNWIND_X86_64_MODE_RBP_FRAME:
 //    RBP based frame where RBP is push on stack immediately after return address,
-//    then RSP is moved to RBP. Thus, to unwind RSP is restored with the current 
-//    EPB value, then RBP is restored by popping off the stack, and the return 
+//    then RSP is moved to RBP. Thus, to unwind RSP is restored with the current
+//    EPB value, then RBP is restored by popping off the stack, and the return
 //    is done by popping the stack once more into the pc.
 //    All non-volatile registers that need to be restored must have been saved
-//    in a small range in the stack that starts RBP-8 to RBP-2040.  The offset/8 
+//    in a small range in the stack that starts RBP-8 to RBP-2040.  The offset/8
 //    is encoded in the UNWIND_X86_64_RBP_FRAME_OFFSET bits.  The registers saved
 //    are encoded in the UNWIND_X86_64_RBP_FRAME_REGISTERS bits as five 3-bit entries.
-//    Each entry contains which register to restore.  
+//    Each entry contains which register to restore.
 // UNWIND_X86_64_MODE_STACK_IMMD:
-//    A "frameless" (RBP not used as frame pointer) function with a small 
-//    constant stack size.  To return, a constant (encoded in the compact 
-//    unwind encoding) is added to the RSP. Then the return is done by 
+//    A "frameless" (RBP not used as frame pointer) function with a small
+//    constant stack size.  To return, a constant (encoded in the compact
+//    unwind encoding) is added to the RSP. Then the return is done by
 //    popping the stack into the pc.
 //    All non-volatile registers that need to be restored must have been saved
 //    on the stack immediately after the return address.  The stack_size/8 is
 //    encoded in the UNWIND_X86_64_FRAMELESS_STACK_SIZE (max stack size is 2048).
 //    The number of registers saved is encoded in UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT.
-//    UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION constains which registers were
-//    saved and their order.  
+//    UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION contains which registers were
+//    saved and their order.
 // UNWIND_X86_64_MODE_STACK_IND:
-//    A "frameless" (RBP not used as frame pointer) function large constant 
+//    A "frameless" (RBP not used as frame pointer) function large constant
 //    stack size.  This case is like the previous, except the stack size is too
-//    large to encode in the compact unwind encoding.  Instead it requires that 
-//    the function contains "subq $nnnnnnnn,RSP" in its prolog.  The compact 
+//    large to encode in the compact unwind encoding.  Instead it requires that
+//    the function contains "subq $nnnnnnnn,RSP" in its prolog.  The compact
 //    encoding contains the offset to the nnnnnnnn value in the function in
-//    UNWIND_X86_64_FRAMELESS_STACK_SIZE.  
+//    UNWIND_X86_64_FRAMELESS_STACK_SIZE.
 // UNWIND_X86_64_MODE_DWARF:
 //    No compact unwind encoding is available.  Instead the low 24-bits of the
 //    compact encoding is the offset of the DWARF FDE in the __eh_frame section.
-//    This mode is never used in object files.  It is only generated by the 
+//    This mode is never used in object files.  It is only generated by the
 //    linker in final linked images which have only DWARF unwind info for a
 //    function.
 //
@@ -307,20 +307,20 @@ enum {
 //    This is a standard arm64 prolog where FP/LR are immediately pushed on the
 //    stack, then SP is copied to FP. If there are any non-volatile registers
 //    saved, then are copied into the stack frame in pairs in a contiguous
-//    range right below the saved FP/LR pair.  Any subset of the five X pairs 
+//    range right below the saved FP/LR pair.  Any subset of the five X pairs
 //    and four D pairs can be saved, but the memory layout must be in register
-//    number order.  
+//    number order.
 // UNWIND_ARM64_MODE_FRAMELESS:
-//    A "frameless" leaf function, where FP/LR are not saved. The return address 
+//    A "frameless" leaf function, where FP/LR are not saved. The return address
 //    remains in LR throughout the function. If any non-volatile registers
 //    are saved, they must be pushed onto the stack before any stack space is
 //    allocated for local variables.  The stack sized (including any saved
-//    non-volatile registers) divided by 16 is encoded in the bits 
+//    non-volatile registers) divided by 16 is encoded in the bits
 //    UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK.
 // UNWIND_ARM64_MODE_DWARF:
 //    No compact unwind encoding is available.  Instead the low 24-bits of the
 //    compact encoding is the offset of the DWARF FDE in the __eh_frame section.
-//    This mode is never used in object files.  It is only generated by the 
+//    This mode is never used in object files.  It is only generated by the
 //    linker in final linked images which have only DWARF unwind info for a
 //    function.
 //
@@ -337,19 +337,19 @@ enum {
 
 //
 // A compiler can generated compact unwind information for a function by adding
-// a "row" to the __LD,__compact_unwind section.  This section has the 
-// S_ATTR_DEBUG bit set, so the section will be ignored by older linkers. 
-// It is removed by the new linker, so never ends up in final executables. 
-// This section is a table, initially with one row per function (that needs 
+// a "row" to the __LD,__compact_unwind section.  This section has the
+// S_ATTR_DEBUG bit set, so the section will be ignored by older linkers.
+// It is removed by the new linker, so never ends up in final executables.
+// This section is a table, initially with one row per function (that needs
 // unwind info).  The table columns and some conceptual entries are:
 //
 //     range-start               pointer to start of function/range
-//     range-length              
-//     compact-unwind-encoding   32-bit encoding  
+//     range-length
+//     compact-unwind-encoding   32-bit encoding
 //     personality-function      or zero if no personality function
 //     lsda                      or zero if no LSDA data
 //
-// The length and encoding fields are 32-bits.  The other are all pointer sized. 
+// The length and encoding fields are 32-bits.  The other are all pointer sized.
 //
 // In x86_64 assembly, these entry would look like:
 //
@@ -372,23 +372,23 @@ enum {
 //     .quad    except_tab1
 //
 //
-// Notes: There is no need for any labels in the the __compact_unwind section.  
-//        The use of the .set directive is to force the evaluation of the 
+// Notes: There is no need for any labels in the __compact_unwind section.
+//        The use of the .set directive is to force the evaluation of the
 //        range-length at assembly time, instead of generating relocations.
 //
-// To support future compiler optimizations where which non-volatile registers 
+// To support future compiler optimizations where which non-volatile registers
 // are saved changes within a function (e.g. delay saving non-volatiles until
 // necessary), there can by multiple lines in the __compact_unwind table for one
-// function, each with a different (non-overlapping) range and each with 
-// different compact unwind encodings that correspond to the non-volatiles 
+// function, each with a different (non-overlapping) range and each with
+// different compact unwind encodings that correspond to the non-volatiles
 // saved at that range of the function.
 //
 // If a particular function is so wacky that there is no compact unwind way
-// to encode it, then the compiler can emit traditional DWARF unwind info.  
+// to encode it, then the compiler can emit traditional DWARF unwind info.
 // The runtime will use which ever is available.
 //
-// Runtime support for compact unwind encodings are only available on 10.6 
-// and later.  So, the compiler should not generate it when targeting pre-10.6. 
+// Runtime support for compact unwind encodings are only available on 10.6
+// and later.  So, the compiler should not generate it when targeting pre-10.6.
 
 
 
@@ -402,7 +402,7 @@ enum {
 //
 // The __TEXT,__unwind_info section is laid out for an efficient two level lookup.
 // The header of the section contains a coarse index that maps function address
-// to the page (4096 byte block) containing the unwind info for that function.  
+// to the page (4096 byte block) containing the unwind info for that function.
 //
 
 #define UNWIND_SECTION_VERSION 1

+ 2 - 2
contrib/libs/libunwind/include/unwind.h

@@ -93,7 +93,7 @@ extern void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t fc);
 #endif
 
 //
-// The following are semi-suppoted extensions to the C++ ABI
+// The following are semi-supported extensions to the C++ ABI
 //
 
 //
@@ -160,7 +160,7 @@ extern const void *_Unwind_Find_FDE(const void *pc, struct dwarf_eh_bases *);
 extern void *_Unwind_FindEnclosingFunction(void *pc);
 
 // Mac OS X does not support text-rel and data-rel addressing so these functions
-// are unimplemented
+// are unimplemented.
 extern uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context *context)
     LIBUNWIND_UNAVAIL;
 extern uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context *context)

+ 97 - 29
contrib/libs/libunwind/src/AddressSpace.hpp

@@ -24,7 +24,7 @@
 #include "Registers.hpp"
 
 #ifndef _LIBUNWIND_USE_DLADDR
-  #if !defined(_LIBUNWIND_IS_BAREMETAL) && !defined(_WIN32)
+  #if !(defined(_LIBUNWIND_IS_BAREMETAL) || defined(_WIN32) || defined(_AIX))
     #define _LIBUNWIND_USE_DLADDR 1
   #else
     #define _LIBUNWIND_USE_DLADDR 0
@@ -45,6 +45,13 @@ struct EHABIIndexEntry {
 };
 #endif
 
+#if defined(_AIX)
+namespace libunwind {
+char *getFuncNameFromTBTable(uintptr_t pc, uint16_t &NameLen,
+                             unw_word_t *offset);
+}
+#endif
+
 #ifdef __APPLE__
 
   struct dyld_unwind_sections
@@ -59,6 +66,10 @@ struct EHABIIndexEntry {
   // In 10.7.0 or later, libSystem.dylib implements this function.
   extern "C" bool _dyld_find_unwind_sections(void *, dyld_unwind_sections *);
 
+namespace libunwind {
+  bool findDynamicUnwindSections(void *, unw_dynamic_unwind_sections *);
+}
+
 #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL)
 
 // When statically linked on bare-metal, the symbols for the EH table are looked
@@ -239,7 +250,7 @@ inline uint64_t LocalAddressSpace::getULEB128(pint_t &addr, pint_t end) {
 inline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) {
   const uint8_t *p = (uint8_t *)addr;
   const uint8_t *pend = (uint8_t *)end;
-  int64_t result = 0;
+  uint64_t result = 0;
   int bit = 0;
   uint8_t byte;
   do {
@@ -253,7 +264,7 @@ inline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) {
   if ((byte & 0x40) != 0 && bit < 64)
     result |= (-1ULL) << bit;
   addr = (pint_t) p;
-  return result;
+  return (int64_t)result;
 }
 
 inline LocalAddressSpace::pint_t
@@ -366,28 +377,6 @@ LocalAddressSpace::getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
   typedef ElfW(Addr) Elf_Addr;
 #endif
 
-static Elf_Addr calculateImageBase(struct dl_phdr_info *pinfo) {
-  Elf_Addr image_base = pinfo->dlpi_addr;
-#if defined(__ANDROID__) && __ANDROID_API__ < 18
-  if (image_base == 0) {
-    // Normally, an image base of 0 indicates a non-PIE executable. On
-    // versions of Android prior to API 18, the dynamic linker reported a
-    // dlpi_addr of 0 for PIE executables. Compute the true image base
-    // using the PT_PHDR segment.
-    // See https://github.com/android/ndk/issues/505.
-    for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) {
-      const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i];
-      if (phdr->p_type == PT_PHDR) {
-        image_base = reinterpret_cast<Elf_Addr>(pinfo->dlpi_phdr) -
-          phdr->p_vaddr;
-        break;
-      }
-    }
-  }
-#endif
-  return image_base;
-}
-
 struct _LIBUNWIND_HIDDEN dl_iterate_cb_data {
   LocalAddressSpace *addressSpace;
   UnwindInfoSections *sects;
@@ -425,8 +414,8 @@ static bool checkForUnwindInfoSegment(const Elf_Phdr *phdr, size_t image_base,
     cbdata->sects->dwarf_index_section = eh_frame_hdr_start;
     cbdata->sects->dwarf_index_section_length = phdr->p_memsz;
     if (EHHeaderParser<LocalAddressSpace>::decodeEHHdr(
-            *cbdata->addressSpace, eh_frame_hdr_start, phdr->p_memsz,
-            hdrInfo)) {
+            *cbdata->addressSpace, eh_frame_hdr_start,
+            eh_frame_hdr_start + phdr->p_memsz, hdrInfo)) {
       // .eh_frame_hdr records the start of .eh_frame, but not its size.
       // Rely on a zero terminator to find the end of the section.
       cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr;
@@ -461,7 +450,7 @@ static int findUnwindSectionsByPhdr(struct dl_phdr_info *pinfo,
   (void)pinfo_size;
 #endif
 
-  Elf_Addr image_base = calculateImageBase(pinfo);
+  Elf_Addr image_base = pinfo->dlpi_addr;
 
   // Most shared objects seen in this callback function likely don't contain the
   // target address, so optimize for that. Scan for a matching PT_LOAD segment
@@ -512,6 +501,22 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
     info.compact_unwind_section_length = (size_t)dyldInfo.compact_unwind_section_length;
     return true;
   }
+
+  unw_dynamic_unwind_sections dynamicUnwindSectionInfo;
+  if (findDynamicUnwindSections((void *)targetAddr,
+                                &dynamicUnwindSectionInfo)) {
+    info.dso_base = dynamicUnwindSectionInfo.dso_base;
+#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
+    info.dwarf_section = (uintptr_t)dynamicUnwindSectionInfo.dwarf_section;
+    info.dwarf_section_length = dynamicUnwindSectionInfo.dwarf_section_length;
+#endif
+    info.compact_unwind_section =
+        (uintptr_t)dynamicUnwindSectionInfo.compact_unwind_section;
+    info.compact_unwind_section_length =
+        dynamicUnwindSectionInfo.compact_unwind_section_length;
+    return true;
+  }
+
 #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL)
   info.dso_base = 0;
   // Bare metal is statically linked, so no need to ask the dynamic loader
@@ -544,6 +549,7 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
     DWORD err = GetLastError();
     _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: EnumProcessModules failed, "
                                "returned error %d", (int)err);
+    (void)err;
     return false;
   }
 
@@ -580,6 +586,11 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
   (void)targetAddr;
   (void)info;
   return true;
+#elif defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
+  // The traceback table is used for unwinding.
+  (void)targetAddr;
+  (void)info;
+  return true;
 #elif defined(_LIBUNWIND_USE_DL_UNWIND_FIND_EXIDX)
   int length = 0;
   info.arm_section =
@@ -588,6 +599,57 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
   if (info.arm_section && info.arm_section_length)
     return true;
 #elif defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
+  // Use DLFO_STRUCT_HAS_EH_DBASE to determine the existence of
+  // `_dl_find_object`. Use _LIBUNWIND_SUPPORT_DWARF_INDEX, because libunwind
+  // support for _dl_find_object on other unwind formats is not implemented,
+  // yet.
+#if defined(DLFO_STRUCT_HAS_EH_DBASE) & defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
+  // We expect `_dl_find_object` to return PT_GNU_EH_FRAME.
+#if DLFO_EH_SEGMENT_TYPE != PT_GNU_EH_FRAME
+#error _dl_find_object retrieves an unexpected section type
+#endif
+  // We look-up `dl_find_object` dynamically at runtime to ensure backwards
+  // compatibility with earlier version of glibc not yet providing it. On older
+  // systems, we gracefully fallback to `dl_iterate_phdr`. Cache the pointer
+  // so we only look it up once. Do manual lock to avoid _cxa_guard_acquire.
+  static decltype(_dl_find_object) *dlFindObject;
+  static bool dlFindObjectChecked = false;
+  if (!dlFindObjectChecked) {
+    dlFindObject = reinterpret_cast<decltype(_dl_find_object) *>(
+        dlsym(RTLD_DEFAULT, "_dl_find_object"));
+    dlFindObjectChecked = true;
+  }
+  // Try to find the unwind info using `dl_find_object`
+  dl_find_object findResult;
+  if (dlFindObject && dlFindObject((void *)targetAddr, &findResult) == 0) {
+    if (findResult.dlfo_eh_frame == nullptr) {
+      // Found an entry for `targetAddr`, but there is no unwind info.
+      return false;
+    }
+    info.dso_base = reinterpret_cast<uintptr_t>(findResult.dlfo_map_start);
+    info.text_segment_length = static_cast<size_t>(
+        (char *)findResult.dlfo_map_end - (char *)findResult.dlfo_map_start);
+
+    // Record the start of PT_GNU_EH_FRAME.
+    info.dwarf_index_section =
+        reinterpret_cast<uintptr_t>(findResult.dlfo_eh_frame);
+    // `_dl_find_object` does not give us the size of PT_GNU_EH_FRAME.
+    // Setting length to `SIZE_MAX` effectively disables all range checks.
+    info.dwarf_index_section_length = SIZE_MAX;
+    EHHeaderParser<LocalAddressSpace>::EHHeaderInfo hdrInfo;
+    if (!EHHeaderParser<LocalAddressSpace>::decodeEHHdr(
+            *this, info.dwarf_index_section,
+            info.dwarf_index_section + info.dwarf_index_section_length,
+            hdrInfo)) {
+      return false;
+    }
+    // Record the start of the FDE and use SIZE_MAX to indicate that we do
+    // not know the end address.
+    info.dwarf_section = hdrInfo.eh_frame_ptr;
+    info.dwarf_section_length = SIZE_MAX;
+    return true;
+  }
+#endif
   dl_iterate_cb_data cb_data = {this, &info, targetAddr};
   int found = dl_iterate_phdr(findUnwindSectionsByPhdr, &cb_data);
   return static_cast<bool>(found);
@@ -596,7 +658,6 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
   return false;
 }
 
-
 inline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) {
   // TO DO: if OS has way to dynamically register FDEs, check that.
   (void)targetAddr;
@@ -616,6 +677,13 @@ inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf,
       return true;
     }
   }
+#elif defined(_AIX)
+  uint16_t nameLen;
+  char *funcName = getFuncNameFromTBTable(addr, nameLen, offset);
+  if (funcName != NULL) {
+    snprintf(buf, bufLen, "%.*s", nameLen, funcName);
+    return true;
+  }
 #else
   (void)addr;
   (void)buf;

+ 1 - 0
contrib/libs/libunwind/src/CompactUnwinder.hpp

@@ -19,6 +19,7 @@
 #include <mach-o/compact_unwind_encoding.h>
 
 #include "Registers.hpp"
+#include "libunwind_ext.h"
 
 #define EXTRACT_BITS(value, mask)                                              \
   ((value >> __builtin_ctz(mask)) & (((1 << __builtin_popcount(mask))) - 1))

+ 67 - 14
contrib/libs/libunwind/src/DwarfInstructions.hpp

@@ -16,16 +16,17 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "dwarf2.h"
-#include "Registers.hpp"
 #include "DwarfParser.hpp"
+#include "Registers.hpp"
 #include "config.h"
+#include "dwarf2.h"
+#include "libunwind_ext.h"
 
 
 namespace libunwind {
 
 
-/// DwarfInstructions maps abtract DWARF unwind instructions to a particular
+/// DwarfInstructions maps abstract DWARF unwind instructions to a particular
 /// architecture
 template <typename A, typename R>
 class DwarfInstructions {
@@ -34,7 +35,7 @@ public:
   typedef typename A::sint_t sint_t;
 
   static int stepWithDwarf(A &addressSpace, pint_t pc, pint_t fdeStart,
-                           R &registers, bool &isSignalFrame);
+                           R &registers, bool &isSignalFrame, bool stage2);
 
 private:
 
@@ -67,11 +68,15 @@ private:
       return (pint_t)((sint_t)registers.getRegister((int)prolog.cfaRegister) +
              prolog.cfaRegisterOffset);
     if (prolog.cfaExpression != 0)
-      return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace, 
+      return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace,
                                 registers, 0);
     assert(0 && "getCFA(): unknown location");
     __builtin_unreachable();
   }
+#if defined(_LIBUNWIND_TARGET_AARCH64)
+  static bool getRA_SIGN_STATE(A &addressSpace, R registers, pint_t cfa,
+                               PrologInfo &prolog);
+#endif
 };
 
 template <typename R>
@@ -166,11 +171,26 @@ v128 DwarfInstructions<A, R>::getSavedVectorRegister(
   }
   _LIBUNWIND_ABORT("unsupported restore location for vector register");
 }
+#if defined(_LIBUNWIND_TARGET_AARCH64)
+template <typename A, typename R>
+bool DwarfInstructions<A, R>::getRA_SIGN_STATE(A &addressSpace, R registers,
+                                               pint_t cfa, PrologInfo &prolog) {
+  pint_t raSignState;
+  auto regloc = prolog.savedRegisters[UNW_AARCH64_RA_SIGN_STATE];
+  if (regloc.location == CFI_Parser<A>::kRegisterUnused)
+    raSignState = static_cast<pint_t>(regloc.value);
+  else
+    raSignState = getSavedRegister(addressSpace, registers, cfa, regloc);
+
+  // Only bit[0] is meaningful.
+  return raSignState & 0x01;
+}
+#endif
 
 template <typename A, typename R>
 int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
                                            pint_t fdeStart, R &registers,
-                                           bool &isSignalFrame) {
+                                           bool &isSignalFrame, bool stage2) {
   FDE_Info fdeInfo;
   CIE_Info cieInfo;
   if (CFI_Parser<A>::decodeFDE(addressSpace, fdeStart, &fdeInfo,
@@ -181,7 +201,39 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
       // get pointer to cfa (architecture specific)
       pint_t cfa = getCFA(addressSpace, prolog, registers);
 
-       // restore registers that DWARF says were saved
+      (void)stage2;
+      // __unw_step_stage2 is not used for cross unwinding, so we use
+      // __aarch64__ rather than LIBUNWIND_TARGET_AARCH64 to make sure we are
+      // building for AArch64 natively.
+#if defined(__aarch64__)
+      if (stage2 && cieInfo.mteTaggedFrame) {
+        pint_t sp = registers.getSP();
+        pint_t p = sp;
+        // AArch64 doesn't require the value of SP to be 16-byte aligned at
+        // all times, only at memory accesses and public interfaces [1]. Thus,
+        // a signal could arrive at a point where SP is not aligned properly.
+        // In that case, the kernel fixes up [2] the signal frame, but we
+        // still have a misaligned SP in the previous frame. If that signal
+        // handler caused stack unwinding, we would have an unaligned SP.
+        // We do not need to fix up the CFA, as that is the SP at a "public
+        // interface".
+        // [1]:
+        // https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#622the-stack
+        // [2]:
+        // https://github.com/torvalds/linux/blob/1930a6e739c4b4a654a69164dbe39e554d228915/arch/arm64/kernel/signal.c#L718
+        p &= ~0xfULL;
+        // CFA is the bottom of the current stack frame.
+        for (; p < cfa; p += 16) {
+          __asm__ __volatile__(".arch armv8.5-a\n"
+                               ".arch_extension memtag\n"
+                               "stg %[Ptr], [%[Ptr]]\n"
+                               :
+                               : [Ptr] "r"(p)
+                               : "memory");
+        }
+      }
+#endif
+      // restore registers that DWARF says were saved
       R newRegisters = registers;
 
       // Typically, the CFA is the stack pointer at the call site in
@@ -194,9 +246,10 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
       newRegisters.setSP(cfa);
 
       pint_t returnAddress = 0;
-      const int lastReg = R::lastDwarfRegNum();
-      assert(static_cast<int>(CFI_Parser<A>::kMaxRegisterNumber) >= lastReg &&
-             "register range too large");
+      constexpr int lastReg = R::lastDwarfRegNum();
+      static_assert(static_cast<int>(CFI_Parser<A>::kMaxRegisterNumber) >=
+                        lastReg,
+                    "register range too large");
       assert(lastReg >= (int)cieInfo.returnAddressRegister &&
              "register range does not contain return address register");
       for (int i = 0; i <= lastReg; ++i) {
@@ -221,7 +274,7 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
             return UNW_EBADREG;
         } else if (i == (int)cieInfo.returnAddressRegister) {
             // Leaf function keeps the return address in register and there is no
-            // explicit intructions how to restore it.
+            // explicit instructions how to restore it.
             returnAddress = registers.getRegister(cieInfo.returnAddressRegister);
         }
       }
@@ -235,7 +288,7 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
       // restored. autia1716 is used instead of autia as autia1716 assembles
       // to a NOP on pre-v8.3a architectures.
       if ((R::getArch() == REGISTERS_ARM64) &&
-          prolog.savedRegisters[UNW_AARCH64_RA_SIGN_STATE].value &&
+          getRA_SIGN_STATE(addressSpace, registers, cfa, prolog) &&
           returnAddress != 0) {
 #if !defined(_LIBUNWIND_IS_NATIVE_ONLY)
         return UNW_ECROSSRASIGNING;
@@ -311,7 +364,7 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
 #endif
 
       // Return address is address after call site instruction, so setting IP to
-      // that does simualates a return.
+      // that does simulates a return.
       newRegisters.setIP(returnAddress);
 
       // Simulate the step by replacing the register set with the new ones.
@@ -615,7 +668,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
       svalue = (sint_t)*sp;
       *sp = (pint_t)(svalue >> value);
       if (log)
-        fprintf(stderr, "shift left arithmetric\n");
+        fprintf(stderr, "shift left arithmetic\n");
       break;
 
     case DW_OP_xor:

+ 7 - 2
contrib/libs/libunwind/src/DwarfParser.hpp

@@ -51,6 +51,7 @@ public:
     uint8_t   returnAddressRegister;
 #if defined(_LIBUNWIND_TARGET_AARCH64)
     bool      addressesSignedWithBKey;
+    bool      mteTaggedFrame;
 #endif
   };
 
@@ -325,6 +326,7 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie,
   cieInfo->fdesHaveAugmentationData = false;
 #if defined(_LIBUNWIND_TARGET_AARCH64)
   cieInfo->addressesSignedWithBKey = false;
+  cieInfo->mteTaggedFrame = false;
 #endif
   cieInfo->cieStart = cie;
   pint_t p = cie;
@@ -353,7 +355,7 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie,
   while (addressSpace.get8(p) != 0)
     ++p;
   ++p;
-  // parse code aligment factor
+  // parse code alignment factor
   cieInfo->codeAlignFactor = (uint32_t)addressSpace.getULEB128(p, cieContentEnd);
   // parse data alignment factor
   cieInfo->dataAlignFactor = (int)addressSpace.getSLEB128(p, cieContentEnd);
@@ -394,6 +396,9 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie,
       case 'B':
         cieInfo->addressesSignedWithBKey = true;
         break;
+      case 'G':
+        cieInfo->mteTaggedFrame = true;
+        break;
 #endif
       default:
         // ignore unknown letters
@@ -407,7 +412,7 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie,
 }
 
 
-/// "run" the DWARF instructions and create the abstact PrologInfo for an FDE
+/// "run" the DWARF instructions and create the abstract PrologInfo for an FDE
 template <typename A>
 bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
                                          const FDE_Info &fdeInfo,

+ 15 - 1
contrib/libs/libunwind/src/EHHeaderParser.hpp

@@ -55,9 +55,23 @@ template <typename A>
 bool EHHeaderParser<A>::decodeEHHdr(A &addressSpace, pint_t ehHdrStart,
                                     pint_t ehHdrEnd, EHHeaderInfo &ehHdrInfo) {
   pint_t p = ehHdrStart;
+
+  // Ensure that we don't read data beyond the end of .eh_frame_hdr
+  if (ehHdrEnd - ehHdrStart < 4) {
+    // Don't print a message for an empty .eh_frame_hdr (this can happen if
+    // the linker script defines symbols for it even in the empty case).
+    if (ehHdrEnd == ehHdrStart)
+      return false;
+    _LIBUNWIND_LOG("unsupported .eh_frame_hdr at %" PRIx64
+                   ": need at least 4 bytes of data but only got %zd",
+                   static_cast<uint64_t>(ehHdrStart),
+                   static_cast<size_t>(ehHdrEnd - ehHdrStart));
+    return false;
+  }
   uint8_t version = addressSpace.get8(p++);
   if (version != 1) {
-    _LIBUNWIND_LOG0("Unsupported .eh_frame_hdr version");
+    _LIBUNWIND_LOG("unsupported .eh_frame_hdr version: %" PRIu8 " at %" PRIx64,
+                   version, static_cast<uint64_t>(ehHdrStart));
     return false;
   }
 

+ 3 - 3
contrib/libs/libunwind/src/FrameHeaderCache.hpp

@@ -31,8 +31,8 @@
 
 class _LIBUNWIND_HIDDEN FrameHeaderCache {
   struct CacheEntry {
-    uintptr_t LowPC() { return Info.dso_base; };
-    uintptr_t HighPC() { return Info.dso_base + Info.text_segment_length; };
+    uintptr_t LowPC() { return Info.dso_base; }
+    uintptr_t HighPC() { return Info.dso_base + Info.text_segment_length; }
     UnwindInfoSections Info;
     CacheEntry *Next;
   };
@@ -41,7 +41,7 @@ class _LIBUNWIND_HIDDEN FrameHeaderCache {
 
   // Can't depend on the C++ standard library in libunwind, so use an array to
   // allocate the entries, and two linked lists for ordering unused and recently
-  // used entries.  FIXME: Would the the extra memory for a doubly-linked list
+  // used entries.  FIXME: Would the extra memory for a doubly-linked list
   // be better than the runtime cost of traversing a very short singly-linked
   // list on a cache miss? The entries themselves are all small and consecutive,
   // so unlikely to cause page faults when following the pointers. The memory

Some files were not shown because too many files changed in this diff