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