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