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 
16 class ProcessMonitor;
17 
18 // Internal codes for all x86_64 registers.
19 enum
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 
130 class RegisterContext_x86_64
131   : public RegisterContextPOSIX
132 {
133 public:
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 
312 protected:
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 
326 private:
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