1 //===-- NativeRegisterContextLinux_x86_64.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 #if defined(__i386__) || defined(__x86_64__) 11 12 #include "NativeRegisterContextLinux_x86_64.h" 13 14 #include "lldb/Core/DataBufferHeap.h" 15 #include "lldb/Core/Error.h" 16 #include "lldb/Core/Log.h" 17 #include "lldb/Core/RegisterValue.h" 18 #include "lldb/Host/HostInfo.h" 19 20 #include "Plugins/Process/Utility/RegisterContextLinux_i386.h" 21 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" 22 23 using namespace lldb_private; 24 using namespace lldb_private::process_linux; 25 26 // ---------------------------------------------------------------------------- 27 // Private namespace. 28 // ---------------------------------------------------------------------------- 29 30 namespace { 31 // x86 32-bit general purpose registers. 32 const uint32_t g_gpr_regnums_i386[] = { 33 lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386, 34 lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386, 35 lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386, 36 lldb_gs_i386, lldb_ss_i386, lldb_ds_i386, lldb_es_i386, 37 lldb_ax_i386, lldb_bx_i386, lldb_cx_i386, lldb_dx_i386, 38 lldb_di_i386, lldb_si_i386, lldb_bp_i386, lldb_sp_i386, 39 lldb_ah_i386, lldb_bh_i386, lldb_ch_i386, lldb_dh_i386, 40 lldb_al_i386, lldb_bl_i386, lldb_cl_i386, lldb_dl_i386, 41 LLDB_INVALID_REGNUM // register sets need to end with this flag 42 }; 43 static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) - 44 1 == 45 k_num_gpr_registers_i386, 46 "g_gpr_regnums_i386 has wrong number of register infos"); 47 48 // x86 32-bit floating point registers. 49 const uint32_t g_fpu_regnums_i386[] = { 50 lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386, 51 lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386, 52 lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386, 53 lldb_st2_i386, lldb_st3_i386, lldb_st4_i386, lldb_st5_i386, 54 lldb_st6_i386, lldb_st7_i386, lldb_mm0_i386, lldb_mm1_i386, 55 lldb_mm2_i386, lldb_mm3_i386, lldb_mm4_i386, lldb_mm5_i386, 56 lldb_mm6_i386, lldb_mm7_i386, lldb_xmm0_i386, lldb_xmm1_i386, 57 lldb_xmm2_i386, lldb_xmm3_i386, lldb_xmm4_i386, lldb_xmm5_i386, 58 lldb_xmm6_i386, lldb_xmm7_i386, 59 LLDB_INVALID_REGNUM // register sets need to end with this flag 60 }; 61 static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) - 62 1 == 63 k_num_fpr_registers_i386, 64 "g_fpu_regnums_i386 has wrong number of register infos"); 65 66 // x86 32-bit AVX registers. 67 const uint32_t g_avx_regnums_i386[] = { 68 lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386, 69 lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386, 70 LLDB_INVALID_REGNUM // register sets need to end with this flag 71 }; 72 static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) - 73 1 == 74 k_num_avx_registers_i386, 75 " g_avx_regnums_i386 has wrong number of register infos"); 76 77 // x86 64-bit general purpose registers. 78 static const uint32_t g_gpr_regnums_x86_64[] = { 79 lldb_rax_x86_64, lldb_rbx_x86_64, lldb_rcx_x86_64, lldb_rdx_x86_64, 80 lldb_rdi_x86_64, lldb_rsi_x86_64, lldb_rbp_x86_64, lldb_rsp_x86_64, 81 lldb_r8_x86_64, lldb_r9_x86_64, lldb_r10_x86_64, lldb_r11_x86_64, 82 lldb_r12_x86_64, lldb_r13_x86_64, lldb_r14_x86_64, lldb_r15_x86_64, 83 lldb_rip_x86_64, lldb_rflags_x86_64, lldb_cs_x86_64, lldb_fs_x86_64, 84 lldb_gs_x86_64, lldb_ss_x86_64, lldb_ds_x86_64, lldb_es_x86_64, 85 lldb_eax_x86_64, lldb_ebx_x86_64, lldb_ecx_x86_64, lldb_edx_x86_64, 86 lldb_edi_x86_64, lldb_esi_x86_64, lldb_ebp_x86_64, lldb_esp_x86_64, 87 lldb_r8d_x86_64, // Low 32 bits or r8 88 lldb_r9d_x86_64, // Low 32 bits or r9 89 lldb_r10d_x86_64, // Low 32 bits or r10 90 lldb_r11d_x86_64, // Low 32 bits or r11 91 lldb_r12d_x86_64, // Low 32 bits or r12 92 lldb_r13d_x86_64, // Low 32 bits or r13 93 lldb_r14d_x86_64, // Low 32 bits or r14 94 lldb_r15d_x86_64, // Low 32 bits or r15 95 lldb_ax_x86_64, lldb_bx_x86_64, lldb_cx_x86_64, lldb_dx_x86_64, 96 lldb_di_x86_64, lldb_si_x86_64, lldb_bp_x86_64, lldb_sp_x86_64, 97 lldb_r8w_x86_64, // Low 16 bits or r8 98 lldb_r9w_x86_64, // Low 16 bits or r9 99 lldb_r10w_x86_64, // Low 16 bits or r10 100 lldb_r11w_x86_64, // Low 16 bits or r11 101 lldb_r12w_x86_64, // Low 16 bits or r12 102 lldb_r13w_x86_64, // Low 16 bits or r13 103 lldb_r14w_x86_64, // Low 16 bits or r14 104 lldb_r15w_x86_64, // Low 16 bits or r15 105 lldb_ah_x86_64, lldb_bh_x86_64, lldb_ch_x86_64, lldb_dh_x86_64, 106 lldb_al_x86_64, lldb_bl_x86_64, lldb_cl_x86_64, lldb_dl_x86_64, 107 lldb_dil_x86_64, lldb_sil_x86_64, lldb_bpl_x86_64, lldb_spl_x86_64, 108 lldb_r8l_x86_64, // Low 8 bits or r8 109 lldb_r9l_x86_64, // Low 8 bits or r9 110 lldb_r10l_x86_64, // Low 8 bits or r10 111 lldb_r11l_x86_64, // Low 8 bits or r11 112 lldb_r12l_x86_64, // Low 8 bits or r12 113 lldb_r13l_x86_64, // Low 8 bits or r13 114 lldb_r14l_x86_64, // Low 8 bits or r14 115 lldb_r15l_x86_64, // Low 8 bits or r15 116 LLDB_INVALID_REGNUM // register sets need to end with this flag 117 }; 118 static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) - 119 1 == 120 k_num_gpr_registers_x86_64, 121 "g_gpr_regnums_x86_64 has wrong number of register infos"); 122 123 // x86 64-bit floating point registers. 124 static const uint32_t g_fpu_regnums_x86_64[] = { 125 lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64, 126 lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64, 127 lldb_foseg_x86_64, lldb_fooff_x86_64, lldb_mxcsr_x86_64, 128 lldb_mxcsrmask_x86_64, lldb_st0_x86_64, lldb_st1_x86_64, 129 lldb_st2_x86_64, lldb_st3_x86_64, lldb_st4_x86_64, 130 lldb_st5_x86_64, lldb_st6_x86_64, lldb_st7_x86_64, 131 lldb_mm0_x86_64, lldb_mm1_x86_64, lldb_mm2_x86_64, 132 lldb_mm3_x86_64, lldb_mm4_x86_64, lldb_mm5_x86_64, 133 lldb_mm6_x86_64, lldb_mm7_x86_64, lldb_xmm0_x86_64, 134 lldb_xmm1_x86_64, lldb_xmm2_x86_64, lldb_xmm3_x86_64, 135 lldb_xmm4_x86_64, lldb_xmm5_x86_64, lldb_xmm6_x86_64, 136 lldb_xmm7_x86_64, lldb_xmm8_x86_64, lldb_xmm9_x86_64, 137 lldb_xmm10_x86_64, lldb_xmm11_x86_64, lldb_xmm12_x86_64, 138 lldb_xmm13_x86_64, lldb_xmm14_x86_64, lldb_xmm15_x86_64, 139 LLDB_INVALID_REGNUM // register sets need to end with this flag 140 }; 141 static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) - 142 1 == 143 k_num_fpr_registers_x86_64, 144 "g_fpu_regnums_x86_64 has wrong number of register infos"); 145 146 // x86 64-bit AVX registers. 147 static const uint32_t g_avx_regnums_x86_64[] = { 148 lldb_ymm0_x86_64, lldb_ymm1_x86_64, lldb_ymm2_x86_64, lldb_ymm3_x86_64, 149 lldb_ymm4_x86_64, lldb_ymm5_x86_64, lldb_ymm6_x86_64, lldb_ymm7_x86_64, 150 lldb_ymm8_x86_64, lldb_ymm9_x86_64, lldb_ymm10_x86_64, lldb_ymm11_x86_64, 151 lldb_ymm12_x86_64, lldb_ymm13_x86_64, lldb_ymm14_x86_64, lldb_ymm15_x86_64, 152 LLDB_INVALID_REGNUM // register sets need to end with this flag 153 }; 154 static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) - 155 1 == 156 k_num_avx_registers_x86_64, 157 "g_avx_regnums_x86_64 has wrong number of register infos"); 158 159 // Number of register sets provided by this context. 160 enum { k_num_extended_register_sets = 1, k_num_register_sets = 3 }; 161 162 // Register sets for x86 32-bit. 163 static const RegisterSet g_reg_sets_i386[k_num_register_sets] = { 164 {"General Purpose Registers", "gpr", k_num_gpr_registers_i386, 165 g_gpr_regnums_i386}, 166 {"Floating Point Registers", "fpu", k_num_fpr_registers_i386, 167 g_fpu_regnums_i386}, 168 {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386, 169 g_avx_regnums_i386}}; 170 171 // Register sets for x86 64-bit. 172 static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = { 173 {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64, 174 g_gpr_regnums_x86_64}, 175 {"Floating Point Registers", "fpu", k_num_fpr_registers_x86_64, 176 g_fpu_regnums_x86_64}, 177 {"Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64, 178 g_avx_regnums_x86_64}}; 179 } 180 181 #define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize() + sizeof(FPR)) 182 183 // ---------------------------------------------------------------------------- 184 // Required ptrace defines. 185 // ---------------------------------------------------------------------------- 186 187 // Support ptrace extensions even when compiled without required kernel support 188 #ifndef NT_X86_XSTATE 189 #define NT_X86_XSTATE 0x202 190 #endif 191 #ifndef NT_PRXFPREG 192 #define NT_PRXFPREG 0x46e62b7f 193 #endif 194 195 NativeRegisterContextLinux * 196 NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux( 197 const ArchSpec &target_arch, NativeThreadProtocol &native_thread, 198 uint32_t concrete_frame_idx) { 199 return new NativeRegisterContextLinux_x86_64(target_arch, native_thread, 200 concrete_frame_idx); 201 } 202 203 // ---------------------------------------------------------------------------- 204 // NativeRegisterContextLinux_x86_64 members. 205 // ---------------------------------------------------------------------------- 206 207 static RegisterInfoInterface * 208 CreateRegisterInfoInterface(const ArchSpec &target_arch) { 209 if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) { 210 // 32-bit hosts run with a RegisterContextLinux_i386 context. 211 return new RegisterContextLinux_i386(target_arch); 212 } else { 213 assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) && 214 "Register setting path assumes this is a 64-bit host"); 215 // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the 216 // x86_64 register context. 217 return new RegisterContextLinux_x86_64(target_arch); 218 } 219 } 220 221 NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64( 222 const ArchSpec &target_arch, NativeThreadProtocol &native_thread, 223 uint32_t concrete_frame_idx) 224 : NativeRegisterContextLinux(native_thread, concrete_frame_idx, 225 CreateRegisterInfoInterface(target_arch)), 226 m_fpr_type(eFPRTypeNotValid), m_fpr(), m_iovec(), m_ymm_set(), 227 m_reg_info(), m_gpr_x86_64() { 228 // Set up data about ranges of valid registers. 229 switch (target_arch.GetMachine()) { 230 case llvm::Triple::x86: 231 m_reg_info.num_registers = k_num_registers_i386; 232 m_reg_info.num_gpr_registers = k_num_gpr_registers_i386; 233 m_reg_info.num_fpr_registers = k_num_fpr_registers_i386; 234 m_reg_info.num_avx_registers = k_num_avx_registers_i386; 235 m_reg_info.last_gpr = k_last_gpr_i386; 236 m_reg_info.first_fpr = k_first_fpr_i386; 237 m_reg_info.last_fpr = k_last_fpr_i386; 238 m_reg_info.first_st = lldb_st0_i386; 239 m_reg_info.last_st = lldb_st7_i386; 240 m_reg_info.first_mm = lldb_mm0_i386; 241 m_reg_info.last_mm = lldb_mm7_i386; 242 m_reg_info.first_xmm = lldb_xmm0_i386; 243 m_reg_info.last_xmm = lldb_xmm7_i386; 244 m_reg_info.first_ymm = lldb_ymm0_i386; 245 m_reg_info.last_ymm = lldb_ymm7_i386; 246 m_reg_info.first_dr = lldb_dr0_i386; 247 m_reg_info.gpr_flags = lldb_eflags_i386; 248 break; 249 case llvm::Triple::x86_64: 250 m_reg_info.num_registers = k_num_registers_x86_64; 251 m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64; 252 m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64; 253 m_reg_info.num_avx_registers = k_num_avx_registers_x86_64; 254 m_reg_info.last_gpr = k_last_gpr_x86_64; 255 m_reg_info.first_fpr = k_first_fpr_x86_64; 256 m_reg_info.last_fpr = k_last_fpr_x86_64; 257 m_reg_info.first_st = lldb_st0_x86_64; 258 m_reg_info.last_st = lldb_st7_x86_64; 259 m_reg_info.first_mm = lldb_mm0_x86_64; 260 m_reg_info.last_mm = lldb_mm7_x86_64; 261 m_reg_info.first_xmm = lldb_xmm0_x86_64; 262 m_reg_info.last_xmm = lldb_xmm15_x86_64; 263 m_reg_info.first_ymm = lldb_ymm0_x86_64; 264 m_reg_info.last_ymm = lldb_ymm15_x86_64; 265 m_reg_info.first_dr = lldb_dr0_x86_64; 266 m_reg_info.gpr_flags = lldb_rflags_x86_64; 267 break; 268 default: 269 assert(false && "Unhandled target architecture."); 270 break; 271 } 272 273 // Initialize m_iovec to point to the buffer and buffer size 274 // using the conventions of Berkeley style UIO structures, as required 275 // by PTRACE extensions. 276 m_iovec.iov_base = &m_fpr.xstate.xsave; 277 m_iovec.iov_len = sizeof(m_fpr.xstate.xsave); 278 279 // Clear out the FPR state. 280 ::memset(&m_fpr, 0, sizeof(FPR)); 281 282 // Store byte offset of fctrl (i.e. first register of FPR) 283 const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl"); 284 m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset; 285 } 286 287 // CONSIDER after local and llgs debugging are merged, register set support can 288 // be moved into a base x86-64 class with IsRegisterSetAvailable made virtual. 289 uint32_t NativeRegisterContextLinux_x86_64::GetRegisterSetCount() const { 290 uint32_t sets = 0; 291 for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) { 292 if (IsRegisterSetAvailable(set_index)) 293 ++sets; 294 } 295 296 return sets; 297 } 298 299 uint32_t NativeRegisterContextLinux_x86_64::GetUserRegisterCount() const { 300 uint32_t count = 0; 301 for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) { 302 const RegisterSet *set = GetRegisterSet(set_index); 303 if (set) 304 count += set->num_registers; 305 } 306 return count; 307 } 308 309 const RegisterSet * 310 NativeRegisterContextLinux_x86_64::GetRegisterSet(uint32_t set_index) const { 311 if (!IsRegisterSetAvailable(set_index)) 312 return nullptr; 313 314 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { 315 case llvm::Triple::x86: 316 return &g_reg_sets_i386[set_index]; 317 case llvm::Triple::x86_64: 318 return &g_reg_sets_x86_64[set_index]; 319 default: 320 assert(false && "Unhandled target architecture."); 321 return nullptr; 322 } 323 324 return nullptr; 325 } 326 327 Error NativeRegisterContextLinux_x86_64::ReadRegister( 328 const RegisterInfo *reg_info, RegisterValue ®_value) { 329 Error error; 330 331 if (!reg_info) { 332 error.SetErrorString("reg_info NULL"); 333 return error; 334 } 335 336 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; 337 if (reg == LLDB_INVALID_REGNUM) { 338 // This is likely an internal register for lldb use only and should not be 339 // directly queried. 340 error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb " 341 "register, cannot read directly", 342 reg_info->name); 343 return error; 344 } 345 346 if (IsFPR(reg, GetFPRType())) { 347 error = ReadFPR(); 348 if (error.Fail()) 349 return error; 350 } else { 351 uint32_t full_reg = reg; 352 bool is_subreg = reg_info->invalidate_regs && 353 (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM); 354 355 if (is_subreg) { 356 // Read the full aligned 64-bit register. 357 full_reg = reg_info->invalidate_regs[0]; 358 } 359 360 error = ReadRegisterRaw(full_reg, reg_value); 361 362 if (error.Success()) { 363 // If our read was not aligned (for ah,bh,ch,dh), shift our returned value 364 // one byte to the right. 365 if (is_subreg && (reg_info->byte_offset & 0x1)) 366 reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8); 367 368 // If our return byte size was greater than the return value reg size, 369 // then 370 // use the type specified by reg_info rather than the uint64_t default 371 if (reg_value.GetByteSize() > reg_info->byte_size) 372 reg_value.SetType(reg_info); 373 } 374 return error; 375 } 376 377 if (reg_info->encoding == lldb::eEncodingVector) { 378 lldb::ByteOrder byte_order = GetByteOrder(); 379 380 if (byte_order != lldb::eByteOrderInvalid) { 381 if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st) 382 reg_value.SetBytes( 383 m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes, 384 reg_info->byte_size, byte_order); 385 if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm) 386 reg_value.SetBytes( 387 m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes, 388 reg_info->byte_size, byte_order); 389 if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm) 390 reg_value.SetBytes( 391 m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes, 392 reg_info->byte_size, byte_order); 393 if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) { 394 // Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes 395 if (GetFPRType() == eFPRTypeXSAVE && CopyXSTATEtoYMM(reg, byte_order)) 396 reg_value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, 397 reg_info->byte_size, byte_order); 398 else { 399 error.SetErrorString("failed to copy ymm register value"); 400 return error; 401 } 402 } 403 404 if (reg_value.GetType() != RegisterValue::eTypeBytes) 405 error.SetErrorString( 406 "write failed - type was expected to be RegisterValue::eTypeBytes"); 407 408 return error; 409 } 410 411 error.SetErrorString("byte order is invalid"); 412 return error; 413 } 414 415 // Get pointer to m_fpr.xstate.fxsave variable and set the data from it. 416 417 // Byte offsets of all registers are calculated wrt 'UserArea' structure. 418 // However, ReadFPR() reads fpu registers {using ptrace(PTRACE_GETFPREGS,..)} 419 // and stores them in 'm_fpr' (of type FPR structure). To extract values of 420 // fpu 421 // registers, m_fpr should be read at byte offsets calculated wrt to FPR 422 // structure. 423 424 // Since, FPR structure is also one of the member of UserArea structure. 425 // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) - 426 // byte_offset(fctrl wrt UserArea) 427 assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(m_fpr)); 428 uint8_t *src = 429 (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea; 430 switch (reg_info->byte_size) { 431 case 1: 432 reg_value.SetUInt8(*(uint8_t *)src); 433 break; 434 case 2: 435 reg_value.SetUInt16(*(uint16_t *)src); 436 break; 437 case 4: 438 reg_value.SetUInt32(*(uint32_t *)src); 439 break; 440 case 8: 441 reg_value.SetUInt64(*(uint64_t *)src); 442 break; 443 default: 444 assert(false && "Unhandled data size."); 445 error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32, 446 reg_info->byte_size); 447 break; 448 } 449 450 return error; 451 } 452 453 Error NativeRegisterContextLinux_x86_64::WriteRegister( 454 const RegisterInfo *reg_info, const RegisterValue ®_value) { 455 assert(reg_info && "reg_info is null"); 456 457 const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB]; 458 if (reg_index == LLDB_INVALID_REGNUM) 459 return Error("no lldb regnum for %s", reg_info && reg_info->name 460 ? reg_info->name 461 : "<unknown register>"); 462 463 if (IsGPR(reg_index)) 464 return WriteRegisterRaw(reg_index, reg_value); 465 466 if (IsFPR(reg_index, GetFPRType())) { 467 if (reg_info->encoding == lldb::eEncodingVector) { 468 if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st) 469 ::memcpy( 470 m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_st].bytes, 471 reg_value.GetBytes(), reg_value.GetByteSize()); 472 473 if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm) 474 ::memcpy( 475 m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_mm].bytes, 476 reg_value.GetBytes(), reg_value.GetByteSize()); 477 478 if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm) 479 ::memcpy( 480 m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes, 481 reg_value.GetBytes(), reg_value.GetByteSize()); 482 483 if (reg_index >= m_reg_info.first_ymm && 484 reg_index <= m_reg_info.last_ymm) { 485 if (GetFPRType() != eFPRTypeXSAVE) 486 return Error("target processor does not support AVX"); 487 488 // Store ymm register content, and split into the register halves in 489 // xmm.bytes and ymmh.bytes 490 ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes, 491 reg_value.GetBytes(), reg_value.GetByteSize()); 492 if (!CopyYMMtoXSTATE(reg_index, GetByteOrder())) 493 return Error("CopyYMMtoXSTATE() failed"); 494 } 495 } else { 496 // Get pointer to m_fpr.xstate.fxsave variable and set the data to it. 497 498 // Byte offsets of all registers are calculated wrt 'UserArea' structure. 499 // However, WriteFPR() takes m_fpr (of type FPR structure) and writes only 500 // fpu 501 // registers using ptrace(PTRACE_SETFPREGS,..) API. Hence fpu registers 502 // should 503 // be written in m_fpr at byte offsets calculated wrt FPR structure. 504 505 // Since, FPR structure is also one of the member of UserArea structure. 506 // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) - 507 // byte_offset(fctrl wrt UserArea) 508 assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < 509 sizeof(m_fpr)); 510 uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset - 511 m_fctrl_offset_in_userarea; 512 switch (reg_info->byte_size) { 513 case 1: 514 *(uint8_t *)dst = reg_value.GetAsUInt8(); 515 break; 516 case 2: 517 *(uint16_t *)dst = reg_value.GetAsUInt16(); 518 break; 519 case 4: 520 *(uint32_t *)dst = reg_value.GetAsUInt32(); 521 break; 522 case 8: 523 *(uint64_t *)dst = reg_value.GetAsUInt64(); 524 break; 525 default: 526 assert(false && "Unhandled data size."); 527 return Error("unhandled register data size %" PRIu32, 528 reg_info->byte_size); 529 } 530 } 531 532 Error error = WriteFPR(); 533 if (error.Fail()) 534 return error; 535 536 if (IsAVX(reg_index)) { 537 if (!CopyYMMtoXSTATE(reg_index, GetByteOrder())) 538 return Error("CopyYMMtoXSTATE() failed"); 539 } 540 return Error(); 541 } 542 return Error("failed - register wasn't recognized to be a GPR or an FPR, " 543 "write strategy unknown"); 544 } 545 546 Error NativeRegisterContextLinux_x86_64::ReadAllRegisterValues( 547 lldb::DataBufferSP &data_sp) { 548 Error error; 549 550 data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0)); 551 if (!data_sp) { 552 error.SetErrorStringWithFormat( 553 "failed to allocate DataBufferHeap instance of size %" PRIu64, 554 REG_CONTEXT_SIZE); 555 return error; 556 } 557 558 error = ReadGPR(); 559 if (error.Fail()) 560 return error; 561 562 error = ReadFPR(); 563 if (error.Fail()) 564 return error; 565 566 uint8_t *dst = data_sp->GetBytes(); 567 if (dst == nullptr) { 568 error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64 569 " returned a null pointer", 570 REG_CONTEXT_SIZE); 571 return error; 572 } 573 574 ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize()); 575 dst += GetRegisterInfoInterface().GetGPRSize(); 576 if (GetFPRType() == eFPRTypeFXSAVE) 577 ::memcpy(dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave)); 578 else if (GetFPRType() == eFPRTypeXSAVE) { 579 lldb::ByteOrder byte_order = GetByteOrder(); 580 581 // Assemble the YMM register content from the register halves. 582 for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm; 583 ++reg) { 584 if (!CopyXSTATEtoYMM(reg, byte_order)) { 585 error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s " 586 "CopyXSTATEtoYMM() failed for reg num " 587 "%" PRIu32, 588 __FUNCTION__, reg); 589 return error; 590 } 591 } 592 593 // Copy the extended register state including the assembled ymm registers. 594 ::memcpy(dst, &m_fpr, sizeof(m_fpr)); 595 } else { 596 assert(false && "how do we save the floating point registers?"); 597 error.SetErrorString("unsure how to save the floating point registers"); 598 } 599 /** The following code is specific to Linux x86 based architectures, 600 * where the register orig_eax (32 bit)/orig_rax (64 bit) is set to 601 * -1 to solve the bug 23659, such a setting prevents the automatic 602 * decrement of the instruction pointer which was causing the SIGILL 603 * exception. 604 * **/ 605 606 RegisterValue value((uint64_t)-1); 607 const RegisterInfo *reg_info = 608 GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_eax"); 609 if (reg_info == nullptr) 610 reg_info = GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_rax"); 611 612 if (reg_info != nullptr) 613 return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, value); 614 615 return error; 616 } 617 618 Error NativeRegisterContextLinux_x86_64::WriteAllRegisterValues( 619 const lldb::DataBufferSP &data_sp) { 620 Error error; 621 622 if (!data_sp) { 623 error.SetErrorStringWithFormat( 624 "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided", 625 __FUNCTION__); 626 return error; 627 } 628 629 if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) { 630 error.SetErrorStringWithFormat( 631 "NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched " 632 "data size, expected %" PRIu64 ", actual %" PRIu64, 633 __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize()); 634 return error; 635 } 636 637 uint8_t *src = data_sp->GetBytes(); 638 if (src == nullptr) { 639 error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s " 640 "DataBuffer::GetBytes() returned a null " 641 "pointer", 642 __FUNCTION__); 643 return error; 644 } 645 ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize()); 646 647 error = WriteGPR(); 648 if (error.Fail()) 649 return error; 650 651 src += GetRegisterInfoInterface().GetGPRSize(); 652 if (GetFPRType() == eFPRTypeFXSAVE) 653 ::memcpy(&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave)); 654 else if (GetFPRType() == eFPRTypeXSAVE) 655 ::memcpy(&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave)); 656 657 error = WriteFPR(); 658 if (error.Fail()) 659 return error; 660 661 if (GetFPRType() == eFPRTypeXSAVE) { 662 lldb::ByteOrder byte_order = GetByteOrder(); 663 664 // Parse the YMM register content from the register halves. 665 for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm; 666 ++reg) { 667 if (!CopyYMMtoXSTATE(reg, byte_order)) { 668 error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s " 669 "CopyYMMtoXSTATE() failed for reg num " 670 "%" PRIu32, 671 __FUNCTION__, reg); 672 return error; 673 } 674 } 675 } 676 677 return error; 678 } 679 680 bool NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable( 681 uint32_t set_index) const { 682 // Note: Extended register sets are assumed to be at the end of g_reg_sets. 683 uint32_t num_sets = k_num_register_sets - k_num_extended_register_sets; 684 685 if (GetFPRType() == eFPRTypeXSAVE) { 686 // AVX is the first extended register set. 687 ++num_sets; 688 } 689 return (set_index < num_sets); 690 } 691 692 bool NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index) const { 693 // GPRs come first. 694 return reg_index <= m_reg_info.last_gpr; 695 } 696 697 NativeRegisterContextLinux_x86_64::FPRType 698 NativeRegisterContextLinux_x86_64::GetFPRType() const { 699 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 700 if (m_fpr_type == eFPRTypeNotValid) { 701 // TODO: Use assembly to call cpuid on the inferior and query ebx or ecx. 702 703 // Try and see if AVX register retrieval works. 704 m_fpr_type = eFPRTypeXSAVE; 705 if (const_cast<NativeRegisterContextLinux_x86_64 *>(this) 706 ->ReadFPR() 707 .Fail()) { 708 // Fall back to general floating point with no AVX support. 709 m_fpr_type = eFPRTypeFXSAVE; 710 711 // Check if FXSAVE area can be read. 712 if (const_cast<NativeRegisterContextLinux_x86_64 *>(this) 713 ->ReadFPR() 714 .Fail()) { 715 if (log) 716 log->Printf("NativeRegisterContextLinux_x86_64::%s ptrace APIs " 717 "failed to read XSAVE/FXSAVE area", 718 __FUNCTION__); 719 } 720 } 721 } 722 return m_fpr_type; 723 } 724 725 bool NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index) const { 726 return (m_reg_info.first_fpr <= reg_index && 727 reg_index <= m_reg_info.last_fpr); 728 } 729 730 bool NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index, 731 FPRType fpr_type) const { 732 bool generic_fpr = IsFPR(reg_index); 733 734 if (fpr_type == eFPRTypeXSAVE) 735 return generic_fpr || IsAVX(reg_index); 736 return generic_fpr; 737 } 738 739 Error NativeRegisterContextLinux_x86_64::WriteFPR() { 740 const FPRType fpr_type = GetFPRType(); 741 const lldb_private::ArchSpec &target_arch = 742 GetRegisterInfoInterface().GetTargetArchitecture(); 743 switch (fpr_type) { 744 case FPRType::eFPRTypeFXSAVE: 745 // For 32-bit inferiors on x86_32/x86_64 architectures, 746 // FXSAVE area can be written using PTRACE_SETREGSET ptrace api 747 // For 64-bit inferiors on x86_64 architectures, 748 // FXSAVE area can be written using PTRACE_SETFPREGS ptrace api 749 switch (target_arch.GetMachine()) { 750 case llvm::Triple::x86: 751 return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), 752 NT_PRXFPREG); 753 case llvm::Triple::x86_64: 754 return NativeRegisterContextLinux::WriteFPR(); 755 default: 756 assert(false && "Unhandled target architecture."); 757 break; 758 } 759 case FPRType::eFPRTypeXSAVE: 760 return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), 761 NT_X86_XSTATE); 762 default: 763 return Error("Unrecognized FPR type"); 764 } 765 } 766 767 bool NativeRegisterContextLinux_x86_64::IsAVX(uint32_t reg_index) const { 768 return (m_reg_info.first_ymm <= reg_index && 769 reg_index <= m_reg_info.last_ymm); 770 } 771 772 bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM( 773 uint32_t reg_index, lldb::ByteOrder byte_order) { 774 if (!IsAVX(reg_index)) 775 return false; 776 777 if (byte_order == lldb::eByteOrderLittle) { 778 ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes, 779 m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes, 780 sizeof(XMMReg)); 781 ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes + 782 sizeof(XMMReg), 783 m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes, 784 sizeof(YMMHReg)); 785 return true; 786 } 787 788 if (byte_order == lldb::eByteOrderBig) { 789 ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes + 790 sizeof(XMMReg), 791 m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes, 792 sizeof(XMMReg)); 793 ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes, 794 m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes, 795 sizeof(YMMHReg)); 796 return true; 797 } 798 return false; // unsupported or invalid byte order 799 } 800 801 bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE( 802 uint32_t reg, lldb::ByteOrder byte_order) { 803 if (!IsAVX(reg)) 804 return false; 805 806 if (byte_order == lldb::eByteOrderLittle) { 807 ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes, 808 m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(XMMReg)); 809 ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes, 810 m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg), 811 sizeof(YMMHReg)); 812 return true; 813 } 814 815 if (byte_order == lldb::eByteOrderBig) { 816 ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes, 817 m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg), 818 sizeof(XMMReg)); 819 ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes, 820 m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(YMMHReg)); 821 return true; 822 } 823 return false; // unsupported or invalid byte order 824 } 825 826 void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() { 827 const FPRType fpr_type = GetFPRType(); 828 switch (fpr_type) { 829 case FPRType::eFPRTypeFXSAVE: 830 return &m_fpr.xstate.fxsave; 831 case FPRType::eFPRTypeXSAVE: 832 return &m_iovec; 833 default: 834 return nullptr; 835 } 836 } 837 838 size_t NativeRegisterContextLinux_x86_64::GetFPRSize() { 839 const FPRType fpr_type = GetFPRType(); 840 switch (fpr_type) { 841 case FPRType::eFPRTypeFXSAVE: 842 return sizeof(m_fpr.xstate.fxsave); 843 case FPRType::eFPRTypeXSAVE: 844 return sizeof(m_iovec); 845 default: 846 return 0; 847 } 848 } 849 850 Error NativeRegisterContextLinux_x86_64::ReadFPR() { 851 const FPRType fpr_type = GetFPRType(); 852 const lldb_private::ArchSpec &target_arch = 853 GetRegisterInfoInterface().GetTargetArchitecture(); 854 switch (fpr_type) { 855 case FPRType::eFPRTypeFXSAVE: 856 // For 32-bit inferiors on x86_32/x86_64 architectures, 857 // FXSAVE area can be read using PTRACE_GETREGSET ptrace api 858 // For 64-bit inferiors on x86_64 architectures, 859 // FXSAVE area can be read using PTRACE_GETFPREGS ptrace api 860 switch (target_arch.GetMachine()) { 861 case llvm::Triple::x86: 862 return ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_PRXFPREG); 863 case llvm::Triple::x86_64: 864 return NativeRegisterContextLinux::ReadFPR(); 865 default: 866 assert(false && "Unhandled target architecture."); 867 break; 868 } 869 case FPRType::eFPRTypeXSAVE: 870 return ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE); 871 default: 872 return Error("Unrecognized FPR type"); 873 } 874 } 875 876 Error NativeRegisterContextLinux_x86_64::IsWatchpointHit(uint32_t wp_index, 877 bool &is_hit) { 878 if (wp_index >= NumSupportedHardwareWatchpoints()) 879 return Error("Watchpoint index out of range"); 880 881 RegisterValue reg_value; 882 Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value); 883 if (error.Fail()) { 884 is_hit = false; 885 return error; 886 } 887 888 uint64_t status_bits = reg_value.GetAsUInt64(); 889 890 is_hit = status_bits & (1 << wp_index); 891 892 return error; 893 } 894 895 Error NativeRegisterContextLinux_x86_64::GetWatchpointHitIndex( 896 uint32_t &wp_index, lldb::addr_t trap_addr) { 897 uint32_t num_hw_wps = NumSupportedHardwareWatchpoints(); 898 for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) { 899 bool is_hit; 900 Error error = IsWatchpointHit(wp_index, is_hit); 901 if (error.Fail()) { 902 wp_index = LLDB_INVALID_INDEX32; 903 return error; 904 } else if (is_hit) { 905 return error; 906 } 907 } 908 wp_index = LLDB_INVALID_INDEX32; 909 return Error(); 910 } 911 912 Error NativeRegisterContextLinux_x86_64::IsWatchpointVacant(uint32_t wp_index, 913 bool &is_vacant) { 914 if (wp_index >= NumSupportedHardwareWatchpoints()) 915 return Error("Watchpoint index out of range"); 916 917 RegisterValue reg_value; 918 Error error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value); 919 if (error.Fail()) { 920 is_vacant = false; 921 return error; 922 } 923 924 uint64_t control_bits = reg_value.GetAsUInt64(); 925 926 is_vacant = !(control_bits & (1 << (2 * wp_index))); 927 928 return error; 929 } 930 931 Error NativeRegisterContextLinux_x86_64::SetHardwareWatchpointWithIndex( 932 lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) { 933 934 if (wp_index >= NumSupportedHardwareWatchpoints()) 935 return Error("Watchpoint index out of range"); 936 937 // Read only watchpoints aren't supported on x86_64. Fall back to read/write 938 // waitchpoints instead. 939 // TODO: Add logic to detect when a write happens and ignore that watchpoint 940 // hit. 941 if (watch_flags == 0x2) 942 watch_flags = 0x3; 943 944 if (watch_flags != 0x1 && watch_flags != 0x3) 945 return Error("Invalid read/write bits for watchpoint"); 946 947 if (size != 1 && size != 2 && size != 4 && size != 8) 948 return Error("Invalid size for watchpoint"); 949 950 bool is_vacant; 951 Error error = IsWatchpointVacant(wp_index, is_vacant); 952 if (error.Fail()) 953 return error; 954 if (!is_vacant) 955 return Error("Watchpoint index not vacant"); 956 957 RegisterValue reg_value; 958 error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value); 959 if (error.Fail()) 960 return error; 961 962 // for watchpoints 0, 1, 2, or 3, respectively, 963 // set bits 1, 3, 5, or 7 964 uint64_t enable_bit = 1 << (2 * wp_index); 965 966 // set bits 16-17, 20-21, 24-25, or 28-29 967 // with 0b01 for write, and 0b11 for read/write 968 uint64_t rw_bits = watch_flags << (16 + 4 * wp_index); 969 970 // set bits 18-19, 22-23, 26-27, or 30-31 971 // with 0b00, 0b01, 0b10, or 0b11 972 // for 1, 2, 8 (if supported), or 4 bytes, respectively 973 uint64_t size_bits = (size == 8 ? 0x2 : size - 1) << (18 + 4 * wp_index); 974 975 uint64_t bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index)); 976 977 uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask; 978 979 control_bits |= enable_bit | rw_bits | size_bits; 980 981 error = WriteRegisterRaw(m_reg_info.first_dr + wp_index, RegisterValue(addr)); 982 if (error.Fail()) 983 return error; 984 985 error = 986 WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits)); 987 if (error.Fail()) 988 return error; 989 990 error.Clear(); 991 return error; 992 } 993 994 bool NativeRegisterContextLinux_x86_64::ClearHardwareWatchpoint( 995 uint32_t wp_index) { 996 if (wp_index >= NumSupportedHardwareWatchpoints()) 997 return false; 998 999 RegisterValue reg_value; 1000 1001 // for watchpoints 0, 1, 2, or 3, respectively, 1002 // clear bits 0, 1, 2, or 3 of the debug status register (DR6) 1003 Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value); 1004 if (error.Fail()) 1005 return false; 1006 uint64_t bit_mask = 1 << wp_index; 1007 uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask; 1008 error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits)); 1009 if (error.Fail()) 1010 return false; 1011 1012 // for watchpoints 0, 1, 2, or 3, respectively, 1013 // clear bits {0-1,16-19}, {2-3,20-23}, {4-5,24-27}, or {6-7,28-31} 1014 // of the debug control register (DR7) 1015 error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value); 1016 if (error.Fail()) 1017 return false; 1018 bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index)); 1019 uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask; 1020 return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits)) 1021 .Success(); 1022 } 1023 1024 Error NativeRegisterContextLinux_x86_64::ClearAllHardwareWatchpoints() { 1025 RegisterValue reg_value; 1026 1027 // clear bits {0-4} of the debug status register (DR6) 1028 Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value); 1029 if (error.Fail()) 1030 return error; 1031 uint64_t bit_mask = 0xF; 1032 uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask; 1033 error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits)); 1034 if (error.Fail()) 1035 return error; 1036 1037 // clear bits {0-7,16-31} of the debug control register (DR7) 1038 error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value); 1039 if (error.Fail()) 1040 return error; 1041 bit_mask = 0xFF | (0xFFFF << 16); 1042 uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask; 1043 return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits)); 1044 } 1045 1046 uint32_t NativeRegisterContextLinux_x86_64::SetHardwareWatchpoint( 1047 lldb::addr_t addr, size_t size, uint32_t watch_flags) { 1048 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); 1049 const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); 1050 for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index) { 1051 bool is_vacant; 1052 Error error = IsWatchpointVacant(wp_index, is_vacant); 1053 if (is_vacant) { 1054 error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index); 1055 if (error.Success()) 1056 return wp_index; 1057 } 1058 if (error.Fail() && log) { 1059 log->Printf("NativeRegisterContextLinux_x86_64::%s Error: %s", 1060 __FUNCTION__, error.AsCString()); 1061 } 1062 } 1063 return LLDB_INVALID_INDEX32; 1064 } 1065 1066 lldb::addr_t 1067 NativeRegisterContextLinux_x86_64::GetWatchpointAddress(uint32_t wp_index) { 1068 if (wp_index >= NumSupportedHardwareWatchpoints()) 1069 return LLDB_INVALID_ADDRESS; 1070 RegisterValue reg_value; 1071 if (ReadRegisterRaw(m_reg_info.first_dr + wp_index, reg_value).Fail()) 1072 return LLDB_INVALID_ADDRESS; 1073 return reg_value.GetAsUInt64(); 1074 } 1075 1076 uint32_t NativeRegisterContextLinux_x86_64::NumSupportedHardwareWatchpoints() { 1077 // Available debug address registers: dr0, dr1, dr2, dr3 1078 return 4; 1079 } 1080 1081 #endif // defined(__i386__) || defined(__x86_64__) 1082