]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r306956, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / ABI / MacOSX-i386 / ABIMacOSX_i386.cpp
1 //===-- ABIMacOSX_i386.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 "ABIMacOSX_i386.h"
11
12 // C Includes
13 // C++ Includes
14 #include <vector>
15
16 // Other libraries and framework includes
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/Triple.h"
19
20 // Project includes
21 #include "lldb/Core/Module.h"
22 #include "lldb/Core/PluginManager.h"
23 #include "lldb/Core/RegisterValue.h"
24 #include "lldb/Core/Scalar.h"
25 #include "lldb/Core/ValueObjectConstResult.h"
26 #include "lldb/Symbol/UnwindPlan.h"
27 #include "lldb/Target/Process.h"
28 #include "lldb/Target/RegisterContext.h"
29 #include "lldb/Target/Target.h"
30 #include "lldb/Target/Thread.h"
31 #include "lldb/Utility/ConstString.h"
32 #include "lldb/Utility/Status.h"
33
34 using namespace lldb;
35 using namespace lldb_private;
36
37 enum {
38   ehframe_eax = 0,
39   ehframe_ecx,
40   ehframe_edx,
41   ehframe_ebx,
42   ehframe_ebp, // Different from DWARF the regnums - eh_frame esp/ebp had their
43                // regnums switched on i386 darwin
44   ehframe_esp, // Different from DWARF the regnums - eh_frame esp/ebp had their
45                // regnums switched on i386 darwin
46   ehframe_esi,
47   ehframe_edi,
48   ehframe_eip,
49   ehframe_eflags
50 };
51
52 enum {
53   dwarf_eax = 0,
54   dwarf_ecx,
55   dwarf_edx,
56   dwarf_ebx,
57   dwarf_esp,
58   dwarf_ebp,
59   dwarf_esi,
60   dwarf_edi,
61   dwarf_eip,
62   dwarf_eflags,
63   dwarf_stmm0 = 11,
64   dwarf_stmm1,
65   dwarf_stmm2,
66   dwarf_stmm3,
67   dwarf_stmm4,
68   dwarf_stmm5,
69   dwarf_stmm6,
70   dwarf_stmm7,
71   dwarf_xmm0 = 21,
72   dwarf_xmm1,
73   dwarf_xmm2,
74   dwarf_xmm3,
75   dwarf_xmm4,
76   dwarf_xmm5,
77   dwarf_xmm6,
78   dwarf_xmm7,
79   dwarf_ymm0 = dwarf_xmm0,
80   dwarf_ymm1 = dwarf_xmm1,
81   dwarf_ymm2 = dwarf_xmm2,
82   dwarf_ymm3 = dwarf_xmm3,
83   dwarf_ymm4 = dwarf_xmm4,
84   dwarf_ymm5 = dwarf_xmm5,
85   dwarf_ymm6 = dwarf_xmm6,
86   dwarf_ymm7 = dwarf_xmm7
87 };
88
89 static RegisterInfo g_register_infos[] = {
90     //  NAME      ALT      SZ OFF ENCODING         FORMAT
91     //  EH_FRAME              DWARF                 GENERIC
92     //  PROCESS PLUGIN        LLDB NATIVE
93     //  ======    =======  == === =============    ============
94     //  ===================== ===================== ============================
95     //  ====================  ======================
96     {"eax",
97      nullptr,
98      4,
99      0,
100      eEncodingUint,
101      eFormatHex,
102      {ehframe_eax, dwarf_eax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
103       LLDB_INVALID_REGNUM},
104      nullptr,
105      nullptr,
106      nullptr,
107      0},
108     {"ebx",
109      nullptr,
110      4,
111      0,
112      eEncodingUint,
113      eFormatHex,
114      {ehframe_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
115       LLDB_INVALID_REGNUM},
116      nullptr,
117      nullptr,
118      nullptr,
119      0},
120     {"ecx",
121      nullptr,
122      4,
123      0,
124      eEncodingUint,
125      eFormatHex,
126      {ehframe_ecx, dwarf_ecx, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
127       LLDB_INVALID_REGNUM},
128      nullptr,
129      nullptr,
130      nullptr,
131      0},
132     {"edx",
133      nullptr,
134      4,
135      0,
136      eEncodingUint,
137      eFormatHex,
138      {ehframe_edx, dwarf_edx, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
139       LLDB_INVALID_REGNUM},
140      nullptr,
141      nullptr,
142      nullptr,
143      0},
144     {"esi",
145      nullptr,
146      4,
147      0,
148      eEncodingUint,
149      eFormatHex,
150      {ehframe_esi, dwarf_esi, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
151       LLDB_INVALID_REGNUM},
152      nullptr,
153      nullptr,
154      nullptr,
155      0},
156     {"edi",
157      nullptr,
158      4,
159      0,
160      eEncodingUint,
161      eFormatHex,
162      {ehframe_edi, dwarf_edi, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
163       LLDB_INVALID_REGNUM},
164      nullptr,
165      nullptr,
166      nullptr,
167      0},
168     {"ebp",
169      "fp",
170      4,
171      0,
172      eEncodingUint,
173      eFormatHex,
174      {ehframe_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
175       LLDB_INVALID_REGNUM},
176      nullptr,
177      nullptr,
178      nullptr,
179      0},
180     {"esp",
181      "sp",
182      4,
183      0,
184      eEncodingUint,
185      eFormatHex,
186      {ehframe_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
187       LLDB_INVALID_REGNUM},
188      nullptr,
189      nullptr,
190      nullptr,
191      0},
192     {"eip",
193      "pc",
194      4,
195      0,
196      eEncodingUint,
197      eFormatHex,
198      {ehframe_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
199       LLDB_INVALID_REGNUM},
200      nullptr,
201      nullptr,
202      nullptr,
203      0},
204     {"eflags",
205      nullptr,
206      4,
207      0,
208      eEncodingUint,
209      eFormatHex,
210      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
211       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
212      nullptr,
213      nullptr,
214      nullptr,
215      0},
216     {"cs",
217      nullptr,
218      4,
219      0,
220      eEncodingUint,
221      eFormatHex,
222      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
223       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
224      nullptr,
225      nullptr,
226      nullptr,
227      0},
228     {"ss",
229      nullptr,
230      4,
231      0,
232      eEncodingUint,
233      eFormatHex,
234      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
235       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
236      nullptr,
237      nullptr,
238      nullptr,
239      0},
240     {"ds",
241      nullptr,
242      4,
243      0,
244      eEncodingUint,
245      eFormatHex,
246      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
247       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
248      nullptr,
249      nullptr,
250      nullptr,
251      0},
252     {"es",
253      nullptr,
254      4,
255      0,
256      eEncodingUint,
257      eFormatHex,
258      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
259       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
260      nullptr,
261      nullptr,
262      nullptr,
263      0},
264     {"fs",
265      nullptr,
266      4,
267      0,
268      eEncodingUint,
269      eFormatHex,
270      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
271       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
272      nullptr,
273      nullptr,
274      nullptr,
275      0},
276     {"gs",
277      nullptr,
278      4,
279      0,
280      eEncodingUint,
281      eFormatHex,
282      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
283       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
284      nullptr,
285      nullptr,
286      nullptr,
287      0},
288     {"stmm0",
289      nullptr,
290      10,
291      0,
292      eEncodingVector,
293      eFormatVectorOfUInt8,
294      {LLDB_INVALID_REGNUM, dwarf_stmm0, LLDB_INVALID_REGNUM,
295       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
296      nullptr,
297      nullptr,
298      nullptr,
299      0},
300     {"stmm1",
301      nullptr,
302      10,
303      0,
304      eEncodingVector,
305      eFormatVectorOfUInt8,
306      {LLDB_INVALID_REGNUM, dwarf_stmm1, LLDB_INVALID_REGNUM,
307       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
308      nullptr,
309      nullptr,
310      nullptr,
311      0},
312     {"stmm2",
313      nullptr,
314      10,
315      0,
316      eEncodingVector,
317      eFormatVectorOfUInt8,
318      {LLDB_INVALID_REGNUM, dwarf_stmm2, LLDB_INVALID_REGNUM,
319       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
320      nullptr,
321      nullptr,
322      nullptr,
323      0},
324     {"stmm3",
325      nullptr,
326      10,
327      0,
328      eEncodingVector,
329      eFormatVectorOfUInt8,
330      {LLDB_INVALID_REGNUM, dwarf_stmm3, LLDB_INVALID_REGNUM,
331       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
332      nullptr,
333      nullptr,
334      nullptr,
335      0},
336     {"stmm4",
337      nullptr,
338      10,
339      0,
340      eEncodingVector,
341      eFormatVectorOfUInt8,
342      {LLDB_INVALID_REGNUM, dwarf_stmm4, LLDB_INVALID_REGNUM,
343       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
344      nullptr,
345      nullptr,
346      nullptr,
347      0},
348     {"stmm5",
349      nullptr,
350      10,
351      0,
352      eEncodingVector,
353      eFormatVectorOfUInt8,
354      {LLDB_INVALID_REGNUM, dwarf_stmm5, LLDB_INVALID_REGNUM,
355       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
356      nullptr,
357      nullptr,
358      nullptr,
359      0},
360     {"stmm6",
361      nullptr,
362      10,
363      0,
364      eEncodingVector,
365      eFormatVectorOfUInt8,
366      {LLDB_INVALID_REGNUM, dwarf_stmm6, LLDB_INVALID_REGNUM,
367       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
368      nullptr,
369      nullptr,
370      nullptr,
371      0},
372     {"stmm7",
373      nullptr,
374      10,
375      0,
376      eEncodingVector,
377      eFormatVectorOfUInt8,
378      {LLDB_INVALID_REGNUM, dwarf_stmm7, LLDB_INVALID_REGNUM,
379       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
380      nullptr,
381      nullptr,
382      nullptr,
383      0},
384     {"fctrl",
385      nullptr,
386      4,
387      0,
388      eEncodingUint,
389      eFormatHex,
390      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
391       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
392      nullptr,
393      nullptr,
394      nullptr,
395      0},
396     {"fstat",
397      nullptr,
398      4,
399      0,
400      eEncodingUint,
401      eFormatHex,
402      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
403       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
404      nullptr,
405      nullptr,
406      nullptr,
407      0},
408     {"ftag",
409      nullptr,
410      4,
411      0,
412      eEncodingUint,
413      eFormatHex,
414      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
415       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
416      nullptr,
417      nullptr,
418      nullptr,
419      0},
420     {"fiseg",
421      nullptr,
422      4,
423      0,
424      eEncodingUint,
425      eFormatHex,
426      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
427       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
428      nullptr,
429      nullptr,
430      nullptr,
431      0},
432     {"fioff",
433      nullptr,
434      4,
435      0,
436      eEncodingUint,
437      eFormatHex,
438      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
439       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
440      nullptr,
441      nullptr,
442      nullptr,
443      0},
444     {"foseg",
445      nullptr,
446      4,
447      0,
448      eEncodingUint,
449      eFormatHex,
450      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
451       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
452      nullptr,
453      nullptr,
454      nullptr,
455      0},
456     {"fooff",
457      nullptr,
458      4,
459      0,
460      eEncodingUint,
461      eFormatHex,
462      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
463       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
464      nullptr,
465      nullptr,
466      nullptr,
467      0},
468     {"fop",
469      nullptr,
470      4,
471      0,
472      eEncodingUint,
473      eFormatHex,
474      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
475       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
476      nullptr,
477      nullptr,
478      nullptr,
479      0},
480     {"xmm0",
481      nullptr,
482      16,
483      0,
484      eEncodingVector,
485      eFormatVectorOfUInt8,
486      {LLDB_INVALID_REGNUM, dwarf_xmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
487       LLDB_INVALID_REGNUM},
488      nullptr,
489      nullptr,
490      nullptr,
491      0},
492     {"xmm1",
493      nullptr,
494      16,
495      0,
496      eEncodingVector,
497      eFormatVectorOfUInt8,
498      {LLDB_INVALID_REGNUM, dwarf_xmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
499       LLDB_INVALID_REGNUM},
500      nullptr,
501      nullptr,
502      nullptr,
503      0},
504     {"xmm2",
505      nullptr,
506      16,
507      0,
508      eEncodingVector,
509      eFormatVectorOfUInt8,
510      {LLDB_INVALID_REGNUM, dwarf_xmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
511       LLDB_INVALID_REGNUM},
512      nullptr,
513      nullptr,
514      nullptr,
515      0},
516     {"xmm3",
517      nullptr,
518      16,
519      0,
520      eEncodingVector,
521      eFormatVectorOfUInt8,
522      {LLDB_INVALID_REGNUM, dwarf_xmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
523       LLDB_INVALID_REGNUM},
524      nullptr,
525      nullptr,
526      nullptr,
527      0},
528     {"xmm4",
529      nullptr,
530      16,
531      0,
532      eEncodingVector,
533      eFormatVectorOfUInt8,
534      {LLDB_INVALID_REGNUM, dwarf_xmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
535       LLDB_INVALID_REGNUM},
536      nullptr,
537      nullptr,
538      nullptr,
539      0},
540     {"xmm5",
541      nullptr,
542      16,
543      0,
544      eEncodingVector,
545      eFormatVectorOfUInt8,
546      {LLDB_INVALID_REGNUM, dwarf_xmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
547       LLDB_INVALID_REGNUM},
548      nullptr,
549      nullptr,
550      nullptr,
551      0},
552     {"xmm6",
553      nullptr,
554      16,
555      0,
556      eEncodingVector,
557      eFormatVectorOfUInt8,
558      {LLDB_INVALID_REGNUM, dwarf_xmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
559       LLDB_INVALID_REGNUM},
560      nullptr,
561      nullptr,
562      nullptr,
563      0},
564     {"xmm7",
565      nullptr,
566      16,
567      0,
568      eEncodingVector,
569      eFormatVectorOfUInt8,
570      {LLDB_INVALID_REGNUM, dwarf_xmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
571       LLDB_INVALID_REGNUM},
572      nullptr,
573      nullptr,
574      nullptr,
575      0},
576     {"mxcsr",
577      nullptr,
578      4,
579      0,
580      eEncodingUint,
581      eFormatHex,
582      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
583       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
584      nullptr,
585      nullptr,
586      nullptr,
587      0},
588     {"ymm0",
589      nullptr,
590      32,
591      0,
592      eEncodingVector,
593      eFormatVectorOfUInt8,
594      {LLDB_INVALID_REGNUM, dwarf_ymm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
595       LLDB_INVALID_REGNUM},
596      nullptr,
597      nullptr,
598      nullptr,
599      0},
600     {"ymm1",
601      nullptr,
602      32,
603      0,
604      eEncodingVector,
605      eFormatVectorOfUInt8,
606      {LLDB_INVALID_REGNUM, dwarf_ymm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
607       LLDB_INVALID_REGNUM},
608      nullptr,
609      nullptr,
610      nullptr,
611      0},
612     {"ymm2",
613      nullptr,
614      32,
615      0,
616      eEncodingVector,
617      eFormatVectorOfUInt8,
618      {LLDB_INVALID_REGNUM, dwarf_ymm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
619       LLDB_INVALID_REGNUM},
620      nullptr,
621      nullptr,
622      nullptr,
623      0},
624     {"ymm3",
625      nullptr,
626      32,
627      0,
628      eEncodingVector,
629      eFormatVectorOfUInt8,
630      {LLDB_INVALID_REGNUM, dwarf_ymm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
631       LLDB_INVALID_REGNUM},
632      nullptr,
633      nullptr,
634      nullptr,
635      0},
636     {"ymm4",
637      nullptr,
638      32,
639      0,
640      eEncodingVector,
641      eFormatVectorOfUInt8,
642      {LLDB_INVALID_REGNUM, dwarf_ymm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
643       LLDB_INVALID_REGNUM},
644      nullptr,
645      nullptr,
646      nullptr,
647      0},
648     {"ymm5",
649      nullptr,
650      32,
651      0,
652      eEncodingVector,
653      eFormatVectorOfUInt8,
654      {LLDB_INVALID_REGNUM, dwarf_ymm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
655       LLDB_INVALID_REGNUM},
656      nullptr,
657      nullptr,
658      nullptr,
659      0},
660     {"ymm6",
661      nullptr,
662      32,
663      0,
664      eEncodingVector,
665      eFormatVectorOfUInt8,
666      {LLDB_INVALID_REGNUM, dwarf_ymm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
667       LLDB_INVALID_REGNUM},
668      nullptr,
669      nullptr,
670      nullptr,
671      0},
672     {"ymm7",
673      nullptr,
674      32,
675      0,
676      eEncodingVector,
677      eFormatVectorOfUInt8,
678      {LLDB_INVALID_REGNUM, dwarf_ymm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
679       LLDB_INVALID_REGNUM},
680      nullptr,
681      nullptr,
682      nullptr,
683      0}};
684
685 static const uint32_t k_num_register_infos =
686     llvm::array_lengthof(g_register_infos);
687 static bool g_register_info_names_constified = false;
688
689 const lldb_private::RegisterInfo *
690 ABIMacOSX_i386::GetRegisterInfoArray(uint32_t &count) {
691   // Make the C-string names and alt_names for the register infos into const
692   // C-string values by having the ConstString unique the names in the global
693   // constant C-string pool.
694   if (!g_register_info_names_constified) {
695     g_register_info_names_constified = true;
696     for (uint32_t i = 0; i < k_num_register_infos; ++i) {
697       if (g_register_infos[i].name)
698         g_register_infos[i].name =
699             ConstString(g_register_infos[i].name).GetCString();
700       if (g_register_infos[i].alt_name)
701         g_register_infos[i].alt_name =
702             ConstString(g_register_infos[i].alt_name).GetCString();
703     }
704   }
705   count = k_num_register_infos;
706   return g_register_infos;
707 }
708
709 size_t ABIMacOSX_i386::GetRedZoneSize() const { return 0; }
710
711 //------------------------------------------------------------------
712 // Static Functions
713 //------------------------------------------------------------------
714
715 ABISP
716 ABIMacOSX_i386::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
717   static ABISP g_abi_sp;
718   if ((arch.GetTriple().getArch() == llvm::Triple::x86) &&
719       (arch.GetTriple().isMacOSX() || arch.GetTriple().isiOS() ||
720        arch.GetTriple().isWatchOS())) {
721     if (!g_abi_sp)
722       g_abi_sp.reset(new ABIMacOSX_i386(process_sp));
723     return g_abi_sp;
724   }
725   return ABISP();
726 }
727
728 bool ABIMacOSX_i386::PrepareTrivialCall(Thread &thread, addr_t sp,
729                                         addr_t func_addr, addr_t return_addr,
730                                         llvm::ArrayRef<addr_t> args) const {
731   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
732   if (!reg_ctx)
733     return false;
734   uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
735       eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
736   uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
737       eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
738
739   // When writing a register value down to memory, the register info used
740   // to write memory just needs to have the correct size of a 32 bit register,
741   // the actual register it pertains to is not important, just the size needs
742   // to be correct. Here we use "eax"...
743   const RegisterInfo *reg_info_32 = reg_ctx->GetRegisterInfoByName("eax");
744   if (!reg_info_32)
745     return false; // TODO this should actually never happen
746
747   // Make room for the argument(s) on the stack
748
749   Status error;
750   RegisterValue reg_value;
751
752   // Write any arguments onto the stack
753   sp -= 4 * args.size();
754
755   // Align the SP
756   sp &= ~(16ull - 1ull); // 16-byte alignment
757
758   addr_t arg_pos = sp;
759
760   for (addr_t arg : args) {
761     reg_value.SetUInt32(arg);
762     error = reg_ctx->WriteRegisterValueToMemory(
763         reg_info_32, arg_pos, reg_info_32->byte_size, reg_value);
764     if (error.Fail())
765       return false;
766     arg_pos += 4;
767   }
768
769   // The return address is pushed onto the stack (yes after we just set the
770   // alignment above!).
771   sp -= 4;
772   reg_value.SetUInt32(return_addr);
773   error = reg_ctx->WriteRegisterValueToMemory(
774       reg_info_32, sp, reg_info_32->byte_size, reg_value);
775   if (error.Fail())
776     return false;
777
778   // %esp is set to the actual stack value.
779
780   if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp))
781     return false;
782
783   // %eip is set to the address of the called function.
784
785   if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, func_addr))
786     return false;
787
788   return true;
789 }
790
791 static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
792                                 bool is_signed, Process *process,
793                                 addr_t &current_stack_argument) {
794
795   uint32_t byte_size = (bit_width + (8 - 1)) / 8;
796   Status error;
797   if (process->ReadScalarIntegerFromMemory(current_stack_argument, byte_size,
798                                            is_signed, scalar, error)) {
799     current_stack_argument += byte_size;
800     return true;
801   }
802   return false;
803 }
804
805 bool ABIMacOSX_i386::GetArgumentValues(Thread &thread,
806                                        ValueList &values) const {
807   unsigned int num_values = values.GetSize();
808   unsigned int value_index;
809
810   // Get the pointer to the first stack argument so we have a place to start
811   // when reading data
812
813   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
814
815   if (!reg_ctx)
816     return false;
817
818   addr_t sp = reg_ctx->GetSP(0);
819
820   if (!sp)
821     return false;
822
823   addr_t current_stack_argument = sp + 4; // jump over return address
824
825   for (value_index = 0; value_index < num_values; ++value_index) {
826     Value *value = values.GetValueAtIndex(value_index);
827
828     if (!value)
829       return false;
830
831     // We currently only support extracting values with Clang QualTypes.
832     // Do we care about others?
833     CompilerType compiler_type(value->GetCompilerType());
834     if (compiler_type) {
835       bool is_signed;
836
837       if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
838         ReadIntegerArgument(value->GetScalar(),
839                             compiler_type.GetBitSize(&thread), is_signed,
840                             thread.GetProcess().get(), current_stack_argument);
841       } else if (compiler_type.IsPointerType()) {
842         ReadIntegerArgument(value->GetScalar(),
843                             compiler_type.GetBitSize(&thread), false,
844                             thread.GetProcess().get(), current_stack_argument);
845       }
846     }
847   }
848
849   return true;
850 }
851
852 Status ABIMacOSX_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
853                                             lldb::ValueObjectSP &new_value_sp) {
854   Status error;
855   if (!new_value_sp) {
856     error.SetErrorString("Empty value object for return value.");
857     return error;
858   }
859
860   CompilerType compiler_type = new_value_sp->GetCompilerType();
861   if (!compiler_type) {
862     error.SetErrorString("Null clang type for return value.");
863     return error;
864   }
865
866   Thread *thread = frame_sp->GetThread().get();
867
868   bool is_signed;
869   uint32_t count;
870   bool is_complex;
871
872   RegisterContext *reg_ctx = thread->GetRegisterContext().get();
873
874   bool set_it_simple = false;
875   if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
876       compiler_type.IsPointerType()) {
877     DataExtractor data;
878     Status data_error;
879     size_t num_bytes = new_value_sp->GetData(data, data_error);
880     if (data_error.Fail()) {
881       error.SetErrorStringWithFormat(
882           "Couldn't convert return value to raw data: %s",
883           data_error.AsCString());
884       return error;
885     }
886     lldb::offset_t offset = 0;
887     if (num_bytes <= 8) {
888       const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0);
889       if (num_bytes <= 4) {
890         uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
891
892         if (reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value))
893           set_it_simple = true;
894       } else {
895         uint32_t raw_value = data.GetMaxU32(&offset, 4);
896
897         if (reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value)) {
898           const RegisterInfo *edx_info =
899               reg_ctx->GetRegisterInfoByName("edx", 0);
900           uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
901
902           if (reg_ctx->WriteRegisterFromUnsigned(edx_info, raw_value))
903             set_it_simple = true;
904         }
905       }
906     } else {
907       error.SetErrorString("We don't support returning longer than 64 bit "
908                            "integer values at present.");
909     }
910   } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
911     if (is_complex)
912       error.SetErrorString(
913           "We don't support returning complex values at present");
914     else
915       error.SetErrorString(
916           "We don't support returning float values at present");
917   }
918
919   if (!set_it_simple)
920     error.SetErrorString(
921         "We only support setting simple integer return types at present.");
922
923   return error;
924 }
925
926 ValueObjectSP
927 ABIMacOSX_i386::GetReturnValueObjectImpl(Thread &thread,
928                                          CompilerType &compiler_type) const {
929   Value value;
930   ValueObjectSP return_valobj_sp;
931
932   if (!compiler_type)
933     return return_valobj_sp;
934
935   // value.SetContext (Value::eContextTypeClangType,
936   // compiler_type.GetOpaqueQualType());
937   value.SetCompilerType(compiler_type);
938
939   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
940   if (!reg_ctx)
941     return return_valobj_sp;
942
943   bool is_signed;
944
945   if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
946     size_t bit_width = compiler_type.GetBitSize(&thread);
947
948     unsigned eax_id =
949         reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
950     unsigned edx_id =
951         reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB];
952
953     switch (bit_width) {
954     default:
955     case 128:
956       // Scalar can't hold 128-bit literals, so we don't handle this
957       return return_valobj_sp;
958     case 64:
959       uint64_t raw_value;
960       raw_value =
961           thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
962           0xffffffff;
963       raw_value |=
964           (thread.GetRegisterContext()->ReadRegisterAsUnsigned(edx_id, 0) &
965            0xffffffff)
966           << 32;
967       if (is_signed)
968         value.GetScalar() = (int64_t)raw_value;
969       else
970         value.GetScalar() = (uint64_t)raw_value;
971       break;
972     case 32:
973       if (is_signed)
974         value.GetScalar() = (int32_t)(
975             thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
976             0xffffffff);
977       else
978         value.GetScalar() = (uint32_t)(
979             thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
980             0xffffffff);
981       break;
982     case 16:
983       if (is_signed)
984         value.GetScalar() = (int16_t)(
985             thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
986             0xffff);
987       else
988         value.GetScalar() = (uint16_t)(
989             thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
990             0xffff);
991       break;
992     case 8:
993       if (is_signed)
994         value.GetScalar() = (int8_t)(
995             thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
996             0xff);
997       else
998         value.GetScalar() = (uint8_t)(
999             thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
1000             0xff);
1001       break;
1002     }
1003   } else if (compiler_type.IsPointerType()) {
1004     unsigned eax_id =
1005         reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
1006     uint32_t ptr =
1007         thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
1008         0xffffffff;
1009     value.GetScalar() = ptr;
1010   } else {
1011     // not handled yet
1012     return return_valobj_sp;
1013   }
1014
1015   // If we get here, we have a valid Value, so make our ValueObject out of it:
1016
1017   return_valobj_sp = ValueObjectConstResult::Create(
1018       thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
1019   return return_valobj_sp;
1020 }
1021
1022 // This defines the CFA as esp+4
1023 // the saved pc is at CFA-4 (i.e. esp+0)
1024 // The saved esp is CFA+0
1025
1026 bool ABIMacOSX_i386::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1027   unwind_plan.Clear();
1028   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1029
1030   uint32_t sp_reg_num = dwarf_esp;
1031   uint32_t pc_reg_num = dwarf_eip;
1032
1033   UnwindPlan::RowSP row(new UnwindPlan::Row);
1034   row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 4);
1035   row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false);
1036   row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1037   unwind_plan.AppendRow(row);
1038   unwind_plan.SetSourceName("i386 at-func-entry default");
1039   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1040   return true;
1041 }
1042
1043 // This defines the CFA as ebp+8
1044 // The saved pc is at CFA-4 (i.e. ebp+4)
1045 // The saved ebp is at CFA-8 (i.e. ebp+0)
1046 // The saved esp is CFA+0
1047
1048 bool ABIMacOSX_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1049   unwind_plan.Clear();
1050   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1051
1052   uint32_t fp_reg_num = dwarf_ebp;
1053   uint32_t sp_reg_num = dwarf_esp;
1054   uint32_t pc_reg_num = dwarf_eip;
1055
1056   UnwindPlan::RowSP row(new UnwindPlan::Row);
1057   const int32_t ptr_size = 4;
1058
1059   row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
1060   row->SetOffset(0);
1061
1062   row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
1063   row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
1064   row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1065
1066   unwind_plan.AppendRow(row);
1067   unwind_plan.SetSourceName("i386 default unwind plan");
1068   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1069   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1070   return true;
1071 }
1072
1073 bool ABIMacOSX_i386::RegisterIsVolatile(const RegisterInfo *reg_info) {
1074   return !RegisterIsCalleeSaved(reg_info);
1075 }
1076
1077 // v.
1078 // http://developer.apple.com/library/mac/#documentation/developertools/Conceptual/LowLevelABI/130-IA-32_Function_Calling_Conventions/IA32.html#//apple_ref/doc/uid/TP40002492-SW4
1079 //
1080 // This document ("OS X ABI Function Call Guide", chapter "IA-32 Function
1081 // Calling Conventions")
1082 // says that the following registers on i386 are preserved aka non-volatile aka
1083 // callee-saved:
1084 //
1085 // ebx, ebp, esi, edi, esp
1086
1087 bool ABIMacOSX_i386::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1088   if (reg_info) {
1089     // Saved registers are ebx, ebp, esi, edi, esp, eip
1090     const char *name = reg_info->name;
1091     if (name[0] == 'e') {
1092       switch (name[1]) {
1093       case 'b':
1094         if (name[2] == 'x' || name[2] == 'p')
1095           return name[3] == '\0';
1096         break;
1097       case 'd':
1098         if (name[2] == 'i')
1099           return name[3] == '\0';
1100         break;
1101       case 'i':
1102         if (name[2] == 'p')
1103           return name[3] == '\0';
1104         break;
1105       case 's':
1106         if (name[2] == 'i' || name[2] == 'p')
1107           return name[3] == '\0';
1108         break;
1109       }
1110     }
1111     if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
1112       return true;
1113     if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
1114       return true;
1115     if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
1116       return true;
1117   }
1118   return false;
1119 }
1120
1121 void ABIMacOSX_i386::Initialize() {
1122   PluginManager::RegisterPlugin(
1123       GetPluginNameStatic(), "Mac OS X ABI for i386 targets", CreateInstance);
1124 }
1125
1126 void ABIMacOSX_i386::Terminate() {
1127   PluginManager::UnregisterPlugin(CreateInstance);
1128 }
1129
1130 lldb_private::ConstString ABIMacOSX_i386::GetPluginNameStatic() {
1131   static ConstString g_short_name("abi.macosx-i386");
1132   return g_short_name;
1133 }
1134
1135 //------------------------------------------------------------------
1136 // PluginInterface protocol
1137 //------------------------------------------------------------------
1138
1139 lldb_private::ConstString ABIMacOSX_i386::GetPluginName() {
1140   return GetPluginNameStatic();
1141 }
1142
1143 uint32_t ABIMacOSX_i386::GetPluginVersion() { return 1; }