| 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, generic) \ |
| 28 | { \ |
| 29 | #reg, alt, 8, 0, eEncodingUint, eFormatHexUppercase, \ |
| 30 | {dwarf_##reg##_x86_64, dwarf_##reg##_x86_64, generic, \ |
| 31 | LLDB_INVALID_REGNUM, lldb_##reg##_x86_64 }, \ |
| 32 | nullptr, nullptr, nullptr, \ |
| 33 | } |
| 34 | |
| 35 | #define DEFINE_GPR_BIN(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatBinary |
| 36 | #define DEFINE_FPU_XMM(reg) \ |
| 37 | #reg, NULL, 16, 0, eEncodingUint, eFormatVectorOfUInt64, \ |
| 38 | {dwarf_##reg##_x86_64, dwarf_##reg##_x86_64, LLDB_INVALID_REGNUM, \ |
| 39 | LLDB_INVALID_REGNUM, lldb_##reg##_x86_64}, \ |
| 40 | nullptr, nullptr, nullptr, |
| 41 | |
| 42 | #define DEFINE_GPR_PSEUDO_32(reg) \ |
| 43 | { \ |
| 44 | #reg, nullptr, 4, 0, eEncodingUint, eFormatHexUppercase, \ |
| 45 | {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ |
| 46 | LLDB_INVALID_REGNUM, lldb_##reg##_x86_64 }, \ |
| 47 | nullptr, nullptr, nullptr, \ |
| 48 | } |
| 49 | |
| 50 | #define DEFINE_GPR_PSEUDO_16(reg) \ |
| 51 | { \ |
| 52 | #reg, nullptr, 2, 0, eEncodingUint, eFormatHexUppercase, \ |
| 53 | {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ |
| 54 | LLDB_INVALID_REGNUM, lldb_##reg##_x86_64 }, \ |
| 55 | nullptr, nullptr, nullptr, \ |
| 56 | } |
| 57 | |
| 58 | #define DEFINE_GPR_PSEUDO_8(reg) \ |
| 59 | { \ |
| 60 | #reg, nullptr, 1, 0, eEncodingUint, eFormatHexUppercase, \ |
| 61 | {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ |
| 62 | LLDB_INVALID_REGNUM, lldb_##reg##_x86_64 }, \ |
| 63 | nullptr, nullptr, nullptr, \ |
| 64 | } |
| 65 | |
| 66 | namespace { |
| 67 | |
| 68 | // This enum defines the layout of the global RegisterInfo array. This is |
| 69 | // necessary because lldb register sets are defined in terms of indices into |
| 70 | // the register array. As such, the order of RegisterInfos defined in global |
| 71 | // registers array must match the order defined here. When defining the |
| 72 | // register set layouts, these values can appear in an arbitrary order, and |
| 73 | // that determines the order that register values are displayed in a dump. |
| 74 | enum RegisterIndex { |
| 75 | eRegisterIndexRax, |
| 76 | eRegisterIndexRbx, |
| 77 | eRegisterIndexRcx, |
| 78 | eRegisterIndexRdx, |
| 79 | eRegisterIndexRdi, |
| 80 | eRegisterIndexRsi, |
| 81 | eRegisterIndexRbp, |
| 82 | eRegisterIndexRsp, |
| 83 | eRegisterIndexR8, |
| 84 | eRegisterIndexR9, |
| 85 | eRegisterIndexR10, |
| 86 | eRegisterIndexR11, |
| 87 | eRegisterIndexR12, |
| 88 | eRegisterIndexR13, |
| 89 | eRegisterIndexR14, |
| 90 | eRegisterIndexR15, |
| 91 | eRegisterIndexRip, |
| 92 | eRegisterIndexRflags, |
| 93 | eRegisterIndexEax, |
| 94 | eRegisterIndexEbx, |
| 95 | eRegisterIndexEcx, |
| 96 | eRegisterIndexEdx, |
| 97 | eRegisterIndexEdi, |
| 98 | eRegisterIndexEsi, |
| 99 | eRegisterIndexEbp, |
| 100 | eRegisterIndexEsp, |
| 101 | eRegisterIndexR8d, |
| 102 | eRegisterIndexR9d, |
| 103 | eRegisterIndexR10d, |
| 104 | eRegisterIndexR11d, |
| 105 | eRegisterIndexR12d, |
| 106 | eRegisterIndexR13d, |
| 107 | eRegisterIndexR14d, |
| 108 | eRegisterIndexR15d, |
| 109 | eRegisterIndexAx, |
| 110 | eRegisterIndexBx, |
| 111 | eRegisterIndexCx, |
| 112 | eRegisterIndexDx, |
| 113 | eRegisterIndexDi, |
| 114 | eRegisterIndexSi, |
| 115 | eRegisterIndexBp, |
| 116 | eRegisterIndexSp, |
| 117 | eRegisterIndexR8w, |
| 118 | eRegisterIndexR9w, |
| 119 | eRegisterIndexR10w, |
| 120 | eRegisterIndexR11w, |
| 121 | eRegisterIndexR12w, |
| 122 | eRegisterIndexR13w, |
| 123 | eRegisterIndexR14w, |
| 124 | eRegisterIndexR15w, |
| 125 | eRegisterIndexAh, |
| 126 | eRegisterIndexBh, |
| 127 | eRegisterIndexCh, |
| 128 | eRegisterIndexDh, |
| 129 | eRegisterIndexAl, |
| 130 | eRegisterIndexBl, |
| 131 | eRegisterIndexCl, |
| 132 | eRegisterIndexDl, |
| 133 | eRegisterIndexDil, |
| 134 | eRegisterIndexSil, |
| 135 | eRegisterIndexBpl, |
| 136 | eRegisterIndexSpl, |
| 137 | eRegisterIndexR8l, |
| 138 | eRegisterIndexR9l, |
| 139 | eRegisterIndexR10l, |
| 140 | eRegisterIndexR11l, |
| 141 | eRegisterIndexR12l, |
| 142 | eRegisterIndexR13l, |
| 143 | eRegisterIndexR14l, |
| 144 | eRegisterIndexR15l, |
| 145 | |
| 146 | eRegisterIndexXmm0, |
| 147 | eRegisterIndexXmm1, |
| 148 | eRegisterIndexXmm2, |
| 149 | eRegisterIndexXmm3, |
| 150 | eRegisterIndexXmm4, |
| 151 | eRegisterIndexXmm5, |
| 152 | eRegisterIndexXmm6, |
| 153 | eRegisterIndexXmm7, |
| 154 | eRegisterIndexXmm8, |
| 155 | eRegisterIndexXmm9, |
| 156 | eRegisterIndexXmm10, |
| 157 | eRegisterIndexXmm11, |
| 158 | eRegisterIndexXmm12, |
| 159 | eRegisterIndexXmm13, |
| 160 | eRegisterIndexXmm14, |
| 161 | eRegisterIndexXmm15 |
| 162 | }; |
| 163 | |
| 164 | // Array of all register information supported by Windows x86 |
| 165 | RegisterInfo g_register_infos[] = { |
| 166 | DEFINE_GPR(rax, nullptr, LLDB_INVALID_REGNUM), |
| 167 | DEFINE_GPR(rbx, nullptr, LLDB_INVALID_REGNUM), |
| 168 | DEFINE_GPR(rcx, nullptr, LLDB_REGNUM_GENERIC_ARG1), |
| 169 | DEFINE_GPR(rdx, nullptr, LLDB_REGNUM_GENERIC_ARG2), |
| 170 | DEFINE_GPR(rdi, nullptr, LLDB_INVALID_REGNUM), |
| 171 | DEFINE_GPR(rsi, nullptr, LLDB_INVALID_REGNUM), |
| 172 | DEFINE_GPR(rbp, "fp" , LLDB_REGNUM_GENERIC_FP), |
| 173 | DEFINE_GPR(rsp, "sp" , LLDB_REGNUM_GENERIC_SP), |
| 174 | DEFINE_GPR(r8, nullptr, LLDB_REGNUM_GENERIC_ARG3), |
| 175 | DEFINE_GPR(r9, nullptr, LLDB_REGNUM_GENERIC_ARG4), |
| 176 | DEFINE_GPR(r10, nullptr, LLDB_INVALID_REGNUM), |
| 177 | DEFINE_GPR(r11, nullptr, LLDB_INVALID_REGNUM), |
| 178 | DEFINE_GPR(r12, nullptr, LLDB_INVALID_REGNUM), |
| 179 | DEFINE_GPR(r13, nullptr, LLDB_INVALID_REGNUM), |
| 180 | DEFINE_GPR(r14, nullptr, LLDB_INVALID_REGNUM), |
| 181 | DEFINE_GPR(r15, nullptr, LLDB_INVALID_REGNUM), |
| 182 | DEFINE_GPR(rip, "pc" , LLDB_REGNUM_GENERIC_PC), |
| 183 | { |
| 184 | DEFINE_GPR_BIN(eflags, "flags" ), |
| 185 | .kinds: {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, |
| 186 | LLDB_INVALID_REGNUM, lldb_rflags_x86_64}, |
| 187 | .value_regs: nullptr, |
| 188 | .invalidate_regs: nullptr, |
| 189 | .flags_type: nullptr, |
| 190 | }, |
| 191 | DEFINE_GPR_PSEUDO_32(eax), |
| 192 | DEFINE_GPR_PSEUDO_32(ebx), |
| 193 | DEFINE_GPR_PSEUDO_32(ecx), |
| 194 | DEFINE_GPR_PSEUDO_32(edx), |
| 195 | DEFINE_GPR_PSEUDO_32(edi), |
| 196 | DEFINE_GPR_PSEUDO_32(esi), |
| 197 | DEFINE_GPR_PSEUDO_32(ebp), |
| 198 | DEFINE_GPR_PSEUDO_32(esp), |
| 199 | DEFINE_GPR_PSEUDO_32(r8d), |
| 200 | DEFINE_GPR_PSEUDO_32(r9d), |
| 201 | DEFINE_GPR_PSEUDO_32(r10d), |
| 202 | DEFINE_GPR_PSEUDO_32(r11d), |
| 203 | DEFINE_GPR_PSEUDO_32(r12d), |
| 204 | DEFINE_GPR_PSEUDO_32(r13d), |
| 205 | DEFINE_GPR_PSEUDO_32(r14d), |
| 206 | DEFINE_GPR_PSEUDO_32(r15d), |
| 207 | DEFINE_GPR_PSEUDO_16(ax), |
| 208 | DEFINE_GPR_PSEUDO_16(bx), |
| 209 | DEFINE_GPR_PSEUDO_16(cx), |
| 210 | DEFINE_GPR_PSEUDO_16(dx), |
| 211 | DEFINE_GPR_PSEUDO_16(di), |
| 212 | DEFINE_GPR_PSEUDO_16(si), |
| 213 | DEFINE_GPR_PSEUDO_16(bp), |
| 214 | DEFINE_GPR_PSEUDO_16(sp), |
| 215 | DEFINE_GPR_PSEUDO_16(r8w), |
| 216 | DEFINE_GPR_PSEUDO_16(r9w), |
| 217 | DEFINE_GPR_PSEUDO_16(r10w), |
| 218 | DEFINE_GPR_PSEUDO_16(r11w), |
| 219 | DEFINE_GPR_PSEUDO_16(r12w), |
| 220 | DEFINE_GPR_PSEUDO_16(r13w), |
| 221 | DEFINE_GPR_PSEUDO_16(r14w), |
| 222 | DEFINE_GPR_PSEUDO_16(r15w), |
| 223 | DEFINE_GPR_PSEUDO_8(ah), |
| 224 | DEFINE_GPR_PSEUDO_8(bh), |
| 225 | DEFINE_GPR_PSEUDO_8(ch), |
| 226 | DEFINE_GPR_PSEUDO_8(dh), |
| 227 | DEFINE_GPR_PSEUDO_8(al), |
| 228 | DEFINE_GPR_PSEUDO_8(bl), |
| 229 | DEFINE_GPR_PSEUDO_8(cl), |
| 230 | DEFINE_GPR_PSEUDO_8(dl), |
| 231 | DEFINE_GPR_PSEUDO_8(dil), |
| 232 | DEFINE_GPR_PSEUDO_8(sil), |
| 233 | DEFINE_GPR_PSEUDO_8(bpl), |
| 234 | DEFINE_GPR_PSEUDO_8(spl), |
| 235 | DEFINE_GPR_PSEUDO_8(r8l), |
| 236 | DEFINE_GPR_PSEUDO_8(r9l), |
| 237 | DEFINE_GPR_PSEUDO_8(r10l), |
| 238 | DEFINE_GPR_PSEUDO_8(r11l), |
| 239 | DEFINE_GPR_PSEUDO_8(r12l), |
| 240 | DEFINE_GPR_PSEUDO_8(r13l), |
| 241 | DEFINE_GPR_PSEUDO_8(r14l), |
| 242 | DEFINE_GPR_PSEUDO_8(r15l), |
| 243 | {DEFINE_FPU_XMM(xmm0)}, |
| 244 | {DEFINE_FPU_XMM(xmm1)}, |
| 245 | {DEFINE_FPU_XMM(xmm2)}, |
| 246 | {DEFINE_FPU_XMM(xmm3)}, |
| 247 | {DEFINE_FPU_XMM(xmm4)}, |
| 248 | {DEFINE_FPU_XMM(xmm5)}, |
| 249 | {DEFINE_FPU_XMM(xmm6)}, |
| 250 | {DEFINE_FPU_XMM(xmm7)}, |
| 251 | {DEFINE_FPU_XMM(xmm8)}, |
| 252 | {DEFINE_FPU_XMM(xmm9)}, |
| 253 | {DEFINE_FPU_XMM(xmm10)}, |
| 254 | {DEFINE_FPU_XMM(xmm11)}, |
| 255 | {DEFINE_FPU_XMM(xmm12)}, |
| 256 | {DEFINE_FPU_XMM(xmm13)}, |
| 257 | {DEFINE_FPU_XMM(xmm14)}, |
| 258 | {DEFINE_FPU_XMM(xmm15)}}; |
| 259 | |
| 260 | static size_t k_num_register_infos = std::size(g_register_infos); |
| 261 | |
| 262 | // Array of lldb register numbers used to define the set of all General Purpose |
| 263 | // Registers |
| 264 | uint32_t g_gpr_reg_indices[] = { |
| 265 | eRegisterIndexRax, eRegisterIndexRbx, eRegisterIndexRcx, |
| 266 | eRegisterIndexRdx, eRegisterIndexRdi, eRegisterIndexRsi, |
| 267 | eRegisterIndexRbp, eRegisterIndexRsp, eRegisterIndexR8, |
| 268 | eRegisterIndexR9, eRegisterIndexR10, eRegisterIndexR11, |
| 269 | eRegisterIndexR12, eRegisterIndexR13, eRegisterIndexR14, |
| 270 | eRegisterIndexR15, eRegisterIndexRip, eRegisterIndexRflags, |
| 271 | eRegisterIndexEax, eRegisterIndexEbx, eRegisterIndexEcx, |
| 272 | eRegisterIndexEdx, eRegisterIndexEdi, eRegisterIndexEsi, |
| 273 | eRegisterIndexEbp, eRegisterIndexEsp, eRegisterIndexR8d, |
| 274 | eRegisterIndexR9d, eRegisterIndexR10d, eRegisterIndexR11d, |
| 275 | eRegisterIndexR12d, eRegisterIndexR13d, eRegisterIndexR14d, |
| 276 | eRegisterIndexR15d, eRegisterIndexAx, eRegisterIndexBx, |
| 277 | eRegisterIndexCx, eRegisterIndexDx, eRegisterIndexDi, |
| 278 | eRegisterIndexSi, eRegisterIndexBp, eRegisterIndexSp, |
| 279 | eRegisterIndexR8w, eRegisterIndexR9w, eRegisterIndexR10w, |
| 280 | eRegisterIndexR11w, eRegisterIndexR12w, eRegisterIndexR13w, |
| 281 | eRegisterIndexR14w, eRegisterIndexR15w, eRegisterIndexAh, |
| 282 | eRegisterIndexBh, eRegisterIndexCh, eRegisterIndexDh, |
| 283 | eRegisterIndexAl, eRegisterIndexBl, eRegisterIndexCl, |
| 284 | eRegisterIndexDl, eRegisterIndexDil, eRegisterIndexSil, |
| 285 | eRegisterIndexBpl, eRegisterIndexSpl, eRegisterIndexR8l, |
| 286 | eRegisterIndexR9l, eRegisterIndexR10l, eRegisterIndexR11l, |
| 287 | eRegisterIndexR12l, eRegisterIndexR13l, eRegisterIndexR14l, |
| 288 | eRegisterIndexR15l |
| 289 | }; |
| 290 | |
| 291 | uint32_t g_fpu_reg_indices[] = { |
| 292 | eRegisterIndexXmm0, eRegisterIndexXmm1, eRegisterIndexXmm2, |
| 293 | eRegisterIndexXmm3, eRegisterIndexXmm4, eRegisterIndexXmm5, |
| 294 | eRegisterIndexXmm6, eRegisterIndexXmm7, eRegisterIndexXmm8, |
| 295 | eRegisterIndexXmm9, eRegisterIndexXmm10, eRegisterIndexXmm11, |
| 296 | eRegisterIndexXmm12, eRegisterIndexXmm13, eRegisterIndexXmm14, |
| 297 | eRegisterIndexXmm15 |
| 298 | }; |
| 299 | |
| 300 | RegisterSet g_register_sets[] = { |
| 301 | {.name: "General Purpose Registers" , .short_name: "gpr" , .num_registers: std::size(g_gpr_reg_indices), |
| 302 | .registers: g_gpr_reg_indices}, |
| 303 | {.name: "Floating Point Registers" , .short_name: "fpu" , .num_registers: std::size(g_fpu_reg_indices), |
| 304 | .registers: g_fpu_reg_indices}}; |
| 305 | } |
| 306 | |
| 307 | // Constructors and Destructors |
| 308 | RegisterContextWindows_x64::RegisterContextWindows_x64( |
| 309 | Thread &thread, uint32_t concrete_frame_idx) |
| 310 | : RegisterContextWindows(thread, concrete_frame_idx) {} |
| 311 | |
| 312 | RegisterContextWindows_x64::~RegisterContextWindows_x64() {} |
| 313 | |
| 314 | size_t RegisterContextWindows_x64::GetRegisterCount() { |
| 315 | return std::size(g_register_infos); |
| 316 | } |
| 317 | |
| 318 | const RegisterInfo * |
| 319 | RegisterContextWindows_x64::GetRegisterInfoAtIndex(size_t reg) { |
| 320 | if (reg < k_num_register_infos) |
| 321 | return &g_register_infos[reg]; |
| 322 | return NULL; |
| 323 | } |
| 324 | |
| 325 | size_t RegisterContextWindows_x64::GetRegisterSetCount() { |
| 326 | return std::size(g_register_sets); |
| 327 | } |
| 328 | |
| 329 | const RegisterSet *RegisterContextWindows_x64::GetRegisterSet(size_t reg_set) { |
| 330 | return &g_register_sets[reg_set]; |
| 331 | } |
| 332 | |
| 333 | bool RegisterContextWindows_x64::ReadRegister(const RegisterInfo *reg_info, |
| 334 | RegisterValue ®_value) { |
| 335 | if (!CacheAllRegisterValues()) |
| 336 | return false; |
| 337 | |
| 338 | if (reg_info == nullptr) |
| 339 | return false; |
| 340 | |
| 341 | const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; |
| 342 | |
| 343 | switch (reg) { |
| 344 | #define GPR_CASE(size, reg_case, reg_val) \ |
| 345 | case reg_case: \ |
| 346 | reg_value.SetUInt##size(reg_val); \ |
| 347 | break; |
| 348 | |
| 349 | GPR_CASE(64, lldb_rax_x86_64, m_context.Rax); |
| 350 | GPR_CASE(64, lldb_rbx_x86_64, m_context.Rbx); |
| 351 | GPR_CASE(64, lldb_rcx_x86_64, m_context.Rcx); |
| 352 | GPR_CASE(64, lldb_rdx_x86_64, m_context.Rdx); |
| 353 | GPR_CASE(64, lldb_rdi_x86_64, m_context.Rdi); |
| 354 | GPR_CASE(64, lldb_rsi_x86_64, m_context.Rsi); |
| 355 | GPR_CASE(64, lldb_r8_x86_64, m_context.R8); |
| 356 | GPR_CASE(64, lldb_r9_x86_64, m_context.R9); |
| 357 | GPR_CASE(64, lldb_r10_x86_64, m_context.R10); |
| 358 | GPR_CASE(64, lldb_r11_x86_64, m_context.R11); |
| 359 | GPR_CASE(64, lldb_r12_x86_64, m_context.R12); |
| 360 | GPR_CASE(64, lldb_r13_x86_64, m_context.R13); |
| 361 | GPR_CASE(64, lldb_r14_x86_64, m_context.R14); |
| 362 | GPR_CASE(64, lldb_r15_x86_64, m_context.R15); |
| 363 | GPR_CASE(64, lldb_rbp_x86_64, m_context.Rbp); |
| 364 | GPR_CASE(64, lldb_rsp_x86_64, m_context.Rsp); |
| 365 | GPR_CASE(64, lldb_rip_x86_64, m_context.Rip); |
| 366 | GPR_CASE(64, lldb_rflags_x86_64, m_context.EFlags); |
| 367 | GPR_CASE(32, lldb_eax_x86_64, static_cast<uint32_t>(m_context.Rax)); |
| 368 | GPR_CASE(32, lldb_ebx_x86_64, static_cast<uint32_t>(m_context.Rbx)); |
| 369 | GPR_CASE(32, lldb_ecx_x86_64, static_cast<uint32_t>(m_context.Rcx)); |
| 370 | GPR_CASE(32, lldb_edx_x86_64, static_cast<uint32_t>(m_context.Rdx)); |
| 371 | GPR_CASE(32, lldb_edi_x86_64, static_cast<uint32_t>(m_context.Rdi)); |
| 372 | GPR_CASE(32, lldb_esi_x86_64, static_cast<uint32_t>(m_context.Rsi)); |
| 373 | GPR_CASE(32, lldb_ebp_x86_64, static_cast<uint32_t>(m_context.Rbp)); |
| 374 | GPR_CASE(32, lldb_esp_x86_64, static_cast<uint32_t>(m_context.Rsp)); |
| 375 | GPR_CASE(32, lldb_r8d_x86_64, static_cast<uint32_t>(m_context.R8)); |
| 376 | GPR_CASE(32, lldb_r9d_x86_64, static_cast<uint32_t>(m_context.R9)); |
| 377 | GPR_CASE(32, lldb_r10d_x86_64, static_cast<uint32_t>(m_context.R10)); |
| 378 | GPR_CASE(32, lldb_r11d_x86_64, static_cast<uint32_t>(m_context.R11)); |
| 379 | GPR_CASE(32, lldb_r12d_x86_64, static_cast<uint32_t>(m_context.R12)); |
| 380 | GPR_CASE(32, lldb_r13d_x86_64, static_cast<uint32_t>(m_context.R13)); |
| 381 | GPR_CASE(32, lldb_r14d_x86_64, static_cast<uint32_t>(m_context.R14)); |
| 382 | GPR_CASE(32, lldb_r15d_x86_64, static_cast<uint32_t>(m_context.R15)); |
| 383 | GPR_CASE(16, lldb_ax_x86_64, static_cast<uint16_t>(m_context.Rax)); |
| 384 | GPR_CASE(16, lldb_bx_x86_64, static_cast<uint16_t>(m_context.Rbx)); |
| 385 | GPR_CASE(16, lldb_cx_x86_64, static_cast<uint16_t>(m_context.Rcx)); |
| 386 | GPR_CASE(16, lldb_dx_x86_64, static_cast<uint16_t>(m_context.Rdx)); |
| 387 | GPR_CASE(16, lldb_di_x86_64, static_cast<uint16_t>(m_context.Rdi)); |
| 388 | GPR_CASE(16, lldb_si_x86_64, static_cast<uint16_t>(m_context.Rsi)); |
| 389 | GPR_CASE(16, lldb_bp_x86_64, static_cast<uint16_t>(m_context.Rbp)); |
| 390 | GPR_CASE(16, lldb_sp_x86_64, static_cast<uint16_t>(m_context.Rsp)); |
| 391 | GPR_CASE(16, lldb_r8w_x86_64, static_cast<uint16_t>(m_context.R8)); |
| 392 | GPR_CASE(16, lldb_r9w_x86_64, static_cast<uint16_t>(m_context.R9)); |
| 393 | GPR_CASE(16, lldb_r10w_x86_64, static_cast<uint16_t>(m_context.R10)); |
| 394 | GPR_CASE(16, lldb_r11w_x86_64, static_cast<uint16_t>(m_context.R11)); |
| 395 | GPR_CASE(16, lldb_r12w_x86_64, static_cast<uint16_t>(m_context.R12)); |
| 396 | GPR_CASE(16, lldb_r13w_x86_64, static_cast<uint16_t>(m_context.R13)); |
| 397 | GPR_CASE(16, lldb_r14w_x86_64, static_cast<uint16_t>(m_context.R14)); |
| 398 | GPR_CASE(16, lldb_r15w_x86_64, static_cast<uint16_t>(m_context.R15)); |
| 399 | GPR_CASE(8, lldb_ah_x86_64, static_cast<uint16_t>(m_context.Rax) >> 8); |
| 400 | GPR_CASE(8, lldb_bh_x86_64, static_cast<uint16_t>(m_context.Rbx) >> 8); |
| 401 | GPR_CASE(8, lldb_ch_x86_64, static_cast<uint16_t>(m_context.Rcx) >> 8); |
| 402 | GPR_CASE(8, lldb_dh_x86_64, static_cast<uint16_t>(m_context.Rdx) >> 8); |
| 403 | GPR_CASE(8, lldb_al_x86_64, static_cast<uint8_t>(m_context.Rax)); |
| 404 | GPR_CASE(8, lldb_bl_x86_64, static_cast<uint8_t>(m_context.Rbx)); |
| 405 | GPR_CASE(8, lldb_cl_x86_64, static_cast<uint8_t>(m_context.Rcx)); |
| 406 | GPR_CASE(8, lldb_dl_x86_64, static_cast<uint8_t>(m_context.Rdx)); |
| 407 | GPR_CASE(8, lldb_dil_x86_64, static_cast<uint8_t>(m_context.Rdi)); |
| 408 | GPR_CASE(8, lldb_sil_x86_64, static_cast<uint8_t>(m_context.Rsi)); |
| 409 | GPR_CASE(8, lldb_bpl_x86_64, static_cast<uint8_t>(m_context.Rbp)); |
| 410 | GPR_CASE(8, lldb_spl_x86_64, static_cast<uint8_t>(m_context.Rsp)); |
| 411 | GPR_CASE(8, lldb_r8l_x86_64, static_cast<uint8_t>(m_context.R8)); |
| 412 | GPR_CASE(8, lldb_r9l_x86_64, static_cast<uint8_t>(m_context.R9)); |
| 413 | GPR_CASE(8, lldb_r10l_x86_64, static_cast<uint8_t>(m_context.R10)); |
| 414 | GPR_CASE(8, lldb_r11l_x86_64, static_cast<uint8_t>(m_context.R11)); |
| 415 | GPR_CASE(8, lldb_r12l_x86_64, static_cast<uint8_t>(m_context.R12)); |
| 416 | GPR_CASE(8, lldb_r13l_x86_64, static_cast<uint8_t>(m_context.R13)); |
| 417 | GPR_CASE(8, lldb_r14l_x86_64, static_cast<uint8_t>(m_context.R14)); |
| 418 | GPR_CASE(8, lldb_r15l_x86_64, static_cast<uint8_t>(m_context.R15)); |
| 419 | |
| 420 | case lldb_xmm0_x86_64: |
| 421 | reg_value.SetBytes(&m_context.Xmm0, |
| 422 | reg_info->byte_size, endian::InlHostByteOrder()); |
| 423 | break; |
| 424 | case lldb_xmm1_x86_64: |
| 425 | reg_value.SetBytes(&m_context.Xmm1, |
| 426 | reg_info->byte_size, endian::InlHostByteOrder()); |
| 427 | break; |
| 428 | case lldb_xmm2_x86_64: |
| 429 | reg_value.SetBytes(&m_context.Xmm2, |
| 430 | reg_info->byte_size, endian::InlHostByteOrder()); |
| 431 | break; |
| 432 | case lldb_xmm3_x86_64: |
| 433 | reg_value.SetBytes(&m_context.Xmm3, |
| 434 | reg_info->byte_size, endian::InlHostByteOrder()); |
| 435 | break; |
| 436 | case lldb_xmm4_x86_64: |
| 437 | reg_value.SetBytes(&m_context.Xmm4, |
| 438 | reg_info->byte_size, endian::InlHostByteOrder()); |
| 439 | break; |
| 440 | case lldb_xmm5_x86_64: |
| 441 | reg_value.SetBytes(&m_context.Xmm5, |
| 442 | reg_info->byte_size, endian::InlHostByteOrder()); |
| 443 | break; |
| 444 | case lldb_xmm6_x86_64: |
| 445 | reg_value.SetBytes(&m_context.Xmm6, |
| 446 | reg_info->byte_size, endian::InlHostByteOrder()); |
| 447 | break; |
| 448 | case lldb_xmm7_x86_64: |
| 449 | reg_value.SetBytes(&m_context.Xmm7, |
| 450 | reg_info->byte_size, endian::InlHostByteOrder()); |
| 451 | break; |
| 452 | case lldb_xmm8_x86_64: |
| 453 | reg_value.SetBytes(&m_context.Xmm8, |
| 454 | reg_info->byte_size, endian::InlHostByteOrder()); |
| 455 | break; |
| 456 | case lldb_xmm9_x86_64: |
| 457 | reg_value.SetBytes(&m_context.Xmm9, |
| 458 | reg_info->byte_size, endian::InlHostByteOrder()); |
| 459 | break; |
| 460 | case lldb_xmm10_x86_64: |
| 461 | reg_value.SetBytes(&m_context.Xmm10, |
| 462 | reg_info->byte_size, endian::InlHostByteOrder()); |
| 463 | break; |
| 464 | case lldb_xmm11_x86_64: |
| 465 | reg_value.SetBytes(&m_context.Xmm11, |
| 466 | reg_info->byte_size, endian::InlHostByteOrder()); |
| 467 | break; |
| 468 | case lldb_xmm12_x86_64: |
| 469 | reg_value.SetBytes(&m_context.Xmm12, |
| 470 | reg_info->byte_size, endian::InlHostByteOrder()); |
| 471 | break; |
| 472 | case lldb_xmm13_x86_64: |
| 473 | reg_value.SetBytes(&m_context.Xmm13, |
| 474 | reg_info->byte_size, endian::InlHostByteOrder()); |
| 475 | break; |
| 476 | case lldb_xmm14_x86_64: |
| 477 | reg_value.SetBytes(&m_context.Xmm14, |
| 478 | reg_info->byte_size, endian::InlHostByteOrder()); |
| 479 | break; |
| 480 | case lldb_xmm15_x86_64: |
| 481 | reg_value.SetBytes(&m_context.Xmm15, |
| 482 | reg_info->byte_size, endian::InlHostByteOrder()); |
| 483 | break; |
| 484 | } |
| 485 | return true; |
| 486 | } |
| 487 | |
| 488 | bool RegisterContextWindows_x64::WriteRegister(const RegisterInfo *reg_info, |
| 489 | const RegisterValue ®_value) { |
| 490 | // Since we cannot only write a single register value to the inferior, we |
| 491 | // need to make sure our cached copy of the register values are fresh. |
| 492 | // Otherwise when writing EAX, for example, we may also overwrite some other |
| 493 | // register with a stale value. |
| 494 | if (!CacheAllRegisterValues()) |
| 495 | return false; |
| 496 | |
| 497 | switch (reg_info->kinds[eRegisterKindLLDB]) { |
| 498 | case lldb_rax_x86_64: |
| 499 | m_context.Rax = reg_value.GetAsUInt64(); |
| 500 | break; |
| 501 | case lldb_rbx_x86_64: |
| 502 | m_context.Rbx = reg_value.GetAsUInt64(); |
| 503 | break; |
| 504 | case lldb_rcx_x86_64: |
| 505 | m_context.Rcx = reg_value.GetAsUInt64(); |
| 506 | break; |
| 507 | case lldb_rdx_x86_64: |
| 508 | m_context.Rdx = reg_value.GetAsUInt64(); |
| 509 | break; |
| 510 | case lldb_rdi_x86_64: |
| 511 | m_context.Rdi = reg_value.GetAsUInt64(); |
| 512 | break; |
| 513 | case lldb_rsi_x86_64: |
| 514 | m_context.Rsi = reg_value.GetAsUInt64(); |
| 515 | break; |
| 516 | case lldb_r8_x86_64: |
| 517 | m_context.R8 = reg_value.GetAsUInt64(); |
| 518 | break; |
| 519 | case lldb_r9_x86_64: |
| 520 | m_context.R9 = reg_value.GetAsUInt64(); |
| 521 | break; |
| 522 | case lldb_r10_x86_64: |
| 523 | m_context.R10 = reg_value.GetAsUInt64(); |
| 524 | break; |
| 525 | case lldb_r11_x86_64: |
| 526 | m_context.R11 = reg_value.GetAsUInt64(); |
| 527 | break; |
| 528 | case lldb_r12_x86_64: |
| 529 | m_context.R12 = reg_value.GetAsUInt64(); |
| 530 | break; |
| 531 | case lldb_r13_x86_64: |
| 532 | m_context.R13 = reg_value.GetAsUInt64(); |
| 533 | break; |
| 534 | case lldb_r14_x86_64: |
| 535 | m_context.R14 = reg_value.GetAsUInt64(); |
| 536 | break; |
| 537 | case lldb_r15_x86_64: |
| 538 | m_context.R15 = reg_value.GetAsUInt64(); |
| 539 | break; |
| 540 | case lldb_rbp_x86_64: |
| 541 | m_context.Rbp = reg_value.GetAsUInt64(); |
| 542 | break; |
| 543 | case lldb_rsp_x86_64: |
| 544 | m_context.Rsp = reg_value.GetAsUInt64(); |
| 545 | break; |
| 546 | case lldb_rip_x86_64: |
| 547 | m_context.Rip = reg_value.GetAsUInt64(); |
| 548 | break; |
| 549 | case lldb_rflags_x86_64: |
| 550 | m_context.EFlags = reg_value.GetAsUInt64(); |
| 551 | break; |
| 552 | case lldb_xmm0_x86_64: |
| 553 | memcpy(&m_context.Xmm0, reg_value.GetBytes(), 16); |
| 554 | break; |
| 555 | case lldb_xmm1_x86_64: |
| 556 | memcpy(&m_context.Xmm1, reg_value.GetBytes(), 16); |
| 557 | break; |
| 558 | case lldb_xmm2_x86_64: |
| 559 | memcpy(&m_context.Xmm2, reg_value.GetBytes(), 16); |
| 560 | break; |
| 561 | case lldb_xmm3_x86_64: |
| 562 | memcpy(&m_context.Xmm3, reg_value.GetBytes(), 16); |
| 563 | break; |
| 564 | case lldb_xmm4_x86_64: |
| 565 | memcpy(&m_context.Xmm4, reg_value.GetBytes(), 16); |
| 566 | break; |
| 567 | case lldb_xmm5_x86_64: |
| 568 | memcpy(&m_context.Xmm5, reg_value.GetBytes(), 16); |
| 569 | break; |
| 570 | case lldb_xmm6_x86_64: |
| 571 | memcpy(&m_context.Xmm6, reg_value.GetBytes(), 16); |
| 572 | break; |
| 573 | case lldb_xmm7_x86_64: |
| 574 | memcpy(&m_context.Xmm7, reg_value.GetBytes(), 16); |
| 575 | break; |
| 576 | case lldb_xmm8_x86_64: |
| 577 | memcpy(&m_context.Xmm8, reg_value.GetBytes(), 16); |
| 578 | break; |
| 579 | case lldb_xmm9_x86_64: |
| 580 | memcpy(&m_context.Xmm9, reg_value.GetBytes(), 16); |
| 581 | break; |
| 582 | case lldb_xmm10_x86_64: |
| 583 | memcpy(&m_context.Xmm10, reg_value.GetBytes(), 16); |
| 584 | break; |
| 585 | case lldb_xmm11_x86_64: |
| 586 | memcpy(&m_context.Xmm11, reg_value.GetBytes(), 16); |
| 587 | break; |
| 588 | case lldb_xmm12_x86_64: |
| 589 | memcpy(&m_context.Xmm12, reg_value.GetBytes(), 16); |
| 590 | break; |
| 591 | case lldb_xmm13_x86_64: |
| 592 | memcpy(&m_context.Xmm13, reg_value.GetBytes(), 16); |
| 593 | break; |
| 594 | case lldb_xmm14_x86_64: |
| 595 | memcpy(&m_context.Xmm14, reg_value.GetBytes(), 16); |
| 596 | break; |
| 597 | case lldb_xmm15_x86_64: |
| 598 | memcpy(&m_context.Xmm15, reg_value.GetBytes(), 16); |
| 599 | break; |
| 600 | } |
| 601 | |
| 602 | // Physically update the registers in the target process. |
| 603 | return ApplyAllRegisterValues(); |
| 604 | } |
| 605 | |
| 606 | #endif // defined(__x86_64__) || defined(_M_X64) |
| 607 | |