From 46818e45dd36a9337973ec6fbc9a7f9bdfe73d1a Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Jan 16 2021 08:14:04 +0000 Subject: import gcc-toolset-10-gdb-9.2-4.el8 --- diff --git a/SOURCES/_gdb.spec.Patch.include b/SOURCES/_gdb.spec.Patch.include index 1bf37e7..c2d3e52 100644 --- a/SOURCES/_gdb.spec.Patch.include +++ b/SOURCES/_gdb.spec.Patch.include @@ -412,3 +412,79 @@ Patch101: gdb-rhbz1844458-use-fputX_unfiltered.patch # (Aaron Merey, RH BZ 183877) Patch102: gdb-rhbz1838777-debuginfod.patch +# Use pkg-config for debuginfod.m4. +# (Aaron Merey) +Patch103: debuginfod-use-pkg-config.patch + +# Remove hack for GDB which sets the section size to 0 +# Kevin Buettner, RH BZ 1842691 +Patch104: gdb-rhbz1842691-corefile-mem-access-1of15.patch + +# Adjust corefile.exp test to show regression after bfd hack removal +# Kevin Buettner, RH BZ 1842691 +Patch105: gdb-rhbz1842691-corefile-mem-access-2of15.patch + +# section_table_xfer_memory: Replace section name with callback predicate +# Kevin Buettner, RH BZ 1842691 +Patch106: gdb-rhbz1842691-corefile-mem-access-3of15.patch + +# Provide access to non SEC_HAS_CONTENTS core file sections +# Kevin Buettner, RH BZ 1842961 +Patch107: gdb-rhbz1842691-corefile-mem-access-4of15.patch + +# Test ability to access unwritten-to mmap data in core file +# Kevin Buettner, RH BZ 1842961 +Patch108: gdb-rhbz1842691-corefile-mem-access-5of15.patch + +# Update binary_get_section_contents to seek using section's file position +# Kevin Buettner, RH BZ 1842961 +Patch109: gdb-rhbz1842691-corefile-mem-access-6of15.patch + +# Add new gdbarch method, read_core_file_mappings +# Kevin Buettner, RH BZ 1842961 +Patch110: gdb-rhbz1842691-corefile-mem-access-7of15.patch + +# Use NT_FILE note section for reading core target memory +# Kevin Buettner, RH BZ 1842961 +Patch111: gdb-rhbz1842691-corefile-mem-access-8of15.patch + +# Add test for accessing read-only mmapped data in a core file +# Kevin Buettner, RH BZ 1842691 +Patch112: gdb-rhbz1842691-corefile-mem-access-9of15.patch + +# gcore command: Place all file-backed mappings in NT_FILE note +# Kevin Buettner, RH BZ 1842961 +Patch113: gdb-rhbz1842691-corefile-mem-access-10of15.patch + +# Adjust coredump-filter.exp to account for NT_FILE note handling +# Kevin Buettner, RH BZ 1842961 +Patch114: gdb-rhbz1842691-corefile-mem-access-11of15.patch + +# Add new command "maint print core-file-backed-mappings" +# Kevin Buettner, RH BZ 1842961 +Patch115: gdb-rhbz1842691-corefile-mem-access-12of15.patch + +# Add documentation for "maint print core-file-backed-mappings" +# Kevin Buettner, RH BZ 1842961 +Patch116: gdb-rhbz1842691-corefile-mem-access-13of15.patch + +# New core file tests with mappings over existing program memory +# Kevin Buettner, RH BZ 1842961 +Patch117: gdb-rhbz1842691-corefile-mem-access-14of15.patch + +# Add period to help text for maint print core-file-backed-mappings +# Kevin Buettner, RH BZ 1842961 +Patch118: gdb-rhbz1842691-corefile-mem-access-15of15.patch + +# Backport of "Exclude debuginfo files from 'outside of ELF segments' +# warning" (Keith Seitz) +Patch119: gdb-rhbz1898252-loadable-section-outside-ELF-segments.patch + +# Backport "fortran dynamic type related fixes" +# Andrew Burgess (RH BZ 1905702) +Patch120: gdb-rhbz1905702-DWARF-data_location.patch + +# Backport of "Correct recording of 'store on condition' insns" +# Andreas Arnaz (RH BZ 1903374) +Patch121: gdb-rhbz1903375-s390x-store-on-condition.patch + diff --git a/SOURCES/_gdb.spec.patch.include b/SOURCES/_gdb.spec.patch.include index 48f09cd..a663edb 100644 --- a/SOURCES/_gdb.spec.patch.include +++ b/SOURCES/_gdb.spec.patch.include @@ -100,3 +100,22 @@ %patch100 -p1 %patch101 -p1 %patch102 -p1 +%patch103 -p1 +%patch104 -p1 +%patch105 -p1 +%patch106 -p1 +%patch107 -p1 +%patch108 -p1 +%patch109 -p1 +%patch110 -p1 +%patch111 -p1 +%patch112 -p1 +%patch113 -p1 +%patch114 -p1 +%patch115 -p1 +%patch116 -p1 +%patch117 -p1 +%patch118 -p1 +%patch119 -p1 +%patch120 -p1 +%patch121 -p1 diff --git a/SOURCES/debuginfod-use-pkg-config.patch b/SOURCES/debuginfod-use-pkg-config.patch new file mode 100644 index 0000000..4373b8a --- /dev/null +++ b/SOURCES/debuginfod-use-pkg-config.patch @@ -0,0 +1,814 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Fri, 24 Jul 2020 16:09:15 -0400 +Subject: debuginfod-use-pkg-config.patch + +;; Use pkg-config for debuginfod.m4. +;; (Aaron Merey) + +From: Aaron Merey +Date: Fri, 24 Jul 2020 15:16:20 -0400 +Subject: [PATCH] config/debuginfod.m4: Use PKG_CHECK_MODULES + +Use PKG_CHECK_MODULES to set debuginfod autoconf vars. Also add +pkg.m4 to config/. + +ChangeLog: + + * config/debuginfod.m4: use PKG_CHECK_MODULES. + * config/pkg.m4: New file. + * configure: Rebuild. + * configure.ac: Remove AC_DEBUGINFOD. + +ChangeLog/binutils: + + * Makefile.am: Replace LIBDEBUGINFOD with DEBUGINFOD_LIBS. + * Makefile.in: Rebuild. + * configure: Rebuild. + * doc/Makefile.in: Rebuild. + +ChangeLog/gdb: + + * Makefile.in: Replace LIBDEBUGINFOD with DEBUGINFOD_LIBS. + * configure: Rebuild. + +diff --git a/config/debuginfod.m4 b/config/debuginfod.m4 +--- a/config/debuginfod.m4 ++++ b/config/debuginfod.m4 +@@ -1,38 +1,30 @@ +-dnl Copyright (C) 1997-2019 Free Software Foundation, Inc. ++dnl Copyright (C) 1997-2020 Free Software Foundation, Inc. + dnl This file is free software, distributed under the terms of the GNU + dnl General Public License. As a special exception to the GNU General + dnl Public License, this file may be distributed as part of a program + dnl that contains a configuration script generated by Autoconf, under + dnl the same distribution terms as the rest of that program. + ++m4_include([../config/pkg.m4]) ++ + AC_DEFUN([AC_DEBUGINFOD], + [ +-# Enable debuginfod ++# Handle optional debuginfod support + AC_ARG_WITH([debuginfod], +- AC_HELP_STRING([--with-debuginfod], +- [Enable debuginfo lookups with debuginfod (auto/yes/no)]), +- [], [with_debuginfod=auto]) ++ AC_HELP_STRING([--with-debuginfod], [Enable debuginfo lookups with debuginfod (auto/yes/no)]), ++ [], [with_debuginfod=auto]) + AC_MSG_CHECKING([whether to use debuginfod]) + AC_MSG_RESULT([$with_debuginfod]) + +-if test "${with_debuginfod}" = no; then +- AC_MSG_WARN([debuginfod support disabled; some features may be unavailable.]) ++if test "x$with_debuginfod" != xno; then ++ PKG_CHECK_MODULES([DEBUGINFOD], [libdebuginfod >= 0.179], ++ [AC_DEFINE([HAVE_LIBDEBUGINFOD], [1], [Define to 1 if debuginfod is enabled.])], ++ [if test "x$with_debuginfod" = xyes; then ++ AC_MSG_ERROR(["--with-debuginfod was given, but libdebuginfod is missing or unusable."]) ++ else ++ AC_MSG_WARN([libdebuginfod is missing or unusable; some features may be unavailable.]) ++ fi]) + else +- AC_CHECK_LIB([debuginfod], [debuginfod_begin], [have_debuginfod_lib=yes]) +- AC_CHECK_DECL([debuginfod_begin], [have_debuginfod_h=yes], [], +- [#include ]) +- if test "x$have_debuginfod_lib" = "xyes" -a \ +- "x$have_debuginfod_h" = "xyes"; then +- AC_DEFINE([HAVE_LIBDEBUGINFOD], [1], +- [Define to 1 if debuginfod is enabled.]) +- AC_SUBST([LIBDEBUGINFOD], ["-ldebuginfod"]) +- else +- AC_SUBST([LIBDEBUGINFOD], []) +- if test "$with_debuginfod" = yes; then +- AC_MSG_ERROR([debuginfod is missing or unusable]) +- else +- AC_MSG_WARN([debuginfod is missing or unusable; some features may be unavailable.]) +- fi +- fi ++ AC_MSG_WARN([debuginfod support disabled; some features may be unavailable.]) + fi + ]) +diff --git a/config/pkg.m4 b/config/pkg.m4 +new file mode 100644 +--- /dev/null ++++ b/config/pkg.m4 +@@ -0,0 +1,275 @@ ++# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- ++# serial 12 (pkg-config-0.29.2) ++ ++dnl Copyright © 2004 Scott James Remnant . ++dnl Copyright © 2012-2015 Dan Nicholson ++dnl ++dnl This program is free software; you can redistribute it and/or modify ++dnl it under the terms of the GNU General Public License as published by ++dnl the Free Software Foundation; either version 2 of the License, or ++dnl (at your option) any later version. ++dnl ++dnl This program is distributed in the hope that it will be useful, but ++dnl WITHOUT ANY WARRANTY; without even the implied warranty of ++dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++dnl General Public License for more details. ++dnl ++dnl You should have received a copy of the GNU General Public License ++dnl along with this program; if not, write to the Free Software ++dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ++dnl 02111-1307, USA. ++dnl ++dnl As a special exception to the GNU General Public License, if you ++dnl distribute this file as part of a program that contains a ++dnl configuration script generated by Autoconf, you may include it under ++dnl the same distribution terms that you use for the rest of that ++dnl program. ++ ++dnl PKG_PREREQ(MIN-VERSION) ++dnl ----------------------- ++dnl Since: 0.29 ++dnl ++dnl Verify that the version of the pkg-config macros are at least ++dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's ++dnl installed version of pkg-config, this checks the developer's version ++dnl of pkg.m4 when generating configure. ++dnl ++dnl To ensure that this macro is defined, also add: ++dnl m4_ifndef([PKG_PREREQ], ++dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) ++dnl ++dnl See the "Since" comment for each macro you use to see what version ++dnl of the macros you require. ++m4_defun([PKG_PREREQ], ++[m4_define([PKG_MACROS_VERSION], [0.29.2]) ++m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, ++ [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ++])dnl PKG_PREREQ ++ ++dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) ++dnl ---------------------------------- ++dnl Since: 0.16 ++dnl ++dnl Search for the pkg-config tool and set the PKG_CONFIG variable to ++dnl first found in the path. Checks that the version of pkg-config found ++dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is ++dnl used since that's the first version where most current features of ++dnl pkg-config existed. ++AC_DEFUN([PKG_PROG_PKG_CONFIG], ++[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) ++m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) ++m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) ++AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) ++AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) ++AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) ++ ++if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then ++ AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) ++fi ++if test -n "$PKG_CONFIG"; then ++ _pkg_min_version=m4_default([$1], [0.9.0]) ++ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) ++ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then ++ AC_MSG_RESULT([yes]) ++ else ++ AC_MSG_RESULT([no]) ++ PKG_CONFIG="" ++ fi ++fi[]dnl ++])dnl PKG_PROG_PKG_CONFIG ++ ++dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) ++dnl ------------------------------------------------------------------- ++dnl Since: 0.18 ++dnl ++dnl Check to see whether a particular set of modules exists. Similar to ++dnl PKG_CHECK_MODULES(), but does not set variables or print errors. ++dnl ++dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) ++dnl only at the first occurence in configure.ac, so if the first place ++dnl it's called might be skipped (such as if it is within an "if", you ++dnl have to call PKG_CHECK_EXISTS manually ++AC_DEFUN([PKG_CHECK_EXISTS], ++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl ++if test -n "$PKG_CONFIG" && \ ++ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then ++ m4_default([$2], [:]) ++m4_ifvaln([$3], [else ++ $3])dnl ++fi]) ++ ++dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) ++dnl --------------------------------------------- ++dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting ++dnl pkg_failed based on the result. ++m4_define([_PKG_CONFIG], ++[if test -n "$$1"; then ++ pkg_cv_[]$1="$$1" ++ elif test -n "$PKG_CONFIG"; then ++ PKG_CHECK_EXISTS([$3], ++ [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ], ++ [pkg_failed=yes]) ++ else ++ pkg_failed=untried ++fi[]dnl ++])dnl _PKG_CONFIG ++ ++dnl _PKG_SHORT_ERRORS_SUPPORTED ++dnl --------------------------- ++dnl Internal check to see if pkg-config supports short errors. ++AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], ++[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) ++if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then ++ _pkg_short_errors_supported=yes ++else ++ _pkg_short_errors_supported=no ++fi[]dnl ++])dnl _PKG_SHORT_ERRORS_SUPPORTED ++ ++ ++dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], ++dnl [ACTION-IF-NOT-FOUND]) ++dnl -------------------------------------------------------------- ++dnl Since: 0.4.0 ++dnl ++dnl Note that if there is a possibility the first call to ++dnl PKG_CHECK_MODULES might not happen, you should be sure to include an ++dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac ++AC_DEFUN([PKG_CHECK_MODULES], ++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl ++AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl ++AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl ++ ++pkg_failed=no ++AC_MSG_CHECKING([for $2]) ++ ++_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) ++_PKG_CONFIG([$1][_LIBS], [libs], [$2]) ++ ++m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS ++and $1[]_LIBS to avoid the need to call pkg-config. ++See the pkg-config man page for more details.]) ++ ++if test $pkg_failed = yes; then ++ AC_MSG_RESULT([no]) ++ _PKG_SHORT_ERRORS_SUPPORTED ++ if test $_pkg_short_errors_supported = yes; then ++ $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` ++ else ++ $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` ++ fi ++ # Put the nasty error message in config.log where it belongs ++ echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD ++ ++ m4_default([$4], [AC_MSG_ERROR( ++[Package requirements ($2) were not met: ++ ++$$1_PKG_ERRORS ++ ++Consider adjusting the PKG_CONFIG_PATH environment variable if you ++installed software in a non-standard prefix. ++ ++_PKG_TEXT])[]dnl ++ ]) ++elif test $pkg_failed = untried; then ++ AC_MSG_RESULT([no]) ++ m4_default([$4], [AC_MSG_FAILURE( ++[The pkg-config script could not be found or is too old. Make sure it ++is in your PATH or set the PKG_CONFIG environment variable to the full ++path to pkg-config. ++ ++_PKG_TEXT ++ ++To get pkg-config, see .])[]dnl ++ ]) ++else ++ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS ++ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS ++ AC_MSG_RESULT([yes]) ++ $3 ++fi[]dnl ++])dnl PKG_CHECK_MODULES ++ ++ ++dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], ++dnl [ACTION-IF-NOT-FOUND]) ++dnl --------------------------------------------------------------------- ++dnl Since: 0.29 ++dnl ++dnl Checks for existence of MODULES and gathers its build flags with ++dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags ++dnl and VARIABLE-PREFIX_LIBS from --libs. ++dnl ++dnl Note that if there is a possibility the first call to ++dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to ++dnl include an explicit call to PKG_PROG_PKG_CONFIG in your ++dnl configure.ac. ++AC_DEFUN([PKG_CHECK_MODULES_STATIC], ++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl ++_save_PKG_CONFIG=$PKG_CONFIG ++PKG_CONFIG="$PKG_CONFIG --static" ++PKG_CHECK_MODULES($@) ++PKG_CONFIG=$_save_PKG_CONFIG[]dnl ++])dnl PKG_CHECK_MODULES_STATIC ++ ++ ++dnl PKG_INSTALLDIR([DIRECTORY]) ++dnl ------------------------- ++dnl Since: 0.27 ++dnl ++dnl Substitutes the variable pkgconfigdir as the location where a module ++dnl should install pkg-config .pc files. By default the directory is ++dnl $libdir/pkgconfig, but the default can be changed by passing ++dnl DIRECTORY. The user can override through the --with-pkgconfigdir ++dnl parameter. ++AC_DEFUN([PKG_INSTALLDIR], ++[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) ++m4_pushdef([pkg_description], ++ [pkg-config installation directory @<:@]pkg_default[@:>@]) ++AC_ARG_WITH([pkgconfigdir], ++ [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, ++ [with_pkgconfigdir=]pkg_default) ++AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) ++m4_popdef([pkg_default]) ++m4_popdef([pkg_description]) ++])dnl PKG_INSTALLDIR ++ ++ ++dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) ++dnl -------------------------------- ++dnl Since: 0.27 ++dnl ++dnl Substitutes the variable noarch_pkgconfigdir as the location where a ++dnl module should install arch-independent pkg-config .pc files. By ++dnl default the directory is $datadir/pkgconfig, but the default can be ++dnl changed by passing DIRECTORY. The user can override through the ++dnl --with-noarch-pkgconfigdir parameter. ++AC_DEFUN([PKG_NOARCH_INSTALLDIR], ++[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) ++m4_pushdef([pkg_description], ++ [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) ++AC_ARG_WITH([noarch-pkgconfigdir], ++ [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, ++ [with_noarch_pkgconfigdir=]pkg_default) ++AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) ++m4_popdef([pkg_default]) ++m4_popdef([pkg_description]) ++])dnl PKG_NOARCH_INSTALLDIR ++ ++ ++dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, ++dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) ++dnl ------------------------------------------- ++dnl Since: 0.28 ++dnl ++dnl Retrieves the value of the pkg-config variable for the given module. ++AC_DEFUN([PKG_CHECK_VAR], ++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl ++AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl ++ ++_PKG_CONFIG([$1], [variable="][$3]["], [$2]) ++AS_VAR_COPY([$1], [pkg_cv_][$1]) ++ ++AS_VAR_IF([$1], [""], [$5], [$4])dnl ++])dnl PKG_CHECK_VAR +diff --git a/gdb/Makefile.in b/gdb/Makefile.in +--- a/gdb/Makefile.in ++++ b/gdb/Makefile.in +@@ -587,7 +587,8 @@ INTERNAL_CFLAGS_BASE = \ + $(GDB_CFLAGS) $(OPCODES_CFLAGS) $(READLINE_CFLAGS) $(ZLIBINC) \ + $(BFD_CFLAGS) $(INCLUDE_CFLAGS) $(LIBDECNUMBER_CFLAGS) \ + $(INTL_CFLAGS) $(INCGNU) $(ENABLE_CFLAGS) $(INTERNAL_CPPFLAGS) \ +- $(SRCHIGH_CFLAGS) $(TOP_CFLAGS) $(PTHREAD_CFLAGS) ++ $(SRCHIGH_CFLAGS) $(TOP_CFLAGS) $(PTHREAD_CFLAGS) \ ++ @DEBUGINFOD_CFLAGS@ + INTERNAL_WARN_CFLAGS = $(INTERNAL_CFLAGS_BASE) $(GDB_WARN_CFLAGS) + INTERNAL_CFLAGS = $(INTERNAL_WARN_CFLAGS) $(GDB_WERROR_CFLAGS) + +@@ -613,7 +614,7 @@ CLIBS = $(SIM) $(READLINE) $(OPCODES) $(BFD) $(LIBCTF) $(ZLIB) \ + $(LIBEXPAT) $(LIBLZMA) $(LIBBABELTRACE) $(LIBIPT) \ + $(LIBIBERTY) $(WIN32LIBS) $(LIBGNU) $(LIBICONV) $(LIBMPFR) \ + $(SRCHIGH_LIBS) $(LIBXXHASH) $(PTHREAD_LIBS) \ +- @LIBDEBUGINFOD@ ++ @DEBUGINFOD_LIBS@ + CDEPS = $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE_DEPS) $(LIBCTF) \ + $(OPCODES) $(INTL_DEPS) $(LIBIBERTY) $(CONFIG_DEPS) $(LIBGNU) + +diff --git a/gdb/configure b/gdb/configure +--- a/gdb/configure ++++ b/gdb/configure +@@ -758,7 +758,11 @@ REPORT_BUGS_TEXI + REPORT_BUGS_TO + PKGVERSION + CODESIGN_CERT +-LIBDEBUGINFOD ++DEBUGINFOD_LIBS ++DEBUGINFOD_CFLAGS ++PKG_CONFIG_LIBDIR ++PKG_CONFIG_PATH ++PKG_CONFIG + HAVE_NATIVE_GCORE_TARGET + TARGET_OBS + subdirs +@@ -937,6 +941,9 @@ MAKEINFOFLAGS + PKG_CONFIG + PKG_CONFIG_PATH + PKG_CONFIG_LIBDIR ++PKG_CONFIG_CFLAGS ++DEBUGINFOD_CFLAGS ++DEBUGINFOD_LIBS + RPM_CFLAGS + RPM_LIBS + YACC +@@ -1683,6 +1690,10 @@ Some influential environment variables: + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path ++ DEBUGINFOD_CFLAGS ++ C compiler flags for DEBUGINFOD, overriding pkg-config ++ DEBUGINFOD_LIBS ++ linker flags for DEBUGINFOD, overriding pkg-config + RPM_CFLAGS C compiler flags for RPM, overriding pkg-config + RPM_LIBS linker flags for RPM, overriding pkg-config + YACC The `Yet Another Compiler Compiler' implementation to use. +@@ -2275,52 +2286,6 @@ rm -f conftest.val + + } # ac_fn_c_compute_int + +-# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +-# --------------------------------------------- +-# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +-# accordingly. +-ac_fn_c_check_decl () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- as_decl_name=`echo $2|sed 's/ *(.*//'` +- as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +-$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +-if eval \${$3+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-$4 +-int +-main () +-{ +-#ifndef $as_decl_name +-#ifdef __cplusplus +- (void) $as_decl_use; +-#else +- (void) $as_decl_name; +-#endif +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- eval "$3=yes" +-else +- eval "$3=no" +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-eval ac_res=\$$3 +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- +-} # ac_fn_c_check_decl +- + # ac_fn_c_check_func LINENO FUNC VAR + # ---------------------------------- + # Tests whether FUNC exists, setting the cache variable VAR accordingly +@@ -2388,6 +2353,52 @@ $as_echo "$ac_res" >&6; } + + } # ac_fn_c_check_func + ++# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES ++# --------------------------------------------- ++# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR ++# accordingly. ++ac_fn_c_check_decl () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ as_decl_name=`echo $2|sed 's/ *(.*//'` ++ as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 ++$as_echo_n "checking whether $as_decl_name is declared... " >&6; } ++if eval \${$3+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++$4 ++int ++main () ++{ ++#ifndef $as_decl_name ++#ifdef __cplusplus ++ (void) $as_decl_use; ++#else ++ (void) $as_decl_name; ++#endif ++#endif ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ eval "$3=yes" ++else ++ eval "$3=no" ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++eval ac_res=\$$3 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 ++$as_echo "$ac_res" >&6; } ++ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno ++ ++} # ac_fn_c_check_decl ++ + # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES + # ---------------------------------------------------- + # Tries to find if the field MEMBER exists in type AGGR, after including +@@ -7338,7 +7349,127 @@ esac + + # Handle optional debuginfod support + +-# Enable debuginfod ++ ++ ++ ++ ++ ++ ++if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. ++set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_path_PKG_CONFIG+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ case $PKG_CONFIG in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++fi ++PKG_CONFIG=$ac_cv_path_PKG_CONFIG ++if test -n "$PKG_CONFIG"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 ++$as_echo "$PKG_CONFIG" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++fi ++if test -z "$ac_cv_path_PKG_CONFIG"; then ++ ac_pt_PKG_CONFIG=$PKG_CONFIG ++ # Extract the first word of "pkg-config", so it can be a program name with args. ++set dummy pkg-config; ac_word=$2 ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } ++if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ case $ac_pt_PKG_CONFIG in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" ++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++ done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++fi ++ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG ++if test -n "$ac_pt_PKG_CONFIG"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 ++$as_echo "$ac_pt_PKG_CONFIG" >&6; } ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ if test "x$ac_pt_PKG_CONFIG" = x; then ++ PKG_CONFIG="" ++ else ++ case $cross_compiling:$ac_tool_warned in ++yes:) ++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ++ac_tool_warned=yes ;; ++esac ++ PKG_CONFIG=$ac_pt_PKG_CONFIG ++ fi ++else ++ PKG_CONFIG="$ac_cv_path_PKG_CONFIG" ++fi ++ ++fi ++if test -n "$PKG_CONFIG"; then ++ _pkg_min_version=0.9.0 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 ++$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } ++ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ PKG_CONFIG="" ++ fi ++fi ++ ++# Handle optional debuginfod support + + # Check whether --with-debuginfod was given. + if test "${with_debuginfod+set}" = set; then : +@@ -7352,72 +7483,93 @@ $as_echo_n "checking whether to use debuginfod... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_debuginfod" >&5 + $as_echo "$with_debuginfod" >&6; } + +-if test "${with_debuginfod}" = no; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: debuginfod support disabled; some features may be unavailable." >&5 +-$as_echo "$as_me: WARNING: debuginfod support disabled; some features may be unavailable." >&2;} +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for debuginfod_begin in -ldebuginfod" >&5 +-$as_echo_n "checking for debuginfod_begin in -ldebuginfod... " >&6; } +-if ${ac_cv_lib_debuginfod_debuginfod_begin+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_check_lib_save_LIBS=$LIBS +-LIBS="-ldebuginfod $LIBS" +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ ++if test "x$with_debuginfod" != xno; then + +-/* 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 debuginfod_begin (); +-int +-main () +-{ +-return debuginfod_begin (); +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ac_cv_lib_debuginfod_debuginfod_begin=yes ++pkg_failed=no ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libdebuginfod >= 0.179" >&5 ++$as_echo_n "checking for libdebuginfod >= 0.179... " >&6; } ++ ++if test -n "$DEBUGINFOD_CFLAGS"; then ++ pkg_cv_DEBUGINFOD_CFLAGS="$DEBUGINFOD_CFLAGS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdebuginfod >= 0.179\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "libdebuginfod >= 0.179") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ pkg_cv_DEBUGINFOD_CFLAGS=`$PKG_CONFIG --cflags "libdebuginfod >= 0.179" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes + else +- ac_cv_lib_debuginfod_debuginfod_begin=no ++ pkg_failed=yes + fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +-LIBS=$ac_check_lib_save_LIBS ++ else ++ pkg_failed=untried ++fi ++if test -n "$DEBUGINFOD_LIBS"; then ++ pkg_cv_DEBUGINFOD_LIBS="$DEBUGINFOD_LIBS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdebuginfod >= 0.179\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "libdebuginfod >= 0.179") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ pkg_cv_DEBUGINFOD_LIBS=`$PKG_CONFIG --libs "libdebuginfod >= 0.179" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ++else ++ pkg_failed=yes + fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_debuginfod_debuginfod_begin" >&5 +-$as_echo "$ac_cv_lib_debuginfod_debuginfod_begin" >&6; } +-if test "x$ac_cv_lib_debuginfod_debuginfod_begin" = xyes; then : +- have_debuginfod_lib=yes ++ else ++ pkg_failed=untried + fi + +- ac_fn_c_check_decl "$LINENO" "debuginfod_begin" "ac_cv_have_decl_debuginfod_begin" "#include +-" +-if test "x$ac_cv_have_decl_debuginfod_begin" = xyes; then : +- have_debuginfod_h=yes +-fi + +- if test "x$have_debuginfod_lib" = "xyes" -a \ +- "x$have_debuginfod_h" = "xyes"; then + +-$as_echo "#define HAVE_LIBDEBUGINFOD 1" >>confdefs.h ++if test $pkg_failed = yes; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } + +- LIBDEBUGINFOD="-ldebuginfod" ++if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then ++ _pkg_short_errors_supported=yes ++else ++ _pkg_short_errors_supported=no ++fi ++ if test $_pkg_short_errors_supported = yes; then ++ DEBUGINFOD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libdebuginfod >= 0.179" 2>&1` ++ else ++ DEBUGINFOD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libdebuginfod >= 0.179" 2>&1` ++ fi ++ # Put the nasty error message in config.log where it belongs ++ echo "$DEBUGINFOD_PKG_ERRORS" >&5 + +- else ++ if test "x$with_debuginfod" = xyes; then ++ as_fn_error $? "\"--with-debuginfod was given, but libdebuginfod is missing or unusable.\"" "$LINENO" 5 ++ else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libdebuginfod is missing or unusable; some features may be unavailable." >&5 ++$as_echo "$as_me: WARNING: libdebuginfod is missing or unusable; some features may be unavailable." >&2;} ++ fi ++elif test $pkg_failed = untried; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ if test "x$with_debuginfod" = xyes; then ++ as_fn_error $? "\"--with-debuginfod was given, but libdebuginfod is missing or unusable.\"" "$LINENO" 5 ++ else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libdebuginfod is missing or unusable; some features may be unavailable." >&5 ++$as_echo "$as_me: WARNING: libdebuginfod is missing or unusable; some features may be unavailable." >&2;} ++ fi ++else ++ DEBUGINFOD_CFLAGS=$pkg_cv_DEBUGINFOD_CFLAGS ++ DEBUGINFOD_LIBS=$pkg_cv_DEBUGINFOD_LIBS ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } + +- if test "$with_debuginfod" = yes; then +- as_fn_error $? "debuginfod is missing or unusable" "$LINENO" 5 +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: debuginfod is missing or unusable; some features may be unavailable." >&5 +-$as_echo "$as_me: WARNING: debuginfod is missing or unusable; some features may be unavailable." >&2;} +- fi +- fi ++$as_echo "#define HAVE_LIBDEBUGINFOD 1" >>confdefs.h ++ ++fi ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: debuginfod support disabled; some features may be unavailable." >&5 ++$as_echo "$as_me: WARNING: debuginfod support disabled; some features may be unavailable." >&2;} + fi + + diff --git a/SOURCES/gdb-rhbz1838777-debuginfod.patch b/SOURCES/gdb-rhbz1838777-debuginfod.patch index fb836b3..7e0e5f6 100644 --- a/SOURCES/gdb-rhbz1838777-debuginfod.patch +++ b/SOURCES/gdb-rhbz1838777-debuginfod.patch @@ -857,13 +857,13 @@ diff --git a/gdb/elfread.c b/gdb/elfread.c + has_dwarf2 = true; + } + } ++ /* Check if any separate debug info has been extracted out. */ ++ else if (bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink") ++ != NULL) ++ debug_print_missing (objfile_name (objfile), build_id_filename.get ()); ++ else ++ has_dwarf2 = false; + } -+ /* Check if any separate debug info has been extracted out. */ -+ else if (bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink") -+ != NULL) -+ debug_print_missing (objfile_name (objfile), build_id_filename.get ()); -+ else -+ has_dwarf2 = false; + } } @@ -919,7 +919,7 @@ diff --git a/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp b/gdb/testsu new file mode 100644 --- /dev/null +++ b/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp -@@ -0,0 +1,214 @@ +@@ -0,0 +1,246 @@ +# Copyright 2020 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify @@ -952,7 +952,8 @@ new file mode 100644 +} + +# Skip testing if gdb was not configured with debuginfod -+if { [string first "with-debuginfod" [exec $GDB --configuration]] == -1 } { ++if { [string first "with-debuginfod" \ ++ [eval exec $GDB $INTERNAL_GDBFLAGS --configuration]] == -1 } { + untested "gdb not configured with debuginfod" + return -1 +} @@ -979,31 +980,6 @@ new file mode 100644 + return -1 +} + -+setenv DEBUGINFOD_URLS "" -+setenv DEBUGINFOD_TIMEOUT 30 -+setenv DEBUGINFOD_CACHE_PATH $cache -+ -+# Test that gdb cannot find source without debuginfod -+clean_restart $binfile -+gdb_test_no_output "set substitute-path $outputdir /dev/null" -+gdb_test "list" ".*No such file or directory.*" -+ -+# Strip symbols into separate file and move it so gdb cannot find it without debuginfod -+if { [gdb_gnu_strip_debug $binfile ""] != 0 } { -+ fail "strip debuginfo" -+ return -1 -+} -+ -+set debugdir [standard_output_file "debug"] -+set debuginfo [standard_output_file "fetch_src_and_symbols.debug"] -+ -+file mkdir $debugdir -+file rename -force $debuginfo $debugdir -+ -+# Test that gdb cannot find symbols without debuginfod -+clean_restart $binfile -+gdb_test "file" ".*No symbol file.*" -+ +# Write some assembly that just has a .gnu_debugaltlink section. +# Copied from testsuite/gdb.dwarf2/dwzbuildid.exp. +proc write_just_debugaltlink {filename dwzname buildid} { @@ -1039,7 +1015,7 @@ new file mode 100644 + + cu {} { + compile_unit {{language @DW_LANG_C}} { -+ int_label2: base_type { ++ int_label2: base_type { + {name int} + {byte_size 4 sdata} + {encoding @DW_ATE_signed} @@ -1055,85 +1031,141 @@ new file mode 100644 + } +} + -+set buildid "01234567890abcdef0123456" ++proc no_url { } { ++ global binfile outputdir debugdir + -+write_just_debugaltlink ${binfile}_has_altlink.S ${binfile}_dwz.o $buildid -+write_dwarf_file ${binfile}_dwz.S $buildid ++ setenv DEBUGINFOD_URLS "" + -+if {[gdb_compile ${binfile}_has_altlink.S ${binfile}_alt.o object nodebug] != ""} { -+ fail "compile main with altlink" -+ return -1 -+} ++ # Test that gdb cannot find source without debuginfod ++ clean_restart $binfile ++ gdb_test_no_output "set substitute-path $outputdir /dev/null" \ ++ "set substitute-path" ++ gdb_test "list" ".*No such file or directory.*" + -+if {[gdb_compile ${binfile}_dwz.S ${binfile}_dwz.o object nodebug] != ""} { -+ fail "compile altlink" -+ return -1 -+} ++ # Strip symbols into separate file and move it so gdb cannot find it \ ++ without debuginfod ++ if { [gdb_gnu_strip_debug $binfile ""] != 0 } { ++ fail "strip debuginfo" ++ return -1 ++ } + -+file rename -force ${binfile}_dwz.o $debugdir ++ set debugdir [standard_output_file "debug"] ++ set debuginfo [standard_output_file "fetch_src_and_symbols.debug"] + -+# Test that gdb cannot find dwz without debuginfod. -+clean_restart -+gdb_test "file ${binfile}_alt.o" ".*could not find '.gnu_debugaltlink'.*" ++ file mkdir $debugdir ++ file rename -force $debuginfo $debugdir + -+# Find an unused port -+set port 7999 -+set found 0 -+while { ! $found } { -+ incr port -+ if { $port == 65536 } { -+ fail "no available ports" -+ return -1 -+ } -+ -+ spawn debuginfod -vvvv -d $db -p $port -F $debugdir -+ expect { -+ "started http server on IPv4 IPv6 port=$port" { set found 1 } -+ "failed to bind to port" { kill_wait_spawned_process $spawn_id } -+ timeout { -+ fail "find port timeout" -+ return -1 ++ # Test that gdb cannot find symbols without debuginfod ++ clean_restart $binfile ++ gdb_test "file" ".*No symbol file.*" ++ ++ set buildid "01234567890abcdef0123456" ++ ++ write_just_debugaltlink ${binfile}_has_altlink.S ${binfile}_dwz.o \ ++ $buildid ++ write_dwarf_file ${binfile}_dwz.S $buildid ++ ++ if {[gdb_compile ${binfile}_has_altlink.S ${binfile}_alt.o object \ ++ nodebug] != ""} { ++ fail "compile main with altlink" ++ return -1 + } -+ } -+} + -+set metrics [list "ready 1" \ -+ "thread_work_total{role=\"traverse\"} 1" \ -+ "thread_work_pending{role=\"scan\"} 0" \ -+ "thread_busy{role=\"scan\"} 0"] ++ if {[gdb_compile ${binfile}_dwz.S ${binfile}_dwz.o object \ ++ nodebug] != ""} { ++ fail "compile altlink" ++ return -1 ++ } ++ ++ file rename -force ${binfile}_dwz.o $debugdir + -+# Check server metrics to confirm init has completed. -+foreach m $metrics { -+ set timelim 20 -+ while { $timelim != 0 } { -+ sleep 0.5 -+ catch {exec curl -s http://127.0.0.1:$port/metrics} got ++ # Test that gdb cannot find dwz without debuginfod. ++ clean_restart ++ gdb_test "file ${binfile}_alt.o" \ ++ ".*could not find '.gnu_debugaltlink'.*" \ ++ "file [file tail ${binfile}_alt.o]" ++} ++ ++proc local_url { } { ++ global binfile outputdir db debugdir ++ ++ # Find an unused port ++ set port 7999 ++ set found 0 ++ while { ! $found } { ++ incr port ++ if { $port == 65536 } { ++ fail "no available ports" ++ return -1 ++ } + -+ if { [regexp $m $got] } { -+ break ++ spawn debuginfod -vvvv -d $db -p $port -F $debugdir ++ expect { ++ "started http server on IPv4 IPv6 port=$port" { set found 1 } ++ "failed to bind to port" { kill_wait_spawned_process $spawn_id } ++ timeout { ++ fail "find port timeout" ++ return -1 ++ } ++ } + } + -+ incr timelim -1 -+ } ++ set metrics [list "ready 1" \ ++ "thread_work_total{role=\"traverse\"} 1" \ ++ "thread_work_pending{role=\"scan\"} 0" \ ++ "thread_busy{role=\"scan\"} 0"] + -+ if { $timelim == 0 } { -+ fail "server init timeout" -+ break -+ } ++ # Check server metrics to confirm init has completed. ++ foreach m $metrics { ++ set timelim 20 ++ while { $timelim != 0 } { ++ sleep 0.5 ++ catch {exec curl -s http://127.0.0.1:$port/metrics} got ++ ++ if { [regexp $m $got] } { ++ break ++ } ++ ++ incr timelim -1 ++ } ++ ++ if { $timelim == 0 } { ++ fail "server init timeout" ++ return -1 ++ } ++ } ++ ++ # Point the client to the server ++ setenv DEBUGINFOD_URLS http://127.0.0.1:$port ++ ++ # gdb should now find the symbol and source files ++ clean_restart $binfile ++ gdb_test_no_output "set substitute-path $outputdir /dev/null" \ ++ "set substitute-path" ++ gdb_test "br main" "Breakpoint 1 at.*file.*" ++ gdb_test "l" ".*This program is distributed in the hope.*" ++ ++ # gdb should now find the debugaltlink file ++ clean_restart ++ gdb_test "file ${binfile}_alt.o" \ ++ ".*Reading symbols from ${binfile}_alt.o\.\.\.*" \ ++ "file [file tail ${binfile}_alt.o]" +} + -+# Point the client to the server -+setenv DEBUGINFOD_URLS http://127.0.0.1:$port ++set envlist \ ++ [list \ ++ env(DEBUGINFOD_URLS) \ ++ env(DEBUGINFOD_TIMEOUT) \ ++ env(DEBUGINFOD_CACHE_PATH)] + -+# gdb should now find the symbol and source files -+clean_restart $binfile -+gdb_test_no_output "set substitute-path $outputdir /dev/null" -+gdb_test "br main" "Breakpoint 1 at.*file.*" -+gdb_test "l" ".*This program is distributed in the hope.*" ++save_vars $envlist { ++ setenv DEBUGINFOD_TIMEOUT 30 ++ setenv DEBUGINFOD_CACHE_PATH $cache + -+# gdb should now find the debugaltlink file -+clean_restart -+gdb_test "file ${binfile}_alt.o" ".*Reading symbols from ${binfile}_alt.o\.\.\.*" ++ with_test_prefix no_url no_url ++ ++ with_test_prefix local_url local_url ++} diff --git a/gdb/testsuite/gdb.debuginfod/main.c b/gdb/testsuite/gdb.debuginfod/main.c new file mode 100644 --- /dev/null diff --git a/SOURCES/gdb-rhbz1842691-corefile-mem-access-10of15.patch b/SOURCES/gdb-rhbz1842691-corefile-mem-access-10of15.patch new file mode 100644 index 0000000..01ba626 --- /dev/null +++ b/SOURCES/gdb-rhbz1842691-corefile-mem-access-10of15.patch @@ -0,0 +1,121 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Mon, 27 Jul 2020 19:38:20 -0400 +Subject: gdb-rhbz1842691-corefile-mem-access-10of15.patch + +;; gcore command: Place all file-backed mappings in NT_FILE note +;; Kevin Buettner, RH BZ 1842961 + + Author: Kevin Buettner + Date: Wed Jul 1 06:34:50 2020 -0700 + + gcore command: Place all file-backed mappings in NT_FILE note + + When making a core file with the GDB's gcore command on Linux, + the same criteria used for determining which mappings should be + dumped were also being used for determining which entries should + be placed in the NT_FILE note. This is wrong; we want to place + all file-backed mappings in this note. + + The predicate function, dump_mapping_p, was used to determine whether + or not to dump a mapping from within linux_find_memory_regions_full. + This commit leaves this predicate in place, but adds a new parameter, + should_dump_mapping_p, to linux_find_memory_regions_full. It then + calls should_dump_mapping_p instead of dump_mapping_p. dump_mapping_p + is passed to linux_find_memory_regions_full at one call site; at the + other call site, dump_note_entry_p is passed instead. + + gdb/ChangeLog: + + * linux-tdep.c (dump_note_entry_p): New function. + (linux_dump_mapping_p_ftype): New typedef. + (linux_find_memory_regions_full): Add new parameter, + should_dump_mapping_p. + (linux_find_memory_regions): Adjust call to + linux_find_memory_regions_full. + (linux_make_mappings_core_file_notes): Use dump_note_entry_p in + call to linux_find_memory_regions_full. + +diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c +--- a/gdb/linux-tdep.c ++++ b/gdb/linux-tdep.c +@@ -732,6 +732,25 @@ dump_mapping_p (filter_flags filterflags, const struct smaps_vmflags *v, + return dump_p; + } + ++/* As above, but return true only when we should dump the NT_FILE ++ entry. */ ++ ++static int ++dump_note_entry_p (filter_flags filterflags, const struct smaps_vmflags *v, ++ int maybe_private_p, int mapping_anon_p, int mapping_file_p, ++ const char *filename, ULONGEST addr, ULONGEST offset) ++{ ++ /* vDSO and vsyscall mappings will end up in the core file. Don't ++ put them in the NT_FILE note. */ ++ if (strcmp ("[vdso]", filename) == 0 ++ || strcmp ("[vsyscall]", filename) == 0) ++ return 0; ++ ++ /* Otherwise, any other file-based mapping should be placed in the ++ note. */ ++ return filename != nullptr; ++} ++ + /* Implement the "info proc" command. */ + + static void +@@ -1246,10 +1265,20 @@ typedef int linux_find_memory_region_ftype (ULONGEST vaddr, ULONGEST size, + const char *filename, + void *data); + ++typedef int linux_dump_mapping_p_ftype (filter_flags filterflags, ++ const struct smaps_vmflags *v, ++ int maybe_private_p, ++ int mapping_anon_p, ++ int mapping_file_p, ++ const char *filename, ++ ULONGEST addr, ++ ULONGEST offset); ++ + /* List memory regions in the inferior for a corefile. */ + + static int + linux_find_memory_regions_full (struct gdbarch *gdbarch, ++ linux_dump_mapping_p_ftype *should_dump_mapping_p, + linux_find_memory_region_ftype *func, + void *obfd) + { +@@ -1400,9 +1429,10 @@ linux_find_memory_regions_full (struct gdbarch *gdbarch, + } + + if (has_anonymous) +- should_dump_p = dump_mapping_p (filterflags, &v, priv, +- mapping_anon_p, mapping_file_p, +- filename, addr, offset); ++ should_dump_p = should_dump_mapping_p (filterflags, &v, priv, ++ mapping_anon_p, ++ mapping_file_p, ++ filename, addr, offset); + else + { + /* Older Linux kernels did not support the "Anonymous:" counter. +@@ -1466,6 +1496,7 @@ linux_find_memory_regions (struct gdbarch *gdbarch, + data.obfd = obfd; + + return linux_find_memory_regions_full (gdbarch, ++ dump_mapping_p, + linux_find_memory_regions_thunk, + &data); + } +@@ -1561,7 +1592,9 @@ linux_make_mappings_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, + pack_long (buf, long_type, 1); + obstack_grow (&data_obstack, buf, TYPE_LENGTH (long_type)); + +- linux_find_memory_regions_full (gdbarch, linux_make_mappings_callback, ++ linux_find_memory_regions_full (gdbarch, ++ dump_note_entry_p, ++ linux_make_mappings_callback, + &mapping_data); + + if (mapping_data.file_count != 0) diff --git a/SOURCES/gdb-rhbz1842691-corefile-mem-access-11of15.patch b/SOURCES/gdb-rhbz1842691-corefile-mem-access-11of15.patch new file mode 100644 index 0000000..6551038 --- /dev/null +++ b/SOURCES/gdb-rhbz1842691-corefile-mem-access-11of15.patch @@ -0,0 +1,87 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Tue, 28 Jul 2020 09:26:44 -0400 +Subject: gdb-rhbz1842691-corefile-mem-access-11of15.patch + +;; Adjust coredump-filter.exp to account for NT_FILE note handling +;; Kevin Buettner, RH BZ 1842961 + + Author: Kevin Buettner + Date: Fri Jul 3 20:10:22 2020 -0700 + + Adjust coredump-filter.exp to account for NT_FILE note handling + + This commit makes adjustments to coredump-filter.exp to account + for the fact that NT_FILE file-backed mappings are now available + when a core file is loaded. Thus, a test which was expected + to PASS when a memory region was determined to be unavailable + (due to no file-backed mappings being available) will now FAIL + due to those mappings being available from having loaded the + NT_FILE note. + + I had originally marked the test as XFAIL, but Mihails Strasuns + suggested a much better approach: + + 1) First test that it still works if file is accessible in the + filesystem. + 2) Temporarily move / rename the file and test that disassembly + doesn't work anymore. + + That's what this commit implements. + + gdb/testsuite/ChangeLog: + + * gdb.base/coredump-filter.exp: Add second + non-Private-Shared-Anon-File test. + (test_disasm): Rename binfile for test which is expected + to fail. + +diff --git a/gdb/testsuite/gdb.base/coredump-filter.exp b/gdb/testsuite/gdb.base/coredump-filter.exp +--- a/gdb/testsuite/gdb.base/coredump-filter.exp ++++ b/gdb/testsuite/gdb.base/coredump-filter.exp +@@ -80,15 +80,26 @@ proc do_load_and_test_core { core var working_var working_value dump_excluded } + # disassemble of a function (i.e., the binary's .text section). GDB + # should fail in this case. However, it must succeed if the binary is + # provided along with the corefile. This is what we test here. ++# ++# A further complication is that Linux NT_FILE notes are now read from ++# the corefile. This note allows GDB to find the binary for file ++# backed mappings even though the binary wasn't loaded by GDB in the ++# conventional manner. In order to see the expected failure for this ++# case, we rename the binary in order to perform this test. + + proc test_disasm { core address should_fail } { +- global testfile hex ++ global testfile hex binfile + + # Restart GDB without loading the binary. + with_test_prefix "no binary" { + gdb_exit + gdb_start + ++ set hide_binfile [standard_output_file "${testfile}.hide"] ++ if { $should_fail == 1 } { ++ remote_exec host "mv -f $binfile $hide_binfile" ++ } ++ + set core_loaded [gdb_core_cmd "$core" "load core"] + if { $core_loaded == -1 } { + fail "loading $core" +@@ -96,6 +107,7 @@ proc test_disasm { core address should_fail } { + } + + if { $should_fail == 1 } { ++ remote_exec host "mv -f $hide_binfile $binfile" + gdb_test "x/i \$pc" "=> $hex:\tCannot access memory at address $hex" \ + "disassemble function with corefile and without a binary" + } else { +@@ -225,5 +237,9 @@ foreach item $all_anon_corefiles { + } + + with_test_prefix "loading and testing corefile for non-Private-Shared-Anon-File" { ++ test_disasm $non_private_shared_anon_file_core $main_addr 0 ++} ++ ++with_test_prefix "loading and testing corefile for non-Private-Shared-Anon-File with renamed binary" { + test_disasm $non_private_shared_anon_file_core $main_addr 1 + } diff --git a/SOURCES/gdb-rhbz1842691-corefile-mem-access-12of15.patch b/SOURCES/gdb-rhbz1842691-corefile-mem-access-12of15.patch new file mode 100644 index 0000000..dddf5c0 --- /dev/null +++ b/SOURCES/gdb-rhbz1842691-corefile-mem-access-12of15.patch @@ -0,0 +1,177 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Tue, 28 Jul 2020 09:32:50 -0400 +Subject: gdb-rhbz1842691-corefile-mem-access-12of15.patch + +;; Add new command "maint print core-file-backed-mappings" +;; Kevin Buettner, RH BZ 1842961 + + Author: Kevin Buettner + Date: Fri Jul 3 21:55:51 2020 -0700 + + Add new command "maint print core-file-backed-mappings" + + I wrote a read_core_file_mappings method for FreeBSD and then registered + this gdbarch method. I saw some strange behavior while testing it and + wanted a way to make sure that mappings were being correctly loaded + into corelow.c, so I wrote the new command which is the topic of this + commit. I think it might be occasionally useful for debugging strange + corefile behavior. + + With regard to FreeBSD, my work isn't ready yet. Unlike Linux, + FreeBSD puts all mappings into its core file note. And, unlike Linux, + it doesn't dump load segments which occupy no space in the file. So + my (perhaps naive) implementation of a FreeBSD read_core_file_mappings + didn't work all that well: I saw more failures in the corefile2.exp + tests than without it. I think it should be possible to make FreeBSD + work as well as Linux, but it will require doing something with all of + the mappings, not just the file based mappings that I was considering. + + In the v4 series, Pedro asked the following: + + I don't understand what this command provides that "info proc + mappings" doesn't? Can you give an example of when you'd use this + command over "info proc mappings" ? + + On Linux, "info proc mappings" and "maint print core-file-backed-mappings" + will produce similar, possibly identical, output. This need not be + the case for other OSes. E.g. on FreeBSD, had I finished the + implementation, the output from these commands would have been very + different. The FreeBSD "info proc mappings" command would show + additional (non-file-backed) mappings in addition to at least one + additional field (memory permissions) for each mapping. + + As noted earlier, I was seeing some unexpected behavior while working + on the FreeBSD implementation and wanted to be certain that the + mappings were being correctly loaded by corelow.c. "info proc + mappings" prints the core file mappings, but doesn't tell us anything + about whether they've been loaded by corelow.c This new maintenance + command directly interrogates the data structures and prints the + values found there. + + gdb/ChangeLog: + + * corelow.c (gdbcmd.h): Include. + (core_target::info_proc_mappings): New method. + (get_current_core_target): New function. + (maintenance_print_core_file_backed_mappings): New function. + (_initialize_corelow): Add core-file-backed-mappings to + "maint print" commands. + +diff --git a/gdb/corelow.c b/gdb/corelow.c +--- a/gdb/corelow.c ++++ b/gdb/corelow.c +@@ -51,6 +51,7 @@ + #include "build-id.h" + #include "gdbsupport/pathstuff.h" + #include ++#include "gdbcmd.h" + + #ifndef O_LARGEFILE + #define O_LARGEFILE 0 +@@ -121,6 +122,9 @@ public: + const char *human_name, + bool required); + ++ /* See definition. */ ++ void info_proc_mappings (struct gdbarch *gdbarch); ++ + private: /* per-core data */ + + /* The core's section table. Note that these target sections are +@@ -1170,6 +1174,86 @@ core_target::info_proc (const char *args, enum info_proc_what request) + return true; + } + ++/* Get a pointer to the current core target. If not connected to a ++ core target, return NULL. */ ++ ++static core_target * ++get_current_core_target () ++{ ++ target_ops *proc_target = find_target_at (process_stratum); ++ return dynamic_cast (proc_target); ++} ++ ++/* Display file backed mappings from core file. */ ++ ++void ++core_target::info_proc_mappings (struct gdbarch *gdbarch) ++{ ++ if (m_core_file_mappings.sections != m_core_file_mappings.sections_end) ++ { ++ printf_filtered (_("Mapped address spaces:\n\n")); ++ if (gdbarch_addr_bit (gdbarch) == 32) ++ { ++ printf_filtered ("\t%10s %10s %10s %10s %s\n", ++ "Start Addr", ++ " End Addr", ++ " Size", " Offset", "objfile"); ++ } ++ else ++ { ++ printf_filtered (" %18s %18s %10s %10s %s\n", ++ "Start Addr", ++ " End Addr", ++ " Size", " Offset", "objfile"); ++ } ++ } ++ ++ for (const struct target_section *tsp = m_core_file_mappings.sections; ++ tsp < m_core_file_mappings.sections_end; ++ tsp++) ++ { ++ ULONGEST start = tsp->addr; ++ ULONGEST end = tsp->endaddr; ++ ULONGEST file_ofs = tsp->the_bfd_section->filepos; ++ const char *filename = bfd_get_filename (tsp->the_bfd_section->owner); ++ ++ if (gdbarch_addr_bit (gdbarch) == 32) ++ printf_filtered ("\t%10s %10s %10s %10s %s\n", ++ paddress (gdbarch, start), ++ paddress (gdbarch, end), ++ hex_string (end - start), ++ hex_string (file_ofs), ++ filename); ++ else ++ printf_filtered (" %18s %18s %10s %10s %s\n", ++ paddress (gdbarch, start), ++ paddress (gdbarch, end), ++ hex_string (end - start), ++ hex_string (file_ofs), ++ filename); ++ } ++} ++ ++/* Implement "maintenance print core-file-backed-mappings" command. ++ ++ If mappings are loaded, the results should be similar to the ++ mappings shown by "info proc mappings". This command is mainly a ++ debugging tool for GDB developers to make sure that the expected ++ mappings are present after loading a core file. For Linux, the ++ output provided by this command will be very similar (if not ++ identical) to that provided by "info proc mappings". This is not ++ necessarily the case for other OSes which might provide ++ more/different information in the "info proc mappings" output. */ ++ ++static void ++maintenance_print_core_file_backed_mappings (const char *args, int from_tty) ++{ ++ core_target *targ = get_current_core_target (); ++ if (targ != nullptr) ++ targ->info_proc_mappings (targ->core_gdbarch ()); ++} ++ ++void _initialize_corelow (); + void + _initialize_corelow (void) + { +@@ -1181,4 +1265,8 @@ Set whether CORE-FILE loads the build-id associated files automatically."), _("\ + Show whether CORE-FILE loads the build-id associated files automatically."), + NULL, NULL, NULL, + &setlist, &showlist); ++ add_cmd ("core-file-backed-mappings", class_maintenance, ++ maintenance_print_core_file_backed_mappings, ++ _("Print core file's file-backed mappings"), ++ &maintenanceprintlist); + } diff --git a/SOURCES/gdb-rhbz1842691-corefile-mem-access-13of15.patch b/SOURCES/gdb-rhbz1842691-corefile-mem-access-13of15.patch new file mode 100644 index 0000000..524c53a --- /dev/null +++ b/SOURCES/gdb-rhbz1842691-corefile-mem-access-13of15.patch @@ -0,0 +1,41 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Tue, 28 Jul 2020 09:44:04 -0400 +Subject: gdb-rhbz1842691-corefile-mem-access-13of15.patch + +;; Add documentation for "maint print core-file-backed-mappings" +;; Kevin Buettner, RH BZ 1842961 + + Author: Kevin Buettner + Date: Fri Jul 3 22:09:20 2020 -0700 + + Add documentation for "maint print core-file-backed-mappings" + + gdb/ChangeLog: + + * NEWS (New commands): Mention new command + "maintenance print core-file-backed-mappings". + + gdb/doc/ChangeLog: + + * gdb.texinfo (Maintenance Commands): Add documentation for + new command "maintenance print core-file-backed-mappings". + +diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo +--- a/gdb/doc/gdb.texinfo ++++ b/gdb/doc/gdb.texinfo +@@ -38268,6 +38268,14 @@ library. This exercises all @code{libthread_db} functionality used by + @code{libthread_db} uses. Note that parts of the test may be skipped + on some platforms when debugging core files. + ++@kindex maint print core-file-backed-mappings ++@cindex memory address space mappings ++@item maint print core-file-backed-mappings ++Print the file-backed mappings which were loaded from a core file note. ++This output represents state internal to @value{GDBN} and should be ++similar to the mappings displayed by the @code{info proc mappings} ++command. ++ + @kindex maint print dummy-frames + @item maint print dummy-frames + Prints the contents of @value{GDBN}'s internal dummy-frame stack. diff --git a/SOURCES/gdb-rhbz1842691-corefile-mem-access-14of15.patch b/SOURCES/gdb-rhbz1842691-corefile-mem-access-14of15.patch new file mode 100644 index 0000000..4a09679 --- /dev/null +++ b/SOURCES/gdb-rhbz1842691-corefile-mem-access-14of15.patch @@ -0,0 +1,439 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Tue, 28 Jul 2020 09:46:44 -0400 +Subject: gdb-rhbz1842691-corefile-mem-access-14of15.patch + +;; New core file tests with mappings over existing program memory +;; Kevin Buettner, RH BZ 1842961 + + Author: Kevin Buettner + Date: Wed Jun 17 19:25:47 2020 -0700 + + New core file tests with mappings over existing program memory + + This test case was inspired by Pedro's demonstration of a problem + with my v2 patches. It can be found here: + + https://sourceware.org/pipermail/gdb-patches/2020-May/168826.html + + In a nutshell, my earlier patches could not handle the case in + which a read-only mapping created with mmap() was created at + an address used by other file-backed read-only memory in use by + the process. + + This problem has been fixed (for Linux, anyway) by the commit "Use + NT_FILE note section for reading core target memory". + + When I run this test without any of my recent corefile patches, + I see these failures: + + FAIL: gdb.base/corefile2.exp: kernel core: print/x mbuf_ro[0]@4 + FAIL: gdb.base/corefile2.exp: kernel core: print/x mbuf_ro[pagesize-4]@4 + FAIL: gdb.base/corefile2.exp: kernel core: print/x mbuf_ro[-3]@6 + FAIL: gdb.base/corefile2.exp: kernel core: print/x mbuf_rw[pagesize-3]@6 + FAIL: gdb.base/corefile2.exp: kernel core: print/x mbuf_ro[pagesize-3]@6 + FAIL: gdb.base/corefile2.exp: maint print core-file-backed-mappings + FAIL: gdb.base/corefile2.exp: gcore core: print/x mbuf_ro[-3]@6 + + The ones involving mbuf_ro will almost certainly fail when run on + non-Linux systems; I've used setup_xfail on those tests to prevent + them from outright FAILing when not run on Linux. For a time, I + had considered skipping these tests altogether when not run on + Linux, but I changed my mind due to this failure... + + FAIL: gdb.base/corefile2.exp: print/x mbuf_rw[pagesize-3]@6 + + I think it *should* pass without my recent corefile patches. The fact + that it doesn't is likely due to a bug in GDB. The following + interaction with GDB demonstrates the problem: + + (gdb) print/x mbuf_rw[pagesize-3]@6 + $1 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0} + (gdb) print/x mbuf_rw[pagesize]@3 + $2 = {0x6b, 0x6b, 0x6b} + + The last three values in display of $1 should be the same as those + shown by $2. Like this... + + (gdb) print/x mbuf_rw[pagesize-3]@6 + $1 = {0x0, 0x0, 0x0, 0x6b, 0x6b, 0x6b} + (gdb) print/x mbuf_rw[pagesize]@3 + $2 = {0x6b, 0x6b, 0x6b} + + That latter output was obtained with the use of all of my current + corefile patches. I see no failures on Linux when running this test + with my current set of corefile patches. I tested 3 architectures: + x86_64, s390x, and aarch64. + + I also tested on FreeBSD 12.1-RELEASE. I see the following results + both with and without the current set of core file patches: + + # of expected passes 26 + # of expected failures 8 + + Of particular interest is that I did *not* see the problematic mbuf_rw + failure noted earlier (both with and without the core file patches). + I still don't have an explanation for why this failure occurred on + Linux. Prior to running the tests, I had hypothesized that I'd see + this failure on FreeBSD too, but testing shows that this is not the + case. + + Also of importance is that we see no FAILs with this test on FreeBSD + which indicates that I XFAILed the correct tests. + + This version runs the interesting tests twice, once with a kernel + created core file and another time with a gcore created core file. + + It also does a very minimal test of the new command "maint print + core-file-backed-mappings". + + gdb/testsuite/ChangeLog: + + * gdb.base/corefile2.exp: New file. + * gdb.base/coremaker2.exp: New file. + +diff --git a/gdb/testsuite/gdb.base/corefile2.exp b/gdb/testsuite/gdb.base/corefile2.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/corefile2.exp +@@ -0,0 +1,185 @@ ++# Copyright 2020 Free Software Foundation, Inc. ++ ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++# Tests of core file memory accesses when mmap() has been used to ++# create a "hole" of zeroes over pre-existing memory regions. See ++# coremaker2.c for details. ++ ++# are we on a target board ++if ![isnative] then { ++ return ++} ++ ++# Some of these tests will only work on GNU/Linux due to the ++# fact that Linux core files includes a section describing ++# memory address to file mappings. We'll use set_up_xfail for the ++# affected tests. As other targets become supported, the condition ++# can be changed accordingly. ++ ++set xfail 0 ++if { ![istarget *-linux*] } { ++ set xfail 1 ++} ++ ++standard_testfile coremaker2.c ++ ++if {[build_executable $testfile.exp $testfile $srcfile debug] == -1} { ++ untested "failed to compile" ++ return -1 ++} ++ ++set corefile [core_find $binfile {}] ++if {$corefile == ""} { ++ return 0 ++} ++ ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${binfile} ++ ++# Attempt to load the core file. ++ ++gdb_test_multiple "core-file $corefile" "core-file command" { ++ -re ".* program is being debugged already.*y or n. $" { ++ # gdb_load may connect us to a gdbserver. ++ send_gdb "y\n" ++ exp_continue ++ } ++ -re "Core was generated by .*corefile.*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { ++ pass "core-file command" ++ } ++ -re "Core was generated by .*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { ++ pass "core-file command (with bad program name)" ++ } ++ -re ".*registers from core file: File in wrong format.* $" { ++ fail "core-file command (could not read registers from core file)" ++ } ++} ++ ++# Perform the "interesting" tests which check the contents of certain ++# memory regions. ++ ++proc do_tests { } { ++ global xfail ++ ++ # Check contents of beginning of buf_rw and buf_ro. ++ ++ gdb_test {print/x buf_rw[0]@4} {\{0x6b, 0x6b, 0x6b, 0x6b\}} ++ gdb_test {print/x buf_ro[0]@4} {\{0xc5, 0xc5, 0xc5, 0xc5\}} ++ ++ # Check for correct contents at beginning of mbuf_rw and mbuf_ro. ++ ++ gdb_test {print/x mbuf_rw[0]@4} {\{0x0, 0x0, 0x0, 0x0\}} ++ ++ if { $xfail } { setup_xfail "*-*-*" } ++ gdb_test {print/x mbuf_ro[0]@4} {\{0x0, 0x0, 0x0, 0x0\}} ++ ++ # Check contents of mbuf_rw and mbuf_ro at the end of these regions. ++ ++ gdb_test {print/x mbuf_rw[pagesize-4]@4} {\{0x0, 0x0, 0x0, 0x0\}} ++ ++ if { $xfail } { setup_xfail "*-*-*" } ++ gdb_test {print/x mbuf_ro[pagesize-4]@4} {\{0x0, 0x0, 0x0, 0x0\}} ++ ++ # Check contents of mbuf_rw and mbuf_ro, right before the hole, ++ # overlapping into the beginning of these mmap'd regions. ++ ++ gdb_test {print/x mbuf_rw[-3]@6} {\{0x6b, 0x6b, 0x6b, 0x0, 0x0, 0x0\}} ++ ++ if { $xfail } { setup_xfail "*-*-*" } ++ gdb_test {print/x mbuf_ro[-3]@6} {\{0xc5, 0xc5, 0xc5, 0x0, 0x0, 0x0\}} ++ ++ # Likewise, at the end of the mbuf_rw and mbuf_ro, with overlap. ++ ++ # If this test FAILs, it's probably a genuine bug unrelated to whether ++ # the core file includes a section describing memory address to file ++ # mappings or not. (So don't xfail it!) ++ gdb_test {print/x mbuf_rw[pagesize-3]@6} {\{0x0, 0x0, 0x0, 0x6b, 0x6b, 0x6b\}} ++ ++ if { $xfail } { setup_xfail "*-*-*" } ++ gdb_test {print/x mbuf_ro[pagesize-3]@6} {\{0x0, 0x0, 0x0, 0xc5, 0xc5, 0xc5\}} ++ ++ # Check contents of (what should be) buf_rw and buf_ro immediately after ++ # mbuf_rw and mbuf_ro holes. ++ ++ gdb_test {print/x mbuf_rw[pagesize]@4} {\{0x6b, 0x6b, 0x6b, 0x6b\}} ++ gdb_test {print/x mbuf_ro[pagesize]@4} {\{0xc5, 0xc5, 0xc5, 0xc5\}} ++ ++ # Check contents at ends of buf_rw and buf_rw. ++ ++ gdb_test {print/x buf_rw[sizeof(buf_rw)-4]@4} {\{0x6b, 0x6b, 0x6b, 0x6b\}} ++ gdb_test {print/x buf_ro[sizeof(buf_ro)-4]@4} {\{0xc5, 0xc5, 0xc5, 0xc5\}} ++} ++ ++# Run tests with kernel-produced core file. ++ ++with_test_prefix "kernel core" { ++ do_tests ++} ++ ++# Verify that "maint print core-file-backed-mappings" exists and does ++# not crash GDB. If it produces any output at all, make sure that ++# that output at least mentions binfile. ++ ++set test "maint print core-file-backed-mappings" ++gdb_test_multiple $test "" { ++ -re ".*$binfile.*$gdb_prompt $" { ++ pass $test ++ } ++ -re "^$test\[\r\n\]*$gdb_prompt $" { ++ pass "$test (no output)" ++ } ++} ++ ++# Restart and run to the abort call. ++ ++clean_restart $binfile ++ ++if ![runto_main] then { ++ fail "can't run to main" ++ return ++} ++ ++gdb_breakpoint [gdb_get_line_number "abort"] ++gdb_continue_to_breakpoint "at abort" ++ ++# Do not execute abort call; instead, invoke gcore command to make a ++# gdb-produced core file. ++ ++set corefile [standard_output_file gcore.test] ++set core_supported [gdb_gcore_cmd "$corefile" "save a corefile"] ++if {!$core_supported} { ++ return ++} ++ ++# maint print-core-file-backed-mappings shouldn't produce any output ++# when not debugging a core file. ++ ++gdb_test_no_output "maint print core-file-backed-mappings" \ ++ "maint print core-file-backed-mapping with no core file" ++ ++clean_restart $binfile ++ ++set core_loaded [gdb_core_cmd "$corefile" "re-load generated corefile"] ++if { $core_loaded == -1 } { ++ # No use proceeding from here. ++ return ++} ++ ++# Run tests using gcore-produced core file. ++ ++with_test_prefix "gcore core" { ++ do_tests ++} +diff --git a/gdb/testsuite/gdb.base/coremaker2.c b/gdb/testsuite/gdb.base/coremaker2.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/coremaker2.c +@@ -0,0 +1,150 @@ ++/* Copyright 1992-2020 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++/* This test has two large memory areas buf_rw and buf_ro. ++ ++ buf_rw is written to by the program while buf_ro is initialized at ++ compile / load time. Thus, when a core file is created, buf_rw's ++ memory should reside in the core file, but buf_ro probably won't be. ++ Instead, the contents of buf_ro are available from the executable. ++ ++ Now, for the wrinkle: We create a one page read-only mapping over ++ both of these areas. This will create a one page "hole" of all ++ zeros in each area. ++ ++ Will GDB be able to correctly read memory from each of the four ++ (or six, if you count the regions on the other side of each hole) ++ memory regions? */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* These are globals so that we can find them easily when debugging ++ the core file. */ ++long pagesize; ++unsigned long long addr; ++char *mbuf_ro; ++char *mbuf_rw; ++ ++/* 24 KiB buffer. */ ++char buf_rw[24 * 1024]; ++ ++/* 24 KiB worth of data. For this test case, we can't allocate a ++ buffer and then fill it; we want GDB to have to read this data ++ from the executable; it should NOT find it in the core file. */ ++ ++#define C5_16 \ ++ 0xc5, 0xc5, 0xc5, 0xc5, \ ++ 0xc5, 0xc5, 0xc5, 0xc5, \ ++ 0xc5, 0xc5, 0xc5, 0xc5, \ ++ 0xc5, 0xc5, 0xc5, 0xc5 ++ ++#define C5_256 \ ++ C5_16, C5_16, C5_16, C5_16, \ ++ C5_16, C5_16, C5_16, C5_16, \ ++ C5_16, C5_16, C5_16, C5_16, \ ++ C5_16, C5_16, C5_16, C5_16 ++ ++#define C5_1k \ ++ C5_256, C5_256, C5_256, C5_256 ++ ++#define C5_24k \ ++ C5_1k, C5_1k, C5_1k, C5_1k, \ ++ C5_1k, C5_1k, C5_1k, C5_1k, \ ++ C5_1k, C5_1k, C5_1k, C5_1k, \ ++ C5_1k, C5_1k, C5_1k, C5_1k, \ ++ C5_1k, C5_1k, C5_1k, C5_1k, \ ++ C5_1k, C5_1k, C5_1k, C5_1k ++ ++const char buf_ro[] = { C5_24k }; ++ ++int ++main (int argc, char **argv) ++{ ++ int i, bitcount; ++ ++#ifdef _SC_PAGESIZE ++ pagesize = sysconf (_SC_PAGESIZE); ++#else ++ pagesize = 8192; ++#endif ++ ++ /* Verify that pagesize is a power of 2. */ ++ bitcount = 0; ++ for (i = 0; i < 4 * sizeof (pagesize); i++) ++ if (pagesize & (1 << i)) ++ bitcount++; ++ ++ if (bitcount != 1) ++ { ++ fprintf (stderr, "pagesize is not a power of 2.\n"); ++ exit (1); ++ } ++ ++ /* Compute an address that should be within buf_ro. Complain if not. */ ++ addr = ((unsigned long long) buf_ro + pagesize) & ~(pagesize - 1); ++ ++ if (addr <= (unsigned long long) buf_ro ++ || addr >= (unsigned long long) buf_ro + sizeof (buf_ro)) ++ { ++ fprintf (stderr, "Unable to compute a suitable address within buf_ro.\n"); ++ exit (1); ++ } ++ ++ mbuf_ro = mmap ((void *) addr, pagesize, PROT_READ, ++ MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0); ++ ++ if (mbuf_ro == MAP_FAILED) ++ { ++ fprintf (stderr, "mmap #1 failed: %s.\n", strerror (errno)); ++ exit (1); ++ } ++ ++ /* Write (and fill) the R/W region. */ ++ for (i = 0; i < sizeof (buf_rw); i++) ++ buf_rw[i] = 0x6b; ++ ++ /* Compute an mmap address within buf_rw. Complain if it's somewhere ++ else. */ ++ addr = ((unsigned long long) buf_rw + pagesize) & ~(pagesize - 1); ++ ++ if (addr <= (unsigned long long) buf_rw ++ || addr >= (unsigned long long) buf_rw + sizeof (buf_rw)) ++ { ++ fprintf (stderr, "Unable to compute a suitable address within buf_rw.\n"); ++ exit (1); ++ } ++ ++ mbuf_rw = mmap ((void *) addr, pagesize, PROT_READ, ++ MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0); ++ ++ if (mbuf_rw == MAP_FAILED) ++ { ++ fprintf (stderr, "mmap #2 failed: %s.\n", strerror (errno)); ++ exit (1); ++ } ++ ++ /* With correct ulimit, etc. this should cause a core dump. */ ++ abort (); ++} diff --git a/SOURCES/gdb-rhbz1842691-corefile-mem-access-15of15.patch b/SOURCES/gdb-rhbz1842691-corefile-mem-access-15of15.patch new file mode 100644 index 0000000..4703d22 --- /dev/null +++ b/SOURCES/gdb-rhbz1842691-corefile-mem-access-15of15.patch @@ -0,0 +1,30 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Tue, 28 Jul 2020 09:49:56 -0400 +Subject: gdb-rhbz1842691-corefile-mem-access-15of15.patch + +;; Add period to help text for maint print core-file-backed-mappings +;; Kevin Buettner, RH BZ 1842961 + + Author: Kevin Buettner + Date: Thu Jul 23 13:26:44 2020 -0700 + + Fix BZ 26294 - Add period to help text for maint print core-file-backed-mappings + + gdb/ChangeLog: + + PR corefiles/26294 + * corelow.c (_initialize_corelow): Add period to help text + for "maintenance print core-file-backed-mappings". + +diff --git a/gdb/corelow.c b/gdb/corelow.c +--- a/gdb/corelow.c ++++ b/gdb/corelow.c +@@ -1267,6 +1267,6 @@ Show whether CORE-FILE loads the build-id associated files automatically."), + &setlist, &showlist); + add_cmd ("core-file-backed-mappings", class_maintenance, + maintenance_print_core_file_backed_mappings, +- _("Print core file's file-backed mappings"), ++ _("Print core file's file-backed mappings."), + &maintenanceprintlist); + } diff --git a/SOURCES/gdb-rhbz1842691-corefile-mem-access-1of15.patch b/SOURCES/gdb-rhbz1842691-corefile-mem-access-1of15.patch new file mode 100644 index 0000000..6a8c206 --- /dev/null +++ b/SOURCES/gdb-rhbz1842691-corefile-mem-access-1of15.patch @@ -0,0 +1,60 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Mon, 27 Jul 2020 16:34:37 -0400 +Subject: gdb-rhbz1842691-corefile-mem-access-1of15.patch + +;; Remove hack for GDB which sets the section size to 0 +;; Kevin Buettner, RH BZ 1842691 + + Author: Kevin Buettner + + Remove hack for GDB which sets the section size to 0 + + This commit removes a hack for GDB which was introduced in 2007. + See: + + https://sourceware.org/ml/binutils/2007-08/msg00044.html + + That hack mostly allowed GDB's handling of core files to continue to + work without any changes to GDB. + + The problem with setting the section size to zero is that GDB won't + know how big that section is/was. Often, this doesn't matter because + the data in question are found in the exec file. But it can happen + that the section describes memory that had been allocated, but never + written to. In this instance, the contents of that memory region are + not written to the core file. Also, since the region in question was + dynamically allocated, it won't appear in the exec file. We don't + want these regions to appear as inaccessible to GDB (since they *were* + accessible when the process was live), so it's important that GDB know + the size of the region. + + I've made changes to GDB which correctly handles this case. When + attempting to access memory, GDB will first consider core file data + for which both SEC_ALLOC and SEC_HAS_CONTENTS is set. Next, if that + fails, GDB will attempt to find the data in the exec file. Finally, + if that also fails, GDB will attempt to access memory in the sections + which are flagged as SEC_ALLOC, but not SEC_HAS_CONTENTS. + + bfd/ChangeLog: + + * elf.c (_bfd_elf_make_section_from_phdr): Remove hack for GDB. + +diff --git a/bfd/elf.c b/bfd/elf.c +--- a/bfd/elf.c ++++ b/bfd/elf.c +@@ -3032,14 +3032,6 @@ _bfd_elf_make_section_from_phdr (bfd *abfd, + newsect->alignment_power = bfd_log2 (align); + if (hdr->p_type == PT_LOAD) + { +- /* Hack for gdb. Segments that have not been modified do +- not have their contents written to a core file, on the +- assumption that a debugger can find the contents in the +- executable. We flag this case by setting the fake +- section size to zero. Note that "real" bss sections will +- always have their contents dumped to the core file. */ +- if (bfd_get_format (abfd) == bfd_core) +- newsect->size = 0; + newsect->flags |= SEC_ALLOC; + if (hdr->p_flags & PF_X) + newsect->flags |= SEC_CODE; diff --git a/SOURCES/gdb-rhbz1842691-corefile-mem-access-2of15.patch b/SOURCES/gdb-rhbz1842691-corefile-mem-access-2of15.patch new file mode 100644 index 0000000..60f8e77 --- /dev/null +++ b/SOURCES/gdb-rhbz1842691-corefile-mem-access-2of15.patch @@ -0,0 +1,129 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Mon, 27 Jul 2020 16:47:19 -0400 +Subject: gdb-rhbz1842691-corefile-mem-access-2of15.patch + +;; Adjust corefile.exp test to show regression after bfd hack removal +;; Kevin Buettner, RH BZ 1842691 + + Author: Kevin Buettner + Date: Tue May 12 17:44:19 2020 -0700 + + Adjust corefile.exp test to show regression after bfd hack removal + + In his review of my BZ 25631 patch series, Pedro was unable to + reproduce the regression which should occur after patch #1, "Remove + hack for GDB which sets the section size to 0", is applied. + + Pedro was using an ld version older than 2.30. Version 2.30 + introduced the linker option -z separate-code. Here's what the man + page has to say about it: + + Create separate code "PT_LOAD" segment header in the object. This + specifies a memory segment that should contain only instructions + and must be in wholly disjoint pages from any other data. + + In ld version 2.31, use of separate-code became the default for + Linux/x86. So, really, 2.31 or later is required in order to see the + regression that occurs in recent Linux distributions when only the + bfd hack removal patch is applied. + + For the test case in question, use of the separate-code linker option + means that the global variable "coremaker_ro" ends up in a separate + load segment (though potentially with other read-only data). The + upshot of this is that when only patch #1 is applied, GDB won't be + able to correctly access coremaker_ro. The reason for this is due + to the fact that this section will now have a non-zero size, but + will not have contents from the core file to find this data. + So GDB will ask BFD for the contents and BFD will respond with + zeroes for anything from those sections. GDB should instead be + looking in the executable for this data. Failing that, it can + then ask BFD for a reasonable value. This is what a later patch + in this series does. + + When using ld versions earlier than 2.31 (or 2.30 w/ the + -z separate-code option explicitly provided to the linker), there is + the possibility that coremaker_ro ends up being placed near other data + which is recorded in the core file. That means that the correct value + will end up in the core file, simply because it resides on a page that + the kernel chooses to put in the core file. This is why Pedro wasn't + able to reproduce the regression that should occur after fixing the + BFD hack. + + This patch places a big chunk of memory, two pages worth on x86, in + front of "coremaker_ro" to attempt to force it onto another page + without requiring use of that new-fangled linker switch. + + Speaking of which, I considered changing the test to use + -z separate-code, but this won't work because it didn't + exist prior to version 2.30. The linker would probably complain + of an unrecognized switch. Also, it likely won't be available in + other linkers not based on current binutils. I.e. it probably won't + work in FreeBSD, NetBSD, etc. + + To make this more concrete, this is what *should* happen when + attempting to access coremaker_ro when only patch #1 is applied: + + Core was generated by `/mesquite2/sourceware-git/f28-coresegs/bld/gdb/testsuite/outputs/gdb.base/coref'. + Program terminated with signal SIGABRT, Aborted. + #0 0x00007f68205deefb in raise () from /lib64/libc.so.6 + (gdb) p coremaker_ro + $1 = 0 + + Note that this result is wrong; 201 should have been printed instead. + But that's the point of the rest of the patch series. + + However, without this commit, or when using an old Linux distro with + a pre-2.31 ld, this is what you might see instead: + + Core was generated by `/mesquite2/sourceware-git/f28-coresegs/bld/gdb/testsuite/outputs/gdb.base/coref'. + Program terminated with signal SIGABRT, Aborted. + #0 0x00007f63dd658efb in raise () from /lib64/libc.so.6 + (gdb) p coremaker_ro + $1 = 201 + + I.e. it prints the right answer, which sort of makes it seem like the + rest of the series isn't required. + + Now, back to the patch itself... what should be the size of the memory + chunk placed before coremaker_ro? + + It needs to be at least as big as the page size (PAGE_SIZE) from + the kernel. For x86 and several other architectures this value is + 4096. I used MAPSIZE which is defined to be 8192 in coremaker.c. + So it's twice as big as what's currently needed for most Linux + architectures. The constant PAGE_SIZE is available from , + but this isn't portable either. In the end, it seemed simpler to + just pick a value and hope that it's big enough. (Running a separate + program which finds the page size via sysconf(_SC_PAGESIZE) and then + passes it to the compilation via a -D switch seemed like overkill + for a case which is rendered moot by recent linker versions.) + + Further information can be found here: + + https://sourceware.org/pipermail/gdb-patches/2020-May/168168.html + https://sourceware.org/pipermail/gdb-patches/2020-May/168170.html + + Thanks to H.J. Lu for telling me about the '-z separate-code' linker + switch. + + gdb/testsuite/ChangeLog: + + * gdb.base/coremaker.c (filler_ro): New global constant. + +diff --git a/gdb/testsuite/gdb.base/coremaker.c b/gdb/testsuite/gdb.base/coremaker.c +--- a/gdb/testsuite/gdb.base/coremaker.c ++++ b/gdb/testsuite/gdb.base/coremaker.c +@@ -42,6 +42,12 @@ char *buf2; + int coremaker_data = 1; /* In Data section */ + int coremaker_bss; /* In BSS section */ + ++/* Place a chunk of memory before coremaker_ro to improve the chances ++ that coremaker_ro will end up on it's own page. See: ++ ++ https://sourceware.org/pipermail/gdb-patches/2020-May/168168.html ++ https://sourceware.org/pipermail/gdb-patches/2020-May/168170.html */ ++const unsigned char filler_ro[MAPSIZE] = {1, 2, 3, 4, 5, 6, 7, 8}; + const int coremaker_ro = 201; /* In Read-Only Data section */ + + /* Note that if the mapping fails for any reason, we set buf2 diff --git a/SOURCES/gdb-rhbz1842691-corefile-mem-access-3of15.patch b/SOURCES/gdb-rhbz1842691-corefile-mem-access-3of15.patch new file mode 100644 index 0000000..57cb6ed --- /dev/null +++ b/SOURCES/gdb-rhbz1842691-corefile-mem-access-3of15.patch @@ -0,0 +1,174 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Mon, 27 Jul 2020 16:52:18 -0400 +Subject: gdb-rhbz1842691-corefile-mem-access-3of15.patch + +;; section_table_xfer_memory: Replace section name with callback predicate +;; Kevin Buettner, RH BZ 1842691 + + Author: Kevin Buettner + Date: Wed Mar 4 17:42:41 2020 -0700 + + section_table_xfer_memory: Replace section name with callback predicate + + This patch is motivated by the need to be able to select sections + that section_table_xfer_memory_partial should consider for memory + transfers. I'll use this facility in the next patch in this series. + + section_table_xfer_memory_partial() can currently be passed a section + name which may be used to make name-based selections. This is similar + to what I want to do, except that I want to be able to consider + section flags instead of the name. + + I'm replacing the section name parameter with a predicate that, + when passed a pointer to a target_section struct, will return + true if that section should be further considered, or false which + indicates that it shouldn't. + + I've converted the one existing use where a non-NULL section + name is passed to section_table_xfer_memory_partial(). Instead + of passing the section name, it now looks like this: + + auto match_cb = [=] (const struct target_section *s) + { + return (strcmp (section_name, s->the_bfd_section->name) == 0); + }; + + return section_table_xfer_memory_partial (readbuf, writebuf, + memaddr, len, xfered_len, + table->sections, + table->sections_end, + match_cb); + + The other callers all passed NULL; they've been simplified somewhat + in that they no longer need to pass NULL. + + gdb/ChangeLog: + + * exec.h (section_table_xfer_memory): Revise declaration, + replacing section name parameter with an optional callback + predicate. + * exec.c (section_table_xfer_memory): Likewise. + * bfd-target.c, exec.c, target.c, corelow.c: Adjust all callers + of section_table_xfer_memory. + +diff --git a/gdb/bfd-target.c b/gdb/bfd-target.c +--- a/gdb/bfd-target.c ++++ b/gdb/bfd-target.c +@@ -77,8 +77,7 @@ target_bfd::xfer_partial (target_object object, + return section_table_xfer_memory_partial (readbuf, writebuf, + offset, len, xfered_len, + m_table.sections, +- m_table.sections_end, +- NULL); ++ m_table.sections_end); + } + default: + return TARGET_XFER_E_IO; +diff --git a/gdb/corelow.c b/gdb/corelow.c +--- a/gdb/corelow.c ++++ b/gdb/corelow.c +@@ -758,8 +758,7 @@ core_target::xfer_partial (enum target_object object, const char *annex, + (readbuf, writebuf, + offset, len, xfered_len, + m_core_section_table.sections, +- m_core_section_table.sections_end, +- NULL)); ++ m_core_section_table.sections_end)); + + case TARGET_OBJECT_AUXV: + if (readbuf) +diff --git a/gdb/exec.c b/gdb/exec.c +--- a/gdb/exec.c ++++ b/gdb/exec.c +@@ -792,7 +792,8 @@ section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf, + ULONGEST *xfered_len, + struct target_section *sections, + struct target_section *sections_end, +- const char *section_name) ++ gdb::function_view match_cb) + { + int res; + struct target_section *p; +@@ -808,7 +809,7 @@ section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf, + struct bfd_section *asect = p->the_bfd_section; + bfd *abfd = asect->owner; + +- if (section_name && strcmp (section_name, asect->name) != 0) ++ if (match_cb != nullptr && !match_cb (p)) + continue; /* not the section we need. */ + if (memaddr >= p->addr) + { +@@ -881,8 +882,7 @@ exec_target::xfer_partial (enum target_object object, + return section_table_xfer_memory_partial (readbuf, writebuf, + offset, len, xfered_len, + table->sections, +- table->sections_end, +- NULL); ++ table->sections_end); + else + return TARGET_XFER_E_IO; + } +diff --git a/gdb/exec.h b/gdb/exec.h +--- a/gdb/exec.h ++++ b/gdb/exec.h +@@ -58,8 +58,13 @@ extern enum target_xfer_status + Request to transfer up to LEN 8-bit bytes of the target sections + defined by SECTIONS and SECTIONS_END. The OFFSET specifies the + starting address. +- If SECTION_NAME is not NULL, only access sections with that same +- name. ++ ++ The MATCH_CB predicate is optional; when provided it will be called ++ for each section under consideration. When MATCH_CB evaluates as ++ true, the section remains under consideration; a false result ++ removes it from consideration for performing the memory transfers ++ noted above. See memory_xfer_partial_1() in target.c for an ++ example. + + Return the number of bytes actually transfered, or zero when no + data is available for the requested range. +@@ -76,7 +81,9 @@ extern enum target_xfer_status + ULONGEST, ULONGEST, ULONGEST *, + struct target_section *, + struct target_section *, +- const char *); ++ gdb::function_view match_cb ++ = nullptr); + + /* Read from mappable read-only sections of BFD executable files. + Similar to exec_read_partial_read_only, but return +diff --git a/gdb/target.c b/gdb/target.c +--- a/gdb/target.c ++++ b/gdb/target.c +@@ -1022,11 +1022,17 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object, + const char *section_name = section->the_bfd_section->name; + + memaddr = overlay_mapped_address (memaddr, section); ++ ++ auto match_cb = [=] (const struct target_section *s) ++ { ++ return (strcmp (section_name, s->the_bfd_section->name) == 0); ++ }; ++ + return section_table_xfer_memory_partial (readbuf, writebuf, + memaddr, len, xfered_len, + table->sections, + table->sections_end, +- section_name); ++ match_cb); + } + } + +@@ -1044,8 +1050,7 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object, + return section_table_xfer_memory_partial (readbuf, writebuf, + memaddr, len, xfered_len, + table->sections, +- table->sections_end, +- NULL); ++ table->sections_end); + } + } + diff --git a/SOURCES/gdb-rhbz1842691-corefile-mem-access-4of15.patch b/SOURCES/gdb-rhbz1842691-corefile-mem-access-4of15.patch new file mode 100644 index 0000000..1f86388 --- /dev/null +++ b/SOURCES/gdb-rhbz1842691-corefile-mem-access-4of15.patch @@ -0,0 +1,236 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Mon, 27 Jul 2020 17:11:49 -0400 +Subject: gdb-rhbz1842691-corefile-mem-access-4of15.patch + +;; Provide access to non SEC_HAS_CONTENTS core file sections +;; Kevin Buettner, RH BZ 1842961 + + Author: Kevin Buettner + Date: Wed Mar 4 17:42:42 2020 -0700 + + Provide access to non SEC_HAS_CONTENTS core file sections + + Consider the following program: + + - - - mkmmapcore.c - - - + + static char *buf; + + int + main (int argc, char **argv) + { + buf = mmap (NULL, 8192, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + abort (); + } + - - - end mkmmapcore.c - - - + + Compile it like this: + + gcc -g -o mkmmapcore mkmmapcore.c + + Now let's run it from GDB. I've already placed a breakpoint on the + line with the abort() call and have run to that breakpoint. + + Breakpoint 1, main (argc=1, argv=0x7fffffffd678) at mkmmapcore.c:11 + 11 abort (); + (gdb) x/x buf + 0x7ffff7fcb000: 0x00000000 + + Note that we can examine the memory allocated via the call to mmap(). + + Now let's try debugging a core file created by running this program. + Depending on your system, in order to make a core file, you may have to + run the following as root (or using sudo): + + echo core > /proc/sys/kernel/core_pattern + + It may also be necessary to do: + + ulimit -c unlimited + + I'm using Fedora 31. YMMV if you're using one of the BSDs or some other + (non-Linux) system. + + This is what things look like when we debug the core file: + + [kev@f31-1 tmp]$ gdb -q ./mkmmapcore core.304767 + Reading symbols from ./mkmmapcore... + [New LWP 304767] + Core was generated by `/tmp/mkmmapcore'. + Program terminated with signal SIGABRT, Aborted. + #0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50 + 50 return ret; + (gdb) x/x buf + 0x7ffff7fcb000: Cannot access memory at address 0x7ffff7fcb000 + + Note that we can no longer access the memory region allocated by mmap(). + + Back in 2007, a hack for GDB was added to _bfd_elf_make_section_from_phdr() + in bfd/elf.c: + + /* Hack for gdb. Segments that have not been modified do + not have their contents written to a core file, on the + assumption that a debugger can find the contents in the + executable. We flag this case by setting the fake + section size to zero. Note that "real" bss sections will + always have their contents dumped to the core file. */ + if (bfd_get_format (abfd) == bfd_core) + newsect->size = 0; + + You can find the entire patch plus links to other discussion starting + here: + + https://sourceware.org/ml/binutils/2007-08/msg00047.html + + This hack sets the size of certain BFD sections to 0, which + effectively causes GDB to ignore them. I think it's likely that the + bug described above existed even before this hack was added, but I + have no easy way to test this now. + + The output from objdump -h shows the result of this hack: + + 25 load13 00000000 00007ffff7fcb000 0000000000000000 00013000 2**12 + ALLOC + + (The first field, after load13, shows the size of 0.) + + Once the hack is removed, the output from objdump -h shows the correct + size: + + 25 load13 00002000 00007ffff7fcb000 0000000000000000 00013000 2**12 + ALLOC + + (This is a digression, but I think it's good that objdump will now show + the correct size.) + + If we remove the hack from bfd/elf.c, but do nothing to GDB, we'll + see the following regression: + + FAIL: gdb.base/corefile.exp: print coremaker_ro + + The reason for this is that all sections which have the BFD flag + SEC_ALLOC set, but for which SEC_HAS_CONTENTS is not set no longer + have zero size. Some of these sections have data that can (and should) + be read from the executable. (Sections for which SEC_HAS_CONTENTS + is set should be read from the core file; sections which do not have + this flag set need to either be read from the executable or, failing + that, from the core file using whatever BFD decides is the best value + to present to the user - it uses zeros.) + + At present, due to the way that the target strata are traversed when + attempting to access memory, the non-SEC_HAS_CONTENTS sections will be + read as zeroes from the process_stratum (which in this case is the + core file stratum) without first checking the file stratum, which is + where the data might actually be found. + + What we should be doing is this: + + - Attempt to access core file data for SEC_HAS_CONTENTS sections. + - Attempt to access executable file data if the above fails. + - Attempt to access core file data for non SEC_HAS_CONTENTS sections, if + both of the above fail. + + This corresponds to the analysis of Daniel Jacobowitz back in 2007 + when the hack was added to BFD: + + https://sourceware.org/legacy-ml/binutils/2007-08/msg00045.html + + The difference, observed by Pedro in his review of my v1 patches, is + that I'm using "the section flags as proxy for the p_filesz/p_memsz + checks." + + gdb/ChangeLog: + + PR corefiles/25631 + * corelow.c (core_target:xfer_partial): Revise + TARGET_OBJECT_MEMORY case to consider non-SEC_HAS_CONTENTS + case after first checking the stratum beneath the core + target. + (has_all_memory): Return true. + * target.c (raw_memory_xfer_partial): Revise comment + regarding use of has_all_memory. + +diff --git a/gdb/corelow.c b/gdb/corelow.c +--- a/gdb/corelow.c ++++ b/gdb/corelow.c +@@ -93,7 +93,7 @@ public: + + const char *thread_name (struct thread_info *) override; + +- bool has_all_memory () override { return false; } ++ bool has_all_memory () override { return true; } + bool has_memory () override; + bool has_stack () override; + bool has_registers () override; +@@ -754,12 +754,47 @@ core_target::xfer_partial (enum target_object object, const char *annex, + switch (object) + { + case TARGET_OBJECT_MEMORY: +- return (section_table_xfer_memory_partial +- (readbuf, writebuf, +- offset, len, xfered_len, +- m_core_section_table.sections, +- m_core_section_table.sections_end)); ++ { ++ enum target_xfer_status xfer_status; ++ ++ /* Try accessing memory contents from core file data, ++ restricting consideration to those sections for which ++ the BFD section flag SEC_HAS_CONTENTS is set. */ ++ auto has_contents_cb = [] (const struct target_section *s) ++ { ++ return ((s->the_bfd_section->flags & SEC_HAS_CONTENTS) != 0); ++ }; ++ xfer_status = section_table_xfer_memory_partial ++ (readbuf, writebuf, ++ offset, len, xfered_len, ++ m_core_section_table.sections, ++ m_core_section_table.sections_end, ++ has_contents_cb); ++ if (xfer_status == TARGET_XFER_OK) ++ return TARGET_XFER_OK; ++ ++ /* Now check the stratum beneath us; this should be file_stratum. */ ++ xfer_status = this->beneath ()->xfer_partial (object, annex, readbuf, ++ writebuf, offset, len, ++ xfered_len); ++ if (xfer_status == TARGET_XFER_OK) ++ return TARGET_XFER_OK; + ++ /* Finally, attempt to access data in core file sections with ++ no contents. These will typically read as all zero. */ ++ auto no_contents_cb = [&] (const struct target_section *s) ++ { ++ return !has_contents_cb (s); ++ }; ++ xfer_status = section_table_xfer_memory_partial ++ (readbuf, writebuf, ++ offset, len, xfered_len, ++ m_core_section_table.sections, ++ m_core_section_table.sections_end, ++ no_contents_cb); ++ ++ return xfer_status; ++ } + case TARGET_OBJECT_AUXV: + if (readbuf) + { +diff --git a/gdb/target.c b/gdb/target.c +--- a/gdb/target.c ++++ b/gdb/target.c +@@ -967,8 +967,11 @@ raw_memory_xfer_partial (struct target_ops *ops, gdb_byte *readbuf, + if (res == TARGET_XFER_UNAVAILABLE) + break; + +- /* We want to continue past core files to executables, but not +- past a running target's memory. */ ++ /* Don't continue past targets which have all the memory. ++ At one time, this code was necessary to read data from ++ executables / shared libraries when data for the requested ++ addresses weren't available in the core file. But now the ++ core target handles this case itself. */ + if (ops->has_all_memory ()) + break; + diff --git a/SOURCES/gdb-rhbz1842691-corefile-mem-access-5of15.patch b/SOURCES/gdb-rhbz1842691-corefile-mem-access-5of15.patch new file mode 100644 index 0000000..9b0a49f --- /dev/null +++ b/SOURCES/gdb-rhbz1842691-corefile-mem-access-5of15.patch @@ -0,0 +1,68 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Mon, 27 Jul 2020 17:27:39 -0400 +Subject: gdb-rhbz1842691-corefile-mem-access-5of15.patch + +;; Test ability to access unwritten-to mmap data in core file +;; Kevin Buettner, RH BZ 1842961 + + Author: Kevin Buettner + Date: Wed Mar 4 17:42:43 2020 -0700 + + Test ability to access unwritten-to mmap data in core file + + gdb/testsuite/ChangeLog: + + PR corefiles/25631 + * gdb.base/corefile.exp (accessing anonymous, unwritten-to mmap data): + New test. + * gdb.base/coremaker.c (buf3): New global. + (mmapdata): Add mmap call which uses MAP_ANONYMOUS and MAP_PRIVATE + flags. + +diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp +--- a/gdb/testsuite/gdb.base/corefile.exp ++++ b/gdb/testsuite/gdb.base/corefile.exp +@@ -175,6 +175,15 @@ gdb_test_multiple "x/8bd buf2" "$test" { + } + } + ++# Test ability to read anonymous and, more importantly, unwritten-to ++# mmap'd data. ++ ++if { ![istarget *-linux*] } { ++ setup_xfail "*-*-*" ++} ++gdb_test "x/wx buf3" "$hex:\[ \t\]+0x00000000" \ ++ "accessing anonymous, unwritten-to mmap data" ++ + # test reinit_frame_cache + + gdb_load ${binfile} +diff --git a/gdb/testsuite/gdb.base/coremaker.c b/gdb/testsuite/gdb.base/coremaker.c +--- a/gdb/testsuite/gdb.base/coremaker.c ++++ b/gdb/testsuite/gdb.base/coremaker.c +@@ -38,6 +38,7 @@ + + char *buf1; + char *buf2; ++char *buf3; + + int coremaker_data = 1; /* In Data section */ + int coremaker_bss; /* In BSS section */ +@@ -104,6 +105,15 @@ mmapdata () + } + /* Touch buf2 so kernel writes it out into 'core'. */ + buf2[0] = buf1[0]; ++ ++ /* Create yet another region which is allocated, but not written to. */ ++ buf3 = mmap (NULL, MAPSIZE, PROT_READ | PROT_WRITE, ++ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); ++ if (buf3 == (char *) -1) ++ { ++ perror ("mmap failed"); ++ return; ++ } + } + + void diff --git a/SOURCES/gdb-rhbz1842691-corefile-mem-access-6of15.patch b/SOURCES/gdb-rhbz1842691-corefile-mem-access-6of15.patch new file mode 100644 index 0000000..0df6f68 --- /dev/null +++ b/SOURCES/gdb-rhbz1842691-corefile-mem-access-6of15.patch @@ -0,0 +1,62 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Mon, 27 Jul 2020 17:32:50 -0400 +Subject: gdb-rhbz1842691-corefile-mem-access-6of15.patch + +;; Update binary_get_section_contents to seek using section's file position +;; Kevin Buettner, RH BZ 1842961 + + Author: Kevin Buettner + Date: Thu Jun 11 18:58:49 2020 -0700 + + Update binary_get_section_contents to seek using section's file position + + I have a patch for GDB which opens and reads from BFDs using the + "binary" target. However, for it to work, we need to be able to get a + section's contents based from the file position of that section. + + At the moment, reading a section's contents will always read from the + start of the file regardless of where that section is located. While + this was fine for the original use of the "binary" target, it won't + work for my use case. This change shouldn't impact any existing + callers due to the fact that the single .data section is initialized + with a filepos of 0. + + bfd/ChangeLog: + + * binary.c (binary_get_section_contents): Seek using offset + from section's file position. + +diff --git a/bfd/binary.c b/bfd/binary.c +--- a/bfd/binary.c ++++ b/bfd/binary.c +@@ -19,10 +19,10 @@ + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +-/* This is a BFD backend which may be used to write binary objects. +- It may only be used for output, not input. The intention is that +- this may be used as an output format for objcopy in order to +- generate raw binary data. ++/* This is a BFD backend which may be used to read or write binary ++ objects. Historically, it was used as an output format for objcopy ++ in order to generate raw binary data, but is now used for other ++ purposes as well. + + This is very simple. The only complication is that the real data + will start at some address X, and in some cases we will not want to +@@ -97,12 +97,12 @@ binary_object_p (bfd *abfd) + + static bfd_boolean + binary_get_section_contents (bfd *abfd, +- asection *section ATTRIBUTE_UNUSED, ++ asection *section, + void * location, + file_ptr offset, + bfd_size_type count) + { +- if (bfd_seek (abfd, offset, SEEK_SET) != 0 ++ if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0 + || bfd_bread (location, count, abfd) != count) + return FALSE; + return TRUE; diff --git a/SOURCES/gdb-rhbz1842691-corefile-mem-access-7of15.patch b/SOURCES/gdb-rhbz1842691-corefile-mem-access-7of15.patch new file mode 100644 index 0000000..2bfb3e6 --- /dev/null +++ b/SOURCES/gdb-rhbz1842691-corefile-mem-access-7of15.patch @@ -0,0 +1,180 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Mon, 27 Jul 2020 18:01:32 -0400 +Subject: gdb-rhbz1842691-corefile-mem-access-7of15.patch + +;; Add new gdbarch method, read_core_file_mappings +;; Kevin Buettner, RH BZ 1842961 + + Author: Kevin Buettner + Date: Fri Jul 3 13:32:08 2020 -0700 + + Add new gdbarch method, read_core_file_mappings + + The new gdbarch method, read_core_file_mappings, will be used for + reading file-backed mappings from a core file. It'll be used + for two purposes: 1) to construct a table of file-backed mappings + in corelow.c, and 2) for display of core file mappings. + + For Linux, I tried a different approach in which knowledge of the note + format was placed directly in corelow.c. This seemed okay at first; + it was only one note format and the note format was fairly simple. + After looking at FreeBSD's note/mapping reading code, I concluded + that it's best to leave architecture specific details for decoding + the note in (architecture specific) tdep files. + + With regard to display of core file mappings, I experimented with + placing the mappings display code in corelow.c. It has access to the + file-backed mappings which were read in when the core file was loaded. + And, better, still common code could be used for all architectures. + But, again, the FreeBSD mapping code convinced me that this was not + the best approach since it has even more mapping info than Linux. + Display code which would work well for Linux will leave out mappings + as well as protection info for mappings. + + So, for these reasons, I'm introducing a new gdbarch method for + reading core file mappings. + + gdb/ChangeLog: + + * arch-utils.c (default_read_core_file_mappings): New function. + * arch-utils.c (default_read_core_file_mappings): Declare. + * gdbarch.sh (read_core_file_mappings): New gdbarch method. + * gdbarch.h, gdbarch.c: Regenerate. + +diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c +--- a/gdb/arch-utils.c ++++ b/gdb/arch-utils.c +@@ -1004,6 +1004,22 @@ default_get_pc_address_flags (frame_info *frame, CORE_ADDR pc) + return ""; + } + ++/* See arch-utils.h. */ ++void ++default_read_core_file_mappings (struct gdbarch *gdbarch, ++ struct bfd *cbfd, ++ gdb::function_view ++ pre_loop_cb, ++ gdb::function_view ++ loop_cb) ++{ ++} ++ + void + _initialize_gdbarch_utils (void) + { +diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h +--- a/gdb/arch-utils.h ++++ b/gdb/arch-utils.h +@@ -276,4 +276,16 @@ extern ULONGEST default_type_align (struct gdbarch *gdbarch, + extern std::string default_get_pc_address_flags (frame_info *frame, + CORE_ADDR pc); + ++/* Default implementation of gdbarch read_core_file_mappings method. */ ++extern void default_read_core_file_mappings (struct gdbarch *gdbarch, ++ struct bfd *cbfd, ++ gdb::function_view ++ pre_loop_cb, ++ gdb::function_view ++ loop_cb); + #endif /* ARCH_UTILS_H */ +diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c +--- a/gdb/gdbarch.c ++++ b/gdb/gdbarch.c +@@ -358,6 +358,7 @@ struct gdbarch + const disasm_options_and_args_t * valid_disassembler_options; + gdbarch_type_align_ftype *type_align; + gdbarch_get_pc_address_flags_ftype *get_pc_address_flags; ++ gdbarch_read_core_file_mappings_ftype *read_core_file_mappings; + }; + + /* Create a new ``struct gdbarch'' based on information provided by +@@ -473,6 +474,7 @@ gdbarch_alloc (const struct gdbarch_info *info, + gdbarch->addressable_memory_unit_size = default_addressable_memory_unit_size; + gdbarch->type_align = default_type_align; + gdbarch->get_pc_address_flags = default_get_pc_address_flags; ++ gdbarch->read_core_file_mappings = default_read_core_file_mappings; + /* gdbarch_alloc() */ + + return gdbarch; +@@ -721,6 +723,7 @@ verify_gdbarch (struct gdbarch *gdbarch) + /* Skip verify of valid_disassembler_options, invalid_p == 0 */ + /* Skip verify of type_align, invalid_p == 0 */ + /* Skip verify of get_pc_address_flags, invalid_p == 0 */ ++ /* Skip verify of read_core_file_mappings, invalid_p == 0 */ + if (!log.empty ()) + internal_error (__FILE__, __LINE__, + _("verify_gdbarch: the following are invalid ...%s"), +@@ -1287,6 +1290,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) + fprintf_unfiltered (file, + "gdbarch_dump: ravenscar_ops = %s\n", + host_address_to_string (gdbarch->ravenscar_ops)); ++ fprintf_unfiltered (file, ++ "gdbarch_dump: read_core_file_mappings = <%s>\n", ++ host_address_to_string (gdbarch->read_core_file_mappings)); + fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_read_pc_p() = %d\n", + gdbarch_read_pc_p (gdbarch)); +@@ -5156,6 +5162,23 @@ set_gdbarch_get_pc_address_flags (struct gdbarch *gdbarch, + gdbarch->get_pc_address_flags = get_pc_address_flags; + } + ++void ++gdbarch_read_core_file_mappings (struct gdbarch *gdbarch, struct bfd *cbfd,gdb::function_view pre_loop_cb,gdb::function_view loop_cb) ++{ ++ gdb_assert (gdbarch != NULL); ++ gdb_assert (gdbarch->read_core_file_mappings != NULL); ++ if (gdbarch_debug >= 2) ++ fprintf_unfiltered (gdb_stdlog, "gdbarch_read_core_file_mappings called\n"); ++ gdbarch->read_core_file_mappings (gdbarch, cbfd, pre_loop_cb, loop_cb); ++} ++ ++void ++set_gdbarch_read_core_file_mappings (struct gdbarch *gdbarch, ++ gdbarch_read_core_file_mappings_ftype read_core_file_mappings) ++{ ++ gdbarch->read_core_file_mappings = read_core_file_mappings; ++} ++ + + /* Keep a registry of per-architecture data-pointers required by GDB + modules. */ +diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h +--- a/gdb/gdbarch.h ++++ b/gdb/gdbarch.h +@@ -1640,6 +1640,12 @@ typedef std::string (gdbarch_get_pc_address_flags_ftype) (frame_info *frame, COR + extern std::string gdbarch_get_pc_address_flags (struct gdbarch *gdbarch, frame_info *frame, CORE_ADDR pc); + extern void set_gdbarch_get_pc_address_flags (struct gdbarch *gdbarch, gdbarch_get_pc_address_flags_ftype *get_pc_address_flags); + ++/* Read core file mappings */ ++ ++typedef void (gdbarch_read_core_file_mappings_ftype) (struct gdbarch *gdbarch, struct bfd *cbfd,gdb::function_view pre_loop_cb,gdb::function_view loop_cb); ++extern void gdbarch_read_core_file_mappings (struct gdbarch *gdbarch, struct bfd *cbfd,gdb::function_view pre_loop_cb,gdb::function_view loop_cb); ++extern void set_gdbarch_read_core_file_mappings (struct gdbarch *gdbarch, gdbarch_read_core_file_mappings_ftype *read_core_file_mappings); ++ + extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch); + + +diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh +--- a/gdb/gdbarch.sh ++++ b/gdb/gdbarch.sh +@@ -1209,6 +1209,9 @@ m;ULONGEST;type_align;struct type *type;type;;default_type_align;;0 + # Return a string containing any flags for the given PC in the given FRAME. + f;std::string;get_pc_address_flags;frame_info *frame, CORE_ADDR pc;frame, pc;;default_get_pc_address_flags;;0 + ++# Read core file mappings ++m;void;read_core_file_mappings;struct bfd *cbfd,gdb::function_view pre_loop_cb,gdb::function_view loop_cb;cbfd, pre_loop_cb, loop_cb;;default_read_core_file_mappings;;0 ++ + EOF + } + diff --git a/SOURCES/gdb-rhbz1842691-corefile-mem-access-8of15.patch b/SOURCES/gdb-rhbz1842691-corefile-mem-access-8of15.patch new file mode 100644 index 0000000..9fefa37 --- /dev/null +++ b/SOURCES/gdb-rhbz1842691-corefile-mem-access-8of15.patch @@ -0,0 +1,531 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Mon, 27 Jul 2020 18:51:07 -0400 +Subject: gdb-rhbz1842691-corefile-mem-access-8of15.patch + +;; Use NT_FILE note section for reading core target memory +;; Kevin Buettner, RH BZ 1842961 + + Author: Kevin Buettner + Date: Thu Jun 11 19:20:03 2020 -0700 + + Use NT_FILE note section for reading core target memory + + In his reviews of my v1 and v2 corefile related patches, Pedro + identified two cases which weren't handled by those patches. + + In https://sourceware.org/pipermail/gdb-patches/2020-May/168826.html, + Pedro showed that debugging a core file in which mmap() is used to + create a new mapping over an existing file-backed mapping will + produce incorrect results. I.e, for his example, GDB would + show: + + (gdb) disassemble main + Dump of assembler code for function main: + 0x00000000004004e6 <+0>: push %rbp + 0x00000000004004e7 <+1>: mov %rsp,%rbp + => 0x00000000004004ea <+4>: callq 0x4003f0 + End of assembler dump. + + This sort of looks like it might be correct, but is not due to the + fact that mmap(...MAP_FIXED...) was used to create a mapping (of all + zeros) on top of the .text section. So, the correct result should be: + + (gdb) disassemble main + Dump of assembler code for function main: + 0x00000000004004e6 <+0>: add %al,(%rax) + 0x00000000004004e8 <+2>: add %al,(%rax) + => 0x00000000004004ea <+4>: add %al,(%rax) + 0x00000000004004ec <+6>: add %al,(%rax) + 0x00000000004004ee <+8>: add %al,(%rax) + End of assembler dump. + + The other case that Pedro found involved an attempted examination of a + particular section in the test case from gdb.base/corefile.exp. On + Fedora 27 or 28, the following behavior may be observed: + + (gdb) info proc mappings + Mapped address spaces: + + Start Addr End Addr Size Offset objfile + ... + 0x7ffff7839000 0x7ffff7a38000 0x1ff000 0x1b5000 /usr/lib64/libc-2.27.so + ... + (gdb) x/4x 0x7ffff7839000 + 0x7ffff7839000: Cannot access memory at address 0x7ffff7839000 + + FYI, this section appears to be unrelocated vtable data. See + https://sourceware.org/pipermail/gdb-patches/2020-May/168331.html for + a detailed analysis. + + The important thing here is that GDB should be able to access this + address since it should be backed by the shared library. I.e. it + should do this: + + (gdb) x/4x 0x7ffff7839000 + 0x7ffff7839000: 0x0007ddf0 0x00000000 0x0007dba0 0x00000000 + + Both of these cases are fixed with this commit. + + In a nutshell, this commit opens a "binary" target BFD for each of the + files that are mentioned in an NT_FILE / .note.linuxcore.file note + section. It then uses these mappings instead of the file stratum + mappings that GDB has used in the past. + + If this note section doesn't exist or is mangled for some reason, then + GDB will use the file stratum as before. Should this happen, then + we can expect both of the above problems to again be present. + + See the code comments in the commit for other details. + + gdb/ChangeLog: + + * corelow.c (solist.h, unordered_map): Include. + (class core_target): Add field m_core_file_mappings and + method build_file_mappings. + (core_target::core_target): Call build_file_mappings. + (core_target::~core_target): Free memory associated with + m_core_file_mappings. + (core_target::build_file_mappings): New method. + (core_target::xfer_partial): Use m_core_file_mappings + for memory transfers. + * linux-tdep.c (linux_read_core_file_mappings): New + function. + (linux_core_info_proc_mappings): Rewrite to use + linux_read_core_file_mappings. + (linux_init_abi): Register linux_read_core_file_mappings. + +diff --git a/gdb/corelow.c b/gdb/corelow.c +--- a/gdb/corelow.c ++++ b/gdb/corelow.c +@@ -41,6 +41,7 @@ + #include "exec.h" + #include "readline/tilde.h" + #include "solib.h" ++#include "solist.h" + #include "filenames.h" + #include "progspace.h" + #include "objfiles.h" +@@ -48,6 +49,8 @@ + #include "completer.h" + #include "gdbsupport/filestuff.h" + #include "build-id.h" ++#include "gdbsupport/pathstuff.h" ++#include + + #ifndef O_LARGEFILE + #define O_LARGEFILE 0 +@@ -132,6 +135,13 @@ private: /* per-core data */ + core file currently open on core_bfd. */ + core_fns *m_core_vec = NULL; + ++ /* File-backed address space mappings: some core files include ++ information about memory mapped files. */ ++ target_section_table m_core_file_mappings {}; ++ ++ /* Build m_core_file_mappings. Called from the constructor. */ ++ void build_file_mappings (); ++ + /* FIXME: kettenis/20031023: Eventually this field should + disappear. */ + struct gdbarch *m_core_gdbarch = NULL; +@@ -150,11 +160,120 @@ core_target::core_target () + &m_core_section_table.sections_end)) + error (_("\"%s\": Can't find sections: %s"), + bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ())); ++ ++ build_file_mappings (); + } + + core_target::~core_target () + { + xfree (m_core_section_table.sections); ++ xfree (m_core_file_mappings.sections); ++} ++ ++/* Construct the target_section_table for file-backed mappings if ++ they exist. ++ ++ For each unique path in the note, we'll open a BFD with a bfd ++ target of "binary". This is an unstructured bfd target upon which ++ we'll impose a structure from the mappings in the architecture-specific ++ mappings note. A BFD section is allocated and initialized for each ++ file-backed mapping. ++ ++ We take care to not share already open bfds with other parts of ++ GDB; in particular, we don't want to add new sections to existing ++ BFDs. We do, however, ensure that the BFDs that we allocate here ++ will go away (be deallocated) when the core target is detached. */ ++ ++void ++core_target::build_file_mappings () ++{ ++ std::unordered_map bfd_map; ++ ++ /* See linux_read_core_file_mappings() in linux-tdep.c for an example ++ read_core_file_mappings method. */ ++ gdbarch_read_core_file_mappings (m_core_gdbarch, core_bfd, ++ ++ /* After determining the number of mappings, read_core_file_mappings ++ will invoke this lambda which allocates target_section storage for ++ the mappings. */ ++ [&] (ULONGEST count) ++ { ++ m_core_file_mappings.sections = XNEWVEC (struct target_section, count); ++ m_core_file_mappings.sections_end = m_core_file_mappings.sections; ++ }, ++ ++ /* read_core_file_mappings will invoke this lambda for each mapping ++ that it finds. */ ++ [&] (int num, ULONGEST start, ULONGEST end, ULONGEST file_ofs, ++ const char *filename, const void *other) ++ { ++ /* Architecture-specific read_core_mapping methods are expected to ++ weed out non-file-backed mappings. */ ++ gdb_assert (filename != nullptr); ++ ++ struct bfd *bfd = bfd_map[filename]; ++ if (bfd == nullptr) ++ { ++ /* Use exec_file_find() to do sysroot expansion. It'll ++ also strip the potential sysroot "target:" prefix. If ++ there is no sysroot, an equivalent (possibly more ++ canonical) pathname will be provided. */ ++ gdb::unique_xmalloc_ptr expanded_fname ++ = exec_file_find (filename, NULL); ++ if (expanded_fname == nullptr) ++ { ++ warning (_("Can't open file %s during file-backed mapping " ++ "note processing"), ++ expanded_fname.get ()); ++ return; ++ } ++ ++ bfd = bfd_map[filename] = bfd_openr (expanded_fname.get (), ++ "binary"); ++ ++ if (bfd == nullptr || !bfd_check_format (bfd, bfd_object)) ++ { ++ /* If we get here, there's a good chance that it's due to ++ an internal error. We issue a warning instead of an ++ internal error because of the possibility that the ++ file was removed in between checking for its ++ existence during the expansion in exec_file_find() ++ and the calls to bfd_openr() / bfd_check_format(). ++ Output both the path from the core file note along ++ with its expansion to make debugging this problem ++ easier. */ ++ warning (_("Can't open file %s which was expanded to %s " ++ "during file-backed mapping note processing"), ++ filename, expanded_fname.get ()); ++ if (bfd != nullptr) ++ bfd_close (bfd); ++ return; ++ } ++ /* Ensure that the bfd will be closed when core_bfd is closed. ++ This can be checked before/after a core file detach via ++ "maint info bfds". */ ++ gdb_bfd_record_inclusion (core_bfd, bfd); ++ } ++ ++ /* Make new BFD section. All sections have the same name, ++ which is permitted by bfd_make_section_anyway(). */ ++ asection *sec = bfd_make_section_anyway (bfd, "load"); ++ if (sec == nullptr) ++ error (_("Can't make section")); ++ sec->filepos = file_ofs; ++ bfd_set_section_flags (sec, SEC_READONLY | SEC_HAS_CONTENTS); ++ bfd_set_section_size (sec, end - start); ++ bfd_set_section_vma (sec, start); ++ bfd_set_section_lma (sec, start); ++ bfd_set_section_alignment (sec, 2); ++ ++ /* Set target_section fields. */ ++ struct target_section *ts = m_core_file_mappings.sections_end++; ++ ts->addr = start; ++ ts->endaddr = end; ++ ts->owner = nullptr; ++ ts->the_bfd_section = sec; ++ }); + } + + /* List of all available core_fns. On gdb startup, each core file +@@ -773,10 +892,21 @@ core_target::xfer_partial (enum target_object object, const char *annex, + if (xfer_status == TARGET_XFER_OK) + return TARGET_XFER_OK; + +- /* Now check the stratum beneath us; this should be file_stratum. */ +- xfer_status = this->beneath ()->xfer_partial (object, annex, readbuf, +- writebuf, offset, len, +- xfered_len); ++ /* Check file backed mappings. If they're available, use ++ core file provided mappings (e.g. from .note.linuxcore.file ++ or the like) as this should provide a more accurate ++ result. If not, check the stratum beneath us, which should ++ be the file stratum. */ ++ if (m_core_file_mappings.sections != nullptr) ++ xfer_status = section_table_xfer_memory_partial ++ (readbuf, writebuf, ++ offset, len, xfered_len, ++ m_core_file_mappings.sections, ++ m_core_file_mappings.sections_end); ++ else ++ xfer_status = this->beneath ()->xfer_partial (object, annex, readbuf, ++ writebuf, offset, len, ++ xfered_len); + if (xfer_status == TARGET_XFER_OK) + return TARGET_XFER_OK; + +diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c +--- a/gdb/linux-tdep.c ++++ b/gdb/linux-tdep.c +@@ -1024,106 +1024,174 @@ linux_info_proc (struct gdbarch *gdbarch, const char *args, + } + } + +-/* Implement "info proc mappings" for a corefile. */ ++/* Implementation of `gdbarch_read_core_file_mappings', as defined in ++ gdbarch.h. ++ ++ This function reads the NT_FILE note (which BFD turns into the ++ section ".note.linuxcore.file"). The format of this note / section ++ is described as follows in the Linux kernel sources in ++ fs/binfmt_elf.c: ++ ++ long count -- how many files are mapped ++ long page_size -- units for file_ofs ++ array of [COUNT] elements of ++ long start ++ long end ++ long file_ofs ++ followed by COUNT filenames in ASCII: "FILE1" NUL "FILE2" NUL... ++ ++ CBFD is the BFD of the core file. ++ ++ PRE_LOOP_CB is the callback function to invoke prior to starting ++ the loop which processes individual entries. This callback will ++ only be executed after the note has been examined in enough ++ detail to verify that it's not malformed in some way. ++ ++ LOOP_CB is the callback function that will be executed once ++ for each mapping. */ + + static void +-linux_core_info_proc_mappings (struct gdbarch *gdbarch, const char *args) ++linux_read_core_file_mappings (struct gdbarch *gdbarch, ++ struct bfd *cbfd, ++ gdb::function_view ++ pre_loop_cb, ++ gdb::function_view ++ loop_cb) + { +- asection *section; +- ULONGEST count, page_size; +- unsigned char *descdata, *filenames, *descend; +- size_t note_size; +- unsigned int addr_size_bits, addr_size; +- struct gdbarch *core_gdbarch = gdbarch_from_bfd (core_bfd); +- /* We assume this for reading 64-bit core files. */ ++ /* Ensure that ULONGEST is big enough for reading 64-bit core files. */ + gdb_static_assert (sizeof (ULONGEST) >= 8); + +- section = bfd_get_section_by_name (core_bfd, ".note.linuxcore.file"); +- if (section == NULL) +- { +- warning (_("unable to find mappings in core file")); +- return; +- } ++ /* It's not required that the NT_FILE note exists, so return silently ++ if it's not found. Beyond this point though, we'll complain ++ if problems are found. */ ++ asection *section = bfd_get_section_by_name (cbfd, ".note.linuxcore.file"); ++ if (section == nullptr) ++ return; + +- addr_size_bits = gdbarch_addr_bit (core_gdbarch); +- addr_size = addr_size_bits / 8; +- note_size = bfd_section_size (section); ++ unsigned int addr_size_bits = gdbarch_addr_bit (gdbarch); ++ unsigned int addr_size = addr_size_bits / 8; ++ size_t note_size = bfd_section_size (section); + + if (note_size < 2 * addr_size) +- error (_("malformed core note - too short for header")); ++ { ++ warning (_("malformed core note - too short for header")); ++ return; ++ } + +- gdb::def_vector contents (note_size); ++ gdb::def_vector contents (note_size); + if (!bfd_get_section_contents (core_bfd, section, contents.data (), + 0, note_size)) +- error (_("could not get core note contents")); ++ { ++ warning (_("could not get core note contents")); ++ return; ++ } + +- descdata = contents.data (); +- descend = descdata + note_size; ++ gdb_byte *descdata = contents.data (); ++ char *descend = (char *) descdata + note_size; + + if (descdata[note_size - 1] != '\0') +- error (_("malformed note - does not end with \\0")); ++ { ++ warning (_("malformed note - does not end with \\0")); ++ return; ++ } + +- count = bfd_get (addr_size_bits, core_bfd, descdata); ++ ULONGEST count = bfd_get (addr_size_bits, core_bfd, descdata); + descdata += addr_size; + +- page_size = bfd_get (addr_size_bits, core_bfd, descdata); ++ ULONGEST page_size = bfd_get (addr_size_bits, core_bfd, descdata); + descdata += addr_size; + + if (note_size < 2 * addr_size + count * 3 * addr_size) +- error (_("malformed note - too short for supplied file count")); +- +- printf_filtered (_("Mapped address spaces:\n\n")); +- if (gdbarch_addr_bit (gdbarch) == 32) +- { +- printf_filtered ("\t%10s %10s %10s %10s %s\n", +- "Start Addr", +- " End Addr", +- " Size", " Offset", "objfile"); +- } +- else + { +- printf_filtered (" %18s %18s %10s %10s %s\n", +- "Start Addr", +- " End Addr", +- " Size", " Offset", "objfile"); ++ warning (_("malformed note - too short for supplied file count")); ++ return; + } + +- filenames = descdata + count * 3 * addr_size; +- while (--count > 0) ++ char *filenames = (char *) descdata + count * 3 * addr_size; ++ ++ /* Make sure that the correct number of filenames exist. Complain ++ if there aren't enough or are too many. */ ++ char *f = filenames; ++ for (int i = 0; i < count; i++) + { +- ULONGEST start, end, file_ofs; ++ if (f >= descend) ++ { ++ warning (_("malformed note - filename area is too small")); ++ return; ++ } ++ f += strnlen (f, descend - f) + 1; ++ } ++ /* Complain, but don't return early if the filename area is too big. */ ++ if (f != descend) ++ warning (_("malformed note - filename area is too big")); + +- if (filenames == descend) +- error (_("malformed note - filenames end too early")); ++ pre_loop_cb (count); + +- start = bfd_get (addr_size_bits, core_bfd, descdata); ++ for (int i = 0; i < count; i++) ++ { ++ ULONGEST start = bfd_get (addr_size_bits, core_bfd, descdata); + descdata += addr_size; +- end = bfd_get (addr_size_bits, core_bfd, descdata); ++ ULONGEST end = bfd_get (addr_size_bits, core_bfd, descdata); + descdata += addr_size; +- file_ofs = bfd_get (addr_size_bits, core_bfd, descdata); ++ ULONGEST file_ofs ++ = bfd_get (addr_size_bits, core_bfd, descdata) * page_size; + descdata += addr_size; ++ char * filename = filenames; ++ filenames += strlen ((char *) filenames) + 1; + +- file_ofs *= page_size; +- +- if (gdbarch_addr_bit (gdbarch) == 32) +- printf_filtered ("\t%10s %10s %10s %10s %s\n", +- paddress (gdbarch, start), +- paddress (gdbarch, end), +- hex_string (end - start), +- hex_string (file_ofs), +- filenames); +- else +- printf_filtered (" %18s %18s %10s %10s %s\n", +- paddress (gdbarch, start), +- paddress (gdbarch, end), +- hex_string (end - start), +- hex_string (file_ofs), +- filenames); +- +- filenames += 1 + strlen ((char *) filenames); ++ loop_cb (i, start, end, file_ofs, filename, nullptr); + } + } + ++/* Implement "info proc mappings" for a corefile. */ ++ ++static void ++linux_core_info_proc_mappings (struct gdbarch *gdbarch, const char *args) ++{ ++ linux_read_core_file_mappings (gdbarch, core_bfd, ++ [=] (ULONGEST count) ++ { ++ printf_filtered (_("Mapped address spaces:\n\n")); ++ if (gdbarch_addr_bit (gdbarch) == 32) ++ { ++ printf_filtered ("\t%10s %10s %10s %10s %s\n", ++ "Start Addr", ++ " End Addr", ++ " Size", " Offset", "objfile"); ++ } ++ else ++ { ++ printf_filtered (" %18s %18s %10s %10s %s\n", ++ "Start Addr", ++ " End Addr", ++ " Size", " Offset", "objfile"); ++ } ++ }, ++ [=] (int num, ULONGEST start, ULONGEST end, ULONGEST file_ofs, ++ const char *filename, const void *other) ++ { ++ if (gdbarch_addr_bit (gdbarch) == 32) ++ printf_filtered ("\t%10s %10s %10s %10s %s\n", ++ paddress (gdbarch, start), ++ paddress (gdbarch, end), ++ hex_string (end - start), ++ hex_string (file_ofs), ++ filename); ++ else ++ printf_filtered (" %18s %18s %10s %10s %s\n", ++ paddress (gdbarch, start), ++ paddress (gdbarch, end), ++ hex_string (end - start), ++ hex_string (file_ofs), ++ filename); ++ }); ++} ++ + /* Implement "info proc" for a corefile. */ + + static void +@@ -2471,6 +2539,7 @@ linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) + set_gdbarch_info_proc (gdbarch, linux_info_proc); + set_gdbarch_core_info_proc (gdbarch, linux_core_info_proc); + set_gdbarch_core_xfer_siginfo (gdbarch, linux_core_xfer_siginfo); ++ set_gdbarch_read_core_file_mappings (gdbarch, linux_read_core_file_mappings); + set_gdbarch_find_memory_regions (gdbarch, linux_find_memory_regions); + set_gdbarch_make_corefile_notes (gdbarch, linux_make_corefile_notes); + set_gdbarch_has_shared_address_space (gdbarch, diff --git a/SOURCES/gdb-rhbz1842691-corefile-mem-access-9of15.patch b/SOURCES/gdb-rhbz1842691-corefile-mem-access-9of15.patch new file mode 100644 index 0000000..5591b78 --- /dev/null +++ b/SOURCES/gdb-rhbz1842691-corefile-mem-access-9of15.patch @@ -0,0 +1,101 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Mon, 27 Jul 2020 19:21:54 -0400 +Subject: gdb-rhbz1842691-corefile-mem-access-9of15.patch + +;; Add test for accessing read-only mmapped data in a core file +;; Kevin Buettner, RH BZ 1842691 + + Author: Kevin Buettner + Date: Tue Jun 16 11:39:22 2020 -0700 + + Add test for accessing read-only mmapped data in a core file + + This test passes when run using a GDB with my corefile patches. When + run against a GDB without my patches, I see the following failures, + the first of which is due to the test added by this commit: + + FAIL: gdb.base/corefile.exp: accessing read-only mmapped data in core file ( + FAIL: gdb.base/corefile.exp: accessing anonymous, unwritten-to mmap data + + gdb/testsuite/ChangeLog: + + * gdb.base/corefile.exp: Add test "accessing read-only mmapped + data in core file". + * gdb.base/coremaker.c (buf2ro): New global. + (mmapdata): Add a read-only mmap mapping. + +diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp +--- a/gdb/testsuite/gdb.base/corefile.exp ++++ b/gdb/testsuite/gdb.base/corefile.exp +@@ -34,7 +34,10 @@ if {[build_executable $testfile.exp $testfile $srcfile debug] == -1} { + return -1 + } + +-set corefile [core_find $binfile {coremmap.data}] ++# Do not delete coremap.data when calling core_find. This file is ++# required for GDB to find mmap'd data in the "accessing read-only ++# mmapped data in core file" test. ++set corefile [core_find $binfile {}] + if {$corefile == ""} { + return 0 + } +@@ -175,6 +178,19 @@ gdb_test_multiple "x/8bd buf2" "$test" { + } + } + ++set test "accessing read-only mmapped data in core file" ++gdb_test_multiple "x/8bd buf2ro" "$test" { ++ -re ".*:.*0.*1.*2.*3.*4.*5.*6.*7.*$gdb_prompt $" { ++ pass "$test" ++ } ++ -re "0x\[f\]*:.*Cannot access memory at address 0x\[f\]*.*$gdb_prompt $" { ++ fail "$test (mapping failed at runtime)" ++ } ++ -re "0x.*:.*Cannot access memory at address 0x.*$gdb_prompt $" { ++ fail "$test (mapping address not found in core file)" ++ } ++} ++ + # Test ability to read anonymous and, more importantly, unwritten-to + # mmap'd data. + +diff --git a/gdb/testsuite/gdb.base/coremaker.c b/gdb/testsuite/gdb.base/coremaker.c +--- a/gdb/testsuite/gdb.base/coremaker.c ++++ b/gdb/testsuite/gdb.base/coremaker.c +@@ -38,6 +38,7 @@ + + char *buf1; + char *buf2; ++char *buf2ro; + char *buf3; + + int coremaker_data = 1; /* In Data section */ +@@ -90,16 +91,25 @@ mmapdata () + return; + } + ++ /* Map in another copy, read-only. We won't write to this copy so it ++ will likely not end up in the core file. */ ++ buf2ro = (char *) mmap (0, MAPSIZE, PROT_READ, MAP_PRIVATE, fd, 0); ++ if (buf2ro == (char *) -1) ++ { ++ perror ("mmap failed"); ++ return; ++ } ++ + /* Verify that the original data and the mapped data are identical. + If not, we'd rather fail now than when trying to access the mapped + data from the core file. */ + + for (j = 0; j < MAPSIZE; ++j) + { +- if (buf1[j] != buf2[j]) ++ if (buf1[j] != buf2[j] || buf1[j] != buf2ro[j]) + { + fprintf (stderr, "mapped data is incorrect"); +- buf2 = (char *) -1; ++ buf2 = buf2ro = (char *) -1; + return; + } + } diff --git a/SOURCES/gdb-rhbz1844458-use-fputX_unfiltered.patch b/SOURCES/gdb-rhbz1844458-use-fputX_unfiltered.patch index e3763fe..63b3fe0 100644 --- a/SOURCES/gdb-rhbz1844458-use-fputX_unfiltered.patch +++ b/SOURCES/gdb-rhbz1844458-use-fputX_unfiltered.patch @@ -6,10 +6,9 @@ Subject: gdb-rhbz1844458-use-fputX_unfiltered.patch ;; Fix fput?_unfiltered functions ;; RH BZ 1844458 (Sergio Durigan Junior and Tom Tromey) -From 9effb44ccbf50c16da66aaab5fd535fe17e38e32 Mon Sep 17 00:00:00 2001 -From: Sergio Durigan Junior -Date: Wed, 19 Feb 2020 16:40:48 -0500 -Subject: [PATCH] Make '{putchar,fputc}_unfiltered' use 'fputs_unfiltered' + From: Sergio Durigan Junior + Date: Wed, 19 Feb 2020 16:40:48 -0500 + Subject: [PATCH] Make '{putchar,fputc}_unfiltered' use 'fputs_unfiltered' There is currently a regression when using '{putchar,fputc}_unfiltered' with 'puts_unfiltered' which was diff --git a/SOURCES/gdb-rhbz1898252-loadable-section-outside-ELF-segments.patch b/SOURCES/gdb-rhbz1898252-loadable-section-outside-ELF-segments.patch new file mode 100644 index 0000000..b07d9d6 --- /dev/null +++ b/SOURCES/gdb-rhbz1898252-loadable-section-outside-ELF-segments.patch @@ -0,0 +1,67 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Mon, 16 Nov 2020 12:42:09 -0500 +Subject: gdb-rhbz1898252-loadable-section-outside-ELF-segments.patch + +;; Backport of "Exclude debuginfo files from 'outside of ELF segments' +;; warning" (Keith Seitz) + + Exclude debuginfo files from "outside of ELF segments" warning + + When GDB loads an ELF file, it will warn when a section is not located + in an ELF segment: + + $ ./gdb -q -iex "set build-id-verbose 0" --ex "b systemctl_main" -ex "r" -batch --args systemctl kexec + Breakpoint 1 at 0xc24d: file ../src/systemctl/systemctl.c, line 8752. + warning: Loadable section ".note.gnu.property" outside of ELF segments + in .gnu_debugdata for /lib64/libgcc_s.so.1 + [Thread debugging using libthread_db enabled] + Using host libthread_db library "/lib64/libthread_db.so.1". + warning: Loadable section ".note.gnu.property" outside of ELF segments + in .gnu_debugdata for /lib64/libcap.so.2 + warning: Loadable section ".note.gnu.property" outside of ELF segments + in .gnu_debugdata for /lib64/libacl.so.1 + warning: Loadable section ".note.gnu.property" outside of ELF segments + in .gnu_debugdata for /lib64/libcryptsetup.so.12 + warning: Loadable section ".note.gnu.property" outside of ELF segments + in .gnu_debugdata for /lib64/libgcrypt.so.20 + warning: Loadable section ".note.gnu.property" outside of ELF segments + in .gnu_debugdata for /lib64/libip4tc.so.2 + [snip] + This has feature has also been reported by various users, most notably + the Fedora-EOL'd bug 1553086. + + Mark Wielaard explains the issue quite nicely in + + https://sourceware.org/bugzilla/show_bug.cgi?id=24717#c2 + + The short of it is, the ELF program headers for debuginfo files are + not suited to this particular use case. Consequently, the warning + generated above really is useless and should be ignored. + + This patch follows the same heuristic that BFD itself uses. + + gdb/ChangeLog + 2020-11-13 Keith Seitz + + https://bugzilla.redhat.com/show_bug.cgi?id=1553086 + * elfread.c (elf_symfile_segments): Omit "Loadable section ... + outside of ELF segments" warning for debugin + +diff --git a/gdb/elfread.c b/gdb/elfread.c +--- a/gdb/elfread.c ++++ b/gdb/elfread.c +@@ -151,7 +151,12 @@ elf_symfile_segments (bfd *abfd) + RealView) use SHT_NOBITS for uninitialized data. Since it is + uninitialized, it doesn't need a program header. Such + binaries are not relocatable. */ +- if (bfd_section_size (sect) > 0 && j == num_segments ++ ++ /* Exclude debuginfo files from this warning, too, since those ++ are often not strictly compliant with the standard. See, e.g., ++ ld/24717 for more discussion. */ ++ if (!is_debuginfo_file (abfd) ++ && bfd_section_size (sect) > 0 && j == num_segments + && (bfd_section_flags (sect) & SEC_LOAD) != 0) + warning (_("Loadable section \"%s\" outside of ELF segments"), + bfd_section_name (sect)); diff --git a/SOURCES/gdb-rhbz1903375-s390x-store-on-condition.patch b/SOURCES/gdb-rhbz1903375-s390x-store-on-condition.patch new file mode 100644 index 0000000..7372834 --- /dev/null +++ b/SOURCES/gdb-rhbz1903375-s390x-store-on-condition.patch @@ -0,0 +1,64 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Andreas Arnez +Date: Thu, 19 Nov 2020 19:10:58 +0100 +Subject: gdb-rhbz1903375-s390x-store-on-condition.patch + +;; Backport of "Correct recording of 'store on condition' insns" +;; Andreas Arnaz (RH BZ 1903374) + +gdb/s390: Correct recording of "store on condition" insns + +The "store on condition" instructions STOC, STOCG, and STOCFH are recorded +as if their instruction formats resembled that of STG. This is wrong, +usually resulting in "failed to record execution log" errors when trying +to record code with any of these instructions. + +This patch fixes the recording of these instructions. + +gdb/ChangeLog: + + PR tdep/26916 + * s390-tdep.c (s390_process_record): Fix recording of STOC, STOCG, + and STOCFH. + +diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c +--- a/gdb/s390-tdep.c ++++ b/gdb/s390-tdep.c +@@ -5380,7 +5380,6 @@ ex: + case 0xe325: /* NTSTG - nontransactional store */ + case 0xe326: /* CVDY - convert to decimal */ + case 0xe32f: /* STRVG - store reversed */ +- case 0xebe3: /* STOCG - store on condition */ + case 0xed67: /* STDY - store */ + oaddr = s390_record_calc_disp (gdbarch, regcache, inib[3], insn[1], ibyte[4]); + if (record_full_arch_list_add_mem (oaddr, 8)) +@@ -5409,8 +5408,6 @@ ex: + case 0xe33e: /* STRV - store reversed */ + case 0xe350: /* STY - store */ + case 0xe3cb: /* STFH - store high */ +- case 0xebe1: /* STOCFH - store high on condition */ +- case 0xebf3: /* STOC - store on condition */ + case 0xed66: /* STEY - store */ + oaddr = s390_record_calc_disp (gdbarch, regcache, inib[3], insn[1], ibyte[4]); + if (record_full_arch_list_add_mem (oaddr, 4)) +@@ -6123,6 +6120,20 @@ ex: + + /* 0xeb9c-0xebbf undefined */ + /* 0xebc1-0xebdb undefined */ ++ ++ case 0xebe1: /* STOCFH - store high on condition */ ++ case 0xebf3: /* STOC - store on condition */ ++ oaddr = s390_record_calc_disp (gdbarch, regcache, 0, insn[1], ibyte[4]); ++ if (record_full_arch_list_add_mem (oaddr, 4)) ++ return -1; ++ break; ++ ++ case 0xebe3: /* STOCG - store on condition */ ++ oaddr = s390_record_calc_disp (gdbarch, regcache, 0, insn[1], ibyte[4]); ++ if (record_full_arch_list_add_mem (oaddr, 8)) ++ return -1; ++ break; ++ + /* 0xebe5 undefined */ + /* 0xebe9 undefined */ + /* 0xebeb-0xebf1 undefined */ diff --git a/SOURCES/gdb-rhbz1905702-DWARF-data_location.patch b/SOURCES/gdb-rhbz1905702-DWARF-data_location.patch new file mode 100644 index 0000000..1b24f46 --- /dev/null +++ b/SOURCES/gdb-rhbz1905702-DWARF-data_location.patch @@ -0,0 +1,565 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Wed, 9 Dec 2020 16:47:07 -0500 +Subject: gdb-rhbz1905702-DWARF-data_location.patch + +;; Backport "fortran dynamic type related fixes" +;; Andrew Burgess (RH BZ 1905702) + +commit e79eb02f2f09baecffb144bac6804f975065466f + +gdb/fortran: resolve dynamic types when readjusting after an indirection + +After dereferencing a pointer (in value_ind) or following a +reference (in coerce_ref) we call readjust_indirect_value_type to +"fixup" the type of the resulting value object. + +This fixup handles cases relating to the type of the resulting object +being different (a sub-class) of the original pointers target type. + +If we encounter a pointer to a dynamic type then after dereferencing a +pointer (in value_ind) the type of the object created will have had +its dynamic type resolved. However, in readjust_indirect_value_type, +we use the target type of the original pointer to "fixup" the type of +the resulting value. In this case, the target type will be a dynamic +type, so the resulting value object, once again has a dynamic type. + +This then triggers an assertion later within GDB. + +The solution I propose here is that we call resolve_dynamic_type on +the pointer's target type (within readjust_indirect_value_type) so +that the resulting value is not converted back to a dynamic type. + +The test case is based on the original test in the bug report. + +gdb/ChangeLog: + + PR fortran/23051 + PR fortran/26139 + * valops.c (value_ind): Pass address to + readjust_indirect_value_type. + * value.c (readjust_indirect_value_type): Make parameter + non-const, and add extra address parameter. Resolve original type + before using it. + * value.h (readjust_indirect_value_type): Update function + signature and comment. + +gdb/testsuite/ChangeLog: + + PR fortran/23051 + PR fortran/26139 + * gdb.fortran/class-allocatable-array.exp: New file. + * gdb.fortran/class-allocatable-array.f90: New file. + * gdb.fortran/pointer-to-pointer.exp: New file. + * gdb.fortran/pointer-to-pointer.f90: New file. + +diff --git a/gdb/testsuite/gdb.dwarf2/graalvm-data-loc2.c b/gdb/testsuite/gdb.dwarf2/graalvm-data-loc2.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.dwarf2/graalvm-data-loc2.c +@@ -0,0 +1,63 @@ ++/* Copyright 2014-2020 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++/* This C file simulates the implementation of object pointers in ++ GraalVM Java native images where the object data is not addressed ++ directly. It serves as a regression test for a bug where printing ++ of such redirected data structures suffers from a gdb exception. ++ ++ Debugging information on how to decode an object pointer to ++ identify the address of the underlying data will be generated ++ separately by the testcase using that file. */ ++ ++#include ++#include ++ ++struct Object { ++ struct Object *next; ++ int val; ++}; ++ ++struct Object *testOop; ++ ++extern int debugMe() { ++ return 0; ++} ++ ++struct Object *newObject() { ++ char *bytes = malloc(sizeof(struct Object)); ++ return (struct Object *)bytes; ++} ++ ++int ++main (void) ++{ ++ struct Object *obj1 = newObject(); ++ struct Object *obj2 = newObject(); ++ struct Object *obj3 = newObject(); ++ obj1->val = 0; ++ obj2->val = 1; ++ obj3->val = 2; ++ ++ obj1->next = obj2; ++ obj2->next = obj3; ++ obj3->next = obj1; ++ ++ testOop = obj1; ++ ++ return debugMe(); ++} +diff --git a/gdb/testsuite/gdb.dwarf2/graalvm-data-loc2.exp b/gdb/testsuite/gdb.dwarf2/graalvm-data-loc2.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.dwarf2/graalvm-data-loc2.exp +@@ -0,0 +1,122 @@ ++# Copyright 2014-2020 Free Software Foundation, Inc. ++ ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++load_lib dwarf.exp ++ ++# This test can only be run on targets which support DWARF-2 and use gas. ++if {![dwarf2_support]} { ++ return 0 ++} ++ ++standard_testfile .c -dw.S ++ ++if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { ++ return -1 ++} ++ ++# Make some DWARF for the test. ++set asm_file [standard_output_file $srcfile2] ++Dwarf::assemble $asm_file { ++ ++ cu {} { ++ DW_TAG_compile_unit { ++ {DW_AT_language @DW_LANG_C99} ++ {DW_AT_name data-loc2.c} ++ {DW_AT_comp_dir /tmp} ++ } { ++ declare_labels integer_label struct_label pointer_label ++ ++ integer_label: DW_TAG_base_type { ++ {DW_AT_byte_size 4 DW_FORM_sdata} ++ {DW_AT_encoding @DW_ATE_signed} ++ {DW_AT_name integer} ++ } ++ ++ struct_label: DW_TAG_structure_type { ++ {DW_AT_name "Object"} ++ {DW_AT_byte_size 20 DW_FORM_sdata} ++ {DW_AT_data_location { ++ DW_OP_push_object_address ++ } SPECIAL_expr} ++ } { ++ member { ++ {name next} ++ {type :$pointer_label} ++ {data_member_location 0 data1} ++ } ++ member { ++ {name val} ++ {type :$integer_label} ++ {data_member_location 8 data1} ++ } ++ } ++ pointer_label: DW_TAG_pointer_type { ++ {DW_AT_byte_size 4 DW_FORM_sdata} ++ {DW_AT_type :$struct_label} ++ } ++ DW_TAG_variable { ++ {DW_AT_name testOop} ++ {DW_AT_type :$pointer_label} ++ {DW_AT_location { ++ DW_OP_addr [gdb_target_symbol testOop] ++ } SPECIAL_expr} ++ {external 1 flag} ++ } ++ } ++ } ++} ++ ++# Now that we've generated the DWARF debugging info, rebuild our ++# program using our debug info instead of the info generated by ++# the compiler. ++ ++if { [prepare_for_testing "failed to prepare" ${testfile} \ ++ [list $srcfile $asm_file] {nodebug}] } { ++ return -1 ++} ++ ++if ![runto_main] { ++ return -1 ++} ++ ++# ensure the object network is set up as expected and check that ++# printing of structs which employ the data_location does not ++# fail with a gdb exception ++ ++gdb_test "break debugMe" \ ++ "Breakpoint .*" \ ++ "set breakpoint at debugMe" ++ ++gdb_continue_to_breakpoint "continue to debugMe" ++ ++gdb_test "print testOop->val" \ ++ ".* = 0" ++ ++gdb_test "print testOop->next->val" \ ++ ".* = 1" ++ ++gdb_test "print testOop->next->next->val" \ ++ ".* = 2" ++ ++gdb_test "print *testOop" \ ++ ".* = {next = .*, val = 0}" \ ++ "print contents of struct" ++ ++gdb_test "print *testOop->next" \ ++ ".* = {next = .*, val = 1}" \ ++ "print contents of an indirect struct" ++ ++gdb_test "print *testOop->next->next" \ ++ ".* = {next = .*, val = 2}" \ ++ "print contents of a double indirect struct" +diff --git a/gdb/testsuite/gdb.fortran/class-allocatable-array.exp b/gdb/testsuite/gdb.fortran/class-allocatable-array.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.fortran/class-allocatable-array.exp +@@ -0,0 +1,43 @@ ++# Copyright 2020 Free Software Foundation, Inc. ++ ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++# Test that GDB can print an allocatable array that is a data field ++# within a class like type. ++ ++if {[skip_fortran_tests]} { return -1 } ++ ++standard_testfile ".f90" ++load_lib fortran.exp ++ ++if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ ++ {debug f90}]} { ++ return -1 ++} ++ ++if {![runto MAIN__]} { ++ untested main"could not run to main" ++ return -1 ++} ++ ++gdb_breakpoint [gdb_get_line_number "Break Here"] ++gdb_continue_to_breakpoint "Break Here" ++ ++# If this first test fails then the Fortran compiler being used uses ++# different names, or maybe a completely different approach, for ++# representing class like structures. The following tests are ++# cetainly going to fail. ++gdb_test "print this" " = \\( _data = \[^\r\n\]+, _vptr = \[^\r\n\]+\\)" ++gdb_test "print this%_data" " = \\(PTR TO -> \\( Type test_type \\)\\) \[^\r\n\]+" ++gdb_test "print this%_data%b" " = \\(\\( 1, 2, 3\\) \\( 4, 5, 6\\) \\)" +diff --git a/gdb/testsuite/gdb.fortran/class-allocatable-array.f90 b/gdb/testsuite/gdb.fortran/class-allocatable-array.f90 +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.fortran/class-allocatable-array.f90 +@@ -0,0 +1,54 @@ ++! Copyright 2020 Free Software Foundation, Inc. ++! ++! This program is free software; you can redistribute it and/or modify ++! it under the terms of the GNU General Public License as published by ++! the Free Software Foundation; either version 3 of the License, or ++! (at your option) any later version. ++! ++! This program is distributed in the hope that it will be useful, ++! but WITHOUT ANY WARRANTY; without even the implied warranty of ++! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++! GNU General Public License for more details. ++! ++! You should have received a copy of the GNU General Public License ++! along with this program. If not, see . ++ ++module test_module ++ type test_type ++ integer a ++ real, allocatable :: b (:, :) ++ contains ++ procedure :: test_proc ++ end type test_type ++ ++contains ++ ++ subroutine test_proc (this) ++ class(test_type), intent (inout) :: this ++ allocate (this%b (3, 2)) ++ call fill_array_2d (this%b) ++ print *, "" ! Break Here ++ contains ++ ! Helper subroutine to fill 2-dimensional array with unique ++ ! values. ++ subroutine fill_array_2d (array) ++ real, dimension (:,:) :: array ++ real :: counter ++ ++ counter = 1.0 ++ do i=LBOUND (array, 2), UBOUND (array, 2), 1 ++ do j=LBOUND (array, 1), UBOUND (array, 1), 1 ++ array (j,i) = counter ++ counter = counter + 1 ++ end do ++ end do ++ end subroutine fill_array_2d ++ end subroutine test_proc ++end module ++ ++program test ++ use test_module ++ implicit none ++ type(test_type) :: t ++ call t%test_proc () ++end program test +diff --git a/gdb/testsuite/gdb.fortran/pointer-to-pointer.exp b/gdb/testsuite/gdb.fortran/pointer-to-pointer.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.fortran/pointer-to-pointer.exp +@@ -0,0 +1,46 @@ ++# Copyright 2020 Free Software Foundation, Inc. ++ ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++# Test for GDB printing a pointer to a type containing a buffer. ++ ++if {[skip_fortran_tests]} { return -1 } ++ ++standard_testfile ".f90" ++load_lib fortran.exp ++ ++if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ ++ {debug f90}]} { ++ return -1 ++} ++ ++if {![runto MAIN__]} { ++ untested "could not run to main" ++ return -1 ++} ++ ++gdb_breakpoint [gdb_get_line_number "Break Here"] ++gdb_continue_to_breakpoint "Break Here" ++ ++gdb_test "print *buffer" \ ++ " = \\( alpha = \\(1\\.5, 2\\.5, 3\\.5, 4\\.5, 5\\.5\\) \\)" ++ ++set l_buffer_type [multi_line \ ++ "Type l_buffer" \ ++ " real\\(kind=4\\) :: alpha\\(.\\)" \ ++ "End Type l_buffer" ] ++ ++gdb_test "ptype buffer" "type = PTR TO -> \\( ${l_buffer_type} \\)" ++gdb_test "ptype *buffer" "type = ${l_buffer_type}" ++gdb_test "ptype buffer%alpha" "type = real\\(kind=4\\) \\(5\\)" +diff --git a/gdb/testsuite/gdb.fortran/pointer-to-pointer.f90 b/gdb/testsuite/gdb.fortran/pointer-to-pointer.f90 +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.fortran/pointer-to-pointer.f90 +@@ -0,0 +1,34 @@ ++! Copyright 2020 Free Software Foundation, Inc. ++! ++! This program is free software; you can redistribute it and/or modify ++! it under the terms of the GNU General Public License as published by ++! the Free Software Foundation; either version 3 of the License, or ++! (at your option) any later version. ++! ++! This program is distributed in the hope that it will be useful, ++! but WITHOUT ANY WARRANTY; without even the implied warranty of ++! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++! GNU General Public License for more details. ++! ++! You should have received a copy of the GNU General Public License ++! along with this program. If not, see . ++ ++program allocate_array ++ ++ type l_buffer ++ real, dimension(:), pointer :: alpha ++ end type l_buffer ++ type(l_buffer), pointer :: buffer ++ ++ allocate (buffer) ++ allocate (buffer%alpha (5)) ++ ++ buffer%alpha (1) = 1.5 ++ buffer%alpha (2) = 2.5 ++ buffer%alpha (3) = 3.5 ++ buffer%alpha (4) = 4.5 ++ buffer%alpha (5) = 5.5 ++ ++ print *, buffer%alpha ! Break Here. ++ ++end program allocate_array +diff --git a/gdb/valops.c b/gdb/valops.c +--- a/gdb/valops.c ++++ b/gdb/valops.c +@@ -1553,38 +1553,28 @@ value_ind (struct value *arg1) + if (TYPE_CODE (base_type) == TYPE_CODE_PTR) + { + struct type *enc_type; +- CORE_ADDR addr; +- +- if (type_not_associated (base_type)) +- error (_("Attempt to take contents of a not associated pointer.")); +- +- if (NULL != TYPE_DATA_LOCATION (TYPE_TARGET_TYPE (base_type))) +- addr = value_address (arg1); +- else +- addr = value_as_address (arg1); +- +- if (addr != 0) +- TYPE_TARGET_TYPE (base_type) = +- resolve_dynamic_type (TYPE_TARGET_TYPE (base_type), NULL, addr); + + /* We may be pointing to something embedded in a larger object. + Get the real type of the enclosing object. */ + enc_type = check_typedef (value_enclosing_type (arg1)); + enc_type = TYPE_TARGET_TYPE (enc_type); + ++ CORE_ADDR base_addr; + if (TYPE_CODE (check_typedef (enc_type)) == TYPE_CODE_FUNC + || TYPE_CODE (check_typedef (enc_type)) == TYPE_CODE_METHOD) + /* For functions, go through find_function_addr, which knows + how to handle function descriptors. */ +- arg2 = value_at_lazy (enc_type, +- find_function_addr (arg1, NULL)); ++ base_addr = find_function_addr (arg1, NULL); + else +- /* Retrieve the enclosing object pointed to. */ +- arg2 = value_at_lazy (enc_type, +- (addr - value_pointed_to_offset (arg1))); +- ++ { ++ /* Retrieve the enclosing object pointed to. */ ++ base_addr = (value_as_address (arg1) ++ - value_pointed_to_offset (arg1)); ++ } ++ arg2 = value_at_lazy (enc_type, base_addr); + enc_type = value_type (arg2); +- return readjust_indirect_value_type (arg2, enc_type, base_type, arg1); ++ return readjust_indirect_value_type (arg2, enc_type, base_type, ++ arg1, base_addr); + } + + error (_("Attempt to take contents of a non-pointer value.")); +diff --git a/gdb/value.c b/gdb/value.c +--- a/gdb/value.c ++++ b/gdb/value.c +@@ -3630,10 +3630,19 @@ coerce_ref_if_computed (const struct value *arg) + struct value * + readjust_indirect_value_type (struct value *value, struct type *enc_type, + const struct type *original_type, +- const struct value *original_value) ++ struct value *original_value, ++ CORE_ADDR original_value_address) + { ++ gdb_assert (TYPE_CODE (original_type) == TYPE_CODE_PTR ++ || TYPE_IS_REFERENCE (original_type)); ++ ++ struct type *original_target_type = TYPE_TARGET_TYPE (original_type); ++ struct type *resolved_original_target_type ++ = resolve_dynamic_type (original_target_type, NULL, ++ original_value_address); ++ + /* Re-adjust type. */ +- deprecated_set_value_type (value, TYPE_TARGET_TYPE (original_type)); ++ deprecated_set_value_type (value, resolved_original_target_type); + + /* Add embedding info. */ + set_value_enclosing_type (value, enc_type); +@@ -3660,12 +3669,11 @@ coerce_ref (struct value *arg) + enc_type = check_typedef (value_enclosing_type (arg)); + enc_type = TYPE_TARGET_TYPE (enc_type); + +- retval = value_at_lazy (enc_type, +- unpack_pointer (value_type (arg), +- value_contents (arg))); ++ CORE_ADDR addr = unpack_pointer (value_type (arg), value_contents (arg)); ++ retval = value_at_lazy (enc_type, addr); + enc_type = value_type (retval); +- return readjust_indirect_value_type (retval, enc_type, +- value_type_arg_tmp, arg); ++ return readjust_indirect_value_type (retval, enc_type, value_type_arg_tmp, ++ arg, addr); + } + + struct value * +diff --git a/gdb/value.h b/gdb/value.h +--- a/gdb/value.h ++++ b/gdb/value.h +@@ -488,7 +488,9 @@ extern struct value *coerce_ref_if_computed (const struct value *arg); + + /* Setup a new value type and enclosing value type for dereferenced value VALUE. + ENC_TYPE is the new enclosing type that should be set. ORIGINAL_TYPE and +- ORIGINAL_VAL are the type and value of the original reference or pointer. ++ ORIGINAL_VAL are the type and value of the original reference or ++ pointer. ORIGINAL_VALUE_ADDRESS is the address within VALUE, that is ++ the address that was dereferenced. + + Note, that VALUE is modified by this function. + +@@ -497,7 +499,8 @@ extern struct value *coerce_ref_if_computed (const struct value *arg); + extern struct value * readjust_indirect_value_type (struct value *value, + struct type *enc_type, + const struct type *original_type, +- const struct value *original_val); ++ struct value *original_val, ++ CORE_ADDR original_value_address); + + /* Convert a REF to the object referenced. */ + diff --git a/SPECS/gdb.spec b/SPECS/gdb.spec index 4aa3055..36ecacc 100644 --- a/SPECS/gdb.spec +++ b/SPECS/gdb.spec @@ -34,7 +34,7 @@ Version: 9.2 # The release always contains a leading reserved number, start it at 1. # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing. -Release: 2%{?dist} +Release: 4%{?dist} License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and LGPLv3+ and BSD and Public Domain and GFDL # Do not provide URL for snapshots as the file lasts there only for 2 days. @@ -1167,6 +1167,20 @@ fi %endif %changelog +* Fri Dec 11 2020 Keith Seitz - 9.2-4 +- Backport "Correct recording of 'store on condition' insns" + (Andreas Arnaz, RH BZ 1903375) +- Backport "Fortran dynamic type related fixes" + (Andrew Burgess, RH BZ 1905702) + +* Mon Nov 16 2020 Keith Seitz - 9.2-3 +- Fix missing debuginfo messages. (Keith Seitz, RH BZ 1894703) +- Add debuginfod.m4 patch to use pkg-config. +- Backport "Corefile memory access problems" patches. + (Kevin Buettner, RH BZ 1886602) +- Backport "Exclude debuginfo files from 'outside ELF segments' warning". + (Keith Seitz, RH BZ 1898252) + * Tue Jun 9 2020 Keith Seitz - 9.2-2 - Backport debuginfod support.