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