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 llvm_unreachable("Unhandled target architecture."); 282 } 283 } 284 285 static constexpr int RegNumX86ToX86_64(int regnum) { 286 switch (regnum) { 287 case lldb_eax_i386: 288 return lldb_rax_x86_64; 289 case lldb_ebx_i386: 290 return lldb_rbx_x86_64; 291 case lldb_ecx_i386: 292 return lldb_rcx_x86_64; 293 case lldb_edx_i386: 294 return lldb_rdx_x86_64; 295 case lldb_edi_i386: 296 return lldb_rdi_x86_64; 297 case lldb_esi_i386: 298 return lldb_rsi_x86_64; 299 case lldb_ebp_i386: 300 return lldb_rbp_x86_64; 301 case lldb_esp_i386: 302 return lldb_rsp_x86_64; 303 case lldb_eip_i386: 304 return lldb_rip_x86_64; 305 case lldb_eflags_i386: 306 return lldb_rflags_x86_64; 307 case lldb_cs_i386: 308 return lldb_cs_x86_64; 309 case lldb_fs_i386: 310 return lldb_fs_x86_64; 311 case lldb_gs_i386: 312 return lldb_gs_x86_64; 313 case lldb_ss_i386: 314 return lldb_ss_x86_64; 315 case lldb_ds_i386: 316 return lldb_ds_x86_64; 317 case lldb_es_i386: 318 return lldb_es_x86_64; 319 case lldb_fctrl_i386: 320 return lldb_fctrl_x86_64; 321 case lldb_fstat_i386: 322 return lldb_fstat_x86_64; 323 case lldb_ftag_i386: 324 return lldb_ftag_x86_64; 325 case lldb_fop_i386: 326 return lldb_fop_x86_64; 327 case lldb_fiseg_i386: 328 return lldb_fiseg_x86_64; 329 case lldb_fioff_i386: 330 return lldb_fioff_x86_64; 331 case lldb_foseg_i386: 332 return lldb_foseg_x86_64; 333 case lldb_fooff_i386: 334 return lldb_fooff_x86_64; 335 case lldb_mxcsr_i386: 336 return lldb_mxcsr_x86_64; 337 case lldb_mxcsrmask_i386: 338 return lldb_mxcsrmask_x86_64; 339 case lldb_st0_i386: 340 case lldb_st1_i386: 341 case lldb_st2_i386: 342 case lldb_st3_i386: 343 case lldb_st4_i386: 344 case lldb_st5_i386: 345 case lldb_st6_i386: 346 case lldb_st7_i386: 347 return lldb_st0_x86_64 + regnum - lldb_st0_i386; 348 case lldb_mm0_i386: 349 case lldb_mm1_i386: 350 case lldb_mm2_i386: 351 case lldb_mm3_i386: 352 case lldb_mm4_i386: 353 case lldb_mm5_i386: 354 case lldb_mm6_i386: 355 case lldb_mm7_i386: 356 return lldb_mm0_x86_64 + regnum - lldb_mm0_i386; 357 case lldb_xmm0_i386: 358 case lldb_xmm1_i386: 359 case lldb_xmm2_i386: 360 case lldb_xmm3_i386: 361 case lldb_xmm4_i386: 362 case lldb_xmm5_i386: 363 case lldb_xmm6_i386: 364 case lldb_xmm7_i386: 365 return lldb_xmm0_x86_64 + regnum - lldb_xmm0_i386; 366 case lldb_ymm0_i386: 367 case lldb_ymm1_i386: 368 case lldb_ymm2_i386: 369 case lldb_ymm3_i386: 370 case lldb_ymm4_i386: 371 case lldb_ymm5_i386: 372 case lldb_ymm6_i386: 373 case lldb_ymm7_i386: 374 return lldb_ymm0_x86_64 + regnum - lldb_ymm0_i386; 375 case lldb_bnd0_i386: 376 case lldb_bnd1_i386: 377 case lldb_bnd2_i386: 378 case lldb_bnd3_i386: 379 return lldb_bnd0_x86_64 + regnum - lldb_bnd0_i386; 380 case lldb_bndcfgu_i386: 381 return lldb_bndcfgu_x86_64; 382 case lldb_bndstatus_i386: 383 return lldb_bndstatus_x86_64; 384 case lldb_dr0_i386: 385 case lldb_dr1_i386: 386 case lldb_dr2_i386: 387 case lldb_dr3_i386: 388 case lldb_dr4_i386: 389 case lldb_dr5_i386: 390 case lldb_dr6_i386: 391 case lldb_dr7_i386: 392 return lldb_dr0_x86_64 + regnum - lldb_dr0_i386; 393 default: 394 llvm_unreachable("Unhandled i386 register."); 395 } 396 } 397 398 int NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum( 399 int reg_num) const { 400 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { 401 case llvm::Triple::x86: 402 if (reg_num >= k_first_gpr_i386 && reg_num <= k_last_gpr_i386) 403 return GPRegSet; 404 if (reg_num >= k_first_fpr_i386 && reg_num <= k_last_fpr_i386) 405 return FPRegSet; 406 if (reg_num >= k_first_avx_i386 && reg_num <= k_last_avx_i386) 407 return XStateRegSet; // AVX 408 if (reg_num >= k_first_mpxr_i386 && reg_num <= k_last_mpxr_i386) 409 return -1; // MPXR 410 if (reg_num >= k_first_mpxc_i386 && reg_num <= k_last_mpxc_i386) 411 return -1; // MPXC 412 if (reg_num >= k_first_dbr_i386 && reg_num <= k_last_dbr_i386) 413 return DBRegSet; // DBR 414 break; 415 case llvm::Triple::x86_64: 416 if (reg_num >= k_first_gpr_x86_64 && reg_num <= k_last_gpr_x86_64) 417 return GPRegSet; 418 if (reg_num >= k_first_fpr_x86_64 && reg_num <= k_last_fpr_x86_64) 419 return FPRegSet; 420 if (reg_num >= k_first_avx_x86_64 && reg_num <= k_last_avx_x86_64) 421 return XStateRegSet; // AVX 422 if (reg_num >= k_first_mpxr_x86_64 && reg_num <= k_last_mpxr_x86_64) 423 return -1; // MPXR 424 if (reg_num >= k_first_mpxc_x86_64 && reg_num <= k_last_mpxc_x86_64) 425 return -1; // MPXC 426 if (reg_num >= k_first_dbr_x86_64 && reg_num <= k_last_dbr_x86_64) 427 return DBRegSet; // DBR 428 break; 429 default: 430 llvm_unreachable("Unhandled target architecture."); 431 } 432 433 llvm_unreachable("Register does not belong to any register set"); 434 } 435 436 Status NativeRegisterContextNetBSD_x86_64::ReadRegisterSet(uint32_t set) { 437 switch (set) { 438 case GPRegSet: 439 return DoRegisterSet(PT_GETREGS, &m_gpr); 440 case FPRegSet: 441 #if defined(__x86_64__) 442 return DoRegisterSet(PT_GETFPREGS, &m_fpr); 443 #else 444 return DoRegisterSet(PT_GETXMMREGS, &m_fpr); 445 #endif 446 case DBRegSet: 447 return DoRegisterSet(PT_GETDBREGS, &m_dbr); 448 case XStateRegSet: 449 #ifdef HAVE_XSTATE 450 { 451 struct iovec iov = {&m_xstate, sizeof(m_xstate)}; 452 return DoRegisterSet(PT_GETXSTATE, &iov); 453 } 454 #else 455 return Status("XState is not supported by the kernel"); 456 #endif 457 } 458 llvm_unreachable("NativeRegisterContextNetBSD_x86_64::ReadRegisterSet"); 459 } 460 461 Status NativeRegisterContextNetBSD_x86_64::WriteRegisterSet(uint32_t set) { 462 switch (set) { 463 case GPRegSet: 464 return DoRegisterSet(PT_SETREGS, &m_gpr); 465 case FPRegSet: 466 #if defined(__x86_64__) 467 return DoRegisterSet(PT_SETFPREGS, &m_fpr); 468 #else 469 return DoRegisterSet(PT_SETXMMREGS, &m_fpr); 470 #endif 471 case DBRegSet: 472 return DoRegisterSet(PT_SETDBREGS, &m_dbr); 473 case XStateRegSet: 474 #ifdef HAVE_XSTATE 475 { 476 struct iovec iov = {&m_xstate, sizeof(m_xstate)}; 477 return DoRegisterSet(PT_SETXSTATE, &iov); 478 } 479 #else 480 return Status("XState is not supported by the kernel"); 481 #endif 482 } 483 llvm_unreachable("NativeRegisterContextNetBSD_x86_64::WriteRegisterSet"); 484 } 485 486 Status 487 NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info, 488 RegisterValue ®_value) { 489 Status error; 490 491 if (!reg_info) { 492 error.SetErrorString("reg_info NULL"); 493 return error; 494 } 495 496 uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; 497 if (reg == LLDB_INVALID_REGNUM) { 498 // This is likely an internal register for lldb use only and should not be 499 // directly queried. 500 error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb " 501 "register, cannot read directly", 502 reg_info->name); 503 return error; 504 } 505 506 int set = GetSetForNativeRegNum(reg); 507 if (set == -1) { 508 // This is likely an internal register for lldb use only and should not be 509 // directly queried. 510 error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set", 511 reg_info->name); 512 return error; 513 } 514 515 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { 516 case llvm::Triple::x86_64: 517 break; 518 case llvm::Triple::x86: 519 reg = RegNumX86ToX86_64(reg); 520 break; 521 default: 522 llvm_unreachable("Unhandled target architecture."); 523 } 524 525 error = ReadRegisterSet(set); 526 if (error.Fail()) 527 return error; 528 529 switch (reg) { 530 #if defined(__x86_64__) 531 case lldb_rax_x86_64: 532 reg_value = (uint64_t)m_gpr.regs[_REG_RAX]; 533 break; 534 case lldb_rbx_x86_64: 535 reg_value = (uint64_t)m_gpr.regs[_REG_RBX]; 536 break; 537 case lldb_rcx_x86_64: 538 reg_value = (uint64_t)m_gpr.regs[_REG_RCX]; 539 break; 540 case lldb_rdx_x86_64: 541 reg_value = (uint64_t)m_gpr.regs[_REG_RDX]; 542 break; 543 case lldb_rdi_x86_64: 544 reg_value = (uint64_t)m_gpr.regs[_REG_RDI]; 545 break; 546 case lldb_rsi_x86_64: 547 reg_value = (uint64_t)m_gpr.regs[_REG_RSI]; 548 break; 549 case lldb_rbp_x86_64: 550 reg_value = (uint64_t)m_gpr.regs[_REG_RBP]; 551 break; 552 case lldb_rsp_x86_64: 553 reg_value = (uint64_t)m_gpr.regs[_REG_RSP]; 554 break; 555 case lldb_r8_x86_64: 556 reg_value = (uint64_t)m_gpr.regs[_REG_R8]; 557 break; 558 case lldb_r9_x86_64: 559 reg_value = (uint64_t)m_gpr.regs[_REG_R9]; 560 break; 561 case lldb_r10_x86_64: 562 reg_value = (uint64_t)m_gpr.regs[_REG_R10]; 563 break; 564 case lldb_r11_x86_64: 565 reg_value = (uint64_t)m_gpr.regs[_REG_R11]; 566 break; 567 case lldb_r12_x86_64: 568 reg_value = (uint64_t)m_gpr.regs[_REG_R12]; 569 break; 570 case lldb_r13_x86_64: 571 reg_value = (uint64_t)m_gpr.regs[_REG_R13]; 572 break; 573 case lldb_r14_x86_64: 574 reg_value = (uint64_t)m_gpr.regs[_REG_R14]; 575 break; 576 case lldb_r15_x86_64: 577 reg_value = (uint64_t)m_gpr.regs[_REG_R15]; 578 break; 579 case lldb_rip_x86_64: 580 reg_value = (uint64_t)m_gpr.regs[_REG_RIP]; 581 break; 582 case lldb_rflags_x86_64: 583 reg_value = (uint64_t)m_gpr.regs[_REG_RFLAGS]; 584 break; 585 case lldb_cs_x86_64: 586 reg_value = (uint64_t)m_gpr.regs[_REG_CS]; 587 break; 588 case lldb_fs_x86_64: 589 reg_value = (uint64_t)m_gpr.regs[_REG_FS]; 590 break; 591 case lldb_gs_x86_64: 592 reg_value = (uint64_t)m_gpr.regs[_REG_GS]; 593 break; 594 case lldb_ss_x86_64: 595 reg_value = (uint64_t)m_gpr.regs[_REG_SS]; 596 break; 597 case lldb_ds_x86_64: 598 reg_value = (uint64_t)m_gpr.regs[_REG_DS]; 599 break; 600 case lldb_es_x86_64: 601 reg_value = (uint64_t)m_gpr.regs[_REG_ES]; 602 break; 603 #else 604 case lldb_rax_x86_64: 605 reg_value = (uint32_t)m_gpr.r_eax; 606 break; 607 case lldb_rbx_x86_64: 608 reg_value = (uint32_t)m_gpr.r_ebx; 609 break; 610 case lldb_rcx_x86_64: 611 reg_value = (uint32_t)m_gpr.r_ecx; 612 break; 613 case lldb_rdx_x86_64: 614 reg_value = (uint32_t)m_gpr.r_edx; 615 break; 616 case lldb_rdi_x86_64: 617 reg_value = (uint32_t)m_gpr.r_edi; 618 break; 619 case lldb_rsi_x86_64: 620 reg_value = (uint32_t)m_gpr.r_esi; 621 break; 622 case lldb_rsp_x86_64: 623 reg_value = (uint32_t)m_gpr.r_esp; 624 break; 625 case lldb_rbp_x86_64: 626 reg_value = (uint32_t)m_gpr.r_ebp; 627 break; 628 case lldb_rip_x86_64: 629 reg_value = (uint32_t)m_gpr.r_eip; 630 break; 631 case lldb_rflags_x86_64: 632 reg_value = (uint32_t)m_gpr.r_eflags; 633 break; 634 case lldb_cs_x86_64: 635 reg_value = (uint32_t)m_gpr.r_cs; 636 break; 637 case lldb_fs_x86_64: 638 reg_value = (uint32_t)m_gpr.r_fs; 639 break; 640 case lldb_gs_x86_64: 641 reg_value = (uint32_t)m_gpr.r_gs; 642 break; 643 case lldb_ss_x86_64: 644 reg_value = (uint32_t)m_gpr.r_ss; 645 break; 646 case lldb_ds_x86_64: 647 reg_value = (uint32_t)m_gpr.r_ds; 648 break; 649 case lldb_es_x86_64: 650 reg_value = (uint32_t)m_gpr.r_es; 651 break; 652 #endif 653 case lldb_fctrl_x86_64: 654 reg_value = (uint16_t)m_fpr.fxstate.fx_cw; 655 break; 656 case lldb_fstat_x86_64: 657 reg_value = (uint16_t)m_fpr.fxstate.fx_sw; 658 break; 659 case lldb_ftag_x86_64: 660 reg_value = (uint16_t)m_fpr.fxstate.fx_tw; 661 break; 662 case lldb_fop_x86_64: 663 reg_value = (uint64_t)m_fpr.fxstate.fx_opcode; 664 break; 665 case lldb_fiseg_x86_64: 666 reg_value = (uint32_t)m_fpr.fxstate.fx_ip.fa_32.fa_seg; 667 break; 668 case lldb_fioff_x86_64: 669 reg_value = (uint32_t)m_fpr.fxstate.fx_ip.fa_32.fa_off; 670 break; 671 case lldb_foseg_x86_64: 672 reg_value = (uint32_t)m_fpr.fxstate.fx_dp.fa_32.fa_seg; 673 break; 674 case lldb_fooff_x86_64: 675 reg_value = (uint32_t)m_fpr.fxstate.fx_dp.fa_32.fa_off; 676 break; 677 case lldb_mxcsr_x86_64: 678 reg_value = (uint32_t)m_fpr.fxstate.fx_mxcsr; 679 break; 680 case lldb_mxcsrmask_x86_64: 681 reg_value = (uint32_t)m_fpr.fxstate.fx_mxcsr_mask; 682 break; 683 case lldb_st0_x86_64: 684 case lldb_st1_x86_64: 685 case lldb_st2_x86_64: 686 case lldb_st3_x86_64: 687 case lldb_st4_x86_64: 688 case lldb_st5_x86_64: 689 case lldb_st6_x86_64: 690 case lldb_st7_x86_64: 691 reg_value.SetBytes(&m_fpr.fxstate.fx_87_ac[reg - lldb_st0_x86_64], 692 reg_info->byte_size, endian::InlHostByteOrder()); 693 break; 694 case lldb_mm0_x86_64: 695 case lldb_mm1_x86_64: 696 case lldb_mm2_x86_64: 697 case lldb_mm3_x86_64: 698 case lldb_mm4_x86_64: 699 case lldb_mm5_x86_64: 700 case lldb_mm6_x86_64: 701 case lldb_mm7_x86_64: 702 reg_value.SetBytes(&m_fpr.fxstate.fx_87_ac[reg - lldb_mm0_x86_64], 703 reg_info->byte_size, endian::InlHostByteOrder()); 704 break; 705 case lldb_xmm0_x86_64: 706 case lldb_xmm1_x86_64: 707 case lldb_xmm2_x86_64: 708 case lldb_xmm3_x86_64: 709 case lldb_xmm4_x86_64: 710 case lldb_xmm5_x86_64: 711 case lldb_xmm6_x86_64: 712 case lldb_xmm7_x86_64: 713 case lldb_xmm8_x86_64: 714 case lldb_xmm9_x86_64: 715 case lldb_xmm10_x86_64: 716 case lldb_xmm11_x86_64: 717 case lldb_xmm12_x86_64: 718 case lldb_xmm13_x86_64: 719 case lldb_xmm14_x86_64: 720 case lldb_xmm15_x86_64: 721 reg_value.SetBytes(&m_fpr.fxstate.fx_xmm[reg - lldb_xmm0_x86_64], 722 reg_info->byte_size, endian::InlHostByteOrder()); 723 break; 724 case lldb_ymm0_x86_64: 725 case lldb_ymm1_x86_64: 726 case lldb_ymm2_x86_64: 727 case lldb_ymm3_x86_64: 728 case lldb_ymm4_x86_64: 729 case lldb_ymm5_x86_64: 730 case lldb_ymm6_x86_64: 731 case lldb_ymm7_x86_64: 732 case lldb_ymm8_x86_64: 733 case lldb_ymm9_x86_64: 734 case lldb_ymm10_x86_64: 735 case lldb_ymm11_x86_64: 736 case lldb_ymm12_x86_64: 737 case lldb_ymm13_x86_64: 738 case lldb_ymm14_x86_64: 739 case lldb_ymm15_x86_64: 740 #ifdef HAVE_XSTATE 741 if (!(m_xstate.xs_rfbm & XCR0_SSE) || 742 !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) { 743 error.SetErrorStringWithFormat("register \"%s\" not supported by CPU/kernel", 744 reg_info->name); 745 } else { 746 uint32_t reg_index = reg - lldb_ymm0_x86_64; 747 YMMReg ymm = XStateToYMM( 748 m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes, 749 m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes); 750 reg_value.SetBytes(ymm.bytes, reg_info->byte_size, 751 endian::InlHostByteOrder()); 752 } 753 #else 754 error.SetErrorString("XState queries not supported by the kernel"); 755 #endif 756 break; 757 case lldb_dr0_x86_64: 758 case lldb_dr1_x86_64: 759 case lldb_dr2_x86_64: 760 case lldb_dr3_x86_64: 761 case lldb_dr4_x86_64: 762 case lldb_dr5_x86_64: 763 case lldb_dr6_x86_64: 764 case lldb_dr7_x86_64: 765 reg_value = (uint64_t)m_dbr.dr[reg - lldb_dr0_x86_64]; 766 break; 767 default: 768 llvm_unreachable("Reading unknown/unsupported register"); 769 } 770 771 return error; 772 } 773 774 Status NativeRegisterContextNetBSD_x86_64::WriteRegister( 775 const RegisterInfo *reg_info, const RegisterValue ®_value) { 776 777 Status error; 778 779 if (!reg_info) { 780 error.SetErrorString("reg_info NULL"); 781 return error; 782 } 783 784 uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; 785 if (reg == LLDB_INVALID_REGNUM) { 786 // This is likely an internal register for lldb use only and should not be 787 // directly queried. 788 error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb " 789 "register, cannot read directly", 790 reg_info->name); 791 return error; 792 } 793 794 int set = GetSetForNativeRegNum(reg); 795 if (set == -1) { 796 // This is likely an internal register for lldb use only and should not be 797 // directly queried. 798 error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set", 799 reg_info->name); 800 return error; 801 } 802 803 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { 804 case llvm::Triple::x86_64: 805 break; 806 case llvm::Triple::x86: 807 reg = RegNumX86ToX86_64(reg); 808 break; 809 default: 810 llvm_unreachable("Unhandled target architecture."); 811 } 812 813 error = ReadRegisterSet(set); 814 if (error.Fail()) 815 return error; 816 817 switch (reg) { 818 #if defined(__x86_64__) 819 case lldb_rax_x86_64: 820 m_gpr.regs[_REG_RAX] = reg_value.GetAsUInt64(); 821 break; 822 case lldb_rbx_x86_64: 823 m_gpr.regs[_REG_RBX] = reg_value.GetAsUInt64(); 824 break; 825 case lldb_rcx_x86_64: 826 m_gpr.regs[_REG_RCX] = reg_value.GetAsUInt64(); 827 break; 828 case lldb_rdx_x86_64: 829 m_gpr.regs[_REG_RDX] = reg_value.GetAsUInt64(); 830 break; 831 case lldb_rdi_x86_64: 832 m_gpr.regs[_REG_RDI] = reg_value.GetAsUInt64(); 833 break; 834 case lldb_rsi_x86_64: 835 m_gpr.regs[_REG_RSI] = reg_value.GetAsUInt64(); 836 break; 837 case lldb_rbp_x86_64: 838 m_gpr.regs[_REG_RBP] = reg_value.GetAsUInt64(); 839 break; 840 case lldb_rsp_x86_64: 841 m_gpr.regs[_REG_RSP] = reg_value.GetAsUInt64(); 842 break; 843 case lldb_r8_x86_64: 844 m_gpr.regs[_REG_R8] = reg_value.GetAsUInt64(); 845 break; 846 case lldb_r9_x86_64: 847 m_gpr.regs[_REG_R9] = reg_value.GetAsUInt64(); 848 break; 849 case lldb_r10_x86_64: 850 m_gpr.regs[_REG_R10] = reg_value.GetAsUInt64(); 851 break; 852 case lldb_r11_x86_64: 853 m_gpr.regs[_REG_R11] = reg_value.GetAsUInt64(); 854 break; 855 case lldb_r12_x86_64: 856 m_gpr.regs[_REG_R12] = reg_value.GetAsUInt64(); 857 break; 858 case lldb_r13_x86_64: 859 m_gpr.regs[_REG_R13] = reg_value.GetAsUInt64(); 860 break; 861 case lldb_r14_x86_64: 862 m_gpr.regs[_REG_R14] = reg_value.GetAsUInt64(); 863 break; 864 case lldb_r15_x86_64: 865 m_gpr.regs[_REG_R15] = reg_value.GetAsUInt64(); 866 break; 867 case lldb_rip_x86_64: 868 m_gpr.regs[_REG_RIP] = reg_value.GetAsUInt64(); 869 break; 870 case lldb_rflags_x86_64: 871 m_gpr.regs[_REG_RFLAGS] = reg_value.GetAsUInt64(); 872 break; 873 case lldb_cs_x86_64: 874 m_gpr.regs[_REG_CS] = reg_value.GetAsUInt64(); 875 break; 876 case lldb_fs_x86_64: 877 m_gpr.regs[_REG_FS] = reg_value.GetAsUInt64(); 878 break; 879 case lldb_gs_x86_64: 880 m_gpr.regs[_REG_GS] = reg_value.GetAsUInt64(); 881 break; 882 case lldb_ss_x86_64: 883 m_gpr.regs[_REG_SS] = reg_value.GetAsUInt64(); 884 break; 885 case lldb_ds_x86_64: 886 m_gpr.regs[_REG_DS] = reg_value.GetAsUInt64(); 887 break; 888 case lldb_es_x86_64: 889 m_gpr.regs[_REG_ES] = reg_value.GetAsUInt64(); 890 break; 891 #else 892 case lldb_rax_x86_64: 893 m_gpr.r_eax = reg_value.GetAsUInt32(); 894 break; 895 case lldb_rbx_x86_64: 896 m_gpr.r_ebx = reg_value.GetAsUInt32(); 897 break; 898 case lldb_rcx_x86_64: 899 m_gpr.r_ecx = reg_value.GetAsUInt32(); 900 break; 901 case lldb_rdx_x86_64: 902 m_gpr.r_edx = reg_value.GetAsUInt32(); 903 break; 904 case lldb_rdi_x86_64: 905 m_gpr.r_edi = reg_value.GetAsUInt32(); 906 break; 907 case lldb_rsi_x86_64: 908 m_gpr.r_esi = reg_value.GetAsUInt32(); 909 break; 910 case lldb_rsp_x86_64: 911 m_gpr.r_esp = reg_value.GetAsUInt32(); 912 break; 913 case lldb_rbp_x86_64: 914 m_gpr.r_ebp = reg_value.GetAsUInt32(); 915 break; 916 case lldb_rip_x86_64: 917 m_gpr.r_eip = reg_value.GetAsUInt32(); 918 break; 919 case lldb_rflags_x86_64: 920 m_gpr.r_eflags = reg_value.GetAsUInt32(); 921 break; 922 case lldb_cs_x86_64: 923 m_gpr.r_cs = reg_value.GetAsUInt32(); 924 break; 925 case lldb_fs_x86_64: 926 m_gpr.r_fs = reg_value.GetAsUInt32(); 927 break; 928 case lldb_gs_x86_64: 929 m_gpr.r_gs = reg_value.GetAsUInt32(); 930 break; 931 case lldb_ss_x86_64: 932 m_gpr.r_ss = reg_value.GetAsUInt32(); 933 break; 934 case lldb_ds_x86_64: 935 m_gpr.r_ds = reg_value.GetAsUInt32(); 936 break; 937 case lldb_es_x86_64: 938 m_gpr.r_es = reg_value.GetAsUInt32(); 939 break; 940 #endif 941 case lldb_fctrl_x86_64: 942 m_fpr.fxstate.fx_cw = reg_value.GetAsUInt16(); 943 break; 944 case lldb_fstat_x86_64: 945 m_fpr.fxstate.fx_sw = reg_value.GetAsUInt16(); 946 break; 947 case lldb_ftag_x86_64: 948 m_fpr.fxstate.fx_tw = reg_value.GetAsUInt16(); 949 break; 950 case lldb_fop_x86_64: 951 m_fpr.fxstate.fx_opcode = reg_value.GetAsUInt16(); 952 break; 953 case lldb_fiseg_x86_64: 954 m_fpr.fxstate.fx_ip.fa_32.fa_seg = reg_value.GetAsUInt32(); 955 break; 956 case lldb_fioff_x86_64: 957 m_fpr.fxstate.fx_ip.fa_32.fa_off = reg_value.GetAsUInt32(); 958 break; 959 case lldb_foseg_x86_64: 960 m_fpr.fxstate.fx_dp.fa_32.fa_seg = reg_value.GetAsUInt32(); 961 break; 962 case lldb_fooff_x86_64: 963 m_fpr.fxstate.fx_dp.fa_32.fa_off = reg_value.GetAsUInt32(); 964 break; 965 case lldb_mxcsr_x86_64: 966 m_fpr.fxstate.fx_mxcsr = reg_value.GetAsUInt32(); 967 break; 968 case lldb_mxcsrmask_x86_64: 969 m_fpr.fxstate.fx_mxcsr_mask = reg_value.GetAsUInt32(); 970 break; 971 case lldb_st0_x86_64: 972 case lldb_st1_x86_64: 973 case lldb_st2_x86_64: 974 case lldb_st3_x86_64: 975 case lldb_st4_x86_64: 976 case lldb_st5_x86_64: 977 case lldb_st6_x86_64: 978 case lldb_st7_x86_64: 979 ::memcpy(&m_fpr.fxstate.fx_87_ac[reg - lldb_st0_x86_64], 980 reg_value.GetBytes(), reg_value.GetByteSize()); 981 break; 982 case lldb_mm0_x86_64: 983 case lldb_mm1_x86_64: 984 case lldb_mm2_x86_64: 985 case lldb_mm3_x86_64: 986 case lldb_mm4_x86_64: 987 case lldb_mm5_x86_64: 988 case lldb_mm6_x86_64: 989 case lldb_mm7_x86_64: 990 ::memcpy(&m_fpr.fxstate.fx_87_ac[reg - lldb_mm0_x86_64], 991 reg_value.GetBytes(), reg_value.GetByteSize()); 992 break; 993 case lldb_xmm0_x86_64: 994 case lldb_xmm1_x86_64: 995 case lldb_xmm2_x86_64: 996 case lldb_xmm3_x86_64: 997 case lldb_xmm4_x86_64: 998 case lldb_xmm5_x86_64: 999 case lldb_xmm6_x86_64: 1000 case lldb_xmm7_x86_64: 1001 case lldb_xmm8_x86_64: 1002 case lldb_xmm9_x86_64: 1003 case lldb_xmm10_x86_64: 1004 case lldb_xmm11_x86_64: 1005 case lldb_xmm12_x86_64: 1006 case lldb_xmm13_x86_64: 1007 case lldb_xmm14_x86_64: 1008 case lldb_xmm15_x86_64: 1009 ::memcpy(&m_fpr.fxstate.fx_xmm[reg - lldb_xmm0_x86_64], 1010 reg_value.GetBytes(), reg_value.GetByteSize()); 1011 break; 1012 case lldb_ymm0_x86_64: 1013 case lldb_ymm1_x86_64: 1014 case lldb_ymm2_x86_64: 1015 case lldb_ymm3_x86_64: 1016 case lldb_ymm4_x86_64: 1017 case lldb_ymm5_x86_64: 1018 case lldb_ymm6_x86_64: 1019 case lldb_ymm7_x86_64: 1020 case lldb_ymm8_x86_64: 1021 case lldb_ymm9_x86_64: 1022 case lldb_ymm10_x86_64: 1023 case lldb_ymm11_x86_64: 1024 case lldb_ymm12_x86_64: 1025 case lldb_ymm13_x86_64: 1026 case lldb_ymm14_x86_64: 1027 case lldb_ymm15_x86_64: 1028 #ifdef HAVE_XSTATE 1029 if (!(m_xstate.xs_rfbm & XCR0_SSE) || 1030 !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) { 1031 error.SetErrorStringWithFormat("register \"%s\" not supported by CPU/kernel", 1032 reg_info->name); 1033 } else { 1034 uint32_t reg_index = reg - lldb_ymm0_x86_64; 1035 YMMReg ymm; 1036 ::memcpy(ymm.bytes, reg_value.GetBytes(), reg_value.GetByteSize()); 1037 YMMToXState(ymm, 1038 m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes, 1039 m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes); 1040 } 1041 #else 1042 error.SetErrorString("XState not supported by the kernel"); 1043 return error; 1044 #endif 1045 break; 1046 case lldb_dr0_x86_64: 1047 case lldb_dr1_x86_64: 1048 case lldb_dr2_x86_64: 1049 case lldb_dr3_x86_64: 1050 case lldb_dr4_x86_64: 1051 case lldb_dr5_x86_64: 1052 case lldb_dr6_x86_64: 1053 case lldb_dr7_x86_64: 1054 m_dbr.dr[reg - lldb_dr0_x86_64] = reg_value.GetAsUInt64(); 1055 break; 1056 default: 1057 llvm_unreachable("Reading unknown/unsupported register"); 1058 } 1059 1060 return WriteRegisterSet(set); 1061 } 1062 1063 Status NativeRegisterContextNetBSD_x86_64::ReadAllRegisterValues( 1064 lldb::DataBufferSP &data_sp) { 1065 Status error; 1066 1067 data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0)); 1068 error = ReadRegisterSet(GPRegSet); 1069 if (error.Fail()) 1070 return error; 1071 1072 uint8_t *dst = data_sp->GetBytes(); 1073 ::memcpy(dst, &m_gpr, GetRegisterInfoInterface().GetGPRSize()); 1074 dst += GetRegisterInfoInterface().GetGPRSize(); 1075 1076 return error; 1077 } 1078 1079 Status NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues( 1080 const lldb::DataBufferSP &data_sp) { 1081 Status error; 1082 1083 if (!data_sp) { 1084 error.SetErrorStringWithFormat( 1085 "NativeRegisterContextNetBSD_x86_64::%s invalid data_sp provided", 1086 __FUNCTION__); 1087 return error; 1088 } 1089 1090 if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) { 1091 error.SetErrorStringWithFormat( 1092 "NativeRegisterContextNetBSD_x86_64::%s data_sp contained mismatched " 1093 "data size, expected %zu, actual %" PRIu64, 1094 __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize()); 1095 return error; 1096 } 1097 1098 uint8_t *src = data_sp->GetBytes(); 1099 if (src == nullptr) { 1100 error.SetErrorStringWithFormat("NativeRegisterContextNetBSD_x86_64::%s " 1101 "DataBuffer::GetBytes() returned a null " 1102 "pointer", 1103 __FUNCTION__); 1104 return error; 1105 } 1106 ::memcpy(&m_gpr, src, GetRegisterInfoInterface().GetGPRSize()); 1107 1108 error = WriteRegisterSet(GPRegSet); 1109 if (error.Fail()) 1110 return error; 1111 src += GetRegisterInfoInterface().GetGPRSize(); 1112 1113 return error; 1114 } 1115 1116 int NativeRegisterContextNetBSD_x86_64::GetDR(int num) const { 1117 assert(num >= 0 && num <= 7); 1118 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { 1119 case llvm::Triple::x86: 1120 return lldb_dr0_i386 + num; 1121 case llvm::Triple::x86_64: 1122 return lldb_dr0_x86_64 + num; 1123 default: 1124 llvm_unreachable("Unhandled target architecture."); 1125 } 1126 } 1127 1128 Status NativeRegisterContextNetBSD_x86_64::IsWatchpointHit(uint32_t wp_index, 1129 bool &is_hit) { 1130 if (wp_index >= NumSupportedHardwareWatchpoints()) 1131 return Status("Watchpoint index out of range"); 1132 1133 RegisterValue reg_value; 1134 const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(GetDR(6)); 1135 Status error = ReadRegister(reg_info, reg_value); 1136 if (error.Fail()) { 1137 is_hit = false; 1138 return error; 1139 } 1140 1141 uint64_t status_bits = reg_value.GetAsUInt64(); 1142 1143 is_hit = status_bits & (1 << wp_index); 1144 1145 return error; 1146 } 1147 1148 Status NativeRegisterContextNetBSD_x86_64::GetWatchpointHitIndex( 1149 uint32_t &wp_index, lldb::addr_t trap_addr) { 1150 uint32_t num_hw_wps = NumSupportedHardwareWatchpoints(); 1151 for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) { 1152 bool is_hit; 1153 Status error = IsWatchpointHit(wp_index, is_hit); 1154 if (error.Fail()) { 1155 wp_index = LLDB_INVALID_INDEX32; 1156 return error; 1157 } else if (is_hit) { 1158 return error; 1159 } 1160 } 1161 wp_index = LLDB_INVALID_INDEX32; 1162 return Status(); 1163 } 1164 1165 Status NativeRegisterContextNetBSD_x86_64::IsWatchpointVacant(uint32_t wp_index, 1166 bool &is_vacant) { 1167 if (wp_index >= NumSupportedHardwareWatchpoints()) 1168 return Status("Watchpoint index out of range"); 1169 1170 RegisterValue reg_value; 1171 const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(GetDR(7)); 1172 Status error = ReadRegister(reg_info, reg_value); 1173 if (error.Fail()) { 1174 is_vacant = false; 1175 return error; 1176 } 1177 1178 uint64_t control_bits = reg_value.GetAsUInt64(); 1179 1180 is_vacant = !(control_bits & (1 << (2 * wp_index + 1))); 1181 1182 return error; 1183 } 1184 1185 Status NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpointWithIndex( 1186 lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) { 1187 1188 if (wp_index >= NumSupportedHardwareWatchpoints()) 1189 return Status("Watchpoint index out of range"); 1190 1191 // Read only watchpoints aren't supported on x86_64. Fall back to read/write 1192 // waitchpoints instead. 1193 // TODO: Add logic to detect when a write happens and ignore that watchpoint 1194 // hit. 1195 if (watch_flags == 0x2) 1196 watch_flags = 0x3; 1197 1198 if (watch_flags != 0x1 && watch_flags != 0x3) 1199 return Status("Invalid read/write bits for watchpoint"); 1200 1201 if (size != 1 && size != 2 && size != 4 && size != 8) 1202 return Status("Invalid size for watchpoint"); 1203 1204 bool is_vacant; 1205 Status error = IsWatchpointVacant(wp_index, is_vacant); 1206 if (error.Fail()) 1207 return error; 1208 if (!is_vacant) 1209 return Status("Watchpoint index not vacant"); 1210 1211 const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7)); 1212 RegisterValue dr7_value; 1213 error = ReadRegister(reg_info_dr7, dr7_value); 1214 if (error.Fail()) 1215 return error; 1216 1217 // for watchpoints 0, 1, 2, or 3, respectively, set bits 1, 3, 5, or 7 1218 uint64_t enable_bit = 1 << (2 * wp_index + 1); 1219 1220 // set bits 16-17, 20-21, 24-25, or 28-29 1221 // with 0b01 for write, and 0b11 for read/write 1222 uint64_t rw_bits = watch_flags << (16 + 4 * wp_index); 1223 1224 // set bits 18-19, 22-23, 26-27, or 30-31 1225 // with 0b00, 0b01, 0b10, or 0b11 1226 // for 1, 2, 8 (if supported), or 4 bytes, respectively 1227 uint64_t size_bits = (size == 8 ? 0x2 : size - 1) << (18 + 4 * wp_index); 1228 1229 uint64_t bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index)); 1230 1231 uint64_t control_bits = dr7_value.GetAsUInt64() & ~bit_mask; 1232 1233 control_bits |= enable_bit | rw_bits | size_bits; 1234 1235 const RegisterInfo *const reg_info_drN = 1236 GetRegisterInfoAtIndex(GetDR(wp_index)); 1237 RegisterValue drN_value; 1238 error = ReadRegister(reg_info_drN, drN_value); 1239 if (error.Fail()) 1240 return error; 1241 1242 // clear dr6 if address or bits changed (i.e. we're not reenabling the same 1243 // watchpoint) 1244 if (drN_value.GetAsUInt64() != addr || 1245 (dr7_value.GetAsUInt64() & bit_mask) != (rw_bits | size_bits)) { 1246 ClearWatchpointHit(wp_index); 1247 1248 error = WriteRegister(reg_info_drN, RegisterValue(addr)); 1249 if (error.Fail()) 1250 return error; 1251 } 1252 1253 error = WriteRegister(reg_info_dr7, RegisterValue(control_bits)); 1254 if (error.Fail()) 1255 return error; 1256 1257 error.Clear(); 1258 return error; 1259 } 1260 1261 bool NativeRegisterContextNetBSD_x86_64::ClearHardwareWatchpoint( 1262 uint32_t wp_index) { 1263 if (wp_index >= NumSupportedHardwareWatchpoints()) 1264 return false; 1265 1266 // for watchpoints 0, 1, 2, or 3, respectively, clear bits 0-1, 2-3, 4-5 1267 // or 6-7 of the debug control register (DR7) 1268 const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7)); 1269 RegisterValue reg_value; 1270 Status error = ReadRegister(reg_info_dr7, reg_value); 1271 if (error.Fail()) 1272 return false; 1273 uint64_t bit_mask = 0x3 << (2 * wp_index); 1274 uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask; 1275 1276 return WriteRegister(reg_info_dr7, RegisterValue(control_bits)).Success(); 1277 } 1278 1279 Status NativeRegisterContextNetBSD_x86_64::ClearWatchpointHit(uint32_t wp_index) { 1280 if (wp_index >= NumSupportedHardwareWatchpoints()) 1281 return Status("Watchpoint index out of range"); 1282 1283 // for watchpoints 0, 1, 2, or 3, respectively, check bits 0, 1, 2, or 3 of 1284 // the debug status register (DR6) 1285 const RegisterInfo *const reg_info_dr6 = GetRegisterInfoAtIndex(GetDR(6)); 1286 RegisterValue reg_value; 1287 Status error = ReadRegister(reg_info_dr6, reg_value); 1288 if (error.Fail()) 1289 return error; 1290 1291 uint64_t bit_mask = 1 << wp_index; 1292 uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask; 1293 return WriteRegister(reg_info_dr6, RegisterValue(status_bits)); 1294 } 1295 1296 Status NativeRegisterContextNetBSD_x86_64::ClearAllHardwareWatchpoints() { 1297 RegisterValue reg_value; 1298 1299 // clear bits {0-4} of the debug status register (DR6) 1300 const RegisterInfo *const reg_info_dr6 = GetRegisterInfoAtIndex(GetDR(6)); 1301 Status error = ReadRegister(reg_info_dr6, reg_value); 1302 if (error.Fail()) 1303 return error; 1304 uint64_t bit_mask = 0xF; 1305 uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask; 1306 error = WriteRegister(reg_info_dr6, RegisterValue(status_bits)); 1307 if (error.Fail()) 1308 return error; 1309 1310 // clear bits {0-7,16-31} of the debug control register (DR7) 1311 const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7)); 1312 error = ReadRegister(reg_info_dr7, reg_value); 1313 if (error.Fail()) 1314 return error; 1315 bit_mask = 0xFF | (0xFFFF << 16); 1316 uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask; 1317 return WriteRegister(reg_info_dr7, RegisterValue(control_bits)); 1318 } 1319 1320 uint32_t NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpoint( 1321 lldb::addr_t addr, size_t size, uint32_t watch_flags) { 1322 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); 1323 const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); 1324 for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index) { 1325 bool is_vacant; 1326 Status error = IsWatchpointVacant(wp_index, is_vacant); 1327 if (is_vacant) { 1328 error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index); 1329 if (error.Success()) 1330 return wp_index; 1331 } 1332 if (error.Fail() && log) { 1333 LLDB_LOGF(log, "NativeRegisterContextNetBSD_x86_64::%s Error: %s", 1334 __FUNCTION__, error.AsCString()); 1335 } 1336 } 1337 return LLDB_INVALID_INDEX32; 1338 } 1339 1340 lldb::addr_t 1341 NativeRegisterContextNetBSD_x86_64::GetWatchpointAddress(uint32_t wp_index) { 1342 if (wp_index >= NumSupportedHardwareWatchpoints()) 1343 return LLDB_INVALID_ADDRESS; 1344 RegisterValue reg_value; 1345 const RegisterInfo *const reg_info_drN = 1346 GetRegisterInfoAtIndex(GetDR(wp_index)); 1347 if (ReadRegister(reg_info_drN, reg_value).Fail()) 1348 return LLDB_INVALID_ADDRESS; 1349 return reg_value.GetAsUInt64(); 1350 } 1351 1352 uint32_t NativeRegisterContextNetBSD_x86_64::NumSupportedHardwareWatchpoints() { 1353 // Available debug address registers: dr0, dr1, dr2, dr3 1354 return 4; 1355 } 1356 1357 Status NativeRegisterContextNetBSD_x86_64::CopyHardwareWatchpointsFrom( 1358 NativeRegisterContextNetBSD &source) { 1359 auto &r_source = static_cast<NativeRegisterContextNetBSD_x86_64&>(source); 1360 Status res = r_source.ReadRegisterSet(DBRegSet); 1361 if (!res.Fail()) { 1362 // copy dbregs only if any watchpoints were set 1363 if ((r_source.m_dbr.dr[7] & 0xFF) == 0) 1364 return res; 1365 1366 m_dbr = r_source.m_dbr; 1367 res = WriteRegisterSet(DBRegSet); 1368 } 1369 return res; 1370 } 1371 1372 #endif // defined(__x86_64__) 1373