forked from OSchip/llvm-project
[libunwind] Add SystemZ support
Add support for the SystemZ (s390x) architecture to libunwind. Support should be feature-complete with the exception of unwinding from signal handlers (to be added later). Reviewed by: MaskRay Differential Revision: https://reviews.llvm.org/D124248
This commit is contained in:
parent
c7662dc3e5
commit
364c5023d2
|
@ -29,6 +29,7 @@
|
||||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON 34
|
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON 34
|
||||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV 64
|
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV 64
|
||||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE 143
|
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE 143
|
||||||
|
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X 83
|
||||||
|
|
||||||
#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
|
#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
|
||||||
# if defined(__linux__)
|
# if defined(__linux__)
|
||||||
|
@ -160,6 +161,11 @@
|
||||||
# define _LIBUNWIND_CONTEXT_SIZE 67
|
# define _LIBUNWIND_CONTEXT_SIZE 67
|
||||||
# define _LIBUNWIND_CURSOR_SIZE 79
|
# define _LIBUNWIND_CURSOR_SIZE 79
|
||||||
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE
|
# 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
|
||||||
# else
|
# else
|
||||||
# error "Unsupported architecture."
|
# error "Unsupported architecture."
|
||||||
# endif
|
# endif
|
||||||
|
@ -178,6 +184,7 @@
|
||||||
# define _LIBUNWIND_TARGET_HEXAGON 1
|
# define _LIBUNWIND_TARGET_HEXAGON 1
|
||||||
# define _LIBUNWIND_TARGET_RISCV 1
|
# define _LIBUNWIND_TARGET_RISCV 1
|
||||||
# define _LIBUNWIND_TARGET_VE 1
|
# define _LIBUNWIND_TARGET_VE 1
|
||||||
|
# define _LIBUNWIND_TARGET_S390X 1
|
||||||
# define _LIBUNWIND_CONTEXT_SIZE 167
|
# define _LIBUNWIND_CONTEXT_SIZE 167
|
||||||
# define _LIBUNWIND_CURSOR_SIZE 179
|
# define _LIBUNWIND_CURSOR_SIZE 179
|
||||||
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287
|
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287
|
||||||
|
|
|
@ -1177,4 +1177,46 @@ enum {
|
||||||
UNW_VE_VL = 145,
|
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
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -39,6 +39,7 @@ enum {
|
||||||
REGISTERS_HEXAGON,
|
REGISTERS_HEXAGON,
|
||||||
REGISTERS_RISCV,
|
REGISTERS_RISCV,
|
||||||
REGISTERS_VE,
|
REGISTERS_VE,
|
||||||
|
REGISTERS_S390X,
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(_LIBUNWIND_TARGET_I386)
|
#if defined(_LIBUNWIND_TARGET_I386)
|
||||||
|
@ -4716,6 +4717,293 @@ inline const char *Registers_ve::getRegisterName(int regNum) {
|
||||||
}
|
}
|
||||||
#endif // _LIBUNWIND_TARGET_VE
|
#endif // _LIBUNWIND_TARGET_VE
|
||||||
|
|
||||||
|
#if defined(_LIBUNWIND_TARGET_S390X)
|
||||||
|
/// Registers_s390x holds the register state of a thread in a
|
||||||
|
/// 64-bit Linux on IBM zSystems process.
|
||||||
|
class _LIBUNWIND_HIDDEN Registers_s390x {
|
||||||
|
public:
|
||||||
|
Registers_s390x();
|
||||||
|
Registers_s390x(const void *registers);
|
||||||
|
|
||||||
|
bool validRegister(int num) const;
|
||||||
|
uint64_t getRegister(int num) const;
|
||||||
|
void setRegister(int num, uint64_t value);
|
||||||
|
bool validFloatRegister(int num) const;
|
||||||
|
double getFloatRegister(int num) const;
|
||||||
|
void setFloatRegister(int num, double value);
|
||||||
|
bool validVectorRegister(int num) const;
|
||||||
|
v128 getVectorRegister(int num) const;
|
||||||
|
void setVectorRegister(int num, v128 value);
|
||||||
|
static const char *getRegisterName(int num);
|
||||||
|
void jumpto();
|
||||||
|
static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X; }
|
||||||
|
static int getArch() { return REGISTERS_S390X; }
|
||||||
|
|
||||||
|
uint64_t getSP() const { return _registers.__gpr[15]; }
|
||||||
|
void setSP(uint64_t value) { _registers.__gpr[15] = value; }
|
||||||
|
uint64_t getIP() const { return _registers.__pswa; }
|
||||||
|
void setIP(uint64_t value) { _registers.__pswa = value; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct s390x_thread_state_t {
|
||||||
|
uint64_t __pswm; // Problem Status Word: Mask
|
||||||
|
uint64_t __pswa; // Problem Status Word: Address (PC)
|
||||||
|
uint64_t __gpr[16]; // General Purpose Registers
|
||||||
|
double __fpr[16]; // Floating-Point Registers
|
||||||
|
};
|
||||||
|
|
||||||
|
s390x_thread_state_t _registers;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline Registers_s390x::Registers_s390x(const void *registers) {
|
||||||
|
static_assert((check_fit<Registers_s390x, unw_context_t>::does_fit),
|
||||||
|
"s390x registers do not fit into unw_context_t");
|
||||||
|
memcpy(&_registers, static_cast<const uint8_t *>(registers),
|
||||||
|
sizeof(_registers));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Registers_s390x::Registers_s390x() {
|
||||||
|
memset(&_registers, 0, sizeof(_registers));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Registers_s390x::validRegister(int regNum) const {
|
||||||
|
switch (regNum) {
|
||||||
|
case UNW_S390X_PSWM:
|
||||||
|
case UNW_S390X_PSWA:
|
||||||
|
case UNW_REG_IP:
|
||||||
|
case UNW_REG_SP:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regNum >= UNW_S390X_R0 && regNum <= UNW_S390X_R15)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint64_t Registers_s390x::getRegister(int regNum) const {
|
||||||
|
if (regNum >= UNW_S390X_R0 && regNum <= UNW_S390X_R15)
|
||||||
|
return _registers.__gpr[regNum - UNW_S390X_R0];
|
||||||
|
|
||||||
|
switch (regNum) {
|
||||||
|
case UNW_S390X_PSWM:
|
||||||
|
return _registers.__pswm;
|
||||||
|
case UNW_S390X_PSWA:
|
||||||
|
case UNW_REG_IP:
|
||||||
|
return _registers.__pswa;
|
||||||
|
case UNW_REG_SP:
|
||||||
|
return _registers.__gpr[15];
|
||||||
|
}
|
||||||
|
_LIBUNWIND_ABORT("unsupported s390x register");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Registers_s390x::setRegister(int regNum, uint64_t value) {
|
||||||
|
if (regNum >= UNW_S390X_R0 && regNum <= UNW_S390X_R15) {
|
||||||
|
_registers.__gpr[regNum - UNW_S390X_R0] = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (regNum) {
|
||||||
|
case UNW_S390X_PSWM:
|
||||||
|
_registers.__pswm = value;
|
||||||
|
return;
|
||||||
|
case UNW_S390X_PSWA:
|
||||||
|
case UNW_REG_IP:
|
||||||
|
_registers.__pswa = value;
|
||||||
|
return;
|
||||||
|
case UNW_REG_SP:
|
||||||
|
_registers.__gpr[15] = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_LIBUNWIND_ABORT("unsupported s390x register");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Registers_s390x::validFloatRegister(int regNum) const {
|
||||||
|
return regNum >= UNW_S390X_F0 && regNum <= UNW_S390X_F15;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double Registers_s390x::getFloatRegister(int regNum) const {
|
||||||
|
// NOTE: FPR DWARF register numbers are not consecutive.
|
||||||
|
switch (regNum) {
|
||||||
|
case UNW_S390X_F0:
|
||||||
|
return _registers.__fpr[0];
|
||||||
|
case UNW_S390X_F1:
|
||||||
|
return _registers.__fpr[1];
|
||||||
|
case UNW_S390X_F2:
|
||||||
|
return _registers.__fpr[2];
|
||||||
|
case UNW_S390X_F3:
|
||||||
|
return _registers.__fpr[3];
|
||||||
|
case UNW_S390X_F4:
|
||||||
|
return _registers.__fpr[4];
|
||||||
|
case UNW_S390X_F5:
|
||||||
|
return _registers.__fpr[5];
|
||||||
|
case UNW_S390X_F6:
|
||||||
|
return _registers.__fpr[6];
|
||||||
|
case UNW_S390X_F7:
|
||||||
|
return _registers.__fpr[7];
|
||||||
|
case UNW_S390X_F8:
|
||||||
|
return _registers.__fpr[8];
|
||||||
|
case UNW_S390X_F9:
|
||||||
|
return _registers.__fpr[9];
|
||||||
|
case UNW_S390X_F10:
|
||||||
|
return _registers.__fpr[10];
|
||||||
|
case UNW_S390X_F11:
|
||||||
|
return _registers.__fpr[11];
|
||||||
|
case UNW_S390X_F12:
|
||||||
|
return _registers.__fpr[12];
|
||||||
|
case UNW_S390X_F13:
|
||||||
|
return _registers.__fpr[13];
|
||||||
|
case UNW_S390X_F14:
|
||||||
|
return _registers.__fpr[14];
|
||||||
|
case UNW_S390X_F15:
|
||||||
|
return _registers.__fpr[15];
|
||||||
|
}
|
||||||
|
_LIBUNWIND_ABORT("unsupported s390x register");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Registers_s390x::setFloatRegister(int regNum, double value) {
|
||||||
|
// NOTE: FPR DWARF register numbers are not consecutive.
|
||||||
|
switch (regNum) {
|
||||||
|
case UNW_S390X_F0:
|
||||||
|
_registers.__fpr[0] = value;
|
||||||
|
return;
|
||||||
|
case UNW_S390X_F1:
|
||||||
|
_registers.__fpr[1] = value;
|
||||||
|
return;
|
||||||
|
case UNW_S390X_F2:
|
||||||
|
_registers.__fpr[2] = value;
|
||||||
|
return;
|
||||||
|
case UNW_S390X_F3:
|
||||||
|
_registers.__fpr[3] = value;
|
||||||
|
return;
|
||||||
|
case UNW_S390X_F4:
|
||||||
|
_registers.__fpr[4] = value;
|
||||||
|
return;
|
||||||
|
case UNW_S390X_F5:
|
||||||
|
_registers.__fpr[5] = value;
|
||||||
|
return;
|
||||||
|
case UNW_S390X_F6:
|
||||||
|
_registers.__fpr[6] = value;
|
||||||
|
return;
|
||||||
|
case UNW_S390X_F7:
|
||||||
|
_registers.__fpr[7] = value;
|
||||||
|
return;
|
||||||
|
case UNW_S390X_F8:
|
||||||
|
_registers.__fpr[8] = value;
|
||||||
|
return;
|
||||||
|
case UNW_S390X_F9:
|
||||||
|
_registers.__fpr[9] = value;
|
||||||
|
return;
|
||||||
|
case UNW_S390X_F10:
|
||||||
|
_registers.__fpr[10] = value;
|
||||||
|
return;
|
||||||
|
case UNW_S390X_F11:
|
||||||
|
_registers.__fpr[11] = value;
|
||||||
|
return;
|
||||||
|
case UNW_S390X_F12:
|
||||||
|
_registers.__fpr[12] = value;
|
||||||
|
return;
|
||||||
|
case UNW_S390X_F13:
|
||||||
|
_registers.__fpr[13] = value;
|
||||||
|
return;
|
||||||
|
case UNW_S390X_F14:
|
||||||
|
_registers.__fpr[14] = value;
|
||||||
|
return;
|
||||||
|
case UNW_S390X_F15:
|
||||||
|
_registers.__fpr[15] = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_LIBUNWIND_ABORT("unsupported s390x register");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Registers_s390x::validVectorRegister(int /*regNum*/) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v128 Registers_s390x::getVectorRegister(int /*regNum*/) const {
|
||||||
|
_LIBUNWIND_ABORT("s390x vector support not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Registers_s390x::setVectorRegister(int /*regNum*/, v128 /*value*/) {
|
||||||
|
_LIBUNWIND_ABORT("s390x vector support not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const char *Registers_s390x::getRegisterName(int regNum) {
|
||||||
|
switch (regNum) {
|
||||||
|
case UNW_REG_IP:
|
||||||
|
return "ip";
|
||||||
|
case UNW_REG_SP:
|
||||||
|
return "sp";
|
||||||
|
case UNW_S390X_R0:
|
||||||
|
return "r0";
|
||||||
|
case UNW_S390X_R1:
|
||||||
|
return "r1";
|
||||||
|
case UNW_S390X_R2:
|
||||||
|
return "r2";
|
||||||
|
case UNW_S390X_R3:
|
||||||
|
return "r3";
|
||||||
|
case UNW_S390X_R4:
|
||||||
|
return "r4";
|
||||||
|
case UNW_S390X_R5:
|
||||||
|
return "r5";
|
||||||
|
case UNW_S390X_R6:
|
||||||
|
return "r6";
|
||||||
|
case UNW_S390X_R7:
|
||||||
|
return "r7";
|
||||||
|
case UNW_S390X_R8:
|
||||||
|
return "r8";
|
||||||
|
case UNW_S390X_R9:
|
||||||
|
return "r9";
|
||||||
|
case UNW_S390X_R10:
|
||||||
|
return "r10";
|
||||||
|
case UNW_S390X_R11:
|
||||||
|
return "r11";
|
||||||
|
case UNW_S390X_R12:
|
||||||
|
return "r12";
|
||||||
|
case UNW_S390X_R13:
|
||||||
|
return "r13";
|
||||||
|
case UNW_S390X_R14:
|
||||||
|
return "r14";
|
||||||
|
case UNW_S390X_R15:
|
||||||
|
return "r15";
|
||||||
|
case UNW_S390X_F0:
|
||||||
|
return "f0";
|
||||||
|
case UNW_S390X_F1:
|
||||||
|
return "f1";
|
||||||
|
case UNW_S390X_F2:
|
||||||
|
return "f2";
|
||||||
|
case UNW_S390X_F3:
|
||||||
|
return "f3";
|
||||||
|
case UNW_S390X_F4:
|
||||||
|
return "f4";
|
||||||
|
case UNW_S390X_F5:
|
||||||
|
return "f5";
|
||||||
|
case UNW_S390X_F6:
|
||||||
|
return "f6";
|
||||||
|
case UNW_S390X_F7:
|
||||||
|
return "f7";
|
||||||
|
case UNW_S390X_F8:
|
||||||
|
return "f8";
|
||||||
|
case UNW_S390X_F9:
|
||||||
|
return "f9";
|
||||||
|
case UNW_S390X_F10:
|
||||||
|
return "f10";
|
||||||
|
case UNW_S390X_F11:
|
||||||
|
return "f11";
|
||||||
|
case UNW_S390X_F12:
|
||||||
|
return "f12";
|
||||||
|
case UNW_S390X_F13:
|
||||||
|
return "f13";
|
||||||
|
case UNW_S390X_F14:
|
||||||
|
return "f14";
|
||||||
|
case UNW_S390X_F15:
|
||||||
|
return "f15";
|
||||||
|
}
|
||||||
|
return "unknown register";
|
||||||
|
}
|
||||||
|
#endif // _LIBUNWIND_TARGET_S390X
|
||||||
|
|
||||||
|
|
||||||
} // namespace libunwind
|
} // namespace libunwind
|
||||||
|
|
||||||
#endif // __REGISTERS_HPP__
|
#endif // __REGISTERS_HPP__
|
||||||
|
|
|
@ -1220,6 +1220,12 @@ private:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined (_LIBUNWIND_TARGET_S390X)
|
||||||
|
compact_unwind_encoding_t dwarfEncoding(Registers_s390x &) const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
|
#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
|
||||||
|
|
||||||
#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
|
#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
|
||||||
|
|
|
@ -1252,6 +1252,43 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv)
|
||||||
|
|
||||||
ret // jump to ra
|
ret // jump to ra
|
||||||
|
|
||||||
|
#elif defined(__s390x__)
|
||||||
|
|
||||||
|
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_s390x6jumptoEv)
|
||||||
|
//
|
||||||
|
// void libunwind::Registers_s390x::jumpto()
|
||||||
|
//
|
||||||
|
// On entry:
|
||||||
|
// thread_state pointer is in r2
|
||||||
|
//
|
||||||
|
|
||||||
|
// Skip PSWM, but load PSWA into r1
|
||||||
|
lg %r1, 8(%r2)
|
||||||
|
|
||||||
|
// Restore FPRs
|
||||||
|
ld %f0, 144(%r2)
|
||||||
|
ld %f1, 152(%r2)
|
||||||
|
ld %f2, 160(%r2)
|
||||||
|
ld %f3, 168(%r2)
|
||||||
|
ld %f4, 176(%r2)
|
||||||
|
ld %f5, 184(%r2)
|
||||||
|
ld %f6, 192(%r2)
|
||||||
|
ld %f7, 200(%r2)
|
||||||
|
ld %f8, 208(%r2)
|
||||||
|
ld %f9, 216(%r2)
|
||||||
|
ld %f10, 224(%r2)
|
||||||
|
ld %f11, 232(%r2)
|
||||||
|
ld %f12, 240(%r2)
|
||||||
|
ld %f13, 248(%r2)
|
||||||
|
ld %f14, 256(%r2)
|
||||||
|
ld %f15, 264(%r2)
|
||||||
|
|
||||||
|
// Restore GPRs - skipping %r0 and %r1
|
||||||
|
lmg %r2, %r15, 32(%r2)
|
||||||
|
|
||||||
|
// Return to PSWA (was loaded into %r1 above)
|
||||||
|
br %r1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */
|
#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */
|
||||||
|
|
|
@ -1179,6 +1179,49 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
|
||||||
|
|
||||||
li a0, 0 // return UNW_ESUCCESS
|
li a0, 0 // return UNW_ESUCCESS
|
||||||
ret // jump to ra
|
ret // jump to ra
|
||||||
|
|
||||||
|
#elif defined(__s390x__)
|
||||||
|
|
||||||
|
//
|
||||||
|
// extern int __unw_getcontext(unw_context_t* thread_state)
|
||||||
|
//
|
||||||
|
// On entry:
|
||||||
|
// thread_state pointer is in r2
|
||||||
|
//
|
||||||
|
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
|
||||||
|
|
||||||
|
// Save GPRs
|
||||||
|
stmg %r0, %r15, 16(%r2)
|
||||||
|
|
||||||
|
// Save PSWM
|
||||||
|
epsw %r0, %r1
|
||||||
|
stm %r0, %r1, 0(%r2)
|
||||||
|
|
||||||
|
// Store return address as PSWA
|
||||||
|
stg %r14, 8(%r2)
|
||||||
|
|
||||||
|
// Save FPRs
|
||||||
|
std %f0, 144(%r2)
|
||||||
|
std %f1, 152(%r2)
|
||||||
|
std %f2, 160(%r2)
|
||||||
|
std %f3, 168(%r2)
|
||||||
|
std %f4, 176(%r2)
|
||||||
|
std %f5, 184(%r2)
|
||||||
|
std %f6, 192(%r2)
|
||||||
|
std %f7, 200(%r2)
|
||||||
|
std %f8, 208(%r2)
|
||||||
|
std %f9, 216(%r2)
|
||||||
|
std %f10, 224(%r2)
|
||||||
|
std %f11, 232(%r2)
|
||||||
|
std %f12, 240(%r2)
|
||||||
|
std %f13, 248(%r2)
|
||||||
|
std %f14, 256(%r2)
|
||||||
|
std %f15, 264(%r2)
|
||||||
|
|
||||||
|
// Return UNW_ESUCCESS
|
||||||
|
lghi %r2, 0
|
||||||
|
br %r14
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WEAK_ALIAS(__unw_getcontext, unw_getcontext)
|
WEAK_ALIAS(__unw_getcontext, unw_getcontext)
|
||||||
|
|
|
@ -115,7 +115,7 @@
|
||||||
#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || \
|
#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || \
|
||||||
(!defined(__APPLE__) && defined(__arm__)) || defined(__aarch64__) || \
|
(!defined(__APPLE__) && defined(__arm__)) || defined(__aarch64__) || \
|
||||||
defined(__mips__) || defined(__riscv) || defined(__hexagon__) || \
|
defined(__mips__) || defined(__riscv) || defined(__hexagon__) || \
|
||||||
defined(__sparc__)
|
defined(__sparc__) || defined(__s390x__)
|
||||||
#if !defined(_LIBUNWIND_BUILD_SJLJ_APIS)
|
#if !defined(_LIBUNWIND_BUILD_SJLJ_APIS)
|
||||||
#define _LIBUNWIND_BUILD_ZERO_COST_APIS
|
#define _LIBUNWIND_BUILD_ZERO_COST_APIS
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -75,6 +75,8 @@ _LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor,
|
||||||
# define REGISTER_KIND Registers_riscv
|
# define REGISTER_KIND Registers_riscv
|
||||||
#elif defined(__ve__)
|
#elif defined(__ve__)
|
||||||
# define REGISTER_KIND Registers_ve
|
# define REGISTER_KIND Registers_ve
|
||||||
|
#elif defined(__s390x__)
|
||||||
|
# define REGISTER_KIND Registers_s390x
|
||||||
#else
|
#else
|
||||||
# error Architecture not supported
|
# error Architecture not supported
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue