diff options
Diffstat (limited to 'devel/gdb/files/commit-97de354')
-rw-r--r-- | devel/gdb/files/commit-97de354 | 690 |
1 files changed, 690 insertions, 0 deletions
diff --git a/devel/gdb/files/commit-97de354 b/devel/gdb/files/commit-97de354 new file mode 100644 index 000000000000..5709edb1da9e --- /dev/null +++ b/devel/gdb/files/commit-97de354 @@ -0,0 +1,690 @@ +diff --git bfd/elf.c bfd/elf.c +index a031b9e..41fb023 100644 +--- bfd/elf.c ++++ bfd/elf.c +@@ -8737,6 +8737,9 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note) + if (note->namesz == 6 + && strcmp (note->namedata, "LINUX") == 0) + return elfcore_grok_xstatereg (abfd, note); ++ else if (note->namesz == 8 ++ && strcmp (note->namedata, "FreeBSD") == 0) ++ return elfcore_grok_xstatereg (abfd, note); + else + return TRUE; + +@@ -9556,7 +9559,11 @@ char * + elfcore_write_xstatereg (bfd *abfd, char *buf, int *bufsiz, + const void *xfpregs, int size) + { +- char *note_name = "LINUX"; ++ char *note_name; ++ if (get_elf_backend_data (abfd)->elf_osabi == ELFOSABI_FREEBSD) ++ note_name = "FreeBSD"; ++ else ++ note_name = "LINUX"; + return elfcore_write_note (abfd, buf, bufsiz, + note_name, NT_X86_XSTATE, xfpregs, size); + } +diff --git gdb/amd64-tdep.c gdb/amd64-tdep.c +index 3e5d1bd..461b701 100644 +--- gdb/amd64-tdep.c ++++ gdb/amd64-tdep.c +@@ -39,6 +39,7 @@ + #include "disasm.h" + #include "amd64-tdep.h" + #include "i387-tdep.h" ++#include "x86-xstate.h" + + #include "features/i386/amd64.c" + #include "features/i386/amd64-avx.c" +@@ -3118,6 +3119,25 @@ amd64_x32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) + set_gdbarch_ptr_bit (gdbarch, 32); + } + ++/* Return the target description for a specified XSAVE feature mask. */ ++ ++const struct target_desc * ++amd64_target_description (uint64_t xcr0) ++{ ++ switch (xcr0 & X86_XSTATE_ALL_MASK) ++ { ++ case X86_XSTATE_MPX_AVX512_MASK: ++ case X86_XSTATE_AVX512_MASK: ++ return tdesc_amd64_avx512; ++ case X86_XSTATE_MPX_MASK: ++ return tdesc_amd64_mpx; ++ case X86_XSTATE_AVX_MASK: ++ return tdesc_amd64_avx; ++ default: ++ return tdesc_amd64; ++ } ++} ++ + /* Provide a prototype to silence -Wmissing-prototypes. */ + void _initialize_amd64_tdep (void); + +diff --git gdb/amd64-tdep.h gdb/amd64-tdep.h +index 318fd43..704225e 100644 +--- gdb/amd64-tdep.h ++++ gdb/amd64-tdep.h +@@ -84,6 +84,8 @@ enum amd64_regnum + + #define AMD64_NUM_REGS (AMD64_ZMM31H_REGNUM + 1) + ++extern struct target_desc *tdesc_amd64; ++ + extern struct displaced_step_closure *amd64_displaced_step_copy_insn + (struct gdbarch *gdbarch, CORE_ADDR from, CORE_ADDR to, + struct regcache *regs); +@@ -95,6 +97,7 @@ extern void amd64_displaced_step_fixup (struct gdbarch *gdbarch, + extern void amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch); + extern void amd64_x32_init_abi (struct gdbarch_info info, + struct gdbarch *gdbarch); ++extern const struct target_desc *amd64_target_description (uint64_t xcr0); + + /* Fill register REGNUM in REGCACHE with the appropriate + floating-point or SSE register value from *FXSAVE. If REGNUM is +diff --git gdb/amd64bsd-nat.c gdb/amd64bsd-nat.c +index 31060a123..66d4289 100644 +--- gdb/amd64bsd-nat.c ++++ gdb/amd64bsd-nat.c +@@ -35,6 +35,10 @@ + #include "inf-ptrace.h" + + ++#ifdef PT_GETXSTATE_INFO ++size_t amd64bsd_xsave_len; ++#endif ++ + /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this + for all registers (including the floating-point registers). */ + +@@ -60,6 +64,20 @@ amd64bsd_fetch_inferior_registers (struct target_ops *ops, + if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum)) + { + struct fpreg fpregs; ++#ifdef PT_GETXSTATE_INFO ++ char *xstateregs; ++ ++ if (amd64bsd_xsave_len != 0) ++ { ++ xstateregs = alloca (amd64bsd_xsave_len); ++ if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid), ++ (PTRACE_TYPE_ARG3) xstateregs, 0) == -1) ++ perror_with_name (_("Couldn't get extended state status")); ++ ++ amd64_supply_xsave (regcache, -1, xstateregs); ++ return; ++ } ++#endif + + if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), + (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) +@@ -99,6 +117,24 @@ amd64bsd_store_inferior_registers (struct target_ops *ops, + if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum)) + { + struct fpreg fpregs; ++#ifdef PT_GETXSTATE_INFO ++ char *xstateregs; ++ ++ if (amd64bsd_xsave_len != 0) ++ { ++ xstateregs = alloca (amd64bsd_xsave_len); ++ if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid), ++ (PTRACE_TYPE_ARG3) xstateregs, 0) == -1) ++ perror_with_name (_("Couldn't get extended state status")); ++ ++ amd64_collect_xsave (regcache, regnum, xstateregs, 0); ++ ++ if (ptrace (PT_SETXSTATE, ptid_get_pid (inferior_ptid), ++ (PTRACE_TYPE_ARG3) xstateregs, amd64bsd_xsave_len) == -1) ++ perror_with_name (_("Couldn't write extended state status")); ++ return; ++ } ++#endif + + if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), + (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) +diff --git gdb/amd64bsd-nat.h gdb/amd64bsd-nat.h +index 167eb56..09776ee 100644 +--- gdb/amd64bsd-nat.h ++++ gdb/amd64bsd-nat.h +@@ -20,6 +20,9 @@ + #ifndef AMD64BSD_NAT_H + #define AMD64BSD_NAT_H + ++/* Low level amd64 XSAVE info. */ ++extern size_t amd64bsd_xsave_len; ++ + /* Low level amd64 debug register functions. */ + + extern void amd64bsd_dr_set_control (unsigned long control); +diff --git gdb/amd64fbsd-nat.c gdb/amd64fbsd-nat.c +index b1b261c..a721f48 100644 +--- gdb/amd64fbsd-nat.c ++++ gdb/amd64fbsd-nat.c +@@ -151,6 +151,50 @@ amd64fbsd_mourn_inferior (struct target_ops *ops) + super_mourn_inferior (ops); + } + ++/* Implement the to_read_description method. */ ++ ++static const struct target_desc * ++amd64fbsd_read_description (struct target_ops *ops) ++{ ++#ifdef PT_GETXSTATE_INFO ++ static int xsave_probed; ++ static uint64_t xcr0; ++#endif ++ struct reg regs; ++ int is64; ++ ++ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), ++ (PTRACE_TYPE_ARG3) ®s, 0) == -1) ++ perror_with_name (_("Couldn't get registers")); ++ is64 = (regs.r_cs == GSEL (GUCODE_SEL, SEL_UPL)); ++#ifdef PT_GETXSTATE_INFO ++ if (!xsave_probed) ++ { ++ struct ptrace_xstate_info info; ++ ++ if (ptrace (PT_GETXSTATE_INFO, ptid_get_pid (inferior_ptid), ++ (PTRACE_TYPE_ARG3) &info, sizeof (info)) == 0) ++ { ++ amd64bsd_xsave_len = info.xsave_len; ++ xcr0 = info.xsave_mask; ++ } ++ xsave_probed = 1; ++ } ++ ++ if (amd64bsd_xsave_len != 0) ++ { ++ if (is64) ++ return amd64_target_description (xcr0); ++ else ++ return i386_target_description (xcr0); ++ } ++#endif ++ if (is64) ++ return tdesc_amd64; ++ else ++ return tdesc_i386; ++} ++ + /* Provide a prototype to silence -Wmissing-prototypes. */ + void _initialize_amd64fbsd_nat (void); + +@@ -181,6 +225,7 @@ _initialize_amd64fbsd_nat (void) + + super_mourn_inferior = t->to_mourn_inferior; + t->to_mourn_inferior = amd64fbsd_mourn_inferior; ++ t->to_read_description = amd64fbsd_read_description; + + t->to_pid_to_exec_file = fbsd_pid_to_exec_file; + t->to_find_memory_regions = fbsd_find_memory_regions; +diff --git gdb/amd64fbsd-tdep.c gdb/amd64fbsd-tdep.c +index 62dcb83..52705d9 100644 +--- gdb/amd64fbsd-tdep.c ++++ gdb/amd64fbsd-tdep.c +@@ -23,6 +23,9 @@ + #include "gdbcore.h" + #include "regcache.h" + #include "osabi.h" ++#include "regset.h" ++#include "i386fbsd-tdep.h" ++#include "x86-xstate.h" + + #include "amd64-tdep.h" + #include "bsd-uthread.h" +@@ -169,6 +172,59 @@ static int amd64fbsd_jmp_buf_reg_offset[] = + 0 * 8 /* %rip */ + }; + ++/* Implement the core_read_description gdbarch method. */ ++ ++static const struct target_desc * ++amd64fbsd_core_read_description (struct gdbarch *gdbarch, ++ struct target_ops *target, ++ bfd *abfd) ++{ ++ return amd64_target_description (i386fbsd_core_read_xcr0 (abfd)); ++} ++ ++/* Similar to amd64_supply_fpregset, but use XSAVE extended state. */ ++ ++static void ++amd64fbsd_supply_xstateregset (const struct regset *regset, ++ struct regcache *regcache, int regnum, ++ const void *xstateregs, size_t len) ++{ ++ amd64_supply_xsave (regcache, regnum, xstateregs); ++} ++ ++/* Similar to amd64_collect_fpregset, but use XSAVE extended state. */ ++ ++static void ++amd64fbsd_collect_xstateregset (const struct regset *regset, ++ const struct regcache *regcache, ++ int regnum, void *xstateregs, size_t len) ++{ ++ amd64_collect_xsave (regcache, regnum, xstateregs, 1); ++} ++ ++static const struct regset amd64fbsd_xstateregset = ++ { ++ NULL, ++ amd64fbsd_supply_xstateregset, ++ amd64fbsd_collect_xstateregset ++ }; ++ ++/* Iterate over core file register note sections. */ ++ ++static void ++amd64fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch, ++ iterate_over_regset_sections_cb *cb, ++ void *cb_data, ++ const struct regcache *regcache) ++{ ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ ++ cb (".reg", tdep->sizeof_gregset, &i386_gregset, NULL, cb_data); ++ cb (".reg2", tdep->sizeof_fpregset, &amd64_fpregset, NULL, cb_data); ++ cb (".reg-xstate", X86_XSTATE_SIZE(tdep->xcr0), ++ &amd64fbsd_xstateregset, "XSAVE extended state", cb_data); ++} ++ + static void + amd64fbsd_supply_uthread (struct regcache *regcache, + int regnum, CORE_ADDR addr) +@@ -233,6 +289,15 @@ amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) + tdep->sc_reg_offset = amd64fbsd_sc_reg_offset; + tdep->sc_num_regs = ARRAY_SIZE (amd64fbsd_sc_reg_offset); + ++ tdep->xsave_xcr0_offset = I386_FBSD_XSAVE_XCR0_OFFSET; ++ ++ /* Iterate over core file register note sections. */ ++ set_gdbarch_iterate_over_regset_sections ++ (gdbarch, amd64fbsd_iterate_over_regset_sections); ++ ++ set_gdbarch_core_read_description (gdbarch, ++ amd64fbsd_core_read_description); ++ + /* FreeBSD provides a user-level threads implementation. */ + bsd_uthread_set_supply_uthread (gdbarch, amd64fbsd_supply_uthread); + bsd_uthread_set_collect_uthread (gdbarch, amd64fbsd_collect_uthread); +diff --git gdb/i386-tdep.c gdb/i386-tdep.c +index 4d97915..0c7eb5a 100644 +--- gdb/i386-tdep.c ++++ gdb/i386-tdep.c +@@ -8598,6 +8598,25 @@ i386_coff_osabi_sniffer (bfd *abfd) + } + + ++/* Return the target description for a specified XSAVE feature mask. */ ++ ++const struct target_desc * ++i386_target_description (uint64_t xcr0) ++{ ++ switch (xcr0 & X86_XSTATE_ALL_MASK) ++ { ++ case X86_XSTATE_MPX_AVX512_MASK: ++ case X86_XSTATE_AVX512_MASK: ++ return tdesc_i386_avx512; ++ case X86_XSTATE_MPX_MASK: ++ return tdesc_i386_mpx; ++ case X86_XSTATE_AVX_MASK: ++ return tdesc_i386_avx; ++ default: ++ return tdesc_i386; ++ } ++} ++ + /* Provide a prototype to silence -Wmissing-prototypes. */ + void _initialize_i386_tdep (void); + +diff --git gdb/i386-tdep.h gdb/i386-tdep.h +index 8bfd412..7880f6c 100644 +--- gdb/i386-tdep.h ++++ gdb/i386-tdep.h +@@ -328,6 +328,8 @@ enum record_i386_regnum + /* Size of the largest register. */ + #define I386_MAX_REGISTER_SIZE 64 + ++extern struct target_desc *tdesc_i386; ++ + /* Types for i386-specific registers. */ + extern struct type *i387_ext_type (struct gdbarch *gdbarch); + +@@ -416,6 +418,7 @@ extern void i386_svr4_init_abi (struct gdbarch_info, struct gdbarch *); + + extern int i386_process_record (struct gdbarch *gdbarch, + struct regcache *regcache, CORE_ADDR addr); ++extern const struct target_desc *i386_target_description (uint64_t xcr0); + + + +diff --git gdb/i386bsd-nat.c gdb/i386bsd-nat.c +index 16e0707..ac8a19b 100644 +--- gdb/i386bsd-nat.c ++++ gdb/i386bsd-nat.c +@@ -81,6 +81,10 @@ static int i386bsd_r_reg_offset[] = + so that we try PT_GETXMMREGS the first time around. */ + static int have_ptrace_xmmregs = -1; + #endif ++ ++#ifdef PT_GETXSTATE_INFO ++size_t i386bsd_xsave_len; ++#endif + + + /* Supply the general-purpose registers in GREGS, to REGCACHE. */ +@@ -148,7 +152,24 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops, + struct fpreg fpregs; + #ifdef HAVE_PT_GETXMMREGS + char xmmregs[512]; ++#endif ++ ++#ifdef PT_GETXSTATE_INFO ++ if (i386bsd_xsave_len != 0) ++ { ++ char *xstateregs; ++ ++ xstateregs = alloca (i386bsd_xsave_len); ++ if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid), ++ (PTRACE_TYPE_ARG3) xstateregs, 0) == -1) ++ perror_with_name (_("Couldn't get extended state status")); + ++ i387_supply_xsave (regcache, -1, xstateregs); ++ return; ++ } ++#endif ++ ++#ifdef HAVE_PT_GETXMMREGS + if (have_ptrace_xmmregs != 0 + && ptrace(PT_GETXMMREGS, ptid_get_pid (inferior_ptid), + (PTRACE_TYPE_ARG3) xmmregs, 0) == 0) +@@ -158,18 +179,15 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops, + } + else + { ++ have_ptrace_xmmregs = 0; ++#endif + if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), + (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) + perror_with_name (_("Couldn't get floating point status")); + + i387_supply_fsave (regcache, -1, &fpregs); ++#ifdef HAVE_PT_GETXMMREGS + } +-#else +- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), +- (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) +- perror_with_name (_("Couldn't get floating point status")); +- +- i387_supply_fsave (regcache, -1, &fpregs); + #endif + } + } +@@ -204,7 +222,28 @@ i386bsd_store_inferior_registers (struct target_ops *ops, + struct fpreg fpregs; + #ifdef HAVE_PT_GETXMMREGS + char xmmregs[512]; ++#endif ++ ++#ifdef PT_GETXSTATE_INFO ++ if (i386bsd_xsave_len != 0) ++ { ++ char *xstateregs; ++ ++ xstateregs = alloca (i386bsd_xsave_len); ++ if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid), ++ (PTRACE_TYPE_ARG3) xstateregs, 0) == -1) ++ perror_with_name (_("Couldn't get extended state status")); + ++ i387_collect_xsave (regcache, -1, xstateregs, 0); ++ ++ if (ptrace (PT_SETXSTATE, ptid_get_pid (inferior_ptid), ++ (PTRACE_TYPE_ARG3) xstateregs, i386bsd_xsave_len) == -1) ++ perror_with_name (_("Couldn't write extended state status")); ++ return; ++ } ++#endif ++ ++#ifdef HAVE_PT_GETXMMREGS + if (have_ptrace_xmmregs != 0 + && ptrace(PT_GETXMMREGS, ptid_get_pid (inferior_ptid), + (PTRACE_TYPE_ARG3) xmmregs, 0) == 0) +diff --git gdb/i386bsd-nat.h gdb/i386bsd-nat.h +index a11f554..2f50c32 100644 +--- gdb/i386bsd-nat.h ++++ gdb/i386bsd-nat.h +@@ -25,6 +25,9 @@ + + extern struct target_ops *i386bsd_target (void); + ++/* Low level i386 XSAVE info. */ ++extern size_t i386bsd_xsave_len; ++ + /* low level i386 debug register functions used in i386fbsd-nat.c. */ + + extern void i386bsd_dr_set_control (unsigned long control); +diff --git gdb/i386fbsd-nat.c gdb/i386fbsd-nat.c +index ad439e3..6c43f2c 100644 +--- gdb/i386fbsd-nat.c ++++ gdb/i386fbsd-nat.c +@@ -116,6 +116,37 @@ i386fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) + } + + ++#ifdef PT_GETXSTATE_INFO ++/* Implement the to_read_description method. */ ++ ++static const struct target_desc * ++i386fbsd_read_description (struct target_ops *ops) ++{ ++ static int xsave_probed; ++ static uint64_t xcr0; ++ ++ if (!xsave_probed) ++ { ++ struct ptrace_xstate_info info; ++ ++ if (ptrace (PT_GETXSTATE_INFO, ptid_get_pid (inferior_ptid), ++ (PTRACE_TYPE_ARG3) &info, sizeof (info)) == 0) ++ { ++ i386bsd_xsave_len = info.xsave_len; ++ xcr0 = info.xsave_mask; ++ } ++ xsave_probed = 1; ++ } ++ ++ if (i386bsd_xsave_len != 0) ++ { ++ return i386_target_description (xcr0); ++ } ++ else ++ return tdesc_i386; ++} ++#endif ++ + /* Prevent warning from -Wmissing-prototypes. */ + void _initialize_i386fbsd_nat (void); + +@@ -140,6 +171,9 @@ _initialize_i386fbsd_nat (void) + + #endif /* HAVE_PT_GETDBREGS */ + ++#ifdef PT_GETXSTATE_INFO ++ t->to_read_description = i386fbsd_read_description; ++#endif + + t->to_resume = i386fbsd_resume; + t->to_pid_to_exec_file = fbsd_pid_to_exec_file; +diff --git gdb/i386fbsd-tdep.c gdb/i386fbsd-tdep.c +index ed41706..99e08cb 100644 +--- gdb/i386fbsd-tdep.c ++++ gdb/i386fbsd-tdep.c +@@ -22,6 +22,9 @@ + #include "gdbcore.h" + #include "osabi.h" + #include "regcache.h" ++#include "regset.h" ++#include "i386fbsd-tdep.h" ++#include "x86-xstate.h" + + #include "i386-tdep.h" + #include "i387-tdep.h" +@@ -235,6 +238,100 @@ static int i386fbsd_jmp_buf_reg_offset[] = + 0 * 4 /* %eip */ + }; + ++/* Get XSAVE extended state xcr0 from core dump. */ ++ ++uint64_t ++i386fbsd_core_read_xcr0 (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 < X86_XSTATE_AVX_SIZE) ++ xcr0 = X86_XSTATE_SSE_MASK; ++ else ++ { ++ char contents[8]; ++ ++ if (! bfd_get_section_contents (abfd, xstate, contents, ++ I386_FBSD_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 = 0; ++ ++ return xcr0; ++} ++ ++/* Implement the core_read_description gdbarch method. */ ++ ++static const struct target_desc * ++i386fbsd_core_read_description (struct gdbarch *gdbarch, ++ struct target_ops *target, ++ bfd *abfd) ++{ ++ return i386_target_description (i386fbsd_core_read_xcr0 (abfd)); ++} ++ ++/* Similar to i386_supply_fpregset, but use XSAVE extended state. */ ++ ++static void ++i386fbsd_supply_xstateregset (const struct regset *regset, ++ struct regcache *regcache, int regnum, ++ const void *xstateregs, size_t len) ++{ ++ i387_supply_xsave (regcache, regnum, xstateregs); ++} ++ ++/* Similar to i386_collect_fpregset, but use XSAVE extended state. */ ++ ++static void ++i386fbsd_collect_xstateregset (const struct regset *regset, ++ const struct regcache *regcache, ++ int regnum, void *xstateregs, size_t len) ++{ ++ i387_collect_xsave (regcache, regnum, xstateregs, 1); ++} ++ ++/* Register set definitions. */ ++ ++static const struct regset i386fbsd_xstateregset = ++ { ++ NULL, ++ i386fbsd_supply_xstateregset, ++ i386fbsd_collect_xstateregset ++ }; ++ ++/* Iterate over core file register note sections. */ ++ ++static void ++i386fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch, ++ iterate_over_regset_sections_cb *cb, ++ void *cb_data, ++ const struct regcache *regcache) ++{ ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ ++ cb (".reg", tdep->sizeof_gregset, &i386_gregset, NULL, cb_data); ++ cb (".reg2", tdep->sizeof_fpregset, &i386_fpregset, NULL, cb_data); ++ ++ if (tdep->xcr0 & X86_XSTATE_AVX) ++ cb (".reg-xstate", X86_XSTATE_SIZE(tdep->xcr0), ++ &i386fbsd_xstateregset, "XSAVE extended state", cb_data); ++} ++ + static void + i386fbsd_supply_uthread (struct regcache *regcache, + int regnum, CORE_ADDR addr) +@@ -376,6 +473,15 @@ i386fbsd4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) + /* FreeBSD 4.0 introduced a new `struct sigcontext'. */ + tdep->sc_reg_offset = i386fbsd4_sc_reg_offset; + tdep->sc_num_regs = ARRAY_SIZE (i386fbsd4_sc_reg_offset); ++ ++ tdep->xsave_xcr0_offset = I386_FBSD_XSAVE_XCR0_OFFSET; ++ ++ /* Iterate over core file register note sections. */ ++ set_gdbarch_iterate_over_regset_sections ++ (gdbarch, i386fbsd_iterate_over_regset_sections); ++ ++ set_gdbarch_core_read_description (gdbarch, ++ i386fbsd_core_read_description); + } + + +diff --git gdb/i386fbsd-tdep.h gdb/i386fbsd-tdep.h +new file mode 100644 +index 0000000..8d6f998 +--- /dev/null ++++ gdb/i386fbsd-tdep.h +@@ -0,0 +1,31 @@ ++/* Target-dependent code for FreeBSD x86. ++ ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see <http://www.gnu.org/licenses/>. */ ++ ++#ifndef I386FBSD_TDEP_H ++#define I386FBSD_TDEP_H ++ ++/* Get XSAVE extended state xcr0 from core dump. */ ++extern uint64_t i386fbsd_core_read_xcr0 (bfd *abfd); ++ ++/* The format of the XSAVE extended area is determined by hardware. ++ Cores store the XSAVE extended area in a NT_X86_XSTATE note that ++ matches the layout on Linux. */ ++#define I386_FBSD_XSAVE_XCR0_OFFSET 464 ++ ++#endif /* i386fbsd-tdep.h */ |