1 //===-- RegisterContextWindows_x64.cpp ------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #if defined(__x86_64__) || defined(_M_X64) 10 11 #include "lldb/Host/windows/HostThreadWindows.h" 12 #include "lldb/Host/windows/windows.h" 13 #include "lldb/Utility/RegisterValue.h" 14 #include "lldb/Utility/Status.h" 15 #include "lldb/lldb-private-types.h" 16 17 #include "RegisterContextWindows_x64.h" 18 #include "Plugins/Process/Utility/RegisterContext_x86.h" 19 #include "TargetThreadWindows.h" 20 #include "Plugins/Process/Utility/lldb-x86-register-enums.h" 21 22 #include "llvm/ADT/STLExtras.h" 23 24 using namespace lldb; 25 using namespace lldb_private; 26 27 #define DEFINE_GPR(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatHexUppercase 28 #define DEFINE_GPR_BIN(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatBinary 29 #define DEFINE_FPU_XMM(reg) \ 30 #reg, NULL, 16, 0, eEncodingUint, eFormatVectorOfUInt64, \ 31 {dwarf_##reg##_x86_64, dwarf_##reg##_x86_64, LLDB_INVALID_REGNUM, \ 32 LLDB_INVALID_REGNUM, lldb_##reg##_x86_64}, \ 33 nullptr, nullptr 34 35 namespace { 36 37 // This enum defines the layout of the global RegisterInfo array. This is 38 // necessary because lldb register sets are defined in terms of indices into 39 // the register array. As such, the order of RegisterInfos defined in global 40 // registers array must match the order defined here. When defining the 41 // register set layouts, these values can appear in an arbitrary order, and 42 // that determines the order that register values are displayed in a dump. 43 enum RegisterIndex { 44 eRegisterIndexRax, 45 eRegisterIndexRbx, 46 eRegisterIndexRcx, 47 eRegisterIndexRdx, 48 eRegisterIndexRdi, 49 eRegisterIndexRsi, 50 eRegisterIndexRbp, 51 eRegisterIndexRsp, 52 eRegisterIndexR8, 53 eRegisterIndexR9, 54 eRegisterIndexR10, 55 eRegisterIndexR11, 56 eRegisterIndexR12, 57 eRegisterIndexR13, 58 eRegisterIndexR14, 59 eRegisterIndexR15, 60 eRegisterIndexRip, 61 eRegisterIndexRflags, 62 63 eRegisterIndexXmm0, 64 eRegisterIndexXmm1, 65 eRegisterIndexXmm2, 66 eRegisterIndexXmm3, 67 eRegisterIndexXmm4, 68 eRegisterIndexXmm5, 69 eRegisterIndexXmm6, 70 eRegisterIndexXmm7, 71 eRegisterIndexXmm8, 72 eRegisterIndexXmm9, 73 eRegisterIndexXmm10, 74 eRegisterIndexXmm11, 75 eRegisterIndexXmm12, 76 eRegisterIndexXmm13, 77 eRegisterIndexXmm14, 78 eRegisterIndexXmm15 79 }; 80 81 // Array of all register information supported by Windows x86 82 RegisterInfo g_register_infos[] = { 83 // Macro auto defines most stuff eh_frame DWARF 84 // GENERIC 85 // GDB LLDB VALUE REGS INVALIDATE REGS 86 // ================================ ========================= 87 // ====================== ========================= 88 // =================== ================= ========== =============== 89 {DEFINE_GPR(rax, nullptr), 90 {dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, 91 LLDB_INVALID_REGNUM, lldb_rax_x86_64}, 92 nullptr, 93 nullptr, 94 }, 95 {DEFINE_GPR(rbx, nullptr), 96 {dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, 97 LLDB_INVALID_REGNUM, lldb_rbx_x86_64}, 98 nullptr, 99 nullptr, 100 }, 101 {DEFINE_GPR(rcx, nullptr), 102 {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG1, 103 LLDB_INVALID_REGNUM, lldb_rcx_x86_64}, 104 nullptr, 105 nullptr, 106 }, 107 {DEFINE_GPR(rdx, nullptr), 108 {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG2, 109 LLDB_INVALID_REGNUM, lldb_rdx_x86_64}, 110 nullptr, 111 nullptr, 112 }, 113 {DEFINE_GPR(rdi, nullptr), 114 {dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_INVALID_REGNUM, 115 LLDB_INVALID_REGNUM, lldb_rdi_x86_64}, 116 nullptr, 117 nullptr, 118 }, 119 {DEFINE_GPR(rsi, nullptr), 120 {dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_INVALID_REGNUM, 121 LLDB_INVALID_REGNUM, lldb_rsi_x86_64}, 122 nullptr, 123 nullptr, 124 }, 125 {DEFINE_GPR(rbp, "fp"), 126 {dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, 127 LLDB_INVALID_REGNUM, lldb_rbp_x86_64}, 128 nullptr, 129 nullptr, 130 }, 131 {DEFINE_GPR(rsp, "sp"), 132 {dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, 133 LLDB_INVALID_REGNUM, lldb_rsp_x86_64}, 134 nullptr, 135 nullptr, 136 }, 137 {DEFINE_GPR(r8, nullptr), 138 {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG3, 139 LLDB_INVALID_REGNUM, lldb_r8_x86_64}, 140 nullptr, 141 nullptr, 142 }, 143 {DEFINE_GPR(r9, nullptr), 144 {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG4, 145 LLDB_INVALID_REGNUM, lldb_r9_x86_64}, 146 nullptr, 147 nullptr, 148 }, 149 {DEFINE_GPR(r10, nullptr), 150 {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, 151 LLDB_INVALID_REGNUM, lldb_r10_x86_64}, 152 nullptr, 153 nullptr, 154 }, 155 {DEFINE_GPR(r11, nullptr), 156 {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, 157 LLDB_INVALID_REGNUM, lldb_r11_x86_64}, 158 nullptr, 159 nullptr, 160 }, 161 {DEFINE_GPR(r12, nullptr), 162 {dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, 163 LLDB_INVALID_REGNUM, lldb_r12_x86_64}, 164 nullptr, 165 nullptr, 166 }, 167 {DEFINE_GPR(r13, nullptr), 168 {dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, 169 LLDB_INVALID_REGNUM, lldb_r13_x86_64}, 170 nullptr, 171 nullptr, 172 }, 173 {DEFINE_GPR(r14, nullptr), 174 {dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, 175 LLDB_INVALID_REGNUM, lldb_r14_x86_64}, 176 nullptr, 177 nullptr, 178 }, 179 {DEFINE_GPR(r15, nullptr), 180 {dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, 181 LLDB_INVALID_REGNUM, lldb_r15_x86_64}, 182 nullptr, 183 nullptr, 184 }, 185 {DEFINE_GPR(rip, "pc"), 186 {dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, 187 LLDB_INVALID_REGNUM, lldb_rip_x86_64}, 188 nullptr, 189 nullptr, 190 }, 191 {DEFINE_GPR_BIN(eflags, "flags"), 192 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, 193 LLDB_INVALID_REGNUM, lldb_rflags_x86_64}, 194 nullptr, 195 nullptr, 196 }, 197 {DEFINE_FPU_XMM(xmm0)}, 198 {DEFINE_FPU_XMM(xmm1)}, 199 {DEFINE_FPU_XMM(xmm2)}, 200 {DEFINE_FPU_XMM(xmm3)}, 201 {DEFINE_FPU_XMM(xmm4)}, 202 {DEFINE_FPU_XMM(xmm5)}, 203 {DEFINE_FPU_XMM(xmm6)}, 204 {DEFINE_FPU_XMM(xmm7)}, 205 {DEFINE_FPU_XMM(xmm8)}, 206 {DEFINE_FPU_XMM(xmm9)}, 207 {DEFINE_FPU_XMM(xmm10)}, 208 {DEFINE_FPU_XMM(xmm11)}, 209 {DEFINE_FPU_XMM(xmm12)}, 210 {DEFINE_FPU_XMM(xmm13)}, 211 {DEFINE_FPU_XMM(xmm14)}, 212 {DEFINE_FPU_XMM(xmm15)} 213 }; 214 215 static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos); 216 217 // Array of lldb register numbers used to define the set of all General Purpose 218 // Registers 219 uint32_t g_gpr_reg_indices[] = { 220 eRegisterIndexRax, eRegisterIndexRbx, eRegisterIndexRcx, 221 eRegisterIndexRdx, eRegisterIndexRdi, eRegisterIndexRsi, 222 eRegisterIndexRbp, eRegisterIndexRsp, eRegisterIndexR8, 223 eRegisterIndexR9, eRegisterIndexR10, eRegisterIndexR11, 224 eRegisterIndexR12, eRegisterIndexR13, eRegisterIndexR14, 225 eRegisterIndexR15, eRegisterIndexRip, eRegisterIndexRflags}; 226 227 uint32_t g_fpu_reg_indices[] = { 228 eRegisterIndexXmm0, eRegisterIndexXmm1, eRegisterIndexXmm2, 229 eRegisterIndexXmm3, eRegisterIndexXmm4, eRegisterIndexXmm5, 230 eRegisterIndexXmm6, eRegisterIndexXmm7, eRegisterIndexXmm8, 231 eRegisterIndexXmm9, eRegisterIndexXmm10, eRegisterIndexXmm11, 232 eRegisterIndexXmm12, eRegisterIndexXmm13, eRegisterIndexXmm14, 233 eRegisterIndexXmm15 234 }; 235 236 RegisterSet g_register_sets[] = { 237 {"General Purpose Registers", "gpr", 238 llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices}, 239 {"Floating Point Registers", "fpu", 240 llvm::array_lengthof(g_fpu_reg_indices), g_fpu_reg_indices}}; 241 } 242 243 // Constructors and Destructors 244 RegisterContextWindows_x64::RegisterContextWindows_x64( 245 Thread &thread, uint32_t concrete_frame_idx) 246 : RegisterContextWindows(thread, concrete_frame_idx) {} 247 248 RegisterContextWindows_x64::~RegisterContextWindows_x64() {} 249 250 size_t RegisterContextWindows_x64::GetRegisterCount() { 251 return llvm::array_lengthof(g_register_infos); 252 } 253 254 const RegisterInfo * 255 RegisterContextWindows_x64::GetRegisterInfoAtIndex(size_t reg) { 256 if (reg < k_num_register_infos) 257 return &g_register_infos[reg]; 258 return NULL; 259 } 260 261 size_t RegisterContextWindows_x64::GetRegisterSetCount() { 262 return llvm::array_lengthof(g_register_sets); 263 } 264 265 const RegisterSet *RegisterContextWindows_x64::GetRegisterSet(size_t reg_set) { 266 return &g_register_sets[reg_set]; 267 } 268 269 bool RegisterContextWindows_x64::ReadRegister(const RegisterInfo *reg_info, 270 RegisterValue ®_value) { 271 if (!CacheAllRegisterValues()) 272 return false; 273 274 if (reg_info == nullptr) 275 return false; 276 277 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 278 279 switch (reg) { 280 case lldb_rax_x86_64: 281 reg_value.SetUInt64(m_context.Rax); 282 break; 283 case lldb_rbx_x86_64: 284 reg_value.SetUInt64(m_context.Rbx); 285 break; 286 case lldb_rcx_x86_64: 287 reg_value.SetUInt64(m_context.Rcx); 288 break; 289 case lldb_rdx_x86_64: 290 reg_value.SetUInt64(m_context.Rdx); 291 break; 292 case lldb_rdi_x86_64: 293 reg_value.SetUInt64(m_context.Rdi); 294 break; 295 case lldb_rsi_x86_64: 296 reg_value.SetUInt64(m_context.Rsi); 297 break; 298 case lldb_r8_x86_64: 299 reg_value.SetUInt64(m_context.R8); 300 break; 301 case lldb_r9_x86_64: 302 reg_value.SetUInt64(m_context.R9); 303 break; 304 case lldb_r10_x86_64: 305 reg_value.SetUInt64(m_context.R10); 306 break; 307 case lldb_r11_x86_64: 308 reg_value.SetUInt64(m_context.R11); 309 break; 310 case lldb_r12_x86_64: 311 reg_value.SetUInt64(m_context.R12); 312 break; 313 case lldb_r13_x86_64: 314 reg_value.SetUInt64(m_context.R13); 315 break; 316 case lldb_r14_x86_64: 317 reg_value.SetUInt64(m_context.R14); 318 break; 319 case lldb_r15_x86_64: 320 reg_value.SetUInt64(m_context.R15); 321 break; 322 case lldb_rbp_x86_64: 323 reg_value.SetUInt64(m_context.Rbp); 324 break; 325 case lldb_rsp_x86_64: 326 reg_value.SetUInt64(m_context.Rsp); 327 break; 328 case lldb_rip_x86_64: 329 reg_value.SetUInt64(m_context.Rip); 330 break; 331 case lldb_rflags_x86_64: 332 reg_value.SetUInt64(m_context.EFlags); 333 break; 334 case lldb_xmm0_x86_64: 335 reg_value.SetBytes(&m_context.Xmm0, 336 reg_info->byte_size, endian::InlHostByteOrder()); 337 break; 338 case lldb_xmm1_x86_64: 339 reg_value.SetBytes(&m_context.Xmm1, 340 reg_info->byte_size, endian::InlHostByteOrder()); 341 break; 342 case lldb_xmm2_x86_64: 343 reg_value.SetBytes(&m_context.Xmm2, 344 reg_info->byte_size, endian::InlHostByteOrder()); 345 break; 346 case lldb_xmm3_x86_64: 347 reg_value.SetBytes(&m_context.Xmm3, 348 reg_info->byte_size, endian::InlHostByteOrder()); 349 break; 350 case lldb_xmm4_x86_64: 351 reg_value.SetBytes(&m_context.Xmm4, 352 reg_info->byte_size, endian::InlHostByteOrder()); 353 break; 354 case lldb_xmm5_x86_64: 355 reg_value.SetBytes(&m_context.Xmm5, 356 reg_info->byte_size, endian::InlHostByteOrder()); 357 break; 358 case lldb_xmm6_x86_64: 359 reg_value.SetBytes(&m_context.Xmm6, 360 reg_info->byte_size, endian::InlHostByteOrder()); 361 break; 362 case lldb_xmm7_x86_64: 363 reg_value.SetBytes(&m_context.Xmm7, 364 reg_info->byte_size, endian::InlHostByteOrder()); 365 break; 366 case lldb_xmm8_x86_64: 367 reg_value.SetBytes(&m_context.Xmm8, 368 reg_info->byte_size, endian::InlHostByteOrder()); 369 break; 370 case lldb_xmm9_x86_64: 371 reg_value.SetBytes(&m_context.Xmm9, 372 reg_info->byte_size, endian::InlHostByteOrder()); 373 break; 374 case lldb_xmm10_x86_64: 375 reg_value.SetBytes(&m_context.Xmm10, 376 reg_info->byte_size, endian::InlHostByteOrder()); 377 break; 378 case lldb_xmm11_x86_64: 379 reg_value.SetBytes(&m_context.Xmm11, 380 reg_info->byte_size, endian::InlHostByteOrder()); 381 break; 382 case lldb_xmm12_x86_64: 383 reg_value.SetBytes(&m_context.Xmm12, 384 reg_info->byte_size, endian::InlHostByteOrder()); 385 break; 386 case lldb_xmm13_x86_64: 387 reg_value.SetBytes(&m_context.Xmm13, 388 reg_info->byte_size, endian::InlHostByteOrder()); 389 break; 390 case lldb_xmm14_x86_64: 391 reg_value.SetBytes(&m_context.Xmm14, 392 reg_info->byte_size, endian::InlHostByteOrder()); 393 break; 394 case lldb_xmm15_x86_64: 395 reg_value.SetBytes(&m_context.Xmm15, 396 reg_info->byte_size, endian::InlHostByteOrder()); 397 break; 398 } 399 return true; 400 } 401 402 bool RegisterContextWindows_x64::WriteRegister(const RegisterInfo *reg_info, 403 const RegisterValue ®_value) { 404 // Since we cannot only write a single register value to the inferior, we 405 // need to make sure our cached copy of the register values are fresh. 406 // Otherwise when writing EAX, for example, we may also overwrite some other 407 // register with a stale value. 408 if (!CacheAllRegisterValues()) 409 return false; 410 411 switch (reg_info->kinds[eRegisterKindLLDB]) { 412 case lldb_rax_x86_64: 413 m_context.Rax = reg_value.GetAsUInt64(); 414 break; 415 case lldb_rbx_x86_64: 416 m_context.Rbx = reg_value.GetAsUInt64(); 417 break; 418 case lldb_rcx_x86_64: 419 m_context.Rcx = reg_value.GetAsUInt64(); 420 break; 421 case lldb_rdx_x86_64: 422 m_context.Rdx = reg_value.GetAsUInt64(); 423 break; 424 case lldb_rdi_x86_64: 425 m_context.Rdi = reg_value.GetAsUInt64(); 426 break; 427 case lldb_rsi_x86_64: 428 m_context.Rsi = reg_value.GetAsUInt64(); 429 break; 430 case lldb_r8_x86_64: 431 m_context.R8 = reg_value.GetAsUInt64(); 432 break; 433 case lldb_r9_x86_64: 434 m_context.R9 = reg_value.GetAsUInt64(); 435 break; 436 case lldb_r10_x86_64: 437 m_context.R10 = reg_value.GetAsUInt64(); 438 break; 439 case lldb_r11_x86_64: 440 m_context.R11 = reg_value.GetAsUInt64(); 441 break; 442 case lldb_r12_x86_64: 443 m_context.R12 = reg_value.GetAsUInt64(); 444 break; 445 case lldb_r13_x86_64: 446 m_context.R13 = reg_value.GetAsUInt64(); 447 break; 448 case lldb_r14_x86_64: 449 m_context.R14 = reg_value.GetAsUInt64(); 450 break; 451 case lldb_r15_x86_64: 452 m_context.R15 = reg_value.GetAsUInt64(); 453 break; 454 case lldb_rbp_x86_64: 455 m_context.Rbp = reg_value.GetAsUInt64(); 456 break; 457 case lldb_rsp_x86_64: 458 m_context.Rsp = reg_value.GetAsUInt64(); 459 break; 460 case lldb_rip_x86_64: 461 m_context.Rip = reg_value.GetAsUInt64(); 462 break; 463 case lldb_rflags_x86_64: 464 m_context.EFlags = reg_value.GetAsUInt64(); 465 break; 466 case lldb_xmm0_x86_64: 467 memcpy(&m_context.Xmm0, reg_value.GetBytes(), 16); 468 break; 469 case lldb_xmm1_x86_64: 470 memcpy(&m_context.Xmm1, reg_value.GetBytes(), 16); 471 break; 472 case lldb_xmm2_x86_64: 473 memcpy(&m_context.Xmm2, reg_value.GetBytes(), 16); 474 break; 475 case lldb_xmm3_x86_64: 476 memcpy(&m_context.Xmm3, reg_value.GetBytes(), 16); 477 break; 478 case lldb_xmm4_x86_64: 479 memcpy(&m_context.Xmm4, reg_value.GetBytes(), 16); 480 break; 481 case lldb_xmm5_x86_64: 482 memcpy(&m_context.Xmm5, reg_value.GetBytes(), 16); 483 break; 484 case lldb_xmm6_x86_64: 485 memcpy(&m_context.Xmm6, reg_value.GetBytes(), 16); 486 break; 487 case lldb_xmm7_x86_64: 488 memcpy(&m_context.Xmm7, reg_value.GetBytes(), 16); 489 break; 490 case lldb_xmm8_x86_64: 491 memcpy(&m_context.Xmm8, reg_value.GetBytes(), 16); 492 break; 493 case lldb_xmm9_x86_64: 494 memcpy(&m_context.Xmm9, reg_value.GetBytes(), 16); 495 break; 496 case lldb_xmm10_x86_64: 497 memcpy(&m_context.Xmm10, reg_value.GetBytes(), 16); 498 break; 499 case lldb_xmm11_x86_64: 500 memcpy(&m_context.Xmm11, reg_value.GetBytes(), 16); 501 break; 502 case lldb_xmm12_x86_64: 503 memcpy(&m_context.Xmm12, reg_value.GetBytes(), 16); 504 break; 505 case lldb_xmm13_x86_64: 506 memcpy(&m_context.Xmm13, reg_value.GetBytes(), 16); 507 break; 508 case lldb_xmm14_x86_64: 509 memcpy(&m_context.Xmm14, reg_value.GetBytes(), 16); 510 break; 511 case lldb_xmm15_x86_64: 512 memcpy(&m_context.Xmm15, reg_value.GetBytes(), 16); 513 break; 514 } 515 516 // Physically update the registers in the target process. 517 return ApplyAllRegisterValues(); 518 } 519 520 #endif // defined(__x86_64__) || defined(_M_X64) 521