]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
Vendor import of lldb trunk r256945:
[FreeBSD/FreeBSD.git] / source / Plugins / Process / Windows / Common / x86 / RegisterContextWindows_x86.cpp
1 //===-- RegisterContextWindows_x86.cpp --------------------------*- 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 #include "lldb/lldb-private-types.h"
11 #include "lldb/Core/Error.h"
12 #include "lldb/Core/RegisterValue.h"
13 #include "lldb/Host/windows/HostThreadWindows.h"
14 #include "lldb/Host/windows/windows.h"
15
16 #include "lldb-x86-register-enums.h"
17 #include "ProcessWindowsLog.h"
18 #include "RegisterContext_x86.h"
19 #include "RegisterContextWindows_x86.h"
20
21 #include "llvm/ADT/STLExtras.h"
22
23 using namespace lldb;
24 using namespace lldb_private;
25
26 #define DEFINE_GPR(reg, alt) #reg, alt, 4, 0, eEncodingUint, eFormatHexUppercase
27 #define DEFINE_GPR_BIN(reg, alt) #reg, alt, 4, 0, eEncodingUint, eFormatBinary
28
29 namespace
30 {
31
32 // This enum defines the layout of the global RegisterInfo array.  This is necessary because
33 // lldb register sets are defined in terms of indices into the register array.  As such, the
34 // order of RegisterInfos defined in global registers array must match the order defined here.
35 // When defining the register set layouts, these values can appear in an arbitrary order, and that
36 // determines the order that register values are displayed in a dump.
37 enum RegisterIndex
38 {
39     eRegisterIndexEax,
40     eRegisterIndexEbx,
41     eRegisterIndexEcx,
42     eRegisterIndexEdx,
43     eRegisterIndexEdi,
44     eRegisterIndexEsi,
45     eRegisterIndexEbp,
46     eRegisterIndexEsp,
47     eRegisterIndexEip,
48     eRegisterIndexEflags
49 };
50
51 // Array of all register information supported by Windows x86
52 RegisterInfo g_register_infos[] =
53 {
54 //  Macro auto defines most stuff   eh_frame                DWARF                GENERIC                    GDB                   LLDB               VALUE REGS    INVALIDATE REGS
55 //  ==============================  ======================= ===================  =========================  ===================   =================  ==========    ===============
56     { DEFINE_GPR(eax,    nullptr),  { ehframe_eax_i386,     dwarf_eax_i386,      LLDB_INVALID_REGNUM,       LLDB_INVALID_REGNUM,  lldb_eax_i386   },  nullptr,      nullptr},
57     { DEFINE_GPR(ebx,    nullptr),  { ehframe_ebx_i386,     dwarf_ebx_i386,      LLDB_INVALID_REGNUM,       LLDB_INVALID_REGNUM,  lldb_ebx_i386   },  nullptr,      nullptr},
58     { DEFINE_GPR(ecx,    nullptr),  { ehframe_ecx_i386,     dwarf_ecx_i386,      LLDB_INVALID_REGNUM,       LLDB_INVALID_REGNUM,  lldb_ecx_i386   },  nullptr,      nullptr},
59     { DEFINE_GPR(edx,    nullptr),  { ehframe_edx_i386,     dwarf_edx_i386,      LLDB_INVALID_REGNUM,       LLDB_INVALID_REGNUM,  lldb_edx_i386   },  nullptr,      nullptr},
60     { DEFINE_GPR(edi,    nullptr),  { ehframe_edi_i386,     dwarf_edi_i386,      LLDB_INVALID_REGNUM,       LLDB_INVALID_REGNUM,  lldb_edi_i386   },  nullptr,      nullptr},
61     { DEFINE_GPR(esi,    nullptr),  { ehframe_esi_i386,     dwarf_esi_i386,      LLDB_INVALID_REGNUM,       LLDB_INVALID_REGNUM,  lldb_esi_i386   },  nullptr,      nullptr},
62     { DEFINE_GPR(ebp,    "fp"),     { ehframe_ebp_i386,     dwarf_ebp_i386,      LLDB_REGNUM_GENERIC_FP,    LLDB_INVALID_REGNUM,  lldb_ebp_i386   },  nullptr,      nullptr},
63     { DEFINE_GPR(esp,    "sp"),     { ehframe_esp_i386,     dwarf_esp_i386,      LLDB_REGNUM_GENERIC_SP,    LLDB_INVALID_REGNUM,  lldb_esp_i386   },  nullptr,      nullptr},
64     { DEFINE_GPR(eip,    "pc"),     { ehframe_eip_i386,     dwarf_eip_i386,      LLDB_REGNUM_GENERIC_PC,    LLDB_INVALID_REGNUM,  lldb_eip_i386   },  nullptr,      nullptr},
65     { DEFINE_GPR_BIN(eflags, "flags"), { ehframe_eflags_i386, dwarf_eflags_i386,   LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,  lldb_eflags_i386},  nullptr,      nullptr},
66 };
67
68 // Array of lldb register numbers used to define the set of all General Purpose Registers
69 uint32_t g_gpr_reg_indices[] =
70 {
71     eRegisterIndexEax,
72     eRegisterIndexEbx,
73     eRegisterIndexEcx,
74     eRegisterIndexEdx,
75     eRegisterIndexEdi,
76     eRegisterIndexEsi,
77     eRegisterIndexEbp,
78     eRegisterIndexEsp,
79     eRegisterIndexEip,
80     eRegisterIndexEflags
81 };
82
83 RegisterSet g_register_sets[] = {
84     {"General Purpose Registers", "gpr", llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices},
85 };
86 }
87
88 //------------------------------------------------------------------
89 // Constructors and Destructors
90 //------------------------------------------------------------------
91 RegisterContextWindows_x86::RegisterContextWindows_x86(Thread &thread, uint32_t concrete_frame_idx)
92     : RegisterContextWindows(thread, concrete_frame_idx)
93 {
94 }
95
96 RegisterContextWindows_x86::~RegisterContextWindows_x86()
97 {
98 }
99
100 size_t
101 RegisterContextWindows_x86::GetRegisterCount()
102 {
103     return llvm::array_lengthof(g_register_infos);
104 }
105
106 const RegisterInfo *
107 RegisterContextWindows_x86::GetRegisterInfoAtIndex(size_t reg)
108 {
109     return &g_register_infos[reg];
110 }
111
112 size_t
113 RegisterContextWindows_x86::GetRegisterSetCount()
114 {
115     return llvm::array_lengthof(g_register_sets);
116 }
117
118 const RegisterSet *
119 RegisterContextWindows_x86::GetRegisterSet(size_t reg_set)
120 {
121     return &g_register_sets[reg_set];
122 }
123
124 bool
125 RegisterContextWindows_x86::ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)
126 {
127     if (!CacheAllRegisterValues())
128         return false;
129
130     uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
131     switch (reg)
132     {
133         case lldb_eax_i386:
134             WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EAX", m_context.Eax);
135             reg_value.SetUInt32(m_context.Eax);
136             break;
137         case lldb_ebx_i386:
138             WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EBX", m_context.Ebx);
139             reg_value.SetUInt32(m_context.Ebx);
140             break;
141         case lldb_ecx_i386:
142             WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from ECX", m_context.Ecx);
143             reg_value.SetUInt32(m_context.Ecx);
144             break;
145         case lldb_edx_i386:
146             WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EDX", m_context.Edx);
147             reg_value.SetUInt32(m_context.Edx);
148             break;
149         case lldb_edi_i386:
150             WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EDI", m_context.Edi);
151             reg_value.SetUInt32(m_context.Edi);
152             break;
153         case lldb_esi_i386:
154             WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from ESI", m_context.Esi);
155             reg_value.SetUInt32(m_context.Esi);
156             break;
157         case lldb_ebp_i386:
158             WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EBP", m_context.Ebp);
159             reg_value.SetUInt32(m_context.Ebp);
160             break;
161         case lldb_esp_i386:
162             WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from ESP", m_context.Esp);
163             reg_value.SetUInt32(m_context.Esp);
164             break;
165         case lldb_eip_i386:
166             WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EIP", m_context.Eip);
167             reg_value.SetUInt32(m_context.Eip);
168             break;
169         case lldb_eflags_i386:
170             WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EFLAGS", m_context.EFlags);
171             reg_value.SetUInt32(m_context.EFlags);
172             break;
173         default:
174             WINWARN_IFALL(WINDOWS_LOG_REGISTERS, "Requested unknown register %u", reg);
175             break;
176     }
177     return true;
178 }