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