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