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