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