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