diff --git a/src/coreclr/nativeaot/Runtime/unix/UnixNativeCodeManager.cpp b/src/coreclr/nativeaot/Runtime/unix/UnixNativeCodeManager.cpp index 1ef2f8205314df..d566b600ef9274 100644 --- a/src/coreclr/nativeaot/Runtime/unix/UnixNativeCodeManager.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/UnixNativeCodeManager.cpp @@ -56,6 +56,11 @@ struct UnixNativeMethodInfo // Ensure that UnixNativeMethodInfo fits into the space reserved by MethodInfo static_assert(sizeof(UnixNativeMethodInfo) <= sizeof(MethodInfo), "UnixNativeMethodInfo too big"); +struct UnwindSectionsLookupArgs +{ + typedef uintptr_t link_hardened_reg_arg_t; +}; + UnixNativeCodeManager::UnixNativeCodeManager(TADDR moduleBase, PTR_VOID pvManagedCodeStartRange, uint32_t cbManagedCodeRange, PTR_PTR_VOID pClasslibFunctions, uint32_t nClasslibFunctions) @@ -64,7 +69,7 @@ UnixNativeCodeManager::UnixNativeCodeManager(TADDR moduleBase, m_pClasslibFunctions(pClasslibFunctions), m_nClasslibFunctions(nClasslibFunctions) { // Cache the location of unwind sections - libunwind::LocalAddressSpace::sThisAddressSpace.findUnwindSections( + libunwind::LocalAddressSpace::sThisAddressSpace.findUnwindSections( (uintptr_t)pvManagedCodeStartRange, m_UnwindInfoSections); } diff --git a/src/coreclr/nativeaot/Runtime/unix/UnwindHelpers.cpp b/src/coreclr/nativeaot/Runtime/unix/UnwindHelpers.cpp index b1e51f8cad6782..8670e11dda09ed 100644 --- a/src/coreclr/nativeaot/Runtime/unix/UnwindHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/UnwindHelpers.cpp @@ -67,6 +67,10 @@ LocalAddressSpace _addressSpace; // Shim that implements methods required by libunwind over REGDISPLAY struct Registers_REGDISPLAY : REGDISPLAY { + typedef uint64_t reg_t; + typedef uint64_t link_reg_t; + typedef const link_reg_t &link_hardened_reg_arg_t; + static int getArch() { return libunwind::REGISTERS_X86_64; } inline uint64_t getRegister(int regNum) const @@ -116,7 +120,8 @@ struct Registers_REGDISPLAY : REGDISPLAY abort(); } - inline void setRegister(int regNum, uint64_t value, uint64_t location) + // Callee-saved registers are tracked by the location they were saved at, see setRegisterLocation + inline void setRegister(int regNum, uint64_t value) { switch (regNum) { @@ -125,8 +130,21 @@ struct Registers_REGDISPLAY : REGDISPLAY IP = value; return; case UNW_REG_SP: + case UNW_X86_64_RSP: SP = value; return; + } + } + + inline void setRegisterLocation(int regNum, uint64_t location) + { + switch (regNum) + { + case UNW_REG_IP: + case UNW_X86_64_RIP: + case UNW_REG_SP: + case UNW_X86_64_RSP: + return; case UNW_X86_64_RAX: pRax = (PTR_uintptr_t)location; return; @@ -148,9 +166,6 @@ struct Registers_REGDISPLAY : REGDISPLAY case UNW_X86_64_RBP: pRbp = (PTR_uintptr_t)location; return; - case UNW_X86_64_RSP: - SP = value; - return; case UNW_X86_64_R8: pR8 = (PTR_uintptr_t)location; return; @@ -207,30 +222,36 @@ struct Registers_REGDISPLAY : REGDISPLAY inline void setVectorRegister(int, ...) { abort(); } uint64_t getSP() const { return SP; } - void setSP(uint64_t value, uint64_t location) { SP = value; } + void setSP(uint64_t value) { SP = value; } uint64_t getIP() const { return IP; } - void setIP(uint64_t value, uint64_t location) { IP = value; } + void setIP(uint64_t value) { IP = value; } + // Called by the compact unwinder, which reports where each register was saved through + // setRegisterLocation right after. REGDISPLAY only tracks that location, so the value is unused. uint64_t getRBP() const { return *pRbp; } - void setRBP(uint64_t value, uint64_t location) { pRbp = (PTR_uintptr_t)location; } + void setRBP(uint64_t) { } uint64_t getRBX() const { return *pRbx; } - void setRBX(uint64_t value, uint64_t location) { pRbx = (PTR_uintptr_t)location; } + void setRBX(uint64_t) { } uint64_t getR12() const { return *pR12; } - void setR12(uint64_t value, uint64_t location) { pR12 = (PTR_uintptr_t)location; } + void setR12(uint64_t) { } uint64_t getR13() const { return *pR13; } - void setR13(uint64_t value, uint64_t location) { pR13 = (PTR_uintptr_t)location; } + void setR13(uint64_t) { } uint64_t getR14() const { return *pR14; } - void setR14(uint64_t value, uint64_t location) { pR14 = (PTR_uintptr_t)location; } + void setR14(uint64_t) { } uint64_t getR15() const { return *pR15; } - void setR15(uint64_t value, uint64_t location) { pR15 = (PTR_uintptr_t)location; } + void setR15(uint64_t) { } }; #endif // TARGET_AMD64 #if defined(TARGET_X86) struct Registers_REGDISPLAY : REGDISPLAY { + typedef uint32_t reg_t; + typedef uint32_t link_reg_t; + typedef const link_reg_t &link_hardened_reg_arg_t; + static int getArch() { return libunwind::REGISTERS_X86; } inline uint64_t getRegister(int regNum) const @@ -263,7 +284,8 @@ struct Registers_REGDISPLAY : REGDISPLAY abort(); } - inline void setRegister(int regNum, uint64_t value, uint64_t location) + // Callee-saved registers are tracked by the location they were saved at, see setRegisterLocation + inline void setRegister(int regNum, uint64_t value) { switch (regNum) { @@ -271,8 +293,20 @@ struct Registers_REGDISPLAY : REGDISPLAY IP = value; return; case UNW_REG_SP: + case UNW_X86_ESP: SP = value; return; + } + } + + inline void setRegisterLocation(int regNum, uint64_t location) + { + switch (regNum) + { + case UNW_REG_IP: + case UNW_REG_SP: + case UNW_X86_ESP: + return; case UNW_X86_EAX: pRax = (PTR_uintptr_t)location; return; @@ -294,9 +328,6 @@ struct Registers_REGDISPLAY : REGDISPLAY case UNW_X86_EBP: pRbp = (PTR_uintptr_t)location; return; - case UNW_X86_ESP: - SP = value; - return; } // Unsupported x86_64 register @@ -328,16 +359,14 @@ struct Registers_REGDISPLAY : REGDISPLAY inline double getVectorRegister(int) const { abort(); } inline void setVectorRegister(int, ...) { abort(); } - void setSP(uint64_t value, uint64_t location) { SP = value; } + void setSP(uint64_t value) { SP = value; } uint64_t getIP() const { return IP; } - void setIP(uint64_t value, uint64_t location) { IP = value; } + void setIP(uint64_t value) { IP = value; } uint64_t getEBP() const { return *pRbp; } - void setEBP(uint64_t value, uint64_t location) { pRbp = (PTR_uintptr_t)location; } uint64_t getEBX() const { return *pRbx; } - void setEBX(uint64_t value, uint64_t location) { pRbx = (PTR_uintptr_t)location; } }; #endif // TARGET_X86 @@ -345,6 +374,10 @@ struct Registers_REGDISPLAY : REGDISPLAY struct Registers_REGDISPLAY : REGDISPLAY { + typedef uint32_t reg_t; + typedef uint32_t link_reg_t; + typedef const link_reg_t &link_hardened_reg_arg_t; + inline static int getArch() { return libunwind::REGISTERS_ARM; } static constexpr int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM; } @@ -353,7 +386,8 @@ struct Registers_REGDISPLAY : REGDISPLAY bool validVectorRegister(int num) const { return false; } uint32_t getRegister(int num) const; - void setRegister(int num, uint32_t value, uint32_t location); + void setRegister(int num, uint32_t value); + void setRegisterLocation(int num, uint32_t location); unw_fpreg_t getFloatRegister(int num) const; void setFloatRegister(int num, unw_fpreg_t value); @@ -362,11 +396,10 @@ struct Registers_REGDISPLAY : REGDISPLAY void setVectorRegister(int num, libunwind::v128 value) { abort(); } uint32_t getSP() const { return SP; } - void setSP(uint32_t value, uint32_t location) { SP = value; } + void setSP(uint32_t value) { SP = value; } uint32_t getIP() const { return IP; } - void setIP(uint32_t value, uint32_t location) { IP = value; } + void setIP(uint32_t value) { IP = value; } uint32_t getFP() const { return *pR11; } - void setFP(uint32_t value, uint32_t location) { pR11 = (PTR_uintptr_t)location; } }; struct ArmUnwindCursor : public libunwind::AbstractUnwindCursor @@ -376,8 +409,8 @@ struct ArmUnwindCursor : public libunwind::AbstractUnwindCursor ArmUnwindCursor(Registers_REGDISPLAY *registers) : _registers(registers) {} virtual bool validReg(int num) { return _registers->validRegister(num); } virtual unw_word_t getReg(int num) { return _registers->getRegister(num); } - virtual void setReg(int num, unw_word_t value, unw_word_t location) { _registers->setRegister(num, value, location); } - virtual unw_word_t getRegLocation(int num) { abort(); } + virtual void setReg(int num, unw_word_t value) { _registers->setRegister(num, value); } + virtual void setRegLocation(int num, unw_word_t location) { _registers->setRegisterLocation(num, location); } virtual bool validFloatReg(int num) { return _registers->validFloatRegister(num); } virtual unw_fpreg_t getFloatReg(int num) { return _registers->getFloatRegister(num); } virtual void setFloatReg(int num, unw_fpreg_t value) { _registers->setFloatRegister(num, value); } @@ -454,20 +487,27 @@ inline uint32_t Registers_REGDISPLAY::getRegister(int regNum) const { PORTABILITY_ASSERT("unsupported arm register"); } -void Registers_REGDISPLAY::setRegister(int num, uint32_t value, uint32_t location) +// Callee-saved registers are tracked by the location they were saved at, see setRegisterLocation +void Registers_REGDISPLAY::setRegister(int num, uint32_t value) { if (num == UNW_REG_SP || num == UNW_ARM_SP) { SP = (uintptr_t )value; return; } - if (num == UNW_ARM_LR) { - pLR = (PTR_uintptr_t)location; + if (num == UNW_REG_IP || num == UNW_ARM_IP) { + IP = value; return; } +} - if (num == UNW_REG_IP || num == UNW_ARM_IP) { - IP = value; +void Registers_REGDISPLAY::setRegisterLocation(int num, uint32_t location) +{ + if (num == UNW_REG_SP || num == UNW_ARM_SP || num == UNW_REG_IP || num == UNW_ARM_IP) + return; + + if (num == UNW_ARM_LR) { + pLR = (PTR_uintptr_t)location; return; } @@ -537,6 +577,8 @@ void Registers_REGDISPLAY::setFloatRegister(int num, unw_fpreg_t value) struct Registers_REGDISPLAY : REGDISPLAY { typedef uint64_t reg_t; + typedef uint64_t link_reg_t; + typedef const link_reg_t &link_hardened_reg_arg_t; inline static int getArch() { return libunwind::REGISTERS_ARM64; } static constexpr int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; } @@ -546,7 +588,8 @@ struct Registers_REGDISPLAY : REGDISPLAY bool validVectorRegister(int num) const { return false; } uint64_t getRegister(int num) const; - void setRegister(int num, uint64_t value, uint64_t location); + void setRegister(int num, uint64_t value); + void setRegisterLocation(int num, uint64_t location); double getFloatRegister(int num) const; void setFloatRegister(int num, double value); @@ -555,11 +598,13 @@ struct Registers_REGDISPLAY : REGDISPLAY void setVectorRegister(int num, libunwind::v128 value) { abort(); } uint64_t getSP() const { return SP; } - void setSP(uint64_t value, uint64_t location) { SP = value; } + void setSP(uint64_t value) { SP = value; } uint64_t getIP() const { return IP; } - void setIP(uint64_t value, uint64_t location) { IP = value; } + void setIP(uint64_t value) { IP = value; } uint64_t getFP() const { return *pFP; } - void setFP(uint64_t value, uint64_t location) { pFP = (PTR_uintptr_t)location; } + // Called by the compact unwinder, which reports where FP was saved through setRegisterLocation + // right after. REGDISPLAY only tracks that location, so the value is unused. + void setFP(uint64_t) { } }; inline bool Registers_REGDISPLAY::validRegister(int num) const { @@ -664,13 +709,25 @@ inline uint64_t Registers_REGDISPLAY::getRegister(int regNum) const { PORTABILITY_ASSERT("unsupported arm64 register"); } -void Registers_REGDISPLAY::setRegister(int num, uint64_t value, uint64_t location) +// Callee-saved registers are tracked by the location they were saved at, see setRegisterLocation +void Registers_REGDISPLAY::setRegister(int num, uint64_t value) { if (num == UNW_REG_SP || num == UNW_ARM64_SP) { SP = (uintptr_t )value; return; } + if (num == UNW_REG_IP) { + IP = value; + return; + } +} + +void Registers_REGDISPLAY::setRegisterLocation(int num, uint64_t location) +{ + if (num == UNW_REG_SP || num == UNW_ARM64_SP || num == UNW_REG_IP) + return; + if (num == UNW_ARM64_FP) { pFP = (PTR_uintptr_t)location; return; @@ -681,11 +738,6 @@ void Registers_REGDISPLAY::setRegister(int num, uint64_t value, uint64_t locatio return; } - if (num == UNW_REG_IP) { - IP = value; - return; - } - switch (num) { case (UNW_ARM64_X0): @@ -799,6 +851,10 @@ void Registers_REGDISPLAY::setFloatRegister(int num, double value) // Shim that implements methods required by libunwind over REGDISPLAY struct Registers_REGDISPLAY : REGDISPLAY { + typedef uint64_t reg_t; + typedef uint64_t link_reg_t; + typedef const link_reg_t &link_hardened_reg_arg_t; + inline static int getArch() { return libunwind::REGISTERS_LOONGARCH; } static constexpr int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH; } @@ -807,7 +863,8 @@ struct Registers_REGDISPLAY : REGDISPLAY bool validVectorRegister(int num) const { return false; } uint64_t getRegister(int num) const; - void setRegister(int num, uint64_t value, uint64_t location); + void setRegister(int num, uint64_t value); + void setRegisterLocation(int num, uint64_t location); double getFloatRegister(int num) const; void setFloatRegister(int num, double value); @@ -816,11 +873,10 @@ struct Registers_REGDISPLAY : REGDISPLAY void setVectorRegister(int num, libunwind::v128 value) { abort(); } uint64_t getSP() const { return SP; } - void setSP(uint64_t value, uint64_t location) { SP = value; } + void setSP(uint64_t value) { SP = value; } uint64_t getIP() const { return IP; } - void setIP(uint64_t value, uint64_t location) { IP = value; } + void setIP(uint64_t value) { IP = value; } uint64_t getFP() const { return *pFP; } - void setFP(uint64_t value, uint64_t location) { pFP = (PTR_uintptr_t)location; } }; inline bool Registers_REGDISPLAY::validRegister(int num) const { @@ -925,13 +981,25 @@ inline uint64_t Registers_REGDISPLAY::getRegister(int regNum) const { PORTABILITY_ASSERT("unsupported loongarch64 register"); } -void Registers_REGDISPLAY::setRegister(int num, uint64_t value, uint64_t location) +// Callee-saved registers are tracked by the location they were saved at, see setRegisterLocation +void Registers_REGDISPLAY::setRegister(int num, uint64_t value) { if (num == UNW_REG_SP || num == UNW_LOONGARCH_R3) { SP = (uintptr_t )value; return; } + if (num == UNW_REG_IP) { + IP = value; + return; + } +} + +void Registers_REGDISPLAY::setRegisterLocation(int num, uint64_t location) +{ + if (num == UNW_REG_SP || num == UNW_LOONGARCH_R3 || num == UNW_REG_IP) + return; + if (num == UNW_LOONGARCH_R22) { pFP = (PTR_uintptr_t)location; return; @@ -942,11 +1010,6 @@ void Registers_REGDISPLAY::setRegister(int num, uint64_t value, uint64_t locatio return; } - if (num == UNW_REG_IP) { - IP = value; - return; - } - switch (num) { case (UNW_LOONGARCH_R0): @@ -1060,6 +1123,10 @@ void Registers_REGDISPLAY::setFloatRegister(int num, double value) // Shim that implements methods required by libunwind over REGDISPLAY struct Registers_REGDISPLAY : REGDISPLAY { + typedef uint64_t reg_t; + typedef uint64_t link_reg_t; + typedef const link_reg_t &link_hardened_reg_arg_t; + inline static int getArch() { return libunwind::REGISTERS_RISCV; } static constexpr int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV; } @@ -1068,7 +1135,8 @@ struct Registers_REGDISPLAY : REGDISPLAY bool validVectorRegister(int num) const { return false; } uint64_t getRegister(int num) const; - void setRegister(int num, uint64_t value, uint64_t location); + void setRegister(int num, uint64_t value); + void setRegisterLocation(int num, uint64_t location); double getFloatRegister(int num) const; void setFloatRegister(int num, double value); @@ -1077,11 +1145,10 @@ struct Registers_REGDISPLAY : REGDISPLAY void setVectorRegister(int num, libunwind::v128 value) { abort(); } uint64_t getSP() const { return SP; } - void setSP(uint64_t value, uint64_t location) { SP = value; } + void setSP(uint64_t value) { SP = value; } uint64_t getIP() const { return IP; } - void setIP(uint64_t value, uint64_t location) { IP = value; } + void setIP(uint64_t value) { IP = value; } uint64_t getFP() const { return *pFP; } - void setFP(uint64_t value, uint64_t location) { pFP = (PTR_uintptr_t)location; } }; inline bool Registers_REGDISPLAY::validRegister(int num) const { @@ -1158,19 +1225,30 @@ inline uint64_t Registers_REGDISPLAY::getRegister(int regNum) const { } } -void Registers_REGDISPLAY::setRegister(int regNum, uint64_t value, uint64_t location) +// Callee-saved registers are tracked by the location they were saved at, see setRegisterLocation +void Registers_REGDISPLAY::setRegister(int regNum, uint64_t value) { switch (regNum) { case UNW_REG_IP: IP = (uintptr_t)value; break; - case UNW_RISCV_X1: - pRA = (PTR_uintptr_t)location; - break; case UNW_REG_SP: case UNW_RISCV_X2: SP = (uintptr_t)value; break; + } +} + +void Registers_REGDISPLAY::setRegisterLocation(int regNum, uint64_t location) +{ + switch (regNum) { + case UNW_REG_IP: + case UNW_REG_SP: + case UNW_RISCV_X2: + break; + case UNW_RISCV_X1: + pRA = (PTR_uintptr_t)location; + break; case UNW_RISCV_X3: pGP = (PTR_uintptr_t)location; break; @@ -1294,7 +1372,9 @@ bool UnwindHelpers::StepFrame(REGDISPLAY *regs, unw_word_t start_ip, uint32_t fo #endif - uintptr_t pc = regs->GetIP(); + // libunwind applies only the CFI rows before pc; pass pc + 1 so the row at pc applies too, + // which unwinding from an interrupted instruction requires. + uintptr_t pc = regs->GetIP() + 1; bool isSignalFrame = false; DwarfInstructions dwarfInst; @@ -1324,17 +1404,17 @@ bool UnwindHelpers::StepFrame(REGDISPLAY *regs, unw_word_t start_ip, uint32_t fo bool UnwindHelpers::GetUnwindProcInfo(PCODE pc, UnwindInfoSections &uwInfoSections, unw_proc_info_t *procInfo) { #if defined(TARGET_AMD64) - libunwind::UnwindCursor uc(_addressSpace); + libunwind::UnwindCursor uc(_addressSpace, nullptr); #elif defined(TARGET_ARM) - libunwind::UnwindCursor uc(_addressSpace); + libunwind::UnwindCursor uc(_addressSpace, nullptr); #elif defined(TARGET_ARM64) - libunwind::UnwindCursor uc(_addressSpace); + libunwind::UnwindCursor uc(_addressSpace, nullptr); #elif defined(HOST_X86) - libunwind::UnwindCursor uc(_addressSpace); + libunwind::UnwindCursor uc(_addressSpace, nullptr); #elif defined(HOST_LOONGARCH64) - libunwind::UnwindCursor uc(_addressSpace); + libunwind::UnwindCursor uc(_addressSpace, nullptr); #elif defined(HOST_RISCV64) - libunwind::UnwindCursor uc(_addressSpace); + libunwind::UnwindCursor uc(_addressSpace, nullptr); #else #error "Unwinding is not implemented for this architecture yet." #endif diff --git a/src/native/external/llvm-libunwind-version.txt b/src/native/external/llvm-libunwind-version.txt index 060e788248fa0b..1f2620f7dcd856 100644 --- a/src/native/external/llvm-libunwind-version.txt +++ b/src/native/external/llvm-libunwind-version.txt @@ -1,6 +1,4 @@ v22.1.1 https://github.com/llvm/llvm-project/releases/tag/llvmorg-22.1.1 -Apply https://github.com/dotnet/runtime/commit/35b7d59fa1075ab0fefb921393409806a821d8ed -Apply https://github.com/dotnet/runtime/commit/be5f98fb6702704afbaf705dce0b54d55479c6f1 -Apply https://github.com/llvm/llvm-project/commit/588451c160c34b888ced1c3d9263d361df22f757 +Apply https://github.com/dotnet/runtime/commit/f32dd3cca659e5f34def913f36a23da3ac984de6 diff --git a/src/native/external/llvm-libunwind/include/__libunwind_config.h b/src/native/external/llvm-libunwind/include/__libunwind_config.h index 1210771f4182ab..980d11ef5d4f23 100644 --- a/src/native/external/llvm-libunwind/include/__libunwind_config.h +++ b/src/native/external/llvm-libunwind/include/__libunwind_config.h @@ -41,8 +41,8 @@ # endif # if defined(__i386__) # define _LIBUNWIND_TARGET_I386 -# define _LIBUNWIND_CONTEXT_SIZE 13 -# define _LIBUNWIND_CURSOR_SIZE 19 +# define _LIBUNWIND_CONTEXT_SIZE 8 +# define _LIBUNWIND_CURSOR_SIZE 15 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86 # elif defined(__x86_64__) # define _LIBUNWIND_TARGET_X86_64 1 @@ -57,8 +57,8 @@ # define _LIBUNWIND_CONTEXT_SIZE 21 # define _LIBUNWIND_CURSOR_SIZE 28 # else -# define _LIBUNWIND_CONTEXT_SIZE 38 -# define _LIBUNWIND_CURSOR_SIZE 50 +# define _LIBUNWIND_CONTEXT_SIZE 21 +# define _LIBUNWIND_CURSOR_SIZE 33 # endif # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64 # elif defined(__powerpc64__) @@ -73,11 +73,11 @@ # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC # elif defined(__aarch64__) # define _LIBUNWIND_TARGET_AARCH64 1 -# define _LIBUNWIND_CONTEXT_SIZE 100 +#define _LIBUNWIND_CONTEXT_SIZE 67 # if defined(__SEH__) -# define _LIBUNWIND_CURSOR_SIZE 198 +# define _LIBUNWIND_CURSOR_SIZE 164 # else -# define _LIBUNWIND_CURSOR_SIZE 112 +#define _LIBUNWIND_CURSOR_SIZE 79 # endif # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64 # elif defined(__arm__) @@ -89,8 +89,8 @@ # define _LIBUNWIND_CONTEXT_SIZE 61 # define _LIBUNWIND_CURSOR_SIZE 68 # else -# define _LIBUNWIND_CONTEXT_SIZE 50 -# define _LIBUNWIND_CURSOR_SIZE 57 +# define _LIBUNWIND_CONTEXT_SIZE 42 +# define _LIBUNWIND_CURSOR_SIZE 49 # endif # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM # elif defined(__or1k__) @@ -154,7 +154,7 @@ # else # define RISCV_FLEN 0 # endif -# define _LIBUNWIND_CONTEXT_SIZE (32 * (__riscv_xlen + RISCV_FLEN) / 64) + 32 +# define _LIBUNWIND_CONTEXT_SIZE (32 * (__riscv_xlen + RISCV_FLEN) / 64) # if __riscv_xlen == 32 # define _LIBUNWIND_CURSOR_SIZE (_LIBUNWIND_CONTEXT_SIZE + 7) # elif __riscv_xlen == 64 @@ -176,13 +176,8 @@ #elif defined(__loongarch__) #define _LIBUNWIND_TARGET_LOONGARCH 1 #if __loongarch_grlen == 64 -#define _LIBUNWIND_CONTEXT_SIZE 98 -#define _LIBUNWIND_CURSOR_SIZE 110 -#elif defined(HOST_WASM) -#define _LIBUNWIND_TARGET_WASM 1 -// TODO: Determine the right values -#define _LIBUNWIND_CONTEXT_SIZE 0xbadf00d -#define _LIBUNWIND_CURSOR_SIZE 0xbadf00d +#define _LIBUNWIND_CONTEXT_SIZE 65 +#define _LIBUNWIND_CURSOR_SIZE 77 #else #error "Unsupported LoongArch ABI" #endif diff --git a/src/native/external/llvm-libunwind/include/libunwind.h b/src/native/external/llvm-libunwind/include/libunwind.h index 6084196e04bea0..56ca7110274a30 100644 --- a/src/native/external/llvm-libunwind/include/libunwind.h +++ b/src/native/external/llvm-libunwind/include/libunwind.h @@ -206,26 +206,6 @@ struct unw_proc_info_t { }; typedef struct unw_proc_info_t unw_proc_info_t; -enum unw_save_loc_type_t -{ - UNW_SLT_NONE, /* register is not saved ("not an l-value") */ - UNW_SLT_MEMORY, /* register has been saved in memory */ - UNW_SLT_REG /* register has been saved in (another) register */ -}; -typedef enum unw_save_loc_type_t unw_save_loc_type_t; - -struct unw_save_loc_t -{ - unw_save_loc_type_t type; - union - { - unw_word_t addr; /* valid if type==UNW_SLT_MEMORY */ - unw_regnum_t regnum; /* valid if type==UNW_SLT_REG */ - } - u; -}; -typedef struct unw_save_loc_t unw_save_loc_t; - #ifdef __cplusplus extern "C" { #endif @@ -235,7 +215,7 @@ extern int unw_init_local(unw_cursor_t *, unw_context_t *) LIBUNWIND_AVAIL; extern int unw_step(unw_cursor_t *) LIBUNWIND_AVAIL; extern int unw_get_reg(unw_cursor_t *, unw_regnum_t, unw_word_t *) LIBUNWIND_AVAIL; extern int unw_get_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t *) LIBUNWIND_AVAIL; -extern int unw_set_reg(unw_cursor_t *, unw_regnum_t, unw_word_t, unw_word_t *) LIBUNWIND_AVAIL; +extern int unw_set_reg(unw_cursor_t *, unw_regnum_t, unw_word_t) LIBUNWIND_AVAIL; extern int unw_set_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t) LIBUNWIND_AVAIL; extern int unw_resume(unw_cursor_t *) LIBUNWIND_AVAIL; @@ -253,7 +233,7 @@ extern int unw_get_proc_info(unw_cursor_t *, unw_proc_info_t *) LIBUNWIND_AVAIL; extern int unw_is_fpreg(unw_cursor_t *, unw_regnum_t) LIBUNWIND_AVAIL; extern int unw_is_signal_frame(unw_cursor_t *) LIBUNWIND_AVAIL; extern int unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *) LIBUNWIND_AVAIL; -extern int unw_get_save_loc(unw_cursor_t*, int, unw_save_loc_t*) LIBUNWIND_AVAIL; +//extern int unw_get_save_loc(unw_cursor_t*, int, unw_save_loc_t*); extern const char *unw_strerror(int) LIBUNWIND_AVAIL; extern unw_addr_space_t unw_local_addr_space; diff --git a/src/native/external/llvm-libunwind/include/unwind_arm_ehabi.h b/src/native/external/llvm-libunwind/include/unwind_arm_ehabi.h index fa38def6ade841..68e02e47602d60 100644 --- a/src/native/external/llvm-libunwind/include/unwind_arm_ehabi.h +++ b/src/native/external/llvm-libunwind/include/unwind_arm_ehabi.h @@ -118,7 +118,7 @@ _Unwind_VRS_Get(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, extern _Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, uint32_t regno, _Unwind_VRS_DataRepresentation representation, - void *valuep, uintptr_t *pos); + void *valuep); extern _Unwind_VRS_Result _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, @@ -150,8 +150,8 @@ uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index) { _LIBUNWIND_EXPORT_UNWIND_LEVEL1 void _Unwind_SetGR(struct _Unwind_Context *context, int index, - uintptr_t value, uintptr_t *pos) { - _Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value, pos); + uintptr_t value) { + _Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value); } _LIBUNWIND_EXPORT_UNWIND_LEVEL1 @@ -163,7 +163,7 @@ uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { _LIBUNWIND_EXPORT_UNWIND_LEVEL1 void _Unwind_SetIP(struct _Unwind_Context *context, uintptr_t value) { uintptr_t thumb_bit = _Unwind_GetGR(context, 15) & ((uintptr_t)0x1); - _Unwind_SetGR(context, 15, value | thumb_bit, NULL); + _Unwind_SetGR(context, 15, value | thumb_bit); } #ifdef __cplusplus diff --git a/src/native/external/llvm-libunwind/include/unwind_itanium.h b/src/native/external/llvm-libunwind/include/unwind_itanium.h index 7e813c7c2b07a0..d94a6183be2901 100644 --- a/src/native/external/llvm-libunwind/include/unwind_itanium.h +++ b/src/native/external/llvm-libunwind/include/unwind_itanium.h @@ -65,7 +65,7 @@ extern void _Unwind_DeleteException(_Unwind_Exception *exception_object); extern uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index); extern void _Unwind_SetGR(struct _Unwind_Context *context, int index, - uintptr_t new_value, uintptr_t *pos); + uintptr_t new_value); extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *context); extern void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t new_value); diff --git a/src/native/external/llvm-libunwind/src/AddressSpace.hpp b/src/native/external/llvm-libunwind/src/AddressSpace.hpp index 435232dff8f423..5044576899e723 100644 --- a/src/native/external/llvm-libunwind/src/AddressSpace.hpp +++ b/src/native/external/llvm-libunwind/src/AddressSpace.hpp @@ -22,7 +22,6 @@ #include "dwarf2.h" #include "EHHeaderParser.hpp" #include "Registers.hpp" -#include "libunwind_ext.h" #ifndef _LIBUNWIND_USE_DLADDR #if !(defined(_LIBUNWIND_IS_BAREMETAL) || defined(_WIN32) || defined(_AIX)) @@ -48,20 +47,11 @@ struct EHABIIndexEntry { #if defined(_AIX) namespace libunwind { - char *getFuncNameFromTBTable(uintptr_t pc, uint16_t &NameLen, unw_word_t *offset); } #endif -namespace libunwind { - -struct LocalAddressSpaceDefaultArgType { - typedef uintptr_t link_hardened_reg_arg_t; -}; - -} - #ifdef __APPLE__ struct dyld_unwind_sections @@ -212,10 +202,6 @@ class _LIBUNWIND_HIDDEN LocalAddressSpace { pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding, pint_t datarelBase = 0, pint_t *resultAddr = nullptr); - bool findFunctionName(pint_t addr, char *buf, size_t bufLen, - unw_word_t *offset); - bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info); - bool findOtherFDE(pint_t targetAddr, pint_t &fde); template bool findFunctionName(typename R::link_hardened_reg_arg_t addr, char *buf, size_t bufLen, unw_word_t *offset); @@ -684,21 +670,6 @@ inline bool LocalAddressSpace::findUnwindSections( return false; } -inline bool LocalAddressSpace::findUnwindSections( - pint_t targetAddr, UnwindInfoSections &info) { - return findUnwindSections(targetAddr, info); -} - -inline bool LocalAddressSpace::findFunctionName( - pint_t addr, char *buf, size_t bufLen, unw_word_t *offset) { - return findFunctionName(addr, buf, bufLen, - offset); -} - -inline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) { - return findOtherFDE(targetAddr, fde); -} - template inline bool LocalAddressSpace::findOtherFDE(typename R::link_hardened_reg_arg_t targetAddr, diff --git a/src/native/external/llvm-libunwind/src/CompactUnwinder.hpp b/src/native/external/llvm-libunwind/src/CompactUnwinder.hpp index 389bd37dcafc21..f6810af3e9f8d0 100644 --- a/src/native/external/llvm-libunwind/src/CompactUnwinder.hpp +++ b/src/native/external/llvm-libunwind/src/CompactUnwinder.hpp @@ -26,37 +26,49 @@ namespace libunwind { +// Reports where a register was restored from to register sets that track +// save locations (by implementing setRegisterLocation); no-op otherwise. +template +inline auto setSavedRegisterLocation(R ®isters, int regNum, + uint64_t location, int) + -> decltype(registers.setRegisterLocation(regNum, location), void()) { + registers.setRegisterLocation(regNum, location); +} + +template +inline void setSavedRegisterLocation(R &, int, uint64_t, long) {} + #if defined(_LIBUNWIND_TARGET_I386) /// CompactUnwinder_x86 uses a compact unwind info to virtually "step" (aka /// unwind) by modifying a Registers_x86 register set -template +template class CompactUnwinder_x86 { public: static int stepWithCompactEncoding(compact_unwind_encoding_t info, uint32_t functionStart, A &addressSpace, - R ®isters); + Registers_x86 ®isters); private: typename A::pint_t pint_t; - static void frameUnwind(A &addressSpace, R ®isters); + static void frameUnwind(A &addressSpace, Registers_x86 ®isters); static void framelessUnwind(A &addressSpace, typename A::pint_t returnAddressLocation, - R ®isters); + Registers_x86 ®isters); static int stepWithCompactEncodingEBPFrame(compact_unwind_encoding_t compactEncoding, uint32_t functionStart, A &addressSpace, - R ®isters); + Registers_x86 ®isters); static int stepWithCompactEncodingFrameless( compact_unwind_encoding_t compactEncoding, uint32_t functionStart, - A &addressSpace, R ®isters, bool indirectStackSize); + A &addressSpace, Registers_x86 ®isters, bool indirectStackSize); }; -template -int CompactUnwinder_x86::stepWithCompactEncoding( +template +int CompactUnwinder_x86::stepWithCompactEncoding( compact_unwind_encoding_t compactEncoding, uint32_t functionStart, - A &addressSpace, R ®isters) { + A &addressSpace, Registers_x86 ®isters) { switch (compactEncoding & UNWIND_X86_MODE_MASK) { case UNWIND_X86_MODE_EBP_FRAME: return stepWithCompactEncodingEBPFrame(compactEncoding, functionStart, @@ -71,10 +83,10 @@ int CompactUnwinder_x86::stepWithCompactEncoding( _LIBUNWIND_ABORT("invalid compact unwind encoding"); } -template -int CompactUnwinder_x86::stepWithCompactEncodingEBPFrame( +template +int CompactUnwinder_x86::stepWithCompactEncodingEBPFrame( compact_unwind_encoding_t compactEncoding, uint32_t functionStart, - A &addressSpace, R ®isters) { + A &addressSpace, Registers_x86 ®isters) { uint32_t savedRegistersOffset = EXTRACT_BITS(compactEncoding, UNWIND_X86_EBP_FRAME_OFFSET); uint32_t savedRegistersLocations = @@ -87,19 +99,19 @@ int CompactUnwinder_x86::stepWithCompactEncodingEBPFrame( // no register saved in this slot break; case UNWIND_X86_REG_EBX: - registers.setEBX(addressSpace.get32(savedRegisters), savedRegisters); + registers.setEBX(addressSpace.get32(savedRegisters)); break; case UNWIND_X86_REG_ECX: - registers.setECX(addressSpace.get32(savedRegisters), savedRegisters); + registers.setECX(addressSpace.get32(savedRegisters)); break; case UNWIND_X86_REG_EDX: - registers.setEDX(addressSpace.get32(savedRegisters), savedRegisters); + registers.setEDX(addressSpace.get32(savedRegisters)); break; case UNWIND_X86_REG_EDI: - registers.setEDI(addressSpace.get32(savedRegisters), savedRegisters); + registers.setEDI(addressSpace.get32(savedRegisters)); break; case UNWIND_X86_REG_ESI: - registers.setESI(addressSpace.get32(savedRegisters), savedRegisters); + registers.setESI(addressSpace.get32(savedRegisters)); break; default: (void)functionStart; @@ -115,10 +127,10 @@ int CompactUnwinder_x86::stepWithCompactEncodingEBPFrame( return UNW_STEP_SUCCESS; } -template -int CompactUnwinder_x86::stepWithCompactEncodingFrameless( +template +int CompactUnwinder_x86::stepWithCompactEncodingFrameless( compact_unwind_encoding_t encoding, uint32_t functionStart, - A &addressSpace, R ®isters, bool indirectStackSize) { + A &addressSpace, Registers_x86 ®isters, bool indirectStackSize) { uint32_t stackSizeEncoded = EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_SIZE); uint32_t stackAdjust = @@ -204,22 +216,22 @@ int CompactUnwinder_x86::stepWithCompactEncodingFrameless( for (uint32_t i = 0; i < regCount; ++i) { switch (registersSaved[i]) { case UNWIND_X86_REG_EBX: - registers.setEBX(addressSpace.get32(savedRegisters), savedRegisters); + registers.setEBX(addressSpace.get32(savedRegisters)); break; case UNWIND_X86_REG_ECX: - registers.setECX(addressSpace.get32(savedRegisters), savedRegisters); + registers.setECX(addressSpace.get32(savedRegisters)); break; case UNWIND_X86_REG_EDX: - registers.setEDX(addressSpace.get32(savedRegisters), savedRegisters); + registers.setEDX(addressSpace.get32(savedRegisters)); break; case UNWIND_X86_REG_EDI: - registers.setEDI(addressSpace.get32(savedRegisters), savedRegisters); + registers.setEDI(addressSpace.get32(savedRegisters)); break; case UNWIND_X86_REG_ESI: - registers.setESI(addressSpace.get32(savedRegisters), savedRegisters); + registers.setESI(addressSpace.get32(savedRegisters)); break; case UNWIND_X86_REG_EBP: - registers.setEBP(addressSpace.get32(savedRegisters), savedRegisters); + registers.setEBP(addressSpace.get32(savedRegisters)); break; default: _LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for " @@ -234,26 +246,26 @@ int CompactUnwinder_x86::stepWithCompactEncodingFrameless( } -template -void CompactUnwinder_x86::frameUnwind(A &addressSpace, - R ®isters) { +template +void CompactUnwinder_x86::frameUnwind(A &addressSpace, + Registers_x86 ®isters) { typename A::pint_t bp = registers.getEBP(); // ebp points to old ebp - registers.setEBP(addressSpace.get32(bp), bp); + registers.setEBP(addressSpace.get32(bp)); // old esp is ebp less saved ebp and return address - registers.setSP((uint32_t)bp + 8, 0); + registers.setSP((uint32_t)bp + 8); // pop return address into eip - registers.setIP(addressSpace.get32(bp + 4), bp + 4); + registers.setIP(addressSpace.get32(bp + 4)); } -template -void CompactUnwinder_x86::framelessUnwind( +template +void CompactUnwinder_x86::framelessUnwind( A &addressSpace, typename A::pint_t returnAddressLocation, - R ®isters) { + Registers_x86 ®isters) { // return address is on stack after last saved register - registers.setIP(addressSpace.get32(returnAddressLocation), returnAddressLocation); + registers.setIP(addressSpace.get32(returnAddressLocation)); // old esp is before return address - registers.setSP((uint32_t)returnAddressLocation + 4, 0); + registers.setSP((uint32_t)returnAddressLocation + 4); } #endif // _LIBUNWIND_TARGET_I386 @@ -318,19 +330,24 @@ int CompactUnwinder_x86_64::stepWithCompactEncodingRBPFrame( // no register saved in this slot break; case UNWIND_X86_64_REG_RBX: - registers.setRBX(addressSpace.get64(savedRegisters), savedRegisters); + registers.setRBX(addressSpace.get64(savedRegisters)); + setSavedRegisterLocation(registers, UNW_X86_64_RBX, savedRegisters, 0); break; case UNWIND_X86_64_REG_R12: - registers.setR12(addressSpace.get64(savedRegisters), savedRegisters); + registers.setR12(addressSpace.get64(savedRegisters)); + setSavedRegisterLocation(registers, UNW_X86_64_R12, savedRegisters, 0); break; case UNWIND_X86_64_REG_R13: - registers.setR13(addressSpace.get64(savedRegisters), savedRegisters); + registers.setR13(addressSpace.get64(savedRegisters)); + setSavedRegisterLocation(registers, UNW_X86_64_R13, savedRegisters, 0); break; case UNWIND_X86_64_REG_R14: - registers.setR14(addressSpace.get64(savedRegisters), savedRegisters); + registers.setR14(addressSpace.get64(savedRegisters)); + setSavedRegisterLocation(registers, UNW_X86_64_R14, savedRegisters, 0); break; case UNWIND_X86_64_REG_R15: - registers.setR15(addressSpace.get64(savedRegisters), savedRegisters); + registers.setR15(addressSpace.get64(savedRegisters)); + setSavedRegisterLocation(registers, UNW_X86_64_R15, savedRegisters, 0); break; default: (void)functionStart; @@ -435,22 +452,28 @@ int CompactUnwinder_x86_64::stepWithCompactEncodingFrameless( for (uint32_t i = 0; i < regCount; ++i) { switch (registersSaved[i]) { case UNWIND_X86_64_REG_RBX: - registers.setRBX(addressSpace.get64(savedRegisters), savedRegisters); + registers.setRBX(addressSpace.get64(savedRegisters)); + setSavedRegisterLocation(registers, UNW_X86_64_RBX, savedRegisters, 0); break; case UNWIND_X86_64_REG_R12: - registers.setR12(addressSpace.get64(savedRegisters), savedRegisters); + registers.setR12(addressSpace.get64(savedRegisters)); + setSavedRegisterLocation(registers, UNW_X86_64_R12, savedRegisters, 0); break; case UNWIND_X86_64_REG_R13: - registers.setR13(addressSpace.get64(savedRegisters), savedRegisters); + registers.setR13(addressSpace.get64(savedRegisters)); + setSavedRegisterLocation(registers, UNW_X86_64_R13, savedRegisters, 0); break; case UNWIND_X86_64_REG_R14: - registers.setR14(addressSpace.get64(savedRegisters), savedRegisters); + registers.setR14(addressSpace.get64(savedRegisters)); + setSavedRegisterLocation(registers, UNW_X86_64_R14, savedRegisters, 0); break; case UNWIND_X86_64_REG_R15: - registers.setR15(addressSpace.get64(savedRegisters), savedRegisters); + registers.setR15(addressSpace.get64(savedRegisters)); + setSavedRegisterLocation(registers, UNW_X86_64_R15, savedRegisters, 0); break; case UNWIND_X86_64_REG_RBP: - registers.setRBP(addressSpace.get64(savedRegisters), savedRegisters); + registers.setRBP(addressSpace.get64(savedRegisters)); + setSavedRegisterLocation(registers, UNW_X86_64_RBP, savedRegisters, 0); break; default: _LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for " @@ -470,11 +493,12 @@ void CompactUnwinder_x86_64::frameUnwind(A &addressSpace, R ®isters) { uint64_t rbp = registers.getRBP(); // ebp points to old ebp - registers.setRBP(addressSpace.get64(rbp), rbp); + registers.setRBP(addressSpace.get64(rbp)); + setSavedRegisterLocation(registers, UNW_X86_64_RBP, rbp, 0); // old esp is ebp less saved ebp and return address - registers.setSP(rbp + 16, 0); + registers.setSP(rbp + 16); // pop return address into eip - registers.setIP(addressSpace.get64(rbp + 8), rbp + 8); + registers.setIP(addressSpace.get64(rbp + 8)); } template @@ -482,9 +506,9 @@ void CompactUnwinder_x86_64::framelessUnwind(A &addressSpace, uint64_t returnAddressLocation, R ®isters) { // return address is on stack after last saved register - registers.setIP(addressSpace.get64(returnAddressLocation), returnAddressLocation); + registers.setIP(addressSpace.get64(returnAddressLocation)); // old esp is before return address - registers.setSP(returnAddressLocation + 8, 0); + registers.setSP(returnAddressLocation + 8); } #endif // _LIBUNWIND_TARGET_X86_64 @@ -538,33 +562,43 @@ int CompactUnwinder_arm64::stepWithCompactEncodingFrameless( uint64_t savedRegisterLoc = registers.getSP() + stackSize; if (encoding & UNWIND_ARM64_FRAME_X19_X20_PAIR) { - registers.setRegister(UNW_AARCH64_X19, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X19, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X19, savedRegisterLoc, 0); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X20, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X20, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X20, savedRegisterLoc, 0); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X21_X22_PAIR) { - registers.setRegister(UNW_AARCH64_X21, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X21, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X21, savedRegisterLoc, 0); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X22, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X22, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X22, savedRegisterLoc, 0); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X23_X24_PAIR) { - registers.setRegister(UNW_AARCH64_X23, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X23, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X23, savedRegisterLoc, 0); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X24, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X24, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X24, savedRegisterLoc, 0); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X25_X26_PAIR) { - registers.setRegister(UNW_AARCH64_X25, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X25, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X25, savedRegisterLoc, 0); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X26, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X26, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X26, savedRegisterLoc, 0); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X27_X28_PAIR) { - registers.setRegister(UNW_AARCH64_X27, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X27, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X27, savedRegisterLoc, 0); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X28, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X28, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X28, savedRegisterLoc, 0); savedRegisterLoc -= 8; } @@ -606,12 +640,12 @@ int CompactUnwinder_arm64::stepWithCompactEncodingFrameless( Registers_arm64::reg_t linkRegister = registers.getRegister(UNW_AARCH64_LR); // subtract stack size off of sp - registers.setSP(savedRegisterLoc, 0); + registers.setSP(savedRegisterLoc); // Set pc to be value in lr. This needs to be performed after the new SP has // been set, as the PC authentication schema entangles the SP of the new // frame. - registers.setIP(linkRegister, 0); + registers.setIP(linkRegister); return UNW_STEP_SUCCESS; } @@ -620,36 +654,46 @@ template int CompactUnwinder_arm64::stepWithCompactEncodingFrame( compact_unwind_encoding_t encoding, uint64_t, A &addressSpace, R ®isters) { - typename R::reg_t savedRegisterLoc = registers.getFP() - 8; + Registers_arm64::reg_t savedRegisterLoc = registers.getFP() - 8; if (encoding & UNWIND_ARM64_FRAME_X19_X20_PAIR) { - registers.setRegister(UNW_AARCH64_X19, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X19, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X19, savedRegisterLoc, 0); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X20, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X20, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X20, savedRegisterLoc, 0); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X21_X22_PAIR) { - registers.setRegister(UNW_AARCH64_X21, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X21, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X21, savedRegisterLoc, 0); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X22, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X22, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X22, savedRegisterLoc, 0); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X23_X24_PAIR) { - registers.setRegister(UNW_AARCH64_X23, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X23, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X23, savedRegisterLoc, 0); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X24, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X24, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X24, savedRegisterLoc, 0); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X25_X26_PAIR) { - registers.setRegister(UNW_AARCH64_X25, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X25, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X25, savedRegisterLoc, 0); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X26, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X26, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X26, savedRegisterLoc, 0); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X27_X28_PAIR) { - registers.setRegister(UNW_AARCH64_X27, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X27, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X27, savedRegisterLoc, 0); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X28, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X28, addressSpace.get64(savedRegisterLoc)); + setSavedRegisterLocation(registers, UNW_AARCH64_X28, savedRegisterLoc, 0); savedRegisterLoc -= 8; } @@ -689,11 +733,16 @@ int CompactUnwinder_arm64::stepWithCompactEncodingFrame( Registers_arm64::reg_t fp = registers.getFP(); // fp points to old fp - registers.setFP(addressSpace.get64(fp), fp); - // old sp is fp less saved fp and lr - registers.setSP(fp + 16, 0); + registers.setFP(addressSpace.get64(fp)); + setSavedRegisterLocation(registers, UNW_AARCH64_FP, fp, 0); + + // Old sp is fp less saved fp and lr. We need to set this prior to setting + // the lr as the pointer authentication schema for the lr incorporates the + // sp as part of the diversifier. + registers.setSP(fp + 16); + // pop return address into pc - registers.setIP(addressSpace.get64(fp + 8), fp + 8); + registers.setIP(addressSpace.get64(fp + 8)); return UNW_STEP_SUCCESS; } diff --git a/src/native/external/llvm-libunwind/src/DwarfInstructions.hpp b/src/native/external/llvm-libunwind/src/DwarfInstructions.hpp index 1fc8baa8036b07..ff01227609f6bb 100644 --- a/src/native/external/llvm-libunwind/src/DwarfInstructions.hpp +++ b/src/native/external/llvm-libunwind/src/DwarfInstructions.hpp @@ -34,7 +34,7 @@ class DwarfInstructions { typedef typename A::sint_t sint_t; static int stepWithDwarf(A &addressSpace, - pint_t pc, + typename R::link_hardened_reg_arg_t pc, pint_t fdeStart, R ®isters, bool &isSignalFrame, bool stage2); @@ -57,8 +57,27 @@ class DwarfInstructions { const R ®isters, pint_t initialStackValue); static pint_t getSavedRegister(A &addressSpace, const R ®isters, - pint_t cfa, const RegisterLocation &savedReg, - pint_t& location); + pint_t cfa, const RegisterLocation &savedReg); + // Reports where a register was restored from to register sets that track + // save locations (by implementing setRegisterLocation); no-op otherwise. + template + static auto setSavedRegisterLocation(A &addressSpace, const R ®isters, + pint_t cfa, + const RegisterLocation &savedReg, + T &newRegisters, int regNum, int) + -> decltype(newRegisters.setRegisterLocation(regNum, pint_t()), void()) { + pint_t location = 0; + if (savedReg.location == CFI_Parser::kRegisterInCFA) + location = cfa + (pint_t)savedReg.value; + else if (savedReg.location == CFI_Parser::kRegisterAtExpression) + location = evaluateExpression((pint_t)savedReg.value, addressSpace, + registers, cfa); + newRegisters.setRegisterLocation(regNum, location); + } + template + static void setSavedRegisterLocation(A &, const R &, pint_t, + const RegisterLocation &, T &, int, + long) {} static double getSavedFloatRegister(A &addressSpace, const R ®isters, pint_t cfa, const RegisterLocation &savedReg); static v128 getSavedVectorRegister(A &addressSpace, const R ®isters, @@ -95,28 +114,24 @@ template uint64_t getSparcWCookie(const R &, long) { template typename A::pint_t DwarfInstructions::getSavedRegister( A &addressSpace, const R ®isters, pint_t cfa, - const RegisterLocation &savedReg, - typename A::pint_t& location) { + const RegisterLocation &savedReg) { switch (savedReg.location) { case CFI_Parser::kRegisterInCFA: - location = cfa + (pint_t)savedReg.value; - return (pint_t)addressSpace.getP(location); + return (pint_t)addressSpace.getRegister(cfa + (pint_t)savedReg.value); case CFI_Parser::kRegisterInCFADecrypt: // sparc64 specific return (pint_t)(addressSpace.getP(cfa + (pint_t)savedReg.value) ^ getSparcWCookie(registers, 0)); case CFI_Parser::kRegisterAtExpression: - location = evaluateExpression((pint_t)savedReg.value, addressSpace, - registers, cfa); - return (pint_t)addressSpace.getP(location); + return (pint_t)addressSpace.getRegister(evaluateExpression( + (pint_t)savedReg.value, addressSpace, registers, cfa)); case CFI_Parser::kRegisterIsExpression: - location = 0; return evaluateExpression((pint_t)savedReg.value, addressSpace, registers, cfa); + case CFI_Parser::kRegisterInRegister: - location = 0; return registers.getRegister((int)savedReg.value); case CFI_Parser::kRegisterUndefined: return 0; @@ -186,12 +201,11 @@ bool DwarfInstructions::isReturnAddressSigned(A &addressSpace, R registers, pint_t cfa, PrologInfo &prolog) { pint_t raSignState; - pint_t location; auto regloc = prolog.savedRegisters[UNW_AARCH64_RA_SIGN_STATE]; if (regloc.location == CFI_Parser::kRegisterUnused) raSignState = static_cast(regloc.value); else - raSignState = getSavedRegister(addressSpace, registers, cfa, regloc, location); + raSignState = getSavedRegister(addressSpace, registers, cfa, regloc); // Only bit[0] is meaningful. return raSignState & 0x01; @@ -203,12 +217,11 @@ bool DwarfInstructions::isReturnAddressSignedWithPC(A &addressSpace, pint_t cfa, PrologInfo &prolog) { pint_t raSignState; - pint_t location; auto regloc = prolog.savedRegisters[UNW_AARCH64_RA_SIGN_STATE]; if (regloc.location == CFI_Parser::kRegisterUnused) raSignState = static_cast(regloc.value); else - raSignState = getSavedRegister(addressSpace, registers, cfa, regloc, location); + raSignState = getSavedRegister(addressSpace, registers, cfa, regloc); // Only bit[1] is meaningful. return raSignState & 0x02; @@ -217,7 +230,7 @@ bool DwarfInstructions::isReturnAddressSignedWithPC(A &addressSpace, template int DwarfInstructions::stepWithDwarf( - A &addressSpace, pint_t pc, pint_t fdeStart, + A &addressSpace, typename R::link_hardened_reg_arg_t pc, pint_t fdeStart, R ®isters, bool &isSignalFrame, bool stage2) { FDE_Info fdeInfo; CIE_Info cieInfo; @@ -271,10 +284,9 @@ int DwarfInstructions::stepWithDwarf( // // We set the SP here to the CFA, allowing for it to be overridden // by a CFI directive later on. - newRegisters.setSP(cfa, 0); + newRegisters.setSP(cfa); - pint_t returnAddress = 0; - pint_t returnAddressLocation = 0; + typename R::reg_t returnAddress = 0; constexpr int lastReg = R::lastDwarfRegNum(); static_assert(static_cast(CFI_Parser::kMaxRegisterNumber) >= lastReg, @@ -294,22 +306,18 @@ int DwarfInstructions::stepWithDwarf( prolog.savedRegisters[i])); else if (i == (int)cieInfo.returnAddressRegister) { returnAddress = getSavedRegister(addressSpace, registers, cfa, - prolog.savedRegisters[i], - returnAddressLocation); - if (registers.validRegister(i)) { - newRegisters.setRegister(i, returnAddress, returnAddressLocation); - } - } - else if (registers.validRegister(i)) { - pint_t value; - pint_t location; - value = getSavedRegister(addressSpace, registers, cfa, - prolog.savedRegisters[i], - location); - - newRegisters.setRegister(i, value, location); - } - else + prolog.savedRegisters[i]); + setSavedRegisterLocation(addressSpace, registers, cfa, + prolog.savedRegisters[i], newRegisters, + i, 0); + } else if (registers.validRegister(i)) { + newRegisters.setRegister( + i, getSavedRegister(addressSpace, registers, cfa, + prolog.savedRegisters[i])); + setSavedRegisterLocation(addressSpace, registers, cfa, + prolog.savedRegisters[i], newRegisters, + i, 0); + } else return UNW_EBADREG; } else if (i == (int)cieInfo.returnAddressRegister) { // Leaf function keeps the return address in register and there is no @@ -429,7 +437,7 @@ int DwarfInstructions::stepWithDwarf( // Return address is address after call site instruction, so setting IP to // that does simulates a return. - newRegisters.setIP(returnAddress, returnAddressLocation); + newRegisters.setIP(returnAddress); // Simulate the step by replacing the register set with the new ones. registers = newRegisters; diff --git a/src/native/external/llvm-libunwind/src/DwarfParser.hpp b/src/native/external/llvm-libunwind/src/DwarfParser.hpp index 55c29f7103ef6e..22de49023cb452 100644 --- a/src/native/external/llvm-libunwind/src/DwarfParser.hpp +++ b/src/native/external/llvm-libunwind/src/DwarfParser.hpp @@ -161,7 +161,7 @@ class CFI_Parser { }; template - static bool findFDE(A &addressSpace, pint_t pc, + static bool findFDE(A &addressSpace, typename R::link_hardened_reg_arg_t pc, pint_t ehSectionStart, size_t sectionLength, pint_t fdeHint, FDE_Info *fdeInfo, CIE_Info *cieInfo); static const char *decodeFDE(A &addressSpace, pint_t fdeStart, @@ -170,7 +170,7 @@ class CFI_Parser { template static bool parseFDEInstructions(A &addressSpace, const FDE_Info &fdeInfo, const CIE_Info &cieInfo, - pint_t upToPC, + typename R::link_hardened_reg_arg_t upToPC, int arch, PrologInfo *results); static const char *parseCIE(A &addressSpace, pint_t cie, CIE_Info *cieInfo); @@ -244,7 +244,7 @@ const char *CFI_Parser::decodeFDE(A &addressSpace, pint_t fdeStart, template template bool CFI_Parser::findFDE(A &addressSpace, - pint_t pc, + typename R::link_hardened_reg_arg_t pc, pint_t ehSectionStart, size_t sectionLength, pint_t fdeHint, FDE_Info *fdeInfo, CIE_Info *cieInfo) { @@ -460,7 +460,7 @@ template template bool CFI_Parser::parseFDEInstructions( A &addressSpace, const FDE_Info &fdeInfo, const CIE_Info &cieInfo, - pint_t upToPC, int arch, PrologInfo *results) { + typename R::link_hardened_reg_arg_t upToPC, int arch, PrologInfo *results) { // Alloca is used for the allocation of the rememberStack entries. It removes // the dependency on new/malloc but the below for loop can not be refactored // into functions. Entry could be saved during the processing of a CIE and @@ -494,7 +494,7 @@ bool CFI_Parser::parseFDEInstructions( static_cast(instructionsEnd)); // see DWARF Spec, section 6.4.2 for details on unwind opcodes - while ((p < instructionsEnd) && (codeOffset <= pcoffset)) { + while ((p < instructionsEnd) && (codeOffset < pcoffset)) { uint64_t reg; uint64_t reg2; int64_t offset; diff --git a/src/native/external/llvm-libunwind/src/Registers.hpp b/src/native/external/llvm-libunwind/src/Registers.hpp index 47a6e0d06947a6..88c2d3b4e8c9bb 100644 --- a/src/native/external/llvm-libunwind/src/Registers.hpp +++ b/src/native/external/llvm-libunwind/src/Registers.hpp @@ -71,8 +71,7 @@ class _LIBUNWIND_HIDDEN Registers_x86 { bool validRegister(int num) const; uint32_t getRegister(int num) const; - void setRegister(int num, uint32_t value, uint32_t location); - uint32_t getRegisterLocation(int num) const; + void setRegister(int num, uint32_t value); bool validFloatRegister(int) const { return false; } double getFloatRegister(int num) const; void setFloatRegister(int num, double value); @@ -87,21 +86,21 @@ class _LIBUNWIND_HIDDEN Registers_x86 { static int getArch() { return REGISTERS_X86; } uint32_t getSP() const { return _registers.__esp; } - void setSP(uint32_t value, uint32_t location) { _registers.__esp = value; _registerLocations.__esp = location; } + void setSP(uint32_t value) { _registers.__esp = value; } uint32_t getIP() const { return _registers.__eip; } - void setIP(uint32_t value, uint32_t location) { _registers.__eip = value; _registerLocations.__eip = location; } + void setIP(uint32_t value) { _registers.__eip = value; } uint32_t getEBP() const { return _registers.__ebp; } - void setEBP(uint32_t value, uint32_t location) { _registers.__ebp = value; _registerLocations.__ebp = location; } + void setEBP(uint32_t value) { _registers.__ebp = value; } uint32_t getEBX() const { return _registers.__ebx; } - void setEBX(uint32_t value, uint32_t location) { _registers.__ebx = value; _registerLocations.__ebx = location; } + void setEBX(uint32_t value) { _registers.__ebx = value; } uint32_t getECX() const { return _registers.__ecx; } - void setECX(uint32_t value, uint32_t location) { _registers.__ecx = value; _registerLocations.__ecx = location; } + void setECX(uint32_t value) { _registers.__ecx = value; } uint32_t getEDX() const { return _registers.__edx; } - void setEDX(uint32_t value, uint32_t location) { _registers.__edx = value; _registerLocations.__edx = location; } + void setEDX(uint32_t value) { _registers.__edx = value; } uint32_t getESI() const { return _registers.__esi; } - void setESI(uint32_t value, uint32_t location) { _registers.__esi = value; _registerLocations.__esi = location; } + void setESI(uint32_t value) { _registers.__esi = value; } uint32_t getEDI() const { return _registers.__edi; } - void setEDI(uint32_t value, uint32_t location) { _registers.__edi = value; _registerLocations.__edi = location; } + void setEDI(uint32_t value) { _registers.__edi = value; } private: struct GPRs { @@ -122,32 +121,18 @@ class _LIBUNWIND_HIDDEN Registers_x86 { unsigned int __fs; unsigned int __gs; }; - struct GPRLocations { - unsigned int __eax; - unsigned int __ebx; - unsigned int __ecx; - unsigned int __edx; - unsigned int __edi; - unsigned int __esi; - unsigned int __ebp; - unsigned int __esp; - unsigned int __eip; - }; GPRs _registers; - GPRLocations _registerLocations; }; inline Registers_x86::Registers_x86(const void *registers) { static_assert((check_fit::does_fit), "x86 registers do not fit into unw_context_t"); memcpy(&_registers, registers, sizeof(_registers)); - memset(&_registerLocations, 0, sizeof(_registerLocations)); } inline Registers_x86::Registers_x86() { memset(&_registers, 0, sizeof(_registers)); - memset(&_registerLocations, 0, sizeof(_registerLocations)); } inline bool Registers_x86::validRegister(int regNum) const { @@ -196,31 +181,25 @@ inline uint32_t Registers_x86::getRegister(int regNum) const { _LIBUNWIND_ABORT("unsupported x86 register"); } -inline void Registers_x86::setRegister(int regNum, uint32_t value, uint32_t location) { +inline void Registers_x86::setRegister(int regNum, uint32_t value) { switch (regNum) { case UNW_REG_IP: _registers.__eip = value; - _registerLocations.__eip = location; return; case UNW_REG_SP: _registers.__esp = value; - _registerLocations.__esp = location; return; case UNW_X86_EAX: _registers.__eax = value; - _registerLocations.__eax = location; return; case UNW_X86_ECX: _registers.__ecx = value; - _registerLocations.__ecx = location; return; case UNW_X86_EDX: _registers.__edx = value; - _registerLocations.__edx = location; return; case UNW_X86_EBX: _registers.__ebx = value; - _registerLocations.__ebx = location; return; #if !defined(__APPLE__) case UNW_X86_ESP: @@ -228,7 +207,6 @@ inline void Registers_x86::setRegister(int regNum, uint32_t value, uint32_t loca case UNW_X86_EBP: #endif _registers.__ebp = value; - _registerLocations.__ebp = location; return; #if !defined(__APPLE__) case UNW_X86_EBP: @@ -236,46 +214,17 @@ inline void Registers_x86::setRegister(int regNum, uint32_t value, uint32_t loca case UNW_X86_ESP: #endif _registers.__esp = value; - _registerLocations.__esp = location; return; case UNW_X86_ESI: _registers.__esi = value; - _registerLocations.__esi = location; return; case UNW_X86_EDI: _registers.__edi = value; - _registerLocations.__edi = location; return; } _LIBUNWIND_ABORT("unsupported x86 register"); } -inline uint32_t Registers_x86::getRegisterLocation(int regNum) const { - switch (regNum) { - case UNW_REG_IP: - return _registerLocations.__eip; - case UNW_REG_SP: - return _registerLocations.__esp; - case UNW_X86_EAX: - return _registerLocations.__eax; - case UNW_X86_ECX: - return _registerLocations.__ecx; - case UNW_X86_EDX: - return _registerLocations.__edx; - case UNW_X86_EBX: - return _registerLocations.__ebx; - case UNW_X86_EBP: - return _registerLocations.__ebp; - case UNW_X86_ESP: - return _registerLocations.__esp; - case UNW_X86_ESI: - return _registerLocations.__esi; - case UNW_X86_EDI: - return _registerLocations.__edi; - } - _LIBUNWIND_ABORT("unsupported x86 register"); -} - inline const char *Registers_x86::getRegisterName(int regNum) { switch (regNum) { case UNW_REG_IP: @@ -344,8 +293,7 @@ class _LIBUNWIND_HIDDEN Registers_x86_64 { bool validRegister(int num) const; uint64_t getRegister(int num) const; - void setRegister(int num, uint64_t value, uint64_t location); - uint64_t getRegisterLocation(int num) const; + void setRegister(int num, uint64_t value); bool validFloatRegister(int) const { return false; } double getFloatRegister(int num) const; void setFloatRegister(int num, double value); @@ -360,21 +308,21 @@ class _LIBUNWIND_HIDDEN Registers_x86_64 { static int getArch() { return REGISTERS_X86_64; } uint64_t getSP() const { return _registers.__rsp; } - void setSP(uint64_t value, uint64_t location) { _registers.__rsp = value; _registerLocations.__rsp = location;} + void setSP(uint64_t value) { _registers.__rsp = value; } uint64_t getIP() const { return _registers.__rip; } - void setIP(uint64_t value, uint64_t location) { _registers.__rip = value; _registerLocations.__rip = location; } + void setIP(uint64_t value) { _registers.__rip = value; } uint64_t getRBP() const { return _registers.__rbp; } - void setRBP(uint64_t value, uint64_t location) { _registers.__rbp = value; _registerLocations.__rbp = location; } + void setRBP(uint64_t value) { _registers.__rbp = value; } uint64_t getRBX() const { return _registers.__rbx; } - void setRBX(uint64_t value, uint64_t location) { _registers.__rbx = value; _registerLocations.__rbx = location; } + void setRBX(uint64_t value) { _registers.__rbx = value; } uint64_t getR12() const { return _registers.__r12; } - void setR12(uint64_t value, uint64_t location) { _registers.__r12 = value; _registerLocations.__r12 = location; } + void setR12(uint64_t value) { _registers.__r12 = value; } uint64_t getR13() const { return _registers.__r13; } - void setR13(uint64_t value, uint64_t location) { _registers.__r13 = value; _registerLocations.__r13 = location; } + void setR13(uint64_t value) { _registers.__r13 = value; } uint64_t getR14() const { return _registers.__r14; } - void setR14(uint64_t value, uint64_t location) { _registers.__r14 = value; _registerLocations.__r14 = location; } + void setR14(uint64_t value) { _registers.__r14 = value; } uint64_t getR15() const { return _registers.__r15; } - void setR15(uint64_t value, uint64_t location) { _registers.__r15 = value; _registerLocations.__r15 = location; } + void setR15(uint64_t value) { _registers.__r15 = value; } private: struct GPRs { @@ -403,27 +351,7 @@ class _LIBUNWIND_HIDDEN Registers_x86_64 { uint64_t __padding; // 16-byte align #endif }; - struct GPRLocations { - uint64_t __rax; - uint64_t __rbx; - uint64_t __rcx; - uint64_t __rdx; - uint64_t __rdi; - uint64_t __rsi; - uint64_t __rbp; - uint64_t __rsp; - uint64_t __r8; - uint64_t __r9; - uint64_t __r10; - uint64_t __r11; - uint64_t __r12; - uint64_t __r13; - uint64_t __r14; - uint64_t __r15; - uint64_t __rip; - }; GPRs _registers; - GPRLocations _registerLocations; #if defined(_WIN64) v128 _xmm[16]; #endif @@ -433,12 +361,10 @@ inline Registers_x86_64::Registers_x86_64(const void *registers) { static_assert((check_fit::does_fit), "x86_64 registers do not fit into unw_context_t"); memcpy(&_registers, registers, sizeof(_registers)); - memset(&_registerLocations, 0, sizeof(_registerLocations)); } inline Registers_x86_64::Registers_x86_64() { memset(&_registers, 0, sizeof(_registers)); - memset(&_registerLocations, 0, sizeof(_registerLocations)); } inline bool Registers_x86_64::validRegister(int regNum) const { @@ -496,122 +422,62 @@ inline uint64_t Registers_x86_64::getRegister(int regNum) const { _LIBUNWIND_ABORT("unsupported x86_64 register"); } -inline uint64_t Registers_x86_64::getRegisterLocation(int regNum) const { - switch (regNum) { - case UNW_REG_IP: - return _registerLocations.__rip; - case UNW_REG_SP: - return _registerLocations.__rsp; - case UNW_X86_64_RAX: - return _registerLocations.__rax; - case UNW_X86_64_RDX: - return _registerLocations.__rdx; - case UNW_X86_64_RCX: - return _registerLocations.__rcx; - case UNW_X86_64_RBX: - return _registerLocations.__rbx; - case UNW_X86_64_RSI: - return _registerLocations.__rsi; - case UNW_X86_64_RDI: - return _registerLocations.__rdi; - case UNW_X86_64_RBP: - return _registerLocations.__rbp; - case UNW_X86_64_RSP: - return _registerLocations.__rsp; - case UNW_X86_64_R8: - return _registerLocations.__r8; - case UNW_X86_64_R9: - return _registerLocations.__r9; - case UNW_X86_64_R10: - return _registerLocations.__r10; - case UNW_X86_64_R11: - return _registerLocations.__r11; - case UNW_X86_64_R12: - return _registerLocations.__r12; - case UNW_X86_64_R13: - return _registerLocations.__r13; - case UNW_X86_64_R14: - return _registerLocations.__r14; - case UNW_X86_64_R15: - return _registerLocations.__r15; - } - _LIBUNWIND_ABORT("unsupported x86_64 register"); -} - -inline void Registers_x86_64::setRegister(int regNum, uint64_t value, uint64_t location) { +inline void Registers_x86_64::setRegister(int regNum, uint64_t value) { switch (regNum) { case UNW_REG_IP: case UNW_X86_64_RIP: _registers.__rip = value; - _registerLocations.__rip = location; return; case UNW_REG_SP: _registers.__rsp = value; - _registerLocations.__rsp = location; return; case UNW_X86_64_RAX: _registers.__rax = value; - _registerLocations.__rax = location; return; case UNW_X86_64_RDX: _registers.__rdx = value; - _registerLocations.__rdx = location; return; case UNW_X86_64_RCX: _registers.__rcx = value; - _registerLocations.__rcx = location; return; case UNW_X86_64_RBX: _registers.__rbx = value; - _registerLocations.__rbx = location; return; case UNW_X86_64_RSI: _registers.__rsi = value; - _registerLocations.__rsi = location; return; case UNW_X86_64_RDI: _registers.__rdi = value; - _registerLocations.__rdi = location; return; case UNW_X86_64_RBP: _registers.__rbp = value; - _registerLocations.__rbp = location; return; case UNW_X86_64_RSP: _registers.__rsp = value; - _registerLocations.__rsp = location; return; case UNW_X86_64_R8: _registers.__r8 = value; - _registerLocations.__r8 = location; return; case UNW_X86_64_R9: _registers.__r9 = value; - _registerLocations.__r9 = location; return; case UNW_X86_64_R10: _registers.__r10 = value; - _registerLocations.__r10 = location; return; case UNW_X86_64_R11: _registers.__r11 = value; - _registerLocations.__r11 = location; return; case UNW_X86_64_R12: _registers.__r12 = value; - _registerLocations.__r12 = location; return; case UNW_X86_64_R13: _registers.__r13 = value; - _registerLocations.__r13 = location; return; case UNW_X86_64_R14: _registers.__r14 = value; - _registerLocations.__r14 = location; return; case UNW_X86_64_R15: _registers.__r15 = value; - _registerLocations.__r15 = location; return; } _LIBUNWIND_ABORT("unsupported x86_64 register"); @@ -1326,8 +1192,7 @@ class _LIBUNWIND_HIDDEN Registers_ppc64 { bool validRegister(int num) const; uint64_t getRegister(int num) const; - void setRegister(int num, uint64_t value, uint64_t location); - uint64_t getRegisterLocation(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); @@ -2000,14 +1865,13 @@ class _LIBUNWIND_HIDDEN Registers_arm64 { bool validRegister(int num) const; uint64_t getRegister(int num) const; - void setRegister(int num, uint64_t value, uint64_t location); + 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); - uint64_t getRegisterLocation(int regNum) const; static const char *getRegisterName(int num); void jumpto(unsigned walkedFrames = 0) { zaDisable(); @@ -2023,10 +1887,7 @@ class _LIBUNWIND_HIDDEN Registers_arm64 { static int getArch() { return REGISTERS_ARM64; } uint64_t getSP() const { return _registers.__sp; } - void setSP(uint64_t value, uint64_t location) { - _registers.__sp = value; - _registerLocations.__sp = location; - } + void setSP(uint64_t value) { _registers.__sp = value; } uint64_t getIP() const { uint64_t value = _registers.__pc; #if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING) @@ -2040,7 +1901,7 @@ class _LIBUNWIND_HIDDEN Registers_arm64 { #endif return value; } - void setIP(uint64_t value, uint64_t location) { + void setIP(uint64_t value) { #if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING) // Note the value which was set should have been signed with the SP. // We then resign with the slot we are being stored in to so that both SP @@ -2052,13 +1913,9 @@ class _LIBUNWIND_HIDDEN Registers_arm64 { &_registers.__pc); #endif _registers.__pc = value; - _registerLocations.__pc = location; } uint64_t getFP() const { return _registers.__fp; } - void setFP(uint64_t value, uint64_t location) { - _registers.__fp = value; - _registerLocations.__fp = location; - } + void setFP(uint64_t value) { _registers.__fp = value; } #if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING) void @@ -2112,21 +1969,12 @@ class _LIBUNWIND_HIDDEN Registers_arm64 { uint64_t __ra_sign_state = 0; // RA sign state register }; - struct GPRLocations { - uint64_t __x[29] = {}; // x0-x28 - uint64_t __fp = 0; // Frame pointer x29 - uint64_t __lr = 0; // Link register x30 - uint64_t __sp = 0; // Stack pointer x31 - uint64_t __pc = 0; // Program counter - }; - struct Misc { mutable uint32_t __vg = 0; // Vector Granule bool __has_sme = checkHasSME(); }; GPRs _registers = {}; - GPRLocations _registerLocations = {}; // Currently only the lower double in 128-bit vectore registers // is perserved during unwinding. We could define new register // numbers (> 96) which mean whole vector registers, then this @@ -2144,9 +1992,7 @@ inline Registers_arm64::Registers_arm64(const void *registers) { static_assert((check_fit::does_fit), "arm64 registers do not fit into unw_context_t"); memcpy(&_registers, registers, sizeof(_registers)); - memset(&_registerLocations, 0, sizeof(_registerLocations)); - static_assert( - sizeof(GPRs) == 0x110, + static_assert(sizeof(GPRs) == 0x110, "expected VFP registers to be at offset 272"); memcpy(_vectorHalfRegisters, static_cast(registers) + sizeof(GPRs), @@ -2161,7 +2007,7 @@ inline Registers_arm64::Registers_arm64(const void *registers) { uint64_t pcRegister = 0; memmove(&pcRegister, ((uint8_t *)&_registers) + offsetof(GPRs, __pc), sizeof(pcRegister)); - setIP(pcRegister, 0); + setIP(pcRegister); #endif } @@ -2174,7 +2020,7 @@ Registers_arm64::operator=(const Registers_arm64 &other) { memmove(static_cast(this), &other, sizeof(*this)); // We perform this step to ensure that we correctly authenticate and re-sign // the pc after the bitwise copy. - setIP(other.getIP(), other.getRegisterLocation(UNW_REG_IP)); + setIP(other.getIP()); return *this; } @@ -2228,53 +2074,25 @@ inline uint64_t Registers_arm64::getRegister(int regNum) const { _LIBUNWIND_ABORT("unsupported arm64 register"); } -inline void Registers_arm64::setRegister(int regNum, uint64_t value, uint64_t location) { +inline void Registers_arm64::setRegister(int regNum, uint64_t value) { if (regNum == UNW_REG_IP || regNum == UNW_AARCH64_PC) - setIP(value, location); - else if (regNum == UNW_REG_SP || regNum == UNW_AARCH64_SP) { + setIP(value); + else if (regNum == UNW_REG_SP || regNum == UNW_AARCH64_SP) _registers.__sp = value; - _registerLocations.__sp = location; - } else if (regNum == UNW_AARCH64_RA_SIGN_STATE) _registers.__ra_sign_state = value; - else if (regNum == UNW_AARCH64_FP) { - _registers.__fp = value; - _registerLocations.__fp = location; - } - else if (regNum == UNW_AARCH64_LR) { + else if (regNum == UNW_AARCH64_FP) + setFP(value); + else if (regNum == UNW_AARCH64_LR) _registers.__lr = value; - _registerLocations.__lr = location; - } - else if ((regNum >= 0) && (regNum < 29)) { - _registers.__x[regNum] = value; - _registerLocations.__x[regNum] = location; - } else if (regNum == UNW_AARCH64_VG) _misc_registers.__vg = value; + else if ((regNum >= 0) && (regNum < 29)) + _registers.__x[regNum] = value; else _LIBUNWIND_ABORT("unsupported arm64 register"); } -inline uint64_t Registers_arm64::getRegisterLocation(int regNum) const { - if (regNum == UNW_REG_IP) - return _registerLocations.__pc; - if (regNum == UNW_AARCH64_PC) - return _registerLocations.__pc; - if (regNum == UNW_REG_SP) - return _registerLocations.__sp; - if (regNum == UNW_AARCH64_SP) - return _registerLocations.__sp; - if (regNum == UNW_AARCH64_FP) - return _registerLocations.__fp; - if (regNum == UNW_AARCH64_LR) - return _registerLocations.__lr; - if ((regNum >= 0) && (regNum < 29)) - return _registerLocations.__x[regNum]; - if (regNum == UNW_AARCH64_RA_SIGN_STATE || regNum == UNW_AARCH64_VG) - return 0; - _LIBUNWIND_ABORT("unsupported arm64 register"); -} - inline const char *Registers_arm64::getRegisterName(int regNum) { switch (regNum) { case UNW_REG_IP: @@ -2464,8 +2282,7 @@ class _LIBUNWIND_HIDDEN Registers_arm { bool validRegister(int num) const; uint32_t getRegister(int num) const; - void setRegister(int num, uint32_t value, uint32_t location); - uint32_t getRegisterLocation(int num) const; + void setRegister(int num, uint32_t value); bool validFloatRegister(int num) const; unw_fpreg_t getFloatRegister(int num); void setFloatRegister(int num, unw_fpreg_t value); @@ -2483,9 +2300,9 @@ class _LIBUNWIND_HIDDEN Registers_arm { static int getArch() { return REGISTERS_ARM; } uint32_t getSP() const { return _registers.__sp; } - void setSP(uint32_t value, uint32_t location) { _registers.__sp = value; _registerLocations.__sp = location; } + void setSP(uint32_t value) { _registers.__sp = value; } uint32_t getIP() const { return _registers.__pc; } - void setIP(uint32_t value, uint32_t location) { _registers.__pc = value; _registerLocations.__pc = location; } + void setIP(uint32_t value) { _registers.__pc = value; } void saveVFPAsX() { assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15); @@ -2522,14 +2339,6 @@ class _LIBUNWIND_HIDDEN Registers_arm { }; static void saveVFPWithFSTMD(void*); - - struct GPRLocations { - uint32_t __r[13]; // r0-r12 - uint32_t __sp; // Stack pointer r13 - uint32_t __lr; // Link register r14 - uint32_t __pc; // Program counter r15 - }; - static void saveVFPWithFSTMX(void*); static void saveVFPv3(void*); static void restoreVFPWithFLDMD(void*); @@ -2546,7 +2355,6 @@ class _LIBUNWIND_HIDDEN Registers_arm { // ARM registers GPRs _registers; PseudoRegisters _pseudo_registers; - GPRLocations _registerLocations; // We save floating point registers lazily because we can't know ahead of // time which ones are used. See EHABI #4.7. @@ -2585,7 +2393,6 @@ inline Registers_arm::Registers_arm(const void *registers) // See __unw_getcontext() note about data. memcpy(&_registers, registers, sizeof(_registers)); memset(&_pseudo_registers, 0, sizeof(_pseudo_registers)); - memset(&_registerLocations, 0, sizeof(_registerLocations)); memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad)); memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31)); #if defined(__ARM_WMMX) @@ -2602,7 +2409,6 @@ inline Registers_arm::Registers_arm() _saved_vfp_d16_d31(false) { memset(&_registers, 0, sizeof(_registers)); memset(&_pseudo_registers, 0, sizeof(_pseudo_registers)); - memset(&_registerLocations, 0, sizeof(_registerLocations)); memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad)); memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31)); #if defined(__ARM_WMMX) @@ -2669,28 +2475,24 @@ inline uint32_t Registers_arm::getRegister(int regNum) const { _LIBUNWIND_ABORT("unsupported arm register"); } -inline void Registers_arm::setRegister(int regNum, uint32_t value, uint32_t location) { +inline void Registers_arm::setRegister(int regNum, uint32_t value) { if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) { _registers.__sp = value; - _registerLocations.__sp = location; return; } if (regNum == UNW_ARM_LR) { _registers.__lr = value; - _registerLocations.__lr = location; return; } if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) { _registers.__pc = value; - _registerLocations.__pc = location; return; } if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) { _registers.__r[regNum] = value; - _registerLocations.__r[regNum] = location; return; } @@ -2713,22 +2515,6 @@ inline void Registers_arm::setRegister(int regNum, uint32_t value, uint32_t loca _LIBUNWIND_ABORT("unsupported arm register"); } -inline uint32_t Registers_arm::getRegisterLocation(int regNum) const { - if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) - return _registerLocations.__sp; - - if (regNum == UNW_ARM_LR) - return _registerLocations.__lr; - - if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) - return _registerLocations.__pc; - - if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) - return _registerLocations.__r[regNum]; - - _LIBUNWIND_ABORT("unsupported arm register"); -} - inline const char *Registers_arm::getRegisterName(int regNum) { switch (regNum) { case UNW_REG_IP: @@ -4452,14 +4238,13 @@ class _LIBUNWIND_HIDDEN Registers_riscv { bool validRegister(int num) const; reg_t getRegister(int num) const; - void setRegister(int num, reg_t value, uint64_t location); + void setRegister(int num, reg_t value); bool validFloatRegister(int num) const; fp_t getFloatRegister(int num) const; void setFloatRegister(int num, fp_t value); bool validVectorRegister(int num) const; v128 getVectorRegister(int num) const; void setVectorRegister(int num, v128 value); - uint64_t getRegisterLocation(int num) const; static const char *getRegisterName(int num); void jumpto(); static constexpr int lastDwarfRegNum() { @@ -4468,14 +4253,13 @@ class _LIBUNWIND_HIDDEN Registers_riscv { static int getArch() { return REGISTERS_RISCV; } reg_t getSP() const { return _registers[2]; } - void setSP(reg_t value, uint64_t location) { _registers[2] = value; } + void setSP(reg_t value) { _registers[2] = value; } reg_t getIP() const { return _registers[0]; } - void setIP(reg_t value, uint64_t location) { _registers[0] = value; } + void setIP(reg_t value) { _registers[0] = value; } private: // _registers[0] holds the pc reg_t _registers[32]; - reg_t _registerLocations[32]; # if defined(__riscv_flen) fp_t _floats[32]; # endif @@ -4485,7 +4269,6 @@ inline Registers_riscv::Registers_riscv(const void *registers) { static_assert((check_fit::does_fit), "riscv registers do not fit into unw_context_t"); memcpy(&_registers, registers, sizeof(_registers)); - memset(&_registerLocations, 0, sizeof(_registerLocations)); # if __riscv_xlen == 32 static_assert(sizeof(_registers) == 0x80, "expected float registers to be at offset 128"); @@ -4505,7 +4288,6 @@ inline Registers_riscv::Registers_riscv(const void *registers) { inline Registers_riscv::Registers_riscv() { memset(&_registers, 0, sizeof(_registers)); - memset(&_registerLocations, 0, sizeof(_registerLocations)); # if defined(__riscv_flen) memset(&_floats, 0, sizeof(_floats)); # endif @@ -4542,41 +4324,20 @@ inline reg_t Registers_riscv::getRegister(int regNum) const { _LIBUNWIND_ABORT("unsupported riscv register"); } -inline void Registers_riscv::setRegister(int regNum, reg_t value, uint64_t location) { - if (regNum == UNW_REG_IP) { +inline void Registers_riscv::setRegister(int regNum, reg_t value) { + if (regNum == UNW_REG_IP) _registers[0] = value; - _registerLocations[0] = value; - } else if (regNum == UNW_REG_SP) _registers[2] = value; else if (regNum == UNW_RISCV_X0) /* x0 is hardwired to zero */ return; - else if ((regNum > 0) && (regNum < 32)) { + else if ((regNum > 0) && (regNum < 32)) _registers[regNum] = value; - _registerLocations[regNum - UNW_RISCV_X0] = location; - } else _LIBUNWIND_ABORT("unsupported riscv register"); } -inline uint64_t Registers_riscv::getRegisterLocation(int regNum) const { - if (regNum == UNW_REG_IP) - return _registerLocations[0]; - if (regNum == UNW_REG_SP) - return _registerLocations[2]; - if (regNum == UNW_RISCV_X0) - return 0; - if ((regNum > 0) && (regNum < 32)) - return _registerLocations[regNum]; - if (regNum == UNW_RISCV_VLENB) { - reg_t vlenb; - __asm__("csrr %0, 0xC22" : "=r"(vlenb)); - return vlenb; - } - _LIBUNWIND_ABORT("unsupported riscv register"); -} - inline const char *Registers_riscv::getRegisterName(int regNum) { switch (regNum) { case UNW_REG_IP: @@ -5517,14 +5278,13 @@ class _LIBUNWIND_HIDDEN Registers_loongarch { bool validRegister(int num) const; uint64_t getRegister(int num) const; - void setRegister(int num, uint64_t value, uint64_t location); + 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); - uint64_t getRegisterLocation(int num) const; static const char *getRegisterName(int num); void jumpto(); static constexpr int lastDwarfRegNum() { @@ -5533,23 +5293,17 @@ class _LIBUNWIND_HIDDEN Registers_loongarch { static int getArch() { return REGISTERS_LOONGARCH; } uint64_t getSP() const { return _registers.__r[3]; } - void setSP(uint64_t value, uint64_t location) { _registers.__r[3] = value; } + void setSP(uint64_t value) { _registers.__r[3] = value; } uint64_t getIP() const { return _registers.__pc; } - void setIP(uint64_t value, uint64_t location) { _registers.__pc = value; } + void setIP(uint64_t value) { _registers.__pc = value; } private: - struct GPRs { + struct loongarch_thread_state_t { uint64_t __r[32]; uint64_t __pc; }; - struct GPRLocations { - uint64_t __r[32]; - uint64_t __pc; - }; - - GPRs _registers; - GPRLocations _registerLocations; + loongarch_thread_state_t _registers; #if __loongarch_frlen == 64 double _floats[32]; #endif @@ -5559,7 +5313,6 @@ inline Registers_loongarch::Registers_loongarch(const void *registers) { static_assert((check_fit::does_fit), "loongarch registers do not fit into unw_context_t"); memcpy(&_registers, registers, sizeof(_registers)); - memset(&_registerLocations, 0, sizeof(_registerLocations)); static_assert(sizeof(_registers) == 0x108, "expected float registers to be at offset 264"); #if __loongarch_frlen == 64 @@ -5570,7 +5323,6 @@ inline Registers_loongarch::Registers_loongarch(const void *registers) { inline Registers_loongarch::Registers_loongarch() { memset(&_registers, 0, sizeof(_registers)); - memset(&_registerLocations, 0, sizeof(_registerLocations)); #if __loongarch_frlen == 64 memset(&_floats, 0, sizeof(_floats)); #endif @@ -5595,33 +5347,17 @@ inline uint64_t Registers_loongarch::getRegister(int regNum) const { _LIBUNWIND_ABORT("unsupported loongarch register"); } -inline void Registers_loongarch::setRegister(int regNum, uint64_t value, uint64_t location) { - if (regNum >= UNW_LOONGARCH_R0 && regNum <= UNW_LOONGARCH_R31) { +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; - _registerLocations.__r[regNum - UNW_LOONGARCH_R0] = location; - } - else if (regNum == UNW_REG_IP) { + else if (regNum == UNW_REG_IP) _registers.__pc = value; - _registerLocations.__pc = location; - } - else if (regNum == UNW_REG_SP) { + else if (regNum == UNW_REG_SP) _registers.__r[3] = value; - _registerLocations.__r[3] = location; - } else _LIBUNWIND_ABORT("unsupported loongarch register"); } -inline uint64_t Registers_loongarch::getRegisterLocation(int regNum) const { - if (regNum == UNW_REG_IP) - return _registerLocations.__pc; - if (regNum == UNW_REG_SP) - return _registerLocations.__r[3]; - if ((regNum >= 0) && (regNum < 32)) - return _registerLocations.__r[regNum]; - _LIBUNWIND_ABORT("unsupported loongarch64 register"); -} - inline const char *Registers_loongarch::getRegisterName(int regNum) { switch (regNum) { case UNW_REG_IP: diff --git a/src/native/external/llvm-libunwind/src/Unwind-EHABI.cpp b/src/native/external/llvm-libunwind/src/Unwind-EHABI.cpp index 338c853bca780e..29ab7d6e13a8c7 100644 --- a/src/native/external/llvm-libunwind/src/Unwind-EHABI.cpp +++ b/src/native/external/llvm-libunwind/src/Unwind-EHABI.cpp @@ -228,7 +228,7 @@ decode_eht_entry(const uint32_t* data, size_t* off, size_t* len) { // only by the personality routine. Fortunately, all existing assembler // implementations, including GNU assembler, LLVM integrated assembler, // and ARM assembler, assume that the unwind opcodes come after the - // personality routine address. + // personality rountine address. *off = 1; // First byte is size data. *len = (((data[1] >> 24) & 0xff) + 1) * 4; data++; // Skip the first word, which is the prel31 offset. @@ -271,7 +271,7 @@ _Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data, sp -= (((uint32_t)byte & 0x3f) << 2) + 4; else sp += ((uint32_t)byte << 2) + 4; - _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp, NULL); + _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp); } else { switch (byte & 0xf0) { case 0x80: { @@ -295,7 +295,7 @@ _Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data, _Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_R0 + reg, _UVRSD_UINT32, &sp); _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, - &sp, NULL); + &sp); break; } case 0xa0: { @@ -337,7 +337,7 @@ _Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data, &sp); sp += 0x204 + (addend << 2); _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, - &sp, NULL); + &sp); break; } case 0xb3: { @@ -438,7 +438,7 @@ _Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data, #else (void)hasReturnAddrAuthCode; #endif - _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_IP, _UVRSD_UINT32, &lr, NULL); + _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_IP, _UVRSD_UINT32, &lr); } return _URC_CONTINUE_UNWIND; } @@ -589,7 +589,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor // // See #7.4.6 for details. __unw_set_reg(cursor, UNW_REG_IP, - exception_object->unwinder_cache.reserved2, NULL); + exception_object->unwinder_cache.reserved2); resume = false; } @@ -909,7 +909,7 @@ ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation, _LIBUNWIND_EXPORT _Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, uint32_t regno, _Unwind_VRS_DataRepresentation representation, - void *valuep, unw_word_t *pos) { + void *valuep) { _LIBUNWIND_TRACE_API("_Unwind_VRS_Set(context=%p, regclass=%d, reg=%d, " "rep=%d, value=0x%llX)", static_cast(context), regclass, regno, @@ -921,7 +921,7 @@ _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, if (representation != _UVRSD_UINT32 || regno > 15) return _UVRSR_FAILED; return __unw_set_reg(cursor, (unw_regnum_t)(UNW_ARM_R0 + regno), - *(unw_word_t *)valuep,(unw_word_t *)pos) == UNW_ESUCCESS + *(unw_word_t *)valuep) == UNW_ESUCCESS ? _UVRSR_OK : _UVRSR_FAILED; case _UVRSC_VFP: @@ -965,7 +965,7 @@ _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, if (representation != _UVRSD_UINT32 || regno != 0) return _UVRSR_FAILED; return __unw_set_reg(cursor, (unw_regnum_t)(UNW_ARM_RA_AUTH_CODE), - *(unw_word_t *)valuep, NULL) == UNW_ESUCCESS + *(unw_word_t *)valuep) == UNW_ESUCCESS ? _UVRSR_OK : _UVRSR_FAILED; break; @@ -1071,7 +1071,6 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, // computed new stack location. See EHABI #7.5.4 table 3. bool poppedSP = false; uint32_t* sp; - uint32_t* pos; if (_Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp) != _UVRSR_OK) { return _UVRSR_FAILED; @@ -1079,18 +1078,21 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, for (uint32_t i = 0; i < 16; ++i) { if (!(discriminator & static_cast(1 << i))) continue; - pos = sp; uint32_t value = *sp++; if (regclass == _UVRSC_CORE && i == 13) poppedSP = true; if (_Unwind_VRS_Set(context, regclass, i, - _UVRSD_UINT32, &value, pos) != _UVRSR_OK) { + _UVRSD_UINT32, &value) != _UVRSR_OK) { return _UVRSR_FAILED; } + if (regclass == _UVRSC_CORE) + __unw_set_reg_location((unw_cursor_t *)context, + (unw_regnum_t)(UNW_ARM_R0 + i), + (unw_word_t)(sp - 1)); } if (!poppedSP) { return _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, - _UVRSD_UINT32, &sp, NULL); + _UVRSD_UINT32, &sp); } return _UVRSR_OK; } @@ -1122,14 +1124,14 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, #else #error "Unable to determine endianess" #endif - if (_Unwind_VRS_Set(context, regclass, i, representation, &value, NULL) != + if (_Unwind_VRS_Set(context, regclass, i, representation, &value) != _UVRSR_OK) return _UVRSR_FAILED; } if (representation == _UVRSD_VFPX) ++sp; return _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, - &sp, NULL); + &sp); } case _UVRSC_PSEUDO: { if (representation != _UVRSD_UINT32 || discriminator != 0) @@ -1141,8 +1143,8 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, return _UVRSR_FAILED; } uint32_t pac = *sp++; - _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp, NULL); - return _Unwind_VRS_Set(context, _UVRSC_PSEUDO, 0, _UVRSD_UINT32, &pac, NULL); + _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp); + return _Unwind_VRS_Set(context, _UVRSC_PSEUDO, 0, _UVRSD_UINT32, &pac); } } _LIBUNWIND_ABORT("unsupported register class"); diff --git a/src/native/external/llvm-libunwind/src/UnwindCursor.hpp b/src/native/external/llvm-libunwind/src/UnwindCursor.hpp index 7a23d2ff2a89c2..4726654bbb35f7 100644 --- a/src/native/external/llvm-libunwind/src/UnwindCursor.hpp +++ b/src/native/external/llvm-libunwind/src/UnwindCursor.hpp @@ -460,12 +460,10 @@ class _LIBUNWIND_HIDDEN AbstractUnwindCursor { virtual ~AbstractUnwindCursor() {} virtual bool validReg(int) { _LIBUNWIND_ABORT("validReg not implemented"); } virtual unw_word_t getReg(int) { _LIBUNWIND_ABORT("getReg not implemented"); } - virtual void setReg(int, unw_word_t, unw_word_t) { + virtual void setReg(int, unw_word_t) { _LIBUNWIND_ABORT("setReg not implemented"); } - virtual unw_word_t getRegLocation(int) { - _LIBUNWIND_ABORT("getRegLocation not implemented"); - } + virtual void setRegLocation(int, unw_word_t) {} virtual bool validFloatReg(int) { _LIBUNWIND_ABORT("validFloatReg not implemented"); } @@ -969,14 +967,12 @@ template class UnwindCursor : public AbstractUnwindCursor{ typedef typename A::pint_t pint_t; public: - UnwindCursor(A &as); UnwindCursor(unw_context_t *context, A &as); UnwindCursor(A &as, void *threadArg); virtual ~UnwindCursor() {} virtual bool validReg(int); virtual unw_word_t getReg(int); - virtual void setReg(int, unw_word_t, unw_word_t); - virtual unw_word_t getRegLocation(int); + virtual void setReg(int, unw_word_t); virtual bool validFloatReg(int); virtual unw_fpreg_t getFloatReg(int); virtual void setFloatReg(int, unw_fpreg_t); @@ -1013,6 +1009,7 @@ class UnwindCursor : public AbstractUnwindCursor{ #if defined(_LIBUNWIND_ARM_EHABI) public: bool getInfoFromEHABISection(pint_t pc, const UnwindInfoSections §s); +private: int stepWithEHABI() { size_t len = 0; @@ -1071,12 +1068,10 @@ class UnwindCursor : public AbstractUnwindCursor{ const typename CFI_Parser::CIE_Info &cieInfo, typename R::link_hardened_reg_arg_t pc, uintptr_t dso_base); - public: bool getInfoFromDwarfSection(typename R::link_hardened_reg_arg_t pc, const UnwindInfoSections §s, uint32_t fdeSectionOffsetHint = 0); - private: int stepWithDwarfFDE(bool stage2) { #if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING) @@ -1391,13 +1386,6 @@ class UnwindCursor : public AbstractUnwindCursor{ #endif }; -template -UnwindCursor::UnwindCursor(A &as) - : _addressSpace(as) - , _unwindInfoMissing(false) - , _isSignalFrame(false) { - memset(&_info, 0, sizeof(_info)); -} template UnwindCursor::UnwindCursor(unw_context_t *context, A &as) @@ -1411,10 +1399,9 @@ UnwindCursor::UnwindCursor(unw_context_t *context, A &as) } template -UnwindCursor::UnwindCursor(A &as, void *arg) - : _addressSpace(as),_registers(arg), _unwindInfoMissing(false), - _isSignalFrame(false) { - memset(&_info, 0, sizeof(_info)); +UnwindCursor::UnwindCursor(A &as, void *) + : _addressSpace(as), _unwindInfoMissing(false), _isSignalFrame(false) { + memset(static_cast(&_info), 0, sizeof(_info)); // FIXME // fill in _registers from thread arg } @@ -1431,13 +1418,8 @@ unw_word_t UnwindCursor::getReg(int regNum) { } template -void UnwindCursor::setReg(int regNum, unw_word_t value, unw_word_t location) { - _registers.setRegister(regNum, (typename A::pint_t)value, (typename A::pint_t)location); -} - -template -unw_word_t UnwindCursor::getRegLocation(int regNum) { - return _registers.getRegisterLocation(regNum); +void UnwindCursor::setReg(int regNum, unw_word_t value) { + _registers.setRegister(regNum, (typename A::pint_t)value); } template @@ -1790,14 +1772,12 @@ bool UnwindCursor::getInfoFromDwarfSection( typename CFI_Parser::CIE_Info cieInfo; bool foundFDE = false; bool foundInCache = false; - // If compact encoding table gave offset into dwarf section, go directly there if (fdeSectionOffsetHint != 0) { foundFDE = CFI_Parser::template findFDE( _addressSpace, pc, sects.dwarf_section, sects.dwarf_section_length, sects.dwarf_section + fdeSectionOffsetHint, &fdeInfo, &cieInfo); } - #if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) if (!foundFDE && (sects.dwarf_index_section != 0)) { foundFDE = EHHeaderParser::template findFDE( @@ -1805,7 +1785,6 @@ bool UnwindCursor::getInfoFromDwarfSection( (uint32_t)sects.dwarf_index_section_length, &fdeInfo, &cieInfo); } #endif - if (!foundFDE) { // otherwise, search cache of previously found FDEs. pint_t cachedFDE = @@ -2970,10 +2949,10 @@ int UnwindCursor::stepThroughSigReturn(Registers_arm64 &) { for (int i = 0; i <= 30; ++i) { uint64_t value = _addressSpace.get64(sigctx + kOffsetGprs + static_cast(i * 8)); - _registers.setRegister(UNW_AARCH64_X0 + i, value, 0); + _registers.setRegister(UNW_AARCH64_X0 + i, value); } - _registers.setSP(_addressSpace.get64(sigctx + kOffsetSp), 0); - _registers.setIP(_addressSpace.get64(sigctx + kOffsetPc), 0); + _registers.setSP(_addressSpace.get64(sigctx + kOffsetSp)); + _registers.setIP(_addressSpace.get64(sigctx + kOffsetPc)); _isSignalFrame = true; return UNW_STEP_SUCCESS; } @@ -3022,12 +3001,12 @@ int UnwindCursor::stepThroughSigReturn(Registers_loongarch &) { const pint_t kOffsetSpToSigcontext = 128 + 8 + 8 + 24 + 8 + 128; const pint_t sigctx = _registers.getSP() + kOffsetSpToSigcontext; - _registers.setIP(_addressSpace.get64(sigctx), 0); + _registers.setIP(_addressSpace.get64(sigctx)); for (int i = UNW_LOONGARCH_R1; i <= UNW_LOONGARCH_R31; ++i) { // skip R0 uint64_t value = _addressSpace.get64(sigctx + static_cast((i + 1) * 8)); - _registers.setRegister(i, value, 0); + _registers.setRegister(i, value); } _isSignalFrame = true; return UNW_STEP_SUCCESS; @@ -3077,10 +3056,10 @@ int UnwindCursor::stepThroughSigReturn(Registers_riscv &) { const pint_t kOffsetSpToSigcontext = 128 + 8 + 8 + 24 + 8 + 128; const pint_t sigctx = _registers.getSP() + kOffsetSpToSigcontext; - _registers.setIP(_addressSpace.get64(sigctx), 0); + _registers.setIP(_addressSpace.get64(sigctx)); for (int i = UNW_RISCV_X1; i <= UNW_RISCV_X31; ++i) { uint64_t value = _addressSpace.get64(sigctx + static_cast(i * 8)); - _registers.setRegister(i, value, 0); + _registers.setRegister(i, value); } _isSignalFrame = true; return UNW_STEP_SUCCESS; @@ -3258,23 +3237,23 @@ int UnwindCursor::stepThroughSigReturn() { pint_t bp = this->getReg(UNW_X86_64_RBP); vregs *regs = (vregs *)(bp + 0x70); - _registers.setRegister(UNW_REG_IP, regs->rip, 0); - _registers.setRegister(UNW_REG_SP, regs->rsp, 0); - _registers.setRegister(UNW_X86_64_RAX, regs->rax, 0); - _registers.setRegister(UNW_X86_64_RDX, regs->rdx, 0); - _registers.setRegister(UNW_X86_64_RCX, regs->rcx, 0); - _registers.setRegister(UNW_X86_64_RBX, regs->rbx, 0); - _registers.setRegister(UNW_X86_64_RSI, regs->rsi, 0); - _registers.setRegister(UNW_X86_64_RDI, regs->rdi, 0); - _registers.setRegister(UNW_X86_64_RBP, regs->rbp, 0); - _registers.setRegister(UNW_X86_64_R8, regs->r8, 0); - _registers.setRegister(UNW_X86_64_R9, regs->r9, 0); - _registers.setRegister(UNW_X86_64_R10, regs->r10, 0); - _registers.setRegister(UNW_X86_64_R11, regs->r11, 0); - _registers.setRegister(UNW_X86_64_R12, regs->r12, 0); - _registers.setRegister(UNW_X86_64_R13, regs->r13, 0); - _registers.setRegister(UNW_X86_64_R14, regs->r14, 0); - _registers.setRegister(UNW_X86_64_R15, regs->r15, 0); + _registers.setRegister(UNW_REG_IP, regs->rip); + _registers.setRegister(UNW_REG_SP, regs->rsp); + _registers.setRegister(UNW_X86_64_RAX, regs->rax); + _registers.setRegister(UNW_X86_64_RDX, regs->rdx); + _registers.setRegister(UNW_X86_64_RCX, regs->rcx); + _registers.setRegister(UNW_X86_64_RBX, regs->rbx); + _registers.setRegister(UNW_X86_64_RSI, regs->rsi); + _registers.setRegister(UNW_X86_64_RDI, regs->rdi); + _registers.setRegister(UNW_X86_64_RBP, regs->rbp); + _registers.setRegister(UNW_X86_64_R8, regs->r8); + _registers.setRegister(UNW_X86_64_R9, regs->r9); + _registers.setRegister(UNW_X86_64_R10, regs->r10); + _registers.setRegister(UNW_X86_64_R11, regs->r11); + _registers.setRegister(UNW_X86_64_R12, regs->r12); + _registers.setRegister(UNW_X86_64_R13, regs->r13); + _registers.setRegister(UNW_X86_64_R14, regs->r14); + _registers.setRegister(UNW_X86_64_R15, regs->r15); // TODO: XMM #endif // defined(_LIBUNWIND_TARGET_X86_64) diff --git a/src/native/external/llvm-libunwind/src/libunwind.cpp b/src/native/external/llvm-libunwind/src/libunwind.cpp index 2f2032c6c28147..31559251a1a567 100644 --- a/src/native/external/llvm-libunwind/src/libunwind.cpp +++ b/src/native/external/llvm-libunwind/src/libunwind.cpp @@ -111,14 +111,13 @@ _LIBUNWIND_WEAK_ALIAS(__unw_get_reg, unw_get_reg) /// Set value of specified register at cursor position in stack frame. _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum, - unw_word_t value, unw_word_t *pos) { + unw_word_t value) { _LIBUNWIND_TRACE_API("__unw_set_reg(cursor=%p, regNum=%d, value=0x%" PRIxPTR ")", static_cast(cursor), regNum, value); typedef LocalAddressSpace::pint_t pint_t; AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; if (co->validReg(regNum)) { - co->setReg(regNum, (pint_t)value, (pint_t)pos); // special case altering IP to re-find info (being called by personality // function) if (regNum == UNW_REG_IP) { @@ -175,11 +174,11 @@ _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum, // this should actually be - info.gp. LLVM doesn't currently support // any such platforms and Clang doesn't export a macro for them. if (info.gp) - co->setReg(UNW_REG_SP, sp + info.gp, 0); - co->setReg(UNW_REG_IP, value, (pint_t)pos); + co->setReg(UNW_REG_SP, sp + info.gp); + co->setReg(UNW_REG_IP, value); co->setInfoBasedOnIPRegister(false); } else { - co->setReg(regNum, (pint_t)value, (pint_t)pos); + co->setReg(regNum, (pint_t)value); } return UNW_ESUCCESS; } @@ -187,6 +186,14 @@ _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum, } _LIBUNWIND_WEAK_ALIAS(__unw_set_reg, unw_set_reg) +/// Report the address a register was restored from at cursor position. +_LIBUNWIND_HIDDEN void __unw_set_reg_location(unw_cursor_t *cursor, + unw_regnum_t regNum, + unw_word_t location) { + AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; + co->setRegLocation(regNum, location); +} + /// Get value of specified float register at cursor position in stack frame. _LIBUNWIND_HIDDEN int __unw_get_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, unw_fpreg_t *value) { @@ -221,21 +228,6 @@ _LIBUNWIND_HIDDEN int __unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, } _LIBUNWIND_WEAK_ALIAS(__unw_set_fpreg, unw_set_fpreg) -/// Get location of specified register at cursor position in stack frame. -_LIBUNWIND_HIDDEN int __unw_get_save_loc(unw_cursor_t *cursor, int regNum, - unw_save_loc_t* location) -{ - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; - if (co->validReg(regNum)) { - // We only support memory locations, not register locations - location->u.addr = co->getRegLocation(regNum); - location->type = (location->u.addr == 0) ? UNW_SLT_NONE : UNW_SLT_MEMORY; - return UNW_ESUCCESS; - } - return UNW_EBADREG; -} -_LIBUNWIND_WEAK_ALIAS(__unw_get_save_loc, unw_get_save_loc) - /// Move cursor to next frame. _LIBUNWIND_HIDDEN int __unw_step(unw_cursor_t *cursor) { _LIBUNWIND_TRACE_API("__unw_step(cursor=%p)", static_cast(cursor)); diff --git a/src/native/external/llvm-libunwind/src/libunwind_ext.h b/src/native/external/llvm-libunwind/src/libunwind_ext.h index da77ea3c4dab75..d8618a536748af 100644 --- a/src/native/external/llvm-libunwind/src/libunwind_ext.h +++ b/src/native/external/llvm-libunwind/src/libunwind_ext.h @@ -29,7 +29,8 @@ extern int __unw_step(unw_cursor_t *); extern int __unw_step_stage2(unw_cursor_t *); extern int __unw_get_reg(unw_cursor_t *, unw_regnum_t, unw_word_t *); extern int __unw_get_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t *); -extern int __unw_set_reg(unw_cursor_t *, unw_regnum_t, unw_word_t, unw_word_t *); +extern int __unw_set_reg(unw_cursor_t *, unw_regnum_t, unw_word_t); +extern void __unw_set_reg_location(unw_cursor_t *, unw_regnum_t, unw_word_t); extern int __unw_set_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t); _LIBUNWIND_TRACE_NO_INLINE extern int __unw_resume_with_frames_walked(unw_cursor_t *, unsigned); @@ -48,7 +49,6 @@ extern int __unw_is_fpreg(unw_cursor_t *, unw_regnum_t); extern int __unw_is_signal_frame(unw_cursor_t *); extern int __unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *); extern const char *__unw_strerror(int); -extern int __unw_get_save_loc(unw_cursor_t *, int, unw_save_loc_t *); #if defined(_AIX) extern uintptr_t __unw_get_data_rel_base(unw_cursor_t *);