authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-08-04 18:09:10-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-08-04 18:09:10-07:00
log2f635c3ce9be74f9e9ffb71324f7ba51bd2987f4
treef04b0f4fb7a0e5ce0e36829bfd9aaa032447ac2a
parentc0d9578a84c95f66f34729f6c8842a98a995f223

update libunwind to LLVM 15

release/15.x commit 134fd359a5d884f16662a9edd22ab24feeb1498c

21 files changed, 1515 insertions(+), 134 deletions(-)

lib/libunwind/include/__libunwind_config.h+10-1
......@@ -9,8 +9,10 @@
99#ifndef ____LIBUNWIND_CONFIG_H__
1010#define ____LIBUNWIND_CONFIG_H__
1111
12#define _LIBUNWIND_VERSION 15000
13
1214#if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \
13 !defined(__ARM_DWARF_EH__)
15 !defined(__ARM_DWARF_EH__) && !defined(__SEH__)
1416#define _LIBUNWIND_ARM_EHABI
1517#endif
1618
......@@ -27,6 +29,7 @@
2729#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON 34
2830#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV 64
2931#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE 143
32#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X 83
3033
3134#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
3235# if defined(__linux__)
......@@ -158,6 +161,11 @@
158161# define _LIBUNWIND_CONTEXT_SIZE 67
159162# define _LIBUNWIND_CURSOR_SIZE 79
160163# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE
164# elif defined(__s390x__)
165# define _LIBUNWIND_TARGET_S390X 1
166# define _LIBUNWIND_CONTEXT_SIZE 34
167# define _LIBUNWIND_CURSOR_SIZE 46
168# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X
161169# else
162170# error "Unsupported architecture."
163171# endif
......@@ -176,6 +184,7 @@
176184# define _LIBUNWIND_TARGET_HEXAGON 1
177185# define _LIBUNWIND_TARGET_RISCV 1
178186# define _LIBUNWIND_TARGET_VE 1
187# define _LIBUNWIND_TARGET_S390X 1
179188# define _LIBUNWIND_CONTEXT_SIZE 167
180189# define _LIBUNWIND_CURSOR_SIZE 179
181190# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287
lib/libunwind/include/libunwind.h+46-1
......@@ -81,7 +81,7 @@ typedef struct unw_addr_space *unw_addr_space_t;
8181
8282typedef int unw_regnum_t;
8383typedef uintptr_t unw_word_t;
84#if defined(__arm__) && !defined(__ARM_DWARF_EH__)
84#if defined(__arm__) && !defined(__ARM_DWARF_EH__) && !defined(__SEH__)
8585typedef uint64_t unw_fpreg_t;
8686#else
8787typedef double unw_fpreg_t;
......@@ -120,6 +120,9 @@ extern int unw_resume(unw_cursor_t *) LIBUNWIND_AVAIL;
120120extern void unw_save_vfp_as_X(unw_cursor_t *) LIBUNWIND_AVAIL;
121121#endif
122122
123#ifdef _AIX
124extern uintptr_t unw_get_data_rel_base(unw_cursor_t *) LIBUNWIND_AVAIL;
125#endif
123126
124127extern const char *unw_regname(unw_cursor_t *, unw_regnum_t) LIBUNWIND_AVAIL;
125128extern int unw_get_proc_info(unw_cursor_t *, unw_proc_info_t *) LIBUNWIND_AVAIL;
......@@ -1174,4 +1177,46 @@ enum {
11741177 UNW_VE_VL = 145,
11751178};
11761179
1180// s390x register numbers
1181enum {
1182 UNW_S390X_R0 = 0,
1183 UNW_S390X_R1 = 1,
1184 UNW_S390X_R2 = 2,
1185 UNW_S390X_R3 = 3,
1186 UNW_S390X_R4 = 4,
1187 UNW_S390X_R5 = 5,
1188 UNW_S390X_R6 = 6,
1189 UNW_S390X_R7 = 7,
1190 UNW_S390X_R8 = 8,
1191 UNW_S390X_R9 = 9,
1192 UNW_S390X_R10 = 10,
1193 UNW_S390X_R11 = 11,
1194 UNW_S390X_R12 = 12,
1195 UNW_S390X_R13 = 13,
1196 UNW_S390X_R14 = 14,
1197 UNW_S390X_R15 = 15,
1198 UNW_S390X_F0 = 16,
1199 UNW_S390X_F2 = 17,
1200 UNW_S390X_F4 = 18,
1201 UNW_S390X_F6 = 19,
1202 UNW_S390X_F1 = 20,
1203 UNW_S390X_F3 = 21,
1204 UNW_S390X_F5 = 22,
1205 UNW_S390X_F7 = 23,
1206 UNW_S390X_F8 = 24,
1207 UNW_S390X_F10 = 25,
1208 UNW_S390X_F12 = 26,
1209 UNW_S390X_F14 = 27,
1210 UNW_S390X_F9 = 28,
1211 UNW_S390X_F11 = 29,
1212 UNW_S390X_F13 = 30,
1213 UNW_S390X_F15 = 31,
1214 // 32-47 Control Registers
1215 // 48-63 Access Registers
1216 UNW_S390X_PSWM = 64,
1217 UNW_S390X_PSWA = 65,
1218 // 66-67 Reserved
1219 // 68-83 Vector Registers %v16-%v31
1220};
1221
11771222#endif
lib/libunwind/include/unwind.h+1-1
......@@ -160,7 +160,7 @@ extern const void *_Unwind_Find_FDE(const void *pc, struct dwarf_eh_bases *);
160160extern void *_Unwind_FindEnclosingFunction(void *pc);
161161
162162// Mac OS X does not support text-rel and data-rel addressing so these functions
163// are unimplemented
163// are unimplemented.
164164extern uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context *context)
165165 LIBUNWIND_UNAVAIL;
166166extern uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context *context)
lib/libunwind/src/AddressSpace.hpp+21-2
......@@ -24,7 +24,7 @@
2424#include "Registers.hpp"
2525
2626#ifndef _LIBUNWIND_USE_DLADDR
27 #if !defined(_LIBUNWIND_IS_BAREMETAL) && !defined(_WIN32)
27 #if !(defined(_LIBUNWIND_IS_BAREMETAL) || defined(_WIN32) || defined(_AIX))
2828 #define _LIBUNWIND_USE_DLADDR 1
2929 #else
3030 #define _LIBUNWIND_USE_DLADDR 0
......@@ -45,6 +45,13 @@ struct EHABIIndexEntry {
4545};
4646#endif
4747
48#if defined(_AIX)
49namespace libunwind {
50char *getFuncNameFromTBTable(uintptr_t pc, uint16_t &NameLen,
51 unw_word_t *offset);
52}
53#endif
54
4855#ifdef __APPLE__
4956
5057 struct dyld_unwind_sections
......@@ -544,6 +551,7 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
544551 DWORD err = GetLastError();
545552 _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: EnumProcessModules failed, "
546553 "returned error %d", (int)err);
554 (void)err;
547555 return false;
548556 }
549557
......@@ -580,6 +588,11 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
580588 (void)targetAddr;
581589 (void)info;
582590 return true;
591#elif defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
592 // The traceback table is used for unwinding.
593 (void)targetAddr;
594 (void)info;
595 return true;
583596#elif defined(_LIBUNWIND_USE_DL_UNWIND_FIND_EXIDX)
584597 int length = 0;
585598 info.arm_section =
......@@ -596,7 +609,6 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
596609 return false;
597610}
598611
599
600612inline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) {
601613 // TO DO: if OS has way to dynamically register FDEs, check that.
602614 (void)targetAddr;
......@@ -616,6 +628,13 @@ inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf,
616628 return true;
617629 }
618630 }
631#elif defined(_AIX)
632 uint16_t nameLen;
633 char *funcName = getFuncNameFromTBTable(addr, nameLen, offset);
634 if (funcName != NULL) {
635 snprintf(buf, bufLen, "%.*s", nameLen, funcName);
636 return true;
637 }
619638#else
620639 (void)addr;
621640 (void)buf;
lib/libunwind/src/DwarfInstructions.hpp+24-4
......@@ -72,6 +72,10 @@ private:
7272 assert(0 && "getCFA(): unknown location");
7373 __builtin_unreachable();
7474 }
75#if defined(_LIBUNWIND_TARGET_AARCH64)
76 static bool getRA_SIGN_STATE(A &addressSpace, R registers, pint_t cfa,
77 PrologInfo &prolog);
78#endif
7579};
7680
7781template <typename R>
......@@ -166,6 +170,21 @@ v128 DwarfInstructions<A, R>::getSavedVectorRegister(
166170 }
167171 _LIBUNWIND_ABORT("unsupported restore location for vector register");
168172}
173#if defined(_LIBUNWIND_TARGET_AARCH64)
174template <typename A, typename R>
175bool DwarfInstructions<A, R>::getRA_SIGN_STATE(A &addressSpace, R registers,
176 pint_t cfa, PrologInfo &prolog) {
177 pint_t raSignState;
178 auto regloc = prolog.savedRegisters[UNW_AARCH64_RA_SIGN_STATE];
179 if (regloc.location == CFI_Parser<A>::kRegisterUnused)
180 raSignState = static_cast<pint_t>(regloc.value);
181 else
182 raSignState = getSavedRegister(addressSpace, registers, cfa, regloc);
183
184 // Only bit[0] is meaningful.
185 return raSignState & 0x01;
186}
187#endif
169188
170189template <typename A, typename R>
171190int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
......@@ -194,9 +213,10 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
194213 newRegisters.setSP(cfa);
195214
196215 pint_t returnAddress = 0;
197 const int lastReg = R::lastDwarfRegNum();
198 assert(static_cast<int>(CFI_Parser<A>::kMaxRegisterNumber) >= lastReg &&
199 "register range too large");
216 constexpr int lastReg = R::lastDwarfRegNum();
217 static_assert(static_cast<int>(CFI_Parser<A>::kMaxRegisterNumber) >=
218 lastReg,
219 "register range too large");
200220 assert(lastReg >= (int)cieInfo.returnAddressRegister &&
201221 "register range does not contain return address register");
202222 for (int i = 0; i <= lastReg; ++i) {
......@@ -235,7 +255,7 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
235255 // restored. autia1716 is used instead of autia as autia1716 assembles
236256 // to a NOP on pre-v8.3a architectures.
237257 if ((R::getArch() == REGISTERS_ARM64) &&
238 prolog.savedRegisters[UNW_AARCH64_RA_SIGN_STATE].value &&
258 getRA_SIGN_STATE(addressSpace, registers, cfa, prolog) &&
239259 returnAddress != 0) {
240260#if !defined(_LIBUNWIND_IS_NATIVE_ONLY)
241261 return UNW_ECROSSRASIGNING;
lib/libunwind/src/EHHeaderParser.hpp+2-1
......@@ -57,7 +57,8 @@ bool EHHeaderParser<A>::decodeEHHdr(A &addressSpace, pint_t ehHdrStart,
5757 pint_t p = ehHdrStart;
5858 uint8_t version = addressSpace.get8(p++);
5959 if (version != 1) {
60 _LIBUNWIND_LOG0("Unsupported .eh_frame_hdr version");
60 _LIBUNWIND_LOG("unsupported .eh_frame_hdr version: %" PRIu8 " at %" PRIx64,
61 version, static_cast<uint64_t>(ehHdrStart));
6162 return false;
6263 }
6364
lib/libunwind/src/Registers.hpp+334-14
......@@ -39,6 +39,7 @@ enum {
3939 REGISTERS_HEXAGON,
4040 REGISTERS_RISCV,
4141 REGISTERS_VE,
42 REGISTERS_S390X,
4243};
4344
4445#if defined(_LIBUNWIND_TARGET_I386)
......@@ -69,7 +70,9 @@ public:
6970 void setVectorRegister(int num, v128 value);
7071 static const char *getRegisterName(int num);
7172 void jumpto() { __libunwind_Registers_x86_jumpto(this); }
72 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; }
73 static constexpr int lastDwarfRegNum() {
74 return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86;
75 }
7376 static int getArch() { return REGISTERS_X86; }
7477
7578 uint32_t getSP() const { return _registers.__esp; }
......@@ -285,7 +288,9 @@ public:
285288 void setVectorRegister(int num, v128 value);
286289 static const char *getRegisterName(int num);
287290 void jumpto() { __libunwind_Registers_x86_64_jumpto(this); }
288 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; }
291 static constexpr int lastDwarfRegNum() {
292 return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64;
293 }
289294 static int getArch() { return REGISTERS_X86_64; }
290295
291296 uint64_t getSP() const { return _registers.__rsp; }
......@@ -602,13 +607,17 @@ public:
602607 void setVectorRegister(int num, v128 value);
603608 static const char *getRegisterName(int num);
604609 void jumpto();
605 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC; }
610 static constexpr int lastDwarfRegNum() {
611 return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC;
612 }
606613 static int getArch() { return REGISTERS_PPC; }
607614
608615 uint64_t getSP() const { return _registers.__r1; }
609616 void setSP(uint32_t value) { _registers.__r1 = value; }
610617 uint64_t getIP() const { return _registers.__srr0; }
611618 void setIP(uint32_t value) { _registers.__srr0 = value; }
619 uint64_t getCR() const { return _registers.__cr; }
620 void setCR(uint32_t value) { _registers.__cr = value; }
612621
613622private:
614623 struct ppc_thread_state_t {
......@@ -1168,13 +1177,17 @@ public:
11681177 void setVectorRegister(int num, v128 value);
11691178 static const char *getRegisterName(int num);
11701179 void jumpto();
1171 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64; }
1180 static constexpr int lastDwarfRegNum() {
1181 return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64;
1182 }
11721183 static int getArch() { return REGISTERS_PPC64; }
11731184
11741185 uint64_t getSP() const { return _registers.__r1; }
11751186 void setSP(uint64_t value) { _registers.__r1 = value; }
11761187 uint64_t getIP() const { return _registers.__srr0; }
11771188 void setIP(uint64_t value) { _registers.__srr0 = value; }
1189 uint64_t getCR() const { return _registers.__cr; }
1190 void setCR(uint64_t value) { _registers.__cr = value; }
11781191
11791192private:
11801193 struct ppc64_thread_state_t {
......@@ -1813,7 +1826,9 @@ public:
18131826 void setVectorRegister(int num, v128 value);
18141827 static const char *getRegisterName(int num);
18151828 void jumpto() { __libunwind_Registers_arm64_jumpto(this); }
1816 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; }
1829 static constexpr int lastDwarfRegNum() {
1830 return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64;
1831 }
18171832 static int getArch() { return REGISTERS_ARM64; }
18181833
18191834 uint64_t getSP() const { return _registers.__sp; }
......@@ -2103,7 +2118,9 @@ public:
21032118 restoreSavedFloatRegisters();
21042119 restoreCoreAndJumpTo();
21052120 }
2106 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM; }
2121 static constexpr int lastDwarfRegNum() {
2122 return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM;
2123 }
21072124 static int getArch() { return REGISTERS_ARM; }
21082125
21092126 uint32_t getSP() const { return _registers.__sp; }
......@@ -2603,7 +2620,9 @@ public:
26032620 void setVectorRegister(int num, v128 value);
26042621 static const char *getRegisterName(int num);
26052622 void jumpto();
2606 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K; }
2623 static constexpr int lastDwarfRegNum() {
2624 return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K;
2625 }
26072626 static int getArch() { return REGISTERS_OR1K; }
26082627
26092628 uint64_t getSP() const { return _registers.__r[1]; }
......@@ -2800,7 +2819,9 @@ public:
28002819 void setVectorRegister(int num, v128 value);
28012820 static const char *getRegisterName(int num);
28022821 void jumpto();
2803 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
2822 static constexpr int lastDwarfRegNum() {
2823 return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS;
2824 }
28042825 static int getArch() { return REGISTERS_MIPS_O32; }
28052826
28062827 uint32_t getSP() const { return _registers.__r[29]; }
......@@ -3127,7 +3148,9 @@ public:
31273148 void setVectorRegister(int num, v128 value);
31283149 static const char *getRegisterName(int num);
31293150 void jumpto();
3130 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
3151 static constexpr int lastDwarfRegNum() {
3152 return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS;
3153 }
31313154 static int getArch() { return REGISTERS_MIPS_NEWABI; }
31323155
31333156 uint64_t getSP() const { return _registers.__r[29]; }
......@@ -3422,7 +3445,9 @@ public:
34223445 void setVectorRegister(int num, v128 value);
34233446 static const char *getRegisterName(int num);
34243447 void jumpto();
3425 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC; }
3448 static constexpr int lastDwarfRegNum() {
3449 return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC;
3450 }
34263451 static int getArch() { return REGISTERS_SPARC; }
34273452
34283453 uint64_t getSP() const { return _registers.__regs[UNW_SPARC_O6]; }
......@@ -3606,7 +3631,7 @@ public:
36063631 void setVectorRegister(int num, v128 value);
36073632 const char *getRegisterName(int num);
36083633 void jumpto();
3609 static int lastDwarfRegNum() {
3634 static constexpr int lastDwarfRegNum() {
36103635 return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC64;
36113636 }
36123637 static int getArch() { return REGISTERS_SPARC64; }
......@@ -3791,7 +3816,9 @@ public:
37913816 void setVectorRegister(int num, v128 value);
37923817 const char *getRegisterName(int num);
37933818 void jumpto();
3794 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON; }
3819 static constexpr int lastDwarfRegNum() {
3820 return _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON;
3821 }
37953822 static int getArch() { return REGISTERS_HEXAGON; }
37963823
37973824 uint32_t getSP() const { return _registers.__r[UNW_HEXAGON_R29]; }
......@@ -4004,7 +4031,9 @@ public:
40044031 void setVectorRegister(int num, v128 value);
40054032 static const char *getRegisterName(int num);
40064033 void jumpto();
4007 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV; }
4034 static constexpr int lastDwarfRegNum() {
4035 return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV;
4036 }
40084037 static int getArch() { return REGISTERS_RISCV; }
40094038
40104039 reg_t getSP() const { return _registers[2]; }
......@@ -4290,7 +4319,9 @@ public:
42904319 void setVectorRegister(int num, v128 value);
42914320 static const char *getRegisterName(int num);
42924321 void jumpto();
4293 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE; }
4322 static constexpr int lastDwarfRegNum() {
4323 return _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE;
4324 }
42944325 static int getArch() { return REGISTERS_VE; }
42954326
42964327 uint64_t getSP() const { return _registers.__s[11]; }
......@@ -4712,6 +4743,295 @@ inline const char *Registers_ve::getRegisterName(int regNum) {
47124743}
47134744#endif // _LIBUNWIND_TARGET_VE
47144745
4746#if defined(_LIBUNWIND_TARGET_S390X)
4747/// Registers_s390x holds the register state of a thread in a
4748/// 64-bit Linux on IBM zSystems process.
4749class _LIBUNWIND_HIDDEN Registers_s390x {
4750public:
4751 Registers_s390x();
4752 Registers_s390x(const void *registers);
4753
4754 bool validRegister(int num) const;
4755 uint64_t getRegister(int num) const;
4756 void setRegister(int num, uint64_t value);
4757 bool validFloatRegister(int num) const;
4758 double getFloatRegister(int num) const;
4759 void setFloatRegister(int num, double value);
4760 bool validVectorRegister(int num) const;
4761 v128 getVectorRegister(int num) const;
4762 void setVectorRegister(int num, v128 value);
4763 static const char *getRegisterName(int num);
4764 void jumpto();
4765 static constexpr int lastDwarfRegNum() {
4766 return _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X;
4767 }
4768 static int getArch() { return REGISTERS_S390X; }
4769
4770 uint64_t getSP() const { return _registers.__gpr[15]; }
4771 void setSP(uint64_t value) { _registers.__gpr[15] = value; }
4772 uint64_t getIP() const { return _registers.__pswa; }
4773 void setIP(uint64_t value) { _registers.__pswa = value; }
4774
4775private:
4776 struct s390x_thread_state_t {
4777 uint64_t __pswm; // Problem Status Word: Mask
4778 uint64_t __pswa; // Problem Status Word: Address (PC)
4779 uint64_t __gpr[16]; // General Purpose Registers
4780 double __fpr[16]; // Floating-Point Registers
4781 };
4782
4783 s390x_thread_state_t _registers;
4784};
4785
4786inline Registers_s390x::Registers_s390x(const void *registers) {
4787 static_assert((check_fit<Registers_s390x, unw_context_t>::does_fit),
4788 "s390x registers do not fit into unw_context_t");
4789 memcpy(&_registers, static_cast<const uint8_t *>(registers),
4790 sizeof(_registers));
4791}
4792
4793inline Registers_s390x::Registers_s390x() {
4794 memset(&_registers, 0, sizeof(_registers));
4795}
4796
4797inline bool Registers_s390x::validRegister(int regNum) const {
4798 switch (regNum) {
4799 case UNW_S390X_PSWM:
4800 case UNW_S390X_PSWA:
4801 case UNW_REG_IP:
4802 case UNW_REG_SP:
4803 return true;
4804 }
4805
4806 if (regNum >= UNW_S390X_R0 && regNum <= UNW_S390X_R15)
4807 return true;
4808
4809 return false;
4810}
4811
4812inline uint64_t Registers_s390x::getRegister(int regNum) const {
4813 if (regNum >= UNW_S390X_R0 && regNum <= UNW_S390X_R15)
4814 return _registers.__gpr[regNum - UNW_S390X_R0];
4815
4816 switch (regNum) {
4817 case UNW_S390X_PSWM:
4818 return _registers.__pswm;
4819 case UNW_S390X_PSWA:
4820 case UNW_REG_IP:
4821 return _registers.__pswa;
4822 case UNW_REG_SP:
4823 return _registers.__gpr[15];
4824 }
4825 _LIBUNWIND_ABORT("unsupported s390x register");
4826}
4827
4828inline void Registers_s390x::setRegister(int regNum, uint64_t value) {
4829 if (regNum >= UNW_S390X_R0 && regNum <= UNW_S390X_R15) {
4830 _registers.__gpr[regNum - UNW_S390X_R0] = value;
4831 return;
4832 }
4833
4834 switch (regNum) {
4835 case UNW_S390X_PSWM:
4836 _registers.__pswm = value;
4837 return;
4838 case UNW_S390X_PSWA:
4839 case UNW_REG_IP:
4840 _registers.__pswa = value;
4841 return;
4842 case UNW_REG_SP:
4843 _registers.__gpr[15] = value;
4844 return;
4845 }
4846 _LIBUNWIND_ABORT("unsupported s390x register");
4847}
4848
4849inline bool Registers_s390x::validFloatRegister(int regNum) const {
4850 return regNum >= UNW_S390X_F0 && regNum <= UNW_S390X_F15;
4851}
4852
4853inline double Registers_s390x::getFloatRegister(int regNum) const {
4854 // NOTE: FPR DWARF register numbers are not consecutive.
4855 switch (regNum) {
4856 case UNW_S390X_F0:
4857 return _registers.__fpr[0];
4858 case UNW_S390X_F1:
4859 return _registers.__fpr[1];
4860 case UNW_S390X_F2:
4861 return _registers.__fpr[2];
4862 case UNW_S390X_F3:
4863 return _registers.__fpr[3];
4864 case UNW_S390X_F4:
4865 return _registers.__fpr[4];
4866 case UNW_S390X_F5:
4867 return _registers.__fpr[5];
4868 case UNW_S390X_F6:
4869 return _registers.__fpr[6];
4870 case UNW_S390X_F7:
4871 return _registers.__fpr[7];
4872 case UNW_S390X_F8:
4873 return _registers.__fpr[8];
4874 case UNW_S390X_F9:
4875 return _registers.__fpr[9];
4876 case UNW_S390X_F10:
4877 return _registers.__fpr[10];
4878 case UNW_S390X_F11:
4879 return _registers.__fpr[11];
4880 case UNW_S390X_F12:
4881 return _registers.__fpr[12];
4882 case UNW_S390X_F13:
4883 return _registers.__fpr[13];
4884 case UNW_S390X_F14:
4885 return _registers.__fpr[14];
4886 case UNW_S390X_F15:
4887 return _registers.__fpr[15];
4888 }
4889 _LIBUNWIND_ABORT("unsupported s390x register");
4890}
4891
4892inline void Registers_s390x::setFloatRegister(int regNum, double value) {
4893 // NOTE: FPR DWARF register numbers are not consecutive.
4894 switch (regNum) {
4895 case UNW_S390X_F0:
4896 _registers.__fpr[0] = value;
4897 return;
4898 case UNW_S390X_F1:
4899 _registers.__fpr[1] = value;
4900 return;
4901 case UNW_S390X_F2:
4902 _registers.__fpr[2] = value;
4903 return;
4904 case UNW_S390X_F3:
4905 _registers.__fpr[3] = value;
4906 return;
4907 case UNW_S390X_F4:
4908 _registers.__fpr[4] = value;
4909 return;
4910 case UNW_S390X_F5:
4911 _registers.__fpr[5] = value;
4912 return;
4913 case UNW_S390X_F6:
4914 _registers.__fpr[6] = value;
4915 return;
4916 case UNW_S390X_F7:
4917 _registers.__fpr[7] = value;
4918 return;
4919 case UNW_S390X_F8:
4920 _registers.__fpr[8] = value;
4921 return;
4922 case UNW_S390X_F9:
4923 _registers.__fpr[9] = value;
4924 return;
4925 case UNW_S390X_F10:
4926 _registers.__fpr[10] = value;
4927 return;
4928 case UNW_S390X_F11:
4929 _registers.__fpr[11] = value;
4930 return;
4931 case UNW_S390X_F12:
4932 _registers.__fpr[12] = value;
4933 return;
4934 case UNW_S390X_F13:
4935 _registers.__fpr[13] = value;
4936 return;
4937 case UNW_S390X_F14:
4938 _registers.__fpr[14] = value;
4939 return;
4940 case UNW_S390X_F15:
4941 _registers.__fpr[15] = value;
4942 return;
4943 }
4944 _LIBUNWIND_ABORT("unsupported s390x register");
4945}
4946
4947inline bool Registers_s390x::validVectorRegister(int /*regNum*/) const {
4948 return false;
4949}
4950
4951inline v128 Registers_s390x::getVectorRegister(int /*regNum*/) const {
4952 _LIBUNWIND_ABORT("s390x vector support not implemented");
4953}
4954
4955inline void Registers_s390x::setVectorRegister(int /*regNum*/, v128 /*value*/) {
4956 _LIBUNWIND_ABORT("s390x vector support not implemented");
4957}
4958
4959inline const char *Registers_s390x::getRegisterName(int regNum) {
4960 switch (regNum) {
4961 case UNW_REG_IP:
4962 return "ip";
4963 case UNW_REG_SP:
4964 return "sp";
4965 case UNW_S390X_R0:
4966 return "r0";
4967 case UNW_S390X_R1:
4968 return "r1";
4969 case UNW_S390X_R2:
4970 return "r2";
4971 case UNW_S390X_R3:
4972 return "r3";
4973 case UNW_S390X_R4:
4974 return "r4";
4975 case UNW_S390X_R5:
4976 return "r5";
4977 case UNW_S390X_R6:
4978 return "r6";
4979 case UNW_S390X_R7:
4980 return "r7";
4981 case UNW_S390X_R8:
4982 return "r8";
4983 case UNW_S390X_R9:
4984 return "r9";
4985 case UNW_S390X_R10:
4986 return "r10";
4987 case UNW_S390X_R11:
4988 return "r11";
4989 case UNW_S390X_R12:
4990 return "r12";
4991 case UNW_S390X_R13:
4992 return "r13";
4993 case UNW_S390X_R14:
4994 return "r14";
4995 case UNW_S390X_R15:
4996 return "r15";
4997 case UNW_S390X_F0:
4998 return "f0";
4999 case UNW_S390X_F1:
5000 return "f1";
5001 case UNW_S390X_F2:
5002 return "f2";
5003 case UNW_S390X_F3:
5004 return "f3";
5005 case UNW_S390X_F4:
5006 return "f4";
5007 case UNW_S390X_F5:
5008 return "f5";
5009 case UNW_S390X_F6:
5010 return "f6";
5011 case UNW_S390X_F7:
5012 return "f7";
5013 case UNW_S390X_F8:
5014 return "f8";
5015 case UNW_S390X_F9:
5016 return "f9";
5017 case UNW_S390X_F10:
5018 return "f10";
5019 case UNW_S390X_F11:
5020 return "f11";
5021 case UNW_S390X_F12:
5022 return "f12";
5023 case UNW_S390X_F13:
5024 return "f13";
5025 case UNW_S390X_F14:
5026 return "f14";
5027 case UNW_S390X_F15:
5028 return "f15";
5029 }
5030 return "unknown register";
5031}
5032#endif // _LIBUNWIND_TARGET_S390X
5033
5034
47155035} // namespace libunwind
47165036
47175037#endif // __REGISTERS_HPP__
lib/libunwind/src/Unwind-EHABI.cpp+5-4
......@@ -432,10 +432,11 @@ _Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data,
432432 uint32_t sp;
433433 uint32_t pac;
434434 _Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp);
435 _Unwind_VRS_Get(context, _UVRSC_PSEUDO, UNW_ARM_RA_AUTH_CODE,
436 _UVRSD_UINT32, &pac);
435 _Unwind_VRS_Get(context, _UVRSC_PSEUDO, 0, _UVRSD_UINT32, &pac);
437436 __asm__ __volatile__("autg %0, %1, %2" : : "r"(pac), "r"(lr), "r"(sp) :);
438437 }
438#else
439 (void)hasReturnAddrAuthCode;
439440#endif
440441 _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_IP, _UVRSD_UINT32, &lr);
441442 }
......@@ -1136,8 +1137,7 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
11361137 }
11371138 uint32_t pac = *sp++;
11381139 _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp);
1139 return _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_RA_AUTH_CODE,
1140 _UVRSD_UINT32, &pac);
1140 return _Unwind_VRS_Set(context, _UVRSC_PSEUDO, 0, _UVRSD_UINT32, &pac);
11411141 }
11421142 }
11431143 _LIBUNWIND_ABORT("unsupported register class");
......@@ -1193,6 +1193,7 @@ _Unwind_DeleteException(_Unwind_Exception *exception_object) {
11931193extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code
11941194__gnu_unwind_frame(_Unwind_Exception *exception_object,
11951195 struct _Unwind_Context *context) {
1196 (void)exception_object;
11961197 unw_cursor_t *cursor = (unw_cursor_t *)context;
11971198 switch (__unw_step(cursor)) {
11981199 case UNW_STEP_SUCCESS:
lib/libunwind/src/Unwind-seh.cpp+3-3
......@@ -104,7 +104,7 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx,
104104 if (!ctx) {
105105 __unw_init_seh(&cursor, disp->ContextRecord);
106106 __unw_seh_set_disp_ctx(&cursor, disp);
107 __unw_set_reg(&cursor, UNW_REG_IP, disp->ControlPc - 1);
107 __unw_set_reg(&cursor, UNW_REG_IP, disp->ControlPc);
108108 ctx = (struct _Unwind_Context *)&cursor;
109109
110110 if (!IS_UNWINDING(ms_exc->ExceptionFlags)) {
......@@ -255,8 +255,8 @@ unwind_phase2_forced(unw_context_t *uc,
255255 (frameInfo.start_ip + offset > frameInfo.end_ip))
256256 functionName = ".anonymous.";
257257 _LIBUNWIND_TRACE_UNWINDING(
258 "unwind_phase2_forced(ex_ojb=%p): start_ip=0x%" PRIx64
259 ", func=%s, lsda=0x%" PRIx64 ", personality=0x%" PRIx64,
258 "unwind_phase2_forced(ex_ojb=%p): start_ip=0x%" PRIxPTR
259 ", func=%s, lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR,
260260 (void *)exception_object, frameInfo.start_ip, functionName,
261261 frameInfo.lsda, frameInfo.handler);
262262 }
lib/libunwind/src/UnwindCursor.hpp+714-19
......@@ -24,6 +24,19 @@
2424#ifdef __APPLE__
2525 #include <mach-o/dyld.h>
2626#endif
27#ifdef _AIX
28#include <dlfcn.h>
29#include <sys/debug.h>
30#include <sys/pseg.h>
31#endif
32
33#if defined(_LIBUNWIND_TARGET_LINUX) && \
34 (defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_S390X))
35#include <sys/syscall.h>
36#include <sys/uio.h>
37#include <unistd.h>
38#define _LIBUNWIND_CHECK_LINUX_SIGRETURN 1
39#endif
2740
2841#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
2942// Provide a definition for the DISPATCHER_CONTEXT struct for old (Win7 and
......@@ -451,6 +464,12 @@ public:
451464 virtual void saveVFPAsX() { _LIBUNWIND_ABORT("saveVFPAsX not implemented"); }
452465#endif
453466
467#ifdef _AIX
468 virtual uintptr_t getDataRelBase() {
469 _LIBUNWIND_ABORT("getDataRelBase not implemented");
470 }
471#endif
472
454473#if defined(_LIBUNWIND_USE_CET)
455474 virtual void *get_registers() {
456475 _LIBUNWIND_ABORT("get_registers not implemented");
......@@ -499,6 +518,14 @@ private:
499518 pint_t getLastPC() const { return _dispContext.ControlPc; }
500519 void setLastPC(pint_t pc) { _dispContext.ControlPc = pc; }
501520 RUNTIME_FUNCTION *lookUpSEHUnwindInfo(pint_t pc, pint_t *base) {
521#ifdef __arm__
522 // Remove the thumb bit; FunctionEntry ranges don't include the thumb bit.
523 pc &= ~1U;
524#endif
525 // If pc points exactly at the end of the range, we might resolve the
526 // next function instead. Decrement pc by 1 to fit inside the current
527 // function.
528 pc -= 1;
502529 _dispContext.FunctionEntry = RtlLookupFunctionEntry(pc,
503530 &_dispContext.ImageBase,
504531 _dispContext.HistoryTable);
......@@ -844,7 +871,7 @@ void UnwindCursor<A, R>::setFloatReg(int regNum, unw_fpreg_t value) {
844871 uint32_t w;
845872 float f;
846873 } d;
847 d.f = value;
874 d.f = (float)value;
848875 _msContext.S[regNum - UNW_ARM_S0] = d.w;
849876 }
850877 if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D31) {
......@@ -910,9 +937,14 @@ public:
910937 virtual void saveVFPAsX();
911938#endif
912939
940#ifdef _AIX
941 virtual uintptr_t getDataRelBase();
942#endif
943
913944#if defined(_LIBUNWIND_USE_CET)
914945 virtual void *get_registers() { return &_registers; }
915946#endif
947
916948 // libunwind does not and should not depend on C++ library which means that we
917949 // need our own defition of inline placement new.
918950 static void *operator new(size_t, UnwindCursor<A, R> *p) { return p; }
......@@ -937,7 +969,7 @@ private:
937969 }
938970#endif
939971
940#if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
972#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
941973 bool setInfoForSigReturn() {
942974 R dummy;
943975 return setInfoForSigReturn(dummy);
......@@ -946,8 +978,14 @@ private:
946978 R dummy;
947979 return stepThroughSigReturn(dummy);
948980 }
981#if defined(_LIBUNWIND_TARGET_AARCH64)
949982 bool setInfoForSigReturn(Registers_arm64 &);
950983 int stepThroughSigReturn(Registers_arm64 &);
984#endif
985#if defined(_LIBUNWIND_TARGET_S390X)
986 bool setInfoForSigReturn(Registers_s390x &);
987 int stepThroughSigReturn(Registers_s390x &);
988#endif
951989 template <typename Registers> bool setInfoForSigReturn(Registers &) {
952990 return false;
953991 }
......@@ -1204,6 +1242,12 @@ private:
12041242 }
12051243#endif
12061244
1245#if defined (_LIBUNWIND_TARGET_S390X)
1246 compact_unwind_encoding_t dwarfEncoding(Registers_s390x &) const {
1247 return 0;
1248 }
1249#endif
1250
12071251#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
12081252
12091253#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
......@@ -1220,13 +1264,23 @@ private:
12201264 int stepWithSEHData() { /* FIXME: Implement */ return 0; }
12211265#endif // defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
12221266
1267#if defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
1268 bool getInfoFromTBTable(pint_t pc, R &registers);
1269 int stepWithTBTable(pint_t pc, tbtable *TBTable, R &registers,
1270 bool &isSignalFrame);
1271 int stepWithTBTableData() {
1272 return stepWithTBTable(reinterpret_cast<pint_t>(this->getReg(UNW_REG_IP)),
1273 reinterpret_cast<tbtable *>(_info.unwind_info),
1274 _registers, _isSignalFrame);
1275 }
1276#endif // defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
12231277
12241278 A &_addressSpace;
12251279 R _registers;
12261280 unw_proc_info_t _info;
12271281 bool _unwindInfoMissing;
12281282 bool _isSignalFrame;
1229#if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
1283#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
12301284 bool _isSigReturn = false;
12311285#endif
12321286};
......@@ -1292,6 +1346,13 @@ template <typename A, typename R> void UnwindCursor<A, R>::saveVFPAsX() {
12921346}
12931347#endif
12941348
1349#ifdef _AIX
1350template <typename A, typename R>
1351uintptr_t UnwindCursor<A, R>::getDataRelBase() {
1352 return reinterpret_cast<uintptr_t>(_info.extra);
1353}
1354#endif
1355
12951356template <typename A, typename R>
12961357const char *UnwindCursor<A, R>::getRegisterName(int regNum) {
12971358 return _registers.getRegisterName(regNum);
......@@ -1912,20 +1973,517 @@ bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) {
19121973 _info.handler = 0;
19131974 }
19141975 }
1915#elif defined(_LIBUNWIND_TARGET_ARM)
1916 _info.end_ip = _info.start_ip + unwindEntry->FunctionLength;
1917 _info.lsda = 0; // FIXME
1918 _info.handler = 0; // FIXME
19191976#endif
19201977 setLastPC(pc);
19211978 return true;
19221979}
19231980#endif
19241981
1982#if defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
1983// Masks for traceback table field xtbtable.
1984enum xTBTableMask : uint8_t {
1985 reservedBit = 0x02, // The traceback table was incorrectly generated if set
1986 // (see comments in function getInfoFromTBTable().
1987 ehInfoBit = 0x08 // Exception handling info is present if set
1988};
1989
1990enum frameType : unw_word_t {
1991 frameWithXLEHStateTable = 0,
1992 frameWithEHInfo = 1
1993};
1994
1995extern "C" {
1996typedef _Unwind_Reason_Code __xlcxx_personality_v0_t(int, _Unwind_Action,
1997 uint64_t,
1998 _Unwind_Exception *,
1999 struct _Unwind_Context *);
2000__attribute__((__weak__)) __xlcxx_personality_v0_t __xlcxx_personality_v0;
2001}
2002
2003static __xlcxx_personality_v0_t *xlcPersonalityV0;
2004static RWMutex xlcPersonalityV0InitLock;
2005
2006template <typename A, typename R>
2007bool UnwindCursor<A, R>::getInfoFromTBTable(pint_t pc, R &registers) {
2008 uint32_t *p = reinterpret_cast<uint32_t *>(pc);
2009
2010 // Keep looking forward until a word of 0 is found. The traceback
2011 // table starts at the following word.
2012 while (*p)
2013 ++p;
2014 tbtable *TBTable = reinterpret_cast<tbtable *>(p + 1);
2015
2016 if (_LIBUNWIND_TRACING_UNWINDING) {
2017 char functionBuf[512];
2018 const char *functionName = functionBuf;
2019 unw_word_t offset;
2020 if (!getFunctionName(functionBuf, sizeof(functionBuf), &offset)) {
2021 functionName = ".anonymous.";
2022 }
2023 _LIBUNWIND_TRACE_UNWINDING("%s: Look up traceback table of func=%s at %p",
2024 __func__, functionName,
2025 reinterpret_cast<void *>(TBTable));
2026 }
2027
2028 // If the traceback table does not contain necessary info, bypass this frame.
2029 if (!TBTable->tb.has_tboff)
2030 return false;
2031
2032 // Structure tbtable_ext contains important data we are looking for.
2033 p = reinterpret_cast<uint32_t *>(&TBTable->tb_ext);
2034
2035 // Skip field parminfo if it exists.
2036 if (TBTable->tb.fixedparms || TBTable->tb.floatparms)
2037 ++p;
2038
2039 // p now points to tb_offset, the offset from start of function to TB table.
2040 unw_word_t start_ip =
2041 reinterpret_cast<unw_word_t>(TBTable) - *p - sizeof(uint32_t);
2042 unw_word_t end_ip = reinterpret_cast<unw_word_t>(TBTable);
2043 ++p;
2044
2045 _LIBUNWIND_TRACE_UNWINDING("start_ip=%p, end_ip=%p\n",
2046 reinterpret_cast<void *>(start_ip),
2047 reinterpret_cast<void *>(end_ip));
2048
2049 // Skip field hand_mask if it exists.
2050 if (TBTable->tb.int_hndl)
2051 ++p;
2052
2053 unw_word_t lsda = 0;
2054 unw_word_t handler = 0;
2055 unw_word_t flags = frameType::frameWithXLEHStateTable;
2056
2057 if (TBTable->tb.lang == TB_CPLUSPLUS && TBTable->tb.has_ctl) {
2058 // State table info is available. The ctl_info field indicates the
2059 // number of CTL anchors. There should be only one entry for the C++
2060 // state table.
2061 assert(*p == 1 && "libunwind: there must be only one ctl_info entry");
2062 ++p;
2063 // p points to the offset of the state table into the stack.
2064 pint_t stateTableOffset = *p++;
2065
2066 int framePointerReg;
2067
2068 // Skip fields name_len and name if exist.
2069 if (TBTable->tb.name_present) {
2070 const uint16_t name_len = *(reinterpret_cast<uint16_t *>(p));
2071 p = reinterpret_cast<uint32_t *>(reinterpret_cast<char *>(p) + name_len +
2072 sizeof(uint16_t));
2073 }
2074
2075 if (TBTable->tb.uses_alloca)
2076 framePointerReg = *(reinterpret_cast<char *>(p));
2077 else
2078 framePointerReg = 1; // default frame pointer == SP
2079
2080 _LIBUNWIND_TRACE_UNWINDING(
2081 "framePointerReg=%d, framePointer=%p, "
2082 "stateTableOffset=%#lx\n",
2083 framePointerReg,
2084 reinterpret_cast<void *>(_registers.getRegister(framePointerReg)),
2085 stateTableOffset);
2086 lsda = _registers.getRegister(framePointerReg) + stateTableOffset;
2087
2088 // Since the traceback table generated by the legacy XLC++ does not
2089 // provide the location of the personality for the state table,
2090 // function __xlcxx_personality_v0(), which is the personality for the state
2091 // table and is exported from libc++abi, is directly assigned as the
2092 // handler here. When a legacy XLC++ frame is encountered, the symbol
2093 // is resolved dynamically using dlopen() to avoid hard dependency from
2094 // libunwind on libc++abi.
2095
2096 // Resolve the function pointer to the state table personality if it has
2097 // not already.
2098 if (xlcPersonalityV0 == NULL) {
2099 xlcPersonalityV0InitLock.lock();
2100 if (xlcPersonalityV0 == NULL) {
2101 // If libc++abi is statically linked in, symbol __xlcxx_personality_v0
2102 // has been resolved at the link time.
2103 xlcPersonalityV0 = &__xlcxx_personality_v0;
2104 if (xlcPersonalityV0 == NULL) {
2105 // libc++abi is dynamically linked. Resolve __xlcxx_personality_v0
2106 // using dlopen().
2107 const char libcxxabi[] = "libc++abi.a(libc++abi.so.1)";
2108 void *libHandle;
2109 libHandle = dlopen(libcxxabi, RTLD_MEMBER | RTLD_NOW);
2110 if (libHandle == NULL) {
2111 _LIBUNWIND_TRACE_UNWINDING("dlopen() failed with errno=%d\n",
2112 errno);
2113 assert(0 && "dlopen() failed");
2114 }
2115 xlcPersonalityV0 = reinterpret_cast<__xlcxx_personality_v0_t *>(
2116 dlsym(libHandle, "__xlcxx_personality_v0"));
2117 if (xlcPersonalityV0 == NULL) {
2118 _LIBUNWIND_TRACE_UNWINDING("dlsym() failed with errno=%d\n", errno);
2119 assert(0 && "dlsym() failed");
2120 }
2121 dlclose(libHandle);
2122 }
2123 }
2124 xlcPersonalityV0InitLock.unlock();
2125 }
2126 handler = reinterpret_cast<unw_word_t>(xlcPersonalityV0);
2127 _LIBUNWIND_TRACE_UNWINDING("State table: LSDA=%p, Personality=%p\n",
2128 reinterpret_cast<void *>(lsda),
2129 reinterpret_cast<void *>(handler));
2130 } else if (TBTable->tb.longtbtable) {
2131 // This frame has the traceback table extension. Possible cases are
2132 // 1) a C++ frame that has the 'eh_info' structure; 2) a C++ frame that
2133 // is not EH aware; or, 3) a frame of other languages. We need to figure out
2134 // if the traceback table extension contains the 'eh_info' structure.
2135 //
2136 // We also need to deal with the complexity arising from some XL compiler
2137 // versions use the wrong ordering of 'longtbtable' and 'has_vec' bits
2138 // where the 'longtbtable' bit is meant to be the 'has_vec' bit and vice
2139 // versa. For frames of code generated by those compilers, the 'longtbtable'
2140 // bit may be set but there isn't really a traceback table extension.
2141 //
2142 // In </usr/include/sys/debug.h>, there is the following definition of
2143 // 'struct tbtable_ext'. It is not really a structure but a dummy to
2144 // collect the description of optional parts of the traceback table.
2145 //
2146 // struct tbtable_ext {
2147 // ...
2148 // char alloca_reg; /* Register for alloca automatic storage */
2149 // struct vec_ext vec_ext; /* Vector extension (if has_vec is set) */
2150 // unsigned char xtbtable; /* More tbtable fields, if longtbtable is set*/
2151 // };
2152 //
2153 // Depending on how the 'has_vec'/'longtbtable' bit is interpreted, the data
2154 // following 'alloca_reg' can be treated either as 'struct vec_ext' or
2155 // 'unsigned char xtbtable'. 'xtbtable' bits are defined in
2156 // </usr/include/sys/debug.h> as flags. The 7th bit '0x02' is currently
2157 // unused and should not be set. 'struct vec_ext' is defined in
2158 // </usr/include/sys/debug.h> as follows:
2159 //
2160 // struct vec_ext {
2161 // unsigned vr_saved:6; /* Number of non-volatile vector regs saved
2162 // */
2163 // /* first register saved is assumed to be */
2164 // /* 32 - vr_saved */
2165 // unsigned saves_vrsave:1; /* Set if vrsave is saved on the stack */
2166 // unsigned has_varargs:1;
2167 // ...
2168 // };
2169 //
2170 // Here, the 7th bit is used as 'saves_vrsave'. To determine whether it
2171 // is 'struct vec_ext' or 'xtbtable' that follows 'alloca_reg',
2172 // we checks if the 7th bit is set or not because 'xtbtable' should
2173 // never have the 7th bit set. The 7th bit of 'xtbtable' will be reserved
2174 // in the future to make sure the mitigation works. This mitigation
2175 // is not 100% bullet proof because 'struct vec_ext' may not always have
2176 // 'saves_vrsave' bit set.
2177 //
2178 // 'reservedBit' is defined in enum 'xTBTableMask' above as the mask for
2179 // checking the 7th bit.
2180
2181 // p points to field name len.
2182 uint8_t *charPtr = reinterpret_cast<uint8_t *>(p);
2183
2184 // Skip fields name_len and name if they exist.
2185 if (TBTable->tb.name_present) {
2186 const uint16_t name_len = *(reinterpret_cast<uint16_t *>(charPtr));
2187 charPtr = charPtr + name_len + sizeof(uint16_t);
2188 }
2189
2190 // Skip field alloc_reg if it exists.
2191 if (TBTable->tb.uses_alloca)
2192 ++charPtr;
2193
2194 // Check traceback table bit has_vec. Skip struct vec_ext if it exists.
2195 if (TBTable->tb.has_vec)
2196 // Note struct vec_ext does exist at this point because whether the
2197 // ordering of longtbtable and has_vec bits is correct or not, both
2198 // are set.
2199 charPtr += sizeof(struct vec_ext);
2200
2201 // charPtr points to field 'xtbtable'. Check if the EH info is available.
2202 // Also check if the reserved bit of the extended traceback table field
2203 // 'xtbtable' is set. If it is, the traceback table was incorrectly
2204 // generated by an XL compiler that uses the wrong ordering of 'longtbtable'
2205 // and 'has_vec' bits and this is in fact 'struct vec_ext'. So skip the
2206 // frame.
2207 if ((*charPtr & xTBTableMask::ehInfoBit) &&
2208 !(*charPtr & xTBTableMask::reservedBit)) {
2209 // Mark this frame has the new EH info.
2210 flags = frameType::frameWithEHInfo;
2211
2212 // eh_info is available.
2213 charPtr++;
2214 // The pointer is 4-byte aligned.
2215 if (reinterpret_cast<uintptr_t>(charPtr) % 4)
2216 charPtr += 4 - reinterpret_cast<uintptr_t>(charPtr) % 4;
2217 uintptr_t *ehInfo =
2218 reinterpret_cast<uintptr_t *>(*(reinterpret_cast<uintptr_t *>(
2219 registers.getRegister(2) +
2220 *(reinterpret_cast<uintptr_t *>(charPtr)))));
2221
2222 // ehInfo points to structure en_info. The first member is version.
2223 // Only version 0 is currently supported.
2224 assert(*(reinterpret_cast<uint32_t *>(ehInfo)) == 0 &&
2225 "libunwind: ehInfo version other than 0 is not supported");
2226
2227 // Increment ehInfo to point to member lsda.
2228 ++ehInfo;
2229 lsda = *ehInfo++;
2230
2231 // enInfo now points to member personality.
2232 handler = *ehInfo;
2233
2234 _LIBUNWIND_TRACE_UNWINDING("Range table: LSDA=%#lx, Personality=%#lx\n",
2235 lsda, handler);
2236 }
2237 }
2238
2239 _info.start_ip = start_ip;
2240 _info.end_ip = end_ip;
2241 _info.lsda = lsda;
2242 _info.handler = handler;
2243 _info.gp = 0;
2244 _info.flags = flags;
2245 _info.format = 0;
2246 _info.unwind_info = reinterpret_cast<unw_word_t>(TBTable);
2247 _info.unwind_info_size = 0;
2248 _info.extra = registers.getRegister(2);
2249
2250 return true;
2251}
2252
2253// Step back up the stack following the frame back link.
2254template <typename A, typename R>
2255int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
2256 R &registers, bool &isSignalFrame) {
2257 if (_LIBUNWIND_TRACING_UNWINDING) {
2258 char functionBuf[512];
2259 const char *functionName = functionBuf;
2260 unw_word_t offset;
2261 if (!getFunctionName(functionBuf, sizeof(functionBuf), &offset)) {
2262 functionName = ".anonymous.";
2263 }
2264 _LIBUNWIND_TRACE_UNWINDING("%s: Look up traceback table of func=%s at %p",
2265 __func__, functionName,
2266 reinterpret_cast<void *>(TBTable));
2267 }
2268
2269#if defined(__powerpc64__)
2270 // Instruction to reload TOC register "l r2,40(r1)"
2271 const uint32_t loadTOCRegInst = 0xe8410028;
2272 const int32_t unwPPCF0Index = UNW_PPC64_F0;
2273 const int32_t unwPPCV0Index = UNW_PPC64_V0;
2274#else
2275 // Instruction to reload TOC register "l r2,20(r1)"
2276 const uint32_t loadTOCRegInst = 0x80410014;
2277 const int32_t unwPPCF0Index = UNW_PPC_F0;
2278 const int32_t unwPPCV0Index = UNW_PPC_V0;
2279#endif
2280
2281 R newRegisters = registers;
2282
2283 // lastStack points to the stack frame of the next routine up.
2284 pint_t lastStack = *(reinterpret_cast<pint_t *>(registers.getSP()));
2285
2286 // Return address is the address after call site instruction.
2287 pint_t returnAddress;
2288
2289 if (isSignalFrame) {
2290 _LIBUNWIND_TRACE_UNWINDING("Possible signal handler frame: lastStack=%p",
2291 reinterpret_cast<void *>(lastStack));
2292
2293 sigcontext *sigContext = reinterpret_cast<sigcontext *>(
2294 reinterpret_cast<char *>(lastStack) + STKMIN);
2295 returnAddress = sigContext->sc_jmpbuf.jmp_context.iar;
2296
2297 _LIBUNWIND_TRACE_UNWINDING("From sigContext=%p, returnAddress=%p\n",
2298 reinterpret_cast<void *>(sigContext),
2299 reinterpret_cast<void *>(returnAddress));
2300
2301 if (returnAddress < 0x10000000) {
2302 // Try again using STKMINALIGN
2303 sigContext = reinterpret_cast<sigcontext *>(
2304 reinterpret_cast<char *>(lastStack) + STKMINALIGN);
2305 returnAddress = sigContext->sc_jmpbuf.jmp_context.iar;
2306 if (returnAddress < 0x10000000) {
2307 _LIBUNWIND_TRACE_UNWINDING("Bad returnAddress=%p\n",
2308 reinterpret_cast<void *>(returnAddress));
2309 return UNW_EBADFRAME;
2310 } else {
2311 _LIBUNWIND_TRACE_UNWINDING("Tried again using STKMINALIGN: "
2312 "sigContext=%p, returnAddress=%p. "
2313 "Seems to be a valid address\n",
2314 reinterpret_cast<void *>(sigContext),
2315 reinterpret_cast<void *>(returnAddress));
2316 }
2317 }
2318 // Restore the condition register from sigcontext.
2319 newRegisters.setCR(sigContext->sc_jmpbuf.jmp_context.cr);
2320
2321 // Restore GPRs from sigcontext.
2322 for (int i = 0; i < 32; ++i)
2323 newRegisters.setRegister(i, sigContext->sc_jmpbuf.jmp_context.gpr[i]);
2324
2325 // Restore FPRs from sigcontext.
2326 for (int i = 0; i < 32; ++i)
2327 newRegisters.setFloatRegister(i + unwPPCF0Index,
2328 sigContext->sc_jmpbuf.jmp_context.fpr[i]);
2329
2330 // Restore vector registers if there is an associated extended context
2331 // structure.
2332 if (sigContext->sc_jmpbuf.jmp_context.msr & __EXTCTX) {
2333 ucontext_t *uContext = reinterpret_cast<ucontext_t *>(sigContext);
2334 if (uContext->__extctx->__extctx_magic == __EXTCTX_MAGIC) {
2335 for (int i = 0; i < 32; ++i)
2336 newRegisters.setVectorRegister(
2337 i + unwPPCV0Index, *(reinterpret_cast<v128 *>(
2338 &(uContext->__extctx->__vmx.__vr[i]))));
2339 }
2340 }
2341 } else {
2342 // Step up a normal frame.
2343 returnAddress = reinterpret_cast<pint_t *>(lastStack)[2];
2344
2345 _LIBUNWIND_TRACE_UNWINDING("Extract info from lastStack=%p, "
2346 "returnAddress=%p\n",
2347 reinterpret_cast<void *>(lastStack),
2348 reinterpret_cast<void *>(returnAddress));
2349 _LIBUNWIND_TRACE_UNWINDING("fpr_regs=%d, gpr_regs=%d, saves_cr=%d\n",
2350 TBTable->tb.fpr_saved, TBTable->tb.gpr_saved,
2351 TBTable->tb.saves_cr);
2352
2353 // Restore FP registers.
2354 char *ptrToRegs = reinterpret_cast<char *>(lastStack);
2355 double *FPRegs = reinterpret_cast<double *>(
2356 ptrToRegs - (TBTable->tb.fpr_saved * sizeof(double)));
2357 for (int i = 0; i < TBTable->tb.fpr_saved; ++i)
2358 newRegisters.setFloatRegister(
2359 32 - TBTable->tb.fpr_saved + i + unwPPCF0Index, FPRegs[i]);
2360
2361 // Restore GP registers.
2362 ptrToRegs = reinterpret_cast<char *>(FPRegs);
2363 uintptr_t *GPRegs = reinterpret_cast<uintptr_t *>(
2364 ptrToRegs - (TBTable->tb.gpr_saved * sizeof(uintptr_t)));
2365 for (int i = 0; i < TBTable->tb.gpr_saved; ++i)
2366 newRegisters.setRegister(32 - TBTable->tb.gpr_saved + i, GPRegs[i]);
2367
2368 // Restore Vector registers.
2369 ptrToRegs = reinterpret_cast<char *>(GPRegs);
2370
2371 // Restore vector registers only if this is a Clang frame. Also
2372 // check if traceback table bit has_vec is set. If it is, structure
2373 // vec_ext is available.
2374 if (_info.flags == frameType::frameWithEHInfo && TBTable->tb.has_vec) {
2375
2376 // Get to the vec_ext structure to check if vector registers are saved.
2377 uint32_t *p = reinterpret_cast<uint32_t *>(&TBTable->tb_ext);
2378
2379 // Skip field parminfo if exists.
2380 if (TBTable->tb.fixedparms || TBTable->tb.floatparms)
2381 ++p;
2382
2383 // Skip field tb_offset if exists.
2384 if (TBTable->tb.has_tboff)
2385 ++p;
2386
2387 // Skip field hand_mask if exists.
2388 if (TBTable->tb.int_hndl)
2389 ++p;
2390
2391 // Skip fields ctl_info and ctl_info_disp if exist.
2392 if (TBTable->tb.has_ctl) {
2393 // Skip field ctl_info.
2394 ++p;
2395 // Skip field ctl_info_disp.
2396 ++p;
2397 }
2398
2399 // Skip fields name_len and name if exist.
2400 // p is supposed to point to field name_len now.
2401 uint8_t *charPtr = reinterpret_cast<uint8_t *>(p);
2402 if (TBTable->tb.name_present) {
2403 const uint16_t name_len = *(reinterpret_cast<uint16_t *>(charPtr));
2404 charPtr = charPtr + name_len + sizeof(uint16_t);
2405 }
2406
2407 // Skip field alloc_reg if it exists.
2408 if (TBTable->tb.uses_alloca)
2409 ++charPtr;
2410
2411 struct vec_ext *vec_ext = reinterpret_cast<struct vec_ext *>(charPtr);
2412
2413 _LIBUNWIND_TRACE_UNWINDING("vr_saved=%d\n", vec_ext->vr_saved);
2414
2415 // Restore vector register(s) if saved on the stack.
2416 if (vec_ext->vr_saved) {
2417 // Saved vector registers are 16-byte aligned.
2418 if (reinterpret_cast<uintptr_t>(ptrToRegs) % 16)
2419 ptrToRegs -= reinterpret_cast<uintptr_t>(ptrToRegs) % 16;
2420 v128 *VecRegs = reinterpret_cast<v128 *>(ptrToRegs - vec_ext->vr_saved *
2421 sizeof(v128));
2422 for (int i = 0; i < vec_ext->vr_saved; ++i) {
2423 newRegisters.setVectorRegister(
2424 32 - vec_ext->vr_saved + i + unwPPCV0Index, VecRegs[i]);
2425 }
2426 }
2427 }
2428 if (TBTable->tb.saves_cr) {
2429 // Get the saved condition register. The condition register is only
2430 // a single word.
2431 newRegisters.setCR(
2432 *(reinterpret_cast<uint32_t *>(lastStack + sizeof(uintptr_t))));
2433 }
2434
2435 // Restore the SP.
2436 newRegisters.setSP(lastStack);
2437
2438 // The first instruction after return.
2439 uint32_t firstInstruction = *(reinterpret_cast<uint32_t *>(returnAddress));
2440
2441 // Do we need to set the TOC register?
2442 _LIBUNWIND_TRACE_UNWINDING(
2443 "Current gpr2=%p\n",
2444 reinterpret_cast<void *>(newRegisters.getRegister(2)));
2445 if (firstInstruction == loadTOCRegInst) {
2446 _LIBUNWIND_TRACE_UNWINDING(
2447 "Set gpr2=%p from frame\n",
2448 reinterpret_cast<void *>(reinterpret_cast<pint_t *>(lastStack)[5]));
2449 newRegisters.setRegister(2, reinterpret_cast<pint_t *>(lastStack)[5]);
2450 }
2451 }
2452 _LIBUNWIND_TRACE_UNWINDING("lastStack=%p, returnAddress=%p, pc=%p\n",
2453 reinterpret_cast<void *>(lastStack),
2454 reinterpret_cast<void *>(returnAddress),
2455 reinterpret_cast<void *>(pc));
2456
2457 // The return address is the address after call site instruction, so
2458 // setting IP to that simualates a return.
2459 newRegisters.setIP(reinterpret_cast<uintptr_t>(returnAddress));
2460
2461 // Simulate the step by replacing the register set with the new ones.
2462 registers = newRegisters;
2463
2464 // Check if the next frame is a signal frame.
2465 pint_t nextStack = *(reinterpret_cast<pint_t *>(registers.getSP()));
2466
2467 // Return address is the address after call site instruction.
2468 pint_t nextReturnAddress = reinterpret_cast<pint_t *>(nextStack)[2];
2469
2470 if (nextReturnAddress > 0x01 && nextReturnAddress < 0x10000) {
2471 _LIBUNWIND_TRACE_UNWINDING("The next is a signal handler frame: "
2472 "nextStack=%p, next return address=%p\n",
2473 reinterpret_cast<void *>(nextStack),
2474 reinterpret_cast<void *>(nextReturnAddress));
2475 isSignalFrame = true;
2476 } else {
2477 isSignalFrame = false;
2478 }
2479
2480 return UNW_STEP_SUCCESS;
2481}
2482#endif // defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
19252483
19262484template <typename A, typename R>
19272485void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
1928#if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
2486#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
19292487 _isSigReturn = false;
19302488#endif
19312489
......@@ -1948,7 +2506,14 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
19482506 // To disambiguate this, back up the pc when we know it is a return
19492507 // address.
19502508 if (isReturnAddress)
2509#if defined(_AIX)
2510 // PC needs to be a 4-byte aligned address to be able to look for a
2511 // word of 0 that indicates the start of the traceback table at the end
2512 // of a function on AIX.
2513 pc -= 4;
2514#else
19512515 --pc;
2516#endif
19522517
19532518 // Ask address space object to find unwind sections for this pc.
19542519 UnwindInfoSections sects;
......@@ -1982,6 +2547,12 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
19822547 return;
19832548#endif
19842549
2550#if defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
2551 // If there is unwind info in the traceback table, look there next.
2552 if (this->getInfoFromTBTable(pc, _registers))
2553 return;
2554#endif
2555
19852556#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
19862557 // If there is dwarf unwind info, look there next.
19872558 if (sects.dwarf_section != 0) {
......@@ -2027,7 +2598,7 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
20272598 }
20282599#endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
20292600
2030#if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
2601#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
20312602 if (setInfoForSigReturn())
20322603 return;
20332604#endif
......@@ -2036,7 +2607,8 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
20362607 _unwindInfoMissing = true;
20372608}
20382609
2039#if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
2610#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \
2611 defined(_LIBUNWIND_TARGET_AARCH64)
20402612template <typename A, typename R>
20412613bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_arm64 &) {
20422614 // Look for the sigreturn trampoline. The trampoline's body is two
......@@ -2055,14 +2627,28 @@ bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_arm64 &) {
20552627 //
20562628 // [1] https://github.com/torvalds/linux/blob/master/arch/arm64/kernel/vdso/sigreturn.S
20572629 const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
2630 // The PC might contain an invalid address if the unwind info is bad, so
2631 // directly accessing it could cause a segfault. Use process_vm_readv to read
2632 // the memory safely instead. process_vm_readv was added in Linux 3.2, and
2633 // AArch64 supported was added in Linux 3.7, so the syscall is guaranteed to
2634 // be present. Unfortunately, there are Linux AArch64 environments where the
2635 // libc wrapper for the syscall might not be present (e.g. Android 5), so call
2636 // the syscall directly instead.
2637 uint32_t instructions[2];
2638 struct iovec local_iov = {&instructions, sizeof instructions};
2639 struct iovec remote_iov = {reinterpret_cast<void *>(pc), sizeof instructions};
2640 long bytesRead =
2641 syscall(SYS_process_vm_readv, getpid(), &local_iov, 1, &remote_iov, 1, 0);
20582642 // Look for instructions: mov x8, #0x8b; svc #0x0
2059 if (_addressSpace.get32(pc) == 0xd2801168 &&
2060 _addressSpace.get32(pc + 4) == 0xd4000001) {
2061 _info = {};
2062 _isSigReturn = true;
2063 return true;
2064 }
2065 return false;
2643 if (bytesRead != sizeof instructions || instructions[0] != 0xd2801168 ||
2644 instructions[1] != 0xd4000001)
2645 return false;
2646
2647 _info = {};
2648 _info.start_ip = pc;
2649 _info.end_ip = pc + 4;
2650 _isSigReturn = true;
2651 return true;
20662652}
20672653
20682654template <typename A, typename R>
......@@ -2096,7 +2682,114 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) {
20962682 _isSignalFrame = true;
20972683 return UNW_STEP_SUCCESS;
20982684}
2099#endif // defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
2685#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
2686 // defined(_LIBUNWIND_TARGET_AARCH64)
2687
2688#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \
2689 defined(_LIBUNWIND_TARGET_S390X)
2690template <typename A, typename R>
2691bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_s390x &) {
2692 // Look for the sigreturn trampoline. The trampoline's body is a
2693 // specific instruction (see below). Typically the trampoline comes from the
2694 // vDSO (i.e. the __kernel_[rt_]sigreturn function). A libc might provide its
2695 // own restorer function, though, or user-mode QEMU might write a trampoline
2696 // onto the stack.
2697 const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
2698 // The PC might contain an invalid address if the unwind info is bad, so
2699 // directly accessing it could cause a segfault. Use process_vm_readv to
2700 // read the memory safely instead.
2701 uint16_t inst;
2702 struct iovec local_iov = {&inst, sizeof inst};
2703 struct iovec remote_iov = {reinterpret_cast<void *>(pc), sizeof inst};
2704 long bytesRead = process_vm_readv(getpid(), &local_iov, 1, &remote_iov, 1, 0);
2705 if (bytesRead == sizeof inst && (inst == 0x0a77 || inst == 0x0aad)) {
2706 _info = {};
2707 _info.start_ip = pc;
2708 _info.end_ip = pc + 2;
2709 _isSigReturn = true;
2710 return true;
2711 }
2712 return false;
2713}
2714
2715template <typename A, typename R>
2716int UnwindCursor<A, R>::stepThroughSigReturn(Registers_s390x &) {
2717 // Determine current SP.
2718 const pint_t sp = static_cast<pint_t>(this->getReg(UNW_REG_SP));
2719 // According to the s390x ABI, the CFA is at (incoming) SP + 160.
2720 const pint_t cfa = sp + 160;
2721
2722 // Determine current PC and instruction there (this must be either
2723 // a "svc __NR_sigreturn" or "svc __NR_rt_sigreturn").
2724 const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
2725 const uint16_t inst = _addressSpace.get16(pc);
2726
2727 // Find the addresses of the signo and sigcontext in the frame.
2728 pint_t pSigctx = 0;
2729 pint_t pSigno = 0;
2730
2731 // "svc __NR_sigreturn" uses a non-RT signal trampoline frame.
2732 if (inst == 0x0a77) {
2733 // Layout of a non-RT signal trampoline frame, starting at the CFA:
2734 // - 8-byte signal mask
2735 // - 8-byte pointer to sigcontext, followed by signo
2736 // - 4-byte signo
2737 pSigctx = _addressSpace.get64(cfa + 8);
2738 pSigno = pSigctx + 344;
2739 }
2740
2741 // "svc __NR_rt_sigreturn" uses a RT signal trampoline frame.
2742 if (inst == 0x0aad) {
2743 // Layout of a RT signal trampoline frame, starting at the CFA:
2744 // - 8-byte retcode (+ alignment)
2745 // - 128-byte siginfo struct (starts with signo)
2746 // - ucontext struct:
2747 // - 8-byte long (uc_flags)
2748 // - 8-byte pointer (uc_link)
2749 // - 24-byte stack_t
2750 // - 8 bytes of padding because sigcontext has 16-byte alignment
2751 // - sigcontext/mcontext_t
2752 pSigctx = cfa + 8 + 128 + 8 + 8 + 24 + 8;
2753 pSigno = cfa + 8;
2754 }
2755
2756 assert(pSigctx != 0);
2757 assert(pSigno != 0);
2758
2759 // Offsets from sigcontext to each register.
2760 const pint_t kOffsetPc = 8;
2761 const pint_t kOffsetGprs = 16;
2762 const pint_t kOffsetFprs = 216;
2763
2764 // Restore all registers.
2765 for (int i = 0; i < 16; ++i) {
2766 uint64_t value = _addressSpace.get64(pSigctx + kOffsetGprs +
2767 static_cast<pint_t>(i * 8));
2768 _registers.setRegister(UNW_S390X_R0 + i, value);
2769 }
2770 for (int i = 0; i < 16; ++i) {
2771 static const int fpr[16] = {
2772 UNW_S390X_F0, UNW_S390X_F1, UNW_S390X_F2, UNW_S390X_F3,
2773 UNW_S390X_F4, UNW_S390X_F5, UNW_S390X_F6, UNW_S390X_F7,
2774 UNW_S390X_F8, UNW_S390X_F9, UNW_S390X_F10, UNW_S390X_F11,
2775 UNW_S390X_F12, UNW_S390X_F13, UNW_S390X_F14, UNW_S390X_F15
2776 };
2777 double value = _addressSpace.getDouble(pSigctx + kOffsetFprs +
2778 static_cast<pint_t>(i * 8));
2779 _registers.setFloatRegister(fpr[i], value);
2780 }
2781 _registers.setIP(_addressSpace.get64(pSigctx + kOffsetPc));
2782
2783 // SIGILL, SIGFPE and SIGTRAP are delivered with psw_addr
2784 // after the faulting instruction rather than before it.
2785 // Do not set _isSignalFrame in that case.
2786 uint32_t signo = _addressSpace.get32(pSigno);
2787 _isSignalFrame = (signo != 4 && signo != 5 && signo != 8);
2788
2789 return UNW_STEP_SUCCESS;
2790}
2791#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
2792 // defined(_LIBUNWIND_TARGET_S390X)
21002793
21012794template <typename A, typename R>
21022795int UnwindCursor<A, R>::step() {
......@@ -2106,7 +2799,7 @@ int UnwindCursor<A, R>::step() {
21062799
21072800 // Use unwinding info to modify register set as if function returned.
21082801 int result;
2109#if defined(_LIBUNWIND_TARGET_LINUX) && defined(_LIBUNWIND_TARGET_AARCH64)
2802#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
21102803 if (_isSigReturn) {
21112804 result = this->stepThroughSigReturn();
21122805 } else
......@@ -2116,6 +2809,8 @@ int UnwindCursor<A, R>::step() {
21162809 result = this->stepWithCompactEncoding();
21172810#elif defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
21182811 result = this->stepWithSEHData();
2812#elif defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
2813 result = this->stepWithTBTableData();
21192814#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
21202815 result = this->stepWithDwarfFDE();
21212816#elif defined(_LIBUNWIND_ARM_EHABI)
lib/libunwind/src/UnwindLevel1-gcc-ext.c+5-2
......@@ -59,12 +59,15 @@ _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) {
5959/// relative encodings.
6060_LIBUNWIND_EXPORT uintptr_t
6161_Unwind_GetDataRelBase(struct _Unwind_Context *context) {
62 (void)context;
6362 _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)", (void *)context);
63#if defined(_AIX)
64 return unw_get_data_rel_base((unw_cursor_t *)context);
65#else
66 (void)context;
6467 _LIBUNWIND_ABORT("_Unwind_GetDataRelBase() not implemented");
68#endif
6569}
6670
67
6871/// Called by personality handler during phase 2 to get base address for text
6972/// relative encodings.
7073_LIBUNWIND_EXPORT uintptr_t
lib/libunwind/src/UnwindLevel1.c+7-1
......@@ -44,7 +44,11 @@
4444// directly jump to __libunwind_Registerts_x86/x86_64_jumpto instead of using
4545// a regular function call to avoid pushing to CET shadow stack again.
4646#if !defined(_LIBUNWIND_USE_CET)
47#define __unw_phase2_resume(cursor, fn) __unw_resume((cursor))
47#define __unw_phase2_resume(cursor, fn) \
48 do { \
49 (void)fn; \
50 __unw_resume((cursor)); \
51 } while (0)
4852#elif defined(_LIBUNWIND_TARGET_I386)
4953#define __unw_phase2_resume(cursor, fn) \
5054 do { \
......@@ -480,11 +484,13 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
480484 _LIBUNWIND_TRACE_API(
481485 "_Unwind_GetLanguageSpecificData(context=%p) => 0x%" PRIxPTR,
482486 (void *)context, result);
487#if !defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
483488 if (result != 0) {
484489 if (*((uint8_t *)result) != 0xFF)
485490 _LIBUNWIND_DEBUG_LOG("lsda at 0x%" PRIxPTR " does not start with 0xFF",
486491 result);
487492 }
493#endif
488494 return result;
489495}
490496
lib/libunwind/src/UnwindRegistersRestore.S+138-61
......@@ -8,7 +8,11 @@
88
99#include "assembly.h"
1010
11#if defined(_AIX)
12 .toc
13#else
1114 .text
15#endif
1216
1317#if !defined(__USING_SJLJ_EXCEPTIONS__)
1418
......@@ -222,27 +226,36 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv)
222226 PPC64_LVS(30)
223227 PPC64_LVS(31)
224228
225 // use VRSAVE to conditionally restore the remaining VS regs,
226 // that are where the V regs are mapped
229#define PPC64_CLVS_RESTORE(n) \
230 addi 4, 3, PPC64_OFFS_FP + n * 16 ;\
231 lxvd2x n, 0, 4
227232
233#if !defined(_AIX)
234 // use VRSAVE to conditionally restore the remaining VS regs, that are
235 // where the V regs are mapped. In the AIX ABI, VRSAVE is not used.
228236 ld 5, PPC64_OFFS_VRSAVE(3) // test VRsave
229237 cmpwi 5, 0
230238 beq Lnovec
231239
232240// conditionally load VS
233#define PPC64_CLVS_BOTTOM(n) \
234 beq Ldone##n ;\
235 addi 4, 3, PPC64_OFFS_FP + n * 16 ;\
236 lxvd2x n, 0, 4 ;\
241#define PPC64_CLVSl(n) \
242 andis. 0, 5, (1 PPC_LEFT_SHIFT(47-n)) ;\
243 beq Ldone##n ;\
244 PPC64_CLVS_RESTORE(n) ;\
237245Ldone##n:
238246
239#define PPC64_CLVSl(n) \
240 andis. 0, 5, (1 PPC_LEFT_SHIFT(47-n)) ;\
241PPC64_CLVS_BOTTOM(n)
247#define PPC64_CLVSh(n) \
248 andi. 0, 5, (1 PPC_LEFT_SHIFT(63-n)) ;\
249 beq Ldone##n ;\
250 PPC64_CLVS_RESTORE(n) ;\
251Ldone##n:
252
253#else
242254
243#define PPC64_CLVSh(n) \
244 andi. 0, 5, (1 PPC_LEFT_SHIFT(63-n)) ;\
245PPC64_CLVS_BOTTOM(n)
255#define PPC64_CLVSl(n) PPC64_CLVS_RESTORE(n)
256#define PPC64_CLVSh(n) PPC64_CLVS_RESTORE(n)
257
258#endif // !defined(_AIX)
246259
247260 PPC64_CLVSl(32)
248261 PPC64_CLVSl(33)
......@@ -318,32 +331,44 @@ PPC64_CLVS_BOTTOM(n)
318331 PPC64_LF(31)
319332
320333#if defined(__ALTIVEC__)
321 // restore vector registers if any are in use
334
335#define PPC64_CLV_UNALIGNED_RESTORE(n) \
336 ld 0, (PPC64_OFFS_V + n * 16)(3) ;\
337 std 0, 0(4) ;\
338 ld 0, (PPC64_OFFS_V + n * 16 + 8)(3) ;\
339 std 0, 8(4) ;\
340 lvx n, 0, 4
341
342#if !defined(_AIX)
343 // restore vector registers if any are in use. In the AIX ABI, VRSAVE is
344 // not used.
322345 ld 5, PPC64_OFFS_VRSAVE(3) // test VRsave
323346 cmpwi 5, 0
324347 beq Lnovec
325348
326 subi 4, 1, 16
327 // r4 is now a 16-byte aligned pointer into the red zone
328 // the _vectorScalarRegisters may not be 16-byte aligned
329 // so copy via red zone temp buffer
349#define PPC64_CLV_UNALIGNEDl(n) \
350 andis. 0, 5, (1 PPC_LEFT_SHIFT(15-n)) ;\
351 beq Ldone##n ;\
352 PPC64_CLV_UNALIGNED_RESTORE(n) ;\
353Ldone ## n:
330354
331#define PPC64_CLV_UNALIGNED_BOTTOM(n) \
332 beq Ldone##n ;\
333 ld 0, (PPC64_OFFS_V + n * 16)(3) ;\
334 std 0, 0(4) ;\
335 ld 0, (PPC64_OFFS_V + n * 16 + 8)(3) ;\
336 std 0, 8(4) ;\
337 lvx n, 0, 4 ;\
355#define PPC64_CLV_UNALIGNEDh(n) \
356 andi. 0, 5, (1 PPC_LEFT_SHIFT(31-n)) ;\
357 beq Ldone##n ;\
358 PPC64_CLV_UNALIGNED_RESTORE(n) ;\
338359Ldone ## n:
339360
340#define PPC64_CLV_UNALIGNEDl(n) \
341 andis. 0, 5, (1 PPC_LEFT_SHIFT(15-n)) ;\
342PPC64_CLV_UNALIGNED_BOTTOM(n)
361#else
362
363#define PPC64_CLV_UNALIGNEDl(n) PPC64_CLV_UNALIGNED_RESTORE(n)
364#define PPC64_CLV_UNALIGNEDh(n) PPC64_CLV_UNALIGNED_RESTORE(n)
365
366#endif // !defined(_AIX)
343367
344#define PPC64_CLV_UNALIGNEDh(n) \
345 andi. 0, 5, (1 PPC_LEFT_SHIFT(31-n)) ;\
346PPC64_CLV_UNALIGNED_BOTTOM(n)
368 subi 4, 1, 16
369 // r4 is now a 16-byte aligned pointer into the red zone
370 // the _vectorScalarRegisters may not be 16-byte aligned
371 // so copy via red zone temp buffer
347372
348373 PPC64_CLV_UNALIGNEDl(0)
349374 PPC64_CLV_UNALIGNEDl(1)
......@@ -387,11 +412,23 @@ Lnovec:
387412 ld 0, PPC64_OFFS_SRR0(3)
388413 mtctr 0
389414
415#if defined(_AIX)
416 // After setting GPR1 to a higher address, AIX wipes out the original
417 // stack space below that address invalidated by the new GPR1 value. Use
418 // GPR0 to save the value of GPR3 in the context before it is wiped out.
419 // This compromises the content of GPR0 which is a volatile register.
420 ld 0, (8 * (3 + 2))(3)
421#else
390422 PPC64_LR(0)
423#endif
391424 PPC64_LR(5)
392425 PPC64_LR(4)
393426 PPC64_LR(1)
427#if defined(_AIX)
428 mr 3, 0
429#else
394430 PPC64_LR(3)
431#endif
395432 bctr
396433
397434#elif defined(__powerpc__)
......@@ -475,45 +512,48 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)
475512#endif
476513
477514#if defined(__ALTIVEC__)
478 // restore vector registers if any are in use
515
516#define LOAD_VECTOR_RESTORE(_index) \
517 lwz 0, 424+_index*16(3) SEPARATOR \
518 stw 0, 0(4) SEPARATOR \
519 lwz 0, 424+_index*16+4(3) SEPARATOR \
520 stw 0, 4(4) SEPARATOR \
521 lwz 0, 424+_index*16+8(3) SEPARATOR \
522 stw 0, 8(4) SEPARATOR \
523 lwz 0, 424+_index*16+12(3) SEPARATOR \
524 stw 0, 12(4) SEPARATOR \
525 lvx _index, 0, 4
526
527#if !defined(_AIX)
528 // restore vector registers if any are in use. In the AIX ABI, VRSAVE
529 // is not used.
479530 lwz 5, 156(3) // test VRsave
480531 cmpwi 5, 0
481532 beq Lnovec
482533
483 subi 4, 1, 16
484 rlwinm 4, 4, 0, 0, 27 // mask low 4-bits
485 // r4 is now a 16-byte aligned pointer into the red zone
486 // the _vectorRegisters may not be 16-byte aligned so copy via red zone temp buffer
487
488
489#define LOAD_VECTOR_UNALIGNEDl(_index) \
490 andis. 0, 5, (1 PPC_LEFT_SHIFT(15-_index)) SEPARATOR \
491 beq Ldone ## _index SEPARATOR \
492 lwz 0, 424+_index*16(3) SEPARATOR \
493 stw 0, 0(%r4) SEPARATOR \
494 lwz 0, 424+_index*16+4(%r3) SEPARATOR \
495 stw 0, 4(%r4) SEPARATOR \
496 lwz 0, 424+_index*16+8(%r3) SEPARATOR \
497 stw 0, 8(%r4) SEPARATOR \
498 lwz 0, 424+_index*16+12(%r3) SEPARATOR \
499 stw 0, 12(%r4) SEPARATOR \
500 lvx _index, 0, 4 SEPARATOR \
534#define LOAD_VECTOR_UNALIGNEDl(_index) \
535 andis. 0, 5, (1 PPC_LEFT_SHIFT(15-_index)) SEPARATOR \
536 beq Ldone ## _index SEPARATOR \
537 LOAD_VECTOR_RESTORE(_index) SEPARATOR \
501538 Ldone ## _index:
502539
503#define LOAD_VECTOR_UNALIGNEDh(_index) \
504 andi. 0, 5, (1 PPC_LEFT_SHIFT(31-_index)) SEPARATOR \
505 beq Ldone ## _index SEPARATOR \
506 lwz 0, 424+_index*16(3) SEPARATOR \
507 stw 0, 0(4) SEPARATOR \
508 lwz 0, 424+_index*16+4(3) SEPARATOR \
509 stw 0, 4(4) SEPARATOR \
510 lwz 0, 424+_index*16+8(3) SEPARATOR \
511 stw 0, 8(%r4) SEPARATOR \
512 lwz 0, 424+_index*16+12(3) SEPARATOR \
513 stw 0, 12(4) SEPARATOR \
514 lvx _index, 0, 4 SEPARATOR \
540#define LOAD_VECTOR_UNALIGNEDh(_index) \
541 andi. 0, 5, (1 PPC_LEFT_SHIFT(31-_index)) SEPARATOR \
542 beq Ldone ## _index SEPARATOR \
543 LOAD_VECTOR_RESTORE(_index) SEPARATOR \
515544 Ldone ## _index:
516545
546#else
547
548#define LOAD_VECTOR_UNALIGNEDl(_index) LOAD_VECTOR_RESTORE(_index)
549#define LOAD_VECTOR_UNALIGNEDh(_index) LOAD_VECTOR_RESTORE(_index)
550
551#endif // !defined(_AIX)
552
553 subi 4, 1, 16
554 rlwinm 4, 4, 0, 0, 27 // mask low 4-bits
555 // r4 is now a 16-byte aligned pointer into the red zone
556 // the _vectorRegisters may not be 16-byte aligned so copy via red zone temp buffer
517557
518558 LOAD_VECTOR_UNALIGNEDl(0)
519559 LOAD_VECTOR_UNALIGNEDl(1)
......@@ -1212,6 +1252,43 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv)
12121252
12131253 ret // jump to ra
12141254
1255#elif defined(__s390x__)
1256
1257DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_s390x6jumptoEv)
1258//
1259// void libunwind::Registers_s390x::jumpto()
1260//
1261// On entry:
1262// thread_state pointer is in r2
1263//
1264
1265 // Skip PSWM, but load PSWA into r1
1266 lg %r1, 8(%r2)
1267
1268 // Restore FPRs
1269 ld %f0, 144(%r2)
1270 ld %f1, 152(%r2)
1271 ld %f2, 160(%r2)
1272 ld %f3, 168(%r2)
1273 ld %f4, 176(%r2)
1274 ld %f5, 184(%r2)
1275 ld %f6, 192(%r2)
1276 ld %f7, 200(%r2)
1277 ld %f8, 208(%r2)
1278 ld %f9, 216(%r2)
1279 ld %f10, 224(%r2)
1280 ld %f11, 232(%r2)
1281 ld %f12, 240(%r2)
1282 ld %f13, 248(%r2)
1283 ld %f14, 256(%r2)
1284 ld %f15, 264(%r2)
1285
1286 // Restore GPRs - skipping %r0 and %r1
1287 lmg %r2, %r15, 32(%r2)
1288
1289 // Return to PSWA (was loaded into %r1 above)
1290 br %r1
1291
12151292#endif
12161293
12171294#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */
lib/libunwind/src/UnwindRegistersSave.S+55-1
......@@ -8,7 +8,11 @@
88
99#include "assembly.h"
1010
11#if defined(_AIX)
12 .toc
13#else
1114 .text
15#endif
1216
1317#if !defined(__USING_SJLJ_EXCEPTIONS__)
1418
......@@ -334,8 +338,11 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
334338// On entry:
335339// thread_state pointer is in r3
336340//
341#if defined(_AIX)
342DEFINE_LIBUNWIND_FUNCTION_AND_WEAK_ALIAS(__unw_getcontext, unw_getcontext)
343#else
337344DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
338
345#endif
339346// store register (GPR)
340347#define PPC64_STR(n) \
341348 std n, (8 * (n + 2))(3)
......@@ -567,7 +574,11 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
567574// On entry:
568575// thread_state pointer is in r3
569576//
577#if defined(_AIX)
578DEFINE_LIBUNWIND_FUNCTION_AND_WEAK_ALIAS(__unw_getcontext, unw_getcontext)
579#else
570580DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
581#endif
571582 stw 0, 8(3)
572583 mflr 0
573584 stw 0, 0(3) // store lr as ssr0
......@@ -1168,6 +1179,49 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
11681179
11691180 li a0, 0 // return UNW_ESUCCESS
11701181 ret // jump to ra
1182
1183#elif defined(__s390x__)
1184
1185//
1186// extern int __unw_getcontext(unw_context_t* thread_state)
1187//
1188// On entry:
1189// thread_state pointer is in r2
1190//
1191DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
1192
1193 // Save GPRs
1194 stmg %r0, %r15, 16(%r2)
1195
1196 // Save PSWM
1197 epsw %r0, %r1
1198 stm %r0, %r1, 0(%r2)
1199
1200 // Store return address as PSWA
1201 stg %r14, 8(%r2)
1202
1203 // Save FPRs
1204 std %f0, 144(%r2)
1205 std %f1, 152(%r2)
1206 std %f2, 160(%r2)
1207 std %f3, 168(%r2)
1208 std %f4, 176(%r2)
1209 std %f5, 184(%r2)
1210 std %f6, 192(%r2)
1211 std %f7, 200(%r2)
1212 std %f8, 208(%r2)
1213 std %f9, 216(%r2)
1214 std %f10, 224(%r2)
1215 std %f11, 232(%r2)
1216 std %f12, 240(%r2)
1217 std %f13, 248(%r2)
1218 std %f14, 256(%r2)
1219 std %f15, 264(%r2)
1220
1221 // Return UNW_ESUCCESS
1222 lghi %r2, 0
1223 br %r14
1224
11711225#endif
11721226
11731227 WEAK_ALIAS(__unw_getcontext, unw_getcontext)
lib/libunwind/src/Unwind_AIXExtras.cpp created+63
......@@ -0,0 +1,63 @@
1//===--------------------- Unwind_AIXExtras.cpp -------------------------===//
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//===----------------------------------------------------------------------===//
9
10// This file is only used for AIX.
11#if defined(_AIX)
12
13#include "config.h"
14#include "libunwind_ext.h"
15#include <sys/debug.h>
16
17namespace libunwind {
18// getFuncNameFromTBTable
19// Get the function name from its traceback table.
20char *getFuncNameFromTBTable(uintptr_t Pc, uint16_t &NameLen,
21 unw_word_t *Offset) {
22 uint32_t *p = reinterpret_cast<uint32_t *>(Pc);
23 *Offset = 0;
24
25 // Keep looking forward until a word of 0 is found. The traceback
26 // table starts at the following word.
27 while (*p)
28 p++;
29 tbtable *TBTable = reinterpret_cast<tbtable *>(p + 1);
30
31 if (!TBTable->tb.name_present)
32 return NULL;
33
34 // Get to the name of the function.
35 p = reinterpret_cast<uint32_t *>(&TBTable->tb_ext);
36
37 // Skip field parminfo if it exists.
38 if (TBTable->tb.fixedparms || TBTable->tb.floatparms)
39 p++;
40
41 // If the tb_offset field exisits, get the offset from the start of
42 // the function to pc. Skip the field.
43 if (TBTable->tb.has_tboff) {
44 unw_word_t StartIp =
45 reinterpret_cast<uintptr_t>(TBTable) - *p - sizeof(uint32_t);
46 *Offset = Pc - StartIp;
47 p++;
48 }
49
50 // Skip field hand_mask if it exists.
51 if (TBTable->tb.int_hndl)
52 p++;
53
54 // Skip fields ctl_info and ctl_info_disp if they exist.
55 if (TBTable->tb.has_ctl) {
56 p += 1 + *p;
57 }
58
59 NameLen = *(reinterpret_cast<uint16_t *>(p));
60 return reinterpret_cast<char *>(p) + sizeof(uint16_t);
61}
62} // namespace libunwind
63#endif // defined(_AIX)
lib/libunwind/src/assembly.h+48-1
......@@ -67,7 +67,8 @@
6767#define SEPARATOR ;
6868#endif
6969
70#if defined(__powerpc64__) && (!defined(_CALL_ELF) || _CALL_ELF == 1)
70#if defined(__powerpc64__) && (!defined(_CALL_ELF) || _CALL_ELF == 1) && \
71 !defined(_AIX)
7172#define PPC64_OPD1 .section .opd,"aw",@progbits SEPARATOR
7273#define PPC64_OPD2 SEPARATOR \
7374 .p2align 3 SEPARATOR \
......@@ -203,12 +204,57 @@
203204
204205#elif defined(__sparc__)
205206
207#elif defined(_AIX)
208
209#if defined(__powerpc64__)
210#define VBYTE_LEN 8
211#define CSECT_ALIGN 3
212#else
213#define VBYTE_LEN 4
214#define CSECT_ALIGN 2
215#endif
216
217// clang-format off
218#define DEFINE_LIBUNWIND_FUNCTION_AND_WEAK_ALIAS(name, aliasname) \
219 .csect .text[PR], 2 SEPARATOR \
220 .csect .name[PR], 2 SEPARATOR \
221 .globl name[DS] SEPARATOR \
222 .globl .name[PR] SEPARATOR \
223 .align 4 SEPARATOR \
224 .csect name[DS], CSECT_ALIGN SEPARATOR \
225aliasname: \
226 .vbyte VBYTE_LEN, .name[PR] SEPARATOR \
227 .vbyte VBYTE_LEN, TOC[TC0] SEPARATOR \
228 .vbyte VBYTE_LEN, 0 SEPARATOR \
229 .weak aliasname SEPARATOR \
230 .weak .aliasname SEPARATOR \
231 .csect .name[PR], 2 SEPARATOR \
232.aliasname: \
233
234#define WEAK_ALIAS(name, aliasname)
235#define NO_EXEC_STACK_DIRECTIVE
236
237// clang-format on
206238#else
207239
208240#error Unsupported target
209241
210242#endif
211243
244#if defined(_AIX)
245 // clang-format off
246#define DEFINE_LIBUNWIND_FUNCTION(name) \
247 .globl name[DS] SEPARATOR \
248 .globl .name SEPARATOR \
249 .align 4 SEPARATOR \
250 .csect name[DS], CSECT_ALIGN SEPARATOR \
251 .vbyte VBYTE_LEN, .name SEPARATOR \
252 .vbyte VBYTE_LEN, TOC[TC0] SEPARATOR \
253 .vbyte VBYTE_LEN, 0 SEPARATOR \
254 .csect .text[PR], 2 SEPARATOR \
255.name:
256 // clang-format on
257#else
212258#define DEFINE_LIBUNWIND_FUNCTION(name) \
213259 .globl SYMBOL_NAME(name) SEPARATOR \
214260 HIDDEN_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \
......@@ -217,6 +263,7 @@
217263 SYMBOL_NAME(name): \
218264 PPC64_OPD2 \
219265 AARCH64_BTI
266#endif
220267
221268#if defined(__arm__)
222269#if !defined(__ARM_ARCH)
lib/libunwind/src/cet_unwind.h+1-1
......@@ -36,6 +36,6 @@
3636#endif
3737
3838extern void *__libunwind_cet_get_registers(unw_cursor_t *);
39extern void *__libunwind_cet_get_jump_target();
39extern void *__libunwind_cet_get_jump_target(void);
4040
4141#endif
lib/libunwind/src/config.h+9-6
......@@ -43,6 +43,9 @@
4343 // For ARM EHABI, Bionic didn't implement dl_iterate_phdr until API 21. After
4444 // API 21, dl_iterate_phdr exists, but dl_unwind_find_exidx is much faster.
4545 #define _LIBUNWIND_USE_DL_UNWIND_FIND_EXIDX 1
46#elif defined(_AIX)
47// The traceback table at the end of each function is used for unwinding.
48#define _LIBUNWIND_SUPPORT_TBTAB_UNWIND 1
4649#else
4750 // Assume an ELF system with a dl_iterate_phdr function.
4851 #define _LIBUNWIND_USE_DL_ITERATE_PHDR 1
......@@ -57,7 +60,7 @@
5760 #define _LIBUNWIND_EXPORT
5861 #define _LIBUNWIND_HIDDEN
5962#else
60 #if !defined(__ELF__) && !defined(__MACH__)
63 #if !defined(__ELF__) && !defined(__MACH__) && !defined(_AIX)
6164 #define _LIBUNWIND_EXPORT __declspec(dllexport)
6265 #define _LIBUNWIND_HIDDEN
6366 #else
......@@ -80,7 +83,7 @@
8083 __asm__(".globl " SYMBOL_NAME(aliasname)); \
8184 __asm__(SYMBOL_NAME(aliasname) " = " SYMBOL_NAME(name)); \
8285 _LIBUNWIND_ALIAS_VISIBILITY(SYMBOL_NAME(aliasname))
83#elif defined(__ELF__)
86#elif defined(__ELF__) || defined(_AIX)
8487#define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \
8588 extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname \
8689 __attribute__((weak, alias(#name)));
......@@ -112,7 +115,7 @@
112115#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || \
113116 (!defined(__APPLE__) && defined(__arm__)) || defined(__aarch64__) || \
114117 defined(__mips__) || defined(__riscv) || defined(__hexagon__) || \
115 defined(__sparc__)
118 defined(__sparc__) || defined(__s390x__)
116119#if !defined(_LIBUNWIND_BUILD_SJLJ_APIS)
117120#define _LIBUNWIND_BUILD_ZERO_COST_APIS
118121#endif
......@@ -188,9 +191,9 @@
188191 #ifdef __cplusplus
189192 extern "C" {
190193 #endif
191 extern bool logAPIs();
192 extern bool logUnwinding();
193 extern bool logDWARF();
194 extern bool logAPIs(void);
195 extern bool logUnwinding(void);
196 extern bool logDWARF(void);
194197 #ifdef __cplusplus
195198 }
196199 #endif
lib/libunwind/src/libunwind.cpp+12
......@@ -75,6 +75,8 @@ _LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor,
7575# define REGISTER_KIND Registers_riscv
7676#elif defined(__ve__)
7777# define REGISTER_KIND Registers_ve
78#elif defined(__s390x__)
79# define REGISTER_KIND Registers_s390x
7880#else
7981# error Architecture not supported
8082#endif
......@@ -247,6 +249,16 @@ _LIBUNWIND_HIDDEN int __unw_is_signal_frame(unw_cursor_t *cursor) {
247249}
248250_LIBUNWIND_WEAK_ALIAS(__unw_is_signal_frame, unw_is_signal_frame)
249251
252#ifdef _AIX
253_LIBUNWIND_EXPORT uintptr_t __unw_get_data_rel_base(unw_cursor_t *cursor) {
254 _LIBUNWIND_TRACE_API("unw_get_data_rel_base(cursor=%p)",
255 static_cast<void *>(cursor));
256 AbstractUnwindCursor *co = reinterpret_cast<AbstractUnwindCursor *>(cursor);
257 return co->getDataRelBase();
258}
259_LIBUNWIND_WEAK_ALIAS(__unw_get_data_rel_base, unw_get_data_rel_base)
260#endif
261
250262#ifdef __arm__
251263// Save VFP registers d0-d15 using FSTMIADX instead of FSTMIADD
252264_LIBUNWIND_HIDDEN void __unw_save_vfp_as_X(unw_cursor_t *cursor) {
lib/libunwind/src/libunwind_ext.h+4
......@@ -43,6 +43,10 @@ extern int __unw_is_fpreg(unw_cursor_t *, unw_regnum_t);
4343extern int __unw_is_signal_frame(unw_cursor_t *);
4444extern int __unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *);
4545
46#if defined(_AIX)
47extern uintptr_t __unw_get_data_rel_base(unw_cursor_t *);
48#endif
49
4650// SPI
4751extern void __unw_iterate_dwarf_unwind_cache(void (*func)(
4852 unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh));
src/libunwind.zig+13-11
......@@ -33,17 +33,6 @@ pub fn buildStaticLib(comp: *Compilation) !void {
3333 .directory = null, // Put it in the cache directory.
3434 .basename = basename,
3535 };
36 const unwind_src_list = [_][]const u8{
37 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "libunwind.cpp",
38 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-EHABI.cpp",
39 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-seh.cpp",
40 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindLevel1.c",
41 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindLevel1-gcc-ext.c",
42 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-sjlj.c",
43 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersRestore.S",
44 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersSave.S",
45 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "gcc_personality_v0.c",
46 };
4736 var c_source_files: [unwind_src_list.len]Compilation.CSourceFile = undefined;
4837 for (unwind_src_list) |unwind_src, i| {
4938 var cflags = std.ArrayList([]const u8).init(arena);
......@@ -150,3 +139,16 @@ pub fn buildStaticLib(comp: *Compilation) !void {
150139 .lock = sub_compilation.bin_file.toOwnedLock(),
151140 };
152141}
142
143const unwind_src_list = [_][]const u8{
144 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "libunwind.cpp",
145 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-EHABI.cpp",
146 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-seh.cpp",
147 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindLevel1.c",
148 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindLevel1-gcc-ext.c",
149 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-sjlj.c",
150 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersRestore.S",
151 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersSave.S",
152 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind_AIXExtras.cpp",
153 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "gcc_personality_v0.c",
154};