LLDB  mainline
ABISysV_mips64.cpp
Go to the documentation of this file.
1 //===-- ABISysV_mips64.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 
9 #include "ABISysV_mips64.h"
10 
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/Triple.h"
13 
14 #include "lldb/Core/Module.h"
16 #include "lldb/Core/Value.h"
20 #include "lldb/Symbol/UnwindPlan.h"
21 #include "lldb/Target/Process.h"
23 #include "lldb/Target/StackFrame.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Target/Thread.h"
28 #include "lldb/Utility/Log.h"
30 #include "lldb/Utility/Status.h"
31 
32 using namespace lldb;
33 using namespace lldb_private;
34 
36  dwarf_r0 = 0,
74 };
75 
76 static const RegisterInfo g_register_infos_mips64[] = {
77  // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
78  // DWARF GENERIC PROCESS PLUGIN
79  // LLDB NATIVE
80  // ======== ====== == === ============= ========== =============
81  // ================= ==================== =================
82  // ====================
83  {"r0",
84  "zero",
85  8,
86  0,
88  eFormatHex,
90  LLDB_INVALID_REGNUM},
91  nullptr,
92  nullptr,
93  nullptr,
94  0},
95  {"r1",
96  "AT",
97  8,
98  0,
100  eFormatHex,
102  LLDB_INVALID_REGNUM},
103  nullptr,
104  nullptr,
105  nullptr,
106  0},
107  {"r2",
108  "v0",
109  8,
110  0,
112  eFormatHex,
114  LLDB_INVALID_REGNUM},
115  nullptr,
116  nullptr,
117  nullptr,
118  0},
119  {"r3",
120  "v1",
121  8,
122  0,
124  eFormatHex,
126  LLDB_INVALID_REGNUM},
127  nullptr,
128  nullptr,
129  nullptr,
130  0},
131  {"r4",
132  "arg1",
133  8,
134  0,
136  eFormatHex,
138  LLDB_INVALID_REGNUM},
139  nullptr,
140  nullptr,
141  nullptr,
142  0},
143  {"r5",
144  "arg2",
145  8,
146  0,
148  eFormatHex,
150  LLDB_INVALID_REGNUM},
151  nullptr,
152  nullptr,
153  nullptr,
154  0},
155  {"r6",
156  "arg3",
157  8,
158  0,
160  eFormatHex,
162  LLDB_INVALID_REGNUM},
163  nullptr,
164  nullptr,
165  nullptr,
166  0},
167  {"r7",
168  "arg4",
169  8,
170  0,
172  eFormatHex,
174  LLDB_INVALID_REGNUM},
175  nullptr,
176  nullptr,
177  nullptr,
178  0},
179  {"r8",
180  "arg5",
181  8,
182  0,
184  eFormatHex,
186  LLDB_INVALID_REGNUM},
187  nullptr,
188  nullptr,
189  nullptr,
190  0},
191  {"r9",
192  "arg6",
193  8,
194  0,
196  eFormatHex,
198  LLDB_INVALID_REGNUM},
199  nullptr,
200  nullptr,
201  nullptr,
202  0},
203  {"r10",
204  "arg7",
205  8,
206  0,
208  eFormatHex,
210  LLDB_INVALID_REGNUM},
211  nullptr,
212  nullptr,
213  nullptr,
214  0},
215  {"r11",
216  "arg8",
217  8,
218  0,
220  eFormatHex,
222  LLDB_INVALID_REGNUM},
223  nullptr,
224  nullptr,
225  nullptr,
226  0},
227  {"r12",
228  nullptr,
229  8,
230  0,
232  eFormatHex,
234  LLDB_INVALID_REGNUM},
235  nullptr,
236  nullptr,
237  nullptr,
238  0},
239  {"r13",
240  nullptr,
241  8,
242  0,
244  eFormatHex,
246  LLDB_INVALID_REGNUM},
247  nullptr,
248  nullptr,
249  nullptr,
250  0},
251  {"r14",
252  nullptr,
253  8,
254  0,
256  eFormatHex,
258  LLDB_INVALID_REGNUM},
259  nullptr,
260  nullptr,
261  nullptr,
262  0},
263  {"r15",
264  nullptr,
265  8,
266  0,
268  eFormatHex,
270  LLDB_INVALID_REGNUM},
271  nullptr,
272  nullptr,
273  nullptr,
274  0},
275  {"r16",
276  nullptr,
277  8,
278  0,
280  eFormatHex,
282  LLDB_INVALID_REGNUM},
283  nullptr,
284  nullptr,
285  nullptr,
286  0},
287  {"r17",
288  nullptr,
289  8,
290  0,
292  eFormatHex,
294  LLDB_INVALID_REGNUM},
295  nullptr,
296  nullptr,
297  nullptr,
298  0},
299  {"r18",
300  nullptr,
301  8,
302  0,
304  eFormatHex,
306  LLDB_INVALID_REGNUM},
307  nullptr,
308  nullptr,
309  nullptr,
310  0},
311  {"r19",
312  nullptr,
313  8,
314  0,
316  eFormatHex,
318  LLDB_INVALID_REGNUM},
319  nullptr,
320  nullptr,
321  nullptr,
322  0},
323  {"r20",
324  nullptr,
325  8,
326  0,
328  eFormatHex,
330  LLDB_INVALID_REGNUM},
331  nullptr,
332  nullptr,
333  nullptr,
334  0},
335  {"r21",
336  nullptr,
337  8,
338  0,
340  eFormatHex,
342  LLDB_INVALID_REGNUM},
343  nullptr,
344  nullptr,
345  nullptr,
346  0},
347  {"r22",
348  nullptr,
349  8,
350  0,
352  eFormatHex,
354  LLDB_INVALID_REGNUM},
355  nullptr,
356  nullptr,
357  nullptr,
358  0},
359  {"r23",
360  nullptr,
361  8,
362  0,
364  eFormatHex,
366  LLDB_INVALID_REGNUM},
367  nullptr,
368  nullptr,
369  nullptr,
370  0},
371  {"r24",
372  nullptr,
373  8,
374  0,
376  eFormatHex,
378  LLDB_INVALID_REGNUM},
379  nullptr,
380  nullptr,
381  nullptr,
382  0},
383  {"r25",
384  nullptr,
385  8,
386  0,
388  eFormatHex,
390  LLDB_INVALID_REGNUM},
391  nullptr,
392  nullptr,
393  nullptr,
394  0},
395  {"r26",
396  nullptr,
397  8,
398  0,
400  eFormatHex,
402  LLDB_INVALID_REGNUM},
403  nullptr,
404  nullptr,
405  nullptr,
406  0},
407  {"r27",
408  nullptr,
409  8,
410  0,
412  eFormatHex,
414  LLDB_INVALID_REGNUM},
415  nullptr,
416  nullptr,
417  nullptr,
418  0},
419  {"r28",
420  "gp",
421  8,
422  0,
424  eFormatHex,
426  LLDB_INVALID_REGNUM},
427  nullptr,
428  nullptr,
429  nullptr,
430  0},
431  {"r29",
432  "sp",
433  8,
434  0,
436  eFormatHex,
438  LLDB_INVALID_REGNUM},
439  nullptr,
440  nullptr,
441  nullptr,
442  0},
443  {"r30",
444  "fp",
445  8,
446  0,
448  eFormatHex,
450  LLDB_INVALID_REGNUM},
451  nullptr,
452  nullptr,
453  nullptr,
454  0},
455  {"r31",
456  "ra",
457  8,
458  0,
460  eFormatHex,
462  LLDB_INVALID_REGNUM},
463  nullptr,
464  nullptr,
465  nullptr,
466  0},
467  {"sr",
468  nullptr,
469  4,
470  0,
472  eFormatHex,
474  LLDB_INVALID_REGNUM},
475  nullptr,
476  nullptr,
477  nullptr,
478  0},
479  {"lo",
480  nullptr,
481  8,
482  0,
484  eFormatHex,
486  LLDB_INVALID_REGNUM},
487  nullptr,
488  nullptr,
489  nullptr,
490  0},
491  {"hi",
492  nullptr,
493  8,
494  0,
496  eFormatHex,
498  LLDB_INVALID_REGNUM},
499  nullptr,
500  nullptr,
501  nullptr,
502  0},
503  {"bad",
504  nullptr,
505  8,
506  0,
508  eFormatHex,
510  LLDB_INVALID_REGNUM},
511  nullptr,
512  nullptr,
513  nullptr,
514  0},
515  {"cause",
516  nullptr,
517  8,
518  0,
520  eFormatHex,
522  LLDB_INVALID_REGNUM},
523  nullptr,
524  nullptr,
525  nullptr,
526  0},
527  {"pc",
528  nullptr,
529  8,
530  0,
532  eFormatHex,
534  LLDB_INVALID_REGNUM},
535  nullptr,
536  nullptr,
537  nullptr,
538  0},
539 };
540 
542  llvm::array_lengthof(g_register_infos_mips64);
543 
544 const lldb_private::RegisterInfo *
546  count = k_num_register_infos;
548 }
549 
550 size_t ABISysV_mips64::GetRedZoneSize() const { return 0; }
551 
552 // Static Functions
553 
554 ABISP
555 ABISysV_mips64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
556  const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
557  if ((arch_type == llvm::Triple::mips64) ||
558  (arch_type == llvm::Triple::mips64el)) {
559  return ABISP(new ABISysV_mips64(process_sp));
560  }
561  return ABISP();
562 }
563 
565  addr_t func_addr, addr_t return_addr,
566  llvm::ArrayRef<addr_t> args) const {
568 
569  if (log) {
570  StreamString s;
571  s.Printf("ABISysV_mips64::PrepareTrivialCall (tid = 0x%" PRIx64
572  ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
573  ", return_addr = 0x%" PRIx64,
574  thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
575  (uint64_t)return_addr);
576 
577  for (size_t i = 0; i < args.size(); ++i)
578  s.Printf(", arg%zd = 0x%" PRIx64, i + 1, args[i]);
579  s.PutCString(")");
580  log->PutString(s.GetString());
581  }
582 
583  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
584  if (!reg_ctx)
585  return false;
586 
587  const RegisterInfo *reg_info = nullptr;
588 
589  if (args.size() > 8) // TODO handle more than 8 arguments
590  return false;
591 
592  for (size_t i = 0; i < args.size(); ++i) {
593  reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
595  if (log)
596  log->Printf("About to write arg%zd (0x%" PRIx64 ") into %s", i + 1,
597  args[i], reg_info->name);
598  if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
599  return false;
600  }
601 
602  // First, align the SP
603 
604  if (log)
605  log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
606  (uint64_t)sp, (uint64_t)(sp & ~0xfull));
607 
608  sp &= ~(0xfull); // 16-byte alignment
609 
610  Status error;
611  const RegisterInfo *pc_reg_info =
613  const RegisterInfo *sp_reg_info =
615  const RegisterInfo *ra_reg_info =
617  const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0);
618  const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0);
619 
620  if (log)
621  log->Printf("Writing R0: 0x%" PRIx64, (uint64_t)0);
622 
623  /* Write r0 with 0, in case we are stopped in syscall,
624  * such setting prevents automatic decrement of the PC.
625  * This clears the bug 23659 for MIPS.
626  */
627  if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0))
628  return false;
629 
630  if (log)
631  log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
632 
633  // Set "sp" to the requested value
634  if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
635  return false;
636 
637  if (log)
638  log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
639 
640  // Set "ra" to the return address
641  if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
642  return false;
643 
644  if (log)
645  log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
646 
647  // Set pc to the address of the called function.
648  if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
649  return false;
650 
651  if (log)
652  log->Printf("Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
653 
654  // All callers of position independent functions must place the address of
655  // the called function in t9 (r25)
656  if (!reg_ctx->WriteRegisterFromUnsigned(r25_info, func_addr))
657  return false;
658 
659  return true;
660 }
661 
663  ValueList &values) const {
664  return false;
665 }
666 
667 Status ABISysV_mips64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
668  lldb::ValueObjectSP &new_value_sp) {
669  Status error;
670  if (!new_value_sp) {
671  error.SetErrorString("Empty value object for return value.");
672  return error;
673  }
674 
675  CompilerType compiler_type = new_value_sp->GetCompilerType();
676  if (!compiler_type) {
677  error.SetErrorString("Null clang type for return value.");
678  return error;
679  }
680 
681  Thread *thread = frame_sp->GetThread().get();
682 
683  RegisterContext *reg_ctx = thread->GetRegisterContext().get();
684 
685  if (!reg_ctx)
686  error.SetErrorString("no registers are available");
687 
688  DataExtractor data;
689  Status data_error;
690  size_t num_bytes = new_value_sp->GetData(data, data_error);
691  if (data_error.Fail()) {
693  "Couldn't convert return value to raw data: %s",
694  data_error.AsCString());
695  return error;
696  }
697 
698  const uint32_t type_flags = compiler_type.GetTypeInfo(nullptr);
699 
700  if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
701  if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
702  lldb::offset_t offset = 0;
703 
704  if (num_bytes <= 16) {
705  const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
706  if (num_bytes <= 8) {
707  uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
708 
709  if (!reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value))
710  error.SetErrorString("failed to write register r2");
711  } else {
712  uint64_t raw_value = data.GetMaxU64(&offset, 8);
713  if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) {
714  const RegisterInfo *r3_info =
715  reg_ctx->GetRegisterInfoByName("r3", 0);
716  raw_value = data.GetMaxU64(&offset, num_bytes - offset);
717 
718  if (!reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value))
719  error.SetErrorString("failed to write register r3");
720  } else
721  error.SetErrorString("failed to write register r2");
722  }
723  } else {
724  error.SetErrorString("We don't support returning longer than 128 bit "
725  "integer values at present.");
726  }
727  } else if (type_flags & eTypeIsFloat) {
728  error.SetErrorString("TODO: Handle Float Types.");
729  }
730  } else if (type_flags & eTypeIsVector) {
731  error.SetErrorString("returning vector values are not supported");
732  }
733 
734  return error;
735 }
736 
738  Thread &thread, CompilerType &return_compiler_type) const {
739  ValueObjectSP return_valobj_sp;
740  return return_valobj_sp;
741 }
742 
744  Thread &thread, CompilerType &return_compiler_type) const {
745  ValueObjectSP return_valobj_sp;
746  Value value;
747  Status error;
748 
749  ExecutionContext exe_ctx(thread.shared_from_this());
750  if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
751  return return_valobj_sp;
752 
753  value.SetCompilerType(return_compiler_type);
754 
755  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
756  if (!reg_ctx)
757  return return_valobj_sp;
758 
759  Target *target = exe_ctx.GetTargetPtr();
760  const ArchSpec target_arch = target->GetArchitecture();
761  ByteOrder target_byte_order = target_arch.GetByteOrder();
762  llvm::Optional<uint64_t> byte_size =
763  return_compiler_type.GetByteSize(nullptr);
764  if (!byte_size)
765  return return_valobj_sp;
766  const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
767  uint32_t fp_flag =
769 
770  const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
771  const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
772 
773  if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
774  value.SetValueType(Value::eValueTypeScalar);
775 
776  bool success = false;
777  if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
778  // Extract the register context so we can read arguments from registers
779  // In MIPS register "r2" (v0) holds the integer function return values
780 
781  uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0);
782 
783  const bool is_signed = (type_flags & eTypeIsSigned) != 0;
784  switch (*byte_size) {
785  default:
786  break;
787 
788  case sizeof(uint64_t):
789  if (is_signed)
790  value.GetScalar() = (int64_t)(raw_value);
791  else
792  value.GetScalar() = (uint64_t)(raw_value);
793  success = true;
794  break;
795 
796  case sizeof(uint32_t):
797  if (is_signed)
798  value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
799  else
800  value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
801  success = true;
802  break;
803 
804  case sizeof(uint16_t):
805  if (is_signed)
806  value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
807  else
808  value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
809  success = true;
810  break;
811 
812  case sizeof(uint8_t):
813  if (is_signed)
814  value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
815  else
816  value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
817  success = true;
818  break;
819  }
820  } else if (type_flags & eTypeIsFloat) {
821  if (type_flags & eTypeIsComplex) {
822  // Don't handle complex yet.
823  } else if (IsSoftFloat(fp_flag)) {
824  uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0);
825  switch (*byte_size) {
826  case 4:
827  value.GetScalar() = *((float *)(&raw_value));
828  success = true;
829  break;
830  case 8:
831  value.GetScalar() = *((double *)(&raw_value));
832  success = true;
833  break;
834  case 16:
835  uint64_t result[2];
836  if (target_byte_order == eByteOrderLittle) {
837  result[0] = raw_value;
838  result[1] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0);
839  value.GetScalar() = *((long double *)(result));
840  } else {
841  result[0] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0);
842  result[1] = raw_value;
843  value.GetScalar() = *((long double *)(result));
844  }
845  success = true;
846  break;
847  }
848 
849  } else {
850  if (*byte_size <= sizeof(long double)) {
851  const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
852 
853  RegisterValue f0_value;
854  DataExtractor f0_data;
855 
856  reg_ctx->ReadRegister(f0_info, f0_value);
857 
858  f0_value.GetData(f0_data);
859 
860  lldb::offset_t offset = 0;
861  if (*byte_size == sizeof(float)) {
862  value.GetScalar() = (float)f0_data.GetFloat(&offset);
863  success = true;
864  } else if (*byte_size == sizeof(double)) {
865  value.GetScalar() = (double)f0_data.GetDouble(&offset);
866  success = true;
867  } else if (*byte_size == sizeof(long double)) {
868  const RegisterInfo *f2_info =
869  reg_ctx->GetRegisterInfoByName("f2", 0);
870  RegisterValue f2_value;
871  DataExtractor f2_data;
872  reg_ctx->ReadRegister(f2_info, f2_value);
873  DataExtractor *copy_from_extractor = nullptr;
874  DataBufferSP data_sp(new DataBufferHeap(16, 0));
875  DataExtractor return_ext(
876  data_sp, target_byte_order,
877  target->GetArchitecture().GetAddressByteSize());
878 
879  if (target_byte_order == eByteOrderLittle) {
880  copy_from_extractor = &f0_data;
881  copy_from_extractor->CopyByteOrderedData(
882  0, 8, data_sp->GetBytes(), *byte_size - 8, target_byte_order);
883  f2_value.GetData(f2_data);
884  copy_from_extractor = &f2_data;
885  copy_from_extractor->CopyByteOrderedData(
886  0, 8, data_sp->GetBytes() + 8, *byte_size - 8,
887  target_byte_order);
888  } else {
889  copy_from_extractor = &f0_data;
890  copy_from_extractor->CopyByteOrderedData(
891  0, 8, data_sp->GetBytes() + 8, *byte_size - 8,
892  target_byte_order);
893  f2_value.GetData(f2_data);
894  copy_from_extractor = &f2_data;
895  copy_from_extractor->CopyByteOrderedData(
896  0, 8, data_sp->GetBytes(), *byte_size - 8, target_byte_order);
897  }
898 
899  return_valobj_sp = ValueObjectConstResult::Create(
900  &thread, return_compiler_type, ConstString(""), return_ext);
901  return return_valobj_sp;
902  }
903  }
904  }
905  }
906 
907  if (success)
908  return_valobj_sp = ValueObjectConstResult::Create(
909  thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
910  } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass ||
911  type_flags & eTypeIsVector) {
912  // Any structure of up to 16 bytes in size is returned in the registers.
913  if (*byte_size <= 16) {
914  DataBufferSP data_sp(new DataBufferHeap(16, 0));
915  DataExtractor return_ext(data_sp, target_byte_order,
916  target->GetArchitecture().GetAddressByteSize());
917 
918  RegisterValue r2_value, r3_value, f0_value, f1_value, f2_value;
919  // Tracks how much bytes of r2 and r3 registers we've consumed so far
920  uint32_t integer_bytes = 0;
921 
922  // True if return values are in FP return registers.
923  bool use_fp_regs = 0;
924  // True if we found any non floating point field in structure.
925  bool found_non_fp_field = 0;
926  // True if return values are in r2 register.
927  bool use_r2 = 0;
928  // True if return values are in r3 register.
929  bool use_r3 = 0;
930  // True if the result is copied into our data buffer
931  bool sucess = 0;
932  std::string name;
933  bool is_complex;
934  uint32_t count;
935  const uint32_t num_children = return_compiler_type.GetNumFields();
936 
937  // A structure consisting of one or two FP values (and nothing else) will
938  // be returned in the two FP return-value registers i.e fp0 and fp2.
939  if (num_children <= 2) {
940  uint64_t field_bit_offset = 0;
941 
942  // Check if this structure contains only floating point fields
943  for (uint32_t idx = 0; idx < num_children; idx++) {
944  CompilerType field_compiler_type =
945  return_compiler_type.GetFieldAtIndex(idx, name, &field_bit_offset,
946  nullptr, nullptr);
947 
948  if (field_compiler_type.IsFloatingPointType(count, is_complex))
949  use_fp_regs = 1;
950  else
951  found_non_fp_field = 1;
952  }
953 
954  if (use_fp_regs && !found_non_fp_field) {
955  // We have one or two FP-only values in this structure. Get it from
956  // f0/f2 registers.
957  DataExtractor f0_data, f1_data, f2_data;
958  const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
959  const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
960  const RegisterInfo *f2_info = reg_ctx->GetRegisterInfoByName("f2", 0);
961 
962  reg_ctx->ReadRegister(f0_info, f0_value);
963  reg_ctx->ReadRegister(f2_info, f2_value);
964 
965  f0_value.GetData(f0_data);
966 
967  for (uint32_t idx = 0; idx < num_children; idx++) {
968  CompilerType field_compiler_type =
969  return_compiler_type.GetFieldAtIndex(
970  idx, name, &field_bit_offset, nullptr, nullptr);
971  llvm::Optional<uint64_t> field_byte_width =
972  field_compiler_type.GetByteSize(nullptr);
973  if (!field_byte_width)
974  return return_valobj_sp;
975 
976  DataExtractor *copy_from_extractor = nullptr;
977  uint64_t return_value[2];
978  offset_t offset = 0;
979 
980  if (idx == 0) {
981  // This case is for long double type.
982  if (*field_byte_width == 16) {
983 
984  // If structure contains long double type, then it is returned
985  // in fp0/fp1 registers.
986  if (target_byte_order == eByteOrderLittle) {
987  return_value[0] = f0_data.GetU64(&offset);
988  reg_ctx->ReadRegister(f1_info, f1_value);
989  f1_value.GetData(f1_data);
990  offset = 0;
991  return_value[1] = f1_data.GetU64(&offset);
992  } else {
993  return_value[1] = f0_data.GetU64(&offset);
994  reg_ctx->ReadRegister(f1_info, f1_value);
995  f1_value.GetData(f1_data);
996  offset = 0;
997  return_value[0] = f1_data.GetU64(&offset);
998  }
999 
1000  f0_data.SetData(return_value, *field_byte_width,
1001  target_byte_order);
1002  }
1003  copy_from_extractor = &f0_data; // This is in f0, copy from
1004  // register to our result
1005  // structure
1006  } else {
1007  f2_value.GetData(f2_data);
1008  // This is in f2, copy from register to our result structure
1009  copy_from_extractor = &f2_data;
1010  }
1011 
1012  // Sanity check to avoid crash
1013  if (!copy_from_extractor ||
1014  *field_byte_width > copy_from_extractor->GetByteSize())
1015  return return_valobj_sp;
1016 
1017  // copy the register contents into our data buffer
1018  copy_from_extractor->CopyByteOrderedData(
1019  0, *field_byte_width,
1020  data_sp->GetBytes() + (field_bit_offset / 8), *field_byte_width,
1021  target_byte_order);
1022  }
1023 
1024  // The result is in our data buffer. Create a variable object out of
1025  // it
1026  return_valobj_sp = ValueObjectConstResult::Create(
1027  &thread, return_compiler_type, ConstString(""), return_ext);
1028 
1029  return return_valobj_sp;
1030  }
1031  }
1032 
1033  // If we reach here, it means this structure either contains more than
1034  // two fields or it contains at least one non floating point type. In
1035  // that case, all fields are returned in GP return registers.
1036  for (uint32_t idx = 0; idx < num_children; idx++) {
1037  uint64_t field_bit_offset = 0;
1038  bool is_signed;
1039  uint32_t padding;
1040 
1041  CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
1042  idx, name, &field_bit_offset, nullptr, nullptr);
1043  llvm::Optional<uint64_t> field_byte_width =
1044  field_compiler_type.GetByteSize(nullptr);
1045 
1046  // if we don't know the size of the field (e.g. invalid type), just
1047  // bail out
1048  if (!field_byte_width || *field_byte_width == 0)
1049  break;
1050 
1051  uint32_t field_byte_offset = field_bit_offset / 8;
1052 
1053  if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1054  field_compiler_type.IsPointerType() ||
1055  field_compiler_type.IsFloatingPointType(count, is_complex)) {
1056  padding = field_byte_offset - integer_bytes;
1057 
1058  if (integer_bytes < 8) {
1059  // We have not yet consumed r2 completely.
1060  if (integer_bytes + *field_byte_width + padding <= 8) {
1061  // This field fits in r2, copy its value from r2 to our result
1062  // structure
1063  integer_bytes = integer_bytes + *field_byte_width +
1064  padding; // Increase the consumed bytes.
1065  use_r2 = 1;
1066  } else {
1067  // There isn't enough space left in r2 for this field, so this
1068  // will be in r3.
1069  integer_bytes = integer_bytes + *field_byte_width +
1070  padding; // Increase the consumed bytes.
1071  use_r3 = 1;
1072  }
1073  }
1074  // We already have consumed at-least 8 bytes that means r2 is done,
1075  // and this field will be in r3. Check if this field can fit in r3.
1076  else if (integer_bytes + *field_byte_width + padding <= 16) {
1077  integer_bytes = integer_bytes + *field_byte_width + padding;
1078  use_r3 = 1;
1079  } else {
1080  // There isn't any space left for this field, this should not
1081  // happen as we have already checked the overall size is not
1082  // greater than 16 bytes. For now, return a nullptr return value
1083  // object.
1084  return return_valobj_sp;
1085  }
1086  }
1087  }
1088  // Vector types up to 16 bytes are returned in GP return registers
1089  if (type_flags & eTypeIsVector) {
1090  if (*byte_size <= 8)
1091  use_r2 = 1;
1092  else {
1093  use_r2 = 1;
1094  use_r3 = 1;
1095  }
1096  }
1097 
1098  if (use_r2) {
1099  reg_ctx->ReadRegister(r2_info, r2_value);
1100 
1101  const size_t bytes_copied = r2_value.GetAsMemoryData(
1102  r2_info, data_sp->GetBytes(), r2_info->byte_size, target_byte_order,
1103  error);
1104  if (bytes_copied != r2_info->byte_size)
1105  return return_valobj_sp;
1106  sucess = 1;
1107  }
1108  if (use_r3) {
1109  reg_ctx->ReadRegister(r3_info, r3_value);
1110  const size_t bytes_copied = r3_value.GetAsMemoryData(
1111  r3_info, data_sp->GetBytes() + r2_info->byte_size,
1112  r3_info->byte_size, target_byte_order, error);
1113 
1114  if (bytes_copied != r3_info->byte_size)
1115  return return_valobj_sp;
1116  sucess = 1;
1117  }
1118  if (sucess) {
1119  // The result is in our data buffer. Create a variable object out of
1120  // it
1121  return_valobj_sp = ValueObjectConstResult::Create(
1122  &thread, return_compiler_type, ConstString(""), return_ext);
1123  }
1124  return return_valobj_sp;
1125  }
1126 
1127  // Any structure/vector greater than 16 bytes in size is returned in
1128  // memory. The pointer to that memory is returned in r2.
1129  uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned(
1130  reg_ctx->GetRegisterInfoByName("r2", 0), 0);
1131 
1132  // We have got the address. Create a memory object out of it
1133  return_valobj_sp = ValueObjectMemory::Create(
1134  &thread, "", Address(mem_address, nullptr), return_compiler_type);
1135  }
1136  return return_valobj_sp;
1137 }
1138 
1140  unwind_plan.Clear();
1141  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1142 
1144 
1145  // Our Call Frame Address is the stack pointer value
1146  row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
1147 
1148  // The previous PC is in the RA
1149  row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
1150  unwind_plan.AppendRow(row);
1151 
1152  // All other registers are the same.
1153 
1154  unwind_plan.SetSourceName("mips64 at-func-entry default");
1155  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1156  unwind_plan.SetReturnAddressRegister(dwarf_r31);
1157  return true;
1158 }
1159 
1161  unwind_plan.Clear();
1162  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1163 
1165 
1166  row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
1167 
1168  row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
1169 
1170  unwind_plan.AppendRow(row);
1171  unwind_plan.SetSourceName("mips64 default unwind plan");
1172  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1174  return true;
1175 }
1176 
1177 bool ABISysV_mips64::RegisterIsVolatile(const RegisterInfo *reg_info) {
1178  return !RegisterIsCalleeSaved(reg_info);
1179 }
1180 
1182  return (fp_flag == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT);
1183 }
1184 
1185 bool ABISysV_mips64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1186  if (reg_info) {
1187  // Preserved registers are :
1188  // r16-r23, r28, r29, r30, r31
1189 
1190  int reg = ((reg_info->byte_offset) / 8);
1191 
1192  bool save = (reg >= 16) && (reg <= 23);
1193  save |= (reg >= 28) && (reg <= 31);
1194 
1195  return save;
1196  }
1197  return false;
1198 }
1199 
1201  PluginManager::RegisterPlugin(
1202  GetPluginNameStatic(), "System V ABI for mips64 targets", CreateInstance);
1203 }
1204 
1206  PluginManager::UnregisterPlugin(CreateInstance);
1207 }
1208 
1210  static ConstString g_name("sysv-mips64");
1211  return g_name;
1212 }
1213 
1214 // PluginInterface protocol
1215 
1217  return GetPluginNameStatic();
1218 }
1219 
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:61
uint32_t GetFlags() const
Definition: ArchSpec.h:501
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:63
An data extractor class.
Definition: DataExtractor.h:47
lldb_private::Status SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override
#define LLDB_REGNUM_GENERIC_ARG6
Definition: lldb-defines.h:78
void SetSourceName(const char *)
Definition: UnwindPlan.cpp:542
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
const ArchSpec & GetArchitecture() const
Definition: Target.h:941
const void * GetData(lldb::offset_t *offset_ptr, lldb::offset_t length) const
Extract length bytes from *offset_ptr.
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override
static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch)
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition: ArchSpec.cpp:742
#define LLDB_REGNUM_GENERIC_RA
Definition: lldb-defines.h:66
uint64_t ReadRegisterAsUnsigned(uint32_t reg, uint64_t fail_value)
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
#define LLDB_REGNUM_GENERIC_ARG4
Definition: lldb-defines.h:74
bool IsIntegerOrEnumerationType(bool &is_signed) const
void PutString(llvm::StringRef str)
Definition: Log.cpp:110
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition: UserID.h:49
static void Initialize()
An architecture specification class.
Definition: ArchSpec.h:32
#define LLDB_REGNUM_GENERIC_ARG2
Definition: lldb-defines.h:70
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) const
void SetValueType(ValueType value_type)
Definition: Value.h:154
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
#define LLDB_REGNUM_GENERIC_SP
Definition: lldb-defines.h:64
#define LLDB_REGNUM_GENERIC_ARG7
Definition: lldb-defines.h:80
llvm::Optional< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
#define LLDB_REGNUM_GENERIC_ARG5
Definition: lldb-defines.h:76
float GetFloat(lldb::offset_t *offset_ptr) const
Extract a float from *offset_ptr.
uint32_t GetNumFields() const
A subclass of DataBuffer that stores a data buffer on the heap.
#define LLDB_REGNUM_GENERIC_ARG1
Definition: lldb-defines.h:68
bool IsPointerType(CompilerType *pointee_type=nullptr) const
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:431
bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
#define LLDB_REGNUM_GENERIC_FP
Definition: lldb-defines.h:65
#define UINT32_MAX
Definition: lldb-defines.h:31
bool IsSoftFloat(uint32_t fp_flag) const
bool IsFloatingPointType(uint32_t &count, bool &is_complex) 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.
uint64_t offset_t
Definition: lldb-types.h:87
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:57
size_t GetRedZoneSize() const override
std::shared_ptr< Row > RowSP
Definition: UnwindPlan.h:366
void AppendRow(const RowSP &row_sp)
Definition: UnwindPlan.cpp:355
bool GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override
uint32_t GetPluginVersion() override
llvm::StringRef GetString() const
virtual lldb::RegisterContextSP GetRegisterContext()=0
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
Definition: Status.cpp:241
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)=0
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition: ArchSpec.cpp:788
double GetDouble(lldb::offset_t *offset_ptr) const
#define LLDB_REGNUM_GENERIC_FLAGS
Definition: lldb-defines.h:67
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
void SetRegisterKind(lldb::RegisterKind kind)
Definition: UnwindPlan.h:408
A section + offset based address class.
Definition: Address.h:80
static const uint32_t k_num_register_infos
bool WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval)
dwarf_regnums
uint64_t GetMaxU64(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an unsigned integer of size byte_size from *offset_ptr.
uint64_t GetByteSize() const
Get the number of bytes contained in this object.
lldb::ValueObjectSP GetReturnValueObjectSimple(lldb_private::Thread &thread, lldb_private::CompilerType &ast_type) const
const RegisterInfo * GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num)
void SetUnwindPlanValidAtAllInstructions(lldb_private::LazyBool valid_at_all_insn)
Definition: UnwindPlan.h:461
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...
static lldb_private::ConstString GetPluginNameStatic()
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info)
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override
bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
uint64_t addr_t
Definition: lldb-types.h:83
bool GetData(DataExtractor &data) const
A uniqued constant string class.
Definition: ConstString.h:38
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
#define LLDB_REGNUM_GENERIC_ARG8
Definition: lldb-defines.h:82
const lldb_private::RegisterInfo * GetRegisterInfoArray(uint32_t &count) override
#define LLDB_REGNUM_GENERIC_ARG3
Definition: lldb-defines.h:72
Definition: SBAddress.h:15
static const RegisterInfo g_register_infos_mips64[]
static void Terminate()
CompilerType GetFieldAtIndex(size_t idx, std::string &name, uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) const
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:255
void SetCompilerType(const CompilerType &compiler_type)
Definition: Value.cpp:268
#define LIBLLDB_LOG_EXPRESSIONS
Definition: Logging.h:22
const Scalar & GetScalar() const
Definition: Value.h:178
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:130
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:395
void Printf(const char *format,...) __attribute__((format(printf
Definition: Log.cpp:113
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
Definition: UnwindPlan.h:449
lldb_private::ConstString GetPluginName() override
void SetReturnAddressRegister(uint32_t regnum)
Definition: UnwindPlan.h:410
uint64_t GetU64(lldb::offset_t *offset_ptr) const
Extract a uint64_t value from *offset_ptr.
An error handling class.
Definition: Status.h:44
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:90