]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-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(new ABISysV_mips(process_sp));
560   }
561   return ABISP();
562 }
563
564 bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp,
565                                       addr_t func_addr, addr_t return_addr,
566                                       llvm::ArrayRef<addr_t> args) const {
567   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
568
569   if (log) {
570     StreamString s;
571     s.Printf("ABISysV_mips::PrepareTrivialCall (tid = 0x%" PRIx64
572              ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
573              ", return_addr = 0x%" PRIx64,
574              thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
575              (uint64_t)return_addr);
576
577     for (size_t i = 0; i < args.size(); ++i)
578       s.Printf(", arg%zd = 0x%" PRIx64, i + 1, args[i]);
579     s.PutCString(")");
580     log->PutString(s.GetString());
581   }
582
583   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
584   if (!reg_ctx)
585     return false;
586
587   const RegisterInfo *reg_info = nullptr;
588
589   RegisterValue reg_value;
590
591   // Argument registers
592   const char *reg_names[] = {"r4", "r5", "r6", "r7"};
593
594   llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
595
596   // Write arguments to registers
597   for (size_t i = 0; i < llvm::array_lengthof(reg_names); ++i) {
598     if (ai == ae)
599       break;
600
601     reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
602                                         LLDB_REGNUM_GENERIC_ARG1 + i);
603     if (log)
604       log->Printf("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       if (log)
634         log->Printf("About to write arg%zd (0x%" PRIx64 ") at  0x%" PRIx64 "",
635                     i + 1, args[i], arg_pos);
636
637       if (reg_ctx
638               ->WriteRegisterValueToMemory(reg_info, arg_pos,
639                                            reg_info->byte_size, reg_value)
640               .Fail())
641         return false;
642       arg_pos += reg_info->byte_size;
643       i++;
644     }
645   }
646
647   Status error;
648   const RegisterInfo *pc_reg_info =
649       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
650   const RegisterInfo *sp_reg_info =
651       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
652   const RegisterInfo *ra_reg_info =
653       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
654   const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0);
655   const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0);
656
657   if (log)
658     log->Printf("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   if (log)
668     log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
669
670   // Set "sp" to the requested value
671   if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
672     return false;
673
674   if (log)
675     log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
676
677   // Set "ra" to the return address
678   if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
679     return false;
680
681   if (log)
682     log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
683
684   // Set pc to the address of the called function.
685   if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
686     return false;
687
688   if (log)
689     log->Printf("Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
690
691   // All callers of position independent functions must place the address of
692   // the called function in t9 (r25)
693   if (!reg_ctx->WriteRegisterFromUnsigned(r25_info, func_addr))
694     return false;
695
696   return true;
697 }
698
699 bool ABISysV_mips::GetArgumentValues(Thread &thread, ValueList &values) const {
700   return false;
701 }
702
703 Status ABISysV_mips::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
704                                           lldb::ValueObjectSP &new_value_sp) {
705   Status error;
706   if (!new_value_sp) {
707     error.SetErrorString("Empty value object for return value.");
708     return error;
709   }
710
711   CompilerType compiler_type = new_value_sp->GetCompilerType();
712   if (!compiler_type) {
713     error.SetErrorString("Null clang type for return value.");
714     return error;
715   }
716
717   Thread *thread = frame_sp->GetThread().get();
718
719   bool is_signed;
720   uint32_t count;
721   bool is_complex;
722
723   RegisterContext *reg_ctx = thread->GetRegisterContext().get();
724
725   bool set_it_simple = false;
726   if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
727       compiler_type.IsPointerType()) {
728     DataExtractor data;
729     Status data_error;
730     size_t num_bytes = new_value_sp->GetData(data, data_error);
731     if (data_error.Fail()) {
732       error.SetErrorStringWithFormat(
733           "Couldn't convert return value to raw data: %s",
734           data_error.AsCString());
735       return error;
736     }
737
738     lldb::offset_t offset = 0;
739     if (num_bytes <= 8) {
740       const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
741       if (num_bytes <= 4) {
742         uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
743
744         if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value))
745           set_it_simple = true;
746       } else {
747         uint32_t raw_value = data.GetMaxU32(&offset, 4);
748
749         if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) {
750           const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
751           uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
752
753           if (reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value))
754             set_it_simple = true;
755         }
756       }
757     } else {
758       error.SetErrorString("We don't support returning longer than 64 bit "
759                            "integer values at present.");
760     }
761   } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
762     if (is_complex)
763       error.SetErrorString(
764           "We don't support returning complex values at present");
765     else
766       error.SetErrorString(
767           "We don't support returning float values at present");
768   }
769
770   if (!set_it_simple)
771     error.SetErrorString(
772         "We only support setting simple integer return types at present.");
773
774   return error;
775 }
776
777 ValueObjectSP ABISysV_mips::GetReturnValueObjectSimple(
778     Thread &thread, CompilerType &return_compiler_type) const {
779   ValueObjectSP return_valobj_sp;
780   return return_valobj_sp;
781 }
782
783 ValueObjectSP ABISysV_mips::GetReturnValueObjectImpl(
784     Thread &thread, CompilerType &return_compiler_type) const {
785   ValueObjectSP return_valobj_sp;
786   Value value;
787
788   if (!return_compiler_type)
789     return return_valobj_sp;
790
791   ExecutionContext exe_ctx(thread.shared_from_this());
792   if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
793     return return_valobj_sp;
794
795   Target *target = exe_ctx.GetTargetPtr();
796   const ArchSpec target_arch = target->GetArchitecture();
797   ByteOrder target_byte_order = target_arch.GetByteOrder();
798   value.SetCompilerType(return_compiler_type);
799   uint32_t fp_flag =
800       target_arch.GetFlags() & lldb_private::ArchSpec::eMIPS_ABI_FP_mask;
801
802   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
803   if (!reg_ctx)
804     return return_valobj_sp;
805
806   bool is_signed = false;
807   bool is_complex = false;
808   uint32_t count = 0;
809
810   // In MIPS register "r2" (v0) holds the integer function return values
811   const RegisterInfo *r2_reg_info = reg_ctx->GetRegisterInfoByName("r2", 0);
812   llvm::Optional<uint64_t> bit_width = return_compiler_type.GetBitSize(&thread);
813   if (!bit_width)
814     return return_valobj_sp;
815   if (return_compiler_type.IsIntegerOrEnumerationType(is_signed)) {
816     switch (*bit_width) {
817     default:
818       return return_valobj_sp;
819     case 64: {
820       const RegisterInfo *r3_reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);
821       uint64_t raw_value;
822       raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX;
823       raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0) &
824                                UINT32_MAX))
825                    << 32;
826       if (is_signed)
827         value.GetScalar() = (int64_t)raw_value;
828       else
829         value.GetScalar() = (uint64_t)raw_value;
830     } break;
831     case 32:
832       if (is_signed)
833         value.GetScalar() = (int32_t)(
834             reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX);
835       else
836         value.GetScalar() = (uint32_t)(
837             reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX);
838       break;
839     case 16:
840       if (is_signed)
841         value.GetScalar() = (int16_t)(
842             reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT16_MAX);
843       else
844         value.GetScalar() = (uint16_t)(
845             reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT16_MAX);
846       break;
847     case 8:
848       if (is_signed)
849         value.GetScalar() = (int8_t)(
850             reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT8_MAX);
851       else
852         value.GetScalar() = (uint8_t)(
853             reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT8_MAX);
854       break;
855     }
856   } else if (return_compiler_type.IsPointerType()) {
857     uint32_t ptr =
858         thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_reg_info, 0) &
859         UINT32_MAX;
860     value.GetScalar() = ptr;
861   } else if (return_compiler_type.IsAggregateType()) {
862     // Structure/Vector is always passed in memory and pointer to that memory
863     // is passed in r2.
864     uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned(
865         reg_ctx->GetRegisterInfoByName("r2", 0), 0);
866     // We have got the address. Create a memory object out of it
867     return_valobj_sp = ValueObjectMemory::Create(
868         &thread, "", Address(mem_address, nullptr), return_compiler_type);
869     return return_valobj_sp;
870   } else if (return_compiler_type.IsFloatingPointType(count, is_complex)) {
871     if (IsSoftFloat(fp_flag)) {
872       uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0);
873       if (count != 1 && is_complex)
874         return return_valobj_sp;
875       switch (*bit_width) {
876       default:
877         return return_valobj_sp;
878       case 32:
879         static_assert(sizeof(float) == sizeof(uint32_t), "");
880         value.GetScalar() = *((float *)(&raw_value));
881         break;
882       case 64:
883         static_assert(sizeof(double) == sizeof(uint64_t), "");
884         const RegisterInfo *r3_reg_info =
885             reg_ctx->GetRegisterInfoByName("r3", 0);
886         if (target_byte_order == eByteOrderLittle)
887           raw_value =
888               ((reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0)) << 32) |
889               raw_value;
890         else
891           raw_value = (raw_value << 32) |
892                       reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0);
893         value.GetScalar() = *((double *)(&raw_value));
894         break;
895       }
896     }
897
898     else {
899       const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
900       RegisterValue f0_value;
901       DataExtractor f0_data;
902       reg_ctx->ReadRegister(f0_info, f0_value);
903       f0_value.GetData(f0_data);
904       lldb::offset_t offset = 0;
905
906       if (count == 1 && !is_complex) {
907         switch (*bit_width) {
908         default:
909           return return_valobj_sp;
910         case 64: {
911           static_assert(sizeof(double) == sizeof(uint64_t), "");
912           const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
913           RegisterValue f1_value;
914           DataExtractor f1_data;
915           reg_ctx->ReadRegister(f1_info, f1_value);
916           DataExtractor *copy_from_extractor = nullptr;
917           DataBufferSP data_sp(new DataBufferHeap(8, 0));
918           DataExtractor return_ext(
919               data_sp, target_byte_order,
920               target->GetArchitecture().GetAddressByteSize());
921
922           if (target_byte_order == eByteOrderLittle) {
923             copy_from_extractor = &f0_data;
924             copy_from_extractor->CopyByteOrderedData(
925                 offset, 4, data_sp->GetBytes(), 4, target_byte_order);
926             f1_value.GetData(f1_data);
927             copy_from_extractor = &f1_data;
928             copy_from_extractor->CopyByteOrderedData(
929                 offset, 4, data_sp->GetBytes() + 4, 4, target_byte_order);
930           } else {
931             copy_from_extractor = &f0_data;
932             copy_from_extractor->CopyByteOrderedData(
933                 offset, 4, data_sp->GetBytes() + 4, 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, target_byte_order);
938           }
939           value.GetScalar() = (double)return_ext.GetDouble(&offset);
940           break;
941         }
942         case 32: {
943           static_assert(sizeof(float) == sizeof(uint32_t), "");
944           value.GetScalar() = (float)f0_data.GetFloat(&offset);
945           break;
946         }
947         }
948       } else {
949         // not handled yet
950         return return_valobj_sp;
951       }
952     }
953   } else {
954     // not handled yet
955     return return_valobj_sp;
956   }
957
958   // If we get here, we have a valid Value, so make our ValueObject out of it:
959
960   return_valobj_sp = ValueObjectConstResult::Create(
961       thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
962   return return_valobj_sp;
963 }
964
965 bool ABISysV_mips::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
966   unwind_plan.Clear();
967   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
968
969   UnwindPlan::RowSP row(new UnwindPlan::Row);
970
971   // Our Call Frame Address is the stack pointer value
972   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
973
974   // The previous PC is in the RA
975   row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
976   unwind_plan.AppendRow(row);
977
978   // All other registers are the same.
979
980   unwind_plan.SetSourceName("mips at-func-entry default");
981   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
982   unwind_plan.SetReturnAddressRegister(dwarf_r31);
983   return true;
984 }
985
986 bool ABISysV_mips::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
987   unwind_plan.Clear();
988   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
989
990   UnwindPlan::RowSP row(new UnwindPlan::Row);
991
992   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
993
994   row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
995
996   unwind_plan.AppendRow(row);
997   unwind_plan.SetSourceName("mips default unwind plan");
998   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
999   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1000   return true;
1001 }
1002
1003 bool ABISysV_mips::RegisterIsVolatile(const RegisterInfo *reg_info) {
1004   return !RegisterIsCalleeSaved(reg_info);
1005 }
1006
1007 bool ABISysV_mips::IsSoftFloat(uint32_t fp_flags) const {
1008   return (fp_flags == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT);
1009 }
1010
1011 bool ABISysV_mips::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1012   if (reg_info) {
1013     // Preserved registers are :
1014     // r16-r23, r28, r29, r30, r31
1015     const char *name = reg_info->name;
1016
1017     if (name[0] == 'r') {
1018       switch (name[1]) {
1019       case '1':
1020         if (name[2] == '6' || name[2] == '7' || name[2] == '8' ||
1021             name[2] == '9') // r16-r19
1022           return name[3] == '\0';
1023         break;
1024       case '2':
1025         if (name[2] == '0' || name[2] == '1' || name[2] == '2' ||
1026             name[2] == '3'                       // r20-r23
1027             || name[2] == '8' || name[2] == '9') // r28 and r29
1028           return name[3] == '\0';
1029         break;
1030       case '3':
1031         if (name[2] == '0' || name[2] == '1') // r30 and r31
1032           return name[3] == '\0';
1033         break;
1034       }
1035
1036       if (name[0] == 'g' && name[1] == 'p' && name[2] == '\0') // gp (r28)
1037         return true;
1038       if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp (r29)
1039         return true;
1040       if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp (r30)
1041         return true;
1042       if (name[0] == 'r' && name[1] == 'a' && name[2] == '\0') // ra (r31)
1043         return true;
1044     }
1045   }
1046   return false;
1047 }
1048
1049 void ABISysV_mips::Initialize() {
1050   PluginManager::RegisterPlugin(
1051       GetPluginNameStatic(), "System V ABI for mips targets", CreateInstance);
1052 }
1053
1054 void ABISysV_mips::Terminate() {
1055   PluginManager::UnregisterPlugin(CreateInstance);
1056 }
1057
1058 lldb_private::ConstString ABISysV_mips::GetPluginNameStatic() {
1059   static ConstString g_name("sysv-mips");
1060   return g_name;
1061 }
1062
1063 // PluginInterface protocol
1064
1065 lldb_private::ConstString ABISysV_mips::GetPluginName() {
1066   return GetPluginNameStatic();
1067 }
1068
1069 uint32_t ABISysV_mips::GetPluginVersion() { return 1; }