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