]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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
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
33 using namespace lldb;
34 using namespace lldb_private;
35
36 enum
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
98 enum
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
112 enum
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
142 enum
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
195 RegisterContextDarwin_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
210 RegisterContextDarwin_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
231 static 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
284 static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo));
285
286 void
287 RegisterContextDarwin_i386::InvalidateAllRegisters ()
288 {
289     InvalidateAllRegisterStates();
290 }
291
292
293 size_t
294 RegisterContextDarwin_i386::GetRegisterCount ()
295 {
296     assert(k_num_register_infos == k_num_registers);
297     return k_num_registers;
298 }
299
300 const RegisterInfo *
301 RegisterContextDarwin_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
309 size_t
310 RegisterContextDarwin_i386::GetRegisterInfosCount ()
311 {
312     return k_num_register_infos;
313 }
314
315 const RegisterInfo *
316 RegisterContextDarwin_i386::GetRegisterInfos ()
317 {
318     return g_register_infos;
319 }
320
321
322 // General purpose registers
323 static uint32_t
324 g_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
345 static uint32_t
346 g_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
378 static uint32_t
379 g_exc_regnums[] =
380 {
381     exc_trapno,
382     exc_err,
383     exc_faultvaddr
384 };
385
386 // Number of registers in each register set
387 const size_t k_num_gpr_registers = sizeof(g_gpr_regnums) / sizeof(uint32_t);
388 const size_t k_num_fpu_registers = sizeof(g_fpu_regnums) / sizeof(uint32_t);
389 const 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 //----------------------------------------------------------------------
396 static 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
403 const size_t k_num_regsets = sizeof(g_reg_sets) / sizeof(RegisterSet);
404
405
406 size_t
407 RegisterContextDarwin_i386::GetRegisterSetCount ()
408 {
409     return k_num_regsets;
410 }
411
412 const RegisterSet *
413 RegisterContextDarwin_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 //----------------------------------------------------------------------
424 int
425 RegisterContextDarwin_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
437 void
438 RegisterContextDarwin_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
454 int
455 RegisterContextDarwin_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
465 int
466 RegisterContextDarwin_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
476 int
477 RegisterContextDarwin_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
487 int
488 RegisterContextDarwin_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
501 int
502 RegisterContextDarwin_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
515 int
516 RegisterContextDarwin_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
529 int
530 RegisterContextDarwin_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
542 int
543 RegisterContextDarwin_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
559 bool
560 RegisterContextDarwin_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
679 bool
680 RegisterContextDarwin_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
797 bool
798 RegisterContextDarwin_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
819 bool
820 RegisterContextDarwin_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
845 uint32_t
846 RegisterContextDarwin_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
952 bool
953 RegisterContextDarwin_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