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, nullptr, 0 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 nullptr, 95 0}, 96 {DEFINE_GPR(rbx, nullptr), 97 {dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, 98 LLDB_INVALID_REGNUM, lldb_rbx_x86_64}, 99 nullptr, 100 nullptr, 101 nullptr, 102 0}, 103 {DEFINE_GPR(rcx, nullptr), 104 {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG1, 105 LLDB_INVALID_REGNUM, lldb_rcx_x86_64}, 106 nullptr, 107 nullptr, 108 nullptr, 109 0}, 110 {DEFINE_GPR(rdx, nullptr), 111 {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG2, 112 LLDB_INVALID_REGNUM, lldb_rdx_x86_64}, 113 nullptr, 114 nullptr, 115 nullptr, 116 0}, 117 {DEFINE_GPR(rdi, nullptr), 118 {dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_INVALID_REGNUM, 119 LLDB_INVALID_REGNUM, lldb_rdi_x86_64}, 120 nullptr, 121 nullptr, 122 nullptr, 123 0}, 124 {DEFINE_GPR(rsi, nullptr), 125 {dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_INVALID_REGNUM, 126 LLDB_INVALID_REGNUM, lldb_rsi_x86_64}, 127 nullptr, 128 nullptr, 129 nullptr, 130 0}, 131 {DEFINE_GPR(rbp, "fp"), 132 {dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, 133 LLDB_INVALID_REGNUM, lldb_rbp_x86_64}, 134 nullptr, 135 nullptr, 136 nullptr, 137 0}, 138 {DEFINE_GPR(rsp, "sp"), 139 {dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, 140 LLDB_INVALID_REGNUM, lldb_rsp_x86_64}, 141 nullptr, 142 nullptr, 143 nullptr, 144 0}, 145 {DEFINE_GPR(r8, nullptr), 146 {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG3, 147 LLDB_INVALID_REGNUM, lldb_r8_x86_64}, 148 nullptr, 149 nullptr, 150 nullptr, 151 0}, 152 {DEFINE_GPR(r9, nullptr), 153 {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG4, 154 LLDB_INVALID_REGNUM, lldb_r9_x86_64}, 155 nullptr, 156 nullptr, 157 nullptr, 158 0}, 159 {DEFINE_GPR(r10, nullptr), 160 {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, 161 LLDB_INVALID_REGNUM, lldb_r10_x86_64}, 162 nullptr, 163 nullptr, 164 nullptr, 165 0}, 166 {DEFINE_GPR(r11, nullptr), 167 {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, 168 LLDB_INVALID_REGNUM, lldb_r11_x86_64}, 169 nullptr, 170 nullptr, 171 nullptr, 172 0}, 173 {DEFINE_GPR(r12, nullptr), 174 {dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, 175 LLDB_INVALID_REGNUM, lldb_r12_x86_64}, 176 nullptr, 177 nullptr, 178 nullptr, 179 0}, 180 {DEFINE_GPR(r13, nullptr), 181 {dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, 182 LLDB_INVALID_REGNUM, lldb_r13_x86_64}, 183 nullptr, 184 nullptr, 185 nullptr, 186 0}, 187 {DEFINE_GPR(r14, nullptr), 188 {dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, 189 LLDB_INVALID_REGNUM, lldb_r14_x86_64}, 190 nullptr, 191 nullptr, 192 nullptr, 193 0}, 194 {DEFINE_GPR(r15, nullptr), 195 {dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, 196 LLDB_INVALID_REGNUM, lldb_r15_x86_64}, 197 nullptr, 198 nullptr, 199 nullptr, 200 0}, 201 {DEFINE_GPR(rip, "pc"), 202 {dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, 203 LLDB_INVALID_REGNUM, lldb_rip_x86_64}, 204 nullptr, 205 nullptr, 206 nullptr, 207 0}, 208 {DEFINE_GPR_BIN(eflags, "flags"), 209 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, 210 LLDB_INVALID_REGNUM, lldb_rflags_x86_64}, 211 nullptr, 212 nullptr, 213 nullptr, 214 0}, 215 {DEFINE_FPU_XMM(xmm0)}, 216 {DEFINE_FPU_XMM(xmm1)}, 217 {DEFINE_FPU_XMM(xmm2)}, 218 {DEFINE_FPU_XMM(xmm3)}, 219 {DEFINE_FPU_XMM(xmm4)}, 220 {DEFINE_FPU_XMM(xmm5)}, 221 {DEFINE_FPU_XMM(xmm6)}, 222 {DEFINE_FPU_XMM(xmm7)}, 223 {DEFINE_FPU_XMM(xmm8)}, 224 {DEFINE_FPU_XMM(xmm9)}, 225 {DEFINE_FPU_XMM(xmm10)}, 226 {DEFINE_FPU_XMM(xmm11)}, 227 {DEFINE_FPU_XMM(xmm12)}, 228 {DEFINE_FPU_XMM(xmm13)}, 229 {DEFINE_FPU_XMM(xmm14)}, 230 {DEFINE_FPU_XMM(xmm15)} 231 }; 232 233 static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos); 234 235 // Array of lldb register numbers used to define the set of all General Purpose 236 // Registers 237 uint32_t g_gpr_reg_indices[] = { 238 eRegisterIndexRax, eRegisterIndexRbx, eRegisterIndexRcx, 239 eRegisterIndexRdx, eRegisterIndexRdi, eRegisterIndexRsi, 240 eRegisterIndexRbp, eRegisterIndexRsp, eRegisterIndexR8, 241 eRegisterIndexR9, eRegisterIndexR10, eRegisterIndexR11, 242 eRegisterIndexR12, eRegisterIndexR13, eRegisterIndexR14, 243 eRegisterIndexR15, eRegisterIndexRip, eRegisterIndexRflags}; 244 245 uint32_t g_fpu_reg_indices[] = { 246 eRegisterIndexXmm0, eRegisterIndexXmm1, eRegisterIndexXmm2, 247 eRegisterIndexXmm3, eRegisterIndexXmm4, eRegisterIndexXmm5, 248 eRegisterIndexXmm6, eRegisterIndexXmm7, eRegisterIndexXmm8, 249 eRegisterIndexXmm9, eRegisterIndexXmm10, eRegisterIndexXmm11, 250 eRegisterIndexXmm12, eRegisterIndexXmm13, eRegisterIndexXmm14, 251 eRegisterIndexXmm15 252 }; 253 254 RegisterSet g_register_sets[] = { 255 {"General Purpose Registers", "gpr", 256 llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices}, 257 {"Floating Point Registers", "fpu", 258 llvm::array_lengthof(g_fpu_reg_indices), g_fpu_reg_indices}}; 259 } 260 261 // Constructors and Destructors 262 RegisterContextWindows_x64::RegisterContextWindows_x64( 263 Thread &thread, uint32_t concrete_frame_idx) 264 : RegisterContextWindows(thread, concrete_frame_idx) {} 265 266 RegisterContextWindows_x64::~RegisterContextWindows_x64() {} 267 268 size_t RegisterContextWindows_x64::GetRegisterCount() { 269 return llvm::array_lengthof(g_register_infos); 270 } 271 272 const RegisterInfo * 273 RegisterContextWindows_x64::GetRegisterInfoAtIndex(size_t reg) { 274 if (reg < k_num_register_infos) 275 return &g_register_infos[reg]; 276 return NULL; 277 } 278 279 size_t RegisterContextWindows_x64::GetRegisterSetCount() { 280 return llvm::array_lengthof(g_register_sets); 281 } 282 283 const RegisterSet *RegisterContextWindows_x64::GetRegisterSet(size_t reg_set) { 284 return &g_register_sets[reg_set]; 285 } 286 287 bool RegisterContextWindows_x64::ReadRegister(const RegisterInfo *reg_info, 288 RegisterValue ®_value) { 289 if (!CacheAllRegisterValues()) 290 return false; 291 292 if (reg_info == nullptr) 293 return false; 294 295 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 296 297 switch (reg) { 298 case lldb_rax_x86_64: 299 reg_value.SetUInt64(m_context.Rax); 300 break; 301 case lldb_rbx_x86_64: 302 reg_value.SetUInt64(m_context.Rbx); 303 break; 304 case lldb_rcx_x86_64: 305 reg_value.SetUInt64(m_context.Rcx); 306 break; 307 case lldb_rdx_x86_64: 308 reg_value.SetUInt64(m_context.Rdx); 309 break; 310 case lldb_rdi_x86_64: 311 reg_value.SetUInt64(m_context.Rdi); 312 break; 313 case lldb_rsi_x86_64: 314 reg_value.SetUInt64(m_context.Rsi); 315 break; 316 case lldb_r8_x86_64: 317 reg_value.SetUInt64(m_context.R8); 318 break; 319 case lldb_r9_x86_64: 320 reg_value.SetUInt64(m_context.R9); 321 break; 322 case lldb_r10_x86_64: 323 reg_value.SetUInt64(m_context.R10); 324 break; 325 case lldb_r11_x86_64: 326 reg_value.SetUInt64(m_context.R11); 327 break; 328 case lldb_r12_x86_64: 329 reg_value.SetUInt64(m_context.R12); 330 break; 331 case lldb_r13_x86_64: 332 reg_value.SetUInt64(m_context.R13); 333 break; 334 case lldb_r14_x86_64: 335 reg_value.SetUInt64(m_context.R14); 336 break; 337 case lldb_r15_x86_64: 338 reg_value.SetUInt64(m_context.R15); 339 break; 340 case lldb_rbp_x86_64: 341 reg_value.SetUInt64(m_context.Rbp); 342 break; 343 case lldb_rsp_x86_64: 344 reg_value.SetUInt64(m_context.Rsp); 345 break; 346 case lldb_rip_x86_64: 347 reg_value.SetUInt64(m_context.Rip); 348 break; 349 case lldb_rflags_x86_64: 350 reg_value.SetUInt64(m_context.EFlags); 351 break; 352 case lldb_xmm0_x86_64: 353 reg_value.SetBytes(&m_context.Xmm0, 354 reg_info->byte_size, endian::InlHostByteOrder()); 355 break; 356 case lldb_xmm1_x86_64: 357 reg_value.SetBytes(&m_context.Xmm1, 358 reg_info->byte_size, endian::InlHostByteOrder()); 359 break; 360 case lldb_xmm2_x86_64: 361 reg_value.SetBytes(&m_context.Xmm2, 362 reg_info->byte_size, endian::InlHostByteOrder()); 363 break; 364 case lldb_xmm3_x86_64: 365 reg_value.SetBytes(&m_context.Xmm3, 366 reg_info->byte_size, endian::InlHostByteOrder()); 367 break; 368 case lldb_xmm4_x86_64: 369 reg_value.SetBytes(&m_context.Xmm4, 370 reg_info->byte_size, endian::InlHostByteOrder()); 371 break; 372 case lldb_xmm5_x86_64: 373 reg_value.SetBytes(&m_context.Xmm5, 374 reg_info->byte_size, endian::InlHostByteOrder()); 375 break; 376 case lldb_xmm6_x86_64: 377 reg_value.SetBytes(&m_context.Xmm6, 378 reg_info->byte_size, endian::InlHostByteOrder()); 379 break; 380 case lldb_xmm7_x86_64: 381 reg_value.SetBytes(&m_context.Xmm7, 382 reg_info->byte_size, endian::InlHostByteOrder()); 383 break; 384 case lldb_xmm8_x86_64: 385 reg_value.SetBytes(&m_context.Xmm8, 386 reg_info->byte_size, endian::InlHostByteOrder()); 387 break; 388 case lldb_xmm9_x86_64: 389 reg_value.SetBytes(&m_context.Xmm9, 390 reg_info->byte_size, endian::InlHostByteOrder()); 391 break; 392 case lldb_xmm10_x86_64: 393 reg_value.SetBytes(&m_context.Xmm10, 394 reg_info->byte_size, endian::InlHostByteOrder()); 395 break; 396 case lldb_xmm11_x86_64: 397 reg_value.SetBytes(&m_context.Xmm11, 398 reg_info->byte_size, endian::InlHostByteOrder()); 399 break; 400 case lldb_xmm12_x86_64: 401 reg_value.SetBytes(&m_context.Xmm12, 402 reg_info->byte_size, endian::InlHostByteOrder()); 403 break; 404 case lldb_xmm13_x86_64: 405 reg_value.SetBytes(&m_context.Xmm13, 406 reg_info->byte_size, endian::InlHostByteOrder()); 407 break; 408 case lldb_xmm14_x86_64: 409 reg_value.SetBytes(&m_context.Xmm14, 410 reg_info->byte_size, endian::InlHostByteOrder()); 411 break; 412 case lldb_xmm15_x86_64: 413 reg_value.SetBytes(&m_context.Xmm15, 414 reg_info->byte_size, endian::InlHostByteOrder()); 415 break; 416 } 417 return true; 418 } 419 420 bool RegisterContextWindows_x64::WriteRegister(const RegisterInfo *reg_info, 421 const RegisterValue ®_value) { 422 // Since we cannot only write a single register value to the inferior, we 423 // need to make sure our cached copy of the register values are fresh. 424 // Otherwise when writing EAX, for example, we may also overwrite some other 425 // register with a stale value. 426 if (!CacheAllRegisterValues()) 427 return false; 428 429 switch (reg_info->kinds[eRegisterKindLLDB]) { 430 case lldb_rax_x86_64: 431 m_context.Rax = reg_value.GetAsUInt64(); 432 break; 433 case lldb_rbx_x86_64: 434 m_context.Rbx = reg_value.GetAsUInt64(); 435 break; 436 case lldb_rcx_x86_64: 437 m_context.Rcx = reg_value.GetAsUInt64(); 438 break; 439 case lldb_rdx_x86_64: 440 m_context.Rdx = reg_value.GetAsUInt64(); 441 break; 442 case lldb_rdi_x86_64: 443 m_context.Rdi = reg_value.GetAsUInt64(); 444 break; 445 case lldb_rsi_x86_64: 446 m_context.Rsi = reg_value.GetAsUInt64(); 447 break; 448 case lldb_r8_x86_64: 449 m_context.R8 = reg_value.GetAsUInt64(); 450 break; 451 case lldb_r9_x86_64: 452 m_context.R9 = reg_value.GetAsUInt64(); 453 break; 454 case lldb_r10_x86_64: 455 m_context.R10 = reg_value.GetAsUInt64(); 456 break; 457 case lldb_r11_x86_64: 458 m_context.R11 = reg_value.GetAsUInt64(); 459 break; 460 case lldb_r12_x86_64: 461 m_context.R12 = reg_value.GetAsUInt64(); 462 break; 463 case lldb_r13_x86_64: 464 m_context.R13 = reg_value.GetAsUInt64(); 465 break; 466 case lldb_r14_x86_64: 467 m_context.R14 = reg_value.GetAsUInt64(); 468 break; 469 case lldb_r15_x86_64: 470 m_context.R15 = reg_value.GetAsUInt64(); 471 break; 472 case lldb_rbp_x86_64: 473 m_context.Rbp = reg_value.GetAsUInt64(); 474 break; 475 case lldb_rsp_x86_64: 476 m_context.Rsp = reg_value.GetAsUInt64(); 477 break; 478 case lldb_rip_x86_64: 479 m_context.Rip = reg_value.GetAsUInt64(); 480 break; 481 case lldb_rflags_x86_64: 482 m_context.EFlags = reg_value.GetAsUInt64(); 483 break; 484 case lldb_xmm0_x86_64: 485 memcpy(&m_context.Xmm0, reg_value.GetBytes(), 16); 486 break; 487 case lldb_xmm1_x86_64: 488 memcpy(&m_context.Xmm1, reg_value.GetBytes(), 16); 489 break; 490 case lldb_xmm2_x86_64: 491 memcpy(&m_context.Xmm2, reg_value.GetBytes(), 16); 492 break; 493 case lldb_xmm3_x86_64: 494 memcpy(&m_context.Xmm3, reg_value.GetBytes(), 16); 495 break; 496 case lldb_xmm4_x86_64: 497 memcpy(&m_context.Xmm4, reg_value.GetBytes(), 16); 498 break; 499 case lldb_xmm5_x86_64: 500 memcpy(&m_context.Xmm5, reg_value.GetBytes(), 16); 501 break; 502 case lldb_xmm6_x86_64: 503 memcpy(&m_context.Xmm6, reg_value.GetBytes(), 16); 504 break; 505 case lldb_xmm7_x86_64: 506 memcpy(&m_context.Xmm7, reg_value.GetBytes(), 16); 507 break; 508 case lldb_xmm8_x86_64: 509 memcpy(&m_context.Xmm8, reg_value.GetBytes(), 16); 510 break; 511 case lldb_xmm9_x86_64: 512 memcpy(&m_context.Xmm9, reg_value.GetBytes(), 16); 513 break; 514 case lldb_xmm10_x86_64: 515 memcpy(&m_context.Xmm10, reg_value.GetBytes(), 16); 516 break; 517 case lldb_xmm11_x86_64: 518 memcpy(&m_context.Xmm11, reg_value.GetBytes(), 16); 519 break; 520 case lldb_xmm12_x86_64: 521 memcpy(&m_context.Xmm12, reg_value.GetBytes(), 16); 522 break; 523 case lldb_xmm13_x86_64: 524 memcpy(&m_context.Xmm13, reg_value.GetBytes(), 16); 525 break; 526 case lldb_xmm14_x86_64: 527 memcpy(&m_context.Xmm14, reg_value.GetBytes(), 16); 528 break; 529 case lldb_xmm15_x86_64: 530 memcpy(&m_context.Xmm15, reg_value.GetBytes(), 16); 531 break; 532 } 533 534 // Physically update the registers in the target process. 535 return ApplyAllRegisterValues(); 536 } 537 538 #endif // defined(__x86_64__) || defined(_M_X64) 539