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