1//===-- RegisterContextDarwin_x86_64.h --------------------------*- 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#ifndef liblldb_RegisterContextDarwin_x86_64_h_
11#define liblldb_RegisterContextDarwin_x86_64_h_
12
13// C Includes
14// C++ Includes
15// Other libraries and framework includes
16// Project includes
17#include "lldb/lldb-private.h"
18#include "lldb/Target/RegisterContext.h"
19
20class RegisterContextDarwin_x86_64 : public lldb_private::RegisterContext
21{
22public:
23    RegisterContextDarwin_x86_64 (lldb_private::Thread &thread,
24                                  uint32_t concrete_frame_idx);
25
26    virtual
27    ~RegisterContextDarwin_x86_64();
28
29    virtual void
30    InvalidateAllRegisters ();
31
32    virtual size_t
33    GetRegisterCount ();
34
35    virtual const lldb_private::RegisterInfo *
36    GetRegisterInfoAtIndex (size_t reg);
37
38    virtual size_t
39    GetRegisterSetCount ();
40
41    virtual const lldb_private::RegisterSet *
42    GetRegisterSet (size_t set);
43
44    virtual bool
45    ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
46
47    virtual bool
48    WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
49
50    virtual bool
51    ReadAllRegisterValues (lldb::DataBufferSP &data_sp);
52
53    virtual bool
54    WriteAllRegisterValues (const lldb::DataBufferSP &data_sp);
55
56    virtual uint32_t
57    ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
58
59    virtual bool
60    HardwareSingleStep (bool enable);
61
62    struct GPR
63    {
64        uint64_t rax;
65        uint64_t rbx;
66        uint64_t rcx;
67        uint64_t rdx;
68        uint64_t rdi;
69        uint64_t rsi;
70        uint64_t rbp;
71        uint64_t rsp;
72        uint64_t r8;
73        uint64_t r9;
74        uint64_t r10;
75        uint64_t r11;
76        uint64_t r12;
77        uint64_t r13;
78        uint64_t r14;
79        uint64_t r15;
80        uint64_t rip;
81        uint64_t rflags;
82        uint64_t cs;
83        uint64_t fs;
84        uint64_t gs;
85    };
86
87    struct MMSReg
88    {
89        uint8_t bytes[10];
90        uint8_t pad[6];
91    };
92
93    struct XMMReg
94    {
95        uint8_t bytes[16];
96    };
97
98    struct FPU
99    {
100        uint32_t    pad[2];
101        uint16_t    fcw;    // "fctrl"
102        uint16_t    fsw;    // "fstat"
103        uint8_t     ftw;    // "ftag"
104        uint8_t     pad1;
105        uint16_t    fop;    // "fop"
106        uint32_t    ip;     // "fioff"
107        uint16_t    cs;     // "fiseg"
108        uint16_t    pad2;
109        uint32_t    dp;     // "fooff"
110        uint16_t    ds;     // "foseg"
111        uint16_t    pad3;
112        uint32_t    mxcsr;
113        uint32_t    mxcsrmask;
114        MMSReg      stmm[8];
115        XMMReg      xmm[16];
116        uint8_t     pad4[6*16];
117        int         pad5;
118    };
119
120    struct EXC
121    {
122        uint32_t trapno;
123        uint32_t err;
124        uint64_t faultvaddr;
125    };
126
127protected:
128
129    enum
130    {
131        GPRRegSet = 4,
132        FPURegSet = 5,
133        EXCRegSet = 6
134    };
135
136    enum
137    {
138        GPRWordCount = sizeof(GPR)/sizeof(uint32_t),
139        FPUWordCount = sizeof(FPU)/sizeof(uint32_t),
140        EXCWordCount = sizeof(EXC)/sizeof(uint32_t)
141    };
142
143    enum
144    {
145        Read = 0,
146        Write = 1,
147        kNumErrors = 2
148    };
149
150    GPR gpr;
151    FPU fpu;
152    EXC exc;
153    int gpr_errs[2]; // Read/Write errors
154    int fpu_errs[2]; // Read/Write errors
155    int exc_errs[2]; // Read/Write errors
156
157    void
158    InvalidateAllRegisterStates()
159    {
160        SetError (GPRRegSet, Read, -1);
161        SetError (FPURegSet, Read, -1);
162        SetError (EXCRegSet, Read, -1);
163    }
164
165    int
166    GetError (int flavor, uint32_t err_idx) const
167    {
168        if (err_idx < kNumErrors)
169        {
170            switch (flavor)
171            {
172            // When getting all errors, just OR all values together to see if
173            // we got any kind of error.
174            case GPRRegSet:    return gpr_errs[err_idx];
175            case FPURegSet:    return fpu_errs[err_idx];
176            case EXCRegSet:    return exc_errs[err_idx];
177            default: break;
178            }
179        }
180        return -1;
181    }
182
183    bool
184    SetError (int flavor, uint32_t err_idx, int err)
185    {
186        if (err_idx < kNumErrors)
187        {
188            switch (flavor)
189            {
190            case GPRRegSet:
191                gpr_errs[err_idx] = err;
192                return true;
193
194            case FPURegSet:
195                fpu_errs[err_idx] = err;
196                return true;
197
198            case EXCRegSet:
199                exc_errs[err_idx] = err;
200                return true;
201
202            default: break;
203            }
204        }
205        return false;
206    }
207
208    bool
209    RegisterSetIsCached (int set) const
210    {
211        return GetError(set, Read) == 0;
212    }
213
214    void
215    LogGPR (lldb_private::Log *log, const char *format, ...);
216
217    int
218    ReadGPR (bool force);
219
220    int
221    ReadFPU (bool force);
222
223    int
224    ReadEXC (bool force);
225
226    int
227    WriteGPR ();
228
229    int
230    WriteFPU ();
231
232    int
233    WriteEXC ();
234
235    // Subclasses override these to do the actual reading.
236    virtual int
237    DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr) = 0;
238
239    virtual int
240    DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) = 0;
241
242    virtual int
243    DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) = 0;
244
245    virtual int
246    DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) = 0;
247
248    virtual int
249    DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) = 0;
250
251    virtual int
252    DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) = 0;
253
254    int
255    ReadRegisterSet (uint32_t set, bool force);
256
257    int
258    WriteRegisterSet (uint32_t set);
259
260    static uint32_t
261    GetRegisterNumber (uint32_t reg_kind, uint32_t reg_num);
262
263    static int
264    GetSetForNativeRegNum (int reg_num);
265
266    static size_t
267    GetRegisterInfosCount ();
268
269    static const lldb_private::RegisterInfo *
270    GetRegisterInfos ();
271
272};
273
274#endif  // liblldb_RegisterContextDarwin_x86_64_h_
275