Index: head/devel/gdb/Makefile =================================================================== --- head/devel/gdb/Makefile (revision 528131) +++ head/devel/gdb/Makefile (revision 528132) @@ -1,193 +1,182 @@ # Created by: Steven Kreuzer # $FreeBSD$ PORTNAME= gdb -PORTVERSION= 8.3.1 -PORTREVISION= 1 +PORTVERSION= 9.1 CATEGORIES= devel MASTER_SITES= GNU MAINTAINER= pizzamig@FreeBSD.org COMMENT= GNU GDB of newer version than comes with the system LICENSE= GPLv3 LICENSE_FILE= ${WRKSRC}/COPYING3 # untested on sparc64, might work NOT_FOR_ARCHS= sparc64 LIB_DEPENDS= libmpfr.so:math/mpfr TEST_DEPENDS= runtest:misc/dejagnu -USES= compiler:c++11-lang cpe gmake libtool pkgconfig tar:xz +USES= compiler:c++11-lang cpe gmake libtool makeinfo pkgconfig tar:xz USE_PYTHON= flavors py3kplist TEST_TARGET= check USE_CSTD= gnu89 CPE_VENDOR= gnu GNU_CONFIGURE= yes CONFIGURE_ENV= CONFIGURED_M4=m4 CONFIGURED_BISON=byacc CONFIGURE_ARGS= --program-suffix=${PORTVERSION:S/.//g} \ --enable-targets=all --enable-64-bit-bfd \ --with-separate-debug-dir=/usr/lib/debug \ ${ICONV_CONFIGURE_ARG} \ --with-expat=yes --with-libexpat-prefix=${LOCALBASE} \ --without-libunwind-ia64 --with-system-zlib +CONFIGURE_OUTSOURCE= yes CFLAGS:= ${CFLAGS:C/ +$//} # blanks at EOL creep in sometimes CFLAGS+= -DRL_NO_COMPAT -Wno-unused-function -Wno-unused-variable CFLAGS+= -Wno-unknown-warning-option EXCLUDE= dejagnu expect sim texinfo intl EXTRACT_AFTER_ARGS= ${EXCLUDE:S/^/--exclude /} -EXTRA_PATCHES= ${FILESDIR}/commit-1163a4b7a3 \ - ${FILESDIR}/commit-dd6876c91c \ - ${FILESDIR}/commit-6e056c8178 \ - ${FILESDIR}/commit-36c53a0262 \ - ${FILESDIR}/commit-ef0bd2046f \ - ${FILESDIR}/commit-945f3901b5 \ - ${FILESDIR}/commit-f5424cfa7e \ - ${FILESDIR}/commit-ce25aa57a3 \ - ${FILESDIR}/commit-8399425f5f LIB_DEPENDS+= libexpat.so:textproc/expat2 VER= ${PORTVERSION:S/.//g} PLIST_SUB= VER=${VER} OPTIONS_DEFINE= DEBUG GDB_LINK GUILE KGDB NLS PYTHON SOURCE_HIGHLIGHT TUI OPTIONS_DEFAULT= GDB_LINK KGDB NLS PYTHON SOURCE_HIGHLIGHT TUI OPTIONS_DEFAULT+= PORT_READLINE PORT_ICONV SYSTEM_ZLIB OPTIONS_SINGLE= READLINE ICONV ZLIB OPTIONS_SINGLE_READLINE= BUNDLED_READLINE PORT_READLINE OPTIONS_SINGLE_ICONV= PORT_ICONV SYSTEM_ICONV OPTIONS_SINGLE_ZLIB= BUNDLED_ZLIB SYSTEM_ZLIB GDB_LINK_DESC= Create ${PREFIX}/bin/gdb symlink KGDB_DESC= Kernel Debugging Support BUNDLED_READLINE_DESC= from gdb distfile BUNDLED_ZLIB_DESC= from gdb distfile PORT_READLINE_DESC= from devel/readline port PORT_ICONV_DESC= use libiconv, with wider charset support SOURCE_HIGHLIGHT_DESC= Source Code Styling SYSTEM_ICONV_DESC= use libc iconv, with no wchar support SYSTEM_ZLIB_DESC= use system zlib TUI_DESC= Text User Interface enabled OPTIONS_SUB= yes BUNDLED_READLINE_CONFIGURE_OFF= --with-system-readline DEBUG_CFLAGS= -g GUILE_CONFIGURE_WITH= guile GUILE_USES= pkgconfig GUILE_LIB_DEPENDS= libguile-2.2.so:lang/guile2 GUILE_EXTRA_PATCHES= ${FILESDIR}/extrapatch-guile22 NLS_USES= gettext-runtime PORT_READLINE_USES= readline:port PORT_ICONV_USES= iconv:wchar_t PYTHON_CONFIGURE_ON= --with-python=${PYTHON_CMD} PYTHON_CONFIGURE_OFF= --without-python PYTHON_USES= python SOURCE_HIGHLIGHT_WITH= source-highlight SOURCE_HIGHLIGHT_LIB_DEPENDS= \ libsource-highlight.so:textproc/source-highlight SYSTEM_ICONV_USES= iconv SYSTEM_ZLIB_WITH= system-zlib TUI_CONFIGURE_ENABLE= tui .include .if ${PORT_OPTIONS:MPYTHON} .if ${PYTHON_VER} != ${PYTHON_DEFAULT} PKGNAMESUFFIX= ${PYTHON_PKGNAMESUFFIX} .endif .endif .if ${PORT_OPTIONS:MPYTHON} && exists(/usr/lib/libc++.so.1) USE_GITHUB= nodefault GH_ACCOUNT= bsdjhb:libcxx GH_PROJECT= libcxx-gdbpy:libcxx GH_TAGNAME= 229610a:libcxx # Workaround USE_GITHUB preventing the default DISTFILES DISTFILES= ${DISTNAME}${EXTRACT_SUFX} PLIST_SUB+= LIBCXX="" .else PLIST_SUB+= LIBCXX="@comment " .endif -.if ! ${PORT_OPTIONS:MBUNDLED_READLINE} -EXCLUDE+= readline -.endif - .if ! ${PORT_OPTIONS:MBUNDLED_ZLIB} EXCLUDE+= zlib .endif .if ${ARCH} == amd64 CONFIGURE_TARGET= x86_64-portbld-freebsd${OSREL} .endif .if ${CHOSEN_COMPILER_TYPE} == clang CFLAGS+= -Wno-extended-offsetof .endif post-patch: @${REINPLACE_CMD} -e 's|$$| [GDB v${PORTVERSION} for FreeBSD]|' \ ${WRKSRC}/gdb/version.in post-patch-KGDB-on: @${CP} -r ${FILESDIR}/kgdb/*.[ch] ${WRKSRC}/gdb/ @${PATCH} -d ${PATCH_WRKSRC} ${PATCH_ARGS} < ${FILESDIR}/extrapatch-kgdb do-install: - ${INSTALL_PROGRAM} ${WRKSRC}/gdb/gdb \ + ${INSTALL_PROGRAM} ${INSTALL_WRKSRC}/gdb/gdb \ ${STAGEDIR}${PREFIX}/bin/gdb${VER} ${INSTALL_MAN} ${WRKSRC}/gdb/doc/gdb.1 \ ${STAGEDIR}${MAN1PREFIX}/man/man1/gdb${VER}.1 - (cd ${WRKSRC}/gdb/data-directory ; \ + (cd ${INSTALL_WRKSRC}/gdb/data-directory ; \ ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-syscalls ) do-install-KGDB-on: - ${INSTALL_PROGRAM} ${WRKSRC}/gdb/kgdb \ + ${INSTALL_PROGRAM} ${INSTALL_WRKSRC}/gdb/kgdb \ ${STAGEDIR}${PREFIX}/bin/kgdb${VER} ${INSTALL_MAN} ${FILESDIR}/kgdb/kgdb.1 \ ${STAGEDIR}${MAN1PREFIX}/man/man1/kgdb${VER}.1 do-install-TUI-on: ${LN} -sf gdb${VER} ${STAGEDIR}${PREFIX}/bin/gdbtui${VER} do-install-GDB_LINK-on: ${LN} -sf gdb${VER} ${STAGEDIR}${PREFIX}/bin/gdb ${LN} -sf gdb${VER}.1 ${STAGEDIR}${MAN1PREFIX}/man/man1/gdb.1 .if ${PORT_OPTIONS:MKGDB} ${LN} -sf kgdb${VER} ${STAGEDIR}${PREFIX}/bin/kgdb ${LN} -sf kgdb${VER}.1 ${STAGEDIR}${MAN1PREFIX}/man/man1/kgdb.1 .endif do-install-PYTHON-on: - (cd ${WRKSRC}/gdb; ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-python ) - (cd ${WRKSRC}/gdb/data-directory ; \ + (cd ${INSTALL_WRKSRC}/gdb ; \ ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-python ) + (cd ${INSTALL_WRKSRC}/gdb/data-directory ; \ + ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-python ) @(cd ${STAGEDIR}${PREFIX}/share/gdb/python && \ ${PYTHON_CMD} -m compileall .) . for f in gdb gdb/command gdb/function gdb/printer @(cd ${STAGEDIR}${PREFIX}/share/gdb/python/${f} ; ${CHMOD} 644 *.py* ) . endfor .if exists(/usr/lib/libc++.so.1) @(cd ${WRKSRC_libcxx} ; \ ${SETENV} ${MAKE_ENV} ${MAKE} ${MAKE_ARGS} install ) @(cd ${STAGEDIR}${PREFIX}/share/gdb/auto-load/usr/lib && \ ${PYTHON_CMD} -m compileall .) @(cd ${STAGEDIR}${PREFIX}/share/libcxx-gdbpy/libcxx && \ ${PYTHON_CMD} -m compileall .) .endif do-install-GUILE-on: - (cd ${WRKSRC}/gdb; ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-guile ) - (cd ${WRKSRC}/gdb/data-directory ; \ + (cd ${INSTALL_WRKSRC}/gdb ; \ + ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-guile ) + (cd ${INSTALL_WRKSRC}/gdb/data-directory ; \ ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-guile ) .include Index: head/devel/gdb/distinfo =================================================================== --- head/devel/gdb/distinfo (revision 528131) +++ head/devel/gdb/distinfo (revision 528132) @@ -1,5 +1,5 @@ -TIMESTAMP = 1569514923 -SHA256 (gdb-8.3.1.tar.xz) = 1e55b4d7cdca7b34be12f4ceae651623aa73b2fd640152313f9f66a7149757c4 -SIZE (gdb-8.3.1.tar.xz) = 20489528 +TIMESTAMP = 1582826568 +SHA256 (gdb-9.1.tar.xz) = 699e0ec832fdd2f21c8266171ea5bf44024bd05164fdf064e4d10cc4cf0d1737 +SIZE (gdb-9.1.tar.xz) = 20980824 SHA256 (bsdjhb-libcxx-gdbpy-229610a_GH0.tar.gz) = d4235f98b71c4d5e3f01744de279e64808229dd46c0f00cac6a12fdeb3a998a1 SIZE (bsdjhb-libcxx-gdbpy-229610a_GH0.tar.gz) = 5299 Index: head/devel/gdb/files/commit-ef0bd2046f =================================================================== --- head/devel/gdb/files/commit-ef0bd2046f (revision 528131) +++ head/devel/gdb/files/commit-ef0bd2046f (nonexistent) @@ -1,165 +0,0 @@ -commit ef0bd2046f58fac69577892c2d3b44b20d027476 -Author: John Baldwin -Date: Tue Mar 12 13:39:02 2019 -0700 - - Add a more general version of lookup_struct_elt_type. - - lookup_struct_elt is a new function which returns a tuple of - information about a component of a structure or union. The returned - tuple contains a pointer to the struct field object for the component - as well as a bit offset of that field within the structure. If the - field names a field in an anonymous substructure, the offset is the - "global" offset relative to the original structure type. If noerr is - set, then the returned tuple will set the field pointer to NULL to - indicate a missing component rather than throwing an error. - - lookup_struct_elt_type is now reimplemented in terms of this new - function. It simply returns the type of the returned field. - - gdb/ChangeLog: - - * gdbtypes.c (lookup_struct_elt): New function. - (lookup_struct_elt_type): Reimplement via lookup_struct_elt. - * gdbtypes.h (struct struct_elt): New type. - (lookup_struct_elt): New prototype. - -diff --git gdb/gdbtypes.c gdb/gdbtypes.c -index 5924b15520..db470dafac 100644 ---- gdb/gdbtypes.c -+++ gdb/gdbtypes.c -@@ -1644,19 +1644,10 @@ lookup_template_type (char *name, struct type *type, - return (SYMBOL_TYPE (sym)); - } - --/* Given a type TYPE, lookup the type of the component named NAME. -+/* See gdbtypes.h. */ - -- TYPE can be either a struct or union, or a pointer or reference to -- a struct or union. If it is a pointer or reference, its target -- type is automatically used. Thus '.' and '->' are interchangable, -- as specified for the definitions of the expression element types -- STRUCTOP_STRUCT and STRUCTOP_PTR. -- -- If NOERR is nonzero, return NULL if there is no component named -- NAME. */ -- --struct type * --lookup_struct_elt_type (struct type *type, const char *name, int noerr) -+struct_elt -+lookup_struct_elt (struct type *type, const char *name, int noerr) - { - int i; - -@@ -1683,39 +1674,47 @@ lookup_struct_elt_type (struct type *type, const char *name, int noerr) - - if (t_field_name && (strcmp_iw (t_field_name, name) == 0)) - { -- return TYPE_FIELD_TYPE (type, i); -+ return {&TYPE_FIELD (type, i), TYPE_FIELD_BITPOS (type, i)}; - } - else if (!t_field_name || *t_field_name == '\0') - { -- struct type *subtype -- = lookup_struct_elt_type (TYPE_FIELD_TYPE (type, i), name, 1); -- -- if (subtype != NULL) -- return subtype; -+ struct_elt elt -+ = lookup_struct_elt (TYPE_FIELD_TYPE (type, i), name, 1); -+ if (elt.field != NULL) -+ { -+ elt.offset += TYPE_FIELD_BITPOS (type, i); -+ return elt; -+ } - } - } - - /* OK, it's not in this class. Recursively check the baseclasses. */ - for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--) - { -- struct type *t; -- -- t = lookup_struct_elt_type (TYPE_BASECLASS (type, i), name, 1); -- if (t != NULL) -- { -- return t; -- } -+ struct_elt elt = lookup_struct_elt (TYPE_BASECLASS (type, i), name, 1); -+ if (elt.field != NULL) -+ return elt; - } - - if (noerr) -- { -- return NULL; -- } -+ return {nullptr, 0}; - - std::string type_name = type_to_string (type); - error (_("Type %s has no component named %s."), type_name.c_str (), name); - } - -+/* See gdbtypes.h. */ -+ -+struct type * -+lookup_struct_elt_type (struct type *type, const char *name, int noerr) -+{ -+ struct_elt elt = lookup_struct_elt (type, name, noerr); -+ if (elt.field != NULL) -+ return FIELD_TYPE (*elt.field); -+ else -+ return NULL; -+} -+ - /* Store in *MAX the largest number representable by unsigned integer type - TYPE. */ - -diff --git gdb/gdbtypes.h gdb/gdbtypes.h -index a6d4f64e9b..66051cf02c 100644 ---- gdb/gdbtypes.h -+++ gdb/gdbtypes.h -@@ -1873,6 +1873,44 @@ extern struct type *allocate_stub_method (struct type *); - - extern const char *type_name_or_error (struct type *type); - -+struct struct_elt -+{ -+ /* The field of the element, or NULL if no element was found. */ -+ struct field *field; -+ -+ /* The bit offset of the element in the parent structure. */ -+ LONGEST offset; -+}; -+ -+/* Given a type TYPE, lookup the field and offset of the component named -+ NAME. -+ -+ TYPE can be either a struct or union, or a pointer or reference to -+ a struct or union. If it is a pointer or reference, its target -+ type is automatically used. Thus '.' and '->' are interchangable, -+ as specified for the definitions of the expression element types -+ STRUCTOP_STRUCT and STRUCTOP_PTR. -+ -+ If NOERR is nonzero, the returned structure will have field set to -+ NULL if there is no component named NAME. -+ -+ If the component NAME is a field in an anonymous substructure of -+ TYPE, the returned offset is a "global" offset relative to TYPE -+ rather than an offset within the substructure. */ -+ -+extern struct_elt lookup_struct_elt (struct type *, const char *, int); -+ -+/* Given a type TYPE, lookup the type of the component named NAME. -+ -+ TYPE can be either a struct or union, or a pointer or reference to -+ a struct or union. If it is a pointer or reference, its target -+ type is automatically used. Thus '.' and '->' are interchangable, -+ as specified for the definitions of the expression element types -+ STRUCTOP_STRUCT and STRUCTOP_PTR. -+ -+ If NOERR is nonzero, return NULL if there is no component named -+ NAME. */ -+ - extern struct type *lookup_struct_elt_type (struct type *, const char *, int); - - extern struct type *make_pointer_type (struct type *, struct type **); Property changes on: head/devel/gdb/files/commit-ef0bd2046f ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/devel/gdb/files/patch-gdb_common_common-defs.h =================================================================== --- head/devel/gdb/files/patch-gdb_common_common-defs.h (revision 528131) +++ head/devel/gdb/files/patch-gdb_common_common-defs.h (nonexistent) @@ -1,18 +0,0 @@ ---- gdb/common/common-defs.h.orig 2017-09-12 12:25:12 UTC -+++ gdb/common/common-defs.h -@@ -44,9 +44,15 @@ - - Must do this before including any system header, since other system - headers may include stdint.h/inttypes.h. */ -+#ifndef __STDC_CONSTANT_MACROS - #define __STDC_CONSTANT_MACROS 1 -+#endif -+#ifndef __STDC_LIMIT_MACROS - #define __STDC_LIMIT_MACROS 1 -+#endif -+#ifndef __STDC_FORMAT_MACROS - #define __STDC_FORMAT_MACROS 1 -+#endif - - #include - #include Property changes on: head/devel/gdb/files/patch-gdb_common_common-defs.h ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/devel/gdb/files/commit-1163a4b7a3 =================================================================== --- head/devel/gdb/files/commit-1163a4b7a3 (revision 528131) +++ head/devel/gdb/files/commit-1163a4b7a3 (nonexistent) @@ -1,419 +0,0 @@ -commit 1163a4b7a38a79ebd153dc5ee76ce93877d21dbd -Author: John Baldwin -Date: Tue Mar 12 13:39:02 2019 -0700 - - Support the fs_base and gs_base registers on i386. - - As on amd64, these registers hold the base address of the fs and gs - segments, respectively. For i386 these two registers are 32 bits. - - gdb/ChangeLog: - - * amd64-fbsd-nat.c (amd64_fbsd_nat_target::read_description): - Update calls to i386_target_description to add 'segments' - parameter. - * amd64-tdep.c (amd64_init_abi): Set tdep->fsbase_regnum. Don't - add segment base registers. - * arch/i386.c (i386_create_target_description): Add 'segments' - parameter to enable segment base registers. - * arch/i386.h (i386_create_target_description): Likewise. - * features/i386/32bit-segments.xml: New file. - * features/i386/32bit-segments.c: Generate. - * i386-fbsd-nat.c (i386_fbsd_nat_target::read_description): Update - call to i386_target_description to add 'segments' parameter. - * i386-fbsd-tdep.c (i386fbsd_core_read_description): Likewise. - * i386-go32-tdep.c (i386_go32_init_abi): Likewise. - * i386-linux-tdep.c (i386_linux_read_description): Likewise. - * i386-tdep.c (i386_validate_tdesc_p): Add segment base registers - if feature is present. - (i386_gdbarch_init): Pass I386_NUM_REGS to set_gdbarch_num_regs. - Add 'segments' parameter to call to i386_target_description. - (i386_target_description): Add 'segments' parameter to enable - segment base registers. - (_initialize_i386_tdep) [GDB_SELF_TEST]: Add 'segments' parameter - to call to i386_target_description. - * i386-tdep.h (struct gdbarch_tdep): Add 'fsbase_regnum'. - (enum i386_regnum): Add I386_FSBASE_REGNUM and I386_GSBASE_REGNUM. - Define I386_NUM_REGS. - (i386_target_description): Add 'segments' parameter to enable - segment base registers. - - gdb/gdbserver/ChangeLog: - - * linux-x86-tdesc.c (i386_linux_read_description): Update call to - i386_create_target_description for 'segments' parameter. - * lynx-i386-low.c (lynx_i386_arch_setup): Likewise. - * nto-x86-low.c (nto_x86_arch_setup): Likewise. - * win32-i386-low.c (i386_arch_setup): Likewise. - -diff --git gdb/amd64-fbsd-nat.c gdb/amd64-fbsd-nat.c -index 74ef240766..9fff763dd3 100644 ---- gdb/amd64-fbsd-nat.c -+++ gdb/amd64-fbsd-nat.c -@@ -190,13 +190,13 @@ amd64_fbsd_nat_target::read_description () - if (is64) - return amd64_target_description (xcr0, true); - else -- return i386_target_description (xcr0); -+ return i386_target_description (xcr0, false); - } - #endif - if (is64) - return amd64_target_description (X86_XSTATE_SSE_MASK, true); - else -- return i386_target_description (X86_XSTATE_SSE_MASK); -+ return i386_target_description (X86_XSTATE_SSE_MASK, false); - } - - #if defined(HAVE_PT_GETDBREGS) && defined(USE_SIGTRAP_SIGINFO) -diff --git gdb/amd64-tdep.c gdb/amd64-tdep.c -index 3f61997d66..d5892954d7 100644 ---- gdb/amd64-tdep.c -+++ gdb/amd64-tdep.c -@@ -3107,15 +3107,7 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch, - - if (tdesc_find_feature (tdesc, "org.gnu.gdb.i386.segments") != NULL) - { -- const struct tdesc_feature *feature = -- tdesc_find_feature (tdesc, "org.gnu.gdb.i386.segments"); -- struct tdesc_arch_data *tdesc_data_segments = -- (struct tdesc_arch_data *) info.tdep_info; -- -- tdesc_numbered_register (feature, tdesc_data_segments, -- AMD64_FSBASE_REGNUM, "fs_base"); -- tdesc_numbered_register (feature, tdesc_data_segments, -- AMD64_GSBASE_REGNUM, "gs_base"); -+ tdep->fsbase_regnum = AMD64_FSBASE_REGNUM; - } - - if (tdesc_find_feature (tdesc, "org.gnu.gdb.i386.pkeys") != NULL) -diff --git gdb/arch/i386.c gdb/arch/i386.c -index 7d2901333b..ab24cf71cb 100644 ---- gdb/arch/i386.c -+++ gdb/arch/i386.c -@@ -28,11 +28,12 @@ - #include "../features/i386/32bit-avx512.c" - #include "../features/i386/32bit-mpx.c" - #include "../features/i386/32bit-pkeys.c" -+#include "../features/i386/32bit-segments.c" - - /* Create i386 target descriptions according to XCR0. */ - - target_desc * --i386_create_target_description (uint64_t xcr0, bool is_linux) -+i386_create_target_description (uint64_t xcr0, bool is_linux, bool segments) - { - target_desc *tdesc = allocate_target_description (); - -@@ -53,6 +54,9 @@ i386_create_target_description (uint64_t xcr0, bool is_linux) - if (is_linux) - regnum = create_feature_i386_32bit_linux (tdesc, regnum); - -+ if (segments) -+ regnum = create_feature_i386_32bit_segments (tdesc, regnum); -+ - if (xcr0 & X86_XSTATE_AVX) - regnum = create_feature_i386_32bit_avx (tdesc, regnum); - -diff --git gdb/arch/i386.h gdb/arch/i386.h -index fa85438080..9a831cea30 100644 ---- gdb/arch/i386.h -+++ gdb/arch/i386.h -@@ -21,6 +21,7 @@ - #include "common/tdesc.h" - #include - --target_desc *i386_create_target_description (uint64_t xcr0, bool is_linux); -+target_desc *i386_create_target_description (uint64_t xcr0, bool is_linux, -+ bool segments); - - #endif /* ARCH_I386_H */ -diff --git gdb/features/i386/32bit-segments.c gdb/features/i386/32bit-segments.c -new file mode 100644 -index 0000000000..c22c3dfbc3 ---- /dev/null -+++ gdb/features/i386/32bit-segments.c -@@ -0,0 +1,15 @@ -+/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: -+ Original: 32bit-segments.xml */ -+ -+#include "common/tdesc.h" -+ -+static int -+create_feature_i386_32bit_segments (struct target_desc *result, long regnum) -+{ -+ struct tdesc_feature *feature; -+ -+ feature = tdesc_create_feature (result, "org.gnu.gdb.i386.segments"); -+ tdesc_create_reg (feature, "fs_base", regnum++, 1, NULL, 32, "int"); -+ tdesc_create_reg (feature, "gs_base", regnum++, 1, NULL, 32, "int"); -+ return regnum; -+} -diff --git gdb/features/i386/32bit-segments.xml gdb/features/i386/32bit-segments.xml -new file mode 100644 -index 0000000000..098948e5ec ---- /dev/null -+++ gdb/features/i386/32bit-segments.xml -@@ -0,0 +1,12 @@ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git gdb/gdbserver/linux-x86-tdesc.c gdb/gdbserver/linux-x86-tdesc.c -index 04bccc84ed..8f24a3d72d 100644 ---- gdb/gdbserver/linux-x86-tdesc.c -+++ gdb/gdbserver/linux-x86-tdesc.c -@@ -87,7 +87,7 @@ i386_linux_read_description (uint64_t xcr0) - - if (*tdesc == NULL) - { -- *tdesc = i386_create_target_description (xcr0, true); -+ *tdesc = i386_create_target_description (xcr0, true, false); - - init_target_desc (*tdesc, i386_expedite_regs); - } -diff --git gdb/gdbserver/lynx-i386-low.c gdb/gdbserver/lynx-i386-low.c -index bc1027dc52..e47f6b92f6 100644 ---- gdb/gdbserver/lynx-i386-low.c -+++ gdb/gdbserver/lynx-i386-low.c -@@ -331,7 +331,7 @@ static void - lynx_i386_arch_setup (void) - { - struct target_desc *tdesc -- = i386_create_target_description (X86_XSTATE_SSE_MASK, false); -+ = i386_create_target_description (X86_XSTATE_SSE_MASK, false, false); - - init_target_desc (tdesc, i386_expedite_regs); - -diff --git gdb/gdbserver/nto-x86-low.c gdb/gdbserver/nto-x86-low.c -index 1b00f7f6cc..cfbe7ba6d8 100644 ---- gdb/gdbserver/nto-x86-low.c -+++ gdb/gdbserver/nto-x86-low.c -@@ -89,7 +89,7 @@ nto_x86_arch_setup (void) - { - the_low_target.num_regs = 16; - struct target_desc *tdesc -- = i386_create_target_description (X86_XSTATE_SSE_MASK, false); -+ = i386_create_target_description (X86_XSTATE_SSE_MASK, false, false); - - init_target_desc (tdesc, i386_expedite_regs); - -diff --git gdb/gdbserver/win32-i386-low.c gdb/gdbserver/win32-i386-low.c -index 3be75d2bf2..7b187d3bea 100644 ---- gdb/gdbserver/win32-i386-low.c -+++ gdb/gdbserver/win32-i386-low.c -@@ -439,7 +439,7 @@ i386_arch_setup (void) - false, false); - const char **expedite_regs = amd64_expedite_regs; - #else -- tdesc = i386_create_target_description (X86_XSTATE_SSE_MASK, false); -+ tdesc = i386_create_target_description (X86_XSTATE_SSE_MASK, false, false); - const char **expedite_regs = i386_expedite_regs; - #endif - -diff --git gdb/i386-fbsd-nat.c gdb/i386-fbsd-nat.c -index 2309b76506..7106e90801 100644 ---- gdb/i386-fbsd-nat.c -+++ gdb/i386-fbsd-nat.c -@@ -160,7 +160,7 @@ i386_fbsd_nat_target::read_description () - if (x86bsd_xsave_len == 0) - xcr0 = X86_XSTATE_SSE_MASK; - -- return i386_target_description (xcr0); -+ return i386_target_description (xcr0, false); - } - #endif - -diff --git gdb/i386-fbsd-tdep.c gdb/i386-fbsd-tdep.c -index 236edd692a..2f28bad728 100644 ---- gdb/i386-fbsd-tdep.c -+++ gdb/i386-fbsd-tdep.c -@@ -267,7 +267,7 @@ i386fbsd_core_read_description (struct gdbarch *gdbarch, - struct target_ops *target, - bfd *abfd) - { -- return i386_target_description (i386fbsd_core_read_xcr0 (abfd)); -+ return i386_target_description (i386fbsd_core_read_xcr0 (abfd), false); - } - - /* Similar to i386_supply_fpregset, but use XSAVE extended state. */ -diff --git gdb/i386-go32-tdep.c gdb/i386-go32-tdep.c -index 06833c346c..30db72d880 100644 ---- gdb/i386-go32-tdep.c -+++ gdb/i386-go32-tdep.c -@@ -35,7 +35,7 @@ i386_go32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) - - /* DJGPP does not support the SSE registers. */ - if (!tdesc_has_registers (info.target_desc)) -- tdep->tdesc = i386_target_description (X86_XSTATE_X87_MASK); -+ tdep->tdesc = i386_target_description (X86_XSTATE_X87_MASK, false); - - /* Native compiler is GCC, which uses the SVR4 register numbering - even in COFF and STABS. See the comment in i386_gdbarch_init, -diff --git gdb/i386-linux-tdep.c gdb/i386-linux-tdep.c -index da81715061..fa6b86f1c8 100644 ---- gdb/i386-linux-tdep.c -+++ gdb/i386-linux-tdep.c -@@ -694,7 +694,7 @@ i386_linux_read_description (uint64_t xcr0) - [(xcr0 & X86_XSTATE_PKRU) ? 1 : 0]; - - if (*tdesc == NULL) -- *tdesc = i386_create_target_description (xcr0, true); -+ *tdesc = i386_create_target_description (xcr0, true, false); - - return *tdesc; - } -diff --git gdb/i386-tdep.c gdb/i386-tdep.c -index bc9ba752ed..4e63832b0e 100644 ---- gdb/i386-tdep.c -+++ gdb/i386-tdep.c -@@ -8175,7 +8175,7 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep, - const struct tdesc_feature *feature_core; - - const struct tdesc_feature *feature_sse, *feature_avx, *feature_mpx, -- *feature_avx512, *feature_pkeys; -+ *feature_avx512, *feature_pkeys, *feature_segments; - int i, num_regs, valid_p; - - if (! tdesc_has_registers (tdesc)) -@@ -8198,6 +8198,9 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep, - /* Try AVX512 registers. */ - feature_avx512 = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx512"); - -+ /* Try segment base registers. */ -+ feature_segments = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.segments"); -+ - /* Try PKEYS */ - feature_pkeys = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.pkeys"); - -@@ -8307,6 +8310,16 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep, - tdep->mpx_register_names[i]); - } - -+ if (feature_segments) -+ { -+ if (tdep->fsbase_regnum < 0) -+ tdep->fsbase_regnum = I386_FSBASE_REGNUM; -+ valid_p &= tdesc_numbered_register (feature_segments, tdesc_data, -+ tdep->fsbase_regnum, "fs_base"); -+ valid_p &= tdesc_numbered_register (feature_segments, tdesc_data, -+ tdep->fsbase_regnum + 1, "gs_base"); -+ } -+ - if (feature_pkeys) - { - tdep->xcr0 |= X86_XSTATE_PKRU; -@@ -8543,14 +8556,14 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) - /* Even though the default ABI only includes general-purpose registers, - floating-point registers and the SSE registers, we have to leave a - gap for the upper AVX, MPX and AVX512 registers. */ -- set_gdbarch_num_regs (gdbarch, I386_PKEYS_NUM_REGS); -+ set_gdbarch_num_regs (gdbarch, I386_NUM_REGS); - - set_gdbarch_gnu_triplet_regexp (gdbarch, i386_gnu_triplet_regexp); - - /* Get the x86 target description from INFO. */ - tdesc = info.target_desc; - if (! tdesc_has_registers (tdesc)) -- tdesc = i386_target_description (X86_XSTATE_SSE_MASK); -+ tdesc = i386_target_description (X86_XSTATE_SSE_MASK, false); - tdep->tdesc = tdesc; - - tdep->num_core_regs = I386_NUM_GREGS + I387_NUM_REGS; -@@ -8592,6 +8605,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) - tdep->pkru_regnum = -1; - tdep->num_pkeys_regs = 0; - -+ /* No segment base registers. */ -+ tdep->fsbase_regnum = -1; -+ - tdesc_data = tdesc_data_alloc (); - - set_gdbarch_relocate_instruction (gdbarch, i386_relocate_instruction); -@@ -8717,20 +8733,21 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) - /* Return the target description for a specified XSAVE feature mask. */ - - const struct target_desc * --i386_target_description (uint64_t xcr0) -+i386_target_description (uint64_t xcr0, bool segments) - { - static target_desc *i386_tdescs \ -- [2/*SSE*/][2/*AVX*/][2/*MPX*/][2/*AVX512*/][2/*PKRU*/] = {}; -+ [2/*SSE*/][2/*AVX*/][2/*MPX*/][2/*AVX512*/][2/*PKRU*/][2/*segments*/] = {}; - target_desc **tdesc; - - tdesc = &i386_tdescs[(xcr0 & X86_XSTATE_SSE) ? 1 : 0] - [(xcr0 & X86_XSTATE_AVX) ? 1 : 0] - [(xcr0 & X86_XSTATE_MPX) ? 1 : 0] - [(xcr0 & X86_XSTATE_AVX512) ? 1 : 0] -- [(xcr0 & X86_XSTATE_PKRU) ? 1 : 0]; -+ [(xcr0 & X86_XSTATE_PKRU) ? 1 : 0] -+ [segments ? 1 : 0]; - - if (*tdesc == NULL) -- *tdesc = i386_create_target_description (xcr0, false); -+ *tdesc = i386_create_target_description (xcr0, false, segments); - - return *tdesc; - } -@@ -9072,7 +9089,7 @@ Show Intel Memory Protection Extensions specific variables."), - - for (auto &a : xml_masks) - { -- auto tdesc = i386_target_description (a.mask); -+ auto tdesc = i386_target_description (a.mask, false); - - selftests::record_xml_tdesc (a.xml, tdesc); - } -diff --git gdb/i386-tdep.h gdb/i386-tdep.h -index 2532306e5c..c0d494824c 100644 ---- gdb/i386-tdep.h -+++ gdb/i386-tdep.h -@@ -200,6 +200,10 @@ struct gdbarch_tdep - /* PKEYS register names. */ - const char **pkeys_register_names; - -+ /* Register number for %fsbase. Set this to -1 to indicate the -+ absence of segment base registers. */ -+ int fsbase_regnum; -+ - /* Target description. */ - const struct target_desc *tdesc; - -@@ -296,7 +300,9 @@ enum i386_regnum - I386_K7_REGNUM = I386_K0_REGNUM + 7, - I386_ZMM0H_REGNUM, /* %zmm0h */ - I386_ZMM7H_REGNUM = I386_ZMM0H_REGNUM + 7, -- I386_PKRU_REGNUM -+ I386_PKRU_REGNUM, -+ I386_FSBASE_REGNUM, -+ I386_GSBASE_REGNUM - }; - - /* Register numbers of RECORD_REGMAP. */ -@@ -337,6 +343,7 @@ enum record_i386_regnum - #define I386_MPX_NUM_REGS (I386_BNDSTATUS_REGNUM + 1) - #define I386_AVX512_NUM_REGS (I386_ZMM7H_REGNUM + 1) - #define I386_PKEYS_NUM_REGS (I386_PKRU_REGNUM + 1) -+#define I386_NUM_REGS (I386_GSBASE_REGNUM + 1) - - /* Size of the largest register. */ - #define I386_MAX_REGISTER_SIZE 64 -@@ -440,7 +447,8 @@ extern int i386_svr4_reg_to_regnum (struct gdbarch *gdbarch, int reg); - - 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); -+extern const struct target_desc *i386_target_description (uint64_t xcr0, -+ bool segments); - - /* Return true iff the current target is MPX enabled. */ - extern int i386_mpx_enabled (void); Property changes on: head/devel/gdb/files/commit-1163a4b7a3 ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/devel/gdb/files/commit-945f3901b5 =================================================================== --- head/devel/gdb/files/commit-945f3901b5 (revision 528131) +++ head/devel/gdb/files/commit-945f3901b5 (nonexistent) @@ -1,224 +0,0 @@ -commit 945f3901b5889e57edf5a2ee25acb51f0078a719 -Author: John Baldwin -Date: Tue Mar 12 13:39:02 2019 -0700 - - Add a helper function to resolve TLS variable addresses for FreeBSD. - - The fbsd_get_thread_local_address function accepts the base address of - a thread's DTV array and the base address of an object file's link map - and uses this to compute a TLS variable's address. FreeBSD - architectures use an architecture-specific method to determine the - address of the DTV array pointer and call this helper function to - perform the rest of the address calculation. - - * fbsd-tdep.c (fbsd_pspace_data_handle): New variable. - (struct fbsd_pspace_data): New type. - (get_fbsd_pspace_data, fbsd_pspace_data_cleanup) - (fbsd_read_integer_by_name, fbsd_fetch_rtld_offsets) - (fbsd_get_tls_index, fbsd_get_thread_local_address): New function. - (_initialize_fbsd_tdep): Initialize 'fbsd_pspace_data_handle'. - * fbsd-tdep.c (fbsd_get_thread_local_address): New prototype. - -diff --git gdb/fbsd-tdep.c gdb/fbsd-tdep.c -index d971d3a653..f06836216d 100644 ---- gdb/fbsd-tdep.c -+++ gdb/fbsd-tdep.c -@@ -24,6 +24,7 @@ - #include "regcache.h" - #include "regset.h" - #include "gdbthread.h" -+#include "objfiles.h" - #include "xml-syscall.h" - #include - #include -@@ -444,6 +445,41 @@ get_fbsd_gdbarch_data (struct gdbarch *gdbarch) - gdbarch_data (gdbarch, fbsd_gdbarch_data_handle)); - } - -+/* Per-program-space data for FreeBSD architectures. */ -+static const struct program_space_data *fbsd_pspace_data_handle; -+ -+struct fbsd_pspace_data -+{ -+ /* Offsets in the runtime linker's 'Obj_Entry' structure. */ -+ LONGEST off_linkmap; -+ LONGEST off_tlsindex; -+ bool rtld_offsets_valid; -+}; -+ -+static struct fbsd_pspace_data * -+get_fbsd_pspace_data (struct program_space *pspace) -+{ -+ struct fbsd_pspace_data *data; -+ -+ data = ((struct fbsd_pspace_data *) -+ program_space_data (pspace, fbsd_pspace_data_handle)); -+ if (data == NULL) -+ { -+ data = XCNEW (struct fbsd_pspace_data); -+ set_program_space_data (pspace, fbsd_pspace_data_handle, data); -+ } -+ -+ return data; -+} -+ -+/* The cleanup callback for FreeBSD architecture per-program-space data. */ -+ -+static void -+fbsd_pspace_data_cleanup (struct program_space *pspace, void *data) -+{ -+ xfree (data); -+} -+ - /* This is how we want PTIDs from core files to be printed. */ - - static const char * -@@ -1932,6 +1968,121 @@ fbsd_get_syscall_number (struct gdbarch *gdbarch, thread_info *thread) - internal_error (__FILE__, __LINE__, _("fbsd_get_sycall_number called")); - } - -+/* Read an integer symbol value from the current target. */ -+ -+static LONGEST -+fbsd_read_integer_by_name (struct gdbarch *gdbarch, const char *name) -+{ -+ bound_minimal_symbol ms = lookup_minimal_symbol (name, NULL, NULL); -+ if (ms.minsym == NULL) -+ error (_("Unable to resolve symbol '%s'"), name); -+ -+ gdb_byte buf[4]; -+ if (target_read_memory (BMSYMBOL_VALUE_ADDRESS (ms), buf, sizeof buf) != 0) -+ error (_("Unable to read value of '%s'"), name); -+ -+ return extract_signed_integer (buf, sizeof buf, gdbarch_byte_order (gdbarch)); -+} -+ -+/* Lookup offsets of fields in the runtime linker's 'Obj_Entry' -+ structure needed to determine the TLS index of an object file. */ -+ -+static void -+fbsd_fetch_rtld_offsets (struct gdbarch *gdbarch, struct fbsd_pspace_data *data) -+{ -+ TRY -+ { -+ /* Fetch offsets from debug symbols in rtld. */ -+ struct symbol *obj_entry_sym -+ = lookup_symbol_in_language ("Struct_Obj_Entry", NULL, STRUCT_DOMAIN, -+ language_c, NULL).symbol; -+ if (obj_entry_sym == NULL) -+ error (_("Unable to find Struct_Obj_Entry symbol")); -+ data->off_linkmap = lookup_struct_elt (SYMBOL_TYPE(obj_entry_sym), -+ "linkmap", 0).offset / 8; -+ data->off_tlsindex = lookup_struct_elt (SYMBOL_TYPE(obj_entry_sym), -+ "tlsindex", 0).offset / 8; -+ data->rtld_offsets_valid = true; -+ return; -+ } -+ CATCH (e, RETURN_MASK_ERROR) -+ { -+ data->off_linkmap = -1; -+ } -+ END_CATCH -+ -+ TRY -+ { -+ /* Fetch offsets from global variables in libthr. Note that -+ this does not work for single-threaded processes that are not -+ linked against libthr. */ -+ data->off_linkmap = fbsd_read_integer_by_name (gdbarch, -+ "_thread_off_linkmap"); -+ data->off_tlsindex = fbsd_read_integer_by_name (gdbarch, -+ "_thread_off_tlsindex"); -+ data->rtld_offsets_valid = true; -+ return; -+ } -+ CATCH (e, RETURN_MASK_ERROR) -+ { -+ data->off_linkmap = -1; -+ } -+ END_CATCH -+} -+ -+/* Helper function to read the TLS index of an object file associated -+ with a link map entry at LM_ADDR. */ -+ -+static LONGEST -+fbsd_get_tls_index (struct gdbarch *gdbarch, CORE_ADDR lm_addr) -+{ -+ struct fbsd_pspace_data *data = get_fbsd_pspace_data (current_program_space); -+ -+ if (!data->rtld_offsets_valid) -+ fbsd_fetch_rtld_offsets (gdbarch, data); -+ -+ if (data->off_linkmap == -1) -+ throw_error (TLS_GENERIC_ERROR, -+ _("Cannot fetch runtime linker structure offsets")); -+ -+ /* Simulate container_of to convert from LM_ADDR to the Obj_Entry -+ pointer and then compute the offset of the tlsindex member. */ -+ CORE_ADDR tlsindex_addr = lm_addr - data->off_linkmap + data->off_tlsindex; -+ -+ gdb_byte buf[4]; -+ if (target_read_memory (tlsindex_addr, buf, sizeof buf) != 0) -+ throw_error (TLS_GENERIC_ERROR, -+ _("Cannot find thread-local variables on this target")); -+ -+ return extract_signed_integer (buf, sizeof buf, gdbarch_byte_order (gdbarch)); -+} -+ -+/* See fbsd-tdep.h. */ -+ -+CORE_ADDR -+fbsd_get_thread_local_address (struct gdbarch *gdbarch, CORE_ADDR dtv_addr, -+ CORE_ADDR lm_addr, CORE_ADDR offset) -+{ -+ LONGEST tls_index = fbsd_get_tls_index (gdbarch, lm_addr); -+ -+ gdb_byte buf[gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT]; -+ if (target_read_memory (dtv_addr, buf, sizeof buf) != 0) -+ throw_error (TLS_GENERIC_ERROR, -+ _("Cannot find thread-local variables on this target")); -+ -+ const struct builtin_type *builtin = builtin_type (gdbarch); -+ CORE_ADDR addr = gdbarch_pointer_to_address (gdbarch, -+ builtin->builtin_data_ptr, buf); -+ -+ addr += (tls_index + 1) * TYPE_LENGTH (builtin->builtin_data_ptr); -+ if (target_read_memory (addr, buf, sizeof buf) != 0) -+ throw_error (TLS_GENERIC_ERROR, -+ _("Cannot find thread-local variables on this target")); -+ -+ addr = gdbarch_pointer_to_address (gdbarch, builtin->builtin_data_ptr, buf); -+ return addr + offset; -+} -+ - /* To be called from GDB_OSABI_FREEBSD handlers. */ - - void -@@ -1957,4 +2108,6 @@ _initialize_fbsd_tdep (void) - { - fbsd_gdbarch_data_handle = - gdbarch_data_register_post_init (init_fbsd_gdbarch_data); -+ fbsd_pspace_data_handle -+ = register_program_space_data_with_cleanup (NULL, fbsd_pspace_data_cleanup); - } -diff --git gdb/fbsd-tdep.h gdb/fbsd-tdep.h -index efd7c2c78f..0e29508c9f 100644 ---- gdb/fbsd-tdep.h -+++ gdb/fbsd-tdep.h -@@ -60,4 +60,15 @@ extern void fbsd_info_proc_mappings_entry (int addr_bit, ULONGEST kve_start, - int kve_flags, int kve_protection, - const void *kve_path); - -+/* Helper function to fetch the address of a thread-local variable. -+ DTV_ADDR is the base address of the thread's dtv array. LM_ADDR is -+ the address of the link_map structure for the associated object -+ file. OFFSET is the offset of the variable in the object file's -+ thread-local variable block. */ -+ -+extern CORE_ADDR fbsd_get_thread_local_address (struct gdbarch *gdbarch, -+ CORE_ADDR dtv_addr, -+ CORE_ADDR lm_addr, -+ CORE_ADDR offset); -+ - #endif /* fbsd-tdep.h */ Property changes on: head/devel/gdb/files/commit-945f3901b5 ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/devel/gdb/files/commit-ce25aa57a3 =================================================================== --- head/devel/gdb/files/commit-ce25aa57a3 (revision 528131) +++ head/devel/gdb/files/commit-ce25aa57a3 (nonexistent) @@ -1,64 +0,0 @@ -commit ce25aa57a3cdd028be5868423e6e55506ccd1053 -Author: John Baldwin -Date: Tue Mar 12 13:39:02 2019 -0700 - - Support TLS variables on FreeBSD/i386. - - Derive the pointer to the DTV array from the gs_base register. As - with FreeBSD/amd64, gs_base is currently only available via the native - target. - - gdb/ChangeLog: - - * i386-fbsd-tdep.c (i386fbsd_get_thread_local_address): New. - (i386fbsd_init_abi): Install gdbarch - "fetch_tls_load_module_address" and "get_thread_local_address" - methods. - -diff --git gdb/i386-fbsd-tdep.c gdb/i386-fbsd-tdep.c -index ac57e7383d..f274847174 100644 ---- gdb/i386-fbsd-tdep.c -+++ gdb/i386-fbsd-tdep.c -@@ -320,6 +320,30 @@ i386fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch, - "XSAVE extended state", cb_data); - } - -+/* Implement the get_thread_local_address gdbarch method. */ -+ -+static CORE_ADDR -+i386fbsd_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid, -+ CORE_ADDR lm_addr, CORE_ADDR offset) -+{ -+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); -+ struct regcache *regcache; -+ -+ if (tdep->fsbase_regnum == -1) -+ error (_("Unable to fetch %%gsbase")); -+ -+ regcache = get_thread_arch_regcache (ptid, gdbarch); -+ -+ target_fetch_registers (regcache, tdep->fsbase_regnum + 1); -+ -+ ULONGEST gsbase; -+ if (regcache->cooked_read (tdep->fsbase_regnum + 1, &gsbase) != REG_VALID) -+ error (_("Unable to fetch %%gsbase")); -+ -+ CORE_ADDR dtv_addr = gsbase + gdbarch_ptr_bit (gdbarch) / 8; -+ return fbsd_get_thread_local_address (gdbarch, dtv_addr, lm_addr, offset); -+} -+ - static void - i386fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) - { -@@ -418,6 +442,11 @@ i386fbsd4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) - - set_gdbarch_core_read_description (gdbarch, - i386fbsd_core_read_description); -+ -+ set_gdbarch_fetch_tls_load_module_address (gdbarch, -+ svr4_fetch_objfile_link_map); -+ set_gdbarch_get_thread_local_address (gdbarch, -+ i386fbsd_get_thread_local_address); - } - - void Property changes on: head/devel/gdb/files/commit-ce25aa57a3 ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/devel/gdb/files/patch-gdb_gnulib_import_stddef.in.h =================================================================== --- head/devel/gdb/files/patch-gdb_gnulib_import_stddef.in.h (revision 528131) +++ head/devel/gdb/files/patch-gdb_gnulib_import_stddef.in.h (nonexistent) @@ -1,11 +0,0 @@ ---- gdb/gnulib/import/stddef.in.h.orig 2017-09-14 09:28:17 UTC -+++ gdb/gnulib/import/stddef.in.h -@@ -84,7 +84,7 @@ - /* Some platforms lack max_align_t. The check for _GCC_MAX_ALIGN_T is - a hack in case the configure-time test was done with g++ even though - we are currently compiling with gcc. */ --#if ! (@HAVE_MAX_ALIGN_T@ || defined _GCC_MAX_ALIGN_T) -+#if 0 - /* On the x86, the maximum storage alignment of double, long, etc. is 4, - but GCC's C11 ABI for x86 says that max_align_t has an alignment of 8, - and the C11 standard allows this. Work around this problem by Property changes on: head/devel/gdb/files/patch-gdb_gnulib_import_stddef.in.h ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/devel/gdb/files/commit-6e056c8178 =================================================================== --- head/devel/gdb/files/commit-6e056c8178 (revision 528131) +++ head/devel/gdb/files/commit-6e056c8178 (nonexistent) @@ -1,166 +0,0 @@ -commit 6e056c817845f3d736a1be6b68c69b439c6c6d25 -Author: John Baldwin -Date: Tue Mar 12 13:39:02 2019 -0700 - - Add a new gdbarch method to resolve the address of TLS variables. - - Permit TLS variable addresses to be resolved purely by an ABI rather - than requiring a target method. This doesn't try the target method if - the ABI function is present (even if the ABI function fails) to - simplify error handling. - - gdb/ChangeLog: - - * gdbarch.sh (get_thread_local_address): New method. - * gdbarch.h, gdbarch.c: Regenerate. - * target.c (target_translate_tls_address): Use - gdbarch_get_thread_local_address if present instead of - target::get_thread_local_address. - -diff --git gdb/gdbarch.c gdb/gdbarch.c -index 434ee3bfcf..2b3fcef004 100644 ---- gdb/gdbarch.c -+++ gdb/gdbarch.c -@@ -251,6 +251,7 @@ struct gdbarch - CORE_ADDR deprecated_function_start_offset; - gdbarch_remote_register_number_ftype *remote_register_number; - gdbarch_fetch_tls_load_module_address_ftype *fetch_tls_load_module_address; -+ gdbarch_get_thread_local_address_ftype *get_thread_local_address; - CORE_ADDR frame_args_skip; - gdbarch_unwind_pc_ftype *unwind_pc; - gdbarch_unwind_sp_ftype *unwind_sp; -@@ -613,6 +614,7 @@ verify_gdbarch (struct gdbarch *gdbarch) - /* Skip verify of deprecated_function_start_offset, invalid_p == 0 */ - /* Skip verify of remote_register_number, invalid_p == 0 */ - /* Skip verify of fetch_tls_load_module_address, has predicate. */ -+ /* Skip verify of get_thread_local_address, has predicate. */ - /* Skip verify of frame_args_skip, invalid_p == 0 */ - /* Skip verify of unwind_pc, invalid_p == 0 */ - /* Skip verify of unwind_sp, invalid_p == 0 */ -@@ -1073,6 +1075,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) - fprintf_unfiltered (file, - "gdbarch_dump: get_syscall_number = <%s>\n", - host_address_to_string (gdbarch->get_syscall_number)); -+ fprintf_unfiltered (file, -+ "gdbarch_dump: gdbarch_get_thread_local_address_p() = %d\n", -+ gdbarch_get_thread_local_address_p (gdbarch)); -+ fprintf_unfiltered (file, -+ "gdbarch_dump: get_thread_local_address = <%s>\n", -+ host_address_to_string (gdbarch->get_thread_local_address)); - fprintf_unfiltered (file, - "gdbarch_dump: gnu_triplet_regexp = <%s>\n", - host_address_to_string (gdbarch->gnu_triplet_regexp)); -@@ -3018,6 +3026,30 @@ set_gdbarch_fetch_tls_load_module_address (struct gdbarch *gdbarch, - gdbarch->fetch_tls_load_module_address = fetch_tls_load_module_address; - } - -+int -+gdbarch_get_thread_local_address_p (struct gdbarch *gdbarch) -+{ -+ gdb_assert (gdbarch != NULL); -+ return gdbarch->get_thread_local_address != NULL; -+} -+ -+CORE_ADDR -+gdbarch_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid, CORE_ADDR lm_addr, CORE_ADDR offset) -+{ -+ gdb_assert (gdbarch != NULL); -+ gdb_assert (gdbarch->get_thread_local_address != NULL); -+ if (gdbarch_debug >= 2) -+ fprintf_unfiltered (gdb_stdlog, "gdbarch_get_thread_local_address called\n"); -+ return gdbarch->get_thread_local_address (gdbarch, ptid, lm_addr, offset); -+} -+ -+void -+set_gdbarch_get_thread_local_address (struct gdbarch *gdbarch, -+ gdbarch_get_thread_local_address_ftype get_thread_local_address) -+{ -+ gdbarch->get_thread_local_address = get_thread_local_address; -+} -+ - CORE_ADDR - gdbarch_frame_args_skip (struct gdbarch *gdbarch) - { -diff --git gdb/gdbarch.h gdb/gdbarch.h -index 75618376ab..abb72e752b 100644 ---- gdb/gdbarch.h -+++ gdb/gdbarch.h -@@ -649,6 +649,18 @@ typedef CORE_ADDR (gdbarch_fetch_tls_load_module_address_ftype) (struct objfile - extern CORE_ADDR gdbarch_fetch_tls_load_module_address (struct gdbarch *gdbarch, struct objfile *objfile); - extern void set_gdbarch_fetch_tls_load_module_address (struct gdbarch *gdbarch, gdbarch_fetch_tls_load_module_address_ftype *fetch_tls_load_module_address); - -+/* Return the thread-local address at OFFSET in the thread-local -+ storage for the thread PTID and the shared library or executable -+ file given by LM_ADDR. If that block of thread-local storage hasn't -+ been allocated yet, this function may throw an error. LM_ADDR may -+ be zero for statically linked multithreaded inferiors. */ -+ -+extern int gdbarch_get_thread_local_address_p (struct gdbarch *gdbarch); -+ -+typedef CORE_ADDR (gdbarch_get_thread_local_address_ftype) (struct gdbarch *gdbarch, ptid_t ptid, CORE_ADDR lm_addr, CORE_ADDR offset); -+extern CORE_ADDR gdbarch_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid, CORE_ADDR lm_addr, CORE_ADDR offset); -+extern void set_gdbarch_get_thread_local_address (struct gdbarch *gdbarch, gdbarch_get_thread_local_address_ftype *get_thread_local_address); -+ - extern CORE_ADDR gdbarch_frame_args_skip (struct gdbarch *gdbarch); - extern void set_gdbarch_frame_args_skip (struct gdbarch *gdbarch, CORE_ADDR frame_args_skip); - -diff --git gdb/gdbarch.sh gdb/gdbarch.sh -index 48fcebd19a..63bfbad7d9 100755 ---- gdb/gdbarch.sh -+++ gdb/gdbarch.sh -@@ -602,6 +602,14 @@ m;int;remote_register_number;int regno;regno;;default_remote_register_number;;0 - - # Fetch the target specific address used to represent a load module. - F;CORE_ADDR;fetch_tls_load_module_address;struct objfile *objfile;objfile -+ -+# Return the thread-local address at OFFSET in the thread-local -+# storage for the thread PTID and the shared library or executable -+# file given by LM_ADDR. If that block of thread-local storage hasn't -+# been allocated yet, this function may throw an error. LM_ADDR may -+# be zero for statically linked multithreaded inferiors. -+ -+M;CORE_ADDR;get_thread_local_address;ptid_t ptid, CORE_ADDR lm_addr, CORE_ADDR offset;ptid, lm_addr, offset - # - v;CORE_ADDR;frame_args_skip;;;0;;;0 - m;CORE_ADDR;unwind_pc;struct frame_info *next_frame;next_frame;;default_unwind_pc;;0 -diff --git gdb/target.c gdb/target.c -index 8579c19d05..c27157d209 100644 ---- gdb/target.c -+++ gdb/target.c -@@ -698,8 +698,9 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset) - { - volatile CORE_ADDR addr = 0; - struct target_ops *target = current_top_target (); -+ struct gdbarch *gdbarch = target_gdbarch (); - -- if (gdbarch_fetch_tls_load_module_address_p (target_gdbarch ())) -+ if (gdbarch_fetch_tls_load_module_address_p (gdbarch)) - { - ptid_t ptid = inferior_ptid; - -@@ -708,10 +709,14 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset) - CORE_ADDR lm_addr; - - /* Fetch the load module address for this objfile. */ -- lm_addr = gdbarch_fetch_tls_load_module_address (target_gdbarch (), -+ lm_addr = gdbarch_fetch_tls_load_module_address (gdbarch, - objfile); - -- addr = target->get_thread_local_address (ptid, lm_addr, offset); -+ if (gdbarch_get_thread_local_address_p (gdbarch)) -+ addr = gdbarch_get_thread_local_address (gdbarch, ptid, lm_addr, -+ offset); -+ else -+ addr = target->get_thread_local_address (ptid, lm_addr, offset); - } - /* If an error occurred, print TLS related messages here. Otherwise, - throw the error to some higher catcher. */ -@@ -766,8 +771,6 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset) - } - END_CATCH - } -- /* It wouldn't be wrong here to try a gdbarch method, too; finding -- TLS is an ABI-specific thing. But we don't do that yet. */ - else - error (_("Cannot find thread-local variables on this target")); - Property changes on: head/devel/gdb/files/commit-6e056c8178 ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/devel/gdb/files/commit-cd250a1898 =================================================================== --- head/devel/gdb/files/commit-cd250a1898 (revision 528131) +++ head/devel/gdb/files/commit-cd250a1898 (nonexistent) @@ -1,30 +0,0 @@ -commit cd250a1898bb6fdb41f4a1063dbcfac04affcd11 -Author: John Baldwin -Date: Tue Mar 12 13:39:02 2019 -0700 - - Update comment for target::get_thread_local_address. - - There isn't an 'objfile' parameter, instead 'load_module_addr' is used - to indicate the executable or shared library. Also, the function - throws errors rather than returning error values. - - gdb/ChangeLog: - - * target.h (target::get_thread_local_address): Update comment. - -diff --git gdb/target.h gdb/target.h -index c95151a404..5fe6aa74b0 100644 ---- gdb/target.h -+++ gdb/target.h -@@ -718,9 +718,9 @@ struct target_ops - TARGET_DEFAULT_NORETURN (tcomplain ()); - /* Return the thread-local address at OFFSET in the - thread-local storage for the thread PTID and the shared library -- or executable file given by OBJFILE. If that block of -+ or executable file given by LOAD_MODULE_ADDR. If that block of - thread-local storage hasn't been allocated yet, this function -- may return an error. LOAD_MODULE_ADDR may be zero for statically -+ may throw an error. LOAD_MODULE_ADDR may be zero for statically - linked multithreaded inferiors. */ - virtual CORE_ADDR get_thread_local_address (ptid_t ptid, - CORE_ADDR load_module_addr, Property changes on: head/devel/gdb/files/commit-cd250a1898 ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/devel/gdb/files/commit-dd6876c91c =================================================================== --- head/devel/gdb/files/commit-dd6876c91c (revision 528131) +++ head/devel/gdb/files/commit-dd6876c91c (nonexistent) @@ -1,237 +0,0 @@ -commit dd6876c91cd40cc105b1a91f418ca2c80683b314 -Author: John Baldwin -Date: Tue Mar 12 13:39:02 2019 -0700 - - Support fs_base and gs_base on FreeBSD/i386. - - The i386 BSD native target uses the same ptrace operations - (PT_[GS]ET[FG]SBASE) as the amd64 BSD native target to fetch and store - the registers. - - The amd64 BSD native now uses 'tdep->fsbase_regnum' instead of - hardcoding AMD64_FSBASE_REGNUM and AMD64_GSBASE_REGNUM to support - 32-bit targets. In addition, the store operations explicitly zero the - new register value before fetching it from the register cache to - ensure 32-bit values are zero-extended. - - gdb/ChangeLog: - - * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers): Use - tdep->fsbase_regnum instead of constants for fs_base and gs_base. - (amd64bsd_store_inferior_registers): Likewise. - * amd64-fbsd-nat.c (amd64_fbsd_nat_target::read_description): - Enable segment base registers. - * i386-bsd-nat.c (i386bsd_fetch_inferior_registers): Use - PT_GETFSBASE and PT_GETGSBASE. - (i386bsd_store_inferior_registers): Use PT_SETFSBASE and - PT_SETGSBASE. - * i386-fbsd-nat.c (i386_fbsd_nat_target::read_description): Enable - segment base registers. - * i386-fbsd-tdep.c (i386fbsd_core_read_description): Likewise. - -diff --git gdb/amd64-bsd-nat.c gdb/amd64-bsd-nat.c -index a2a91abb91..35763a5b95 100644 ---- gdb/amd64-bsd-nat.c -+++ gdb/amd64-bsd-nat.c -@@ -43,6 +43,9 @@ amd64bsd_fetch_inferior_registers (struct regcache *regcache, int regnum) - { - struct gdbarch *gdbarch = regcache->arch (); - pid_t pid = get_ptrace_pid (regcache->ptid ()); -+#if defined(PT_GETFSBASE) || defined(PT_GETGSBASE) -+ const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); -+#endif - - if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum)) - { -@@ -57,27 +60,27 @@ amd64bsd_fetch_inferior_registers (struct regcache *regcache, int regnum) - } - - #ifdef PT_GETFSBASE -- if (regnum == -1 || regnum == AMD64_FSBASE_REGNUM) -+ if (regnum == -1 || regnum == tdep->fsbase_regnum) - { - register_t base; - - if (ptrace (PT_GETFSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) - perror_with_name (_("Couldn't get segment register fs_base")); - -- regcache->raw_supply (AMD64_FSBASE_REGNUM, &base); -+ regcache->raw_supply (tdep->fsbase_regnum, &base); - if (regnum != -1) - return; - } - #endif - #ifdef PT_GETGSBASE -- if (regnum == -1 || regnum == AMD64_GSBASE_REGNUM) -+ if (regnum == -1 || regnum == tdep->fsbase_regnum + 1) - { - register_t base; - - if (ptrace (PT_GETGSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) - perror_with_name (_("Couldn't get segment register gs_base")); - -- regcache->raw_supply (AMD64_GSBASE_REGNUM, &base); -+ regcache->raw_supply (tdep->fsbase_regnum + 1, &base); - if (regnum != -1) - return; - } -@@ -116,6 +119,9 @@ amd64bsd_store_inferior_registers (struct regcache *regcache, int regnum) - { - struct gdbarch *gdbarch = regcache->arch (); - pid_t pid = get_ptrace_pid (regcache->ptid ()); -+#if defined(PT_SETFSBASE) || defined(PT_SETGSBASE) -+ const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); -+#endif - - if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum)) - { -@@ -134,11 +140,13 @@ amd64bsd_store_inferior_registers (struct regcache *regcache, int regnum) - } - - #ifdef PT_SETFSBASE -- if (regnum == -1 || regnum == AMD64_FSBASE_REGNUM) -+ if (regnum == -1 || regnum == tdep->fsbase_regnum) - { - register_t base; - -- regcache->raw_collect (AMD64_FSBASE_REGNUM, &base); -+ /* Clear the full base value to support 32-bit targets. */ -+ base = 0; -+ regcache->raw_collect (tdep->fsbase_regnum, &base); - - if (ptrace (PT_SETFSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) - perror_with_name (_("Couldn't write segment register fs_base")); -@@ -147,11 +155,13 @@ amd64bsd_store_inferior_registers (struct regcache *regcache, int regnum) - } - #endif - #ifdef PT_SETGSBASE -- if (regnum == -1 || regnum == AMD64_GSBASE_REGNUM) -+ if (regnum == -1 || regnum == tdep->fsbase_regnum + 1) - { - register_t base; - -- regcache->raw_collect (AMD64_GSBASE_REGNUM, &base); -+ /* Clear the full base value to support 32-bit targets. */ -+ base = 0; -+ regcache->raw_collect (tdep->fsbase_regnum + 1, &base); - - if (ptrace (PT_SETGSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) - perror_with_name (_("Couldn't write segment register gs_base")); -diff --git gdb/amd64-fbsd-nat.c gdb/amd64-fbsd-nat.c -index 9fff763dd3..cc676d3214 100644 ---- gdb/amd64-fbsd-nat.c -+++ gdb/amd64-fbsd-nat.c -@@ -190,13 +190,13 @@ amd64_fbsd_nat_target::read_description () - if (is64) - return amd64_target_description (xcr0, true); - else -- return i386_target_description (xcr0, false); -+ return i386_target_description (xcr0, true); - } - #endif - if (is64) - return amd64_target_description (X86_XSTATE_SSE_MASK, true); - else -- return i386_target_description (X86_XSTATE_SSE_MASK, false); -+ return i386_target_description (X86_XSTATE_SSE_MASK, true); - } - - #if defined(HAVE_PT_GETDBREGS) && defined(USE_SIGTRAP_SIGINFO) -diff --git gdb/i386-bsd-nat.c gdb/i386-bsd-nat.c -index 009a8dc1b2..a10b496096 100644 ---- gdb/i386-bsd-nat.c -+++ gdb/i386-bsd-nat.c -@@ -144,6 +144,33 @@ i386bsd_fetch_inferior_registers (struct regcache *regcache, int regnum) - return; - } - -+#ifdef PT_GETFSBASE -+ if (regnum == -1 || regnum == I386_FSBASE_REGNUM) -+ { -+ register_t base; -+ -+ if (ptrace (PT_GETFSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) -+ perror_with_name (_("Couldn't get segment register fs_base")); -+ -+ regcache->raw_supply (I386_FSBASE_REGNUM, &base); -+ if (regnum != -1) -+ return; -+ } -+#endif -+#ifdef PT_GETGSBASE -+ if (regnum == -1 || regnum == I386_GSBASE_REGNUM) -+ { -+ register_t base; -+ -+ if (ptrace (PT_GETGSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) -+ perror_with_name (_("Couldn't get segment register gs_base")); -+ -+ regcache->raw_supply (I386_GSBASE_REGNUM, &base); -+ if (regnum != -1) -+ return; -+ } -+#endif -+ - if (regnum == -1 || regnum >= I386_ST0_REGNUM) - { - struct fpreg fpregs; -@@ -211,6 +238,33 @@ i386bsd_store_inferior_registers (struct regcache *regcache, int regnum) - return; - } - -+#ifdef PT_SETFSBASE -+ if (regnum == -1 || regnum == I386_FSBASE_REGNUM) -+ { -+ register_t base; -+ -+ regcache->raw_collect (I386_FSBASE_REGNUM, &base); -+ -+ if (ptrace (PT_SETFSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) -+ perror_with_name (_("Couldn't write segment register fs_base")); -+ if (regnum != -1) -+ return; -+ } -+#endif -+#ifdef PT_SETGSBASE -+ if (regnum == -1 || regnum == I386_GSBASE_REGNUM) -+ { -+ register_t base; -+ -+ regcache->raw_collect (I386_GSBASE_REGNUM, &base); -+ -+ if (ptrace (PT_SETGSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) -+ perror_with_name (_("Couldn't write segment register gs_base")); -+ if (regnum != -1) -+ return; -+ } -+#endif -+ - if (regnum == -1 || regnum >= I386_ST0_REGNUM) - { - struct fpreg fpregs; -diff --git gdb/i386-fbsd-nat.c gdb/i386-fbsd-nat.c -index 7106e90801..be5d4c67be 100644 ---- gdb/i386-fbsd-nat.c -+++ gdb/i386-fbsd-nat.c -@@ -160,7 +160,7 @@ i386_fbsd_nat_target::read_description () - if (x86bsd_xsave_len == 0) - xcr0 = X86_XSTATE_SSE_MASK; - -- return i386_target_description (xcr0, false); -+ return i386_target_description (xcr0, true); - } - #endif - -diff --git gdb/i386-fbsd-tdep.c gdb/i386-fbsd-tdep.c -index 2f28bad728..ac57e7383d 100644 ---- gdb/i386-fbsd-tdep.c -+++ gdb/i386-fbsd-tdep.c -@@ -267,7 +267,7 @@ i386fbsd_core_read_description (struct gdbarch *gdbarch, - struct target_ops *target, - bfd *abfd) - { -- return i386_target_description (i386fbsd_core_read_xcr0 (abfd), false); -+ return i386_target_description (i386fbsd_core_read_xcr0 (abfd), true); - } - - /* Similar to i386_supply_fpregset, but use XSAVE extended state. */ Property changes on: head/devel/gdb/files/commit-dd6876c91c ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/devel/gdb/files/commit-8399425f5f =================================================================== --- head/devel/gdb/files/commit-8399425f5f (revision 528131) +++ head/devel/gdb/files/commit-8399425f5f (nonexistent) @@ -1,69 +0,0 @@ -commit 8399425f5f472ad8e630bb30ad2dbefeddbb68b7 -Author: John Baldwin -Date: Tue Mar 12 13:39:02 2019 -0700 - - Support TLS variables on FreeBSD/powerpc. - - Derive the pointer to the DTV array from the %r2 register on 32-bit - powerpc and %r13 on 64-bit powerpc. - - gdb/ChangeLog: - - * ppc-fbsd-tdep.c (ppcfbsd_get_thread_local_address): New. - (ppcfbsd_init_abi): Install gdbarch - "fetch_tls_load_module_address" and "get_thread_local_address" - methods. - -diff --git gdb/ppc-fbsd-tdep.c gdb/ppc-fbsd-tdep.c -index c21a52c898..290bd1fd88 100644 ---- gdb/ppc-fbsd-tdep.c -+++ gdb/ppc-fbsd-tdep.c -@@ -279,6 +279,39 @@ ppcfbsd_return_value (struct gdbarch *gdbarch, struct value *function, - regcache, readbuf, writebuf); - } - -+/* Implement the "get_thread_local_address" gdbarch method. */ -+ -+static CORE_ADDR -+ppcfbsd_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid, -+ CORE_ADDR lm_addr, CORE_ADDR offset) -+{ -+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); -+ struct regcache *regcache; -+ int tp_offset, tp_regnum; -+ -+ regcache = get_thread_arch_regcache (ptid, gdbarch); -+ -+ if (tdep->wordsize == 4) -+ { -+ tp_offset = 0x7008; -+ tp_regnum = PPC_R0_REGNUM + 2; -+ } -+ else -+ { -+ tp_offset = 0x7010; -+ tp_regnum = PPC_R0_REGNUM + 13; -+ } -+ target_fetch_registers (regcache, tp_regnum); -+ -+ ULONGEST tp; -+ if (regcache->cooked_read (tp_regnum, &tp) != REG_VALID) -+ error (_("Unable to fetch tcb pointer")); -+ -+ /* tp points to the end of the TCB block. The first member of the -+ TCB is the pointer to the DTV array. */ -+ CORE_ADDR dtv_addr = tp - tp_offset; -+ return fbsd_get_thread_local_address (gdbarch, dtv_addr, lm_addr, offset); -+} - - static void - ppcfbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) -@@ -322,6 +355,8 @@ ppcfbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) - - set_gdbarch_fetch_tls_load_module_address (gdbarch, - svr4_fetch_objfile_link_map); -+ set_gdbarch_get_thread_local_address (gdbarch, -+ ppcfbsd_get_thread_local_address); - } - - void Property changes on: head/devel/gdb/files/commit-8399425f5f ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/devel/gdb/files/commit-b0f87ed032 =================================================================== --- head/devel/gdb/files/commit-b0f87ed032 (revision 528131) +++ head/devel/gdb/files/commit-b0f87ed032 (nonexistent) @@ -1,60 +0,0 @@ -commit b0f87ed032bb68a9965de81cbf9fd676a83b9174 -Author: John Baldwin -Date: Tue Mar 12 13:39:02 2019 -0700 - - Support TLS variables on FreeBSD/riscv. - - Derive the pointer to the DTV array from the tp register. - - gdb/ChangeLog: - - * riscv-fbsd-tdep.c (riscv_fbsd_get_thread_local_address): New. - (riscv_fbsd_init_abi): Install gdbarch - "fetch_tls_load_module_address" and "get_thread_local_address" - methods. - -diff --git gdb/riscv-fbsd-tdep.c gdb/riscv-fbsd-tdep.c -index 97ad28f59a..3125a2285e 100644 ---- gdb/riscv-fbsd-tdep.c -+++ gdb/riscv-fbsd-tdep.c -@@ -174,6 +174,28 @@ static const struct tramp_frame riscv_fbsd_sigframe = - riscv_fbsd_sigframe_init - }; - -+/* Implement the "get_thread_local_address" gdbarch method. */ -+ -+static CORE_ADDR -+riscv_fbsd_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid, -+ CORE_ADDR lm_addr, CORE_ADDR offset) -+{ -+ struct regcache *regcache; -+ -+ regcache = get_thread_arch_regcache (ptid, gdbarch); -+ -+ target_fetch_registers (regcache, RISCV_TP_REGNUM); -+ -+ ULONGEST tp; -+ if (regcache->cooked_read (RISCV_TP_REGNUM, &tp) != REG_VALID) -+ error (_("Unable to fetch %%tp")); -+ -+ /* %tp points to the end of the TCB which contains two pointers. -+ The first pointer in the TCB points to the DTV array. */ -+ CORE_ADDR dtv_addr = tp - (gdbarch_ptr_bit (gdbarch) / 8) * 2; -+ return fbsd_get_thread_local_address (gdbarch, dtv_addr, lm_addr, offset); -+} -+ - /* Implement the 'init_osabi' method of struct gdb_osabi_handler. */ - - static void -@@ -193,6 +215,11 @@ riscv_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) - - set_gdbarch_iterate_over_regset_sections - (gdbarch, riscv_fbsd_iterate_over_regset_sections); -+ -+ set_gdbarch_fetch_tls_load_module_address (gdbarch, -+ svr4_fetch_objfile_link_map); -+ set_gdbarch_get_thread_local_address (gdbarch, -+ riscv_fbsd_get_thread_local_address); - } - - void Property changes on: head/devel/gdb/files/commit-b0f87ed032 ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/devel/gdb/files/commit-36c53a0262 =================================================================== --- head/devel/gdb/files/commit-36c53a0262 (revision 528131) +++ head/devel/gdb/files/commit-36c53a0262 (nonexistent) @@ -1,60 +0,0 @@ -commit 36c53a0262f84ad11d738471789dadfa9c4eb320 -Author: John Baldwin -Date: Tue Mar 12 13:39:02 2019 -0700 - - Remove code disabled since at least 1999 from lookup_struct_elt_type. - - Update the comment above the function to reflect the code removal and - document the existing behavior. - - gdb/ChangeLog: - - * gdbtypes.c (lookup_struct_elt_type): Update comment and - remove disabled code block. - -diff --git gdb/gdbtypes.c gdb/gdbtypes.c -index 09284ef259..5924b15520 100644 ---- gdb/gdbtypes.c -+++ gdb/gdbtypes.c -@@ -1644,8 +1644,7 @@ lookup_template_type (char *name, struct type *type, - return (SYMBOL_TYPE (sym)); - } - --/* Given a type TYPE, lookup the type of the component of type named -- NAME. -+/* Given a type TYPE, lookup the type of the component named NAME. - - TYPE can be either a struct or union, or a pointer or reference to - a struct or union. If it is a pointer or reference, its target -@@ -1653,8 +1652,8 @@ lookup_template_type (char *name, struct type *type, - as specified for the definitions of the expression element types - STRUCTOP_STRUCT and STRUCTOP_PTR. - -- If NOERR is nonzero, return zero if NAME is not suitably defined. -- If NAME is the name of a baseclass type, return that type. */ -+ If NOERR is nonzero, return NULL if there is no component named -+ NAME. */ - - struct type * - lookup_struct_elt_type (struct type *type, const char *name, int noerr) -@@ -1678,20 +1677,6 @@ lookup_struct_elt_type (struct type *type, const char *name, int noerr) - type_name.c_str ()); - } - --#if 0 -- /* FIXME: This change put in by Michael seems incorrect for the case -- where the structure tag name is the same as the member name. -- I.e. when doing "ptype bell->bar" for "struct foo { int bar; int -- foo; } bell;" Disabled by fnf. */ -- { -- char *type_name; -- -- type_name = TYPE_NAME (type); -- if (type_name != NULL && strcmp (type_name, name) == 0) -- return type; -- } --#endif -- - for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--) - { - const char *t_field_name = TYPE_FIELD_NAME (type, i); Property changes on: head/devel/gdb/files/commit-36c53a0262 ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/devel/gdb/files/commit-df22c1e5d5 =================================================================== --- head/devel/gdb/files/commit-df22c1e5d5 (revision 528131) +++ head/devel/gdb/files/commit-df22c1e5d5 (nonexistent) @@ -1,36 +0,0 @@ -commit df22c1e5d53c38f38bce6072bb46de240f9e0e2b -Author: John Baldwin -Date: Tue Mar 12 13:39:02 2019 -0700 - - Handle an edge case for minisym TLS variable lookups. - - If a TLS variable is provided by a minisym from a separate debug file, - the separate debug file is passed to - gdbarch_fetch_tls_load_module_address. However, the object files - stored in the shared object list are the original object files, not - the separate debug object files. In this case, - svr4_fetch_objfile_link_map was failing to find the link map entry - since the debug object file is not in its internal list, only the - original object file. - - gdb/ChangeLog: - - * solib-svr4.c (svr4_fetch_objfile_link_map): Look for - objfile->separate_debug_objfile_backlink if not NULL. - -diff --git gdb/solib-svr4.c gdb/solib-svr4.c -index 84693c1766..14a471b6dc 100644 ---- gdb/solib-svr4.c -+++ gdb/solib-svr4.c -@@ -1551,6 +1551,11 @@ svr4_fetch_objfile_link_map (struct objfile *objfile) - if (objfile == symfile_objfile) - return info->main_lm_addr; - -+ /* If OBJFILE is a separate debug object file, look for the -+ original object file. */ -+ if (objfile->separate_debug_objfile_backlink != NULL) -+ objfile = objfile->separate_debug_objfile_backlink; -+ - /* The other link map addresses may be found by examining the list - of shared libraries. */ - for (so = master_so_list (); so; so = so->next) Property changes on: head/devel/gdb/files/commit-df22c1e5d5 ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/devel/gdb/files/commit-f5424cfa7e =================================================================== --- head/devel/gdb/files/commit-f5424cfa7e (revision 528131) +++ head/devel/gdb/files/commit-f5424cfa7e (nonexistent) @@ -1,63 +0,0 @@ -commit f5424cfa7e9337a6cb02a1f83c9feea0995c5350 -Author: John Baldwin -Date: Tue Mar 12 13:39:02 2019 -0700 - - Support TLS variables on FreeBSD/amd64. - - Use the fs_base register to fetch the address of a thread's tcb and - calculate the address of the DTV array. This value is then passed to - fbsd_get_thread_local_address to compute the final variable address. - - Note that fs_base is currently only available via the native target as - core dumps on FreeBSD do not store the value of fs_base. - - gdb/ChangeLog: - - * amd64-fbsd-tdep.c (amd64fbsd_get_thread_local_address): New. - (amd64fbsd_init_abi): Install gdbarch - "fetch_tls_load_module_address" and "get_thread_local_address" - methods. - -diff --git gdb/amd64-fbsd-tdep.c gdb/amd64-fbsd-tdep.c -index 403e65022d..7e2e9edf21 100644 ---- gdb/amd64-fbsd-tdep.c -+++ gdb/amd64-fbsd-tdep.c -@@ -204,6 +204,26 @@ amd64fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch, - &amd64fbsd_xstateregset, "XSAVE extended state", cb_data); - } - -+/* Implement the get_thread_local_address gdbarch method. */ -+ -+static CORE_ADDR -+amd64fbsd_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid, -+ CORE_ADDR lm_addr, CORE_ADDR offset) -+{ -+ struct regcache *regcache; -+ -+ regcache = get_thread_arch_regcache (ptid, gdbarch); -+ -+ target_fetch_registers (regcache, AMD64_FSBASE_REGNUM); -+ -+ ULONGEST fsbase; -+ if (regcache->cooked_read (AMD64_FSBASE_REGNUM, &fsbase) != REG_VALID) -+ error (_("Unable to fetch %%fsbase")); -+ -+ CORE_ADDR dtv_addr = fsbase + gdbarch_ptr_bit (gdbarch) / 8; -+ return fbsd_get_thread_local_address (gdbarch, dtv_addr, lm_addr, offset); -+} -+ - static void - amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) - { -@@ -241,6 +261,11 @@ amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) - /* FreeBSD uses SVR4-style shared libraries. */ - set_solib_svr4_fetch_link_map_offsets - (gdbarch, svr4_lp64_fetch_link_map_offsets); -+ -+ set_gdbarch_fetch_tls_load_module_address (gdbarch, -+ svr4_fetch_objfile_link_map); -+ set_gdbarch_get_thread_local_address (gdbarch, -+ amd64fbsd_get_thread_local_address); - } - - void Property changes on: head/devel/gdb/files/commit-f5424cfa7e ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/devel/gdb/files/extrapatch-kgdb =================================================================== --- head/devel/gdb/files/extrapatch-kgdb (revision 528131) +++ head/devel/gdb/files/extrapatch-kgdb (revision 528132) @@ -1,549 +1,540 @@ diff --git gdb/Makefile.in gdb/Makefile.in -index 5614cc3386..b9acc63c3f 100644 +index c3e074b21f..8d026a98cb 100644 --- gdb/Makefile.in +++ gdb/Makefile.in -@@ -230,7 +230,8 @@ INCGNU = -I$(srcdir)/gnulib/import -I$(GNULIB_BUILDDIR)/import - - # Generated headers in the gnulib directory. These must be listed - # so that they are generated before other files are compiled. --GNULIB_H = $(GNULIB_BUILDDIR)/import/string.h @GNULIB_STDINT_H@ -+GNULIB_H = $(GNULIB_BUILDDIR)/import/string.h \ -+ $(GNULIB_BUILDDIR)/import/alloca.h @GNULIB_STDINT_H@ - - # - # CLI sub directory definitons -@@ -632,6 +633,7 @@ TARGET_OBS = @TARGET_OBS@ +@@ -648,6 +648,7 @@ TARGET_OBS = @TARGET_OBS@ # All target-dependent objects files that require 64-bit CORE_ADDR # (used with --enable-targets=all --enable-64-bit-bfd). ALL_64_TARGET_OBS = \ + aarch64-fbsd-kern.o \ aarch64-fbsd-tdep.o \ aarch64-linux-tdep.o \ aarch64-newlib-tdep.o \ -@@ -646,6 +648,7 @@ ALL_64_TARGET_OBS = \ +@@ -662,6 +663,7 @@ ALL_64_TARGET_OBS = \ amd64-darwin-tdep.o \ amd64-dicos-tdep.o \ amd64-fbsd-tdep.o \ + amd64fbsd-kern.o \ amd64-linux-tdep.o \ amd64-nbsd-tdep.o \ amd64-obsd-tdep.o \ -@@ -660,6 +663,7 @@ ALL_64_TARGET_OBS = \ +@@ -676,6 +678,7 @@ ALL_64_TARGET_OBS = \ ia64-vms-tdep.o \ mips64-obsd-tdep.o \ sparc64-fbsd-tdep.o \ + sparc64fbsd-kern.o \ sparc64-linux-tdep.o \ sparc64-nbsd-tdep.o \ sparc64-obsd-tdep.o \ -@@ -676,6 +680,7 @@ ALL_TARGET_OBS = \ +@@ -694,6 +697,7 @@ ALL_TARGET_OBS = \ arch/ppc-linux-common.o \ arch/riscv.o \ arm-bsd-tdep.o \ + arm-fbsd-kern.o \ arm-fbsd-tdep.o \ arm-linux-tdep.o \ arm-nbsd-tdep.o \ -@@ -693,6 +698,8 @@ ALL_TARGET_OBS = \ +@@ -711,6 +715,8 @@ ALL_TARGET_OBS = \ csky-linux-tdep.o \ csky-tdep.o \ dicos-tdep.o \ + fbsd-kld.o \ + fbsd-kthr.o \ fbsd-tdep.o \ frv-linux-tdep.o \ frv-tdep.o \ -@@ -709,6 +716,7 @@ ALL_TARGET_OBS = \ +@@ -727,6 +733,7 @@ ALL_TARGET_OBS = \ i386-darwin-tdep.o \ i386-dicos-tdep.o \ i386-fbsd-tdep.o \ + i386fbsd-kern.o \ i386-gnu-tdep.o \ i386-go32-tdep.o \ i386-linux-tdep.o \ -@@ -732,6 +740,7 @@ ALL_TARGET_OBS = \ +@@ -750,6 +757,7 @@ ALL_TARGET_OBS = \ mep-tdep.o \ microblaze-linux-tdep.o \ microblaze-tdep.o \ + mipsfbsd-kern.o \ mips-fbsd-tdep.o \ mips-linux-tdep.o \ mips-nbsd-tdep.o \ -@@ -750,6 +759,7 @@ ALL_TARGET_OBS = \ +@@ -768,6 +776,7 @@ ALL_TARGET_OBS = \ or1k-linux-tdep.o \ or1k-tdep.o \ ppc-fbsd-tdep.o \ + ppcfbsd-kern.o \ ppc-linux-tdep.o \ ppc-nbsd-tdep.o \ ppc-obsd-tdep.o \ -@@ -757,6 +767,7 @@ ALL_TARGET_OBS = \ +@@ -775,6 +784,7 @@ ALL_TARGET_OBS = \ ppc-sysv-tdep.o \ ppc64-tdep.o \ ravenscar-thread.o \ + riscv-fbsd-kern.o \ riscv-fbsd-tdep.o \ riscv-linux-tdep.o \ riscv-tdep.o \ -@@ -1629,7 +1640,7 @@ generated_files = \ +@@ -1648,7 +1658,7 @@ generated_files = \ # Flags needed to compile Python code PYTHON_CFLAGS = @PYTHON_CFLAGS@ -all: gdb$(EXEEXT) $(CONFIG_ALL) gdb-gdb.py gdb-gdb.gdb +all: gdb$(EXEEXT) kgdb$(EXEEXT) $(CONFIG_ALL) gdb-gdb.py gdb-gdb.gdb @$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed 's/testsuite//'`" subdir_do # Rule for compiling .c files in the top-level gdb directory. -@@ -1894,6 +1905,12 @@ ifneq ($(CODESIGN_CERT),) +@@ -1913,6 +1923,12 @@ ifneq ($(CODESIGN_CERT),) $(ECHO_SIGN) $(CODESIGN) -s $(CODESIGN_CERT) gdb$(EXEEXT) endif +kgdb$(EXEEXT): kgdb-main.o $(LIBGDB_OBS) $(ADD_DEPS) $(CDEPS) $(TDEPLIBS) + $(SILENCE) rm -f kgdb$(EXEEXT) + $(ECHO_CXXLD) $(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) \ + -o kgdb$(EXEEXT) kgdb-main.o $(LIBGDB_OBS) \ + $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES) + # Convenience rule to handle recursion. - $(LIBGNU) $(GNULIB_H): all-lib - all-lib: $(GNULIB_BUILDDIR)/Makefile -@@ -1940,6 +1957,7 @@ clean mostlyclean: $(CONFIG_CLEAN) + .PHONY: all-data-directory + all-data-directory: data-directory/Makefile +@@ -1953,6 +1969,7 @@ clean mostlyclean: $(CONFIG_CLEAN) rm -f init.c stamp-init version.c stamp-version rm -f gdb$(EXEEXT) core make.log rm -f gdb[0-9]$(EXEEXT) + rm -f kgdb$(EXEEXT) rm -f test-cp-name-parser$(EXEEXT) rm -f xml-builtin.c stamp-xml rm -f $(DEPDIR)/* -@@ -2154,6 +2172,7 @@ force_update: - MAKEOVERRIDES = +@@ -2152,6 +2169,7 @@ MAKEOVERRIDES = ALLDEPFILES = \ + aarch32-tdep.c \ + aarch64-fbsd-kern.c \ aarch64-fbsd-nat.c \ aarch64-fbsd-tdep.c \ aarch64-linux-nat.c \ -@@ -2173,6 +2192,7 @@ ALLDEPFILES = \ +@@ -2171,6 +2189,7 @@ ALLDEPFILES = \ amd64-bsd-nat.c \ amd64-darwin-tdep.c \ amd64-dicos-tdep.c \ + amd64fbsd-kern.c \ amd64-fbsd-nat.c \ amd64-fbsd-tdep.c \ amd64-linux-nat.c \ -@@ -2187,6 +2207,7 @@ ALLDEPFILES = \ +@@ -2185,6 +2204,7 @@ ALLDEPFILES = \ arc-tdep.c \ arm.c \ arm-bsd-tdep.c \ + arm-fbsd-kern.c \ arm-fbsd-nat.c \ arm-fbsd-tdep.c \ arm-get-next-pcs.c \ -@@ -2207,6 +2228,9 @@ ALLDEPFILES = \ +@@ -2205,6 +2225,9 @@ ALLDEPFILES = \ csky-tdep.c \ darwin-nat.c \ dicos-tdep.c \ + fbsd-kld.c \ + fbsd-kthr.c \ + fbsd-kvm.c \ fbsd-nat.c \ fbsd-tdep.c \ fork-child.c \ -@@ -2228,6 +2252,7 @@ ALLDEPFILES = \ +@@ -2226,6 +2249,7 @@ ALLDEPFILES = \ i386-darwin-nat.c \ i386-darwin-tdep.c \ i386-dicos-tdep.c \ + i386fbsd-kern.c \ i386-fbsd-nat.c \ i386-fbsd-tdep.c \ i386-gnu-nat.c \ -@@ -2264,6 +2289,7 @@ ALLDEPFILES = \ +@@ -2262,6 +2286,7 @@ ALLDEPFILES = \ microblaze-linux-tdep.c \ microblaze-tdep.c \ mingw-hdep.c \ + mipsfbsd-kern.c \ mips-fbsd-nat.c \ mips-fbsd-tdep.c \ mips-linux-nat.c \ -@@ -2283,6 +2309,7 @@ ALLDEPFILES = \ +@@ -2281,6 +2306,7 @@ ALLDEPFILES = \ obsd-nat.c \ obsd-tdep.c \ posix-hdep.c \ + ppcfbsd-kern.c \ ppc-fbsd-nat.c \ ppc-fbsd-tdep.c \ ppc-linux-nat.c \ -@@ -2297,6 +2324,7 @@ ALLDEPFILES = \ +@@ -2295,6 +2321,7 @@ ALLDEPFILES = \ procfs.c \ ravenscar-thread.c \ remote-sim.c \ + riscv-fbsd-kern.c \ riscv-fbsd-nat.c \ riscv-fbsd-tdep.c \ riscv-linux-nat.c \ -@@ -2333,6 +2361,7 @@ ALLDEPFILES = \ +@@ -2330,6 +2357,7 @@ ALLDEPFILES = \ sparc-sol2-nat.c \ sparc-sol2-tdep.c \ sparc-tdep.c \ + sparc64fbsd-kern.c \ sparc64-fbsd-nat.c \ sparc64-fbsd-tdep.c \ sparc64-linux-nat.c \ -@@ -2596,7 +2625,7 @@ endif +@@ -2588,7 +2616,7 @@ endif # A list of all the objects we might care about in this build, for # dependency tracking. -all_object_files = gdb.o $(LIBGDB_OBS) gdbtk-main.o \ +all_object_files = kgdb-main.o gdb.o $(LIBGDB_OBS) gdbtk-main.o \ test-cp-name-parser.o # All the .deps files to include. diff --git gdb/config.in gdb/config.in -index ea907d2b56..1019e448c5 100644 +index cb886ba8e1..b8a937f6de 100644 --- gdb/config.in +++ gdb/config.in -@@ -219,6 +219,12 @@ +@@ -218,6 +218,12 @@ /* Define to 1 if your system has the kinfo_getvmmap function. */ #undef HAVE_KINFO_GETVMMAP +/* Define to 1 if your system has the kvm_kerndisp function. */ +#undef HAVE_KVM_DISP + +/* Define to 1 if your system has the kvm_open2 function. */ +#undef HAVE_KVM_OPEN2 + /* Define if you have and nl_langinfo(CODESET). */ #undef HAVE_LANGINFO_CODESET diff --git gdb/configure gdb/configure -index 854837c50a..df64effa90 100755 +index b572d414ca..12e08354cc 100755 --- gdb/configure +++ gdb/configure -@@ -8107,6 +8107,126 @@ $as_echo "#define HAVE_KINFO_GETFILE 1" >>confdefs.h +@@ -8064,6 +8064,126 @@ $as_echo "#define HAVE_KINFO_GETFILE 1" >>confdefs.h fi +# kgdb needs kvm_open2 for cross-debugging +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing kvm_open2" >&5 +$as_echo_n "checking for library containing kvm_open2... " >&6; } +if ${ac_cv_search_kvm_open2+:} false; 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 kvm_open2 (); +int +main () +{ +return kvm_open2 (); + ; + return 0; +} +_ACEOF +for ac_lib in '' kvm; 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_kvm_open2=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_kvm_open2+:} false; then : + break +fi +done +if ${ac_cv_search_kvm_open2+:} false; then : + +else + ac_cv_search_kvm_open2=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_kvm_open2" >&5 +$as_echo "$ac_cv_search_kvm_open2" >&6; } +ac_res=$ac_cv_search_kvm_open2 +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define HAVE_KVM_OPEN2 1" >>confdefs.h + +fi + + +# kgdb needs kvm_kerndisp for relocatable kernels +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing kvm_kerndisp" >&5 +$as_echo_n "checking for library containing kvm_kerndisp... " >&6; } +if ${ac_cv_search_kvm_kerndisp+:} false; 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 kvm_kerndisp (); +int +main () +{ +return kvm_kerndisp (); + ; + return 0; +} +_ACEOF +for ac_lib in '' kvm; 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_kvm_kerndisp=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_kvm_kerndisp+:} false; then : + break +fi +done +if ${ac_cv_search_kvm_kerndisp+:} false; then : + +else + ac_cv_search_kvm_kerndisp=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_kvm_kerndisp" >&5 +$as_echo "$ac_cv_search_kvm_kerndisp" >&6; } +ac_res=$ac_cv_search_kvm_kerndisp +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define HAVE_KVM_DISP 1" >>confdefs.h + +fi + + if test "X$prefix" = "XNONE"; then acl_final_prefix="$ac_default_prefix" diff --git gdb/configure.ac gdb/configure.ac -index 1527585839..7ff0361e69 100644 +index ca0da7980c..39dc6a3559 100644 --- gdb/configure.ac +++ gdb/configure.ac -@@ -511,6 +511,16 @@ AC_SEARCH_LIBS(kinfo_getfile, util util-freebsd, +@@ -485,6 +485,16 @@ AC_SEARCH_LIBS(kinfo_getfile, util util-freebsd, [AC_DEFINE(HAVE_KINFO_GETFILE, 1, [Define to 1 if your system has the kinfo_getfile function. ])]) +# kgdb needs kvm_open2 for cross-debugging +AC_SEARCH_LIBS(kvm_open2, kvm, + [AC_DEFINE(HAVE_KVM_OPEN2, 1, + [Define to 1 if your system has the kvm_open2 function. ])]) + +# kgdb needs kvm_kerndisp for relocatable kernels +AC_SEARCH_LIBS(kvm_kerndisp, kvm, + [AC_DEFINE(HAVE_KVM_DISP, 1, + [Define to 1 if your system has the kvm_kerndisp function. ])]) + AM_ICONV # GDB may fork/exec the iconv program to get the list of supported character diff --git gdb/configure.nat gdb/configure.nat -index 64ee101d83..f32e6328e0 100644 +index fb4522f579..a5059ff37d 100644 --- gdb/configure.nat +++ gdb/configure.nat @@ -63,7 +63,8 @@ case ${gdb_host} in LOADLIBES='-ldl $(RDYNAMIC)' ;; fbsd*) - NATDEPFILES='fork-child.o nat/fork-inferior.o inf-ptrace.o fbsd-nat.o' + NATDEPFILES='fork-child.o nat/fork-inferior.o inf-ptrace.o fbsd-nat.o \ + fbsd-kvm.o' HAVE_NATIVE_GCORE_HOST=1 LOADLIBES='-lkvm' ;; diff --git gdb/configure.tgt gdb/configure.tgt -index 27f122ad04..5fa0d0179e 100644 +index caa42be1c0..45668ccaed 100644 --- gdb/configure.tgt +++ gdb/configure.tgt -@@ -98,7 +98,7 @@ esac +@@ -101,7 +101,7 @@ esac case "${targ}" in *-*-freebsd* | *-*-kfreebsd*-gnu) - os_obs="fbsd-tdep.o solib-svr4.o";; + os_obs="fbsd-tdep.o solib-svr4.o fbsd-kld.o fbsd-kthr.o";; *-*-netbsd* | *-*-knetbsd*-gnu) os_obs="nbsd-tdep.o solib-svr4.o";; *-*-openbsd*) -@@ -115,7 +115,7 @@ aarch64*-*-elf | aarch64*-*-rtems*) +@@ -118,7 +118,7 @@ aarch64*-*-elf | aarch64*-*-rtems*) aarch64*-*-freebsd*) # Target: FreeBSD/aarch64 - gdb_target_obs="aarch64-fbsd-tdep.o" + gdb_target_obs="aarch64-fbsd-tdep.o aarch64-fbsd-kern.o" ;; aarch64*-*-linux*) -@@ -168,7 +168,7 @@ arm*-*-linux*) +@@ -171,7 +171,7 @@ arm*-*-linux*) ;; arm*-*-freebsd*) # Target: FreeBSD/arm - gdb_target_obs="arm-fbsd-tdep.o" + gdb_target_obs="arm-fbsd-tdep.o arm-fbsd-kern.o" ;; arm*-*-netbsd* | arm*-*-knetbsd*-gnu) # Target: NetBSD/arm -@@ -267,7 +267,11 @@ i[34567]86-*-dicos*) +@@ -270,7 +270,11 @@ i[34567]86-*-dicos*) ;; i[34567]86-*-freebsd* | i[34567]86-*-kfreebsd*-gnu) # Target: FreeBSD/i386 - gdb_target_obs="i386-bsd-tdep.o i386-fbsd-tdep.o " + gdb_target_obs="i386-bsd-tdep.o i386-fbsd-tdep.o i386fbsd-kern.o" + if test "x$enable_64_bit_bfd" = "xyes"; then + # Target: FreeBSD amd64 + gdb_target_obs="amd64fbsd-tdep.o amd64fbsd-kern.o ${gdb_target_obs}" + fi ;; i[34567]86-*-netbsd* | i[34567]86-*-knetbsd*-gnu) # Target: NetBSD/i386 -@@ -421,7 +425,7 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu) +@@ -424,7 +428,7 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu) ;; mips*-*-freebsd*) # Target: MIPS running FreeBSD - gdb_target_obs="mips-tdep.o mips-fbsd-tdep.o" + gdb_target_obs="mips-tdep.o mips-fbsd-tdep.o mipsfbsd-kern.o" gdb_sim=../sim/mips/libsim.a ;; mips64*-*-openbsd*) -@@ -488,7 +492,7 @@ or1k-*-* | or1knd-*-*) +@@ -491,7 +495,7 @@ or1k-*-* | or1knd-*-*) powerpc*-*-freebsd*) # Target: FreeBSD/powerpc gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc64-tdep.o \ - ppc-fbsd-tdep.o \ + ppc-fbsd-tdep.o ppcfbsd-kern.o \ ravenscar-thread.o ppc-ravenscar-thread.o" ;; -@@ -543,7 +547,7 @@ s390*-*-linux*) +@@ -545,7 +549,7 @@ s390*-*-linux*) riscv*-*-freebsd*) # Target: FreeBSD/riscv - gdb_target_obs="riscv-fbsd-tdep.o" + gdb_target_obs="riscv-fbsd-tdep.o riscv-fbsd-kern.o" ;; riscv*-*-linux*) -@@ -622,6 +626,7 @@ sparc64-*-linux*) +@@ -624,6 +628,7 @@ sparc64-*-linux*) sparc*-*-freebsd* | sparc*-*-kfreebsd*-gnu) # Target: FreeBSD/sparc64 gdb_target_obs="sparc-tdep.o sparc64-tdep.o sparc64-fbsd-tdep.o \ + sparc64fbsd-kern.o \ ravenscar-thread.o sparc-ravenscar-thread.o" ;; sparc-*-netbsd* | sparc-*-knetbsd*-gnu) -@@ -749,8 +754,8 @@ x86_64-*-linux*) +@@ -745,8 +750,8 @@ x86_64-*-linux*) ;; x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) # Target: FreeBSD/amd64 - gdb_target_obs="amd64-fbsd-tdep.o ${i386_tobjs} \ - i386-bsd-tdep.o i386-fbsd-tdep.o" + gdb_target_obs="amd64-fbsd-tdep.o amd64fbsd-kern.o ${i386_tobjs} \ + i386-bsd-tdep.o i386-fbsd-tdep.o i386fbsd-kern.o" ;; x86_64-*-mingw* | x86_64-*-cygwin*) # Target: MingW/amd64 diff --git gdb/defs.h gdb/defs.h -index a44e186907..c4bfd42073 100644 +index 567f214b81..abbaa1f950 100644 --- gdb/defs.h +++ gdb/defs.h -@@ -484,6 +484,7 @@ enum gdb_osabi +@@ -481,6 +481,7 @@ enum gdb_osabi GDB_OSABI_SOLARIS, GDB_OSABI_LINUX, GDB_OSABI_FREEBSD, + GDB_OSABI_FREEBSD_KERNEL, GDB_OSABI_NETBSD, GDB_OSABI_OPENBSD, GDB_OSABI_WINCE, -diff --git gdb/gnulib/configure gdb/gnulib/configure -index 340c622cb3..bf0c4dd5d9 100644 ---- gdb/gnulib/configure -+++ gdb/gnulib/configure -@@ -18579,6 +18579,7 @@ else - case "$host_os" in - # Guess all is fine on glibc systems. - *-gnu*) gl_cv_func_gettimeofday_clobber="guessing no" ;; -+ freebsd*) gl_cv_func_gettimeofday_clobber="guessing no" ;; - # If we don't know, assume the worst. - *) gl_cv_func_gettimeofday_clobber="guessing yes" ;; - esac diff --git gdb/osabi.c gdb/osabi.c -index 5d4bbcdff8..a982b22624 100644 +index dec1bddc4c..06c514167e 100644 --- gdb/osabi.c +++ gdb/osabi.c @@ -66,6 +66,7 @@ static const struct osabi_names gdb_osabi_names[] = { "Solaris", NULL }, { "GNU/Linux", "linux(-gnu[^-]*)?" }, { "FreeBSD", NULL }, + { "FreeBSD/kernel", NULL }, { "NetBSD", NULL }, { "OpenBSD", NULL }, { "WindowsCE", NULL }, diff --git gdb/regcache.c gdb/regcache.c -index 6e3eee9663..49ca1e1535 100644 +index 1580359cd4..50ff8d4039 100644 --- gdb/regcache.c +++ gdb/regcache.c -@@ -1003,6 +1003,22 @@ reg_buffer::raw_supply_zeroed (int regnum) +@@ -996,6 +996,22 @@ reg_buffer::raw_supply_zeroed (int regnum) m_register_status[regnum] = REG_VALID; } +void +reg_buffer::raw_supply_unsigned (int regnum, ULONGEST val) +{ + enum bfd_endian byte_order = gdbarch_byte_order (m_descr->gdbarch); + gdb_byte *regbuf; + size_t regsize; + + assert_regnum (regnum); + + regbuf = register_buffer (regnum); + regsize = m_descr->sizeof_register[regnum]; + + store_unsigned_integer (regbuf, regsize, byte_order, val); + m_register_status[regnum] = REG_VALID; +} + - /* See common/common-regcache.h. */ + /* See gdbsupport/common-regcache.h. */ void diff --git gdb/regcache.h gdb/regcache.h -index 2b703ea4a4..d06e001957 100644 +index e2935eea74..83654be825 100644 --- gdb/regcache.h +++ gdb/regcache.h -@@ -224,6 +224,8 @@ public: +@@ -226,6 +226,8 @@ public: only LEN, without editing the rest of the register. */ void raw_supply_part (int regnum, int offset, int len, const gdb_byte *in); + void raw_supply_unsigned (int regnum, ULONGEST val); + void invalidate (int regnum); virtual ~reg_buffer () = default; +diff --git gnulib/configure gnulib/configure +index 7c74371e8f..396467f68d 100644 +--- gnulib/configure ++++ gnulib/configure +@@ -20267,6 +20267,8 @@ else + case "$host_os" in + # Guess all is fine on glibc systems. + *-gnu*) gl_cv_func_gettimeofday_clobber="guessing no" ;; ++ # Guess all is fine on FreeBSD. ++ freebsd*) gl_cv_func_gettimeofday_clobber="guessing no" ;; + # If we don't know, assume the worst. + *) gl_cv_func_gettimeofday_clobber="guessing yes" ;; + esac Index: head/devel/gdb/files/kgdb/aarch64-fbsd-kern.c =================================================================== --- head/devel/gdb/files/kgdb/aarch64-fbsd-kern.c (revision 528131) +++ head/devel/gdb/files/kgdb/aarch64-fbsd-kern.c (revision 528132) @@ -1,201 +1,202 @@ /*- * Copyright (c) 2017 John Baldwin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ */ /* Target-dependent code for FreeBSD/aarch64 kernels. */ #include "defs.h" #include "aarch64-tdep.h" #include "frame-unwind.h" +#include "gdbarch.h" #include "gdbcore.h" #include "osabi.h" #include "regcache.h" #include "regset.h" #include "solib.h" #include "target.h" #include "trad-frame.h" #include "kgdb.h" static const struct regcache_map_entry aarch64_fbsd_pcbmap[] = { { 30, AARCH64_X0_REGNUM, 8 }, /* x0 ... x29 */ { 1, AARCH64_PC_REGNUM, 8 }, { 1, REGCACHE_MAP_SKIP, 8 }, { 1, AARCH64_SP_REGNUM, 8 }, { 0 } }; static const struct regset aarch64_fbsd_pcbregset = { aarch64_fbsd_pcbmap, regcache_supply_regset, regcache_collect_regset }; static void aarch64_fbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) { gdb_byte buf[8 * 33]; if (target_read_memory (pcb_addr, buf, sizeof buf) == 0) regcache_supply_regset (&aarch64_fbsd_pcbregset, regcache, -1, buf, sizeof (buf)); } static struct trad_frame_cache * aarch64_fbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; CORE_ADDR func, pc, sp; const char *name; int i; if (*this_cache != NULL) return ((struct trad_frame_cache *)*this_cache); cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_func (this_frame); sp = get_frame_register_unsigned (this_frame, AARCH64_SP_REGNUM); find_pc_partial_function (func, &name, NULL, NULL); if (strcmp(name, "fork_trampoline") == 0 && get_frame_pc (this_frame) == func) { /* fork_exit hasn't been called (kthread has never run), so SP hasn't been initialized yet. The stack pointer is stored in the X2 in the pcb. */ sp = get_frame_register_unsigned (this_frame, AARCH64_X0_REGNUM + 2); } trad_frame_set_reg_addr (cache, AARCH64_SP_REGNUM, sp); trad_frame_set_reg_addr (cache, AARCH64_LR_REGNUM, sp + 8); trad_frame_set_reg_addr (cache, AARCH64_PC_REGNUM, sp + 16); trad_frame_set_reg_addr (cache, AARCH64_CPSR_REGNUM, sp + 24); for (i = 0; i < 30; i++) trad_frame_set_reg_addr (cache, AARCH64_X0_REGNUM + i, sp + 32 + i * 8); /* Read $PC from trap frame. */ pc = read_memory_unsigned_integer (sp + 16, 8, byte_order); if (pc == 0 && strcmp(name, "fork_trampoline") == 0) { /* Initial frame of a kthread; terminate backtrace. */ trad_frame_set_id (cache, outer_frame_id); } else { /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (sp + 8 * 34, func)); } return cache; } static void aarch64_fbsd_trapframe_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) { struct trad_frame_cache *cache = aarch64_fbsd_trapframe_cache (this_frame, this_cache); trad_frame_get_id (cache, this_id); } static struct value * aarch64_fbsd_trapframe_prev_register (struct frame_info *this_frame, void **this_cache, int regnum) { struct trad_frame_cache *cache = aarch64_fbsd_trapframe_cache (this_frame, this_cache); return trad_frame_get_register (cache, this_frame, regnum); } static int aarch64_fbsd_trapframe_sniffer (const struct frame_unwind *self, struct frame_info *this_frame, void **this_prologue_cache) { const char *name; find_pc_partial_function (get_frame_func (this_frame), &name, NULL, NULL); return (name && ((strcmp (name, "handle_el1h_sync") == 0) || (strcmp (name, "handle_el1h_irq") == 0) || (strcmp (name, "handle_el0_sync") == 0) || (strcmp (name, "handle_el0_irq") == 0) || (strcmp (name, "handle_el0_error") == 0) || (strcmp (name, "fork_trampoline") == 0))); } static const struct frame_unwind aarch64_fbsd_trapframe_unwind = { SIGTRAMP_FRAME, default_frame_unwind_stop_reason, aarch64_fbsd_trapframe_this_id, aarch64_fbsd_trapframe_prev_register, NULL, aarch64_fbsd_trapframe_sniffer }; /* Implement the 'init_osabi' method of struct gdb_osabi_handler. */ static void aarch64_fbsd_kernel_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); frame_unwind_prepend_unwinder (gdbarch, &aarch64_fbsd_trapframe_unwind); set_solib_ops (gdbarch, &kld_so_ops); /* Enable longjmp. */ tdep->jb_pc = 13; fbsd_vmcore_set_supply_pcb (gdbarch, aarch64_fbsd_supply_pcb); fbsd_vmcore_set_cpu_pcb_addr (gdbarch, kgdb_trgt_stop_pcb); /* The kernel is linked at a virtual address with the upper 4 bits set, so all 64 bits of virtual addresses need to be treated as significant. */ set_gdbarch_significant_addr_bit (gdbarch, 64); } /* Provide a prototype to silence -Wmissing-prototypes. */ extern initialize_file_ftype _initialize_aarch64_kgdb_tdep; void _initialize_aarch64_kgdb_tdep (void) { gdbarch_register_osabi_sniffer(bfd_arch_aarch64, bfd_target_elf_flavour, fbsd_kernel_osabi_sniffer); gdbarch_register_osabi (bfd_arch_aarch64, 0, GDB_OSABI_FREEBSD_KERNEL, aarch64_fbsd_kernel_init_abi); } Index: head/devel/gdb/files/kgdb/amd64fbsd-kern.c =================================================================== --- head/devel/gdb/files/kgdb/amd64fbsd-kern.c (revision 528131) +++ head/devel/gdb/files/kgdb/amd64fbsd-kern.c (revision 528132) @@ -1,311 +1,311 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include "defs.h" #include "frame-unwind.h" #include "gdbcore.h" #include "osabi.h" #include "regcache.h" #include "solib.h" #include "stack.h" #include "symtab.h" #include "trad-frame.h" #include "amd64-tdep.h" -#include "common/x86-xstate.h" +#include "gdbsupport/x86-xstate.h" #ifdef __amd64__ #include #include #endif #include "kgdb.h" static const int amd64fbsd_pcb_offset[] = { -1, /* %rax */ 6 * 8, /* %rbx */ -1, /* %rcx */ -1, /* %rdx */ -1, /* %rsi */ -1, /* %rdi */ 4 * 8, /* %rbp */ 5 * 8, /* %rsp */ -1, /* %r8 ... */ -1, -1, -1, 3 * 8, 2 * 8, 1 * 8, 0 * 8, /* ... %r15 */ 7 * 8, /* %rip */ -1, /* %eflags */ -1, /* %cs */ -1, /* %ss */ -1, /* %ds */ -1, /* %es */ -1, /* %fs */ -1 /* %gs */ }; #define CODE_SEL (4 << 3) #define DATA_SEL (5 << 3) static void amd64fbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) { gdb_byte buf[8]; int i; memset(buf, 0, sizeof(buf)); /* * XXX The PCB may have been swapped out. Supply a dummy %rip value * so as to avoid triggering an exception during stack unwinding. */ regcache->raw_supply(AMD64_RIP_REGNUM, buf); for (i = 0; i < ARRAY_SIZE (amd64fbsd_pcb_offset); i++) if (amd64fbsd_pcb_offset[i] != -1) { if (target_read_memory(pcb_addr + amd64fbsd_pcb_offset[i], buf, sizeof buf) != 0) continue; regcache->raw_supply(i, buf); } regcache->raw_supply_unsigned(AMD64_CS_REGNUM, CODE_SEL); regcache->raw_supply_unsigned(AMD64_SS_REGNUM, DATA_SEL); } static const int amd64fbsd_trapframe_offset[] = { 6 * 8, /* %rax */ 7 * 8, /* %rbx */ 3 * 8, /* %rcx */ 2 * 8, /* %rdx */ 1 * 8, /* %rsi */ 0 * 8, /* %rdi */ 8 * 8, /* %rbp */ 22 * 8, /* %rsp */ 4 * 8, /* %r8 ... */ 5 * 8, 9 * 8, 10 * 8, 11 * 8, 12 * 8, 13 * 8, 14 * 8, /* ... %r15 */ 19 * 8, /* %rip */ 21 * 8, /* %eflags */ 20 * 8, /* %cs */ 23 * 8, /* %ss */ -1, /* %ds */ -1, /* %es */ -1, /* %fs */ -1 /* %gs */ }; #define TRAPFRAME_SIZE 192 static struct trad_frame_cache * amd64fbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; CORE_ADDR addr, func, pc, sp; const char *name; int i; if (*this_cache != NULL) return ((struct trad_frame_cache *)*this_cache); cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_func (this_frame); sp = get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM); find_pc_partial_function (func, &name, NULL, NULL); if (strcmp(name, "fork_trampoline") == 0 && get_frame_pc (this_frame) == func) { /* fork_exit hasn't been called (kthread has never run), so %rsp in the pcb points to the trapframe. GDB has auto-adjusted %rsp for this frame to account for the "call" into fork_trampoline, so "undo" the adjustment. */ sp += 8; } for (i = 0; i < ARRAY_SIZE (amd64fbsd_trapframe_offset); i++) if (amd64fbsd_trapframe_offset[i] != -1) trad_frame_set_reg_addr (cache, i, sp + amd64fbsd_trapframe_offset[i]); /* Read %rip from trap frame. */ addr = sp + amd64fbsd_trapframe_offset[AMD64_RIP_REGNUM]; pc = read_memory_unsigned_integer (addr, 8, byte_order); if (pc == 0 && strcmp(name, "fork_trampoline") == 0) { /* Initial frame of a kthread; terminate backtrace. */ trad_frame_set_id (cache, outer_frame_id); } else { /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (sp + TRAPFRAME_SIZE, func)); } return cache; } static void amd64fbsd_trapframe_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) { struct trad_frame_cache *cache = amd64fbsd_trapframe_cache (this_frame, this_cache); trad_frame_get_id (cache, this_id); } static struct value * amd64fbsd_trapframe_prev_register (struct frame_info *this_frame, void **this_cache, int regnum) { struct trad_frame_cache *cache = amd64fbsd_trapframe_cache (this_frame, this_cache); return trad_frame_get_register (cache, this_frame, regnum); } static int amd64fbsd_trapframe_sniffer (const struct frame_unwind *self, struct frame_info *this_frame, void **this_prologue_cache) { const char *name; find_pc_partial_function (get_frame_func (this_frame), &name, NULL, NULL); return (name && ((strcmp (name, "calltrap") == 0) || (strcmp (name, "fast_syscall_common") == 0) || (strcmp (name, "fork_trampoline") == 0) || (strcmp (name, "mchk_calltrap") == 0) || (strcmp (name, "nmi_calltrap") == 0) || (name[0] == 'X' && name[1] != '_'))); } static const struct frame_unwind amd64fbsd_trapframe_unwind = { SIGTRAMP_FRAME, default_frame_unwind_stop_reason, amd64fbsd_trapframe_this_id, amd64fbsd_trapframe_prev_register, NULL, amd64fbsd_trapframe_sniffer }; static void amd64fbsd_kernel_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch) { amd64_init_abi(info, gdbarch, amd64_target_description (X86_XSTATE_SSE_MASK, true)); frame_unwind_prepend_unwinder(gdbarch, &amd64fbsd_trapframe_unwind); set_solib_ops(gdbarch, &kld_so_ops); fbsd_vmcore_set_supply_pcb(gdbarch, amd64fbsd_supply_pcb); fbsd_vmcore_set_cpu_pcb_addr(gdbarch, kgdb_trgt_stop_pcb); } void _initialize_amd64_kgdb_tdep(void) { gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_FREEBSD_KERNEL, amd64fbsd_kernel_init_abi); #ifdef __amd64__ gdb_assert(offsetof(struct pcb, pcb_rbx) == amd64fbsd_pcb_offset[AMD64_RBX_REGNUM]); gdb_assert(offsetof(struct pcb, pcb_rbp) == amd64fbsd_pcb_offset[AMD64_RBP_REGNUM]); gdb_assert(offsetof(struct pcb, pcb_rsp) == amd64fbsd_pcb_offset[AMD64_RSP_REGNUM]); gdb_assert(offsetof(struct pcb, pcb_r12) == amd64fbsd_pcb_offset[AMD64_R12_REGNUM]); gdb_assert(offsetof(struct pcb, pcb_r13) == amd64fbsd_pcb_offset[AMD64_R13_REGNUM]); gdb_assert(offsetof(struct pcb, pcb_r14) == amd64fbsd_pcb_offset[AMD64_R14_REGNUM]); gdb_assert(offsetof(struct pcb, pcb_r15) == amd64fbsd_pcb_offset[AMD64_R15_REGNUM]); gdb_assert(offsetof(struct pcb, pcb_rip) == amd64fbsd_pcb_offset[AMD64_RIP_REGNUM]); gdb_assert(CODE_SEL == GSEL(GCODE_SEL, SEL_KPL)); gdb_assert(DATA_SEL == GSEL(GDATA_SEL, SEL_KPL)); gdb_assert(sizeof(struct trapframe) == TRAPFRAME_SIZE); gdb_assert(offsetof(struct trapframe, tf_rax) == amd64fbsd_trapframe_offset[AMD64_RAX_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_rbx) == amd64fbsd_trapframe_offset[AMD64_RBX_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_rcx) == amd64fbsd_trapframe_offset[AMD64_RCX_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_rdx) == amd64fbsd_trapframe_offset[AMD64_RDX_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_rsi) == amd64fbsd_trapframe_offset[AMD64_RSI_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_rdi) == amd64fbsd_trapframe_offset[AMD64_RDI_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_rbp) == amd64fbsd_trapframe_offset[AMD64_RBP_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_rsp) == amd64fbsd_trapframe_offset[AMD64_RSP_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_r8) == amd64fbsd_trapframe_offset[AMD64_R8_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_r9) == amd64fbsd_trapframe_offset[AMD64_R9_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_r10) == amd64fbsd_trapframe_offset[AMD64_R10_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_r11) == amd64fbsd_trapframe_offset[AMD64_R11_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_r12) == amd64fbsd_trapframe_offset[AMD64_R12_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_r13) == amd64fbsd_trapframe_offset[AMD64_R13_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_r14) == amd64fbsd_trapframe_offset[AMD64_R14_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_r15) == amd64fbsd_trapframe_offset[AMD64_R15_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_rip) == amd64fbsd_trapframe_offset[AMD64_RIP_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_rflags) == amd64fbsd_trapframe_offset[AMD64_EFLAGS_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_cs) == amd64fbsd_trapframe_offset[AMD64_CS_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_ss) == amd64fbsd_trapframe_offset[AMD64_SS_REGNUM]); #endif } Index: head/devel/gdb/files/kgdb/fbsd-kld.c =================================================================== --- head/devel/gdb/files/kgdb/fbsd-kld.c (revision 528131) +++ head/devel/gdb/files/kgdb/fbsd-kld.c (revision 528132) @@ -1,571 +1,582 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include "defs.h" #include "command.h" #include "completer.h" #include "environ.h" #include "exec.h" #include "frame-unwind.h" #include "inferior.h" #include "objfiles.h" #include "gdbcore.h" #include "language.h" #include "solib.h" #include "solist.h" #include "kgdb.h" struct lm_info_kld : public lm_info_base { CORE_ADDR base_address; }; struct kld_info { /* Offsets of fields in linker_file structure. */ CORE_ADDR off_address, off_filename, off_pathname, off_next; /* KVA of 'linker_path' which corresponds to the kern.module_path sysctl .*/ CORE_ADDR module_path_addr; CORE_ADDR linker_files_addr; CORE_ADDR kernel_file_addr; }; struct target_so_ops kld_so_ops; /* Per-program-space data key. */ static const struct program_space_data *kld_pspace_data; static void kld_pspace_data_cleanup (struct program_space *pspace, void *arg) { struct kld_info *info = (struct kld_info *)arg; xfree (info); } /* Get the current kld data. If none is found yet, add it now. This function always returns a valid object. */ static struct kld_info * get_kld_info (void) { struct kld_info *info; info = (struct kld_info *) program_space_data (current_program_space, kld_pspace_data); if (info != NULL) return info; info = XCNEW (struct kld_info); set_program_space_data (current_program_space, kld_pspace_data, info); return info; } static int kld_ok (char *path) { struct stat sb; if (stat(path, &sb) == 0 && S_ISREG(sb.st_mode)) return (1); return (0); } /* * Look for a matching file checking for debug suffixes before the raw file: * - filename + ".debug" (e.g. foo.ko.debug) * - filename (e.g. foo.ko) */ static const char *kld_suffixes[] = { ".debug", ".symbols", "", NULL }; static int check_kld_path (char *path, size_t path_size) { const char **suffix; char *ep; ep = path + strlen(path); suffix = kld_suffixes; while (*suffix != NULL) { if (strlcat(path, *suffix, path_size) < path_size) { if (kld_ok(path)) return (1); } /* Restore original path to remove suffix. */ *ep = '\0'; suffix++; } return (0); } /* * Try to find the path for a kld by looking in the kernel's directory and * in the various paths in the module path. */ static int find_kld_path (const char *filename, char *path, size_t path_size) { struct kld_info *info; gdb::unique_xmalloc_ptr module_path; char *module_dir, *cp; int error; info = get_kld_info(); if (exec_bfd) { std::string kernel_dir = ldirname(bfd_get_filename(exec_bfd)); if (!kernel_dir.empty()) { snprintf(path, path_size, "%s/%s", kernel_dir.c_str(), filename); if (check_kld_path(path, path_size)) return (1); } } if (info->module_path_addr != 0) { target_read_string(info->module_path_addr, &module_path, PATH_MAX, &error); if (error == 0) { cp = module_path.get(); while ((module_dir = strsep(&cp, ";")) != NULL) { snprintf(path, path_size, "%s/%s", module_dir, filename); if (check_kld_path(path, path_size)) return (1); } } } return (0); } /* * Read a kernel pointer given a KVA in 'address'. */ static CORE_ADDR read_pointer (CORE_ADDR address) { struct type *ptr_type; gdb_byte ptr_buf[8]; int arch_size; arch_size = bfd_get_arch_size (exec_bfd); if (arch_size == -1) return (0); ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; if (target_read_memory(address, ptr_buf, arch_size / 8) != 0) return (0); return (extract_typed_address (ptr_buf, ptr_type)); } /* * Try to find this kld in the kernel linker's list of linker files. */ static int find_kld_address (const char *arg, CORE_ADDR *address) { struct kld_info *info; CORE_ADDR kld; gdb::unique_xmalloc_ptr kld_filename; const char *filename; int error; info = get_kld_info(); if (info->linker_files_addr == 0 || info->off_address == 0 || info->off_filename == 0 || info->off_next == 0) return (0); filename = lbasename(arg); for (kld = read_pointer(info->linker_files_addr); kld != 0; kld = read_pointer(kld + info->off_next)) { /* Try to read this linker file's filename. */ target_read_string(read_pointer(kld + info->off_filename), &kld_filename, PATH_MAX, &error); if (error) continue; /* Compare this kld's filename against our passed in name. */ if (strcmp(kld_filename.get(), filename) != 0) continue; /* * We found a match, use its address as the base * address if we can read it. */ *address = read_pointer(kld + info->off_address); if (*address == 0) return (0); return (1); } return (0); } static void adjust_section_address (struct target_section *sec, CORE_ADDR *curr_base) { struct bfd_section *asect = sec->the_bfd_section; bfd *abfd = asect->owner; if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0) { sec->addr += *curr_base; sec->endaddr += *curr_base; return; } *curr_base = align_power(*curr_base, - bfd_get_section_alignment(abfd, asect)); + bfd_section_alignment(asect)); sec->addr = *curr_base; - sec->endaddr = sec->addr + bfd_section_size(abfd, asect); + sec->endaddr = sec->addr + bfd_section_size(asect); *curr_base = sec->endaddr; } static void load_kld (char *path, CORE_ADDR base_addr, int from_tty) { struct target_section *sections = NULL, *sections_end = NULL, *s; - struct cleanup *cleanup; gdb_bfd_ref_ptr bfd; CORE_ADDR curr_addr; symfile_add_flags add_flags; int i; /* Open the kld. */ bfd = gdb_bfd_openr(path, gnutarget); if (bfd == NULL) error("\"%s\": can't open: %s", path, bfd_errmsg(bfd_get_error())); if (!bfd_check_format(bfd.get(), bfd_object)) error("\%s\": not an object file", path); /* Make sure we have a .text section. */ if (bfd_get_section_by_name (bfd.get(), ".text") == NULL) error("\"%s\": can't find text section", path); /* Build a section table from the bfd and relocate the sections. */ if (build_section_table (bfd.get(), §ions, §ions_end)) error("\"%s\": can't find file sections", path); - cleanup = make_cleanup(xfree, sections); curr_addr = base_addr; for (s = sections; s < sections_end; s++) adjust_section_address(s, &curr_addr); /* Build a section addr info to pass to symbol_file_add(). */ section_addr_info sap = build_section_addr_info_from_section_table (sections, sections_end); + xfree(sections); printf_unfiltered("add symbol table from file \"%s\" at\n", path); for (i = 0; i < sap.size(); i++) printf_unfiltered("\t%s_addr = %s\n", sap[i].name.c_str(), paddress(target_gdbarch(), sap[i].addr)); if (from_tty && (!query("%s", ""))) error("Not confirmed."); add_flags = 0; if (from_tty) add_flags |= SYMFILE_VERBOSE; symbol_file_add_from_bfd(bfd.get(), path, add_flags, &sap, OBJF_USERLOADED, NULL); - - do_cleanups(cleanup); } static void kgdb_add_kld_cmd (const char *arg, int from_tty) { char path[PATH_MAX]; CORE_ADDR base_addr; if (!exec_bfd) error("No kernel symbol file"); /* Try to open the raw path to handle absolute paths first. */ snprintf(path, sizeof(path), "%s", arg); if (!check_kld_path(path, sizeof(path))) { /* * If that didn't work, look in the various possible * paths for the module. */ if (!find_kld_path(arg, path, sizeof(path))) { error("Unable to locate kld"); return; } } if (!find_kld_address(arg, &base_addr)) { error("Unable to find kld in kernel"); return; } load_kld(path, base_addr, from_tty); reinit_frame_cache(); } static void kld_relocate_section_addresses (struct so_list *so, struct target_section *sec) { lm_info_kld *li = (lm_info_kld *) so->lm_info; static CORE_ADDR curr_addr; if (sec == so->sections) curr_addr = li->base_address; adjust_section_address(sec, &curr_addr); } static void kld_free_so (struct so_list *so) { lm_info_kld *li = (lm_info_kld *) so->lm_info; delete li; } static void kld_clear_so (struct so_list *so) { lm_info_kld *li = (lm_info_kld *) so->lm_info; if (li != NULL) li->base_address = 0; } static void kld_clear_solib (void) { struct kld_info *info; info = get_kld_info(); memset(info, 0, sizeof(*info)); } static void kld_solib_create_inferior_hook (int from_tty) { struct kld_info *info; info = get_kld_info(); /* * Compute offsets of relevant members in struct linker_file * and the addresses of global variables. Newer kernels * include constants we can use without requiring debug - * symbols. If those aren't present, fall back to using - * home-grown offsetof() equivalents. + * symbols. */ - TRY { + try { info->off_address = parse_and_eval_long("kld_off_address"); info->off_filename = parse_and_eval_long("kld_off_filename"); info->off_pathname = parse_and_eval_long("kld_off_pathname"); info->off_next = parse_and_eval_long("kld_off_next"); - } CATCH(e, RETURN_MASK_ERROR) { - TRY { - info->off_address = parse_and_eval_address( - "&((struct linker_file *)0)->address"); - info->off_filename = parse_and_eval_address( - "&((struct linker_file *)0)->filename"); - info->off_pathname = parse_and_eval_address( - "&((struct linker_file *)0)->pathname"); - info->off_next = parse_and_eval_address( - "&((struct linker_file *)0)->link.tqe_next"); - } CATCH(e2, RETURN_MASK_ERROR) { + } catch (const gdb_exception_error &e) { + try { + struct symbol *linker_file_sym = + lookup_symbol_in_language ("struct linker_file", + NULL, STRUCT_DOMAIN, language_c, NULL).symbol; + if (linker_file_sym == NULL) + error (_( + "Unable to find struct linker_file symbol")); + + info->off_address = + lookup_struct_elt (SYMBOL_TYPE (linker_file_sym), + "address", 0).offset / 8; + info->off_filename = + lookup_struct_elt (SYMBOL_TYPE (linker_file_sym), + "filename", 0).offset / 8; + info->off_pathname = + lookup_struct_elt (SYMBOL_TYPE (linker_file_sym), + "pathname", 0).offset / 8; + + struct type *link_type = + lookup_struct_elt_type (SYMBOL_TYPE (linker_file_sym), + "link", 0); + if (link_type == NULL) + error (_("Unable to find link type")); + + info->off_next = + lookup_struct_elt (link_type, "tqe_next", + 0).offset / 8; + } catch (const gdb_exception_error &e2) { return; } - END_CATCH } - END_CATCH - TRY { + try { info->module_path_addr = parse_and_eval_address("linker_path"); info->linker_files_addr = kgdb_lookup("linker_files"); info->kernel_file_addr = kgdb_lookup("linker_kernel_file"); - } CATCH(e, RETURN_MASK_ERROR) { + } catch (const gdb_exception_error &e) { return; } - END_CATCH solib_add(NULL, from_tty, auto_solib_add); } static struct so_list * kld_current_sos (void) { struct so_list *head, **prev, *newobj; struct kld_info *info; CORE_ADDR kld, kernel; gdb::unique_xmalloc_ptr path; int error; info = get_kld_info(); if (info->linker_files_addr == 0 || info->kernel_file_addr == 0 || info->off_address == 0 || info->off_filename == 0 || info->off_next == 0) return (NULL); head = NULL; prev = &head; /* * Walk the list of linker files creating so_list entries for * each non-kernel file. */ kernel = read_pointer(info->kernel_file_addr); for (kld = read_pointer(info->linker_files_addr); kld != 0; kld = read_pointer(kld + info->off_next)) { /* Skip the main kernel file. */ if (kld == kernel) continue; newobj = XCNEW (struct so_list); lm_info_kld *li = new lm_info_kld; li->base_address = 0; newobj->lm_info = li; /* Read the base filename and store it in so_original_name. */ target_read_string(read_pointer(kld + info->off_filename), &path, sizeof(newobj->so_original_name), &error); if (error != 0) { warning("kld_current_sos: Can't read filename: %s\n", safe_strerror(error)); free_so(newobj); continue; } strlcpy(newobj->so_original_name, path.get(), sizeof(newobj->so_original_name)); /* * Try to read the pathname (if it exists) and store * it in so_name. */ if (find_kld_path(newobj->so_original_name, newobj->so_name, sizeof(newobj->so_name))) { /* we found the kld */; } else if (info->off_pathname != 0) { target_read_string(read_pointer(kld + info->off_pathname), &path, sizeof(newobj->so_name), &error); if (error != 0) { warning( "kld_current_sos: Can't read pathname for \"%s\": %s\n", newobj->so_original_name, safe_strerror(error)); strlcpy(newobj->so_name, newobj->so_original_name, sizeof(newobj->so_name)); } else { strlcpy(newobj->so_name, path.get(), sizeof(newobj->so_name)); } } else strlcpy(newobj->so_name, newobj->so_original_name, sizeof(newobj->so_name)); /* Read this kld's base address. */ li->base_address = read_pointer(kld + info->off_address); if (li->base_address == 0) { warning( "kld_current_sos: Invalid address for kld \"%s\"", newobj->so_original_name); free_so(newobj); continue; } /* Append to the list. */ *prev = newobj; prev = &newobj->next; } return (head); } static int kld_open_symbol_file_object (int from_tty) { return (0); } static int kld_in_dynsym_resolve_code (CORE_ADDR pc) { return (0); } static int kld_find_and_open_solib (const char *solib, unsigned o_flags, gdb::unique_xmalloc_ptr *temp_pathname) { char path[PATH_MAX]; int fd; temp_pathname->reset (NULL); if (!find_kld_path(solib, path, sizeof(path))) { errno = ENOENT; return (-1); } fd = open(path, o_flags, 0); if (fd >= 0) temp_pathname->reset(xstrdup(path)); return (fd); } void _initialize_kld_target(void) { struct cmd_list_element *c; kld_so_ops.relocate_section_addresses = kld_relocate_section_addresses; kld_so_ops.free_so = kld_free_so; kld_so_ops.clear_so = kld_clear_so; kld_so_ops.clear_solib = kld_clear_solib; kld_so_ops.solib_create_inferior_hook = kld_solib_create_inferior_hook; kld_so_ops.current_sos = kld_current_sos; kld_so_ops.open_symbol_file_object = kld_open_symbol_file_object; kld_so_ops.in_dynsym_resolve_code = kld_in_dynsym_resolve_code; kld_so_ops.bfd_open = solib_bfd_open; kld_so_ops.find_and_open_solib = kld_find_and_open_solib; c = add_com("add-kld", class_files, kgdb_add_kld_cmd, "Usage: add-kld FILE\n\ Load the symbols from the kernel loadable module FILE."); set_cmd_completer(c, filename_completer); kld_pspace_data = register_program_space_data_with_cleanup (NULL, kld_pspace_data_cleanup); } Index: head/devel/gdb/files/kgdb/fbsd-kthr.c =================================================================== --- head/devel/gdb/files/kgdb/fbsd-kthr.c (revision 528131) +++ head/devel/gdb/files/kgdb/fbsd-kthr.c (revision 528132) @@ -1,343 +1,366 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include "gdbcore.h" #include "objfiles.h" #include "value.h" #include "kgdb.h" static CORE_ADDR dumppcb; static LONGEST dumptid; static CORE_ADDR stopped_cpus; static LONGEST mp_maxid; static struct kthr *first, *last; struct kthr *curkthr; static int proc_off_p_pid, proc_off_p_comm, proc_off_p_list, proc_off_p_threads; static int thread_off_td_tid, thread_off_td_oncpu, thread_off_td_pcb; static int thread_off_td_name, thread_off_td_plist; static int thread_oncpu_size; CORE_ADDR kgdb_lookup(const char *sym) { struct bound_minimal_symbol msym; msym = lookup_minimal_symbol(sym, NULL, NULL); if (msym.minsym == NULL) return (0); return (BMSYMBOL_VALUE_ADDRESS(msym)); } /* * Perform the equivalent of CPU_ISSET() to see if 'cpu' is set in the * kernel's stopped_cpus set. The set contains an array of longs. * This function determines the specific long to read and tests the * necessary bit in the long. */ static bool cpu_stopped(int cpu) { struct gdbarch *gdbarch = target_gdbarch (); CORE_ADDR addr; ULONGEST mask; int bit, long_bytes, word; if (cpu < 0 || cpu > mp_maxid || stopped_cpus == 0) return (false); bit = cpu % gdbarch_long_bit (gdbarch); word = cpu / gdbarch_long_bit (gdbarch); long_bytes = gdbarch_long_bit (gdbarch) / 8; addr = stopped_cpus + word * long_bytes; mask = read_memory_unsigned_integer (addr, long_bytes, gdbarch_byte_order (gdbarch)); return (mask & ((ULONGEST)1 << bit)) != 0; } struct kthr * kgdb_thr_first(void) { return (first); } static void kgdb_thr_add_procs(CORE_ADDR paddr, CORE_ADDR (*cpu_pcb_addr) (u_int)) { struct gdbarch *gdbarch = target_gdbarch (); struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct kthr *kt; CORE_ADDR pcb, pnext, tdaddr, tdnext; ULONGEST oncpu; LONGEST pid, tid; while (paddr != 0) { - TRY { + try { tdaddr = read_memory_typed_address (paddr + proc_off_p_threads, ptr_type); pid = read_memory_integer (paddr + proc_off_p_pid, 4, byte_order); pnext = read_memory_typed_address (paddr + proc_off_p_list, ptr_type); - } CATCH(e, RETURN_MASK_ERROR) { + } catch (const gdb_exception_error &e) { break; - } END_CATCH + } while (tdaddr != 0) { - TRY { + try { tid = read_memory_integer (tdaddr + thread_off_td_tid, 4, byte_order); oncpu = read_memory_unsigned_integer (tdaddr + thread_off_td_oncpu, thread_oncpu_size, byte_order); pcb = read_memory_typed_address (tdaddr + thread_off_td_pcb, ptr_type); tdnext = read_memory_typed_address (tdaddr + thread_off_td_plist, ptr_type); - } CATCH(e, RETURN_MASK_ERROR) { + } catch (const gdb_exception_error &e) { break; - } END_CATCH + } kt = XNEW (struct kthr); if (last == NULL) first = last = kt; else last->next = kt; kt->next = NULL; kt->kaddr = tdaddr; if (tid == dumptid) kt->pcb = dumppcb; else if (cpu_stopped(oncpu)) kt->pcb = cpu_pcb_addr(oncpu); else kt->pcb = pcb; kt->tid = tid; kt->pid = pid; kt->paddr = paddr; kt->cpu = oncpu; last = kt; tdaddr = tdnext; } paddr = pnext; } } struct kthr * kgdb_thr_init(CORE_ADDR (*cpu_pcb_addr) (u_int)) { struct gdbarch *gdbarch = target_gdbarch (); struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; struct kthr *kt; CORE_ADDR addr, paddr; while (first != NULL) { kt = first; first = kt->next; free(kt); } last = NULL; addr = kgdb_lookup("allproc"); if (addr == 0) return (NULL); - TRY { + try { paddr = read_memory_typed_address (addr, ptr_type); - } CATCH(e, RETURN_MASK_ERROR) { + } catch (const gdb_exception_error &e) { return (NULL); - } END_CATCH + } dumppcb = kgdb_lookup("dumppcb"); if (dumppcb == 0) return (NULL); - TRY { + try { dumptid = parse_and_eval_long("dumptid"); - } CATCH(e, RETURN_MASK_ERROR) { + } catch (const gdb_exception_error &e) { dumptid = -1; - } END_CATCH + } - TRY { + try { mp_maxid = parse_and_eval_long("mp_maxid"); - } CATCH(e, RETURN_MASK_ERROR) { + } catch (const gdb_exception_error &e) { mp_maxid = 0; - } END_CATCH + } stopped_cpus = kgdb_lookup("stopped_cpus"); /* * Newer kernels export a set of global variables with the offsets * of certain members in struct proc and struct thread. For older * kernels, try to extract these offsets using debug symbols. If * that fails, use native values. */ - TRY { + try { proc_off_p_pid = parse_and_eval_long("proc_off_p_pid"); proc_off_p_comm = parse_and_eval_long("proc_off_p_comm"); proc_off_p_list = parse_and_eval_long("proc_off_p_list"); proc_off_p_threads = parse_and_eval_long("proc_off_p_threads"); thread_off_td_tid = parse_and_eval_long("thread_off_td_tid"); thread_off_td_name = parse_and_eval_long("thread_off_td_name"); thread_off_td_oncpu = parse_and_eval_long("thread_off_td_oncpu"); thread_off_td_pcb = parse_and_eval_long("thread_off_td_pcb"); thread_off_td_plist = parse_and_eval_long("thread_off_td_plist"); thread_oncpu_size = 4; - } CATCH(e, RETURN_MASK_ERROR) { - TRY { - proc_off_p_pid = parse_and_eval_address( - "&((struct proc *)0)->p_pid"); - proc_off_p_comm = parse_and_eval_address( - "&((struct proc *)0)->p_comm"); - proc_off_p_list = parse_and_eval_address( - "&((struct proc *)0)->p_list"); - proc_off_p_threads = parse_and_eval_address( - "&((struct proc *)0)->p_threads"); - thread_off_td_tid = parse_and_eval_address( - "&((struct thread *)0)->td_tid"); - thread_off_td_name = parse_and_eval_address( - "&((struct thread *)0)->td_name"); - thread_off_td_oncpu = parse_and_eval_address( - "&((struct thread *)0)->td_oncpu"); - thread_off_td_pcb = parse_and_eval_address( - "&((struct thread *)0)->td_pcb"); - thread_off_td_plist = parse_and_eval_address( - "&((struct thread *)0)->td_plist"); - thread_oncpu_size = parse_and_eval_long( - "sizeof(((struct thread *)0)->td_oncpu)"); - } CATCH(e2, RETURN_MASK_ERROR) { + } catch (const gdb_exception_error &e) { + try { + struct symbol *proc_sym = + lookup_symbol_in_language ("struct proc", NULL, + STRUCT_DOMAIN, language_c, NULL).symbol; + if (proc_sym == NULL) + error (_("Unable to find struct proc symbol")); + + proc_off_p_pid = + lookup_struct_elt (SYMBOL_TYPE (proc_sym), "p_pid", + 0).offset / 8; + proc_off_p_comm = + lookup_struct_elt (SYMBOL_TYPE (proc_sym), "p_comm", + 0).offset / 8; + proc_off_p_list = + lookup_struct_elt (SYMBOL_TYPE (proc_sym), "p_list", + 0).offset / 8; + proc_off_p_threads = + lookup_struct_elt (SYMBOL_TYPE (proc_sym), + "p_threads", 0).offset / 8; + + struct symbol *thread_sym = + lookup_symbol_in_language ("struct thread", NULL, + STRUCT_DOMAIN, language_c, NULL).symbol; + if (thread_sym == NULL) + error (_("Unable to find struct thread symbol")); + + thread_off_td_tid = + lookup_struct_elt (SYMBOL_TYPE (proc_sym), "td_tid", + 0).offset / 8; + thread_off_td_name = + lookup_struct_elt (SYMBOL_TYPE (proc_sym), "td_name", + 0).offset / 8; + thread_off_td_pcb = + lookup_struct_elt (SYMBOL_TYPE (proc_sym), "td_pcb", + 0).offset / 8; + thread_off_td_plist = + lookup_struct_elt (SYMBOL_TYPE (proc_sym), "td_plist", + 0).offset / 8; + + struct_elt td_oncpu = + lookup_struct_elt (SYMBOL_TYPE (proc_sym), "td_oncpu", + 0); + thread_off_td_oncpu = td_oncpu.offset / 8; + thread_oncpu_size = FIELD_BITSIZE(*td_oncpu.field) / 8; + } catch (const gdb_exception_error &e2) { proc_off_p_pid = offsetof(struct proc, p_pid); proc_off_p_comm = offsetof(struct proc, p_comm); proc_off_p_list = offsetof(struct proc, p_list); proc_off_p_threads = offsetof(struct proc, p_threads); thread_off_td_tid = offsetof(struct thread, td_tid); thread_off_td_name = offsetof(struct thread, td_name); thread_off_td_oncpu = offsetof(struct thread, td_oncpu); thread_off_td_pcb = offsetof(struct thread, td_pcb); thread_off_td_plist = offsetof(struct thread, td_plist); thread_oncpu_size = sizeof(((struct thread *)0)->td_oncpu); - } END_CATCH - } END_CATCH + } + } kgdb_thr_add_procs(paddr, cpu_pcb_addr); addr = kgdb_lookup("zombproc"); if (addr != 0) { - TRY { + try { paddr = read_memory_typed_address (addr, ptr_type); kgdb_thr_add_procs(paddr, cpu_pcb_addr); - } CATCH(e, RETURN_MASK_ERROR) { - } END_CATCH + } catch (const gdb_exception_error &e) { + } } curkthr = kgdb_thr_lookup_tid(dumptid); if (curkthr == NULL) curkthr = first; return (first); } struct kthr * kgdb_thr_lookup_tid(int tid) { struct kthr *kt; kt = first; while (kt != NULL && kt->tid != tid) kt = kt->next; return (kt); } struct kthr * kgdb_thr_lookup_taddr(uintptr_t taddr) { struct kthr *kt; kt = first; while (kt != NULL && kt->kaddr != taddr) kt = kt->next; return (kt); } struct kthr * kgdb_thr_lookup_pid(int pid) { struct kthr *kt; kt = first; while (kt != NULL && kt->pid != pid) kt = kt->next; return (kt); } struct kthr * kgdb_thr_lookup_paddr(uintptr_t paddr) { struct kthr *kt; kt = first; while (kt != NULL && kt->paddr != paddr) kt = kt->next; return (kt); } struct kthr * kgdb_thr_next(struct kthr *kt) { return (kt->next); } const char * kgdb_thr_extra_thread_info(int tid) { char comm[MAXCOMLEN + 1]; char td_name[MAXCOMLEN + 1]; struct kthr *kt; static char buf[64]; kt = kgdb_thr_lookup_tid(tid); if (kt == NULL) return (NULL); snprintf(buf, sizeof(buf), "PID=%d", kt->pid); - TRY { + try { read_memory_string (kt->paddr + proc_off_p_comm, comm, sizeof(comm)); strlcat(buf, ": ", sizeof(buf)); strlcat(buf, comm, sizeof(buf)); read_memory_string (kt->kaddr + thread_off_td_name, td_name, sizeof(td_name)); if (strcmp(comm, td_name) != 0) { strlcat(buf, "/", sizeof(buf)); strlcat(buf, td_name, sizeof(buf)); } - } CATCH(e, RETURN_MASK_ERROR) { - } END_CATCH + } catch (const gdb_exception_error &e) { + } return (buf); } Index: head/devel/gdb/files/kgdb/fbsd-kvm.c =================================================================== --- head/devel/gdb/files/kgdb/fbsd-kvm.c (revision 528131) +++ head/devel/gdb/files/kgdb/fbsd-kvm.c (revision 528132) @@ -1,669 +1,667 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include "defs.h" #include "command.h" #include "elf-bfd.h" #include "filenames.h" #include "gdbcore.h" #include "gdbthread.h" #include "gdb_obstack.h" #include "inferior.h" #include "objfiles.h" #include "osabi.h" #include "process-stratum-target.h" #include "solib.h" #include "target.h" #include "value.h" #include "readline/tilde.h" +#include "gdbsupport/pathstuff.h" #include #include #include #include "kgdb.h" static CORE_ADDR stoppcbs; static LONGEST pcb_size; static char *vmcore; /* Per-architecture data key. */ static struct gdbarch_data *fbsd_vmcore_data; struct fbsd_vmcore_ops { /* Supply registers for a pcb to a register cache. */ void (*supply_pcb)(struct regcache *, CORE_ADDR); /* Return address of pcb for thread running on a CPU. */ CORE_ADDR (*cpu_pcb_addr)(u_int); }; static void * fbsd_vmcore_init (struct obstack *obstack) { struct fbsd_vmcore_ops *ops; ops = OBSTACK_ZALLOC (obstack, struct fbsd_vmcore_ops); return ops; } /* Set the function that supplies registers from a pcb for architecture GDBARCH to SUPPLY_PCB. */ void fbsd_vmcore_set_supply_pcb (struct gdbarch *gdbarch, void (*supply_pcb) (struct regcache *, CORE_ADDR)) { struct fbsd_vmcore_ops *ops = (struct fbsd_vmcore_ops *) gdbarch_data (gdbarch, fbsd_vmcore_data); ops->supply_pcb = supply_pcb; } /* Set the function that returns the address of the pcb for a thread running on a CPU for architecture GDBARCH to CPU_PCB_ADDR. */ void fbsd_vmcore_set_cpu_pcb_addr (struct gdbarch *gdbarch, CORE_ADDR (*cpu_pcb_addr) (u_int)) { struct fbsd_vmcore_ops *ops = (struct fbsd_vmcore_ops *) gdbarch_data (gdbarch, fbsd_vmcore_data); ops->cpu_pcb_addr = cpu_pcb_addr; } static CORE_ADDR kernstart; static kvm_t *kvm; int kgdb_quiet; static ptid_t fbsd_vmcore_ptid(int tid) { if (kvm == NULL) /* * The remote target stores the 'tid' in the lwp * field. */ return ptid_t(inferior_ptid.pid(), tid, 0); /* * This follows the model described in bsd-kvm.c except that * in kernel tids are used as the tid of the ptid instead of a * process ID. */ return ptid_t(1, 1, tid); } #define MSGBUF_SEQ_TO_POS(size, seq) ((seq) % (size)) static void kgdb_dmesg(void) { CORE_ADDR bufp; int size, rseq, wseq; gdb_byte c; /* * Display the unread portion of the message buffer. This gives the * user a some initial data to work from. */ if (kgdb_quiet) return; - TRY { + try { bufp = parse_and_eval_address("msgbufp->msg_ptr"); size = parse_and_eval_long("msgbufp->msg_size"); rseq = parse_and_eval_long("msgbufp->msg_rseq"); wseq = parse_and_eval_long("msgbufp->msg_wseq"); - } CATCH(e, RETURN_MASK_ERROR) { + } catch (const gdb_exception_error &e) { return; - } END_CATCH + } rseq = MSGBUF_SEQ_TO_POS(size, rseq); wseq = MSGBUF_SEQ_TO_POS(size, wseq); if (rseq == wseq) return; printf("\nUnread portion of the kernel message buffer:\n"); while (rseq < wseq) { read_memory(bufp + rseq, &c, 1); putchar(c); rseq++; if (rseq == size) rseq = 0; } if (c != '\n') putchar('\n'); putchar('\n'); } #define KERNEL_INTERP "/red/herring" enum gdb_osabi fbsd_kernel_osabi_sniffer(bfd *abfd) { asection *s; bfd_byte buf[sizeof(KERNEL_INTERP)]; bfd_byte *bufp; /* First, determine if this is a FreeBSD/ELF binary. */ switch (elf_elfheader(abfd)->e_ident[EI_OSABI]) { case ELFOSABI_FREEBSD: break; case ELFOSABI_NONE: { enum gdb_osabi osabi = GDB_OSABI_UNKNOWN; bfd_map_over_sections (abfd, generic_elf_osabi_sniff_abi_tag_sections, &osabi); /* * aarch64 kernels don't have the right note tag for * kernels so just look for /red/herring anyway. */ if (osabi == GDB_OSABI_UNKNOWN && elf_elfheader(abfd)->e_machine == EM_AARCH64) break; if (osabi != GDB_OSABI_FREEBSD) return (GDB_OSABI_UNKNOWN); break; } default: return (GDB_OSABI_UNKNOWN); } /* FreeBSD ELF kernels have an interpreter path of "/red/herring". */ bufp = buf; s = bfd_get_section_by_name(abfd, ".interp"); - if (s != NULL && bfd_section_size(abfd, s) == sizeof(buf) && + if (s != NULL && bfd_section_size(s) == sizeof(buf) && bfd_get_full_section_contents(abfd, s, &bufp) && memcmp(buf, KERNEL_INTERP, sizeof(buf)) == 0) return (GDB_OSABI_FREEBSD_KERNEL); return (GDB_OSABI_UNKNOWN); } /* The FreeBSD libkvm target. */ static const target_info fbsd_kvm_target_info = { "vmcore", N_("Kernel core dump file"), N_("Use a vmcore file as a target.\n\ If no filename is specified, /dev/mem is used to examine the running kernel.\n\ target vmcore [-w] [filename]") }; class fbsd_kvm_target final : public process_stratum_target { public: fbsd_kvm_target () = default; const target_info &info () const override { return fbsd_kvm_target_info; } void close () override; void fetch_registers (struct regcache *, int) override; enum target_xfer_status xfer_partial (enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) override; void files_info () override; bool thread_alive (ptid_t ptid) override; void update_thread_list () override; - const char *pid_to_str (ptid_t) override; + std::string pid_to_str (ptid_t) override; const char *extra_thread_info (thread_info *) override; bool has_all_memory () override { return false; } bool has_memory () override; bool has_stack () override; bool has_registers () override; bool has_execution (ptid_t) override { return false; } }; /* Target ops for libkvm interface. */ static fbsd_kvm_target fbsd_kvm_ops; #ifdef HAVE_KVM_OPEN2 static int kgdb_resolve_symbol(const char *name, kvaddr_t *kva) { struct bound_minimal_symbol ms; ms = lookup_minimal_symbol (name, NULL, NULL); if (ms.minsym == NULL) return (1); *kva = BMSYMBOL_VALUE_ADDRESS (ms); return (0); } #endif static void fbsd_kvm_target_open (const char *args, int from_tty) { struct fbsd_vmcore_ops *ops = (struct fbsd_vmcore_ops *) gdbarch_data (target_gdbarch(), fbsd_vmcore_data); char kvm_err[_POSIX2_LINE_MAX]; struct inferior *inf; struct cleanup *old_chain; struct kthr *kt; kvm_t *nkvm; - char *temp, *kernel, *filename; + const char *kernel; + char *temp, *filename; bool writeable; if (ops == NULL || ops->supply_pcb == NULL || ops->cpu_pcb_addr == NULL) error ("ABI doesn't support a vmcore target"); target_preopen (from_tty); - kernel = get_exec_file (1); + kernel = get_exec_file (0); if (kernel == NULL) error ("Can't open a vmcore without a kernel"); writeable = false; filename = NULL; if (args != NULL) { gdb_argv built_argv (args); for (char **argv = built_argv.get (); *argv != NULL; argv++) { if (**argv == '-') { if (strcmp (*argv, "-w") == 0) writeable = true; else error (_("Invalid argument")); } else { if (filename != NULL) error (_("Invalid argument")); filename = tilde_expand (*argv); - if (!IS_ABSOLUTE_PATH (filename)) { - temp = concat (current_directory, "/", - filename, NULL); - xfree(filename); - filename = temp; + if (filename[0] != '/') { + gdb::unique_xmalloc_ptr temp (gdb_abspath (filename)); + + xfree (filename); + filename = temp.release (); } } } } - old_chain = make_cleanup (xfree, filename); - #ifdef HAVE_KVM_OPEN2 nkvm = kvm_open2(kernel, filename, writeable ? O_RDWR : O_RDONLY, kvm_err, kgdb_resolve_symbol); #else nkvm = kvm_openfiles(kernel, filename, NULL, writeable ? O_RDWR : O_RDONLY, kvm_err); #endif - if (nkvm == NULL) + if (nkvm == NULL) { + xfree (filename); error ("Failed to open vmcore: %s", kvm_err); + } /* Don't free the filename now and close any previous vmcore. */ - discard_cleanups(old_chain); unpush_target(&fbsd_kvm_ops); #ifdef HAVE_KVM_DISP /* Relocate kernel objfile if needed. */ if (symfile_objfile && (bfd_get_file_flags(symfile_objfile->obfd) & (EXEC_P | DYNAMIC)) != 0) { struct section_offsets *new_offsets; int i; CORE_ADDR displacement; displacement = kvm_kerndisp(nkvm); if (displacement != 0) { new_offsets = XALLOCAVEC (struct section_offsets, symfile_objfile->num_sections); for (i = 0; i < symfile_objfile->num_sections; i++) new_offsets->offsets[i] = displacement; objfile_relocate(symfile_objfile, new_offsets); } } #endif /* * Determine the first address in KVA. Newer kernels export * VM_MAXUSER_ADDRESS and the first kernel address can be * determined by adding one. Older kernels do not provide a * symbol that is valid on all platforms, but kernbase is close * for most platforms. */ - TRY { + try { kernstart = parse_and_eval_address("vm_maxuser_address") + 1; - } CATCH(e, RETURN_MASK_ERROR) { + } catch (const gdb_exception_error &e) { kernstart = kgdb_lookup("kernbase"); - } END_CATCH + } /* * Lookup symbols needed for stoppcbs[] handling, but don't * fail if they aren't present. */ stoppcbs = kgdb_lookup("stoppcbs"); - TRY { + try { pcb_size = parse_and_eval_long("pcb_size"); - } CATCH(e, RETURN_MASK_ERROR) { + } catch (const gdb_exception_error &e) { pcb_size = 0; - } END_CATCH + } if (pcb_size == 0) { - TRY { + try { pcb_size = parse_and_eval_long("sizeof(struct pcb)"); - } CATCH(e, RETURN_MASK_ERROR) { + } catch (const gdb_exception_error &e) { #ifdef HAVE_KVM_OPEN2 if (kvm_native(nkvm)) pcb_size = sizeof(struct pcb); else pcb_size = 0; #else pcb_size = sizeof(struct pcb); #endif - } END_CATCH + } } kvm = nkvm; vmcore = filename; push_target (&fbsd_kvm_ops); kgdb_dmesg(); inf = current_inferior(); if (inf->pid == 0) { inferior_appeared(inf, 1); inf->fake_pid_p = 1; } solib_create_inferior_hook(0); init_thread_list(); kt = kgdb_thr_init(ops->cpu_pcb_addr); while (kt != NULL) { add_thread_silent(fbsd_vmcore_ptid(kt->tid)); kt = kgdb_thr_next(kt); } if (curkthr != 0) inferior_ptid = fbsd_vmcore_ptid(curkthr->tid); target_fetch_registers (get_current_regcache (), -1); reinit_frame_cache (); print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1); } void fbsd_kvm_target::close() { if (kvm != NULL) { clear_solib(); if (kvm_close(kvm) != 0) warning("cannot close \"%s\": %s", vmcore, kvm_geterr(kvm)); kvm = NULL; xfree(vmcore); vmcore = NULL; } inferior_ptid = null_ptid; } #if 0 static void kgdb_trgt_detach(struct target_ops *ops, const char *args, int from_tty) { if (args) error ("Too many arguments"); unpush_target(&kgdb_trgt_ops); reinit_frame_cache(); if (from_tty) printf_filtered("No vmcore file now.\n"); } #endif const char * fbsd_kvm_target::extra_thread_info(thread_info *ti) { return (kgdb_thr_extra_thread_info(ti->ptid.tid())); } bool fbsd_kvm_target::has_memory () { return (kvm != NULL); } bool fbsd_kvm_target::has_stack () { return (kvm != NULL); } bool fbsd_kvm_target::has_registers () { return (kvm != NULL); } void fbsd_kvm_target::files_info() { printf_filtered ("\t`%s', ", vmcore); wrap_here (" "); printf_filtered ("file type %s.\n", "FreeBSD kernel vmcore"); } void fbsd_kvm_target::update_thread_list() { /* * XXX: We should probably rescan the thread list here and update * it if there are any changes. One nit though is that we'd have * to detect exited threads. */ gdb_assert(kvm != NULL); #if 0 prune_threads(); #endif #if 0 struct target_ops *tb; if (kvm != NULL) return; tb = find_target_beneath(ops); if (tb->to_update_thread_list != NULL) tb->to_update_thread_list(tb); #endif } -const char * +std::string fbsd_kvm_target::pid_to_str(ptid_t ptid) { - static char buf[33]; - - snprintf(buf, sizeof(buf), "Thread %ld", ptid.tid()); - return (buf); + return string_printf (_("Thread %ld"), ptid.tid ()); } bool fbsd_kvm_target::thread_alive(ptid_t ptid) { return (kgdb_thr_lookup_tid(ptid.tid()) != NULL); } void fbsd_kvm_target::fetch_registers(struct regcache *regcache, int regnum) { struct fbsd_vmcore_ops *ops = (struct fbsd_vmcore_ops *) gdbarch_data (target_gdbarch(), fbsd_vmcore_data); struct kthr *kt; if (ops->supply_pcb == NULL) return; kt = kgdb_thr_lookup_tid(inferior_ptid.tid()); if (kt == NULL) return; ops->supply_pcb(regcache, kt->pcb); } enum target_xfer_status fbsd_kvm_target::xfer_partial(enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) { ssize_t nbytes; gdb_assert(kvm != NULL); switch (object) { case TARGET_OBJECT_MEMORY: nbytes = len; if (readbuf != NULL) #ifdef HAVE_KVM_OPEN2 nbytes = kvm_read2(kvm, offset, readbuf, len); #else nbytes = kvm_read(kvm, offset, readbuf, len); #endif if (writebuf != NULL && len > 0) nbytes = kvm_write(kvm, offset, writebuf, len); if (nbytes < 0) return TARGET_XFER_E_IO; if (nbytes == 0) return TARGET_XFER_EOF; *xfered_len = nbytes; return TARGET_XFER_OK; default: return TARGET_XFER_E_IO; } } #if 0 static int kgdb_trgt_insert_breakpoint(struct target_ops *ops, struct gdbarch *gdbarch, struct bp_target_info *bp_tgt) { return 0; } static int kgdb_trgt_remove_breakpoint(struct target_ops *ops, struct gdbarch *gdbarch, struct bp_target_info *bp_tgt, enum remove_bp_reason reason) { return 0; } #endif static void kgdb_switch_to_thread(const char *arg, int tid) { struct thread_info *tp; tp = find_thread_ptid (fbsd_vmcore_ptid (tid)); if (tp == NULL) error ("invalid tid"); thread_select (arg, tp); } static void kgdb_set_proc_cmd (const char *arg, int from_tty) { CORE_ADDR addr; struct kthr *thr; if (!arg) error_no_arg ("proc address for the new context"); if (kvm == NULL) error ("only supported for core file target"); addr = parse_and_eval_address (arg); if (addr < kernstart) { thr = kgdb_thr_lookup_pid((int)addr); if (thr == NULL) error ("invalid pid"); } else { thr = kgdb_thr_lookup_paddr(addr); if (thr == NULL) error("invalid proc address"); } kgdb_switch_to_thread(arg, thr->tid); } static void kgdb_set_tid_cmd (const char *arg, int from_tty) { CORE_ADDR addr; struct kthr *thr; if (!arg) error_no_arg ("TID or thread address for the new context"); addr = (CORE_ADDR) parse_and_eval_address (arg); if (kvm != NULL && addr >= kernstart) { thr = kgdb_thr_lookup_taddr(addr); if (thr == NULL) error("invalid thread address"); addr = thr->tid; } kgdb_switch_to_thread(arg, addr); } void _initialize_kgdb_target(void) { add_target(fbsd_kvm_target_info, fbsd_kvm_target_open); fbsd_vmcore_data = gdbarch_data_register_pre_init(fbsd_vmcore_init); add_com ("proc", class_obscure, kgdb_set_proc_cmd, "Set current process context"); add_com ("tid", class_obscure, kgdb_set_tid_cmd, "Set current thread context"); } CORE_ADDR kgdb_trgt_stop_pcb(u_int cpuid) { if (stoppcbs == 0 || pcb_size == 0) return 0; return (stoppcbs + pcb_size * cpuid); } Index: head/devel/gdb/files/kgdb/i386fbsd-kern.c =================================================================== --- head/devel/gdb/files/kgdb/i386fbsd-kern.c (revision 528131) +++ head/devel/gdb/files/kgdb/i386fbsd-kern.c (revision 528132) @@ -1,580 +1,580 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include "defs.h" #include "frame-unwind.h" #include "gdbcore.h" #include "inferior.h" #include "osabi.h" #include "regcache.h" #include "progspace.h" #include "solib.h" #include "trad-frame.h" #include "i386-tdep.h" #ifdef __i386__ #include #include #include #include #include #endif #include "kgdb.h" struct i386fbsd_info { int ofs_fix; }; /* Per-program-space data key. */ static const struct program_space_data *i386fbsd_pspace_data; static void i386fbsd_pspace_data_cleanup (struct program_space *pspace, void *arg) { struct i386fbsd_info *info = (struct i386fbsd_info *)arg; xfree (info); } /* Get the current i386fbsd data. If none is found yet, add it now. This function always returns a valid object. */ static struct i386fbsd_info * get_i386fbsd_info (void) { struct i386fbsd_info *info; info = (struct i386fbsd_info *) program_space_data (current_program_space, i386fbsd_pspace_data); if (info != NULL) return info; info = XCNEW (struct i386fbsd_info); set_program_space_data (current_program_space, i386fbsd_pspace_data, info); /* * In revision 1.117 of i386/i386/exception.S trap handlers * were changed to pass trapframes by reference rather than * by value. Detect this by seeing if the first instruction * at the 'calltrap' label is a "push %esp" which has the * opcode 0x54. */ if (parse_and_eval_long("((char *)calltrap)[0]") == 0x54) info->ofs_fix = 4; else info->ofs_fix = 0; return info; } /* * Even though the pcb contains fields for the segment selectors, only * %gs is updated on each context switch. The other selectors are * saved in stoppcbs[], but we just hardcode their known values rather * than handling that special case. */ static const int i386fbsd_pcb_offset[] = { -1, /* %eax */ -1, /* %ecx */ -1, /* %edx */ 4 * 4, /* %ebx */ 3 * 4, /* %esp */ 2 * 4, /* %ebp */ 1 * 4, /* %esi */ 0 * 4, /* %edi */ 5 * 4, /* %eip */ -1, /* %eflags */ -1, /* %cs */ -1, /* %ss */ -1, /* %ds */ -1, /* %es */ -1, /* %fs */ -1, /* %gs */ }; #define CODE_SEL (4 << 3) #define DATA_SEL (5 << 3) #define PRIV_SEL (1 << 3) static void i386fbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) { gdb_byte buf[4]; int i; memset(buf, 0, sizeof(buf)); /* * XXX The PCB may have been swapped out. Supply a dummy %eip value * so as to avoid triggering an exception during stack unwinding. */ regcache->raw_supply(I386_EIP_REGNUM, buf); for (i = 0; i < ARRAY_SIZE (i386fbsd_pcb_offset); i++) if (i386fbsd_pcb_offset[i] != -1) { if (target_read_memory(pcb_addr + i386fbsd_pcb_offset[i], buf, sizeof buf) != 0) continue; regcache->raw_supply(i, buf); } regcache->raw_supply_unsigned(I386_CS_REGNUM, CODE_SEL); regcache->raw_supply_unsigned(I386_DS_REGNUM, DATA_SEL); regcache->raw_supply_unsigned(I386_ES_REGNUM, DATA_SEL); regcache->raw_supply_unsigned(I386_FS_REGNUM, PRIV_SEL); regcache->raw_supply_unsigned(I386_GS_REGNUM, DATA_SEL); regcache->raw_supply_unsigned(I386_SS_REGNUM, DATA_SEL); } #ifdef __i386__ /* TODO: Make this cross-debugger friendly. */ static const int i386fbsd_tss_offset[] = { 10 * 4, /* %eax */ 11 * 4, /* %ecx */ 12 * 4, /* %edx */ 13 * 4, /* %ebx */ 14 * 4, /* %esp */ 15 * 4, /* %ebp */ 16 * 4, /* %esi */ 17 * 4, /* %edi */ 8 * 4, /* %eip */ 9 * 4, /* %eflags */ 19 * 4, /* %cs */ 20 * 4, /* %ss */ 21 * 4, /* %ds */ 18 * 4, /* %es */ 22 * 4, /* %fs */ 23 * 4, /* %gs */ }; /* * If the current thread is executing on a CPU, fetch the common_tss * for that CPU. * * This is painful because 'struct pcpu' is variant sized, so we can't * use it. Instead, we lookup the GDT selector for this CPU and * extract the base of the TSS from there. */ static CORE_ADDR i386fbsd_fetch_tss(void) { struct kthr *kt; struct segment_descriptor sd; CORE_ADDR addr, cpu0prvpage, tss; kt = kgdb_thr_lookup_tid(inferior_ptid.tid()); if (kt == NULL || kt->cpu == NOCPU || kt->cpu < 0) return (0); addr = kgdb_lookup("gdt"); if (addr == 0) return (0); addr += (kt->cpu * NGDT + GPROC0_SEL) * sizeof(sd); if (target_read_memory(addr, (gdb_byte *)&sd, sizeof(sd)) != 0) return (0); if (sd.sd_type != SDT_SYS386BSY) { warning ("descriptor is not a busy TSS"); return (0); } tss = sd.sd_hibase << 24 | sd.sd_lobase; /* * In SMP kernels, the TSS is stored as part of the per-CPU * data. On older kernels, the CPU0's private page * is stored at an address that isn't mapped in minidumps. * However, the data is mapped at the alternate cpu0prvpage * address. Thus, if the TSS is at the invalid address, * change it to be relative to cpu0prvpage instead. */ if (trunc_page(tss) == 0xffc00000) { - TRY { + try { cpu0prvpage = parse_and_eval_address("cpu0prvpage"); - } CATCH(e, RETURN_MASK_ERROR) { + } catch (const gdb_exception_error &e) { return (0); - } END_CATCH + } tss = cpu0prvpage + (tss & PAGE_MASK); } return (tss); } static struct trad_frame_cache * i386fbsd_dblfault_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; CORE_ADDR addr, func, tss; int i; if (*this_cache != NULL) return (struct trad_frame_cache *)(*this_cache); cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_func (this_frame); tss = i386fbsd_fetch_tss (); for (i = 0; i < ARRAY_SIZE (i386fbsd_tss_offset); i++) if (i386fbsd_tss_offset[i] != -1) trad_frame_set_reg_addr (cache, i, tss + i386fbsd_tss_offset[i]); /* Construct the frame ID using the function start. */ /* XXX: Stack address should be dbfault_stack + PAGE_SIZE. */ trad_frame_set_id (cache, frame_id_build (tss + sizeof(struct i386tss), func)); return cache; } static void i386fbsd_dblfault_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) { struct trad_frame_cache *cache = i386fbsd_dblfault_cache (this_frame, this_cache); trad_frame_get_id (cache, this_id); } static struct value * i386fbsd_dblfault_prev_register (struct frame_info *this_frame, void **this_cache, int regnum) { struct trad_frame_cache *cache = i386fbsd_dblfault_cache (this_frame, this_cache); return trad_frame_get_register (cache, this_frame, regnum); } static int i386fbsd_dblfault_sniffer (const struct frame_unwind *self, struct frame_info *this_frame, void **this_prologue_cache) { const char *name; find_pc_partial_function (get_frame_func (this_frame), &name, NULL, NULL); return (name && strcmp (name, "dblfault_handler") == 0); } static const struct frame_unwind i386fbsd_dblfault_unwind = { SIGTRAMP_FRAME, default_frame_unwind_stop_reason, i386fbsd_dblfault_this_id, i386fbsd_dblfault_prev_register, NULL, i386fbsd_dblfault_sniffer }; #endif static const int i386fbsd_trapframe_offset[] = { 10 * 4, /* %eax */ 9 * 4, /* %ecx */ 8 * 4, /* %edx */ 7 * 4, /* %ebx */ 16 * 4, /* %esp */ 5 * 4, /* %ebp */ 4 * 4, /* %esi */ 3 * 4, /* %edi */ 13 * 4, /* %eip */ 15 * 4, /* %eflags */ 14 * 4, /* %cs */ 17 * 4, /* %ss */ 2 * 4, /* %ds */ 1 * 4, /* %es */ 0 * 4, /* %fs */ -1 /* %gs */ }; #define TRAPFRAME_SIZE 72 static struct trad_frame_cache * i386fbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; struct i386fbsd_info *info; CORE_ADDR addr, cs, func, pc, sp; const char *name; int i; if (*this_cache != NULL) return ((struct trad_frame_cache *)*this_cache); info = get_i386fbsd_info(); cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_func (this_frame); sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM); find_pc_partial_function (func, &name, NULL, NULL); if (strcmp(name, "calltrap") == 0 || strcmp(name, "Xlcall_syscall") == 0 || strcmp(name, "Xint0x80_syscall") == 0) /* Traps in later kernels pass the trap frame by reference. */ sp += info->ofs_fix; else if (strcmp(name, "Xtimerint") == 0) /* Timer interrupts also pass the trap frame by reference. */ sp += info->ofs_fix; else if (strcmp(name, "Xcpustop") == 0 || strcmp(name, "Xrendezvous") == 0 || strcmp(name, "Xipi_intr_bitmap_handler") == 0 || strcmp(name, "Xlazypmap") == 0) /* These handlers push a trap frame only. */ ; else if (strcmp(name, "fork_trampoline") == 0) if (get_frame_pc (this_frame) == func) { /* fork_exit hasn't been called (kthread has never run), so %esp in the pcb points to the word above the trapframe. */ sp += 4; } else { /* fork_exit has been called, so %esp in fork_exit's frame is &tf - 12. */ sp += 12; } else { /* Interrupt frames pass the IDT vector in addition to the trap frame. */ sp += info->ofs_fix + 4; } addr = sp + i386fbsd_trapframe_offset[I386_CS_REGNUM]; cs = read_memory_unsigned_integer (addr, 4, byte_order); for (i = 0; i < ARRAY_SIZE (i386fbsd_trapframe_offset); i++) { /* %ss/%esp are only present in the trapframe for a trap from userland. */ if ((cs & I386_SEL_RPL) == I386_SEL_KPL) { if (i == I386_SS_REGNUM) continue; if (i == I386_ESP_REGNUM) { trad_frame_set_reg_value (cache, i, sp + TRAPFRAME_SIZE - 8); continue; } } if (i386fbsd_trapframe_offset[i] != -1) trad_frame_set_reg_addr (cache, i, sp + i386fbsd_trapframe_offset[i]); } /* Read %eip from trap frame. */ addr = sp + i386fbsd_trapframe_offset[I386_EIP_REGNUM]; pc = read_memory_unsigned_integer (addr, 4, byte_order); if (pc == 0 && strcmp(name, "fork_trampoline") == 0) { /* Initial frame of a kthread; terminate backtrace. */ trad_frame_set_id (cache, outer_frame_id); } else { /* Construct the frame ID using the function start. */ sp += TRAPFRAME_SIZE; if ((cs & I386_SEL_RPL) == I386_SEL_KPL) sp -= 8; trad_frame_set_id (cache, frame_id_build (sp, func)); } return cache; } static void i386fbsd_trapframe_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) { struct trad_frame_cache *cache = i386fbsd_trapframe_cache (this_frame, this_cache); trad_frame_get_id (cache, this_id); } static struct value * i386fbsd_trapframe_prev_register (struct frame_info *this_frame, void **this_cache, int regnum) { struct trad_frame_cache *cache = i386fbsd_trapframe_cache (this_frame, this_cache); return trad_frame_get_register (cache, this_frame, regnum); } static int i386fbsd_trapframe_sniffer (const struct frame_unwind *self, struct frame_info *this_frame, void **this_prologue_cache) { const char *name; find_pc_partial_function (get_frame_func (this_frame), &name, NULL, NULL); return (name && ((strcmp (name, "calltrap") == 0) || (strcmp (name, "fork_trampoline") == 0) || (name[0] == 'X' && name[1] != '_'))); } static const struct frame_unwind i386fbsd_trapframe_unwind = { SIGTRAMP_FRAME, default_frame_unwind_stop_reason, i386fbsd_trapframe_this_id, i386fbsd_trapframe_prev_register, NULL, i386fbsd_trapframe_sniffer }; static void i386fbsd_kernel_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch) { i386_elf_init_abi(info, gdbarch); #ifdef __i386__ frame_unwind_prepend_unwinder(gdbarch, &i386fbsd_dblfault_unwind); #endif frame_unwind_prepend_unwinder(gdbarch, &i386fbsd_trapframe_unwind); set_solib_ops(gdbarch, &kld_so_ops); fbsd_vmcore_set_supply_pcb(gdbarch, i386fbsd_supply_pcb); fbsd_vmcore_set_cpu_pcb_addr(gdbarch, kgdb_trgt_stop_pcb); } void _initialize_i386_kgdb_tdep(void) { /* This is used for both i386 and amd64, but amd64 always includes this target, so just include it here. */ gdbarch_register_osabi_sniffer(bfd_arch_i386, bfd_target_elf_flavour, fbsd_kernel_osabi_sniffer); gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_FREEBSD_KERNEL, i386fbsd_kernel_init_abi); i386fbsd_pspace_data = register_program_space_data_with_cleanup (NULL, i386fbsd_pspace_data_cleanup); #ifdef __i386__ /* * FreeBSD/i386 kernels prior to the introduction of AVX * support used a different layout for the PCB. If gdb is * compiled on these systems, these asserts will fail. The * package builders build packages on older systems which are * then run on newer systems. These binaries trip over these * assertions even when debugging user programs and even * though the running kernel is new enough. To cope, disable * the assertion checks unless gdb is built against a new * enough world. Note that this means kgdb is not going to * parse PCBs correctly on FreeBSD/i386 kernels before AVX was * merged. */ #if __FreeBSD_version >= 1001505 gdb_assert(offsetof(struct pcb, pcb_ebx) == i386fbsd_pcb_offset[I386_EBX_REGNUM]); gdb_assert(offsetof(struct pcb, pcb_esp) == i386fbsd_pcb_offset[I386_ESP_REGNUM]); gdb_assert(offsetof(struct pcb, pcb_ebp) == i386fbsd_pcb_offset[I386_EBP_REGNUM]); gdb_assert(offsetof(struct pcb, pcb_esi) == i386fbsd_pcb_offset[I386_ESI_REGNUM]); gdb_assert(offsetof(struct pcb, pcb_edi) == i386fbsd_pcb_offset[I386_EDI_REGNUM]); gdb_assert(offsetof(struct pcb, pcb_eip) == i386fbsd_pcb_offset[I386_EIP_REGNUM]); #endif gdb_assert(CODE_SEL == GSEL(GCODE_SEL, SEL_KPL)); gdb_assert(DATA_SEL == GSEL(GDATA_SEL, SEL_KPL)); gdb_assert(PRIV_SEL == GSEL(GPRIV_SEL, SEL_KPL)); gdb_assert(sizeof(struct trapframe) == TRAPFRAME_SIZE); gdb_assert(offsetof(struct trapframe, tf_eax) == i386fbsd_trapframe_offset[I386_EAX_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_ecx) == i386fbsd_trapframe_offset[I386_ECX_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_edx) == i386fbsd_trapframe_offset[I386_EDX_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_ebx) == i386fbsd_trapframe_offset[I386_EBX_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_esp) == i386fbsd_trapframe_offset[I386_ESP_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_ebp) == i386fbsd_trapframe_offset[I386_EBP_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_esi) == i386fbsd_trapframe_offset[I386_ESI_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_edi) == i386fbsd_trapframe_offset[I386_EDI_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_eip) == i386fbsd_trapframe_offset[I386_EIP_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_eflags) == i386fbsd_trapframe_offset[I386_EFLAGS_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_cs) == i386fbsd_trapframe_offset[I386_CS_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_ss) == i386fbsd_trapframe_offset[I386_SS_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_ds) == i386fbsd_trapframe_offset[I386_DS_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_es) == i386fbsd_trapframe_offset[I386_ES_REGNUM]); gdb_assert(offsetof(struct trapframe, tf_fs) == i386fbsd_trapframe_offset[I386_FS_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_eax) == i386fbsd_tss_offset[I386_EAX_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_ecx) == i386fbsd_tss_offset[I386_ECX_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_edx) == i386fbsd_tss_offset[I386_EDX_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_ebx) == i386fbsd_tss_offset[I386_EBX_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_esp) == i386fbsd_tss_offset[I386_ESP_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_ebp) == i386fbsd_tss_offset[I386_EBP_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_esi) == i386fbsd_tss_offset[I386_ESI_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_edi) == i386fbsd_tss_offset[I386_EDI_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_eip) == i386fbsd_tss_offset[I386_EIP_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_eflags) == i386fbsd_tss_offset[I386_EFLAGS_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_cs) == i386fbsd_tss_offset[I386_CS_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_ss) == i386fbsd_tss_offset[I386_SS_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_ds) == i386fbsd_tss_offset[I386_DS_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_es) == i386fbsd_tss_offset[I386_ES_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_fs) == i386fbsd_tss_offset[I386_FS_REGNUM]); gdb_assert(offsetof(struct i386tss, tss_gs) == i386fbsd_tss_offset[I386_GS_REGNUM]); #endif } Index: head/devel/gdb/files/kgdb/riscv-fbsd-kern.c =================================================================== --- head/devel/gdb/files/kgdb/riscv-fbsd-kern.c (revision 528131) +++ head/devel/gdb/files/kgdb/riscv-fbsd-kern.c (revision 528132) @@ -1,210 +1,211 @@ /*- * Copyright (c) 2018 John Baldwin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ */ /* Target-dependent code for FreeBSD/riscv64 kernels. */ #include "defs.h" #include "riscv-tdep.h" #include "frame-unwind.h" +#include "gdbarch.h" #include "gdbcore.h" #include "osabi.h" #include "regcache.h" #include "regset.h" #include "solib.h" #include "target.h" #include "trad-frame.h" #include "kgdb.h" static const struct regcache_map_entry riscv_fbsd_pcbmap[] = { { 1, RISCV_RA_REGNUM, 0 }, { 1, RISCV_SP_REGNUM, 0 }, { 1, RISCV_GP_REGNUM, 0 }, { 1, RISCV_TP_REGNUM, 0 }, { 3, 5, 0 }, /* t0 - t2 */ { 4, 28, 0 }, /* t3 - t6 */ { 2, RISCV_FP_REGNUM, 0 }, /* s0 - s1 */ { 10, 18, 0 }, /* s2 - s11 */ { 8, RISCV_A0_REGNUM, 0 }, /* a0 - a7 */ { 0 } }; static const struct regset riscv_fbsd_pcbregset = { riscv_fbsd_pcbmap, regcache_supply_regset, regcache_collect_regset }; static void riscv_fbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) { gdb_byte buf[31 * 8]; /* Always give a value for PC in case the PCB isn't readable. */ regcache->raw_supply_zeroed (RISCV_PC_REGNUM); regcache->raw_supply_zeroed (RISCV_ZERO_REGNUM); if (target_read_memory (pcb_addr, buf, sizeof buf) == 0) { regcache->supply_regset (&riscv_fbsd_pcbregset, -1, buf, sizeof (buf)); /* Supply the RA as PC as well to simulate the PC as if the thread had just returned. */ regcache->raw_supply (RISCV_PC_REGNUM, buf); } } static const struct regcache_map_entry riscv_fbsd_tfmap[] = { { 1, RISCV_RA_REGNUM, 0 }, { 1, RISCV_SP_REGNUM, 0 }, { 1, RISCV_GP_REGNUM, 0 }, { 1, RISCV_TP_REGNUM, 0 }, { 3, 5, 0 }, /* t0 - t2 */ { 4, 28, 0 }, /* t3 - t6 */ { 2, RISCV_FP_REGNUM, 0 }, /* s0 - s1 */ { 10, 18, 0 }, /* s2 - s11 */ { 8, RISCV_A0_REGNUM, 0 }, /* a0 - a7 */ { 1, RISCV_PC_REGNUM, 0 }, { 1, RISCV_CSR_SSTATUS_REGNUM, 0 }, { 1, RISCV_CSR_STVAL_REGNUM, 0 }, { 1, RISCV_CSR_SCAUSE_REGNUM, 0 }, { 0 } }; static struct trad_frame_cache * riscv_fbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; CORE_ADDR func, pc, sp; const char *name; int xlen; if (*this_cache != NULL) return ((struct trad_frame_cache *)*this_cache); cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; sp = get_frame_register_unsigned (this_frame, RISCV_SP_REGNUM); xlen = riscv_isa_xlen (gdbarch); trad_frame_set_reg_regmap (cache, riscv_fbsd_tfmap, sp, 35 * xlen); /* Read $PC from trap frame. */ func = get_frame_func (this_frame); find_pc_partial_function (func, &name, NULL, NULL); pc = read_memory_unsigned_integer (sp + 31 * xlen, xlen, byte_order); if (pc == 0 && strcmp(name, "fork_trampoline") == 0) { /* Initial frame of a kthread; terminate backtrace. */ trad_frame_set_id (cache, outer_frame_id); } else { /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (sp + 35 * xlen, func)); } return cache; } static void riscv_fbsd_trapframe_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) { struct trad_frame_cache *cache = riscv_fbsd_trapframe_cache (this_frame, this_cache); trad_frame_get_id (cache, this_id); } static struct value * riscv_fbsd_trapframe_prev_register (struct frame_info *this_frame, void **this_cache, int regnum) { struct trad_frame_cache *cache = riscv_fbsd_trapframe_cache (this_frame, this_cache); return trad_frame_get_register (cache, this_frame, regnum); } static int riscv_fbsd_trapframe_sniffer (const struct frame_unwind *self, struct frame_info *this_frame, void **this_prologue_cache) { const char *name; find_pc_partial_function (get_frame_func (this_frame), &name, NULL, NULL); return (name != NULL && ((strcmp (name, "cpu_exception_handler_user") == 0) || (strcmp (name, "cpu_exception_handler_supervisor") == 0))); } static const struct frame_unwind riscv_fbsd_trapframe_unwind = { SIGTRAMP_FRAME, default_frame_unwind_stop_reason, riscv_fbsd_trapframe_this_id, riscv_fbsd_trapframe_prev_register, NULL, riscv_fbsd_trapframe_sniffer }; /* Implement the 'init_osabi' method of struct gdb_osabi_handler. */ static void riscv_fbsd_kernel_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { frame_unwind_prepend_unwinder (gdbarch, &riscv_fbsd_trapframe_unwind); set_solib_ops (gdbarch, &kld_so_ops); set_gdbarch_software_single_step (gdbarch, riscv_software_single_step); fbsd_vmcore_set_supply_pcb (gdbarch, riscv_fbsd_supply_pcb); fbsd_vmcore_set_cpu_pcb_addr (gdbarch, kgdb_trgt_stop_pcb); } /* Provide a prototype to silence -Wmissing-prototypes. */ extern initialize_file_ftype _initialize_riscv_kgdb_tdep; void _initialize_riscv_kgdb_tdep (void) { gdbarch_register_osabi_sniffer(bfd_arch_riscv, bfd_target_elf_flavour, fbsd_kernel_osabi_sniffer); gdbarch_register_osabi (bfd_arch_riscv, 0, GDB_OSABI_FREEBSD_KERNEL, riscv_fbsd_kernel_init_abi); } Index: head/devel/gdb/files/kgdb/sparc64fbsd-kern.c =================================================================== --- head/devel/gdb/files/kgdb/sparc64fbsd-kern.c (revision 528131) +++ head/devel/gdb/files/kgdb/sparc64fbsd-kern.c (revision 528132) @@ -1,314 +1,315 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include "defs.h" +#include "gdbarch.h" #include "gdbcore.h" #include "osabi.h" #include "regcache.h" #include "target.h" #include "frame-unwind.h" #include "solib.h" #include "trad-frame.h" #include "sparc-tdep.h" #include "sparc64-tdep.h" #ifdef __sparc64__ #include #include #include #endif #include "kgdb.h" #ifdef __sparc64__ static void sparc64fbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) { struct pcb pcb; if (target_read_memory(pcb_addr, &pcb, sizeof(pcb)) != 0) memset(&pcb, 0, sizeof(pcb)); regcache_raw_supply(regcache, SPARC_SP_REGNUM, (char *)&pcb.pcb_sp); sparc_supply_rwindow(regcache, pcb.pcb_sp, -1); regcache_raw_supply(regcache, SPARC64_PC_REGNUM, (char *)&pcb.pcb_pc); pcb.pcb_pc += 4; regcache_raw_supply(regcache, SPARC64_NPC_REGNUM, (char *)&pcb.pcb_pc); } #endif #define OFF_TF_SP (14 * 8) #define OFF_TF_TPC (25 * 8) #define OFF_TF_TNPC (24 * 8) #define OFF_TF_OUT (8 * 8) #define TRAPFRAME_SIZE (32 * 8) #ifdef __sparc64__ _Static_assert(sizeof(struct trapframe) == TRAPFRAME_SIZE, "trapframe size"); _Static_assert(offsetof(struct trapframe, tf_sp) == OFF_TF_SP, "tf_sp offset"); _Static_assert(offsetof(struct trapframe, tf_tpc) == OFF_TF_TPC, "tf_tpc offset"); _Static_assert(offsetof(struct trapframe, tf_tnpc) == OFF_TF_TNPC, "tf_tnpc offset"); _Static_assert(offsetof(struct trapframe, tf_out) == OFF_TF_OUT, "tf_out offset"); #endif static struct sparc_frame_cache * sparc64fbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache) { struct sparc_frame_cache *cache; CORE_ADDR fp, sp, trapframe_addr; int regnum; if (*this_cache) return (struct sparc_frame_cache *)*this_cache; cache = sparc_frame_cache (this_frame, this_cache); gdb_assert (cache == *this_cache); fp = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM); trapframe_addr = fp + BIAS - TRAPFRAME_SIZE; sp = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM); cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); cache->saved_regs[SPARC_SP_REGNUM].addr = trapframe_addr + OFF_TF_SP; #ifdef notyet cache->saved_regs[SPARC64_STATE_REGNUM].addr = trapframe_addr + OFF_TF_TSTATE; #endif cache->saved_regs[SPARC64_PC_REGNUM].addr = trapframe_addr + OFF_TF_TPC; cache->saved_regs[SPARC64_NPC_REGNUM].addr = trapframe_addr + OFF_TF_TNPC; for (regnum = SPARC_O0_REGNUM; regnum <= SPARC_O7_REGNUM; regnum++) cache->saved_regs[regnum].addr = trapframe_addr + OFF_TF_OUT + (regnum - SPARC_O0_REGNUM) * 8; for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++) cache->saved_regs[regnum].addr = sp + BIAS + (regnum - SPARC_L0_REGNUM) * 8; return cache; } static void sparc64fbsd_trapframe_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) { struct sparc_frame_cache *cache = sparc64fbsd_trapframe_cache (this_frame, this_cache); (*this_id) = frame_id_build (cache->base, cache->pc); } static struct value * sparc64fbsd_trapframe_prev_register (struct frame_info *this_frame, void **this_cache, int regnum) { struct sparc_frame_cache *cache = sparc64fbsd_trapframe_cache (this_frame, this_cache); return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum); } static int sparc64fbsd_trapframe_sniffer (const struct frame_unwind *self, struct frame_info *this_frame, void **this_cache) { CORE_ADDR pc; const char *name; pc = get_frame_address_in_block (this_frame); find_pc_partial_function (pc, &name, NULL, NULL); if (name && (strcmp(name, "tl0_intr") == 0 || strcmp(name, "tl0_trap") == 0 || strcmp(name, "tl1_intr") == 0 || strcmp(name, "tl1_trap") == 0)) return 1; return 0; } static const struct frame_unwind sparc64fbsd_trapframe_unwind = { SIGTRAMP_FRAME, default_frame_unwind_stop_reason, sparc64fbsd_trapframe_this_id, sparc64fbsd_trapframe_prev_register, NULL, sparc64fbsd_trapframe_sniffer }; #if 0 struct kgdb_frame_cache { CORE_ADDR pc; CORE_ADDR sp; CORE_ADDR fp; }; static struct kgdb_frame_cache * kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) { char buf[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; cache = *this_cache; if (cache == NULL) { cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); *this_cache = cache; cache->pc = frame_func_unwind(next_frame); frame_unwind_register(next_frame, SPARC_SP_REGNUM, buf); cache->sp = extract_unsigned_integer(buf, register_size(current_gdbarch, SPARC_SP_REGNUM)); frame_unwind_register(next_frame, SPARC_FP_REGNUM, buf); cache->fp = extract_unsigned_integer(buf, register_size(current_gdbarch, SPARC_FP_REGNUM)); cache->fp += BIAS - sizeof(struct trapframe); } return (cache); } static void kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, struct frame_id *this_id) { struct kgdb_frame_cache *cache; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *this_id = frame_id_build(cache->sp, cache->pc); } static void kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, void *valuep) { char dummy_valuep[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; int ofs, regsz; regsz = register_size(current_gdbarch, regnum); if (valuep == NULL) valuep = dummy_valuep; memset(valuep, 0, regsz); *optimizedp = 0; *addrp = 0; *lvalp = not_lval; *realnump = -1; cache = kgdb_trgt_frame_cache(next_frame, this_cache); switch (regnum) { case SPARC_SP_REGNUM: ofs = offsetof(struct trapframe, tf_sp); break; case SPARC64_PC_REGNUM: ofs = offsetof(struct trapframe, tf_tpc); break; case SPARC64_NPC_REGNUM: ofs = offsetof(struct trapframe, tf_tnpc); break; case SPARC_O0_REGNUM: case SPARC_O1_REGNUM: case SPARC_O2_REGNUM: case SPARC_O3_REGNUM: case SPARC_O4_REGNUM: case SPARC_O5_REGNUM: case SPARC_O7_REGNUM: ofs = offsetof(struct trapframe, tf_out) + (regnum - SPARC_O0_REGNUM) * 8; break; default: if (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) { ofs = (regnum - SPARC_L0_REGNUM) * 8; *addrp = cache->sp + BIAS + ofs; *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); } return; } *addrp = cache->fp + ofs; *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); } static const struct frame_unwind kgdb_trgt_trapframe_unwind = { UNKNOWN_FRAME, &kgdb_trgt_trapframe_this_id, &kgdb_trgt_trapframe_prev_register }; const struct frame_unwind * kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) { char *pname; CORE_ADDR pc; pc = frame_func_unwind(next_frame); pname = NULL; find_pc_partial_function(pc, &pname, NULL, NULL); if (pname == NULL) return (NULL); if (strcmp(pname, "tl0_intr") == 0 || strcmp(pname, "tl0_trap") == 0 || strcmp(pname, "tl1_intr") == 0 || strcmp(pname, "tl1_trap") == 0) return (&kgdb_trgt_trapframe_unwind); /* printf("%s: %lx =%s\n", __func__, pc, pname); */ return (NULL); } #endif static void sparc64fbsd_kernel_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch) { sparc64_init_abi(info, gdbarch); frame_unwind_prepend_unwinder(gdbarch, &sparc64fbsd_trapframe_unwind); set_solib_ops(gdbarch, &kld_so_ops); #ifdef __sparc64__ fbsd_vmcore_set_supply_pcb(gdbarch, sparc64fbsd_supply_pcb); fbsd_vmcore_set_cpu_pcb_addr(gdbarch, kgdb_trgt_stop_pcb); #endif } void _initialize_sparc64_kgdb_tdep(void) { gdbarch_register_osabi_sniffer(bfd_arch_sparc, bfd_target_elf_flavour, fbsd_kernel_osabi_sniffer); gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9, GDB_OSABI_FREEBSD_KERNEL, sparc64fbsd_kernel_init_abi); } Index: head/devel/gdb/files/patch-gdb_gdbsupport_common-defs.h =================================================================== --- head/devel/gdb/files/patch-gdb_gdbsupport_common-defs.h (nonexistent) +++ head/devel/gdb/files/patch-gdb_gdbsupport_common-defs.h (revision 528132) @@ -0,0 +1,18 @@ +--- gdb/gdbsupport/common-defs.h.orig 2020-02-08 04:50:14.000000000 -0800 ++++ gdb/gdbsupport/common-defs.h 2020-02-27 10:06:21.899297000 -0800 +@@ -55,9 +55,15 @@ + + Must do this before including any system header, since other system + headers may include stdint.h/inttypes.h. */ ++#ifndef __STDC_CONSTANT_MACROS + #define __STDC_CONSTANT_MACROS 1 ++#endif ++#ifndef __STDC_LIMIT_MACROS + #define __STDC_LIMIT_MACROS 1 ++#endif ++#ifndef __STDC_FORMAT_MACROS + #define __STDC_FORMAT_MACROS 1 ++#endif + + /* Some distros enable _FORTIFY_SOURCE by default, which on occasion + has caused build failures with -Wunused-result when a patch is Property changes on: head/devel/gdb/files/patch-gdb_gdbsupport_common-defs.h ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/devel/gdb/files/patch-gnulib_import_stddef.in.h =================================================================== --- head/devel/gdb/files/patch-gnulib_import_stddef.in.h (nonexistent) +++ head/devel/gdb/files/patch-gnulib_import_stddef.in.h (revision 528132) @@ -0,0 +1,11 @@ +--- gnulib/import/stddef.in.h.orig 2020-02-08 04:50:14.000000000 -0800 ++++ gnulib/import/stddef.in.h 2020-02-27 10:09:59.859133000 -0800 +@@ -84,7 +84,7 @@ + /* Some platforms lack max_align_t. The check for _GCC_MAX_ALIGN_T is + a hack in case the configure-time test was done with g++ even though + we are currently compiling with gcc. */ +-#if ! (@HAVE_MAX_ALIGN_T@ || defined _GCC_MAX_ALIGN_T) ++#if 0 + /* On the x86, the maximum storage alignment of double, long, etc. is 4, + but GCC's C11 ABI for x86 says that max_align_t has an alignment of 8, + and the C11 standard allows this. Work around this problem by Property changes on: head/devel/gdb/files/patch-gnulib_import_stddef.in.h ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/devel/gdb/files/patch-libctf_swap.h =================================================================== --- head/devel/gdb/files/patch-libctf_swap.h (nonexistent) +++ head/devel/gdb/files/patch-libctf_swap.h (revision 528132) @@ -0,0 +1,11 @@ +--- libctf/swap.h.orig 2020-02-27 15:22:32.550650000 -0800 ++++ libctf/swap.h 2020-02-27 15:22:43.397285000 -0800 +@@ -43,7 +43,7 @@ bswap_32 (uint32_t v) + | ((v & 0x000000ff) << 24)); + } + +-inline uint64_t ++static inline uint64_t + bswap_identity_64 (uint64_t v) + { + return v; Property changes on: head/devel/gdb/files/patch-libctf_swap.h ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property