xref: /llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp (revision 593be023615a456ca6ee0ef9bedc21301d73b73c)
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/TargetParser/Triple.h"
13 
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/PluginManager.h"
16 #include "lldb/Core/Value.h"
17 #include "lldb/Symbol/UnwindPlan.h"
18 #include "lldb/Target/Process.h"
19 #include "lldb/Target/RegisterContext.h"
20 #include "lldb/Target/StackFrame.h"
21 #include "lldb/Target/Target.h"
22 #include "lldb/Target/Thread.h"
23 #include "lldb/Utility/ConstString.h"
24 #include "lldb/Utility/DataExtractor.h"
25 #include "lldb/Utility/LLDBLog.h"
26 #include "lldb/Utility/Log.h"
27 #include "lldb/Utility/RegisterValue.h"
28 #include "lldb/Utility/Status.h"
29 #include "lldb/ValueObject/ValueObjectConstResult.h"
30 #include "lldb/ValueObject/ValueObjectMemory.h"
31 #include "lldb/ValueObject/ValueObjectRegister.h"
32 #include <optional>
33 
34 using namespace lldb;
35 using namespace lldb_private;
36 
37 LLDB_PLUGIN_DEFINE(ABISysV_mips64)
38 
39 enum dwarf_regnums {
40   dwarf_r0 = 0,
41   dwarf_r1,
42   dwarf_r2,
43   dwarf_r3,
44   dwarf_r4,
45   dwarf_r5,
46   dwarf_r6,
47   dwarf_r7,
48   dwarf_r8,
49   dwarf_r9,
50   dwarf_r10,
51   dwarf_r11,
52   dwarf_r12,
53   dwarf_r13,
54   dwarf_r14,
55   dwarf_r15,
56   dwarf_r16,
57   dwarf_r17,
58   dwarf_r18,
59   dwarf_r19,
60   dwarf_r20,
61   dwarf_r21,
62   dwarf_r22,
63   dwarf_r23,
64   dwarf_r24,
65   dwarf_r25,
66   dwarf_r26,
67   dwarf_r27,
68   dwarf_r28,
69   dwarf_r29,
70   dwarf_r30,
71   dwarf_r31,
72   dwarf_sr,
73   dwarf_lo,
74   dwarf_hi,
75   dwarf_bad,
76   dwarf_cause,
77   dwarf_pc
78 };
79 
80 static const RegisterInfo g_register_infos_mips64[] = {
81     {"r0",
82      "zero",
83      8,
84      0,
85      eEncodingUint,
86      eFormatHex,
87      {dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
88       LLDB_INVALID_REGNUM},
89      nullptr,
90      nullptr,
91      nullptr,
92     },
93     {"r1",
94      "AT",
95      8,
96      0,
97      eEncodingUint,
98      eFormatHex,
99      {dwarf_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
100       LLDB_INVALID_REGNUM},
101      nullptr,
102      nullptr,
103      nullptr,
104 
105     },
106     {"r2",
107      "v0",
108      8,
109      0,
110      eEncodingUint,
111      eFormatHex,
112      {dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
113       LLDB_INVALID_REGNUM},
114      nullptr,
115      nullptr,
116      nullptr,
117     },
118     {"r3",
119      "v1",
120      8,
121      0,
122      eEncodingUint,
123      eFormatHex,
124      {dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
125       LLDB_INVALID_REGNUM},
126      nullptr,
127      nullptr,
128      nullptr,
129     },
130     {"r4",
131      nullptr,
132      8,
133      0,
134      eEncodingUint,
135      eFormatHex,
136      {dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
137       LLDB_INVALID_REGNUM},
138      nullptr,
139      nullptr,
140      nullptr,
141     },
142     {"r5",
143      nullptr,
144      8,
145      0,
146      eEncodingUint,
147      eFormatHex,
148      {dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
149       LLDB_INVALID_REGNUM},
150      nullptr,
151      nullptr,
152      nullptr,
153     },
154     {"r6",
155      nullptr,
156      8,
157      0,
158      eEncodingUint,
159      eFormatHex,
160      {dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
161       LLDB_INVALID_REGNUM},
162      nullptr,
163      nullptr,
164      nullptr,
165     },
166     {"r7",
167      nullptr,
168      8,
169      0,
170      eEncodingUint,
171      eFormatHex,
172      {dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
173       LLDB_INVALID_REGNUM},
174      nullptr,
175      nullptr,
176      nullptr,
177     },
178     {"r8",
179      nullptr,
180      8,
181      0,
182      eEncodingUint,
183      eFormatHex,
184      {dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM,
185       LLDB_INVALID_REGNUM},
186      nullptr,
187      nullptr,
188      nullptr,
189     },
190     {"r9",
191      nullptr,
192      8,
193      0,
194      eEncodingUint,
195      eFormatHex,
196      {dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM,
197       LLDB_INVALID_REGNUM},
198      nullptr,
199      nullptr,
200      nullptr,
201     },
202     {"r10",
203      nullptr,
204      8,
205      0,
206      eEncodingUint,
207      eFormatHex,
208      {dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM,
209       LLDB_INVALID_REGNUM},
210      nullptr,
211      nullptr,
212      nullptr,
213     },
214     {"r11",
215      nullptr,
216      8,
217      0,
218      eEncodingUint,
219      eFormatHex,
220      {dwarf_r11, dwarf_r11, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM,
221       LLDB_INVALID_REGNUM},
222      nullptr,
223      nullptr,
224      nullptr,
225     },
226     {"r12",
227      nullptr,
228      8,
229      0,
230      eEncodingUint,
231      eFormatHex,
232      {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
233       LLDB_INVALID_REGNUM},
234      nullptr,
235      nullptr,
236      nullptr,
237     },
238     {"r13",
239      nullptr,
240      8,
241      0,
242      eEncodingUint,
243      eFormatHex,
244      {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
245       LLDB_INVALID_REGNUM},
246      nullptr,
247      nullptr,
248      nullptr,
249     },
250     {"r14",
251      nullptr,
252      8,
253      0,
254      eEncodingUint,
255      eFormatHex,
256      {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
257       LLDB_INVALID_REGNUM},
258      nullptr,
259      nullptr,
260      nullptr,
261     },
262     {"r15",
263      nullptr,
264      8,
265      0,
266      eEncodingUint,
267      eFormatHex,
268      {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
269       LLDB_INVALID_REGNUM},
270      nullptr,
271      nullptr,
272      nullptr,
273     },
274     {"r16",
275      nullptr,
276      8,
277      0,
278      eEncodingUint,
279      eFormatHex,
280      {dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
281       LLDB_INVALID_REGNUM},
282      nullptr,
283      nullptr,
284      nullptr,
285     },
286     {"r17",
287      nullptr,
288      8,
289      0,
290      eEncodingUint,
291      eFormatHex,
292      {dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
293       LLDB_INVALID_REGNUM},
294      nullptr,
295      nullptr,
296      nullptr,
297     },
298     {"r18",
299      nullptr,
300      8,
301      0,
302      eEncodingUint,
303      eFormatHex,
304      {dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
305       LLDB_INVALID_REGNUM},
306      nullptr,
307      nullptr,
308      nullptr,
309     },
310     {"r19",
311      nullptr,
312      8,
313      0,
314      eEncodingUint,
315      eFormatHex,
316      {dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
317       LLDB_INVALID_REGNUM},
318      nullptr,
319      nullptr,
320      nullptr,
321     },
322     {"r20",
323      nullptr,
324      8,
325      0,
326      eEncodingUint,
327      eFormatHex,
328      {dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
329       LLDB_INVALID_REGNUM},
330      nullptr,
331      nullptr,
332      nullptr,
333     },
334     {"r21",
335      nullptr,
336      8,
337      0,
338      eEncodingUint,
339      eFormatHex,
340      {dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
341       LLDB_INVALID_REGNUM},
342      nullptr,
343      nullptr,
344      nullptr,
345     },
346     {"r22",
347      nullptr,
348      8,
349      0,
350      eEncodingUint,
351      eFormatHex,
352      {dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
353       LLDB_INVALID_REGNUM},
354      nullptr,
355      nullptr,
356      nullptr,
357     },
358     {"r23",
359      nullptr,
360      8,
361      0,
362      eEncodingUint,
363      eFormatHex,
364      {dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
365       LLDB_INVALID_REGNUM},
366      nullptr,
367      nullptr,
368      nullptr,
369     },
370     {"r24",
371      nullptr,
372      8,
373      0,
374      eEncodingUint,
375      eFormatHex,
376      {dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
377       LLDB_INVALID_REGNUM},
378      nullptr,
379      nullptr,
380      nullptr,
381     },
382     {"r25",
383      nullptr,
384      8,
385      0,
386      eEncodingUint,
387      eFormatHex,
388      {dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
389       LLDB_INVALID_REGNUM},
390      nullptr,
391      nullptr,
392      nullptr,
393     },
394     {"r26",
395      nullptr,
396      8,
397      0,
398      eEncodingUint,
399      eFormatHex,
400      {dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
401       LLDB_INVALID_REGNUM},
402      nullptr,
403      nullptr,
404      nullptr,
405     },
406     {"r27",
407      nullptr,
408      8,
409      0,
410      eEncodingUint,
411      eFormatHex,
412      {dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
413       LLDB_INVALID_REGNUM},
414      nullptr,
415      nullptr,
416      nullptr,
417     },
418     {"r28",
419      "gp",
420      8,
421      0,
422      eEncodingUint,
423      eFormatHex,
424      {dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
425       LLDB_INVALID_REGNUM},
426      nullptr,
427      nullptr,
428      nullptr,
429     },
430     {"r29",
431      nullptr,
432      8,
433      0,
434      eEncodingUint,
435      eFormatHex,
436      {dwarf_r29, dwarf_r29, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
437       LLDB_INVALID_REGNUM},
438      nullptr,
439      nullptr,
440      nullptr,
441     },
442     {"r30",
443      nullptr,
444      8,
445      0,
446      eEncodingUint,
447      eFormatHex,
448      {dwarf_r30, dwarf_r30, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
449       LLDB_INVALID_REGNUM},
450      nullptr,
451      nullptr,
452      nullptr,
453     },
454     {"r31",
455      nullptr,
456      8,
457      0,
458      eEncodingUint,
459      eFormatHex,
460      {dwarf_r31, dwarf_r31, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
461       LLDB_INVALID_REGNUM},
462      nullptr,
463      nullptr,
464      nullptr,
465     },
466     {"sr",
467      nullptr,
468      4,
469      0,
470      eEncodingUint,
471      eFormatHex,
472      {dwarf_sr, dwarf_sr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
473       LLDB_INVALID_REGNUM},
474      nullptr,
475      nullptr,
476      nullptr,
477     },
478     {"lo",
479      nullptr,
480      8,
481      0,
482      eEncodingUint,
483      eFormatHex,
484      {dwarf_lo, dwarf_lo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
485       LLDB_INVALID_REGNUM},
486      nullptr,
487      nullptr,
488      nullptr,
489     },
490     {"hi",
491      nullptr,
492      8,
493      0,
494      eEncodingUint,
495      eFormatHex,
496      {dwarf_hi, dwarf_hi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
497       LLDB_INVALID_REGNUM},
498      nullptr,
499      nullptr,
500      nullptr,
501     },
502     {"bad",
503      nullptr,
504      8,
505      0,
506      eEncodingUint,
507      eFormatHex,
508      {dwarf_bad, dwarf_bad, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
509       LLDB_INVALID_REGNUM},
510      nullptr,
511      nullptr,
512      nullptr,
513     },
514     {"cause",
515      nullptr,
516      8,
517      0,
518      eEncodingUint,
519      eFormatHex,
520      {dwarf_cause, dwarf_cause, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
521       LLDB_INVALID_REGNUM},
522      nullptr,
523      nullptr,
524      nullptr,
525     },
526     {"pc",
527      nullptr,
528      8,
529      0,
530      eEncodingUint,
531      eFormatHex,
532      {dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
533       LLDB_INVALID_REGNUM},
534      nullptr,
535      nullptr,
536      nullptr,
537     },
538 };
539 
540 static const uint32_t k_num_register_infos = std::size(g_register_infos_mips64);
541 
542 const lldb_private::RegisterInfo *
543 ABISysV_mips64::GetRegisterInfoArray(uint32_t &count) {
544   count = k_num_register_infos;
545   return g_register_infos_mips64;
546 }
547 
548 size_t ABISysV_mips64::GetRedZoneSize() const { return 0; }
549 
550 // Static Functions
551 
552 ABISP
553 ABISysV_mips64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
554   if (arch.GetTriple().isMIPS64())
555     return ABISP(
556         new ABISysV_mips64(std::move(process_sp), MakeMCRegisterInfo(arch)));
557   return ABISP();
558 }
559 
560 bool ABISysV_mips64::PrepareTrivialCall(Thread &thread, addr_t sp,
561                                         addr_t func_addr, addr_t return_addr,
562                                         llvm::ArrayRef<addr_t> args) const {
563   Log *log = GetLog(LLDBLog::Expressions);
564 
565   if (log) {
566     StreamString s;
567     s.Printf("ABISysV_mips64::PrepareTrivialCall (tid = 0x%" PRIx64
568              ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
569              ", return_addr = 0x%" PRIx64,
570              thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
571              (uint64_t)return_addr);
572 
573     for (size_t i = 0; i < args.size(); ++i)
574       s.Printf(", arg%zd = 0x%" PRIx64, i + 1, args[i]);
575     s.PutCString(")");
576     log->PutString(s.GetString());
577   }
578 
579   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
580   if (!reg_ctx)
581     return false;
582 
583   const RegisterInfo *reg_info = nullptr;
584 
585   if (args.size() > 8) // TODO handle more than 8 arguments
586     return false;
587 
588   for (size_t i = 0; i < args.size(); ++i) {
589     reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
590                                         LLDB_REGNUM_GENERIC_ARG1 + i);
591     LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") into %s", i + 1,
592               args[i], reg_info->name);
593     if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
594       return false;
595   }
596 
597   // First, align the SP
598 
599   LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
600             (uint64_t)sp, (uint64_t)(sp & ~0xfull));
601 
602   sp &= ~(0xfull); // 16-byte alignment
603 
604   Status error;
605   const RegisterInfo *pc_reg_info =
606       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
607   const RegisterInfo *sp_reg_info =
608       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
609   const RegisterInfo *ra_reg_info =
610       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
611   const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0);
612   const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0);
613 
614   LLDB_LOGF(log, "Writing R0: 0x%" PRIx64, (uint64_t)0);
615 
616   /* Write r0 with 0, in case we are stopped in syscall,
617    * such setting prevents automatic decrement of the PC.
618    * This clears the bug 23659 for MIPS.
619   */
620   if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0))
621     return false;
622 
623   LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
624 
625   // Set "sp" to the requested value
626   if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
627     return false;
628 
629   LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
630 
631   // Set "ra" to the return address
632   if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
633     return false;
634 
635   LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
636 
637   // Set pc to the address of the called function.
638   if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
639     return false;
640 
641   LLDB_LOGF(log, "Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
642 
643   // All callers of position independent functions must place the address of
644   // the called function in t9 (r25)
645   if (!reg_ctx->WriteRegisterFromUnsigned(r25_info, func_addr))
646     return false;
647 
648   return true;
649 }
650 
651 bool ABISysV_mips64::GetArgumentValues(Thread &thread,
652                                        ValueList &values) const {
653   return false;
654 }
655 
656 Status ABISysV_mips64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
657                                             lldb::ValueObjectSP &new_value_sp) {
658   Status error;
659   if (!new_value_sp) {
660     error = Status::FromErrorString("Empty value object for return value.");
661     return error;
662   }
663 
664   CompilerType compiler_type = new_value_sp->GetCompilerType();
665   if (!compiler_type) {
666     error = Status::FromErrorString("Null clang type for return value.");
667     return error;
668   }
669 
670   Thread *thread = frame_sp->GetThread().get();
671 
672   RegisterContext *reg_ctx = thread->GetRegisterContext().get();
673 
674   if (!reg_ctx)
675     error = Status::FromErrorString("no registers are available");
676 
677   DataExtractor data;
678   Status data_error;
679   size_t num_bytes = new_value_sp->GetData(data, data_error);
680   if (data_error.Fail()) {
681     error = Status::FromErrorStringWithFormat(
682         "Couldn't convert return value to raw data: %s",
683         data_error.AsCString());
684     return error;
685   }
686 
687   const uint32_t type_flags = compiler_type.GetTypeInfo(nullptr);
688 
689   if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
690     if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
691       lldb::offset_t offset = 0;
692 
693       if (num_bytes <= 16) {
694         const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
695         if (num_bytes <= 8) {
696           uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
697 
698           if (!reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value))
699             error = Status::FromErrorString("failed to write register r2");
700         } else {
701           uint64_t raw_value = data.GetMaxU64(&offset, 8);
702           if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) {
703             const RegisterInfo *r3_info =
704                 reg_ctx->GetRegisterInfoByName("r3", 0);
705             raw_value = data.GetMaxU64(&offset, num_bytes - offset);
706 
707             if (!reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value))
708               error = Status::FromErrorString("failed to write register r3");
709           } else
710             error = Status::FromErrorString("failed to write register r2");
711         }
712       } else {
713         error = Status::FromErrorString(
714             "We don't support returning longer than 128 bit "
715             "integer values at present.");
716       }
717     } else if (type_flags & eTypeIsFloat) {
718       error = Status::FromErrorString("TODO: Handle Float Types.");
719     }
720   } else if (type_flags & eTypeIsVector) {
721     error =
722         Status::FromErrorString("returning vector values are not supported");
723   }
724 
725   return error;
726 }
727 
728 ValueObjectSP ABISysV_mips64::GetReturnValueObjectSimple(
729     Thread &thread, CompilerType &return_compiler_type) const {
730   ValueObjectSP return_valobj_sp;
731   return return_valobj_sp;
732 }
733 
734 ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
735     Thread &thread, CompilerType &return_compiler_type) const {
736   ValueObjectSP return_valobj_sp;
737   Value value;
738   Status error;
739 
740   ExecutionContext exe_ctx(thread.shared_from_this());
741   if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
742     return return_valobj_sp;
743 
744   value.SetCompilerType(return_compiler_type);
745 
746   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
747   if (!reg_ctx)
748     return return_valobj_sp;
749 
750   Target *target = exe_ctx.GetTargetPtr();
751   const ArchSpec target_arch = target->GetArchitecture();
752   ByteOrder target_byte_order = target_arch.GetByteOrder();
753   std::optional<uint64_t> byte_size = return_compiler_type.GetByteSize(&thread);
754   if (!byte_size)
755     return return_valobj_sp;
756   const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
757   uint32_t fp_flag =
758       target_arch.GetFlags() & lldb_private::ArchSpec::eMIPS_ABI_FP_mask;
759 
760   const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
761   const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
762   assert(r2_info && r3_info && "Basic registers should always be present.");
763 
764   if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
765     value.SetValueType(Value::ValueType::Scalar);
766 
767     bool success = false;
768     if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
769       // Extract the register context so we can read arguments from registers
770       // In MIPS register "r2" (v0) holds the integer function return values
771 
772       uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0);
773 
774       const bool is_signed = (type_flags & eTypeIsSigned) != 0;
775       switch (*byte_size) {
776       default:
777         break;
778 
779       case sizeof(uint64_t):
780         if (is_signed)
781           value.GetScalar() = (int64_t)(raw_value);
782         else
783           value.GetScalar() = (uint64_t)(raw_value);
784         success = true;
785         break;
786 
787       case sizeof(uint32_t):
788         if (is_signed)
789           value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
790         else
791           value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
792         success = true;
793         break;
794 
795       case sizeof(uint16_t):
796         if (is_signed)
797           value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
798         else
799           value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
800         success = true;
801         break;
802 
803       case sizeof(uint8_t):
804         if (is_signed)
805           value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
806         else
807           value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
808         success = true;
809         break;
810       }
811     } else if (type_flags & eTypeIsFloat) {
812       if (type_flags & eTypeIsComplex) {
813         // Don't handle complex yet.
814       } else if (IsSoftFloat(fp_flag)) {
815         uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0);
816         switch (*byte_size) {
817         case 4:
818           value.GetScalar() = *((float *)(&raw_value));
819           success = true;
820           break;
821         case 8:
822           value.GetScalar() = *((double *)(&raw_value));
823           success = true;
824           break;
825         case 16:
826           uint64_t result[2];
827           if (target_byte_order == eByteOrderLittle) {
828             result[0] = raw_value;
829             result[1] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0);
830             value.GetScalar() = *((long double *)(result));
831           } else {
832             result[0] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0);
833             result[1] = raw_value;
834             value.GetScalar() = *((long double *)(result));
835           }
836           success = true;
837           break;
838         }
839 
840       } else {
841         if (*byte_size <= sizeof(long double)) {
842           const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
843 
844           RegisterValue f0_value;
845           DataExtractor f0_data;
846 
847           reg_ctx->ReadRegister(f0_info, f0_value);
848 
849           f0_value.GetData(f0_data);
850 
851           lldb::offset_t offset = 0;
852           if (*byte_size == sizeof(float)) {
853             value.GetScalar() = (float)f0_data.GetFloat(&offset);
854             success = true;
855           } else if (*byte_size == sizeof(double)) {
856             value.GetScalar() = (double)f0_data.GetDouble(&offset);
857             success = true;
858           } else if (*byte_size == sizeof(long double)) {
859             const RegisterInfo *f2_info =
860                 reg_ctx->GetRegisterInfoByName("f2", 0);
861             RegisterValue f2_value;
862             DataExtractor f2_data;
863             reg_ctx->ReadRegister(f2_info, f2_value);
864             DataExtractor *copy_from_extractor = nullptr;
865             WritableDataBufferSP data_sp(new DataBufferHeap(16, 0));
866             DataExtractor return_ext(
867                 data_sp, target_byte_order,
868                 target->GetArchitecture().GetAddressByteSize());
869 
870             if (target_byte_order == eByteOrderLittle) {
871               copy_from_extractor = &f0_data;
872               copy_from_extractor->CopyByteOrderedData(
873                   0, 8, data_sp->GetBytes(), *byte_size - 8, target_byte_order);
874               f2_value.GetData(f2_data);
875               copy_from_extractor = &f2_data;
876               copy_from_extractor->CopyByteOrderedData(
877                   0, 8, data_sp->GetBytes() + 8, *byte_size - 8,
878                   target_byte_order);
879             } else {
880               copy_from_extractor = &f0_data;
881               copy_from_extractor->CopyByteOrderedData(
882                   0, 8, data_sp->GetBytes() + 8, *byte_size - 8,
883                   target_byte_order);
884               f2_value.GetData(f2_data);
885               copy_from_extractor = &f2_data;
886               copy_from_extractor->CopyByteOrderedData(
887                   0, 8, data_sp->GetBytes(), *byte_size - 8, target_byte_order);
888             }
889 
890             return_valobj_sp = ValueObjectConstResult::Create(
891                 &thread, return_compiler_type, ConstString(""), return_ext);
892             return return_valobj_sp;
893           }
894         }
895       }
896     }
897 
898     if (success)
899       return_valobj_sp = ValueObjectConstResult::Create(
900           thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
901   } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass ||
902              type_flags & eTypeIsVector) {
903     // Any structure of up to 16 bytes in size is returned in the registers.
904     if (*byte_size <= 16) {
905       WritableDataBufferSP data_sp(new DataBufferHeap(16, 0));
906       DataExtractor return_ext(data_sp, target_byte_order,
907                                target->GetArchitecture().GetAddressByteSize());
908 
909       RegisterValue r2_value, r3_value, f0_value, f1_value, f2_value;
910       // Tracks how much bytes of r2 and r3 registers we've consumed so far
911       uint32_t integer_bytes = 0;
912 
913       // True if return values are in FP return registers.
914       bool use_fp_regs = false;
915       // True if we found any non floating point field in structure.
916       bool found_non_fp_field = false;
917       // True if return values are in r2 register.
918       bool use_r2 = false;
919       // True if return values are in r3 register.
920       bool use_r3 = false;
921       // True if the result is copied into our data buffer
922       bool sucess = false;
923       std::string name;
924       bool is_complex;
925       uint32_t count;
926       const uint32_t num_children = return_compiler_type.GetNumFields();
927 
928       // A structure consisting of one or two FP values (and nothing else) will
929       // be returned in the two FP return-value registers i.e fp0 and fp2.
930       if (num_children <= 2) {
931         uint64_t field_bit_offset = 0;
932 
933         // Check if this structure contains only floating point fields
934         for (uint32_t idx = 0; idx < num_children; idx++) {
935           CompilerType field_compiler_type =
936               return_compiler_type.GetFieldAtIndex(idx, name, &field_bit_offset,
937                                                    nullptr, nullptr);
938 
939           if (field_compiler_type.IsFloatingPointType(count, is_complex))
940             use_fp_regs = true;
941           else
942             found_non_fp_field = true;
943         }
944 
945         if (use_fp_regs && !found_non_fp_field) {
946           // We have one or two FP-only values in this structure. Get it from
947           // f0/f2 registers.
948           DataExtractor f0_data, f1_data, f2_data;
949           const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
950           const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
951           const RegisterInfo *f2_info = reg_ctx->GetRegisterInfoByName("f2", 0);
952 
953           reg_ctx->ReadRegister(f0_info, f0_value);
954           reg_ctx->ReadRegister(f2_info, f2_value);
955 
956           f0_value.GetData(f0_data);
957 
958           for (uint32_t idx = 0; idx < num_children; idx++) {
959             CompilerType field_compiler_type =
960                 return_compiler_type.GetFieldAtIndex(
961                     idx, name, &field_bit_offset, nullptr, nullptr);
962             std::optional<uint64_t> field_byte_width =
963                 field_compiler_type.GetByteSize(&thread);
964             if (!field_byte_width)
965               return return_valobj_sp;
966 
967             DataExtractor *copy_from_extractor = nullptr;
968             uint64_t return_value[2];
969             offset_t offset = 0;
970 
971             if (idx == 0) {
972               // This case is for long double type.
973               if (*field_byte_width == 16) {
974 
975                 // If structure contains long double type, then it is returned
976                 // in fp0/fp1 registers.
977                 if (target_byte_order == eByteOrderLittle) {
978                   return_value[0] = f0_data.GetU64(&offset);
979                   reg_ctx->ReadRegister(f1_info, f1_value);
980                   f1_value.GetData(f1_data);
981                   offset = 0;
982                   return_value[1] = f1_data.GetU64(&offset);
983                 } else {
984                   return_value[1] = f0_data.GetU64(&offset);
985                   reg_ctx->ReadRegister(f1_info, f1_value);
986                   f1_value.GetData(f1_data);
987                   offset = 0;
988                   return_value[0] = f1_data.GetU64(&offset);
989                 }
990 
991                 f0_data.SetData(return_value, *field_byte_width,
992                                 target_byte_order);
993               }
994               copy_from_extractor = &f0_data; // This is in f0, copy from
995                                               // register to our result
996                                               // structure
997             } else {
998               f2_value.GetData(f2_data);
999               // This is in f2, copy from register to our result structure
1000               copy_from_extractor = &f2_data;
1001             }
1002 
1003             // Sanity check to avoid crash
1004             if (!copy_from_extractor ||
1005                 *field_byte_width > copy_from_extractor->GetByteSize())
1006               return return_valobj_sp;
1007 
1008             // copy the register contents into our data buffer
1009             copy_from_extractor->CopyByteOrderedData(
1010                 0, *field_byte_width,
1011                 data_sp->GetBytes() + (field_bit_offset / 8), *field_byte_width,
1012                 target_byte_order);
1013           }
1014 
1015           // The result is in our data buffer.  Create a variable object out of
1016           // it
1017           return_valobj_sp = ValueObjectConstResult::Create(
1018               &thread, return_compiler_type, ConstString(""), return_ext);
1019 
1020           return return_valobj_sp;
1021         }
1022       }
1023 
1024       // If we reach here, it means this structure either contains more than
1025       // two fields or it contains at least one non floating point type. In
1026       // that case, all fields are returned in GP return registers.
1027       for (uint32_t idx = 0; idx < num_children; idx++) {
1028         uint64_t field_bit_offset = 0;
1029         bool is_signed;
1030         uint32_t padding;
1031 
1032         CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
1033             idx, name, &field_bit_offset, nullptr, nullptr);
1034         std::optional<uint64_t> field_byte_width =
1035             field_compiler_type.GetByteSize(&thread);
1036 
1037         // if we don't know the size of the field (e.g. invalid type), just
1038         // bail out
1039         if (!field_byte_width || *field_byte_width == 0)
1040           break;
1041 
1042         uint32_t field_byte_offset = field_bit_offset / 8;
1043 
1044         if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1045             field_compiler_type.IsPointerType() ||
1046             field_compiler_type.IsFloatingPointType(count, is_complex)) {
1047           padding = field_byte_offset - integer_bytes;
1048 
1049           if (integer_bytes < 8) {
1050             // We have not yet consumed r2 completely.
1051             if (integer_bytes + *field_byte_width + padding <= 8) {
1052               // This field fits in r2, copy its value from r2 to our result
1053               // structure
1054               integer_bytes = integer_bytes + *field_byte_width +
1055                               padding; // Increase the consumed bytes.
1056               use_r2 = true;
1057             } else {
1058               // There isn't enough space left in r2 for this field, so this
1059               // will be in r3.
1060               integer_bytes = integer_bytes + *field_byte_width +
1061                               padding; // Increase the consumed bytes.
1062               use_r3 = true;
1063             }
1064           }
1065           // We already have consumed at-least 8 bytes that means r2 is done,
1066           // and this field will be in r3. Check if this field can fit in r3.
1067           else if (integer_bytes + *field_byte_width + padding <= 16) {
1068             integer_bytes = integer_bytes + *field_byte_width + padding;
1069             use_r3 = true;
1070           } else {
1071             // There isn't any space left for this field, this should not
1072             // happen as we have already checked the overall size is not
1073             // greater than 16 bytes. For now, return a nullptr return value
1074             // object.
1075             return return_valobj_sp;
1076           }
1077         }
1078       }
1079       // Vector types up to 16 bytes are returned in GP return registers
1080       if (type_flags & eTypeIsVector) {
1081         if (*byte_size <= 8)
1082           use_r2 = true;
1083         else {
1084           use_r2 = true;
1085           use_r3 = true;
1086         }
1087       }
1088 
1089       if (use_r2) {
1090         reg_ctx->ReadRegister(r2_info, r2_value);
1091 
1092         const size_t bytes_copied = r2_value.GetAsMemoryData(
1093             *r2_info, data_sp->GetBytes(), r2_info->byte_size,
1094             target_byte_order, error);
1095         if (bytes_copied != r2_info->byte_size)
1096           return return_valobj_sp;
1097         sucess = true;
1098       }
1099       if (use_r3) {
1100         reg_ctx->ReadRegister(r3_info, r3_value);
1101         const size_t bytes_copied = r3_value.GetAsMemoryData(
1102             *r3_info, data_sp->GetBytes() + r2_info->byte_size,
1103             r3_info->byte_size, target_byte_order, error);
1104 
1105         if (bytes_copied != r3_info->byte_size)
1106           return return_valobj_sp;
1107         sucess = true;
1108       }
1109       if (sucess) {
1110         // The result is in our data buffer.  Create a variable object out of
1111         // it
1112         return_valobj_sp = ValueObjectConstResult::Create(
1113             &thread, return_compiler_type, ConstString(""), return_ext);
1114       }
1115       return return_valobj_sp;
1116     }
1117 
1118     // Any structure/vector greater than 16 bytes in size is returned in
1119     // memory. The pointer to that memory is returned in r2.
1120     uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned(
1121         reg_ctx->GetRegisterInfoByName("r2", 0), 0);
1122 
1123     // We have got the address. Create a memory object out of it
1124     return_valobj_sp = ValueObjectMemory::Create(
1125         &thread, "", Address(mem_address, nullptr), return_compiler_type);
1126   }
1127   return return_valobj_sp;
1128 }
1129 
1130 bool ABISysV_mips64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1131   unwind_plan.Clear();
1132   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1133 
1134   UnwindPlan::RowSP row(new UnwindPlan::Row);
1135 
1136   // Our Call Frame Address is the stack pointer value
1137   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
1138 
1139   // The previous PC is in the RA
1140   row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
1141   unwind_plan.AppendRow(row);
1142 
1143   // All other registers are the same.
1144 
1145   unwind_plan.SetSourceName("mips64 at-func-entry default");
1146   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1147   unwind_plan.SetReturnAddressRegister(dwarf_r31);
1148   return true;
1149 }
1150 
1151 bool ABISysV_mips64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1152   unwind_plan.Clear();
1153   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1154 
1155   UnwindPlan::RowSP row(new UnwindPlan::Row);
1156 
1157   row->SetUnspecifiedRegistersAreUndefined(true);
1158   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
1159 
1160   row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
1161 
1162   unwind_plan.AppendRow(row);
1163   unwind_plan.SetSourceName("mips64 default unwind plan");
1164   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1165   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1166   unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1167   return true;
1168 }
1169 
1170 bool ABISysV_mips64::RegisterIsVolatile(const RegisterInfo *reg_info) {
1171   return !RegisterIsCalleeSaved(reg_info);
1172 }
1173 
1174 bool ABISysV_mips64::IsSoftFloat(uint32_t fp_flag) const {
1175   return (fp_flag == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT);
1176 }
1177 
1178 bool ABISysV_mips64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1179   if (reg_info) {
1180     // Preserved registers are :
1181     // r16-r23, r28, r29, r30, r31
1182 
1183     int reg = ((reg_info->byte_offset) / 8);
1184 
1185     bool save = (reg >= 16) && (reg <= 23);
1186     save |= (reg >= 28) && (reg <= 31);
1187 
1188     return save;
1189   }
1190   return false;
1191 }
1192 
1193 void ABISysV_mips64::Initialize() {
1194   PluginManager::RegisterPlugin(
1195       GetPluginNameStatic(), "System V ABI for mips64 targets", CreateInstance);
1196 }
1197 
1198 void ABISysV_mips64::Terminate() {
1199   PluginManager::UnregisterPlugin(CreateInstance);
1200 }
1201