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(new_size: 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(data_sp: 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(i: 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(i: 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 | reg_kind: eRegisterKindLLDB, reg_num: reg_info->value_regs[i]); |
99 | if (!parent_reg) |
100 | return false; |
101 | combined_data.resize(new_size: offset + parent_reg->byte_size); |
102 | if (m_reg_data.CopyData(offset: parent_reg->byte_offset, length: parent_reg->byte_size, |
103 | dst: 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: *reg_info, src: combined_data.data(), src_len: combined_data.size(), |
112 | src_byte_order: 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: *reg_info, data&: m_reg_data, offset: 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(force: false); |
131 | |
132 | const size_t reg_byte_size = reg_info->byte_size; |
133 | memcpy(dest: const_cast<uint8_t *>( |
134 | m_reg_data.PeekData(offset: reg_info->byte_offset, length: reg_byte_size)), |
135 | src: data.data(), n: std::min(a: data.size(), b: reg_byte_size)); |
136 | bool success = data.size() >= reg_byte_size; |
137 | if (success) { |
138 | SetRegisterIsValid(reg, valid: 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, valid: 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(force: 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(offset: reg_info->byte_offset, length: reg_info->byte_size)); |
175 | |
176 | if (dst == nullptr) |
177 | return false; |
178 | |
179 | if (data.CopyByteOrderedData(src_offset: 0, // src offset |
180 | src_len: reg_info->byte_size, // src length |
181 | dst, // dst |
182 | dst_len: reg_info->byte_size, // dst length |
183 | dst_byte_order: m_reg_data.GetByteOrder())) // dst byte order |
184 | { |
185 | SetRegisterIsValid(reg, valid: 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(tid: m_thread.GetProtocolID(), reg_num: remote_reg)) |
199 | return PrivateSetRegisterValue( |
200 | reg: lldb_reg, data: 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(force: 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(tid: m_thread.GetProtocolID())) { |
224 | memcpy(dest: const_cast<uint8_t *>(m_reg_data.GetDataStart()), |
225 | src: buffer_sp->GetBytes(), |
226 | n: std::min(a: buffer_sp->GetByteSize(), b: 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 | First: m_reg_info_sp->registers< |
233 | DynamicRegisterInfo::reg_collection_const_range>())) { |
234 | const struct RegisterInfo ®info = 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(mask: 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(reg_kind: eRegisterKindLLDB, reg_num: 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(reg: prim_reg)) |
276 | success = GetPrimordialRegister(reg_info: 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, valid: 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 | reg_kind: eRegisterKindLLDB, reg_num: 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 | reg_kind: eRegisterKindLLDB, reg_num: reg_info->value_regs[i]); |
321 | assert(parent_reg); |
322 | |
323 | DataExtractor parent_data{data, offset, parent_reg->byte_size}; |
324 | if (!WriteRegisterBytes(reg_info: parent_reg, data&: parent_data, data_offset: 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, data_offset: 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, valid: false); |
344 | |
345 | return gdb_comm.WriteRegister( |
346 | tid: m_thread.GetProtocolID(), reg_num: reg_info->kinds[eRegisterKindProcessPlugin], |
347 | data: {m_reg_data.PeekData(offset: reg_info->byte_offset, length: reg_info->byte_size), |
348 | reg_info->byte_size}); |
349 | } |
350 | |
351 | bool GDBRemoteRegisterContext::(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(offset: reg_info->byte_offset, length: reg_info->byte_size)); |
375 | |
376 | if (dst == nullptr) |
377 | return false; |
378 | |
379 | const bool should_reconfigure_registers = |
380 | RegisterWriteCausesReconfigure(name: reg_info->name); |
381 | |
382 | if (data.CopyByteOrderedData(src_offset: data_offset, // src offset |
383 | src_len: reg_info->byte_size, // src length |
384 | dst, // dst |
385 | dst_len: reg_info->byte_size, // dst length |
386 | dst_byte_order: 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(force: true); |
393 | |
394 | // Set all registers in one packet |
395 | if (gdb_comm.WriteAllRegisters( |
396 | tid: m_thread.GetProtocolID(), |
397 | data: {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(reg_kind: eRegisterKindLLDB, reg_num: reg); |
426 | if (value_reg_info == nullptr) |
427 | success = false; |
428 | else |
429 | success = SetPrimordialRegister(reg_info: 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(reg: ConvertRegisterKindToRegisterNumber( |
443 | kind: eRegisterKindLLDB, num: reg), |
444 | valid: false); |
445 | } |
446 | |
447 | if (success && should_reconfigure_registers && |
448 | ReconfigureRegisterInfo()) |
449 | InvalidateAllRegisters(); |
450 | |
451 | return success; |
452 | } |
453 | } else { |
454 | Log *log(GetLog(mask: GDBRLog::Thread | GDBRLog::Packets)); |
455 | if (log) { |
456 | if (log->GetVerbose()) { |
457 | StreamString strm; |
458 | process->DumpPluginHistory(s&: 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 ®_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(tid: 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(data_sp&: reg_checkpoint.GetData()); |
494 | } |
495 | } |
496 | |
497 | bool GDBRemoteRegisterContext::WriteAllRegisterValues( |
498 | const RegisterCheckpoint ®_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(tid: m_thread.GetProtocolID(), save_id); |
512 | } else { |
513 | return WriteAllRegisterValues(data_sp: 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(process: (ProcessGDBRemote *)process); |
531 | |
532 | GDBRemoteClientBase::Lock lock(gdb_comm); |
533 | if (lock) { |
534 | if (gdb_comm.SyncThreadState(tid: m_thread.GetProtocolID())) |
535 | InvalidateAllRegisters(); |
536 | |
537 | if (use_g_packet) { |
538 | if (DataBufferSP data_buffer = |
539 | gdb_comm.ReadAllRegisters(tid: m_thread.GetProtocolID())) { |
540 | data_sp = std::make_shared<DataBufferHeap>(args&: *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(reg: 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 | args: m_reg_data.GetDataStart(), args: m_reg_info_sp->GetRegisterDataByteSize()); |
560 | return true; |
561 | } else { |
562 | |
563 | Log *log(GetLog(mask: GDBRLog::Thread | GDBRLog::Packets)); |
564 | if (log) { |
565 | if (log->GetVerbose()) { |
566 | StreamString strm; |
567 | process->DumpPluginHistory(s&: 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(process: (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 | tid: m_thread.GetProtocolID(), |
607 | data: {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: 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: 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(offset: register_offset, length: reg_byte_size); |
687 | if (restore_src) { |
688 | SetRegisterIsValid(reg, valid: false); |
689 | if (gdb_comm.WriteRegister( |
690 | tid: m_thread.GetProtocolID(), |
691 | reg_num: reg_info->kinds[eRegisterKindProcessPlugin], |
692 | data: {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(reg: 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(s1: reg_info->name, s2: "fpsr" ) == 0 || |
724 | strcmp(s1: reg_info->name, s2: "fpcr" ) == 0)) { |
725 | continue; |
726 | } |
727 | |
728 | SetRegisterIsValid(reg_info, valid: false); |
729 | if (gdb_comm.WriteRegister(tid: m_thread.GetProtocolID(), |
730 | reg_num: reg_info->kinds[eRegisterKindProcessPlugin], |
731 | data: {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(mask: GDBRLog::Thread | GDBRLog::Packets)); |
739 | if (log) { |
740 | if (log->GetVerbose()) { |
741 | StreamString strm; |
742 | process->DumpPluginHistory(s&: 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(reg_info&: *(m_reg_info_sp.get()), |
775 | reg_data&: m_reg_data, reg_context&: *this); |
776 | return false; |
777 | } |
778 | |