1//===-- RegisterContext_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_RegisterContext_x86_64_H_
11#define liblldb_RegisterContext_x86_64_H_
12
13#include "lldb/Core/Log.h"
14#include "RegisterContextPOSIX.h"
15
16class ProcessMonitor;
17
18// Internal codes for all x86_64 registers.
19enum
20{
21    k_first_gpr,
22    gpr_rax = k_first_gpr,
23    gpr_rbx,
24    gpr_rcx,
25    gpr_rdx,
26    gpr_rdi,
27    gpr_rsi,
28    gpr_rbp,
29    gpr_rsp,
30    gpr_r8,
31    gpr_r9,
32    gpr_r10,
33    gpr_r11,
34    gpr_r12,
35    gpr_r13,
36    gpr_r14,
37    gpr_r15,
38    gpr_rip,
39    gpr_rflags,
40    gpr_cs,
41    gpr_fs,
42    gpr_gs,
43    gpr_ss,
44    gpr_ds,
45    gpr_es,
46    k_first_i386,
47    gpr_eax = k_first_i386,
48    gpr_ebx,
49    gpr_ecx,
50    gpr_edx,
51    gpr_edi,
52    gpr_esi,
53    gpr_ebp,
54    gpr_esp,
55    gpr_eip,
56    gpr_eflags, // eRegisterKindLLDB == 33
57    k_last_i386 = gpr_eflags,
58    k_last_gpr = gpr_eflags,
59
60    k_first_fpr,
61    fpu_fcw = k_first_fpr,
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    k_last_fpr = fpu_xmm15,
96    k_first_avx,
97    fpu_ymm0 = k_first_avx,
98    fpu_ymm1,
99    fpu_ymm2,
100    fpu_ymm3,
101    fpu_ymm4,
102    fpu_ymm5,
103    fpu_ymm6,
104    fpu_ymm7,
105    fpu_ymm8,
106    fpu_ymm9,
107    fpu_ymm10,
108    fpu_ymm11,
109    fpu_ymm12,
110    fpu_ymm13,
111    fpu_ymm14,
112    fpu_ymm15,
113    k_last_avx = fpu_ymm15,
114
115    dr0,
116    dr1,
117    dr2,
118    dr3,
119    dr4,
120    dr5,
121    dr6,
122    dr7,
123
124    k_num_registers,
125    k_num_gpr_registers = k_last_gpr - k_first_gpr + 1,
126    k_num_fpr_registers = k_last_fpr - k_first_fpr + 1,
127    k_num_avx_registers = k_last_avx - k_first_avx + 1
128};
129
130class RegisterContext_x86_64
131  : public RegisterContextPOSIX
132{
133public:
134    RegisterContext_x86_64 (lldb_private::Thread &thread,
135                            uint32_t concrete_frame_idx);
136
137    ~RegisterContext_x86_64();
138
139    void
140    Invalidate();
141
142    void
143    InvalidateAllRegisters();
144
145    size_t
146    GetRegisterCount();
147
148    virtual size_t
149    GetGPRSize() = 0;
150
151    virtual unsigned
152    GetRegisterSize(unsigned reg);
153
154    virtual unsigned
155    GetRegisterOffset(unsigned reg);
156
157    const lldb_private::RegisterInfo *
158    GetRegisterInfoAtIndex(size_t reg);
159
160    size_t
161    GetRegisterSetCount();
162
163    const lldb_private::RegisterSet *
164    GetRegisterSet(size_t set);
165
166    unsigned
167    GetRegisterIndexFromOffset(unsigned offset);
168
169    const char *
170    GetRegisterName(unsigned reg);
171
172    virtual bool
173    ReadRegister(const lldb_private::RegisterInfo *reg_info,
174                 lldb_private::RegisterValue &value);
175
176    bool
177    ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
178
179    virtual bool
180    WriteRegister(const lldb_private::RegisterInfo *reg_info,
181                  const lldb_private::RegisterValue &value);
182
183    bool
184    WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
185
186    uint32_t
187    ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num);
188
189    uint32_t
190    NumSupportedHardwareWatchpoints();
191
192    uint32_t
193    SetHardwareWatchpoint(lldb::addr_t, size_t size, bool read, bool write);
194
195    bool
196    SetHardwareWatchpointWithIndex(lldb::addr_t, size_t size, bool read,
197                                   bool write, uint32_t hw_index);
198
199    bool
200    ClearHardwareWatchpoint(uint32_t hw_index);
201
202    bool
203    HardwareSingleStep(bool enable);
204
205    bool
206    UpdateAfterBreakpoint();
207
208    bool
209    IsWatchpointVacant(uint32_t hw_index);
210
211    bool
212    IsWatchpointHit (uint32_t hw_index);
213
214    lldb::addr_t
215    GetWatchpointAddress (uint32_t hw_index);
216
217    bool
218    ClearWatchpointHits();
219
220    //---------------------------------------------------------------------------
221    // Generic floating-point registers
222    //---------------------------------------------------------------------------
223
224    struct MMSReg
225    {
226        uint8_t bytes[10];
227        uint8_t pad[6];
228    };
229
230    struct XMMReg
231    {
232        uint8_t bytes[16]; // 128-bits for each XMM register
233    };
234
235    struct FXSAVE
236    {
237        uint16_t fcw;
238        uint16_t fsw;
239        uint16_t ftw;
240        uint16_t fop;
241        uint64_t ip;
242        uint64_t dp;
243        uint32_t mxcsr;
244        uint32_t mxcsrmask;
245        MMSReg   stmm[8];
246        XMMReg   xmm[16];
247        uint32_t padding[24];
248    };
249
250    //---------------------------------------------------------------------------
251    // Extended floating-point registers
252    //---------------------------------------------------------------------------
253    struct YMMHReg
254    {
255        uint8_t  bytes[16];     // 16 * 8 bits for the high bytes of each YMM register
256    };
257
258    struct YMMReg
259    {
260        uint8_t  bytes[32];     // 16 * 16 bits for each YMM register
261    };
262
263    struct YMM
264    {
265        YMMReg   ymm[16];       // assembled from ymmh and xmm registers
266    };
267
268    struct XSAVE_HDR
269    {
270        uint64_t  xstate_bv;    // OS enabled xstate mask to determine the extended states supported by the processor
271        uint64_t  reserved1[2];
272        uint64_t  reserved2[5];
273    } __attribute__((packed));
274
275    // x86 extensions to FXSAVE (i.e. for AVX processors)
276    struct XSAVE
277    {
278        FXSAVE    i387;         // floating point registers typical in i387_fxsave_struct
279        XSAVE_HDR header;       // The xsave_hdr_struct can be used to determine if the following extensions are usable
280        YMMHReg   ymmh[16];     // High 16 bytes of each of 16 YMM registers (the low bytes are in FXSAVE.xmm for compatibility with SSE)
281        // Slot any extensions to the register file here
282    } __attribute__((packed, aligned (64)));
283
284    struct IOVEC
285    {
286        void    *iov_base;      // pointer to XSAVE
287        size_t   iov_len;       // sizeof(XSAVE)
288    };
289
290    //---------------------------------------------------------------------------
291    // Note: prefer kernel definitions over user-land
292    //---------------------------------------------------------------------------
293    enum FPRType
294    {
295        eNotValid = 0,
296        eFSAVE,  // TODO
297        eFXSAVE,
298        eSOFT,   // TODO
299        eXSAVE
300    };
301
302    // Floating-point registers
303    struct FPR
304    {
305        // Thread state for the floating-point unit of the processor read by ptrace.
306        union XSTATE {
307            FXSAVE   fxsave;    // Generic floating-point registers.
308            XSAVE    xsave;     // x86 extended processor state.
309        } xstate;
310    };
311
312protected:
313    // Determines if an extended register set is supported on the processor running the inferior process.
314    virtual bool
315    IsRegisterSetAvailable(size_t set_index);
316
317    virtual const lldb_private::RegisterInfo *
318    GetRegisterInfo();
319
320    virtual bool
321    ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
322
323    virtual bool
324    WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value);
325
326private:
327    uint64_t m_gpr[k_num_gpr_registers]; // general purpose registers.
328    FPRType  m_fpr_type;                 // determines the type of data stored by union FPR, if any.
329    FPR      m_fpr;                      // floating-point registers including extended register sets.
330    IOVEC    m_iovec;                    // wrapper for xsave.
331    YMM      m_ymm_set;                  // copy of ymmh and xmm register halves.
332
333    ProcessMonitor &GetMonitor();
334    lldb::ByteOrder GetByteOrder();
335
336    bool CopyXSTATEtoYMM(uint32_t reg, lldb::ByteOrder byte_order);
337    bool CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order);
338    bool IsFPR(unsigned reg, FPRType fpr_type);
339
340    bool ReadGPR();
341    bool ReadFPR();
342
343    bool WriteGPR();
344    bool WriteFPR();
345};
346
347#endif // #ifndef liblldb_RegisterContext_x86_64_H_
348