Skip to content

Commit ea4cf92

Browse files
[lldb][FreeBSD][AArch64] Enable register field detection (#85058)
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.
1 parent bf7a775 commit ea4cf92

19 files changed

+109
-62
lines changed

lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@
99
#ifndef lldb_NativeRegisterContextFreeBSD_h
1010
#define lldb_NativeRegisterContextFreeBSD_h
1111

12-
#include "lldb/Host/common/NativeThreadProtocol.h"
13-
1412
#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h"
1513

1614
namespace lldb_private {
1715
namespace process_freebsd {
1816

1917
class NativeProcessFreeBSD;
18+
class NativeThreadFreeBSD;
2019

2120
class NativeRegisterContextFreeBSD
2221
: public virtual NativeRegisterContextRegisterInfo {
@@ -28,7 +27,7 @@ class NativeRegisterContextFreeBSD
2827
// executable.
2928
static NativeRegisterContextFreeBSD *
3029
CreateHostNativeRegisterContextFreeBSD(const ArchSpec &target_arch,
31-
NativeThreadProtocol &native_thread);
30+
NativeThreadFreeBSD &native_thread);
3231
virtual llvm::Error
3332
CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source) = 0;
3433

lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ using namespace lldb_private::process_freebsd;
2929

3030
NativeRegisterContextFreeBSD *
3131
NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
32-
const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
32+
const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) {
3333
return new NativeRegisterContextFreeBSD_arm(target_arch, native_thread);
3434
}
3535

3636
NativeRegisterContextFreeBSD_arm::NativeRegisterContextFreeBSD_arm(
37-
const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
37+
const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread)
3838
: NativeRegisterContextRegisterInfo(
3939
native_thread, new RegisterInfoPOSIX_arm(target_arch)) {}
4040

lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h"
1818
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
19+
#include "Plugins/Process/Utility/RegisterFlagsDetector_arm64.h"
1920
#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
2021

2122
// clang-format off
@@ -28,21 +29,40 @@ using namespace lldb;
2829
using namespace lldb_private;
2930
using namespace lldb_private::process_freebsd;
3031

32+
// A NativeRegisterContext is constructed per thread, but all threads' registers
33+
// will contain the same fields. Therefore this mutex prevents each instance
34+
// competing with the other, and subsequent instances from having to detect the
35+
// fields all over again.
36+
static std::mutex g_register_flags_detector_mutex;
37+
static Arm64RegisterFlagsDetector g_register_flags_detector;
38+
3139
NativeRegisterContextFreeBSD *
3240
NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
33-
const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
41+
const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) {
42+
std::lock_guard<std::mutex> lock(g_register_flags_detector_mutex);
43+
if (!g_register_flags_detector.HasDetected()) {
44+
NativeProcessFreeBSD &process = native_thread.GetProcess();
45+
g_register_flags_detector.DetectFields(
46+
process.GetAuxValue(AuxVector::AUXV_FREEBSD_AT_HWCAP).value_or(0),
47+
process.GetAuxValue(AuxVector::AUXV_AT_HWCAP2).value_or(0));
48+
}
49+
3450
return new NativeRegisterContextFreeBSD_arm64(target_arch, native_thread);
3551
}
3652

3753
NativeRegisterContextFreeBSD_arm64::NativeRegisterContextFreeBSD_arm64(
38-
const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
54+
const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread)
3955
: NativeRegisterContextRegisterInfo(
4056
native_thread, new RegisterInfoPOSIX_arm64(target_arch, 0))
4157
#ifdef LLDB_HAS_FREEBSD_WATCHPOINT
4258
,
4359
m_read_dbreg(false)
4460
#endif
4561
{
62+
g_register_flags_detector.UpdateRegisterInfo(
63+
GetRegisterInfoInterface().GetRegisterInfo(),
64+
GetRegisterInfoInterface().GetRegisterCount());
65+
4666
::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
4767
::memset(&m_hbp_regs, 0, sizeof(m_hbp_regs));
4868
}

lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class NativeRegisterContextFreeBSD_arm64
3737
public NativeRegisterContextDBReg_arm64 {
3838
public:
3939
NativeRegisterContextFreeBSD_arm64(const ArchSpec &target_arch,
40-
NativeThreadProtocol &native_thread);
40+
NativeThreadFreeBSD &native_thread);
4141

4242
uint32_t GetRegisterSetCount() const override;
4343

lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ using namespace lldb_private::process_freebsd;
3030

3131
NativeRegisterContextFreeBSD *
3232
NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
33-
const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
33+
const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) {
3434
return new NativeRegisterContextFreeBSD_mips64(target_arch, native_thread);
3535
}
3636

