mirror of
https://github.com/ziglang/zig.git
synced 2024-11-27 07:32:44 +00:00
update libunwind to llvm 16
This commit is contained in:
parent
e41b58ddc3
commit
1e7083d09c
2
lib/libcxx/include/__config
vendored
2
lib/libcxx/include/__config
vendored
@ -10,8 +10,6 @@
|
|||||||
#ifndef _LIBCPP___CONFIG
|
#ifndef _LIBCPP___CONFIG
|
||||||
#define _LIBCPP___CONFIG
|
#define _LIBCPP___CONFIG
|
||||||
|
|
||||||
#include <__config_site>
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||||||
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
# define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
|
# define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
|
||||||
|
12
lib/libunwind/include/__libunwind_config.h
vendored
12
lib/libunwind/include/__libunwind_config.h
vendored
@ -30,6 +30,7 @@
|
|||||||
#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
|
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X 83
|
||||||
|
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH 64
|
||||||
|
|
||||||
#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
|
#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
|
||||||
# if defined(__linux__)
|
# if defined(__linux__)
|
||||||
@ -166,6 +167,16 @@
|
|||||||
# define _LIBUNWIND_CONTEXT_SIZE 34
|
# define _LIBUNWIND_CONTEXT_SIZE 34
|
||||||
# define _LIBUNWIND_CURSOR_SIZE 46
|
# define _LIBUNWIND_CURSOR_SIZE 46
|
||||||
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X
|
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X
|
||||||
|
#elif defined(__loongarch__)
|
||||||
|
#define _LIBUNWIND_TARGET_LOONGARCH 1
|
||||||
|
#if __loongarch_grlen == 64
|
||||||
|
#define _LIBUNWIND_CONTEXT_SIZE 65
|
||||||
|
#define _LIBUNWIND_CURSOR_SIZE 77
|
||||||
|
#else
|
||||||
|
#error "Unsupported LoongArch ABI"
|
||||||
|
#endif
|
||||||
|
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER \
|
||||||
|
_LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH
|
||||||
# else
|
# else
|
||||||
# error "Unsupported architecture."
|
# error "Unsupported architecture."
|
||||||
# endif
|
# endif
|
||||||
@ -185,6 +196,7 @@
|
|||||||
# 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_TARGET_S390X 1
|
||||||
|
#define _LIBUNWIND_TARGET_LOONGARCH 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
|
||||||
|
78
lib/libunwind/include/libunwind.h
vendored
78
lib/libunwind/include/libunwind.h
vendored
@ -1023,6 +1023,16 @@ enum {
|
|||||||
UNW_RISCV_F29 = 61,
|
UNW_RISCV_F29 = 61,
|
||||||
UNW_RISCV_F30 = 62,
|
UNW_RISCV_F30 = 62,
|
||||||
UNW_RISCV_F31 = 63,
|
UNW_RISCV_F31 = 63,
|
||||||
|
// 65-95 -- Reserved for future standard extensions
|
||||||
|
// 96-127 -- v0-v31 (Vector registers)
|
||||||
|
// 128-3071 -- Reserved for future standard extensions
|
||||||
|
// 3072-4095 -- Reserved for custom extensions
|
||||||
|
// 4096-8191 -- CSRs
|
||||||
|
//
|
||||||
|
// VLENB CSR number: 0xC22 -- defined by section 3 of v-spec:
|
||||||
|
// https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#3-vector-extension-programmers-model
|
||||||
|
// VLENB DWARF number: 0x1000 + 0xC22
|
||||||
|
UNW_RISCV_VLENB = 0x1C22,
|
||||||
};
|
};
|
||||||
|
|
||||||
// VE register numbers
|
// VE register numbers
|
||||||
@ -1219,4 +1229,72 @@ enum {
|
|||||||
// 68-83 Vector Registers %v16-%v31
|
// 68-83 Vector Registers %v16-%v31
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// LoongArch registers.
|
||||||
|
enum {
|
||||||
|
UNW_LOONGARCH_R0 = 0,
|
||||||
|
UNW_LOONGARCH_R1 = 1,
|
||||||
|
UNW_LOONGARCH_R2 = 2,
|
||||||
|
UNW_LOONGARCH_R3 = 3,
|
||||||
|
UNW_LOONGARCH_R4 = 4,
|
||||||
|
UNW_LOONGARCH_R5 = 5,
|
||||||
|
UNW_LOONGARCH_R6 = 6,
|
||||||
|
UNW_LOONGARCH_R7 = 7,
|
||||||
|
UNW_LOONGARCH_R8 = 8,
|
||||||
|
UNW_LOONGARCH_R9 = 9,
|
||||||
|
UNW_LOONGARCH_R10 = 10,
|
||||||
|
UNW_LOONGARCH_R11 = 11,
|
||||||
|
UNW_LOONGARCH_R12 = 12,
|
||||||
|
UNW_LOONGARCH_R13 = 13,
|
||||||
|
UNW_LOONGARCH_R14 = 14,
|
||||||
|
UNW_LOONGARCH_R15 = 15,
|
||||||
|
UNW_LOONGARCH_R16 = 16,
|
||||||
|
UNW_LOONGARCH_R17 = 17,
|
||||||
|
UNW_LOONGARCH_R18 = 18,
|
||||||
|
UNW_LOONGARCH_R19 = 19,
|
||||||
|
UNW_LOONGARCH_R20 = 20,
|
||||||
|
UNW_LOONGARCH_R21 = 21,
|
||||||
|
UNW_LOONGARCH_R22 = 22,
|
||||||
|
UNW_LOONGARCH_R23 = 23,
|
||||||
|
UNW_LOONGARCH_R24 = 24,
|
||||||
|
UNW_LOONGARCH_R25 = 25,
|
||||||
|
UNW_LOONGARCH_R26 = 26,
|
||||||
|
UNW_LOONGARCH_R27 = 27,
|
||||||
|
UNW_LOONGARCH_R28 = 28,
|
||||||
|
UNW_LOONGARCH_R29 = 29,
|
||||||
|
UNW_LOONGARCH_R30 = 30,
|
||||||
|
UNW_LOONGARCH_R31 = 31,
|
||||||
|
UNW_LOONGARCH_F0 = 32,
|
||||||
|
UNW_LOONGARCH_F1 = 33,
|
||||||
|
UNW_LOONGARCH_F2 = 34,
|
||||||
|
UNW_LOONGARCH_F3 = 35,
|
||||||
|
UNW_LOONGARCH_F4 = 36,
|
||||||
|
UNW_LOONGARCH_F5 = 37,
|
||||||
|
UNW_LOONGARCH_F6 = 38,
|
||||||
|
UNW_LOONGARCH_F7 = 39,
|
||||||
|
UNW_LOONGARCH_F8 = 40,
|
||||||
|
UNW_LOONGARCH_F9 = 41,
|
||||||
|
UNW_LOONGARCH_F10 = 42,
|
||||||
|
UNW_LOONGARCH_F11 = 43,
|
||||||
|
UNW_LOONGARCH_F12 = 44,
|
||||||
|
UNW_LOONGARCH_F13 = 45,
|
||||||
|
UNW_LOONGARCH_F14 = 46,
|
||||||
|
UNW_LOONGARCH_F15 = 47,
|
||||||
|
UNW_LOONGARCH_F16 = 48,
|
||||||
|
UNW_LOONGARCH_F17 = 49,
|
||||||
|
UNW_LOONGARCH_F18 = 50,
|
||||||
|
UNW_LOONGARCH_F19 = 51,
|
||||||
|
UNW_LOONGARCH_F20 = 52,
|
||||||
|
UNW_LOONGARCH_F21 = 53,
|
||||||
|
UNW_LOONGARCH_F22 = 54,
|
||||||
|
UNW_LOONGARCH_F23 = 55,
|
||||||
|
UNW_LOONGARCH_F24 = 56,
|
||||||
|
UNW_LOONGARCH_F25 = 57,
|
||||||
|
UNW_LOONGARCH_F26 = 58,
|
||||||
|
UNW_LOONGARCH_F27 = 59,
|
||||||
|
UNW_LOONGARCH_F28 = 60,
|
||||||
|
UNW_LOONGARCH_F29 = 61,
|
||||||
|
UNW_LOONGARCH_F30 = 62,
|
||||||
|
UNW_LOONGARCH_F31 = 63,
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// The compact unwind endoding is a 32-bit value which encoded in an
|
// The compact unwind encoding is a 32-bit value which encoded in an
|
||||||
// architecture specific way, which registers to restore from where, and how
|
// architecture specific way, which registers to restore from where, and how
|
||||||
// to unwind out of the function.
|
// to unwind out of the function.
|
||||||
//
|
//
|
||||||
@ -116,7 +116,7 @@ enum {
|
|||||||
// on the stack immediately after the return address. The stack_size/4 is
|
// on the stack immediately after the return address. The stack_size/4 is
|
||||||
// encoded in the UNWIND_X86_FRAMELESS_STACK_SIZE (max stack size is 1024).
|
// encoded in the UNWIND_X86_FRAMELESS_STACK_SIZE (max stack size is 1024).
|
||||||
// The number of registers saved is encoded in UNWIND_X86_FRAMELESS_STACK_REG_COUNT.
|
// The number of registers saved is encoded in UNWIND_X86_FRAMELESS_STACK_REG_COUNT.
|
||||||
// UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION constains which registers were
|
// UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION contains which registers were
|
||||||
// saved and their order.
|
// saved and their order.
|
||||||
// UNWIND_X86_MODE_STACK_IND:
|
// UNWIND_X86_MODE_STACK_IND:
|
||||||
// A "frameless" (EBP not used as frame pointer) function large constant
|
// A "frameless" (EBP not used as frame pointer) function large constant
|
||||||
@ -250,7 +250,7 @@ enum {
|
|||||||
// on the stack immediately after the return address. The stack_size/8 is
|
// on the stack immediately after the return address. The stack_size/8 is
|
||||||
// encoded in the UNWIND_X86_64_FRAMELESS_STACK_SIZE (max stack size is 2048).
|
// encoded in the UNWIND_X86_64_FRAMELESS_STACK_SIZE (max stack size is 2048).
|
||||||
// The number of registers saved is encoded in UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT.
|
// The number of registers saved is encoded in UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT.
|
||||||
// UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION constains which registers were
|
// UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION contains which registers were
|
||||||
// saved and their order.
|
// saved and their order.
|
||||||
// UNWIND_X86_64_MODE_STACK_IND:
|
// UNWIND_X86_64_MODE_STACK_IND:
|
||||||
// A "frameless" (RBP not used as frame pointer) function large constant
|
// A "frameless" (RBP not used as frame pointer) function large constant
|
||||||
|
2
lib/libunwind/include/unwind.h
vendored
2
lib/libunwind/include/unwind.h
vendored
@ -93,7 +93,7 @@ extern void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t fc);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// The following are semi-suppoted extensions to the C++ ABI
|
// The following are semi-supported extensions to the C++ ABI
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
|
78
lib/libunwind/src/AddressSpace.hpp
vendored
78
lib/libunwind/src/AddressSpace.hpp
vendored
@ -246,7 +246,7 @@ inline uint64_t LocalAddressSpace::getULEB128(pint_t &addr, pint_t end) {
|
|||||||
inline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) {
|
inline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) {
|
||||||
const uint8_t *p = (uint8_t *)addr;
|
const uint8_t *p = (uint8_t *)addr;
|
||||||
const uint8_t *pend = (uint8_t *)end;
|
const uint8_t *pend = (uint8_t *)end;
|
||||||
int64_t result = 0;
|
uint64_t result = 0;
|
||||||
int bit = 0;
|
int bit = 0;
|
||||||
uint8_t byte;
|
uint8_t byte;
|
||||||
do {
|
do {
|
||||||
@ -260,7 +260,7 @@ inline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) {
|
|||||||
if ((byte & 0x40) != 0 && bit < 64)
|
if ((byte & 0x40) != 0 && bit < 64)
|
||||||
result |= (-1ULL) << bit;
|
result |= (-1ULL) << bit;
|
||||||
addr = (pint_t) p;
|
addr = (pint_t) p;
|
||||||
return result;
|
return (int64_t)result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline LocalAddressSpace::pint_t
|
inline LocalAddressSpace::pint_t
|
||||||
@ -373,28 +373,6 @@ LocalAddressSpace::getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
|
|||||||
typedef ElfW(Addr) Elf_Addr;
|
typedef ElfW(Addr) Elf_Addr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static Elf_Addr calculateImageBase(struct dl_phdr_info *pinfo) {
|
|
||||||
Elf_Addr image_base = pinfo->dlpi_addr;
|
|
||||||
#if defined(__ANDROID__) && __ANDROID_API__ < 18
|
|
||||||
if (image_base == 0) {
|
|
||||||
// Normally, an image base of 0 indicates a non-PIE executable. On
|
|
||||||
// versions of Android prior to API 18, the dynamic linker reported a
|
|
||||||
// dlpi_addr of 0 for PIE executables. Compute the true image base
|
|
||||||
// using the PT_PHDR segment.
|
|
||||||
// See https://github.com/android/ndk/issues/505.
|
|
||||||
for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) {
|
|
||||||
const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i];
|
|
||||||
if (phdr->p_type == PT_PHDR) {
|
|
||||||
image_base = reinterpret_cast<Elf_Addr>(pinfo->dlpi_phdr) -
|
|
||||||
phdr->p_vaddr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return image_base;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct _LIBUNWIND_HIDDEN dl_iterate_cb_data {
|
struct _LIBUNWIND_HIDDEN dl_iterate_cb_data {
|
||||||
LocalAddressSpace *addressSpace;
|
LocalAddressSpace *addressSpace;
|
||||||
UnwindInfoSections *sects;
|
UnwindInfoSections *sects;
|
||||||
@ -468,7 +446,7 @@ static int findUnwindSectionsByPhdr(struct dl_phdr_info *pinfo,
|
|||||||
(void)pinfo_size;
|
(void)pinfo_size;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Elf_Addr image_base = calculateImageBase(pinfo);
|
Elf_Addr image_base = pinfo->dlpi_addr;
|
||||||
|
|
||||||
// Most shared objects seen in this callback function likely don't contain the
|
// Most shared objects seen in this callback function likely don't contain the
|
||||||
// target address, so optimize for that. Scan for a matching PT_LOAD segment
|
// target address, so optimize for that. Scan for a matching PT_LOAD segment
|
||||||
@ -601,6 +579,56 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
|
|||||||
if (info.arm_section && info.arm_section_length)
|
if (info.arm_section && info.arm_section_length)
|
||||||
return true;
|
return true;
|
||||||
#elif defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
|
#elif defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
|
||||||
|
// Use DLFO_STRUCT_HAS_EH_DBASE to determine the existence of
|
||||||
|
// `_dl_find_object`. Use _LIBUNWIND_SUPPORT_DWARF_INDEX, because libunwind
|
||||||
|
// support for _dl_find_object on other unwind formats is not implemented,
|
||||||
|
// yet.
|
||||||
|
#if defined(DLFO_STRUCT_HAS_EH_DBASE) & defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
|
||||||
|
// We expect `_dl_find_object` to return PT_GNU_EH_FRAME.
|
||||||
|
#if DLFO_EH_SEGMENT_TYPE != PT_GNU_EH_FRAME
|
||||||
|
#error _dl_find_object retrieves an unexpected section type
|
||||||
|
#endif
|
||||||
|
// We look-up `dl_find_object` dynamically at runtime to ensure backwards
|
||||||
|
// compatibility with earlier version of glibc not yet providing it. On older
|
||||||
|
// systems, we gracefully fallback to `dl_iterate_phdr`. Cache the pointer
|
||||||
|
// so we only look it up once. Do manual lock to avoid _cxa_guard_acquire.
|
||||||
|
static decltype(_dl_find_object) *dlFindObject;
|
||||||
|
static bool dlFindObjectChecked = false;
|
||||||
|
if (!dlFindObjectChecked) {
|
||||||
|
dlFindObject = reinterpret_cast<decltype(_dl_find_object) *>(
|
||||||
|
dlsym(RTLD_DEFAULT, "_dl_find_object"));
|
||||||
|
dlFindObjectChecked = true;
|
||||||
|
}
|
||||||
|
// Try to find the unwind info using `dl_find_object`
|
||||||
|
dl_find_object findResult;
|
||||||
|
if (dlFindObject && dlFindObject((void *)targetAddr, &findResult) == 0) {
|
||||||
|
if (findResult.dlfo_eh_frame == nullptr) {
|
||||||
|
// Found an entry for `targetAddr`, but there is no unwind info.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
info.dso_base = reinterpret_cast<uintptr_t>(findResult.dlfo_map_start);
|
||||||
|
info.text_segment_length = static_cast<size_t>(
|
||||||
|
(char *)findResult.dlfo_map_end - (char *)findResult.dlfo_map_start);
|
||||||
|
|
||||||
|
// Record the start of PT_GNU_EH_FRAME.
|
||||||
|
info.dwarf_index_section =
|
||||||
|
reinterpret_cast<uintptr_t>(findResult.dlfo_eh_frame);
|
||||||
|
// `_dl_find_object` does not give us the size of PT_GNU_EH_FRAME.
|
||||||
|
// Setting length to `SIZE_MAX` effectively disables all range checks.
|
||||||
|
info.dwarf_index_section_length = SIZE_MAX;
|
||||||
|
EHHeaderParser<LocalAddressSpace>::EHHeaderInfo hdrInfo;
|
||||||
|
if (!EHHeaderParser<LocalAddressSpace>::decodeEHHdr(
|
||||||
|
*this, info.dwarf_index_section, info.dwarf_index_section_length,
|
||||||
|
hdrInfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Record the start of the FDE and use SIZE_MAX to indicate that we do
|
||||||
|
// not know the end address.
|
||||||
|
info.dwarf_section = hdrInfo.eh_frame_ptr;
|
||||||
|
info.dwarf_section_length = SIZE_MAX;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
dl_iterate_cb_data cb_data = {this, &info, targetAddr};
|
dl_iterate_cb_data cb_data = {this, &info, targetAddr};
|
||||||
int found = dl_iterate_phdr(findUnwindSectionsByPhdr, &cb_data);
|
int found = dl_iterate_phdr(findUnwindSectionsByPhdr, &cb_data);
|
||||||
return static_cast<bool>(found);
|
return static_cast<bool>(found);
|
||||||
|
1
lib/libunwind/src/CompactUnwinder.hpp
vendored
1
lib/libunwind/src/CompactUnwinder.hpp
vendored
@ -19,6 +19,7 @@
|
|||||||
#include <mach-o/compact_unwind_encoding.h>
|
#include <mach-o/compact_unwind_encoding.h>
|
||||||
|
|
||||||
#include "Registers.hpp"
|
#include "Registers.hpp"
|
||||||
|
#include "libunwind_ext.h"
|
||||||
|
|
||||||
#define EXTRACT_BITS(value, mask) \
|
#define EXTRACT_BITS(value, mask) \
|
||||||
((value >> __builtin_ctz(mask)) & (((1 << __builtin_popcount(mask))) - 1))
|
((value >> __builtin_ctz(mask)) & (((1 << __builtin_popcount(mask))) - 1))
|
||||||
|
50
lib/libunwind/src/DwarfInstructions.hpp
vendored
50
lib/libunwind/src/DwarfInstructions.hpp
vendored
@ -16,16 +16,17 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "dwarf2.h"
|
|
||||||
#include "Registers.hpp"
|
|
||||||
#include "DwarfParser.hpp"
|
#include "DwarfParser.hpp"
|
||||||
|
#include "Registers.hpp"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "dwarf2.h"
|
||||||
|
#include "libunwind_ext.h"
|
||||||
|
|
||||||
|
|
||||||
namespace libunwind {
|
namespace libunwind {
|
||||||
|
|
||||||
|
|
||||||
/// DwarfInstructions maps abtract DWARF unwind instructions to a particular
|
/// DwarfInstructions maps abstract DWARF unwind instructions to a particular
|
||||||
/// architecture
|
/// architecture
|
||||||
template <typename A, typename R>
|
template <typename A, typename R>
|
||||||
class DwarfInstructions {
|
class DwarfInstructions {
|
||||||
@ -34,7 +35,7 @@ public:
|
|||||||
typedef typename A::sint_t sint_t;
|
typedef typename A::sint_t sint_t;
|
||||||
|
|
||||||
static int stepWithDwarf(A &addressSpace, pint_t pc, pint_t fdeStart,
|
static int stepWithDwarf(A &addressSpace, pint_t pc, pint_t fdeStart,
|
||||||
R ®isters, bool &isSignalFrame);
|
R ®isters, bool &isSignalFrame, bool stage2);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -189,7 +190,7 @@ bool DwarfInstructions<A, R>::getRA_SIGN_STATE(A &addressSpace, R registers,
|
|||||||
template <typename A, typename R>
|
template <typename A, typename R>
|
||||||
int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
|
int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
|
||||||
pint_t fdeStart, R ®isters,
|
pint_t fdeStart, R ®isters,
|
||||||
bool &isSignalFrame) {
|
bool &isSignalFrame, bool stage2) {
|
||||||
FDE_Info fdeInfo;
|
FDE_Info fdeInfo;
|
||||||
CIE_Info cieInfo;
|
CIE_Info cieInfo;
|
||||||
if (CFI_Parser<A>::decodeFDE(addressSpace, fdeStart, &fdeInfo,
|
if (CFI_Parser<A>::decodeFDE(addressSpace, fdeStart, &fdeInfo,
|
||||||
@ -200,7 +201,38 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
|
|||||||
// get pointer to cfa (architecture specific)
|
// get pointer to cfa (architecture specific)
|
||||||
pint_t cfa = getCFA(addressSpace, prolog, registers);
|
pint_t cfa = getCFA(addressSpace, prolog, registers);
|
||||||
|
|
||||||
// restore registers that DWARF says were saved
|
(void)stage2;
|
||||||
|
// __unw_step_stage2 is not used for cross unwinding, so we use
|
||||||
|
// __aarch64__ rather than LIBUNWIND_TARGET_AARCH64 to make sure we are
|
||||||
|
// building for AArch64 natively.
|
||||||
|
#if defined(__aarch64__)
|
||||||
|
if (stage2 && cieInfo.mteTaggedFrame) {
|
||||||
|
pint_t sp = registers.getSP();
|
||||||
|
pint_t p = sp;
|
||||||
|
// AArch64 doesn't require the value of SP to be 16-byte aligned at
|
||||||
|
// all times, only at memory accesses and public interfaces [1]. Thus,
|
||||||
|
// a signal could arrive at a point where SP is not aligned properly.
|
||||||
|
// In that case, the kernel fixes up [2] the signal frame, but we
|
||||||
|
// still have a misaligned SP in the previous frame. If that signal
|
||||||
|
// handler caused stack unwinding, we would have an unaligned SP.
|
||||||
|
// We do not need to fix up the CFA, as that is the SP at a "public
|
||||||
|
// interface".
|
||||||
|
// [1]:
|
||||||
|
// https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#622the-stack
|
||||||
|
// [2]:
|
||||||
|
// https://github.com/torvalds/linux/blob/1930a6e739c4b4a654a69164dbe39e554d228915/arch/arm64/kernel/signal.c#L718
|
||||||
|
p &= ~0xfULL;
|
||||||
|
// CFA is the bottom of the current stack frame.
|
||||||
|
for (; p < cfa; p += 16) {
|
||||||
|
__asm__ __volatile__(".arch_extension memtag\n"
|
||||||
|
"stg %[Ptr], [%[Ptr]]\n"
|
||||||
|
:
|
||||||
|
: [Ptr] "r"(p)
|
||||||
|
: "memory");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// restore registers that DWARF says were saved
|
||||||
R newRegisters = registers;
|
R newRegisters = registers;
|
||||||
|
|
||||||
// Typically, the CFA is the stack pointer at the call site in
|
// Typically, the CFA is the stack pointer at the call site in
|
||||||
@ -241,7 +273,7 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
|
|||||||
return UNW_EBADREG;
|
return UNW_EBADREG;
|
||||||
} else if (i == (int)cieInfo.returnAddressRegister) {
|
} else if (i == (int)cieInfo.returnAddressRegister) {
|
||||||
// Leaf function keeps the return address in register and there is no
|
// Leaf function keeps the return address in register and there is no
|
||||||
// explicit intructions how to restore it.
|
// explicit instructions how to restore it.
|
||||||
returnAddress = registers.getRegister(cieInfo.returnAddressRegister);
|
returnAddress = registers.getRegister(cieInfo.returnAddressRegister);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -331,7 +363,7 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Return address is address after call site instruction, so setting IP to
|
// Return address is address after call site instruction, so setting IP to
|
||||||
// that does simualates a return.
|
// that does simulates a return.
|
||||||
newRegisters.setIP(returnAddress);
|
newRegisters.setIP(returnAddress);
|
||||||
|
|
||||||
// Simulate the step by replacing the register set with the new ones.
|
// Simulate the step by replacing the register set with the new ones.
|
||||||
@ -635,7 +667,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
|
|||||||
svalue = (sint_t)*sp;
|
svalue = (sint_t)*sp;
|
||||||
*sp = (pint_t)(svalue >> value);
|
*sp = (pint_t)(svalue >> value);
|
||||||
if (log)
|
if (log)
|
||||||
fprintf(stderr, "shift left arithmetric\n");
|
fprintf(stderr, "shift left arithmetic\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_OP_xor:
|
case DW_OP_xor:
|
||||||
|
9
lib/libunwind/src/DwarfParser.hpp
vendored
9
lib/libunwind/src/DwarfParser.hpp
vendored
@ -51,6 +51,7 @@ public:
|
|||||||
uint8_t returnAddressRegister;
|
uint8_t returnAddressRegister;
|
||||||
#if defined(_LIBUNWIND_TARGET_AARCH64)
|
#if defined(_LIBUNWIND_TARGET_AARCH64)
|
||||||
bool addressesSignedWithBKey;
|
bool addressesSignedWithBKey;
|
||||||
|
bool mteTaggedFrame;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -325,6 +326,7 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie,
|
|||||||
cieInfo->fdesHaveAugmentationData = false;
|
cieInfo->fdesHaveAugmentationData = false;
|
||||||
#if defined(_LIBUNWIND_TARGET_AARCH64)
|
#if defined(_LIBUNWIND_TARGET_AARCH64)
|
||||||
cieInfo->addressesSignedWithBKey = false;
|
cieInfo->addressesSignedWithBKey = false;
|
||||||
|
cieInfo->mteTaggedFrame = false;
|
||||||
#endif
|
#endif
|
||||||
cieInfo->cieStart = cie;
|
cieInfo->cieStart = cie;
|
||||||
pint_t p = cie;
|
pint_t p = cie;
|
||||||
@ -353,7 +355,7 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie,
|
|||||||
while (addressSpace.get8(p) != 0)
|
while (addressSpace.get8(p) != 0)
|
||||||
++p;
|
++p;
|
||||||
++p;
|
++p;
|
||||||
// parse code aligment factor
|
// parse code alignment factor
|
||||||
cieInfo->codeAlignFactor = (uint32_t)addressSpace.getULEB128(p, cieContentEnd);
|
cieInfo->codeAlignFactor = (uint32_t)addressSpace.getULEB128(p, cieContentEnd);
|
||||||
// parse data alignment factor
|
// parse data alignment factor
|
||||||
cieInfo->dataAlignFactor = (int)addressSpace.getSLEB128(p, cieContentEnd);
|
cieInfo->dataAlignFactor = (int)addressSpace.getSLEB128(p, cieContentEnd);
|
||||||
@ -394,6 +396,9 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie,
|
|||||||
case 'B':
|
case 'B':
|
||||||
cieInfo->addressesSignedWithBKey = true;
|
cieInfo->addressesSignedWithBKey = true;
|
||||||
break;
|
break;
|
||||||
|
case 'G':
|
||||||
|
cieInfo->mteTaggedFrame = true;
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
// ignore unknown letters
|
// ignore unknown letters
|
||||||
@ -407,7 +412,7 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// "run" the DWARF instructions and create the abstact PrologInfo for an FDE
|
/// "run" the DWARF instructions and create the abstract PrologInfo for an FDE
|
||||||
template <typename A>
|
template <typename A>
|
||||||
bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
|
bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
|
||||||
const FDE_Info &fdeInfo,
|
const FDE_Info &fdeInfo,
|
||||||
|
277
lib/libunwind/src/Registers.hpp
vendored
277
lib/libunwind/src/Registers.hpp
vendored
@ -40,6 +40,7 @@ enum {
|
|||||||
REGISTERS_RISCV,
|
REGISTERS_RISCV,
|
||||||
REGISTERS_VE,
|
REGISTERS_VE,
|
||||||
REGISTERS_S390X,
|
REGISTERS_S390X,
|
||||||
|
REGISTERS_LOONGARCH,
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(_LIBUNWIND_TARGET_I386)
|
#if defined(_LIBUNWIND_TARGET_I386)
|
||||||
@ -4003,7 +4004,7 @@ typedef float fp_t;
|
|||||||
# error "Unsupported __riscv_flen"
|
# error "Unsupported __riscv_flen"
|
||||||
# endif
|
# endif
|
||||||
# else
|
# else
|
||||||
// This is just for supressing undeclared error of fp_t.
|
// This is just for suppressing undeclared error of fp_t.
|
||||||
typedef double fp_t;
|
typedef double fp_t;
|
||||||
# endif
|
# endif
|
||||||
# else
|
# else
|
||||||
@ -4084,6 +4085,8 @@ inline bool Registers_riscv::validRegister(int regNum) const {
|
|||||||
return true;
|
return true;
|
||||||
if (regNum < 0)
|
if (regNum < 0)
|
||||||
return false;
|
return false;
|
||||||
|
if (regNum == UNW_RISCV_VLENB)
|
||||||
|
return true;
|
||||||
if (regNum > UNW_RISCV_F31)
|
if (regNum > UNW_RISCV_F31)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
@ -4098,6 +4101,11 @@ inline reg_t Registers_riscv::getRegister(int regNum) const {
|
|||||||
return 0;
|
return 0;
|
||||||
if ((regNum > 0) && (regNum < 32))
|
if ((regNum > 0) && (regNum < 32))
|
||||||
return _registers[regNum];
|
return _registers[regNum];
|
||||||
|
if (regNum == UNW_RISCV_VLENB) {
|
||||||
|
reg_t vlenb;
|
||||||
|
__asm__("csrr %0, 0xC22" : "=r"(vlenb));
|
||||||
|
return vlenb;
|
||||||
|
}
|
||||||
_LIBUNWIND_ABORT("unsupported riscv register");
|
_LIBUNWIND_ABORT("unsupported riscv register");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4249,6 +4257,8 @@ inline const char *Registers_riscv::getRegisterName(int regNum) {
|
|||||||
return "ft10";
|
return "ft10";
|
||||||
case UNW_RISCV_F31:
|
case UNW_RISCV_F31:
|
||||||
return "ft11";
|
return "ft11";
|
||||||
|
case UNW_RISCV_VLENB:
|
||||||
|
return "vlenb";
|
||||||
default:
|
default:
|
||||||
return "unknown register";
|
return "unknown register";
|
||||||
}
|
}
|
||||||
@ -5031,6 +5041,271 @@ inline const char *Registers_s390x::getRegisterName(int regNum) {
|
|||||||
}
|
}
|
||||||
#endif // _LIBUNWIND_TARGET_S390X
|
#endif // _LIBUNWIND_TARGET_S390X
|
||||||
|
|
||||||
|
#if defined(_LIBUNWIND_TARGET_LOONGARCH)
|
||||||
|
/// Registers_loongarch holds the register state of a thread in a 64-bit
|
||||||
|
/// LoongArch process.
|
||||||
|
class _LIBUNWIND_HIDDEN Registers_loongarch {
|
||||||
|
public:
|
||||||
|
Registers_loongarch();
|
||||||
|
Registers_loongarch(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 constexpr int lastDwarfRegNum() {
|
||||||
|
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH;
|
||||||
|
}
|
||||||
|
static int getArch() { return REGISTERS_LOONGARCH; }
|
||||||
|
|
||||||
|
uint64_t getSP() const { return _registers.__r[3]; }
|
||||||
|
void setSP(uint64_t value) { _registers.__r[3] = value; }
|
||||||
|
uint64_t getIP() const { return _registers.__pc; }
|
||||||
|
void setIP(uint64_t value) { _registers.__pc = value; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct loongarch_thread_state_t {
|
||||||
|
uint64_t __r[32];
|
||||||
|
uint64_t __pc;
|
||||||
|
};
|
||||||
|
|
||||||
|
loongarch_thread_state_t _registers;
|
||||||
|
#if __loongarch_frlen == 64
|
||||||
|
double _floats[32];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
inline Registers_loongarch::Registers_loongarch(const void *registers) {
|
||||||
|
static_assert((check_fit<Registers_loongarch, unw_context_t>::does_fit),
|
||||||
|
"loongarch registers do not fit into unw_context_t");
|
||||||
|
memcpy(&_registers, registers, sizeof(_registers));
|
||||||
|
static_assert(sizeof(_registers) == 0x108,
|
||||||
|
"expected float registers to be at offset 264");
|
||||||
|
#if __loongarch_frlen == 64
|
||||||
|
memcpy(_floats, static_cast<const uint8_t *>(registers) + sizeof(_registers),
|
||||||
|
sizeof(_floats));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Registers_loongarch::Registers_loongarch() {
|
||||||
|
memset(&_registers, 0, sizeof(_registers));
|
||||||
|
#if __loongarch_frlen == 64
|
||||||
|
memset(&_floats, 0, sizeof(_floats));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Registers_loongarch::validRegister(int regNum) const {
|
||||||
|
if (regNum == UNW_REG_IP || regNum == UNW_REG_SP)
|
||||||
|
return true;
|
||||||
|
if (regNum < 0 || regNum > UNW_LOONGARCH_F31)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint64_t Registers_loongarch::getRegister(int regNum) const {
|
||||||
|
if (regNum >= UNW_LOONGARCH_R0 && regNum <= UNW_LOONGARCH_R31)
|
||||||
|
return _registers.__r[regNum - UNW_LOONGARCH_R0];
|
||||||
|
|
||||||
|
if (regNum == UNW_REG_IP)
|
||||||
|
return _registers.__pc;
|
||||||
|
if (regNum == UNW_REG_SP)
|
||||||
|
return _registers.__r[3];
|
||||||
|
_LIBUNWIND_ABORT("unsupported loongarch register");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Registers_loongarch::setRegister(int regNum, uint64_t value) {
|
||||||
|
if (regNum >= UNW_LOONGARCH_R0 && regNum <= UNW_LOONGARCH_R31)
|
||||||
|
_registers.__r[regNum - UNW_LOONGARCH_R0] = value;
|
||||||
|
else if (regNum == UNW_REG_IP)
|
||||||
|
_registers.__pc = value;
|
||||||
|
else if (regNum == UNW_REG_SP)
|
||||||
|
_registers.__r[3] = value;
|
||||||
|
else
|
||||||
|
_LIBUNWIND_ABORT("unsupported loongarch register");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const char *Registers_loongarch::getRegisterName(int regNum) {
|
||||||
|
switch (regNum) {
|
||||||
|
case UNW_REG_IP:
|
||||||
|
return "$pc";
|
||||||
|
case UNW_REG_SP:
|
||||||
|
return "$sp";
|
||||||
|
case UNW_LOONGARCH_R0:
|
||||||
|
return "$r0";
|
||||||
|
case UNW_LOONGARCH_R1:
|
||||||
|
return "$r1";
|
||||||
|
case UNW_LOONGARCH_R2:
|
||||||
|
return "$r2";
|
||||||
|
case UNW_LOONGARCH_R3:
|
||||||
|
return "$r3";
|
||||||
|
case UNW_LOONGARCH_R4:
|
||||||
|
return "$r4";
|
||||||
|
case UNW_LOONGARCH_R5:
|
||||||
|
return "$r5";
|
||||||
|
case UNW_LOONGARCH_R6:
|
||||||
|
return "$r6";
|
||||||
|
case UNW_LOONGARCH_R7:
|
||||||
|
return "$r7";
|
||||||
|
case UNW_LOONGARCH_R8:
|
||||||
|
return "$r8";
|
||||||
|
case UNW_LOONGARCH_R9:
|
||||||
|
return "$r9";
|
||||||
|
case UNW_LOONGARCH_R10:
|
||||||
|
return "$r10";
|
||||||
|
case UNW_LOONGARCH_R11:
|
||||||
|
return "$r11";
|
||||||
|
case UNW_LOONGARCH_R12:
|
||||||
|
return "$r12";
|
||||||
|
case UNW_LOONGARCH_R13:
|
||||||
|
return "$r13";
|
||||||
|
case UNW_LOONGARCH_R14:
|
||||||
|
return "$r14";
|
||||||
|
case UNW_LOONGARCH_R15:
|
||||||
|
return "$r15";
|
||||||
|
case UNW_LOONGARCH_R16:
|
||||||
|
return "$r16";
|
||||||
|
case UNW_LOONGARCH_R17:
|
||||||
|
return "$r17";
|
||||||
|
case UNW_LOONGARCH_R18:
|
||||||
|
return "$r18";
|
||||||
|
case UNW_LOONGARCH_R19:
|
||||||
|
return "$r19";
|
||||||
|
case UNW_LOONGARCH_R20:
|
||||||
|
return "$r20";
|
||||||
|
case UNW_LOONGARCH_R21:
|
||||||
|
return "$r21";
|
||||||
|
case UNW_LOONGARCH_R22:
|
||||||
|
return "$r22";
|
||||||
|
case UNW_LOONGARCH_R23:
|
||||||
|
return "$r23";
|
||||||
|
case UNW_LOONGARCH_R24:
|
||||||
|
return "$r24";
|
||||||
|
case UNW_LOONGARCH_R25:
|
||||||
|
return "$r25";
|
||||||
|
case UNW_LOONGARCH_R26:
|
||||||
|
return "$r26";
|
||||||
|
case UNW_LOONGARCH_R27:
|
||||||
|
return "$r27";
|
||||||
|
case UNW_LOONGARCH_R28:
|
||||||
|
return "$r28";
|
||||||
|
case UNW_LOONGARCH_R29:
|
||||||
|
return "$r29";
|
||||||
|
case UNW_LOONGARCH_R30:
|
||||||
|
return "$r30";
|
||||||
|
case UNW_LOONGARCH_R31:
|
||||||
|
return "$r31";
|
||||||
|
case UNW_LOONGARCH_F0:
|
||||||
|
return "$f0";
|
||||||
|
case UNW_LOONGARCH_F1:
|
||||||
|
return "$f1";
|
||||||
|
case UNW_LOONGARCH_F2:
|
||||||
|
return "$f2";
|
||||||
|
case UNW_LOONGARCH_F3:
|
||||||
|
return "$f3";
|
||||||
|
case UNW_LOONGARCH_F4:
|
||||||
|
return "$f4";
|
||||||
|
case UNW_LOONGARCH_F5:
|
||||||
|
return "$f5";
|
||||||
|
case UNW_LOONGARCH_F6:
|
||||||
|
return "$f6";
|
||||||
|
case UNW_LOONGARCH_F7:
|
||||||
|
return "$f7";
|
||||||
|
case UNW_LOONGARCH_F8:
|
||||||
|
return "$f8";
|
||||||
|
case UNW_LOONGARCH_F9:
|
||||||
|
return "$f9";
|
||||||
|
case UNW_LOONGARCH_F10:
|
||||||
|
return "$f10";
|
||||||
|
case UNW_LOONGARCH_F11:
|
||||||
|
return "$f11";
|
||||||
|
case UNW_LOONGARCH_F12:
|
||||||
|
return "$f12";
|
||||||
|
case UNW_LOONGARCH_F13:
|
||||||
|
return "$f13";
|
||||||
|
case UNW_LOONGARCH_F14:
|
||||||
|
return "$f14";
|
||||||
|
case UNW_LOONGARCH_F15:
|
||||||
|
return "$f15";
|
||||||
|
case UNW_LOONGARCH_F16:
|
||||||
|
return "$f16";
|
||||||
|
case UNW_LOONGARCH_F17:
|
||||||
|
return "$f17";
|
||||||
|
case UNW_LOONGARCH_F18:
|
||||||
|
return "$f18";
|
||||||
|
case UNW_LOONGARCH_F19:
|
||||||
|
return "$f19";
|
||||||
|
case UNW_LOONGARCH_F20:
|
||||||
|
return "$f20";
|
||||||
|
case UNW_LOONGARCH_F21:
|
||||||
|
return "$f21";
|
||||||
|
case UNW_LOONGARCH_F22:
|
||||||
|
return "$f22";
|
||||||
|
case UNW_LOONGARCH_F23:
|
||||||
|
return "$f23";
|
||||||
|
case UNW_LOONGARCH_F24:
|
||||||
|
return "$f24";
|
||||||
|
case UNW_LOONGARCH_F25:
|
||||||
|
return "$f25";
|
||||||
|
case UNW_LOONGARCH_F26:
|
||||||
|
return "$f26";
|
||||||
|
case UNW_LOONGARCH_F27:
|
||||||
|
return "$f27";
|
||||||
|
case UNW_LOONGARCH_F28:
|
||||||
|
return "$f28";
|
||||||
|
case UNW_LOONGARCH_F29:
|
||||||
|
return "$f29";
|
||||||
|
case UNW_LOONGARCH_F30:
|
||||||
|
return "$f30";
|
||||||
|
case UNW_LOONGARCH_F31:
|
||||||
|
return "$f31";
|
||||||
|
default:
|
||||||
|
return "unknown register";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Registers_loongarch::validFloatRegister(int regNum) const {
|
||||||
|
if (regNum < UNW_LOONGARCH_F0 || regNum > UNW_LOONGARCH_F31)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double Registers_loongarch::getFloatRegister(int regNum) const {
|
||||||
|
#if __loongarch_frlen == 64
|
||||||
|
assert(validFloatRegister(regNum));
|
||||||
|
return _floats[regNum - UNW_LOONGARCH_F0];
|
||||||
|
#else
|
||||||
|
_LIBUNWIND_ABORT("libunwind not built with float support");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Registers_loongarch::setFloatRegister(int regNum, double value) {
|
||||||
|
#if __loongarch_frlen == 64
|
||||||
|
assert(validFloatRegister(regNum));
|
||||||
|
_floats[regNum - UNW_LOONGARCH_F0] = value;
|
||||||
|
#else
|
||||||
|
_LIBUNWIND_ABORT("libunwind not built with float support");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Registers_loongarch::validVectorRegister(int) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v128 Registers_loongarch::getVectorRegister(int) const {
|
||||||
|
_LIBUNWIND_ABORT("loongarch vector support not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Registers_loongarch::setVectorRegister(int, v128) {
|
||||||
|
_LIBUNWIND_ABORT("loongarch vector support not implemented");
|
||||||
|
}
|
||||||
|
#endif //_LIBUNWIND_TARGET_LOONGARCH
|
||||||
|
|
||||||
} // namespace libunwind
|
} // namespace libunwind
|
||||||
|
|
||||||
|
4
lib/libunwind/src/Unwind-EHABI.cpp
vendored
4
lib/libunwind/src/Unwind-EHABI.cpp
vendored
@ -235,7 +235,7 @@ decode_eht_entry(const uint32_t* data, size_t* off, size_t* len) {
|
|||||||
} else {
|
} else {
|
||||||
// 6.3: ARM Compact Model
|
// 6.3: ARM Compact Model
|
||||||
//
|
//
|
||||||
// EHT entries here correspond to the __aeabi_unwind_cpp_pr[012] PRs indeded
|
// EHT entries here correspond to the __aeabi_unwind_cpp_pr[012] PRs indeed
|
||||||
// by format:
|
// by format:
|
||||||
Descriptor::Format format =
|
Descriptor::Format format =
|
||||||
static_cast<Descriptor::Format>((*data & 0x0f000000) >> 24);
|
static_cast<Descriptor::Format>((*data & 0x0f000000) >> 24);
|
||||||
@ -845,7 +845,7 @@ _LIBUNWIND_EXPORT void _Unwind_Complete(_Unwind_Exception* exception_object) {
|
|||||||
/// may force a jump to a landing pad in that function, the landing
|
/// may force a jump to a landing pad in that function, the landing
|
||||||
/// pad code may then call _Unwind_Resume() to continue with the
|
/// pad code may then call _Unwind_Resume() to continue with the
|
||||||
/// unwinding. Note: the call to _Unwind_Resume() is from compiler
|
/// unwinding. Note: the call to _Unwind_Resume() is from compiler
|
||||||
/// geneated user code. All other _Unwind_* routines are called
|
/// generated user code. All other _Unwind_* routines are called
|
||||||
/// by the C++ runtime __cxa_* routines.
|
/// by the C++ runtime __cxa_* routines.
|
||||||
///
|
///
|
||||||
/// Note: re-throwing an exception (as opposed to continuing the unwind)
|
/// Note: re-throwing an exception (as opposed to continuing the unwind)
|
||||||
|
6
lib/libunwind/src/Unwind-seh.cpp
vendored
6
lib/libunwind/src/Unwind-seh.cpp
vendored
@ -137,7 +137,7 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx,
|
|||||||
// If we were called by __libunwind_seh_personality(), indicate that
|
// If we were called by __libunwind_seh_personality(), indicate that
|
||||||
// a handler was found; otherwise, initiate phase 2 by unwinding.
|
// a handler was found; otherwise, initiate phase 2 by unwinding.
|
||||||
if (ours && ms_exc->NumberParameters > 1)
|
if (ours && ms_exc->NumberParameters > 1)
|
||||||
return 4 /* ExecptionExecuteHandler in mingw */;
|
return 4 /* ExceptionExecuteHandler in mingw */;
|
||||||
// This should never happen in phase 2.
|
// This should never happen in phase 2.
|
||||||
if (IS_UNWINDING(ms_exc->ExceptionFlags))
|
if (IS_UNWINDING(ms_exc->ExceptionFlags))
|
||||||
_LIBUNWIND_ABORT("Personality indicated exception handler in phase 2!");
|
_LIBUNWIND_ABORT("Personality indicated exception handler in phase 2!");
|
||||||
@ -155,7 +155,7 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx,
|
|||||||
// a handler was found; otherwise, it's time to initiate a collided
|
// a handler was found; otherwise, it's time to initiate a collided
|
||||||
// unwind to the target.
|
// unwind to the target.
|
||||||
if (ours && !IS_UNWINDING(ms_exc->ExceptionFlags) && ms_exc->NumberParameters > 1)
|
if (ours && !IS_UNWINDING(ms_exc->ExceptionFlags) && ms_exc->NumberParameters > 1)
|
||||||
return 4 /* ExecptionExecuteHandler in mingw */;
|
return 4 /* ExceptionExecuteHandler in mingw */;
|
||||||
// This should never happen in phase 1.
|
// This should never happen in phase 1.
|
||||||
if (!IS_UNWINDING(ms_exc->ExceptionFlags))
|
if (!IS_UNWINDING(ms_exc->ExceptionFlags))
|
||||||
_LIBUNWIND_ABORT("Personality installed context during phase 1!");
|
_LIBUNWIND_ABORT("Personality installed context during phase 1!");
|
||||||
@ -354,7 +354,7 @@ _Unwind_RaiseException(_Unwind_Exception *exception_object) {
|
|||||||
/// may force a jump to a landing pad in that function; the landing
|
/// may force a jump to a landing pad in that function; the landing
|
||||||
/// pad code may then call \c _Unwind_Resume() to continue with the
|
/// pad code may then call \c _Unwind_Resume() to continue with the
|
||||||
/// unwinding. Note: the call to \c _Unwind_Resume() is from compiler
|
/// unwinding. Note: the call to \c _Unwind_Resume() is from compiler
|
||||||
/// geneated user code. All other \c _Unwind_* routines are called
|
/// generated user code. All other \c _Unwind_* routines are called
|
||||||
/// by the C++ runtime \c __cxa_* routines.
|
/// by the C++ runtime \c __cxa_* routines.
|
||||||
///
|
///
|
||||||
/// Note: re-throwing an exception (as opposed to continuing the unwind)
|
/// Note: re-throwing an exception (as opposed to continuing the unwind)
|
||||||
|
6
lib/libunwind/src/Unwind-sjlj.c
vendored
6
lib/libunwind/src/Unwind-sjlj.c
vendored
@ -33,7 +33,7 @@ struct _Unwind_FunctionContext {
|
|||||||
struct _Unwind_FunctionContext *prev;
|
struct _Unwind_FunctionContext *prev;
|
||||||
|
|
||||||
#if defined(__ve__)
|
#if defined(__ve__)
|
||||||
// VE requires to store 64 bit pointers in the buffer for SjLj execption.
|
// VE requires to store 64 bit pointers in the buffer for SjLj exception.
|
||||||
// We expand the size of values defined here. This size must be matched
|
// We expand the size of values defined here. This size must be matched
|
||||||
// to the size returned by TargetMachine::getSjLjDataSize().
|
// to the size returned by TargetMachine::getSjLjDataSize().
|
||||||
|
|
||||||
@ -357,7 +357,7 @@ _Unwind_SjLj_RaiseException(struct _Unwind_Exception *exception_object) {
|
|||||||
/// may force a jump to a landing pad in that function, the landing
|
/// may force a jump to a landing pad in that function, the landing
|
||||||
/// pad code may then call _Unwind_Resume() to continue with the
|
/// pad code may then call _Unwind_Resume() to continue with the
|
||||||
/// unwinding. Note: the call to _Unwind_Resume() is from compiler
|
/// unwinding. Note: the call to _Unwind_Resume() is from compiler
|
||||||
/// geneated user code. All other _Unwind_* routines are called
|
/// generated user code. All other _Unwind_* routines are called
|
||||||
/// by the C++ runtime __cxa_* routines.
|
/// by the C++ runtime __cxa_* routines.
|
||||||
///
|
///
|
||||||
/// Re-throwing an exception is implemented by having the code call
|
/// Re-throwing an exception is implemented by having the code call
|
||||||
@ -394,7 +394,7 @@ _Unwind_SjLj_Resume_or_Rethrow(struct _Unwind_Exception *exception_object) {
|
|||||||
// std::terminate()
|
// std::terminate()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call through to _Unwind_Resume() which distiguishes between forced and
|
// Call through to _Unwind_Resume() which distinguishes between forced and
|
||||||
// regular exceptions.
|
// regular exceptions.
|
||||||
_Unwind_SjLj_Resume(exception_object);
|
_Unwind_SjLj_Resume(exception_object);
|
||||||
_LIBUNWIND_ABORT("__Unwind_SjLj_Resume_or_Rethrow() called "
|
_LIBUNWIND_ABORT("__Unwind_SjLj_Resume_or_Rethrow() called "
|
||||||
|
82
lib/libunwind/src/UnwindCursor.hpp
vendored
82
lib/libunwind/src/UnwindCursor.hpp
vendored
@ -38,6 +38,17 @@
|
|||||||
#define _LIBUNWIND_CHECK_LINUX_SIGRETURN 1
|
#define _LIBUNWIND_CHECK_LINUX_SIGRETURN 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "AddressSpace.hpp"
|
||||||
|
#include "CompactUnwinder.hpp"
|
||||||
|
#include "config.h"
|
||||||
|
#include "DwarfInstructions.hpp"
|
||||||
|
#include "EHHeaderParser.hpp"
|
||||||
|
#include "libunwind.h"
|
||||||
|
#include "libunwind_ext.h"
|
||||||
|
#include "Registers.hpp"
|
||||||
|
#include "RWMutex.hpp"
|
||||||
|
#include "Unwind-EHABI.h"
|
||||||
|
|
||||||
#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
|
#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
|
||||||
// Provide a definition for the DISPATCHER_CONTEXT struct for old (Win7 and
|
// Provide a definition for the DISPATCHER_CONTEXT struct for old (Win7 and
|
||||||
// earlier) SDKs.
|
// earlier) SDKs.
|
||||||
@ -75,18 +86,6 @@ extern "C" _Unwind_Reason_Code __libunwind_seh_personality(
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include "AddressSpace.hpp"
|
|
||||||
#include "CompactUnwinder.hpp"
|
|
||||||
#include "config.h"
|
|
||||||
#include "DwarfInstructions.hpp"
|
|
||||||
#include "EHHeaderParser.hpp"
|
|
||||||
#include "libunwind.h"
|
|
||||||
#include "Registers.hpp"
|
|
||||||
#include "RWMutex.hpp"
|
|
||||||
#include "Unwind-EHABI.h"
|
|
||||||
|
|
||||||
namespace libunwind {
|
namespace libunwind {
|
||||||
|
|
||||||
#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
|
#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
|
||||||
@ -443,7 +442,7 @@ public:
|
|||||||
virtual void setFloatReg(int, unw_fpreg_t) {
|
virtual void setFloatReg(int, unw_fpreg_t) {
|
||||||
_LIBUNWIND_ABORT("setFloatReg not implemented");
|
_LIBUNWIND_ABORT("setFloatReg not implemented");
|
||||||
}
|
}
|
||||||
virtual int step() { _LIBUNWIND_ABORT("step not implemented"); }
|
virtual int step(bool = false) { _LIBUNWIND_ABORT("step not implemented"); }
|
||||||
virtual void getInfo(unw_proc_info_t *) {
|
virtual void getInfo(unw_proc_info_t *) {
|
||||||
_LIBUNWIND_ABORT("getInfo not implemented");
|
_LIBUNWIND_ABORT("getInfo not implemented");
|
||||||
}
|
}
|
||||||
@ -495,7 +494,7 @@ public:
|
|||||||
virtual bool validFloatReg(int);
|
virtual bool validFloatReg(int);
|
||||||
virtual unw_fpreg_t getFloatReg(int);
|
virtual unw_fpreg_t getFloatReg(int);
|
||||||
virtual void setFloatReg(int, unw_fpreg_t);
|
virtual void setFloatReg(int, unw_fpreg_t);
|
||||||
virtual int step();
|
virtual int step(bool = false);
|
||||||
virtual void getInfo(unw_proc_info_t *);
|
virtual void getInfo(unw_proc_info_t *);
|
||||||
virtual void jumpto();
|
virtual void jumpto();
|
||||||
virtual bool isSignalFrame();
|
virtual bool isSignalFrame();
|
||||||
@ -510,7 +509,7 @@ public:
|
|||||||
void setDispatcherContext(DISPATCHER_CONTEXT *disp) { _dispContext = *disp; }
|
void setDispatcherContext(DISPATCHER_CONTEXT *disp) { _dispContext = *disp; }
|
||||||
|
|
||||||
// libunwind does not and should not depend on C++ library which means that we
|
// libunwind does not and should not depend on C++ library which means that we
|
||||||
// need our own defition of inline placement new.
|
// need our own definition of inline placement new.
|
||||||
static void *operator new(size_t, UnwindCursor<A, R> *p) { return p; }
|
static void *operator new(size_t, UnwindCursor<A, R> *p) { return p; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -926,7 +925,7 @@ public:
|
|||||||
virtual bool validFloatReg(int);
|
virtual bool validFloatReg(int);
|
||||||
virtual unw_fpreg_t getFloatReg(int);
|
virtual unw_fpreg_t getFloatReg(int);
|
||||||
virtual void setFloatReg(int, unw_fpreg_t);
|
virtual void setFloatReg(int, unw_fpreg_t);
|
||||||
virtual int step();
|
virtual int step(bool stage2 = false);
|
||||||
virtual void getInfo(unw_proc_info_t *);
|
virtual void getInfo(unw_proc_info_t *);
|
||||||
virtual void jumpto();
|
virtual void jumpto();
|
||||||
virtual bool isSignalFrame();
|
virtual bool isSignalFrame();
|
||||||
@ -946,7 +945,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// libunwind does not and should not depend on C++ library which means that we
|
// libunwind does not and should not depend on C++ library which means that we
|
||||||
// need our own defition of inline placement new.
|
// need our own definition of inline placement new.
|
||||||
static void *operator new(size_t, UnwindCursor<A, R> *p) { return p; }
|
static void *operator new(size_t, UnwindCursor<A, R> *p) { return p; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -1000,22 +999,21 @@ private:
|
|||||||
pint_t pc, uintptr_t dso_base);
|
pint_t pc, uintptr_t dso_base);
|
||||||
bool getInfoFromDwarfSection(pint_t pc, const UnwindInfoSections §s,
|
bool getInfoFromDwarfSection(pint_t pc, const UnwindInfoSections §s,
|
||||||
uint32_t fdeSectionOffsetHint=0);
|
uint32_t fdeSectionOffsetHint=0);
|
||||||
int stepWithDwarfFDE() {
|
int stepWithDwarfFDE(bool stage2) {
|
||||||
return DwarfInstructions<A, R>::stepWithDwarf(_addressSpace,
|
return DwarfInstructions<A, R>::stepWithDwarf(
|
||||||
(pint_t)this->getReg(UNW_REG_IP),
|
_addressSpace, (pint_t)this->getReg(UNW_REG_IP),
|
||||||
(pint_t)_info.unwind_info,
|
(pint_t)_info.unwind_info, _registers, _isSignalFrame, stage2);
|
||||||
_registers, _isSignalFrame);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
|
#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
|
||||||
bool getInfoFromCompactEncodingSection(pint_t pc,
|
bool getInfoFromCompactEncodingSection(pint_t pc,
|
||||||
const UnwindInfoSections §s);
|
const UnwindInfoSections §s);
|
||||||
int stepWithCompactEncoding() {
|
int stepWithCompactEncoding(bool stage2 = false) {
|
||||||
#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
|
#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
|
||||||
if ( compactSaysUseDwarf() )
|
if ( compactSaysUseDwarf() )
|
||||||
return stepWithDwarfFDE();
|
return stepWithDwarfFDE(stage2);
|
||||||
#endif
|
#endif
|
||||||
R dummy;
|
R dummy;
|
||||||
return stepWithCompactEncoding(dummy);
|
return stepWithCompactEncoding(dummy);
|
||||||
}
|
}
|
||||||
@ -1066,6 +1064,10 @@ private:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(_LIBUNWIND_TARGET_LOONGARCH)
|
||||||
|
int stepWithCompactEncoding(Registers_loongarch &) { return UNW_EINVAL; }
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_LIBUNWIND_TARGET_SPARC)
|
#if defined(_LIBUNWIND_TARGET_SPARC)
|
||||||
int stepWithCompactEncoding(Registers_sparc &) { return UNW_EINVAL; }
|
int stepWithCompactEncoding(Registers_sparc &) { return UNW_EINVAL; }
|
||||||
#endif
|
#endif
|
||||||
@ -1142,6 +1144,12 @@ private:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(_LIBUNWIND_TARGET_LOONGARCH)
|
||||||
|
bool compactSaysUseDwarf(Registers_loongarch &, uint32_t *) const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_LIBUNWIND_TARGET_SPARC)
|
#if defined(_LIBUNWIND_TARGET_SPARC)
|
||||||
bool compactSaysUseDwarf(Registers_sparc &, uint32_t *) const { return true; }
|
bool compactSaysUseDwarf(Registers_sparc &, uint32_t *) const { return true; }
|
||||||
#endif
|
#endif
|
||||||
@ -1226,6 +1234,12 @@ private:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(_LIBUNWIND_TARGET_LOONGARCH)
|
||||||
|
compact_unwind_encoding_t dwarfEncoding(Registers_loongarch &) const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_LIBUNWIND_TARGET_SPARC)
|
#if defined(_LIBUNWIND_TARGET_SPARC)
|
||||||
compact_unwind_encoding_t dwarfEncoding(Registers_sparc &) const { return 0; }
|
compact_unwind_encoding_t dwarfEncoding(Registers_sparc &) const { return 0; }
|
||||||
#endif
|
#endif
|
||||||
@ -2106,6 +2120,11 @@ bool UnwindCursor<A, R>::getInfoFromTBTable(pint_t pc, R ®isters) {
|
|||||||
// using dlopen().
|
// using dlopen().
|
||||||
const char libcxxabi[] = "libc++abi.a(libc++abi.so.1)";
|
const char libcxxabi[] = "libc++abi.a(libc++abi.so.1)";
|
||||||
void *libHandle;
|
void *libHandle;
|
||||||
|
// The AIX dlopen() sets errno to 0 when it is successful, which
|
||||||
|
// clobbers the value of errno from the user code. This is an AIX
|
||||||
|
// bug because according to POSIX it should not set errno to 0. To
|
||||||
|
// workaround before AIX fixes the bug, errno is saved and restored.
|
||||||
|
int saveErrno = errno;
|
||||||
libHandle = dlopen(libcxxabi, RTLD_MEMBER | RTLD_NOW);
|
libHandle = dlopen(libcxxabi, RTLD_MEMBER | RTLD_NOW);
|
||||||
if (libHandle == NULL) {
|
if (libHandle == NULL) {
|
||||||
_LIBUNWIND_TRACE_UNWINDING("dlopen() failed with errno=%d\n",
|
_LIBUNWIND_TRACE_UNWINDING("dlopen() failed with errno=%d\n",
|
||||||
@ -2119,6 +2138,7 @@ bool UnwindCursor<A, R>::getInfoFromTBTable(pint_t pc, R ®isters) {
|
|||||||
assert(0 && "dlsym() failed");
|
assert(0 && "dlsym() failed");
|
||||||
}
|
}
|
||||||
dlclose(libHandle);
|
dlclose(libHandle);
|
||||||
|
errno = saveErrno;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xlcPersonalityV0InitLock.unlock();
|
xlcPersonalityV0InitLock.unlock();
|
||||||
@ -2455,7 +2475,7 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
|
|||||||
reinterpret_cast<void *>(pc));
|
reinterpret_cast<void *>(pc));
|
||||||
|
|
||||||
// The return address is the address after call site instruction, so
|
// The return address is the address after call site instruction, so
|
||||||
// setting IP to that simualates a return.
|
// setting IP to that simulates a return.
|
||||||
newRegisters.setIP(reinterpret_cast<uintptr_t>(returnAddress));
|
newRegisters.setIP(reinterpret_cast<uintptr_t>(returnAddress));
|
||||||
|
|
||||||
// Simulate the step by replacing the register set with the new ones.
|
// Simulate the step by replacing the register set with the new ones.
|
||||||
@ -2791,8 +2811,8 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_s390x &) {
|
|||||||
#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
|
#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
|
||||||
// defined(_LIBUNWIND_TARGET_S390X)
|
// defined(_LIBUNWIND_TARGET_S390X)
|
||||||
|
|
||||||
template <typename A, typename R>
|
template <typename A, typename R> int UnwindCursor<A, R>::step(bool stage2) {
|
||||||
int UnwindCursor<A, R>::step() {
|
(void)stage2;
|
||||||
// Bottom of stack is defined is when unwind info cannot be found.
|
// Bottom of stack is defined is when unwind info cannot be found.
|
||||||
if (_unwindInfoMissing)
|
if (_unwindInfoMissing)
|
||||||
return UNW_STEP_END;
|
return UNW_STEP_END;
|
||||||
@ -2806,13 +2826,13 @@ int UnwindCursor<A, R>::step() {
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
|
#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
|
||||||
result = this->stepWithCompactEncoding();
|
result = this->stepWithCompactEncoding(stage2);
|
||||||
#elif defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
|
#elif defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
|
||||||
result = this->stepWithSEHData();
|
result = this->stepWithSEHData();
|
||||||
#elif defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
|
#elif defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
|
||||||
result = this->stepWithTBTableData();
|
result = this->stepWithTBTableData();
|
||||||
#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
|
#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
|
||||||
result = this->stepWithDwarfFDE();
|
result = this->stepWithDwarfFDE(stage2);
|
||||||
#elif defined(_LIBUNWIND_ARM_EHABI)
|
#elif defined(_LIBUNWIND_ARM_EHABI)
|
||||||
result = this->stepWithEHABI();
|
result = this->stepWithEHABI();
|
||||||
#else
|
#else
|
||||||
|
33
lib/libunwind/src/UnwindLevel1-gcc-ext.c
vendored
33
lib/libunwind/src/UnwindLevel1-gcc-ext.c
vendored
@ -22,6 +22,10 @@
|
|||||||
#include "Unwind-EHABI.h"
|
#include "Unwind-EHABI.h"
|
||||||
#include "unwind.h"
|
#include "unwind.h"
|
||||||
|
|
||||||
|
#if defined(_AIX)
|
||||||
|
#include <sys/debug.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)
|
#if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)
|
||||||
|
|
||||||
#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
|
#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
|
||||||
@ -48,7 +52,7 @@ _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) {
|
|||||||
// std::terminate().
|
// std::terminate().
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call through to _Unwind_Resume() which distiguishes between forced and
|
// Call through to _Unwind_Resume() which distinguishes between forced and
|
||||||
// regular exceptions.
|
// regular exceptions.
|
||||||
_Unwind_Resume(exception_object);
|
_Unwind_Resume(exception_object);
|
||||||
_LIBUNWIND_ABORT("_Unwind_Resume_or_Rethrow() called _Unwind_RaiseException()"
|
_LIBUNWIND_ABORT("_Unwind_Resume_or_Rethrow() called _Unwind_RaiseException()"
|
||||||
@ -82,6 +86,32 @@ _Unwind_GetTextRelBase(struct _Unwind_Context *context) {
|
|||||||
/// specified code address "pc".
|
/// specified code address "pc".
|
||||||
_LIBUNWIND_EXPORT void *_Unwind_FindEnclosingFunction(void *pc) {
|
_LIBUNWIND_EXPORT void *_Unwind_FindEnclosingFunction(void *pc) {
|
||||||
_LIBUNWIND_TRACE_API("_Unwind_FindEnclosingFunction(pc=%p)", pc);
|
_LIBUNWIND_TRACE_API("_Unwind_FindEnclosingFunction(pc=%p)", pc);
|
||||||
|
#if defined(_AIX)
|
||||||
|
if (pc == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Get the start address of the enclosing function from the function's
|
||||||
|
// traceback table.
|
||||||
|
uint32_t *p = (uint32_t *)pc;
|
||||||
|
|
||||||
|
// Keep looking forward until a word of 0 is found. The traceback
|
||||||
|
// table starts at the following word.
|
||||||
|
while (*p)
|
||||||
|
++p;
|
||||||
|
struct tbtable *TBTable = (struct tbtable *)(p + 1);
|
||||||
|
|
||||||
|
// Get the address of the traceback table extension.
|
||||||
|
p = (uint32_t *)&TBTable->tb_ext;
|
||||||
|
|
||||||
|
// Skip field parminfo if it exists.
|
||||||
|
if (TBTable->tb.fixedparms || TBTable->tb.floatparms)
|
||||||
|
++p;
|
||||||
|
|
||||||
|
if (TBTable->tb.has_tboff)
|
||||||
|
// *p contains the offset from the function start to traceback table.
|
||||||
|
return (void *)((uintptr_t)TBTable - *p - sizeof(uint32_t));
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
// This is slow, but works.
|
// This is slow, but works.
|
||||||
// We create an unwind cursor then alter the IP to be pc
|
// We create an unwind cursor then alter the IP to be pc
|
||||||
unw_cursor_t cursor;
|
unw_cursor_t cursor;
|
||||||
@ -94,6 +124,7 @@ _LIBUNWIND_EXPORT void *_Unwind_FindEnclosingFunction(void *pc) {
|
|||||||
return (void *)(intptr_t) info.start_ip;
|
return (void *)(intptr_t) info.start_ip;
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Walk every frame and call trace function at each one. If trace function
|
/// Walk every frame and call trace function at each one. If trace function
|
||||||
|
84
lib/libunwind/src/UnwindLevel1.c
vendored
84
lib/libunwind/src/UnwindLevel1.c
vendored
@ -41,7 +41,7 @@
|
|||||||
// In exception handing, some stack frames will be skipped before jumping to
|
// In exception handing, some stack frames will be skipped before jumping to
|
||||||
// landing pad and we must adjust CET shadow stack accordingly.
|
// landing pad and we must adjust CET shadow stack accordingly.
|
||||||
// _LIBUNWIND_POP_CET_SSP is used to adjust CET shadow stack pointer and we
|
// _LIBUNWIND_POP_CET_SSP is used to adjust CET shadow stack pointer and we
|
||||||
// directly jump to __libunwind_Registerts_x86/x86_64_jumpto instead of using
|
// directly jump to __libunwind_Registers_x86/x86_64_jumpto instead of using
|
||||||
// a regular function call to avoid pushing to CET shadow stack again.
|
// a regular function call to avoid pushing to CET shadow stack again.
|
||||||
#if !defined(_LIBUNWIND_USE_CET)
|
#if !defined(_LIBUNWIND_USE_CET)
|
||||||
#define __unw_phase2_resume(cursor, fn) \
|
#define __unw_phase2_resume(cursor, fn) \
|
||||||
@ -50,6 +50,7 @@
|
|||||||
__unw_resume((cursor)); \
|
__unw_resume((cursor)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#elif defined(_LIBUNWIND_TARGET_I386)
|
#elif defined(_LIBUNWIND_TARGET_I386)
|
||||||
|
#define __cet_ss_step_size 4
|
||||||
#define __unw_phase2_resume(cursor, fn) \
|
#define __unw_phase2_resume(cursor, fn) \
|
||||||
do { \
|
do { \
|
||||||
_LIBUNWIND_POP_CET_SSP((fn)); \
|
_LIBUNWIND_POP_CET_SSP((fn)); \
|
||||||
@ -61,6 +62,7 @@
|
|||||||
"d"(cetJumpAddress)); \
|
"d"(cetJumpAddress)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#elif defined(_LIBUNWIND_TARGET_X86_64)
|
#elif defined(_LIBUNWIND_TARGET_X86_64)
|
||||||
|
#define __cet_ss_step_size 8
|
||||||
#define __unw_phase2_resume(cursor, fn) \
|
#define __unw_phase2_resume(cursor, fn) \
|
||||||
do { \
|
do { \
|
||||||
_LIBUNWIND_POP_CET_SSP((fn)); \
|
_LIBUNWIND_POP_CET_SSP((fn)); \
|
||||||
@ -82,13 +84,13 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
|
|||||||
int stepResult = __unw_step(cursor);
|
int stepResult = __unw_step(cursor);
|
||||||
if (stepResult == 0) {
|
if (stepResult == 0) {
|
||||||
_LIBUNWIND_TRACE_UNWINDING(
|
_LIBUNWIND_TRACE_UNWINDING(
|
||||||
"unwind_phase1(ex_ojb=%p): __unw_step() reached "
|
"unwind_phase1(ex_obj=%p): __unw_step() reached "
|
||||||
"bottom => _URC_END_OF_STACK",
|
"bottom => _URC_END_OF_STACK",
|
||||||
(void *)exception_object);
|
(void *)exception_object);
|
||||||
return _URC_END_OF_STACK;
|
return _URC_END_OF_STACK;
|
||||||
} else if (stepResult < 0) {
|
} else if (stepResult < 0) {
|
||||||
_LIBUNWIND_TRACE_UNWINDING(
|
_LIBUNWIND_TRACE_UNWINDING(
|
||||||
"unwind_phase1(ex_ojb=%p): __unw_step failed => "
|
"unwind_phase1(ex_obj=%p): __unw_step failed => "
|
||||||
"_URC_FATAL_PHASE1_ERROR",
|
"_URC_FATAL_PHASE1_ERROR",
|
||||||
(void *)exception_object);
|
(void *)exception_object);
|
||||||
return _URC_FATAL_PHASE1_ERROR;
|
return _URC_FATAL_PHASE1_ERROR;
|
||||||
@ -99,7 +101,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
|
|||||||
unw_word_t sp;
|
unw_word_t sp;
|
||||||
if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
|
if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
|
||||||
_LIBUNWIND_TRACE_UNWINDING(
|
_LIBUNWIND_TRACE_UNWINDING(
|
||||||
"unwind_phase1(ex_ojb=%p): __unw_get_proc_info "
|
"unwind_phase1(ex_obj=%p): __unw_get_proc_info "
|
||||||
"failed => _URC_FATAL_PHASE1_ERROR",
|
"failed => _URC_FATAL_PHASE1_ERROR",
|
||||||
(void *)exception_object);
|
(void *)exception_object);
|
||||||
return _URC_FATAL_PHASE1_ERROR;
|
return _URC_FATAL_PHASE1_ERROR;
|
||||||
@ -118,7 +120,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
|
|||||||
unw_word_t pc;
|
unw_word_t pc;
|
||||||
__unw_get_reg(cursor, UNW_REG_IP, &pc);
|
__unw_get_reg(cursor, UNW_REG_IP, &pc);
|
||||||
_LIBUNWIND_TRACE_UNWINDING(
|
_LIBUNWIND_TRACE_UNWINDING(
|
||||||
"unwind_phase1(ex_ojb=%p): pc=0x%" PRIxPTR ", start_ip=0x%" PRIxPTR
|
"unwind_phase1(ex_obj=%p): pc=0x%" PRIxPTR ", start_ip=0x%" PRIxPTR
|
||||||
", func=%s, lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR "",
|
", func=%s, lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR "",
|
||||||
(void *)exception_object, pc, frameInfo.start_ip, functionName,
|
(void *)exception_object, pc, frameInfo.start_ip, functionName,
|
||||||
frameInfo.lsda, frameInfo.handler);
|
frameInfo.lsda, frameInfo.handler);
|
||||||
@ -131,7 +133,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
|
|||||||
_Unwind_Personality_Fn p =
|
_Unwind_Personality_Fn p =
|
||||||
(_Unwind_Personality_Fn)(uintptr_t)(frameInfo.handler);
|
(_Unwind_Personality_Fn)(uintptr_t)(frameInfo.handler);
|
||||||
_LIBUNWIND_TRACE_UNWINDING(
|
_LIBUNWIND_TRACE_UNWINDING(
|
||||||
"unwind_phase1(ex_ojb=%p): calling personality function %p",
|
"unwind_phase1(ex_obj=%p): calling personality function %p",
|
||||||
(void *)exception_object, (void *)(uintptr_t)p);
|
(void *)exception_object, (void *)(uintptr_t)p);
|
||||||
_Unwind_Reason_Code personalityResult =
|
_Unwind_Reason_Code personalityResult =
|
||||||
(*p)(1, _UA_SEARCH_PHASE, exception_object->exception_class,
|
(*p)(1, _UA_SEARCH_PHASE, exception_object->exception_class,
|
||||||
@ -143,13 +145,13 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
|
|||||||
__unw_get_reg(cursor, UNW_REG_SP, &sp);
|
__unw_get_reg(cursor, UNW_REG_SP, &sp);
|
||||||
exception_object->private_2 = (uintptr_t)sp;
|
exception_object->private_2 = (uintptr_t)sp;
|
||||||
_LIBUNWIND_TRACE_UNWINDING(
|
_LIBUNWIND_TRACE_UNWINDING(
|
||||||
"unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND",
|
"unwind_phase1(ex_obj=%p): _URC_HANDLER_FOUND",
|
||||||
(void *)exception_object);
|
(void *)exception_object);
|
||||||
return _URC_NO_REASON;
|
return _URC_NO_REASON;
|
||||||
|
|
||||||
case _URC_CONTINUE_UNWIND:
|
case _URC_CONTINUE_UNWIND:
|
||||||
_LIBUNWIND_TRACE_UNWINDING(
|
_LIBUNWIND_TRACE_UNWINDING(
|
||||||
"unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND",
|
"unwind_phase1(ex_obj=%p): _URC_CONTINUE_UNWIND",
|
||||||
(void *)exception_object);
|
(void *)exception_object);
|
||||||
// continue unwinding
|
// continue unwinding
|
||||||
break;
|
break;
|
||||||
@ -157,7 +159,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
|
|||||||
default:
|
default:
|
||||||
// something went wrong
|
// something went wrong
|
||||||
_LIBUNWIND_TRACE_UNWINDING(
|
_LIBUNWIND_TRACE_UNWINDING(
|
||||||
"unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR",
|
"unwind_phase1(ex_obj=%p): _URC_FATAL_PHASE1_ERROR",
|
||||||
(void *)exception_object);
|
(void *)exception_object);
|
||||||
return _URC_FATAL_PHASE1_ERROR;
|
return _URC_FATAL_PHASE1_ERROR;
|
||||||
}
|
}
|
||||||
@ -165,33 +167,36 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
|
|||||||
}
|
}
|
||||||
return _URC_NO_REASON;
|
return _URC_NO_REASON;
|
||||||
}
|
}
|
||||||
|
extern int __unw_step_stage2(unw_cursor_t *);
|
||||||
|
|
||||||
static _Unwind_Reason_Code
|
static _Unwind_Reason_Code
|
||||||
unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
|
unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
|
||||||
__unw_init_local(cursor, uc);
|
__unw_init_local(cursor, uc);
|
||||||
|
|
||||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)",
|
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_obj=%p)",
|
||||||
(void *)exception_object);
|
(void *)exception_object);
|
||||||
|
|
||||||
// uc is initialized by __unw_getcontext in the parent frame. The first stack
|
// uc is initialized by __unw_getcontext in the parent frame. The first stack
|
||||||
// frame walked is unwind_phase2.
|
// frame walked is unwind_phase2.
|
||||||
unsigned framesWalked = 1;
|
unsigned framesWalked = 1;
|
||||||
|
#ifdef _LIBUNWIND_USE_CET
|
||||||
|
unsigned long shadowStackTop = _get_ssp();
|
||||||
|
#endif
|
||||||
// Walk each frame until we reach where search phase said to stop.
|
// Walk each frame until we reach where search phase said to stop.
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
// Ask libunwind to get next frame (skip over first which is
|
// Ask libunwind to get next frame (skip over first which is
|
||||||
// _Unwind_RaiseException).
|
// _Unwind_RaiseException).
|
||||||
int stepResult = __unw_step(cursor);
|
int stepResult = __unw_step_stage2(cursor);
|
||||||
if (stepResult == 0) {
|
if (stepResult == 0) {
|
||||||
_LIBUNWIND_TRACE_UNWINDING(
|
_LIBUNWIND_TRACE_UNWINDING(
|
||||||
"unwind_phase2(ex_ojb=%p): __unw_step() reached "
|
"unwind_phase2(ex_obj=%p): __unw_step_stage2() reached "
|
||||||
"bottom => _URC_END_OF_STACK",
|
"bottom => _URC_END_OF_STACK",
|
||||||
(void *)exception_object);
|
(void *)exception_object);
|
||||||
return _URC_END_OF_STACK;
|
return _URC_END_OF_STACK;
|
||||||
} else if (stepResult < 0) {
|
} else if (stepResult < 0) {
|
||||||
_LIBUNWIND_TRACE_UNWINDING(
|
_LIBUNWIND_TRACE_UNWINDING(
|
||||||
"unwind_phase2(ex_ojb=%p): __unw_step failed => "
|
"unwind_phase2(ex_obj=%p): __unw_step_stage2 failed => "
|
||||||
"_URC_FATAL_PHASE1_ERROR",
|
"_URC_FATAL_PHASE1_ERROR",
|
||||||
(void *)exception_object);
|
(void *)exception_object);
|
||||||
return _URC_FATAL_PHASE2_ERROR;
|
return _URC_FATAL_PHASE2_ERROR;
|
||||||
@ -203,7 +208,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
|
|||||||
__unw_get_reg(cursor, UNW_REG_SP, &sp);
|
__unw_get_reg(cursor, UNW_REG_SP, &sp);
|
||||||
if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
|
if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
|
||||||
_LIBUNWIND_TRACE_UNWINDING(
|
_LIBUNWIND_TRACE_UNWINDING(
|
||||||
"unwind_phase2(ex_ojb=%p): __unw_get_proc_info "
|
"unwind_phase2(ex_obj=%p): __unw_get_proc_info "
|
||||||
"failed => _URC_FATAL_PHASE1_ERROR",
|
"failed => _URC_FATAL_PHASE1_ERROR",
|
||||||
(void *)exception_object);
|
(void *)exception_object);
|
||||||
return _URC_FATAL_PHASE2_ERROR;
|
return _URC_FATAL_PHASE2_ERROR;
|
||||||
@ -219,7 +224,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
|
|||||||
&offset) != UNW_ESUCCESS) ||
|
&offset) != UNW_ESUCCESS) ||
|
||||||
(frameInfo.start_ip + offset > frameInfo.end_ip))
|
(frameInfo.start_ip + offset > frameInfo.end_ip))
|
||||||
functionName = ".anonymous.";
|
functionName = ".anonymous.";
|
||||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): start_ip=0x%" PRIxPTR
|
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_obj=%p): start_ip=0x%" PRIxPTR
|
||||||
", func=%s, sp=0x%" PRIxPTR ", lsda=0x%" PRIxPTR
|
", func=%s, sp=0x%" PRIxPTR ", lsda=0x%" PRIxPTR
|
||||||
", personality=0x%" PRIxPTR,
|
", personality=0x%" PRIxPTR,
|
||||||
(void *)exception_object, frameInfo.start_ip,
|
(void *)exception_object, frameInfo.start_ip,
|
||||||
@ -228,6 +233,20 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// In CET enabled environment, we check return address stored in normal stack
|
||||||
|
// against return address stored in CET shadow stack, if the 2 addresses don't
|
||||||
|
// match, it means return address in normal stack has been corrupted, we return
|
||||||
|
// _URC_FATAL_PHASE2_ERROR.
|
||||||
|
#ifdef _LIBUNWIND_USE_CET
|
||||||
|
if (shadowStackTop != 0) {
|
||||||
|
unw_word_t retInNormalStack;
|
||||||
|
__unw_get_reg(cursor, UNW_REG_IP, &retInNormalStack);
|
||||||
|
unsigned long retInShadowStack = *(
|
||||||
|
unsigned long *)(shadowStackTop + __cet_ss_step_size * framesWalked);
|
||||||
|
if (retInNormalStack != retInShadowStack)
|
||||||
|
return _URC_FATAL_PHASE2_ERROR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
++framesWalked;
|
++framesWalked;
|
||||||
// If there is a personality routine, tell it we are unwinding.
|
// If there is a personality routine, tell it we are unwinding.
|
||||||
if (frameInfo.handler != 0) {
|
if (frameInfo.handler != 0) {
|
||||||
@ -245,7 +264,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
|
|||||||
case _URC_CONTINUE_UNWIND:
|
case _URC_CONTINUE_UNWIND:
|
||||||
// Continue unwinding
|
// Continue unwinding
|
||||||
_LIBUNWIND_TRACE_UNWINDING(
|
_LIBUNWIND_TRACE_UNWINDING(
|
||||||
"unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND",
|
"unwind_phase2(ex_obj=%p): _URC_CONTINUE_UNWIND",
|
||||||
(void *)exception_object);
|
(void *)exception_object);
|
||||||
if (sp == exception_object->private_2) {
|
if (sp == exception_object->private_2) {
|
||||||
// Phase 1 said we would stop at this frame, but we did not...
|
// Phase 1 said we would stop at this frame, but we did not...
|
||||||
@ -255,7 +274,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
|
|||||||
break;
|
break;
|
||||||
case _URC_INSTALL_CONTEXT:
|
case _URC_INSTALL_CONTEXT:
|
||||||
_LIBUNWIND_TRACE_UNWINDING(
|
_LIBUNWIND_TRACE_UNWINDING(
|
||||||
"unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT",
|
"unwind_phase2(ex_obj=%p): _URC_INSTALL_CONTEXT",
|
||||||
(void *)exception_object);
|
(void *)exception_object);
|
||||||
// Personality routine says to transfer control to landing pad.
|
// Personality routine says to transfer control to landing pad.
|
||||||
// We may get control back if landing pad calls _Unwind_Resume().
|
// We may get control back if landing pad calls _Unwind_Resume().
|
||||||
@ -263,7 +282,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
|
|||||||
unw_word_t pc;
|
unw_word_t pc;
|
||||||
__unw_get_reg(cursor, UNW_REG_IP, &pc);
|
__unw_get_reg(cursor, UNW_REG_IP, &pc);
|
||||||
__unw_get_reg(cursor, UNW_REG_SP, &sp);
|
__unw_get_reg(cursor, UNW_REG_SP, &sp);
|
||||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
|
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_obj=%p): re-entering "
|
||||||
"user code with ip=0x%" PRIxPTR
|
"user code with ip=0x%" PRIxPTR
|
||||||
", sp=0x%" PRIxPTR,
|
", sp=0x%" PRIxPTR,
|
||||||
(void *)exception_object, pc, sp);
|
(void *)exception_object, pc, sp);
|
||||||
@ -296,14 +315,15 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
|
|||||||
// frame walked is unwind_phase2_forced.
|
// frame walked is unwind_phase2_forced.
|
||||||
unsigned framesWalked = 1;
|
unsigned framesWalked = 1;
|
||||||
// Walk each frame until we reach where search phase said to stop
|
// Walk each frame until we reach where search phase said to stop
|
||||||
while (__unw_step(cursor) > 0) {
|
while (__unw_step_stage2(cursor) > 0) {
|
||||||
|
|
||||||
// Update info about this frame.
|
// Update info about this frame.
|
||||||
unw_proc_info_t frameInfo;
|
unw_proc_info_t frameInfo;
|
||||||
if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
|
if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
|
||||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_step "
|
_LIBUNWIND_TRACE_UNWINDING(
|
||||||
"failed => _URC_END_OF_STACK",
|
"unwind_phase2_forced(ex_obj=%p): __unw_step_stage2 "
|
||||||
(void *)exception_object);
|
"failed => _URC_END_OF_STACK",
|
||||||
|
(void *)exception_object);
|
||||||
return _URC_FATAL_PHASE2_ERROR;
|
return _URC_FATAL_PHASE2_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,7 +338,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
|
|||||||
(frameInfo.start_ip + offset > frameInfo.end_ip))
|
(frameInfo.start_ip + offset > frameInfo.end_ip))
|
||||||
functionName = ".anonymous.";
|
functionName = ".anonymous.";
|
||||||
_LIBUNWIND_TRACE_UNWINDING(
|
_LIBUNWIND_TRACE_UNWINDING(
|
||||||
"unwind_phase2_forced(ex_ojb=%p): start_ip=0x%" PRIxPTR
|
"unwind_phase2_forced(ex_obj=%p): start_ip=0x%" PRIxPTR
|
||||||
", func=%s, lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR,
|
", func=%s, lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR,
|
||||||
(void *)exception_object, frameInfo.start_ip, functionName,
|
(void *)exception_object, frameInfo.start_ip, functionName,
|
||||||
frameInfo.lsda, frameInfo.handler);
|
frameInfo.lsda, frameInfo.handler);
|
||||||
@ -332,11 +352,11 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
|
|||||||
(*stop)(1, action, exception_object->exception_class, exception_object,
|
(*stop)(1, action, exception_object->exception_class, exception_object,
|
||||||
(struct _Unwind_Context *)(cursor), stop_parameter);
|
(struct _Unwind_Context *)(cursor), stop_parameter);
|
||||||
_LIBUNWIND_TRACE_UNWINDING(
|
_LIBUNWIND_TRACE_UNWINDING(
|
||||||
"unwind_phase2_forced(ex_ojb=%p): stop function returned %d",
|
"unwind_phase2_forced(ex_obj=%p): stop function returned %d",
|
||||||
(void *)exception_object, stopResult);
|
(void *)exception_object, stopResult);
|
||||||
if (stopResult != _URC_NO_REASON) {
|
if (stopResult != _URC_NO_REASON) {
|
||||||
_LIBUNWIND_TRACE_UNWINDING(
|
_LIBUNWIND_TRACE_UNWINDING(
|
||||||
"unwind_phase2_forced(ex_ojb=%p): stopped by stop function",
|
"unwind_phase2_forced(ex_obj=%p): stopped by stop function",
|
||||||
(void *)exception_object);
|
(void *)exception_object);
|
||||||
return _URC_FATAL_PHASE2_ERROR;
|
return _URC_FATAL_PHASE2_ERROR;
|
||||||
}
|
}
|
||||||
@ -347,21 +367,21 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
|
|||||||
_Unwind_Personality_Fn p =
|
_Unwind_Personality_Fn p =
|
||||||
(_Unwind_Personality_Fn)(intptr_t)(frameInfo.handler);
|
(_Unwind_Personality_Fn)(intptr_t)(frameInfo.handler);
|
||||||
_LIBUNWIND_TRACE_UNWINDING(
|
_LIBUNWIND_TRACE_UNWINDING(
|
||||||
"unwind_phase2_forced(ex_ojb=%p): calling personality function %p",
|
"unwind_phase2_forced(ex_obj=%p): calling personality function %p",
|
||||||
(void *)exception_object, (void *)(uintptr_t)p);
|
(void *)exception_object, (void *)(uintptr_t)p);
|
||||||
_Unwind_Reason_Code personalityResult =
|
_Unwind_Reason_Code personalityResult =
|
||||||
(*p)(1, action, exception_object->exception_class, exception_object,
|
(*p)(1, action, exception_object->exception_class, exception_object,
|
||||||
(struct _Unwind_Context *)(cursor));
|
(struct _Unwind_Context *)(cursor));
|
||||||
switch (personalityResult) {
|
switch (personalityResult) {
|
||||||
case _URC_CONTINUE_UNWIND:
|
case _URC_CONTINUE_UNWIND:
|
||||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
|
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_obj=%p): "
|
||||||
"personality returned "
|
"personality returned "
|
||||||
"_URC_CONTINUE_UNWIND",
|
"_URC_CONTINUE_UNWIND",
|
||||||
(void *)exception_object);
|
(void *)exception_object);
|
||||||
// Destructors called, continue unwinding
|
// Destructors called, continue unwinding
|
||||||
break;
|
break;
|
||||||
case _URC_INSTALL_CONTEXT:
|
case _URC_INSTALL_CONTEXT:
|
||||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
|
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_obj=%p): "
|
||||||
"personality returned "
|
"personality returned "
|
||||||
"_URC_INSTALL_CONTEXT",
|
"_URC_INSTALL_CONTEXT",
|
||||||
(void *)exception_object);
|
(void *)exception_object);
|
||||||
@ -370,7 +390,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Personality routine returned an unknown result code.
|
// Personality routine returned an unknown result code.
|
||||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
|
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_obj=%p): "
|
||||||
"personality returned %d, "
|
"personality returned %d, "
|
||||||
"_URC_FATAL_PHASE2_ERROR",
|
"_URC_FATAL_PHASE2_ERROR",
|
||||||
(void *)exception_object, personalityResult);
|
(void *)exception_object, personalityResult);
|
||||||
@ -381,7 +401,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
|
|||||||
|
|
||||||
// Call stop function one last time and tell it we've reached the end
|
// Call stop function one last time and tell it we've reached the end
|
||||||
// of the stack.
|
// of the stack.
|
||||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling stop "
|
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_obj=%p): calling stop "
|
||||||
"function with _UA_END_OF_STACK",
|
"function with _UA_END_OF_STACK",
|
||||||
(void *)exception_object);
|
(void *)exception_object);
|
||||||
_Unwind_Action lastAction =
|
_Unwind_Action lastAction =
|
||||||
@ -425,7 +445,7 @@ _Unwind_RaiseException(_Unwind_Exception *exception_object) {
|
|||||||
/// may force a jump to a landing pad in that function, the landing
|
/// may force a jump to a landing pad in that function, the landing
|
||||||
/// pad code may then call _Unwind_Resume() to continue with the
|
/// pad code may then call _Unwind_Resume() to continue with the
|
||||||
/// unwinding. Note: the call to _Unwind_Resume() is from compiler
|
/// unwinding. Note: the call to _Unwind_Resume() is from compiler
|
||||||
/// geneated user code. All other _Unwind_* routines are called
|
/// generated user code. All other _Unwind_* routines are called
|
||||||
/// by the C++ runtime __cxa_* routines.
|
/// by the C++ runtime __cxa_* routines.
|
||||||
///
|
///
|
||||||
/// Note: re-throwing an exception (as opposed to continuing the unwind)
|
/// Note: re-throwing an exception (as opposed to continuing the unwind)
|
||||||
|
191
lib/libunwind/src/UnwindRegistersRestore.S
vendored
191
lib/libunwind/src/UnwindRegistersRestore.S
vendored
@ -8,6 +8,12 @@
|
|||||||
|
|
||||||
#include "assembly.h"
|
#include "assembly.h"
|
||||||
|
|
||||||
|
#define FROM_0_TO_15 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
||||||
|
#define FROM_16_TO_31 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
|
||||||
|
|
||||||
|
#define FROM_0_TO_31 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
|
||||||
|
#define FROM_32_TO_63 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63
|
||||||
|
|
||||||
#if defined(_AIX)
|
#if defined(_AIX)
|
||||||
.toc
|
.toc
|
||||||
#else
|
#else
|
||||||
@ -441,7 +447,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)
|
|||||||
// thread_state pointer is in r3
|
// thread_state pointer is in r3
|
||||||
//
|
//
|
||||||
|
|
||||||
// restore integral registerrs
|
// restore integral registers
|
||||||
// skip r0 for now
|
// skip r0 for now
|
||||||
// skip r1 for now
|
// skip r1 for now
|
||||||
lwz 2, 16(3)
|
lwz 2, 16(3)
|
||||||
@ -1026,38 +1032,9 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv)
|
|||||||
.set noreorder
|
.set noreorder
|
||||||
.set nomacro
|
.set nomacro
|
||||||
#ifdef __mips_hard_float
|
#ifdef __mips_hard_float
|
||||||
ldc1 $f0, (8 * 35)($4)
|
.irp i,FROM_0_TO_31
|
||||||
ldc1 $f1, (8 * 36)($4)
|
ldc1 $f\i, (280+8*\i)($4)
|
||||||
ldc1 $f2, (8 * 37)($4)
|
.endr
|
||||||
ldc1 $f3, (8 * 38)($4)
|
|
||||||
ldc1 $f4, (8 * 39)($4)
|
|
||||||
ldc1 $f5, (8 * 40)($4)
|
|
||||||
ldc1 $f6, (8 * 41)($4)
|
|
||||||
ldc1 $f7, (8 * 42)($4)
|
|
||||||
ldc1 $f8, (8 * 43)($4)
|
|
||||||
ldc1 $f9, (8 * 44)($4)
|
|
||||||
ldc1 $f10, (8 * 45)($4)
|
|
||||||
ldc1 $f11, (8 * 46)($4)
|
|
||||||
ldc1 $f12, (8 * 47)($4)
|
|
||||||
ldc1 $f13, (8 * 48)($4)
|
|
||||||
ldc1 $f14, (8 * 49)($4)
|
|
||||||
ldc1 $f15, (8 * 50)($4)
|
|
||||||
ldc1 $f16, (8 * 51)($4)
|
|
||||||
ldc1 $f17, (8 * 52)($4)
|
|
||||||
ldc1 $f18, (8 * 53)($4)
|
|
||||||
ldc1 $f19, (8 * 54)($4)
|
|
||||||
ldc1 $f20, (8 * 55)($4)
|
|
||||||
ldc1 $f21, (8 * 56)($4)
|
|
||||||
ldc1 $f22, (8 * 57)($4)
|
|
||||||
ldc1 $f23, (8 * 58)($4)
|
|
||||||
ldc1 $f24, (8 * 59)($4)
|
|
||||||
ldc1 $f25, (8 * 60)($4)
|
|
||||||
ldc1 $f26, (8 * 61)($4)
|
|
||||||
ldc1 $f27, (8 * 62)($4)
|
|
||||||
ldc1 $f28, (8 * 63)($4)
|
|
||||||
ldc1 $f29, (8 * 64)($4)
|
|
||||||
ldc1 $f30, (8 * 65)($4)
|
|
||||||
ldc1 $f31, (8 * 66)($4)
|
|
||||||
#endif
|
#endif
|
||||||
// restore hi and lo
|
// restore hi and lo
|
||||||
ld $8, (8 * 33)($4)
|
ld $8, (8 * 33)($4)
|
||||||
@ -1069,32 +1046,9 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv)
|
|||||||
ld $2, (8 * 2)($4)
|
ld $2, (8 * 2)($4)
|
||||||
ld $3, (8 * 3)($4)
|
ld $3, (8 * 3)($4)
|
||||||
// skip a0 for now
|
// skip a0 for now
|
||||||
ld $5, (8 * 5)($4)
|
.irp i,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
|
||||||
ld $6, (8 * 6)($4)
|
ld $\i, (8 * \i)($4)
|
||||||
ld $7, (8 * 7)($4)
|
.endr
|
||||||
ld $8, (8 * 8)($4)
|
|
||||||
ld $9, (8 * 9)($4)
|
|
||||||
ld $10, (8 * 10)($4)
|
|
||||||
ld $11, (8 * 11)($4)
|
|
||||||
ld $12, (8 * 12)($4)
|
|
||||||
ld $13, (8 * 13)($4)
|
|
||||||
ld $14, (8 * 14)($4)
|
|
||||||
ld $15, (8 * 15)($4)
|
|
||||||
ld $16, (8 * 16)($4)
|
|
||||||
ld $17, (8 * 17)($4)
|
|
||||||
ld $18, (8 * 18)($4)
|
|
||||||
ld $19, (8 * 19)($4)
|
|
||||||
ld $20, (8 * 20)($4)
|
|
||||||
ld $21, (8 * 21)($4)
|
|
||||||
ld $22, (8 * 22)($4)
|
|
||||||
ld $23, (8 * 23)($4)
|
|
||||||
ld $24, (8 * 24)($4)
|
|
||||||
ld $25, (8 * 25)($4)
|
|
||||||
ld $26, (8 * 26)($4)
|
|
||||||
ld $27, (8 * 27)($4)
|
|
||||||
ld $28, (8 * 28)($4)
|
|
||||||
ld $29, (8 * 29)($4)
|
|
||||||
ld $30, (8 * 30)($4)
|
|
||||||
// load new pc into ra
|
// load new pc into ra
|
||||||
ld $31, (8 * 32)($4)
|
ld $31, (8 * 32)($4)
|
||||||
// jump to ra, load a0 in the delay slot
|
// jump to ra, load a0 in the delay slot
|
||||||
@ -1182,72 +1136,20 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_sparc6jumptoEv)
|
|||||||
.p2align 2
|
.p2align 2
|
||||||
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv)
|
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv)
|
||||||
# if defined(__riscv_flen)
|
# if defined(__riscv_flen)
|
||||||
FLOAD f0, (RISCV_FOFFSET + RISCV_FSIZE * 0)(a0)
|
.irp i,FROM_0_TO_31
|
||||||
FLOAD f1, (RISCV_FOFFSET + RISCV_FSIZE * 1)(a0)
|
FLOAD f\i, (RISCV_FOFFSET + RISCV_FSIZE * \i)(a0)
|
||||||
FLOAD f2, (RISCV_FOFFSET + RISCV_FSIZE * 2)(a0)
|
.endr
|
||||||
FLOAD f3, (RISCV_FOFFSET + RISCV_FSIZE * 3)(a0)
|
|
||||||
FLOAD f4, (RISCV_FOFFSET + RISCV_FSIZE * 4)(a0)
|
|
||||||
FLOAD f5, (RISCV_FOFFSET + RISCV_FSIZE * 5)(a0)
|
|
||||||
FLOAD f6, (RISCV_FOFFSET + RISCV_FSIZE * 6)(a0)
|
|
||||||
FLOAD f7, (RISCV_FOFFSET + RISCV_FSIZE * 7)(a0)
|
|
||||||
FLOAD f8, (RISCV_FOFFSET + RISCV_FSIZE * 8)(a0)
|
|
||||||
FLOAD f9, (RISCV_FOFFSET + RISCV_FSIZE * 9)(a0)
|
|
||||||
FLOAD f10, (RISCV_FOFFSET + RISCV_FSIZE * 10)(a0)
|
|
||||||
FLOAD f11, (RISCV_FOFFSET + RISCV_FSIZE * 11)(a0)
|
|
||||||
FLOAD f12, (RISCV_FOFFSET + RISCV_FSIZE * 12)(a0)
|
|
||||||
FLOAD f13, (RISCV_FOFFSET + RISCV_FSIZE * 13)(a0)
|
|
||||||
FLOAD f14, (RISCV_FOFFSET + RISCV_FSIZE * 14)(a0)
|
|
||||||
FLOAD f15, (RISCV_FOFFSET + RISCV_FSIZE * 15)(a0)
|
|
||||||
FLOAD f16, (RISCV_FOFFSET + RISCV_FSIZE * 16)(a0)
|
|
||||||
FLOAD f17, (RISCV_FOFFSET + RISCV_FSIZE * 17)(a0)
|
|
||||||
FLOAD f18, (RISCV_FOFFSET + RISCV_FSIZE * 18)(a0)
|
|
||||||
FLOAD f19, (RISCV_FOFFSET + RISCV_FSIZE * 19)(a0)
|
|
||||||
FLOAD f20, (RISCV_FOFFSET + RISCV_FSIZE * 20)(a0)
|
|
||||||
FLOAD f21, (RISCV_FOFFSET + RISCV_FSIZE * 21)(a0)
|
|
||||||
FLOAD f22, (RISCV_FOFFSET + RISCV_FSIZE * 22)(a0)
|
|
||||||
FLOAD f23, (RISCV_FOFFSET + RISCV_FSIZE * 23)(a0)
|
|
||||||
FLOAD f24, (RISCV_FOFFSET + RISCV_FSIZE * 24)(a0)
|
|
||||||
FLOAD f25, (RISCV_FOFFSET + RISCV_FSIZE * 25)(a0)
|
|
||||||
FLOAD f26, (RISCV_FOFFSET + RISCV_FSIZE * 26)(a0)
|
|
||||||
FLOAD f27, (RISCV_FOFFSET + RISCV_FSIZE * 27)(a0)
|
|
||||||
FLOAD f28, (RISCV_FOFFSET + RISCV_FSIZE * 28)(a0)
|
|
||||||
FLOAD f29, (RISCV_FOFFSET + RISCV_FSIZE * 29)(a0)
|
|
||||||
FLOAD f30, (RISCV_FOFFSET + RISCV_FSIZE * 30)(a0)
|
|
||||||
FLOAD f31, (RISCV_FOFFSET + RISCV_FSIZE * 31)(a0)
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
// x0 is zero
|
// x0 is zero
|
||||||
ILOAD x1, (RISCV_ISIZE * 0)(a0) // restore pc into ra
|
ILOAD x1, (RISCV_ISIZE * 0)(a0) // restore pc into ra
|
||||||
ILOAD x2, (RISCV_ISIZE * 2)(a0)
|
.irp i,2,3,4,5,6,7,8,9
|
||||||
ILOAD x3, (RISCV_ISIZE * 3)(a0)
|
ILOAD x\i, (RISCV_ISIZE * \i)(a0)
|
||||||
ILOAD x4, (RISCV_ISIZE * 4)(a0)
|
.endr
|
||||||
ILOAD x5, (RISCV_ISIZE * 5)(a0)
|
|
||||||
ILOAD x6, (RISCV_ISIZE * 6)(a0)
|
|
||||||
ILOAD x7, (RISCV_ISIZE * 7)(a0)
|
|
||||||
ILOAD x8, (RISCV_ISIZE * 8)(a0)
|
|
||||||
ILOAD x9, (RISCV_ISIZE * 9)(a0)
|
|
||||||
// skip a0 for now
|
// skip a0 for now
|
||||||
ILOAD x11, (RISCV_ISIZE * 11)(a0)
|
.irp i,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
|
||||||
ILOAD x12, (RISCV_ISIZE * 12)(a0)
|
ILOAD x\i, (RISCV_ISIZE * \i)(a0)
|
||||||
ILOAD x13, (RISCV_ISIZE * 13)(a0)
|
.endr
|
||||||
ILOAD x14, (RISCV_ISIZE * 14)(a0)
|
|
||||||
ILOAD x15, (RISCV_ISIZE * 15)(a0)
|
|
||||||
ILOAD x16, (RISCV_ISIZE * 16)(a0)
|
|
||||||
ILOAD x17, (RISCV_ISIZE * 17)(a0)
|
|
||||||
ILOAD x18, (RISCV_ISIZE * 18)(a0)
|
|
||||||
ILOAD x19, (RISCV_ISIZE * 19)(a0)
|
|
||||||
ILOAD x20, (RISCV_ISIZE * 20)(a0)
|
|
||||||
ILOAD x21, (RISCV_ISIZE * 21)(a0)
|
|
||||||
ILOAD x22, (RISCV_ISIZE * 22)(a0)
|
|
||||||
ILOAD x23, (RISCV_ISIZE * 23)(a0)
|
|
||||||
ILOAD x24, (RISCV_ISIZE * 24)(a0)
|
|
||||||
ILOAD x25, (RISCV_ISIZE * 25)(a0)
|
|
||||||
ILOAD x26, (RISCV_ISIZE * 26)(a0)
|
|
||||||
ILOAD x27, (RISCV_ISIZE * 27)(a0)
|
|
||||||
ILOAD x28, (RISCV_ISIZE * 28)(a0)
|
|
||||||
ILOAD x29, (RISCV_ISIZE * 29)(a0)
|
|
||||||
ILOAD x30, (RISCV_ISIZE * 30)(a0)
|
|
||||||
ILOAD x31, (RISCV_ISIZE * 31)(a0)
|
|
||||||
ILOAD x10, (RISCV_ISIZE * 10)(a0) // restore a0
|
ILOAD x10, (RISCV_ISIZE * 10)(a0) // restore a0
|
||||||
|
|
||||||
ret // jump to ra
|
ret // jump to ra
|
||||||
@ -1266,22 +1168,9 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_s390x6jumptoEv)
|
|||||||
lg %r1, 8(%r2)
|
lg %r1, 8(%r2)
|
||||||
|
|
||||||
// Restore FPRs
|
// Restore FPRs
|
||||||
ld %f0, 144(%r2)
|
.irp i,FROM_0_TO_15
|
||||||
ld %f1, 152(%r2)
|
ld %f\i, (144+8*\i)(%r2)
|
||||||
ld %f2, 160(%r2)
|
.endr
|
||||||
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
|
// Restore GPRs - skipping %r0 and %r1
|
||||||
lmg %r2, %r15, 32(%r2)
|
lmg %r2, %r15, 32(%r2)
|
||||||
@ -1289,6 +1178,36 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_s390x6jumptoEv)
|
|||||||
// Return to PSWA (was loaded into %r1 above)
|
// Return to PSWA (was loaded into %r1 above)
|
||||||
br %r1
|
br %r1
|
||||||
|
|
||||||
|
#elif defined(__loongarch__) && __loongarch_grlen == 64
|
||||||
|
|
||||||
|
//
|
||||||
|
// void libunwind::Registers_loongarch::jumpto()
|
||||||
|
//
|
||||||
|
// On entry:
|
||||||
|
// thread_state pointer is in $a0($r4)
|
||||||
|
//
|
||||||
|
.p2align 2
|
||||||
|
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind19Registers_loongarch6jumptoEv)
|
||||||
|
# if __loongarch_frlen == 64
|
||||||
|
.irp i,FROM_0_TO_31
|
||||||
|
fld.d $f\i, $a0, (8 * 33 + 8 * \i)
|
||||||
|
.endr
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// $r0 is zero
|
||||||
|
.irp i,1,2,3
|
||||||
|
ld.d $r\i, $a0, (8 * \i)
|
||||||
|
.endr
|
||||||
|
// skip $a0 for now
|
||||||
|
.irp i,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
|
||||||
|
ld.d $r\i, $a0, (8 * \i)
|
||||||
|
.endr
|
||||||
|
|
||||||
|
ld.d $r4, $a0, (8 * 4) // restore $a0 last
|
||||||
|
ld.d $r1, $a0, (8 * 32) // load new pc into $ra
|
||||||
|
|
||||||
|
jr $ra
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */
|
#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */
|
||||||
|
186
lib/libunwind/src/UnwindRegistersSave.S
vendored
186
lib/libunwind/src/UnwindRegistersSave.S
vendored
@ -8,6 +8,12 @@
|
|||||||
|
|
||||||
#include "assembly.h"
|
#include "assembly.h"
|
||||||
|
|
||||||
|
#define FROM_0_TO_15 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
||||||
|
#define FROM_16_TO_31 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
|
||||||
|
|
||||||
|
#define FROM_0_TO_31 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
|
||||||
|
#define FROM_32_TO_63 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63
|
||||||
|
|
||||||
#if defined(_AIX)
|
#if defined(_AIX)
|
||||||
.toc
|
.toc
|
||||||
#else
|
#else
|
||||||
@ -244,37 +250,9 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
|
|||||||
.set noat
|
.set noat
|
||||||
.set noreorder
|
.set noreorder
|
||||||
.set nomacro
|
.set nomacro
|
||||||
sd $1, (8 * 1)($4)
|
.irp i,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
|
||||||
sd $2, (8 * 2)($4)
|
sd $\i, (8 * \i)($4)
|
||||||
sd $3, (8 * 3)($4)
|
.endr
|
||||||
sd $4, (8 * 4)($4)
|
|
||||||
sd $5, (8 * 5)($4)
|
|
||||||
sd $6, (8 * 6)($4)
|
|
||||||
sd $7, (8 * 7)($4)
|
|
||||||
sd $8, (8 * 8)($4)
|
|
||||||
sd $9, (8 * 9)($4)
|
|
||||||
sd $10, (8 * 10)($4)
|
|
||||||
sd $11, (8 * 11)($4)
|
|
||||||
sd $12, (8 * 12)($4)
|
|
||||||
sd $13, (8 * 13)($4)
|
|
||||||
sd $14, (8 * 14)($4)
|
|
||||||
sd $15, (8 * 15)($4)
|
|
||||||
sd $16, (8 * 16)($4)
|
|
||||||
sd $17, (8 * 17)($4)
|
|
||||||
sd $18, (8 * 18)($4)
|
|
||||||
sd $19, (8 * 19)($4)
|
|
||||||
sd $20, (8 * 20)($4)
|
|
||||||
sd $21, (8 * 21)($4)
|
|
||||||
sd $22, (8 * 22)($4)
|
|
||||||
sd $23, (8 * 23)($4)
|
|
||||||
sd $24, (8 * 24)($4)
|
|
||||||
sd $25, (8 * 25)($4)
|
|
||||||
sd $26, (8 * 26)($4)
|
|
||||||
sd $27, (8 * 27)($4)
|
|
||||||
sd $28, (8 * 28)($4)
|
|
||||||
sd $29, (8 * 29)($4)
|
|
||||||
sd $30, (8 * 30)($4)
|
|
||||||
sd $31, (8 * 31)($4)
|
|
||||||
# Store return address to pc
|
# Store return address to pc
|
||||||
sd $31, (8 * 32)($4)
|
sd $31, (8 * 32)($4)
|
||||||
# hi and lo
|
# hi and lo
|
||||||
@ -283,38 +261,9 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
|
|||||||
mflo $8
|
mflo $8
|
||||||
sd $8, (8 * 34)($4)
|
sd $8, (8 * 34)($4)
|
||||||
#ifdef __mips_hard_float
|
#ifdef __mips_hard_float
|
||||||
sdc1 $f0, (8 * 35)($4)
|
.irp i,FROM_0_TO_31
|
||||||
sdc1 $f1, (8 * 36)($4)
|
sdc1 $f\i, (280+8*\i)($4)
|
||||||
sdc1 $f2, (8 * 37)($4)
|
.endr
|
||||||
sdc1 $f3, (8 * 38)($4)
|
|
||||||
sdc1 $f4, (8 * 39)($4)
|
|
||||||
sdc1 $f5, (8 * 40)($4)
|
|
||||||
sdc1 $f6, (8 * 41)($4)
|
|
||||||
sdc1 $f7, (8 * 42)($4)
|
|
||||||
sdc1 $f8, (8 * 43)($4)
|
|
||||||
sdc1 $f9, (8 * 44)($4)
|
|
||||||
sdc1 $f10, (8 * 45)($4)
|
|
||||||
sdc1 $f11, (8 * 46)($4)
|
|
||||||
sdc1 $f12, (8 * 47)($4)
|
|
||||||
sdc1 $f13, (8 * 48)($4)
|
|
||||||
sdc1 $f14, (8 * 49)($4)
|
|
||||||
sdc1 $f15, (8 * 50)($4)
|
|
||||||
sdc1 $f16, (8 * 51)($4)
|
|
||||||
sdc1 $f17, (8 * 52)($4)
|
|
||||||
sdc1 $f18, (8 * 53)($4)
|
|
||||||
sdc1 $f19, (8 * 54)($4)
|
|
||||||
sdc1 $f20, (8 * 55)($4)
|
|
||||||
sdc1 $f21, (8 * 56)($4)
|
|
||||||
sdc1 $f22, (8 * 57)($4)
|
|
||||||
sdc1 $f23, (8 * 58)($4)
|
|
||||||
sdc1 $f24, (8 * 59)($4)
|
|
||||||
sdc1 $f25, (8 * 60)($4)
|
|
||||||
sdc1 $f26, (8 * 61)($4)
|
|
||||||
sdc1 $f27, (8 * 62)($4)
|
|
||||||
sdc1 $f28, (8 * 63)($4)
|
|
||||||
sdc1 $f29, (8 * 64)($4)
|
|
||||||
sdc1 $f30, (8 * 65)($4)
|
|
||||||
sdc1 $f31, (8 * 66)($4)
|
|
||||||
#endif
|
#endif
|
||||||
jr $31
|
jr $31
|
||||||
# return UNW_ESUCCESS
|
# return UNW_ESUCCESS
|
||||||
@ -1110,71 +1059,14 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
|
|||||||
#
|
#
|
||||||
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
|
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
|
||||||
ISTORE x1, (RISCV_ISIZE * 0)(a0) // store ra as pc
|
ISTORE x1, (RISCV_ISIZE * 0)(a0) // store ra as pc
|
||||||
ISTORE x1, (RISCV_ISIZE * 1)(a0)
|
.irp i,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
|
||||||
ISTORE x2, (RISCV_ISIZE * 2)(a0)
|
ISTORE x\i, (RISCV_ISIZE * \i)(a0)
|
||||||
ISTORE x3, (RISCV_ISIZE * 3)(a0)
|
.endr
|
||||||
ISTORE x4, (RISCV_ISIZE * 4)(a0)
|
|
||||||
ISTORE x5, (RISCV_ISIZE * 5)(a0)
|
|
||||||
ISTORE x6, (RISCV_ISIZE * 6)(a0)
|
|
||||||
ISTORE x7, (RISCV_ISIZE * 7)(a0)
|
|
||||||
ISTORE x8, (RISCV_ISIZE * 8)(a0)
|
|
||||||
ISTORE x9, (RISCV_ISIZE * 9)(a0)
|
|
||||||
ISTORE x10, (RISCV_ISIZE * 10)(a0)
|
|
||||||
ISTORE x11, (RISCV_ISIZE * 11)(a0)
|
|
||||||
ISTORE x12, (RISCV_ISIZE * 12)(a0)
|
|
||||||
ISTORE x13, (RISCV_ISIZE * 13)(a0)
|
|
||||||
ISTORE x14, (RISCV_ISIZE * 14)(a0)
|
|
||||||
ISTORE x15, (RISCV_ISIZE * 15)(a0)
|
|
||||||
ISTORE x16, (RISCV_ISIZE * 16)(a0)
|
|
||||||
ISTORE x17, (RISCV_ISIZE * 17)(a0)
|
|
||||||
ISTORE x18, (RISCV_ISIZE * 18)(a0)
|
|
||||||
ISTORE x19, (RISCV_ISIZE * 19)(a0)
|
|
||||||
ISTORE x20, (RISCV_ISIZE * 20)(a0)
|
|
||||||
ISTORE x21, (RISCV_ISIZE * 21)(a0)
|
|
||||||
ISTORE x22, (RISCV_ISIZE * 22)(a0)
|
|
||||||
ISTORE x23, (RISCV_ISIZE * 23)(a0)
|
|
||||||
ISTORE x24, (RISCV_ISIZE * 24)(a0)
|
|
||||||
ISTORE x25, (RISCV_ISIZE * 25)(a0)
|
|
||||||
ISTORE x26, (RISCV_ISIZE * 26)(a0)
|
|
||||||
ISTORE x27, (RISCV_ISIZE * 27)(a0)
|
|
||||||
ISTORE x28, (RISCV_ISIZE * 28)(a0)
|
|
||||||
ISTORE x29, (RISCV_ISIZE * 29)(a0)
|
|
||||||
ISTORE x30, (RISCV_ISIZE * 30)(a0)
|
|
||||||
ISTORE x31, (RISCV_ISIZE * 31)(a0)
|
|
||||||
|
|
||||||
# if defined(__riscv_flen)
|
# if defined(__riscv_flen)
|
||||||
FSTORE f0, (RISCV_FOFFSET + RISCV_FSIZE * 0)(a0)
|
.irp i,FROM_0_TO_31
|
||||||
FSTORE f1, (RISCV_FOFFSET + RISCV_FSIZE * 1)(a0)
|
FSTORE f\i, (RISCV_FOFFSET + RISCV_FSIZE * \i)(a0)
|
||||||
FSTORE f2, (RISCV_FOFFSET + RISCV_FSIZE * 2)(a0)
|
.endr
|
||||||
FSTORE f3, (RISCV_FOFFSET + RISCV_FSIZE * 3)(a0)
|
|
||||||
FSTORE f4, (RISCV_FOFFSET + RISCV_FSIZE * 4)(a0)
|
|
||||||
FSTORE f5, (RISCV_FOFFSET + RISCV_FSIZE * 5)(a0)
|
|
||||||
FSTORE f6, (RISCV_FOFFSET + RISCV_FSIZE * 6)(a0)
|
|
||||||
FSTORE f7, (RISCV_FOFFSET + RISCV_FSIZE * 7)(a0)
|
|
||||||
FSTORE f8, (RISCV_FOFFSET + RISCV_FSIZE * 8)(a0)
|
|
||||||
FSTORE f9, (RISCV_FOFFSET + RISCV_FSIZE * 9)(a0)
|
|
||||||
FSTORE f10, (RISCV_FOFFSET + RISCV_FSIZE * 10)(a0)
|
|
||||||
FSTORE f11, (RISCV_FOFFSET + RISCV_FSIZE * 11)(a0)
|
|
||||||
FSTORE f12, (RISCV_FOFFSET + RISCV_FSIZE * 12)(a0)
|
|
||||||
FSTORE f13, (RISCV_FOFFSET + RISCV_FSIZE * 13)(a0)
|
|
||||||
FSTORE f14, (RISCV_FOFFSET + RISCV_FSIZE * 14)(a0)
|
|
||||||
FSTORE f15, (RISCV_FOFFSET + RISCV_FSIZE * 15)(a0)
|
|
||||||
FSTORE f16, (RISCV_FOFFSET + RISCV_FSIZE * 16)(a0)
|
|
||||||
FSTORE f17, (RISCV_FOFFSET + RISCV_FSIZE * 17)(a0)
|
|
||||||
FSTORE f18, (RISCV_FOFFSET + RISCV_FSIZE * 18)(a0)
|
|
||||||
FSTORE f19, (RISCV_FOFFSET + RISCV_FSIZE * 19)(a0)
|
|
||||||
FSTORE f20, (RISCV_FOFFSET + RISCV_FSIZE * 20)(a0)
|
|
||||||
FSTORE f21, (RISCV_FOFFSET + RISCV_FSIZE * 21)(a0)
|
|
||||||
FSTORE f22, (RISCV_FOFFSET + RISCV_FSIZE * 22)(a0)
|
|
||||||
FSTORE f23, (RISCV_FOFFSET + RISCV_FSIZE * 23)(a0)
|
|
||||||
FSTORE f24, (RISCV_FOFFSET + RISCV_FSIZE * 24)(a0)
|
|
||||||
FSTORE f25, (RISCV_FOFFSET + RISCV_FSIZE * 25)(a0)
|
|
||||||
FSTORE f26, (RISCV_FOFFSET + RISCV_FSIZE * 26)(a0)
|
|
||||||
FSTORE f27, (RISCV_FOFFSET + RISCV_FSIZE * 27)(a0)
|
|
||||||
FSTORE f28, (RISCV_FOFFSET + RISCV_FSIZE * 28)(a0)
|
|
||||||
FSTORE f29, (RISCV_FOFFSET + RISCV_FSIZE * 29)(a0)
|
|
||||||
FSTORE f30, (RISCV_FOFFSET + RISCV_FSIZE * 30)(a0)
|
|
||||||
FSTORE f31, (RISCV_FOFFSET + RISCV_FSIZE * 31)(a0)
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
li a0, 0 // return UNW_ESUCCESS
|
li a0, 0 // return UNW_ESUCCESS
|
||||||
@ -1201,27 +1093,37 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
|
|||||||
stg %r14, 8(%r2)
|
stg %r14, 8(%r2)
|
||||||
|
|
||||||
// Save FPRs
|
// Save FPRs
|
||||||
std %f0, 144(%r2)
|
.irp i,FROM_0_TO_15
|
||||||
std %f1, 152(%r2)
|
std %f\i, (144+8*\i)(%r2)
|
||||||
std %f2, 160(%r2)
|
.endr
|
||||||
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
|
// Return UNW_ESUCCESS
|
||||||
lghi %r2, 0
|
lghi %r2, 0
|
||||||
br %r14
|
br %r14
|
||||||
|
|
||||||
|
#elif defined(__loongarch__) && __loongarch_grlen == 64
|
||||||
|
|
||||||
|
#
|
||||||
|
# extern int __unw_getcontext(unw_context_t* thread_state)
|
||||||
|
#
|
||||||
|
# On entry:
|
||||||
|
# thread_state pointer is in $a0($r4)
|
||||||
|
#
|
||||||
|
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
|
||||||
|
.irp i,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
|
||||||
|
st.d $r\i, $a0, (8*\i)
|
||||||
|
.endr
|
||||||
|
st.d $r1, $a0, (8 * 32) // store $ra to pc
|
||||||
|
|
||||||
|
# if __loongarch_frlen == 64
|
||||||
|
.irp i,FROM_0_TO_31
|
||||||
|
fst.d $f\i, $a0, (8 * 33 + 8 * \i)
|
||||||
|
.endr
|
||||||
|
# endif
|
||||||
|
|
||||||
|
move $a0, $zero // UNW_ESUCCESS
|
||||||
|
jr $ra
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WEAK_ALIAS(__unw_getcontext, unw_getcontext)
|
WEAK_ALIAS(__unw_getcontext, unw_getcontext)
|
||||||
|
2
lib/libunwind/src/Unwind_AIXExtras.cpp
vendored
2
lib/libunwind/src/Unwind_AIXExtras.cpp
vendored
@ -38,7 +38,7 @@ char *getFuncNameFromTBTable(uintptr_t Pc, uint16_t &NameLen,
|
|||||||
if (TBTable->tb.fixedparms || TBTable->tb.floatparms)
|
if (TBTable->tb.fixedparms || TBTable->tb.floatparms)
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
// If the tb_offset field exisits, get the offset from the start of
|
// If the tb_offset field exists, get the offset from the start of
|
||||||
// the function to pc. Skip the field.
|
// the function to pc. Skip the field.
|
||||||
if (TBTable->tb.has_tboff) {
|
if (TBTable->tb.has_tboff) {
|
||||||
unw_word_t StartIp =
|
unw_word_t StartIp =
|
||||||
|
2
lib/libunwind/src/config.h
vendored
2
lib/libunwind/src/config.h
vendored
@ -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(__s390x__)
|
defined(__sparc__) || defined(__s390x__) || defined(__loongarch__)
|
||||||
#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
|
||||||
|
13
lib/libunwind/src/libunwind.cpp
vendored
13
lib/libunwind/src/libunwind.cpp
vendored
@ -77,6 +77,8 @@ _LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor,
|
|||||||
# define REGISTER_KIND Registers_ve
|
# define REGISTER_KIND Registers_ve
|
||||||
#elif defined(__s390x__)
|
#elif defined(__s390x__)
|
||||||
# define REGISTER_KIND Registers_s390x
|
# define REGISTER_KIND Registers_s390x
|
||||||
|
#elif defined(__loongarch__) && __loongarch_grlen == 64
|
||||||
|
#define REGISTER_KIND Registers_loongarch
|
||||||
#else
|
#else
|
||||||
# error Architecture not supported
|
# error Architecture not supported
|
||||||
#endif
|
#endif
|
||||||
@ -117,7 +119,7 @@ _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
|
|||||||
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
|
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
|
||||||
if (co->validReg(regNum)) {
|
if (co->validReg(regNum)) {
|
||||||
co->setReg(regNum, (pint_t)value);
|
co->setReg(regNum, (pint_t)value);
|
||||||
// specical case altering IP to re-find info (being called by personality
|
// special case altering IP to re-find info (being called by personality
|
||||||
// function)
|
// function)
|
||||||
if (regNum == UNW_REG_IP) {
|
if (regNum == UNW_REG_IP) {
|
||||||
unw_proc_info_t info;
|
unw_proc_info_t info;
|
||||||
@ -181,6 +183,15 @@ _LIBUNWIND_HIDDEN int __unw_step(unw_cursor_t *cursor) {
|
|||||||
}
|
}
|
||||||
_LIBUNWIND_WEAK_ALIAS(__unw_step, unw_step)
|
_LIBUNWIND_WEAK_ALIAS(__unw_step, unw_step)
|
||||||
|
|
||||||
|
// Move cursor to next frame and for stage2 of unwinding.
|
||||||
|
// This resets MTE tags of tagged frames to zero.
|
||||||
|
extern "C" _LIBUNWIND_HIDDEN int __unw_step_stage2(unw_cursor_t *cursor) {
|
||||||
|
_LIBUNWIND_TRACE_API("__unw_step_stage2(cursor=%p)",
|
||||||
|
static_cast<void *>(cursor));
|
||||||
|
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
|
||||||
|
return co->step(true);
|
||||||
|
}
|
||||||
|
|
||||||
/// Get unwind info at cursor position in stack frame.
|
/// Get unwind info at cursor position in stack frame.
|
||||||
_LIBUNWIND_HIDDEN int __unw_get_proc_info(unw_cursor_t *cursor,
|
_LIBUNWIND_HIDDEN int __unw_get_proc_info(unw_cursor_t *cursor,
|
||||||
unw_proc_info_t *info) {
|
unw_proc_info_t *info) {
|
||||||
|
Loading…
Reference in New Issue
Block a user