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