3737
NativeRegisterContextFreeBSD_mips64::NativeRegisterContextFreeBSD_mips64(
38-
const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
38+
const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread)
3939
: NativeRegisterContextRegisterInfo(
4040
native_thread, new RegisterContextFreeBSD_mips64(target_arch)) {}
4141

lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ static const RegisterSet g_reg_sets_powerpc[k_num_register_sets] = {
6767

6868
NativeRegisterContextFreeBSD *
6969
NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
70-
const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
70+
const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) {
7171
return new NativeRegisterContextFreeBSD_powerpc(target_arch, native_thread);
7272
}
7373

@@ -83,7 +83,7 @@ CreateRegisterInfoInterface(const ArchSpec &target_arch) {
8383
}
8484

8585
NativeRegisterContextFreeBSD_powerpc::NativeRegisterContextFreeBSD_powerpc(
86-
const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
86+
const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread)
8787
: NativeRegisterContextRegisterInfo(
8888
native_thread, CreateRegisterInfoInterface(target_arch)) {}
8989

lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {
237237

238238
NativeRegisterContextFreeBSD *
239239
NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
240-
const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
240+
const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) {
241241
return new NativeRegisterContextFreeBSD_x86_64(target_arch, native_thread);
242242
}
243243

@@ -258,7 +258,7 @@ CreateRegisterInfoInterface(const ArchSpec &target_arch) {
258258
}
259259

260260
NativeRegisterContextFreeBSD_x86_64::NativeRegisterContextFreeBSD_x86_64(
261-
const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
261+
const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread)
262262
: NativeRegisterContextRegisterInfo(
263263
native_thread, CreateRegisterInfoInterface(target_arch)),
264264
NativeRegisterContextDBReg_x86(native_thread), m_regset_offsets({0}) {

lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,10 @@ NativeThreadFreeBSD::CopyWatchpointsFrom(NativeThreadFreeBSD &source) {
316316
return s;
317317
}
318318

319+
NativeProcessFreeBSD &NativeThreadFreeBSD::GetProcess() {
320+
return static_cast<NativeProcessFreeBSD &>(m_process);
321+
}
322+
319323
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
320324
NativeThreadFreeBSD::GetSiginfo() const {
321325
Log *log = GetLog(POSIXLog::Process);

lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ class NativeThreadFreeBSD : public NativeThreadProtocol {
4747

4848
Status RemoveHardwareBreakpoint(lldb::addr_t addr) override;
4949

50+
NativeProcessFreeBSD &GetProcess();
51+
5052
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
5153
GetSiginfo() const override;
5254

lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include "Plugins/Process/Linux/Procfs.h"
2424
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
2525
#include "Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h"
26-
#include "Plugins/Process/Utility/RegisterFlagsLinux_arm64.h"
26+
#include "Plugins/Process/Utility/RegisterFlagsDetector_arm64.h"
2727
#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
2828

2929
// System includes - They have to be included after framework includes because
@@ -72,8 +72,8 @@ using namespace lldb_private::process_linux;
7272
// will contain the same fields. Therefore this mutex prevents each instance
7373
// competing with the other, and subsequent instances from having to detect the
7474
// fields all over again.
75-
static std::mutex g_register_flags_mutex;
76-
static LinuxArm64RegisterFlags g_register_flags;
75+
static std::mutex g_register_flags_detector_mutex;
76+
static Arm64RegisterFlagsDetector g_register_flags_detector;
7777

7878
std::unique_ptr<NativeRegisterContextLinux>
7979
NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
@@ -144,10 +144,10 @@ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
144144

145145
opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskTLS);
146146

147-
std::lock_guard<std::mutex> lock(g_register_flags_mutex);
148-
if (!g_register_flags.HasDetected())
149-
g_register_flags.DetectFields(auxv_at_hwcap.value_or(0),
150-
auxv_at_hwcap2.value_or(0));
147+
std::lock_guard<std::mutex> lock(g_register_flags_detector_mutex);
148+
if (!g_register_flags_detector.HasDetected())
149+
g_register_flags_detector.DetectFields(auxv_at_hwcap.value_or(0),
150+
auxv_at_hwcap2.value_or(0));
151151

152152
auto register_info_up =
153153
std::make_unique<RegisterInfoPOSIX_arm64>(target_arch, opt_regsets);
@@ -171,7 +171,7 @@ NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
171171
: NativeRegisterContextRegisterInfo(native_thread,
172172
register_info_up.release()),
173173
NativeRegisterContextLinux(native_thread) {
174-
g_register_flags.UpdateRegisterInfo(
174+
g_register_flags_detector.UpdateRegisterInfo(
175175
GetRegisterInfoInterface().GetRegisterInfo(),
176176
GetRegisterInfoInterface().GetRegisterCount());
177177

0 commit comments

Comments
 (0)