11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/Triple.h"
509 const lldb_private::RegisterInfo *
523 new ABISysV_mips64(std::move(process_sp), MakeMCRegisterInfo(arch)));
529 llvm::ArrayRef<addr_t> args)
const {
534 s.
Printf(
"ABISysV_mips64::PrepareTrivialCall (tid = 0x%" PRIx64
535 ", sp = 0x%" PRIx64
", func_addr = 0x%" PRIx64
536 ", return_addr = 0x%" PRIx64,
537 thread.
GetID(), (uint64_t)
sp, (uint64_t)func_addr,
538 (uint64_t)return_addr);
540 for (
size_t i = 0; i < args.size(); ++i)
541 s.
Printf(
", arg%zd = 0x%" PRIx64, i + 1, args[i]);
550 const RegisterInfo *reg_info =
nullptr;
555 for (
size_t i = 0; i < args.size(); ++i) {
558 LLDB_LOGF(log,
"About to write arg%zd (0x%" PRIx64
") into %s", i + 1,
559 args[i], reg_info->name);
566 LLDB_LOGF(log,
"16-byte aligning SP: 0x%" PRIx64
" to 0x%" PRIx64,
567 (uint64_t)
sp, (uint64_t)(
sp & ~0xfull));
572 const RegisterInfo *pc_reg_info =
574 const RegisterInfo *sp_reg_info =
576 const RegisterInfo *ra_reg_info =
581 LLDB_LOGF(log,
"Writing R0: 0x%" PRIx64, (uint64_t)0);
590 LLDB_LOGF(log,
"Writing SP: 0x%" PRIx64, (uint64_t)
sp);
596 LLDB_LOGF(log,
"Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
602 LLDB_LOGF(log,
"Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
608 LLDB_LOGF(log,
"Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
624 lldb::ValueObjectSP &new_value_sp) {
627 error.SetErrorString(
"Empty value object for return value.");
631 CompilerType compiler_type = new_value_sp->GetCompilerType();
632 if (!compiler_type) {
633 error.SetErrorString(
"Null clang type for return value.");
637 Thread *thread = frame_sp->GetThread().get();
642 error.SetErrorString(
"no registers are available");
646 size_t num_bytes = new_value_sp->GetData(data, data_error);
647 if (data_error.
Fail()) {
648 error.SetErrorStringWithFormat(
649 "Couldn't convert return value to raw data: %s",
656 if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
657 if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
660 if (num_bytes <= 16) {
662 if (num_bytes <= 8) {
663 uint64_t raw_value = data.
GetMaxU64(&offset, num_bytes);
666 error.SetErrorString(
"failed to write register r2");
668 uint64_t raw_value = data.
GetMaxU64(&offset, 8);
670 const RegisterInfo *r3_info =
672 raw_value = data.
GetMaxU64(&offset, num_bytes - offset);
675 error.SetErrorString(
"failed to write register r3");
677 error.SetErrorString(
"failed to write register r2");
680 error.SetErrorString(
"We don't support returning longer than 128 bit "
681 "integer values at present.");
683 }
else if (type_flags & eTypeIsFloat) {
684 error.SetErrorString(
"TODO: Handle Float Types.");
686 }
else if (type_flags & eTypeIsVector) {
687 error.SetErrorString(
"returning vector values are not supported");
695 ValueObjectSP return_valobj_sp;
696 return return_valobj_sp;
701 ValueObjectSP return_valobj_sp;
707 return return_valobj_sp;
713 return return_valobj_sp;
718 llvm::Optional<uint64_t> byte_size =
721 return return_valobj_sp;
729 if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
732 bool success =
false;
733 if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
739 const bool is_signed = (type_flags & eTypeIsSigned) != 0;
740 switch (*byte_size) {
744 case sizeof(uint64_t):
746 value.
GetScalar() = (int64_t)(raw_value);
748 value.
GetScalar() = (uint64_t)(raw_value);
762 value.
GetScalar() = (int16_t)(raw_value & UINT16_MAX);
768 case sizeof(uint8_t):
770 value.
GetScalar() = (int8_t)(raw_value & UINT8_MAX);
772 value.
GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
776 }
else if (type_flags & eTypeIsFloat) {
777 if (type_flags & eTypeIsComplex) {
779 }
else if (IsSoftFloat(fp_flag)) {
781 switch (*byte_size) {
783 value.
GetScalar() = *((
float *)(&raw_value));
787 value.
GetScalar() = *((
double *)(&raw_value));
793 result[0] = raw_value;
795 value.
GetScalar() = *((
long double *)(result));
798 result[1] = raw_value;
799 value.
GetScalar() = *((
long double *)(result));
806 if (*byte_size <=
sizeof(
long double)) {
817 if (*byte_size ==
sizeof(
float)) {
820 }
else if (*byte_size ==
sizeof(
double)) {
823 }
else if (*byte_size ==
sizeof(
long double)) {
824 const RegisterInfo *f2_info =
832 data_sp, target_byte_order,
836 copy_from_extractor = &f0_data;
838 0, 8, data_sp->GetBytes(), *byte_size - 8, target_byte_order);
840 copy_from_extractor = &f2_data;
842 0, 8, data_sp->GetBytes() + 8, *byte_size - 8,
845 copy_from_extractor = &f0_data;
847 0, 8, data_sp->GetBytes() + 8, *byte_size - 8,
850 copy_from_extractor = &f2_data;
852 0, 8, data_sp->GetBytes(), *byte_size - 8, target_byte_order);
855 return_valobj_sp = ValueObjectConstResult::Create(
856 &thread, return_compiler_type,
ConstString(
""), return_ext);
857 return return_valobj_sp;
864 return_valobj_sp = ValueObjectConstResult::Create(
866 }
else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass ||
867 type_flags & eTypeIsVector) {
869 if (*byte_size <= 16) {
874 RegisterValue r2_value, r3_value, f0_value, f1_value, f2_value;
879 bool use_fp_regs =
false;
881 bool found_non_fp_field =
false;
895 if (num_children <= 2) {
896 uint64_t field_bit_offset = 0;
899 for (
uint32_t idx = 0; idx < num_children; idx++) {
907 found_non_fp_field =
true;
910 if (use_fp_regs && !found_non_fp_field) {
923 for (
uint32_t idx = 0; idx < num_children; idx++) {
926 idx, name, &field_bit_offset,
nullptr,
nullptr);
927 llvm::Optional<uint64_t> field_byte_width =
929 if (!field_byte_width)
930 return return_valobj_sp;
933 uint64_t return_value[2];
938 if (*field_byte_width == 16) {
943 return_value[0] = f0_data.
GetU64(&offset);
947 return_value[1] = f1_data.
GetU64(&offset);
949 return_value[1] = f0_data.
GetU64(&offset);
953 return_value[0] = f1_data.
GetU64(&offset);
956 f0_data.
SetData(return_value, *field_byte_width,
959 copy_from_extractor = &f0_data;
965 copy_from_extractor = &f2_data;
969 if (!copy_from_extractor ||
970 *field_byte_width > copy_from_extractor->
GetByteSize())
971 return return_valobj_sp;
975 0, *field_byte_width,
976 data_sp->GetBytes() + (field_bit_offset / 8), *field_byte_width,
982 return_valobj_sp = ValueObjectConstResult::Create(
983 &thread, return_compiler_type,
ConstString(
""), return_ext);
985 return return_valobj_sp;
992 for (
uint32_t idx = 0; idx < num_children; idx++) {
993 uint64_t field_bit_offset = 0;
998 idx, name, &field_bit_offset,
nullptr,
nullptr);
999 llvm::Optional<uint64_t> field_byte_width =
1004 if (!field_byte_width || *field_byte_width == 0)
1007 uint32_t field_byte_offset = field_bit_offset / 8;
1012 padding = field_byte_offset - integer_bytes;
1014 if (integer_bytes < 8) {
1016 if (integer_bytes + *field_byte_width + padding <= 8) {
1019 integer_bytes = integer_bytes + *field_byte_width +
1025 integer_bytes = integer_bytes + *field_byte_width +
1032 else if (integer_bytes + *field_byte_width + padding <= 16) {
1033 integer_bytes = integer_bytes + *field_byte_width + padding;
1040 return return_valobj_sp;
1045 if (type_flags & eTypeIsVector) {
1046 if (*byte_size <= 8)
1058 r2_info, data_sp->GetBytes(), r2_info->byte_size, target_byte_order,
1060 if (bytes_copied != r2_info->byte_size)
1061 return return_valobj_sp;
1067 r3_info, data_sp->GetBytes() + r2_info->byte_size,
1068 r3_info->byte_size, target_byte_order,
error);
1070 if (bytes_copied != r3_info->byte_size)
1071 return return_valobj_sp;
1077 return_valobj_sp = ValueObjectConstResult::Create(
1078 &thread, return_compiler_type,
ConstString(
""), return_ext);
1080 return return_valobj_sp;
1089 return_valobj_sp = ValueObjectMemory::Create(
1090 &thread,
"",
Address(mem_address,
nullptr), return_compiler_type);
1092 return return_valobj_sp;
1096 unwind_plan.
Clear();
1102 row->GetCFAValue().SetIsRegisterPlusOffset(
dwarf_r29, 0);
1117 unwind_plan.
Clear();
1122 row->SetUnspecifiedRegistersAreUndefined(
true);
1123 row->GetCFAValue().SetIsRegisterPlusOffset(
dwarf_r29, 0);
1136 return !RegisterIsCalleeSaved(reg_info);
1148 int reg = ((reg_info->byte_offset) / 8);
1150 bool save = (reg >= 16) && (reg <= 23);
1151 save |= (reg >= 28) && (reg <= 31);
1159 PluginManager::RegisterPlugin(
1160 GetPluginNameStatic(),
"System V ABI for mips64 targets", CreateInstance);
1164 PluginManager::UnregisterPlugin(CreateInstance);