LLDB  mainline
ABISysV_mips.cpp
Go to the documentation of this file.
1 //===-- ABISysV_mips.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_mips.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 
38  dwarf_r0 = 0,
76 };
77 
78 static const RegisterInfo g_register_infos[] = {
79  // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
80  // DWARF GENERIC PROCESS PLUGINS
81  // LLDB NATIVE VALUE REGS INVALIDATE REGS
82  // ======== ====== == === ============= =========== ============
83  // ============== ============ =================
84  // =================== ========== =================
85  {"r0",
86  "zero",
87  4,
88  0,
90  eFormatHex,
93  nullptr,
94  nullptr,
95  },
96  {"r1",
97  "AT",
98  4,
99  0,
101  eFormatHex,
104  nullptr,
105  nullptr,
106  },
107  {"r2",
108  "v0",
109  4,
110  0,
112  eFormatHex,
115  nullptr,
116  nullptr,
117  },
118  {"r3",
119  "v1",
120  4,
121  0,
123  eFormatHex,
126  nullptr,
127  nullptr,
128  },
129  {"r4",
130  nullptr,
131  4,
132  0,
134  eFormatHex,
137  nullptr,
138  nullptr,
139  },
140  {"r5",
141  nullptr,
142  4,
143  0,
145  eFormatHex,
148  nullptr,
149  nullptr,
150  },
151  {"r6",
152  nullptr,
153  4,
154  0,
156  eFormatHex,
159  nullptr,
160  nullptr,
161  },
162  {"r7",
163  nullptr,
164  4,
165  0,
167  eFormatHex,
170  nullptr,
171  nullptr,
172  },
173  {"r8",
174  "arg5",
175  4,
176  0,
178  eFormatHex,
181  nullptr,
182  nullptr,
183  },
184  {"r9",
185  "arg6",
186  4,
187  0,
189  eFormatHex,
192  nullptr,
193  nullptr,
194  },
195  {"r10",
196  "arg7",
197  4,
198  0,
200  eFormatHex,
203  nullptr,
204  nullptr,
205  },
206  {"r11",
207  "arg8",
208  4,
209  0,
211  eFormatHex,
214  nullptr,
215  nullptr,
216  },
217  {"r12",
218  nullptr,
219  4,
220  0,
222  eFormatHex,
225  nullptr,
226  nullptr,
227  },
228  {"r13",
229  nullptr,
230  4,
231  0,
233  eFormatHex,
236  nullptr,
237  nullptr,
238  },
239  {"r14",
240  nullptr,
241  4,
242  0,
244  eFormatHex,
247  nullptr,
248  nullptr,
249  },
250  {"r15",
251  nullptr,
252  4,
253  0,
255  eFormatHex,
258  nullptr,
259  nullptr,
260  },
261  {"r16",
262  nullptr,
263  4,
264  0,
266  eFormatHex,
269  nullptr,
270  nullptr,
271  },
272  {"r17",
273  nullptr,
274  4,
275  0,
277  eFormatHex,
280  nullptr,
281  nullptr,
282  },
283  {"r18",
284  nullptr,
285  4,
286  0,
288  eFormatHex,
291  nullptr,
292  nullptr,
293  },
294  {"r19",
295  nullptr,
296  4,
297  0,
299  eFormatHex,
302  nullptr,
303  nullptr,
304  },
305  {"r20",
306  nullptr,
307  4,
308  0,
310  eFormatHex,
313  nullptr,
314  nullptr,
315  },
316  {"r21",
317  nullptr,
318  4,
319  0,
321  eFormatHex,
324  nullptr,
325  nullptr,
326  },
327  {"r22",
328  nullptr,
329  4,
330  0,
332  eFormatHex,
335  nullptr,
336  nullptr,
337  },
338  {"r23",
339  nullptr,
340  4,
341  0,
343  eFormatHex,
346  nullptr,
347  nullptr,
348  },
349  {"r24",
350  nullptr,
351  4,
352  0,
354  eFormatHex,
357  nullptr,
358  nullptr,
359  },
360  {"r25",
361  nullptr,
362  4,
363  0,
365  eFormatHex,
368  nullptr,
369  nullptr,
370  },
371  {"r26",
372  nullptr,
373  4,
374  0,
376  eFormatHex,
379  nullptr,
380  nullptr,
381  },
382  {"r27",
383  nullptr,
384  4,
385  0,
387  eFormatHex,
390  nullptr,
391  nullptr,
392  },
393  {"r28",
394  "gp",
395  4,
396  0,
398  eFormatHex,
401  nullptr,
402  nullptr,
403  },
404  {"r29",
405  nullptr,
406  4,
407  0,
409  eFormatHex,
412  nullptr,
413  nullptr,
414  },
415  {"r30",
416  nullptr,
417  4,
418  0,
420  eFormatHex,
423  nullptr,
424  nullptr,
425  },
426  {"r31",
427  nullptr,
428  4,
429  0,
431  eFormatHex,
434  nullptr,
435  nullptr,
436  },
437  {"sr",
438  nullptr,
439  4,
440  0,
442  eFormatHex,
445  nullptr,
446  nullptr,
447  },
448  {"lo",
449  nullptr,
450  4,
451  0,
453  eFormatHex,
456  nullptr,
457  nullptr,
458  },
459  {"hi",
460  nullptr,
461  4,
462  0,
464  eFormatHex,
467  nullptr,
468  nullptr,
469  },
470  {"bad",
471  nullptr,
472  4,
473  0,
475  eFormatHex,
478  nullptr,
479  nullptr,
480  },
481  {"cause",
482  nullptr,
483  4,
484  0,
486  eFormatHex,
489  nullptr,
490  nullptr,
491  },
492  {"pc",
493  nullptr,
494  4,
495  0,
497  eFormatHex,
500  nullptr,
501  nullptr,
502  },
503 };
504 
506  llvm::array_lengthof(g_register_infos);
507 
508 const lldb_private::RegisterInfo *
510  count = k_num_register_infos;
511  return g_register_infos;
512 }
513 
514 size_t ABISysV_mips::GetRedZoneSize() const { return 0; }
515 
516 // Static Functions
517 
518 ABISP
519 ABISysV_mips::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
520  const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
521  if ((arch_type == llvm::Triple::mips) ||
522  (arch_type == llvm::Triple::mipsel)) {
523  return ABISP(
524  new ABISysV_mips(std::move(process_sp), MakeMCRegisterInfo(arch)));
525  }
526  return ABISP();
527 }
528 
530  addr_t func_addr, addr_t return_addr,
531  llvm::ArrayRef<addr_t> args) const {
533 
534  if (log) {
535  StreamString s;
536  s.Printf("ABISysV_mips::PrepareTrivialCall (tid = 0x%" PRIx64
537  ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
538  ", return_addr = 0x%" PRIx64,
539  thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
540  (uint64_t)return_addr);
541 
542  for (size_t i = 0; i < args.size(); ++i)
543  s.Printf(", arg%zd = 0x%" PRIx64, i + 1, args[i]);
544  s.PutCString(")");
545  log->PutString(s.GetString());
546  }
547 
548  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
549  if (!reg_ctx)
550  return false;
551 
552  const RegisterInfo *reg_info = nullptr;
553 
554  RegisterValue reg_value;
555 
556  // Argument registers
557  const char *reg_names[] = {"r4", "r5", "r6", "r7"};
558 
559  llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
560 
561  // Write arguments to registers
562  for (size_t i = 0; i < llvm::array_lengthof(reg_names); ++i) {
563  if (ai == ae)
564  break;
565 
566  reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
568  LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") into %s", i + 1,
569  args[i], reg_info->name);
570 
571  if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
572  return false;
573 
574  ++ai;
575  }
576 
577  // If we have more than 4 arguments --Spill onto the stack
578  if (ai != ae) {
579  // No of arguments to go on stack
580  size_t num_stack_regs = args.size();
581 
582  // Allocate needed space for args on the stack
583  sp -= (num_stack_regs * 4);
584 
585  // Keep the stack 8 byte aligned
586  sp &= ~(8ull - 1ull);
587 
588  // just using arg1 to get the right size
589  const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
591 
592  addr_t arg_pos = sp + 16;
593 
594  size_t i = 4;
595  for (; ai != ae; ++ai) {
596  reg_value.SetUInt32(*ai);
597  LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") at 0x%" PRIx64 "",
598  i + 1, args[i], arg_pos);
599 
600  if (reg_ctx
601  ->WriteRegisterValueToMemory(reg_info, arg_pos,
602  reg_info->byte_size, reg_value)
603  .Fail())
604  return false;
605  arg_pos += reg_info->byte_size;
606  i++;
607  }
608  }
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  LLDB_LOGF(log, "Writing R0: 0x%" PRIx64, (uint64_t)0);
621 
622  /* Write r0 with 0, in case we are stopped in syscall,
623  * such setting prevents automatic decrement of the PC.
624  * This clears the bug 23659 for MIPS.
625  */
626  if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0))
627  return false;
628 
629  LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
630 
631  // Set "sp" to the requested value
632  if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
633  return false;
634 
635  LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
636 
637  // Set "ra" to the return address
638  if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
639  return false;
640 
641  LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
642 
643  // Set pc to the address of the called function.
644  if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
645  return false;
646 
647  LLDB_LOGF(log, "Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
648 
649  // All callers of position independent functions must place the address of
650  // the called function in t9 (r25)
651  if (!reg_ctx->WriteRegisterFromUnsigned(r25_info, func_addr))
652  return false;
653 
654  return true;
655 }
656 
657 bool ABISysV_mips::GetArgumentValues(Thread &thread, ValueList &values) const {
658  return false;
659 }
660 
661 Status ABISysV_mips::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
662  lldb::ValueObjectSP &new_value_sp) {
663  Status error;
664  if (!new_value_sp) {
665  error.SetErrorString("Empty value object for return value.");
666  return error;
667  }
668 
669  CompilerType compiler_type = new_value_sp->GetCompilerType();
670  if (!compiler_type) {
671  error.SetErrorString("Null clang type for return value.");
672  return error;
673  }
674 
675  Thread *thread = frame_sp->GetThread().get();
676 
677  bool is_signed;
678  uint32_t count;
679  bool is_complex;
680 
681  RegisterContext *reg_ctx = thread->GetRegisterContext().get();
682 
683  bool set_it_simple = false;
684  if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
685  compiler_type.IsPointerType()) {
686  DataExtractor data;
687  Status data_error;
688  size_t num_bytes = new_value_sp->GetData(data, data_error);
689  if (data_error.Fail()) {
690  error.SetErrorStringWithFormat(
691  "Couldn't convert return value to raw data: %s",
692  data_error.AsCString());
693  return error;
694  }
695 
696  lldb::offset_t offset = 0;
697  if (num_bytes <= 8) {
698  const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
699  if (num_bytes <= 4) {
700  uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
701 
702  if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value))
703  set_it_simple = true;
704  } else {
705  uint32_t raw_value = data.GetMaxU32(&offset, 4);
706 
707  if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) {
708  const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
709  uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
710 
711  if (reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value))
712  set_it_simple = true;
713  }
714  }
715  } else {
716  error.SetErrorString("We don't support returning longer than 64 bit "
717  "integer values at present.");
718  }
719  } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
720  if (is_complex)
721  error.SetErrorString(
722  "We don't support returning complex values at present");
723  else
724  error.SetErrorString(
725  "We don't support returning float values at present");
726  }
727 
728  if (!set_it_simple)
729  error.SetErrorString(
730  "We only support setting simple integer return types at present.");
731 
732  return error;
733 }
734 
736  Thread &thread, CompilerType &return_compiler_type) const {
737  ValueObjectSP return_valobj_sp;
738  return return_valobj_sp;
739 }
740 
742  Thread &thread, CompilerType &return_compiler_type) const {
743  ValueObjectSP return_valobj_sp;
744  Value value;
745 
746  if (!return_compiler_type)
747  return return_valobj_sp;
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  Target *target = exe_ctx.GetTargetPtr();
754  const ArchSpec target_arch = target->GetArchitecture();
755  ByteOrder target_byte_order = target_arch.GetByteOrder();
756  value.SetCompilerType(return_compiler_type);
757  uint32_t fp_flag =
759 
760  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
761  if (!reg_ctx)
762  return return_valobj_sp;
763 
764  bool is_signed = false;
765  bool is_complex = false;
766  uint32_t count = 0;
767 
768  // In MIPS register "r2" (v0) holds the integer function return values
769  const RegisterInfo *r2_reg_info = reg_ctx->GetRegisterInfoByName("r2", 0);
770  llvm::Optional<uint64_t> bit_width = return_compiler_type.GetBitSize(&thread);
771  if (!bit_width)
772  return return_valobj_sp;
773  if (return_compiler_type.IsIntegerOrEnumerationType(is_signed)) {
774  switch (*bit_width) {
775  default:
776  return return_valobj_sp;
777  case 64: {
778  const RegisterInfo *r3_reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);
779  uint64_t raw_value;
780  raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX;
781  raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0) &
782  UINT32_MAX))
783  << 32;
784  if (is_signed)
785  value.GetScalar() = (int64_t)raw_value;
786  else
787  value.GetScalar() = (uint64_t)raw_value;
788  } break;
789  case 32:
790  if (is_signed)
791  value.GetScalar() = (int32_t)(
792  reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX);
793  else
794  value.GetScalar() = (uint32_t)(
795  reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX);
796  break;
797  case 16:
798  if (is_signed)
799  value.GetScalar() = (int16_t)(
800  reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT16_MAX);
801  else
802  value.GetScalar() = (uint16_t)(
803  reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT16_MAX);
804  break;
805  case 8:
806  if (is_signed)
807  value.GetScalar() = (int8_t)(
808  reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT8_MAX);
809  else
810  value.GetScalar() = (uint8_t)(
811  reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT8_MAX);
812  break;
813  }
814  } else if (return_compiler_type.IsPointerType()) {
815  uint32_t ptr =
816  thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_reg_info, 0) &
817  UINT32_MAX;
818  value.GetScalar() = ptr;
819  } else if (return_compiler_type.IsAggregateType()) {
820  // Structure/Vector is always passed in memory and pointer to that memory
821  // is passed in r2.
822  uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned(
823  reg_ctx->GetRegisterInfoByName("r2", 0), 0);
824  // We have got the address. Create a memory object out of it
825  return_valobj_sp = ValueObjectMemory::Create(
826  &thread, "", Address(mem_address, nullptr), return_compiler_type);
827  return return_valobj_sp;
828  } else if (return_compiler_type.IsFloatingPointType(count, is_complex)) {
829  if (IsSoftFloat(fp_flag)) {
830  uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0);
831  if (count != 1 && is_complex)
832  return return_valobj_sp;
833  switch (*bit_width) {
834  default:
835  return return_valobj_sp;
836  case 32:
837  static_assert(sizeof(float) == sizeof(uint32_t), "");
838  value.GetScalar() = *((float *)(&raw_value));
839  break;
840  case 64:
841  static_assert(sizeof(double) == sizeof(uint64_t), "");
842  const RegisterInfo *r3_reg_info =
843  reg_ctx->GetRegisterInfoByName("r3", 0);
844  if (target_byte_order == eByteOrderLittle)
845  raw_value =
846  ((reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0)) << 32) |
847  raw_value;
848  else
849  raw_value = (raw_value << 32) |
850  reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0);
851  value.GetScalar() = *((double *)(&raw_value));
852  break;
853  }
854  }
855 
856  else {
857  const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
858  RegisterValue f0_value;
859  DataExtractor f0_data;
860  reg_ctx->ReadRegister(f0_info, f0_value);
861  f0_value.GetData(f0_data);
862  lldb::offset_t offset = 0;
863 
864  if (count == 1 && !is_complex) {
865  switch (*bit_width) {
866  default:
867  return return_valobj_sp;
868  case 64: {
869  static_assert(sizeof(double) == sizeof(uint64_t), "");
870  const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
871  RegisterValue f1_value;
872  DataExtractor f1_data;
873  reg_ctx->ReadRegister(f1_info, f1_value);
874  DataExtractor *copy_from_extractor = nullptr;
875  DataBufferSP data_sp(new DataBufferHeap(8, 0));
876  DataExtractor return_ext(
877  data_sp, target_byte_order,
878  target->GetArchitecture().GetAddressByteSize());
879 
880  if (target_byte_order == eByteOrderLittle) {
881  copy_from_extractor = &f0_data;
882  copy_from_extractor->CopyByteOrderedData(
883  offset, 4, data_sp->GetBytes(), 4, target_byte_order);
884  f1_value.GetData(f1_data);
885  copy_from_extractor = &f1_data;
886  copy_from_extractor->CopyByteOrderedData(
887  offset, 4, data_sp->GetBytes() + 4, 4, target_byte_order);
888  } else {
889  copy_from_extractor = &f0_data;
890  copy_from_extractor->CopyByteOrderedData(
891  offset, 4, data_sp->GetBytes() + 4, 4, target_byte_order);
892  f1_value.GetData(f1_data);
893  copy_from_extractor = &f1_data;
894  copy_from_extractor->CopyByteOrderedData(
895  offset, 4, data_sp->GetBytes(), 4, target_byte_order);
896  }
897  value.GetScalar() = (double)return_ext.GetDouble(&offset);
898  break;
899  }
900  case 32: {
901  static_assert(sizeof(float) == sizeof(uint32_t), "");
902  value.GetScalar() = (float)f0_data.GetFloat(&offset);
903  break;
904  }
905  }
906  } else {
907  // not handled yet
908  return return_valobj_sp;
909  }
910  }
911  } else {
912  // not handled yet
913  return return_valobj_sp;
914  }
915 
916  // If we get here, we have a valid Value, so make our ValueObject out of it:
917 
918  return_valobj_sp = ValueObjectConstResult::Create(
919  thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
920  return return_valobj_sp;
921 }
922 
924  unwind_plan.Clear();
925  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
926 
928 
929  // Our Call Frame Address is the stack pointer value
930  row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
931 
932  // The previous PC is in the RA
933  row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
934  unwind_plan.AppendRow(row);
935 
936  // All other registers are the same.
937 
938  unwind_plan.SetSourceName("mips at-func-entry default");
939  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
940  unwind_plan.SetReturnAddressRegister(dwarf_r31);
941  return true;
942 }
943 
945  unwind_plan.Clear();
946  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
947 
949 
950  row->SetUnspecifiedRegistersAreUndefined(true);
951  row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
952 
953  row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
954 
955  unwind_plan.AppendRow(row);
956  unwind_plan.SetSourceName("mips default unwind plan");
957  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
960  return true;
961 }
962 
963 bool ABISysV_mips::RegisterIsVolatile(const RegisterInfo *reg_info) {
964  return !RegisterIsCalleeSaved(reg_info);
965 }
966 
967 bool ABISysV_mips::IsSoftFloat(uint32_t fp_flags) const {
968  return (fp_flags == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT);
969 }
970 
971 bool ABISysV_mips::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
972  if (reg_info) {
973  // Preserved registers are :
974  // r16-r23, r28, r29, r30, r31
975  const char *name = reg_info->name;
976 
977  if (name[0] == 'r') {
978  switch (name[1]) {
979  case '1':
980  if (name[2] == '6' || name[2] == '7' || name[2] == '8' ||
981  name[2] == '9') // r16-r19
982  return name[3] == '\0';
983  break;
984  case '2':
985  if (name[2] == '0' || name[2] == '1' || name[2] == '2' ||
986  name[2] == '3' // r20-r23
987  || name[2] == '8' || name[2] == '9') // r28 and r29
988  return name[3] == '\0';
989  break;
990  case '3':
991  if (name[2] == '0' || name[2] == '1') // r30 and r31
992  return name[3] == '\0';
993  break;
994  }
995 
996  if (name[0] == 'g' && name[1] == 'p' && name[2] == '\0') // gp (r28)
997  return true;
998  if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp (r29)
999  return true;
1000  if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp (r30)
1001  return true;
1002  if (name[0] == 'r' && name[1] == 'a' && name[2] == '\0') // ra (r31)
1003  return true;
1004  }
1005  }
1006  return false;
1007 }
1008 
1010  PluginManager::RegisterPlugin(
1011  GetPluginNameStatic(), "System V ABI for mips targets", CreateInstance);
1012 }
1013 
1015  PluginManager::UnregisterPlugin(CreateInstance);
1016 }
dwarf_r9
@ dwarf_r9
Definition: ABISysV_mips.cpp:47
dwarf_bad
@ dwarf_bad
Definition: ABISysV_mips.cpp:73
dwarf_r20
@ dwarf_r20
Definition: ABISysV_mips.cpp:58
LLDB_REGNUM_GENERIC_ARG2
#define LLDB_REGNUM_GENERIC_ARG2
Definition: lldb-defines.h:70
ABISysV_mips::SetReturnValueObject
lldb_private::Status SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override
Definition: ABISysV_mips.cpp:661
LLDB_REGNUM_GENERIC_ARG3
#define LLDB_REGNUM_GENERIC_ARG3
Definition: lldb-defines.h:72
lldb_private::ExecutionContext
Definition: ExecutionContext.h:292
lldb_private::ArchSpec::GetByteOrder
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition: ArchSpec.cpp:730
dwarf_r28
@ dwarf_r28
Definition: ABISysV_mips.cpp:66
ABISysV_mips::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_mips.cpp:529
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
LLDB_INVALID_REGNUM
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:91
ABISysV_mips::GetRegisterInfoArray
const lldb_private::RegisterInfo * GetRegisterInfoArray(uint32_t &count) override
Definition: ABISysV_mips.cpp:509
lldb_private::RegisterValue
Definition: RegisterValue.h:28
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::ExecutionContext::GetProcessPtr
Process * GetProcessPtr() const
Returns a pointer to the process object.
Definition: ExecutionContext.cpp:208
dwarf_r23
@ dwarf_r23
Definition: ABISysV_mips.cpp:61
lldb::eRegisterKindGeneric
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
Definition: lldb-enumerations.h:230
g_register_infos
static const RegisterInfo g_register_infos[]
Definition: ABISysV_mips.cpp:78
lldb_private::UnwindPlan::SetUnwindPlanValidAtAllInstructions
void SetUnwindPlanValidAtAllInstructions(lldb_private::LazyBool valid_at_all_insn)
Definition: UnwindPlan.h:492
dwarf_r24
@ dwarf_r24
Definition: ABISysV_mips.cpp:62
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
dwarf_r12
@ dwarf_r12
Definition: ABISysV_mips.cpp:50
ABISysV_mips::RegisterIsCalleeSaved
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info)
Definition: ABISysV_mips.cpp:971
lldb_private::ArchSpec::GetFlags
uint32_t GetFlags() const
Definition: ArchSpec.h:514
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
dwarf_regnums
dwarf_regnums
Definition: ABISysV_mips.cpp:37
dwarf_r29
@ dwarf_r29
Definition: ABISysV_mips.cpp:67
StackFrame.h
ValueObjectMemory.h
dwarf_r22
@ dwarf_r22
Definition: ABISysV_mips.cpp:60
lldb_private::ArchSpec::GetTriple
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:444
lldb_private::CompilerType::IsAggregateType
bool IsAggregateType() const
Definition: CompilerType.cpp:31
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::CompilerType::IsFloatingPointType
bool IsFloatingPointType(uint32_t &count, bool &is_complex) const
Definition: CompilerType.cpp:191
dwarf_r5
@ dwarf_r5
Definition: ABISysV_mips.cpp:43
dwarf_r21
@ dwarf_r21
Definition: ABISysV_mips.cpp:59
lldb_private::Target
Definition: Target.h:451
lldb_private::UnwindPlan::SetSourceName
void SetSourceName(const char *)
Definition: UnwindPlan.cpp:562
lldb_private::StreamString::GetString
llvm::StringRef GetString() const
Definition: StreamString.cpp:51
Process.h
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
dwarf_pc
@ dwarf_pc
Definition: ABISysV_mips.cpp:75
Target.h
ABISysV_mips::GetArgumentValues
bool GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override
Definition: ABISysV_mips.cpp:657
lldb_private::Value::GetScalar
const Scalar & GetScalar() const
Definition: Value.h:112
lldb_private::ArchSpec::eMIPS_ABI_FP_mask
@ eMIPS_ABI_FP_mask
Definition: ArchSpec.h:86
LIBLLDB_LOG_EXPRESSIONS
#define LIBLLDB_LOG_EXPRESSIONS
Definition: Logging.h:22
LLDB_REGNUM_GENERIC_FLAGS
#define LLDB_REGNUM_GENERIC_FLAGS
Definition: lldb-defines.h:67
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
dwarf_r4
@ dwarf_r4
Definition: ABISysV_mips.cpp:42
dwarf_r15
@ dwarf_r15
Definition: ABISysV_mips.cpp:53
dwarf_r30
@ dwarf_r30
Definition: ABISysV_mips.cpp:68
lldb_private::DataExtractor
Definition: DataExtractor.h:48
Log.h
dwarf_r17
@ dwarf_r17
Definition: ABISysV_mips.cpp:55
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::GetMaxU32
uint32_t GetMaxU32(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an integer of size byte_size from *offset_ptr.
Definition: DataExtractor.cpp:520
lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT
@ eMIPS_ABI_FP_SOFT
Definition: ArchSpec.h:81
dwarf_r25
@ dwarf_r25
Definition: ABISysV_mips.cpp:63
dwarf_r2
@ dwarf_r2
Definition: ABISysV_mips.cpp:40
lldb_private::DataExtractor::GetDouble
double GetDouble(lldb::offset_t *offset_ptr) const
Definition: DataExtractor.cpp:628
k_num_register_infos
static const uint32_t k_num_register_infos
Definition: ABISysV_mips.cpp:505
lldb_private::RegisterValue::GetData
bool GetData(DataExtractor &data) const
Definition: RegisterValue.cpp:34
dwarf_cause
@ dwarf_cause
Definition: ABISysV_mips.cpp:74
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
dwarf_r7
@ dwarf_r7
Definition: ABISysV_mips.cpp:45
ValueObjectRegister.h
lldb::eEncodingUint
@ eEncodingUint
unsigned integer
Definition: lldb-enumerations.h:148
dwarf_r1
@ dwarf_r1
Definition: ABISysV_mips.cpp:39
lldb_private::ConstString
Definition: ConstString.h:40
lldb_private::StreamString
Definition: StreamString.h:23
lldb_private::GetLogIfAllCategoriesSet
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:58
dwarf_r18
@ dwarf_r18
Definition: ABISysV_mips.cpp:56
sp
@ sp
Definition: CompactUnwindInfo.cpp:1249
dwarf_r10
@ dwarf_r10
Definition: ABISysV_mips.cpp:48
lldb_private::DataExtractor::GetFloat
float GetFloat(lldb::offset_t *offset_ptr) const
Extract a float from *offset_ptr.
Definition: DataExtractor.cpp:624
ABISysV_mips::GetReturnValueObjectImpl
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override
Definition: ABISysV_mips.cpp:741
Thread.h
ABISysV_mips::CreateDefaultUnwindPlan
bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
Definition: ABISysV_mips.cpp:944
UnwindPlan.h
lldb_private::RegisterContext
Definition: RegisterContext.h:17
ABISysV_mips::GetReturnValueObjectSimple
lldb::ValueObjectSP GetReturnValueObjectSimple(lldb_private::Thread &thread, lldb_private::CompilerType &ast_type) const
Definition: ABISysV_mips.cpp:735
lldb_private::ArchSpec::GetAddressByteSize
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition: ArchSpec.cpp:683
lldb_private::UserID::GetID
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition: UserID.h:47
ABISysV_mips::CreateInstance
static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch)
Definition: ABISysV_mips.cpp:519
dwarf_r0
@ dwarf_r0
Definition: ABISysV_mips.cpp:38
ValueObjectConstResult.h
lldb_private::UnwindPlan::RowSP
std::shared_ptr< Row > RowSP
Definition: UnwindPlan.h:395
dwarf_r27
@ dwarf_r27
Definition: ABISysV_mips.cpp:65
lldb_private::RegisterValue::SetUInt32
void SetUInt32(uint32_t uint, Type t=eTypeUInt32)
Definition: RegisterValue.h:200
dwarf_r31
@ dwarf_r31
Definition: ABISysV_mips.cpp:69
lldb_private::Target::GetArchitecture
const ArchSpec & GetArchitecture() const
Definition: Target.h:967
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
dwarf_r26
@ dwarf_r26
Definition: ABISysV_mips.cpp:64
lldb_private::Address
Definition: Address.h:59
ABISysV_mips::IsSoftFloat
bool IsSoftFloat(uint32_t fp_flag) const
Definition: ABISysV_mips.cpp:967
LLDB_REGNUM_GENERIC_SP
#define LLDB_REGNUM_GENERIC_SP
Definition: lldb-defines.h:64
dwarf_r19
@ dwarf_r19
Definition: ABISysV_mips.cpp:57
lldb_private::CompilerType::IsPointerType
bool IsPointerType(CompilerType *pointee_type=nullptr) const
Definition: CompilerType.cpp:157
dwarf_r8
@ dwarf_r8
Definition: ABISysV_mips.cpp:46
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
ABISysV_mips::RegisterIsVolatile
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override
Definition: ABISysV_mips.cpp:963
ABISysV_mips::Initialize
static void Initialize()
Definition: ABISysV_mips.cpp:1009
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:31
dwarf_r11
@ dwarf_r11
Definition: ABISysV_mips.cpp:49
dwarf_lo
@ dwarf_lo
Definition: ABISysV_mips.cpp:71
uint16_t
PluginManager.h
dwarf_hi
@ dwarf_hi
Definition: ABISysV_mips.cpp:72
DataExtractor.h
dwarf_r13
@ dwarf_r13
Definition: ABISysV_mips.cpp:51
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
ABISysV_mips.h
Status.h
LLDB_REGNUM_GENERIC_ARG4
#define LLDB_REGNUM_GENERIC_ARG4
Definition: lldb-defines.h:74
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb::eFormatHex
@ eFormatHex
Definition: lldb-enumerations.h:169
LLDB_REGNUM_GENERIC_FP
#define LLDB_REGNUM_GENERIC_FP
Definition: lldb-defines.h:65
dwarf_sr
@ dwarf_sr
Definition: ABISysV_mips.cpp:70
ABISysV_mips::Terminate
static void Terminate()
Definition: ABISysV_mips.cpp:1014
dwarf_r3
@ dwarf_r3
Definition: ABISysV_mips.cpp:41
LLDB_REGNUM_GENERIC_PC
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:63
ConstString.h
lldb_private::DataExtractor::CopyByteOrderedData
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...
Definition: DataExtractor.cpp:692
LLDB_PLUGIN_DEFINE
#define LLDB_PLUGIN_DEFINE(PluginName)
Definition: PluginManager.h:31
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
dwarf_r14
@ dwarf_r14
Definition: ABISysV_mips.cpp:52
lldb_private::Thread::GetStackFrameAtIndex
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:397
dwarf_r6
@ dwarf_r6
Definition: ABISysV_mips.cpp:44
lldb_private::Thread::GetRegisterContext
virtual lldb::RegisterContextSP GetRegisterContext()=0
ABISysV_mips::GetRedZoneSize
size_t GetRedZoneSize() const override
Definition: ABISysV_mips.cpp:514
lldb::eByteOrderLittle
@ eByteOrderLittle
Definition: lldb-enumerations.h:142
lldb_private::DataBufferHeap
Definition: DataBufferHeap.h:30
lldb_private::UnwindPlan
Definition: UnwindPlan.h:53
lldb
Definition: SBAddress.h:15
RegisterContext.h
Value.h
ABISysV_mips::CreateFunctionEntryUnwindPlan
bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
Definition: ABISysV_mips.cpp:923
dwarf_r16
@ dwarf_r16
Definition: ABISysV_mips.cpp:54
lldb_private::ExecutionContext::GetTargetPtr
Target * GetTargetPtr() const
Returns a pointer to the target object.
Definition: ExecutionContext.cpp:200
lldb_private::RegisterContext::GetRegisterInfoByName
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
Definition: RegisterContext.cpp:52
ABISysV_mips
Definition: ABISysV_mips.h:15
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