Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
96381 views
1
//===-- GDBRemoteRegisterContext.cpp --------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "GDBRemoteRegisterContext.h"
10
11
#include "ProcessGDBRemote.h"
12
#include "ProcessGDBRemoteLog.h"
13
#include "ThreadGDBRemote.h"
14
#include "Utility/ARM_DWARF_Registers.h"
15
#include "Utility/ARM_ehframe_Registers.h"
16
#include "lldb/Core/Architecture.h"
17
#include "lldb/Target/ExecutionContext.h"
18
#include "lldb/Target/Target.h"
19
#include "lldb/Utility/DataBufferHeap.h"
20
#include "lldb/Utility/DataExtractor.h"
21
#include "lldb/Utility/RegisterValue.h"
22
#include "lldb/Utility/Scalar.h"
23
#include "lldb/Utility/StreamString.h"
24
#include "lldb/Utility/StringExtractorGDBRemote.h"
25
26
#include <memory>
27
28
using namespace lldb;
29
using namespace lldb_private;
30
using namespace lldb_private::process_gdb_remote;
31
32
// GDBRemoteRegisterContext constructor
33
GDBRemoteRegisterContext::GDBRemoteRegisterContext(
34
ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
35
GDBRemoteDynamicRegisterInfoSP reg_info_sp, bool read_all_at_once,
36
bool write_all_at_once)
37
: RegisterContext(thread, concrete_frame_idx),
38
m_reg_info_sp(std::move(reg_info_sp)), m_reg_valid(), m_reg_data(),
39
m_read_all_at_once(read_all_at_once),
40
m_write_all_at_once(write_all_at_once), m_gpacket_cached(false) {
41
// Resize our vector of bools to contain one bool for every register. We will
42
// use these boolean values to know when a register value is valid in
43
// m_reg_data.
44
m_reg_valid.resize(m_reg_info_sp->GetNumRegisters());
45
46
// Make a heap based buffer that is big enough to store all registers
47
DataBufferSP reg_data_sp(
48
new DataBufferHeap(m_reg_info_sp->GetRegisterDataByteSize(), 0));
49
m_reg_data.SetData(reg_data_sp);
50
m_reg_data.SetByteOrder(thread.GetProcess()->GetByteOrder());
51
}
52
53
// Destructor
54
GDBRemoteRegisterContext::~GDBRemoteRegisterContext() = default;
55
56
void GDBRemoteRegisterContext::InvalidateAllRegisters() {
57
SetAllRegisterValid(false);
58
}
59
60
void GDBRemoteRegisterContext::SetAllRegisterValid(bool b) {
61
m_gpacket_cached = b;
62
std::vector<bool>::iterator pos, end = m_reg_valid.end();
63
for (pos = m_reg_valid.begin(); pos != end; ++pos)
64
*pos = b;
65
}
66
67
size_t GDBRemoteRegisterContext::GetRegisterCount() {
68
return m_reg_info_sp->GetNumRegisters();
69
}
70
71
const RegisterInfo *
72
GDBRemoteRegisterContext::GetRegisterInfoAtIndex(size_t reg) {
73
return m_reg_info_sp->GetRegisterInfoAtIndex(reg);
74
}
75
76
size_t GDBRemoteRegisterContext::GetRegisterSetCount() {
77
return m_reg_info_sp->GetNumRegisterSets();
78
}
79
80
const RegisterSet *GDBRemoteRegisterContext::GetRegisterSet(size_t reg_set) {
81
return m_reg_info_sp->GetRegisterSet(reg_set);
82
}
83
84
bool GDBRemoteRegisterContext::ReadRegister(const RegisterInfo *reg_info,
85
RegisterValue &value) {
86
// Read the register
87
if (ReadRegisterBytes(reg_info)) {
88
const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
89
if (m_reg_valid[reg] == false)
90
return false;
91
if (reg_info->value_regs &&
92
reg_info->value_regs[0] != LLDB_INVALID_REGNUM &&
93
reg_info->value_regs[1] != LLDB_INVALID_REGNUM) {
94
std::vector<char> combined_data;
95
uint32_t offset = 0;
96
for (int i = 0; reg_info->value_regs[i] != LLDB_INVALID_REGNUM; i++) {
97
const RegisterInfo *parent_reg = GetRegisterInfo(
98
eRegisterKindLLDB, reg_info->value_regs[i]);
99
if (!parent_reg)
100
return false;
101
combined_data.resize(offset + parent_reg->byte_size);
102
if (m_reg_data.CopyData(parent_reg->byte_offset, parent_reg->byte_size,
103
combined_data.data() + offset) !=
104
parent_reg->byte_size)
105
return false;
106
offset += parent_reg->byte_size;
107
}
108
109
Status error;
110
return value.SetFromMemoryData(
111
*reg_info, combined_data.data(), combined_data.size(),
112
m_reg_data.GetByteOrder(), error) == combined_data.size();
113
} else {
114
const bool partial_data_ok = false;
115
Status error(value.SetValueFromData(
116
*reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok));
117
return error.Success();
118
}
119
}
120
return false;
121
}
122
123
bool GDBRemoteRegisterContext::PrivateSetRegisterValue(
124
uint32_t reg, llvm::ArrayRef<uint8_t> data) {
125
const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
126
if (reg_info == nullptr)
127
return false;
128
129
// Invalidate if needed
130
InvalidateIfNeeded(false);
131
132
const size_t reg_byte_size = reg_info->byte_size;
133
memcpy(const_cast<uint8_t *>(
134
m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)),
135
data.data(), std::min(data.size(), reg_byte_size));
136
bool success = data.size() >= reg_byte_size;
137
if (success) {
138
SetRegisterIsValid(reg, true);
139
} else if (data.size() > 0) {
140
// Only set register is valid to false if we copied some bytes, else leave
141
// it as it was.
142
SetRegisterIsValid(reg, false);
143
}
144
return success;
145
}
146
147
bool GDBRemoteRegisterContext::PrivateSetRegisterValue(uint32_t reg,
148
uint64_t new_reg_val) {
149
const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
150
if (reg_info == nullptr)
151
return false;
152
153
// Early in process startup, we can get a thread that has an invalid byte
154
// order because the process hasn't been completely set up yet (see the ctor
155
// where the byte order is setfrom the process). If that's the case, we
156
// can't set the value here.
157
if (m_reg_data.GetByteOrder() == eByteOrderInvalid) {
158
return false;
159
}
160
161
// Invalidate if needed
162
InvalidateIfNeeded(false);
163
164
DataBufferSP buffer_sp(new DataBufferHeap(&new_reg_val, sizeof(new_reg_val)));
165
DataExtractor data(buffer_sp, endian::InlHostByteOrder(), sizeof(void *));
166
167
// If our register context and our register info disagree, which should never
168
// happen, don't overwrite past the end of the buffer.
169
if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
170
return false;
171
172
// Grab a pointer to where we are going to put this register
173
uint8_t *dst = const_cast<uint8_t *>(
174
m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
175
176
if (dst == nullptr)
177
return false;
178
179
if (data.CopyByteOrderedData(0, // src offset
180
reg_info->byte_size, // src length
181
dst, // dst
182
reg_info->byte_size, // dst length
183
m_reg_data.GetByteOrder())) // dst byte order
184
{
185
SetRegisterIsValid(reg, true);
186
return true;
187
}
188
return false;
189
}
190
191
// Helper function for GDBRemoteRegisterContext::ReadRegisterBytes().
192
bool GDBRemoteRegisterContext::GetPrimordialRegister(
193
const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) {
194
const uint32_t lldb_reg = reg_info->kinds[eRegisterKindLLDB];
195
const uint32_t remote_reg = reg_info->kinds[eRegisterKindProcessPlugin];
196
197
if (DataBufferSP buffer_sp =
198
gdb_comm.ReadRegister(m_thread.GetProtocolID(), remote_reg))
199
return PrivateSetRegisterValue(
200
lldb_reg, llvm::ArrayRef<uint8_t>(buffer_sp->GetBytes(),
201
buffer_sp->GetByteSize()));
202
return false;
203
}
204
205
bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info) {
206
ExecutionContext exe_ctx(CalculateThread());
207
208
Process *process = exe_ctx.GetProcessPtr();
209
Thread *thread = exe_ctx.GetThreadPtr();
210
if (process == nullptr || thread == nullptr)
211
return false;
212
213
GDBRemoteCommunicationClient &gdb_comm(
214
((ProcessGDBRemote *)process)->GetGDBRemote());
215
216
InvalidateIfNeeded(false);
217
218
const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
219
220
if (!GetRegisterIsValid(reg)) {
221
if (m_read_all_at_once && !m_gpacket_cached) {
222
if (DataBufferSP buffer_sp =
223
gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())) {
224
memcpy(const_cast<uint8_t *>(m_reg_data.GetDataStart()),
225
buffer_sp->GetBytes(),
226
std::min(buffer_sp->GetByteSize(), m_reg_data.GetByteSize()));
227
if (buffer_sp->GetByteSize() >= m_reg_data.GetByteSize()) {
228
SetAllRegisterValid(true);
229
return true;
230
} else if (buffer_sp->GetByteSize() > 0) {
231
for (auto x : llvm::enumerate(
232
m_reg_info_sp->registers<
233
DynamicRegisterInfo::reg_collection_const_range>())) {
234
const struct RegisterInfo &reginfo = x.value();
235
m_reg_valid[x.index()] =
236
(reginfo.byte_offset + reginfo.byte_size <=
237
buffer_sp->GetByteSize());
238
}
239
240
m_gpacket_cached = true;
241
if (GetRegisterIsValid(reg))
242
return true;
243
} else {
244
Log *log(GetLog(GDBRLog::Thread | GDBRLog::Packets));
245
LLDB_LOGF(
246
log,
247
"error: GDBRemoteRegisterContext::ReadRegisterBytes tried "
248
"to read the "
249
"entire register context at once, expected at least %" PRId64
250
" bytes "
251
"but only got %" PRId64 " bytes.",
252
m_reg_data.GetByteSize(), buffer_sp->GetByteSize());
253
return false;
254
}
255
}
256
}
257
if (reg_info->value_regs) {
258
// Process this composite register request by delegating to the
259
// constituent primordial registers.
260
261
// Index of the primordial register.
262
bool success = true;
263
for (uint32_t idx = 0; success; ++idx) {
264
const uint32_t prim_reg = reg_info->value_regs[idx];
265
if (prim_reg == LLDB_INVALID_REGNUM)
266
break;
267
// We have a valid primordial register as our constituent. Grab the
268
// corresponding register info.
269
const RegisterInfo *prim_reg_info =
270
GetRegisterInfo(eRegisterKindLLDB, prim_reg);
271
if (prim_reg_info == nullptr)
272
success = false;
273
else {
274
// Read the containing register if it hasn't already been read
275
if (!GetRegisterIsValid(prim_reg))
276
success = GetPrimordialRegister(prim_reg_info, gdb_comm);
277
}
278
}
279
280
if (success) {
281
// If we reach this point, all primordial register requests have
282
// succeeded. Validate this composite register.
283
SetRegisterIsValid(reg_info, true);
284
}
285
} else {
286
// Get each register individually
287
GetPrimordialRegister(reg_info, gdb_comm);
288
}
289
290
// Make sure we got a valid register value after reading it
291
if (!GetRegisterIsValid(reg))
292
return false;
293
}
294
295
return true;
296
}
297
298
bool GDBRemoteRegisterContext::WriteRegister(const RegisterInfo *reg_info,
299
const RegisterValue &value) {
300
DataExtractor data;
301
if (value.GetData(data)) {
302
if (reg_info->value_regs &&
303
reg_info->value_regs[0] != LLDB_INVALID_REGNUM &&
304
reg_info->value_regs[1] != LLDB_INVALID_REGNUM) {
305
uint32_t combined_size = 0;
306
for (int i = 0; reg_info->value_regs[i] != LLDB_INVALID_REGNUM; i++) {
307
const RegisterInfo *parent_reg = GetRegisterInfo(
308
eRegisterKindLLDB, reg_info->value_regs[i]);
309
if (!parent_reg)
310
return false;
311
combined_size += parent_reg->byte_size;
312
}
313
314
if (data.GetByteSize() < combined_size)
315
return false;
316
317
uint32_t offset = 0;
318
for (int i = 0; reg_info->value_regs[i] != LLDB_INVALID_REGNUM; i++) {
319
const RegisterInfo *parent_reg = GetRegisterInfo(
320
eRegisterKindLLDB, reg_info->value_regs[i]);
321
assert(parent_reg);
322
323
DataExtractor parent_data{data, offset, parent_reg->byte_size};
324
if (!WriteRegisterBytes(parent_reg, parent_data, 0))
325
return false;
326
offset += parent_reg->byte_size;
327
}
328
assert(offset == combined_size);
329
return true;
330
} else
331
return WriteRegisterBytes(reg_info, data, 0);
332
}
333
return false;
334
}
335
336
// Helper function for GDBRemoteRegisterContext::WriteRegisterBytes().
337
bool GDBRemoteRegisterContext::SetPrimordialRegister(
338
const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) {
339
StreamString packet;
340
StringExtractorGDBRemote response;
341
const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
342
// Invalidate just this register
343
SetRegisterIsValid(reg, false);
344
345
return gdb_comm.WriteRegister(
346
m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin],
347
{m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size),
348
reg_info->byte_size});
349
}
350
351
bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
352
DataExtractor &data,
353
uint32_t data_offset) {
354
ExecutionContext exe_ctx(CalculateThread());
355
356
Process *process = exe_ctx.GetProcessPtr();
357
Thread *thread = exe_ctx.GetThreadPtr();
358
if (process == nullptr || thread == nullptr)
359
return false;
360
361
GDBRemoteCommunicationClient &gdb_comm(
362
((ProcessGDBRemote *)process)->GetGDBRemote());
363
364
assert(m_reg_data.GetByteSize() >=
365
reg_info->byte_offset + reg_info->byte_size);
366
367
// If our register context and our register info disagree, which should never
368
// happen, don't overwrite past the end of the buffer.
369
if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
370
return false;
371
372
// Grab a pointer to where we are going to put this register
373
uint8_t *dst = const_cast<uint8_t *>(
374
m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
375
376
if (dst == nullptr)
377
return false;
378
379
const bool should_reconfigure_registers =
380
RegisterWriteCausesReconfigure(reg_info->name);
381
382
if (data.CopyByteOrderedData(data_offset, // src offset
383
reg_info->byte_size, // src length
384
dst, // dst
385
reg_info->byte_size, // dst length
386
m_reg_data.GetByteOrder())) // dst byte order
387
{
388
GDBRemoteClientBase::Lock lock(gdb_comm);
389
if (lock) {
390
if (m_write_all_at_once) {
391
// Invalidate all register values
392
InvalidateIfNeeded(true);
393
394
// Set all registers in one packet
395
if (gdb_comm.WriteAllRegisters(
396
m_thread.GetProtocolID(),
397
{m_reg_data.GetDataStart(), size_t(m_reg_data.GetByteSize())}))
398
399
{
400
if (should_reconfigure_registers)
401
ReconfigureRegisterInfo();
402
403
InvalidateAllRegisters();
404
405
return true;
406
}
407
} else {
408
bool success = true;
409
410
if (reg_info->value_regs) {
411
// This register is part of another register. In this case we read
412
// the actual register data for any "value_regs", and once all that
413
// data is read, we will have enough data in our register context
414
// bytes for the value of this register
415
416
// Invalidate this composite register first.
417
418
for (uint32_t idx = 0; success; ++idx) {
419
const uint32_t reg = reg_info->value_regs[idx];
420
if (reg == LLDB_INVALID_REGNUM)
421
break;
422
// We have a valid primordial register as our constituent. Grab the
423
// corresponding register info.
424
const RegisterInfo *value_reg_info =
425
GetRegisterInfo(eRegisterKindLLDB, reg);
426
if (value_reg_info == nullptr)
427
success = false;
428
else
429
success = SetPrimordialRegister(value_reg_info, gdb_comm);
430
}
431
} else {
432
// This is an actual register, write it
433
success = SetPrimordialRegister(reg_info, gdb_comm);
434
}
435
436
// Check if writing this register will invalidate any other register
437
// values? If so, invalidate them
438
if (reg_info->invalidate_regs) {
439
for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0];
440
reg != LLDB_INVALID_REGNUM;
441
reg = reg_info->invalidate_regs[++idx])
442
SetRegisterIsValid(ConvertRegisterKindToRegisterNumber(
443
eRegisterKindLLDB, reg),
444
false);
445
}
446
447
if (success && should_reconfigure_registers &&
448
ReconfigureRegisterInfo())
449
InvalidateAllRegisters();
450
451
return success;
452
}
453
} else {
454
Log *log(GetLog(GDBRLog::Thread | GDBRLog::Packets));
455
if (log) {
456
if (log->GetVerbose()) {
457
StreamString strm;
458
process->DumpPluginHistory(strm);
459
LLDB_LOGF(log,
460
"error: failed to get packet sequence mutex, not sending "
461
"write register for \"%s\":\n%s",
462
reg_info->name, strm.GetData());
463
} else
464
LLDB_LOGF(log,
465
"error: failed to get packet sequence mutex, not sending "
466
"write register for \"%s\"",
467
reg_info->name);
468
}
469
}
470
}
471
return false;
472
}
473
474
bool GDBRemoteRegisterContext::ReadAllRegisterValues(
475
RegisterCheckpoint &reg_checkpoint) {
476
ExecutionContext exe_ctx(CalculateThread());
477
478
Process *process = exe_ctx.GetProcessPtr();
479
Thread *thread = exe_ctx.GetThreadPtr();
480
if (process == nullptr || thread == nullptr)
481
return false;
482
483
GDBRemoteCommunicationClient &gdb_comm(
484
((ProcessGDBRemote *)process)->GetGDBRemote());
485
486
uint32_t save_id = 0;
487
if (gdb_comm.SaveRegisterState(thread->GetProtocolID(), save_id)) {
488
reg_checkpoint.SetID(save_id);
489
reg_checkpoint.GetData().reset();
490
return true;
491
} else {
492
reg_checkpoint.SetID(0); // Invalid save ID is zero
493
return ReadAllRegisterValues(reg_checkpoint.GetData());
494
}
495
}
496
497
bool GDBRemoteRegisterContext::WriteAllRegisterValues(
498
const RegisterCheckpoint &reg_checkpoint) {
499
uint32_t save_id = reg_checkpoint.GetID();
500
if (save_id != 0) {
501
ExecutionContext exe_ctx(CalculateThread());
502
503
Process *process = exe_ctx.GetProcessPtr();
504
Thread *thread = exe_ctx.GetThreadPtr();
505
if (process == nullptr || thread == nullptr)
506
return false;
507
508
GDBRemoteCommunicationClient &gdb_comm(
509
((ProcessGDBRemote *)process)->GetGDBRemote());
510
511
return gdb_comm.RestoreRegisterState(m_thread.GetProtocolID(), save_id);
512
} else {
513
return WriteAllRegisterValues(reg_checkpoint.GetData());
514
}
515
}
516
517
bool GDBRemoteRegisterContext::ReadAllRegisterValues(
518
lldb::WritableDataBufferSP &data_sp) {
519
ExecutionContext exe_ctx(CalculateThread());
520
521
Process *process = exe_ctx.GetProcessPtr();
522
Thread *thread = exe_ctx.GetThreadPtr();
523
if (process == nullptr || thread == nullptr)
524
return false;
525
526
GDBRemoteCommunicationClient &gdb_comm(
527
((ProcessGDBRemote *)process)->GetGDBRemote());
528
529
const bool use_g_packet =
530
!gdb_comm.AvoidGPackets((ProcessGDBRemote *)process);
531
532
GDBRemoteClientBase::Lock lock(gdb_comm);
533
if (lock) {
534
if (gdb_comm.SyncThreadState(m_thread.GetProtocolID()))
535
InvalidateAllRegisters();
536
537
if (use_g_packet) {
538
if (DataBufferSP data_buffer =
539
gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())) {
540
data_sp = std::make_shared<DataBufferHeap>(*data_buffer);
541
return true;
542
}
543
}
544
545
// We're going to read each register
546
// individually and store them as binary data in a buffer.
547
const RegisterInfo *reg_info;
548
549
for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != nullptr;
550
i++) {
551
if (reg_info
552
->value_regs) // skip registers that are slices of real registers
553
continue;
554
ReadRegisterBytes(reg_info);
555
// ReadRegisterBytes saves the contents of the register in to the
556
// m_reg_data buffer
557
}
558
data_sp = std::make_shared<DataBufferHeap>(
559
m_reg_data.GetDataStart(), m_reg_info_sp->GetRegisterDataByteSize());
560
return true;
561
} else {
562
563
Log *log(GetLog(GDBRLog::Thread | GDBRLog::Packets));
564
if (log) {
565
if (log->GetVerbose()) {
566
StreamString strm;
567
process->DumpPluginHistory(strm);
568
LLDB_LOGF(log,
569
"error: failed to get packet sequence mutex, not sending "
570
"read all registers:\n%s",
571
strm.GetData());
572
} else
573
LLDB_LOGF(log,
574
"error: failed to get packet sequence mutex, not sending "
575
"read all registers");
576
}
577
}
578
579
data_sp.reset();
580
return false;
581
}
582
583
bool GDBRemoteRegisterContext::WriteAllRegisterValues(
584
const lldb::DataBufferSP &data_sp) {
585
if (!data_sp || data_sp->GetBytes() == nullptr || data_sp->GetByteSize() == 0)
586
return false;
587
588
ExecutionContext exe_ctx(CalculateThread());
589
590
Process *process = exe_ctx.GetProcessPtr();
591
Thread *thread = exe_ctx.GetThreadPtr();
592
if (process == nullptr || thread == nullptr)
593
return false;
594
595
GDBRemoteCommunicationClient &gdb_comm(
596
((ProcessGDBRemote *)process)->GetGDBRemote());
597
598
const bool use_g_packet =
599
!gdb_comm.AvoidGPackets((ProcessGDBRemote *)process);
600
601
GDBRemoteClientBase::Lock lock(gdb_comm);
602
if (lock) {
603
// The data_sp contains the G response packet.
604
if (use_g_packet) {
605
if (gdb_comm.WriteAllRegisters(
606
m_thread.GetProtocolID(),
607
{data_sp->GetBytes(), size_t(data_sp->GetByteSize())}))
608
return true;
609
610
uint32_t num_restored = 0;
611
// We need to manually go through all of the registers and restore them
612
// manually
613
DataExtractor restore_data(data_sp, m_reg_data.GetByteOrder(),
614
m_reg_data.GetAddressByteSize());
615
616
const RegisterInfo *reg_info;
617
618
// The g packet contents may either include the slice registers
619
// (registers defined in terms of other registers, e.g. eax is a subset
620
// of rax) or not. The slice registers should NOT be in the g packet,
621
// but some implementations may incorrectly include them.
622
//
623
// If the slice registers are included in the packet, we must step over
624
// the slice registers when parsing the packet -- relying on the
625
// RegisterInfo byte_offset field would be incorrect. If the slice
626
// registers are not included, then using the byte_offset values into the
627
// data buffer is the best way to find individual register values.
628
629
uint64_t size_including_slice_registers = 0;
630
uint64_t size_not_including_slice_registers = 0;
631
uint64_t size_by_highest_offset = 0;
632
633
for (uint32_t reg_idx = 0;
634
(reg_info = GetRegisterInfoAtIndex(reg_idx)) != nullptr; ++reg_idx) {
635
size_including_slice_registers += reg_info->byte_size;
636
if (reg_info->value_regs == nullptr)
637
size_not_including_slice_registers += reg_info->byte_size;
638
if (reg_info->byte_offset >= size_by_highest_offset)
639
size_by_highest_offset = reg_info->byte_offset + reg_info->byte_size;
640
}
641
642
bool use_byte_offset_into_buffer;
643
if (size_by_highest_offset == restore_data.GetByteSize()) {
644
// The size of the packet agrees with the highest offset: + size in the
645
// register file
646
use_byte_offset_into_buffer = true;
647
} else if (size_not_including_slice_registers ==
648
restore_data.GetByteSize()) {
649
// The size of the packet is the same as concatenating all of the
650
// registers sequentially, skipping the slice registers
651
use_byte_offset_into_buffer = true;
652
} else if (size_including_slice_registers == restore_data.GetByteSize()) {
653
// The slice registers are present in the packet (when they shouldn't
654
// be). Don't try to use the RegisterInfo byte_offset into the
655
// restore_data, it will point to the wrong place.
656
use_byte_offset_into_buffer = false;
657
} else {
658
// None of our expected sizes match the actual g packet data we're
659
// looking at. The most conservative approach here is to use the
660
// running total byte offset.
661
use_byte_offset_into_buffer = false;
662
}
663
664
// In case our register definitions don't include the correct offsets,
665
// keep track of the size of each reg & compute offset based on that.
666
uint32_t running_byte_offset = 0;
667
for (uint32_t reg_idx = 0;
668
(reg_info = GetRegisterInfoAtIndex(reg_idx)) != nullptr;
669
++reg_idx, running_byte_offset += reg_info->byte_size) {
670
// Skip composite aka slice registers (e.g. eax is a slice of rax).
671
if (reg_info->value_regs)
672
continue;
673
674
const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
675
676
uint32_t register_offset;
677
if (use_byte_offset_into_buffer) {
678
register_offset = reg_info->byte_offset;
679
} else {
680
register_offset = running_byte_offset;
681
}
682
683
const uint32_t reg_byte_size = reg_info->byte_size;
684
685
const uint8_t *restore_src =
686
restore_data.PeekData(register_offset, reg_byte_size);
687
if (restore_src) {
688
SetRegisterIsValid(reg, false);
689
if (gdb_comm.WriteRegister(
690
m_thread.GetProtocolID(),
691
reg_info->kinds[eRegisterKindProcessPlugin],
692
{restore_src, reg_byte_size}))
693
++num_restored;
694
}
695
}
696
return num_restored > 0;
697
} else {
698
// For the use_g_packet == false case, we're going to write each register
699
// individually. The data buffer is binary data in this case, instead of
700
// ascii characters.
701
702
bool arm64_debugserver = false;
703
if (m_thread.GetProcess().get()) {
704
const ArchSpec &arch =
705
m_thread.GetProcess()->GetTarget().GetArchitecture();
706
if (arch.IsValid() && (arch.GetMachine() == llvm::Triple::aarch64 ||
707
arch.GetMachine() == llvm::Triple::aarch64_32) &&
708
arch.GetTriple().getVendor() == llvm::Triple::Apple &&
709
arch.GetTriple().getOS() == llvm::Triple::IOS) {
710
arm64_debugserver = true;
711
}
712
}
713
uint32_t num_restored = 0;
714
const RegisterInfo *reg_info;
715
for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != nullptr;
716
i++) {
717
if (reg_info->value_regs) // skip registers that are slices of real
718
// registers
719
continue;
720
// Skip the fpsr and fpcr floating point status/control register
721
// writing to work around a bug in an older version of debugserver that
722
// would lead to register context corruption when writing fpsr/fpcr.
723
if (arm64_debugserver && (strcmp(reg_info->name, "fpsr") == 0 ||
724
strcmp(reg_info->name, "fpcr") == 0)) {
725
continue;
726
}
727
728
SetRegisterIsValid(reg_info, false);
729
if (gdb_comm.WriteRegister(m_thread.GetProtocolID(),
730
reg_info->kinds[eRegisterKindProcessPlugin],
731
{data_sp->GetBytes() + reg_info->byte_offset,
732
reg_info->byte_size}))
733
++num_restored;
734
}
735
return num_restored > 0;
736
}
737
} else {
738
Log *log(GetLog(GDBRLog::Thread | GDBRLog::Packets));
739
if (log) {
740
if (log->GetVerbose()) {
741
StreamString strm;
742
process->DumpPluginHistory(strm);
743
LLDB_LOGF(log,
744
"error: failed to get packet sequence mutex, not sending "
745
"write all registers:\n%s",
746
strm.GetData());
747
} else
748
LLDB_LOGF(log,
749
"error: failed to get packet sequence mutex, not sending "
750
"write all registers");
751
}
752
}
753
return false;
754
}
755
756
uint32_t GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber(
757
lldb::RegisterKind kind, uint32_t num) {
758
return m_reg_info_sp->ConvertRegisterKindToRegisterNumber(kind, num);
759
}
760
761
bool GDBRemoteRegisterContext::RegisterWriteCausesReconfigure(
762
const llvm::StringRef name) {
763
ExecutionContext exe_ctx(CalculateThread());
764
const Architecture *architecture =
765
exe_ctx.GetProcessRef().GetTarget().GetArchitecturePlugin();
766
return architecture && architecture->RegisterWriteCausesReconfigure(name);
767
}
768
769
bool GDBRemoteRegisterContext::ReconfigureRegisterInfo() {
770
ExecutionContext exe_ctx(CalculateThread());
771
const Architecture *architecture =
772
exe_ctx.GetProcessRef().GetTarget().GetArchitecturePlugin();
773
if (architecture)
774
return architecture->ReconfigureRegisterInfo(*(m_reg_info_sp.get()),
775
m_reg_data, *this);
776
return false;
777
}
778
779