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