Home | History | Annotate | Download | only in Utility
      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 
    981