mirror of
https://github.com/ziglang/zig.git
synced 2024-11-27 07:32:44 +00:00
update libunwind to llvm10.0.0rc2
This commit is contained in:
parent
2289036a40
commit
f4317e4387
@ -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_RISCV 64
|
||||
|
||||
#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
|
||||
# if defined(__i386__)
|
||||
@ -118,6 +119,15 @@
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC
|
||||
#define _LIBUNWIND_CONTEXT_SIZE 16
|
||||
#define _LIBUNWIND_CURSOR_SIZE 23
|
||||
# elif defined(__riscv)
|
||||
# if __riscv_xlen == 64
|
||||
# define _LIBUNWIND_TARGET_RISCV 1
|
||||
# define _LIBUNWIND_CONTEXT_SIZE 64
|
||||
# define _LIBUNWIND_CURSOR_SIZE 76
|
||||
# else
|
||||
# error "Unsupported RISC-V ABI"
|
||||
# endif
|
||||
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV
|
||||
# else
|
||||
# error "Unsupported architecture."
|
||||
# endif
|
||||
@ -132,6 +142,7 @@
|
||||
# define _LIBUNWIND_TARGET_MIPS_O32 1
|
||||
# define _LIBUNWIND_TARGET_MIPS_NEWABI 1
|
||||
# define _LIBUNWIND_TARGET_SPARC 1
|
||||
# define _LIBUNWIND_TARGET_RISCV 1
|
||||
# define _LIBUNWIND_CONTEXT_SIZE 167
|
||||
# define _LIBUNWIND_CURSOR_SIZE 179
|
||||
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287
|
||||
|
@ -832,4 +832,75 @@ enum {
|
||||
UNW_SPARC_I7 = 31,
|
||||
};
|
||||
|
||||
// RISC-V registers. These match the DWARF register numbers defined by section
|
||||
// 4 of the RISC-V ELF psABI specification, which can be found at:
|
||||
//
|
||||
// https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md
|
||||
enum {
|
||||
UNW_RISCV_X0 = 0,
|
||||
UNW_RISCV_X1 = 1,
|
||||
UNW_RISCV_X2 = 2,
|
||||
UNW_RISCV_X3 = 3,
|
||||
UNW_RISCV_X4 = 4,
|
||||
UNW_RISCV_X5 = 5,
|
||||
UNW_RISCV_X6 = 6,
|
||||
UNW_RISCV_X7 = 7,
|
||||
UNW_RISCV_X8 = 8,
|
||||
UNW_RISCV_X9 = 9,
|
||||
UNW_RISCV_X10 = 10,
|
||||
UNW_RISCV_X11 = 11,
|
||||
UNW_RISCV_X12 = 12,
|
||||
UNW_RISCV_X13 = 13,
|
||||
UNW_RISCV_X14 = 14,
|
||||
UNW_RISCV_X15 = 15,
|
||||
UNW_RISCV_X16 = 16,
|
||||
UNW_RISCV_X17 = 17,
|
||||
UNW_RISCV_X18 = 18,
|
||||
UNW_RISCV_X19 = 19,
|
||||
UNW_RISCV_X20 = 20,
|
||||
UNW_RISCV_X21 = 21,
|
||||
UNW_RISCV_X22 = 22,
|
||||
UNW_RISCV_X23 = 23,
|
||||
UNW_RISCV_X24 = 24,
|
||||
UNW_RISCV_X25 = 25,
|
||||
UNW_RISCV_X26 = 26,
|
||||
UNW_RISCV_X27 = 27,
|
||||
UNW_RISCV_X28 = 28,
|
||||
UNW_RISCV_X29 = 29,
|
||||
UNW_RISCV_X30 = 30,
|
||||
UNW_RISCV_X31 = 31,
|
||||
UNW_RISCV_F0 = 32,
|
||||
UNW_RISCV_F1 = 33,
|
||||
UNW_RISCV_F2 = 34,
|
||||
UNW_RISCV_F3 = 35,
|
||||
UNW_RISCV_F4 = 36,
|
||||
UNW_RISCV_F5 = 37,
|
||||
UNW_RISCV_F6 = 38,
|
||||
UNW_RISCV_F7 = 39,
|
||||
UNW_RISCV_F8 = 40,
|
||||
UNW_RISCV_F9 = 41,
|
||||
UNW_RISCV_F10 = 42,
|
||||
UNW_RISCV_F11 = 43,
|
||||
UNW_RISCV_F12 = 44,
|
||||
UNW_RISCV_F13 = 45,
|
||||
UNW_RISCV_F14 = 46,
|
||||
UNW_RISCV_F15 = 47,
|
||||
UNW_RISCV_F16 = 48,
|
||||
UNW_RISCV_F17 = 49,
|
||||
UNW_RISCV_F18 = 50,
|
||||
UNW_RISCV_F19 = 51,
|
||||
UNW_RISCV_F20 = 52,
|
||||
UNW_RISCV_F21 = 53,
|
||||
UNW_RISCV_F22 = 54,
|
||||
UNW_RISCV_F23 = 55,
|
||||
UNW_RISCV_F24 = 56,
|
||||
UNW_RISCV_F25 = 57,
|
||||
UNW_RISCV_F26 = 58,
|
||||
UNW_RISCV_F27 = 59,
|
||||
UNW_RISCV_F28 = 60,
|
||||
UNW_RISCV_F29 = 61,
|
||||
UNW_RISCV_F30 = 62,
|
||||
UNW_RISCV_F31 = 63,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -27,11 +27,18 @@
|
||||
|
||||
#if _LIBUNWIND_USE_DLADDR
|
||||
#include <dlfcn.h>
|
||||
#if defined(__unix__) && defined(__ELF__) && defined(_LIBUNWIND_HAS_COMMENT_LIB_PRAGMA)
|
||||
#if defined(__ELF__) && defined(_LIBUNWIND_LINK_DL_LIB)
|
||||
#pragma comment(lib, "dl")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_ARM_EHABI)
|
||||
struct EHABIIndexEntry {
|
||||
uint32_t functionOffset;
|
||||
uint32_t data;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <mach-o/getsect.h>
|
||||
namespace libunwind {
|
||||
@ -426,8 +433,12 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
|
||||
HANDLE process = GetCurrentProcess();
|
||||
DWORD needed;
|
||||
|
||||
if (!EnumProcessModules(process, mods, sizeof(mods), &needed))
|
||||
if (!EnumProcessModules(process, mods, sizeof(mods), &needed)) {
|
||||
DWORD err = GetLastError();
|
||||
_LIBUNWIND_TRACE_UNWINDING("findUnwindSections: EnumProcessModules failed, "
|
||||
"returned error %d", (int)err);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < (needed / sizeof(HMODULE)); i++) {
|
||||
PIMAGE_DOS_HEADER pidh = (PIMAGE_DOS_HEADER)mods[i];
|
||||
@ -462,12 +473,13 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
|
||||
(void)targetAddr;
|
||||
(void)info;
|
||||
return true;
|
||||
#elif defined(_LIBUNWIND_ARM_EHABI) && defined(__BIONIC__) && \
|
||||
(__ANDROID_API__ < 21)
|
||||
#elif defined(_LIBUNWIND_ARM_EHABI) && defined(__BIONIC__)
|
||||
// For ARM EHABI, Bionic didn't implement dl_iterate_phdr until API 21. After
|
||||
// API 21, dl_iterate_phdr exists, but dl_unwind_find_exidx is much faster.
|
||||
int length = 0;
|
||||
info.arm_section =
|
||||
(uintptr_t)dl_unwind_find_exidx((_Unwind_Ptr)targetAddr, &length);
|
||||
info.arm_section_length = (uintptr_t)length;
|
||||
info.arm_section_length = (uintptr_t)length * sizeof(EHABIIndexEntry);
|
||||
if (info.arm_section && info.arm_section_length)
|
||||
return true;
|
||||
#elif defined(_LIBUNWIND_ARM_EHABI) || defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
|
||||
@ -497,32 +509,40 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
|
||||
#if !defined(Elf_Phdr)
|
||||
typedef ElfW(Phdr) Elf_Phdr;
|
||||
#endif
|
||||
#if !defined(Elf_Addr) && defined(__ANDROID__)
|
||||
#if !defined(Elf_Addr)
|
||||
typedef ElfW(Addr) Elf_Addr;
|
||||
#endif
|
||||
|
||||
Elf_Addr image_base = pinfo->dlpi_addr;
|
||||
|
||||
#if defined(__ANDROID__) && __ANDROID_API__ < 18
|
||||
if (image_base == 0) {
|
||||
// Normally, an image base of 0 indicates a non-PIE executable. On
|
||||
// versions of Android prior to API 18, the dynamic linker reported a
|
||||
// dlpi_addr of 0 for PIE executables. Compute the true image base
|
||||
// using the PT_PHDR segment.
|
||||
// See https://github.com/android/ndk/issues/505.
|
||||
for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) {
|
||||
const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i];
|
||||
if (phdr->p_type == PT_PHDR) {
|
||||
image_base = reinterpret_cast<Elf_Addr>(pinfo->dlpi_phdr) -
|
||||
phdr->p_vaddr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
|
||||
#if !defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
|
||||
#error "_LIBUNWIND_SUPPORT_DWARF_UNWIND requires _LIBUNWIND_SUPPORT_DWARF_INDEX on this platform."
|
||||
#endif
|
||||
size_t object_length;
|
||||
#if defined(__ANDROID__)
|
||||
Elf_Addr image_base =
|
||||
pinfo->dlpi_phnum
|
||||
? reinterpret_cast<Elf_Addr>(pinfo->dlpi_phdr) -
|
||||
reinterpret_cast<const Elf_Phdr *>(pinfo->dlpi_phdr)
|
||||
->p_offset
|
||||
: 0;
|
||||
#endif
|
||||
|
||||
for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) {
|
||||
const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i];
|
||||
if (phdr->p_type == PT_LOAD) {
|
||||
uintptr_t begin = pinfo->dlpi_addr + phdr->p_vaddr;
|
||||
#if defined(__ANDROID__)
|
||||
if (pinfo->dlpi_addr == 0 && phdr->p_vaddr < image_base)
|
||||
begin = begin + image_base;
|
||||
#endif
|
||||
uintptr_t begin = image_base + phdr->p_vaddr;
|
||||
uintptr_t end = begin + phdr->p_memsz;
|
||||
if (cbdata->targetAddr >= begin && cbdata->targetAddr < end) {
|
||||
cbdata->sects->dso_base = begin;
|
||||
@ -531,11 +551,7 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
|
||||
}
|
||||
} else if (phdr->p_type == PT_GNU_EH_FRAME) {
|
||||
EHHeaderParser<LocalAddressSpace>::EHHeaderInfo hdrInfo;
|
||||
uintptr_t eh_frame_hdr_start = pinfo->dlpi_addr + phdr->p_vaddr;
|
||||
#if defined(__ANDROID__)
|
||||
if (pinfo->dlpi_addr == 0 && phdr->p_vaddr < image_base)
|
||||
eh_frame_hdr_start = eh_frame_hdr_start + image_base;
|
||||
#endif
|
||||
uintptr_t eh_frame_hdr_start = image_base + phdr->p_vaddr;
|
||||
cbdata->sects->dwarf_index_section = eh_frame_hdr_start;
|
||||
cbdata->sects->dwarf_index_section_length = phdr->p_memsz;
|
||||
found_hdr = EHHeaderParser<LocalAddressSpace>::decodeEHHdr(
|
||||
@ -556,12 +572,12 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
|
||||
for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) {
|
||||
const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i];
|
||||
if (phdr->p_type == PT_LOAD) {
|
||||
uintptr_t begin = pinfo->dlpi_addr + phdr->p_vaddr;
|
||||
uintptr_t begin = image_base + phdr->p_vaddr;
|
||||
uintptr_t end = begin + phdr->p_memsz;
|
||||
if (cbdata->targetAddr >= begin && cbdata->targetAddr < end)
|
||||
found_obj = true;
|
||||
} else if (phdr->p_type == PT_ARM_EXIDX) {
|
||||
uintptr_t exidx_start = pinfo->dlpi_addr + phdr->p_vaddr;
|
||||
uintptr_t exidx_start = image_base + phdr->p_vaddr;
|
||||
cbdata->sects->arm_section = exidx_start;
|
||||
cbdata->sects->arm_section_length = phdr->p_memsz;
|
||||
found_hdr = true;
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
typedef typename A::sint_t sint_t;
|
||||
|
||||
static int stepWithDwarf(A &addressSpace, pint_t pc, pint_t fdeStart,
|
||||
R ®isters);
|
||||
R ®isters, bool &isSignalFrame);
|
||||
|
||||
private:
|
||||
|
||||
@ -150,7 +150,8 @@ v128 DwarfInstructions<A, R>::getSavedVectorRegister(
|
||||
|
||||
template <typename A, typename R>
|
||||
int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
|
||||
pint_t fdeStart, R ®isters) {
|
||||
pint_t fdeStart, R ®isters,
|
||||
bool &isSignalFrame) {
|
||||
FDE_Info fdeInfo;
|
||||
CIE_Info cieInfo;
|
||||
if (CFI_Parser<A>::decodeFDE(addressSpace, fdeStart, &fdeInfo,
|
||||
@ -196,6 +197,8 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
|
||||
// restoring SP means setting it to CFA.
|
||||
newRegisters.setSP(cfa);
|
||||
|
||||
isSignalFrame = cieInfo.isSignalFrame;
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_AARCH64)
|
||||
// If the target is aarch64 then the return address may have been signed
|
||||
// using the v8.3 pointer authentication extensions. The original
|
||||
@ -430,7 +433,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
|
||||
// pick from
|
||||
reg = addressSpace.get8(p);
|
||||
p += 1;
|
||||
value = sp[-reg];
|
||||
value = sp[-(int)reg];
|
||||
*(++sp) = value;
|
||||
if (log)
|
||||
fprintf(stderr, "duplicate %d in stack\n", reg);
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <windows.h>
|
||||
#elif !defined(_LIBUNWIND_HAS_NO_THREADS)
|
||||
#include <pthread.h>
|
||||
#if defined(__unix__) && defined(__ELF__) && defined(_LIBUNWIND_HAS_COMMENT_LIB_PRAGMA)
|
||||
#if defined(__ELF__) && defined(_LIBUNWIND_LINK_PTHREAD_LIB)
|
||||
#pragma comment(lib, "pthread")
|
||||
#endif
|
||||
#endif
|
||||
|
@ -34,6 +34,7 @@ enum {
|
||||
REGISTERS_MIPS_O32,
|
||||
REGISTERS_MIPS_NEWABI,
|
||||
REGISTERS_SPARC,
|
||||
REGISTERS_RISCV,
|
||||
};
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_I386)
|
||||
@ -3517,6 +3518,270 @@ inline const char *Registers_sparc::getRegisterName(int regNum) {
|
||||
}
|
||||
#endif // _LIBUNWIND_TARGET_SPARC
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_RISCV)
|
||||
/// Registers_riscv holds the register state of a thread in a 64-bit RISC-V
|
||||
/// process.
|
||||
class _LIBUNWIND_HIDDEN Registers_riscv {
|
||||
public:
|
||||
Registers_riscv();
|
||||
Registers_riscv(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_RISCV; }
|
||||
static int getArch() { return REGISTERS_RISCV; }
|
||||
|
||||
uint64_t getSP() const { return _registers[2]; }
|
||||
void setSP(uint64_t value) { _registers[2] = value; }
|
||||
uint64_t getIP() const { return _registers[1]; }
|
||||
void setIP(uint64_t value) { _registers[1] = value; }
|
||||
|
||||
private:
|
||||
|
||||
uint64_t _registers[32];
|
||||
double _floats[32];
|
||||
};
|
||||
|
||||
inline Registers_riscv::Registers_riscv(const void *registers) {
|
||||
static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit),
|
||||
"riscv registers do not fit into unw_context_t");
|
||||
memcpy(&_registers, registers, sizeof(_registers));
|
||||
static_assert(sizeof(_registers) == 0x100,
|
||||
"expected float registers to be at offset 256");
|
||||
memcpy(_floats,
|
||||
static_cast<const uint8_t *>(registers) + sizeof(_registers),
|
||||
sizeof(_floats));
|
||||
}
|
||||
|
||||
inline Registers_riscv::Registers_riscv() {
|
||||
memset(&_registers, 0, sizeof(_registers));
|
||||
memset(&_floats, 0, sizeof(_floats));
|
||||
}
|
||||
|
||||
inline bool Registers_riscv::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_RISCV_F31)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline uint64_t Registers_riscv::getRegister(int regNum) const {
|
||||
if (regNum == UNW_REG_IP)
|
||||
return _registers[1];
|
||||
if (regNum == UNW_REG_SP)
|
||||
return _registers[2];
|
||||
if (regNum == UNW_RISCV_X0)
|
||||
return 0;
|
||||
if ((regNum > 0) && (regNum < 32))
|
||||
return _registers[regNum];
|
||||
_LIBUNWIND_ABORT("unsupported riscv register");
|
||||
}
|
||||
|
||||
inline void Registers_riscv::setRegister(int regNum, uint64_t value) {
|
||||
if (regNum == UNW_REG_IP)
|
||||
_registers[1] = value;
|
||||
else if (regNum == UNW_REG_SP)
|
||||
_registers[2] = value;
|
||||
else if (regNum == UNW_RISCV_X0)
|
||||
/* x0 is hardwired to zero */
|
||||
return;
|
||||
else if ((regNum > 0) && (regNum < 32))
|
||||
_registers[regNum] = value;
|
||||
else
|
||||
_LIBUNWIND_ABORT("unsupported riscv register");
|
||||
}
|
||||
|
||||
inline const char *Registers_riscv::getRegisterName(int regNum) {
|
||||
switch (regNum) {
|
||||
case UNW_REG_IP:
|
||||
return "pc";
|
||||
case UNW_REG_SP:
|
||||
return "sp";
|
||||
case UNW_RISCV_X0:
|
||||
return "zero";
|
||||
case UNW_RISCV_X1:
|
||||
return "ra";
|
||||
case UNW_RISCV_X2:
|
||||
return "sp";
|
||||
case UNW_RISCV_X3:
|
||||
return "gp";
|
||||
case UNW_RISCV_X4:
|
||||
return "tp";
|
||||
case UNW_RISCV_X5:
|
||||
return "t0";
|
||||
case UNW_RISCV_X6:
|
||||
return "t1";
|
||||
case UNW_RISCV_X7:
|
||||
return "t2";
|
||||
case UNW_RISCV_X8:
|
||||
return "s0";
|
||||
case UNW_RISCV_X9:
|
||||
return "s1";
|
||||
case UNW_RISCV_X10:
|
||||
return "a0";
|
||||
case UNW_RISCV_X11:
|
||||
return "a1";
|
||||
case UNW_RISCV_X12:
|
||||
return "a2";
|
||||
case UNW_RISCV_X13:
|
||||
return "a3";
|
||||
case UNW_RISCV_X14:
|
||||
return "a4";
|
||||
case UNW_RISCV_X15:
|
||||
return "a5";
|
||||
case UNW_RISCV_X16:
|
||||
return "a6";
|
||||
case UNW_RISCV_X17:
|
||||
return "a7";
|
||||
case UNW_RISCV_X18:
|
||||
return "s2";
|
||||
case UNW_RISCV_X19:
|
||||
return "s3";
|
||||
case UNW_RISCV_X20:
|
||||
return "s4";
|
||||
case UNW_RISCV_X21:
|
||||
return "s5";
|
||||
case UNW_RISCV_X22:
|
||||
return "s6";
|
||||
case UNW_RISCV_X23:
|
||||
return "s7";
|
||||
case UNW_RISCV_X24:
|
||||
return "s8";
|
||||
case UNW_RISCV_X25:
|
||||
return "s9";
|
||||
case UNW_RISCV_X26:
|
||||
return "s10";
|
||||
case UNW_RISCV_X27:
|
||||
return "s11";
|
||||
case UNW_RISCV_X28:
|
||||
return "t3";
|
||||
case UNW_RISCV_X29:
|
||||
return "t4";
|
||||
case UNW_RISCV_X30:
|
||||
return "t5";
|
||||
case UNW_RISCV_X31:
|
||||
return "t6";
|
||||
case UNW_RISCV_F0:
|
||||
return "ft0";
|
||||
case UNW_RISCV_F1:
|
||||
return "ft1";
|
||||
case UNW_RISCV_F2:
|
||||
return "ft2";
|
||||
case UNW_RISCV_F3:
|
||||
return "ft3";
|
||||
case UNW_RISCV_F4:
|
||||
return "ft4";
|
||||
case UNW_RISCV_F5:
|
||||
return "ft5";
|
||||
case UNW_RISCV_F6:
|
||||
return "ft6";
|
||||
case UNW_RISCV_F7:
|
||||
return "ft7";
|
||||
case UNW_RISCV_F8:
|
||||
return "fs0";
|
||||
case UNW_RISCV_F9:
|
||||
return "fs1";
|
||||
case UNW_RISCV_F10:
|
||||
return "fa0";
|
||||
case UNW_RISCV_F11:
|
||||
return "fa1";
|
||||
case UNW_RISCV_F12:
|
||||
return "fa2";
|
||||
case UNW_RISCV_F13:
|
||||
return "fa3";
|
||||
case UNW_RISCV_F14:
|
||||
return "fa4";
|
||||
case UNW_RISCV_F15:
|
||||
return "fa5";
|
||||
case UNW_RISCV_F16:
|
||||
return "fa6";
|
||||
case UNW_RISCV_F17:
|
||||
return "fa7";
|
||||
case UNW_RISCV_F18:
|
||||
return "fs2";
|
||||
case UNW_RISCV_F19:
|
||||
return "fs3";
|
||||
case UNW_RISCV_F20:
|
||||
return "fs4";
|
||||
case UNW_RISCV_F21:
|
||||
return "fs5";
|
||||
case UNW_RISCV_F22:
|
||||
return "fs6";
|
||||
case UNW_RISCV_F23:
|
||||
return "fs7";
|
||||
case UNW_RISCV_F24:
|
||||
return "fs8";
|
||||
case UNW_RISCV_F25:
|
||||
return "fs9";
|
||||
case UNW_RISCV_F26:
|
||||
return "fs10";
|
||||
case UNW_RISCV_F27:
|
||||
return "fs11";
|
||||
case UNW_RISCV_F28:
|
||||
return "ft8";
|
||||
case UNW_RISCV_F29:
|
||||
return "ft9";
|
||||
case UNW_RISCV_F30:
|
||||
return "ft10";
|
||||
case UNW_RISCV_F31:
|
||||
return "ft11";
|
||||
default:
|
||||
return "unknown register";
|
||||
}
|
||||
}
|
||||
|
||||
inline bool Registers_riscv::validFloatRegister(int regNum) const {
|
||||
if (regNum < UNW_RISCV_F0)
|
||||
return false;
|
||||
if (regNum > UNW_RISCV_F31)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline double Registers_riscv::getFloatRegister(int regNum) const {
|
||||
#if defined(__riscv_flen) && __riscv_flen == 64
|
||||
assert(validFloatRegister(regNum));
|
||||
return _floats[regNum - UNW_RISCV_F0];
|
||||
#else
|
||||
_LIBUNWIND_ABORT("libunwind not built with float support");
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void Registers_riscv::setFloatRegister(int regNum, double value) {
|
||||
#if defined(__riscv_flen) && __riscv_flen == 64
|
||||
assert(validFloatRegister(regNum));
|
||||
_floats[regNum - UNW_RISCV_F0] = value;
|
||||
#else
|
||||
_LIBUNWIND_ABORT("libunwind not built with float support");
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool Registers_riscv::validVectorRegister(int) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline v128 Registers_riscv::getVectorRegister(int) const {
|
||||
_LIBUNWIND_ABORT("no riscv vector register support yet");
|
||||
}
|
||||
|
||||
inline void Registers_riscv::setVectorRegister(int, v128) {
|
||||
_LIBUNWIND_ABORT("no riscv vector register support yet");
|
||||
}
|
||||
#endif // _LIBUNWIND_TARGET_RISCV
|
||||
} // namespace libunwind
|
||||
|
||||
#endif // __REGISTERS_HPP__
|
||||
|
@ -941,8 +941,13 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
|
||||
// format 1", which is equivalent to FSTMD + a padding word.
|
||||
for (uint32_t i = first; i < end; ++i) {
|
||||
// SP is only 32-bit aligned so don't copy 64-bit at a time.
|
||||
uint64_t value = *sp++;
|
||||
value |= ((uint64_t)(*sp++)) << 32;
|
||||
uint64_t w0 = *sp++;
|
||||
uint64_t w1 = *sp++;
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
uint64_t value = (w1 << 32) | w0;
|
||||
#else
|
||||
uint64_t value = (w0 << 32) | w1;
|
||||
#endif
|
||||
if (_Unwind_VRS_Set(context, regclass, i, representation, &value) !=
|
||||
_UVRSR_OK)
|
||||
return _UVRSR_FAILED;
|
||||
|
@ -929,7 +929,7 @@ private:
|
||||
return DwarfInstructions<A, R>::stepWithDwarf(_addressSpace,
|
||||
(pint_t)this->getReg(UNW_REG_IP),
|
||||
(pint_t)_info.unwind_info,
|
||||
_registers);
|
||||
_registers, _isSignalFrame);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -995,6 +995,12 @@ private:
|
||||
int stepWithCompactEncoding(Registers_sparc &) { return UNW_EINVAL; }
|
||||
#endif
|
||||
|
||||
#if defined (_LIBUNWIND_TARGET_RISCV)
|
||||
int stepWithCompactEncoding(Registers_riscv &) {
|
||||
return UNW_EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool compactSaysUseDwarf(uint32_t *offset=NULL) const {
|
||||
R dummy;
|
||||
return compactSaysUseDwarf(dummy, offset);
|
||||
@ -1061,6 +1067,12 @@ private:
|
||||
bool compactSaysUseDwarf(Registers_sparc &, uint32_t *) const { return true; }
|
||||
#endif
|
||||
|
||||
#if defined (_LIBUNWIND_TARGET_RISCV)
|
||||
bool compactSaysUseDwarf(Registers_riscv &, uint32_t *) const {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
|
||||
|
||||
#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
|
||||
@ -1127,6 +1139,12 @@ private:
|
||||
compact_unwind_encoding_t dwarfEncoding(Registers_sparc &) const { return 0; }
|
||||
#endif
|
||||
|
||||
#if defined (_LIBUNWIND_TARGET_RISCV)
|
||||
compact_unwind_encoding_t dwarfEncoding(Registers_riscv &) const {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
|
||||
|
||||
#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
|
||||
@ -1222,11 +1240,6 @@ template <typename A, typename R> bool UnwindCursor<A, R>::isSignalFrame() {
|
||||
#endif // defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
|
||||
|
||||
#if defined(_LIBUNWIND_ARM_EHABI)
|
||||
struct EHABIIndexEntry {
|
||||
uint32_t functionOffset;
|
||||
uint32_t data;
|
||||
};
|
||||
|
||||
template<typename A>
|
||||
struct EHABISectionIterator {
|
||||
typedef EHABISectionIterator _Self;
|
||||
@ -1991,7 +2004,10 @@ int UnwindCursor<A, R>::step() {
|
||||
|
||||
template <typename A, typename R>
|
||||
void UnwindCursor<A, R>::getInfo(unw_proc_info_t *info) {
|
||||
*info = _info;
|
||||
if (_unwindInfoMissing)
|
||||
memset(info, 0, sizeof(*info));
|
||||
else
|
||||
*info = _info;
|
||||
}
|
||||
|
||||
template <typename A, typename R>
|
||||
|
@ -221,7 +221,14 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetCFA(struct _Unwind_Context *context) {
|
||||
_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context,
|
||||
int *ipBefore) {
|
||||
_LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p)", (void *)context);
|
||||
*ipBefore = 0;
|
||||
int isSignalFrame = __unw_is_signal_frame((unw_cursor_t *)context);
|
||||
// Negative means some kind of error (probably UNW_ENOINFO), but we have no
|
||||
// good way to report that, and this maintains backward compatibility with the
|
||||
// implementation that hard-coded zero in every case, even signal frames.
|
||||
if (isSignalFrame <= 0)
|
||||
*ipBefore = 0;
|
||||
else
|
||||
*ipBefore = 1;
|
||||
return _Unwind_GetIP(context);
|
||||
}
|
||||
|
||||
|
@ -1029,6 +1029,87 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_sparc6jumptoEv)
|
||||
jmp %o7
|
||||
nop
|
||||
|
||||
#elif defined(__riscv) && __riscv_xlen == 64
|
||||
|
||||
//
|
||||
// void libunwind::Registers_riscv::jumpto()
|
||||
//
|
||||
// On entry:
|
||||
// thread_state pointer is in a0
|
||||
//
|
||||
.p2align 2
|
||||
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv)
|
||||
#if defined(__riscv_flen) && __riscv_flen == 64
|
||||
fld f0, (8 * 32 + 8 * 0)(a0)
|
||||
fld f1, (8 * 32 + 8 * 1)(a0)
|
||||
fld f2, (8 * 32 + 8 * 2)(a0)
|
||||
fld f3, (8 * 32 + 8 * 3)(a0)
|
||||
fld f4, (8 * 32 + 8 * 4)(a0)
|
||||
fld f5, (8 * 32 + 8 * 5)(a0)
|
||||
fld f6, (8 * 32 + 8 * 6)(a0)
|
||||
fld f7, (8 * 32 + 8 * 7)(a0)
|
||||
fld f8, (8 * 32 + 8 * 8)(a0)
|
||||
fld f9, (8 * 32 + 8 * 9)(a0)
|
||||
fld f10, (8 * 32 + 8 * 10)(a0)
|
||||
fld f11, (8 * 32 + 8 * 11)(a0)
|
||||
fld f12, (8 * 32 + 8 * 12)(a0)
|
||||
fld f13, (8 * 32 + 8 * 13)(a0)
|
||||
fld f14, (8 * 32 + 8 * 14)(a0)
|
||||
fld f15, (8 * 32 + 8 * 15)(a0)
|
||||
fld f16, (8 * 32 + 8 * 16)(a0)
|
||||
fld f17, (8 * 32 + 8 * 17)(a0)
|
||||
fld f18, (8 * 32 + 8 * 18)(a0)
|
||||
fld f19, (8 * 32 + 8 * 19)(a0)
|
||||
fld f20, (8 * 32 + 8 * 20)(a0)
|
||||
fld f21, (8 * 32 + 8 * 21)(a0)
|
||||
fld f22, (8 * 32 + 8 * 22)(a0)
|
||||
fld f23, (8 * 32 + 8 * 23)(a0)
|
||||
fld f24, (8 * 32 + 8 * 24)(a0)
|
||||
fld f25, (8 * 32 + 8 * 25)(a0)
|
||||
fld f26, (8 * 32 + 8 * 26)(a0)
|
||||
fld f27, (8 * 32 + 8 * 27)(a0)
|
||||
fld f28, (8 * 32 + 8 * 28)(a0)
|
||||
fld f29, (8 * 32 + 8 * 29)(a0)
|
||||
fld f30, (8 * 32 + 8 * 30)(a0)
|
||||
fld f31, (8 * 32 + 8 * 31)(a0)
|
||||
#endif
|
||||
|
||||
// x0 is zero
|
||||
ld x1, (8 * 1)(a0)
|
||||
ld x2, (8 * 2)(a0)
|
||||
ld x3, (8 * 3)(a0)
|
||||
ld x4, (8 * 4)(a0)
|
||||
ld x5, (8 * 5)(a0)
|
||||
ld x6, (8 * 6)(a0)
|
||||
ld x7, (8 * 7)(a0)
|
||||
ld x8, (8 * 8)(a0)
|
||||
ld x9, (8 * 9)(a0)
|
||||
// skip a0 for now
|
||||
ld x11, (8 * 11)(a0)
|
||||
ld x12, (8 * 12)(a0)
|
||||
ld x13, (8 * 13)(a0)
|
||||
ld x14, (8 * 14)(a0)
|
||||
ld x15, (8 * 15)(a0)
|
||||
ld x16, (8 * 16)(a0)
|
||||
ld x17, (8 * 17)(a0)
|
||||
ld x18, (8 * 18)(a0)
|
||||
ld x19, (8 * 19)(a0)
|
||||
ld x20, (8 * 20)(a0)
|
||||
ld x21, (8 * 21)(a0)
|
||||
ld x22, (8 * 22)(a0)
|
||||
ld x23, (8 * 23)(a0)
|
||||
ld x24, (8 * 24)(a0)
|
||||
ld x25, (8 * 25)(a0)
|
||||
ld x26, (8 * 26)(a0)
|
||||
ld x27, (8 * 27)(a0)
|
||||
ld x28, (8 * 28)(a0)
|
||||
ld x29, (8 * 29)(a0)
|
||||
ld x30, (8 * 30)(a0)
|
||||
ld x31, (8 * 31)(a0)
|
||||
ld x10, (8 * 10)(a0) // restore a0
|
||||
|
||||
ret // jump to ra
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */
|
||||
|
@ -974,6 +974,86 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
|
||||
std %i6, [%o0 + 120]
|
||||
jmp %o7
|
||||
clr %o0 // return UNW_ESUCCESS
|
||||
|
||||
#elif defined(__riscv) && __riscv_xlen == 64
|
||||
|
||||
#
|
||||
# extern int __unw_getcontext(unw_context_t* thread_state)
|
||||
#
|
||||
# On entry:
|
||||
# thread_state pointer is in a0
|
||||
#
|
||||
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
|
||||
// x0 is zero
|
||||
sd x1, (8 * 1)(a0)
|
||||
sd x2, (8 * 2)(a0)
|
||||
sd x3, (8 * 3)(a0)
|
||||
sd x4, (8 * 4)(a0)
|
||||
sd x5, (8 * 5)(a0)
|
||||
sd x6, (8 * 6)(a0)
|
||||
sd x7, (8 * 7)(a0)
|
||||
sd x8, (8 * 8)(a0)
|
||||
sd x9, (8 * 9)(a0)
|
||||
sd x10, (8 * 10)(a0)
|
||||
sd x11, (8 * 11)(a0)
|
||||
sd x12, (8 * 12)(a0)
|
||||
sd x13, (8 * 13)(a0)
|
||||
sd x14, (8 * 14)(a0)
|
||||
sd x15, (8 * 15)(a0)
|
||||
sd x16, (8 * 16)(a0)
|
||||
sd x17, (8 * 17)(a0)
|
||||
sd x18, (8 * 18)(a0)
|
||||
sd x19, (8 * 19)(a0)
|
||||
sd x20, (8 * 20)(a0)
|
||||
sd x21, (8 * 21)(a0)
|
||||
sd x22, (8 * 22)(a0)
|
||||
sd x23, (8 * 23)(a0)
|
||||
sd x24, (8 * 24)(a0)
|
||||
sd x25, (8 * 25)(a0)
|
||||
sd x26, (8 * 26)(a0)
|
||||
sd x27, (8 * 27)(a0)
|
||||
sd x28, (8 * 28)(a0)
|
||||
sd x29, (8 * 29)(a0)
|
||||
sd x30, (8 * 30)(a0)
|
||||
sd x31, (8 * 31)(a0)
|
||||
|
||||
#if defined(__riscv_flen) && __riscv_flen == 64
|
||||
fsd f0, (8 * 32 + 8 * 0)(a0)
|
||||
fsd f1, (8 * 32 + 8 * 1)(a0)
|
||||
fsd f2, (8 * 32 + 8 * 2)(a0)
|
||||
fsd f3, (8 * 32 + 8 * 3)(a0)
|
||||
fsd f4, (8 * 32 + 8 * 4)(a0)
|
||||
fsd f5, (8 * 32 + 8 * 5)(a0)
|
||||
fsd f6, (8 * 32 + 8 * 6)(a0)
|
||||
fsd f7, (8 * 32 + 8 * 7)(a0)
|
||||
fsd f8, (8 * 32 + 8 * 8)(a0)
|
||||
fsd f9, (8 * 32 + 8 * 9)(a0)
|
||||
fsd f10, (8 * 32 + 8 * 10)(a0)
|
||||
fsd f11, (8 * 32 + 8 * 11)(a0)
|
||||
fsd f12, (8 * 32 + 8 * 12)(a0)
|
||||
fsd f13, (8 * 32 + 8 * 13)(a0)
|
||||
fsd f14, (8 * 32 + 8 * 14)(a0)
|
||||
fsd f15, (8 * 32 + 8 * 15)(a0)
|
||||
fsd f16, (8 * 32 + 8 * 16)(a0)
|
||||
fsd f17, (8 * 32 + 8 * 17)(a0)
|
||||
fsd f18, (8 * 32 + 8 * 18)(a0)
|
||||
fsd f19, (8 * 32 + 8 * 19)(a0)
|
||||
fsd f20, (8 * 32 + 8 * 20)(a0)
|
||||
fsd f21, (8 * 32 + 8 * 21)(a0)
|
||||
fsd f22, (8 * 32 + 8 * 22)(a0)
|
||||
fsd f23, (8 * 32 + 8 * 23)(a0)
|
||||
fsd f24, (8 * 32 + 8 * 24)(a0)
|
||||
fsd f25, (8 * 32 + 8 * 25)(a0)
|
||||
fsd f26, (8 * 32 + 8 * 26)(a0)
|
||||
fsd f27, (8 * 32 + 8 * 27)(a0)
|
||||
fsd f28, (8 * 32 + 8 * 28)(a0)
|
||||
fsd f29, (8 * 32 + 8 * 29)(a0)
|
||||
fsd f30, (8 * 32 + 8 * 30)(a0)
|
||||
fsd f31, (8 * 32 + 8 * 31)(a0)
|
||||
#endif
|
||||
|
||||
li a0, 0 // return UNW_ESUCCESS
|
||||
ret // jump to ra
|
||||
#endif
|
||||
|
||||
WEAK_ALIAS(__unw_getcontext, unw_getcontext)
|
||||
|
@ -103,7 +103,8 @@
|
||||
defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__) || \
|
||||
(!defined(__APPLE__) && defined(__arm__)) || \
|
||||
(defined(__arm64__) || defined(__aarch64__)) || \
|
||||
defined(__mips__)
|
||||
defined(__mips__) || \
|
||||
defined(__riscv)
|
||||
#if !defined(_LIBUNWIND_BUILD_SJLJ_APIS)
|
||||
#define _LIBUNWIND_BUILD_ZERO_COST_APIS
|
||||
#endif
|
||||
|
@ -58,6 +58,8 @@ _LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor,
|
||||
# warning The MIPS architecture is not supported with this ABI and environment!
|
||||
#elif defined(__sparc__)
|
||||
# define REGISTER_KIND Registers_sparc
|
||||
#elif defined(__riscv) && __riscv_xlen == 64
|
||||
# define REGISTER_KIND Registers_riscv
|
||||
#else
|
||||
# error Architecture not supported
|
||||
#endif
|
||||
@ -171,8 +173,7 @@ _LIBUNWIND_HIDDEN int __unw_get_proc_info(unw_cursor_t *cursor,
|
||||
co->getInfo(info);
|
||||
if (info->end_ip == 0)
|
||||
return UNW_ENOINFO;
|
||||
else
|
||||
return UNW_ESUCCESS;
|
||||
return UNW_ESUCCESS;
|
||||
}
|
||||
_LIBUNWIND_WEAK_ALIAS(__unw_get_proc_info, unw_get_proc_info)
|
||||
|
||||
@ -194,8 +195,7 @@ _LIBUNWIND_HIDDEN int __unw_get_proc_name(unw_cursor_t *cursor, char *buf,
|
||||
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
|
||||
if (co->getFunctionName(buf, bufLen, offset))
|
||||
return UNW_ESUCCESS;
|
||||
else
|
||||
return UNW_EUNSPEC;
|
||||
return UNW_EUNSPEC;
|
||||
}
|
||||
_LIBUNWIND_WEAK_ALIAS(__unw_get_proc_name, unw_get_proc_name)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user