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