diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2010-04-07 18:43:45 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2010-04-07 18:43:45 +0000 |
commit | c131fcee79bd9082762a1699a657949771fa245f (patch) | |
tree | 3b3f41a8026f682bd2c2f04477fd8f66ce2b6545 /gdb/i386-linux-tdep.c | |
parent | 98adf0f383f6c4087ff347b207e4aad8a139994b (diff) | |
download | gdb-c131fcee79bd9082762a1699a657949771fa245f.zip gdb-c131fcee79bd9082762a1699a657949771fa245f.tar.gz gdb-c131fcee79bd9082762a1699a657949771fa245f.tar.bz2 |
Support i386 AVX.
2010-04-07 H.J. Lu <hongjiu.lu@intel.com>
* i386-linux-nat.c: Include "regset.h", "elf/common.h",
<sys/uio.h> and "i386-xstate.h".
(PTRACE_GETREGSET): New.
(PTRACE_SETREGSET): Likewise.
(fetch_xstateregs): Likewise.
(store_xstateregs): Likewise.
(GETXSTATEREGS_SUPPLIES): Likewise.
(regmap): Include 8 upper YMM registers.
(i386_linux_fetch_inferior_registers): Support XSAVE extended
state.
(i386_linux_store_inferior_registers): Likewise.
(i386_linux_read_description): Check and enable AVX target
descriptions.
* i386-linux-tdep.c: Include "regset.h", "i387-tdep.h",
"i386-xstate.h" and "features/i386/i386-avx-linux.c".
(i386_linux_regset_sections): Add ".reg-xstate".
(i386_linux_gregset_reg_offset): Include 8 upper YMM registers.
(i386_linux_core_read_xcr0): New.
(i386_linux_core_read_description): Check and enable AVX target
description.
(i386_linux_init_abi): Set xsave_xcr0_offset.
(_initialize_i386_linux_tdep): Call
initialize_tdesc_i386_avx_linux.
* i386-linux-tdep.h (I386_LINUX_ORIG_EAX_REGNUM): Replace
I386_SSE_NUM_REGS with I386_AVX_NUM_REGS.
(i386_linux_core_read_xcr0): New.
(tdesc_i386_avx_linux): Likewise.
(I386_LINUX_XSAVE_XCR0_OFFSET): Likewise.
* i386-tdep.c: Include "i386-xstate.h" and
"features/i386/i386-avx.c".
(i386_ymm_names): New.
(i386_ymmh_names): Likewise.
(i386_ymmh_regnum_p): Likewise.
(i386_ymm_regnum_p): Likewise.
(i386_xmm_regnum_p): Likewise.
(i386_register_name): Likewise.
(i386_ymm_type): Likewise.
(i386_supply_xstateregset): Likewise.
(i386_collect_xstateregset): Likewise.
(i386_sse_regnum_p): Removed.
(i386_pseudo_register_name): Support pseudo YMM registers.
(i386_pseudo_register_type): Likewise.
(i386_pseudo_register_read): Likewise.
(i386_pseudo_register_write): Likewise.
(i386_dbx_reg_to_regnum): Return %ymmN register number for
%xmmN if AVX is available.
(i386_regset_from_core_section): Support .reg-xstate section.
(i386_register_reggroup_p): Supper upper YMM and YMM registers.
(i386_process_record): Replace i386_sse_regnum_p with
i386_xmm_regnum_p.
(i386_validate_tdesc_p): Support org.gnu.gdb.i386.avx feature.
Set ymmh_register_names, num_ymm_regs, ymm0h_regnum and xcr0.
(i386_gdbarch_init): Set xstateregset. Set xsave_xcr0_offset.
Call set_gdbarch_register_name. Replace I386_SSE_NUM_REGS with
I386_AVX_NUM_REGS. Set ymmh_register_names, ymm0h_regnum and
num_ymm_regs. Add num_ymm_regs to set_gdbarch_num_pseudo_regs.
Set ymm0_regnum.
(_initialize_i386_tdep): Call initialize_tdesc_i386_avx.
* i386-tdep.h (gdbarch_tdep): Add xstateregset, ymm0_regnum,
xcr0, xsave_xcr0_offset, ymm0h_regnum, ymmh_register_names and
i386_ymm_type.
(i386_regnum): Add I386_YMM0H_REGNUM, and I386_YMM7H_REGNUM.
(I386_AVX_NUM_REGS): New.
(i386_xmm_regnum_p): Likewise.
(i386_ymm_regnum_p): Likewise.
(i386_ymmh_regnum_p): Likewise.
* common/i386-xstate.h: New.
Diffstat (limited to 'gdb/i386-linux-tdep.c')
-rw-r--r-- | gdb/i386-linux-tdep.c | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c index b23c109..34a1924 100644 --- a/gdb/i386-linux-tdep.c +++ b/gdb/i386-linux-tdep.c @@ -23,6 +23,7 @@ #include "frame.h" #include "value.h" #include "regcache.h" +#include "regset.h" #include "inferior.h" #include "osabi.h" #include "reggroups.h" @@ -36,9 +37,11 @@ #include "solib-svr4.h" #include "symtab.h" #include "arch-utils.h" -#include "regset.h" #include "xml-syscall.h" +#include "i387-tdep.h" +#include "i386-xstate.h" + /* The syscall's XML filename for i386. */ #define XML_SYSCALL_FILENAME_I386 "syscalls/i386-linux.xml" @@ -47,6 +50,7 @@ #include <stdint.h> #include "features/i386/i386-linux.c" +#include "features/i386/i386-avx-linux.c" /* Supported register note sections. */ static struct core_regset_section i386_linux_regset_sections[] = @@ -54,6 +58,7 @@ static struct core_regset_section i386_linux_regset_sections[] = { ".reg", 144, "general-purpose" }, { ".reg2", 108, "floating-point" }, { ".reg-xfp", 512, "extended floating-point" }, + { ".reg-xstate", I386_XSTATE_MAX_SIZE, "XSAVE extended state" }, { NULL, 0 } }; @@ -533,6 +538,7 @@ static int i386_linux_gregset_reg_offset[] = -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 11 * 4 /* "orig_eax" */ }; @@ -560,6 +566,43 @@ static int i386_linux_sc_reg_offset[] = 0 * 4 /* %gs */ }; +/* Get XSAVE extended state xcr0 from core dump. */ + +uint64_t +i386_linux_core_read_xcr0 (struct gdbarch *gdbarch, + struct target_ops *target, bfd *abfd) +{ + asection *xstate = bfd_get_section_by_name (abfd, ".reg-xstate"); + uint64_t xcr0; + + if (xstate) + { + size_t size = bfd_section_size (abfd, xstate); + + /* Check extended state size. */ + if (size < I386_XSTATE_AVX_SIZE) + xcr0 = I386_XSTATE_SSE_MASK; + else + { + char contents[8]; + + if (! bfd_get_section_contents (abfd, xstate, contents, + I386_LINUX_XSAVE_XCR0_OFFSET, + 8)) + { + warning (_("Couldn't read `xcr0' bytes from `.reg-xstate' section in core file.")); + return 0; + } + + xcr0 = bfd_get_64 (abfd, contents); + } + } + else + xcr0 = I386_XSTATE_SSE_MASK; + + return xcr0; +} + /* Get Linux/x86 target description from core dump. */ static const struct target_desc * @@ -568,12 +611,17 @@ i386_linux_core_read_description (struct gdbarch *gdbarch, bfd *abfd) { asection *section = bfd_get_section_by_name (abfd, ".reg2"); + uint64_t xcr0; if (section == NULL) return NULL; /* Linux/i386. */ - return tdesc_i386_linux; + xcr0 = i386_linux_core_read_xcr0 (gdbarch, target, abfd); + if ((xcr0 & I386_XSTATE_AVX_MASK) == I386_XSTATE_AVX_MASK) + return tdesc_i386_avx_linux; + else + return tdesc_i386_linux; } static void @@ -623,6 +671,8 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) tdep->sc_reg_offset = i386_linux_sc_reg_offset; tdep->sc_num_regs = ARRAY_SIZE (i386_linux_sc_reg_offset); + tdep->xsave_xcr0_offset = I386_LINUX_XSAVE_XCR0_OFFSET; + set_gdbarch_process_record (gdbarch, i386_process_record); set_gdbarch_process_record_signal (gdbarch, i386_linux_record_signal); @@ -840,4 +890,5 @@ _initialize_i386_linux_tdep (void) /* Initialize the Linux target description */ initialize_tdesc_i386_linux (); + initialize_tdesc_i386_avx_linux (); } |