-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[lldb][FreeBSD][AArch64] Enable register field detection #85058
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-lldb Author: David Spickett (DavidSpickett) ChangesThis extends the existing register fields support from AArch64 Linux
Linux and FreeBSD both have HWCAP/HWCAP2 so the detection mechanism I have confirmed that FreeBSD's treatment of CPSR (spsr as the kernel (see For testing I've enabled the same live process test as Linux Note that the latter does not need XML support because when reading The Patch is 31.18 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/85058.diff 20 Files Affected:
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h
index 0000484beac999..b7f659ef24de2c 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h
@@ -9,14 +9,13 @@
#ifndef lldb_NativeRegisterContextFreeBSD_h
#define lldb_NativeRegisterContextFreeBSD_h
-#include "lldb/Host/common/NativeThreadProtocol.h"
-
#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h"
namespace lldb_private {
namespace process_freebsd {
class NativeProcessFreeBSD;
+class NativeThreadFreeBSD;
class NativeRegisterContextFreeBSD
: public virtual NativeRegisterContextRegisterInfo {
@@ -28,7 +27,7 @@ class NativeRegisterContextFreeBSD
// executable.
static NativeRegisterContextFreeBSD *
CreateHostNativeRegisterContextFreeBSD(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread);
+ NativeThreadFreeBSD &native_thread);
virtual llvm::Error
CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source) = 0;
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp
index 2c50176643878d..f19085600d6c93 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp
@@ -29,12 +29,12 @@ using namespace lldb_private::process_freebsd;
NativeRegisterContextFreeBSD *
NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) {
return new NativeRegisterContextFreeBSD_arm(target_arch, native_thread);
}
NativeRegisterContextFreeBSD_arm::NativeRegisterContextFreeBSD_arm(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread)
: NativeRegisterContextRegisterInfo(
native_thread, new RegisterInfoPOSIX_arm(target_arch)) {}
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
index 9db5970af653e3..28ea8b7ac11826 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
@@ -16,6 +16,7 @@
#include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h"
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "Plugins/Process/Utility/RegisterFlagsDetector_arm64.h"
#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
// clang-format off
@@ -28,14 +29,29 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_freebsd;
+// A NativeRegisterContext is constructed per thread, but all threads' registers
+// will contain the same fields. Therefore this mutex prevents each instance
+// competing with the other, and subsequent instances from having to detect the
+// fields all over again.
+static std::mutex g_register_flags_detector_mutex;
+static Arm64RegisterFlagsDetector g_register_flags_detector;
+
NativeRegisterContextFreeBSD *
NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) {
+ std::lock_guard<std::mutex> lock(g_register_flags_detector_mutex);
+ if (!g_register_flags_detector.HasDetected()) {
+ NativeProcessFreeBSD &process = native_thread.GetProcess();
+ g_register_flags_detector.DetectFields(
+ process.GetAuxValue(AuxVector::AUXV_FREEBSD_AT_HWCAP).value_or(0),
+ process.GetAuxValue(AuxVector::AUXV_AT_HWCAP2).value_or(0));
+ }
+
return new NativeRegisterContextFreeBSD_arm64(target_arch, native_thread);
}
NativeRegisterContextFreeBSD_arm64::NativeRegisterContextFreeBSD_arm64(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread)
: NativeRegisterContextRegisterInfo(
native_thread, new RegisterInfoPOSIX_arm64(target_arch, 0))
#ifdef LLDB_HAS_FREEBSD_WATCHPOINT
@@ -43,6 +59,10 @@ NativeRegisterContextFreeBSD_arm64::NativeRegisterContextFreeBSD_arm64(
m_read_dbreg(false)
#endif
{
+ g_register_flags_detector.UpdateRegisterInfo(
+ GetRegisterInfoInterface().GetRegisterInfo(),
+ GetRegisterInfoInterface().GetRegisterCount());
+
::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
::memset(&m_hbp_regs, 0, sizeof(m_hbp_regs));
}
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h
index 799209e26e868d..ba876006c6c530 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h
@@ -37,7 +37,7 @@ class NativeRegisterContextFreeBSD_arm64
public NativeRegisterContextDBReg_arm64 {
public:
NativeRegisterContextFreeBSD_arm64(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread);
+ NativeThreadFreeBSD &native_thread);
uint32_t GetRegisterSetCount() const override;
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp
index 0349f13945e31c..090d0f3802c3bb 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp
@@ -30,12 +30,12 @@ using namespace lldb_private::process_freebsd;
NativeRegisterContextFreeBSD *
NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) {
return new NativeRegisterContextFreeBSD_mips64(target_arch, native_thread);
}
NativeRegisterContextFreeBSD_mips64::NativeRegisterContextFreeBSD_mips64(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread)
: NativeRegisterContextRegisterInfo(
native_thread, new RegisterContextFreeBSD_mips64(target_arch)) {}
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp
index bdb57251f706a4..fd5eb1ee2a1c84 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp
@@ -67,7 +67,7 @@ static const RegisterSet g_reg_sets_powerpc[k_num_register_sets] = {
NativeRegisterContextFreeBSD *
NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) {
return new NativeRegisterContextFreeBSD_powerpc(target_arch, native_thread);
}
@@ -83,7 +83,7 @@ CreateRegisterInfoInterface(const ArchSpec &target_arch) {
}
NativeRegisterContextFreeBSD_powerpc::NativeRegisterContextFreeBSD_powerpc(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread)
: NativeRegisterContextRegisterInfo(
native_thread, CreateRegisterInfoInterface(target_arch)) {}
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp
index f4171a134aeb79..5eed2d02b0a8ce 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp
@@ -237,7 +237,7 @@ static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {
NativeRegisterContextFreeBSD *
NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) {
return new NativeRegisterContextFreeBSD_x86_64(target_arch, native_thread);
}
@@ -258,7 +258,7 @@ CreateRegisterInfoInterface(const ArchSpec &target_arch) {
}
NativeRegisterContextFreeBSD_x86_64::NativeRegisterContextFreeBSD_x86_64(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread)
: NativeRegisterContextRegisterInfo(
native_thread, CreateRegisterInfoInterface(target_arch)),
NativeRegisterContextDBReg_x86(native_thread), m_regset_offsets({0}) {
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
index 449ec27e0da8fc..a0de7751c7e55c 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
@@ -316,6 +316,10 @@ NativeThreadFreeBSD::CopyWatchpointsFrom(NativeThreadFreeBSD &source) {
return s;
}
+NativeProcessFreeBSD &NativeThreadFreeBSD::GetProcess() {
+ return static_cast<NativeProcessFreeBSD &>(m_process);
+}
+
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
NativeThreadFreeBSD::GetSiginfo() const {
Log *log = GetLog(POSIXLog::Process);
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
index 6294a7a7096356..edfb07658e19c7 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
@@ -47,6 +47,8 @@ class NativeThreadFreeBSD : public NativeThreadProtocol {
Status RemoveHardwareBreakpoint(lldb::addr_t addr) override;
+ NativeProcessFreeBSD &GetProcess();
+
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
GetSiginfo() const override;
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
index 9b5f7aef1efe53..d72b6ce9b0c8e3 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -23,7 +23,7 @@
#include "Plugins/Process/Linux/Procfs.h"
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
#include "Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h"
-#include "Plugins/Process/Utility/RegisterFlagsLinux_arm64.h"
+#include "Plugins/Process/Utility/RegisterFlagsDetector_arm64.h"
#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
// System includes - They have to be included after framework includes because
@@ -72,8 +72,8 @@ using namespace lldb_private::process_linux;
// will contain the same fields. Therefore this mutex prevents each instance
// competing with the other, and subsequent instances from having to detect the
// fields all over again.
-static std::mutex g_register_flags_mutex;
-static LinuxArm64RegisterFlags g_register_flags;
+static std::mutex g_register_flags_detector_mutex;
+static Arm64RegisterFlagsDetector g_register_flags_detector;
std::unique_ptr<NativeRegisterContextLinux>
NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
@@ -144,10 +144,10 @@ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskTLS);
- std::lock_guard<std::mutex> lock(g_register_flags_mutex);
- if (!g_register_flags.HasDetected())
- g_register_flags.DetectFields(auxv_at_hwcap.value_or(0),
- auxv_at_hwcap2.value_or(0));
+ std::lock_guard<std::mutex> lock(g_register_flags_detector_mutex);
+ if (!g_register_flags_detector.HasDetected())
+ g_register_flags_detector.DetectFields(auxv_at_hwcap.value_or(0),
+ auxv_at_hwcap2.value_or(0));
auto register_info_up =
std::make_unique<RegisterInfoPOSIX_arm64>(target_arch, opt_regsets);
@@ -171,7 +171,7 @@ NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
: NativeRegisterContextRegisterInfo(native_thread,
register_info_up.release()),
NativeRegisterContextLinux(native_thread) {
- g_register_flags.UpdateRegisterInfo(
+ g_register_flags_detector.UpdateRegisterInfo(
GetRegisterInfoInterface().GetRegisterInfo(),
GetRegisterInfoInterface().GetRegisterCount());
diff --git a/lldb/source/Plugins/Process/Utility/AuxVector.h b/lldb/source/Plugins/Process/Utility/AuxVector.h
index 3b0f55d35e5d11..9e489b05ab5ee6 100644
--- a/lldb/source/Plugins/Process/Utility/AuxVector.h
+++ b/lldb/source/Plugins/Process/Utility/AuxVector.h
@@ -20,25 +20,34 @@ class AuxVector {
AuxVector(const lldb_private::DataExtractor &data);
/// Constants describing the type of entry.
- /// On Linux, running "LD_SHOW_AUXV=1 ./executable" will spew AUX
+ /// On Linux and FreeBSD, running "LD_SHOW_AUXV=1 ./executable" will spew AUX
/// information. Added AUXV prefix to avoid potential conflicts with system-
- /// defined macros
+ /// defined macros. For FreeBSD, the numbers can be found in sys/elf_common.h.
+ ///
+ /// Linux and FreeBSD values diverge, so the FreeBSD classes will convert
+ /// some entries to the Linux AT_ value so that LLDB only has to use
+ /// the constants listed here when asking the AuxVector for a value.
enum EntryType {
- AUXV_AT_NULL = 0, ///< End of auxv.
- AUXV_AT_IGNORE = 1, ///< Ignore entry.
- AUXV_AT_EXECFD = 2, ///< File descriptor of program.
- AUXV_AT_PHDR = 3, ///< Program headers.
- AUXV_AT_PHENT = 4, ///< Size of program header.
- AUXV_AT_PHNUM = 5, ///< Number of program headers.
- AUXV_AT_PAGESZ = 6, ///< Page size.
- AUXV_AT_BASE = 7, ///< Interpreter base address.
- AUXV_AT_FLAGS = 8, ///< Flags.
- AUXV_AT_ENTRY = 9, ///< Program entry point.
- AUXV_AT_NOTELF = 10, ///< Set if program is not an ELF.
- AUXV_AT_UID = 11, ///< UID.
- AUXV_AT_EUID = 12, ///< Effective UID.
- AUXV_AT_GID = 13, ///< GID.
- AUXV_AT_EGID = 14, ///< Effective GID.
+ AUXV_AT_NULL = 0, ///< End of auxv.
+ AUXV_AT_IGNORE = 1, ///< Ignore entry.
+ AUXV_AT_EXECFD = 2, ///< File descriptor of program.
+ AUXV_AT_PHDR = 3, ///< Program headers.
+ AUXV_AT_PHENT = 4, ///< Size of program header.
+ AUXV_AT_PHNUM = 5, ///< Number of program headers.
+ AUXV_AT_PAGESZ = 6, ///< Page size.
+ AUXV_AT_BASE = 7, ///< Interpreter base address.
+ AUXV_AT_FLAGS = 8, ///< Flags.
+ AUXV_AT_ENTRY = 9, ///< Program entry point.
+ AUXV_AT_NOTELF = 10, ///< Set if program is not an ELF.
+ AUXV_AT_UID = 11, ///< UID.
+ AUXV_AT_EUID = 12, ///< Effective UID.
+ AUXV_AT_GID = 13, ///< GID.
+ AUXV_AT_EGID = 14, ///< Effective GID.
+
+ // At this point Linux and FreeBSD diverge and many of the following values
+ // are Linux specific. If you use them make sure you are in Linux specific
+ // code or they have the same value on other platforms.
+
AUXV_AT_CLKTCK = 17, ///< Clock frequency (e.g. times(2)).
AUXV_AT_PLATFORM = 15, ///< String identifying platform.
AUXV_AT_HWCAP =
@@ -60,6 +69,10 @@ class AuxVector {
AUXV_AT_L1D_CACHESHAPE = 35,
AUXV_AT_L2_CACHESHAPE = 36,
AUXV_AT_L3_CACHESHAPE = 37,
+
+ // Platform specific values which may overlap the Linux values.
+
+ AUXV_FREEBSD_AT_HWCAP = 25, ///< FreeBSD specific AT_HWCAP value.
};
std::optional<uint64_t> GetAuxValue(enum EntryType entry_type) const;
diff --git a/lldb/source/Plugins/Process/Utility/CMakeLists.txt b/lldb/source/Plugins/Process/Utility/CMakeLists.txt
index 37b53b7e3e7edd..5df4a9e5ac5c86 100644
--- a/lldb/source/Plugins/Process/Utility/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/Utility/CMakeLists.txt
@@ -47,7 +47,7 @@ add_lldb_library(lldbPluginProcessUtility
RegisterContextThreadMemory.cpp
RegisterContextWindows_i386.cpp
RegisterContextWindows_x86_64.cpp
- RegisterFlagsLinux_arm64.cpp
+ RegisterFlagsDetector_arm64.cpp
RegisterInfos_x86_64_with_base_shared.cpp
RegisterInfoPOSIX_arm.cpp
RegisterInfoPOSIX_arm64.cpp
diff --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp
similarity index 80%
rename from lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp
rename to lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp
index 51553817921f35..54c1aae36f231c 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterFlagsLinux_arm64.cpp --------------------------------------===//
+//===-- RegisterFlagsDetector_arm64.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,11 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#include "RegisterFlagsLinux_arm64.h"
+#include "RegisterFlagsDetector_arm64.h"
#include "lldb/lldb-private-types.h"
// This file is built on all systems because it is used by native processes and
// core files, so we manually define the needed HWCAP values here.
+// These values are the same for Linux and FreeBSD.
#define HWCAP_FPHP (1ULL << 9)
#define HWCAP_ASIMDHP (1ULL << 10)
@@ -24,34 +25,35 @@
using namespace lldb_private;
-LinuxArm64RegisterFlags::Fields
-LinuxArm64RegisterFlags::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) {
+Arm64RegisterFlagsDetector::Fields
+Arm64RegisterFlagsDetector::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) {
(void)hwcap;
(void)hwcap2;
- // Represents the pseudo register that lldb-server builds, which itself
- // matches the architectural register SCVR. The fields match SVCR in the Arm
- // manual.
+ // Represents the pseudo register that lldb-server on Linux builds, which
+ // itself matches the architectural register SCVR. The fields match SVCR in
+ // the Arm manual.
return {
{"ZA", 1},
{"SM", 0},
};
}
-LinuxArm64RegisterFlags::Fields
-LinuxArm64RegisterFlags::DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2) {
+Arm64RegisterFlagsDetector::Fields
+Arm64RegisterFlagsDetector::DetectMTECtrlFields(uint64_t hwcap,
+ uint64_t hwcap2) {
(void)hwcap;
(void)hwcap2;
- // Represents the contents of NT_ARM_TAGGED_ADDR_CTRL and the value passed
- // to prctl(PR_TAGGED_ADDR_CTRL...). Fields are derived from the defines
- // used to build the value.
+ // Represents the contents of Linux's NT_ARM_TAGGED_ADDR_CTRL and the value
+ // passed to prctl(PR_TAGGED_ADDR_CTRL...). Fields are derived from the
+ // defines used to build the value.
return {{"TAGS", 3, 18}, // 16 bit bitfield shifted up by PR_MTE_TAG_SHIFT.
{"TCF_ASYNC", 2},
{"TCF_SYNC", 1},
{"TAGGED_ADDR_ENABLE", 0}};
}
-LinuxArm64RegisterFlags::Fields
-LinuxArm64RegisterFlags::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2) {
+Arm64RegisterFlagsDetector::Fields
+Arm64RegisterFlagsDetector::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2) {
std::vector<RegisterFlags::Field> fpcr_fields{
{"AHP", 26}, {"DN", 25}, {"FZ", 24}, {"RMode", 22, 23},
// Bits 21-20 are "Stride" which is unused in AArch64 state.
@@ -86,8 +88,8 @@ LinuxArm64RegisterFlags::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2) {
return fpcr_fields;
}
-LinuxArm64RegisterFlags...
[truncated]
|
This extends the existing register fields support from AArch64 Linux to AArch64 FreeBSD. So you will now see output like this: ``` (lldb) register read cpsr cpsr = 0x60000200 = (N = 0, Z = 1, C = 1, V = 0, DIT = 0, SS = 0, IL = 0, SSBS = 0, D = 1, A = 0, I = 0, F = 0, nRW = 0, EL = 0, SP = 0) ``` Linux and FreeBSD both have HWCAP/HWCAP2 so the detection mechanism is the same and I've renamed the detector class to reflect that. I have confirmed that FreeBSD's treatment of CPSR (spsr as the kernel calls it) is similair enough that we can use the same field information. (see `sys/arm64/include/armreg.h` and `PSR_SETTABLE_64`) For testing I've enabled the same live process test as Linux and added a shell test using an existing FreeBSD core file. Note that the latter does not need XML support because when reading a core file we are not sending the information via target.xml, it's just internal to LLDB. The `svcr` and `mte_ctrl` registers will not appear on FreeBSD at all so I've not made their information conditional, it'll just never be used.
146be6d
to
a18b685
Compare
@emaste the previous PRs have landed so this is just a single commit now, easier to review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For a follow up patch, it would be nice to add the ability to expand registers that are ValueObjectRegister.h/.cpp to that a register value object can tell us how many children and vend a ValueObjectRegisterField
object for each field where each one has the name, value and possibly summary if the field is an enum that has a string representation.
Like for the 32 bit ARM CPSR register's mode field which is 5 bits ([4:0]) with values like:
CPSR_M_USR = 0x10U
CPSR_M_FIQ = 0x11U
CPSR_M_IRQ = 0x12U
CPSR_M_SVC = 0x13U
CPSR_M_MON = 0x16U
CPSR_M_ABT = 0x17U
CPSR_M_HYP = 0x1AU
CPSR_M_UND = 0x1BU
CPSR_M_SYS = 0x1FU
Then if the value of M
was 0x10, we would show "0x10" as the value of the ValueObjectRegisterField, and the summary would be "CPSR_M_USR".
https://discourse.llvm.org/t/rfc-adding-register-field-enums-to-lldb/77275 aims to add the type information we need for that, and that will initially be visible via I haven't done anything with value objects yet, just focused on from |
@emaste ping! |
@zxombie fyi |
It looks like |
I'm currently assuming that the process classes will check those HWCAPs and only add those registers to the register info if they exist. This code only patches registers that are already in the info, it doesn't add any new ones. That said, explicit is better than implicit, and I already have the HWCAP values to hand, so I will try checking them to see what should exist or not. |
This extends the existing register fields support from AArch64 Linux
to AArch64 FreeBSD. So you will now see output like this:
Linux and FreeBSD both have HWCAP/HWCAP2 so the detection mechanism
is the same and I've renamed the detector class to reflect that.
I have confirmed that FreeBSD's treatment of CPSR (spsr as the kernel
calls it) is similair enough that we can use the same field information.
(see
sys/arm64/include/armreg.h
andPSR_SETTABLE_64
)For testing I've enabled the same live process test as Linux
and added a shell test using an existing FreeBSD core file.
Note that the latter does not need XML support because when reading
a core file we are not sending the information via target.xml,
it's just internal to LLDB.
The
svcr
andmte_ctrl
registers will not appear on FreeBSDat all so I've not made their information conditional, it'll just
never be used.