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