Home | History | Annotate | Download | only in Utility
      1 //===-- RegisterContextDarwin_x86_64.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 <stdarg.h>
     13 #include <stddef.h>  // offsetof
     14 
     15 // C++ Includes
     16 // Other libraries and framework includes
     17 #include "lldb/Core/DataBufferHeap.h"
     18 #include "lldb/Core/DataExtractor.h"
     19 #include "lldb/Core/Log.h"
     20 #include "lldb/Core/RegisterValue.h"
     21 #include "lldb/Core/Scalar.h"
     22 #include "lldb/Host/Endian.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_x86_64.h"
     33 
     34 using namespace lldb;
     35 using namespace lldb_private;
     36 
     37 enum
     38 {
     39     gpr_rax = 0,
     40     gpr_rbx,
     41     gpr_rcx,
     42     gpr_rdx,
     43     gpr_rdi,
     44     gpr_rsi,
     45     gpr_rbp,
     46     gpr_rsp,
     47     gpr_r8,
     48     gpr_r9,
     49     gpr_r10,
     50     gpr_r11,
     51     gpr_r12,
     52     gpr_r13,
     53     gpr_r14,
     54     gpr_r15,
     55     gpr_rip,
     56     gpr_rflags,
     57     gpr_cs,
     58     gpr_fs,
     59     gpr_gs,
     60 
     61     fpu_fcw,
     62     fpu_fsw,
     63     fpu_ftw,
     64     fpu_fop,
     65     fpu_ip,
     66     fpu_cs,
     67     fpu_dp,
     68     fpu_ds,
     69     fpu_mxcsr,
     70     fpu_mxcsrmask,
     71     fpu_stmm0,
     72     fpu_stmm1,
     73     fpu_stmm2,
     74     fpu_stmm3,
     75     fpu_stmm4,
     76     fpu_stmm5,
     77     fpu_stmm6,
     78     fpu_stmm7,
     79     fpu_xmm0,
     80     fpu_xmm1,
     81     fpu_xmm2,
     82     fpu_xmm3,
     83     fpu_xmm4,
     84     fpu_xmm5,
     85     fpu_xmm6,
     86     fpu_xmm7,
     87     fpu_xmm8,
     88     fpu_xmm9,
     89     fpu_xmm10,
     90     fpu_xmm11,
     91     fpu_xmm12,
     92     fpu_xmm13,
     93     fpu_xmm14,
     94     fpu_xmm15,
     95 
     96     exc_trapno,
     97     exc_err,
     98     exc_faultvaddr,
     99 
    100     k_num_registers,
    101 
    102     // Aliases
    103     fpu_fctrl = fpu_fcw,
    104     fpu_fstat = fpu_fsw,
    105     fpu_ftag  = fpu_ftw,
    106     fpu_fiseg = fpu_cs,
    107     fpu_fioff = fpu_ip,
    108     fpu_foseg = fpu_ds,
    109     fpu_fooff = fpu_dp
    110 };
    111 
    112 enum gcc_dwarf_regnums
    113 {
    114     gcc_dwarf_gpr_rax = 0,
    115     gcc_dwarf_gpr_rdx,
    116     gcc_dwarf_gpr_rcx,
    117     gcc_dwarf_gpr_rbx,
    118     gcc_dwarf_gpr_rsi,
    119     gcc_dwarf_gpr_rdi,
    120     gcc_dwarf_gpr_rbp,
    121     gcc_dwarf_gpr_rsp,
    122     gcc_dwarf_gpr_r8,
    123     gcc_dwarf_gpr_r9,
    124     gcc_dwarf_gpr_r10,
    125     gcc_dwarf_gpr_r11,
    126     gcc_dwarf_gpr_r12,
    127     gcc_dwarf_gpr_r13,
    128     gcc_dwarf_gpr_r14,
    129     gcc_dwarf_gpr_r15,
    130     gcc_dwarf_gpr_rip,
    131     gcc_dwarf_fpu_xmm0,
    132     gcc_dwarf_fpu_xmm1,
    133     gcc_dwarf_fpu_xmm2,
    134     gcc_dwarf_fpu_xmm3,
    135     gcc_dwarf_fpu_xmm4,
    136     gcc_dwarf_fpu_xmm5,
    137     gcc_dwarf_fpu_xmm6,
    138     gcc_dwarf_fpu_xmm7,
    139     gcc_dwarf_fpu_xmm8,
    140     gcc_dwarf_fpu_xmm9,
    141     gcc_dwarf_fpu_xmm10,
    142     gcc_dwarf_fpu_xmm11,
    143     gcc_dwarf_fpu_xmm12,
    144     gcc_dwarf_fpu_xmm13,
    145     gcc_dwarf_fpu_xmm14,
    146     gcc_dwarf_fpu_xmm15,
    147     gcc_dwarf_fpu_stmm0,
    148     gcc_dwarf_fpu_stmm1,
    149     gcc_dwarf_fpu_stmm2,
    150     gcc_dwarf_fpu_stmm3,
    151     gcc_dwarf_fpu_stmm4,
    152     gcc_dwarf_fpu_stmm5,
    153     gcc_dwarf_fpu_stmm6,
    154     gcc_dwarf_fpu_stmm7
    155 
    156 };
    157 
    158 enum gdb_regnums
    159 {
    160     gdb_gpr_rax     =   0,
    161     gdb_gpr_rbx     =   1,
    162     gdb_gpr_rcx     =   2,
    163     gdb_gpr_rdx     =   3,
    164     gdb_gpr_rsi     =   4,
    165     gdb_gpr_rdi     =   5,
    166     gdb_gpr_rbp     =   6,
    167     gdb_gpr_rsp     =   7,
    168     gdb_gpr_r8      =   8,
    169     gdb_gpr_r9      =   9,
    170     gdb_gpr_r10     =  10,
    171     gdb_gpr_r11     =  11,
    172     gdb_gpr_r12     =  12,
    173     gdb_gpr_r13     =  13,
    174     gdb_gpr_r14     =  14,
    175     gdb_gpr_r15     =  15,
    176     gdb_gpr_rip     =  16,
    177     gdb_gpr_rflags  =  17,
    178     gdb_gpr_cs      =  18,
    179     gdb_gpr_ss      =  19,
    180     gdb_gpr_ds      =  20,
    181     gdb_gpr_es      =  21,
    182     gdb_gpr_fs      =  22,
    183     gdb_gpr_gs      =  23,
    184     gdb_fpu_stmm0   =  24,
    185     gdb_fpu_stmm1   =  25,
    186     gdb_fpu_stmm2   =  26,
    187     gdb_fpu_stmm3   =  27,
    188     gdb_fpu_stmm4   =  28,
    189     gdb_fpu_stmm5   =  29,
    190     gdb_fpu_stmm6   =  30,
    191     gdb_fpu_stmm7   =  31,
    192     gdb_fpu_fctrl   =  32,  gdb_fpu_fcw = gdb_fpu_fctrl,
    193     gdb_fpu_fstat   =  33,  gdb_fpu_fsw = gdb_fpu_fstat,
    194     gdb_fpu_ftag    =  34,  gdb_fpu_ftw = gdb_fpu_ftag,
    195     gdb_fpu_fiseg   =  35,  gdb_fpu_cs  = gdb_fpu_fiseg,
    196     gdb_fpu_fioff   =  36,  gdb_fpu_ip  = gdb_fpu_fioff,
    197     gdb_fpu_foseg   =  37,  gdb_fpu_ds  = gdb_fpu_foseg,
    198     gdb_fpu_fooff   =  38,  gdb_fpu_dp  = gdb_fpu_fooff,
    199     gdb_fpu_fop     =  39,
    200     gdb_fpu_xmm0    =  40,
    201     gdb_fpu_xmm1    =  41,
    202     gdb_fpu_xmm2    =  42,
    203     gdb_fpu_xmm3    =  43,
    204     gdb_fpu_xmm4    =  44,
    205     gdb_fpu_xmm5    =  45,
    206     gdb_fpu_xmm6    =  46,
    207     gdb_fpu_xmm7    =  47,
    208     gdb_fpu_xmm8    =  48,
    209     gdb_fpu_xmm9    =  49,
    210     gdb_fpu_xmm10   =  50,
    211     gdb_fpu_xmm11   =  51,
    212     gdb_fpu_xmm12   =  52,
    213     gdb_fpu_xmm13   =  53,
    214     gdb_fpu_xmm14   =  54,
    215     gdb_fpu_xmm15   =  55,
    216     gdb_fpu_mxcsr   =  56
    217 };
    218 
    219 RegisterContextDarwin_x86_64::RegisterContextDarwin_x86_64 (Thread &thread, uint32_t concrete_frame_idx) :
    220     RegisterContext (thread, concrete_frame_idx),
    221     gpr(),
    222     fpu(),
    223     exc()
    224 {
    225     uint32_t i;
    226     for (i=0; i<kNumErrors; i++)
    227     {
    228         gpr_errs[i] = -1;
    229         fpu_errs[i] = -1;
    230         exc_errs[i] = -1;
    231     }
    232 }
    233 
    234 RegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64()
    235 {
    236 }
    237 
    238 #define GPR_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_x86_64::GPR, reg))
    239 #define FPU_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_x86_64::FPU, reg) + sizeof (RegisterContextDarwin_x86_64::GPR))
    240 #define EXC_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_x86_64::EXC, reg) + sizeof (RegisterContextDarwin_x86_64::GPR) + sizeof (RegisterContextDarwin_x86_64::FPU))
    241 
    242 // These macros will auto define the register name, alt name, register size,
    243 // register offset, encoding, format and native register. This ensures that
    244 // the register state structures are defined correctly and have the correct
    245 // sizes and offsets.
    246 #define DEFINE_GPR(reg, alt)    #reg, alt, sizeof(((RegisterContextDarwin_x86_64::GPR *)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, eFormatHex
    247 #define DEFINE_FPU_UINT(reg)    #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::FPU *)NULL)->reg), FPU_OFFSET(reg), eEncodingUint, eFormatHex
    248 #define DEFINE_FPU_VECT(reg, i) #reg#i, NULL, sizeof(((RegisterContextDarwin_x86_64::FPU *)NULL)->reg[i].bytes), FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_fpu_##reg##i, gcc_dwarf_fpu_##reg##i, LLDB_INVALID_REGNUM, gdb_fpu_##reg##i, fpu_##reg##i }, NULL, NULL
    249 #define DEFINE_EXC(reg)         #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::EXC *)NULL)->reg), EXC_OFFSET(reg), eEncodingUint, eFormatHex
    250 
    251 #define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_x86_64::GPR) + sizeof (RegisterContextDarwin_x86_64::FPU) + sizeof (RegisterContextDarwin_x86_64::EXC))
    252 
    253 // General purpose registers for 64 bit
    254 static RegisterInfo g_register_infos[] =
    255 {
    256 //  Macro auto defines most stuff   GCC                    DWARF                GENERIC                    GDB                  LLDB                VALUE REGS    INVALIDATE REGS
    257 //  =============================== ====================== ===================  ========================== ==================== =================== ==========    ===============
    258     { DEFINE_GPR (rax   , NULL)     , { gcc_dwarf_gpr_rax  , gcc_dwarf_gpr_rax  , LLDB_INVALID_REGNUM      , gdb_gpr_rax        , gpr_rax       },       NULL,              NULL},
    259     { DEFINE_GPR (rbx   , NULL)     , { gcc_dwarf_gpr_rbx  , gcc_dwarf_gpr_rbx  , LLDB_INVALID_REGNUM      , gdb_gpr_rbx        , gpr_rbx       },       NULL,              NULL},
    260     { DEFINE_GPR (rcx   , NULL)     , { gcc_dwarf_gpr_rcx  , gcc_dwarf_gpr_rcx  , LLDB_INVALID_REGNUM      , gdb_gpr_rcx        , gpr_rcx       },       NULL,              NULL},
    261     { DEFINE_GPR (rdx   , NULL)     , { gcc_dwarf_gpr_rdx  , gcc_dwarf_gpr_rdx  , LLDB_INVALID_REGNUM      , gdb_gpr_rdx        , gpr_rdx       },       NULL,              NULL},
    262     { DEFINE_GPR (rdi   , NULL)     , { gcc_dwarf_gpr_rdi  , gcc_dwarf_gpr_rdi  , LLDB_INVALID_REGNUM      , gdb_gpr_rdi        , gpr_rdi       },       NULL,              NULL},
    263     { DEFINE_GPR (rsi   , NULL)     , { gcc_dwarf_gpr_rsi  , gcc_dwarf_gpr_rsi  , LLDB_INVALID_REGNUM      , gdb_gpr_rsi        , gpr_rsi       },       NULL,              NULL},
    264     { DEFINE_GPR (rbp   , "fp")     , { gcc_dwarf_gpr_rbp  , gcc_dwarf_gpr_rbp  , LLDB_REGNUM_GENERIC_FP   , gdb_gpr_rbp        , gpr_rbp       },       NULL,              NULL},
    265     { DEFINE_GPR (rsp   , "sp")     , { gcc_dwarf_gpr_rsp  , gcc_dwarf_gpr_rsp  , LLDB_REGNUM_GENERIC_SP   , gdb_gpr_rsp        , gpr_rsp       },       NULL,              NULL},
    266     { DEFINE_GPR (r8    , NULL)     , { gcc_dwarf_gpr_r8   , gcc_dwarf_gpr_r8   , LLDB_INVALID_REGNUM      , gdb_gpr_r8         , gpr_r8        },       NULL,              NULL},
    267     { DEFINE_GPR (r9    , NULL)     , { gcc_dwarf_gpr_r9   , gcc_dwarf_gpr_r9   , LLDB_INVALID_REGNUM      , gdb_gpr_r9         , gpr_r9        },       NULL,              NULL},
    268     { DEFINE_GPR (r10   , NULL)     , { gcc_dwarf_gpr_r10  , gcc_dwarf_gpr_r10  , LLDB_INVALID_REGNUM      , gdb_gpr_r10        , gpr_r10       },       NULL,              NULL},
    269     { DEFINE_GPR (r11   , NULL)     , { gcc_dwarf_gpr_r11  , gcc_dwarf_gpr_r11  , LLDB_INVALID_REGNUM      , gdb_gpr_r11        , gpr_r11       },       NULL,              NULL},
    270     { DEFINE_GPR (r12   , NULL)     , { gcc_dwarf_gpr_r12  , gcc_dwarf_gpr_r12  , LLDB_INVALID_REGNUM      , gdb_gpr_r12        , gpr_r12       },       NULL,              NULL},
    271     { DEFINE_GPR (r13   , NULL)     , { gcc_dwarf_gpr_r13  , gcc_dwarf_gpr_r13  , LLDB_INVALID_REGNUM      , gdb_gpr_r13        , gpr_r13       },       NULL,              NULL},
    272     { DEFINE_GPR (r14   , NULL)     , { gcc_dwarf_gpr_r14  , gcc_dwarf_gpr_r14  , LLDB_INVALID_REGNUM      , gdb_gpr_r14        , gpr_r14       },       NULL,              NULL},
    273     { DEFINE_GPR (r15   , NULL)     , { gcc_dwarf_gpr_r15  , gcc_dwarf_gpr_r15  , LLDB_INVALID_REGNUM      , gdb_gpr_r15        , gpr_r15       },       NULL,              NULL},
    274     { DEFINE_GPR (rip   , "pc")     , { gcc_dwarf_gpr_rip  , gcc_dwarf_gpr_rip  , LLDB_REGNUM_GENERIC_PC   , gdb_gpr_rip        , gpr_rip       },       NULL,              NULL},
    275     { DEFINE_GPR (rflags, "flags")  , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, gdb_gpr_rflags     , gpr_rflags    },       NULL,              NULL},
    276     { DEFINE_GPR (cs    , NULL)     , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_gpr_cs         , gpr_cs        },       NULL,              NULL},
    277     { DEFINE_GPR (fs    , NULL)     , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_gpr_fs         , gpr_fs        },       NULL,              NULL},
    278     { DEFINE_GPR (gs    , NULL)     , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_gpr_gs         , gpr_gs        },       NULL,              NULL},
    279 
    280     { DEFINE_FPU_UINT(fcw)          , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_fpu_fcw        , fpu_fcw       },       NULL,              NULL},
    281     { DEFINE_FPU_UINT(fsw)          , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_fpu_fsw        , fpu_fsw       },       NULL,              NULL},
    282     { DEFINE_FPU_UINT(ftw)          , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_fpu_ftw        , fpu_ftw       },       NULL,              NULL},
    283     { DEFINE_FPU_UINT(fop)          , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_fpu_fop        , fpu_fop       },       NULL,              NULL},
    284     { DEFINE_FPU_UINT(ip)           , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_fpu_ip         , fpu_ip        },       NULL,              NULL},
    285     { DEFINE_FPU_UINT(cs)           , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_fpu_cs         , fpu_cs        },       NULL,              NULL},
    286     { DEFINE_FPU_UINT(dp)           , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_fpu_dp         , fpu_dp        },       NULL,              NULL},
    287     { DEFINE_FPU_UINT(ds)           , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_fpu_ds         , fpu_ds        },       NULL,              NULL},
    288     { DEFINE_FPU_UINT(mxcsr)        , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_fpu_mxcsr      , fpu_mxcsr     },       NULL,              NULL},
    289     { DEFINE_FPU_UINT(mxcsrmask)    , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM, fpu_mxcsrmask },       NULL,              NULL},
    290     { DEFINE_FPU_VECT(stmm,0)   },
    291     { DEFINE_FPU_VECT(stmm,1)   },
    292     { DEFINE_FPU_VECT(stmm,2)   },
    293     { DEFINE_FPU_VECT(stmm,3)   },
    294     { DEFINE_FPU_VECT(stmm,4)   },
    295     { DEFINE_FPU_VECT(stmm,5)   },
    296     { DEFINE_FPU_VECT(stmm,6)   },
    297     { DEFINE_FPU_VECT(stmm,7)   },
    298     { DEFINE_FPU_VECT(xmm,0)    },
    299     { DEFINE_FPU_VECT(xmm,1)    },
    300     { DEFINE_FPU_VECT(xmm,2)    },
    301     { DEFINE_FPU_VECT(xmm,3)    },
    302     { DEFINE_FPU_VECT(xmm,4)    },
    303     { DEFINE_FPU_VECT(xmm,5)    },
    304     { DEFINE_FPU_VECT(xmm,6)    },
    305     { DEFINE_FPU_VECT(xmm,7)    },
    306     { DEFINE_FPU_VECT(xmm,8)    },
    307     { DEFINE_FPU_VECT(xmm,9)    },
    308     { DEFINE_FPU_VECT(xmm,10)   },
    309     { DEFINE_FPU_VECT(xmm,11)   },
    310     { DEFINE_FPU_VECT(xmm,12)   },
    311     { DEFINE_FPU_VECT(xmm,13)   },
    312     { DEFINE_FPU_VECT(xmm,14)   },
    313     { DEFINE_FPU_VECT(xmm,15)   },
    314 
    315     { DEFINE_EXC(trapno)            , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM, exc_trapno     },      NULL,              NULL},
    316     { DEFINE_EXC(err)               , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM, exc_err        },      NULL,              NULL},
    317     { DEFINE_EXC(faultvaddr)        , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM, exc_faultvaddr },      NULL,              NULL}
    318 };
    319 
    320 static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo));
    321 
    322 
    323 void
    324 RegisterContextDarwin_x86_64::InvalidateAllRegisters ()
    325 {
    326     InvalidateAllRegisterStates();
    327 }
    328 
    329 
    330 size_t
    331 RegisterContextDarwin_x86_64::GetRegisterCount ()
    332 {
    333     assert(k_num_register_infos == k_num_registers);
    334     return k_num_registers;
    335 }
    336 
    337 
    338 const RegisterInfo *
    339 RegisterContextDarwin_x86_64::GetRegisterInfoAtIndex (size_t reg)
    340 {
    341     assert(k_num_register_infos == k_num_registers);
    342     if (reg < k_num_registers)
    343         return &g_register_infos[reg];
    344     return NULL;
    345 }
    346 
    347 
    348 size_t
    349 RegisterContextDarwin_x86_64::GetRegisterInfosCount ()
    350 {
    351     return k_num_register_infos;
    352 }
    353 
    354 const lldb_private::RegisterInfo *
    355 RegisterContextDarwin_x86_64::GetRegisterInfos ()
    356 {
    357     return g_register_infos;
    358 }
    359 
    360 
    361 
    362 static uint32_t g_gpr_regnums[] =
    363 {
    364     gpr_rax,
    365     gpr_rbx,
    366     gpr_rcx,
    367     gpr_rdx,
    368     gpr_rdi,
    369     gpr_rsi,
    370     gpr_rbp,
    371     gpr_rsp,
    372     gpr_r8,
    373     gpr_r9,
    374     gpr_r10,
    375     gpr_r11,
    376     gpr_r12,
    377     gpr_r13,
    378     gpr_r14,
    379     gpr_r15,
    380     gpr_rip,
    381     gpr_rflags,
    382     gpr_cs,
    383     gpr_fs,
    384     gpr_gs
    385 };
    386 
    387 static uint32_t g_fpu_regnums[] =
    388 {
    389     fpu_fcw,
    390     fpu_fsw,
    391     fpu_ftw,
    392     fpu_fop,
    393     fpu_ip,
    394     fpu_cs,
    395     fpu_dp,
    396     fpu_ds,
    397     fpu_mxcsr,
    398     fpu_mxcsrmask,
    399     fpu_stmm0,
    400     fpu_stmm1,
    401     fpu_stmm2,
    402     fpu_stmm3,
    403     fpu_stmm4,
    404     fpu_stmm5,
    405     fpu_stmm6,
    406     fpu_stmm7,
    407     fpu_xmm0,
    408     fpu_xmm1,
    409     fpu_xmm2,
    410     fpu_xmm3,
    411     fpu_xmm4,
    412     fpu_xmm5,
    413     fpu_xmm6,
    414     fpu_xmm7,
    415     fpu_xmm8,
    416     fpu_xmm9,
    417     fpu_xmm10,
    418     fpu_xmm11,
    419     fpu_xmm12,
    420     fpu_xmm13,
    421     fpu_xmm14,
    422     fpu_xmm15
    423 };
    424 
    425 static uint32_t
    426 g_exc_regnums[] =
    427 {
    428     exc_trapno,
    429     exc_err,
    430     exc_faultvaddr
    431 };
    432 
    433 // Number of registers in each register set
    434 const size_t k_num_gpr_registers = sizeof(g_gpr_regnums) / sizeof(uint32_t);
    435 const size_t k_num_fpu_registers = sizeof(g_fpu_regnums) / sizeof(uint32_t);
    436 const size_t k_num_exc_registers = sizeof(g_exc_regnums) / sizeof(uint32_t);
    437 
    438 //----------------------------------------------------------------------
    439 // Register set definitions. The first definitions at register set index
    440 // of zero is for all registers, followed by other registers sets. The
    441 // register information for the all register set need not be filled in.
    442 //----------------------------------------------------------------------
    443 static const RegisterSet g_reg_sets[] =
    444 {
    445     { "General Purpose Registers",  "gpr",  k_num_gpr_registers,    g_gpr_regnums,      },
    446     { "Floating Point Registers",   "fpu",  k_num_fpu_registers,    g_fpu_regnums       },
    447     { "Exception State Registers",  "exc",  k_num_exc_registers,    g_exc_regnums       }
    448 };
    449 
    450 const size_t k_num_regsets = sizeof(g_reg_sets) / sizeof(RegisterSet);
    451 
    452 
    453 size_t
    454 RegisterContextDarwin_x86_64::GetRegisterSetCount ()
    455 {
    456     return k_num_regsets;
    457 }
    458 
    459 const RegisterSet *
    460 RegisterContextDarwin_x86_64::GetRegisterSet (size_t reg_set)
    461 {
    462     if (reg_set < k_num_regsets)
    463         return &g_reg_sets[reg_set];
    464     return NULL;
    465 }
    466 
    467 int
    468 RegisterContextDarwin_x86_64::GetSetForNativeRegNum (int reg_num)
    469 {
    470     if (reg_num < fpu_fcw)
    471         return GPRRegSet;
    472     else if (reg_num < exc_trapno)
    473         return FPURegSet;
    474     else if (reg_num < k_num_registers)
    475         return EXCRegSet;
    476     return -1;
    477 }
    478 
    479 void
    480 RegisterContextDarwin_x86_64::LogGPR(Log *log, const char *format, ...)
    481 {
    482     if (log)
    483     {
    484         if (format)
    485         {
    486             va_list args;
    487             va_start (args, format);
    488             log->VAPrintf (format, args);
    489             va_end (args);
    490         }
    491         for (uint32_t i=0; i<k_num_gpr_registers; i++)
    492         {
    493             uint32_t reg = gpr_rax + i;
    494             log->Printf("%12s = 0x%16.16" PRIx64, g_register_infos[reg].name, (&gpr.rax)[reg]);
    495         }
    496     }
    497 }
    498 
    499 int
    500 RegisterContextDarwin_x86_64::ReadGPR (bool force)
    501 {
    502     int set = GPRRegSet;
    503     if (force || !RegisterSetIsCached(set))
    504     {
    505         SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
    506     }
    507     return GetError(GPRRegSet, Read);
    508 }
    509 
    510 int
    511 RegisterContextDarwin_x86_64::ReadFPU (bool force)
    512 {
    513     int set = FPURegSet;
    514     if (force || !RegisterSetIsCached(set))
    515     {
    516         SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
    517     }
    518     return GetError(FPURegSet, Read);
    519 }
    520 
    521 int
    522 RegisterContextDarwin_x86_64::ReadEXC (bool force)
    523 {
    524     int set = EXCRegSet;
    525     if (force || !RegisterSetIsCached(set))
    526     {
    527         SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
    528     }
    529     return GetError(EXCRegSet, Read);
    530 }
    531 
    532 int
    533 RegisterContextDarwin_x86_64::WriteGPR ()
    534 {
    535     int set = GPRRegSet;
    536     if (!RegisterSetIsCached(set))
    537     {
    538         SetError (set, Write, -1);
    539         return -1;
    540     }
    541     SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr));
    542     SetError (set, Read, -1);
    543     return GetError (set, Write);
    544 }
    545 
    546 int
    547 RegisterContextDarwin_x86_64::WriteFPU ()
    548 {
    549     int set = FPURegSet;
    550     if (!RegisterSetIsCached(set))
    551     {
    552         SetError (set, Write, -1);
    553         return -1;
    554     }
    555     SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu));
    556     SetError (set, Read, -1);
    557     return GetError (set, Write);
    558 }
    559 
    560 int
    561 RegisterContextDarwin_x86_64::WriteEXC ()
    562 {
    563     int set = EXCRegSet;
    564     if (!RegisterSetIsCached(set))
    565     {
    566         SetError (set, Write, -1);
    567         return -1;
    568     }
    569     SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc));
    570     SetError (set, Read, -1);
    571     return GetError (set, Write);
    572 }
    573 
    574 int
    575 RegisterContextDarwin_x86_64::ReadRegisterSet(uint32_t set, bool force)
    576 {
    577     switch (set)
    578     {
    579     case GPRRegSet:    return ReadGPR (force);
    580     case FPURegSet:    return ReadFPU (force);
    581     case EXCRegSet:    return ReadEXC (force);
    582     default: break;
    583     }
    584     return -1;
    585 }
    586 
    587 int
    588 RegisterContextDarwin_x86_64::WriteRegisterSet(uint32_t set)
    589 {
    590     // Make sure we have a valid context to set.
    591     switch (set)
    592     {
    593     case GPRRegSet:    return WriteGPR ();
    594     case FPURegSet:    return WriteFPU ();
    595     case EXCRegSet:    return WriteEXC ();
    596     default: break;
    597     }
    598     return -1;
    599 }
    600 
    601 
    602 bool
    603 RegisterContextDarwin_x86_64::ReadRegister (const RegisterInfo *reg_info,
    604                                           RegisterValue &value)
    605 {
    606     const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
    607     int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum (reg);
    608     if (set == -1)
    609         return false;
    610 
    611     if (ReadRegisterSet(set, false) != 0)
    612         return false;
    613 
    614     switch (reg)
    615     {
    616     case gpr_rax:
    617     case gpr_rbx:
    618     case gpr_rcx:
    619     case gpr_rdx:
    620     case gpr_rdi:
    621     case gpr_rsi:
    622     case gpr_rbp:
    623     case gpr_rsp:
    624     case gpr_r8:
    625     case gpr_r9:
    626     case gpr_r10:
    627     case gpr_r11:
    628     case gpr_r12:
    629     case gpr_r13:
    630     case gpr_r14:
    631     case gpr_r15:
    632     case gpr_rip:
    633     case gpr_rflags:
    634     case gpr_cs:
    635     case gpr_fs:
    636     case gpr_gs:
    637         value = (&gpr.rax)[reg - gpr_rax];
    638         break;
    639 
    640     case fpu_fcw:
    641         value = fpu.fcw;
    642         break;
    643 
    644     case fpu_fsw:
    645         value = fpu.fsw;
    646         break;
    647 
    648     case fpu_ftw:
    649         value = fpu.ftw;
    650         break;
    651 
    652     case fpu_fop:
    653         value = fpu.fop;
    654         break;
    655 
    656     case fpu_ip:
    657         value = fpu.ip;
    658         break;
    659 
    660     case fpu_cs:
    661         value = fpu.cs;
    662         break;
    663 
    664     case fpu_dp:
    665         value = fpu.dp;
    666         break;
    667 
    668     case fpu_ds:
    669         value = fpu.ds;
    670         break;
    671 
    672     case fpu_mxcsr:
    673         value = fpu.mxcsr;
    674         break;
    675 
    676     case fpu_mxcsrmask:
    677         value = fpu.mxcsrmask;
    678         break;
    679 
    680     case fpu_stmm0:
    681     case fpu_stmm1:
    682     case fpu_stmm2:
    683     case fpu_stmm3:
    684     case fpu_stmm4:
    685     case fpu_stmm5:
    686     case fpu_stmm6:
    687     case fpu_stmm7:
    688         value.SetBytes(fpu.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder());
    689         break;
    690 
    691     case fpu_xmm0:
    692     case fpu_xmm1:
    693     case fpu_xmm2:
    694     case fpu_xmm3:
    695     case fpu_xmm4:
    696     case fpu_xmm5:
    697     case fpu_xmm6:
    698     case fpu_xmm7:
    699     case fpu_xmm8:
    700     case fpu_xmm9:
    701     case fpu_xmm10:
    702     case fpu_xmm11:
    703     case fpu_xmm12:
    704     case fpu_xmm13:
    705     case fpu_xmm14:
    706     case fpu_xmm15:
    707         value.SetBytes(fpu.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder());
    708         break;
    709 
    710     case exc_trapno:
    711         value = exc.trapno;
    712         break;
    713 
    714     case exc_err:
    715         value = exc.err;
    716         break;
    717 
    718     case exc_faultvaddr:
    719         value = exc.faultvaddr;
    720         break;
    721 
    722     default:
    723         return false;
    724     }
    725     return true;
    726 }
    727 
    728 
    729 bool
    730 RegisterContextDarwin_x86_64::WriteRegister (const RegisterInfo *reg_info,
    731                                            const RegisterValue &value)
    732 {
    733     const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
    734     int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum (reg);
    735 
    736     if (set == -1)
    737         return false;
    738 
    739     if (ReadRegisterSet(set, false) != 0)
    740         return false;
    741 
    742     switch (reg)
    743     {
    744     case gpr_rax:
    745     case gpr_rbx:
    746     case gpr_rcx:
    747     case gpr_rdx:
    748     case gpr_rdi:
    749     case gpr_rsi:
    750     case gpr_rbp:
    751     case gpr_rsp:
    752     case gpr_r8:
    753     case gpr_r9:
    754     case gpr_r10:
    755     case gpr_r11:
    756     case gpr_r12:
    757     case gpr_r13:
    758     case gpr_r14:
    759     case gpr_r15:
    760     case gpr_rip:
    761     case gpr_rflags:
    762     case gpr_cs:
    763     case gpr_fs:
    764     case gpr_gs:
    765         (&gpr.rax)[reg - gpr_rax] = value.GetAsUInt64();
    766         break;
    767 
    768     case fpu_fcw:
    769         fpu.fcw = value.GetAsUInt16();
    770         break;
    771 
    772     case fpu_fsw:
    773         fpu.fsw = value.GetAsUInt16();
    774         break;
    775 
    776     case fpu_ftw:
    777         fpu.ftw = value.GetAsUInt8();
    778         break;
    779 
    780     case fpu_fop:
    781         fpu.fop = value.GetAsUInt16();
    782         break;
    783 
    784     case fpu_ip:
    785         fpu.ip = value.GetAsUInt32();
    786         break;
    787 
    788     case fpu_cs:
    789         fpu.cs = value.GetAsUInt16();
    790         break;
    791 
    792     case fpu_dp:
    793         fpu.dp = value.GetAsUInt32();
    794         break;
    795 
    796     case fpu_ds:
    797         fpu.ds = value.GetAsUInt16();
    798         break;
    799 
    800     case fpu_mxcsr:
    801         fpu.mxcsr = value.GetAsUInt32();
    802         break;
    803 
    804     case fpu_mxcsrmask:
    805         fpu.mxcsrmask = value.GetAsUInt32();
    806         break;
    807 
    808     case fpu_stmm0:
    809     case fpu_stmm1:
    810     case fpu_stmm2:
    811     case fpu_stmm3:
    812     case fpu_stmm4:
    813     case fpu_stmm5:
    814     case fpu_stmm6:
    815     case fpu_stmm7:
    816         ::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize());
    817         break;
    818 
    819     case fpu_xmm0:
    820     case fpu_xmm1:
    821     case fpu_xmm2:
    822     case fpu_xmm3:
    823     case fpu_xmm4:
    824     case fpu_xmm5:
    825     case fpu_xmm6:
    826     case fpu_xmm7:
    827     case fpu_xmm8:
    828     case fpu_xmm9:
    829     case fpu_xmm10:
    830     case fpu_xmm11:
    831     case fpu_xmm12:
    832     case fpu_xmm13:
    833     case fpu_xmm14:
    834     case fpu_xmm15:
    835         ::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize());
    836         return false;
    837 
    838     case exc_trapno:
    839         exc.trapno = value.GetAsUInt32();
    840         break;
    841 
    842     case exc_err:
    843         exc.err = value.GetAsUInt32();
    844         break;
    845 
    846     case exc_faultvaddr:
    847         exc.faultvaddr = value.GetAsUInt64();
    848         break;
    849 
    850     default:
    851         return false;
    852     }
    853     return WriteRegisterSet(set) == 0;
    854 }
    855 
    856 bool
    857 RegisterContextDarwin_x86_64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
    858 {
    859     data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
    860     if (data_sp &&
    861         ReadGPR (false) == 0 &&
    862         ReadFPU (false) == 0 &&
    863         ReadEXC (false) == 0)
    864     {
    865         uint8_t *dst = data_sp->GetBytes();
    866         ::memcpy (dst, &gpr, sizeof(gpr));
    867         dst += sizeof(gpr);
    868 
    869         ::memcpy (dst, &fpu, sizeof(fpu));
    870         dst += sizeof(gpr);
    871 
    872         ::memcpy (dst, &exc, sizeof(exc));
    873         return true;
    874     }
    875     return false;
    876 }
    877 
    878 bool
    879 RegisterContextDarwin_x86_64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
    880 {
    881     if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
    882     {
    883         const uint8_t *src = data_sp->GetBytes();
    884         ::memcpy (&gpr, src, sizeof(gpr));
    885         src += sizeof(gpr);
    886 
    887         ::memcpy (&fpu, src, sizeof(fpu));
    888         src += sizeof(gpr);
    889 
    890         ::memcpy (&exc, src, sizeof(exc));
    891         uint32_t success_count = 0;
    892         if (WriteGPR() == 0)
    893             ++success_count;
    894         if (WriteFPU() == 0)
    895             ++success_count;
    896         if (WriteEXC() == 0)
    897             ++success_count;
    898         return success_count == 3;
    899     }
    900     return false;
    901 }
    902 
    903 
    904 uint32_t
    905 RegisterContextDarwin_x86_64::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t reg)
    906 {
    907     if (kind == eRegisterKindGeneric)
    908     {
    909         switch (reg)
    910         {
    911         case LLDB_REGNUM_GENERIC_PC:    return gpr_rip;
    912         case LLDB_REGNUM_GENERIC_SP:    return gpr_rsp;
    913         case LLDB_REGNUM_GENERIC_FP:    return gpr_rbp;
    914         case LLDB_REGNUM_GENERIC_FLAGS: return gpr_rflags;
    915         case LLDB_REGNUM_GENERIC_RA:
    916         default:
    917             break;
    918         }
    919     }
    920     else if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF)
    921     {
    922         switch (reg)
    923         {
    924         case gcc_dwarf_gpr_rax:  return gpr_rax;
    925         case gcc_dwarf_gpr_rdx:  return gpr_rdx;
    926         case gcc_dwarf_gpr_rcx:  return gpr_rcx;
    927         case gcc_dwarf_gpr_rbx:  return gpr_rbx;
    928         case gcc_dwarf_gpr_rsi:  return gpr_rsi;
    929         case gcc_dwarf_gpr_rdi:  return gpr_rdi;
    930         case gcc_dwarf_gpr_rbp:  return gpr_rbp;
    931         case gcc_dwarf_gpr_rsp:  return gpr_rsp;
    932         case gcc_dwarf_gpr_r8:   return gpr_r8;
    933         case gcc_dwarf_gpr_r9:   return gpr_r9;
    934         case gcc_dwarf_gpr_r10:  return gpr_r10;
    935         case gcc_dwarf_gpr_r11:  return gpr_r11;
    936         case gcc_dwarf_gpr_r12:  return gpr_r12;
    937         case gcc_dwarf_gpr_r13:  return gpr_r13;
    938         case gcc_dwarf_gpr_r14:  return gpr_r14;
    939         case gcc_dwarf_gpr_r15:  return gpr_r15;
    940         case gcc_dwarf_gpr_rip:  return gpr_rip;
    941         case gcc_dwarf_fpu_xmm0: return fpu_xmm0;
    942         case gcc_dwarf_fpu_xmm1: return fpu_xmm1;
    943         case gcc_dwarf_fpu_xmm2: return fpu_xmm2;
    944         case gcc_dwarf_fpu_xmm3: return fpu_xmm3;
    945         case gcc_dwarf_fpu_xmm4: return fpu_xmm4;
    946         case gcc_dwarf_fpu_xmm5: return fpu_xmm5;
    947         case gcc_dwarf_fpu_xmm6: return fpu_xmm6;
    948         case gcc_dwarf_fpu_xmm7: return fpu_xmm7;
    949         case gcc_dwarf_fpu_xmm8: return fpu_xmm8;
    950         case gcc_dwarf_fpu_xmm9: return fpu_xmm9;
    951         case gcc_dwarf_fpu_xmm10: return fpu_xmm10;
    952         case gcc_dwarf_fpu_xmm11: return fpu_xmm11;
    953         case gcc_dwarf_fpu_xmm12: return fpu_xmm12;
    954         case gcc_dwarf_fpu_xmm13: return fpu_xmm13;
    955         case gcc_dwarf_fpu_xmm14: return fpu_xmm14;
    956         case gcc_dwarf_fpu_xmm15: return fpu_xmm15;
    957         case gcc_dwarf_fpu_stmm0: return fpu_stmm0;
    958         case gcc_dwarf_fpu_stmm1: return fpu_stmm1;
    959         case gcc_dwarf_fpu_stmm2: return fpu_stmm2;
    960         case gcc_dwarf_fpu_stmm3: return fpu_stmm3;
    961         case gcc_dwarf_fpu_stmm4: return fpu_stmm4;
    962         case gcc_dwarf_fpu_stmm5: return fpu_stmm5;
    963         case gcc_dwarf_fpu_stmm6: return fpu_stmm6;
    964         case gcc_dwarf_fpu_stmm7: return fpu_stmm7;
    965         default:
    966             break;
    967         }
    968     }
    969     else if (kind == eRegisterKindGDB)
    970     {
    971         switch (reg)
    972         {
    973         case gdb_gpr_rax     : return gpr_rax;
    974         case gdb_gpr_rbx     : return gpr_rbx;
    975         case gdb_gpr_rcx     : return gpr_rcx;
    976         case gdb_gpr_rdx     : return gpr_rdx;
    977         case gdb_gpr_rsi     : return gpr_rsi;
    978         case gdb_gpr_rdi     : return gpr_rdi;
    979         case gdb_gpr_rbp     : return gpr_rbp;
    980         case gdb_gpr_rsp     : return gpr_rsp;
    981         case gdb_gpr_r8      : return gpr_r8;
    982         case gdb_gpr_r9      : return gpr_r9;
    983         case gdb_gpr_r10     : return gpr_r10;
    984         case gdb_gpr_r11     : return gpr_r11;
    985         case gdb_gpr_r12     : return gpr_r12;
    986         case gdb_gpr_r13     : return gpr_r13;
    987         case gdb_gpr_r14     : return gpr_r14;
    988         case gdb_gpr_r15     : return gpr_r15;
    989         case gdb_gpr_rip     : return gpr_rip;
    990         case gdb_gpr_rflags  : return gpr_rflags;
    991         case gdb_gpr_cs      : return gpr_cs;
    992         case gdb_gpr_ss      : return gpr_gs;   // HACK: For now for "ss", just copy what is in "gs"
    993         case gdb_gpr_ds      : return gpr_gs;   // HACK: For now for "ds", just copy what is in "gs"
    994         case gdb_gpr_es      : return gpr_gs;   // HACK: For now for "es", just copy what is in "gs"
    995         case gdb_gpr_fs      : return gpr_fs;
    996         case gdb_gpr_gs      : return gpr_gs;
    997         case gdb_fpu_stmm0   : return fpu_stmm0;
    998         case gdb_fpu_stmm1   : return fpu_stmm1;
    999         case gdb_fpu_stmm2   : return fpu_stmm2;
   1000         case gdb_fpu_stmm3   : return fpu_stmm3;
   1001         case gdb_fpu_stmm4   : return fpu_stmm4;
   1002         case gdb_fpu_stmm5   : return fpu_stmm5;
   1003         case gdb_fpu_stmm6   : return fpu_stmm6;
   1004         case gdb_fpu_stmm7   : return fpu_stmm7;
   1005         case gdb_fpu_fctrl   : return fpu_fctrl;
   1006         case gdb_fpu_fstat   : return fpu_fstat;
   1007         case gdb_fpu_ftag    : return fpu_ftag;
   1008         case gdb_fpu_fiseg   : return fpu_fiseg;
   1009         case gdb_fpu_fioff   : return fpu_fioff;
   1010         case gdb_fpu_foseg   : return fpu_foseg;
   1011         case gdb_fpu_fooff   : return fpu_fooff;
   1012         case gdb_fpu_fop     : return fpu_fop;
   1013         case gdb_fpu_xmm0    : return fpu_xmm0;
   1014         case gdb_fpu_xmm1    : return fpu_xmm1;
   1015         case gdb_fpu_xmm2    : return fpu_xmm2;
   1016         case gdb_fpu_xmm3    : return fpu_xmm3;
   1017         case gdb_fpu_xmm4    : return fpu_xmm4;
   1018         case gdb_fpu_xmm5    : return fpu_xmm5;
   1019         case gdb_fpu_xmm6    : return fpu_xmm6;
   1020         case gdb_fpu_xmm7    : return fpu_xmm7;
   1021         case gdb_fpu_xmm8    : return fpu_xmm8;
   1022         case gdb_fpu_xmm9    : return fpu_xmm9;
   1023         case gdb_fpu_xmm10   : return fpu_xmm10;
   1024         case gdb_fpu_xmm11   : return fpu_xmm11;
   1025         case gdb_fpu_xmm12   : return fpu_xmm12;
   1026         case gdb_fpu_xmm13   : return fpu_xmm13;
   1027         case gdb_fpu_xmm14   : return fpu_xmm14;
   1028         case gdb_fpu_xmm15   : return fpu_xmm15;
   1029         case gdb_fpu_mxcsr   : return fpu_mxcsr;
   1030         default:
   1031             break;
   1032         }
   1033     }
   1034     else if (kind == eRegisterKindLLDB)
   1035     {
   1036         return reg;
   1037     }
   1038     return LLDB_INVALID_REGNUM;
   1039 }
   1040 
   1041 bool
   1042 RegisterContextDarwin_x86_64::HardwareSingleStep (bool enable)
   1043 {
   1044     if (ReadGPR(true) != 0)
   1045         return false;
   1046 
   1047     const uint64_t trace_bit = 0x100ull;
   1048     if (enable)
   1049     {
   1050 
   1051         if (gpr.rflags & trace_bit)
   1052             return true;    // trace bit is already set, there is nothing to do
   1053         else
   1054             gpr.rflags |= trace_bit;
   1055     }
   1056     else
   1057     {
   1058         if (gpr.rflags & trace_bit)
   1059             gpr.rflags &= ~trace_bit;
   1060         else
   1061             return true;    // trace bit is clear, there is nothing to do
   1062     }
   1063 
   1064     return WriteGPR() == 0;
   1065 }
   1066 
   1067