LLDB  mainline
ABISysV_arm64.cpp
Go to the documentation of this file.
1 //===-- ABISysV_arm64.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 "ABISysV_arm64.h"
10 
11 #include <vector>
12 
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/Triple.h"
15 
16 #include "lldb/Core/Module.h"
18 #include "lldb/Core/Value.h"
20 #include "lldb/Symbol/UnwindPlan.h"
21 #include "lldb/Target/Process.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Target/Thread.h"
26 #include "lldb/Utility/Log.h"
28 #include "lldb/Utility/Scalar.h"
29 #include "lldb/Utility/Status.h"
30 
32 
33 using namespace lldb;
34 using namespace lldb_private;
35 
36 bool ABISysV_arm64::GetPointerReturnRegister(const char *&name) {
37  name = "x0";
38  return true;
39 }
40 
41 size_t ABISysV_arm64::GetRedZoneSize() const { return 128; }
42 
43 // Static Functions
44 
45 ABISP
46 ABISysV_arm64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
47  const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
48  const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
49 
50  if (vendor_type != llvm::Triple::Apple) {
51  if (arch_type == llvm::Triple::aarch64 ||
52  arch_type == llvm::Triple::aarch64_32) {
53  return ABISP(
54  new ABISysV_arm64(std::move(process_sp), MakeMCRegisterInfo(arch)));
55  }
56  }
57 
58  return ABISP();
59 }
60 
62  addr_t func_addr, addr_t return_addr,
63  llvm::ArrayRef<addr_t> args) const {
64  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
65  if (!reg_ctx)
66  return false;
67 
69 
70  if (log) {
71  StreamString s;
72  s.Printf("ABISysV_arm64::PrepareTrivialCall (tid = 0x%" PRIx64
73  ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
74  ", return_addr = 0x%" PRIx64,
75  thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
76  (uint64_t)return_addr);
77 
78  for (size_t i = 0; i < args.size(); ++i)
79  s.Printf(", arg%d = 0x%" PRIx64, static_cast<int>(i + 1), args[i]);
80  s.PutCString(")");
81  log->PutString(s.GetString());
82  }
83 
84  // x0 - x7 contain first 8 simple args
85  if (args.size() > 8)
86  return false;
87 
88  for (size_t i = 0; i < args.size(); ++i) {
89  const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
91  LLDB_LOGF(log, "About to write arg%d (0x%" PRIx64 ") into %s",
92  static_cast<int>(i + 1), args[i], reg_info->name);
93  if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
94  return false;
95  }
96 
97  // Set "lr" to the return address
98  if (!reg_ctx->WriteRegisterFromUnsigned(
101  return_addr))
102  return false;
103 
104  // Set "sp" to the requested value
105  if (!reg_ctx->WriteRegisterFromUnsigned(
108  sp))
109  return false;
110 
111  // Set "pc" to the address requested
112  if (!reg_ctx->WriteRegisterFromUnsigned(
115  func_addr))
116  return false;
117 
118  return true;
119 }
120 
121 // TODO: We dont support fp/SIMD arguments in v0-v7
122 bool ABISysV_arm64::GetArgumentValues(Thread &thread, ValueList &values) const {
123  uint32_t num_values = values.GetSize();
124 
125  ExecutionContext exe_ctx(thread.shared_from_this());
126 
127  // Extract the register context so we can read arguments from registers
128 
129  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
130 
131  if (!reg_ctx)
132  return false;
133 
134  addr_t sp = 0;
135 
136  for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
137  // We currently only support extracting values with Clang QualTypes. Do we
138  // care about others?
139  Value *value = values.GetValueAtIndex(value_idx);
140 
141  if (!value)
142  return false;
143 
144  CompilerType value_type = value->GetCompilerType();
145  if (value_type) {
146  bool is_signed = false;
147  size_t bit_width = 0;
148  llvm::Optional<uint64_t> bit_size = value_type.GetBitSize(&thread);
149  if (!bit_size)
150  return false;
151  if (value_type.IsIntegerOrEnumerationType(is_signed)) {
152  bit_width = *bit_size;
153  } else if (value_type.IsPointerOrReferenceType()) {
154  bit_width = *bit_size;
155  } else {
156  // We only handle integer, pointer and reference types currently...
157  return false;
158  }
159 
160  if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
161  if (value_idx < 8) {
162  // Arguments 1-8 are in x0-x7...
163  const RegisterInfo *reg_info = nullptr;
164  reg_info = reg_ctx->GetRegisterInfo(
166 
167  if (reg_info) {
168  RegisterValue reg_value;
169 
170  if (reg_ctx->ReadRegister(reg_info, reg_value)) {
171  if (is_signed)
172  reg_value.SignExtend(bit_width);
173  if (!reg_value.GetScalarValue(value->GetScalar()))
174  return false;
175  continue;
176  }
177  }
178  return false;
179  } else {
180  // TODO: Verify for stack layout for SysV
181  if (sp == 0) {
182  // Read the stack pointer if we already haven't read it
183  sp = reg_ctx->GetSP(0);
184  if (sp == 0)
185  return false;
186  }
187 
188  // Arguments 5 on up are on the stack
189  const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
190  Status error;
192  sp, arg_byte_size, is_signed, value->GetScalar(), error))
193  return false;
194 
195  sp += arg_byte_size;
196  // Align up to the next 8 byte boundary if needed
197  if (sp % 8) {
198  sp >>= 3;
199  sp += 1;
200  sp <<= 3;
201  }
202  }
203  }
204  }
205  }
206  return true;
207 }
208 
209 Status ABISysV_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
210  lldb::ValueObjectSP &new_value_sp) {
211  Status error;
212  if (!new_value_sp) {
213  error.SetErrorString("Empty value object for return value.");
214  return error;
215  }
216 
217  CompilerType return_value_type = new_value_sp->GetCompilerType();
218  if (!return_value_type) {
219  error.SetErrorString("Null clang type for return value.");
220  return error;
221  }
222 
223  Thread *thread = frame_sp->GetThread().get();
224 
225  RegisterContext *reg_ctx = thread->GetRegisterContext().get();
226 
227  if (reg_ctx) {
228  DataExtractor data;
229  Status data_error;
230  const uint64_t byte_size = new_value_sp->GetData(data, data_error);
231  if (data_error.Fail()) {
232  error.SetErrorStringWithFormat(
233  "Couldn't convert return value to raw data: %s",
234  data_error.AsCString());
235  return error;
236  }
237 
238  const uint32_t type_flags = return_value_type.GetTypeInfo(nullptr);
239  if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
240  if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
241  // Extract the register context so we can read arguments from registers
242  lldb::offset_t offset = 0;
243  if (byte_size <= 16) {
244  const RegisterInfo *x0_info = reg_ctx->GetRegisterInfo(
246  if (byte_size <= 8) {
247  uint64_t raw_value = data.GetMaxU64(&offset, byte_size);
248 
249  if (!reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value))
250  error.SetErrorString("failed to write register x0");
251  } else {
252  uint64_t raw_value = data.GetMaxU64(&offset, 8);
253 
254  if (reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value)) {
255  const RegisterInfo *x1_info = reg_ctx->GetRegisterInfo(
257  raw_value = data.GetMaxU64(&offset, byte_size - offset);
258 
259  if (!reg_ctx->WriteRegisterFromUnsigned(x1_info, raw_value))
260  error.SetErrorString("failed to write register x1");
261  }
262  }
263  } else {
264  error.SetErrorString("We don't support returning longer than 128 bit "
265  "integer values at present.");
266  }
267  } else if (type_flags & eTypeIsFloat) {
268  if (type_flags & eTypeIsComplex) {
269  // Don't handle complex yet.
270  error.SetErrorString(
271  "returning complex float values are not supported");
272  } else {
273  const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
274 
275  if (v0_info) {
276  if (byte_size <= 16) {
277  if (byte_size <= RegisterValue::GetMaxByteSize()) {
278  RegisterValue reg_value;
279  error = reg_value.SetValueFromData(v0_info, data, 0, true);
280  if (error.Success()) {
281  if (!reg_ctx->WriteRegister(v0_info, reg_value))
282  error.SetErrorString("failed to write register v0");
283  }
284  } else {
285  error.SetErrorStringWithFormat(
286  "returning float values with a byte size of %" PRIu64
287  " are not supported",
288  byte_size);
289  }
290  } else {
291  error.SetErrorString("returning float values longer than 128 "
292  "bits are not supported");
293  }
294  } else {
295  error.SetErrorString("v0 register is not available on this target");
296  }
297  }
298  }
299  } else if (type_flags & eTypeIsVector) {
300  if (byte_size > 0) {
301  const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
302 
303  if (v0_info) {
304  if (byte_size <= v0_info->byte_size) {
305  RegisterValue reg_value;
306  error = reg_value.SetValueFromData(v0_info, data, 0, true);
307  if (error.Success()) {
308  if (!reg_ctx->WriteRegister(v0_info, reg_value))
309  error.SetErrorString("failed to write register v0");
310  }
311  }
312  }
313  }
314  }
315  } else {
316  error.SetErrorString("no registers are available");
317  }
318 
319  return error;
320 }
321 
323  unwind_plan.Clear();
324  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
325 
326  uint32_t lr_reg_num = arm64_dwarf::lr;
327  uint32_t sp_reg_num = arm64_dwarf::sp;
328 
330 
331  // Our previous Call Frame Address is the stack pointer
332  row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
333 
334  unwind_plan.AppendRow(row);
335  unwind_plan.SetReturnAddressRegister(lr_reg_num);
336 
337  // All other registers are the same.
338 
339  unwind_plan.SetSourceName("arm64 at-func-entry default");
340  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
343 
344  return true;
345 }
346 
348  unwind_plan.Clear();
349  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
350 
351  uint32_t fp_reg_num = arm64_dwarf::fp;
352  uint32_t pc_reg_num = arm64_dwarf::pc;
353 
355  const int32_t ptr_size = 8;
356 
357  row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
358  row->SetOffset(0);
359  row->SetUnspecifiedRegistersAreUndefined(true);
360 
361  row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
362  row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
363 
364  unwind_plan.AppendRow(row);
365  unwind_plan.SetSourceName("arm64 default unwind plan");
366  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
369 
370  return true;
371 }
372 
373 // AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says
374 // registers x19 through x28 and sp are callee preserved. v8-v15 are non-
375 // volatile (and specifically only the lower 8 bytes of these regs), the rest
376 // of the fp/SIMD registers are volatile.
377 
378 // We treat x29 as callee preserved also, else the unwinder won't try to
379 // retrieve fp saves.
380 
381 bool ABISysV_arm64::RegisterIsVolatile(const RegisterInfo *reg_info) {
382  if (reg_info) {
383  const char *name = reg_info->name;
384 
385  // Sometimes we'll be called with the "alternate" name for these registers;
386  // recognize them as non-volatile.
387 
388  if (name[0] == 'p' && name[1] == 'c') // pc
389  return false;
390  if (name[0] == 'f' && name[1] == 'p') // fp
391  return false;
392  if (name[0] == 's' && name[1] == 'p') // sp
393  return false;
394  if (name[0] == 'l' && name[1] == 'r') // lr
395  return false;
396 
397  if (name[0] == 'x' || name[0] == 'r') {
398  // Volatile registers: x0-x18
399  // Although documentation says only x19-28 + sp are callee saved We ll
400  // also have to treat x30 as non-volatile. Each dwarf frame has its own
401  // value of lr. Return false for the non-volatile gpr regs, true for
402  // everything else
403  switch (name[1]) {
404  case '1':
405  switch (name[2]) {
406  case '9':
407  return false; // x19 is non-volatile
408  default:
409  return true;
410  }
411  break;
412  case '2':
413  switch (name[2]) {
414  case '0':
415  case '1':
416  case '2':
417  case '3':
418  case '4':
419  case '5':
420  case '6':
421  case '7':
422  case '8':
423  return false; // x20 - 28 are non-volatile
424  case '9':
425  return false; // x29 aka fp treat as non-volatile
426  default:
427  return true;
428  }
429  case '3': // x30 (lr) and x31 (sp) treat as non-volatile
430  if (name[2] == '0' || name[2] == '1')
431  return false;
432  break;
433  default:
434  return true; // all volatile cases not handled above fall here.
435  }
436  } else if (name[0] == 'v' || name[0] == 's' || name[0] == 'd') {
437  // Volatile registers: v0-7, v16-v31
438  // Return false for non-volatile fp/SIMD regs, true for everything else
439  switch (name[1]) {
440  case '8':
441  case '9':
442  return false; // v8-v9 are non-volatile
443  case '1':
444  switch (name[2]) {
445  case '0':
446  case '1':
447  case '2':
448  case '3':
449  case '4':
450  case '5':
451  return false; // v10-v15 are non-volatile
452  default:
453  return true;
454  }
455  default:
456  return true;
457  }
458  }
459  }
460  return true;
461 }
462 
464  ExecutionContext &exe_ctx, RegisterContext *reg_ctx,
465  const CompilerType &value_type,
466  bool is_return_value, // false => parameter, true => return value
467  uint32_t &NGRN, // NGRN (see ABI documentation)
468  uint32_t &NSRN, // NSRN (see ABI documentation)
469  DataExtractor &data) {
470  llvm::Optional<uint64_t> byte_size =
471  value_type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
472 
473  if (byte_size || *byte_size == 0)
474  return false;
475 
476  std::unique_ptr<DataBufferHeap> heap_data_up(
477  new DataBufferHeap(*byte_size, 0));
478  const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
479  Status error;
480 
481  CompilerType base_type;
482  const uint32_t homogeneous_count =
483  value_type.IsHomogeneousAggregate(&base_type);
484  if (homogeneous_count > 0 && homogeneous_count <= 8) {
485  // Make sure we have enough registers
486  if (NSRN < 8 && (8 - NSRN) >= homogeneous_count) {
487  if (!base_type)
488  return false;
489  llvm::Optional<uint64_t> base_byte_size =
490  base_type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
491  if (!base_byte_size)
492  return false;
493  uint32_t data_offset = 0;
494 
495  for (uint32_t i = 0; i < homogeneous_count; ++i) {
496  char v_name[8];
497  ::snprintf(v_name, sizeof(v_name), "v%u", NSRN);
498  const RegisterInfo *reg_info =
499  reg_ctx->GetRegisterInfoByName(v_name, 0);
500  if (reg_info == nullptr)
501  return false;
502 
503  if (*base_byte_size > reg_info->byte_size)
504  return false;
505 
506  RegisterValue reg_value;
507 
508  if (!reg_ctx->ReadRegister(reg_info, reg_value))
509  return false;
510 
511  // Make sure we have enough room in "heap_data_up"
512  if ((data_offset + *base_byte_size) <= heap_data_up->GetByteSize()) {
513  const size_t bytes_copied = reg_value.GetAsMemoryData(
514  reg_info, heap_data_up->GetBytes() + data_offset, *base_byte_size,
515  byte_order, error);
516  if (bytes_copied != *base_byte_size)
517  return false;
518  data_offset += bytes_copied;
519  ++NSRN;
520  } else
521  return false;
522  }
523  data.SetByteOrder(byte_order);
525  data.SetData(DataBufferSP(heap_data_up.release()));
526  return true;
527  }
528  }
529 
530  const size_t max_reg_byte_size = 16;
531  if (*byte_size <= max_reg_byte_size) {
532  size_t bytes_left = *byte_size;
533  uint32_t data_offset = 0;
534  while (data_offset < *byte_size) {
535  if (NGRN >= 8)
536  return false;
537 
538  const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
540  if (reg_info == nullptr)
541  return false;
542 
543  RegisterValue reg_value;
544 
545  if (!reg_ctx->ReadRegister(reg_info, reg_value))
546  return false;
547 
548  const size_t curr_byte_size = std::min<size_t>(8, bytes_left);
549  const size_t bytes_copied = reg_value.GetAsMemoryData(
550  reg_info, heap_data_up->GetBytes() + data_offset, curr_byte_size,
551  byte_order, error);
552  if (bytes_copied == 0)
553  return false;
554  if (bytes_copied >= bytes_left)
555  break;
556  data_offset += bytes_copied;
557  bytes_left -= bytes_copied;
558  ++NGRN;
559  }
560  } else {
561  const RegisterInfo *reg_info = nullptr;
562  if (is_return_value) {
563  // We are assuming we are decoding this immediately after returning from
564  // a function call and that the address of the structure is in x8
565  reg_info = reg_ctx->GetRegisterInfoByName("x8", 0);
566  } else {
567  // We are assuming we are stopped at the first instruction in a function
568  // and that the ABI is being respected so all parameters appear where
569  // they should be (functions with no external linkage can legally violate
570  // the ABI).
571  if (NGRN >= 8)
572  return false;
573 
574  reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
575  LLDB_REGNUM_GENERIC_ARG1 + NGRN);
576  if (reg_info == nullptr)
577  return false;
578  ++NGRN;
579  }
580 
581  if (reg_info == nullptr)
582  return false;
583 
584  const lldb::addr_t value_addr =
585  reg_ctx->ReadRegisterAsUnsigned(reg_info, LLDB_INVALID_ADDRESS);
586 
587  if (value_addr == LLDB_INVALID_ADDRESS)
588  return false;
589 
590  if (exe_ctx.GetProcessRef().ReadMemory(
591  value_addr, heap_data_up->GetBytes(), heap_data_up->GetByteSize(),
592  error) != heap_data_up->GetByteSize()) {
593  return false;
594  }
595  }
596 
597  data.SetByteOrder(byte_order);
599  data.SetData(DataBufferSP(heap_data_up.release()));
600  return true;
601 }
602 
604  Thread &thread, CompilerType &return_compiler_type) const {
605  ValueObjectSP return_valobj_sp;
606  Value value;
607 
608  ExecutionContext exe_ctx(thread.shared_from_this());
609  if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
610  return return_valobj_sp;
611 
612  // value.SetContext (Value::eContextTypeClangType, return_compiler_type);
613  value.SetCompilerType(return_compiler_type);
614 
615  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
616  if (!reg_ctx)
617  return return_valobj_sp;
618 
619  llvm::Optional<uint64_t> byte_size =
620  return_compiler_type.GetByteSize(&thread);
621  if (!byte_size)
622  return return_valobj_sp;
623 
624  const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
625  if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
626  value.SetValueType(Value::ValueType::Scalar);
627 
628  bool success = false;
629  if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
630  // Extract the register context so we can read arguments from registers
631  if (*byte_size <= 8) {
632  const RegisterInfo *x0_reg_info = nullptr;
633  x0_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
635  if (x0_reg_info) {
636  uint64_t raw_value =
637  thread.GetRegisterContext()->ReadRegisterAsUnsigned(x0_reg_info,
638  0);
639  const bool is_signed = (type_flags & eTypeIsSigned) != 0;
640  switch (*byte_size) {
641  default:
642  break;
643  case 16: // uint128_t
644  // In register x0 and x1
645  {
646  const RegisterInfo *x1_reg_info = nullptr;
647  x1_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
649 
650  if (x1_reg_info) {
651  if (*byte_size <=
652  x0_reg_info->byte_size + x1_reg_info->byte_size) {
653  std::unique_ptr<DataBufferHeap> heap_data_up(
654  new DataBufferHeap(*byte_size, 0));
655  const ByteOrder byte_order =
656  exe_ctx.GetProcessRef().GetByteOrder();
657  RegisterValue x0_reg_value;
658  RegisterValue x1_reg_value;
659  if (reg_ctx->ReadRegister(x0_reg_info, x0_reg_value) &&
660  reg_ctx->ReadRegister(x1_reg_info, x1_reg_value)) {
661  Status error;
662  if (x0_reg_value.GetAsMemoryData(
663  x0_reg_info, heap_data_up->GetBytes() + 0, 8,
664  byte_order, error) &&
665  x1_reg_value.GetAsMemoryData(
666  x1_reg_info, heap_data_up->GetBytes() + 8, 8,
667  byte_order, error)) {
668  DataExtractor data(
669  DataBufferSP(heap_data_up.release()), byte_order,
670  exe_ctx.GetProcessRef().GetAddressByteSize());
671 
672  return_valobj_sp = ValueObjectConstResult::Create(
673  &thread, return_compiler_type, ConstString(""), data);
674  return return_valobj_sp;
675  }
676  }
677  }
678  }
679  }
680  break;
681  case sizeof(uint64_t):
682  if (is_signed)
683  value.GetScalar() = (int64_t)(raw_value);
684  else
685  value.GetScalar() = (uint64_t)(raw_value);
686  success = true;
687  break;
688 
689  case sizeof(uint32_t):
690  if (is_signed)
691  value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
692  else
693  value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
694  success = true;
695  break;
696 
697  case sizeof(uint16_t):
698  if (is_signed)
699  value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
700  else
701  value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
702  success = true;
703  break;
704 
705  case sizeof(uint8_t):
706  if (is_signed)
707  value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
708  else
709  value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
710  success = true;
711  break;
712  }
713  }
714  }
715  } else if (type_flags & eTypeIsFloat) {
716  if (type_flags & eTypeIsComplex) {
717  // Don't handle complex yet.
718  } else {
719  if (*byte_size <= sizeof(long double)) {
720  const RegisterInfo *v0_reg_info =
721  reg_ctx->GetRegisterInfoByName("v0", 0);
722  RegisterValue v0_value;
723  if (reg_ctx->ReadRegister(v0_reg_info, v0_value)) {
724  DataExtractor data;
725  if (v0_value.GetData(data)) {
726  lldb::offset_t offset = 0;
727  if (*byte_size == sizeof(float)) {
728  value.GetScalar() = data.GetFloat(&offset);
729  success = true;
730  } else if (*byte_size == sizeof(double)) {
731  value.GetScalar() = data.GetDouble(&offset);
732  success = true;
733  } else if (*byte_size == sizeof(long double)) {
734  value.GetScalar() = data.GetLongDouble(&offset);
735  success = true;
736  }
737  }
738  }
739  }
740  }
741  }
742 
743  if (success)
744  return_valobj_sp = ValueObjectConstResult::Create(
745  thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
746  } else if (type_flags & eTypeIsVector && *byte_size <= 16) {
747  if (*byte_size > 0) {
748  const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
749 
750  if (v0_info) {
751  std::unique_ptr<DataBufferHeap> heap_data_up(
752  new DataBufferHeap(*byte_size, 0));
753  const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
754  RegisterValue reg_value;
755  if (reg_ctx->ReadRegister(v0_info, reg_value)) {
756  Status error;
757  if (reg_value.GetAsMemoryData(v0_info, heap_data_up->GetBytes(),
758  heap_data_up->GetByteSize(), byte_order,
759  error)) {
760  DataExtractor data(DataBufferSP(heap_data_up.release()), byte_order,
761  exe_ctx.GetProcessRef().GetAddressByteSize());
762  return_valobj_sp = ValueObjectConstResult::Create(
763  &thread, return_compiler_type, ConstString(""), data);
764  }
765  }
766  }
767  }
768  } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass ||
769  (type_flags & eTypeIsVector && *byte_size > 16)) {
770  DataExtractor data;
771 
772  uint32_t NGRN = 0; // Search ABI docs for NGRN
773  uint32_t NSRN = 0; // Search ABI docs for NSRN
774  const bool is_return_value = true;
776  exe_ctx, reg_ctx, return_compiler_type, is_return_value, NGRN, NSRN,
777  data)) {
778  return_valobj_sp = ValueObjectConstResult::Create(
779  &thread, return_compiler_type, ConstString(""), data);
780  }
781  }
782  return return_valobj_sp;
783 }
784 
786  lldb::addr_t pac_sign_extension = 0x0080000000000000ULL;
787  return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
788 }
789 
790 // Reads code or data address mask for the current Linux process.
791 static lldb::addr_t ReadLinuxProcessAddressMask(lldb::ProcessSP process_sp,
792  llvm::StringRef reg_name) {
793  // Linux configures user-space virtual addresses with top byte ignored.
794  // We set default value of mask such that top byte is masked out.
795  uint64_t address_mask = ~((1ULL << 56) - 1);
796  // If Pointer Authentication feature is enabled then Linux exposes
797  // PAC data and code mask register. Try reading relevant register
798  // below and merge it with default address mask calculated above.
799  lldb::ThreadSP thread_sp = process_sp->GetThreadList().GetSelectedThread();
800  if (thread_sp) {
801  lldb::RegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext();
802  if (reg_ctx_sp) {
803  const RegisterInfo *reg_info =
804  reg_ctx_sp->GetRegisterInfoByName(reg_name, 0);
805  if (reg_info) {
806  lldb::addr_t mask_reg_val = reg_ctx_sp->ReadRegisterAsUnsigned(
807  reg_info->kinds[eRegisterKindLLDB], LLDB_INVALID_ADDRESS);
808  if (mask_reg_val != LLDB_INVALID_ADDRESS)
809  address_mask |= mask_reg_val;
810  }
811  }
812  }
813  return address_mask;
814 }
815 
817  if (lldb::ProcessSP process_sp = GetProcessSP()) {
818  if (process_sp->GetTarget().GetArchitecture().GetTriple().isOSLinux() &&
819  !process_sp->GetCodeAddressMask())
820  process_sp->SetCodeAddressMask(
821  ReadLinuxProcessAddressMask(process_sp, "code_mask"));
822 
823  return FixAddress(pc, process_sp->GetCodeAddressMask());
824  }
825  return pc;
826 }
827 
829  if (lldb::ProcessSP process_sp = GetProcessSP()) {
830  if (process_sp->GetTarget().GetArchitecture().GetTriple().isOSLinux() &&
831  !process_sp->GetDataAddressMask())
832  process_sp->SetDataAddressMask(
833  ReadLinuxProcessAddressMask(process_sp, "data_mask"));
834 
835  return FixAddress(pc, process_sp->GetDataAddressMask());
836  }
837  return pc;
838 }
839 
841  PluginManager::RegisterPlugin(GetPluginNameStatic(),
842  "SysV ABI for AArch64 targets", CreateInstance);
843 }
844 
846  PluginManager::UnregisterPlugin(CreateInstance);
847 }
848 
850  static ConstString g_name("SysV-arm64");
851  return g_name;
852 }
arm64_dwarf::fp
@ fp
Definition: ARM64_DWARF_Registers.h:47
lldb_private::RegisterContext::WriteRegister
virtual bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)=0
lldb_private::CompilerType::IsPointerOrReferenceType
bool IsPointerOrReferenceType(CompilerType *pointee_type=nullptr) const
Definition: CompilerType.cpp:166
LLDB_REGNUM_GENERIC_ARG2
#define LLDB_REGNUM_GENERIC_ARG2
Definition: lldb-defines.h:70
lldb_private::ExecutionContext
Definition: ExecutionContext.h:292
ABISysV_arm64::SetReturnValueObject
lldb_private::Status SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override
Definition: ABISysV_arm64.cpp:209
Scalar.h
lldb_private::UnwindPlan::AppendRow
void AppendRow(const RowSP &row_sp)
Definition: UnwindPlan.cpp:360
lldb_private::ArchSpec
Definition: ArchSpec.h:33
lldb_private::Log::PutString
void PutString(llvm::StringRef str)
Definition: Log.cpp:119
LLDB_REGNUM_GENERIC_ARG1
#define LLDB_REGNUM_GENERIC_ARG1
Definition: lldb-defines.h:68
arm64_dwarf::pc
@ pc
Definition: ARM64_DWARF_Registers.h:52
ABISysV_arm64::CreateFunctionEntryUnwindPlan
bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
Definition: ABISysV_arm64.cpp:322
lldb_private::Process::ReadMemory
virtual size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, Status &error)
Read of memory from a process.
Definition: Process.cpp:1926
arm64_dwarf::lr
@ lr
Definition: ARM64_DWARF_Registers.h:49
lldb_private::RegisterValue
Definition: RegisterValue.h:28
lldb_private::Process::ReadScalarIntegerFromMemory
size_t ReadScalarIntegerFromMemory(lldb::addr_t addr, uint32_t byte_size, bool is_signed, Scalar &scalar, Status &error)
Definition: Process.cpp:2267
lldb_private::UnwindPlan::SetRegisterKind
void SetRegisterKind(lldb::RegisterKind kind)
Definition: UnwindPlan.h:439
lldb::eRegisterKindDWARF
@ eRegisterKindDWARF
the register numbers seen DWARF
Definition: lldb-enumerations.h:229
lldb_private::Value
Definition: Value.h:38
lldb_private::Value::SetValueType
void SetValueType(ValueType value_type)
Definition: Value.h:89
lldb_private::ExecutionContext::GetProcessPtr
Process * GetProcessPtr() const
Returns a pointer to the process object.
Definition: ExecutionContext.cpp:208
lldb::eRegisterKindGeneric
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
Definition: lldb-enumerations.h:230
lldb_private::ValueList::GetValueAtIndex
Value * GetValueAtIndex(size_t idx)
Definition: Value.cpp:679
lldb_private::UnwindPlan::SetUnwindPlanValidAtAllInstructions
void SetUnwindPlanValidAtAllInstructions(lldb_private::LazyBool valid_at_all_insn)
Definition: UnwindPlan.h:492
lldb_private::RegisterContext::ReadRegister
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)=0
LLDB_LOGF
#define LLDB_LOGF(log,...)
Definition: Log.h:249
Module.h
lldb_private::RegisterContext::ReadRegisterAsUnsigned
uint64_t ReadRegisterAsUnsigned(uint32_t reg, uint64_t fail_value)
Definition: RegisterContext.cpp:188
lldb_private::CompilerType::GetByteSize
llvm::Optional< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
Definition: CompilerType.cpp:489
lldb_private::UnwindPlan::SetUnwindPlanForSignalTrap
void SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap)
Definition: UnwindPlan.h:504
lldb::offset_t
uint64_t offset_t
Definition: lldb-types.h:87
RegisterValue.h
lldb_private::ValueList
Definition: Value.h:157
lldb_private::ArchSpec::GetTriple
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:444
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
pc
@ pc
Definition: CompactUnwindInfo.cpp:1250
ABISysV_arm64::Initialize
static void Initialize()
Definition: ABISysV_arm64.cpp:840
ABISysV_arm64::GetReturnValueObjectImpl
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &ast_type) const override
Definition: ABISysV_arm64.cpp:603
lldb_private::UnwindPlan::SetSourceName
void SetSourceName(const char *)
Definition: UnwindPlan.cpp:562
lldb_private::ValueList::GetSize
size_t GetSize()
Definition: Value.cpp:677
lldb_private::DataExtractor::SetData
lldb::offset_t SetData(const void *bytes, lldb::offset_t length, lldb::ByteOrder byte_order)
Set data with a buffer that is caller owned.
Definition: DataExtractor.cpp:225
lldb_private::ExecutionContext::GetProcessRef
Process & GetProcessRef() const
Returns a reference to the process object.
Definition: ExecutionContext.cpp:231
lldb_private::StreamString::GetString
llvm::StringRef GetString() const
Definition: StreamString.cpp:51
Process.h
ABISysV_arm64::Terminate
static void Terminate()
Definition: ABISysV_arm64.cpp:845
ReadLinuxProcessAddressMask
static lldb::addr_t ReadLinuxProcessAddressMask(lldb::ProcessSP process_sp, llvm::StringRef reg_name)
Definition: ABISysV_arm64.cpp:791
lldb_private::CompilerType::IsIntegerOrEnumerationType
bool IsIntegerOrEnumerationType(bool &is_signed) const
Definition: CompilerType.cpp:153
lldb_private::Value::SetCompilerType
void SetCompilerType(const CompilerType &compiler_type)
Definition: Value.cpp:254
Target.h
lldb_private::DataExtractor::SetByteOrder
void SetByteOrder(lldb::ByteOrder byte_order)
Set the byte_order value.
Definition: DataExtractor.h:931
lldb_private::Value::GetScalar
const Scalar & GetScalar() const
Definition: Value.h:112
lldb_private::CompilerType::IsHomogeneousAggregate
uint32_t IsHomogeneousAggregate(CompilerType *base_type_ptr) const
Definition: CompilerType.cpp:109
LIBLLDB_LOG_EXPRESSIONS
#define LIBLLDB_LOG_EXPRESSIONS
Definition: Logging.h:22
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
ABISysV_arm64::FixCodeAddress
lldb::addr_t FixCodeAddress(lldb::addr_t pc) override
Some targets might use bits in a code address to indicate a mode switch.
Definition: ABISysV_arm64.cpp:816
lldb::eRegisterKindLLDB
@ eRegisterKindLLDB
lldb's internal register numbers
Definition: lldb-enumerations.h:234
lldb_private::DataExtractor
Definition: DataExtractor.h:48
Log.h
lldb_private::UnwindPlan::SetReturnAddressRegister
void SetReturnAddressRegister(uint32_t regnum)
Definition: UnwindPlan.h:441
lldb_private::Thread
Definition: Thread.h:60
lldb_private::Status::Fail
bool Fail() const
Test for error condition.
Definition: Status.cpp:182
lldb_private::DataExtractor::SetAddressByteSize
void SetAddressByteSize(uint32_t addr_size)
Set the address byte size.
Definition: DataExtractor.h:845
lldb_private::DataExtractor::GetDouble
double GetDouble(lldb::offset_t *offset_ptr) const
Definition: DataExtractor.cpp:628
lldb_private::RegisterValue::GetData
bool GetData(DataExtractor &data) const
Definition: RegisterValue.cpp:34
lldb_private::RegisterContext::GetRegisterInfo
const RegisterInfo * GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num)
Definition: RegisterContext.cpp:80
lldb_private::UnwindPlan::SetSourcedFromCompiler
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
Definition: UnwindPlan.h:480
lldb_private::Process::GetAddressByteSize
uint32_t GetAddressByteSize() const
Definition: Process.cpp:3348
lldb_private::ConstString
Definition: ConstString.h:40
lldb_private::StreamString
Definition: StreamString.h:23
ABISysV_arm64::GetPointerReturnRegister
bool GetPointerReturnRegister(const char *&name) override
Definition: ABISysV_arm64.cpp:36
ABISysV_arm64::PrepareTrivialCall
bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, lldb::addr_t functionAddress, lldb::addr_t returnAddress, llvm::ArrayRef< lldb::addr_t > args) const override
Definition: ABISysV_arm64.cpp:61
lldb_private::GetLogIfAllCategoriesSet
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:58
ABISysV_arm64::CreateInstance
static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch)
Definition: ABISysV_arm64.cpp:46
ABISysV_arm64::GetPluginNameStatic
static lldb_private::ConstString GetPluginNameStatic()
Definition: ABISysV_arm64.cpp:849
sp
@ sp
Definition: CompactUnwindInfo.cpp:1249
lldb_private::DataExtractor::GetFloat
float GetFloat(lldb::offset_t *offset_ptr) const
Extract a float from *offset_ptr.
Definition: DataExtractor.cpp:624
Thread.h
ABISysV_arm64::GetRedZoneSize
size_t GetRedZoneSize() const override
Definition: ABISysV_arm64.cpp:41
ABISysV_arm64::GetArgumentValues
bool GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override
Definition: ABISysV_arm64.cpp:122
UnwindPlan.h
lldb_private::RegisterContext::GetSP
uint64_t GetSP(uint64_t fail_value=LLDB_INVALID_ADDRESS)
Definition: RegisterContext.cpp:152
lldb_private::RegisterContext
Definition: RegisterContext.h:17
ABISysV_arm64::RegisterIsVolatile
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override
Definition: ABISysV_arm64.cpp:381
lldb_private::UserID::GetID
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition: UserID.h:47
ARM64_DWARF_Registers.h
ValueObjectConstResult.h
lldb_private::UnwindPlan::RowSP
std::shared_ptr< Row > RowSP
Definition: UnwindPlan.h:395
ABISysV_arm64.h
lldb_private::RegisterValue::SetValueFromData
Status SetValueFromData(const RegisterInfo *reg_info, DataExtractor &data, lldb::offset_t offset, bool partial_data_ok)
Definition: RegisterValue.cpp:172
arm64_dwarf::sp
@ sp
Definition: ARM64_DWARF_Registers.h:51
lldb_private::UnwindPlan::Clear
void Clear()
Definition: UnwindPlan.h:510
lldb_private::Status
Definition: Status.h:44
lldb_private::RegisterContext::WriteRegisterFromUnsigned
bool WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval)
Definition: RegisterContext.cpp:205
lldb_private::UnwindPlan::Row
Definition: UnwindPlan.h:55
uint32_t
lldb_private::eLazyBoolNo
@ eLazyBoolNo
Definition: lldb-private-enumerations.h:115
lldb_private::ExecutionContext::GetBestExecutionContextScope
ExecutionContextScope * GetBestExecutionContextScope() const
Definition: ExecutionContext.cpp:216
LLDB_REGNUM_GENERIC_SP
#define LLDB_REGNUM_GENERIC_SP
Definition: lldb-defines.h:64
lldb_private::DataExtractor::GetMaxU64
uint64_t GetMaxU64(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an unsigned integer of size byte_size from *offset_ptr.
Definition: DataExtractor.cpp:526
lldb_private::RegisterValue::GetAsMemoryData
uint32_t GetAsMemoryData(const RegisterInfo *reg_info, void *dst, uint32_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
Definition: RegisterValue.cpp:38
lldb_private::CompilerType::GetBitSize
llvm::Optional< uint64_t > GetBitSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bits.
Definition: CompilerType.cpp:482
lldb_private::CompilerType::GetTypeInfo
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) const
Definition: CompilerType.cpp:290
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:31
uint16_t
PluginManager.h
LLDB_INVALID_ADDRESS
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:86
lldb_private::CompilerType
Generic representation of a type in a programming language.
Definition: CompilerType.h:33
lldb_private::Stream::Printf
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
lldb_private::Value::GetCompilerType
const CompilerType & GetCompilerType()
Definition: Value.cpp:225
Status.h
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::DataExtractor::GetLongDouble
long double GetLongDouble(lldb::offset_t *offset_ptr) const
Definition: DataExtractor.cpp:632
ABISysV_arm64::CreateDefaultUnwindPlan
bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
Definition: ABISysV_arm64.cpp:347
LLDB_REGNUM_GENERIC_PC
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:63
ConstString.h
lldb_private::RegisterValue::SignExtend
bool SignExtend(uint32_t sign_bitpos)
Definition: RegisterValue.cpp:459
lldb_private::Process::GetByteOrder
lldb::ByteOrder GetByteOrder() const
Definition: Process.cpp:3344
lldb_private::Log
Definition: Log.h:49
lldb_private::Stream::PutCString
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:63
lldb_private::Thread::GetStackFrameAtIndex
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:397
lldb_private::Thread::GetRegisterContext
virtual lldb::RegisterContextSP GetRegisterContext()=0
ABISysV_arm64::FixAddress
lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) override
Definition: ABISysV_arm64.cpp:785
ABISysV_arm64
Definition: ABISysV_arm64.h:15
lldb_private::DataBufferHeap
Definition: DataBufferHeap.h:30
lldb_private::UnwindPlan
Definition: UnwindPlan.h:53
lldb
Definition: SBAddress.h:15
LoadValueFromConsecutiveGPRRegisters
static bool LoadValueFromConsecutiveGPRRegisters(ExecutionContext &exe_ctx, RegisterContext *reg_ctx, const CompilerType &value_type, bool is_return_value, uint32_t &NGRN, uint32_t &NSRN, DataExtractor &data)
Definition: ABISysV_arm64.cpp:463
RegisterContext.h
Value.h
lldb_private::RegisterValue::GetScalarValue
bool GetScalarValue(Scalar &scalar) const
Definition: RegisterValue.cpp:136
lldb_private::ExecutionContext::GetTargetPtr
Target * GetTargetPtr() const
Returns a pointer to the target object.
Definition: ExecutionContext.cpp:200
ABISysV_arm64::FixDataAddress
lldb::addr_t FixDataAddress(lldb::addr_t pc) override
Definition: ABISysV_arm64.cpp:828
lldb_private::RegisterContext::GetRegisterInfoByName
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
Definition: RegisterContext.cpp:52
lldb::ByteOrder
ByteOrder
Byte ordering definitions.
Definition: lldb-enumerations.h:138
lldb_private::Status::AsCString
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:131
LLDB_REGNUM_GENERIC_RA
#define LLDB_REGNUM_GENERIC_RA
Definition: lldb-defines.h:66