]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
MFV r348534: 9616 Bogus error when attempting to set property on read-only pool
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Process / Utility / RegisterContextDarwin_i386.cpp
1 //===-- RegisterContextDarwin_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 <stddef.h>
11
12 #include "lldb/Utility/DataBufferHeap.h"
13 #include "lldb/Utility/DataExtractor.h"
14 #include "lldb/Utility/Endian.h"
15 #include "lldb/Utility/Log.h"
16 #include "lldb/Utility/RegisterValue.h"
17 #include "lldb/Utility/Scalar.h"
18 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/Support/Compiler.h"
20
21 // Support building against older versions of LLVM, this macro was added
22 // recently.
23 #ifndef LLVM_EXTENSION
24 #define LLVM_EXTENSION
25 #endif
26
27 #include "RegisterContextDarwin_i386.h"
28
29 using namespace lldb;
30 using namespace lldb_private;
31
32 enum {
33   gpr_eax = 0,
34   gpr_ebx,
35   gpr_ecx,
36   gpr_edx,
37   gpr_edi,
38   gpr_esi,
39   gpr_ebp,
40   gpr_esp,
41   gpr_ss,
42   gpr_eflags,
43   gpr_eip,
44   gpr_cs,
45   gpr_ds,
46   gpr_es,
47   gpr_fs,
48   gpr_gs,
49
50   fpu_fcw,
51   fpu_fsw,
52   fpu_ftw,
53   fpu_fop,
54   fpu_ip,
55   fpu_cs,
56   fpu_dp,
57   fpu_ds,
58   fpu_mxcsr,
59   fpu_mxcsrmask,
60   fpu_stmm0,
61   fpu_stmm1,
62   fpu_stmm2,
63   fpu_stmm3,
64   fpu_stmm4,
65   fpu_stmm5,
66   fpu_stmm6,
67   fpu_stmm7,
68   fpu_xmm0,
69   fpu_xmm1,
70   fpu_xmm2,
71   fpu_xmm3,
72   fpu_xmm4,
73   fpu_xmm5,
74   fpu_xmm6,
75   fpu_xmm7,
76
77   exc_trapno,
78   exc_err,
79   exc_faultvaddr,
80
81   k_num_registers,
82
83   // Aliases
84   fpu_fctrl = fpu_fcw,
85   fpu_fstat = fpu_fsw,
86   fpu_ftag = fpu_ftw,
87   fpu_fiseg = fpu_cs,
88   fpu_fioff = fpu_ip,
89   fpu_foseg = fpu_ds,
90   fpu_fooff = fpu_dp
91 };
92
93 enum {
94   ehframe_eax = 0,
95   ehframe_ecx,
96   ehframe_edx,
97   ehframe_ebx,
98   ehframe_ebp,
99   ehframe_esp,
100   ehframe_esi,
101   ehframe_edi,
102   ehframe_eip,
103   ehframe_eflags
104 };
105
106 enum {
107   dwarf_eax = 0,
108   dwarf_ecx,
109   dwarf_edx,
110   dwarf_ebx,
111   dwarf_esp,
112   dwarf_ebp,
113   dwarf_esi,
114   dwarf_edi,
115   dwarf_eip,
116   dwarf_eflags,
117   dwarf_stmm0 = 11,
118   dwarf_stmm1,
119   dwarf_stmm2,
120   dwarf_stmm3,
121   dwarf_stmm4,
122   dwarf_stmm5,
123   dwarf_stmm6,
124   dwarf_stmm7,
125   dwarf_xmm0 = 21,
126   dwarf_xmm1,
127   dwarf_xmm2,
128   dwarf_xmm3,
129   dwarf_xmm4,
130   dwarf_xmm5,
131   dwarf_xmm6,
132   dwarf_xmm7
133 };
134
135 #define GPR_OFFSET(reg)                                                        \
136   (LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::GPR, reg))
137 #define FPU_OFFSET(reg)                                                        \
138   (LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::FPU, reg) +             \
139    sizeof(RegisterContextDarwin_i386::GPR))
140 #define EXC_OFFSET(reg)                                                        \
141   (LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::EXC, reg) +             \
142    sizeof(RegisterContextDarwin_i386::GPR) +                                   \
143    sizeof(RegisterContextDarwin_i386::FPU))
144
145 // These macros will auto define the register name, alt name, register size,
146 // register offset, encoding, format and native register. This ensures that the
147 // register state structures are defined correctly and have the correct sizes
148 // and offsets.
149 #define DEFINE_GPR(reg, alt)                                                   \
150   #reg, alt, sizeof(((RegisterContextDarwin_i386::GPR *) NULL)->reg),          \
151                     GPR_OFFSET(reg), eEncodingUint, eFormatHex
152 #define DEFINE_FPU_UINT(reg)                                                   \
153   #reg, NULL, sizeof(((RegisterContextDarwin_i386::FPU *) NULL)->reg),         \
154                      FPU_OFFSET(reg), eEncodingUint, eFormatHex
155 #define DEFINE_FPU_VECT(reg, i)                                                \
156   #reg #i, NULL,                                                               \
157       sizeof(((RegisterContextDarwin_i386::FPU *) NULL)->reg[i].bytes),        \
158               FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8,       \
159                          {LLDB_INVALID_REGNUM, dwarf_##reg##i,                 \
160                           LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,            \
161                           fpu_##reg##i },                                      \
162                           nullptr, nullptr, nullptr, 0
163
164 #define DEFINE_EXC(reg)                                                        \
165   #reg, NULL, sizeof(((RegisterContextDarwin_i386::EXC *) NULL)->reg),         \
166                      EXC_OFFSET(reg), eEncodingUint, eFormatHex
167 #define REG_CONTEXT_SIZE                                                       \
168   (sizeof(RegisterContextDarwin_i386::GPR) +                                   \
169    sizeof(RegisterContextDarwin_i386::FPU) +                                   \
170    sizeof(RegisterContextDarwin_i386::EXC))
171
172 static RegisterInfo g_register_infos[] = {
173     //  Macro auto defines most stuff   eh_frame                DWARF
174     //  GENERIC                    PROCESS PLUGIN       LLDB
175     //  =============================== =======================
176     //  ===================   =========================  ==================
177     //  =================
178     {DEFINE_GPR(eax, NULL),
179      {ehframe_eax, dwarf_eax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
180       gpr_eax},
181      nullptr,
182      nullptr,
183      nullptr,
184      0},
185     {DEFINE_GPR(ebx, NULL),
186      {ehframe_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
187       gpr_ebx},
188      nullptr,
189      nullptr,
190      nullptr,
191      0},
192     {DEFINE_GPR(ecx, NULL),
193      {ehframe_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
194       gpr_ecx},
195      nullptr,
196      nullptr,
197      nullptr,
198      0},
199     {DEFINE_GPR(edx, NULL),
200      {ehframe_edx, dwarf_edx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
201       gpr_edx},
202      nullptr,
203      nullptr,
204      nullptr,
205      0},
206     {DEFINE_GPR(edi, NULL),
207      {ehframe_edi, dwarf_edi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
208       gpr_edi},
209      nullptr,
210      nullptr,
211      nullptr,
212      0},
213     {DEFINE_GPR(esi, NULL),
214      {ehframe_esi, dwarf_esi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
215       gpr_esi},
216      nullptr,
217      nullptr,
218      nullptr,
219      0},
220     {DEFINE_GPR(ebp, "fp"),
221      {ehframe_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
222       gpr_ebp},
223      nullptr,
224      nullptr,
225      nullptr,
226      0},
227     {DEFINE_GPR(esp, "sp"),
228      {ehframe_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
229       gpr_esp},
230      nullptr,
231      nullptr,
232      nullptr,
233      0},
234     {DEFINE_GPR(ss, NULL),
235      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
236       LLDB_INVALID_REGNUM, gpr_ss},
237      nullptr,
238      nullptr,
239      nullptr,
240      0},
241     {DEFINE_GPR(eflags, "flags"),
242      {ehframe_eflags, dwarf_eflags, LLDB_REGNUM_GENERIC_FLAGS,
243       LLDB_INVALID_REGNUM, gpr_eflags},
244      nullptr,
245      nullptr,
246      nullptr,
247      0},
248     {DEFINE_GPR(eip, "pc"),
249      {ehframe_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
250       gpr_eip},
251      nullptr,
252      nullptr,
253      nullptr,
254      0},
255     {DEFINE_GPR(cs, NULL),
256      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
257       LLDB_INVALID_REGNUM, gpr_cs},
258      nullptr,
259      nullptr,
260      nullptr,
261      0},
262     {DEFINE_GPR(ds, NULL),
263      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
264       LLDB_INVALID_REGNUM, gpr_ds},
265      nullptr,
266      nullptr,
267      nullptr,
268      0},
269     {DEFINE_GPR(es, NULL),
270      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
271       LLDB_INVALID_REGNUM, gpr_es},
272      nullptr,
273      nullptr,
274      nullptr,
275      0},
276     {DEFINE_GPR(fs, NULL),
277      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
278       LLDB_INVALID_REGNUM, gpr_fs},
279      nullptr,
280      nullptr,
281      nullptr,
282      0},
283     {DEFINE_GPR(gs, NULL),
284      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
285       LLDB_INVALID_REGNUM, gpr_gs},
286      nullptr,
287      nullptr,
288      nullptr,
289      0},
290
291     {DEFINE_FPU_UINT(fcw),
292      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
293       LLDB_INVALID_REGNUM, fpu_fcw},
294      nullptr,
295      nullptr,
296      nullptr,
297      0},
298     {DEFINE_FPU_UINT(fsw),
299      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
300       LLDB_INVALID_REGNUM, fpu_fsw},
301      nullptr,
302      nullptr,
303      nullptr,
304      0},
305     {DEFINE_FPU_UINT(ftw),
306      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
307       LLDB_INVALID_REGNUM, fpu_ftw},
308      nullptr,
309      nullptr,
310      nullptr,
311      0},
312     {DEFINE_FPU_UINT(fop),
313      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
314       LLDB_INVALID_REGNUM, fpu_fop},
315      nullptr,
316      nullptr,
317      nullptr,
318      0},
319     {DEFINE_FPU_UINT(ip),
320      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
321       LLDB_INVALID_REGNUM, fpu_ip},
322      nullptr,
323      nullptr,
324      nullptr,
325      0},
326     {DEFINE_FPU_UINT(cs),
327      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
328       LLDB_INVALID_REGNUM, fpu_cs},
329      nullptr,
330      nullptr,
331      nullptr,
332      0},
333     {DEFINE_FPU_UINT(dp),
334      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
335       LLDB_INVALID_REGNUM, fpu_dp},
336      nullptr,
337      nullptr,
338      nullptr,
339      0},
340     {DEFINE_FPU_UINT(ds),
341      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
342       LLDB_INVALID_REGNUM, fpu_ds},
343      nullptr,
344      nullptr,
345      nullptr,
346      0},
347     {DEFINE_FPU_UINT(mxcsr),
348      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
349       LLDB_INVALID_REGNUM, fpu_mxcsr},
350      nullptr,
351      nullptr,
352      nullptr,
353      0},
354     {DEFINE_FPU_UINT(mxcsrmask),
355      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
356       LLDB_INVALID_REGNUM, fpu_mxcsrmask},
357      nullptr,
358      nullptr,
359      nullptr,
360      0},
361     {DEFINE_FPU_VECT(stmm, 0)},
362     {DEFINE_FPU_VECT(stmm, 1)},
363     {DEFINE_FPU_VECT(stmm, 2)},
364     {DEFINE_FPU_VECT(stmm, 3)},
365     {DEFINE_FPU_VECT(stmm, 4)},
366     {DEFINE_FPU_VECT(stmm, 5)},
367     {DEFINE_FPU_VECT(stmm, 6)},
368     {DEFINE_FPU_VECT(stmm, 7)},
369     {DEFINE_FPU_VECT(xmm, 0)},
370     {DEFINE_FPU_VECT(xmm, 1)},
371     {DEFINE_FPU_VECT(xmm, 2)},
372     {DEFINE_FPU_VECT(xmm, 3)},
373     {DEFINE_FPU_VECT(xmm, 4)},
374     {DEFINE_FPU_VECT(xmm, 5)},
375     {DEFINE_FPU_VECT(xmm, 6)},
376     {DEFINE_FPU_VECT(xmm, 7)},
377
378     {DEFINE_EXC(trapno),
379      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
380       LLDB_INVALID_REGNUM, exc_trapno},
381      nullptr,
382      nullptr,
383      nullptr,
384      0},
385     {DEFINE_EXC(err),
386      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
387       LLDB_INVALID_REGNUM, exc_err},
388      nullptr,
389      nullptr,
390      nullptr,
391      0},
392     {DEFINE_EXC(faultvaddr),
393      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
394       LLDB_INVALID_REGNUM, exc_faultvaddr},
395      nullptr,
396      nullptr,
397      nullptr,
398      0}};
399
400 static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
401
402 RegisterContextDarwin_i386::RegisterContextDarwin_i386(
403     Thread &thread, uint32_t concrete_frame_idx)
404     : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {
405   uint32_t i;
406   for (i = 0; i < kNumErrors; i++) {
407     gpr_errs[i] = -1;
408     fpu_errs[i] = -1;
409     exc_errs[i] = -1;
410   }
411 }
412
413 RegisterContextDarwin_i386::~RegisterContextDarwin_i386() {}
414
415 void RegisterContextDarwin_i386::InvalidateAllRegisters() {
416   InvalidateAllRegisterStates();
417 }
418
419 size_t RegisterContextDarwin_i386::GetRegisterCount() {
420   assert(k_num_register_infos == k_num_registers);
421   return k_num_registers;
422 }
423
424 const RegisterInfo *
425 RegisterContextDarwin_i386::GetRegisterInfoAtIndex(size_t reg) {
426   assert(k_num_register_infos == k_num_registers);
427   if (reg < k_num_registers)
428     return &g_register_infos[reg];
429   return NULL;
430 }
431
432 size_t RegisterContextDarwin_i386::GetRegisterInfosCount() {
433   return k_num_register_infos;
434 }
435
436 const RegisterInfo *RegisterContextDarwin_i386::GetRegisterInfos() {
437   return g_register_infos;
438 }
439
440 // General purpose registers
441 static uint32_t g_gpr_regnums[] = {
442     gpr_eax, gpr_ebx,    gpr_ecx, gpr_edx, gpr_edi, gpr_esi, gpr_ebp, gpr_esp,
443     gpr_ss,  gpr_eflags, gpr_eip, gpr_cs,  gpr_ds,  gpr_es,  gpr_fs,  gpr_gs};
444
445 // Floating point registers
446 static uint32_t g_fpu_regnums[] = {
447     fpu_fcw,   fpu_fsw,   fpu_ftw,   fpu_fop,       fpu_ip,    fpu_cs,
448     fpu_dp,    fpu_ds,    fpu_mxcsr, fpu_mxcsrmask, fpu_stmm0, fpu_stmm1,
449     fpu_stmm2, fpu_stmm3, fpu_stmm4, fpu_stmm5,     fpu_stmm6, fpu_stmm7,
450     fpu_xmm0,  fpu_xmm1,  fpu_xmm2,  fpu_xmm3,      fpu_xmm4,  fpu_xmm5,
451     fpu_xmm6,  fpu_xmm7};
452
453 // Exception registers
454
455 static uint32_t g_exc_regnums[] = {exc_trapno, exc_err, exc_faultvaddr};
456
457 // Number of registers in each register set
458 const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums);
459 const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums);
460 const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums);
461
462 //----------------------------------------------------------------------
463 // Register set definitions. The first definitions at register set index of
464 // zero is for all registers, followed by other registers sets. The register
465 // information for the all register set need not be filled in.
466 //----------------------------------------------------------------------
467 static const RegisterSet g_reg_sets[] = {
468     {
469         "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,
470     },
471     {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},
472     {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};
473
474 const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets);
475
476 size_t RegisterContextDarwin_i386::GetRegisterSetCount() {
477   return k_num_regsets;
478 }
479
480 const RegisterSet *RegisterContextDarwin_i386::GetRegisterSet(size_t reg_set) {
481   if (reg_set < k_num_regsets)
482     return &g_reg_sets[reg_set];
483   return NULL;
484 }
485
486 //----------------------------------------------------------------------
487 // Register information definitions for 32 bit i386.
488 //----------------------------------------------------------------------
489 int RegisterContextDarwin_i386::GetSetForNativeRegNum(int reg_num) {
490   if (reg_num < fpu_fcw)
491     return GPRRegSet;
492   else if (reg_num < exc_trapno)
493     return FPURegSet;
494   else if (reg_num < k_num_registers)
495     return EXCRegSet;
496   return -1;
497 }
498
499 void RegisterContextDarwin_i386::LogGPR(Log *log, const char *title) {
500   if (log) {
501     if (title)
502       log->Printf("%s", title);
503     for (uint32_t i = 0; i < k_num_gpr_registers; i++) {
504       uint32_t reg = gpr_eax + i;
505       log->Printf("%12s = 0x%8.8x", g_register_infos[reg].name,
506                   (&gpr.eax)[reg]);
507     }
508   }
509 }
510
511 int RegisterContextDarwin_i386::ReadGPR(bool force) {
512   int set = GPRRegSet;
513   if (force || !RegisterSetIsCached(set)) {
514     SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
515   }
516   return GetError(set, Read);
517 }
518
519 int RegisterContextDarwin_i386::ReadFPU(bool force) {
520   int set = FPURegSet;
521   if (force || !RegisterSetIsCached(set)) {
522     SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
523   }
524   return GetError(set, Read);
525 }
526
527 int RegisterContextDarwin_i386::ReadEXC(bool force) {
528   int set = EXCRegSet;
529   if (force || !RegisterSetIsCached(set)) {
530     SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
531   }
532   return GetError(set, Read);
533 }
534
535 int RegisterContextDarwin_i386::WriteGPR() {
536   int set = GPRRegSet;
537   if (!RegisterSetIsCached(set)) {
538     SetError(set, Write, -1);
539     return -1;
540   }
541   SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
542   SetError(set, Read, -1);
543   return GetError(set, Write);
544 }
545
546 int RegisterContextDarwin_i386::WriteFPU() {
547   int set = FPURegSet;
548   if (!RegisterSetIsCached(set)) {
549     SetError(set, Write, -1);
550     return -1;
551   }
552   SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
553   SetError(set, Read, -1);
554   return GetError(set, Write);
555 }
556
557 int RegisterContextDarwin_i386::WriteEXC() {
558   int set = EXCRegSet;
559   if (!RegisterSetIsCached(set)) {
560     SetError(set, Write, -1);
561     return -1;
562   }
563   SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
564   SetError(set, Read, -1);
565   return GetError(set, Write);
566 }
567
568 int RegisterContextDarwin_i386::ReadRegisterSet(uint32_t set, bool force) {
569   switch (set) {
570   case GPRRegSet:
571     return ReadGPR(force);
572   case FPURegSet:
573     return ReadFPU(force);
574   case EXCRegSet:
575     return ReadEXC(force);
576   default:
577     break;
578   }
579   return -1;
580 }
581
582 int RegisterContextDarwin_i386::WriteRegisterSet(uint32_t set) {
583   // Make sure we have a valid context to set.
584   if (RegisterSetIsCached(set)) {
585     switch (set) {
586     case GPRRegSet:
587       return WriteGPR();
588     case FPURegSet:
589       return WriteFPU();
590     case EXCRegSet:
591       return WriteEXC();
592     default:
593       break;
594     }
595   }
596   return -1;
597 }
598
599 bool RegisterContextDarwin_i386::ReadRegister(const RegisterInfo *reg_info,
600                                               RegisterValue &value) {
601   const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
602   int set = RegisterContextDarwin_i386::GetSetForNativeRegNum(reg);
603
604   if (set == -1)
605     return false;
606
607   if (ReadRegisterSet(set, false) != 0)
608     return false;
609
610   switch (reg) {
611   case gpr_eax:
612   case gpr_ebx:
613   case gpr_ecx:
614   case gpr_edx:
615   case gpr_edi:
616   case gpr_esi:
617   case gpr_ebp:
618   case gpr_esp:
619   case gpr_ss:
620   case gpr_eflags:
621   case gpr_eip:
622   case gpr_cs:
623   case gpr_ds:
624   case gpr_es:
625   case gpr_fs:
626   case gpr_gs:
627     value = (&gpr.eax)[reg - gpr_eax];
628     break;
629
630   case fpu_fcw:
631     value = fpu.fcw;
632     break;
633
634   case fpu_fsw:
635     value = fpu.fsw;
636     break;
637
638   case fpu_ftw:
639     value = fpu.ftw;
640     break;
641
642   case fpu_fop:
643     value = fpu.fop;
644     break;
645
646   case fpu_ip:
647     value = fpu.ip;
648     break;
649
650   case fpu_cs:
651     value = fpu.cs;
652     break;
653
654   case fpu_dp:
655     value = fpu.dp;
656     break;
657
658   case fpu_ds:
659     value = fpu.ds;
660     break;
661
662   case fpu_mxcsr:
663     value = fpu.mxcsr;
664     break;
665
666   case fpu_mxcsrmask:
667     value = fpu.mxcsrmask;
668     break;
669
670   case fpu_stmm0:
671   case fpu_stmm1:
672   case fpu_stmm2:
673   case fpu_stmm3:
674   case fpu_stmm4:
675   case fpu_stmm5:
676   case fpu_stmm6:
677   case fpu_stmm7:
678     // These values don't fit into scalar types,
679     // RegisterContext::ReadRegisterBytes() must be used for these registers
680     //::memcpy (reg_value.value.vector.uint8, fpu.stmm[reg - fpu_stmm0].bytes,
681     //10);
682     return false;
683
684   case fpu_xmm0:
685   case fpu_xmm1:
686   case fpu_xmm2:
687   case fpu_xmm3:
688   case fpu_xmm4:
689   case fpu_xmm5:
690   case fpu_xmm6:
691   case fpu_xmm7:
692     // These values don't fit into scalar types,
693     // RegisterContext::ReadRegisterBytes() must be used for these registers
694     //::memcpy (reg_value.value.vector.uint8, fpu.xmm[reg - fpu_xmm0].bytes,
695     //16);
696     return false;
697
698   case exc_trapno:
699     value = exc.trapno;
700     break;
701
702   case exc_err:
703     value = exc.err;
704     break;
705
706   case exc_faultvaddr:
707     value = exc.faultvaddr;
708     break;
709
710   default:
711     return false;
712   }
713   return true;
714 }
715
716 bool RegisterContextDarwin_i386::WriteRegister(const RegisterInfo *reg_info,
717                                                const RegisterValue &value) {
718   const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
719   int set = GetSetForNativeRegNum(reg);
720
721   if (set == -1)
722     return false;
723
724   if (ReadRegisterSet(set, false) != 0)
725     return false;
726
727   switch (reg) {
728   case gpr_eax:
729   case gpr_ebx:
730   case gpr_ecx:
731   case gpr_edx:
732   case gpr_edi:
733   case gpr_esi:
734   case gpr_ebp:
735   case gpr_esp:
736   case gpr_ss:
737   case gpr_eflags:
738   case gpr_eip:
739   case gpr_cs:
740   case gpr_ds:
741   case gpr_es:
742   case gpr_fs:
743   case gpr_gs:
744     (&gpr.eax)[reg - gpr_eax] = value.GetAsUInt32();
745     break;
746
747   case fpu_fcw:
748     fpu.fcw = value.GetAsUInt16();
749     break;
750
751   case fpu_fsw:
752     fpu.fsw = value.GetAsUInt16();
753     break;
754
755   case fpu_ftw:
756     fpu.ftw = value.GetAsUInt8();
757     break;
758
759   case fpu_fop:
760     fpu.fop = value.GetAsUInt16();
761     break;
762
763   case fpu_ip:
764     fpu.ip = value.GetAsUInt32();
765     break;
766
767   case fpu_cs:
768     fpu.cs = value.GetAsUInt16();
769     break;
770
771   case fpu_dp:
772     fpu.dp = value.GetAsUInt32();
773     break;
774
775   case fpu_ds:
776     fpu.ds = value.GetAsUInt16();
777     break;
778
779   case fpu_mxcsr:
780     fpu.mxcsr = value.GetAsUInt32();
781     break;
782
783   case fpu_mxcsrmask:
784     fpu.mxcsrmask = value.GetAsUInt32();
785     break;
786
787   case fpu_stmm0:
788   case fpu_stmm1:
789   case fpu_stmm2:
790   case fpu_stmm3:
791   case fpu_stmm4:
792   case fpu_stmm5:
793   case fpu_stmm6:
794   case fpu_stmm7:
795     // These values don't fit into scalar types,
796     // RegisterContext::ReadRegisterBytes() must be used for these registers
797     ::memcpy(fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(),
798              value.GetByteSize());
799     return false;
800
801   case fpu_xmm0:
802   case fpu_xmm1:
803   case fpu_xmm2:
804   case fpu_xmm3:
805   case fpu_xmm4:
806   case fpu_xmm5:
807   case fpu_xmm6:
808   case fpu_xmm7:
809     // These values don't fit into scalar types,
810     // RegisterContext::ReadRegisterBytes() must be used for these registers
811     ::memcpy(fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(),
812              value.GetByteSize());
813     return false;
814
815   case exc_trapno:
816     exc.trapno = value.GetAsUInt32();
817     break;
818
819   case exc_err:
820     exc.err = value.GetAsUInt32();
821     break;
822
823   case exc_faultvaddr:
824     exc.faultvaddr = value.GetAsUInt32();
825     break;
826
827   default:
828     return false;
829   }
830   return WriteRegisterSet(set) == 0;
831 }
832
833 bool RegisterContextDarwin_i386::ReadAllRegisterValues(
834     lldb::DataBufferSP &data_sp) {
835   data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
836   if (data_sp && ReadGPR(false) == 0 && ReadFPU(false) == 0 &&
837       ReadEXC(false) == 0) {
838     uint8_t *dst = data_sp->GetBytes();
839     ::memcpy(dst, &gpr, sizeof(gpr));
840     dst += sizeof(gpr);
841
842     ::memcpy(dst, &fpu, sizeof(fpu));
843     dst += sizeof(gpr);
844
845     ::memcpy(dst, &exc, sizeof(exc));
846     return true;
847   }
848   return false;
849 }
850
851 bool RegisterContextDarwin_i386::WriteAllRegisterValues(
852     const lldb::DataBufferSP &data_sp) {
853   if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
854     const uint8_t *src = data_sp->GetBytes();
855     ::memcpy(&gpr, src, sizeof(gpr));
856     src += sizeof(gpr);
857
858     ::memcpy(&fpu, src, sizeof(fpu));
859     src += sizeof(gpr);
860
861     ::memcpy(&exc, src, sizeof(exc));
862     uint32_t success_count = 0;
863     if (WriteGPR() == 0)
864       ++success_count;
865     if (WriteFPU() == 0)
866       ++success_count;
867     if (WriteEXC() == 0)
868       ++success_count;
869     return success_count == 3;
870   }
871   return false;
872 }
873
874 uint32_t RegisterContextDarwin_i386::ConvertRegisterKindToRegisterNumber(
875     lldb::RegisterKind kind, uint32_t reg) {
876   if (kind == eRegisterKindGeneric) {
877     switch (reg) {
878     case LLDB_REGNUM_GENERIC_PC:
879       return gpr_eip;
880     case LLDB_REGNUM_GENERIC_SP:
881       return gpr_esp;
882     case LLDB_REGNUM_GENERIC_FP:
883       return gpr_ebp;
884     case LLDB_REGNUM_GENERIC_FLAGS:
885       return gpr_eflags;
886     case LLDB_REGNUM_GENERIC_RA:
887     default:
888       break;
889     }
890   } else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF) {
891     switch (reg) {
892     case dwarf_eax:
893       return gpr_eax;
894     case dwarf_ecx:
895       return gpr_ecx;
896     case dwarf_edx:
897       return gpr_edx;
898     case dwarf_ebx:
899       return gpr_ebx;
900     case dwarf_esp:
901       return gpr_esp;
902     case dwarf_ebp:
903       return gpr_ebp;
904     case dwarf_esi:
905       return gpr_esi;
906     case dwarf_edi:
907       return gpr_edi;
908     case dwarf_eip:
909       return gpr_eip;
910     case dwarf_eflags:
911       return gpr_eflags;
912     case dwarf_stmm0:
913       return fpu_stmm0;
914     case dwarf_stmm1:
915       return fpu_stmm1;
916     case dwarf_stmm2:
917       return fpu_stmm2;
918     case dwarf_stmm3:
919       return fpu_stmm3;
920     case dwarf_stmm4:
921       return fpu_stmm4;
922     case dwarf_stmm5:
923       return fpu_stmm5;
924     case dwarf_stmm6:
925       return fpu_stmm6;
926     case dwarf_stmm7:
927       return fpu_stmm7;
928     case dwarf_xmm0:
929       return fpu_xmm0;
930     case dwarf_xmm1:
931       return fpu_xmm1;
932     case dwarf_xmm2:
933       return fpu_xmm2;
934     case dwarf_xmm3:
935       return fpu_xmm3;
936     case dwarf_xmm4:
937       return fpu_xmm4;
938     case dwarf_xmm5:
939       return fpu_xmm5;
940     case dwarf_xmm6:
941       return fpu_xmm6;
942     case dwarf_xmm7:
943       return fpu_xmm7;
944     default:
945       break;
946     }
947   } else if (kind == eRegisterKindLLDB) {
948     return reg;
949   }
950   return LLDB_INVALID_REGNUM;
951 }
952
953 bool RegisterContextDarwin_i386::HardwareSingleStep(bool enable) {
954   if (ReadGPR(false) != 0)
955     return false;
956
957   const uint32_t trace_bit = 0x100u;
958   if (enable) {
959     // If the trace bit is already set, there is nothing to do
960     if (gpr.eflags & trace_bit)
961       return true;
962     else
963       gpr.eflags |= trace_bit;
964   } else {
965     // If the trace bit is already cleared, there is nothing to do
966     if (gpr.eflags & trace_bit)
967       gpr.eflags &= ~trace_bit;
968     else
969       return true;
970   }
971
972   return WriteGPR() == 0;
973 }