Skip to content

Commit 4fd7766

Browse files
committed
[LLDB] Add per-thread register infos shared pointer in gdb-remote
In gdb-remote process we have register infos defind as a refernce object of GDBRemoteDynamicRegisterInfo class. In past register infos have remained constant througout the life time of a process. This has changed after AArch64 SVE support where register infos will have per-thread configuration. SVE registers will have per-thread size and can be updated while running. This patch aims to build up for that support by changing GDBRemoteDynamicRegisterInfo reference to a shared pointer deinfed per-thread. Reviewed By: labath Differential Revision: https://reviews.llvm.org/D82857
1 parent 9cc221b commit 4fd7766

File tree

8 files changed

+61
-37
lines changed

8 files changed

+61
-37
lines changed

lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,8 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {
650650
}
651651
}
652652

653+
bool DynamicRegisterInfo::IsReconfigurable() { return m_is_reconfigurable; }
654+
653655
size_t DynamicRegisterInfo::GetNumRegisters() const { return m_regs.size(); }
654656

655657
size_t DynamicRegisterInfo::GetNumRegisterSets() const { return m_sets.size(); }

lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
#include "lldb/lldb-private.h"
1818

1919
class DynamicRegisterInfo {
20+
protected:
21+
DynamicRegisterInfo(DynamicRegisterInfo &) = default;
22+
DynamicRegisterInfo &operator=(DynamicRegisterInfo &) = default;
23+
2024
public:
2125
DynamicRegisterInfo() = default;
2226

@@ -25,9 +29,6 @@ class DynamicRegisterInfo {
2529

2630
virtual ~DynamicRegisterInfo() = default;
2731

28-
DynamicRegisterInfo(DynamicRegisterInfo &) = delete;
29-
void operator=(DynamicRegisterInfo &) = delete;
30-
3132
DynamicRegisterInfo(DynamicRegisterInfo &&info);
3233
DynamicRegisterInfo &operator=(DynamicRegisterInfo &&info);
3334

@@ -63,6 +64,8 @@ class DynamicRegisterInfo {
6364

6465
void Clear();
6566

67+
bool IsReconfigurable();
68+
6669
protected:
6770
// Classes that inherit from DynamicRegisterInfo can see and modify these
6871
typedef std::vector<lldb_private::RegisterInfo> reg_collection;
@@ -89,5 +92,6 @@ class DynamicRegisterInfo {
8992
size_t m_reg_data_byte_size = 0u; // The number of bytes required to store
9093
// all registers
9194
bool m_finalized = false;
95+
bool m_is_reconfigurable = false;
9296
};
9397
#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_DYNAMICREGISTERINFO_H

lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,20 @@ using namespace lldb_private::process_gdb_remote;
3131
// GDBRemoteRegisterContext constructor
3232
GDBRemoteRegisterContext::GDBRemoteRegisterContext(
3333
ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
34-
GDBRemoteDynamicRegisterInfo &reg_info, bool read_all_at_once,
34+
GDBRemoteDynamicRegisterInfoSP reg_info_sp, bool read_all_at_once,
3535
bool write_all_at_once)
36-
: RegisterContext(thread, concrete_frame_idx), m_reg_info(reg_info),
37-
m_reg_valid(), m_reg_data(), m_read_all_at_once(read_all_at_once),
36+
: RegisterContext(thread, concrete_frame_idx),
37+
m_reg_info_sp(std::move(reg_info_sp)), m_reg_valid(), m_reg_data(),
38+
m_read_all_at_once(read_all_at_once),
3839
m_write_all_at_once(write_all_at_once) {
3940
// Resize our vector of bools to contain one bool for every register. We will
4041
// use these boolean values to know when a register value is valid in
4142
// m_reg_data.
42-
m_reg_valid.resize(reg_info.GetNumRegisters());
43+
m_reg_valid.resize(m_reg_info_sp->GetNumRegisters());
4344

4445
// Make a heap based buffer that is big enough to store all registers
4546
DataBufferSP reg_data_sp(
46-
new DataBufferHeap(reg_info.GetRegisterDataByteSize(), 0));
47+
new DataBufferHeap(m_reg_info_sp->GetRegisterDataByteSize(), 0));
4748
m_reg_data.SetData(reg_data_sp);
4849
m_reg_data.SetByteOrder(thread.GetProcess()->GetByteOrder());
4950
}
@@ -62,12 +63,12 @@ void GDBRemoteRegisterContext::SetAllRegisterValid(bool b) {
6263
}
6364

6465
size_t GDBRemoteRegisterContext::GetRegisterCount() {
65-
return m_reg_info.GetNumRegisters();
66+
return m_reg_info_sp->GetNumRegisters();
6667
}
6768

6869
const RegisterInfo *
6970
GDBRemoteRegisterContext::GetRegisterInfoAtIndex(size_t reg) {
70-
RegisterInfo *reg_info = m_reg_info.GetRegisterInfoAtIndex(reg);
71+
RegisterInfo *reg_info = m_reg_info_sp->GetRegisterInfoAtIndex(reg);
7172

7273
if (reg_info && reg_info->dynamic_size_dwarf_expr_bytes) {
7374
const ArchSpec &arch = m_thread.GetProcess()->GetTarget().GetArchitecture();
@@ -78,11 +79,11 @@ GDBRemoteRegisterContext::GetRegisterInfoAtIndex(size_t reg) {
7879
}
7980

8081
size_t GDBRemoteRegisterContext::GetRegisterSetCount() {
81-
return m_reg_info.GetNumRegisterSets();
82+
return m_reg_info_sp->GetNumRegisterSets();
8283
}
8384

8485
const RegisterSet *GDBRemoteRegisterContext::GetRegisterSet(size_t reg_set) {
85-
return m_reg_info.GetRegisterSet(reg_set);
86+
return m_reg_info_sp->GetRegisterSet(reg_set);
8687
}
8788

8889
bool GDBRemoteRegisterContext::ReadRegister(const RegisterInfo *reg_info,
@@ -209,9 +210,10 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
209210
SetAllRegisterValid(true);
210211
return true;
211212
} else if (buffer_sp->GetByteSize() > 0) {
212-
const int regcount = m_reg_info.GetNumRegisters();
213+
const int regcount = m_reg_info_sp->GetNumRegisters();
213214
for (int i = 0; i < regcount; i++) {
214-
struct RegisterInfo *reginfo = m_reg_info.GetRegisterInfoAtIndex(i);
215+
struct RegisterInfo *reginfo =
216+
m_reg_info_sp->GetRegisterInfoAtIndex(i);
215217
if (reginfo->byte_offset + reginfo->byte_size
216218
<= buffer_sp->GetByteSize()) {
217219
m_reg_valid[i] = true;
@@ -506,7 +508,7 @@ bool GDBRemoteRegisterContext::ReadAllRegisterValues(
506508
// m_reg_data buffer
507509
}
508510
data_sp = std::make_shared<DataBufferHeap>(
509-
m_reg_data.GetDataStart(), m_reg_info.GetRegisterDataByteSize());
511+
m_reg_data.GetDataStart(), m_reg_info_sp->GetRegisterDataByteSize());
510512
return true;
511513
} else {
512514

@@ -708,7 +710,7 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues(
708710

709711
uint32_t GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber(
710712
lldb::RegisterKind kind, uint32_t num) {
711-
return m_reg_info.ConvertRegisterKindToRegisterNumber(kind, num);
713+
return m_reg_info_sp->ConvertRegisterKindToRegisterNumber(kind, num);
712714
}
713715

714716
void GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch) {

lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,12 @@ namespace process_gdb_remote {
2727

2828
class ThreadGDBRemote;
2929
class ProcessGDBRemote;
30+
class GDBRemoteDynamicRegisterInfo;
3031

31-
class GDBRemoteDynamicRegisterInfo : public DynamicRegisterInfo {
32+
typedef std::shared_ptr<GDBRemoteDynamicRegisterInfo>
33+
GDBRemoteDynamicRegisterInfoSP;
34+
35+
class GDBRemoteDynamicRegisterInfo final : public DynamicRegisterInfo {
3236
public:
3337
GDBRemoteDynamicRegisterInfo() : DynamicRegisterInfo() {}
3438

@@ -40,7 +44,7 @@ class GDBRemoteDynamicRegisterInfo : public DynamicRegisterInfo {
4044
class GDBRemoteRegisterContext : public RegisterContext {
4145
public:
4246
GDBRemoteRegisterContext(ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
43-
GDBRemoteDynamicRegisterInfo &reg_info,
47+
GDBRemoteDynamicRegisterInfoSP reg_info_sp,
4448
bool read_all_at_once, bool write_all_at_once);
4549

4650
~GDBRemoteRegisterContext() override;
@@ -106,7 +110,7 @@ class GDBRemoteRegisterContext : public RegisterContext {
106110
m_reg_valid[reg] = valid;
107111
}
108112

109-
GDBRemoteDynamicRegisterInfo &m_reg_info;
113+
GDBRemoteDynamicRegisterInfoSP m_reg_info_sp;
110114
std::vector<bool> m_reg_valid;
111115
DataExtractor m_reg_data;
112116
bool m_read_all_at_once;

lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
249249
ListenerSP listener_sp)
250250
: Process(target_sp, listener_sp),
251251
m_debugserver_pid(LLDB_INVALID_PROCESS_ID), m_last_stop_packet_mutex(),
252-
m_register_info(),
252+
m_register_info_sp(nullptr),
253253
m_async_broadcaster(nullptr, "lldb.process.gdb-remote.async-broadcaster"),
254254
m_async_listener_sp(
255255
Listener::MakeListener("lldb.process.gdb-remote.async-listener")),
@@ -368,8 +368,8 @@ bool ProcessGDBRemote::ParsePythonTargetDefinition(
368368
m_breakpoint_pc_offset = breakpoint_pc_int_value->GetValue();
369369
}
370370

371-
if (m_register_info.SetRegisterInfo(*target_definition_sp,
372-
GetTarget().GetArchitecture()) > 0) {
371+
if (m_register_info_sp->SetRegisterInfo(
372+
*target_definition_sp, GetTarget().GetArchitecture()) > 0) {
373373
return true;
374374
}
375375
}
@@ -396,10 +396,10 @@ static size_t SplitCommaSeparatedRegisterNumberString(
396396
}
397397

398398
void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
399-
if (!force && m_register_info.GetNumRegisters() > 0)
399+
if (!force && m_register_info_sp)
400400
return;
401401

402-
m_register_info.Clear();
402+
m_register_info_sp = std::make_shared<GDBRemoteDynamicRegisterInfo>();
403403

404404
// Check if qHostInfo specified a specific packet timeout for this
405405
// connection. If so then lets update our setting so the user knows what the
@@ -581,7 +581,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
581581
if (ABISP abi_sp = ABI::FindPlugin(shared_from_this(), arch_to_use))
582582
abi_sp->AugmentRegisterInfo(reg_info);
583583

584-
m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
584+
m_register_info_sp->AddRegister(reg_info, reg_name, alt_name, set_name);
585585
} else {
586586
break; // ensure exit before reg_num is incremented
587587
}
@@ -590,8 +590,8 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
590590
}
591591
}
592592

593-
if (m_register_info.GetNumRegisters() > 0) {
594-
m_register_info.Finalize(GetTarget().GetArchitecture());
593+
if (m_register_info_sp->GetNumRegisters() > 0) {
594+
m_register_info_sp->Finalize(GetTarget().GetArchitecture());
595595
return;
596596
}
597597

@@ -600,21 +600,21 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
600600
// updated debugserver down on the devices. On the other hand, if the
601601
// accumulated reg_num is positive, see if we can add composite registers to
602602
// the existing primordial ones.
603-
bool from_scratch = (m_register_info.GetNumRegisters() == 0);
603+
bool from_scratch = (m_register_info_sp->GetNumRegisters() == 0);
604604

605605
if (!target_arch.IsValid()) {
606606
if (arch_to_use.IsValid() &&
607607
(arch_to_use.GetMachine() == llvm::Triple::arm ||
608608
arch_to_use.GetMachine() == llvm::Triple::thumb) &&
609609
arch_to_use.GetTriple().getVendor() == llvm::Triple::Apple)
610-
m_register_info.HardcodeARMRegisters(from_scratch);
610+
m_register_info_sp->HardcodeARMRegisters(from_scratch);
611611
} else if (target_arch.GetMachine() == llvm::Triple::arm ||
612612
target_arch.GetMachine() == llvm::Triple::thumb) {
613-
m_register_info.HardcodeARMRegisters(from_scratch);
613+
m_register_info_sp->HardcodeARMRegisters(from_scratch);
614614
}
615615

616616
// At this point, we can finalize our register info.
617-
m_register_info.Finalize(GetTarget().GetArchitecture());
617+
m_register_info_sp->Finalize(GetTarget().GetArchitecture());
618618
}
619619

620620
Status ProcessGDBRemote::WillLaunch(lldb_private::Module *module) {
@@ -4567,7 +4567,7 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess(
45674567
// ABI is also potentially incorrect.
45684568
ABISP abi_to_use_sp = ABI::FindPlugin(shared_from_this(), arch_to_use);
45694569
for (auto &feature_node : feature_nodes) {
4570-
ParseRegisters(feature_node, target_info, this->m_register_info,
4570+
ParseRegisters(feature_node, target_info, *this->m_register_info_sp,
45714571
abi_to_use_sp, reg_num_remote, reg_num_local);
45724572
}
45734573

@@ -4597,9 +4597,9 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
45974597
uint32_t reg_num_local = 0;
45984598
if (GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, "target.xml",
45994599
reg_num_remote, reg_num_local))
4600-
this->m_register_info.Finalize(arch_to_use);
4600+
this->m_register_info_sp->Finalize(arch_to_use);
46014601

4602-
return m_register_info.GetNumRegisters() > 0;
4602+
return m_register_info_sp->GetNumRegisters() > 0;
46034603
}
46044604

46054605
llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() {

lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ class ProcessGDBRemote : public Process,
254254
// the last stop
255255
// packet variable
256256
std::recursive_mutex m_last_stop_packet_mutex;
257-
GDBRemoteDynamicRegisterInfo m_register_info;
257+
GDBRemoteDynamicRegisterInfoSP m_register_info_sp;
258258
Broadcaster m_async_broadcaster;
259259
lldb::ListenerSP m_async_listener_sp;
260260
HostThread m_async_thread;

lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ ThreadGDBRemote::ThreadGDBRemote(Process &process, lldb::tid_t tid)
4242
Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
4343
LLDB_LOG(log, "this = {0}, pid = {1}, tid = {2}", this, process.GetID(),
4444
GetID());
45+
// At this point we can clone reg_info for architectures supporting
46+
// run-time update to register sizes and offsets..
47+
auto &gdb_process = static_cast<ProcessGDBRemote &>(process);
48+
if (!gdb_process.m_register_info_sp->IsReconfigurable())
49+
m_reg_info_sp = gdb_process.m_register_info_sp;
50+
else
51+
m_reg_info_sp = std::make_shared<GDBRemoteDynamicRegisterInfo>(
52+
*gdb_process.m_register_info_sp);
4553
}
4654

4755
ThreadGDBRemote::~ThreadGDBRemote() {
@@ -307,8 +315,8 @@ ThreadGDBRemote::CreateRegisterContextForFrame(StackFrame *frame) {
307315
!pSupported || gdb_process->m_use_g_packet_for_reading;
308316
bool write_all_registers_at_once = !pSupported;
309317
reg_ctx_sp = std::make_shared<GDBRemoteRegisterContext>(
310-
*this, concrete_frame_idx, gdb_process->m_register_info,
311-
read_all_registers_at_once, write_all_registers_at_once);
318+
*this, concrete_frame_idx, m_reg_info_sp, read_all_registers_at_once,
319+
write_all_registers_at_once);
312320
}
313321
} else {
314322
reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);

lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include "lldb/Target/Thread.h"
1515
#include "lldb/Utility/StructuredData.h"
1616

17+
#include "GDBRemoteRegisterContext.h"
18+
1719
class StringExtractor;
1820

1921
namespace lldb_private {
@@ -101,6 +103,8 @@ class ThreadGDBRemote : public Thread {
101103
m_queue_serial_number; // Queue info from stop reply/stop info for thread
102104
lldb_private::LazyBool m_associated_with_libdispatch_queue;
103105

106+
GDBRemoteDynamicRegisterInfoSP m_reg_info_sp;
107+
104108
bool PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef<uint8_t> data);
105109

106110
bool PrivateSetRegisterValue(uint32_t reg, uint64_t regval);

0 commit comments

Comments
 (0)