[Lldb-commits] [lldb] 69a3269 - Support AArch64 PAC elf-core register read
Muhammad Omair Javaid via lldb-commits
lldb-commits at lists.llvm.org
Mon May 3 04:06:19 PDT 2021
Author: Muhammad Omair Javaid
Date: 2021-05-03T16:04:47+05:00
New Revision: 69a3269250715e31ec49be94065c1c8787a3d305
URL: https://github.com/llvm/llvm-project/commit/69a3269250715e31ec49be94065c1c8787a3d305
DIFF: https://github.com/llvm/llvm-project/commit/69a3269250715e31ec49be94065c1c8787a3d305.diff
LOG: Support AArch64 PAC elf-core register read
This adds support for reading AArch64 Pointer Authentication regset
from elf-core file. Also includes a test-case for the same. Furthermore
there is also a slight refactoring of RegisterContextPOSIXCore_arm64
members and constructor. linux-aarch64-pac.core file is generated using
lldb/test/API/functionalities/postmortem/elf-core/main.c with following
clang arguments:
-march=armv8.5-a -mbranch-protection=pac-ret+leaf -nostdlib -static -g
Reviewed By: DavidSpickett
Differential Revision: https://reviews.llvm.org/D99941
Added:
lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64-pac.core
Modified:
lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
Removed:
################################################################################
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
index 06b200e19f1e2..c4e7eda1e5d69 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
@@ -43,6 +43,10 @@ bool RegisterContextPOSIX_arm64::IsSVE(unsigned reg) const {
return m_register_info_up->IsSVEReg(reg);
}
+bool RegisterContextPOSIX_arm64::IsPAuth(unsigned reg) const {
+ return m_register_info_up->IsPAuthReg(reg);
+}
+
RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(
lldb_private::Thread &thread,
std::unique_ptr<RegisterInfoPOSIX_arm64> register_info)
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
index a3f07bb2823b1..7c301599d3af6 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
@@ -54,6 +54,7 @@ class RegisterContextPOSIX_arm64 : public lldb_private::RegisterContext {
size_t GetFPUSize() { return sizeof(RegisterInfoPOSIX_arm64::FPU); }
bool IsSVE(unsigned reg) const;
+ bool IsPAuth(unsigned reg) const;
bool IsSVEZ(unsigned reg) const { return m_register_info_up->IsSVEZReg(reg); }
bool IsSVEP(unsigned reg) const { return m_register_info_up->IsSVEPReg(reg); }
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
index df6e44faefbfb..ba873ba4436ba 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
@@ -109,6 +109,7 @@ class RegisterInfoPOSIX_arm64
}
bool IsSVEEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskSVE); }
+ bool IsPAuthEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskPAuth); }
bool IsSVEReg(unsigned reg) const;
bool IsSVEZReg(unsigned reg) const;
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
index 9379316d1042d..34fd16da38885 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
@@ -21,32 +21,43 @@ std::unique_ptr<RegisterContextCorePOSIX_arm64>
RegisterContextCorePOSIX_arm64::Create(Thread &thread, const ArchSpec &arch,
const DataExtractor &gpregset,
llvm::ArrayRef<CoreNote> notes) {
- DataExtractor sveregset =
- getRegset(notes, arch.GetTriple(), AARCH64_SVE_Desc);
-
Flags opt_regsets = RegisterInfoPOSIX_arm64::eRegsetMaskDefault;
- if (sveregset.GetByteSize() > sizeof(sve::user_sve_header))
+
+ DataExtractor sve_data = getRegset(notes, arch.GetTriple(), AARCH64_SVE_Desc);
+ if (sve_data.GetByteSize() > sizeof(sve::user_sve_header))
opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskSVE);
+
+ // Pointer Authentication register set data is based on struct
+ // user_pac_mask declared in ptrace.h. See reference implementation
+ // in Linux kernel source at arch/arm64/include/uapi/asm/ptrace.h.
+ DataExtractor pac_data = getRegset(notes, arch.GetTriple(), AARCH64_PAC_Desc);
+ if (pac_data.GetByteSize() >= sizeof(uint64_t) * 2)
+ opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskPAuth);
+
auto register_info_up =
std::make_unique<RegisterInfoPOSIX_arm64>(arch, opt_regsets);
return std::unique_ptr<RegisterContextCorePOSIX_arm64>(
new RegisterContextCorePOSIX_arm64(thread, std::move(register_info_up),
- gpregset, sveregset, notes));
+ gpregset, notes));
}
RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
Thread &thread, std::unique_ptr<RegisterInfoPOSIX_arm64> register_info,
- const DataExtractor &gpregset, const DataExtractor &sveregset,
- llvm::ArrayRef<CoreNote> notes)
- : RegisterContextPOSIX_arm64(thread, std::move(register_info)),
- m_sveregset(sveregset) {
- m_gpr_buffer = std::make_shared<DataBufferHeap>(gpregset.GetDataStart(),
- gpregset.GetByteSize());
- m_gpr.SetData(m_gpr_buffer);
- m_gpr.SetByteOrder(gpregset.GetByteOrder());
-
- m_fpregset = getRegset(
- notes, m_register_info_up->GetTargetArchitecture().GetTriple(), FPR_Desc);
+ const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
+ : RegisterContextPOSIX_arm64(thread, std::move(register_info)) {
+ m_gpr_data.SetData(std::make_shared<DataBufferHeap>(gpregset.GetDataStart(),
+ gpregset.GetByteSize()));
+ m_gpr_data.SetByteOrder(gpregset.GetByteOrder());
+
+ const llvm::Triple &target_triple =
+ m_register_info_up->GetTargetArchitecture().GetTriple();
+ m_fpr_data = getRegset(notes, target_triple, FPR_Desc);
+
+ if (m_register_info_up->IsSVEEnabled())
+ m_sve_data = getRegset(notes, target_triple, AARCH64_SVE_Desc);
+
+ if (m_register_info_up->IsPAuthEnabled())
+ m_pac_data = getRegset(notes, target_triple, AARCH64_PAC_Desc);
ConfigureRegisterContext();
}
@@ -68,16 +79,16 @@ bool RegisterContextCorePOSIX_arm64::WriteFPR() {
}
const uint8_t *RegisterContextCorePOSIX_arm64::GetSVEBuffer(uint64_t offset) {
- return m_sveregset.GetDataStart() + offset;
+ return m_sve_data.GetDataStart() + offset;
}
void RegisterContextCorePOSIX_arm64::ConfigureRegisterContext() {
- if (m_sveregset.GetByteSize() > sizeof(sve::user_sve_header)) {
+ if (m_sve_data.GetByteSize() > sizeof(sve::user_sve_header)) {
uint64_t sve_header_field_offset = 8;
- m_sve_vector_length = m_sveregset.GetU16(&sve_header_field_offset);
+ m_sve_vector_length = m_sve_data.GetU16(&sve_header_field_offset);
sve_header_field_offset = 12;
uint16_t sve_header_flags_field =
- m_sveregset.GetU16(&sve_header_field_offset);
+ m_sve_data.GetU16(&sve_header_field_offset);
if ((sve_header_flags_field & sve::ptrace_regs_mask) ==
sve::ptrace_regs_fpsimd)
m_sve_state = SVEState::FPSIMD;
@@ -120,7 +131,7 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
offset = reg_info->byte_offset;
if (offset + reg_info->byte_size <= GetGPRSize()) {
- uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+ uint64_t v = m_gpr_data.GetMaxU64(&offset, reg_info->byte_size);
if (offset == reg_info->byte_offset + reg_info->byte_size) {
value = v;
return true;
@@ -135,8 +146,8 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
if (m_sve_state == SVEState::Disabled) {
// SVE is disabled take legacy route for FPU register access
offset -= GetGPRSize();
- if (offset < m_fpregset.GetByteSize()) {
- value.SetFromMemoryData(reg_info, m_fpregset.GetDataStart() + offset,
+ if (offset < m_fpr_data.GetByteSize()) {
+ value.SetFromMemoryData(reg_info, m_fpr_data.GetDataStart() + offset,
reg_info->byte_size, lldb::eByteOrderLittle,
error);
return error.Success();
@@ -168,7 +179,7 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
}
assert(sve_reg_num != LLDB_INVALID_REGNUM);
- assert(offset < m_sveregset.GetByteSize());
+ assert(offset < m_sve_data.GetByteSize());
value.SetFromMemoryData(reg_info, GetSVEBuffer(offset),
reg_info->byte_size, lldb::eByteOrderLittle,
error);
@@ -190,7 +201,7 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
if (IsSVEZ(reg)) {
byte_size = 16;
offset = CalculateSVEOffset(reg_info);
- assert(offset < m_sveregset.GetByteSize());
+ assert(offset < m_sve_data.GetByteSize());
src = GetSVEBuffer(offset);
}
value.SetFromMemoryData(reg_info, src, byte_size, lldb::eByteOrderLittle,
@@ -198,7 +209,7 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
} break;
case SVEState::Full:
offset = CalculateSVEOffset(reg_info);
- assert(offset < m_sveregset.GetByteSize());
+ assert(offset < m_sve_data.GetByteSize());
value.SetFromMemoryData(reg_info, GetSVEBuffer(offset),
reg_info->byte_size, lldb::eByteOrderLittle,
error);
@@ -207,6 +218,11 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
default:
return false;
}
+ } else if (IsPAuth(reg)) {
+ offset = reg_info->byte_offset - m_register_info_up->GetPAuthOffset();
+ assert(offset < m_pac_data.GetByteSize());
+ value.SetFromMemoryData(reg_info, m_pac_data.GetDataStart() + offset,
+ reg_info->byte_size, lldb::eByteOrderLittle, error);
} else
return false;
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
index ec63eaa861119..3988e3539b897 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
@@ -42,7 +42,6 @@ class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 {
lldb_private::Thread &thread,
std::unique_ptr<RegisterInfoPOSIX_arm64> register_info,
const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &sveregset,
llvm::ArrayRef<lldb_private::CoreNote> notes);
bool ReadGPR() override;
@@ -54,10 +53,10 @@ class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 {
bool WriteFPR() override;
private:
- lldb::DataBufferSP m_gpr_buffer;
- lldb_private::DataExtractor m_gpr;
- lldb_private::DataExtractor m_fpregset;
- lldb_private::DataExtractor m_sveregset;
+ lldb_private::DataExtractor m_gpr_data;
+ lldb_private::DataExtractor m_fpr_data;
+ lldb_private::DataExtractor m_sve_data;
+ lldb_private::DataExtractor m_pac_data;
SVEState m_sve_state;
uint16_t m_sve_vector_length = 0;
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
index 25abd7ed54b7f..b048d39dbc527 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
@@ -111,6 +111,10 @@ constexpr RegsetDesc AARCH64_SVE_Desc[] = {
{llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_SVE},
};
+constexpr RegsetDesc AARCH64_PAC_Desc[] = {
+ {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_PAC_MASK},
+};
+
constexpr RegsetDesc PPC_VMX_Desc[] = {
{llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
{llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
diff --git a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
index 26e85e34da730..6f8d05101baaf 100644
--- a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
+++ b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
@@ -443,6 +443,21 @@ def test_aarch64_sve_regs_full(self):
self.expect("register read --all")
+ @skipIfLLVMTargetMissing("AArch64")
+ def test_aarch64_pac_regs(self):
+ # Test AArch64/Linux Pointer Authenication register read
+ target = self.dbg.CreateTarget(None)
+ self.assertTrue(target, VALID_TARGET)
+ process = target.LoadCore("linux-aarch64-pac.core")
+
+ values = {"data_mask": "0x007f00000000000", "code_mask": "0x007f00000000000"}
+
+ for regname, value in values.items():
+ self.expect("register read {}".format(regname),
+ substrs=["{} = {}".format(regname, value)])
+
+ self.expect("register read --all")
+
@skipIfLLVMTargetMissing("ARM")
def test_arm_core(self):
# check 32 bit ARM core file
diff --git a/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64-pac.core b/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64-pac.core
new file mode 100644
index 0000000000000..3e89a36ec830e
Binary files /dev/null and b/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64-pac.core
diff er
More information about the lldb-commits
mailing list