diff --git a/bfd/elf.c b/bfd/elf.c
index 13d4272..0be2564 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -8670,6 +8670,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;
 
@@ -9490,6 +9493,8 @@ elfcore_write_xstatereg (bfd *abfd, char *buf, int *bufsiz,
 			 const void *xfpregs, int size)
 {
   char *note_name = "LINUX";
+  if (get_elf_backend_data (abfd)->elf_osabi == ELFOSABI_FREEBSD)
+      note_name = "FreeBSD";
   return elfcore_write_note (abfd, buf, bufsiz,
 			     note_name, NT_X86_XSTATE, xfpregs, size);
 }
diff --git a/gdb/amd64-tdep.h b/gdb/amd64-tdep.h
index 318fd43..4fbb38e 100644
--- a/gdb/amd64-tdep.h
+++ b/gdb/amd64-tdep.h
@@ -84,6 +84,11 @@ enum amd64_regnum
 
 #define AMD64_NUM_REGS		(AMD64_ZMM31H_REGNUM + 1)
 
+extern struct target_desc *tdesc_amd64;
+extern struct target_desc *tdesc_amd64_avx;
+extern struct target_desc *tdesc_amd64_mpx;
+extern struct target_desc *tdesc_amd64_avx512;
+
 extern struct displaced_step_closure *amd64_displaced_step_copy_insn
   (struct gdbarch *gdbarch, CORE_ADDR from, CORE_ADDR to,
    struct regcache *regs);
diff --git a/gdb/amd64bsd-nat.c b/gdb/amd64bsd-nat.c
index 31060a123..d489dda 100644
--- a/gdb/amd64bsd-nat.c
+++ b/gdb/amd64bsd-nat.c
@@ -35,6 +35,10 @@
 #include "inf-ptrace.h"
 
 
+#ifdef PT_GETXSTATE_INFO
+size_t x86_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 (x86_xsave_len != 0)
+	{
+	  xstateregs = alloca (x86_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 (x86_xsave_len != 0)
+	{
+	  xstateregs = alloca (x86_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, x86_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 a/gdb/amd64bsd-nat.h b/gdb/amd64bsd-nat.h
index 167eb56..77bd5f3 100644
--- a/gdb/amd64bsd-nat.h
+++ b/gdb/amd64bsd-nat.h
@@ -20,6 +20,9 @@
 #ifndef AMD64BSD_NAT_H
 #define AMD64BSD_NAT_H
 
+/* Low level amd64 XSAVE info. */
+extern size_t x86_xsave_len;
+
 /* Low level amd64 debug register functions.  */
 
 extern void amd64bsd_dr_set_control (unsigned long control);
diff --git a/gdb/amd64fbsd-nat.c b/gdb/amd64fbsd-nat.c
index b1b261c..639191d 100644
--- a/gdb/amd64fbsd-nat.c
+++ b/gdb/amd64fbsd-nat.c
@@ -34,6 +34,7 @@
 #include "amd64-nat.h"
 #include "amd64bsd-nat.h"
 #include "x86-nat.h"
+#include "x86-xstate.h"
 
 
 /* Offset in `struct reg' where MEMBER is stored.  */
@@ -151,6 +152,68 @@ amd64fbsd_mourn_inferior (struct target_ops *ops)
   super_mourn_inferior (ops);
 }
 
+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) &regs, 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)
+	{
+	  x86_xsave_len = info.xsave_len;
+	  xcr0 = info.xsave_mask;
+	}
+      xsave_probed = 1;
+    }
+
+  if (x86_xsave_len != 0)
+    {
+      switch (xcr0 & X86_XSTATE_ALL_MASK)
+	{
+	case X86_XSTATE_MPX_AVX512_MASK:
+	case X86_XSTATE_AVX512_MASK:
+	  if (is64)
+	    return tdesc_amd64_avx512;
+	  else
+	    return tdesc_i386_avx512;
+	case X86_XSTATE_MPX_MASK:
+	  if (is64)
+	    return tdesc_amd64_mpx;
+	  else
+	    return tdesc_i386_mpx;
+	case X86_XSTATE_AVX_MASK:
+	  if (is64)
+	    return tdesc_amd64_avx;
+	  else
+	    return tdesc_i386_avx;
+	default:
+	  if (is64)
+	    return tdesc_amd64;
+	  else
+	    return tdesc_i386;
+	}
+    }
+#endif
+  if (is64)
+    return tdesc_amd64;
+  else
+    return tdesc_i386;
+}
+
 /* Provide a prototype to silence -Wmissing-prototypes.  */
 void _initialize_amd64fbsd_nat (void);
 
@@ -181,6 +244,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 a/gdb/amd64fbsd-tdep.c b/gdb/amd64fbsd-tdep.c
index 62dcb83..cb097d3 100644
--- a/gdb/amd64fbsd-tdep.c
+++ b/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,71 @@ static int amd64fbsd_jmp_buf_reg_offset[] =
   0 * 8				/* %rip */
 };
 
