DNBArchImplI386.h revision 5b4b00f5fd83d87de954d80d54fd6cc922772c19
1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//===-- DNBArchImplI386.h ---------------------------------------*- C++ -*-===//
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//                     The LLVM Compiler Infrastructure
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is distributed under the University of Illinois Open Source
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// License. See LICENSE.TXT for details.
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//===----------------------------------------------------------------------===//
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//  Created by Greg Clayton on 6/25/07.
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//===----------------------------------------------------------------------===//
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef __DNBArchImplI386_h__
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define __DNBArchImplI386_h__
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#if defined (__i386__) || defined (__x86_64__)
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "DNBArch.h"
20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "../HasAVX.h"
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "MachRegisterStatesI386.h"
22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass MachThread;
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass DNBArchImplI386 : public DNBArchProtocol
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpublic:
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    DNBArchImplI386(MachThread *thread) :
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_thread(thread),
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_state()
31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    virtual ~DNBArchImplI386()
34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    static  void            Initialize();
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    virtual bool            GetRegisterValue(int set, int reg, DNBRegisterValue *value);
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    virtual bool            SetRegisterValue(int set, int reg, const DNBRegisterValue *value);
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    virtual nub_size_t      GetRegisterContext (void *buf, nub_size_t buf_len);
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    virtual nub_size_t      SetRegisterContext (const void *buf, nub_size_t buf_len);
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    virtual kern_return_t   GetRegisterState  (int set, bool force);
44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    virtual kern_return_t   SetRegisterState  (int set);
45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    virtual bool            RegisterSetStateIsValid (int set) const;
46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    virtual uint64_t        GetPC(uint64_t failValue);    // Get program counter
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    virtual kern_return_t   SetPC(uint64_t value);
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    virtual uint64_t        GetSP(uint64_t failValue);    // Get stack pointer
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    virtual void            ThreadWillResume();
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    virtual bool            ThreadDidStop();
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    virtual bool            NotifyException(MachException::Data& exc);
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    virtual uint32_t        NumSupportedHardwareWatchpoints();
55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    virtual uint32_t        EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write);
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    virtual bool            DisableHardwareWatchpoint (uint32_t hw_break_index);
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    virtual uint32_t        GetHardwareWatchpointHit();
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathprotected:
607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    kern_return_t           EnableHardwareSingleStep (bool enable);
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef __i386_thread_state_t GPR;
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef __i386_float_state_t FPU;
64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef __i386_exception_state_t EXC;
65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef __i386_avx_state_t AVX;
66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef __i386_debug_state_t DBG;
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    static const DNBRegisterInfo g_gpr_registers[];
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    static const DNBRegisterInfo g_fpu_registers_no_avx[];
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    static const DNBRegisterInfo g_fpu_registers_avx[];
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    static const DNBRegisterInfo g_exc_registers[];
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    static const DNBRegisterSetInfo g_reg_sets_no_avx[];
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    static const DNBRegisterSetInfo g_reg_sets_avx[];
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    static const size_t k_num_gpr_registers;
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    static const size_t k_num_fpu_registers_no_avx;
76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    static const size_t k_num_fpu_registers_avx;
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    static const size_t k_num_exc_registers;
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    static const size_t k_num_all_registers_no_avx;
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    static const size_t k_num_all_registers_avx;
807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    static const size_t k_num_register_sets;
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef enum RegisterSetTag
83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        e_regSetALL = REGISTER_SET_ALL,
85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        e_regSetGPR,
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        e_regSetFPU,
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        e_regSetEXC,
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        e_regSetDBG,
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        kNumRegisterSets
90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    } RegisterSet;
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef enum RegisterSetWordSizeTag
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        e_regSetWordSizeGPR = sizeof(GPR) / sizeof(int),
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        e_regSetWordSizeFPR = sizeof(FPU) / sizeof(int),
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        e_regSetWordSizeEXC = sizeof(EXC) / sizeof(int),
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        e_regSetWordSizeAVX = sizeof(AVX) / sizeof(int),
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        e_regSetWordSizeDBG = sizeof(DBG) / sizeof(int)
99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    } RegisterSetWordSize;
100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    enum
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        Read = 0,
104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        Write = 1,
105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        kNumErrors = 2
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    };
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    struct Context
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        GPR gpr;
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        union {
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            FPU no_avx;
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            AVX avx;
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        } fpu;
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        EXC exc;
116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        DBG dbg;
117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    };
118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    struct State
120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        Context context;
122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        kern_return_t gpr_errs[2];    // Read/Write errors
123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        kern_return_t fpu_errs[2];    // Read/Write errors
124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        kern_return_t exc_errs[2];    // Read/Write errors
125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        kern_return_t dbg_errs[2];    // Read/Write errors
126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        State()
128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        {
129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            uint32_t i;
130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            for (i=0; i<kNumErrors; i++)
131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            {
132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                gpr_errs[i] = -1;
133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                fpu_errs[i] = -1;
134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                exc_errs[i] = -1;
135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                dbg_errs[i] = -1;
136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            }
137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        }
138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        void InvalidateAllRegisterStates()
139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        {
140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            SetError (e_regSetALL, Read, -1);
141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        }
142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        kern_return_t GetError (int flavor, uint32_t err_idx) const
143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        {
144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            if (err_idx < kNumErrors)
145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            {
146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                switch (flavor)
147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                {
148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                // When getting all errors, just OR all values together to see if
149                // we got any kind of error.
150                case e_regSetALL:    return gpr_errs[err_idx] |
151                                            fpu_errs[err_idx] |
152                                            exc_errs[err_idx];
153                case e_regSetGPR:    return gpr_errs[err_idx];
154                case e_regSetFPU:    return fpu_errs[err_idx];
155                case e_regSetEXC:    return exc_errs[err_idx];
156                case e_regSetDBG:    return dbg_errs[err_idx];
157                default: break;
158                }
159            }
160            return -1;
161        }
162        bool SetError (int flavor, uint32_t err_idx, kern_return_t err)
163        {
164            if (err_idx < kNumErrors)
165            {
166                switch (flavor)
167                {
168                case e_regSetALL:
169                    gpr_errs[err_idx] =
170                    fpu_errs[err_idx] =
171                    exc_errs[err_idx] =
172                    dbg_errs[err_idx] = err;
173                    return true;
174
175                case e_regSetGPR:
176                    gpr_errs[err_idx] = err;
177                    return true;
178
179                case e_regSetFPU:
180                    fpu_errs[err_idx] = err;
181                    return true;
182
183                case e_regSetEXC:
184                    exc_errs[err_idx] = err;
185                    return true;
186
187                case e_regSetDBG:
188                    dbg_errs[err_idx] = err;
189                    return true;
190
191                default: break;
192                }
193            }
194            return false;
195        }
196        bool RegsAreValid (int flavor) const
197        {
198            return GetError(flavor, Read) == KERN_SUCCESS;
199        }
200    };
201
202    kern_return_t GetGPRState (bool force);
203    kern_return_t GetFPUState (bool force);
204    kern_return_t GetEXCState (bool force);
205    kern_return_t GetDBGState (bool force);
206
207    kern_return_t SetGPRState ();
208    kern_return_t SetFPUState ();
209    kern_return_t SetEXCState ();
210    kern_return_t SetDBGState ();
211
212    static DNBArchProtocol *
213    Create (MachThread *thread);
214
215    static const uint8_t * const
216    SoftwareBreakpointOpcode (nub_size_t byte_size);
217
218    static const DNBRegisterSetInfo *
219    GetRegisterSetInfo(nub_size_t *num_reg_sets);
220
221    static bool
222    CPUHasAVX()
223    {
224        if (s_has_avx == kAVXUnknown)
225            s_has_avx = (::HasAVX() ? kAVXPresent : kAVXNotPresent);
226
227        return (s_has_avx == kAVXPresent);
228    }
229
230    // Helper functions for watchpoint manipulations.
231    static void SetWatchpoint(DBG &debug_state, uint32_t hw_index, nub_addr_t addr, nub_size_t size, bool read, bool write);
232    static void ClearWatchpoint(DBG &debug_state, uint32_t hw_index);
233    static bool IsWatchpointVacant(const DBG &debug_state, uint32_t hw_index);
234    static void ClearWatchpointHits(DBG &debug_state);
235    static bool IsWatchpointHit(const DBG &debug_state, uint32_t hw_index);
236
237    MachThread *m_thread;
238    State       m_state;
239
240    static enum AVXPresence {
241        kAVXPresent,
242        kAVXNotPresent,
243        kAVXUnknown
244    } s_has_avx;
245};
246
247#endif    // #if defined (__i386__) || defined (__x86_64__)
248#endif    // #ifndef __DNBArchImplI386_h__
249