LLDB  mainline
GDBRemoteRegisterContext.cpp
Go to the documentation of this file.
1 //===-- GDBRemoteRegisterContext.cpp ----------------------------*- C++ -*-===//
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 
10 
12 #include "lldb/Target/Target.h"
16 #include "lldb/Utility/Scalar.h"
18 #include "ProcessGDBRemote.h"
19 #include "ProcessGDBRemoteLog.h"
20 #include "ThreadGDBRemote.h"
24 
25 #include <memory>
26 
27 using namespace lldb;
28 using namespace lldb_private;
29 using namespace lldb_private::process_gdb_remote;
30 
31 // GDBRemoteRegisterContext constructor
32 GDBRemoteRegisterContext::GDBRemoteRegisterContext(
33  ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
34  GDBRemoteDynamicRegisterInfo &reg_info, bool read_all_at_once)
35  : RegisterContext(thread, concrete_frame_idx), m_reg_info(reg_info),
36  m_reg_valid(), m_reg_data(), m_read_all_at_once(read_all_at_once) {
37  // Resize our vector of bools to contain one bool for every register. We will
38  // use these boolean values to know when a register value is valid in
39  // m_reg_data.
40  m_reg_valid.resize(reg_info.GetNumRegisters());
41 
42  // Make a heap based buffer that is big enough to store all registers
43  DataBufferSP reg_data_sp(
44  new DataBufferHeap(reg_info.GetRegisterDataByteSize(), 0));
45  m_reg_data.SetData(reg_data_sp);
46  m_reg_data.SetByteOrder(thread.GetProcess()->GetByteOrder());
47 }
48 
49 // Destructor
51 
53  SetAllRegisterValid(false);
54 }
55 
57  std::vector<bool>::iterator pos, end = m_reg_valid.end();
58  for (pos = m_reg_valid.begin(); pos != end; ++pos)
59  *pos = b;
60 }
61 
63  return m_reg_info.GetNumRegisters();
64 }
65 
66 const RegisterInfo *
68  RegisterInfo *reg_info = m_reg_info.GetRegisterInfoAtIndex(reg);
69 
70  if (reg_info && reg_info->dynamic_size_dwarf_expr_bytes) {
71  const ArchSpec &arch = m_thread.GetProcess()->GetTarget().GetArchitecture();
72  uint8_t reg_size = UpdateDynamicRegisterSize(arch, reg_info);
73  reg_info->byte_size = reg_size;
74  }
75  return reg_info;
76 }
77 
80 }
81 
82 const RegisterSet *GDBRemoteRegisterContext::GetRegisterSet(size_t reg_set) {
83  return m_reg_info.GetRegisterSet(reg_set);
84 }
85 
86 bool GDBRemoteRegisterContext::ReadRegister(const RegisterInfo *reg_info,
87  RegisterValue &value) {
88  // Read the register
89  if (ReadRegisterBytes(reg_info, m_reg_data)) {
90  const bool partial_data_ok = false;
91  Status error(value.SetValueFromData(
92  reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok));
93  return error.Success();
94  }
95  return false;
96 }
97 
99  uint32_t reg, llvm::ArrayRef<uint8_t> data) {
100  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
101  if (reg_info == NULL)
102  return false;
103 
104  // Invalidate if needed
105  InvalidateIfNeeded(false);
106 
107  const size_t reg_byte_size = reg_info->byte_size;
108  memcpy(const_cast<uint8_t *>(
109  m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)),
110  data.data(), std::min(data.size(), reg_byte_size));
111  bool success = data.size() >= reg_byte_size;
112  if (success) {
113  SetRegisterIsValid(reg, true);
114  } else if (data.size() > 0) {
115  // Only set register is valid to false if we copied some bytes, else leave
116  // it as it was.
117  SetRegisterIsValid(reg, false);
118  }
119  return success;
120 }
121 
123  uint64_t new_reg_val) {
124  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
125  if (reg_info == NULL)
126  return false;
127 
128  // Early in process startup, we can get a thread that has an invalid byte
129  // order because the process hasn't been completely set up yet (see the ctor
130  // where the byte order is setfrom the process). If that's the case, we
131  // can't set the value here.
133  return false;
134  }
135 
136  // Invalidate if needed
137  InvalidateIfNeeded(false);
138 
139  DataBufferSP buffer_sp(new DataBufferHeap(&new_reg_val, sizeof(new_reg_val)));
140  DataExtractor data(buffer_sp, endian::InlHostByteOrder(), sizeof(void *));
141 
142  // If our register context and our register info disagree, which should never
143  // happen, don't overwrite past the end of the buffer.
144  if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
145  return false;
146 
147  // Grab a pointer to where we are going to put this register
148  uint8_t *dst = const_cast<uint8_t *>(
149  m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
150 
151  if (dst == NULL)
152  return false;
153 
154  if (data.CopyByteOrderedData(0, // src offset
155  reg_info->byte_size, // src length
156  dst, // dst
157  reg_info->byte_size, // dst length
158  m_reg_data.GetByteOrder())) // dst byte order
159  {
160  SetRegisterIsValid(reg, true);
161  return true;
162  }
163  return false;
164 }
165 
166 // Helper function for GDBRemoteRegisterContext::ReadRegisterBytes().
167 bool GDBRemoteRegisterContext::GetPrimordialRegister(
168  const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) {
169  const uint32_t lldb_reg = reg_info->kinds[eRegisterKindLLDB];
170  const uint32_t remote_reg = reg_info->kinds[eRegisterKindProcessPlugin];
171 
172  if (DataBufferSP buffer_sp =
173  gdb_comm.ReadRegister(m_thread.GetProtocolID(), remote_reg))
175  lldb_reg, llvm::ArrayRef<uint8_t>(buffer_sp->GetBytes(),
176  buffer_sp->GetByteSize()));
177  return false;
178 }
179 
180 bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
181  DataExtractor &data) {
183 
184  Process *process = exe_ctx.GetProcessPtr();
185  Thread *thread = exe_ctx.GetThreadPtr();
186  if (process == NULL || thread == NULL)
187  return false;
188 
190  ((ProcessGDBRemote *)process)->GetGDBRemote());
191 
192  InvalidateIfNeeded(false);
193 
194  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
195 
196  if (!GetRegisterIsValid(reg)) {
197  if (m_read_all_at_once) {
198  if (DataBufferSP buffer_sp =
200  memcpy(const_cast<uint8_t *>(m_reg_data.GetDataStart()),
201  buffer_sp->GetBytes(),
202  std::min(buffer_sp->GetByteSize(), m_reg_data.GetByteSize()));
203  if (buffer_sp->GetByteSize() >= m_reg_data.GetByteSize()) {
204  SetAllRegisterValid(true);
205  return true;
206  } else {
209  if (log)
210  log->Printf ("error: GDBRemoteRegisterContext::ReadRegisterBytes tried to read the "
211  "entire register context at once, expected at least %" PRId64 " bytes "
212  "but only got %" PRId64 " bytes.", m_reg_data.GetByteSize(),
213  buffer_sp->GetByteSize());
214  }
215  }
216  return false;
217  }
218  if (reg_info->value_regs) {
219  // Process this composite register request by delegating to the
220  // constituent primordial registers.
221 
222  // Index of the primordial register.
223  bool success = true;
224  for (uint32_t idx = 0; success; ++idx) {
225  const uint32_t prim_reg = reg_info->value_regs[idx];
226  if (prim_reg == LLDB_INVALID_REGNUM)
227  break;
228  // We have a valid primordial register as our constituent. Grab the
229  // corresponding register info.
230  const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg);
231  if (prim_reg_info == NULL)
232  success = false;
233  else {
234  // Read the containing register if it hasn't already been read
235  if (!GetRegisterIsValid(prim_reg))
236  success = GetPrimordialRegister(prim_reg_info, gdb_comm);
237  }
238  }
239 
240  if (success) {
241  // If we reach this point, all primordial register requests have
242  // succeeded. Validate this composite register.
243  SetRegisterIsValid(reg_info, true);
244  }
245  } else {
246  // Get each register individually
247  GetPrimordialRegister(reg_info, gdb_comm);
248  }
249 
250  // Make sure we got a valid register value after reading it
251  if (!GetRegisterIsValid(reg))
252  return false;
253  }
254 
255  if (&data != &m_reg_data) {
256  assert(m_reg_data.GetByteSize() >=
257  reg_info->byte_offset + reg_info->byte_size);
258  // If our register context and our register info disagree, which should
259  // never happen, don't read past the end of the buffer.
260  if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
261  return false;
262 
263  // If we aren't extracting into our own buffer (which only happens when
264  // this function is called from ReadRegisterValue(uint32_t, Scalar&)) then
265  // we transfer bytes from our buffer into the data buffer that was passed
266  // in
267 
269  data.SetData(m_reg_data, reg_info->byte_offset, reg_info->byte_size);
270  }
271  return true;
272 }
273 
274 bool GDBRemoteRegisterContext::WriteRegister(const RegisterInfo *reg_info,
275  const RegisterValue &value) {
276  DataExtractor data;
277  if (value.GetData(data))
278  return WriteRegisterBytes(reg_info, data, 0);
279  return false;
280 }
281 
282 // Helper function for GDBRemoteRegisterContext::WriteRegisterBytes().
283 bool GDBRemoteRegisterContext::SetPrimordialRegister(
284  const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) {
285  StreamString packet;
286  StringExtractorGDBRemote response;
287  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
288  // Invalidate just this register
289  SetRegisterIsValid(reg, false);
290 
291  return gdb_comm.WriteRegister(
293  {m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size),
294  reg_info->byte_size});
295 }
296 
297 bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
298  DataExtractor &data,
299  uint32_t data_offset) {
301 
302  Process *process = exe_ctx.GetProcessPtr();
303  Thread *thread = exe_ctx.GetThreadPtr();
304  if (process == NULL || thread == NULL)
305  return false;
306 
308  ((ProcessGDBRemote *)process)->GetGDBRemote());
309 
310  assert(m_reg_data.GetByteSize() >=
311  reg_info->byte_offset + reg_info->byte_size);
312 
313  // If our register context and our register info disagree, which should never
314  // happen, don't overwrite past the end of the buffer.
315  if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
316  return false;
317 
318  // Grab a pointer to where we are going to put this register
319  uint8_t *dst = const_cast<uint8_t *>(
320  m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
321 
322  if (dst == NULL)
323  return false;
324 
325  if (data.CopyByteOrderedData(data_offset, // src offset
326  reg_info->byte_size, // src length
327  dst, // dst
328  reg_info->byte_size, // dst length
329  m_reg_data.GetByteOrder())) // dst byte order
330  {
331  GDBRemoteClientBase::Lock lock(gdb_comm, false);
332  if (lock) {
333  if (m_read_all_at_once) {
334  // Invalidate all register values
335  InvalidateIfNeeded(true);
336 
337  // Set all registers in one packet
338  if (gdb_comm.WriteAllRegisters(
341 
342  {
343  SetAllRegisterValid(false);
344  return true;
345  }
346  } else {
347  bool success = true;
348 
349  if (reg_info->value_regs) {
350  // This register is part of another register. In this case we read
351  // the actual register data for any "value_regs", and once all that
352  // data is read, we will have enough data in our register context
353  // bytes for the value of this register
354 
355  // Invalidate this composite register first.
356 
357  for (uint32_t idx = 0; success; ++idx) {
358  const uint32_t reg = reg_info->value_regs[idx];
359  if (reg == LLDB_INVALID_REGNUM)
360  break;
361  // We have a valid primordial register as our constituent. Grab the
362  // corresponding register info.
363  const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg);
364  if (value_reg_info == NULL)
365  success = false;
366  else
367  success = SetPrimordialRegister(value_reg_info, gdb_comm);
368  }
369  } else {
370  // This is an actual register, write it
371  success = SetPrimordialRegister(reg_info, gdb_comm);
372  }
373 
374  // Check if writing this register will invalidate any other register
375  // values? If so, invalidate them
376  if (reg_info->invalidate_regs) {
377  for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0];
378  reg != LLDB_INVALID_REGNUM;
379  reg = reg_info->invalidate_regs[++idx]) {
380  SetRegisterIsValid(reg, false);
381  }
382  }
383 
384  return success;
385  }
386  } else {
389  if (log) {
390  if (log->GetVerbose()) {
391  StreamString strm;
392  gdb_comm.DumpHistory(strm);
393  log->Printf("error: failed to get packet sequence mutex, not sending "
394  "write register for \"%s\":\n%s",
395  reg_info->name, strm.GetData());
396  } else
397  log->Printf("error: failed to get packet sequence mutex, not sending "
398  "write register for \"%s\"",
399  reg_info->name);
400  }
401  }
402  }
403  return false;
404 }
405 
407  RegisterCheckpoint &reg_checkpoint) {
409 
410  Process *process = exe_ctx.GetProcessPtr();
411  Thread *thread = exe_ctx.GetThreadPtr();
412  if (process == NULL || thread == NULL)
413  return false;
414 
416  ((ProcessGDBRemote *)process)->GetGDBRemote());
417 
418  uint32_t save_id = 0;
419  if (gdb_comm.SaveRegisterState(thread->GetProtocolID(), save_id)) {
420  reg_checkpoint.SetID(save_id);
421  reg_checkpoint.GetData().reset();
422  return true;
423  } else {
424  reg_checkpoint.SetID(0); // Invalid save ID is zero
425  return ReadAllRegisterValues(reg_checkpoint.GetData());
426  }
427 }
428 
430  const RegisterCheckpoint &reg_checkpoint) {
431  uint32_t save_id = reg_checkpoint.GetID();
432  if (save_id != 0) {
434 
435  Process *process = exe_ctx.GetProcessPtr();
436  Thread *thread = exe_ctx.GetThreadPtr();
437  if (process == NULL || thread == NULL)
438  return false;
439 
441  ((ProcessGDBRemote *)process)->GetGDBRemote());
442 
443  return gdb_comm.RestoreRegisterState(m_thread.GetProtocolID(), save_id);
444  } else {
445  return WriteAllRegisterValues(reg_checkpoint.GetData());
446  }
447 }
448 
450  lldb::DataBufferSP &data_sp) {
452 
453  Process *process = exe_ctx.GetProcessPtr();
454  Thread *thread = exe_ctx.GetThreadPtr();
455  if (process == NULL || thread == NULL)
456  return false;
457 
459  ((ProcessGDBRemote *)process)->GetGDBRemote());
460 
461  const bool use_g_packet =
462  !gdb_comm.AvoidGPackets((ProcessGDBRemote *)process);
463 
464  GDBRemoteClientBase::Lock lock(gdb_comm, false);
465  if (lock) {
466  if (gdb_comm.SyncThreadState(m_thread.GetProtocolID()))
468 
469  if (use_g_packet &&
470  (data_sp = gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())))
471  return true;
472 
473  // We're going to read each register
474  // individually and store them as binary data in a buffer.
475  const RegisterInfo *reg_info;
476 
477  for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL; i++) {
478  if (reg_info
479  ->value_regs) // skip registers that are slices of real registers
480  continue;
481  ReadRegisterBytes(reg_info, m_reg_data);
482  // ReadRegisterBytes saves the contents of the register in to the
483  // m_reg_data buffer
484  }
485  data_sp = std::make_shared<DataBufferHeap>(
487  return true;
488  } else {
489 
492  if (log) {
493  if (log->GetVerbose()) {
494  StreamString strm;
495  gdb_comm.DumpHistory(strm);
496  log->Printf("error: failed to get packet sequence mutex, not sending "
497  "read all registers:\n%s",
498  strm.GetData());
499  } else
500  log->Printf("error: failed to get packet sequence mutex, not sending "
501  "read all registers");
502  }
503  }
504 
505  data_sp.reset();
506  return false;
507 }
508 
510  const lldb::DataBufferSP &data_sp) {
511  if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0)
512  return false;
513 
515 
516  Process *process = exe_ctx.GetProcessPtr();
517  Thread *thread = exe_ctx.GetThreadPtr();
518  if (process == NULL || thread == NULL)
519  return false;
520 
522  ((ProcessGDBRemote *)process)->GetGDBRemote());
523 
524  const bool use_g_packet =
525  !gdb_comm.AvoidGPackets((ProcessGDBRemote *)process);
526 
527  GDBRemoteClientBase::Lock lock(gdb_comm, false);
528  if (lock) {
529  // The data_sp contains the G response packet.
530  if (use_g_packet) {
531  if (gdb_comm.WriteAllRegisters(
533  {data_sp->GetBytes(), size_t(data_sp->GetByteSize())}))
534  return true;
535 
536  uint32_t num_restored = 0;
537  // We need to manually go through all of the registers and restore them
538  // manually
539  DataExtractor restore_data(data_sp, m_reg_data.GetByteOrder(),
541 
542  const RegisterInfo *reg_info;
543 
544  // The g packet contents may either include the slice registers
545  // (registers defined in terms of other registers, e.g. eax is a subset
546  // of rax) or not. The slice registers should NOT be in the g packet,
547  // but some implementations may incorrectly include them.
548  //
549  // If the slice registers are included in the packet, we must step over
550  // the slice registers when parsing the packet -- relying on the
551  // RegisterInfo byte_offset field would be incorrect. If the slice
552  // registers are not included, then using the byte_offset values into the
553  // data buffer is the best way to find individual register values.
554 
555  uint64_t size_including_slice_registers = 0;
556  uint64_t size_not_including_slice_registers = 0;
557  uint64_t size_by_highest_offset = 0;
558 
559  for (uint32_t reg_idx = 0;
560  (reg_info = GetRegisterInfoAtIndex(reg_idx)) != NULL; ++reg_idx) {
561  size_including_slice_registers += reg_info->byte_size;
562  if (reg_info->value_regs == NULL)
563  size_not_including_slice_registers += reg_info->byte_size;
564  if (reg_info->byte_offset >= size_by_highest_offset)
565  size_by_highest_offset = reg_info->byte_offset + reg_info->byte_size;
566  }
567 
568  bool use_byte_offset_into_buffer;
569  if (size_by_highest_offset == restore_data.GetByteSize()) {
570  // The size of the packet agrees with the highest offset: + size in the
571  // register file
572  use_byte_offset_into_buffer = true;
573  } else if (size_not_including_slice_registers ==
574  restore_data.GetByteSize()) {
575  // The size of the packet is the same as concatenating all of the
576  // registers sequentially, skipping the slice registers
577  use_byte_offset_into_buffer = true;
578  } else if (size_including_slice_registers == restore_data.GetByteSize()) {
579  // The slice registers are present in the packet (when they shouldn't
580  // be). Don't try to use the RegisterInfo byte_offset into the
581  // restore_data, it will point to the wrong place.
582  use_byte_offset_into_buffer = false;
583  } else {
584  // None of our expected sizes match the actual g packet data we're
585  // looking at. The most conservative approach here is to use the
586  // running total byte offset.
587  use_byte_offset_into_buffer = false;
588  }
589 
590  // In case our register definitions don't include the correct offsets,
591  // keep track of the size of each reg & compute offset based on that.
592  uint32_t running_byte_offset = 0;
593  for (uint32_t reg_idx = 0;
594  (reg_info = GetRegisterInfoAtIndex(reg_idx)) != NULL;
595  ++reg_idx, running_byte_offset += reg_info->byte_size) {
596  // Skip composite aka slice registers (e.g. eax is a slice of rax).
597  if (reg_info->value_regs)
598  continue;
599 
600  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
601 
602  uint32_t register_offset;
603  if (use_byte_offset_into_buffer) {
604  register_offset = reg_info->byte_offset;
605  } else {
606  register_offset = running_byte_offset;
607  }
608 
609  const uint32_t reg_byte_size = reg_info->byte_size;
610 
611  const uint8_t *restore_src =
612  restore_data.PeekData(register_offset, reg_byte_size);
613  if (restore_src) {
614  SetRegisterIsValid(reg, false);
615  if (gdb_comm.WriteRegister(
617  reg_info->kinds[eRegisterKindProcessPlugin],
618  {restore_src, reg_byte_size}))
619  ++num_restored;
620  }
621  }
622  return num_restored > 0;
623  } else {
624  // For the use_g_packet == false case, we're going to write each register
625  // individually. The data buffer is binary data in this case, instead of
626  // ascii characters.
627 
628  bool arm64_debugserver = false;
629  if (m_thread.GetProcess().get()) {
630  const ArchSpec &arch =
631  m_thread.GetProcess()->GetTarget().GetArchitecture();
632  if (arch.IsValid() && arch.GetMachine() == llvm::Triple::aarch64 &&
633  arch.GetTriple().getVendor() == llvm::Triple::Apple &&
634  arch.GetTriple().getOS() == llvm::Triple::IOS) {
635  arm64_debugserver = true;
636  }
637  }
638  uint32_t num_restored = 0;
639  const RegisterInfo *reg_info;
640  for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL;
641  i++) {
642  if (reg_info->value_regs) // skip registers that are slices of real
643  // registers
644  continue;
645  // Skip the fpsr and fpcr floating point status/control register
646  // writing to work around a bug in an older version of debugserver that
647  // would lead to register context corruption when writing fpsr/fpcr.
648  if (arm64_debugserver && (strcmp(reg_info->name, "fpsr") == 0 ||
649  strcmp(reg_info->name, "fpcr") == 0)) {
650  continue;
651  }
652 
653  SetRegisterIsValid(reg_info, false);
654  if (gdb_comm.WriteRegister(m_thread.GetProtocolID(),
655  reg_info->kinds[eRegisterKindProcessPlugin],
656  {data_sp->GetBytes() + reg_info->byte_offset,
657  reg_info->byte_size}))
658  ++num_restored;
659  }
660  return num_restored > 0;
661  }
662  } else {
665  if (log) {
666  if (log->GetVerbose()) {
667  StreamString strm;
668  gdb_comm.DumpHistory(strm);
669  log->Printf("error: failed to get packet sequence mutex, not sending "
670  "write all registers:\n%s",
671  strm.GetData());
672  } else
673  log->Printf("error: failed to get packet sequence mutex, not sending "
674  "write all registers");
675  }
676  }
677  return false;
678 }
679 
681  lldb::RegisterKind kind, uint32_t num) {
683 }
684 
686  // For Advanced SIMD and VFP register mapping.
687  static uint32_t g_d0_regs[] = {26, 27, LLDB_INVALID_REGNUM}; // (s0, s1)
688  static uint32_t g_d1_regs[] = {28, 29, LLDB_INVALID_REGNUM}; // (s2, s3)
689  static uint32_t g_d2_regs[] = {30, 31, LLDB_INVALID_REGNUM}; // (s4, s5)
690  static uint32_t g_d3_regs[] = {32, 33, LLDB_INVALID_REGNUM}; // (s6, s7)
691  static uint32_t g_d4_regs[] = {34, 35, LLDB_INVALID_REGNUM}; // (s8, s9)
692  static uint32_t g_d5_regs[] = {36, 37, LLDB_INVALID_REGNUM}; // (s10, s11)
693  static uint32_t g_d6_regs[] = {38, 39, LLDB_INVALID_REGNUM}; // (s12, s13)
694  static uint32_t g_d7_regs[] = {40, 41, LLDB_INVALID_REGNUM}; // (s14, s15)
695  static uint32_t g_d8_regs[] = {42, 43, LLDB_INVALID_REGNUM}; // (s16, s17)
696  static uint32_t g_d9_regs[] = {44, 45, LLDB_INVALID_REGNUM}; // (s18, s19)
697  static uint32_t g_d10_regs[] = {46, 47, LLDB_INVALID_REGNUM}; // (s20, s21)
698  static uint32_t g_d11_regs[] = {48, 49, LLDB_INVALID_REGNUM}; // (s22, s23)
699  static uint32_t g_d12_regs[] = {50, 51, LLDB_INVALID_REGNUM}; // (s24, s25)
700  static uint32_t g_d13_regs[] = {52, 53, LLDB_INVALID_REGNUM}; // (s26, s27)
701  static uint32_t g_d14_regs[] = {54, 55, LLDB_INVALID_REGNUM}; // (s28, s29)
702  static uint32_t g_d15_regs[] = {56, 57, LLDB_INVALID_REGNUM}; // (s30, s31)
703  static uint32_t g_q0_regs[] = {
704  26, 27, 28, 29, LLDB_INVALID_REGNUM}; // (d0, d1) -> (s0, s1, s2, s3)
705  static uint32_t g_q1_regs[] = {
706  30, 31, 32, 33, LLDB_INVALID_REGNUM}; // (d2, d3) -> (s4, s5, s6, s7)
707  static uint32_t g_q2_regs[] = {
708  34, 35, 36, 37, LLDB_INVALID_REGNUM}; // (d4, d5) -> (s8, s9, s10, s11)
709  static uint32_t g_q3_regs[] = {
710  38, 39, 40, 41, LLDB_INVALID_REGNUM}; // (d6, d7) -> (s12, s13, s14, s15)
711  static uint32_t g_q4_regs[] = {
712  42, 43, 44, 45, LLDB_INVALID_REGNUM}; // (d8, d9) -> (s16, s17, s18, s19)
713  static uint32_t g_q5_regs[] = {
714  46, 47, 48, 49,
715  LLDB_INVALID_REGNUM}; // (d10, d11) -> (s20, s21, s22, s23)
716  static uint32_t g_q6_regs[] = {
717  50, 51, 52, 53,
718  LLDB_INVALID_REGNUM}; // (d12, d13) -> (s24, s25, s26, s27)
719  static uint32_t g_q7_regs[] = {
720  54, 55, 56, 57,
721  LLDB_INVALID_REGNUM}; // (d14, d15) -> (s28, s29, s30, s31)
722  static uint32_t g_q8_regs[] = {59, 60, LLDB_INVALID_REGNUM}; // (d16, d17)
723  static uint32_t g_q9_regs[] = {61, 62, LLDB_INVALID_REGNUM}; // (d18, d19)
724  static uint32_t g_q10_regs[] = {63, 64, LLDB_INVALID_REGNUM}; // (d20, d21)
725  static uint32_t g_q11_regs[] = {65, 66, LLDB_INVALID_REGNUM}; // (d22, d23)
726  static uint32_t g_q12_regs[] = {67, 68, LLDB_INVALID_REGNUM}; // (d24, d25)
727  static uint32_t g_q13_regs[] = {69, 70, LLDB_INVALID_REGNUM}; // (d26, d27)
728  static uint32_t g_q14_regs[] = {71, 72, LLDB_INVALID_REGNUM}; // (d28, d29)
729  static uint32_t g_q15_regs[] = {73, 74, LLDB_INVALID_REGNUM}; // (d30, d31)
730 
731  // This is our array of composite registers, with each element coming from
732  // the above register mappings.
733  static uint32_t *g_composites[] = {
734  g_d0_regs, g_d1_regs, g_d2_regs, g_d3_regs, g_d4_regs, g_d5_regs,
735  g_d6_regs, g_d7_regs, g_d8_regs, g_d9_regs, g_d10_regs, g_d11_regs,
736  g_d12_regs, g_d13_regs, g_d14_regs, g_d15_regs, g_q0_regs, g_q1_regs,
737  g_q2_regs, g_q3_regs, g_q4_regs, g_q5_regs, g_q6_regs, g_q7_regs,
738  g_q8_regs, g_q9_regs, g_q10_regs, g_q11_regs, g_q12_regs, g_q13_regs,
739  g_q14_regs, g_q15_regs};
740 
741  // clang-format off
742  static RegisterInfo g_register_infos[] = {
743 // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVALIDATE REGS SIZE EXPR SIZE LEN
744 // ====== ====== === === ============= ========== =================== =================== ====================== ============= ==== ========== =============== ========= ========
745  { "r0", "arg1", 4, 0, eEncodingUint, eFormatHex, { ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1,0, 0 }, nullptr, nullptr, nullptr, 0 },
746  { "r1", "arg2", 4, 0, eEncodingUint, eFormatHex, { ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2,1, 1 }, nullptr, nullptr, nullptr, 0 },
747  { "r2", "arg3", 4, 0, eEncodingUint, eFormatHex, { ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3,2, 2 }, nullptr, nullptr, nullptr, 0 },
748  { "r3", "arg4", 4, 0, eEncodingUint, eFormatHex, { ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4,3, 3 }, nullptr, nullptr, nullptr, 0 },
749  { "r4", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, 4, 4 }, nullptr, nullptr, nullptr, 0 },
750  { "r5", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, 5, 5 }, nullptr, nullptr, nullptr, 0 },
751  { "r6", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, 6, 6 }, nullptr, nullptr, nullptr, 0 },
752  { "r7", "fp", 4, 0, eEncodingUint, eFormatHex, { ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, 7, 7 }, nullptr, nullptr, nullptr, 0 },
753  { "r8", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, 8, 8 }, nullptr, nullptr, nullptr, 0 },
754  { "r9", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, 9, 9 }, nullptr, nullptr, nullptr, 0 },
755  { "r10", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, 10, 10 }, nullptr, nullptr, nullptr, 0 },
756  { "r11", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, 11, 11 }, nullptr, nullptr, nullptr, 0 },
757  { "r12", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, 12, 12 }, nullptr, nullptr, nullptr, 0 },
758  { "sp", "r13", 4, 0, eEncodingUint, eFormatHex, { ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, 13, 13 }, nullptr, nullptr, nullptr, 0 },
759  { "lr", "r14", 4, 0, eEncodingUint, eFormatHex, { ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, 14, 14 }, nullptr, nullptr, nullptr, 0 },
760  { "pc", "r15", 4, 0, eEncodingUint, eFormatHex, { ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, 15, 15 }, nullptr, nullptr, nullptr, 0 },
761  { "f0", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 16, 16 }, nullptr, nullptr, nullptr, 0 },
762  { "f1", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 17, 17 }, nullptr, nullptr, nullptr, 0 },
763  { "f2", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 18, 18 }, nullptr, nullptr, nullptr, 0 },
764  { "f3", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 19, 19 }, nullptr, nullptr, nullptr, 0 },
765  { "f4", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 20, 20 }, nullptr, nullptr, nullptr, 0 },
766  { "f5", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 21, 21 }, nullptr, nullptr, nullptr, 0 },
767  { "f6", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 22, 22 }, nullptr, nullptr, nullptr, 0 },
768  { "f7", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 23, 23 }, nullptr, nullptr, nullptr, 0 },
769  { "fps", nullptr, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 24, 24 }, nullptr, nullptr, nullptr, 0 },
770  { "cpsr","flags", 4, 0, eEncodingUint, eFormatHex, { ehframe_cpsr, dwarf_cpsr, LLDB_INVALID_REGNUM, 25, 25 }, nullptr, nullptr, nullptr, 0 },
771  { "s0", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, 26, 26 }, nullptr, nullptr, nullptr, 0 },
772  { "s1", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, 27, 27 }, nullptr, nullptr, nullptr, 0 },
773  { "s2", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, 28, 28 }, nullptr, nullptr, nullptr, 0 },
774  { "s3", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, 29, 29 }, nullptr, nullptr, nullptr, 0 },
775  { "s4", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, 30, 30 }, nullptr, nullptr, nullptr, 0 },
776  { "s5", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, 31, 31 }, nullptr, nullptr, nullptr, 0 },
777  { "s6", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, 32, 32 }, nullptr, nullptr, nullptr, 0 },
778  { "s7", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, 33, 33 }, nullptr, nullptr, nullptr, 0 },
779  { "s8", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, 34, 34 }, nullptr, nullptr, nullptr, 0 },
780  { "s9", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, 35, 35 }, nullptr, nullptr, nullptr, 0 },
781  { "s10", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, 36, 36 }, nullptr, nullptr, nullptr, 0 },
782  { "s11", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, 37, 37 }, nullptr, nullptr, nullptr, 0 },
783  { "s12", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, 38, 38 }, nullptr, nullptr, nullptr, 0 },
784  { "s13", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, 39, 39 }, nullptr, nullptr, nullptr, 0 },
785  { "s14", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, 40, 40 }, nullptr, nullptr, nullptr, 0 },
786  { "s15", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, 41, 41 }, nullptr, nullptr, nullptr, 0 },
787  { "s16", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, 42, 42 }, nullptr, nullptr, nullptr, 0 },
788  { "s17", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, 43, 43 }, nullptr, nullptr, nullptr, 0 },
789  { "s18", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, 44, 44 }, nullptr, nullptr, nullptr, 0 },
790  { "s19", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, 45, 45 }, nullptr, nullptr, nullptr, 0 },
791  { "s20", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, 46, 46 }, nullptr, nullptr, nullptr, 0 },
792  { "s21", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, 47, 47 }, nullptr, nullptr, nullptr, 0 },
793  { "s22", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, 48, 48 }, nullptr, nullptr, nullptr, 0 },
794  { "s23", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, 49, 49 }, nullptr, nullptr, nullptr, 0 },
795  { "s24", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, 50, 50 }, nullptr, nullptr, nullptr, 0 },
796  { "s25", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, 51, 51 }, nullptr, nullptr, nullptr, 0 },
797  { "s26", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, 52, 52 }, nullptr, nullptr, nullptr, 0 },
798  { "s27", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, 53, 53 }, nullptr, nullptr, nullptr, 0 },
799  { "s28", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, 54, 54 }, nullptr, nullptr, nullptr, 0 },
800  { "s29", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, 55, 55 }, nullptr, nullptr, nullptr, 0 },
801  { "s30", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, 56, 56 }, nullptr, nullptr, nullptr, 0 },
802  { "s31", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, 57, 57 }, nullptr, nullptr, nullptr, 0 },
803  { "fpscr",nullptr, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 58, 58 }, nullptr, nullptr, nullptr, 0 },
804  { "d16", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, 59, 59 }, nullptr, nullptr, nullptr, 0 },
805  { "d17", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, 60, 60 }, nullptr, nullptr, nullptr, 0 },
806  { "d18", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, 61, 61 }, nullptr, nullptr, nullptr, 0 },
807  { "d19", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, 62, 62 }, nullptr, nullptr, nullptr, 0 },
808  { "d20", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, 63, 63 }, nullptr, nullptr, nullptr, 0 },
809  { "d21", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, 64, 64 }, nullptr, nullptr, nullptr, 0 },
810  { "d22", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, 65, 65 }, nullptr, nullptr, nullptr, 0 },
811  { "d23", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, 66, 66 }, nullptr, nullptr, nullptr, 0 },
812  { "d24", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, 67, 67 }, nullptr, nullptr, nullptr, 0 },
813  { "d25", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, 68, 68 }, nullptr, nullptr, nullptr, 0 },
814  { "d26", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, 69, 69 }, nullptr, nullptr, nullptr, 0 },
815  { "d27", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, 70, 70 }, nullptr, nullptr, nullptr, 0 },
816  { "d28", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, 71, 71 }, nullptr, nullptr, nullptr, 0 },
817  { "d29", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, 72, 72 }, nullptr, nullptr, nullptr, 0 },
818  { "d30", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, 73, 73 }, nullptr, nullptr, nullptr, 0 },
819  { "d31", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, 74, 74 }, nullptr, nullptr, nullptr, 0 },
820  { "d0", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, 75, 75 }, g_d0_regs, nullptr, nullptr, 0 },
821  { "d1", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, 76, 76 }, g_d1_regs, nullptr, nullptr, 0 },
822  { "d2", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, 77, 77 }, g_d2_regs, nullptr, nullptr, 0 },
823  { "d3", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, 78, 78 }, g_d3_regs, nullptr, nullptr, 0 },
824  { "d4", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, 79, 79 }, g_d4_regs, nullptr, nullptr, 0 },
825  { "d5", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, 80, 80 }, g_d5_regs, nullptr, nullptr, 0 },
826  { "d6", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, 81, 81 }, g_d6_regs, nullptr, nullptr, 0 },
827  { "d7", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, 82, 82 }, g_d7_regs, nullptr, nullptr, 0 },
828  { "d8", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, 83, 83 }, g_d8_regs, nullptr, nullptr, 0 },
829  { "d9", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, 84, 84 }, g_d9_regs, nullptr, nullptr, 0 },
830  { "d10", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, 85, 85 }, g_d10_regs, nullptr, nullptr, 0 },
831  { "d11", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, 86, 86 }, g_d11_regs, nullptr, nullptr, 0 },
832  { "d12", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, 87, 87 }, g_d12_regs, nullptr, nullptr, 0 },
833  { "d13", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, 88, 88 }, g_d13_regs, nullptr, nullptr, 0 },
834  { "d14", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, 89, 89 }, g_d14_regs, nullptr, nullptr, 0 },
835  { "d15", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, 90, 90 }, g_d15_regs, nullptr, nullptr, 0 },
836  { "q0", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q0, LLDB_INVALID_REGNUM, 91, 91 }, g_q0_regs, nullptr, nullptr, 0 },
837  { "q1", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q1, LLDB_INVALID_REGNUM, 92, 92 }, g_q1_regs, nullptr, nullptr, 0 },
838  { "q2", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q2, LLDB_INVALID_REGNUM, 93, 93 }, g_q2_regs, nullptr, nullptr, 0 },
839  { "q3", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q3, LLDB_INVALID_REGNUM, 94, 94 }, g_q3_regs, nullptr, nullptr, 0 },
840  { "q4", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q4, LLDB_INVALID_REGNUM, 95, 95 }, g_q4_regs, nullptr, nullptr, 0 },
841  { "q5", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q5, LLDB_INVALID_REGNUM, 96, 96 }, g_q5_regs, nullptr, nullptr, 0 },
842  { "q6", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q6, LLDB_INVALID_REGNUM, 97, 97 }, g_q6_regs, nullptr, nullptr, 0 },
843  { "q7", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q7, LLDB_INVALID_REGNUM, 98, 98 }, g_q7_regs, nullptr, nullptr, 0 },
844  { "q8", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q8, LLDB_INVALID_REGNUM, 99, 99 }, g_q8_regs, nullptr, nullptr, 0 },
845  { "q9", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q9, LLDB_INVALID_REGNUM, 100, 100 }, g_q9_regs, nullptr, nullptr, 0 },
846  { "q10", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q10, LLDB_INVALID_REGNUM, 101, 101 }, g_q10_regs, nullptr, nullptr, 0 },
847  { "q11", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q11, LLDB_INVALID_REGNUM, 102, 102 }, g_q11_regs, nullptr, nullptr, 0 },
848  { "q12", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q12, LLDB_INVALID_REGNUM, 103, 103 }, g_q12_regs, nullptr, nullptr, 0 },
849  { "q13", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q13, LLDB_INVALID_REGNUM, 104, 104 }, g_q13_regs, nullptr, nullptr, 0 },
850  { "q14", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q14, LLDB_INVALID_REGNUM, 105, 105 }, g_q14_regs, nullptr, nullptr, 0 },
851  { "q15", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q15, LLDB_INVALID_REGNUM, 106, 106 }, g_q15_regs, nullptr, nullptr, 0 }
852  };
853  // clang-format on
854 
855  static const uint32_t num_registers = llvm::array_lengthof(g_register_infos);
856  static ConstString gpr_reg_set("General Purpose Registers");
857  static ConstString sfp_reg_set("Software Floating Point Registers");
858  static ConstString vfp_reg_set("Floating Point Registers");
859  size_t i;
860  if (from_scratch) {
861  // Calculate the offsets of the registers
862  // Note that the layout of the "composite" registers (d0-d15 and q0-q15)
863  // which comes after the "primordial" registers is important. This enables
864  // us to calculate the offset of the composite register by using the offset
865  // of its first primordial register. For example, to calculate the offset
866  // of q0, use s0's offset.
867  if (g_register_infos[2].byte_offset == 0) {
868  uint32_t byte_offset = 0;
869  for (i = 0; i < num_registers; ++i) {
870  // For primordial registers, increment the byte_offset by the byte_size
871  // to arrive at the byte_offset for the next register. Otherwise, we
872  // have a composite register whose offset can be calculated by
873  // consulting the offset of its first primordial register.
874  if (!g_register_infos[i].value_regs) {
875  g_register_infos[i].byte_offset = byte_offset;
876  byte_offset += g_register_infos[i].byte_size;
877  } else {
878  const uint32_t first_primordial_reg =
879  g_register_infos[i].value_regs[0];
880  g_register_infos[i].byte_offset =
881  g_register_infos[first_primordial_reg].byte_offset;
882  }
883  }
884  }
885  for (i = 0; i < num_registers; ++i) {
886  ConstString name;
887  ConstString alt_name;
888  if (g_register_infos[i].name && g_register_infos[i].name[0])
889  name.SetCString(g_register_infos[i].name);
890  if (g_register_infos[i].alt_name && g_register_infos[i].alt_name[0])
891  alt_name.SetCString(g_register_infos[i].alt_name);
892 
893  if (i <= 15 || i == 25)
894  AddRegister(g_register_infos[i], name, alt_name, gpr_reg_set);
895  else if (i <= 24)
896  AddRegister(g_register_infos[i], name, alt_name, sfp_reg_set);
897  else
898  AddRegister(g_register_infos[i], name, alt_name, vfp_reg_set);
899  }
900  } else {
901  // Add composite registers to our primordial registers, then.
902  const size_t num_composites = llvm::array_lengthof(g_composites);
903  const size_t num_dynamic_regs = GetNumRegisters();
904  const size_t num_common_regs = num_registers - num_composites;
905  RegisterInfo *g_comp_register_infos = g_register_infos + num_common_regs;
906 
907  // First we need to validate that all registers that we already have match
908  // the non composite regs. If so, then we can add the registers, else we
909  // need to bail
910  bool match = true;
911  if (num_dynamic_regs == num_common_regs) {
912  for (i = 0; match && i < num_dynamic_regs; ++i) {
913  // Make sure all register names match
914  if (m_regs[i].name && g_register_infos[i].name) {
915  if (strcmp(m_regs[i].name, g_register_infos[i].name)) {
916  match = false;
917  break;
918  }
919  }
920 
921  // Make sure all register byte sizes match
922  if (m_regs[i].byte_size != g_register_infos[i].byte_size) {
923  match = false;
924  break;
925  }
926  }
927  } else {
928  // Wrong number of registers.
929  match = false;
930  }
931  // If "match" is true, then we can add extra registers.
932  if (match) {
933  for (i = 0; i < num_composites; ++i) {
934  ConstString name;
935  ConstString alt_name;
936  const uint32_t first_primordial_reg =
937  g_comp_register_infos[i].value_regs[0];
938  const char *reg_name = g_register_infos[first_primordial_reg].name;
939  if (reg_name && reg_name[0]) {
940  for (uint32_t j = 0; j < num_dynamic_regs; ++j) {
941  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(j);
942  // Find a matching primordial register info entry.
943  if (reg_info && reg_info->name &&
944  ::strcasecmp(reg_info->name, reg_name) == 0) {
945  // The name matches the existing primordial entry. Find and
946  // assign the offset, and then add this composite register entry.
947  g_comp_register_infos[i].byte_offset = reg_info->byte_offset;
948  name.SetCString(g_comp_register_infos[i].name);
949  AddRegister(g_comp_register_infos[i], name, alt_name,
950  vfp_reg_set);
951  }
952  }
953  }
954  }
955  }
956  }
957 }
size_t GetNumRegisters() const
bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) override
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:63
An data extractor class.
Definition: DataExtractor.h:47
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
#define LLDB_REGNUM_GENERIC_RA
Definition: lldb-defines.h:66
#define LLDB_REGNUM_GENERIC_ARG4
Definition: lldb-defines.h:74
bool PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef< uint8_t > data)
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition: UserID.h:49
#define GDBR_LOG_THREAD
An architecture specification class.
Definition: ArchSpec.h:32
#define LLDB_REGNUM_GENERIC_ARG2
Definition: lldb-defines.h:70
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
#define LLDB_REGNUM_GENERIC_SP
Definition: lldb-defines.h:64
const char * GetData() const
Definition: StreamString.h:43
bool IsValid() const
Tests if this ArchSpec is valid.
Definition: ArchSpec.h:329
virtual lldb::user_id_t GetProtocolID() const
Definition: Thread.h:1060
A subclass of DataBuffer that stores a data buffer on the heap.
#define LLDB_REGNUM_GENERIC_ARG1
Definition: lldb-defines.h:68
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:431
lldb::ThreadSP CalculateThread() override
const RegisterSet * GetRegisterSet(size_t reg_set) override
#define LLDB_REGNUM_GENERIC_FP
Definition: lldb-defines.h:65
size_t GetNumRegisterSets() const
lldb::offset_t SetData(const void *bytes, lldb::offset_t length, lldb::ByteOrder byte_order)
Set data with a buffer that is caller owned.
bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override
lldb::ByteOrder GetByteOrder() const
Get the current byte order value.
uint32_t ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num) const
const lldb_private::RegisterSet * GetRegisterSet(uint32_t i) const
A plug-in interface definition class for debugging a process.
Definition: Process.h:353
bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override
Status SetValueFromData(const RegisterInfo *reg_info, DataExtractor &data, lldb::offset_t offset, bool partial_data_ok)
Process * GetProcessPtr() const
Returns a pointer to the process object.
bool GetVerbose() const
Definition: Log.cpp:250
bool Success() const
Test for success condition.
Definition: Status.cpp:287
bool WriteRegister(lldb::tid_t tid, uint32_t reg_num, llvm::ArrayRef< uint8_t > data)
const RegisterInfo * GetRegisterInfoAtIndex(size_t reg) override
lldb::ProcessSP GetProcess() const
Definition: Thread.h:154
static RegisterInfo g_register_infos[]
uint64_t GetByteSize() const
Get the number of bytes contained in this object.
lldb::DataBufferSP ReadRegister(lldb::tid_t tid, uint32_t reg_num)
lldb::offset_t CopyByteOrderedData(lldb::offset_t src_offset, lldb::offset_t src_len, void *dst, lldb::offset_t dst_len, lldb::ByteOrder dst_byte_order) const
Copy dst_len bytes from *offset_ptr and ensure the copied data is treated as a value that can be swap...
bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value) override
size_t GetRegisterDataByteSize() const
bool GetData(DataExtractor &data) const
Thread * GetThreadPtr() const
Returns a pointer to the thread object.
const uint8_t * GetDataStart() const
Get the data start pointer.
A uniqued constant string class.
Definition: ConstString.h:38
#define LLDB_REGNUM_GENERIC_ARG3
Definition: lldb-defines.h:72
void SetID(lldb::user_id_t uid)
Set accessor for the user ID.
Definition: UserID.h:55
Definition: SBAddress.h:15
int strcasecmp(const char *s1, const char *s2)
void SetRegisterIsValid(const RegisterInfo *reg_info, bool valid)
bool WriteAllRegisters(lldb::tid_t tid, llvm::ArrayRef< uint8_t > data)
lldb::ByteOrder InlHostByteOrder()
Definition: Endian.h:25
uint32_t UpdateDynamicRegisterSize(const lldb_private::ArchSpec &arch, RegisterInfo *reg_info)
bool WriteRegisterBytes(const RegisterInfo *reg_info, DataExtractor &data, uint32_t data_offset)
void Printf(const char *format,...) __attribute__((format(printf
Definition: Log.cpp:113
bool ReadRegisterBytes(const RegisterInfo *reg_info, DataExtractor &data)
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition: ArchSpec.cpp:726
uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override
Convert from a given register numbering scheme to the lldb register numbering scheme.
#define GDBR_LOG_PACKETS
uint32_t GetAddressByteSize() const
Get the current address size.
const lldb_private::RegisterInfo * GetRegisterInfoAtIndex(uint32_t i) const
An error handling class.
Definition: Status.h:44
const uint8_t * PeekData(lldb::offset_t offset, lldb::offset_t length) const
Peek at a bytes at offset.
void SetByteOrder(lldb::ByteOrder byte_order)
Set the byte_order value.
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:90
void SetCString(const char *cstr)
Set the C string value.