+static const struct target_desc *
+amd64fbsd_core_read_description (struct gdbarch *gdbarch,
+				 struct target_ops *target,
+				 bfd *abfd)
+{
+  uint64_t xcr0 = i386fbsd_core_read_xcr0 (abfd);
+
+  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;
+    }
+}
+
+/* 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,
+    REGSET_VARIABLE_SIZE,
+  };
+
+/* 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", regcache ? X86_XSTATE_MAX_SIZE : 0,
+      &amd64fbsd_xstateregset, "XSAVE extended state", cb_data);
+}
+
 static void
 amd64fbsd_supply_uthread (struct regcache *regcache,
 			  int regnum, CORE_ADDR addr)
@@ -233,6 +301,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 a/gdb/i386-tdep.h b/gdb/i386-tdep.h
index 8bfd412..0682f0e 100644
--- a/gdb/i386-tdep.h
+++ b/gdb/i386-tdep.h
@@ -328,6 +328,11 @@ enum record_i386_regnum
 /* Size of the largest register.  */
 #define I386_MAX_REGISTER_SIZE	64
 
+extern struct target_desc *tdesc_i386;
+extern struct target_desc *tdesc_i386_avx;
+extern struct target_desc *tdesc_i386_mpx;
+extern struct target_desc *tdesc_i386_avx512;
+
 /* Types for i386-specific registers.  */
 extern struct type *i387_ext_type (struct gdbarch *gdbarch);
 
diff --git a/gdb/i386bsd-nat.c b/gdb/i386bsd-nat.c
index 16e0707..33a3700 100644
--- a/gdb/i386bsd-nat.c
+++ b/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 x86_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 (x86_xsave_len != 0)
+	{
+	  char *xstateregs;
+
+	  xstateregs = alloca (x86_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 (x86_xsave_len != 0)
+	{
+	  char *xstateregs;
+
+	  xstateregs = alloca (x86_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, x86_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 a/gdb/i386bsd-nat.h b/gdb/i386bsd-nat.h
index a11f554..f086a6c 100644
--- a/gdb/i386bsd-nat.h
+++ b/gdb/i386bsd-nat.h
@@ -25,6 +25,9 @@
 
 extern struct target_ops *i386bsd_target (void);
 
+/* Low level i386 XSAVE info. */
+extern size_t x86_xsave_len;
+
 /* low level i386 debug register functions used in i386fbsd-nat.c.  */
 
 extern void i386bsd_dr_set_control (unsigned long control);
diff --git a/gdb/i386fbsd-nat.c b/gdb/i386fbsd-nat.c
index ad439e3..ac8c2e9 100644
--- a/gdb/i386fbsd-nat.c
+++ b/gdb/i386fbsd-nat.c
@@ -31,6 +31,7 @@
 #include "i386-tdep.h"
 #include "x86-nat.h"
 #include "i386bsd-nat.h"
+#include "x86-xstate.h"
 
 /* Resume execution of the inferior process.  If STEP is nonzero,
    single-step it.  If SIGNAL is nonzero, give it that signal.  */
@@ -116,6 +117,46 @@ i386fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
 }
 
 
+#ifdef PT_GETXSTATE_INFO
+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)
+	{
+	  x86_xsave_len = info.xsave_len;
+	  xcr0 = info.xsave_mask;
+	}
+      xsave_probed = 1;
+    }
+
+  if (x86_xsave_len != 0)
+    {
+      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;
+	}
+    }
+  else
+    return tdesc_i386;
+}
+#endif
+
 /* Prevent warning from -Wmissing-prototypes.  */
 void _initialize_i386fbsd_nat (void);
 
@@ -140,6 +181,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 a/gdb/i386fbsd-tdep.c b/gdb/i386fbsd-tdep.c
index ed41706..1e7e124 100644
--- a/gdb/i386fbsd-tdep.c
+++ b/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,113 @@ 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;
+}
+
+static const struct target_desc *
+i386fbsd_core_read_description (struct gdbarch *gdbarch,
+				struct target_ops *target,
+				bfd *abfd)
+{
+  uint64_t xcr0 = i386fbsd_core_read_xcr0 (abfd);
+
+  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;
+    }
+}
+
+/* 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,
+    REGSET_VARIABLE_SIZE
+  };
+
+/* 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)
+    /* Use max size for writing, accept any size when reading.  */
+    cb (".reg-xstate", regcache ? X86_XSTATE_MAX_SIZE : 0,
+	&i386fbsd_xstateregset, "XSAVE extended state", cb_data);
+}
+
 static void
 i386fbsd_supply_uthread (struct regcache *regcache,
 			 int regnum, CORE_ADDR addr)
@@ -376,6 +486,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 a/gdb/i386fbsd-tdep.h b/gdb/i386fbsd-tdep.h
new file mode 100644
index 0000000..9a39ee1
--- /dev/null
+++ b/gdb/i386fbsd-tdep.h
@@ -0,0 +1,33 @@
+/* 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 */
