mirror of
https://github.com/intel/llvm.git
synced 2026-01-15 12:25:46 +08:00
[lldb] Implement ABI::Fix{Code,Data}Address for AArch64
Implement FixCodeAddress and FixDataAddress for ABIMacOSX_arm64 and ABISysV_arm64 and add missing calls to RegisterContextUnwind. We need this to unwind on Apple Silicon where libraries like libSystem are arm64e even when the program being debugged is arm64. Differential revision: https://reviews.llvm.org/D100521
This commit is contained in:
@@ -117,12 +117,13 @@ public:
|
||||
// "pc".
|
||||
virtual bool CodeAddressIsValid(lldb::addr_t pc) = 0;
|
||||
|
||||
virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc) {
|
||||
// Some targets might use bits in a code address to indicate a mode switch.
|
||||
// ARM uses bit zero to signify a code address is thumb, so any ARM ABI
|
||||
// plug-ins would strip those bits.
|
||||
return pc;
|
||||
}
|
||||
/// Some targets might use bits in a code address to indicate a mode switch.
|
||||
/// ARM uses bit zero to signify a code address is thumb, so any ARM ABI
|
||||
/// plug-ins would strip those bits.
|
||||
/// @{
|
||||
virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc) { return pc; }
|
||||
virtual lldb::addr_t FixDataAddress(lldb::addr_t pc) { return pc; }
|
||||
/// @}
|
||||
|
||||
llvm::MCRegisterInfo &GetMCRegisterInfo() { return *m_mc_register_info_up; }
|
||||
|
||||
@@ -147,6 +148,10 @@ protected:
|
||||
lldb::ProcessWP m_process_wp;
|
||||
std::unique_ptr<llvm::MCRegisterInfo> m_mc_register_info_up;
|
||||
|
||||
virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc, lldb::addr_t mask) {
|
||||
return pc;
|
||||
}
|
||||
|
||||
private:
|
||||
ABI(const ABI &) = delete;
|
||||
const ABI &operator=(const ABI &) = delete;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "ABISysV_arm64.h"
|
||||
#include "Utility/ARM64_DWARF_Registers.h"
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
|
||||
LLDB_PLUGIN_DEFINE(ABIAArch64)
|
||||
|
||||
@@ -24,6 +25,18 @@ void ABIAArch64::Terminate() {
|
||||
ABIMacOSX_arm64::Terminate();
|
||||
}
|
||||
|
||||
lldb::addr_t ABIAArch64::FixCodeAddress(lldb::addr_t pc) {
|
||||
if (lldb::ProcessSP process_sp = GetProcessSP())
|
||||
return FixAddress(pc, process_sp->GetCodeAddressMask());
|
||||
return pc;
|
||||
}
|
||||
|
||||
lldb::addr_t ABIAArch64::FixDataAddress(lldb::addr_t pc) {
|
||||
if (lldb::ProcessSP process_sp = GetProcessSP())
|
||||
return FixAddress(pc, process_sp->GetDataAddressMask());
|
||||
return pc;
|
||||
}
|
||||
|
||||
std::pair<uint32_t, uint32_t>
|
||||
ABIAArch64::GetEHAndDWARFNums(llvm::StringRef name) {
|
||||
if (name == "pc")
|
||||
|
||||
@@ -16,7 +16,14 @@ public:
|
||||
static void Initialize();
|
||||
static void Terminate();
|
||||
|
||||
virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc) override;
|
||||
virtual lldb::addr_t FixDataAddress(lldb::addr_t pc) override;
|
||||
|
||||
protected:
|
||||
virtual lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) {
|
||||
return pc;
|
||||
}
|
||||
|
||||
std::pair<uint32_t, uint32_t>
|
||||
GetEHAndDWARFNums(llvm::StringRef name) override;
|
||||
|
||||
|
||||
@@ -815,6 +815,11 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl(
|
||||
return return_valobj_sp;
|
||||
}
|
||||
|
||||
lldb::addr_t ABIMacOSX_arm64::FixAddress(addr_t pc, addr_t mask) {
|
||||
lldb::addr_t pac_sign_extension = 0x0080000000000000ULL;
|
||||
return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
|
||||
}
|
||||
|
||||
void ABIMacOSX_arm64::Initialize() {
|
||||
PluginManager::RegisterPlugin(GetPluginNameStatic(), pluginDesc,
|
||||
CreateInstance);
|
||||
|
||||
@@ -62,6 +62,8 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) override;
|
||||
|
||||
// Static Functions
|
||||
|
||||
static void Initialize();
|
||||
|
||||
@@ -782,6 +782,11 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl(
|
||||
return return_valobj_sp;
|
||||
}
|
||||
|
||||
lldb::addr_t ABISysV_arm64::FixAddress(addr_t pc, addr_t mask) {
|
||||
lldb::addr_t pac_sign_extension = 0x0080000000000000ULL;
|
||||
return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
|
||||
}
|
||||
|
||||
void ABISysV_arm64::Initialize() {
|
||||
PluginManager::RegisterPlugin(GetPluginNameStatic(),
|
||||
"SysV ABI for AArch64 targets", CreateInstance);
|
||||
|
||||
@@ -67,6 +67,8 @@ public:
|
||||
|
||||
bool GetPointerReturnRegister(const char *&name) override;
|
||||
|
||||
lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) override;
|
||||
|
||||
// Static Functions
|
||||
|
||||
static void Initialize();
|
||||
|
||||
@@ -1730,6 +1730,10 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() {
|
||||
RegisterValue reg_value;
|
||||
if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
|
||||
old_caller_pc_value = reg_value.GetAsUInt64();
|
||||
if (ProcessSP process_sp = m_thread.GetProcess()) {
|
||||
if (ABISP abi = process_sp->GetABI())
|
||||
old_caller_pc_value = abi->FixCodeAddress(old_caller_pc_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1785,6 +1789,10 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() {
|
||||
if (ReadRegisterValueFromRegisterLocation(regloc, reg_info,
|
||||
reg_value)) {
|
||||
new_caller_pc_value = reg_value.GetAsUInt64();
|
||||
if (ProcessSP process_sp = m_thread.GetProcess()) {
|
||||
if (ABISP abi = process_sp->GetABI())
|
||||
new_caller_pc_value = abi->FixCodeAddress(new_caller_pc_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2121,6 +2129,12 @@ bool RegisterContextUnwind::ReadGPRValue(lldb::RegisterKind register_kind,
|
||||
}
|
||||
if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
|
||||
value = reg_value.GetAsUInt64();
|
||||
if (pc_register) {
|
||||
if (ProcessSP process_sp = m_thread.GetProcess()) {
|
||||
if (ABISP abi = process_sp->GetABI())
|
||||
value = abi->FixCodeAddress(value);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -2162,7 +2176,19 @@ bool RegisterContextUnwind::ReadRegister(const RegisterInfo *reg_info,
|
||||
lldb_regnum, regloc, m_frame_number - 1, is_pc_regnum))
|
||||
return false;
|
||||
|
||||
return ReadRegisterValueFromRegisterLocation(regloc, reg_info, value);
|
||||
bool result = ReadRegisterValueFromRegisterLocation(regloc, reg_info, value);
|
||||
if (result) {
|
||||
if (is_pc_regnum && value.GetType() == RegisterValue::eTypeUInt64) {
|
||||
addr_t reg_value = value.GetAsUInt64(LLDB_INVALID_ADDRESS);
|
||||
if (reg_value != LLDB_INVALID_ADDRESS) {
|
||||
if(ProcessSP process_sp = m_thread.GetProcess()) {
|
||||
if (ABISP abi = process_sp->GetABI())
|
||||
value = abi->FixCodeAddress(reg_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool RegisterContextUnwind::WriteRegister(const RegisterInfo *reg_info,
|
||||
|
||||
Reference in New Issue
Block a user