1 //===-- RegisterContextWindows_x64.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/Core/Error.h" 11 #include "lldb/Core/RegisterValue.h" 12 #include "lldb/Host/windows/HostThreadWindows.h" 13 #include "lldb/Host/windows/windows.h" 14 #include "lldb/lldb-private-types.h" 15 16 #include "RegisterContextWindows_x64.h" 17 #include "RegisterContext_x86.h" 18 #include "TargetThreadWindows.h" 19 #include "lldb-x86-register-enums.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, 8, 0, eEncodingUint, eFormatHexUppercase 27 #define DEFINE_GPR_BIN(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatBinary 28 29 namespace { 30 31 // This enum defines the layout of the global RegisterInfo array. This is 32 // necessary because 33 // lldb register sets are defined in terms of indices into the register array. 34 // As such, the 35 // order of RegisterInfos defined in global registers array must match the order 36 // defined here. 37 // When defining the register set layouts, these values can appear in an 38 // arbitrary order, and that 39 // determines the order that register values are displayed in a dump. 40 enum RegisterIndex { 41 eRegisterIndexRax, 42 eRegisterIndexRbx, 43 eRegisterIndexRcx, 44 eRegisterIndexRdx, 45 eRegisterIndexRdi, 46 eRegisterIndexRsi, 47 eRegisterIndexR8, 48 eRegisterIndexR9, 49 eRegisterIndexR10, 50 eRegisterIndexR11, 51 eRegisterIndexR12, 52 eRegisterIndexR13, 53 eRegisterIndexR14, 54 eRegisterIndexR15, 55 eRegisterIndexRbp, 56 eRegisterIndexRsp, 57 eRegisterIndexRip, 58 eRegisterIndexRflags 59 }; 60 61 // Array of all register information supported by Windows x86 62 RegisterInfo g_register_infos[] = { 63 // Macro auto defines most stuff eh_frame DWARF 64 // GENERIC 65 // GDB LLDB VALUE REGS INVALIDATE REGS 66 // ================================ ========================= 67 // ====================== ========================= 68 // =================== ================= ========== =============== 69 {DEFINE_GPR(rax, nullptr), 70 {dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, 71 LLDB_INVALID_REGNUM, lldb_rax_x86_64}, 72 nullptr, 73 nullptr}, 74 {DEFINE_GPR(rbx, nullptr), 75 {dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, 76 LLDB_INVALID_REGNUM, lldb_rbx_x86_64}, 77 nullptr, 78 nullptr}, 79 {DEFINE_GPR(rcx, nullptr), 80 {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_INVALID_REGNUM, 81 LLDB_INVALID_REGNUM, lldb_rcx_x86_64}, 82 nullptr, 83 nullptr}, 84 {DEFINE_GPR(rdx, nullptr), 85 {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_INVALID_REGNUM, 86 LLDB_INVALID_REGNUM, lldb_rdx_x86_64}, 87 nullptr, 88 nullptr}, 89 {DEFINE_GPR(rdi, nullptr), 90 {dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_INVALID_REGNUM, 91 LLDB_INVALID_REGNUM, lldb_rdi_x86_64}, 92 nullptr, 93 nullptr}, 94 {DEFINE_GPR(rsi, nullptr), 95 {dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_INVALID_REGNUM, 96 LLDB_INVALID_REGNUM, lldb_rsi_x86_64}, 97 nullptr, 98 nullptr}, 99 {DEFINE_GPR(r8, nullptr), 100 {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_INVALID_REGNUM, 101 LLDB_INVALID_REGNUM, lldb_r8_x86_64}, 102 nullptr, 103 nullptr}, 104 {DEFINE_GPR(r9, nullptr), 105 {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_INVALID_REGNUM, 106 LLDB_INVALID_REGNUM, lldb_r9_x86_64}, 107 nullptr, 108 nullptr}, 109 {DEFINE_GPR(r10, nullptr), 110 {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, 111 LLDB_INVALID_REGNUM, lldb_r10_x86_64}, 112 nullptr, 113 nullptr}, 114 {DEFINE_GPR(r11, nullptr), 115 {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, 116 LLDB_INVALID_REGNUM, lldb_r11_x86_64}, 117 nullptr, 118 nullptr}, 119 {DEFINE_GPR(r12, nullptr), 120 {dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, 121 LLDB_INVALID_REGNUM, lldb_r12_x86_64}, 122 nullptr, 123 nullptr}, 124 {DEFINE_GPR(r13, nullptr), 125 {dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, 126 LLDB_INVALID_REGNUM, lldb_r13_x86_64}, 127 nullptr, 128 nullptr}, 129 {DEFINE_GPR(r14, nullptr), 130 {dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, 131 LLDB_INVALID_REGNUM, lldb_r14_x86_64}, 132 nullptr, 133 nullptr}, 134 {DEFINE_GPR(r15, nullptr), 135 {dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, 136 LLDB_INVALID_REGNUM, lldb_r15_x86_64}, 137 nullptr, 138 nullptr}, 139 {DEFINE_GPR(rbp, "fp"), 140 {dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, 141 LLDB_INVALID_REGNUM, lldb_rbp_x86_64}, 142 nullptr, 143 nullptr}, 144 {DEFINE_GPR(rsp, "sp"), 145 {dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, 146 LLDB_INVALID_REGNUM, lldb_rsp_x86_64}, 147 nullptr, 148 nullptr}, 149 {DEFINE_GPR(rip, "pc"), 150 {dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, 151 LLDB_INVALID_REGNUM, lldb_rip_x86_64}, 152 nullptr, 153 nullptr}, 154 {DEFINE_GPR_BIN(eflags, "flags"), 155 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, 156 LLDB_INVALID_REGNUM, lldb_rflags_x86_64}, 157 nullptr, 158 nullptr}, 159 }; 160 161 static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos); 162 163 // Array of lldb register numbers used to define the set of all General Purpose 164 // Registers 165 uint32_t g_gpr_reg_indices[] = { 166 eRegisterIndexRax, eRegisterIndexRbx, eRegisterIndexRcx, 167 eRegisterIndexRdx, eRegisterIndexRdi, eRegisterIndexRsi, 168 eRegisterIndexR8, eRegisterIndexR9, eRegisterIndexR10, 169 eRegisterIndexR11, eRegisterIndexR12, eRegisterIndexR13, 170 eRegisterIndexR14, eRegisterIndexR15, eRegisterIndexRbp, 171 eRegisterIndexRsp, eRegisterIndexRip, eRegisterIndexRflags}; 172 173 RegisterSet g_register_sets[] = { 174 {"General Purpose Registers", "gpr", 175 llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices}, 176 }; 177 } 178 179 //------------------------------------------------------------------ 180 // Constructors and Destructors 181 //------------------------------------------------------------------ 182 RegisterContextWindows_x64::RegisterContextWindows_x64( 183 Thread &thread, uint32_t concrete_frame_idx) 184 : RegisterContextWindows(thread, concrete_frame_idx) {} 185 186 RegisterContextWindows_x64::~RegisterContextWindows_x64() {} 187 188 size_t RegisterContextWindows_x64::GetRegisterCount() { 189 return llvm::array_lengthof(g_register_infos); 190 } 191 192 const RegisterInfo * 193 RegisterContextWindows_x64::GetRegisterInfoAtIndex(size_t reg) { 194 if (reg < k_num_register_infos) 195 return &g_register_infos[reg]; 196 return NULL; 197 } 198 199 size_t RegisterContextWindows_x64::GetRegisterSetCount() { 200 return llvm::array_lengthof(g_register_sets); 201 } 202 203 const RegisterSet *RegisterContextWindows_x64::GetRegisterSet(size_t reg_set) { 204 return &g_register_sets[reg_set]; 205 } 206 207 bool RegisterContextWindows_x64::ReadRegister(const RegisterInfo *reg_info, 208 RegisterValue ®_value) { 209 if (!CacheAllRegisterValues()) 210 return false; 211 212 switch (reg_info->kinds[eRegisterKindLLDB]) { 213 case lldb_rax_x86_64: 214 reg_value.SetUInt64(m_context.Rax); 215 break; 216 case lldb_rbx_x86_64: 217 reg_value.SetUInt64(m_context.Rbx); 218 break; 219 case lldb_rcx_x86_64: 220 reg_value.SetUInt64(m_context.Rcx); 221 break; 222 case lldb_rdx_x86_64: 223 reg_value.SetUInt64(m_context.Rdx); 224 break; 225 case lldb_rdi_x86_64: 226 reg_value.SetUInt64(m_context.Rdi); 227 break; 228 case lldb_rsi_x86_64: 229 reg_value.SetUInt64(m_context.Rsi); 230 break; 231 case lldb_r8_x86_64: 232 reg_value.SetUInt64(m_context.R8); 233 break; 234 case lldb_r9_x86_64: 235 reg_value.SetUInt64(m_context.R9); 236 break; 237 case lldb_r10_x86_64: 238 reg_value.SetUInt64(m_context.R10); 239 break; 240 case lldb_r11_x86_64: 241 reg_value.SetUInt64(m_context.R11); 242 break; 243 case lldb_r12_x86_64: 244 reg_value.SetUInt64(m_context.R12); 245 break; 246 case lldb_r13_x86_64: 247 reg_value.SetUInt64(m_context.R13); 248 break; 249 case lldb_r14_x86_64: 250 reg_value.SetUInt64(m_context.R14); 251 break; 252 case lldb_r15_x86_64: 253 reg_value.SetUInt64(m_context.R15); 254 break; 255 case lldb_rbp_x86_64: 256 reg_value.SetUInt64(m_context.Rbp); 257 break; 258 case lldb_rsp_x86_64: 259 reg_value.SetUInt64(m_context.Rsp); 260 break; 261 case lldb_rip_x86_64: 262 reg_value.SetUInt64(m_context.Rip); 263 break; 264 case lldb_rflags_x86_64: 265 reg_value.SetUInt64(m_context.EFlags); 266 break; 267 } 268 return true; 269 } 270 271 bool RegisterContextWindows_x64::WriteRegister(const RegisterInfo *reg_info, 272 const RegisterValue ®_value) { 273 // Since we cannot only write a single register value to the inferior, we need 274 // to make sure 275 // our cached copy of the register values are fresh. Otherwise when writing 276 // EAX, for example, 277 // we may also overwrite some other register with a stale value. 278 if (!CacheAllRegisterValues()) 279 return false; 280 281 switch (reg_info->kinds[eRegisterKindLLDB]) { 282 case lldb_rax_x86_64: 283 m_context.Rax = reg_value.GetAsUInt64(); 284 break; 285 case lldb_rbx_x86_64: 286 m_context.Rbx = reg_value.GetAsUInt64(); 287 break; 288 case lldb_rcx_x86_64: 289 m_context.Rcx = reg_value.GetAsUInt64(); 290 break; 291 case lldb_rdx_x86_64: 292 m_context.Rdx = reg_value.GetAsUInt64(); 293 break; 294 case lldb_rdi_x86_64: 295 m_context.Rdi = reg_value.GetAsUInt64(); 296 break; 297 case lldb_rsi_x86_64: 298 m_context.Rsi = reg_value.GetAsUInt64(); 299 break; 300 case lldb_r8_x86_64: 301 m_context.R8 = reg_value.GetAsUInt64(); 302 break; 303 case lldb_r9_x86_64: 304 m_context.R9 = reg_value.GetAsUInt64(); 305 break; 306 case lldb_r10_x86_64: 307 m_context.R10 = reg_value.GetAsUInt64(); 308 break; 309 case lldb_r11_x86_64: 310 m_context.R11 = reg_value.GetAsUInt64(); 311 break; 312 case lldb_r12_x86_64: 313 m_context.R12 = reg_value.GetAsUInt64(); 314 break; 315 case lldb_r13_x86_64: 316 m_context.R13 = reg_value.GetAsUInt64(); 317 break; 318 case lldb_r14_x86_64: 319 m_context.R14 = reg_value.GetAsUInt64(); 320 break; 321 case lldb_r15_x86_64: 322 m_context.R15 = reg_value.GetAsUInt64(); 323 break; 324 case lldb_rbp_x86_64: 325 m_context.Rbp = reg_value.GetAsUInt64(); 326 break; 327 case lldb_rsp_x86_64: 328 m_context.Rsp = reg_value.GetAsUInt64(); 329 break; 330 case lldb_rip_x86_64: 331 m_context.Rip = reg_value.GetAsUInt64(); 332 break; 333 case lldb_rflags_x86_64: 334 m_context.EFlags = reg_value.GetAsUInt64(); 335 break; 336 } 337 338 // Physically update the registers in the target process. 339 TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread); 340 return ::SetThreadContext( 341 wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context); 342 } 343