diff options
Diffstat (limited to 'gdb/amd64-linux-tdep.c')
-rw-r--r-- | gdb/amd64-linux-tdep.c | 146 |
1 files changed, 69 insertions, 77 deletions
diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c index 4ef0f78..87f09a4 100644 --- a/gdb/amd64-linux-tdep.c +++ b/gdb/amd64-linux-tdep.c @@ -39,17 +39,8 @@ #include "solib-svr4.h" #include "xml-syscall.h" #include "glibc-tdep.h" - -#include "features/i386/amd64-linux.c" -#include "features/i386/amd64-avx-linux.c" -#include "features/i386/amd64-mpx-linux.c" -#include "features/i386/amd64-avx-mpx-linux.c" -#include "features/i386/amd64-avx-avx512-linux.c" -#include "features/i386/amd64-avx-mpx-avx512-pku-linux.c" - -#include "features/i386/x32-linux.c" -#include "features/i386/x32-avx-linux.c" -#include "features/i386/x32-avx-avx512-linux.c" +#include "arch/amd64.h" +#include "target-descriptions.h" /* The syscall's XML filename for i386. */ #define XML_SYSCALL_FILENAME_AMD64 "syscalls/amd64-linux.xml" @@ -1575,6 +1566,34 @@ amd64_linux_record_signal (struct gdbarch *gdbarch, return 0; } +const target_desc * +amd64_linux_read_description (uint64_t xcr0_features_bit, bool is_x32) +{ + static target_desc *amd64_linux_tdescs \ + [2/*AVX*/][2/*MPX*/][2/*AVX512*/][2/*PKRU*/] = {}; + static target_desc *x32_linux_tdescs[2/*AVX*/][2/*AVX512*/] = {}; + + target_desc **tdesc; + + if (is_x32) + { + tdesc = &x32_linux_tdescs[(xcr0_features_bit & X86_XSTATE_AVX) ? 1 : 0 ] + [(xcr0_features_bit & X86_XSTATE_AVX512) ? 1 : 0]; + } + else + { + tdesc = &amd64_linux_tdescs[(xcr0_features_bit & X86_XSTATE_AVX) ? 1 : 0] + [(xcr0_features_bit & X86_XSTATE_MPX) ? 1 : 0] + [(xcr0_features_bit & X86_XSTATE_AVX512) ? 1 : 0] + [(xcr0_features_bit & X86_XSTATE_PKRU) ? 1 : 0]; + } + + if (*tdesc == NULL) + *tdesc = amd64_create_target_description (xcr0_features_bit, is_x32, true); + + return *tdesc; +} + /* Get Linux/x86 target description from core dump. */ static const struct target_desc * @@ -1585,42 +1604,8 @@ amd64_linux_core_read_description (struct gdbarch *gdbarch, /* Linux/x86-64. */ uint64_t xcr0 = i386_linux_core_read_xcr0 (abfd); - switch (xcr0 & X86_XSTATE_ALL_MASK) - { - case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK: - if (gdbarch_ptr_bit (gdbarch) == 32) - /* No MPX on x32, fallback to AVX-AVX512. */ - return tdesc_x32_avx_avx512_linux; - else - return tdesc_amd64_avx_mpx_avx512_pku_linux; - case X86_XSTATE_AVX_AVX512_MASK: - if (gdbarch_ptr_bit (gdbarch) == 32) - return tdesc_x32_avx_avx512_linux; - else - return tdesc_amd64_avx_avx512_linux; - case X86_XSTATE_MPX_MASK: - if (gdbarch_ptr_bit (gdbarch) == 32) - /* No MPX on x32, fallback to AVX-AVX512. */ - return tdesc_x32_avx_linux; - else - return tdesc_amd64_mpx_linux; - case X86_XSTATE_AVX_MPX_MASK: - if (gdbarch_ptr_bit (gdbarch) == 32) - /* No MPX on x32, fallback to AVX-AVX512. */ - return tdesc_x32_avx_linux; - else - return tdesc_amd64_avx_mpx_linux; - case X86_XSTATE_AVX_MASK: - if (gdbarch_ptr_bit (gdbarch) == 32) - return tdesc_x32_avx_linux; - else - return tdesc_amd64_avx_linux; - default: - if (gdbarch_ptr_bit (gdbarch) == 32) - return tdesc_x32_linux; - else - return tdesc_amd64_linux; - } + return amd64_linux_read_description (xcr0 & X86_XSTATE_ALL_MASK, + gdbarch_ptr_bit (gdbarch) == 32); } /* Similar to amd64_supply_fpregset, but use XSAVE extended state. */ @@ -1863,9 +1848,7 @@ static void amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - const struct target_desc *tdesc = info.target_desc; - struct tdesc_arch_data *tdesc_data - = (struct tdesc_arch_data *) info.tdep_info; + struct tdesc_arch_data *tdesc_data = info.tdesc_data; const struct tdesc_feature *feature; int valid_p; @@ -1875,15 +1858,14 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) tdep->gregset_num_regs = ARRAY_SIZE (amd64_linux_gregset_reg_offset); tdep->sizeof_gregset = 27 * 8; - amd64_init_abi (info, gdbarch); + amd64_init_abi (info, gdbarch, + amd64_linux_read_description (X86_XSTATE_SSE_MASK, false)); + + const target_desc *tdesc = tdep->tdesc; /* Reserve a number for orig_rax. */ set_gdbarch_num_regs (gdbarch, AMD64_LINUX_NUM_REGS); - if (! tdesc_has_registers (tdesc)) - tdesc = tdesc_amd64_linux; - tdep->tdesc = tdesc; - feature = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.linux"); if (feature == NULL) return; @@ -2080,9 +2062,7 @@ static void amd64_x32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - const struct target_desc *tdesc = info.target_desc; - struct tdesc_arch_data *tdesc_data - = (struct tdesc_arch_data *) info.tdep_info; + struct tdesc_arch_data *tdesc_data = info.tdesc_data; const struct tdesc_feature *feature; int valid_p; @@ -2092,14 +2072,14 @@ amd64_x32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) tdep->gregset_num_regs = ARRAY_SIZE (amd64_linux_gregset_reg_offset); tdep->sizeof_gregset = 27 * 8; - amd64_x32_init_abi (info, gdbarch); + amd64_x32_init_abi (info, gdbarch, + amd64_linux_read_description (X86_XSTATE_SSE_MASK, + true)); /* Reserve a number for orig_rax. */ set_gdbarch_num_regs (gdbarch, AMD64_LINUX_NUM_REGS); - if (! tdesc_has_registers (tdesc)) - tdesc = tdesc_x32_linux; - tdep->tdesc = tdesc; + const target_desc *tdesc = tdep->tdesc; feature = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.linux"); if (feature == NULL) @@ -2285,10 +2265,6 @@ amd64_x32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_solib_svr4_fetch_link_map_offsets (gdbarch, svr4_ilp32_fetch_link_map_offsets); } - - -/* Provide a prototype to silence -Wmissing-prototypes. */ -extern void _initialize_amd64_linux_tdep (void); void _initialize_amd64_linux_tdep (void) @@ -2298,15 +2274,31 @@ _initialize_amd64_linux_tdep (void) gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x64_32, GDB_OSABI_LINUX, amd64_x32_linux_init_abi); - /* Initialize the Linux target description. */ - initialize_tdesc_amd64_linux (); - initialize_tdesc_amd64_avx_linux (); - initialize_tdesc_amd64_mpx_linux (); - initialize_tdesc_amd64_avx_mpx_linux (); - initialize_tdesc_amd64_avx_avx512_linux (); - initialize_tdesc_amd64_avx_mpx_avx512_pku_linux (); - - initialize_tdesc_x32_linux (); - initialize_tdesc_x32_avx_linux (); - initialize_tdesc_x32_avx_avx512_linux (); +#if GDB_SELF_TEST + struct + { + const char *xml; + uint64_t mask; + } xml_masks[] = { + { "i386/amd64-linux.xml", X86_XSTATE_SSE_MASK }, + { "i386/amd64-avx-linux.xml", X86_XSTATE_AVX_MASK }, + { "i386/amd64-mpx-linux.xml", X86_XSTATE_MPX_MASK }, + { "i386/amd64-avx-mpx-linux.xml", X86_XSTATE_AVX_MPX_MASK }, + { "i386/amd64-avx-avx512-linux.xml", X86_XSTATE_AVX_AVX512_MASK }, + { "i386/amd64-avx-mpx-avx512-pku-linux.xml", + X86_XSTATE_AVX_MPX_AVX512_PKU_MASK }, + { "i386/x32-linux.xml", X86_XSTATE_SSE_MASK }, + { "i386/x32-avx-linux.xml", X86_XSTATE_AVX_MASK }, + { "i386/x32-avx-avx512-linux.xml", X86_XSTATE_AVX_AVX512_MASK }, + }; + + for (auto &a : xml_masks) + { + auto tdesc = amd64_linux_read_description (a.mask, + startswith (a.xml, + "i386/x32")); + + selftests::record_xml_tdesc (a.xml, tdesc); + } +#endif /* GDB_SELF_TEST */ } |