Index: devel/gdb/Makefile =================================================================== --- devel/gdb/Makefile +++ devel/gdb/Makefile @@ -2,8 +2,8 @@ # $FreeBSD$ PORTNAME= gdb -PORTVERSION= 7.8.2 -PORTREVISION= 2 +PORTVERSION= 7.9 +#PORTREVISION= 2 CATEGORIES= devel MASTER_SITES= GNU @@ -27,6 +27,12 @@ CFLAGS+= -DRL_NO_COMPAT -Wno-unused-function -Wno-unused-variable EXCLUDE= dejagnu expect sim texinfo intl EXTRACT_AFTER_ARGS= ${EXCLUDE:S/^/--exclude /} +EXTRA_PATCHES= ${FILESDIR}/commit-c5cb74e \ + ${FILESDIR}/commit-cf424ae \ + ${FILESDIR}/commit-773eacf \ + ${FILESDIR}/commit-2526815 \ + ${FILESDIR}/commit-3ce5b6e \ + ${FILESDIR}/commit-97de354 VER= ${PORTVERSION:S/.//g} PLIST_SUB= VER=${VER} @@ -61,7 +67,6 @@ PYTHON_CONFIGURE_ON= --with-python=${PYTHON_CMD} PYTHON_CONFIGURE_OFF= --without-python PYTHON_USES= python:2 -PORT_READLINE_EXTRA_PATCHES= ${FILESDIR}/extrapatch-gdb-tui-tui-io.c PORT_READLINE_USES= readline:port TUI_CONFIGURE_ENABLE= tui Index: devel/gdb/distinfo =================================================================== --- devel/gdb/distinfo +++ devel/gdb/distinfo @@ -1,2 +1,2 @@ -SHA256 (gdb-7.8.2.tar.xz) = 605954d5747d5f08ea4b7f48e958d1ebbf39265e18f7f36738deeabb83744485 -SIZE (gdb-7.8.2.tar.xz) = 17678568 +SHA256 (gdb-7.9.tar.xz) = 9b315651a16528f7af8c7d8284699fb0c965df316cc7339bb0b7bae335848392 +SIZE (gdb-7.9.tar.xz) = 17859428 Index: devel/gdb/files/commit-2526815 =================================================================== --- /dev/null +++ devel/gdb/files/commit-2526815 @@ -0,0 +1,186 @@ +diff --git gdb/config.in gdb/config.in +index 3ccac37..8a27df0 100644 +--- gdb/config.in ++++ gdb/config.in +@@ -213,6 +213,9 @@ + /* Define to 1 if you have the header file. */ + #undef HAVE_INTTYPES_H + ++/* Define to 1 if your system has the kinfo_getvmmap function. */ ++#undef HAVE_KINFO_GETVMMAP ++ + /* Define if you have and nl_langinfo(CODESET). */ + #undef HAVE_LANGINFO_CODESET + +diff --git gdb/configure gdb/configure +index cca0aeb..78d206b 100755 +--- gdb/configure ++++ gdb/configure +@@ -7159,6 +7159,66 @@ if test "$ac_res" != no; then : + fi + + ++# On FreeBSD we may need libutil for kinfo_getvmmap (used by fbsd-nat.c). ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing kinfo_getvmmap" >&5 ++$as_echo_n "checking for library containing kinfo_getvmmap... " >&6; } ++if test "${ac_cv_search_kinfo_getvmmap+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_func_search_save_LIBS=$LIBS ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char kinfo_getvmmap (); ++int ++main () ++{ ++return kinfo_getvmmap (); ++ ; ++ return 0; ++} ++_ACEOF ++for ac_lib in '' util; do ++ if test -z "$ac_lib"; then ++ ac_res="none required" ++ else ++ ac_res=-l$ac_lib ++ LIBS="-l$ac_lib $ac_func_search_save_LIBS" ++ fi ++ if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_search_kinfo_getvmmap=$ac_res ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext ++ if test "${ac_cv_search_kinfo_getvmmap+set}" = set; then : ++ break ++fi ++done ++if test "${ac_cv_search_kinfo_getvmmap+set}" = set; then : ++ ++else ++ ac_cv_search_kinfo_getvmmap=no ++fi ++rm conftest.$ac_ext ++LIBS=$ac_func_search_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_kinfo_getvmmap" >&5 ++$as_echo "$ac_cv_search_kinfo_getvmmap" >&6; } ++ac_res=$ac_cv_search_kinfo_getvmmap ++if test "$ac_res" != no; then : ++ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" ++ ++$as_echo "#define HAVE_KINFO_GETVMMAP 1" >>confdefs.h ++ ++fi ++ ++ + + + +diff --git gdb/configure.ac gdb/configure.ac +index 4a0b6a3..38747e8 100644 +--- gdb/configure.ac ++++ gdb/configure.ac +@@ -537,6 +537,11 @@ AM_ZLIB + # On HP/UX we may need libxpdl for dlgetmodinfo (used by solib-pa64.c). + AC_SEARCH_LIBS(dlgetmodinfo, [dl xpdl]) + ++# On FreeBSD we may need libutil for kinfo_getvmmap (used by fbsd-nat.c). ++AC_SEARCH_LIBS(kinfo_getvmmap, util, ++ [AC_DEFINE(HAVE_KINFO_GETVMMAP, 1, ++ [Define to 1 if your system has the kinfo_getvmmap function. ])]) ++ + AM_ICONV + + # GDB may fork/exec the iconv program to get the list of supported character +diff --git gdb/fbsd-nat.c gdb/fbsd-nat.c +index 062eede..1ce197d 100644 +--- gdb/fbsd-nat.c ++++ gdb/fbsd-nat.c +@@ -26,6 +26,10 @@ + #include + #include + #include ++#ifdef HAVE_KINFO_GETVMMAP ++#include ++#include ++#endif + + #include "elf-bfd.h" + #include "fbsd-nat.h" +@@ -62,6 +66,64 @@ fbsd_pid_to_exec_file (struct target_ops *self, int pid) + return NULL; + } + ++#ifdef HAVE_KINFO_GETVMMAP ++/* Iterate over all the memory regions in the current inferior, ++ calling FUNC for each memory region. OBFD is passed as the last ++ argument to FUNC. */ ++ ++int ++fbsd_find_memory_regions (struct target_ops *self, ++ find_memory_region_ftype func, void *obfd) ++{ ++ pid_t pid = ptid_get_pid (inferior_ptid); ++ struct kinfo_vmentry *vmentl, *kve; ++ uint64_t size; ++ struct cleanup *cleanup; ++ int i, nitems; ++ ++ vmentl = kinfo_getvmmap (pid, &nitems); ++ if (vmentl == NULL) ++ perror_with_name (_("Couldn't fetch VM map entries.")); ++ cleanup = make_cleanup (free, vmentl); ++ ++ for (i = 0; i < nitems; i++) ++ { ++ kve = &vmentl[i]; ++ ++ /* Skip unreadable segments and those where MAP_NOCORE has been set. */ ++ if (!(kve->kve_protection & KVME_PROT_READ) ++ || kve->kve_flags & KVME_FLAG_NOCOREDUMP) ++ continue; ++ ++ /* Skip segments with an invalid type. */ ++ if (kve->kve_type != KVME_TYPE_DEFAULT ++ && kve->kve_type != KVME_TYPE_VNODE ++ && kve->kve_type != KVME_TYPE_SWAP ++ && kve->kve_type != KVME_TYPE_PHYS) ++ continue; ++ ++ size = kve->kve_end - kve->kve_start; ++ if (info_verbose) ++ { ++ fprintf_filtered (gdb_stdout, ++ "Save segment, %ld bytes at %s (%c%c%c)\n", ++ (long) size, ++ paddress (target_gdbarch (), kve->kve_start), ++ kve->kve_protection & KVME_PROT_READ ? 'r' : '-', ++ kve->kve_protection & KVME_PROT_WRITE ? 'w' : '-', ++ kve->kve_protection & KVME_PROT_EXEC ? 'x' : '-'); ++ } ++ ++ /* Invoke the callback function to create the corefile segment. ++ Pass MODIFIED as true, we do not know the real modification state. */ ++ func (kve->kve_start, size, kve->kve_protection & KVME_PROT_READ, ++ kve->kve_protection & KVME_PROT_WRITE, ++ kve->kve_protection & KVME_PROT_EXEC, 1, obfd); ++ } ++ do_cleanups (cleanup); ++ return 0; ++} ++#else + static int + fbsd_read_mapping (FILE *mapfile, unsigned long *start, unsigned long *end, + char *protection) +@@ -137,3 +199,4 @@ fbsd_find_memory_regions (struct target_ops *self, + do_cleanups (cleanup); + return 0; + } ++#endif Index: devel/gdb/files/commit-3ce5b6e =================================================================== --- /dev/null +++ devel/gdb/files/commit-3ce5b6e @@ -0,0 +1,21 @@ +diff --git gdb/fbsd-tdep.c gdb/fbsd-tdep.c +index 5d17f03..9609cd8 100644 +--- gdb/fbsd-tdep.c ++++ gdb/fbsd-tdep.c +@@ -89,7 +89,7 @@ fbsd_collect_regset_section_cb (const char *sect_name, int size, + static char * + fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) + { +- const struct regcache *regcache = get_current_regcache (); ++ struct regcache *regcache = get_current_regcache (); + char *note_data; + Elf_Internal_Ehdr *i_ehdrp; + struct fbsd_collect_regset_section_cb_data data; +@@ -104,6 +104,7 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) + data.obfd = obfd; + data.note_data = NULL; + data.note_size = note_size; ++ target_fetch_registers (regcache, -1); + gdbarch_iterate_over_regset_sections (gdbarch, + fbsd_collect_regset_section_cb, + &data, regcache); Index: devel/gdb/files/commit-773eacf =================================================================== --- /dev/null +++ devel/gdb/files/commit-773eacf @@ -0,0 +1,99 @@ +diff --git gdb/amd64fbsd-tdep.c gdb/amd64fbsd-tdep.c +index e11b0f3..62dcb83 100644 +--- gdb/amd64fbsd-tdep.c ++++ gdb/amd64fbsd-tdep.c +@@ -51,8 +51,8 @@ amd64fbsd_sigtramp_p (struct frame_info *this_frame) + + if (!safe_frame_unwind_memory (this_frame, pc, buf, sizeof buf)) + return 0; +- if (memcmp (buf, amd64fbsd_sigtramp_code, sizeof amd64fbsd_sigtramp_code) != +- 0) ++ if (memcmp (buf, amd64fbsd_sigtramp_code, sizeof amd64fbsd_sigtramp_code) ++ != 0) + return 0; + + return 1; +diff --git gdb/i386fbsd-tdep.c gdb/i386fbsd-tdep.c +index d4516ee..ed41706 100644 +--- gdb/i386fbsd-tdep.c ++++ gdb/i386fbsd-tdep.c +@@ -105,24 +105,24 @@ static const gdb_byte i386fbsd_osigtramp_end[] = + }; + + /* The three different trampolines are all the same size. */ +-gdb_static_assert (sizeof i386fbsd_sigtramp_start == +- sizeof i386fbsd_freebsd4_sigtramp_start); +-gdb_static_assert (sizeof i386fbsd_sigtramp_start == +- sizeof i386fbsd_osigtramp_start); +-gdb_static_assert (sizeof i386fbsd_sigtramp_middle == +- sizeof i386fbsd_freebsd4_sigtramp_middle); +-gdb_static_assert (sizeof i386fbsd_sigtramp_middle == +- sizeof i386fbsd_osigtramp_middle); +-gdb_static_assert (sizeof i386fbsd_sigtramp_end == +- sizeof i386fbsd_freebsd4_sigtramp_end); +-gdb_static_assert (sizeof i386fbsd_sigtramp_end == +- sizeof i386fbsd_osigtramp_end); ++gdb_static_assert (sizeof i386fbsd_sigtramp_start ++ == sizeof i386fbsd_freebsd4_sigtramp_start); ++gdb_static_assert (sizeof i386fbsd_sigtramp_start ++ == sizeof i386fbsd_osigtramp_start); ++gdb_static_assert (sizeof i386fbsd_sigtramp_middle ++ == sizeof i386fbsd_freebsd4_sigtramp_middle); ++gdb_static_assert (sizeof i386fbsd_sigtramp_middle ++ == sizeof i386fbsd_osigtramp_middle); ++gdb_static_assert (sizeof i386fbsd_sigtramp_end ++ == sizeof i386fbsd_freebsd4_sigtramp_end); ++gdb_static_assert (sizeof i386fbsd_sigtramp_end ++ == sizeof i386fbsd_osigtramp_end); + + /* We assume that the middle is the largest chunk below. */ +-gdb_static_assert (sizeof i386fbsd_sigtramp_middle > +- sizeof i386fbsd_sigtramp_start); +-gdb_static_assert (sizeof i386fbsd_sigtramp_middle > +- sizeof i386fbsd_sigtramp_end); ++gdb_static_assert (sizeof i386fbsd_sigtramp_middle ++ > sizeof i386fbsd_sigtramp_start); ++gdb_static_assert (sizeof i386fbsd_sigtramp_middle ++ > sizeof i386fbsd_sigtramp_end); + + static int + i386fbsd_sigtramp_p (struct frame_info *this_frame) +@@ -135,19 +135,25 @@ i386fbsd_sigtramp_p (struct frame_info *this_frame) + if (!safe_frame_unwind_memory (this_frame, pc, buf, + sizeof i386fbsd_sigtramp_start)) + return 0; +- if (memcmp (buf, i386fbsd_sigtramp_start, sizeof i386fbsd_sigtramp_start) == +- 0) { +- middle = i386fbsd_sigtramp_middle; +- end = i386fbsd_sigtramp_end; +- } else if (memcmp (buf, i386fbsd_freebsd4_sigtramp_start, +- sizeof i386fbsd_freebsd4_sigtramp_start) == 0) { +- middle = i386fbsd_freebsd4_sigtramp_middle; +- end = i386fbsd_freebsd4_sigtramp_end; +- } else if (memcmp (buf, i386fbsd_osigtramp_start, +- sizeof i386fbsd_osigtramp_start) == 0) { +- middle = i386fbsd_osigtramp_middle; +- end = i386fbsd_osigtramp_end; +- } else ++ if (memcmp (buf, i386fbsd_sigtramp_start, sizeof i386fbsd_sigtramp_start) ++ == 0) ++ { ++ middle = i386fbsd_sigtramp_middle; ++ end = i386fbsd_sigtramp_end; ++ } ++ else if (memcmp (buf, i386fbsd_freebsd4_sigtramp_start, ++ sizeof i386fbsd_freebsd4_sigtramp_start) == 0) ++ { ++ middle = i386fbsd_freebsd4_sigtramp_middle; ++ end = i386fbsd_freebsd4_sigtramp_end; ++ } ++ else if (memcmp (buf, i386fbsd_osigtramp_start, ++ sizeof i386fbsd_osigtramp_start) == 0) ++ { ++ middle = i386fbsd_osigtramp_middle; ++ end = i386fbsd_osigtramp_end; ++ } ++ else + return 0; + + /* Since the end is shorter than the middle, check for a matching end Index: devel/gdb/files/commit-97de354 =================================================================== --- /dev/null +++ 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 . */ ++ ++#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 */ Index: devel/gdb/files/commit-c5cb74e =================================================================== --- /dev/null +++ devel/gdb/files/commit-c5cb74e @@ -0,0 +1,22 @@ +diff --git gdb/amd64fbsd-tdep.c gdb/amd64fbsd-tdep.c +index 2d49cdf..abb0cab 100644 +--- gdb/amd64fbsd-tdep.c ++++ gdb/amd64fbsd-tdep.c +@@ -37,12 +37,16 @@ + static CORE_ADDR + amd64fbsd_sigcontext_addr (struct frame_info *this_frame) + { ++ struct gdbarch *gdbarch = get_frame_arch (this_frame); ++ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + CORE_ADDR sp; ++ gdb_byte buf[8]; + + /* The `struct sigcontext' (which really is an `ucontext_t' on + FreeBSD/amd64) lives at a fixed offset in the signal frame. See + . */ +- sp = frame_unwind_register_unsigned (this_frame, AMD64_RSP_REGNUM); ++ get_frame_register (this_frame, AMD64_RSP_REGNUM, buf); ++ sp = extract_unsigned_integer (buf, 8, byte_order); + return sp + 16; + } + Index: devel/gdb/files/commit-cf424ae =================================================================== --- /dev/null +++ devel/gdb/files/commit-cf424ae @@ -0,0 +1,348 @@ +diff --git gdb/amd64fbsd-nat.c gdb/amd64fbsd-nat.c +index 1c396e2..b1b261c 100644 +--- gdb/amd64fbsd-nat.c ++++ gdb/amd64fbsd-nat.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + + #include "fbsd-nat.h" +@@ -244,24 +245,31 @@ Please report this to ."), + + SC_RBP_OFFSET = offset; + +- /* FreeBSD provides a kern.ps_strings sysctl that we can use to +- locate the sigtramp. That way we can still recognize a sigtramp +- if its location is changed in a new kernel. Of course this is +- still based on the assumption that the sigtramp is placed +- directly under the location where the program arguments and +- environment can be found. */ ++#ifdef KERN_PROC_SIGTRAMP ++ /* Normally signal frames are detected via amd64fbsd_sigtramp_p. ++ However, FreeBSD 9.2 through 10.1 do not include the page holding ++ the signal code in core dumps. These releases do provide a ++ kern.proc.sigtramp. sysctl that returns the location of the ++ signal trampoline for a running process. We fetch the location ++ of the current (gdb) process and use this to identify signal ++ frames in core dumps from these releases. Note that this only ++ works for core dumps of 64-bit (FreeBSD/amd64) processes and does ++ not handle core dumps of 32-bit (FreeBSD/i386) processes. */ + { +- int mib[2]; +- long ps_strings; ++ int mib[4]; ++ struct kinfo_sigtramp kst; + size_t len; + + mib[0] = CTL_KERN; +- mib[1] = KERN_PS_STRINGS; +- len = sizeof (ps_strings); +- if (sysctl (mib, 2, &ps_strings, &len, NULL, 0) == 0) ++ mib[1] = KERN_PROC; ++ mib[2] = KERN_PROC_SIGTRAMP; ++ mib[3] = getpid (); ++ len = sizeof (kst); ++ if (sysctl (mib, 4, &kst, &len, NULL, 0) == 0) + { +- amd64fbsd_sigtramp_start_addr = ps_strings - 32; +- amd64fbsd_sigtramp_end_addr = ps_strings; ++ amd64fbsd_sigtramp_start_addr = (uintptr_t) kst.ksigtramp_start; ++ amd64fbsd_sigtramp_end_addr = (uintptr_t) kst.ksigtramp_end; + } + } ++#endif + } +diff --git gdb/amd64fbsd-tdep.c gdb/amd64fbsd-tdep.c +index abb0cab..e11b0f3 100644 +--- gdb/amd64fbsd-tdep.c ++++ gdb/amd64fbsd-tdep.c +@@ -31,6 +31,33 @@ + + /* Support for signal handlers. */ + ++/* Return whether THIS_FRAME corresponds to a FreeBSD sigtramp ++ routine. */ ++ ++static const gdb_byte amd64fbsd_sigtramp_code[] = ++{ ++ 0x48, 0x8d, 0x7c, 0x24, 0x10, /* lea SIGF_UC(%rsp),%rdi */ ++ 0x6a, 0x00, /* pushq $0 */ ++ 0x48, 0xc7, 0xc0, 0xa1, 0x01, 0x00, 0x00, ++ /* movq $SYS_sigreturn,%rax */ ++ 0x0f, 0x05 /* syscall */ ++}; ++ ++static int ++amd64fbsd_sigtramp_p (struct frame_info *this_frame) ++{ ++ CORE_ADDR pc = get_frame_pc (this_frame); ++ gdb_byte buf[sizeof amd64fbsd_sigtramp_code]; ++ ++ if (!safe_frame_unwind_memory (this_frame, pc, buf, sizeof buf)) ++ return 0; ++ if (memcmp (buf, amd64fbsd_sigtramp_code, sizeof amd64fbsd_sigtramp_code) != ++ 0) ++ return 0; ++ ++ return 1; ++} ++ + /* Assuming THIS_FRAME is for a BSD sigtramp routine, return the + address of the associated sigcontext structure. */ + +@@ -88,8 +115,8 @@ static int amd64fbsd_r_reg_offset[] = + }; + + /* Location of the signal trampoline. */ +-CORE_ADDR amd64fbsd_sigtramp_start_addr = 0x7fffffffffc0ULL; +-CORE_ADDR amd64fbsd_sigtramp_end_addr = 0x7fffffffffe0ULL; ++CORE_ADDR amd64fbsd_sigtramp_start_addr; ++CORE_ADDR amd64fbsd_sigtramp_end_addr; + + /* From . */ + int amd64fbsd_sc_reg_offset[] = +@@ -199,6 +226,7 @@ amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) + + amd64_init_abi (info, gdbarch); + ++ tdep->sigtramp_p = amd64fbsd_sigtramp_p; + tdep->sigtramp_start = amd64fbsd_sigtramp_start_addr; + tdep->sigtramp_end = amd64fbsd_sigtramp_end_addr; + tdep->sigcontext_addr = amd64fbsd_sigcontext_addr; +diff --git gdb/i386fbsd-nat.c gdb/i386fbsd-nat.c +index f4951d1..ad439e3 100644 +--- gdb/i386fbsd-nat.c ++++ gdb/i386fbsd-nat.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + #include "fbsd-nat.h" + #include "i386-tdep.h" +@@ -148,25 +149,28 @@ _initialize_i386fbsd_nat (void) + /* Support debugging kernel virtual memory images. */ + bsd_kvm_add_target (i386fbsd_supply_pcb); + +- /* FreeBSD provides a kern.ps_strings sysctl that we can use to +- locate the sigtramp. That way we can still recognize a sigtramp +- if its location is changed in a new kernel. Of course this is +- still based on the assumption that the sigtramp is placed +- directly under the location where the program arguments and +- environment can be found. */ +-#ifdef KERN_PS_STRINGS ++#ifdef KERN_PROC_SIGTRAMP ++ /* Normally signal frames are detected via i386fbsd_sigtramp_p. ++ However, FreeBSD 9.2 through 10.1 do not include the page holding ++ the signal code in core dumps. These releases do provide a ++ kern.proc.sigtramp. sysctl that returns the location of the ++ signal trampoline for a running process. We fetch the location ++ of the current (gdb) process and use this to identify signal ++ frames in core dumps from these releases. */ + { +- int mib[2]; +- u_long ps_strings; ++ int mib[4]; ++ struct kinfo_sigtramp kst; + size_t len; + + mib[0] = CTL_KERN; +- mib[1] = KERN_PS_STRINGS; +- len = sizeof (ps_strings); +- if (sysctl (mib, 2, &ps_strings, &len, NULL, 0) == 0) ++ mib[1] = KERN_PROC; ++ mib[2] = KERN_PROC_SIGTRAMP; ++ mib[3] = getpid (); ++ len = sizeof (kst); ++ if (sysctl (mib, 4, &kst, &len, NULL, 0) == 0) + { +- i386fbsd_sigtramp_start_addr = ps_strings - 128; +- i386fbsd_sigtramp_end_addr = ps_strings; ++ i386fbsd_sigtramp_start_addr = (uintptr_t) kst.ksigtramp_start; ++ i386fbsd_sigtramp_end_addr = (uintptr_t) kst.ksigtramp_end; + } + } + #endif +diff --git gdb/i386fbsd-tdep.c gdb/i386fbsd-tdep.c +index 8d237f0..d4516ee 100644 +--- gdb/i386fbsd-tdep.c ++++ gdb/i386fbsd-tdep.c +@@ -29,6 +29,154 @@ + #include "fbsd-tdep.h" + #include "solib-svr4.h" + ++/* Support for signal handlers. */ ++ ++/* Return whether THIS_FRAME corresponds to a FreeBSD sigtramp ++ routine. */ ++ ++/* FreeBSD/i386 supports three different signal trampolines, one for ++ versions before 4.0, a second for 4.x, and a third for 5.0 and ++ later. To complicate matters, FreeBSD/i386 binaries running under ++ an amd64 kernel use a different set of trampolines. These ++ trampolines differ from the i386 kernel trampolines in that they ++ omit a middle section that conditionally restores %gs. */ ++ ++static const gdb_byte i386fbsd_sigtramp_start[] = ++{ ++ 0x8d, 0x44, 0x24, 0x20, /* lea SIGF_UC(%esp),%eax */ ++ 0x50 /* pushl %eax */ ++}; ++ ++static const gdb_byte i386fbsd_sigtramp_middle[] = ++{ ++ 0xf7, 0x40, 0x54, 0x00, 0x00, 0x02, 0x00, ++ /* testl $PSL_VM,UC_EFLAGS(%eax) */ ++ 0x75, 0x03, /* jne +3 */ ++ 0x8e, 0x68, 0x14 /* mov UC_GS(%eax),%gs */ ++}; ++ ++static const gdb_byte i386fbsd_sigtramp_end[] = ++{ ++ 0xb8, 0xa1, 0x01, 0x00, 0x00, /* movl $SYS_sigreturn,%eax */ ++ 0x50, /* pushl %eax */ ++ 0xcd, 0x80 /* int $0x80 */ ++}; ++ ++static const gdb_byte i386fbsd_freebsd4_sigtramp_start[] = ++{ ++ 0x8d, 0x44, 0x24, 0x14, /* lea SIGF_UC4(%esp),%eax */ ++ 0x50 /* pushl %eax */ ++}; ++ ++static const gdb_byte i386fbsd_freebsd4_sigtramp_middle[] = ++{ ++ 0xf7, 0x40, 0x54, 0x00, 0x00, 0x02, 0x00, ++ /* testl $PSL_VM,UC4_EFLAGS(%eax) */ ++ 0x75, 0x03, /* jne +3 */ ++ 0x8e, 0x68, 0x14 /* mov UC4_GS(%eax),%gs */ ++}; ++ ++static const gdb_byte i386fbsd_freebsd4_sigtramp_end[] = ++{ ++ 0xb8, 0x58, 0x01, 0x00, 0x00, /* movl $344,%eax */ ++ 0x50, /* pushl %eax */ ++ 0xcd, 0x80 /* int $0x80 */ ++}; ++ ++static const gdb_byte i386fbsd_osigtramp_start[] = ++{ ++ 0x8d, 0x44, 0x24, 0x14, /* lea SIGF_SC(%esp),%eax */ ++ 0x50 /* pushl %eax */ ++}; ++ ++static const gdb_byte i386fbsd_osigtramp_middle[] = ++{ ++ 0xf7, 0x40, 0x18, 0x00, 0x00, 0x02, 0x00, ++ /* testl $PSL_VM,SC_PS(%eax) */ ++ 0x75, 0x03, /* jne +3 */ ++ 0x8e, 0x68, 0x44 /* mov SC_GS(%eax),%gs */ ++}; ++ ++static const gdb_byte i386fbsd_osigtramp_end[] = ++{ ++ 0xb8, 0x67, 0x00, 0x00, 0x00, /* movl $103,%eax */ ++ 0x50, /* pushl %eax */ ++ 0xcd, 0x80 /* int $0x80 */ ++}; ++ ++/* The three different trampolines are all the same size. */ ++gdb_static_assert (sizeof i386fbsd_sigtramp_start == ++ sizeof i386fbsd_freebsd4_sigtramp_start); ++gdb_static_assert (sizeof i386fbsd_sigtramp_start == ++ sizeof i386fbsd_osigtramp_start); ++gdb_static_assert (sizeof i386fbsd_sigtramp_middle == ++ sizeof i386fbsd_freebsd4_sigtramp_middle); ++gdb_static_assert (sizeof i386fbsd_sigtramp_middle == ++ sizeof i386fbsd_osigtramp_middle); ++gdb_static_assert (sizeof i386fbsd_sigtramp_end == ++ sizeof i386fbsd_freebsd4_sigtramp_end); ++gdb_static_assert (sizeof i386fbsd_sigtramp_end == ++ sizeof i386fbsd_osigtramp_end); ++ ++/* We assume that the middle is the largest chunk below. */ ++gdb_static_assert (sizeof i386fbsd_sigtramp_middle > ++ sizeof i386fbsd_sigtramp_start); ++gdb_static_assert (sizeof i386fbsd_sigtramp_middle > ++ sizeof i386fbsd_sigtramp_end); ++ ++static int ++i386fbsd_sigtramp_p (struct frame_info *this_frame) ++{ ++ CORE_ADDR pc = get_frame_pc (this_frame); ++ gdb_byte buf[sizeof i386fbsd_sigtramp_middle]; ++ const gdb_byte *middle, *end; ++ ++ /* Look for a matching start. */ ++ if (!safe_frame_unwind_memory (this_frame, pc, buf, ++ sizeof i386fbsd_sigtramp_start)) ++ return 0; ++ if (memcmp (buf, i386fbsd_sigtramp_start, sizeof i386fbsd_sigtramp_start) == ++ 0) { ++ middle = i386fbsd_sigtramp_middle; ++ end = i386fbsd_sigtramp_end; ++ } else if (memcmp (buf, i386fbsd_freebsd4_sigtramp_start, ++ sizeof i386fbsd_freebsd4_sigtramp_start) == 0) { ++ middle = i386fbsd_freebsd4_sigtramp_middle; ++ end = i386fbsd_freebsd4_sigtramp_end; ++ } else if (memcmp (buf, i386fbsd_osigtramp_start, ++ sizeof i386fbsd_osigtramp_start) == 0) { ++ middle = i386fbsd_osigtramp_middle; ++ end = i386fbsd_osigtramp_end; ++ } else ++ return 0; ++ ++ /* Since the end is shorter than the middle, check for a matching end ++ next. */ ++ pc += sizeof i386fbsd_sigtramp_start; ++ if (!safe_frame_unwind_memory (this_frame, pc, buf, ++ sizeof i386fbsd_sigtramp_end)) ++ return 0; ++ if (memcmp (buf, end, sizeof i386fbsd_sigtramp_end) == 0) ++ return 1; ++ ++ /* If the end didn't match, check for a matching middle. */ ++ if (!safe_frame_unwind_memory (this_frame, pc, buf, ++ sizeof i386fbsd_sigtramp_middle)) ++ return 0; ++ if (memcmp (buf, middle, sizeof i386fbsd_sigtramp_middle) != 0) ++ return 0; ++ ++ /* The middle matched, check for a matching end. */ ++ pc += sizeof i386fbsd_sigtramp_middle; ++ if (!safe_frame_unwind_memory (this_frame, pc, buf, ++ sizeof i386fbsd_sigtramp_end)) ++ return 0; ++ if (memcmp (buf, end, sizeof i386fbsd_sigtramp_end) != 0) ++ return 0; ++ ++ return 1; ++} ++ + /* FreeBSD 3.0-RELEASE or later. */ + + /* From . */ +@@ -43,8 +191,8 @@ static int i386fbsd_r_reg_offset[] = + }; + + /* Sigtramp routine location. */ +-CORE_ADDR i386fbsd_sigtramp_start_addr = 0xbfbfdf20; +-CORE_ADDR i386fbsd_sigtramp_end_addr = 0xbfbfdff0; ++CORE_ADDR i386fbsd_sigtramp_start_addr; ++CORE_ADDR i386fbsd_sigtramp_end_addr; + + /* From . */ + int i386fbsd_sc_reg_offset[] = +@@ -139,6 +287,8 @@ i386fbsdaout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) + /* FreeBSD uses -freg-struct-return by default. */ + tdep->struct_return = reg_struct_return; + ++ tdep->sigtramp_p = i386fbsd_sigtramp_p; ++ + /* FreeBSD uses a different memory layout. */ + tdep->sigtramp_start = i386fbsd_sigtramp_start_addr; + tdep->sigtramp_end = i386fbsd_sigtramp_end_addr; Index: devel/gdb/files/extrapatch-gdb-tui-tui-io.c =================================================================== --- devel/gdb/files/extrapatch-gdb-tui-tui-io.c +++ /dev/null @@ -1,17 +0,0 @@ ---- ./gdb/tui/tui-io.c.orig 2013-12-08 04:33:14.000000000 +0000 -+++ ./gdb/tui/tui-io.c 2014-03-01 22:20:33.000000000 +0000 -@@ -128,10 +128,10 @@ - struct ui_out *tui_old_uiout; - - /* Readline previous hooks. */ --static Function *tui_old_rl_getc_function; --static VFunction *tui_old_rl_redisplay_function; --static VFunction *tui_old_rl_prep_terminal; --static VFunction *tui_old_rl_deprep_terminal; -+static rl_getc_func_t *tui_old_rl_getc_function; -+static rl_voidfunc_t *tui_old_rl_redisplay_function; -+static rl_voidfunc_t *tui_old_rl_prep_terminal; -+static rl_voidfunc_t *tui_old_rl_deprep_terminal; - static int tui_old_rl_echoing_p; - - /* Readline output stream. Index: devel/gdb/files/extrapatch-threads =================================================================== --- devel/gdb/files/extrapatch-threads +++ devel/gdb/files/extrapatch-threads @@ -1,16 +1,16 @@ -diff --git a/gdb/Makefile.in b/gdb/Makefile.in -index ea27cf5..d17752f 100644 +diff --git gdb/Makefile.in gdb/Makefile.in +index 7937801..6122f16 100644 --- gdb/Makefile.in +++ gdb/Makefile.in -@@ -668,6 +668,7 @@ ALL_TARGET_OBS = \ +@@ -691,6 +691,7 @@ ALL_TARGET_OBS = \ xtensa-config.o xtensa-tdep.o xtensa-linux-tdep.o \ glibc-tdep.o \ bsd-uthread.o \ + fbsd-threads.o \ nbsd-tdep.o obsd-tdep.o \ sol2-tdep.o \ - solib-frv.o solib-irix.o solib-svr4.o \ -@@ -1327,7 +1328,7 @@ libgdb.a: $(LIBGDB_OBS) + solib-frv.o solib-svr4.o \ +@@ -1366,7 +1367,7 @@ libgdb.a: $(LIBGDB_OBS) # Removing the old gdb first works better if it is running, at least on SunOS. gdb$(EXEEXT): gdb.o $(LIBGDB_OBS) $(ADD_DEPS) $(CDEPS) $(TDEPLIBS) rm -f gdb$(EXEEXT) @@ -19,7 +19,7 @@ -o gdb$(EXEEXT) gdb.o $(LIBGDB_OBS) \ $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES) -@@ -1600,7 +1601,7 @@ ALLDEPFILES = \ +@@ -1639,7 +1640,7 @@ ALLDEPFILES = \ armnbsd-nat.c armbsd-tdep.c armnbsd-tdep.c armobsd-tdep.c \ avr-tdep.c \ bfin-linux-tdep.c bfin-tdep.c \ @@ -28,12 +28,12 @@ core-regset.c \ dcache.c dicos-tdep.c darwin-nat.c \ exec.c \ -diff --git a/gdb/amd64bsd-nat.c b/gdb/amd64bsd-nat.c -index 9e6a0df..7aff6f0 100644 +diff --git gdb/amd64bsd-nat.c gdb/amd64bsd-nat.c +index b1d4a0e..7f189f6 100644 --- gdb/amd64bsd-nat.c +++ gdb/amd64bsd-nat.c -@@ -41,6 +41,19 @@ - size_t x86_xsave_len; +@@ -40,6 +40,19 @@ + size_t amd64bsd_xsave_len; #endif +static pid_t @@ -52,7 +52,7 @@ /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this for all registers (including the floating-point registers). */ -@@ -54,7 +67,7 @@ amd64bsd_fetch_inferior_registers (struct target_ops *ops, +@@ -53,7 +66,7 @@ amd64bsd_fetch_inferior_registers (struct target_ops *ops, { struct reg regs; @@ -61,16 +61,16 @@ (PTRACE_TYPE_ARG3) ®s, 0) == -1) perror_with_name (_("Couldn't get registers")); -@@ -72,7 +85,7 @@ amd64bsd_fetch_inferior_registers (struct target_ops *ops, - if (x86_xsave_len != 0) +@@ -71,7 +84,7 @@ amd64bsd_fetch_inferior_registers (struct target_ops *ops, + if (amd64bsd_xsave_len != 0) { - xstateregs = alloca(x86_xsave_len); + xstateregs = alloca (amd64bsd_xsave_len); - if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid), + if (ptrace (PT_GETXSTATE, ptrace_pid (inferior_ptid), (PTRACE_TYPE_ARG3) xstateregs, 0) == -1) perror_with_name (_("Couldn't get extended state status")); -@@ -81,7 +94,7 @@ amd64bsd_fetch_inferior_registers (struct target_ops *ops, +@@ -80,7 +93,7 @@ amd64bsd_fetch_inferior_registers (struct target_ops *ops, } #endif @@ -79,7 +79,7 @@ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) perror_with_name (_("Couldn't get floating point status")); -@@ -104,11 +117,11 @@ amd64bsd_store_inferior_registers (struct target_ops *ops, +@@ -103,11 +116,11 @@ amd64bsd_store_inferior_registers (struct target_ops *ops, memset( ®s, 0, sizeof(struct reg)); memset( &oldregs, 0, sizeof(struct reg)); @@ -93,7 +93,7 @@ (PTRACE_TYPE_ARG3) &oldregs, 0); amd64_collect_native_gregset (regcache, ®s, regnum); -@@ -118,7 +131,7 @@ amd64bsd_store_inferior_registers (struct target_ops *ops, +@@ -117,7 +130,7 @@ amd64bsd_store_inferior_registers (struct target_ops *ops, regs.r_rflags ^= (regs.r_rflags ^ oldregs.r_rflags ) & ~PSL_USERCHANGE; //printf(" allowed regs.r_rflags = 0x%8.8X\n", regs.r_rflags ); } @@ -102,10 +102,10 @@ (PTRACE_TYPE_ARG3) ®s, 0) == -1) perror_with_name (_("Couldn't write registers")); -@@ -135,26 +148,26 @@ amd64bsd_store_inferior_registers (struct target_ops *ops, - if (x86_xsave_len != 0) +@@ -134,26 +147,26 @@ amd64bsd_store_inferior_registers (struct target_ops *ops, + if (amd64bsd_xsave_len != 0) { - xstateregs = alloca(x86_xsave_len); + xstateregs = alloca (amd64bsd_xsave_len); - if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid), + if (ptrace (PT_GETXSTATE, ptrace_pid (inferior_ptid), (PTRACE_TYPE_ARG3) xstateregs, 0) == -1) @@ -115,7 +115,7 @@ - if (ptrace (PT_SETXSTATE, ptid_get_pid (inferior_ptid), + if (ptrace (PT_SETXSTATE, ptrace_pid (inferior_ptid), - (PTRACE_TYPE_ARG3) xstateregs, x86_xsave_len) == -1) + (PTRACE_TYPE_ARG3) xstateregs, amd64bsd_xsave_len) == -1) perror_with_name (_("Couldn't write extended state status")); return; } @@ -133,7 +133,7 @@ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) perror_with_name (_("Couldn't write floating point status")); } -@@ -184,7 +197,7 @@ amd64bsd_dr_get (ptid_t ptid, int regnum) +@@ -183,7 +196,7 @@ amd64bsd_dr_get (ptid_t ptid, int regnum) { struct dbreg dbregs; @@ -142,7 +142,7 @@ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1) perror_with_name (_("Couldn't read debug registers")); -@@ -196,7 +209,7 @@ amd64bsd_dr_set (int regnum, unsigned long value) +@@ -195,7 +208,7 @@ amd64bsd_dr_set (int regnum, unsigned long value) { struct dbreg dbregs; @@ -151,7 +151,7 @@ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1) perror_with_name (_("Couldn't get debug registers")); -@@ -207,7 +220,7 @@ amd64bsd_dr_set (int regnum, unsigned long value) +@@ -206,7 +219,7 @@ amd64bsd_dr_set (int regnum, unsigned long value) DBREG_DRX ((&dbregs), regnum) = value; @@ -160,8 +160,8 @@ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1) perror_with_name (_("Couldn't write debug registers")); } -diff --git a/gdb/amd64fbsd-nat.c b/gdb/amd64fbsd-nat.c -index eea2472..9ce6a54 100644 +diff --git gdb/amd64fbsd-nat.c gdb/amd64fbsd-nat.c +index a721f48..2534360 100644 --- gdb/amd64fbsd-nat.c +++ gdb/amd64fbsd-nat.c @@ -18,6 +18,7 @@ @@ -172,7 +172,7 @@ #include "inferior.h" #include "regcache.h" #include "target.h" -@@ -95,6 +96,46 @@ static int amd64fbsd32_r_reg_offset[I386_NUM_GREGS] = +@@ -92,6 +93,46 @@ static int amd64fbsd32_r_reg_offset[I386_NUM_GREGS] = }; @@ -219,19 +219,19 @@ /* Support for debugging kernel virtual memory images. */ #include -diff --git a/gdb/amd64fbsd-tdep.c b/gdb/amd64fbsd-tdep.c -index 582ae50..8e07369 100644 +diff --git gdb/amd64fbsd-tdep.c gdb/amd64fbsd-tdep.c +index 52705d9..6d48d8f 100644 --- gdb/amd64fbsd-tdep.c +++ gdb/amd64fbsd-tdep.c -@@ -31,7 +31,6 @@ - #include +@@ -28,7 +28,6 @@ + #include "x86-xstate.h" #include "amd64-tdep.h" -#include "bsd-uthread.h" + #include "fbsd-tdep.h" #include "solib-svr4.h" - /* Supported register note sections. */ -@@ -178,46 +177,6 @@ amd64fbsd_core_read_description (struct gdbarch *gdbarch, +@@ -226,46 +225,6 @@ amd64fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch, } static void @@ -278,7 +278,7 @@ amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); -@@ -245,10 +204,6 @@ amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +@@ -298,10 +257,6 @@ amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_core_read_description (gdbarch, amd64fbsd_core_read_description); @@ -289,42 +289,42 @@ /* FreeBSD uses SVR4-style shared libraries. */ set_solib_svr4_fetch_link_map_offsets (gdbarch, svr4_lp64_fetch_link_map_offsets); -diff --git a/gdb/configure.tgt b/gdb/configure.tgt -index 01311b2..0929a25 100644 +diff --git gdb/configure.tgt gdb/configure.tgt +index 7fdd34e..64afacf 100644 --- gdb/configure.tgt +++ gdb/configure.tgt -@@ -189,7 +189,7 @@ i[34567]86-*-dicos*) +@@ -187,7 +187,7 @@ i[34567]86-*-dicos*) i[34567]86-*-freebsd* | i[34567]86-*-kfreebsd*-gnu) # Target: FreeBSD/i386 gdb_target_obs="i386-tdep.o i387-tdep.o i386bsd-tdep.o i386fbsd-tdep.o \ -- bsd-uthread.o solib-svr4.o" -+ fbsd-threads.o solib-svr4.o" +- bsd-uthread.o fbsd-tdep.o solib-svr4.o" ++ fbsd-threads.o fbsd-tdep.o solib-svr4.o" ;; i[34567]86-*-netbsd* | i[34567]86-*-knetbsd*-gnu) # Target: NetBSD/i386 -@@ -415,7 +415,7 @@ nios2*-*-*) +@@ -410,7 +410,7 @@ nios2*-*-*) powerpc*-*-freebsd*) # Target: FreeBSD/powerpc gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc64-tdep.o \ -- ppcfbsd-tdep.o solib-svr4.o \ -+ ppcfbsd-tdep.o solib-svr4.o fbsd-threads.o \ +- ppcfbsd-tdep.o fbsd-tdep.o solib-svr4.o \ ++ ppcfbsd-tdep.o fbsd-threads.o fbsd-tdep.o solib-svr4.o \ ravenscar-thread.o ppc-ravenscar-thread.o" ;; -@@ -667,7 +667,7 @@ x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) +@@ -663,7 +663,7 @@ x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) # Target: FreeBSD/amd64 gdb_target_obs="amd64-tdep.o amd64fbsd-tdep.o i386-tdep.o \ i387-tdep.o i386bsd-tdep.o i386fbsd-tdep.o \ -- bsd-uthread.o solib-svr4.o" -+ fbsd-threads.o solib-svr4.o" +- bsd-uthread.o fbsd-tdep.o solib-svr4.o" ++ fbsd-threads.o fbsd-tdep.o solib-svr4.o" ;; x86_64-*-mingw* | x86_64-*-cygwin*) # Target: MingW/amd64 -diff --git a/gdb/i386bsd-nat.c b/gdb/i386bsd-nat.c -index c26e830..246acdd 100644 +diff --git gdb/i386bsd-nat.c gdb/i386bsd-nat.c +index ac8a19b..cb2d50e 100644 --- gdb/i386bsd-nat.c +++ gdb/i386bsd-nat.c -@@ -89,9 +89,22 @@ size_t x86_xsave_len; +@@ -87,9 +87,22 @@ size_t i386bsd_xsave_len; #endif @@ -348,7 +348,7 @@ i386bsd_supply_gregset (struct regcache *regcache, const void *gregs) { const char *regs = gregs; -@@ -110,7 +123,7 @@ i386bsd_supply_gregset (struct regcache *regcache, const void *gregs) +@@ -108,7 +121,7 @@ i386bsd_supply_gregset (struct regcache *regcache, const void *gregs) GREGS. If REGNUM is -1, collect and store all appropriate registers. */ @@ -357,7 +357,7 @@ i386bsd_collect_gregset (const struct regcache *regcache, void *gregs, int regnum) { -@@ -140,7 +153,7 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops, +@@ -138,7 +151,7 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops, { struct reg regs; @@ -366,16 +366,16 @@ (PTRACE_TYPE_ARG3) ®s, 0) == -1) perror_with_name (_("Couldn't get registers")); -@@ -162,7 +175,7 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops, +@@ -160,7 +173,7 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops, char *xstateregs; - xstateregs = alloca(x86_xsave_len); + xstateregs = alloca (i386bsd_xsave_len); - if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid), + if (ptrace (PT_GETXSTATE, ptrace_pid (inferior_ptid), (PTRACE_TYPE_ARG3) xstateregs, 0) == -1) perror_with_name (_("Couldn't get extended state status")); -@@ -174,7 +187,7 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops, +@@ -171,7 +184,7 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops, #ifdef HAVE_PT_GETXMMREGS if (have_ptrace_xmmregs != 0 @@ -384,7 +384,7 @@ (PTRACE_TYPE_ARG3) xmmregs, 0) == 0) { have_ptrace_xmmregs = 1; -@@ -184,7 +197,7 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops, +@@ -181,7 +194,7 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops, { have_ptrace_xmmregs = 0; #endif @@ -393,7 +393,7 @@ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) perror_with_name (_("Couldn't get floating point status")); -@@ -206,13 +219,13 @@ i386bsd_store_inferior_registers (struct target_ops *ops, +@@ -203,13 +216,13 @@ i386bsd_store_inferior_registers (struct target_ops *ops, { struct reg regs; @@ -409,10 +409,10 @@ (PTRACE_TYPE_ARG3) ®s, 0) == -1) perror_with_name (_("Couldn't write registers")); -@@ -233,13 +246,13 @@ i386bsd_store_inferior_registers (struct target_ops *ops, +@@ -230,13 +243,13 @@ i386bsd_store_inferior_registers (struct target_ops *ops, char *xstateregs; - xstateregs = alloca(x86_xsave_len); + xstateregs = alloca (i386bsd_xsave_len); - if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid), + if (ptrace (PT_GETXSTATE, ptrace_pid (inferior_ptid), (PTRACE_TYPE_ARG3) xstateregs, 0) == -1) @@ -422,10 +422,10 @@ - if (ptrace (PT_SETXSTATE, ptid_get_pid (inferior_ptid), + if (ptrace (PT_SETXSTATE, ptrace_pid (inferior_ptid), - (PTRACE_TYPE_ARG3) xstateregs, x86_xsave_len) == -1) + (PTRACE_TYPE_ARG3) xstateregs, i386bsd_xsave_len) == -1) perror_with_name (_("Couldn't write extended state status")); - } -@@ -247,14 +260,14 @@ i386bsd_store_inferior_registers (struct target_ops *ops, + return; +@@ -245,14 +258,14 @@ i386bsd_store_inferior_registers (struct target_ops *ops, #ifdef HAVE_PT_GETXMMREGS if (have_ptrace_xmmregs != 0 @@ -442,7 +442,7 @@ (PTRACE_TYPE_ARG3) xmmregs, 0) == -1) perror_with_name (_("Couldn't write XMM registers")); } -@@ -262,13 +275,13 @@ i386bsd_store_inferior_registers (struct target_ops *ops, +@@ -260,13 +273,13 @@ i386bsd_store_inferior_registers (struct target_ops *ops, { have_ptrace_xmmregs = 0; #endif @@ -458,7 +458,7 @@ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) perror_with_name (_("Couldn't write floating point status")); #ifdef HAVE_PT_GETXMMREGS -@@ -307,7 +320,7 @@ i386bsd_dr_get (ptid_t ptid, int regnum) +@@ -305,7 +318,7 @@ i386bsd_dr_get (ptid_t ptid, int regnum) { struct dbreg dbregs; @@ -467,7 +467,7 @@ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1) perror_with_name (_("Couldn't read debug registers")); -@@ -319,7 +332,7 @@ i386bsd_dr_set (int regnum, unsigned int value) +@@ -317,7 +330,7 @@ i386bsd_dr_set (int regnum, unsigned int value) { struct dbreg dbregs; @@ -476,7 +476,7 @@ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1) perror_with_name (_("Couldn't get debug registers")); -@@ -330,7 +343,7 @@ i386bsd_dr_set (int regnum, unsigned int value) +@@ -328,7 +341,7 @@ i386bsd_dr_set (int regnum, unsigned int value) DBREG_DRX ((&dbregs), regnum) = value; @@ -485,8 +485,8 @@ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1) perror_with_name (_("Couldn't write debug registers")); } -diff --git a/gdb/i386bsd-nat.h b/gdb/i386bsd-nat.h -index 044f530..2fca773 100644 +diff --git gdb/i386bsd-nat.h gdb/i386bsd-nat.h +index 2f50c32..bf7f2ff 100644 --- gdb/i386bsd-nat.h +++ gdb/i386bsd-nat.h @@ -38,6 +38,14 @@ extern CORE_ADDR i386bsd_dr_get_addr (int regnum); @@ -504,8 +504,8 @@ extern unsigned long i386bsd_dr_get_control (void); #endif /* i386bsd-nat.h */ -diff --git a/gdb/i386fbsd-nat.c b/gdb/i386fbsd-nat.c -index b9620e1..71abcdf 100644 +diff --git gdb/i386fbsd-nat.c gdb/i386fbsd-nat.c +index a205a26..29b9444 100644 --- gdb/i386fbsd-nat.c +++ gdb/i386fbsd-nat.c @@ -21,6 +21,7 @@ @@ -516,7 +516,7 @@ #include #include -@@ -82,6 +83,49 @@ i386fbsd_resume (struct target_ops *ops, +@@ -81,6 +82,49 @@ i386fbsd_resume (struct target_ops *ops, } @@ -566,19 +566,19 @@ /* Support for debugging kernel virtual memory images. */ #include -diff --git a/gdb/i386fbsd-tdep.c b/gdb/i386fbsd-tdep.c -index 8f7109f..fcb85d8 100644 +diff --git gdb/i386fbsd-tdep.c gdb/i386fbsd-tdep.c +index 99e08cb..5bb15f6 100644 --- gdb/i386fbsd-tdep.c +++ gdb/i386fbsd-tdep.c -@@ -30,7 +30,6 @@ +@@ -28,7 +28,6 @@ #include "i386-tdep.h" #include "i387-tdep.h" -#include "bsd-uthread.h" + #include "fbsd-tdep.h" #include "solib-svr4.h" - /* FreeBSD 3.0-RELEASE or later. */ -@@ -153,46 +152,6 @@ i386fbsd_core_read_description (struct gdbarch *gdbarch, +@@ -333,46 +332,6 @@ i386fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch, } static void @@ -625,7 +625,7 @@ i386fbsdaout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); -@@ -217,10 +176,6 @@ i386fbsdaout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +@@ -399,10 +358,6 @@ i386fbsdaout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* FreeBSD has a more complete `struct sigcontext'. */ tdep->sc_reg_offset = i386fbsd_sc_reg_offset; tdep->sc_num_regs = ARRAY_SIZE (i386fbsd_sc_reg_offset); @@ -636,11 +636,11 @@ } static void -diff --git a/gdb/ppcfbsd-nat.c b/gdb/ppcfbsd-nat.c -index 079bd12..74922f2 100644 +diff --git gdb/ppcfbsd-nat.c gdb/ppcfbsd-nat.c +index 778b4bb..fa9285f 100644 --- gdb/ppcfbsd-nat.c +++ gdb/ppcfbsd-nat.c -@@ -39,6 +39,19 @@ +@@ -37,6 +37,19 @@ #include "inf-ptrace.h" #include "bsd-kvm.h" @@ -660,7 +660,7 @@ /* Fill GDB's register array with the general-purpose register values in *GREGSETP. */ -@@ -123,7 +136,7 @@ ppcfbsd_fetch_inferior_registers (struct target_ops *ops, +@@ -121,7 +134,7 @@ ppcfbsd_fetch_inferior_registers (struct target_ops *ops, { gdb_gregset_t regs; @@ -669,7 +669,7 @@ (PTRACE_TYPE_ARG3) ®s, 0) == -1) perror_with_name (_("Couldn't get registers")); -@@ -134,7 +147,7 @@ ppcfbsd_fetch_inferior_registers (struct target_ops *ops, +@@ -132,7 +145,7 @@ ppcfbsd_fetch_inferior_registers (struct target_ops *ops, const struct regset *fpregset = ppc_fbsd_fpregset (); gdb_fpregset_t fpregs; @@ -678,7 +678,7 @@ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) perror_with_name (_("Couldn't get FP registers")); -@@ -151,13 +164,13 @@ ppcfbsd_store_inferior_registers (struct target_ops *ops, +@@ -149,13 +162,13 @@ ppcfbsd_store_inferior_registers (struct target_ops *ops, { gdb_gregset_t regs; @@ -694,7 +694,7 @@ (PTRACE_TYPE_ARG3) ®s, 0) == -1) perror_with_name (_("Couldn't write registers")); -@@ -165,13 +178,13 @@ ppcfbsd_store_inferior_registers (struct target_ops *ops, +@@ -163,13 +176,13 @@ ppcfbsd_store_inferior_registers (struct target_ops *ops, { gdb_fpregset_t fpregs; Index: devel/gdb/files/fbsd-threads.c =================================================================== --- devel/gdb/files/fbsd-threads.c +++ devel/gdb/files/fbsd-threads.c @@ -18,11 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include -#include -#include -#include - #include #include #include @@ -151,7 +146,7 @@ /* Prototypes for local functions. */ static void fbsd_find_lwp_name(long lwpid, struct private_thread_info *info); -static void fbsd_thread_find_new_threads (struct target_ops *ops); +static void fbsd_thread_update_thread_list (struct target_ops *ops); static int fbsd_thread_alive (struct target_ops *ops, ptid_t ptid); static void attach_thread (ptid_t ptid, const td_thrhandle_t *th_p, const td_thrinfo_t *ti_p, int verbose); @@ -446,7 +441,7 @@ fbsd_thread_active = 1; if (target_has_execution) enable_thread_event_reporting (); - fbsd_thread_find_new_threads (NULL); + fbsd_thread_update_thread_list (NULL); get_current_thread (); } @@ -809,6 +804,7 @@ prgregset_t gregset; prfpregset_t fpregset; td_thrhandle_t th; + td_thrinfo_t ti; td_err_e err; #ifdef PT_GETXMMREGS char xmmregs[512]; @@ -828,6 +824,25 @@ pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid), thread_db_err_str (err)); + err = td_thr_get_info_p (&th, &ti); + if (err != TD_OK) + error ("Cannot get thread info, Thread ID=%ld, %s", + GET_THREAD (inferior_ptid), thread_db_err_str (err)); + + if (ti.ti_lid != 0) + { + struct target_ops *beneath = find_target_beneath (ops); + struct cleanup *old_chain; + + old_chain = save_inferior_ptid (); + + inferior_ptid = BUILD_LWP (ti.ti_lid, GET_PID (inferior_ptid)); + beneath->to_fetch_registers (ops, regcache, regnum); + + do_cleanups (old_chain); + return; + } + err = td_thr_getgregs_p (&th, gregset); if (err != TD_OK) error ("Cannot fetch general-purpose registers for thread %d: Thread ID=%ld, %s", @@ -862,6 +877,7 @@ prgregset_t gregset; prfpregset_t fpregset; td_thrhandle_t th; + td_thrinfo_t ti; td_err_e err; #ifdef PT_GETXMMREGS char xmmregs[512]; @@ -882,6 +898,25 @@ GET_THREAD (inferior_ptid), thread_db_err_str (err)); + err = td_thr_get_info_p (&th, &ti); + if (err != TD_OK) + error ("Cannot get thread info, Thread ID=%ld, %s", + GET_THREAD (inferior_ptid), thread_db_err_str (err)); + + if (ti.ti_lid != 0) + { + struct target_ops *beneath = find_target_beneath (ops); + struct cleanup *old_chain; + + old_chain = save_inferior_ptid (); + + inferior_ptid = BUILD_LWP (ti.ti_lid, GET_PID (inferior_ptid)); + beneath->to_store_registers (ops, regcache, regnum); + + do_cleanups (old_chain); + return; + } + if (regnum != -1) { char old_value[MAX_REGISTER_SIZE]; @@ -1013,7 +1048,7 @@ } static int -find_new_threads_callback (const td_thrhandle_t *th_p, void *data) +update_thread_list_callback (const td_thrhandle_t *th_p, void *data) { td_thrinfo_t ti; td_err_e err; @@ -1033,12 +1068,15 @@ } static void -fbsd_thread_find_new_threads (struct target_ops *ops) +fbsd_thread_update_thread_list (struct target_ops *ops) { td_err_e err; + /* Delete dead threads. */ + prune_threads(); + /* Iterate over all user-space threads to discover new threads. */ - err = td_ta_thr_iter_p (thread_agent, find_new_threads_callback, NULL, + err = td_ta_thr_iter_p (thread_agent, update_thread_list_callback, NULL, TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY, TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS); if (err != TD_OK) @@ -1048,6 +1086,7 @@ static void fbsd_find_lwp_name(long lwpid, struct private_thread_info *info) { + struct cleanup *old_chain; int error, name[4]; unsigned int i; struct kinfo_proc *kipp, *kip; @@ -1061,21 +1100,22 @@ name[3] = pid; error = sysctl(name, 4, NULL, &len, NULL, 0); - if (error < 0 && errno != ESRCH) { - warn("sysctl: kern.proc.pid: %d", pid); - return; - } - if (error < 0) + if (error < 0) { + if (errno != ESRCH) + warning (_("sysctl: kern.proc.pid: %d: %s"), pid, + safe_strerror (errno)); return; + } - kip = malloc(len); + kip = xmalloc(len); if (kip == NULL) - err(-1, "malloc"); + return; + old_chain = make_cleanup(xfree, kip); if (sysctl(name, 4, kip, &len, NULL, 0) < 0) { - warn("sysctl: kern.proc.pid: %d", pid); - free(kip); - return; + warning (_("sysctl: kern.proc.pid: %d: %s"), pid, safe_strerror(errno)); + do_cleanups(old_chain); + return; } for (i = 0; i < len / sizeof(*kipp); i++) { @@ -1097,15 +1137,13 @@ } } - len = strlen(kipp->ki_ocomm) + 1; - lwpstr = xmalloc(len); - strncpy(lwpstr, kipp->ki_ocomm, len); + lwpstr = xstrdup(kipp->ki_ocomm); info->lwp_name = lwpstr; break; } } - free(kip); + do_cleanups(old_chain); } static char * @@ -1316,7 +1354,7 @@ fbsd_thread_ops.to_store_registers = fbsd_thread_store_registers; fbsd_thread_ops.to_mourn_inferior = fbsd_thread_mourn_inferior; fbsd_thread_ops.to_thread_alive = fbsd_thread_alive; - fbsd_thread_ops.to_find_new_threads = fbsd_thread_find_new_threads; + fbsd_thread_ops.to_update_thread_list = fbsd_thread_update_thread_list; fbsd_thread_ops.to_pid_to_str = fbsd_thread_pid_to_str; fbsd_thread_ops.to_stratum = thread_stratum; fbsd_thread_ops.to_get_thread_local_address = fbsd_thread_get_local_address; Index: devel/gdb/files/patch-gdb-amd64bsd-nat.c =================================================================== --- devel/gdb/files/patch-gdb-amd64bsd-nat.c +++ devel/gdb/files/patch-gdb-amd64bsd-nat.c @@ -1,6 +1,8 @@ ---- gdb/amd64bsd-nat.c.orig 2013-04-09 16:45:15.000000000 +0200 -+++ gdb/amd64bsd-nat.c 2013-04-09 18:53:22.000000000 +0200 -@@ -29,6 +29,7 @@ +diff --git gdb/amd64bsd-nat.c gdb/amd64bsd-nat.c +index 66d4289..b1d4a0e 100644 +--- gdb/amd64bsd-nat.c ++++ gdb/amd64bsd-nat.c +@@ -28,6 +28,7 @@ #include #include #include @@ -8,7 +10,7 @@ #include "amd64-tdep.h" #include "amd64-nat.h" -@@ -81,14 +82,24 @@ +@@ -98,14 +99,24 @@ amd64bsd_store_inferior_registers (struct target_ops *ops, if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum)) { Index: devel/gdb/files/patch-gdb-amd64fbsd-nat.c =================================================================== --- devel/gdb/files/patch-gdb-amd64fbsd-nat.c +++ /dev/null @@ -1,56 +0,0 @@ ---- gdb/amd64fbsd-nat.c.orig 2014-06-11 18:34:41.000000000 +0200 -+++ gdb/amd64fbsd-nat.c 2014-09-24 18:27:50.618458853 +0200 -@@ -21,13 +21,16 @@ - #include "inferior.h" - #include "regcache.h" - #include "target.h" - - #include "gdb_assert.h" - #include - #include - #include -+#include - #include - #include -+#include -+#include - #include - - #include "fbsd-nat.h" -@@ -247,6 +291,10 @@ - - SC_RBP_OFFSET = offset; - -+// Newer versions of FreeBSD provide a better way to locate the signtramp -+#if ( __FreeBSD_version/100000 < 9 ) \ -+ || ( ( __FreeBSD_version/100000 == 9 ) && ( __FreeBSD_version < 902505 ) ) \ -+ || ( ( __FreeBSD_version/100000 == 10 ) && ( __FreeBSD_version < 1000700 ) ) - /* FreeBSD provides a kern.ps_strings sysctl that we can use to - locate the sigtramp. That way we can still recognize a sigtramp - if its location is changed in a new kernel. Of course this is -@@ -267,4 +315,25 @@ - amd64fbsd_sigtramp_end_addr = ps_strings; - } - } -+#else -+ /* FreeBSD provides a kern.proc.sigtramp sysctl that we can use to -+ locate the sigtramp. That way we can still recognize a sigtramp -+ if its location is changed in a new kernel. */ -+ { -+ int mib[4]; -+ struct kinfo_sigtramp kst; -+ size_t len; -+ -+ mib[0] = CTL_KERN; -+ mib[1] = KERN_PROC; -+ mib[2] = KERN_PROC_SIGTRAMP; -+ mib[3] = getpid(); -+ len = sizeof (kst); -+ if (sysctl (mib, sizeof(mib)/sizeof(mib[0]), &kst, &len, NULL, 0) == 0) -+ { -+ amd64fbsd_sigtramp_start_addr = kst.ksigtramp_start; -+ amd64fbsd_sigtramp_end_addr = kst.ksigtramp_end; -+ } -+ } -+#endif - } Index: devel/gdb/files/patch-gdb-amd64fbsd-tdep.c =================================================================== --- devel/gdb/files/patch-gdb-amd64fbsd-tdep.c +++ /dev/null @@ -1,20 +0,0 @@ ---- gdb/amd64fbsd-tdep.c.orig 2010-01-01 02:31:29.000000000 -0500 -+++ gdb/amd64fbsd-tdep.c 2011-01-05 17:27:29.264869000 -0500 -@@ -40,12 +39,16 @@ - static CORE_ADDR - amd64fbsd_sigcontext_addr (struct frame_info *this_frame) - { -+ struct gdbarch *gdbarch = get_frame_arch (this_frame); -+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - CORE_ADDR sp; -+ gdb_byte buf[8]; - - /* The `struct sigcontext' (which really is an `ucontext_t' on - FreeBSD/amd64) lives at a fixed offset in the signal frame. See - . */ -- sp = frame_unwind_register_unsigned (this_frame, AMD64_RSP_REGNUM); -+ get_frame_register (this_frame, AMD64_RSP_REGNUM, buf); -+ sp = extract_unsigned_integer (buf, 8, byte_order); - return sp + 16; - } - Index: devel/gdb/files/patch-gdb-configure =================================================================== --- devel/gdb/files/patch-gdb-configure +++ devel/gdb/files/patch-gdb-configure @@ -1,6 +1,8 @@ ---- gdb/configure.orig 2014-07-29 14:37:42.000000000 +0200 -+++ gdb/configure 2014-10-01 14:21:14.902231511 +0200 -@@ -11485,7 +11485,8 @@ +diff --git gdb/configure gdb/configure +index 355f190..9c60e01 100755 +--- gdb/configure ++++ gdb/configure +@@ -11423,7 +11423,8 @@ fi # See if supports the %fs and %gs i386 segment registers. # Older i386 BSD's don't have the r_fs and r_gs members of `struct reg'. @@ -10,7 +12,7 @@ " if test "x$ac_cv_member_struct_reg_r_fs" = x""yes; then : -@@ -11495,7 +11496,8 @@ +@@ -11433,7 +11434,8 @@ _ACEOF fi @@ -20,7 +22,7 @@ " if test "x$ac_cv_member_struct_reg_r_gs" = x""yes; then : -@@ -13007,10 +13009,9 @@ +@@ -12945,10 +12947,9 @@ fi build_warnings="-Wall -Wdeclaration-after-statement -Wpointer-arith \ -Wpointer-sign \ Index: devel/gdb/files/patch-gdb-gdb_wchar.h =================================================================== --- devel/gdb/files/patch-gdb-gdb_wchar.h +++ devel/gdb/files/patch-gdb-gdb_wchar.h @@ -1,15 +1,17 @@ ---- gdb/gdb_wchar.h.orig 2014-06-05 10:44:18.914279516 +0200 -+++ gdb/gdb_wchar.h 2014-06-05 10:46:07.264279306 +0200 -@@ -56,7 +56,7 @@ +diff --git gdb/gdb_wchar.h gdb/gdb_wchar.h +index 868fe04..1311080 100644 +--- gdb/gdb_wchar.h ++++ gdb/gdb_wchar.h +@@ -59,7 +59,7 @@ iconvlist. */ - #if defined (HAVE_ICONV) && defined (HAVE_WCHAR_H) && defined (HAVE_BTOWC) \ + #if defined (HAVE_ICONV) && defined (HAVE_BTOWC) \ && (defined (__STDC_ISO_10646__) \ - || (defined (_LIBICONV_VERSION) && _LIBICONV_VERSION >= 0x108)) + || (!defined (LIBICONV_PLUG) && defined (_LIBICONV_VERSION) && _LIBICONV_VERSION >= 0x108)) - #include - #include -@@ -82,7 +82,7 @@ + typedef wchar_t gdb_wchar_t; + typedef wint_t gdb_wint_t; +@@ -82,7 +82,7 @@ typedef wint_t gdb_wint_t; #define INTERMEDIATE_ENCODING intermediate_encoding () const char *intermediate_encoding (void); Index: devel/gdb/files/patch-gdb-i386fbsd-nat.c =================================================================== --- devel/gdb/files/patch-gdb-i386fbsd-nat.c +++ devel/gdb/files/patch-gdb-i386fbsd-nat.c @@ -1,58 +1,12 @@ ---- gdb/i386fbsd-nat.c.orig 2012-05-24 18:39:09.000000000 +0200 -+++ gdb/i386fbsd-nat.c 2012-08-29 17:19:57.000000000 +0200 -@@ -21,10 +21,12 @@ - #include "inferior.h" - #include "regcache.h" - #include "target.h" - - #include -+#include - #include - #include -+#include - - #include "fbsd-nat.h" - #include "i386-tdep.h" -@@ -140,7 +141,6 @@ - #endif /* HAVE_PT_GETDBREGS */ - +diff --git gdb/i386fbsd-nat.c gdb/i386fbsd-nat.c +index 6c43f2c..a205a26 100644 +--- gdb/i386fbsd-nat.c ++++ gdb/i386fbsd-nat.c +@@ -175,7 +175,6 @@ _initialize_i386fbsd_nat (void) + t->to_read_description = i386fbsd_read_description; + #endif - t->to_resume = i386fbsd_resume; t->to_pid_to_exec_file = fbsd_pid_to_exec_file; t->to_find_memory_regions = fbsd_find_memory_regions; - t->to_make_corefile_notes = fbsd_make_corefile_notes; -@@ -149,13 +149,33 @@ _initialize_i386fbsd_nat (void) - /* Support debugging kernel virtual memory images. */ - bsd_kvm_add_target (i386fbsd_supply_pcb); - -+#ifdef KERN_PROC_SIGTRAMP -+ /* FreeBSD provides a kern.proc.sigtramp sysctl that we can use to -+ locate the sigtramp. That way we can still recognize a sigtramp -+ if its location is changed in a new kernel. */ -+ { -+ int mib[4]; -+ struct kinfo_sigtramp kst; -+ size_t len; -+ -+ mib[0] = CTL_KERN; -+ mib[1] = KERN_PROC; -+ mib[2] = KERN_PROC_SIGTRAMP; -+ mib[3] = getpid(); -+ len = sizeof (kst); -+ if (sysctl (mib, sizeof(mib)/sizeof(mib[0]), &kst, &len, NULL, 0) == 0) -+ { -+ i386fbsd_sigtramp_start_addr = (uintptr_t)kst.ksigtramp_start; -+ i386fbsd_sigtramp_end_addr = (uintptr_t)kst.ksigtramp_end; -+ } -+ } -+#elif defined(KERN_PS_STRINGS) - /* FreeBSD provides a kern.ps_strings sysctl that we can use to - locate the sigtramp. That way we can still recognize a sigtramp - if its location is changed in a new kernel. Of course this is - still based on the assumption that the sigtramp is placed - directly under the location where the program arguments and - environment can be found. */ --#ifdef KERN_PS_STRINGS - { - int mib[2]; - u_long ps_strings; + add_target (t); Index: devel/gdb/files/patch-gdb-python-python-config.py =================================================================== --- devel/gdb/files/patch-gdb-python-python-config.py +++ devel/gdb/files/patch-gdb-python-python-config.py @@ -1,6 +1,8 @@ ---- gdb/python/python-config.py.orig 2013-10-17 11:24:52.000000000 +0200 -+++ gdb/python/python-config.py 2013-10-17 11:25:04.000000000 +0200 -@@ -59,6 +59,8 @@ +diff --git gdb/python/python-config.py gdb/python/python-config.py +index c2b2969..39af8d9 100644 +--- gdb/python/python-config.py ++++ gdb/python/python-config.py +@@ -59,6 +59,8 @@ for opt in opt_flags: elif opt in ('--libs', '--ldflags'): libs = [] Index: devel/gdb/files/patch-sigev =================================================================== --- devel/gdb/files/patch-sigev +++ devel/gdb/files/patch-sigev @@ -1,6 +1,8 @@ ---- gdb/common/signals.c.orig 2013-01-01 07:32:54.000000000 +0100 -+++ gdb/common/signals.c 2013-11-25 16:12:56.000000000 +0100 -@@ -46,6 +46,12 @@ +diff --git gdb/common/signals.c gdb/common/signals.c +index d4cf953..019371e 100644 +--- gdb/common/signals.c ++++ gdb/common/signals.c +@@ -41,6 +41,12 @@ struct gdbarch; # endif #endif @@ -13,7 +15,7 @@ /* This table must match in order and size the signals in enum gdb_signal. */ -@@ -334,6 +340,11 @@ +@@ -332,6 +338,11 @@ gdb_signal_from_host (int hostsig) return GDB_SIGNAL_INFO; #endif @@ -25,7 +27,7 @@ #if defined (REALTIME_LO) if (hostsig >= REALTIME_LO && hostsig < REALTIME_HI) { -@@ -591,6 +602,11 @@ +@@ -585,6 +596,11 @@ do_gdb_signal_to_host (enum gdb_signal oursig, return SIGINFO; #endif @@ -37,9 +39,11 @@ default: #if defined (REALTIME_LO) retsig = 0; ---- gdb/infrun.c.orig 2013-08-30 17:58:55.000000000 +0200 -+++ gdb/infrun.c 2013-11-22 16:12:58.000000000 +0100 -@@ -7291,6 +7291,8 @@ +diff --git gdb/infrun.c gdb/infrun.c +index 11dcc0e..6ec4d0b 100644 +--- gdb/infrun.c ++++ gdb/infrun.c +@@ -7715,6 +7715,8 @@ leave it stopped or free to run as needed."), signal_print[GDB_SIGNAL_WINCH] = 0; signal_stop[GDB_SIGNAL_PRIO] = 0; signal_print[GDB_SIGNAL_PRIO] = 0; @@ -48,12 +52,14 @@ /* These signals are used internally by user-level thread implementations. (See signal(5) on Solaris.) Like the above ---- include/gdb/signals.def.orig 2013-01-01 07:41:30.000000000 +0100 -+++ include/gdb/signals.def 2013-11-25 16:13:42.000000000 +0100 -@@ -197,4 +197,5 @@ +diff --git include/gdb/signals.def include/gdb/signals.def +index 3f49980..857c69d 100644 +--- include/gdb/signals.def ++++ include/gdb/signals.def +@@ -197,4 +197,5 @@ SET (GDB_EXC_BREAKPOINT, 150, "EXC_BREAKPOINT", "Breakpoint") /* If you are adding a new signal, add it just above this comment. */ /* Last and unused enum value, for sizing arrays, etc. */ --SET (GDB_SIGNAL_LAST, 151, NULL, "GDB_SIGNAL_MAGIC") +-SET (GDB_SIGNAL_LAST, 151, NULL, "GDB_SIGNAL_LAST") +SET (GDB_SIGNAL_FBSD_LIBRT, 151, "SIGLIBRT", "GDB_SIGNAL_FBSD_LIBRT") +SET (GDB_SIGNAL_LAST, 152, NULL, "GDB_SIGNAL_MAGIC") Index: devel/gdb/files/patch-unified =================================================================== --- devel/gdb/files/patch-unified +++ devel/gdb/files/patch-unified @@ -1,6 +1,9 @@ ---- gdb/gdb.c Thu Feb 13 13:07:24 2003 -+++ gdb/gdb.c Wed May 17 00:24:39 2006 -@@ -31,5 +32,11 @@ +diff --git gdb/gdb.c gdb/gdb.c +index e554015..dcb9925 100644 +--- gdb/gdb.c ++++ gdb/gdb.c +@@ -28,6 +28,12 @@ main (int argc, char **argv) + memset (&args, 0, sizeof args); args.argc = argc; args.argv = argv; - args.interpreter_p = INTERP_CONSOLE; Index: devel/gdb/files/patch-xsave =================================================================== --- devel/gdb/files/patch-xsave +++ /dev/null @@ -1,606 +0,0 @@ -diff --git a/bfd/elf.c b/bfd/elf.c -index 3f377d1..9481435 100644 ---- bfd/elf.c -+++ bfd/elf.c -@@ -8609,6 +8609,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; - -diff --git a/gdb/amd64-tdep.h b/gdb/amd64-tdep.h -index f1b039e..7a4c1dc 100644 ---- gdb/amd64-tdep.h -+++ 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 4b0a231..9e6a0df 100644 ---- gdb/amd64bsd-nat.c -+++ gdb/amd64bsd-nat.c -@@ -37,6 +37,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). */ - -@@ -62,6 +66,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) -@@ -111,6 +129,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 7ff95f3..9d85a1f 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 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 08de9a1..eea2472 100644 ---- gdb/amd64fbsd-nat.c -+++ gdb/amd64fbsd-nat.c -@@ -36,6 +36,7 @@ - #include "amd64-nat.h" - #include "amd64bsd-nat.h" - #include "i386-nat.h" -+#include "i386-xstate.h" - - - /* Offset in `struct reg' where MEMBER is stored. */ -@@ -153,6 +154,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) ®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) -+ { -+ x86_xsave_len = info.xsave_len; -+ xcr0 = info.xsave_mask; -+ } -+ xsave_probed = 1; -+ } -+ -+ if (x86_xsave_len != 0) -+ { -+ switch (xcr0 & I386_XSTATE_ALL_MASK) -+ { -+ case I386_XSTATE_MPX_AVX512_MASK: -+ case I386_XSTATE_AVX512_MASK: -+ if (is64) -+ return tdesc_amd64_avx512; -+ else -+ return tdesc_i386_avx512; -+ case I386_XSTATE_MPX_MASK: -+ if (is64) -+ return tdesc_amd64_mpx; -+ else -+ return tdesc_i386_mpx; -+ case I386_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); - -@@ -183,6 +246,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 884fbc4..582ae50 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 "i386-xstate.h" - - #include "gdb_assert.h" - #include -@@ -31,6 +34,15 @@ - #include "bsd-uthread.h" - #include "solib-svr4.h" - -+/* Supported register note sections. */ -+static struct core_regset_section amd64fbsd_regset_sections[] = -+{ -+ { ".reg", 22 * 8, "general-purpose" }, -+ { ".reg2", 512, "floating-point" }, -+ { ".reg-xstate", I386_XSTATE_MAX_SIZE, "XSAVE extended state" }, -+ { NULL, 0 } -+}; -+ - /* Support for signal handlers. */ - - /* Assuming THIS_FRAME is for a BSD sigtramp routine, return the -@@ -144,6 +156,27 @@ 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 & I386_XSTATE_ALL_MASK) -+ { -+ case I386_XSTATE_MPX_AVX512_MASK: -+ case I386_XSTATE_AVX512_MASK: -+ return tdesc_amd64_avx512; -+ case I386_XSTATE_MPX_MASK: -+ return tdesc_amd64_mpx; -+ case I386_XSTATE_AVX_MASK: -+ return tdesc_amd64_avx; -+ default: -+ return tdesc_amd64; -+ } -+} -+ - static void - amd64fbsd_supply_uthread (struct regcache *regcache, - int regnum, CORE_ADDR addr) -@@ -204,6 +237,14 @@ 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; -+ -+ /* Install supported register note sections. */ -+ set_gdbarch_core_regset_sections (gdbarch, amd64fbsd_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 e0950a3..0498445 100644 ---- gdb/i386-tdep.h -+++ gdb/i386-tdep.h -@@ -325,6 +325,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 acae6cb..c26e830 100644 ---- gdb/i386bsd-nat.c -+++ gdb/i386bsd-nat.c -@@ -83,6 +83,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. */ -@@ -150,7 +154,25 @@ 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; -+ } -+ else -+#endif -+ -+#ifdef HAVE_PT_GETXMMREGS - if (have_ptrace_xmmregs != 0 - && ptrace(PT_GETXMMREGS, ptid_get_pid (inferior_ptid), - (PTRACE_TYPE_ARG3) xmmregs, 0) == 0) -@@ -160,18 +182,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 - } - } -@@ -206,7 +225,27 @@ 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")); -+ } -+#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 a92fa56..044f530 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 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 fb80991..b9620e1 100644 ---- gdb/i386fbsd-nat.c -+++ gdb/i386fbsd-nat.c -@@ -31,6 +31,7 @@ - #include "i386-tdep.h" - #include "i386-nat.h" - #include "i386bsd-nat.h" -+#include "i386-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 & I386_XSTATE_ALL_MASK) -+ { -+ case I386_XSTATE_MPX_AVX512_MASK: -+ case I386_XSTATE_AVX512_MASK: -+ return tdesc_i386_avx512; -+ case I386_XSTATE_MPX_MASK: -+ return tdesc_i386_mpx; -+ case I386_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_pid_to_exec_file = fbsd_pid_to_exec_file; - t->to_find_memory_regions = fbsd_find_memory_regions; -diff --git a/gdb/i386fbsd-tdep.c b/gdb/i386fbsd-tdep.c -index ed6df6b..8f7109f 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 "i386-xstate.h" - - #include "gdb_assert.h" - -@@ -32,6 +35,15 @@ - - /* FreeBSD 3.0-RELEASE or later. */ - -+/* Supported register note sections. */ -+static struct core_regset_section i386fbsd_regset_sections[] = -+{ -+ { ".reg", 19 * 4, "general-purpose" }, -+ { ".reg2", 512, "floating-point" }, -+ { ".reg-xstate", I386_XSTATE_MAX_SIZE, "XSAVE extended state" }, -+ { NULL, 0 } -+}; -+ - /* From . */ - static int i386fbsd_r_reg_offset[] = - { -@@ -82,6 +94,64 @@ 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 < I386_XSTATE_AVX_SIZE) -+ xcr0 = I386_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 & I386_XSTATE_ALL_MASK) -+ { -+ case I386_XSTATE_MPX_AVX512_MASK: -+ case I386_XSTATE_AVX512_MASK: -+ return tdesc_i386_avx512; -+ case I386_XSTATE_MPX_MASK: -+ return tdesc_i386_mpx; -+ case I386_XSTATE_AVX_MASK: -+ return tdesc_i386_avx; -+ default: -+ return tdesc_i386; -+ } -+} -+ - static void - i386fbsd_supply_uthread (struct regcache *regcache, - int regnum, CORE_ADDR addr) -@@ -218,6 +288,14 @@ 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; -+ -+ /* Install supported register note sections. */ -+ set_gdbarch_core_regset_sections (gdbarch, i386fbsd_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..8935255 ---- /dev/null -+++ gdb/i386fbsd-tdep.h -@@ -0,0 +1,33 @@ -+/* Target-dependent code for FreeBSD x86. -+ -+ Copyright (C) 2014 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 . */ -+ -+#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 */