mirror of
https://github.com/ziglang/zig.git
synced 2025-02-14 00:20:20 +00:00
Import SPARCv9 libunwind
Import LLVM's D32450/D116857 patch to enable unwinding support on SPARCv9 systems.
This commit is contained in:
parent
b5f8fb85e6
commit
55fa349ad9
7
lib/libunwind/include/__libunwind_config.h
vendored
7
lib/libunwind/include/__libunwind_config.h
vendored
@ -23,6 +23,7 @@
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K 32
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS 65
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC 31
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC64 31
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON 34
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV 64
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE 143
|
||||
@ -125,6 +126,11 @@
|
||||
# error "Unsupported MIPS ABI and/or environment"
|
||||
# endif
|
||||
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS
|
||||
# elif defined(__sparc__) && defined(__arch64__)
|
||||
# define _LIBUNWIND_TARGET_SPARC64 1
|
||||
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC64
|
||||
# define _LIBUNWIND_CONTEXT_SIZE 33
|
||||
# define _LIBUNWIND_CURSOR_SIZE 45
|
||||
# elif defined(__sparc__)
|
||||
#define _LIBUNWIND_TARGET_SPARC 1
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC
|
||||
@ -165,6 +171,7 @@
|
||||
# define _LIBUNWIND_TARGET_MIPS_O32 1
|
||||
# define _LIBUNWIND_TARGET_MIPS_NEWABI 1
|
||||
# define _LIBUNWIND_TARGET_SPARC 1
|
||||
# define _LIBUNWIND_TARGET_SPARC64 1
|
||||
# define _LIBUNWIND_TARGET_HEXAGON 1
|
||||
# define _LIBUNWIND_TARGET_RISCV 1
|
||||
# define _LIBUNWIND_TARGET_VE 1
|
||||
|
22
lib/libunwind/src/DwarfInstructions.hpp
vendored
22
lib/libunwind/src/DwarfInstructions.hpp
vendored
@ -67,7 +67,7 @@ private:
|
||||
return (pint_t)((sint_t)registers.getRegister((int)prolog.cfaRegister) +
|
||||
prolog.cfaRegisterOffset);
|
||||
if (prolog.cfaExpression != 0)
|
||||
return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace,
|
||||
return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace,
|
||||
registers, 0);
|
||||
assert(0 && "getCFA(): unknown location");
|
||||
__builtin_unreachable();
|
||||
@ -75,6 +75,14 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template <typename R>
|
||||
auto getSparcWCookie(const R &r, int) -> decltype(r.getWCookie()) {
|
||||
return r.getWCookie();
|
||||
}
|
||||
template <typename R> uint64_t getSparcWCookie(const R &, long) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename A, typename R>
|
||||
typename A::pint_t DwarfInstructions<A, R>::getSavedRegister(
|
||||
A &addressSpace, const R ®isters, pint_t cfa,
|
||||
@ -83,6 +91,10 @@ typename A::pint_t DwarfInstructions<A, R>::getSavedRegister(
|
||||
case CFI_Parser<A>::kRegisterInCFA:
|
||||
return (pint_t)addressSpace.getRegister(cfa + (pint_t)savedReg.value);
|
||||
|
||||
case CFI_Parser<A>::kRegisterInCFADecrypt: // sparc64 specific
|
||||
return addressSpace.getP(cfa + (pint_t)savedReg.value) ^
|
||||
getSparcWCookie(registers, 0);
|
||||
|
||||
case CFI_Parser<A>::kRegisterAtExpression:
|
||||
return (pint_t)addressSpace.getRegister(evaluateExpression(
|
||||
(pint_t)savedReg.value, addressSpace, registers, cfa));
|
||||
@ -121,6 +133,7 @@ double DwarfInstructions<A, R>::getSavedFloatRegister(
|
||||
case CFI_Parser<A>::kRegisterUndefined:
|
||||
case CFI_Parser<A>::kRegisterOffsetFromCFA:
|
||||
case CFI_Parser<A>::kRegisterInRegister:
|
||||
case CFI_Parser<A>::kRegisterInCFADecrypt:
|
||||
// FIX ME
|
||||
break;
|
||||
}
|
||||
@ -145,6 +158,7 @@ v128 DwarfInstructions<A, R>::getSavedVectorRegister(
|
||||
case CFI_Parser<A>::kRegisterUndefined:
|
||||
case CFI_Parser<A>::kRegisterOffsetFromCFA:
|
||||
case CFI_Parser<A>::kRegisterInRegister:
|
||||
case CFI_Parser<A>::kRegisterInCFADecrypt:
|
||||
// FIX ME
|
||||
break;
|
||||
}
|
||||
@ -249,6 +263,12 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_SPARC64)
|
||||
// Skip call site instruction and delay slot
|
||||
if (R::getArch() == REGISTERS_SPARC64)
|
||||
returnAddress += 8;
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_PPC64)
|
||||
#define PPC64_ELFV1_R2_LOAD_INST_ENCODING 0xe8410028u // ld r2,40(r1)
|
||||
#define PPC64_ELFV1_R2_OFFSET 40
|
||||
|
25
lib/libunwind/src/DwarfParser.hpp
vendored
25
lib/libunwind/src/DwarfParser.hpp
vendored
@ -71,6 +71,7 @@ public:
|
||||
kRegisterUnused,
|
||||
kRegisterUndefined,
|
||||
kRegisterInCFA,
|
||||
kRegisterInCFADecrypt, // sparc64 specific
|
||||
kRegisterOffsetFromCFA,
|
||||
kRegisterInRegister,
|
||||
kRegisterAtExpression,
|
||||
@ -723,7 +724,8 @@ bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
|
||||
"DW_CFA_GNU_negative_offset_extended(%" PRId64 ")\n", offset);
|
||||
break;
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_SPARC)
|
||||
#if defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_SPARC) || \
|
||||
defined(_LIBUNWIND_TARGET_SPARC64)
|
||||
// The same constant is used to represent different instructions on
|
||||
// AArch64 (negate_ra_state) and SPARC (window_save).
|
||||
static_assert(DW_CFA_AARCH64_negate_ra_state == DW_CFA_GNU_window_save,
|
||||
@ -757,8 +759,29 @@ bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_SPARC64)
|
||||
// case DW_CFA_GNU_window_save:
|
||||
case REGISTERS_SPARC64:
|
||||
// Don't save %o0-%o7 on sparc64.
|
||||
// https://reviews.llvm.org/D32450#736405
|
||||
|
||||
for (reg = UNW_SPARC_L0; reg <= UNW_SPARC_I7; reg++) {
|
||||
if (reg == UNW_SPARC_I7)
|
||||
results->setRegister(
|
||||
reg, kRegisterInCFADecrypt,
|
||||
((int64_t)reg - UNW_SPARC_L0) * sizeof(pint_t), initialState);
|
||||
else
|
||||
results->setRegister(
|
||||
reg, kRegisterInCFA,
|
||||
((int64_t)reg - UNW_SPARC_L0) * sizeof(pint_t), initialState);
|
||||
}
|
||||
_LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_window_save\n");
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
#else
|
||||
(void)arch;
|
||||
#endif
|
||||
|
187
lib/libunwind/src/Registers.hpp
vendored
187
lib/libunwind/src/Registers.hpp
vendored
@ -34,6 +34,7 @@ enum {
|
||||
REGISTERS_MIPS_O32,
|
||||
REGISTERS_MIPS_NEWABI,
|
||||
REGISTERS_SPARC,
|
||||
REGISTERS_SPARC64,
|
||||
REGISTERS_HEXAGON,
|
||||
REGISTERS_RISCV,
|
||||
REGISTERS_VE,
|
||||
@ -3546,6 +3547,192 @@ inline const char *Registers_sparc::getRegisterName(int regNum) {
|
||||
}
|
||||
#endif // _LIBUNWIND_TARGET_SPARC
|
||||
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_SPARC64)
|
||||
/// Registers_sparc64 holds the register state of a thread in a 64-bit
|
||||
/// sparc process.
|
||||
class _LIBUNWIND_HIDDEN Registers_sparc64 {
|
||||
public:
|
||||
Registers_sparc64() = default;
|
||||
Registers_sparc64(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);
|
||||
const char *getRegisterName(int num);
|
||||
void jumpto();
|
||||
static int lastDwarfRegNum() {
|
||||
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC64;
|
||||
}
|
||||
static int getArch() { return REGISTERS_SPARC64; }
|
||||
|
||||
uint64_t getSP() const { return _registers.__regs[UNW_SPARC_O6] + 2047; }
|
||||
void setSP(uint64_t value) { _registers.__regs[UNW_SPARC_O6] = value - 2047; }
|
||||
uint64_t getIP() const { return _registers.__regs[UNW_SPARC_O7]; }
|
||||
void setIP(uint64_t value) { _registers.__regs[UNW_SPARC_O7] = value; }
|
||||
uint64_t getWCookie() const { return _wcookie; }
|
||||
|
||||
private:
|
||||
struct sparc64_thread_state_t {
|
||||
uint64_t __regs[32];
|
||||
};
|
||||
|
||||
sparc64_thread_state_t _registers{};
|
||||
uint64_t _wcookie = 0;
|
||||
};
|
||||
|
||||
inline Registers_sparc64::Registers_sparc64(const void *registers) {
|
||||
static_assert((check_fit<Registers_sparc64, unw_context_t>::does_fit),
|
||||
"sparc64 registers do not fit into unw_context_t");
|
||||
memcpy(&_registers, registers, sizeof(_registers));
|
||||
memcpy(&_wcookie,
|
||||
static_cast<const uint8_t *>(registers) + sizeof(_registers),
|
||||
sizeof(_wcookie));
|
||||
}
|
||||
|
||||
inline bool Registers_sparc64::validRegister(int regNum) const {
|
||||
if (regNum == UNW_REG_IP)
|
||||
return true;
|
||||
if (regNum == UNW_REG_SP)
|
||||
return true;
|
||||
if (regNum < 0)
|
||||
return false;
|
||||
if (regNum <= UNW_SPARC_I7)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline uint64_t Registers_sparc64::getRegister(int regNum) const {
|
||||
if (regNum >= UNW_SPARC_G0 && regNum <= UNW_SPARC_I7)
|
||||
return _registers.__regs[regNum];
|
||||
|
||||
switch (regNum) {
|
||||
case UNW_REG_IP:
|
||||
return _registers.__regs[UNW_SPARC_O7];
|
||||
case UNW_REG_SP:
|
||||
return _registers.__regs[UNW_SPARC_O6] + 2047;
|
||||
}
|
||||
_LIBUNWIND_ABORT("unsupported sparc64 register");
|
||||
}
|
||||
|
||||
inline void Registers_sparc64::setRegister(int regNum, uint64_t value) {
|
||||
if (regNum >= UNW_SPARC_G0 && regNum <= UNW_SPARC_I7) {
|
||||
_registers.__regs[regNum] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (regNum) {
|
||||
case UNW_REG_IP:
|
||||
_registers.__regs[UNW_SPARC_O7] = value;
|
||||
return;
|
||||
case UNW_REG_SP:
|
||||
_registers.__regs[UNW_SPARC_O6] = value - 2047;
|
||||
return;
|
||||
}
|
||||
_LIBUNWIND_ABORT("unsupported sparc64 register");
|
||||
}
|
||||
|
||||
inline bool Registers_sparc64::validFloatRegister(int) const { return false; }
|
||||
|
||||
inline double Registers_sparc64::getFloatRegister(int) const {
|
||||
_LIBUNWIND_ABORT("no sparc64 float registers");
|
||||
}
|
||||
|
||||
inline void Registers_sparc64::setFloatRegister(int, double) {
|
||||
_LIBUNWIND_ABORT("no sparc64 float registers");
|
||||
}
|
||||
|
||||
inline bool Registers_sparc64::validVectorRegister(int) const { return false; }
|
||||
|
||||
inline v128 Registers_sparc64::getVectorRegister(int) const {
|
||||
_LIBUNWIND_ABORT("no sparc64 vector registers");
|
||||
}
|
||||
|
||||
inline void Registers_sparc64::setVectorRegister(int, v128) {
|
||||
_LIBUNWIND_ABORT("no sparc64 vector registers");
|
||||
}
|
||||
|
||||
inline const char *Registers_sparc64::getRegisterName(int regNum) {
|
||||
switch (regNum) {
|
||||
case UNW_REG_IP:
|
||||
return "pc";
|
||||
case UNW_SPARC_G0:
|
||||
return "g0";
|
||||
case UNW_SPARC_G1:
|
||||
return "g1";
|
||||
case UNW_SPARC_G2:
|
||||
return "g2";
|
||||
case UNW_SPARC_G3:
|
||||
return "g3";
|
||||
case UNW_SPARC_G4:
|
||||
return "g4";
|
||||
case UNW_SPARC_G5:
|
||||
return "g5";
|
||||
case UNW_SPARC_G6:
|
||||
return "g6";
|
||||
case UNW_SPARC_G7:
|
||||
return "g7";
|
||||
case UNW_SPARC_O0:
|
||||
return "o0";
|
||||
case UNW_SPARC_O1:
|
||||
return "o1";
|
||||
case UNW_SPARC_O2:
|
||||
return "o2";
|
||||
case UNW_SPARC_O3:
|
||||
return "o3";
|
||||
case UNW_SPARC_O4:
|
||||
return "o4";
|
||||
case UNW_SPARC_O5:
|
||||
return "o5";
|
||||
case UNW_REG_SP:
|
||||
case UNW_SPARC_O6:
|
||||
return "o6";
|
||||
case UNW_SPARC_O7:
|
||||
return "o7";
|
||||
case UNW_SPARC_L0:
|
||||
return "l0";
|
||||
case UNW_SPARC_L1:
|
||||
return "l1";
|
||||
case UNW_SPARC_L2:
|
||||
return "l2";
|
||||
case UNW_SPARC_L3:
|
||||
return "l3";
|
||||
case UNW_SPARC_L4:
|
||||
return "l4";
|
||||
case UNW_SPARC_L5:
|
||||
return "l5";
|
||||
case UNW_SPARC_L6:
|
||||
return "l6";
|
||||
case UNW_SPARC_L7:
|
||||
return "l7";
|
||||
case UNW_SPARC_I0:
|
||||
return "i0";
|
||||
case UNW_SPARC_I1:
|
||||
return "i1";
|
||||
case UNW_SPARC_I2:
|
||||
return "i2";
|
||||
case UNW_SPARC_I3:
|
||||
return "i3";
|
||||
case UNW_SPARC_I4:
|
||||
return "i4";
|
||||
case UNW_SPARC_I5:
|
||||
return "i5";
|
||||
case UNW_SPARC_I6:
|
||||
return "i6";
|
||||
case UNW_SPARC_I7:
|
||||
return "i7";
|
||||
default:
|
||||
return "unknown register";
|
||||
}
|
||||
}
|
||||
#endif // _LIBUNWIND_TARGET_SPARC64
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_HEXAGON)
|
||||
/// Registers_hexagon holds the register state of a thread in a Hexagon QDSP6
|
||||
/// process.
|
||||
|
16
lib/libunwind/src/UnwindCursor.hpp
vendored
16
lib/libunwind/src/UnwindCursor.hpp
vendored
@ -1020,6 +1020,10 @@ private:
|
||||
int stepWithCompactEncoding(Registers_sparc &) { return UNW_EINVAL; }
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_SPARC64)
|
||||
int stepWithCompactEncoding(Registers_sparc64 &) { return UNW_EINVAL; }
|
||||
#endif
|
||||
|
||||
#if defined (_LIBUNWIND_TARGET_RISCV)
|
||||
int stepWithCompactEncoding(Registers_riscv &) {
|
||||
return UNW_EINVAL;
|
||||
@ -1092,6 +1096,12 @@ private:
|
||||
bool compactSaysUseDwarf(Registers_sparc &, uint32_t *) const { return true; }
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_SPARC64)
|
||||
bool compactSaysUseDwarf(Registers_sparc64 &, uint32_t *) const {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (_LIBUNWIND_TARGET_RISCV)
|
||||
bool compactSaysUseDwarf(Registers_riscv &, uint32_t *) const {
|
||||
return true;
|
||||
@ -1170,6 +1180,12 @@ private:
|
||||
compact_unwind_encoding_t dwarfEncoding(Registers_sparc &) const { return 0; }
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_SPARC64)
|
||||
compact_unwind_encoding_t dwarfEncoding(Registers_sparc64 &) const {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (_LIBUNWIND_TARGET_RISCV)
|
||||
compact_unwind_encoding_t dwarfEncoding(Registers_riscv &) const {
|
||||
return 0;
|
||||
|
47
lib/libunwind/src/UnwindRegistersRestore.S
vendored
47
lib/libunwind/src/UnwindRegistersRestore.S
vendored
@ -1050,6 +1050,53 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv)
|
||||
ld $4, (8 * 4)($4)
|
||||
.set pop
|
||||
|
||||
#elif defined(__sparc__) && defined(__arch64__)
|
||||
|
||||
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind17Registers_sparc646jumptoEv)
|
||||
//
|
||||
// void libunwind::Registers_sparc64::jumpto()
|
||||
//
|
||||
// On entry:
|
||||
// thread_state pointer is in %o0
|
||||
//
|
||||
.register %g2, #scratch
|
||||
.register %g3, #scratch
|
||||
.register %g6, #scratch
|
||||
.register %g7, #scratch
|
||||
flushw
|
||||
ldx [%o0 + 0x08], %g1
|
||||
ldx [%o0 + 0x10], %g2
|
||||
ldx [%o0 + 0x18], %g3
|
||||
ldx [%o0 + 0x20], %g4
|
||||
ldx [%o0 + 0x28], %g5
|
||||
ldx [%o0 + 0x30], %g6
|
||||
ldx [%o0 + 0x38], %g7
|
||||
ldx [%o0 + 0x48], %o1
|
||||
ldx [%o0 + 0x50], %o2
|
||||
ldx [%o0 + 0x58], %o3
|
||||
ldx [%o0 + 0x60], %o4
|
||||
ldx [%o0 + 0x68], %o5
|
||||
ldx [%o0 + 0x70], %o6
|
||||
ldx [%o0 + 0x78], %o7
|
||||
ldx [%o0 + 0x80], %l0
|
||||
ldx [%o0 + 0x88], %l1
|
||||
ldx [%o0 + 0x90], %l2
|
||||
ldx [%o0 + 0x98], %l3
|
||||
ldx [%o0 + 0xa0], %l4
|
||||
ldx [%o0 + 0xa8], %l5
|
||||
ldx [%o0 + 0xb0], %l6
|
||||
ldx [%o0 + 0xb8], %l7
|
||||
ldx [%o0 + 0xc0], %i0
|
||||
ldx [%o0 + 0xc8], %i1
|
||||
ldx [%o0 + 0xd0], %i2
|
||||
ldx [%o0 + 0xd8], %i3
|
||||
ldx [%o0 + 0xe0], %i4
|
||||
ldx [%o0 + 0xe8], %i5
|
||||
ldx [%o0 + 0xf0], %i6
|
||||
ldx [%o0 + 0xf8], %i7
|
||||
jmp %o7
|
||||
ldx [%o0 + 0x40], %o0
|
||||
|
||||
#elif defined(__sparc__)
|
||||
|
||||
//
|
||||
|
60
lib/libunwind/src/UnwindRegistersSave.S
vendored
60
lib/libunwind/src/UnwindRegistersSave.S
vendored
@ -766,7 +766,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
|
||||
@
|
||||
@ On entry:
|
||||
@ thread_state pointer is in r0
|
||||
@
|
||||
@
|
||||
@ Per EHABI #4.7 this only saves the core integer registers.
|
||||
@ EHABI #7.4.5 notes that in general all VRS registers should be restored
|
||||
@ however this is very hard to do for VFP registers because it is unknown
|
||||
@ -996,6 +996,64 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
|
||||
|
||||
jumpr r31
|
||||
|
||||
#elif defined(__sparc__) && defined(__arch64__)
|
||||
|
||||
#
|
||||
# extern int __unw_getcontext(unw_context_t* thread_state)
|
||||
#
|
||||
# On entry:
|
||||
# thread_state pointer is in %o0
|
||||
#
|
||||
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
|
||||
.register %g2, #scratch
|
||||
.register %g3, #scratch
|
||||
.register %g6, #scratch
|
||||
.register %g7, #scratch
|
||||
stx %g1, [%o0 + 0x08]
|
||||
stx %g2, [%o0 + 0x10]
|
||||
stx %g3, [%o0 + 0x18]
|
||||
stx %g4, [%o0 + 0x20]
|
||||
stx %g5, [%o0 + 0x28]
|
||||
stx %g6, [%o0 + 0x30]
|
||||
stx %g7, [%o0 + 0x38]
|
||||
stx %o0, [%o0 + 0x40]
|
||||
stx %o1, [%o0 + 0x48]
|
||||
stx %o2, [%o0 + 0x50]
|
||||
stx %o3, [%o0 + 0x58]
|
||||
stx %o4, [%o0 + 0x60]
|
||||
stx %o5, [%o0 + 0x68]
|
||||
stx %o6, [%o0 + 0x70]
|
||||
stx %o7, [%o0 + 0x78]
|
||||
stx %l0, [%o0 + 0x80]
|
||||
stx %l1, [%o0 + 0x88]
|
||||
stx %l2, [%o0 + 0x90]
|
||||
stx %l3, [%o0 + 0x98]
|
||||
stx %l4, [%o0 + 0xa0]
|
||||
stx %l5, [%o0 + 0xa8]
|
||||
stx %l6, [%o0 + 0xb0]
|
||||
stx %l7, [%o0 + 0xb8]
|
||||
stx %i0, [%o0 + 0xc0]
|
||||
stx %i1, [%o0 + 0xc8]
|
||||
stx %i2, [%o0 + 0xd0]
|
||||
stx %i3, [%o0 + 0xd8]
|
||||
stx %i4, [%o0 + 0xe0]
|
||||
stx %i5, [%o0 + 0xe8]
|
||||
stx %i6, [%o0 + 0xf0]
|
||||
stx %i7, [%o0 + 0xf8]
|
||||
|
||||
# save StackGhost cookie
|
||||
mov %i7, %g4
|
||||
save %sp, -176, %sp
|
||||
# register window flush necessary even without StackGhost
|
||||
flushw
|
||||
restore
|
||||
ldx [%sp + 2047 + 0x78], %g5
|
||||
xor %g4, %g5, %g4
|
||||
stx %g4, [%o0 + 0x100]
|
||||
retl
|
||||
# return UNW_ESUCCESS
|
||||
clr %o0
|
||||
|
||||
#elif defined(__sparc__)
|
||||
|
||||
#
|
||||
|
11
lib/libunwind/src/config.h
vendored
11
lib/libunwind/src/config.h
vendored
@ -109,13 +109,10 @@
|
||||
#define _LIBUNWIND_SUPPORT_FRAME_APIS
|
||||
#endif
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__) || \
|
||||
defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__) || \
|
||||
(!defined(__APPLE__) && defined(__arm__)) || \
|
||||
defined(__aarch64__) || \
|
||||
defined(__mips__) || \
|
||||
defined(__riscv) || \
|
||||
defined(__hexagon__)
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || \
|
||||
(!defined(__APPLE__) && defined(__arm__)) || defined(__aarch64__) || \
|
||||
defined(__mips__) || defined(__riscv) || defined(__hexagon__) || \
|
||||
defined(__sparc__)
|
||||
#if !defined(_LIBUNWIND_BUILD_SJLJ_APIS)
|
||||
#define _LIBUNWIND_BUILD_ZERO_COST_APIS
|
||||
#endif
|
||||
|
2
lib/libunwind/src/libunwind.cpp
vendored
2
lib/libunwind/src/libunwind.cpp
vendored
@ -69,6 +69,8 @@ _LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor,
|
||||
# define REGISTER_KIND Registers_mips_newabi
|
||||
#elif defined(__mips__)
|
||||
# warning The MIPS architecture is not supported with this ABI and environment!
|
||||
#elif defined(__sparc__) && defined(__arch64__)
|
||||
# define REGISTER_KIND Registers_sparc64
|
||||
#elif defined(__sparc__)
|
||||
# define REGISTER_KIND Registers_sparc
|
||||
#elif defined(__riscv)
|
||||
|
Loading…
Reference in New Issue
Block a user