10b167267bda99b68346045ccab14e810121d5de4Glenn Kasten//===-- RegisterContext_i386.h ------------------------------*- C++ -*-===//
20b167267bda99b68346045ccab14e810121d5de4Glenn Kasten//
30b167267bda99b68346045ccab14e810121d5de4Glenn Kasten//                     The LLVM Compiler Infrastructure
40b167267bda99b68346045ccab14e810121d5de4Glenn Kasten//
50b167267bda99b68346045ccab14e810121d5de4Glenn Kasten// This file is distributed under the University of Illinois Open Source
60b167267bda99b68346045ccab14e810121d5de4Glenn Kasten// License. See LICENSE.TXT for details.
70b167267bda99b68346045ccab14e810121d5de4Glenn Kasten//
80b167267bda99b68346045ccab14e810121d5de4Glenn Kasten//===----------------------------------------------------------------------===//
90b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#ifndef liblldb_RegisterContext_i386_h_
110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#define liblldb_RegisterContext_i386_h_
120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten// C Includes
140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten// C++ Includes
150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten// Other libraries and framework includes
160b167267bda99b68346045ccab14e810121d5de4Glenn Kasten// Project includes
170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#include "lldb/Core/Log.h"
180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#include "RegisterContextPOSIX.h"
190b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
200b167267bda99b68346045ccab14e810121d5de4Glenn Kastenclass RegisterContext_i386 : public RegisterContextPOSIX
21ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten{
22e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenpublic:
23e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    RegisterContext_i386(lldb_private::Thread &thread,
240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten                              uint32_t concreate_frame_idx);
25ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
26ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    ~RegisterContext_i386();
27ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
28ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    void
29ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    Invalidate();
30bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten
31ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    void
32ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    InvalidateAllRegisters();
33ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
34ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    size_t
350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    GetRegisterCount();
360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
37ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    const lldb_private::RegisterInfo *
380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    GetRegisterInfoAtIndex(size_t reg);
390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
400b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    size_t
41ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    GetRegisterSetCount();
42ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
43bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    const lldb_private::RegisterSet *
44bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    GetRegisterSet(size_t set);
45bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten
46bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    unsigned
47bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    GetRegisterIndexFromOffset(unsigned offset);
48ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
49ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    const char *
50ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    GetRegisterName(unsigned reg);
510b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
520b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    bool
53ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    ReadRegisterValue(uint32_t reg, lldb_private::Scalar &value);
540b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
550b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    bool
560b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    ReadRegisterBytes(uint32_t reg, lldb_private::DataExtractor &data);
57ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
58ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    virtual bool
59bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    ReadRegister(const lldb_private::RegisterInfo *reg_info,
60bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten                 lldb_private::RegisterValue &value);
61bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten
62bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    bool
63bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
64ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
65ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    bool
66ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    WriteRegisterValue(uint32_t reg, const lldb_private::Scalar &value);
670b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
680b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    bool
69ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    WriteRegisterBytes(uint32_t reg, lldb_private::DataExtractor &data,
700b167267bda99b68346045ccab14e810121d5de4Glenn Kasten                       uint32_t data_offset = 0);
710b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
720b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    virtual bool
73ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    WriteRegister(const lldb_private::RegisterInfo *reg_info,
74ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                  const lldb_private::RegisterValue &value);
750b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
760b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    bool
770b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
780b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
790b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    uint32_t
800b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num);
810b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
820b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    bool
83ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    HardwareSingleStep(bool enable);
84ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
85bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    bool
86bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    UpdateAfterBreakpoint();
87bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten
88bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    struct GPR
89ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    {
90ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        uint32_t ebx;
910b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        uint32_t ecx;
920b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        uint32_t edx;
93ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        uint32_t esi;
94ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        uint32_t edi;
950b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        uint32_t ebp;
96ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        uint32_t eax;
97ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        uint32_t ds;
980b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        uint32_t es;
990b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        uint32_t fs;
100ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        uint32_t gs;
1010b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        uint32_t orig_ax;
1020b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        uint32_t eip;
103ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        uint32_t cs;
104ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        uint32_t eflags;
105bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        uint32_t esp;
106bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        uint32_t ss;
107bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    };
108bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten
109ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    struct MMSReg
110ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    {
111ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        uint8_t bytes[8];
1120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    };
1130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
114ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    struct XMMReg
1150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    {
1160b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        uint8_t bytes[16];
1170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    };
1180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1190b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    struct FPU
1200b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    {
1210b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        uint16_t    fcw;
1220b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        uint16_t    fsw;
1230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        uint16_t    ftw;
1240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        uint16_t    fop;
125bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        uint32_t    ip;
126bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        uint32_t    cs;
127bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        uint32_t    foo;
128bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        uint32_t    fos;
129bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        uint32_t    mxcsr;
130bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        uint32_t    reserved;
131bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        MMSReg      stmm[8];
1320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        XMMReg      xmm[8];
133        uint32_t    pad[56];
134    };
135
136    // A user area like this no longer exists on FreeBSD
137    // making this a Linux artifact. Nonetheless, it is safe
138    // leaving it here while the code is being cleaned up and generalized.
139
140    struct UserArea
141    {
142        GPR      regs;          // General purpose registers.
143        int32_t  fpvalid;       // True if FPU is being used.
144        FPU      i387;          // FPU registers.
145        uint32_t tsize;         // Text segment size.
146        uint32_t dsize;         // Data segment size.
147        uint32_t ssize;         // Stack segment size.
148        uint32_t start_code;    // VM address of text.
149        uint32_t start_stack;   // VM address of stack bottom (top in rsp).
150        int32_t  signal;        // Signal causing core dump.
151        int32_t  reserved;      // Unused.
152        uint32_t ar0;           // Location of GPR's.
153        FPU*     fpstate;       // Location of FPR's.
154        uint32_t magic;         // Identifier for core dumps.
155        char     u_comm[32];    // Command causing core dump.
156        uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7).
157    };
158private:
159    UserArea user;
160
161    ProcessMonitor &GetMonitor();
162
163    void LogGPR(const char *title);
164
165    bool ReadGPR();
166    bool ReadFPR();
167};
168
169#endif // #ifndef liblldb_RegisterContext_i386_h_
170