13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/Triple.h"
37 static const char *
pluginDesc =
"Mac OS X ABI for arm64 targets";
45 const llvm::Triple::ArchType arch_type = arch.
GetTriple().getArch();
46 const llvm::Triple::VendorType vendor_type = arch.
GetTriple().getVendor();
48 if (vendor_type == llvm::Triple::Apple) {
49 if (arch_type == llvm::Triple::aarch64 ||
50 arch_type == llvm::Triple::aarch64_32) {
61 lldb::addr_t return_addr, llvm::ArrayRef<lldb::addr_t> args)
const {
70 s.
Printf(
"ABIMacOSX_arm64::PrepareTrivialCall (tid = 0x%" PRIx64
71 ", sp = 0x%" PRIx64
", func_addr = 0x%" PRIx64
72 ", return_addr = 0x%" PRIx64,
73 thread.
GetID(), (uint64_t)
sp, (uint64_t)func_addr,
74 (uint64_t)return_addr);
76 for (
size_t i = 0; i < args.size(); ++i)
77 s.
Printf(
", arg%d = 0x%" PRIx64,
static_cast<int>(i + 1), args[i]);
93 for (
size_t i = 0; i < args.size(); ++i) {
96 LLDB_LOGF(log,
"About to write arg%d (0x%" PRIx64
") into %s",
97 static_cast<int>(i + 1), args[i], reg_info->name);
135 for (
uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
144 llvm::Optional<uint64_t> bit_size = value_type.
GetBitSize(&thread);
148 bool is_signed =
false;
149 size_t bit_width = 0;
151 bit_width = *bit_size;
153 bit_width = *bit_size;
162 const RegisterInfo *reg_info =
nullptr;
218 const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
239 lldb::ValueObjectSP &new_value_sp) {
242 error.SetErrorString(
"Empty value object for return value.");
246 CompilerType return_value_type = new_value_sp->GetCompilerType();
247 if (!return_value_type) {
248 error.SetErrorString(
"Null clang type for return value.");
252 Thread *thread = frame_sp->GetThread().get();
259 const uint64_t byte_size = new_value_sp->GetData(data, data_error);
260 if (data_error.
Fail()) {
261 error.SetErrorStringWithFormat(
262 "Couldn't convert return value to raw data: %s",
268 if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
269 if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
272 if (byte_size <= 16) {
274 if (byte_size <= 8) {
275 uint64_t raw_value = data.
GetMaxU64(&offset, byte_size);
278 error.SetErrorString(
"failed to write register x0");
280 uint64_t raw_value = data.
GetMaxU64(&offset, 8);
283 const RegisterInfo *x1_info =
285 raw_value = data.
GetMaxU64(&offset, byte_size - offset);
288 error.SetErrorString(
"failed to write register x1");
292 error.SetErrorString(
"We don't support returning longer than 128 bit "
293 "integer values at present.");
295 }
else if (type_flags & eTypeIsFloat) {
296 if (type_flags & eTypeIsComplex) {
298 error.SetErrorString(
299 "returning complex float values are not supported");
304 if (byte_size <= 16) {
305 if (byte_size <= RegisterValue::GetMaxByteSize()) {
308 if (
error.Success()) {
310 error.SetErrorString(
"failed to write register v0");
313 error.SetErrorStringWithFormat(
314 "returning float values with a byte size of %" PRIu64
315 " are not supported",
319 error.SetErrorString(
"returning float values longer than 128 "
320 "bits are not supported");
323 error.SetErrorString(
"v0 register is not available on this target");
327 }
else if (type_flags & eTypeIsVector) {
332 if (byte_size <= v0_info->byte_size) {
335 if (
error.Success()) {
337 error.SetErrorString(
"failed to write register v0");
344 error.SetErrorString(
"no registers are available");
361 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
364 row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num,
true);
384 const int32_t ptr_size = 8;
386 row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
388 row->SetUnspecifiedRegistersAreUndefined(
true);
390 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2,
true);
391 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1,
true);
394 unwind_plan.
SetSourceName(
"arm64-apple-darwin default unwind plan");
413 const char *name = reg_info->name;
418 if (name[0] ==
'p' && name[1] ==
'c')
420 if (name[0] ==
'f' && name[1] ==
'p')
422 if (name[0] ==
's' && name[1] ==
'p')
424 if (name[0] ==
'l' && name[1] ==
'r')
427 if (name[0] ==
'x') {
463 }
else if (name[0] ==
'v' || name[0] ==
's' || name[0] ==
'd') {
493 bool is_return_value,
497 llvm::Optional<uint64_t> byte_size =
499 if (!byte_size || *byte_size == 0)
502 std::unique_ptr<DataBufferHeap> heap_data_up(
510 if (homogeneous_count > 0 && homogeneous_count <= 8) {
512 if (NSRN < 8 && (8 - NSRN) >= homogeneous_count) {
515 llvm::Optional<uint64_t> base_byte_size =
521 for (
uint32_t i = 0; i < homogeneous_count; ++i) {
523 ::snprintf(v_name,
sizeof(v_name),
"v%u", NSRN);
524 const RegisterInfo *reg_info =
526 if (reg_info ==
nullptr)
529 if (*base_byte_size > reg_info->byte_size)
538 if ((data_offset + *base_byte_size) <= heap_data_up->GetByteSize()) {
540 reg_info, heap_data_up->GetBytes() + data_offset, *base_byte_size,
542 if (bytes_copied != *base_byte_size)
544 data_offset += bytes_copied;
551 data.
SetData(DataBufferSP(heap_data_up.release()));
556 const size_t max_reg_byte_size = 16;
557 if (*byte_size <= max_reg_byte_size) {
558 size_t bytes_left = *byte_size;
560 while (data_offset < *byte_size) {
570 if (reg_info ==
nullptr)
578 const size_t curr_byte_size = std::min<size_t>(8, bytes_left);
580 reg_info, heap_data_up->GetBytes() + data_offset, curr_byte_size,
582 if (bytes_copied == 0)
584 if (bytes_copied >= bytes_left)
586 data_offset += bytes_copied;
587 bytes_left -= bytes_copied;
591 const RegisterInfo *reg_info =
nullptr;
592 if (is_return_value) {
610 if (reg_info ==
nullptr)
615 if (reg_info ==
nullptr)
625 value_addr, heap_data_up->GetBytes(), heap_data_up->GetByteSize(),
626 error) != heap_data_up->GetByteSize()) {
633 data.
SetData(DataBufferSP(heap_data_up.release()));
639 ValueObjectSP return_valobj_sp;
644 return return_valobj_sp;
651 return return_valobj_sp;
653 llvm::Optional<uint64_t> byte_size =
656 return return_valobj_sp;
659 if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
662 bool success =
false;
663 if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
665 if (*byte_size <= 8) {
666 const RegisterInfo *x0_reg_info =
672 const bool is_signed = (type_flags & eTypeIsSigned) != 0;
673 switch (*byte_size) {
679 const RegisterInfo *x1_reg_info =
684 x0_reg_info->byte_size + x1_reg_info->byte_size) {
685 std::unique_ptr<DataBufferHeap> heap_data_up(
695 x0_reg_info, heap_data_up->GetBytes() + 0, 8,
696 byte_order,
error) &&
698 x1_reg_info, heap_data_up->GetBytes() + 8, 8,
699 byte_order,
error)) {
701 DataBufferSP(heap_data_up.release()), byte_order,
704 return_valobj_sp = ValueObjectConstResult::Create(
705 &thread, return_compiler_type,
ConstString(
""), data);
706 return return_valobj_sp;
713 case sizeof(uint64_t):
715 value.
GetScalar() = (int64_t)(raw_value);
717 value.
GetScalar() = (uint64_t)(raw_value);
731 value.
GetScalar() = (int16_t)(raw_value & UINT16_MAX);
737 case sizeof(uint8_t):
739 value.
GetScalar() = (int8_t)(raw_value & UINT8_MAX);
741 value.
GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
747 }
else if (type_flags & eTypeIsFloat) {
748 if (type_flags & eTypeIsComplex) {
751 if (*byte_size <=
sizeof(
long double)) {
752 const RegisterInfo *v0_reg_info =
759 if (*byte_size ==
sizeof(
float)) {
762 }
else if (*byte_size ==
sizeof(
double)) {
765 }
else if (*byte_size ==
sizeof(
long double)) {
776 return_valobj_sp = ValueObjectConstResult::Create(
778 }
else if (type_flags & eTypeIsVector) {
779 if (*byte_size > 0) {
784 if (*byte_size <= v0_info->byte_size) {
785 std::unique_ptr<DataBufferHeap> heap_data_up(
792 heap_data_up->GetByteSize(),
793 byte_order,
error)) {
797 return_valobj_sp = ValueObjectConstResult::Create(
798 &thread, return_compiler_type,
ConstString(
""), data);
804 }
else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass) {
809 const bool is_return_value =
true;
811 exe_ctx, reg_ctx, return_compiler_type, is_return_value, NGRN, NSRN,
813 return_valobj_sp = ValueObjectConstResult::Create(
814 &thread, return_compiler_type,
ConstString(
""), data);
817 return return_valobj_sp;
821 lldb::addr_t pac_sign_extension = 0x0080000000000000ULL;
830 mask = 0xffffff8000000000;
832 return (
pc & pac_sign_extension) ?
pc | mask :
pc & (~mask);
836 PluginManager::RegisterPlugin(GetPluginNameStatic(),
pluginDesc,
841 PluginManager::UnregisterPlugin(CreateInstance);