541 lines · cpp
1//===-- RegisterContextPOSIX_x86.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-exception6//7//===----------------------------------------------------------------------===//8 9#include <cerrno>10#include <cstdint>11#include <cstring>12 13#include "lldb/Target/Process.h"14#include "lldb/Target/Target.h"15#include "lldb/Target/Thread.h"16#include "lldb/Utility/DataBufferHeap.h"17#include "lldb/Utility/DataExtractor.h"18#include "lldb/Utility/Endian.h"19#include "lldb/Utility/RegisterValue.h"20#include "lldb/Utility/Scalar.h"21#include "llvm/Support/Compiler.h"22 23#include "RegisterContextPOSIX_x86.h"24#include "RegisterContext_x86.h"25 26using namespace lldb_private;27using namespace lldb;28 29const uint32_t g_gpr_regnums_i386[] = {30 lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386,31 lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386,32 lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386,33 lldb_gs_i386, lldb_ss_i386, lldb_ds_i386, lldb_es_i386,34 lldb_ax_i386, lldb_bx_i386, lldb_cx_i386, lldb_dx_i386,35 lldb_di_i386, lldb_si_i386, lldb_bp_i386, lldb_sp_i386,36 lldb_ah_i386, lldb_bh_i386, lldb_ch_i386, lldb_dh_i386,37 lldb_al_i386, lldb_bl_i386, lldb_cl_i386, lldb_dl_i386,38 LLDB_INVALID_REGNUM, // Register sets must be terminated with39 // LLDB_INVALID_REGNUM.40};41static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -42 1 ==43 k_num_gpr_registers_i386,44 "g_gpr_regnums_i386 has wrong number of register infos");45 46const uint32_t g_lldb_regnums_i386[] = {47 lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386,48 lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386,49 lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386,50 lldb_st2_i386, lldb_st3_i386, lldb_st4_i386, lldb_st5_i386,51 lldb_st6_i386, lldb_st7_i386, lldb_mm0_i386, lldb_mm1_i386,52 lldb_mm2_i386, lldb_mm3_i386, lldb_mm4_i386, lldb_mm5_i386,53 lldb_mm6_i386, lldb_mm7_i386, lldb_xmm0_i386, lldb_xmm1_i386,54 lldb_xmm2_i386, lldb_xmm3_i386, lldb_xmm4_i386, lldb_xmm5_i386,55 lldb_xmm6_i386, lldb_xmm7_i386,56 LLDB_INVALID_REGNUM // Register sets must be terminated with57 // LLDB_INVALID_REGNUM.58};59static_assert((sizeof(g_lldb_regnums_i386) / sizeof(g_lldb_regnums_i386[0])) -60 1 ==61 k_num_fpr_registers_i386,62 "g_lldb_regnums_i386 has wrong number of register infos");63 64const uint32_t g_avx_regnums_i386[] = {65 lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386,66 lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386,67 LLDB_INVALID_REGNUM // Register sets must be terminated with68 // LLDB_INVALID_REGNUM.69};70static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) -71 1 ==72 k_num_avx_registers_i386,73 " g_avx_regnums_i386 has wrong number of register infos");74 75static const uint32_t g_gpr_regnums_x86_64[] = {76 lldb_rax_x86_64, lldb_rbx_x86_64, lldb_rcx_x86_64, lldb_rdx_x86_64,77 lldb_rdi_x86_64, lldb_rsi_x86_64, lldb_rbp_x86_64, lldb_rsp_x86_64,78 lldb_r8_x86_64, lldb_r9_x86_64, lldb_r10_x86_64, lldb_r11_x86_64,79 lldb_r12_x86_64, lldb_r13_x86_64, lldb_r14_x86_64, lldb_r15_x86_64,80 lldb_rip_x86_64, lldb_rflags_x86_64, lldb_cs_x86_64, lldb_fs_x86_64,81 lldb_gs_x86_64, lldb_ss_x86_64, lldb_ds_x86_64, lldb_es_x86_64,82 lldb_eax_x86_64, lldb_ebx_x86_64, lldb_ecx_x86_64, lldb_edx_x86_64,83 lldb_edi_x86_64, lldb_esi_x86_64, lldb_ebp_x86_64, lldb_esp_x86_64,84 lldb_r8d_x86_64, // Low 32 bits or r885 lldb_r9d_x86_64, // Low 32 bits or r986 lldb_r10d_x86_64, // Low 32 bits or r1087 lldb_r11d_x86_64, // Low 32 bits or r1188 lldb_r12d_x86_64, // Low 32 bits or r1289 lldb_r13d_x86_64, // Low 32 bits or r1390 lldb_r14d_x86_64, // Low 32 bits or r1491 lldb_r15d_x86_64, // Low 32 bits or r1592 lldb_ax_x86_64, lldb_bx_x86_64, lldb_cx_x86_64, lldb_dx_x86_64,93 lldb_di_x86_64, lldb_si_x86_64, lldb_bp_x86_64, lldb_sp_x86_64,94 lldb_r8w_x86_64, // Low 16 bits or r895 lldb_r9w_x86_64, // Low 16 bits or r996 lldb_r10w_x86_64, // Low 16 bits or r1097 lldb_r11w_x86_64, // Low 16 bits or r1198 lldb_r12w_x86_64, // Low 16 bits or r1299 lldb_r13w_x86_64, // Low 16 bits or r13100 lldb_r14w_x86_64, // Low 16 bits or r14101 lldb_r15w_x86_64, // Low 16 bits or r15102 lldb_ah_x86_64, lldb_bh_x86_64, lldb_ch_x86_64, lldb_dh_x86_64,103 lldb_al_x86_64, lldb_bl_x86_64, lldb_cl_x86_64, lldb_dl_x86_64,104 lldb_dil_x86_64, lldb_sil_x86_64, lldb_bpl_x86_64, lldb_spl_x86_64,105 lldb_r8l_x86_64, // Low 8 bits or r8106 lldb_r9l_x86_64, // Low 8 bits or r9107 lldb_r10l_x86_64, // Low 8 bits or r10108 lldb_r11l_x86_64, // Low 8 bits or r11109 lldb_r12l_x86_64, // Low 8 bits or r12110 lldb_r13l_x86_64, // Low 8 bits or r13111 lldb_r14l_x86_64, // Low 8 bits or r14112 lldb_r15l_x86_64, // Low 8 bits or r15113 LLDB_INVALID_REGNUM // Register sets must be terminated with114 // LLDB_INVALID_REGNUM.115};116static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -117 1 ==118 k_num_gpr_registers_x86_64,119 "g_gpr_regnums_x86_64 has wrong number of register infos");120 121static const uint32_t g_lldb_regnums_x86_64[] = {122 lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64,123 lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64,124 lldb_fip_x86_64, lldb_foseg_x86_64, lldb_fooff_x86_64,125 lldb_fdp_x86_64, lldb_mxcsr_x86_64, lldb_mxcsrmask_x86_64,126 lldb_st0_x86_64, lldb_st1_x86_64, lldb_st2_x86_64,127 lldb_st3_x86_64, lldb_st4_x86_64, lldb_st5_x86_64,128 lldb_st6_x86_64, lldb_st7_x86_64, lldb_mm0_x86_64,129 lldb_mm1_x86_64, lldb_mm2_x86_64, lldb_mm3_x86_64,130 lldb_mm4_x86_64, lldb_mm5_x86_64, lldb_mm6_x86_64,131 lldb_mm7_x86_64, lldb_xmm0_x86_64, lldb_xmm1_x86_64,132 lldb_xmm2_x86_64, lldb_xmm3_x86_64, lldb_xmm4_x86_64,133 lldb_xmm5_x86_64, lldb_xmm6_x86_64, lldb_xmm7_x86_64,134 lldb_xmm8_x86_64, lldb_xmm9_x86_64, lldb_xmm10_x86_64,135 lldb_xmm11_x86_64, lldb_xmm12_x86_64, lldb_xmm13_x86_64,136 lldb_xmm14_x86_64, lldb_xmm15_x86_64,137 LLDB_INVALID_REGNUM // Register sets must be terminated with138 // LLDB_INVALID_REGNUM.139};140static_assert((sizeof(g_lldb_regnums_x86_64) /141 sizeof(g_lldb_regnums_x86_64[0])) -142 1 ==143 k_num_fpr_registers_x86_64,144 "g_lldb_regnums_x86_64 has wrong number of register infos");145 146static const uint32_t g_avx_regnums_x86_64[] = {147 lldb_ymm0_x86_64, lldb_ymm1_x86_64, lldb_ymm2_x86_64, lldb_ymm3_x86_64,148 lldb_ymm4_x86_64, lldb_ymm5_x86_64, lldb_ymm6_x86_64, lldb_ymm7_x86_64,149 lldb_ymm8_x86_64, lldb_ymm9_x86_64, lldb_ymm10_x86_64, lldb_ymm11_x86_64,150 lldb_ymm12_x86_64, lldb_ymm13_x86_64, lldb_ymm14_x86_64, lldb_ymm15_x86_64,151 LLDB_INVALID_REGNUM // Register sets must be terminated with152 // LLDB_INVALID_REGNUM.153};154static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) -155 1 ==156 k_num_avx_registers_x86_64,157 "g_avx_regnums_x86_64 has wrong number of register infos");158 159uint32_t RegisterContextPOSIX_x86::g_contained_eax[] = {lldb_eax_i386,160 LLDB_INVALID_REGNUM};161uint32_t RegisterContextPOSIX_x86::g_contained_ebx[] = {lldb_ebx_i386,162 LLDB_INVALID_REGNUM};163uint32_t RegisterContextPOSIX_x86::g_contained_ecx[] = {lldb_ecx_i386,164 LLDB_INVALID_REGNUM};165uint32_t RegisterContextPOSIX_x86::g_contained_edx[] = {lldb_edx_i386,166 LLDB_INVALID_REGNUM};167uint32_t RegisterContextPOSIX_x86::g_contained_edi[] = {lldb_edi_i386,168 LLDB_INVALID_REGNUM};169uint32_t RegisterContextPOSIX_x86::g_contained_esi[] = {lldb_esi_i386,170 LLDB_INVALID_REGNUM};171uint32_t RegisterContextPOSIX_x86::g_contained_ebp[] = {lldb_ebp_i386,172 LLDB_INVALID_REGNUM};173uint32_t RegisterContextPOSIX_x86::g_contained_esp[] = {lldb_esp_i386,174 LLDB_INVALID_REGNUM};175 176uint32_t RegisterContextPOSIX_x86::g_invalidate_eax[] = {177 lldb_eax_i386, lldb_ax_i386, lldb_ah_i386, lldb_al_i386,178 LLDB_INVALID_REGNUM};179uint32_t RegisterContextPOSIX_x86::g_invalidate_ebx[] = {180 lldb_ebx_i386, lldb_bx_i386, lldb_bh_i386, lldb_bl_i386,181 LLDB_INVALID_REGNUM};182uint32_t RegisterContextPOSIX_x86::g_invalidate_ecx[] = {183 lldb_ecx_i386, lldb_cx_i386, lldb_ch_i386, lldb_cl_i386,184 LLDB_INVALID_REGNUM};185uint32_t RegisterContextPOSIX_x86::g_invalidate_edx[] = {186 lldb_edx_i386, lldb_dx_i386, lldb_dh_i386, lldb_dl_i386,187 LLDB_INVALID_REGNUM};188uint32_t RegisterContextPOSIX_x86::g_invalidate_edi[] = {189 lldb_edi_i386, lldb_di_i386, LLDB_INVALID_REGNUM};190uint32_t RegisterContextPOSIX_x86::g_invalidate_esi[] = {191 lldb_esi_i386, lldb_si_i386, LLDB_INVALID_REGNUM};192uint32_t RegisterContextPOSIX_x86::g_invalidate_ebp[] = {193 lldb_ebp_i386, lldb_bp_i386, LLDB_INVALID_REGNUM};194uint32_t RegisterContextPOSIX_x86::g_invalidate_esp[] = {195 lldb_esp_i386, lldb_sp_i386, LLDB_INVALID_REGNUM};196 197uint32_t RegisterContextPOSIX_x86::g_contained_rax[] = {lldb_rax_x86_64,198 LLDB_INVALID_REGNUM};199uint32_t RegisterContextPOSIX_x86::g_contained_rbx[] = {lldb_rbx_x86_64,200 LLDB_INVALID_REGNUM};201uint32_t RegisterContextPOSIX_x86::g_contained_rcx[] = {lldb_rcx_x86_64,202 LLDB_INVALID_REGNUM};203uint32_t RegisterContextPOSIX_x86::g_contained_rdx[] = {lldb_rdx_x86_64,204 LLDB_INVALID_REGNUM};205uint32_t RegisterContextPOSIX_x86::g_contained_rdi[] = {lldb_rdi_x86_64,206 LLDB_INVALID_REGNUM};207uint32_t RegisterContextPOSIX_x86::g_contained_rsi[] = {lldb_rsi_x86_64,208 LLDB_INVALID_REGNUM};209uint32_t RegisterContextPOSIX_x86::g_contained_rbp[] = {lldb_rbp_x86_64,210 LLDB_INVALID_REGNUM};211uint32_t RegisterContextPOSIX_x86::g_contained_rsp[] = {lldb_rsp_x86_64,212 LLDB_INVALID_REGNUM};213uint32_t RegisterContextPOSIX_x86::g_contained_r8[] = {lldb_r8_x86_64,214 LLDB_INVALID_REGNUM};215uint32_t RegisterContextPOSIX_x86::g_contained_r9[] = {lldb_r9_x86_64,216 LLDB_INVALID_REGNUM};217uint32_t RegisterContextPOSIX_x86::g_contained_r10[] = {lldb_r10_x86_64,218 LLDB_INVALID_REGNUM};219uint32_t RegisterContextPOSIX_x86::g_contained_r11[] = {lldb_r11_x86_64,220 LLDB_INVALID_REGNUM};221uint32_t RegisterContextPOSIX_x86::g_contained_r12[] = {lldb_r12_x86_64,222 LLDB_INVALID_REGNUM};223uint32_t RegisterContextPOSIX_x86::g_contained_r13[] = {lldb_r13_x86_64,224 LLDB_INVALID_REGNUM};225uint32_t RegisterContextPOSIX_x86::g_contained_r14[] = {lldb_r14_x86_64,226 LLDB_INVALID_REGNUM};227uint32_t RegisterContextPOSIX_x86::g_contained_r15[] = {lldb_r15_x86_64,228 LLDB_INVALID_REGNUM};229 230uint32_t RegisterContextPOSIX_x86::g_invalidate_rax[] = {231 lldb_rax_x86_64, lldb_eax_x86_64, lldb_ax_x86_64,232 lldb_ah_x86_64, lldb_al_x86_64, LLDB_INVALID_REGNUM};233uint32_t RegisterContextPOSIX_x86::g_invalidate_rbx[] = {234 lldb_rbx_x86_64, lldb_ebx_x86_64, lldb_bx_x86_64,235 lldb_bh_x86_64, lldb_bl_x86_64, LLDB_INVALID_REGNUM};236uint32_t RegisterContextPOSIX_x86::g_invalidate_rcx[] = {237 lldb_rcx_x86_64, lldb_ecx_x86_64, lldb_cx_x86_64,238 lldb_ch_x86_64, lldb_cl_x86_64, LLDB_INVALID_REGNUM};239uint32_t RegisterContextPOSIX_x86::g_invalidate_rdx[] = {240 lldb_rdx_x86_64, lldb_edx_x86_64, lldb_dx_x86_64,241 lldb_dh_x86_64, lldb_dl_x86_64, LLDB_INVALID_REGNUM};242uint32_t RegisterContextPOSIX_x86::g_invalidate_rdi[] = {243 lldb_rdi_x86_64, lldb_edi_x86_64, lldb_di_x86_64, lldb_dil_x86_64,244 LLDB_INVALID_REGNUM};245uint32_t RegisterContextPOSIX_x86::g_invalidate_rsi[] = {246 lldb_rsi_x86_64, lldb_esi_x86_64, lldb_si_x86_64, lldb_sil_x86_64,247 LLDB_INVALID_REGNUM};248uint32_t RegisterContextPOSIX_x86::g_invalidate_rbp[] = {249 lldb_rbp_x86_64, lldb_ebp_x86_64, lldb_bp_x86_64, lldb_bpl_x86_64,250 LLDB_INVALID_REGNUM};251uint32_t RegisterContextPOSIX_x86::g_invalidate_rsp[] = {252 lldb_rsp_x86_64, lldb_esp_x86_64, lldb_sp_x86_64, lldb_spl_x86_64,253 LLDB_INVALID_REGNUM};254uint32_t RegisterContextPOSIX_x86::g_invalidate_r8[] = {255 lldb_r8_x86_64, lldb_r8d_x86_64, lldb_r8w_x86_64, lldb_r8l_x86_64,256 LLDB_INVALID_REGNUM};257uint32_t RegisterContextPOSIX_x86::g_invalidate_r9[] = {258 lldb_r9_x86_64, lldb_r9d_x86_64, lldb_r9w_x86_64, lldb_r9l_x86_64,259 LLDB_INVALID_REGNUM};260uint32_t RegisterContextPOSIX_x86::g_invalidate_r10[] = {261 lldb_r10_x86_64, lldb_r10d_x86_64, lldb_r10w_x86_64, lldb_r10l_x86_64,262 LLDB_INVALID_REGNUM};263uint32_t RegisterContextPOSIX_x86::g_invalidate_r11[] = {264 lldb_r11_x86_64, lldb_r11d_x86_64, lldb_r11w_x86_64, lldb_r11l_x86_64,265 LLDB_INVALID_REGNUM};266uint32_t RegisterContextPOSIX_x86::g_invalidate_r12[] = {267 lldb_r12_x86_64, lldb_r12d_x86_64, lldb_r12w_x86_64, lldb_r12l_x86_64,268 LLDB_INVALID_REGNUM};269uint32_t RegisterContextPOSIX_x86::g_invalidate_r13[] = {270 lldb_r13_x86_64, lldb_r13d_x86_64, lldb_r13w_x86_64, lldb_r13l_x86_64,271 LLDB_INVALID_REGNUM};272uint32_t RegisterContextPOSIX_x86::g_invalidate_r14[] = {273 lldb_r14_x86_64, lldb_r14d_x86_64, lldb_r14w_x86_64, lldb_r14l_x86_64,274 LLDB_INVALID_REGNUM};275uint32_t RegisterContextPOSIX_x86::g_invalidate_r15[] = {276 lldb_r15_x86_64, lldb_r15d_x86_64, lldb_r15w_x86_64, lldb_r15l_x86_64,277 LLDB_INVALID_REGNUM};278 279uint32_t RegisterContextPOSIX_x86::g_contained_fip[] = {lldb_fip_x86_64,280 LLDB_INVALID_REGNUM};281uint32_t RegisterContextPOSIX_x86::g_contained_fdp[] = {lldb_fdp_x86_64,282 LLDB_INVALID_REGNUM};283 284uint32_t RegisterContextPOSIX_x86::g_invalidate_fip[] = {285 lldb_fip_x86_64, lldb_fioff_x86_64, lldb_fiseg_x86_64, LLDB_INVALID_REGNUM};286uint32_t RegisterContextPOSIX_x86::g_invalidate_fdp[] = {287 lldb_fdp_x86_64, lldb_fooff_x86_64, lldb_foseg_x86_64, LLDB_INVALID_REGNUM};288 289uint32_t RegisterContextPOSIX_x86::g_contained_st0_32[] = {lldb_st0_i386,290 LLDB_INVALID_REGNUM};291uint32_t RegisterContextPOSIX_x86::g_contained_st1_32[] = {lldb_st1_i386,292 LLDB_INVALID_REGNUM};293uint32_t RegisterContextPOSIX_x86::g_contained_st2_32[] = {lldb_st2_i386,294 LLDB_INVALID_REGNUM};295uint32_t RegisterContextPOSIX_x86::g_contained_st3_32[] = {lldb_st3_i386,296 LLDB_INVALID_REGNUM};297uint32_t RegisterContextPOSIX_x86::g_contained_st4_32[] = {lldb_st4_i386,298 LLDB_INVALID_REGNUM};299uint32_t RegisterContextPOSIX_x86::g_contained_st5_32[] = {lldb_st5_i386,300 LLDB_INVALID_REGNUM};301uint32_t RegisterContextPOSIX_x86::g_contained_st6_32[] = {lldb_st6_i386,302 LLDB_INVALID_REGNUM};303uint32_t RegisterContextPOSIX_x86::g_contained_st7_32[] = {lldb_st7_i386,304 LLDB_INVALID_REGNUM};305 306uint32_t RegisterContextPOSIX_x86::g_invalidate_st0_32[] = {307 lldb_st0_i386, lldb_mm0_i386, LLDB_INVALID_REGNUM};308uint32_t RegisterContextPOSIX_x86::g_invalidate_st1_32[] = {309 lldb_st1_i386, lldb_mm1_i386, LLDB_INVALID_REGNUM};310uint32_t RegisterContextPOSIX_x86::g_invalidate_st2_32[] = {311 lldb_st2_i386, lldb_mm2_i386, LLDB_INVALID_REGNUM};312uint32_t RegisterContextPOSIX_x86::g_invalidate_st3_32[] = {313 lldb_st3_i386, lldb_mm3_i386, LLDB_INVALID_REGNUM};314uint32_t RegisterContextPOSIX_x86::g_invalidate_st4_32[] = {315 lldb_st4_i386, lldb_mm4_i386, LLDB_INVALID_REGNUM};316uint32_t RegisterContextPOSIX_x86::g_invalidate_st5_32[] = {317 lldb_st5_i386, lldb_mm5_i386, LLDB_INVALID_REGNUM};318uint32_t RegisterContextPOSIX_x86::g_invalidate_st6_32[] = {319 lldb_st6_i386, lldb_mm6_i386, LLDB_INVALID_REGNUM};320uint32_t RegisterContextPOSIX_x86::g_invalidate_st7_32[] = {321 lldb_st7_i386, lldb_mm7_i386, LLDB_INVALID_REGNUM};322 323uint32_t RegisterContextPOSIX_x86::g_contained_st0_64[] = {lldb_st0_x86_64,324 LLDB_INVALID_REGNUM};325uint32_t RegisterContextPOSIX_x86::g_contained_st1_64[] = {lldb_st1_x86_64,326 LLDB_INVALID_REGNUM};327uint32_t RegisterContextPOSIX_x86::g_contained_st2_64[] = {lldb_st2_x86_64,328 LLDB_INVALID_REGNUM};329uint32_t RegisterContextPOSIX_x86::g_contained_st3_64[] = {lldb_st3_x86_64,330 LLDB_INVALID_REGNUM};331uint32_t RegisterContextPOSIX_x86::g_contained_st4_64[] = {lldb_st4_x86_64,332 LLDB_INVALID_REGNUM};333uint32_t RegisterContextPOSIX_x86::g_contained_st5_64[] = {lldb_st5_x86_64,334 LLDB_INVALID_REGNUM};335uint32_t RegisterContextPOSIX_x86::g_contained_st6_64[] = {lldb_st6_x86_64,336 LLDB_INVALID_REGNUM};337uint32_t RegisterContextPOSIX_x86::g_contained_st7_64[] = {lldb_st7_x86_64,338 LLDB_INVALID_REGNUM};339 340uint32_t RegisterContextPOSIX_x86::g_invalidate_st0_64[] = {341 lldb_st0_x86_64, lldb_mm0_x86_64, LLDB_INVALID_REGNUM};342uint32_t RegisterContextPOSIX_x86::g_invalidate_st1_64[] = {343 lldb_st1_x86_64, lldb_mm1_x86_64, LLDB_INVALID_REGNUM};344uint32_t RegisterContextPOSIX_x86::g_invalidate_st2_64[] = {345 lldb_st2_x86_64, lldb_mm2_x86_64, LLDB_INVALID_REGNUM};346uint32_t RegisterContextPOSIX_x86::g_invalidate_st3_64[] = {347 lldb_st3_x86_64, lldb_mm3_x86_64, LLDB_INVALID_REGNUM};348uint32_t RegisterContextPOSIX_x86::g_invalidate_st4_64[] = {349 lldb_st4_x86_64, lldb_mm4_x86_64, LLDB_INVALID_REGNUM};350uint32_t RegisterContextPOSIX_x86::g_invalidate_st5_64[] = {351 lldb_st5_x86_64, lldb_mm5_x86_64, LLDB_INVALID_REGNUM};352uint32_t RegisterContextPOSIX_x86::g_invalidate_st6_64[] = {353 lldb_st6_x86_64, lldb_mm6_x86_64, LLDB_INVALID_REGNUM};354uint32_t RegisterContextPOSIX_x86::g_invalidate_st7_64[] = {355 lldb_st7_x86_64, lldb_mm7_x86_64, LLDB_INVALID_REGNUM};356 357// Number of register sets provided by this context.358enum { k_num_extended_register_sets = 1, k_num_register_sets = 3 };359 360static const RegisterSet g_reg_sets_i386[k_num_register_sets] = {361 {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,362 g_gpr_regnums_i386},363 {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,364 g_lldb_regnums_i386},365 {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386,366 g_avx_regnums_i386}};367 368static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {369 {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64,370 g_gpr_regnums_x86_64},371 {"Floating Point Registers", "fpu", k_num_fpr_registers_x86_64,372 g_lldb_regnums_x86_64},373 {"Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64,374 g_avx_regnums_x86_64}};375 376bool RegisterContextPOSIX_x86::IsGPR(unsigned reg) {377 return reg <= GetRegInfo().last_gpr; // GPR's come first.378}379 380bool RegisterContextPOSIX_x86::IsFPR(unsigned reg) {381 return (GetRegInfo().first_fpr <= reg && reg <= GetRegInfo().last_fpr);382}383 384bool RegisterContextPOSIX_x86::IsAVX(unsigned reg) {385 return (GetRegInfo().first_ymm <= reg && reg <= GetRegInfo().last_ymm);386}387 388bool RegisterContextPOSIX_x86::IsFPR(unsigned reg, FPRType fpr_type) {389 bool generic_fpr = IsFPR(reg);390 391 if (fpr_type == eXSAVE)392 return generic_fpr || IsAVX(reg);393 return generic_fpr;394}395 396RegisterContextPOSIX_x86::RegisterContextPOSIX_x86(397 Thread &thread, uint32_t concrete_frame_idx,398 RegisterInfoInterface *register_info)399 : RegisterContext(thread, concrete_frame_idx) {400 m_register_info_up.reset(register_info);401 402 ::memset(&m_fpr, 0, sizeof(FPR));403 ::memset(&m_ymm_set, 0, sizeof(YMM));404 405 m_fpr_type = eNotValid;406}407 408RegisterContextPOSIX_x86::~RegisterContextPOSIX_x86() = default;409 410RegisterContextPOSIX_x86::FPRType RegisterContextPOSIX_x86::GetFPRType() {411 if (m_fpr_type == eNotValid) {412 // TODO: Use assembly to call cpuid on the inferior and query ebx or ecx413 m_fpr_type = eXSAVE; // extended floating-point registers, if available414 if (!ReadFPR())415 m_fpr_type = eFXSAVE; // assume generic floating-point registers416 }417 return m_fpr_type;418}419 420void RegisterContextPOSIX_x86::Invalidate() {}421 422void RegisterContextPOSIX_x86::InvalidateAllRegisters() {}423 424unsigned RegisterContextPOSIX_x86::GetRegisterOffset(unsigned reg) {425 assert(reg < GetRegInfo().num_registers && "Invalid register number.");426 return GetRegisterInfo()[reg].byte_offset;427}428 429RegInfo &RegisterContextPOSIX_x86::GetRegInfo() {430 return GetRegInfoShared(431 m_register_info_up->GetTargetArchitecture().GetMachine(),432 /*with_base=*/false);433}434 435unsigned RegisterContextPOSIX_x86::GetRegisterSize(unsigned reg) {436 assert(reg < GetRegInfo().num_registers && "Invalid register number.");437 return GetRegisterInfo()[reg].byte_size;438}439 440size_t RegisterContextPOSIX_x86::GetRegisterCount() {441 size_t num_registers =442 GetRegInfo().num_gpr_registers + GetRegInfo().num_fpr_registers;443 if (GetFPRType() == eXSAVE)444 return num_registers + GetRegInfo().num_avx_registers;445 return num_registers;446}447 448size_t RegisterContextPOSIX_x86::GetGPRSize() {449 return m_register_info_up->GetGPRSize();450}451 452size_t RegisterContextPOSIX_x86::GetFXSAVEOffset() {453 return GetRegisterInfo()[GetRegInfo().first_fpr].byte_offset;454}455 456const RegisterInfo *RegisterContextPOSIX_x86::GetRegisterInfo() {457 // Commonly, this method is overridden and g_register_infos is copied and458 // specialized. So, use GetRegisterInfo() rather than g_register_infos in459 // this scope.460 return m_register_info_up->GetRegisterInfo();461}462 463const RegisterInfo *464RegisterContextPOSIX_x86::GetRegisterInfoAtIndex(size_t reg) {465 if (reg < GetRegInfo().num_registers)466 return &GetRegisterInfo()[reg];467 else468 return nullptr;469}470 471size_t RegisterContextPOSIX_x86::GetRegisterSetCount() {472 size_t sets = 0;473 for (size_t set = 0; set < k_num_register_sets; ++set) {474 if (IsRegisterSetAvailable(set))475 ++sets;476 }477 478 return sets;479}480 481const RegisterSet *RegisterContextPOSIX_x86::GetRegisterSet(size_t set) {482 if (IsRegisterSetAvailable(set)) {483 switch (m_register_info_up->GetTargetArchitecture().GetMachine()) {484 case llvm::Triple::x86:485 return &g_reg_sets_i386[set];486 case llvm::Triple::x86_64:487 return &g_reg_sets_x86_64[set];488 default:489 assert(false && "Unhandled target architecture.");490 return nullptr;491 }492 }493 return nullptr;494}495 496const char *RegisterContextPOSIX_x86::GetRegisterName(unsigned reg) {497 assert(reg < GetRegInfo().num_registers && "Invalid register offset.");498 return GetRegisterInfo()[reg].name;499}500 501// Parse ymm registers and into xmm.bytes and ymmh.bytes.502bool RegisterContextPOSIX_x86::CopyYMMtoXSTATE(uint32_t reg,503 lldb::ByteOrder byte_order) {504 if (!IsAVX(reg))505 return false;506 507 if (byte_order == eByteOrderLittle) {508 uint32_t reg_no = reg - GetRegInfo().first_ymm;509 YMMToXState(m_ymm_set.ymm[reg_no], m_fpr.fxsave.xmm[reg_no].bytes,510 m_fpr.xsave.ymmh[reg_no].bytes);511 return true;512 }513 514 return false; // unsupported or invalid byte order515}516 517// Concatenate xmm.bytes with ymmh.bytes518bool RegisterContextPOSIX_x86::CopyXSTATEtoYMM(uint32_t reg,519 lldb::ByteOrder byte_order) {520 if (!IsAVX(reg))521 return false;522 523 if (byte_order == eByteOrderLittle) {524 uint32_t reg_no = reg - GetRegInfo().first_ymm;525 m_ymm_set.ymm[reg_no] = XStateToYMM(m_fpr.fxsave.xmm[reg_no].bytes,526 m_fpr.xsave.ymmh[reg_no].bytes);527 return true;528 }529 530 return false; // unsupported or invalid byte order531}532 533bool RegisterContextPOSIX_x86::IsRegisterSetAvailable(size_t set_index) {534 // Note: Extended register sets are assumed to be at the end of g_reg_sets...535 size_t num_sets = k_num_register_sets - k_num_extended_register_sets;536 537 if (GetFPRType() == eXSAVE) // ...and to start with AVX registers.538 ++num_sets;539 return (set_index < num_sets);540}541