1 //===-- ABISysV_mips64.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_mips64.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_mips64)
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_mips64[] = {
79     //  NAME      ALT    SZ OFF ENCODING        FORMAT         EH_FRAME
80     //  DWARF                   GENERIC                     PROCESS PLUGIN
81     //  LLDB NATIVE
82     //  ========  ======  == === =============  ==========     =============
83     //  =================       ====================        =================
84     //  ====================
85     {"r0",
86      "zero",
87      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
184      0,
185      eEncodingUint,
186      eFormatHex,
187      {dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM,
188       LLDB_INVALID_REGNUM},
189      nullptr,
190      nullptr,
191      nullptr,
192      0},
193     {"r9",
194      "arg6",
195      8,
196      0,
197      eEncodingUint,
198      eFormatHex,
199      {dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM,
200       LLDB_INVALID_REGNUM},
201      nullptr,
202      nullptr,
203      nullptr,
204      0},
205     {"r10",
206      "arg7",
207      8,
208      0,
209      eEncodingUint,
210      eFormatHex,
211      {dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM,
212       LLDB_INVALID_REGNUM},
213      nullptr,
214      nullptr,
215      nullptr,
216      0},
217     {"r11",
218      "arg8",
219      8,
220      0,
221      eEncodingUint,
222      eFormatHex,
223      {dwarf_r11, dwarf_r11, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM,
224       LLDB_INVALID_REGNUM},
225      nullptr,
226      nullptr,
227      nullptr,
228      0},
229     {"r12",
230      nullptr,
231      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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      8,
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_mips64);
545 
546 const lldb_private::RegisterInfo *
547 ABISysV_mips64::GetRegisterInfoArray(uint32_t &count) {
548   count = k_num_register_infos;
549   return g_register_infos_mips64;
550 }
551 
552 size_t ABISysV_mips64::GetRedZoneSize() const { return 0; }
553 
554 // Static Functions
555 
556 ABISP
557 ABISysV_mips64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
558   if (arch.GetTriple().isMIPS64())
559     return ABISP(
560         new ABISysV_mips64(std::move(process_sp), MakeMCRegisterInfo(arch)));
561   return ABISP();
562 }
563 
564 bool ABISysV_mips64::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_mips64::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   if (args.size() > 8) // TODO handle more than 8 arguments
590     return false;
591 
592   for (size_t i = 0; i < args.size(); ++i) {
593     reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
594                                         LLDB_REGNUM_GENERIC_ARG1 + i);
595     LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") into %s", i + 1,
596               args[i], reg_info->name);
597     if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
598       return false;
599   }
600 
601   // First, align the SP
602 
603   LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
604             (uint64_t)sp, (uint64_t)(sp & ~0xfull));
605 
606   sp &= ~(0xfull); // 16-byte alignment
607 
608   Status error;
609   const RegisterInfo *pc_reg_info =
610       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
611   const RegisterInfo *sp_reg_info =
612       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
613   const RegisterInfo *ra_reg_info =
614       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
615   const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0);
616   const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0);
617 
618   LLDB_LOGF(log, "Writing R0: 0x%" PRIx64, (uint64_t)0);
619 
620   /* Write r0 with 0, in case we are stopped in syscall,
621    * such setting prevents automatic decrement of the PC.
622    * This clears the bug 23659 for MIPS.
623   */
624   if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0))
625     return false;
626 
627   LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
628 
629   // Set "sp" to the requested value
630   if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
631     return false;
632 
633   LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
634 
635   // Set "ra" to the return address
636   if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
637     return false;
638 
639   LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
640 
641   // Set pc to the address of the called function.
642   if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
643     return false;
644 
645   LLDB_LOGF(log, "Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
646 
647   // All callers of position independent functions must place the address of
648   // the called function in t9 (r25)
649   if (!reg_ctx->WriteRegisterFromUnsigned(r25_info, func_addr))
650     return false;
651 
652   return true;
653 }
654 
655 bool ABISysV_mips64::GetArgumentValues(Thread &thread,
656                                        ValueList &values) const {
657   return false;
658 }
659 
660 Status ABISysV_mips64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
661                                             lldb::ValueObjectSP &new_value_sp) {
662   Status error;
663   if (!new_value_sp) {
664     error.SetErrorString("Empty value object for return value.");
665     return error;
666   }
667 
668   CompilerType compiler_type = new_value_sp->GetCompilerType();
669   if (!compiler_type) {
670     error.SetErrorString("Null clang type for return value.");
671     return error;
672   }
673 
674   Thread *thread = frame_sp->GetThread().get();
675 
676   RegisterContext *reg_ctx = thread->GetRegisterContext().get();
677 
678   if (!reg_ctx)
679     error.SetErrorString("no registers are available");
680 
681   DataExtractor data;
682   Status data_error;
683   size_t num_bytes = new_value_sp->GetData(data, data_error);
684   if (data_error.Fail()) {
685     error.SetErrorStringWithFormat(
686         "Couldn't convert return value to raw data: %s",
687         data_error.AsCString());
688     return error;
689   }
690 
691   const uint32_t type_flags = compiler_type.GetTypeInfo(nullptr);
692 
693   if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
694     if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
695       lldb::offset_t offset = 0;
696 
697       if (num_bytes <= 16) {
698         const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
699         if (num_bytes <= 8) {
700           uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
701 
702           if (!reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value))
703             error.SetErrorString("failed to write register r2");
704         } else {
705           uint64_t raw_value = data.GetMaxU64(&offset, 8);
706           if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) {
707             const RegisterInfo *r3_info =
708                 reg_ctx->GetRegisterInfoByName("r3", 0);
709             raw_value = data.GetMaxU64(&offset, num_bytes - offset);
710 
711             if (!reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value))
712               error.SetErrorString("failed to write register r3");
713           } else
714             error.SetErrorString("failed to write register r2");
715         }
716       } else {
717         error.SetErrorString("We don't support returning longer than 128 bit "
718                              "integer values at present.");
719       }
720     } else if (type_flags & eTypeIsFloat) {
721       error.SetErrorString("TODO: Handle Float Types.");
722     }
723   } else if (type_flags & eTypeIsVector) {
724     error.SetErrorString("returning vector values are not supported");
725   }
726 
727   return error;
728 }
729 
730 ValueObjectSP ABISysV_mips64::GetReturnValueObjectSimple(
731     Thread &thread, CompilerType &return_compiler_type) const {
732   ValueObjectSP return_valobj_sp;
733   return return_valobj_sp;
734 }
735 
736 ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
737     Thread &thread, CompilerType &return_compiler_type) const {
738   ValueObjectSP return_valobj_sp;
739   Value value;
740   Status error;
741 
742   ExecutionContext exe_ctx(thread.shared_from_this());
743   if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
744     return return_valobj_sp;
745 
746   value.SetCompilerType(return_compiler_type);
747 
748   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
749   if (!reg_ctx)
750     return return_valobj_sp;
751 
752   Target *target = exe_ctx.GetTargetPtr();
753   const ArchSpec target_arch = target->GetArchitecture();
754   ByteOrder target_byte_order = target_arch.GetByteOrder();
755   llvm::Optional<uint64_t> byte_size =
756       return_compiler_type.GetByteSize(nullptr);
757   if (!byte_size)
758     return return_valobj_sp;
759   const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
760   uint32_t fp_flag =
761       target_arch.GetFlags() & lldb_private::ArchSpec::eMIPS_ABI_FP_mask;
762 
763   const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
764   const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
765 
766   if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
767     value.SetValueType(Value::eValueTypeScalar);
768 
769     bool success = false;
770     if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
771       // Extract the register context so we can read arguments from registers
772       // In MIPS register "r2" (v0) holds the integer function return values
773 
774       uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0);
775 
776       const bool is_signed = (type_flags & eTypeIsSigned) != 0;
777       switch (*byte_size) {
778       default:
779         break;
780 
781       case sizeof(uint64_t):
782         if (is_signed)
783           value.GetScalar() = (int64_t)(raw_value);
784         else
785           value.GetScalar() = (uint64_t)(raw_value);
786         success = true;
787         break;
788 
789       case sizeof(uint32_t):
790         if (is_signed)
791           value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
792         else
793           value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
794         success = true;
795         break;
796 
797       case sizeof(uint16_t):
798         if (is_signed)
799           value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
800         else
801           value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
802         success = true;
803         break;
804 
805       case sizeof(uint8_t):
806         if (is_signed)
807           value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
808         else
809           value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
810         success = true;
811         break;
812       }
813     } else if (type_flags & eTypeIsFloat) {
814       if (type_flags & eTypeIsComplex) {
815         // Don't handle complex yet.
816       } else if (IsSoftFloat(fp_flag)) {
817         uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0);
818         switch (*byte_size) {
819         case 4:
820           value.GetScalar() = *((float *)(&raw_value));
821           success = true;
822           break;
823         case 8:
824           value.GetScalar() = *((double *)(&raw_value));
825           success = true;
826           break;
827         case 16:
828           uint64_t result[2];
829           if (target_byte_order == eByteOrderLittle) {
830             result[0] = raw_value;
831             result[1] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0);
832             value.GetScalar() = *((long double *)(result));
833           } else {
834             result[0] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0);
835             result[1] = raw_value;
836             value.GetScalar() = *((long double *)(result));
837           }
838           success = true;
839           break;
840         }
841 
842       } else {
843         if (*byte_size <= sizeof(long double)) {
844           const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
845 
846           RegisterValue f0_value;
847           DataExtractor f0_data;
848 
849           reg_ctx->ReadRegister(f0_info, f0_value);
850 
851           f0_value.GetData(f0_data);
852 
853           lldb::offset_t offset = 0;
854           if (*byte_size == sizeof(float)) {
855             value.GetScalar() = (float)f0_data.GetFloat(&offset);
856             success = true;
857           } else if (*byte_size == sizeof(double)) {
858             value.GetScalar() = (double)f0_data.GetDouble(&offset);
859             success = true;
860           } else if (*byte_size == sizeof(long double)) {
861             const RegisterInfo *f2_info =
862                 reg_ctx->GetRegisterInfoByName("f2", 0);
863             RegisterValue f2_value;
864             DataExtractor f2_data;
865             reg_ctx->ReadRegister(f2_info, f2_value);
866             DataExtractor *copy_from_extractor = nullptr;
867             DataBufferSP data_sp(new DataBufferHeap(16, 0));
868             DataExtractor return_ext(
869                 data_sp, target_byte_order,
870                 target->GetArchitecture().GetAddressByteSize());
871 
872             if (target_byte_order == eByteOrderLittle) {
873               copy_from_extractor = &f0_data;
874               copy_from_extractor->CopyByteOrderedData(
875                   0, 8, data_sp->GetBytes(), *byte_size - 8, target_byte_order);
876               f2_value.GetData(f2_data);
877               copy_from_extractor = &f2_data;
878               copy_from_extractor->CopyByteOrderedData(
879                   0, 8, data_sp->GetBytes() + 8, *byte_size - 8,
880                   target_byte_order);
881             } else {
882               copy_from_extractor = &f0_data;
883               copy_from_extractor->CopyByteOrderedData(
884                   0, 8, data_sp->GetBytes() + 8, *byte_size - 8,
885                   target_byte_order);
886               f2_value.GetData(f2_data);
887               copy_from_extractor = &f2_data;
888               copy_from_extractor->CopyByteOrderedData(
889                   0, 8, data_sp->GetBytes(), *byte_size - 8, target_byte_order);
890             }
891 
892             return_valobj_sp = ValueObjectConstResult::Create(
893                 &thread, return_compiler_type, ConstString(""), return_ext);
894             return return_valobj_sp;
895           }
896         }
897       }
898     }
899 
900     if (success)
901       return_valobj_sp = ValueObjectConstResult::Create(
902           thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
903   } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass ||
904              type_flags & eTypeIsVector) {
905     // Any structure of up to 16 bytes in size is returned in the registers.
906     if (*byte_size <= 16) {
907       DataBufferSP data_sp(new DataBufferHeap(16, 0));
908       DataExtractor return_ext(data_sp, target_byte_order,
909                                target->GetArchitecture().GetAddressByteSize());
910 
911       RegisterValue r2_value, r3_value, f0_value, f1_value, f2_value;
912       // Tracks how much bytes of r2 and r3 registers we've consumed so far
913       uint32_t integer_bytes = 0;
914 
915       // True if return values are in FP return registers.
916       bool use_fp_regs = false;
917       // True if we found any non floating point field in structure.
918       bool found_non_fp_field = false;
919       // True if return values are in r2 register.
920       bool use_r2 = false;
921       // True if return values are in r3 register.
922       bool use_r3 = false;
923       // True if the result is copied into our data buffer
924       bool sucess = false;
925       std::string name;
926       bool is_complex;
927       uint32_t count;
928       const uint32_t num_children = return_compiler_type.GetNumFields();
929 
930       // A structure consisting of one or two FP values (and nothing else) will
931       // be returned in the two FP return-value registers i.e fp0 and fp2.
932       if (num_children <= 2) {
933         uint64_t field_bit_offset = 0;
934 
935         // Check if this structure contains only floating point fields
936         for (uint32_t idx = 0; idx < num_children; idx++) {
937           CompilerType field_compiler_type =
938               return_compiler_type.GetFieldAtIndex(idx, name, &field_bit_offset,
939                                                    nullptr, nullptr);
940 
941           if (field_compiler_type.IsFloatingPointType(count, is_complex))
942             use_fp_regs = true;
943           else
944             found_non_fp_field = true;
945         }
946 
947         if (use_fp_regs && !found_non_fp_field) {
948           // We have one or two FP-only values in this structure. Get it from
949           // f0/f2 registers.
950           DataExtractor f0_data, f1_data, f2_data;
951           const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
952           const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
953           const RegisterInfo *f2_info = reg_ctx->GetRegisterInfoByName("f2", 0);
954 
955           reg_ctx->ReadRegister(f0_info, f0_value);
956           reg_ctx->ReadRegister(f2_info, f2_value);
957 
958           f0_value.GetData(f0_data);
959 
960           for (uint32_t idx = 0; idx < num_children; idx++) {
961             CompilerType field_compiler_type =
962                 return_compiler_type.GetFieldAtIndex(
963                     idx, name, &field_bit_offset, nullptr, nullptr);
964             llvm::Optional<uint64_t> field_byte_width =
965                 field_compiler_type.GetByteSize(nullptr);
966             if (!field_byte_width)
967               return return_valobj_sp;
968 
969             DataExtractor *copy_from_extractor = nullptr;
970             uint64_t return_value[2];
971             offset_t offset = 0;
972 
973             if (idx == 0) {
974               // This case is for long double type.
975               if (*field_byte_width == 16) {
976 
977                 // If structure contains long double type, then it is returned
978                 // in fp0/fp1 registers.
979                 if (target_byte_order == eByteOrderLittle) {
980                   return_value[0] = f0_data.GetU64(&offset);
981                   reg_ctx->ReadRegister(f1_info, f1_value);
982                   f1_value.GetData(f1_data);
983                   offset = 0;
984                   return_value[1] = f1_data.GetU64(&offset);
985                 } else {
986                   return_value[1] = f0_data.GetU64(&offset);
987                   reg_ctx->ReadRegister(f1_info, f1_value);
988                   f1_value.GetData(f1_data);
989                   offset = 0;
990                   return_value[0] = f1_data.GetU64(&offset);
991                 }
992 
993                 f0_data.SetData(return_value, *field_byte_width,
994                                 target_byte_order);
995               }
996               copy_from_extractor = &f0_data; // This is in f0, copy from
997                                               // register to our result
998                                               // structure
999             } else {
1000               f2_value.GetData(f2_data);
1001               // This is in f2, copy from register to our result structure
1002               copy_from_extractor = &f2_data;
1003             }
1004 
1005             // Sanity check to avoid crash
1006             if (!copy_from_extractor ||
1007                 *field_byte_width > copy_from_extractor->GetByteSize())
1008               return return_valobj_sp;
1009 
1010             // copy the register contents into our data buffer
1011             copy_from_extractor->CopyByteOrderedData(
1012                 0, *field_byte_width,
1013                 data_sp->GetBytes() + (field_bit_offset / 8), *field_byte_width,
1014                 target_byte_order);
1015           }
1016 
1017           // The result is in our data buffer.  Create a variable object out of
1018           // it
1019           return_valobj_sp = ValueObjectConstResult::Create(
1020               &thread, return_compiler_type, ConstString(""), return_ext);
1021 
1022           return return_valobj_sp;
1023         }
1024       }
1025 
1026       // If we reach here, it means this structure either contains more than
1027       // two fields or it contains at least one non floating point type. In
1028       // that case, all fields are returned in GP return registers.
1029       for (uint32_t idx = 0; idx < num_children; idx++) {
1030         uint64_t field_bit_offset = 0;
1031         bool is_signed;
1032         uint32_t padding;
1033 
1034         CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
1035             idx, name, &field_bit_offset, nullptr, nullptr);
1036         llvm::Optional<uint64_t> field_byte_width =
1037             field_compiler_type.GetByteSize(nullptr);
1038 
1039         // if we don't know the size of the field (e.g. invalid type), just
1040         // bail out
1041         if (!field_byte_width || *field_byte_width == 0)
1042           break;
1043 
1044         uint32_t field_byte_offset = field_bit_offset / 8;
1045 
1046         if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1047             field_compiler_type.IsPointerType() ||
1048             field_compiler_type.IsFloatingPointType(count, is_complex)) {
1049           padding = field_byte_offset - integer_bytes;
1050 
1051           if (integer_bytes < 8) {
1052             // We have not yet consumed r2 completely.
1053             if (integer_bytes + *field_byte_width + padding <= 8) {
1054               // This field fits in r2, copy its value from r2 to our result
1055               // structure
1056               integer_bytes = integer_bytes + *field_byte_width +
1057                               padding; // Increase the consumed bytes.
1058               use_r2 = true;
1059             } else {
1060               // There isn't enough space left in r2 for this field, so this
1061               // will be in r3.
1062               integer_bytes = integer_bytes + *field_byte_width +
1063                               padding; // Increase the consumed bytes.
1064               use_r3 = true;
1065             }
1066           }
1067           // We already have consumed at-least 8 bytes that means r2 is done,
1068           // and this field will be in r3. Check if this field can fit in r3.
1069           else if (integer_bytes + *field_byte_width + padding <= 16) {
1070             integer_bytes = integer_bytes + *field_byte_width + padding;
1071             use_r3 = true;
1072           } else {
1073             // There isn't any space left for this field, this should not
1074             // happen as we have already checked the overall size is not
1075             // greater than 16 bytes. For now, return a nullptr return value
1076             // object.
1077             return return_valobj_sp;
1078           }
1079         }
1080       }
1081       // Vector types up to 16 bytes are returned in GP return registers
1082       if (type_flags & eTypeIsVector) {
1083         if (*byte_size <= 8)
1084           use_r2 = true;
1085         else {
1086           use_r2 = true;
1087           use_r3 = true;
1088         }
1089       }
1090 
1091       if (use_r2) {
1092         reg_ctx->ReadRegister(r2_info, r2_value);
1093 
1094         const size_t bytes_copied = r2_value.GetAsMemoryData(
1095             r2_info, data_sp->GetBytes(), r2_info->byte_size, target_byte_order,
1096             error);
1097         if (bytes_copied != r2_info->byte_size)
1098           return return_valobj_sp;
1099         sucess = true;
1100       }
1101       if (use_r3) {
1102         reg_ctx->ReadRegister(r3_info, r3_value);
1103         const size_t bytes_copied = r3_value.GetAsMemoryData(
1104             r3_info, data_sp->GetBytes() + r2_info->byte_size,
1105             r3_info->byte_size, target_byte_order, error);
1106 
1107         if (bytes_copied != r3_info->byte_size)
1108           return return_valobj_sp;
1109         sucess = true;
1110       }
1111       if (sucess) {
1112         // The result is in our data buffer.  Create a variable object out of
1113         // it
1114         return_valobj_sp = ValueObjectConstResult::Create(
1115             &thread, return_compiler_type, ConstString(""), return_ext);
1116       }
1117       return return_valobj_sp;
1118     }
1119 
1120     // Any structure/vector greater than 16 bytes in size is returned in
1121     // memory. The pointer to that memory is returned in r2.
1122     uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned(
1123         reg_ctx->GetRegisterInfoByName("r2", 0), 0);
1124 
1125     // We have got the address. Create a memory object out of it
1126     return_valobj_sp = ValueObjectMemory::Create(
1127         &thread, "", Address(mem_address, nullptr), return_compiler_type);
1128   }
1129   return return_valobj_sp;
1130 }
1131 
1132 bool ABISysV_mips64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1133   unwind_plan.Clear();
1134   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1135 
1136   UnwindPlan::RowSP row(new UnwindPlan::Row);
1137 
1138   // Our Call Frame Address is the stack pointer value
1139   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
1140 
1141   // The previous PC is in the RA
1142   row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
1143   unwind_plan.AppendRow(row);
1144 
1145   // All other registers are the same.
1146 
1147   unwind_plan.SetSourceName("mips64 at-func-entry default");
1148   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1149   unwind_plan.SetReturnAddressRegister(dwarf_r31);
1150   return true;
1151 }
1152 
1153 bool ABISysV_mips64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1154   unwind_plan.Clear();
1155   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1156 
1157   UnwindPlan::RowSP row(new UnwindPlan::Row);
1158 
1159   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
1160 
1161   row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
1162 
1163   unwind_plan.AppendRow(row);
1164   unwind_plan.SetSourceName("mips64 default unwind plan");
1165   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1166   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1167   unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1168   return true;
1169 }
1170 
1171 bool ABISysV_mips64::RegisterIsVolatile(const RegisterInfo *reg_info) {
1172   return !RegisterIsCalleeSaved(reg_info);
1173 }
1174 
1175 bool ABISysV_mips64::IsSoftFloat(uint32_t fp_flag) const {
1176   return (fp_flag == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT);
1177 }
1178 
1179 bool ABISysV_mips64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1180   if (reg_info) {
1181     // Preserved registers are :
1182     // r16-r23, r28, r29, r30, r31
1183 
1184     int reg = ((reg_info->byte_offset) / 8);
1185 
1186     bool save = (reg >= 16) && (reg <= 23);
1187     save |= (reg >= 28) && (reg <= 31);
1188 
1189     return save;
1190   }
1191   return false;
1192 }
1193 
1194 void ABISysV_mips64::Initialize() {
1195   PluginManager::RegisterPlugin(
1196       GetPluginNameStatic(), "System V ABI for mips64 targets", CreateInstance);
1197 }
1198 
1199 void ABISysV_mips64::Terminate() {
1200   PluginManager::UnregisterPlugin(CreateInstance);
1201 }
1202 
1203 lldb_private::ConstString ABISysV_mips64::GetPluginNameStatic() {
1204   static ConstString g_name("sysv-mips64");
1205   return g_name;
1206 }
1207 
1208 // PluginInterface protocol
1209 
1210 lldb_private::ConstString ABISysV_mips64::GetPluginName() {
1211   return GetPluginNameStatic();
1212 }
1213 
1214 uint32_t ABISysV_mips64::GetPluginVersion() { return 1; }
1215