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 #include "Plugins/Process/Linux/NativeThreadLinux.h" 13 #include "Plugins/Process/Utility/RegisterContextLinux_i386.h" 14 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" 15 #include "lldb/Host/HostInfo.h" 16 #include "lldb/Utility/DataBufferHeap.h" 17 #include "lldb/Utility/Log.h" 18 #include "lldb/Utility/RegisterValue.h" 19 #include "lldb/Utility/Status.h" 20 #include <cpuid.h> 21 #include <linux/elf.h> 22 #include <optional> 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 x86_64_with_base::lldb_rax, x86_64_with_base::lldb_rbx, x86_64_with_base::lldb_rcx, x86_64_with_base::lldb_rdx, 104 x86_64_with_base::lldb_rdi, x86_64_with_base::lldb_rsi, x86_64_with_base::lldb_rbp, x86_64_with_base::lldb_rsp, 105 x86_64_with_base::lldb_r8, x86_64_with_base::lldb_r9, x86_64_with_base::lldb_r10, x86_64_with_base::lldb_r11, 106 x86_64_with_base::lldb_r12, x86_64_with_base::lldb_r13, x86_64_with_base::lldb_r14, x86_64_with_base::lldb_r15, 107 x86_64_with_base::lldb_rip, x86_64_with_base::lldb_rflags, x86_64_with_base::lldb_cs, x86_64_with_base::lldb_fs, 108 x86_64_with_base::lldb_gs, x86_64_with_base::lldb_ss, x86_64_with_base::lldb_fs_base, x86_64_with_base::lldb_gs_base, 109 x86_64_with_base::lldb_ds, x86_64_with_base::lldb_es, 110 x86_64_with_base::lldb_eax, x86_64_with_base::lldb_ebx, x86_64_with_base::lldb_ecx, x86_64_with_base::lldb_edx, 111 x86_64_with_base::lldb_edi, x86_64_with_base::lldb_esi, x86_64_with_base::lldb_ebp, x86_64_with_base::lldb_esp, 112 x86_64_with_base::lldb_r8d, // Low 32 bits or r8 113 x86_64_with_base::lldb_r9d, // Low 32 bits or r9 114 x86_64_with_base::lldb_r10d, // Low 32 bits or r10 115 x86_64_with_base::lldb_r11d, // Low 32 bits or r11 116 x86_64_with_base::lldb_r12d, // Low 32 bits or r12 117 x86_64_with_base::lldb_r13d, // Low 32 bits or r13 118 x86_64_with_base::lldb_r14d, // Low 32 bits or r14 119 x86_64_with_base::lldb_r15d, // Low 32 bits or r15 120 x86_64_with_base::lldb_ax, x86_64_with_base::lldb_bx, x86_64_with_base::lldb_cx, x86_64_with_base::lldb_dx, 121 x86_64_with_base::lldb_di, x86_64_with_base::lldb_si, x86_64_with_base::lldb_bp, x86_64_with_base::lldb_sp, 122 x86_64_with_base::lldb_r8w, // Low 16 bits or r8 123 x86_64_with_base::lldb_r9w, // Low 16 bits or r9 124 x86_64_with_base::lldb_r10w, // Low 16 bits or r10 125 x86_64_with_base::lldb_r11w, // Low 16 bits or r11 126 x86_64_with_base::lldb_r12w, // Low 16 bits or r12 127 x86_64_with_base::lldb_r13w, // Low 16 bits or r13 128 x86_64_with_base::lldb_r14w, // Low 16 bits or r14 129 x86_64_with_base::lldb_r15w, // Low 16 bits or r15 130 x86_64_with_base::lldb_ah, x86_64_with_base::lldb_bh, x86_64_with_base::lldb_ch, x86_64_with_base::lldb_dh, 131 x86_64_with_base::lldb_al, x86_64_with_base::lldb_bl, x86_64_with_base::lldb_cl, x86_64_with_base::lldb_dl, 132 x86_64_with_base::lldb_dil, x86_64_with_base::lldb_sil, x86_64_with_base::lldb_bpl, x86_64_with_base::lldb_spl, 133 x86_64_with_base::lldb_r8l, // Low 8 bits or r8 134 x86_64_with_base::lldb_r9l, // Low 8 bits or r9 135 x86_64_with_base::lldb_r10l, // Low 8 bits or r10 136 x86_64_with_base::lldb_r11l, // Low 8 bits or r11 137 x86_64_with_base::lldb_r12l, // Low 8 bits or r12 138 x86_64_with_base::lldb_r13l, // Low 8 bits or r13 139 x86_64_with_base::lldb_r14l, // Low 8 bits or r14 140 x86_64_with_base::lldb_r15l, // Low 8 bits or r15 141 LLDB_INVALID_REGNUM // register sets need to end with this flag 142 }; 143 static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) - 144 1 == 145 x86_64_with_base::k_num_gpr_registers, 146 "g_gpr_regnums_x86_64 has wrong number of register infos"); 147 148 // x86 64-bit floating point registers. 149 static const uint32_t g_fpu_regnums_x86_64[] = { 150 x86_64_with_base::lldb_fctrl, x86_64_with_base::lldb_fstat, x86_64_with_base::lldb_ftag, 151 x86_64_with_base::lldb_fop, x86_64_with_base::lldb_fiseg, x86_64_with_base::lldb_fioff, 152 x86_64_with_base::lldb_fip, x86_64_with_base::lldb_foseg, x86_64_with_base::lldb_fooff, 153 x86_64_with_base::lldb_fdp, x86_64_with_base::lldb_mxcsr, x86_64_with_base::lldb_mxcsrmask, 154 x86_64_with_base::lldb_st0, x86_64_with_base::lldb_st1, x86_64_with_base::lldb_st2, 155 x86_64_with_base::lldb_st3, x86_64_with_base::lldb_st4, x86_64_with_base::lldb_st5, 156 x86_64_with_base::lldb_st6, x86_64_with_base::lldb_st7, x86_64_with_base::lldb_mm0, 157 x86_64_with_base::lldb_mm1, x86_64_with_base::lldb_mm2, x86_64_with_base::lldb_mm3, 158 x86_64_with_base::lldb_mm4, x86_64_with_base::lldb_mm5, x86_64_with_base::lldb_mm6, 159 x86_64_with_base::lldb_mm7, x86_64_with_base::lldb_xmm0, x86_64_with_base::lldb_xmm1, 160 x86_64_with_base::lldb_xmm2, x86_64_with_base::lldb_xmm3, x86_64_with_base::lldb_xmm4, 161 x86_64_with_base::lldb_xmm5, x86_64_with_base::lldb_xmm6, x86_64_with_base::lldb_xmm7, 162 x86_64_with_base::lldb_xmm8, x86_64_with_base::lldb_xmm9, x86_64_with_base::lldb_xmm10, 163 x86_64_with_base::lldb_xmm11, x86_64_with_base::lldb_xmm12, x86_64_with_base::lldb_xmm13, 164 x86_64_with_base::lldb_xmm14, x86_64_with_base::lldb_xmm15, 165 LLDB_INVALID_REGNUM // register sets need to end with this flag 166 }; 167 static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) - 168 1 == 169 x86_64_with_base::k_num_fpr_registers, 170 "g_fpu_regnums_x86_64 has wrong number of register infos"); 171 172 // x86 64-bit AVX registers. 173 static const uint32_t g_avx_regnums_x86_64[] = { 174 x86_64_with_base::lldb_ymm0, x86_64_with_base::lldb_ymm1, x86_64_with_base::lldb_ymm2, x86_64_with_base::lldb_ymm3, 175 x86_64_with_base::lldb_ymm4, x86_64_with_base::lldb_ymm5, x86_64_with_base::lldb_ymm6, x86_64_with_base::lldb_ymm7, 176 x86_64_with_base::lldb_ymm8, x86_64_with_base::lldb_ymm9, x86_64_with_base::lldb_ymm10, x86_64_with_base::lldb_ymm11, 177 x86_64_with_base::lldb_ymm12, x86_64_with_base::lldb_ymm13, x86_64_with_base::lldb_ymm14, x86_64_with_base::lldb_ymm15, 178 LLDB_INVALID_REGNUM // register sets need to end with this flag 179 }; 180 static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) - 181 1 == 182 x86_64_with_base::k_num_avx_registers, 183 "g_avx_regnums_x86_64 has wrong number of register infos"); 184 185 // x86 64-bit MPX registers. 186 static const uint32_t g_mpx_regnums_x86_64[] = { 187 x86_64_with_base::lldb_bnd0, x86_64_with_base::lldb_bnd1, x86_64_with_base::lldb_bnd2, 188 x86_64_with_base::lldb_bnd3, x86_64_with_base::lldb_bndcfgu, x86_64_with_base::lldb_bndstatus, 189 LLDB_INVALID_REGNUM // register sets need to end with this flag 190 }; 191 static_assert((sizeof(g_mpx_regnums_x86_64) / sizeof(g_mpx_regnums_x86_64[0])) - 192 1 == 193 x86_64_with_base::k_num_mpx_registers, 194 "g_mpx_regnums_x86_64 has wrong number of register infos"); 195 196 // Number of register sets provided by this context. 197 constexpr unsigned k_num_extended_register_sets = 2, k_num_register_sets = 4; 198 199 // Register sets for x86 32-bit. 200 static const RegisterSet g_reg_sets_i386[k_num_register_sets] = { 201 {"General Purpose Registers", "gpr", k_num_gpr_registers_i386, 202 g_gpr_regnums_i386}, 203 {"Floating Point Registers", "fpu", k_num_fpr_registers_i386, 204 g_fpu_regnums_i386}, 205 {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386, 206 g_avx_regnums_i386}, 207 { "Memory Protection Extensions", "mpx", k_num_mpx_registers_i386, 208 g_mpx_regnums_i386}}; 209 210 // Register sets for x86 64-bit. 211 static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = { 212 {"General Purpose Registers", "gpr", x86_64_with_base::k_num_gpr_registers, 213 g_gpr_regnums_x86_64}, 214 {"Floating Point Registers", "fpu", x86_64_with_base::k_num_fpr_registers, 215 g_fpu_regnums_x86_64}, 216 {"Advanced Vector Extensions", "avx", x86_64_with_base::k_num_avx_registers, 217 g_avx_regnums_x86_64}, 218 { "Memory Protection Extensions", "mpx", x86_64_with_base::k_num_mpx_registers, 219 g_mpx_regnums_x86_64}}; 220 221 #define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize() + sizeof(FPR)) 222 223 // Required ptrace defines. 224 225 // Support ptrace extensions even when compiled without required kernel support 226 #ifndef NT_X86_XSTATE 227 #define NT_X86_XSTATE 0x202 228 #endif 229 #ifndef NT_PRXFPREG 230 #define NT_PRXFPREG 0x46e62b7f 231 #endif 232 233 // On x86_64 NT_PRFPREG is used to access the FXSAVE area. On i386, we need to 234 // use NT_PRXFPREG. 235 static inline unsigned int fxsr_regset(const ArchSpec &arch) { 236 return arch.GetAddressByteSize() == 8 ? NT_PRFPREG : NT_PRXFPREG; 237 } 238 239 // Required MPX define. 240 241 // Support MPX extensions also if compiled with compiler without MPX support. 242 #ifndef bit_MPX 243 #define bit_MPX 0x4000 244 #endif 245 246 // XCR0 extended register sets masks. 247 #define mask_XSTATE_AVX (1ULL << 2) 248 #define mask_XSTATE_BNDREGS (1ULL << 3) 249 #define mask_XSTATE_BNDCFG (1ULL << 4) 250 #define mask_XSTATE_MPX (mask_XSTATE_BNDREGS | mask_XSTATE_BNDCFG) 251 252 std::unique_ptr<NativeRegisterContextLinux> 253 NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux( 254 const ArchSpec &target_arch, NativeThreadLinux &native_thread) { 255 return std::unique_ptr<NativeRegisterContextLinux>( 256 new NativeRegisterContextLinux_x86_64(target_arch, native_thread)); 257 } 258 259 llvm::Expected<ArchSpec> 260 NativeRegisterContextLinux::DetermineArchitecture(lldb::tid_t tid) { 261 return DetermineArchitectureViaGPR( 262 tid, RegisterContextLinux_x86_64::GetGPRSizeStatic()); 263 } 264 265 // NativeRegisterContextLinux_x86_64 members. 266 267 static std::unique_ptr<RegisterContextLinux_x86> 268 CreateRegisterInfoInterface(const ArchSpec &target_arch) { 269 if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) { 270 // 32-bit hosts run with a RegisterContextLinux_i386 context. 271 return std::make_unique<RegisterContextLinux_i386>(target_arch); 272 } else { 273 assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) && 274 "Register setting path assumes this is a 64-bit host"); 275 // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the 276 // x86_64 register context. 277 return std::make_unique<RegisterContextLinux_x86_64>(target_arch); 278 } 279 } 280 281 // Return the size of the XSTATE area supported on this cpu. It is necessary to 282 // allocate the full size of the area even if we do not use/recognise all of it 283 // because ptrace(PTRACE_SETREGSET, NT_X86_XSTATE) will refuse to write to it if 284 // we do not pass it a buffer of sufficient size. The size is always at least 285 // sizeof(FPR) so that the allocated buffer can be safely cast to FPR*. 286 static std::size_t GetXSTATESize() { 287 unsigned int eax, ebx, ecx, edx; 288 // First check whether the XSTATE are is supported at all. 289 if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx) || !(ecx & bit_XSAVE)) 290 return sizeof(FPR); 291 292 // Then fetch the maximum size of the area. 293 if (!get_cpuid_count(0x0d, 0, &eax, &ebx, &ecx, &edx)) 294 return sizeof(FPR); 295 return std::max<std::size_t>(ecx, sizeof(FPR)); 296 } 297 298 NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64( 299 const ArchSpec &target_arch, NativeThreadProtocol &native_thread) 300 : NativeRegisterContextRegisterInfo( 301 native_thread, CreateRegisterInfoInterface(target_arch).release()), 302 NativeRegisterContextLinux(native_thread), 303 NativeRegisterContextDBReg_x86(native_thread), 304 m_xstate_type(XStateType::Invalid), m_ymm_set(), m_mpx_set(), 305 m_reg_info(), m_gpr_x86_64() { 306 // Set up data about ranges of valid registers. 307 switch (target_arch.GetMachine()) { 308 case llvm::Triple::x86: 309 m_reg_info.num_registers = k_num_registers_i386; 310 m_reg_info.num_gpr_registers = k_num_gpr_registers_i386; 311 m_reg_info.num_fpr_registers = k_num_fpr_registers_i386; 312 m_reg_info.num_avx_registers = k_num_avx_registers_i386; 313 m_reg_info.num_mpx_registers = k_num_mpx_registers_i386; 314 m_reg_info.last_gpr = k_last_gpr_i386; 315 m_reg_info.first_fpr = k_first_fpr_i386; 316 m_reg_info.last_fpr = k_last_fpr_i386; 317 m_reg_info.first_st = lldb_st0_i386; 318 m_reg_info.last_st = lldb_st7_i386; 319 m_reg_info.first_mm = lldb_mm0_i386; 320 m_reg_info.last_mm = lldb_mm7_i386; 321 m_reg_info.first_xmm = lldb_xmm0_i386; 322 m_reg_info.last_xmm = lldb_xmm7_i386; 323 m_reg_info.first_ymm = lldb_ymm0_i386; 324 m_reg_info.last_ymm = lldb_ymm7_i386; 325 m_reg_info.first_mpxr = lldb_bnd0_i386; 326 m_reg_info.last_mpxr = lldb_bnd3_i386; 327 m_reg_info.first_mpxc = lldb_bndcfgu_i386; 328 m_reg_info.last_mpxc = lldb_bndstatus_i386; 329 m_reg_info.first_dr = lldb_dr0_i386; 330 m_reg_info.last_dr = lldb_dr7_i386; 331 m_reg_info.gpr_flags = lldb_eflags_i386; 332 break; 333 case llvm::Triple::x86_64: 334 m_reg_info.num_registers = x86_64_with_base::k_num_registers; 335 m_reg_info.num_gpr_registers = x86_64_with_base::k_num_gpr_registers; 336 m_reg_info.num_fpr_registers = x86_64_with_base::k_num_fpr_registers; 337 m_reg_info.num_avx_registers = x86_64_with_base::k_num_avx_registers; 338 m_reg_info.num_mpx_registers = x86_64_with_base::k_num_mpx_registers; 339 m_reg_info.last_gpr = x86_64_with_base::k_last_gpr; 340 m_reg_info.first_fpr = x86_64_with_base::k_first_fpr; 341 m_reg_info.last_fpr = x86_64_with_base::k_last_fpr; 342 m_reg_info.first_st = x86_64_with_base::lldb_st0; 343 m_reg_info.last_st = x86_64_with_base::lldb_st7; 344 m_reg_info.first_mm = x86_64_with_base::lldb_mm0; 345 m_reg_info.last_mm = x86_64_with_base::lldb_mm7; 346 m_reg_info.first_xmm = x86_64_with_base::lldb_xmm0; 347 m_reg_info.last_xmm = x86_64_with_base::lldb_xmm15; 348 m_reg_info.first_ymm = x86_64_with_base::lldb_ymm0; 349 m_reg_info.last_ymm = x86_64_with_base::lldb_ymm15; 350 m_reg_info.first_mpxr = x86_64_with_base::lldb_bnd0; 351 m_reg_info.last_mpxr = x86_64_with_base::lldb_bnd3; 352 m_reg_info.first_mpxc = x86_64_with_base::lldb_bndcfgu; 353 m_reg_info.last_mpxc = x86_64_with_base::lldb_bndstatus; 354 m_reg_info.first_dr = x86_64_with_base::lldb_dr0; 355 m_reg_info.last_dr = x86_64_with_base::lldb_dr7; 356 m_reg_info.gpr_flags = x86_64_with_base::lldb_rflags; 357 break; 358 default: 359 assert(false && "Unhandled target architecture."); 360 break; 361 } 362 363 std::size_t xstate_size = GetXSTATESize(); 364 m_xstate.reset(static_cast<FPR *>(std::malloc(xstate_size))); 365 m_iovec.iov_base = m_xstate.get(); 366 m_iovec.iov_len = xstate_size; 367 368 // Clear out the FPR state. 369 ::memset(m_xstate.get(), 0, xstate_size); 370 371 // Store byte offset of fctrl (i.e. first register of FPR) 372 const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl"); 373 m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset; 374 } 375 376 // CONSIDER after local and llgs debugging are merged, register set support can 377 // be moved into a base x86-64 class with IsRegisterSetAvailable made virtual. 378 uint32_t NativeRegisterContextLinux_x86_64::GetRegisterSetCount() const { 379 uint32_t sets = 0; 380 for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) { 381 if (IsRegisterSetAvailable(set_index)) 382 ++sets; 383 } 384 385 return sets; 386 } 387 388 uint32_t NativeRegisterContextLinux_x86_64::GetUserRegisterCount() const { 389 uint32_t count = 0; 390 for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) { 391 const RegisterSet *set = GetRegisterSet(set_index); 392 if (set) 393 count += set->num_registers; 394 } 395 return count; 396 } 397 398 const RegisterSet * 399 NativeRegisterContextLinux_x86_64::GetRegisterSet(uint32_t set_index) const { 400 if (!IsRegisterSetAvailable(set_index)) 401 return nullptr; 402 403 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { 404 case llvm::Triple::x86: 405 return &g_reg_sets_i386[set_index]; 406 case llvm::Triple::x86_64: 407 return &g_reg_sets_x86_64[set_index]; 408 default: 409 assert(false && "Unhandled target architecture."); 410 return nullptr; 411 } 412 413 return nullptr; 414 } 415 416 Status 417 NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info, 418 RegisterValue ®_value) { 419 Status error; 420 421 if (!reg_info) { 422 error = Status::FromErrorString("reg_info NULL"); 423 return error; 424 } 425 426 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; 427 if (reg == LLDB_INVALID_REGNUM) { 428 // This is likely an internal register for lldb use only and should not be 429 // directly queried. 430 error = Status::FromErrorStringWithFormat( 431 "register \"%s\" is an internal-only lldb " 432 "register, cannot read directly", 433 reg_info->name); 434 return error; 435 } 436 437 if (IsFPR(reg) || IsAVX(reg) || IsMPX(reg)) { 438 error = ReadFPR(); 439 if (error.Fail()) 440 return error; 441 } else { 442 uint32_t full_reg = reg; 443 bool is_subreg = reg_info->invalidate_regs && 444 (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM); 445 446 if (is_subreg) { 447 // Read the full aligned 64-bit register. 448 full_reg = reg_info->invalidate_regs[0]; 449 } 450 451 error = ReadRegisterRaw(full_reg, reg_value); 452 453 if (error.Success()) { 454 // If our read was not aligned (for ah,bh,ch,dh), shift our returned 455 // value one byte to the right. 456 if (is_subreg && (reg_info->byte_offset & 0x1)) 457 reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8); 458 459 // If our return byte size was greater than the return value reg size, 460 // then use the type specified by reg_info rather than the uint64_t 461 // default 462 if (reg_value.GetByteSize() > reg_info->byte_size) 463 reg_value.SetType(*reg_info); 464 } 465 return error; 466 } 467 468 if (reg_info->encoding == lldb::eEncodingVector) { 469 lldb::ByteOrder byte_order = GetByteOrder(); 470 471 if (byte_order != lldb::eByteOrderInvalid) { 472 if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st) 473 reg_value.SetBytes( 474 m_xstate->fxsave.stmm[reg - m_reg_info.first_st].bytes, 475 reg_info->byte_size, byte_order); 476 if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm) 477 reg_value.SetBytes( 478 m_xstate->fxsave.stmm[reg - m_reg_info.first_mm].bytes, 479 reg_info->byte_size, byte_order); 480 if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm) 481 reg_value.SetBytes( 482 m_xstate->fxsave.xmm[reg - m_reg_info.first_xmm].bytes, 483 reg_info->byte_size, byte_order); 484 if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) { 485 // Concatenate ymm using the register halves in xmm.bytes and 486 // ymmh.bytes 487 if (CopyXSTATEtoYMM(reg, byte_order)) 488 reg_value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, 489 reg_info->byte_size, byte_order); 490 else { 491 error = Status::FromErrorString("failed to copy ymm register value"); 492 return error; 493 } 494 } 495 if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) { 496 if (CopyXSTATEtoMPX(reg)) 497 reg_value.SetBytes(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, 498 reg_info->byte_size, byte_order); 499 else { 500 error = Status::FromErrorString("failed to copy mpx register value"); 501 return error; 502 } 503 } 504 if (reg >= m_reg_info.first_mpxc && reg <= m_reg_info.last_mpxc) { 505 if (CopyXSTATEtoMPX(reg)) 506 reg_value.SetBytes(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, 507 reg_info->byte_size, byte_order); 508 else { 509 error = Status::FromErrorString("failed to copy mpx register value"); 510 return error; 511 } 512 } 513 514 if (reg_value.GetType() != RegisterValue::eTypeBytes) 515 error = Status::FromErrorString( 516 "write failed - type was expected to be RegisterValue::eTypeBytes"); 517 518 return error; 519 } 520 521 error = Status::FromErrorString("byte order is invalid"); 522 return error; 523 } 524 525 // Get pointer to m_xstate->fxsave variable and set the data from it. 526 527 // Byte offsets of all registers are calculated wrt 'UserArea' structure. 528 // However, ReadFPR() reads fpu registers {using ptrace(PTRACE_GETFPREGS,..)} 529 // and stores them in 'm_fpr' (of type FPR structure). To extract values of 530 // fpu registers, m_fpr should be read at byte offsets calculated wrt to FPR 531 // structure. 532 533 // Since, FPR structure is also one of the member of UserArea structure. 534 // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) - 535 // byte_offset(fctrl wrt UserArea) 536 assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(FPR)); 537 uint8_t *src = (uint8_t *)m_xstate.get() + reg_info->byte_offset - 538 m_fctrl_offset_in_userarea; 539 540 if (src == reinterpret_cast<uint8_t *>(&m_xstate->fxsave.ftag)) { 541 reg_value.SetUInt16(AbridgedToFullTagWord( 542 m_xstate->fxsave.ftag, m_xstate->fxsave.fstat, m_xstate->fxsave.stmm)); 543 return error; 544 } 545 546 switch (reg_info->byte_size) { 547 case 1: 548 reg_value.SetUInt8(*(uint8_t *)src); 549 break; 550 case 2: 551 reg_value.SetUInt16(*(uint16_t *)src); 552 break; 553 case 4: 554 reg_value.SetUInt32(*(uint32_t *)src); 555 break; 556 case 8: 557 reg_value.SetUInt64(*(uint64_t *)src); 558 break; 559 default: 560 assert(false && "Unhandled data size."); 561 error = Status::FromErrorStringWithFormat("unhandled byte size: %" PRIu32, 562 reg_info->byte_size); 563 break; 564 } 565 566 return error; 567 } 568 569 void NativeRegisterContextLinux_x86_64::UpdateXSTATEforWrite( 570 uint32_t reg_index) { 571 XSAVE_HDR::XFeature &xstate_bv = m_xstate->xsave.header.xstate_bv; 572 if (IsFPR(reg_index)) { 573 // IsFPR considers both %st and %xmm registers as floating point, but these 574 // map to two features. Set both flags, just in case. 575 xstate_bv |= XSAVE_HDR::XFeature::FP | XSAVE_HDR::XFeature::SSE; 576 } else if (IsAVX(reg_index)) { 577 // Lower bytes of some %ymm registers are shared with %xmm registers. 578 xstate_bv |= XSAVE_HDR::XFeature::YMM | XSAVE_HDR::XFeature::SSE; 579 } else if (IsMPX(reg_index)) { 580 // MPX registers map to two XSAVE features. 581 xstate_bv |= XSAVE_HDR::XFeature::BNDREGS | XSAVE_HDR::XFeature::BNDCSR; 582 } 583 } 584 585 Status NativeRegisterContextLinux_x86_64::WriteRegister( 586 const RegisterInfo *reg_info, const RegisterValue ®_value) { 587 assert(reg_info && "reg_info is null"); 588 589 const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB]; 590 if (reg_index == LLDB_INVALID_REGNUM) 591 return Status::FromErrorStringWithFormat( 592 "no lldb regnum for %s", 593 reg_info && reg_info->name ? reg_info->name : "<unknown register>"); 594 595 UpdateXSTATEforWrite(reg_index); 596 597 if (IsGPR(reg_index) || IsDR(reg_index)) 598 return WriteRegisterRaw(reg_index, reg_value); 599 600 if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) { 601 if (reg_info->encoding == lldb::eEncodingVector) { 602 if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st) 603 ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_st].bytes, 604 reg_value.GetBytes(), reg_value.GetByteSize()); 605 606 if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm) 607 ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_mm].bytes, 608 reg_value.GetBytes(), reg_value.GetByteSize()); 609 610 if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm) 611 ::memcpy(m_xstate->fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes, 612 reg_value.GetBytes(), reg_value.GetByteSize()); 613 614 if (reg_index >= m_reg_info.first_ymm && 615 reg_index <= m_reg_info.last_ymm) { 616 // Store ymm register content, and split into the register halves in 617 // xmm.bytes and ymmh.bytes 618 ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes, 619 reg_value.GetBytes(), reg_value.GetByteSize()); 620 if (!CopyYMMtoXSTATE(reg_index, GetByteOrder())) 621 return Status::FromErrorString("CopyYMMtoXSTATE() failed"); 622 } 623 624 if (reg_index >= m_reg_info.first_mpxr && 625 reg_index <= m_reg_info.last_mpxr) { 626 ::memcpy(m_mpx_set.mpxr[reg_index - m_reg_info.first_mpxr].bytes, 627 reg_value.GetBytes(), reg_value.GetByteSize()); 628 if (!CopyMPXtoXSTATE(reg_index)) 629 return Status::FromErrorString("CopyMPXtoXSTATE() failed"); 630 } 631 632 if (reg_index >= m_reg_info.first_mpxc && 633 reg_index <= m_reg_info.last_mpxc) { 634 ::memcpy(m_mpx_set.mpxc[reg_index - m_reg_info.first_mpxc].bytes, 635 reg_value.GetBytes(), reg_value.GetByteSize()); 636 if (!CopyMPXtoXSTATE(reg_index)) 637 return Status::FromErrorString("CopyMPXtoXSTATE() failed"); 638 } 639 } else { 640 // Get pointer to m_xstate->fxsave variable and set the data to it. 641 642 // Byte offsets of all registers are calculated wrt 'UserArea' structure. 643 // However, WriteFPR() takes m_fpr (of type FPR structure) and writes 644 // only fpu registers using ptrace(PTRACE_SETFPREGS,..) API. Hence fpu 645 // registers should be written in m_fpr at byte offsets calculated wrt 646 // FPR structure. 647 648 // Since, FPR structure is also one of the member of UserArea structure. 649 // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) - 650 // byte_offset(fctrl wrt UserArea) 651 assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < 652 sizeof(FPR)); 653 uint8_t *dst = (uint8_t *)m_xstate.get() + reg_info->byte_offset - 654 m_fctrl_offset_in_userarea; 655 656 if (dst == reinterpret_cast<uint8_t *>(&m_xstate->fxsave.ftag)) 657 m_xstate->fxsave.ftag = FullToAbridgedTagWord(reg_value.GetAsUInt16()); 658 else { 659 switch (reg_info->byte_size) { 660 case 1: 661 *(uint8_t *)dst = reg_value.GetAsUInt8(); 662 break; 663 case 2: 664 *(uint16_t *)dst = reg_value.GetAsUInt16(); 665 break; 666 case 4: 667 *(uint32_t *)dst = reg_value.GetAsUInt32(); 668 break; 669 case 8: 670 *(uint64_t *)dst = reg_value.GetAsUInt64(); 671 break; 672 default: 673 assert(false && "Unhandled data size."); 674 return Status::FromErrorStringWithFormat( 675 "unhandled register data size %" PRIu32, reg_info->byte_size); 676 } 677 } 678 } 679 680 Status error = WriteFPR(); 681 if (error.Fail()) 682 return error; 683 684 if (IsAVX(reg_index)) { 685 if (!CopyYMMtoXSTATE(reg_index, GetByteOrder())) 686 return Status::FromErrorString("CopyYMMtoXSTATE() failed"); 687 } 688 689 if (IsMPX(reg_index)) { 690 if (!CopyMPXtoXSTATE(reg_index)) 691 return Status::FromErrorString("CopyMPXtoXSTATE() failed"); 692 } 693 return Status(); 694 } 695 return Status::FromErrorString( 696 "failed - register wasn't recognized to be a GPR or an FPR, " 697 "write strategy unknown"); 698 } 699 700 Status NativeRegisterContextLinux_x86_64::ReadAllRegisterValues( 701 lldb::WritableDataBufferSP &data_sp) { 702 Status error; 703 704 data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0)); 705 error = ReadGPR(); 706 if (error.Fail()) 707 return error; 708 709 error = ReadFPR(); 710 if (error.Fail()) 711 return error; 712 713 uint8_t *dst = data_sp->GetBytes(); 714 ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize()); 715 dst += GetRegisterInfoInterface().GetGPRSize(); 716 if (m_xstate_type == XStateType::FXSAVE) 717 ::memcpy(dst, &m_xstate->fxsave, sizeof(m_xstate->fxsave)); 718 else if (m_xstate_type == XStateType::XSAVE) { 719 lldb::ByteOrder byte_order = GetByteOrder(); 720 721 if (IsCPUFeatureAvailable(RegSet::avx)) { 722 // Assemble the YMM register content from the register halves. 723 for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm; 724 ++reg) { 725 if (!CopyXSTATEtoYMM(reg, byte_order)) { 726 error = Status::FromErrorStringWithFormat( 727 "NativeRegisterContextLinux_x86_64::%s " 728 "CopyXSTATEtoYMM() failed for reg num " 729 "%" PRIu32, 730 __FUNCTION__, reg); 731 return error; 732 } 733 } 734 } 735 736 if (IsCPUFeatureAvailable(RegSet::mpx)) { 737 for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc; 738 ++reg) { 739 if (!CopyXSTATEtoMPX(reg)) { 740 error = Status::FromErrorStringWithFormat( 741 "NativeRegisterContextLinux_x86_64::%s " 742 "CopyXSTATEtoMPX() failed for reg num " 743 "%" PRIu32, 744 __FUNCTION__, reg); 745 return error; 746 } 747 } 748 } 749 // Copy the extended register state including the assembled ymm registers. 750 ::memcpy(dst, m_xstate.get(), sizeof(FPR)); 751 } else { 752 assert(false && "how do we save the floating point registers?"); 753 error = Status::FromErrorString( 754 "unsure how to save the floating point registers"); 755 } 756 /** The following code is specific to Linux x86 based architectures, 757 * where the register orig_eax (32 bit)/orig_rax (64 bit) is set to 758 * -1 to solve the bug 23659, such a setting prevents the automatic 759 * decrement of the instruction pointer which was causing the SIGILL 760 * exception. 761 * **/ 762 763 RegisterValue value((uint64_t)-1); 764 const RegisterInfo &info = GetRegisterInfo().GetOrigAxInfo(); 765 return DoWriteRegisterValue(info.byte_offset, info.name, value); 766 767 return error; 768 } 769 770 Status NativeRegisterContextLinux_x86_64::WriteAllRegisterValues( 771 const lldb::DataBufferSP &data_sp) { 772 Status error; 773 774 if (!data_sp) { 775 error = Status::FromErrorStringWithFormat( 776 "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided", 777 __FUNCTION__); 778 return error; 779 } 780 781 if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) { 782 error = Status::FromErrorStringWithFormatv( 783 "data_sp contained mismatched data size, expected {0}, actual {1}", 784 REG_CONTEXT_SIZE, data_sp->GetByteSize()); 785 return error; 786 } 787 788 const uint8_t *src = data_sp->GetBytes(); 789 if (src == nullptr) { 790 error = Status::FromErrorStringWithFormat( 791 "NativeRegisterContextLinux_x86_64::%s " 792 "DataBuffer::GetBytes() returned a null " 793 "pointer", 794 __FUNCTION__); 795 return error; 796 } 797 ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize()); 798 799 error = WriteGPR(); 800 if (error.Fail()) 801 return error; 802 803 src += GetRegisterInfoInterface().GetGPRSize(); 804 if (m_xstate_type == XStateType::FXSAVE) 805 ::memcpy(&m_xstate->fxsave, src, sizeof(m_xstate->fxsave)); 806 else if (m_xstate_type == XStateType::XSAVE) 807 ::memcpy(&m_xstate->xsave, src, sizeof(m_xstate->xsave)); 808 809 error = WriteFPR(); 810 if (error.Fail()) 811 return error; 812 813 if (m_xstate_type == XStateType::XSAVE) { 814 lldb::ByteOrder byte_order = GetByteOrder(); 815 816 if (IsCPUFeatureAvailable(RegSet::avx)) { 817 // Parse the YMM register content from the register halves. 818 for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm; 819 ++reg) { 820 if (!CopyYMMtoXSTATE(reg, byte_order)) { 821 error = Status::FromErrorStringWithFormat( 822 "NativeRegisterContextLinux_x86_64::%s " 823 "CopyYMMtoXSTATE() failed for reg num " 824 "%" PRIu32, 825 __FUNCTION__, reg); 826 return error; 827 } 828 } 829 } 830 831 if (IsCPUFeatureAvailable(RegSet::mpx)) { 832 for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc; 833 ++reg) { 834 if (!CopyMPXtoXSTATE(reg)) { 835 error = Status::FromErrorStringWithFormat( 836 "NativeRegisterContextLinux_x86_64::%s " 837 "CopyMPXtoXSTATE() failed for reg num " 838 "%" PRIu32, 839 __FUNCTION__, reg); 840 return error; 841 } 842 } 843 } 844 } 845 846 return error; 847 } 848 849 bool NativeRegisterContextLinux_x86_64::IsCPUFeatureAvailable( 850 RegSet feature_code) const { 851 if (m_xstate_type == XStateType::Invalid) { 852 if (const_cast<NativeRegisterContextLinux_x86_64 *>(this)->ReadFPR().Fail()) 853 return false; 854 } 855 switch (feature_code) { 856 case RegSet::gpr: 857 case RegSet::fpu: 858 return true; 859 case RegSet::avx: // Check if CPU has AVX and if there is kernel support, by 860 // reading in the XCR0 area of XSAVE. 861 if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX) 862 return true; 863 break; 864 case RegSet::mpx: // Check if CPU has MPX and if there is kernel support, by 865 // reading in the XCR0 area of XSAVE. 866 if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX) 867 return true; 868 break; 869 } 870 return false; 871 } 872 873 bool NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable( 874 uint32_t set_index) const { 875 uint32_t num_sets = k_num_register_sets - k_num_extended_register_sets; 876 877 switch (static_cast<RegSet>(set_index)) { 878 case RegSet::gpr: 879 case RegSet::fpu: 880 return (set_index < num_sets); 881 case RegSet::avx: 882 return IsCPUFeatureAvailable(RegSet::avx); 883 case RegSet::mpx: 884 return IsCPUFeatureAvailable(RegSet::mpx); 885 } 886 return false; 887 } 888 889 bool NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index) const { 890 // GPRs come first. 891 return reg_index <= m_reg_info.last_gpr; 892 } 893 894 bool NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index) const { 895 return (m_reg_info.first_fpr <= reg_index && 896 reg_index <= m_reg_info.last_fpr); 897 } 898 899 bool NativeRegisterContextLinux_x86_64::IsDR(uint32_t reg_index) const { 900 return (m_reg_info.first_dr <= reg_index && 901 reg_index <= m_reg_info.last_dr); 902 } 903 904 Status NativeRegisterContextLinux_x86_64::WriteFPR() { 905 switch (m_xstate_type) { 906 case XStateType::FXSAVE: 907 return WriteRegisterSet( 908 &m_iovec, sizeof(m_xstate->fxsave), 909 fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture())); 910 case XStateType::XSAVE: 911 return WriteRegisterSet(&m_iovec, sizeof(m_xstate->xsave), NT_X86_XSTATE); 912 default: 913 return Status::FromErrorString("Unrecognized FPR type."); 914 } 915 } 916 917 bool NativeRegisterContextLinux_x86_64::IsAVX(uint32_t reg_index) const { 918 if (!IsCPUFeatureAvailable(RegSet::avx)) 919 return false; 920 return (m_reg_info.first_ymm <= reg_index && 921 reg_index <= m_reg_info.last_ymm); 922 } 923 924 bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM( 925 uint32_t reg_index, lldb::ByteOrder byte_order) { 926 if (!IsAVX(reg_index)) 927 return false; 928 929 if (byte_order == lldb::eByteOrderLittle) { 930 uint32_t reg_no = reg_index - m_reg_info.first_ymm; 931 m_ymm_set.ymm[reg_no] = XStateToYMM( 932 m_xstate->fxsave.xmm[reg_no].bytes, 933 m_xstate->xsave.ymmh[reg_no].bytes); 934 return true; 935 } 936 937 return false; // unsupported or invalid byte order 938 } 939 940 bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE( 941 uint32_t reg, lldb::ByteOrder byte_order) { 942 if (!IsAVX(reg)) 943 return false; 944 945 if (byte_order == lldb::eByteOrderLittle) { 946 uint32_t reg_no = reg - m_reg_info.first_ymm; 947 YMMToXState(m_ymm_set.ymm[reg_no], 948 m_xstate->fxsave.xmm[reg_no].bytes, 949 m_xstate->xsave.ymmh[reg_no].bytes); 950 return true; 951 } 952 953 return false; // unsupported or invalid byte order 954 } 955 956 void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() { 957 switch (m_xstate_type) { 958 case XStateType::FXSAVE: 959 return &m_xstate->fxsave; 960 case XStateType::XSAVE: 961 return &m_iovec; 962 default: 963 return nullptr; 964 } 965 } 966 967 size_t NativeRegisterContextLinux_x86_64::GetFPRSize() { 968 switch (m_xstate_type) { 969 case XStateType::FXSAVE: 970 return sizeof(m_xstate->fxsave); 971 case XStateType::XSAVE: 972 return sizeof(m_iovec); 973 default: 974 return 0; 975 } 976 } 977 978 Status NativeRegisterContextLinux_x86_64::ReadFPR() { 979 Status error; 980 981 // Probe XSAVE and if it is not supported fall back to FXSAVE. 982 if (m_xstate_type != XStateType::FXSAVE) { 983 error = ReadRegisterSet(&m_iovec, sizeof(m_xstate->xsave), NT_X86_XSTATE); 984 if (!error.Fail()) { 985 m_xstate_type = XStateType::XSAVE; 986 return error; 987 } 988 } 989 error = ReadRegisterSet( 990 &m_iovec, sizeof(m_xstate->xsave), 991 fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture())); 992 if (!error.Fail()) { 993 m_xstate_type = XStateType::FXSAVE; 994 return error; 995 } 996 return Status::FromErrorString("Unrecognized FPR type."); 997 } 998 999 bool NativeRegisterContextLinux_x86_64::IsMPX(uint32_t reg_index) const { 1000 if (!IsCPUFeatureAvailable(RegSet::mpx)) 1001 return false; 1002 return (m_reg_info.first_mpxr <= reg_index && 1003 reg_index <= m_reg_info.last_mpxc); 1004 } 1005 1006 bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoMPX(uint32_t reg) { 1007 if (!IsMPX(reg)) 1008 return false; 1009 1010 if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) { 1011 ::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, 1012 m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes, 1013 sizeof(MPXReg)); 1014 } else { 1015 ::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, 1016 m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes, 1017 sizeof(MPXCsr)); 1018 } 1019 return true; 1020 } 1021 1022 bool NativeRegisterContextLinux_x86_64::CopyMPXtoXSTATE(uint32_t reg) { 1023 if (!IsMPX(reg)) 1024 return false; 1025 1026 if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) { 1027 ::memcpy(m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes, 1028 m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, sizeof(MPXReg)); 1029 } else { 1030 ::memcpy(m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes, 1031 m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr)); 1032 } 1033 return true; 1034 } 1035 1036 uint32_t 1037 NativeRegisterContextLinux_x86_64::GetPtraceOffset(uint32_t reg_index) { 1038 // If register is MPX, remove extra factor from gdb offset 1039 return GetRegisterInfoAtIndex(reg_index)->byte_offset - 1040 (IsMPX(reg_index) ? 128 : 0); 1041 } 1042 1043 std::optional<NativeRegisterContextLinux::SyscallData> 1044 NativeRegisterContextLinux_x86_64::GetSyscallData() { 1045 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { 1046 case llvm::Triple::x86: { 1047 static const uint8_t Int80[] = {0xcd, 0x80}; 1048 static const uint32_t Args[] = {lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, 1049 lldb_edx_i386, lldb_esi_i386, lldb_edi_i386, 1050 lldb_ebp_i386}; 1051 return SyscallData{Int80, Args, lldb_eax_i386}; 1052 } 1053 case llvm::Triple::x86_64: { 1054 static const uint8_t Syscall[] = {0x0f, 0x05}; 1055 static const uint32_t Args[] = { 1056 x86_64_with_base::lldb_rax, x86_64_with_base::lldb_rdi, x86_64_with_base::lldb_rsi, x86_64_with_base::lldb_rdx, 1057 x86_64_with_base::lldb_r10, x86_64_with_base::lldb_r8, x86_64_with_base::lldb_r9}; 1058 return SyscallData{Syscall, Args, x86_64_with_base::lldb_rax}; 1059 } 1060 default: 1061 llvm_unreachable("Unhandled architecture!"); 1062 } 1063 } 1064 1065 std::optional<NativeRegisterContextLinux::MmapData> 1066 NativeRegisterContextLinux_x86_64::GetMmapData() { 1067 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { 1068 case llvm::Triple::x86: 1069 return MmapData{192, 91}; 1070 case llvm::Triple::x86_64: 1071 return MmapData{9, 11}; 1072 default: 1073 llvm_unreachable("Unhandled architecture!"); 1074 } 1075 } 1076 1077 const RegisterInfo *NativeRegisterContextLinux_x86_64::GetDR(int num) const { 1078 assert(num >= 0 && num <= 7); 1079 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { 1080 case llvm::Triple::x86: 1081 return GetRegisterInfoAtIndex(lldb_dr0_i386 + num); 1082 case llvm::Triple::x86_64: 1083 return GetRegisterInfoAtIndex(x86_64_with_base::lldb_dr0 + num); 1084 default: 1085 llvm_unreachable("Unhandled target architecture."); 1086 } 1087 } 1088 1089 #endif // defined(__i386__) || defined(__x86_64__) 1090