1 //===-- NativeRegisterContextNetBSD_x86_64.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(__i386__) || defined(__x86_64__) 10 11 #include "NativeRegisterContextNetBSD_x86_64.h" 12 13 #include "lldb/Host/HostInfo.h" 14 #include "lldb/Utility/DataBufferHeap.h" 15 #include "lldb/Utility/Log.h" 16 #include "lldb/Utility/RegisterValue.h" 17 #include "lldb/Utility/Status.h" 18 19 #include "Plugins/Process/Utility/RegisterContextNetBSD_i386.h" 20 #include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h" 21 22 // clang-format off 23 #include <sys/types.h> 24 #include <sys/ptrace.h> 25 #include <sys/sysctl.h> 26 #include <sys/uio.h> 27 #include <x86/cpu.h> 28 #include <x86/cpu_extended_state.h> 29 #include <x86/specialreg.h> 30 #include <elf.h> 31 #include <err.h> 32 #include <stdint.h> 33 #include <stdlib.h> 34 // clang-format on 35 36 using namespace lldb_private; 37 using namespace lldb_private::process_netbsd; 38 39 // Private namespace. 40 41 namespace { 42 // x86 64-bit general purpose registers. 43 static const uint32_t g_gpr_regnums_x86_64[] = { 44 lldb_rax_x86_64, lldb_rbx_x86_64, lldb_rcx_x86_64, lldb_rdx_x86_64, 45 lldb_rdi_x86_64, lldb_rsi_x86_64, lldb_rbp_x86_64, lldb_rsp_x86_64, 46 lldb_r8_x86_64, lldb_r9_x86_64, lldb_r10_x86_64, lldb_r11_x86_64, 47 lldb_r12_x86_64, lldb_r13_x86_64, lldb_r14_x86_64, lldb_r15_x86_64, 48 lldb_rip_x86_64, lldb_rflags_x86_64, lldb_cs_x86_64, lldb_fs_x86_64, 49 lldb_gs_x86_64, lldb_ss_x86_64, lldb_ds_x86_64, lldb_es_x86_64, 50 lldb_eax_x86_64, lldb_ebx_x86_64, lldb_ecx_x86_64, lldb_edx_x86_64, 51 lldb_edi_x86_64, lldb_esi_x86_64, lldb_ebp_x86_64, lldb_esp_x86_64, 52 lldb_r8d_x86_64, // Low 32 bits or r8 53 lldb_r9d_x86_64, // Low 32 bits or r9 54 lldb_r10d_x86_64, // Low 32 bits or r10 55 lldb_r11d_x86_64, // Low 32 bits or r11 56 lldb_r12d_x86_64, // Low 32 bits or r12 57 lldb_r13d_x86_64, // Low 32 bits or r13 58 lldb_r14d_x86_64, // Low 32 bits or r14 59 lldb_r15d_x86_64, // Low 32 bits or r15 60 lldb_ax_x86_64, lldb_bx_x86_64, lldb_cx_x86_64, lldb_dx_x86_64, 61 lldb_di_x86_64, lldb_si_x86_64, lldb_bp_x86_64, lldb_sp_x86_64, 62 lldb_r8w_x86_64, // Low 16 bits or r8 63 lldb_r9w_x86_64, // Low 16 bits or r9 64 lldb_r10w_x86_64, // Low 16 bits or r10 65 lldb_r11w_x86_64, // Low 16 bits or r11 66 lldb_r12w_x86_64, // Low 16 bits or r12 67 lldb_r13w_x86_64, // Low 16 bits or r13 68 lldb_r14w_x86_64, // Low 16 bits or r14 69 lldb_r15w_x86_64, // Low 16 bits or r15 70 lldb_ah_x86_64, lldb_bh_x86_64, lldb_ch_x86_64, lldb_dh_x86_64, 71 lldb_al_x86_64, lldb_bl_x86_64, lldb_cl_x86_64, lldb_dl_x86_64, 72 lldb_dil_x86_64, lldb_sil_x86_64, lldb_bpl_x86_64, lldb_spl_x86_64, 73 lldb_r8l_x86_64, // Low 8 bits or r8 74 lldb_r9l_x86_64, // Low 8 bits or r9 75 lldb_r10l_x86_64, // Low 8 bits or r10 76 lldb_r11l_x86_64, // Low 8 bits or r11 77 lldb_r12l_x86_64, // Low 8 bits or r12 78 lldb_r13l_x86_64, // Low 8 bits or r13 79 lldb_r14l_x86_64, // Low 8 bits or r14 80 lldb_r15l_x86_64, // Low 8 bits or r15 81 LLDB_INVALID_REGNUM // register sets need to end with this flag 82 }; 83 static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) - 84 1 == 85 k_num_gpr_registers_x86_64, 86 "g_gpr_regnums_x86_64 has wrong number of register infos"); 87 88 // x86 64-bit floating point registers. 89 static const uint32_t g_fpu_regnums_x86_64[] = { 90 lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64, 91 lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64, 92 lldb_foseg_x86_64, lldb_fooff_x86_64, lldb_mxcsr_x86_64, 93 lldb_mxcsrmask_x86_64, lldb_st0_x86_64, lldb_st1_x86_64, 94 lldb_st2_x86_64, lldb_st3_x86_64, lldb_st4_x86_64, 95 lldb_st5_x86_64, lldb_st6_x86_64, lldb_st7_x86_64, 96 lldb_mm0_x86_64, lldb_mm1_x86_64, lldb_mm2_x86_64, 97 lldb_mm3_x86_64, lldb_mm4_x86_64, lldb_mm5_x86_64, 98 lldb_mm6_x86_64, lldb_mm7_x86_64, lldb_xmm0_x86_64, 99 lldb_xmm1_x86_64, lldb_xmm2_x86_64, lldb_xmm3_x86_64, 100 lldb_xmm4_x86_64, lldb_xmm5_x86_64, lldb_xmm6_x86_64, 101 lldb_xmm7_x86_64, lldb_xmm8_x86_64, lldb_xmm9_x86_64, 102 lldb_xmm10_x86_64, lldb_xmm11_x86_64, lldb_xmm12_x86_64, 103 lldb_xmm13_x86_64, lldb_xmm14_x86_64, lldb_xmm15_x86_64, 104 LLDB_INVALID_REGNUM // register sets need to end with this flag 105 }; 106 static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) - 107 1 == 108 k_num_fpr_registers_x86_64, 109 "g_fpu_regnums_x86_64 has wrong number of register infos"); 110 111 // x86 64-bit registers available via XState. 112 static const uint32_t g_xstate_regnums_x86_64[] = { 113 lldb_ymm0_x86_64, lldb_ymm1_x86_64, lldb_ymm2_x86_64, lldb_ymm3_x86_64, 114 lldb_ymm4_x86_64, lldb_ymm5_x86_64, lldb_ymm6_x86_64, lldb_ymm7_x86_64, 115 lldb_ymm8_x86_64, lldb_ymm9_x86_64, lldb_ymm10_x86_64, lldb_ymm11_x86_64, 116 lldb_ymm12_x86_64, lldb_ymm13_x86_64, lldb_ymm14_x86_64, lldb_ymm15_x86_64, 117 // Note: we currently do not provide them but this is needed to avoid 118 // unnamed groups in SBFrame::GetRegisterContext(). 119 lldb_bnd0_x86_64, lldb_bnd1_x86_64, lldb_bnd2_x86_64, 120 lldb_bnd3_x86_64, lldb_bndcfgu_x86_64, lldb_bndstatus_x86_64, 121 LLDB_INVALID_REGNUM // register sets need to end with this flag 122 }; 123 static_assert((sizeof(g_xstate_regnums_x86_64) / sizeof(g_xstate_regnums_x86_64[0])) - 124 1 == 125 k_num_avx_registers_x86_64 + k_num_mpx_registers_x86_64, 126 "g_xstate_regnums_x86_64 has wrong number of register infos"); 127 128 // x86 debug registers. 129 static const uint32_t g_dbr_regnums_x86_64[] = { 130 lldb_dr0_x86_64, lldb_dr1_x86_64, lldb_dr2_x86_64, lldb_dr3_x86_64, 131 lldb_dr4_x86_64, lldb_dr5_x86_64, lldb_dr6_x86_64, lldb_dr7_x86_64, 132 LLDB_INVALID_REGNUM // register sets need to end with this flag 133 }; 134 static_assert((sizeof(g_dbr_regnums_x86_64) / sizeof(g_dbr_regnums_x86_64[0])) - 135 1 == 136 k_num_dbr_registers_x86_64, 137 "g_dbr_regnums_x86_64 has wrong number of register infos"); 138 139 // x86 32-bit general purpose registers. 140 const uint32_t g_gpr_regnums_i386[] = { 141 lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386, 142 lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386, 143 lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386, 144 lldb_gs_i386, lldb_ss_i386, lldb_ds_i386, lldb_es_i386, 145 lldb_ax_i386, lldb_bx_i386, lldb_cx_i386, lldb_dx_i386, 146 lldb_di_i386, lldb_si_i386, lldb_bp_i386, lldb_sp_i386, 147 lldb_ah_i386, lldb_bh_i386, lldb_ch_i386, lldb_dh_i386, 148 lldb_al_i386, lldb_bl_i386, lldb_cl_i386, lldb_dl_i386, 149 LLDB_INVALID_REGNUM // register sets need to end with this flag 150 }; 151 static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) - 152 1 == 153 k_num_gpr_registers_i386, 154 "g_gpr_regnums_i386 has wrong number of register infos"); 155 156 // x86 32-bit floating point registers. 157 const uint32_t g_fpu_regnums_i386[] = { 158 lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386, 159 lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386, 160 lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386, 161 lldb_st2_i386, lldb_st3_i386, lldb_st4_i386, lldb_st5_i386, 162 lldb_st6_i386, lldb_st7_i386, lldb_mm0_i386, lldb_mm1_i386, 163 lldb_mm2_i386, lldb_mm3_i386, lldb_mm4_i386, lldb_mm5_i386, 164 lldb_mm6_i386, lldb_mm7_i386, lldb_xmm0_i386, lldb_xmm1_i386, 165 lldb_xmm2_i386, lldb_xmm3_i386, lldb_xmm4_i386, lldb_xmm5_i386, 166 lldb_xmm6_i386, lldb_xmm7_i386, 167 LLDB_INVALID_REGNUM // register sets need to end with this flag 168 }; 169 static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) - 170 1 == 171 k_num_fpr_registers_i386, 172 "g_fpu_regnums_i386 has wrong number of register infos"); 173 174 // x86 64-bit registers available via XState. 175 static const uint32_t g_xstate_regnums_i386[] = { 176 lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386, 177 lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386, 178 // Note: we currently do not provide them but this is needed to avoid 179 // unnamed groups in SBFrame::GetRegisterContext(). 180 lldb_bnd0_i386, lldb_bnd1_i386, lldb_bnd2_i386, 181 lldb_bnd3_i386, lldb_bndcfgu_i386, lldb_bndstatus_i386, 182 LLDB_INVALID_REGNUM // register sets need to end with this flag 183 }; 184 static_assert((sizeof(g_xstate_regnums_i386) / sizeof(g_xstate_regnums_i386[0])) - 185 1 == 186 k_num_avx_registers_i386 + k_num_mpx_registers_i386, 187 "g_xstate_regnums_i386 has wrong number of register infos"); 188 189 // x86 debug registers. 190 static const uint32_t g_dbr_regnums_i386[] = { 191 lldb_dr0_i386, lldb_dr1_i386, lldb_dr2_i386, lldb_dr3_i386, 192 lldb_dr4_i386, lldb_dr5_i386, lldb_dr6_i386, lldb_dr7_i386, 193 LLDB_INVALID_REGNUM // register sets need to end with this flag 194 }; 195 static_assert((sizeof(g_dbr_regnums_i386) / sizeof(g_dbr_regnums_i386[0])) - 196 1 == 197 k_num_dbr_registers_i386, 198 "g_dbr_regnums_i386 has wrong number of register infos"); 199 200 201 // Number of register sets provided by this context. 202 enum { k_num_register_sets = 4 }; 203 204 // Register sets for x86 32-bit. 205 static const RegisterSet g_reg_sets_i386[k_num_register_sets] = { 206 {"General Purpose Registers", "gpr", k_num_gpr_registers_i386, 207 g_gpr_regnums_i386}, 208 {"Floating Point Registers", "fpu", k_num_fpr_registers_i386, 209 g_fpu_regnums_i386}, 210 {"Extended State Registers", "xstate", 211 k_num_avx_registers_i386 + k_num_mpx_registers_i386, 212 g_xstate_regnums_i386}, 213 {"Debug Registers", "dbr", k_num_dbr_registers_i386, 214 g_dbr_regnums_i386}, 215 }; 216 217 // Register sets for x86 64-bit. 218 static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = { 219 {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64, 220 g_gpr_regnums_x86_64}, 221 {"Floating Point Registers", "fpu", k_num_fpr_registers_x86_64, 222 g_fpu_regnums_x86_64}, 223 {"Extended State Registers", "xstate", 224 k_num_avx_registers_x86_64 + k_num_mpx_registers_x86_64, 225 g_xstate_regnums_x86_64}, 226 {"Debug Registers", "dbr", k_num_dbr_registers_x86_64, 227 g_dbr_regnums_x86_64}, 228 }; 229 230 #define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize()) 231 } // namespace 232 233 NativeRegisterContextNetBSD * 234 NativeRegisterContextNetBSD::CreateHostNativeRegisterContextNetBSD( 235 const ArchSpec &target_arch, NativeThreadProtocol &native_thread) { 236 return new NativeRegisterContextNetBSD_x86_64(target_arch, native_thread); 237 } 238 239 // NativeRegisterContextNetBSD_x86_64 members. 240 241 static RegisterInfoInterface * 242 CreateRegisterInfoInterface(const ArchSpec &target_arch) { 243 if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) { 244 // 32-bit hosts run with a RegisterContextNetBSD_i386 context. 245 return new RegisterContextNetBSD_i386(target_arch); 246 } else { 247 assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) && 248 "Register setting path assumes this is a 64-bit host"); 249 // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64 250 // register context. 251 return new RegisterContextNetBSD_x86_64(target_arch); 252 } 253 } 254 255 NativeRegisterContextNetBSD_x86_64::NativeRegisterContextNetBSD_x86_64( 256 const ArchSpec &target_arch, NativeThreadProtocol &native_thread) 257 : NativeRegisterContextNetBSD(native_thread, 258 CreateRegisterInfoInterface(target_arch)), 259 m_gpr(), m_fpr(), m_dbr() {} 260 261 // CONSIDER after local and llgs debugging are merged, register set support can 262 // be moved into a base x86-64 class with IsRegisterSetAvailable made virtual. 263 uint32_t NativeRegisterContextNetBSD_x86_64::GetRegisterSetCount() const { 264 uint32_t sets = 0; 265 for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) { 266 if (GetSetForNativeRegNum(set_index) != -1) 267 ++sets; 268 } 269 270 return sets; 271 } 272 273 const RegisterSet * 274 NativeRegisterContextNetBSD_x86_64::GetRegisterSet(uint32_t set_index) const { 275 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { 276 case llvm::Triple::x86: 277 return &g_reg_sets_i386[set_index]; 278 case llvm::Triple::x86_64: 279 return &g_reg_sets_x86_64[set_index]; 280 default: 281 assert(false && "Unhandled target architecture."); 282 return nullptr; 283 } 284 285 return nullptr; 286 } 287 288 static constexpr int RegNumX86ToX86_64(int regnum) { 289 switch (regnum) { 290 case lldb_eax_i386: 291 return lldb_rax_x86_64; 292 case lldb_ebx_i386: 293 return lldb_rbx_x86_64; 294 case lldb_ecx_i386: 295 return lldb_rcx_x86_64; 296 case lldb_edx_i386: 297 return lldb_rdx_x86_64; 298 case lldb_edi_i386: 299 return lldb_rdi_x86_64; 300 case lldb_esi_i386: 301 return lldb_rsi_x86_64; 302 case lldb_ebp_i386: 303 return lldb_rbp_x86_64; 304 case lldb_esp_i386: 305 return lldb_rsp_x86_64; 306 case lldb_eip_i386: 307 return lldb_rip_x86_64; 308 case lldb_eflags_i386: 309 return lldb_rflags_x86_64; 310 case lldb_cs_i386: 311 return lldb_cs_x86_64; 312 case lldb_fs_i386: 313 return lldb_fs_x86_64; 314 case lldb_gs_i386: 315 return lldb_gs_x86_64; 316 case lldb_ss_i386: 317 return lldb_ss_x86_64; 318 case lldb_ds_i386: 319 return lldb_ds_x86_64; 320 case lldb_es_i386: 321 return lldb_es_x86_64; 322 case lldb_fctrl_i386: 323 return lldb_fctrl_x86_64; 324 case lldb_fstat_i386: 325 return lldb_fstat_x86_64; 326 case lldb_ftag_i386: 327 return lldb_fstat_x86_64; 328 case lldb_fop_i386: 329 return lldb_fop_x86_64; 330 case lldb_fiseg_i386: 331 return lldb_fiseg_x86_64; 332 case lldb_fioff_i386: 333 return lldb_fioff_x86_64; 334 case lldb_foseg_i386: 335 return lldb_foseg_x86_64; 336 case lldb_fooff_i386: 337 return lldb_fooff_x86_64; 338 case lldb_mxcsr_i386: 339 return lldb_mxcsr_x86_64; 340 case lldb_mxcsrmask_i386: 341 return lldb_mxcsrmask_x86_64; 342 case lldb_st0_i386: 343 case lldb_st1_i386: 344 case lldb_st2_i386: 345 case lldb_st3_i386: 346 case lldb_st4_i386: 347 case lldb_st5_i386: 348 case lldb_st6_i386: 349 case lldb_st7_i386: 350 return lldb_st0_x86_64 + regnum - lldb_st0_i386; 351 case lldb_mm0_i386: 352 case lldb_mm1_i386: 353 case lldb_mm2_i386: 354 case lldb_mm3_i386: 355 case lldb_mm4_i386: 356 case lldb_mm5_i386: 357 case lldb_mm6_i386: 358 case lldb_mm7_i386: 359 return lldb_mm0_x86_64 + regnum - lldb_mm0_i386; 360 case lldb_xmm0_i386: 361 case lldb_xmm1_i386: 362 case lldb_xmm2_i386: 363 case lldb_xmm3_i386: 364 case lldb_xmm4_i386: 365 case lldb_xmm5_i386: 366 case lldb_xmm6_i386: 367 case lldb_xmm7_i386: 368 return lldb_xmm0_x86_64 + regnum - lldb_xmm0_i386; 369 case lldb_ymm0_i386: 370 case lldb_ymm1_i386: 371 case lldb_ymm2_i386: 372 case lldb_ymm3_i386: 373 case lldb_ymm4_i386: 374 case lldb_ymm5_i386: 375 case lldb_ymm6_i386: 376 case lldb_ymm7_i386: 377 return lldb_ymm0_x86_64 + regnum - lldb_ymm0_i386; 378 case lldb_dr0_i386: 379 case lldb_dr1_i386: 380 case lldb_dr2_i386: 381 case lldb_dr3_i386: 382 case lldb_dr4_i386: 383 case lldb_dr5_i386: 384 case lldb_dr6_i386: 385 case lldb_dr7_i386: 386 return lldb_dr0_x86_64 + regnum - lldb_dr0_i386; 387 default: 388 assert(false && "Unhandled i386 register."); 389 return 0; 390 } 391 } 392 393 int NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum( 394 int reg_num) const { 395 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { 396 case llvm::Triple::x86: 397 if (reg_num <= k_last_gpr_i386) 398 return GPRegSet; 399 else if (reg_num <= k_last_fpr_i386) 400 return FPRegSet; 401 else if (reg_num <= k_last_avx_i386) 402 return XStateRegSet; // AVX 403 else if (reg_num <= lldb_dr7_i386) 404 return DBRegSet; // DBR 405 else 406 return -1; 407 case llvm::Triple::x86_64: 408 if (reg_num <= k_last_gpr_x86_64) 409 return GPRegSet; 410 else if (reg_num <= k_last_fpr_x86_64) 411 return FPRegSet; 412 else if (reg_num <= k_last_avx_x86_64) 413 return XStateRegSet; // AVX 414 else if (reg_num <= k_last_mpxr_x86_64) 415 return -1; // MPXR 416 else if (reg_num <= k_last_mpxc_x86_64) 417 return -1; // MPXC 418 else if (reg_num <= lldb_dr7_x86_64) 419 return DBRegSet; // DBR 420 else 421 return -1; 422 default: 423 assert(false && "Unhandled target architecture."); 424 return -1; 425 } 426 } 427 428 Status NativeRegisterContextNetBSD_x86_64::ReadRegisterSet(uint32_t set) { 429 switch (set) { 430 case GPRegSet: 431 return DoRegisterSet(PT_GETREGS, &m_gpr); 432 case FPRegSet: 433 #if defined(__x86_64__) 434 return DoRegisterSet(PT_GETFPREGS, &m_fpr); 435 #else 436 return DoRegisterSet(PT_GETXMMREGS, &m_fpr); 437 #endif 438 case DBRegSet: 439 return DoRegisterSet(PT_GETDBREGS, &m_dbr); 440 case XStateRegSet: 441 #ifdef HAVE_XSTATE 442 { 443 struct iovec iov = {&m_xstate, sizeof(m_xstate)}; 444 return DoRegisterSet(PT_GETXSTATE, &iov); 445 } 446 #else 447 return Status("XState is not supported by the kernel"); 448 #endif 449 } 450 llvm_unreachable("NativeRegisterContextNetBSD_x86_64::ReadRegisterSet"); 451 } 452 453 Status NativeRegisterContextNetBSD_x86_64::WriteRegisterSet(uint32_t set) { 454 switch (set) { 455 case GPRegSet: 456 return DoRegisterSet(PT_SETREGS, &m_gpr); 457 case FPRegSet: 458 #if defined(__x86_64__) 459 return DoRegisterSet(PT_SETFPREGS, &m_fpr); 460 #else 461 return DoRegisterSet(PT_SETXMMREGS, &m_fpr); 462 #endif 463 case DBRegSet: 464 return DoRegisterSet(PT_SETDBREGS, &m_dbr); 465 case XStateRegSet: 466 #ifdef HAVE_XSTATE 467 { 468 struct iovec iov = {&m_xstate, sizeof(m_xstate)}; 469 return DoRegisterSet(PT_SETXSTATE, &iov); 470 } 471 #else 472 return Status("XState is not supported by the kernel"); 473 #endif 474 } 475 llvm_unreachable("NativeRegisterContextNetBSD_x86_64::WriteRegisterSet"); 476 } 477 478 Status 479 NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info, 480 RegisterValue ®_value) { 481 Status error; 482 483 if (!reg_info) { 484 error.SetErrorString("reg_info NULL"); 485 return error; 486 } 487 488 uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; 489 if (reg == LLDB_INVALID_REGNUM) { 490 // This is likely an internal register for lldb use only and should not be 491 // directly queried. 492 error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb " 493 "register, cannot read directly", 494 reg_info->name); 495 return error; 496 } 497 498 int set = GetSetForNativeRegNum(reg); 499 if (set == -1) { 500 // This is likely an internal register for lldb use only and should not be 501 // directly queried. 502 error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set", 503 reg_info->name); 504 return error; 505 } 506 507 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { 508 case llvm::Triple::x86_64: 509 break; 510 case llvm::Triple::x86: 511 reg = RegNumX86ToX86_64(reg); 512 break; 513 default: 514 assert(false && "Unhandled target architecture."); 515 error.SetErrorString("Unhandled target architecture."); 516 return error; 517 } 518 519 error = ReadRegisterSet(set); 520 if (error.Fail()) 521 return error; 522 523 switch (reg) { 524 #if defined(__x86_64__) 525 case lldb_rax_x86_64: 526 reg_value = (uint64_t)m_gpr.regs[_REG_RAX]; 527 break; 528 case lldb_rbx_x86_64: 529 reg_value = (uint64_t)m_gpr.regs[_REG_RBX]; 530 break; 531 case lldb_rcx_x86_64: 532 reg_value = (uint64_t)m_gpr.regs[_REG_RCX]; 533 break; 534 case lldb_rdx_x86_64: 535 reg_value = (uint64_t)m_gpr.regs[_REG_RDX]; 536 break; 537 case lldb_rdi_x86_64: 538 reg_value = (uint64_t)m_gpr.regs[_REG_RDI]; 539 break; 540 case lldb_rsi_x86_64: 541 reg_value = (uint64_t)m_gpr.regs[_REG_RSI]; 542 break; 543 case lldb_rbp_x86_64: 544 reg_value = (uint64_t)m_gpr.regs[_REG_RBP]; 545 break; 546 case lldb_rsp_x86_64: 547 reg_value = (uint64_t)m_gpr.regs[_REG_RSP]; 548 break; 549 case lldb_r8_x86_64: 550 reg_value = (uint64_t)m_gpr.regs[_REG_R8]; 551 break; 552 case lldb_r9_x86_64: 553 reg_value = (uint64_t)m_gpr.regs[_REG_R9]; 554 break; 555 case lldb_r10_x86_64: 556 reg_value = (uint64_t)m_gpr.regs[_REG_R10]; 557 break; 558 case lldb_r11_x86_64: 559 reg_value = (uint64_t)m_gpr.regs[_REG_R11]; 560 break; 561 case lldb_r12_x86_64: 562 reg_value = (uint64_t)m_gpr.regs[_REG_R12]; 563 break; 564 case lldb_r13_x86_64: 565 reg_value = (uint64_t)m_gpr.regs[_REG_R13]; 566 break; 567 case lldb_r14_x86_64: 568 reg_value = (uint64_t)m_gpr.regs[_REG_R14]; 569 break; 570 case lldb_r15_x86_64: 571 reg_value = (uint64_t)m_gpr.regs[_REG_R15]; 572 break; 573 case lldb_rip_x86_64: 574 reg_value = (uint64_t)m_gpr.regs[_REG_RIP]; 575 break; 576 case lldb_rflags_x86_64: 577 reg_value = (uint64_t)m_gpr.regs[_REG_RFLAGS]; 578 break; 579 case lldb_cs_x86_64: 580 reg_value = (uint64_t)m_gpr.regs[_REG_CS]; 581 break; 582 case lldb_fs_x86_64: 583 reg_value = (uint64_t)m_gpr.regs[_REG_FS]; 584 break; 585 case lldb_gs_x86_64: 586 reg_value = (uint64_t)m_gpr.regs[_REG_GS]; 587 break; 588 case lldb_ss_x86_64: 589 reg_value = (uint64_t)m_gpr.regs[_REG_SS]; 590 break; 591 case lldb_ds_x86_64: 592 reg_value = (uint64_t)m_gpr.regs[_REG_DS]; 593 break; 594 case lldb_es_x86_64: 595 reg_value = (uint64_t)m_gpr.regs[_REG_ES]; 596 break; 597 #else 598 case lldb_rax_x86_64: 599 reg_value = (uint32_t)m_gpr.r_eax; 600 break; 601 case lldb_rbx_x86_64: 602 reg_value = (uint32_t)m_gpr.r_ebx; 603 break; 604 case lldb_rcx_x86_64: 605 reg_value = (uint32_t)m_gpr.r_ecx; 606 break; 607 case lldb_rdx_x86_64: 608 reg_value = (uint32_t)m_gpr.r_edx; 609 break; 610 case lldb_rdi_x86_64: 611 reg_value = (uint32_t)m_gpr.r_edi; 612 break; 613 case lldb_rsi_x86_64: 614 reg_value = (uint32_t)m_gpr.r_esi; 615 break; 616 case lldb_rsp_x86_64: 617 reg_value = (uint32_t)m_gpr.r_esp; 618 break; 619 case lldb_rbp_x86_64: 620 reg_value = (uint32_t)m_gpr.r_ebp; 621 break; 622 case lldb_rip_x86_64: 623 reg_value = (uint32_t)m_gpr.r_eip; 624 break; 625 case lldb_rflags_x86_64: 626 reg_value = (uint32_t)m_gpr.r_eflags; 627 break; 628 case lldb_cs_x86_64: 629 reg_value = (uint32_t)m_gpr.r_cs; 630 break; 631 case lldb_fs_x86_64: 632 reg_value = (uint32_t)m_gpr.r_fs; 633 break; 634 case lldb_gs_x86_64: 635 reg_value = (uint32_t)m_gpr.r_gs; 636 break; 637 case lldb_ss_x86_64: 638 reg_value = (uint32_t)m_gpr.r_ss; 639 break; 640 case lldb_ds_x86_64: 641 reg_value = (uint32_t)m_gpr.r_ds; 642 break; 643 case lldb_es_x86_64: 644 reg_value = (uint32_t)m_gpr.r_es; 645 break; 646 #endif 647 case lldb_fctrl_x86_64: 648 reg_value = (uint16_t)m_fpr.fxstate.fx_cw; 649 break; 650 case lldb_fstat_x86_64: 651 reg_value = (uint16_t)m_fpr.fxstate.fx_sw; 652 break; 653 case lldb_ftag_x86_64: 654 reg_value = (uint8_t)m_fpr.fxstate.fx_tw; 655 break; 656 case lldb_fop_x86_64: 657 reg_value = (uint64_t)m_fpr.fxstate.fx_opcode; 658 break; 659 case lldb_fiseg_x86_64: 660 reg_value = (uint64_t)m_fpr.fxstate.fx_ip.fa_64; 661 break; 662 case lldb_fioff_x86_64: 663 reg_value = (uint32_t)m_fpr.fxstate.fx_ip.fa_32.fa_off; 664 break; 665 case lldb_foseg_x86_64: 666 reg_value = (uint64_t)m_fpr.fxstate.fx_dp.fa_64; 667 break; 668 case lldb_fooff_x86_64: 669 reg_value = (uint32_t)m_fpr.fxstate.fx_dp.fa_32.fa_off; 670 break; 671 case lldb_mxcsr_x86_64: 672 reg_value = (uint32_t)m_fpr.fxstate.fx_mxcsr; 673 break; 674 case lldb_mxcsrmask_x86_64: 675 reg_value = (uint32_t)m_fpr.fxstate.fx_mxcsr_mask; 676 break; 677 case lldb_st0_x86_64: 678 case lldb_st1_x86_64: 679 case lldb_st2_x86_64: 680 case lldb_st3_x86_64: 681 case lldb_st4_x86_64: 682 case lldb_st5_x86_64: 683 case lldb_st6_x86_64: 684 case lldb_st7_x86_64: 685 reg_value.SetBytes(&m_fpr.fxstate.fx_87_ac[reg - lldb_st0_x86_64], 686 reg_info->byte_size, endian::InlHostByteOrder()); 687 break; 688 case lldb_mm0_x86_64: 689 case lldb_mm1_x86_64: 690 case lldb_mm2_x86_64: 691 case lldb_mm3_x86_64: 692 case lldb_mm4_x86_64: 693 case lldb_mm5_x86_64: 694 case lldb_mm6_x86_64: 695 case lldb_mm7_x86_64: 696 reg_value.SetBytes(&m_fpr.fxstate.fx_87_ac[reg - lldb_mm0_x86_64], 697 reg_info->byte_size, endian::InlHostByteOrder()); 698 break; 699 case lldb_xmm0_x86_64: 700 case lldb_xmm1_x86_64: 701 case lldb_xmm2_x86_64: 702 case lldb_xmm3_x86_64: 703 case lldb_xmm4_x86_64: 704 case lldb_xmm5_x86_64: 705 case lldb_xmm6_x86_64: 706 case lldb_xmm7_x86_64: 707 case lldb_xmm8_x86_64: 708 case lldb_xmm9_x86_64: 709 case lldb_xmm10_x86_64: 710 case lldb_xmm11_x86_64: 711 case lldb_xmm12_x86_64: 712 case lldb_xmm13_x86_64: 713 case lldb_xmm14_x86_64: 714 case lldb_xmm15_x86_64: 715 reg_value.SetBytes(&m_fpr.fxstate.fx_xmm[reg - lldb_xmm0_x86_64], 716 reg_info->byte_size, endian::InlHostByteOrder()); 717 break; 718 case lldb_ymm0_x86_64: 719 case lldb_ymm1_x86_64: 720 case lldb_ymm2_x86_64: 721 case lldb_ymm3_x86_64: 722 case lldb_ymm4_x86_64: 723 case lldb_ymm5_x86_64: 724 case lldb_ymm6_x86_64: 725 case lldb_ymm7_x86_64: 726 case lldb_ymm8_x86_64: 727 case lldb_ymm9_x86_64: 728 case lldb_ymm10_x86_64: 729 case lldb_ymm11_x86_64: 730 case lldb_ymm12_x86_64: 731 case lldb_ymm13_x86_64: 732 case lldb_ymm14_x86_64: 733 case lldb_ymm15_x86_64: 734 #ifdef HAVE_XSTATE 735 if (!(m_xstate.xs_rfbm & XCR0_SSE) || 736 !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) { 737 error.SetErrorStringWithFormat("register \"%s\" not supported by CPU/kernel", 738 reg_info->name); 739 } else { 740 uint32_t reg_index = reg - lldb_ymm0_x86_64; 741 YMMReg ymm = XStateToYMM( 742 m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes, 743 m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes); 744 reg_value.SetBytes(ymm.bytes, reg_info->byte_size, 745 endian::InlHostByteOrder()); 746 } 747 #else 748 error.SetErrorString("XState queries not supported by the kernel"); 749 #endif 750 break; 751 case lldb_dr0_x86_64: 752 case lldb_dr1_x86_64: 753 case lldb_dr2_x86_64: 754 case lldb_dr3_x86_64: 755 case lldb_dr4_x86_64: 756 case lldb_dr5_x86_64: 757 case lldb_dr6_x86_64: 758 case lldb_dr7_x86_64: 759 reg_value = (uint64_t)m_dbr.dr[reg - lldb_dr0_x86_64]; 760 break; 761 } 762 763 return error; 764 } 765 766 Status NativeRegisterContextNetBSD_x86_64::WriteRegister( 767 const RegisterInfo *reg_info, const RegisterValue ®_value) { 768 769 Status error; 770 771 if (!reg_info) { 772 error.SetErrorString("reg_info NULL"); 773 return error; 774 } 775 776 uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; 777 if (reg == LLDB_INVALID_REGNUM) { 778 // This is likely an internal register for lldb use only and should not be 779 // directly queried. 780 error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb " 781 "register, cannot read directly", 782 reg_info->name); 783 return error; 784 } 785 786 int set = GetSetForNativeRegNum(reg); 787 if (set == -1) { 788 // This is likely an internal register for lldb use only and should not be 789 // directly queried. 790 error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set", 791 reg_info->name); 792 return error; 793 } 794 795 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { 796 case llvm::Triple::x86_64: 797 break; 798 case llvm::Triple::x86: 799 reg = RegNumX86ToX86_64(reg); 800 break; 801 default: 802 assert(false && "Unhandled target architecture."); 803 error.SetErrorString("Unhandled target architecture."); 804 return error; 805 } 806 807 error = ReadRegisterSet(set); 808 if (error.Fail()) 809 return error; 810 811 switch (reg) { 812 #if defined(__x86_64__) 813 case lldb_rax_x86_64: 814 m_gpr.regs[_REG_RAX] = reg_value.GetAsUInt64(); 815 break; 816 case lldb_rbx_x86_64: 817 m_gpr.regs[_REG_RBX] = reg_value.GetAsUInt64(); 818 break; 819 case lldb_rcx_x86_64: 820 m_gpr.regs[_REG_RCX] = reg_value.GetAsUInt64(); 821 break; 822 case lldb_rdx_x86_64: 823 m_gpr.regs[_REG_RDX] = reg_value.GetAsUInt64(); 824 break; 825 case lldb_rdi_x86_64: 826 m_gpr.regs[_REG_RDI] = reg_value.GetAsUInt64(); 827 break; 828 case lldb_rsi_x86_64: 829 m_gpr.regs[_REG_RSI] = reg_value.GetAsUInt64(); 830 break; 831 case lldb_rbp_x86_64: 832 m_gpr.regs[_REG_RBP] = reg_value.GetAsUInt64(); 833 break; 834 case lldb_rsp_x86_64: 835 m_gpr.regs[_REG_RSP] = reg_value.GetAsUInt64(); 836 break; 837 case lldb_r8_x86_64: 838 m_gpr.regs[_REG_R8] = reg_value.GetAsUInt64(); 839 break; 840 case lldb_r9_x86_64: 841 m_gpr.regs[_REG_R9] = reg_value.GetAsUInt64(); 842 break; 843 case lldb_r10_x86_64: 844 m_gpr.regs[_REG_R10] = reg_value.GetAsUInt64(); 845 break; 846 case lldb_r11_x86_64: 847 m_gpr.regs[_REG_R11] = reg_value.GetAsUInt64(); 848 break; 849 case lldb_r12_x86_64: 850 m_gpr.regs[_REG_R12] = reg_value.GetAsUInt64(); 851 break; 852 case lldb_r13_x86_64: 853 m_gpr.regs[_REG_R13] = reg_value.GetAsUInt64(); 854 break; 855 case lldb_r14_x86_64: 856 m_gpr.regs[_REG_R14] = reg_value.GetAsUInt64(); 857 break; 858 case lldb_r15_x86_64: 859 m_gpr.regs[_REG_R15] = reg_value.GetAsUInt64(); 860 break; 861 case lldb_rip_x86_64: 862 m_gpr.regs[_REG_RIP] = reg_value.GetAsUInt64(); 863 break; 864 case lldb_rflags_x86_64: 865 m_gpr.regs[_REG_RFLAGS] = reg_value.GetAsUInt64(); 866 break; 867 case lldb_cs_x86_64: 868 m_gpr.regs[_REG_CS] = reg_value.GetAsUInt64(); 869 break; 870 case lldb_fs_x86_64: 871 m_gpr.regs[_REG_FS] = reg_value.GetAsUInt64(); 872 break; 873 case lldb_gs_x86_64: 874 m_gpr.regs[_REG_GS] = reg_value.GetAsUInt64(); 875 break; 876 case lldb_ss_x86_64: 877 m_gpr.regs[_REG_SS] = reg_value.GetAsUInt64(); 878 break; 879 case lldb_ds_x86_64: 880 m_gpr.regs[_REG_DS] = reg_value.GetAsUInt64(); 881 break; 882 case lldb_es_x86_64: 883 m_gpr.regs[_REG_ES] = reg_value.GetAsUInt64(); 884 break; 885 #else 886 case lldb_rax_x86_64: 887 m_gpr.r_eax = reg_value.GetAsUInt32(); 888 break; 889 case lldb_rbx_x86_64: 890 m_gpr.r_ebx = reg_value.GetAsUInt32(); 891 break; 892 case lldb_rcx_x86_64: 893 m_gpr.r_ecx = reg_value.GetAsUInt32(); 894 break; 895 case lldb_rdx_x86_64: 896 m_gpr.r_edx = reg_value.GetAsUInt32(); 897 break; 898 case lldb_rdi_x86_64: 899 m_gpr.r_edi = reg_value.GetAsUInt32(); 900 break; 901 case lldb_rsi_x86_64: 902 m_gpr.r_esi = reg_value.GetAsUInt32(); 903 break; 904 case lldb_rsp_x86_64: 905 m_gpr.r_esp = reg_value.GetAsUInt32(); 906 break; 907 case lldb_rbp_x86_64: 908 m_gpr.r_ebp = reg_value.GetAsUInt32(); 909 break; 910 case lldb_rip_x86_64: 911 m_gpr.r_eip = reg_value.GetAsUInt32(); 912 break; 913 case lldb_rflags_x86_64: 914 m_gpr.r_eflags = reg_value.GetAsUInt32(); 915 break; 916 case lldb_cs_x86_64: 917 m_gpr.r_cs = reg_value.GetAsUInt32(); 918 break; 919 case lldb_fs_x86_64: 920 m_gpr.r_fs = reg_value.GetAsUInt32(); 921 break; 922 case lldb_gs_x86_64: 923 m_gpr.r_gs = reg_value.GetAsUInt32(); 924 break; 925 case lldb_ss_x86_64: 926 m_gpr.r_ss = reg_value.GetAsUInt32(); 927 break; 928 case lldb_ds_x86_64: 929 m_gpr.r_ds = reg_value.GetAsUInt32(); 930 break; 931 case lldb_es_x86_64: 932 m_gpr.r_es = reg_value.GetAsUInt32(); 933 break; 934 #endif 935 case lldb_fctrl_x86_64: 936 m_fpr.fxstate.fx_cw = reg_value.GetAsUInt16(); 937 break; 938 case lldb_fstat_x86_64: 939 m_fpr.fxstate.fx_sw = reg_value.GetAsUInt16(); 940 break; 941 case lldb_ftag_x86_64: 942 m_fpr.fxstate.fx_tw = reg_value.GetAsUInt8(); 943 break; 944 case lldb_fop_x86_64: 945 m_fpr.fxstate.fx_opcode = reg_value.GetAsUInt16(); 946 break; 947 case lldb_fiseg_x86_64: 948 m_fpr.fxstate.fx_ip.fa_64 = reg_value.GetAsUInt64(); 949 break; 950 case lldb_fioff_x86_64: 951 m_fpr.fxstate.fx_ip.fa_32.fa_off = reg_value.GetAsUInt32(); 952 break; 953 case lldb_foseg_x86_64: 954 m_fpr.fxstate.fx_dp.fa_64 = reg_value.GetAsUInt64(); 955 break; 956 case lldb_fooff_x86_64: 957 m_fpr.fxstate.fx_dp.fa_32.fa_off = reg_value.GetAsUInt32(); 958 break; 959 case lldb_mxcsr_x86_64: 960 m_fpr.fxstate.fx_mxcsr = reg_value.GetAsUInt32(); 961 break; 962 case lldb_mxcsrmask_x86_64: 963 m_fpr.fxstate.fx_mxcsr_mask = reg_value.GetAsUInt32(); 964 break; 965 case lldb_st0_x86_64: 966 case lldb_st1_x86_64: 967 case lldb_st2_x86_64: 968 case lldb_st3_x86_64: 969 case lldb_st4_x86_64: 970 case lldb_st5_x86_64: 971 case lldb_st6_x86_64: 972 case lldb_st7_x86_64: 973 ::memcpy(&m_fpr.fxstate.fx_87_ac[reg - lldb_st0_x86_64], 974 reg_value.GetBytes(), reg_value.GetByteSize()); 975 break; 976 case lldb_mm0_x86_64: 977 case lldb_mm1_x86_64: 978 case lldb_mm2_x86_64: 979 case lldb_mm3_x86_64: 980 case lldb_mm4_x86_64: 981 case lldb_mm5_x86_64: 982 case lldb_mm6_x86_64: 983 case lldb_mm7_x86_64: 984 ::memcpy(&m_fpr.fxstate.fx_87_ac[reg - lldb_mm0_x86_64], 985 reg_value.GetBytes(), reg_value.GetByteSize()); 986 break; 987 case lldb_xmm0_x86_64: 988 case lldb_xmm1_x86_64: 989 case lldb_xmm2_x86_64: 990 case lldb_xmm3_x86_64: 991 case lldb_xmm4_x86_64: 992 case lldb_xmm5_x86_64: 993 case lldb_xmm6_x86_64: 994 case lldb_xmm7_x86_64: 995 case lldb_xmm8_x86_64: 996 case lldb_xmm9_x86_64: 997 case lldb_xmm10_x86_64: 998 case lldb_xmm11_x86_64: 999 case lldb_xmm12_x86_64: 1000 case lldb_xmm13_x86_64: 1001 case lldb_xmm14_x86_64: 1002 case lldb_xmm15_x86_64: 1003 ::memcpy(&m_fpr.fxstate.fx_xmm[reg - lldb_xmm0_x86_64], 1004 reg_value.GetBytes(), reg_value.GetByteSize()); 1005 break; 1006 case lldb_ymm0_x86_64: 1007 case lldb_ymm1_x86_64: 1008 case lldb_ymm2_x86_64: 1009 case lldb_ymm3_x86_64: 1010 case lldb_ymm4_x86_64: 1011 case lldb_ymm5_x86_64: 1012 case lldb_ymm6_x86_64: 1013 case lldb_ymm7_x86_64: 1014 case lldb_ymm8_x86_64: 1015 case lldb_ymm9_x86_64: 1016 case lldb_ymm10_x86_64: 1017 case lldb_ymm11_x86_64: 1018 case lldb_ymm12_x86_64: 1019 case lldb_ymm13_x86_64: 1020 case lldb_ymm14_x86_64: 1021 case lldb_ymm15_x86_64: 1022 #ifdef HAVE_XSTATE 1023 if (!(m_xstate.xs_rfbm & XCR0_SSE) || 1024 !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) { 1025 error.SetErrorStringWithFormat("register \"%s\" not supported by CPU/kernel", 1026 reg_info->name); 1027 } else { 1028 uint32_t reg_index = reg - lldb_ymm0_x86_64; 1029 YMMReg ymm; 1030 ::memcpy(ymm.bytes, reg_value.GetBytes(), reg_value.GetByteSize()); 1031 YMMToXState(ymm, 1032 m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes, 1033 m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes); 1034 } 1035 #else 1036 error.SetErrorString("XState not supported by the kernel"); 1037 #endif 1038 break; 1039 case lldb_dr0_x86_64: 1040 case lldb_dr1_x86_64: 1041 case lldb_dr2_x86_64: 1042 case lldb_dr3_x86_64: 1043 case lldb_dr4_x86_64: 1044 case lldb_dr5_x86_64: 1045 case lldb_dr6_x86_64: 1046 case lldb_dr7_x86_64: 1047 m_dbr.dr[reg - lldb_dr0_x86_64] = reg_value.GetAsUInt64(); 1048 break; 1049 } 1050 1051 return WriteRegisterSet(set); 1052 } 1053 1054 Status NativeRegisterContextNetBSD_x86_64::ReadAllRegisterValues( 1055 lldb::DataBufferSP &data_sp) { 1056 Status error; 1057 1058 data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0)); 1059 error = ReadRegisterSet(GPRegSet); 1060 if (error.Fail()) 1061 return error; 1062 1063 uint8_t *dst = data_sp->GetBytes(); 1064 ::memcpy(dst, &m_gpr, GetRegisterInfoInterface().GetGPRSize()); 1065 dst += GetRegisterInfoInterface().GetGPRSize(); 1066 1067 return error; 1068 } 1069 1070 Status NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues( 1071 const lldb::DataBufferSP &data_sp) { 1072 Status error; 1073 1074 if (!data_sp) { 1075 error.SetErrorStringWithFormat( 1076 "NativeRegisterContextNetBSD_x86_64::%s invalid data_sp provided", 1077 __FUNCTION__); 1078 return error; 1079 } 1080 1081 if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) { 1082 error.SetErrorStringWithFormat( 1083 "NativeRegisterContextNetBSD_x86_64::%s data_sp contained mismatched " 1084 "data size, expected %zu, actual %" PRIu64, 1085 __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize()); 1086 return error; 1087 } 1088 1089 uint8_t *src = data_sp->GetBytes(); 1090 if (src == nullptr) { 1091 error.SetErrorStringWithFormat("NativeRegisterContextNetBSD_x86_64::%s " 1092 "DataBuffer::GetBytes() returned a null " 1093 "pointer", 1094 __FUNCTION__); 1095 return error; 1096 } 1097 ::memcpy(&m_gpr, src, GetRegisterInfoInterface().GetGPRSize()); 1098 1099 error = WriteRegisterSet(GPRegSet); 1100 if (error.Fail()) 1101 return error; 1102 src += GetRegisterInfoInterface().GetGPRSize(); 1103 1104 return error; 1105 } 1106 1107 int NativeRegisterContextNetBSD_x86_64::GetDR(int num) const { 1108 assert(num >= 0 && num <= 7); 1109 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { 1110 case llvm::Triple::x86: 1111 return lldb_dr0_i386 + num; 1112 case llvm::Triple::x86_64: 1113 return lldb_dr0_x86_64 + num; 1114 default: 1115 return -1; 1116 } 1117 } 1118 1119 Status NativeRegisterContextNetBSD_x86_64::IsWatchpointHit(uint32_t wp_index, 1120 bool &is_hit) { 1121 if (wp_index >= NumSupportedHardwareWatchpoints()) 1122 return Status("Watchpoint index out of range"); 1123 1124 RegisterValue reg_value; 1125 const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(GetDR(6)); 1126 Status error = ReadRegister(reg_info, reg_value); 1127 if (error.Fail()) { 1128 is_hit = false; 1129 return error; 1130 } 1131 1132 uint64_t status_bits = reg_value.GetAsUInt64(); 1133 1134 is_hit = status_bits & (1 << wp_index); 1135 1136 return error; 1137 } 1138 1139 Status NativeRegisterContextNetBSD_x86_64::GetWatchpointHitIndex( 1140 uint32_t &wp_index, lldb::addr_t trap_addr) { 1141 uint32_t num_hw_wps = NumSupportedHardwareWatchpoints(); 1142 for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) { 1143 bool is_hit; 1144 Status error = IsWatchpointHit(wp_index, is_hit); 1145 if (error.Fail()) { 1146 wp_index = LLDB_INVALID_INDEX32; 1147 return error; 1148 } else if (is_hit) { 1149 return error; 1150 } 1151 } 1152 wp_index = LLDB_INVALID_INDEX32; 1153 return Status(); 1154 } 1155 1156 Status NativeRegisterContextNetBSD_x86_64::IsWatchpointVacant(uint32_t wp_index, 1157 bool &is_vacant) { 1158 if (wp_index >= NumSupportedHardwareWatchpoints()) 1159 return Status("Watchpoint index out of range"); 1160 1161 RegisterValue reg_value; 1162 const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(GetDR(7)); 1163 Status error = ReadRegister(reg_info, reg_value); 1164 if (error.Fail()) { 1165 is_vacant = false; 1166 return error; 1167 } 1168 1169 uint64_t control_bits = reg_value.GetAsUInt64(); 1170 1171 is_vacant = !(control_bits & (1 << (2 * wp_index + 1))); 1172 1173 return error; 1174 } 1175 1176 Status NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpointWithIndex( 1177 lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) { 1178 1179 if (wp_index >= NumSupportedHardwareWatchpoints()) 1180 return Status("Watchpoint index out of range"); 1181 1182 // Read only watchpoints aren't supported on x86_64. Fall back to read/write 1183 // waitchpoints instead. 1184 // TODO: Add logic to detect when a write happens and ignore that watchpoint 1185 // hit. 1186 if (watch_flags == 0x2) 1187 watch_flags = 0x3; 1188 1189 if (watch_flags != 0x1 && watch_flags != 0x3) 1190 return Status("Invalid read/write bits for watchpoint"); 1191 1192 if (size != 1 && size != 2 && size != 4 && size != 8) 1193 return Status("Invalid size for watchpoint"); 1194 1195 bool is_vacant; 1196 Status error = IsWatchpointVacant(wp_index, is_vacant); 1197 if (error.Fail()) 1198 return error; 1199 if (!is_vacant) 1200 return Status("Watchpoint index not vacant"); 1201 1202 const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7)); 1203 RegisterValue dr7_value; 1204 error = ReadRegister(reg_info_dr7, dr7_value); 1205 if (error.Fail()) 1206 return error; 1207 1208 // for watchpoints 0, 1, 2, or 3, respectively, set bits 1, 3, 5, or 7 1209 uint64_t enable_bit = 1 << (2 * wp_index + 1); 1210 1211 // set bits 16-17, 20-21, 24-25, or 28-29 1212 // with 0b01 for write, and 0b11 for read/write 1213 uint64_t rw_bits = watch_flags << (16 + 4 * wp_index); 1214 1215 // set bits 18-19, 22-23, 26-27, or 30-31 1216 // with 0b00, 0b01, 0b10, or 0b11 1217 // for 1, 2, 8 (if supported), or 4 bytes, respectively 1218 uint64_t size_bits = (size == 8 ? 0x2 : size - 1) << (18 + 4 * wp_index); 1219 1220 uint64_t bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index)); 1221 1222 uint64_t control_bits = dr7_value.GetAsUInt64() & ~bit_mask; 1223 1224 control_bits |= enable_bit | rw_bits | size_bits; 1225 1226 const RegisterInfo *const reg_info_drN = 1227 GetRegisterInfoAtIndex(GetDR(wp_index)); 1228 RegisterValue drN_value; 1229 error = ReadRegister(reg_info_drN, drN_value); 1230 if (error.Fail()) 1231 return error; 1232 1233 // clear dr6 if address or bits changed (i.e. we're not reenabling the same 1234 // watchpoint) 1235 if (drN_value.GetAsUInt64() != addr || 1236 (dr7_value.GetAsUInt64() & bit_mask) != (rw_bits | size_bits)) { 1237 ClearWatchpointHit(wp_index); 1238 1239 error = WriteRegister(reg_info_drN, RegisterValue(addr)); 1240 if (error.Fail()) 1241 return error; 1242 } 1243 1244 error = WriteRegister(reg_info_dr7, RegisterValue(control_bits)); 1245 if (error.Fail()) 1246 return error; 1247 1248 error.Clear(); 1249 return error; 1250 } 1251 1252 bool NativeRegisterContextNetBSD_x86_64::ClearHardwareWatchpoint( 1253 uint32_t wp_index) { 1254 if (wp_index >= NumSupportedHardwareWatchpoints()) 1255 return false; 1256 1257 // for watchpoints 0, 1, 2, or 3, respectively, clear bits 0-1, 2-3, 4-5 1258 // or 6-7 of the debug control register (DR7) 1259 const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7)); 1260 RegisterValue reg_value; 1261 Status error = ReadRegister(reg_info_dr7, reg_value); 1262 if (error.Fail()) 1263 return false; 1264 uint64_t bit_mask = 0x3 << (2 * wp_index); 1265 uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask; 1266 1267 return WriteRegister(reg_info_dr7, RegisterValue(control_bits)).Success(); 1268 } 1269 1270 Status NativeRegisterContextNetBSD_x86_64::ClearWatchpointHit(uint32_t wp_index) { 1271 if (wp_index >= NumSupportedHardwareWatchpoints()) 1272 return Status("Watchpoint index out of range"); 1273 1274 // for watchpoints 0, 1, 2, or 3, respectively, check bits 0, 1, 2, or 3 of 1275 // the debug status register (DR6) 1276 const RegisterInfo *const reg_info_dr6 = GetRegisterInfoAtIndex(GetDR(6)); 1277 RegisterValue reg_value; 1278 Status error = ReadRegister(reg_info_dr6, reg_value); 1279 if (error.Fail()) 1280 return error; 1281 1282 uint64_t bit_mask = 1 << wp_index; 1283 uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask; 1284 return WriteRegister(reg_info_dr6, RegisterValue(status_bits)); 1285 } 1286 1287 Status NativeRegisterContextNetBSD_x86_64::ClearAllHardwareWatchpoints() { 1288 RegisterValue reg_value; 1289 1290 // clear bits {0-4} of the debug status register (DR6) 1291 const RegisterInfo *const reg_info_dr6 = GetRegisterInfoAtIndex(GetDR(6)); 1292 Status error = ReadRegister(reg_info_dr6, reg_value); 1293 if (error.Fail()) 1294 return error; 1295 uint64_t bit_mask = 0xF; 1296 uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask; 1297 error = WriteRegister(reg_info_dr6, RegisterValue(status_bits)); 1298 if (error.Fail()) 1299 return error; 1300 1301 // clear bits {0-7,16-31} of the debug control register (DR7) 1302 const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7)); 1303 error = ReadRegister(reg_info_dr7, reg_value); 1304 if (error.Fail()) 1305 return error; 1306 bit_mask = 0xFF | (0xFFFF << 16); 1307 uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask; 1308 return WriteRegister(reg_info_dr7, RegisterValue(control_bits)); 1309 } 1310 1311 uint32_t NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpoint( 1312 lldb::addr_t addr, size_t size, uint32_t watch_flags) { 1313 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); 1314 const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); 1315 for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index) { 1316 bool is_vacant; 1317 Status error = IsWatchpointVacant(wp_index, is_vacant); 1318 if (is_vacant) { 1319 error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index); 1320 if (error.Success()) 1321 return wp_index; 1322 } 1323 if (error.Fail() && log) { 1324 LLDB_LOGF(log, "NativeRegisterContextNetBSD_x86_64::%s Error: %s", 1325 __FUNCTION__, error.AsCString()); 1326 } 1327 } 1328 return LLDB_INVALID_INDEX32; 1329 } 1330 1331 lldb::addr_t 1332 NativeRegisterContextNetBSD_x86_64::GetWatchpointAddress(uint32_t wp_index) { 1333 if (wp_index >= NumSupportedHardwareWatchpoints()) 1334 return LLDB_INVALID_ADDRESS; 1335 RegisterValue reg_value; 1336 const RegisterInfo *const reg_info_drN = 1337 GetRegisterInfoAtIndex(GetDR(wp_index)); 1338 if (ReadRegister(reg_info_drN, reg_value).Fail()) 1339 return LLDB_INVALID_ADDRESS; 1340 return reg_value.GetAsUInt64(); 1341 } 1342 1343 uint32_t NativeRegisterContextNetBSD_x86_64::NumSupportedHardwareWatchpoints() { 1344 // Available debug address registers: dr0, dr1, dr2, dr3 1345 return 4; 1346 } 1347 1348 Status NativeRegisterContextNetBSD_x86_64::CopyHardwareWatchpointsFrom( 1349 NativeRegisterContextNetBSD &source) { 1350 auto &r_source = static_cast<NativeRegisterContextNetBSD_x86_64&>(source); 1351 Status res = r_source.ReadRegisterSet(DBRegSet); 1352 if (!res.Fail()) { 1353 // copy dbregs only if any watchpoints were set 1354 if ((r_source.m_dbr.dr[7] & 0xFF) == 0) 1355 return res; 1356 1357 m_dbr = r_source.m_dbr; 1358 res = WriteRegisterSet(DBRegSet); 1359 } 1360 return res; 1361 } 1362 1363 #endif // defined(__x86_64__) 1364