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