diff options
| author | CoprDistGit <infra@openeuler.org> | 2024-08-06 05:48:09 +0000 | 
|---|---|---|
| committer | CoprDistGit <infra@openeuler.org> | 2024-08-06 05:48:09 +0000 | 
| commit | ab322c77aab87050c6ca0ce58e18f31e269e519b (patch) | |
| tree | 7ff9c6a18efd867f35cb6f8fb08893c6b655376f | |
| parent | 19677e130f0cd283f7884cc4b6b3d52f8812dae5 (diff) | |
automatic import of gdbopeneuler24.03_LTS
53 files changed, 11384 insertions, 0 deletions
@@ -0,0 +1 @@ +/gdb-14.1.tar.xz diff --git a/0001-set-entry-point-when-text-segment-is-missing.patch b/0001-set-entry-point-when-text-segment-is-missing.patch new file mode 100644 index 0000000..aa6ef9a --- /dev/null +++ b/0001-set-entry-point-when-text-segment-is-missing.patch @@ -0,0 +1,30 @@ +From 6490b5d2ec9c575757308c860c48b75c8e824bfe Mon Sep 17 00:00:00 2001 +From: cenhuilin <cenhuilin@kylinos.cn> +Date: Fri, 8 Jul 2022 03:22:14 +0000 +Subject: [PATCH] gdb set entry point when text segment is missing + +--- + gdb/symfile.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/gdb/symfile.c b/gdb/symfile.c +index 0eb48d0..9137183 100644 +--- a/gdb/symfile.c ++++ b/gdb/symfile.c +@@ -863,7 +863,12 @@ init_entry_point_info (struct objfile *objfile) + 	} +  +       if (!found) +-	ei->the_bfd_section_index = SECT_OFF_TEXT (objfile); ++	{ ++	  if (objfile->sect_index_text == -1) ++	    ei->entry_point_p = 0; ++	  else ++	    ei->the_bfd_section_index = objfile->sect_index_text; ++	} +     } + } +  +--  +2.33.0 + diff --git a/gdb-6.3-attach-see-vdso-test.patch b/gdb-6.3-attach-see-vdso-test.patch new file mode 100644 index 0000000..daba42f --- /dev/null +++ b/gdb-6.3-attach-see-vdso-test.patch @@ -0,0 +1,120 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-6.3-attach-see-vdso-test.patch + +;; Test kernel VDSO decoding while attaching to an i386 process. +;;=fedoratest + +diff --git a/gdb/testsuite/gdb.base/attach-see-vdso.c b/gdb/testsuite/gdb.base/attach-see-vdso.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/attach-see-vdso.c +@@ -0,0 +1,25 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++   Copyright 2007 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 2 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, write to the Free Software ++   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ++ ++#include <unistd.h> ++ ++int main () ++{ ++  pause (); ++  return 1; ++} +diff --git a/gdb/testsuite/gdb.base/attach-see-vdso.exp b/gdb/testsuite/gdb.base/attach-see-vdso.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/attach-see-vdso.exp +@@ -0,0 +1,77 @@ ++# Copyright 2007 ++ ++# 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 2 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, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ ++# This file was created by Jan Kratochvil <jan.kratochvil@redhat.com>. ++ ++# This test only works on Linux ++if { ![istarget "*-*-linux-gnu*"] } { ++    return 0 ++} ++ ++if {[use_gdb_stub]} { ++    untested "skipping test because of use_gdb_stub" ++    return -1 ++} ++ ++set testfile "attach-see-vdso" ++set srcfile  ${testfile}.c ++set binfile  [standard_output_file ${testfile}] ++set escapedbinfile  [string_to_regexp [standard_output_file ${testfile}]] ++ ++# The kernel VDSO is used for the syscalls returns only on i386 (not x86_64). ++# ++if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-m32}] != "" } { ++    gdb_suppress_entire_file "Testcase nonthraded compile failed, so all tests in this file will automatically fail." ++} ++ ++if [get_compiler_info ${binfile}] { ++    return -1 ++} ++ ++# Start the program running and then wait for a bit, to be sure ++# that it can be attached to. ++ ++set testpid [eval exec $binfile &] ++ ++# Avoid some race: ++sleep 2 ++ ++# Start with clean gdb ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++# Never call: gdb_load ${binfile} ++# as the former problem would not reproduce otherwise. ++ ++set test "attach" ++gdb_test_multiple "attach $testpid" "$test" { ++    -re "Attaching to process $testpid\r?\n.*$gdb_prompt $" { ++	pass "$test" ++    } ++} ++ ++gdb_test "bt" "#0 *0x\[0-9a-f\]* in \[^?\].*" "backtrace decodes VDSO" ++ ++# Exit and detach the process. ++ ++gdb_exit ++ ++# Make sure we don't leave a process around to confuse ++# the next test run (and prevent the compile by keeping ++# the text file busy), in case the "set should_exit" didn't ++# work. ++ ++remote_exec build "kill -9 ${testpid}" diff --git a/gdb-6.3-gstack-20050411.patch b/gdb-6.3-gstack-20050411.patch new file mode 100644 index 0000000..01e8ffa --- /dev/null +++ b/gdb-6.3-gstack-20050411.patch @@ -0,0 +1,258 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Andrew Cagney <cagney@gnu.org> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-6.3-gstack-20050411.patch + +;; Add a wrapper script to GDB that implements pstack using the +;; --readnever option. +;;=push + +2004-11-23  Andrew Cagney  <cagney@redhat.com> + +	* Makefile.in (uninstall-gstack, install-gstack): New rules, add +	to install and uninstall. +	* gstack.sh, gstack.1: New files. + +diff --git a/gdb/Makefile.in b/gdb/Makefile.in +--- a/gdb/Makefile.in ++++ b/gdb/Makefile.in +@@ -2035,7 +2035,7 @@ info install-info clean-info dvi pdf install-pdf html install-html: force + install: all + 	@$(MAKE) $(FLAGS_TO_PASS) install-only +  +-install-only: $(CONFIG_INSTALL) ++install-only: install-gstack $(CONFIG_INSTALL) + 	transformed_name=`t='$(program_transform_name)'; \ + 			  echo gdb | sed -e "$$t"` ; \ + 		if test "x$$transformed_name" = x; then \ +@@ -2085,7 +2085,25 @@ install-guile: + install-python: + 	$(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(GDB_DATADIR)/python/gdb +  +-uninstall: force $(CONFIG_UNINSTALL) ++GSTACK=gstack ++.PHONY: install-gstack ++install-gstack: ++	transformed_name=`t='$(program_transform_name)'; \ ++			  echo $(GSTACK) | sed -e "$$t"` ; \ ++		if test "x$$transformed_name" = x; then \ ++		  transformed_name=$(GSTACK) ; \ ++		else \ ++		  true ; \ ++		fi ; \ ++		$(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(bindir) ; \ ++		$(INSTALL_PROGRAM) $(srcdir)/$(GSTACK).sh \ ++			$(DESTDIR)$(bindir)/$$transformed_name$(EXEEXT) ; \ ++		: $(SHELL) $(srcdir)/../mkinstalldirs \ ++			$(DESTDIR)$(man1dir) ; \ ++		: $(INSTALL_DATA) $(srcdir)/gstack.1 \ ++			$(DESTDIR)$(man1dir)/$$transformed_name.1 ++ ++uninstall: force uninstall-gstack $(CONFIG_UNINSTALL) + 	transformed_name=`t='$(program_transform_name)'; \ + 			  echo gdb | sed -e $$t` ; \ + 		if test "x$$transformed_name" = x; then \ +@@ -2116,6 +2134,18 @@ uninstall: force $(CONFIG_UNINSTALL) + 	rm -f $(DESTDIR)$(bindir)/$$transformed_name + 	@$(MAKE) DO=uninstall "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) subdir_do +  ++.PHONY: uninstall-gstack ++uninstall-gstack: ++	transformed_name=`t='$(program_transform_name)'; \ ++			  echo $(GSTACK) | sed -e $$t` ; \ ++		if test "x$$transformed_name" = x; then \ ++		  transformed_name=$(GSTACK) ; \ ++		else \ ++		  true ; \ ++		fi ; \ ++		rm -f $(DESTDIR)$(bindir)/$$transformed_name$(EXEEXT) \ ++		      $(DESTDIR)$(man1dir)/$$transformed_name.1 ++ + # The C++ name parser can be built standalone for testing. + test-cp-name-parser.o: cp-name-parser.c + 	$(COMPILE) -DTEST_CPNAMES cp-name-parser.c +diff --git a/gdb/gstack.sh b/gdb/gstack.sh +new file mode 100644 +--- /dev/null ++++ b/gdb/gstack.sh +@@ -0,0 +1,43 @@ ++#!/bin/sh ++ ++if test $# -ne 1; then ++    echo "Usage: `basename $0 .sh` <process-id>" 1>&2 ++    exit 1 ++fi ++ ++if test ! -r /proc/$1; then ++    echo "Process $1 not found." 1>&2 ++    exit 1 ++fi ++ ++# GDB doesn't allow "thread apply all bt" when the process isn't ++# threaded; need to peek at the process to determine if that or the ++# simpler "bt" should be used. ++ ++backtrace="bt" ++if test -d /proc/$1/task ; then ++    # Newer kernel; has a task/ directory. ++    if test `/bin/ls /proc/$1/task | /usr/bin/wc -l` -gt 1 2>/dev/null ; then ++	backtrace="thread apply all bt" ++    fi ++elif test -f /proc/$1/maps ; then ++    # Older kernel; go by it loading libpthread. ++    if /bin/grep -e libpthread /proc/$1/maps > /dev/null 2>&1 ; then ++	backtrace="thread apply all bt" ++    fi ++fi ++ ++GDB=${GDB:-gdb} ++ ++# Run GDB, strip out unwanted noise. ++# --readnever is no longer used since .gdb_index is now in use. ++$GDB --quiet -nx $GDBARGS /proc/$1/exe $1 <<EOF 2>&1 | ++set width 0 ++set height 0 ++set pagination no ++$backtrace ++EOF ++/bin/sed -n \ ++    -e 's/^\((gdb) \)*//' \ ++    -e '/^#/p' \ ++    -e '/^Thread/p' +diff --git a/gdb/testsuite/gdb.base/gstack.c b/gdb/testsuite/gdb.base/gstack.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/gstack.c +@@ -0,0 +1,43 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++   Copyright 2005, 2007, 2008, 2009 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 <http://www.gnu.org/licenses/>.  */ ++ ++#include <stdio.h> ++#include <unistd.h> ++#include <string.h> ++ ++void ++func (void) ++{ ++  const char msg[] = "looping\n"; ++ ++  /* Use the most simple notification not to get caught by attach on exiting ++     the function.  */ ++  write (1, msg, strlen (msg)); ++ ++  for (;;); ++} ++ ++int ++main (void) ++{ ++  alarm (60); ++  nice (100); ++ ++  func (); ++ ++  return 0; ++} +diff --git a/gdb/testsuite/gdb.base/gstack.exp b/gdb/testsuite/gdb.base/gstack.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/gstack.exp +@@ -0,0 +1,84 @@ ++# Copyright (C) 2012 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 <http://www.gnu.org/licenses/>. ++ ++set testfile gstack ++set executable ${testfile} ++set binfile [standard_output_file $executable] ++if {[build_executable ${testfile} ${executable} "" {debug}] == -1} { ++    return -1 ++} ++ ++set test "spawn inferior" ++set command "${binfile}" ++set res [remote_spawn host $command]; ++if { $res < 0 || $res == "" } { ++    perror "Spawning $command failed." ++    fail $test ++    return ++} ++ ++# The spawn id of the test inferior. ++set test_spawn_id $res ++ ++set use_gdb_stub 1 ++set pid [exp_pid -i $res] ++gdb_expect { ++    -re "looping\r\n" { ++	pass $test ++    } ++    eof { ++	fail "$test (eof)" ++	return ++    } ++    timeout { ++	fail "$test (timeout)" ++	return ++    } ++} ++ ++# Testcase uses the most simple notification not to get caught by attach on ++# exiting the function.  Still we could retry the gstack command if we fail. ++ ++set test "spawn gstack" ++set command "sh -c GDB=$GDB\\ GDBARGS=-data-directory\\\\\\ $BUILD_DATA_DIRECTORY\\ sh\\ ${srcdir}/../gstack.sh\\ $pid\\;echo\\ GSTACK-END" ++set res [remote_spawn host $command]; ++if { $res < 0 || $res == "" } { ++    perror "Spawning $command failed." ++    fail $test ++} ++ ++set gdb_spawn_id $res ++ ++gdb_test_multiple "" $test { ++    -re "^#0 +(0x\[0-9a-f\]+ in )?\\.?func \\(\\) at \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in \\.?main \\(\\) at \[^\r\n\]*\r\nGSTACK-END\r\n\$" { ++	pass $test ++    } ++} ++ ++gdb_test_multiple "" "gstack exits" { ++    eof { ++	set result [wait -i $gdb_spawn_id] ++	verbose $result ++ ++	gdb_assert { [lindex $result 2] == 0 } "gstack exits with no error" ++	gdb_assert { [lindex $result 3] == 0 } "gstack's exit status is 0" ++ ++	remote_close host ++	clear_gdb_spawn_id ++    } ++} ++ ++# Kill the test inferior. ++kill_wait_spawned_process $test_spawn_id diff --git a/gdb-6.3-mapping-zero-inode-test.patch b/gdb-6.3-mapping-zero-inode-test.patch new file mode 100644 index 0000000..32b62d5 --- /dev/null +++ b/gdb-6.3-mapping-zero-inode-test.patch @@ -0,0 +1,247 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-6.3-mapping-zero-inode-test.patch + +;; Test GCORE for shmid 0 shared memory mappings. +;;=fedoratest: But it is broken anyway, sometimes the case being tested is not reproducible. + +diff --git a/gdb/testsuite/gdb.base/gcore-shmid0.c b/gdb/testsuite/gdb.base/gcore-shmid0.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/gcore-shmid0.c +@@ -0,0 +1,128 @@ ++/* Copyright 2007, 2009 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 2 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, write to the Free Software ++   Foundation, Inc., 59 Temple Place - Suite 330, ++   Boston, MA 02111-1307, USA.  */ ++ ++/* ++ * Test GDB's handling of gcore for mapping with a name but zero inode. ++ */ ++ ++#include <sys/ipc.h> ++#include <sys/shm.h> ++#include <stdio.h> ++#include <errno.h> ++#include <stdlib.h> ++#include <unistd.h> ++#include <assert.h> ++#include <time.h> ++ ++/* The same test running in a parallel testsuite may steal us the zero SID, ++   even if we never get any EEXIST.  Just try a while.  */ ++ ++#define TIMEOUT_SEC 10 ++ ++static volatile int v; ++ ++static void ++initialized (void) ++{ ++  v++; ++} ++ ++static void ++unresolved (void) ++{ ++  v++; ++} ++ ++int ++main (void) ++{ ++  int sid; ++  unsigned int *addr = (void *) -1L; ++  int attempt, round = 0; ++  time_t ts_start, ts; ++ ++  if (time (&ts_start) == (time_t) -1) ++    { ++      printf ("time (): %m\n"); ++      exit (1); ++    } ++ ++  /* The generated SID will cycle with an increment of 32768, attempt until it ++   * wraps to 0.  */ ++ ++  for (attempt = 0; addr == (void *) -1L; attempt++) ++    { ++      /* kernel-2.6.25-8.fc9.x86_64 just never returns the value 0 by ++	 shmget(2).  shmget returns SID range 0..1<<31 in steps of 32768, ++	 0x1000 should be enough but wrap the range it to be sure.  */ ++ ++      if (attempt > 0x21000) ++        { ++	  if (time (&ts) == (time_t) -1) ++	    { ++	      printf ("time (): %m\n"); ++	      exit (1); ++	    } ++ ++	  if (ts >= ts_start && ts < ts_start + TIMEOUT_SEC) ++	    { ++	      attempt = 0; ++	      round++; ++	      continue; ++	    } ++ ++	  printf ("Problem is not reproducible on this kernel (attempt %d, " ++		  "round %d)\n", attempt, round); ++	  unresolved (); ++	  exit (1); ++	} ++ ++      sid = shmget ((key_t) rand (), 0x1000, IPC_CREAT | IPC_EXCL | 0777); ++      if (sid == -1) ++	{ ++	  if (errno == EEXIST) ++	    continue; ++ ++	  printf ("shmget (%d, 0x1000, IPC_CREAT): errno %d\n", 0, errno); ++	  exit (1); ++	} ++ ++      /* Use SID only if it is 0, retry it otherwise.  */ ++ ++      if (sid == 0) ++	{ ++	  addr = shmat (sid, NULL, SHM_RND); ++	  if (addr == (void *) -1L) ++	    { ++	      printf ("shmat (%d, NULL, SHM_RND): errno %d\n", sid, ++		      errno); ++	      exit (1); ++	    } ++	} ++      if (shmctl (sid, IPC_RMID, NULL) != 0) ++	{ ++	  printf ("shmctl (%d, IPC_RMID, NULL): errno %d\n", sid, errno); ++	  exit (1); ++	} ++    } ++ ++  initialized (); ++ ++  return 0; ++} +diff --git a/gdb/testsuite/gdb.base/gcore-shmid0.exp b/gdb/testsuite/gdb.base/gcore-shmid0.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/gcore-shmid0.exp +@@ -0,0 +1,101 @@ ++# Copyright 2007, 2009 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 2 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, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ ++# Test GDB's handling of gcore for mapping with a name but zero inode. ++ ++if { [prepare_for_testing gcore-shmid0.exp gcore-shmid0] } { ++    return -1 ++} ++ ++# Does this gdb support gcore? ++set test "help gcore" ++gdb_test_multiple $test $test { ++    -re "Undefined command: .gcore.*$gdb_prompt $" { ++	# gcore command not supported -- nothing to test here. ++	unsupported "gdb does not support gcore on this target" ++	return -1; ++    } ++    -re "Save a core file .*$gdb_prompt $" { ++	pass $test ++    } ++} ++ ++if { ! [ runto_main ] } then { ++    untested gcore-shmid0.exp ++    return -1 ++} ++ ++gdb_breakpoint "initialized" ++gdb_breakpoint "unresolved" ++ ++set oldtimeout $timeout ++set timeout [expr $oldtimeout + 120] ++ ++set test "Continue to initialized." ++gdb_test_multiple "continue" $test { ++    -re "Breakpoint .*, initialized .* at .*\r\n$gdb_prompt $" { ++	pass $test ++    } ++    -re "Breakpoint .*, unresolved .* at .*\r\n$gdb_prompt $" { ++	set timeout $oldtimeout ++	unsupported $test ++	return -1 ++    } ++} ++set timeout $oldtimeout ++ ++set escapedfilename [string_to_regexp [standard_output_file gcore-shmid0.test]] ++ ++set test "save a corefile" ++gdb_test_multiple "gcore [standard_output_file gcore-shmid0.test]" $test { ++    -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" { ++	pass $test ++    } ++    -re "Can't create a corefile\[\r\n\]+$gdb_prompt $" { ++	unsupported $test ++    } ++} ++ ++# Be sure to remove the handle first. ++# But it would get removed even on a kill by GDB as the handle is already ++# deleted, just it is still attached. ++gdb_continue_to_end "finish" ++ ++set test "core-file command" ++gdb_test_multiple "core-file [standard_output_file gcore-shmid0.test]" $test { ++    -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 .*\r\n\#0  .*\\\(\\\).*\r\n$gdb_prompt $" { ++	# The filename does not fit there anyway so do not check it. ++	pass $test ++    } ++    -re ".*registers from core file: File in wrong format.* $" { ++	fail "core-file command (could not read registers from core file)" ++    } ++} ++ ++set test "backtrace" ++gdb_test_multiple "bt" $test { ++    -re "#0 *initialized \\\(\\\) at .*#1 .* main \\\(.*$gdb_prompt $" { ++	pass $test ++    } ++    -re "#0 *initialized \\\(\\\) at .*Cannot access memory at address .*$gdb_prompt $" { ++	fail $test ++    } ++} diff --git a/gdb-6.3-rh-testversion-20041202.patch b/gdb-6.3-rh-testversion-20041202.patch new file mode 100644 index 0000000..59132bf --- /dev/null +++ b/gdb-6.3-rh-testversion-20041202.patch @@ -0,0 +1,34 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Andrew Burgess <aburgess@redhat.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-6.3-rh-testversion-20041202.patch + +;; Check distro name is included in the version output. + +diff --git a/gdb/testsuite/gdb.base/fedora-version.exp b/gdb/testsuite/gdb.base/fedora-version.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/fedora-version.exp +@@ -0,0 +1,22 @@ ++# Copyright 2023 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 <http://www.gnu.org/licenses/>. ++ ++# Start with a fresh gdb ++clean_restart ++ ++# Check the version string contains either the Fedora or RHEL distro ++# name, and that the version number looks roughly correct in format. ++gdb_test "show version" \ ++    "GNU gdb \\((Fedora Linux|Red Hat Enterprise Linux)\\) \[0-9\]+\\.\[0-9\]+-\[0-9\]+.*" diff --git a/gdb-6.5-BEA-testsuite.patch b/gdb-6.5-BEA-testsuite.patch new file mode 100644 index 0000000..a15cec2 --- /dev/null +++ b/gdb-6.5-BEA-testsuite.patch @@ -0,0 +1,938 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-6.5-BEA-testsuite.patch + +;; Improved testsuite results by the testsuite provided by the courtesy of BEA. +;;=fedoratest: For upstream it should be rewritten as a dejagnu test, the test of no "??" was useful. + +diff --git a/gdb/testsuite/gdb.threads/threadcrash.c b/gdb/testsuite/gdb.threads/threadcrash.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.threads/threadcrash.c +@@ -0,0 +1,301 @@ ++/* ++ * The point of this program is to crash in a multi-threaded app. ++ * There are seven threads, doing the following things: ++ * * Spinning ++ * * Spinning inside a signal handler ++ * * Spinning inside a signal handler executing on the altstack ++ * * In a syscall ++ * * In a syscall inside a signal handler ++ * * In a syscall inside a signal handler executing on the altstack ++ * * Finally, the main thread crashes in main, with no frills. ++ * ++ * These are the things threads in JRockit tend to be doing.  If gdb ++ * can handle those things, both in core files and during live ++ * debugging, that will help (at least) JRockit development. ++ * ++ * Let the program create a core file, then load the core file into ++ * gdb.  Inside gdb, you should be able to do something like this: ++ * ++ * (gdb) t a a bt ++ * ++ * Thread 7 (process 4352): ++ * #0  0x001ba7dc in __nanosleep_nocancel () from /lib/tls/libc.so.6 ++ * #1  0x001ba5ff in sleep () from /lib/tls/libc.so.6 ++ * #2  0x080488a2 in makeSyscall (ignored=0x0) at threadcrash.c:118 ++ * #3  0x006aadec in start_thread () from /lib/tls/libpthread.so.0 ++ * #4  0x001ed19a in clone () from /lib/tls/libc.so.6 ++ * ++ * Thread 6 (process 4353): ++ * #0  0x001ba7dc in __nanosleep_nocancel () from /lib/tls/libc.so.6 ++ * #1  0x001ba5ff in sleep () from /lib/tls/libc.so.6 ++ * #2  0x0804898f in syscallingSighandler (signo=10, info=0xb6be76f0, context=0xb6be7770) ++ *     at threadcrash.c:168 ++ * #3  <signal handler called> ++ * #4  0x006adf5e in pthread_kill () from /lib/tls/libpthread.so.0 ++ * #5  0x08048a51 in makeSyscallFromSighandler (ignored=0x0) at threadcrash.c:204 ++ * #6  0x006aadec in start_thread () from /lib/tls/libpthread.so.0 ++ * #7  0x001ed19a in clone () from /lib/tls/libc.so.6 ++ * ++ * Thread 5 (process 4354): ++ * #0  0x001ba7dc in __nanosleep_nocancel () from /lib/tls/libc.so.6 ++ * #1  0x001ba5ff in sleep () from /lib/tls/libc.so.6 ++ * #2  0x08048936 in syscallingAltSighandler (signo=3, info=0x959cd70, context=0x959cdf0) ++ *     at threadcrash.c:144 ++ * #3  <signal handler called> ++ * #4  0x006adf5e in pthread_kill () from /lib/tls/libpthread.so.0 ++ * #5  0x080489e2 in makeSyscallFromAltSighandler (ignored=0x0) at threadcrash.c:190 ++ * #6  0x006aadec in start_thread () from /lib/tls/libpthread.so.0 ++ * #7  0x001ed19a in clone () from /lib/tls/libc.so.6 ++ * ++ * Thread 4 (process 4355): ++ * #0  spin (ignored=0x0) at threadcrash.c:242 ++ * #1  0x006aadec in start_thread () from /lib/tls/libpthread.so.0 ++ * #2  0x001ed19a in clone () from /lib/tls/libc.so.6 ++ * ++ * Thread 3 (process 4356): ++ * #0  spinningSighandler (signo=12, info=0xb4de46f0, context=0xb4de4770) at threadcrash.c:180 ++ * #1  <signal handler called> ++ * #2  0x006adf5e in pthread_kill () from /lib/tls/libpthread.so.0 ++ * #3  0x08048b2f in spinFromSighandler (ignored=0x0) at threadcrash.c:232 ++ * #4  0x006aadec in start_thread () from /lib/tls/libpthread.so.0 ++ * #5  0x001ed19a in clone () from /lib/tls/libc.so.6 ++ * ++ * Thread 2 (process 4357): ++ * #0  spinningAltSighandler (signo=14, info=0x959ee50, context=0x959eed0) at threadcrash.c:156 ++ * #1  <signal handler called> ++ * #2  0x006adf5e in pthread_kill () from /lib/tls/libpthread.so.0 ++ * #3  0x08048ac0 in spinFromAltSighandler (ignored=0x0) at threadcrash.c:218 ++ * #4  0x006aadec in start_thread () from /lib/tls/libpthread.so.0 ++ * #5  0x001ed19a in clone () from /lib/tls/libc.so.6 ++ * ++ * Thread 1 (process 4351): ++ * #0  0x08048cf3 in main (argc=1, argv=0xbfff9d74) at threadcrash.c:273 ++ * (gdb) ++ */ ++ ++#include <pthread.h> ++#include <signal.h> ++#include <assert.h> ++#include <unistd.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++ ++#define SIGSYSCALL_ALT SIGQUIT ++#define SIGSYSCALL SIGUSR1 ++#define SIGSPIN_ALT SIGALRM ++#define SIGSPIN SIGUSR2 ++ ++typedef void (*sigaction_t)(int, siginfo_t *, void *); ++ ++static void installHandler(int signo, sigaction_t handler, int onAltstack) { ++   struct sigaction action; ++   sigset_t sigset; ++   int result; ++   stack_t altstack; ++   stack_t oldaltstack; ++ ++   memset(&action, 0, sizeof(action)); ++   memset(&altstack, 0, sizeof(altstack)); ++   memset(&oldaltstack, 0, sizeof(oldaltstack)); ++ ++   if (onAltstack) { ++      altstack.ss_sp = malloc(SIGSTKSZ); ++      assert(altstack.ss_sp != NULL); ++      altstack.ss_size = SIGSTKSZ; ++      altstack.ss_flags = 0; ++      result = sigaltstack(&altstack, &oldaltstack); ++      assert(result == 0); ++      assert(oldaltstack.ss_flags == SS_DISABLE); ++   } ++ ++   sigemptyset(&sigset); ++ ++   action.sa_handler = NULL; ++   action.sa_sigaction = handler; ++   action.sa_mask = sigset; ++   action.sa_flags = SA_SIGINFO; ++   if (onAltstack) { ++      action.sa_flags |= SA_ONSTACK; ++   } ++ ++   result = sigaction(signo, &action, NULL); ++   assert(result == 0); ++} ++ ++static void installNormalHandler(int signo, sigaction_t handler) { ++   installHandler(signo, handler, 0); ++} ++ ++static void installAlthandler(int signo, sigaction_t handler) { ++   installHandler(signo, handler, 1); ++} ++ ++static void *makeSyscall(void *ignored) { ++   (void)ignored; ++ ++   sleep(42); ++ ++   fprintf(stderr, "%s: returning\n", __FUNCTION__); ++   return NULL; ++} ++ ++/* Return true if we're currently executing on the altstack */ ++static int onAltstack(void) { ++   stack_t stack; ++   int result; ++ ++   result = sigaltstack(NULL, &stack); ++   assert(result == 0); ++ ++   return stack.ss_flags & SS_ONSTACK; ++} ++ ++static void syscallingAltSighandler(int signo, siginfo_t *info, void *context) { ++   (void)signo; ++   (void)info; ++   (void)context; ++ ++   if (!onAltstack()) { ++      printf("%s() not running on altstack!\n", __FUNCTION__); ++   } ++ ++   sleep(42); ++} ++ ++static void spinningAltSighandler(int signo, siginfo_t *info, void *context) { ++   (void)signo; ++   (void)info; ++   (void)context; ++ ++   if (!onAltstack()) { ++      printf("%s() not running on altstack!\n", __FUNCTION__); ++   } ++ ++   while (1); ++} ++ ++static void syscallingSighandler(int signo, siginfo_t *info, void *context) { ++   (void)signo; ++   (void)info; ++   (void)context; ++ ++   if (onAltstack()) { ++      printf("%s() running on altstack!\n", __FUNCTION__); ++   } ++ ++   sleep(42); ++} ++ ++static void spinningSighandler(int signo, siginfo_t *info, void *context) { ++   (void)signo; ++   (void)info; ++   (void)context; ++ ++   if (onAltstack()) { ++      printf("%s() running on altstack!\n", __FUNCTION__); ++   } ++ ++   while (1); ++} ++ ++static void *makeSyscallFromAltSighandler(void *ignored) { ++   (void)ignored; ++ ++   int result; ++ ++   installAlthandler(SIGSYSCALL_ALT, syscallingAltSighandler); ++ ++   result = pthread_kill(pthread_self(), SIGSYSCALL_ALT); ++   assert(result == 0); ++ ++   fprintf(stderr, "%s: returning\n", __FUNCTION__); ++   return NULL; ++} ++ ++static void *makeSyscallFromSighandler(void *ignored) { ++   (void)ignored; ++ ++   int result; ++ ++   installNormalHandler(SIGSYSCALL, syscallingSighandler); ++ ++   result = pthread_kill(pthread_self(), SIGSYSCALL); ++   assert(result == 0); ++ ++   fprintf(stderr, "%s: returning\n", __FUNCTION__); ++   return NULL; ++} ++ ++static void *spinFromAltSighandler(void *ignored) { ++   (void)ignored; ++ ++   int result; ++ ++   installAlthandler(SIGSPIN_ALT, spinningAltSighandler); ++ ++   result = pthread_kill(pthread_self(), SIGSPIN_ALT); ++   assert(result == 0); ++ ++   fprintf(stderr, "%s: returning\n", __FUNCTION__); ++   return NULL; ++} ++ ++static void *spinFromSighandler(void *ignored) { ++   (void)ignored; ++ ++   int result; ++ ++   installNormalHandler(SIGSPIN, spinningSighandler); ++ ++   result = pthread_kill(pthread_self(), SIGSPIN); ++   assert(result == 0); ++ ++   fprintf(stderr, "%s: returning\n", __FUNCTION__); ++   return NULL; ++} ++ ++static void *spin(void *ignored) { ++   (void)ignored; ++ ++   while (1); ++ ++   fprintf(stderr, "%s: returning\n", __FUNCTION__); ++   return NULL; ++} ++ ++int main(int argc, char *argv[]) { ++   int result; ++   pthread_t thread; ++   volatile int bad; ++ ++   result = pthread_create(&thread, NULL, makeSyscall, NULL); ++   assert(result == 0); ++   result = pthread_create(&thread, NULL, makeSyscallFromSighandler, NULL); ++   assert(result == 0); ++   result = pthread_create(&thread, NULL, makeSyscallFromAltSighandler, NULL); ++   assert(result == 0); ++   result = pthread_create(&thread, NULL, spin, NULL); ++   assert(result == 0); ++   result = pthread_create(&thread, NULL, spinFromSighandler, NULL); ++   assert(result == 0); ++   result = pthread_create(&thread, NULL, spinFromAltSighandler, NULL); ++   assert(result == 0); ++ ++   // Give threads some time to get going ++   sleep(3); ++ ++   // Crash ++   bad = *(int*)7; ++ ++   /* Workaround: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29628 ++      Simulate use to ensure `DW_AT_location' for them: ++      readelf -a --debug threadcrash|grep -A5 -w argc ++      --> DW_AT_location    : 2 byte block: 71 0     (DW_OP_breg1: 0) ++      This case verified on: gcc-4.1.1-30.i386 ++      Keep it late to ensure persistency in the registers.  */ ++   bad = (int) argc; ++   bad = (unsigned long) argv; ++ ++   return 0; ++} +diff --git a/gdb/testsuite/gdb.threads/threadcrash.exp b/gdb/testsuite/gdb.threads/threadcrash.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.threads/threadcrash.exp +@@ -0,0 +1,37 @@ ++# threadcrash.exp - The point of this program is to crash in a multi-threaded app. ++ ++ ++set testfile threadcrash ++set srcfile ${testfile}.c ++set shellfile ${srcdir}/${subdir}/${testfile}.sh ++set binfile [standard_output_file ${testfile}] ++ ++set GDB_abs ${GDB} ++if [regexp "^\[^/\]" ${GDB_abs}] { ++    set GDB_abs $env(PWD)/${GDB_abs} ++} ++ ++if [istarget "*-*-linux"] then { ++    set target_cflags "-D_MIT_POSIX_THREADS" ++} else { ++    set target_cflags "" ++} ++ ++if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { ++    return -1 ++} ++ ++# ${shellfile} argument must not contain any directories. ++set fd [open "|bash ${shellfile} ${binfile} $GDB $INTERNAL_GDBFLAGS $GDBFLAGS [host_info gdb_opts]" r] ++while { [gets $fd line] >= 0 } { ++    if [regexp " PASS: (.*)$" $line trash message] { ++	pass $message ++    } elseif [regexp " FAIL: (.*)$" $line trash message] { ++	fail $message ++    } ++} ++catch { ++    close $fd ++} ++ ++return 0 +diff --git a/gdb/testsuite/gdb.threads/threadcrash.sh b/gdb/testsuite/gdb.threads/threadcrash.sh +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.threads/threadcrash.sh +@@ -0,0 +1,324 @@ ++#! /bin/bash ++ ++# NOTE: threadcrash.c *must* be built with debugging symbols ++# ++# The point of this shell script is to crash treadcrash.c, load the ++# resulting core file into gdb and verify that gdb can extract enough ++# information from the core file. ++# ++# The return code from this script is the number of failed tests. ++ ++LOG=gdbresult.log ++ ++if [ $# = 0 ] ; then ++    echo >&2 Syntax: $0 \<name of threadcrash binary\> [\<gdb binary\> \<args...\>] ++    exit 1 ++fi ++RUNME="$1" ++shift ++GDB="${*:-gdb}" ++ ++ ++pf_prefix="" ++function pf_prefix() { ++	pf_prefix="$*" ++} ++ ++set_test="" ++function set_test() { ++	if [ -n "$set_test" ] ; then ++		echo >&2 "DEJAGNU-BASH ERROR: set_test already set" ++		exit 1 ++	fi ++	set_test="$*" ++	if [ -n "$pf_prefix" ] ; then ++		set_test="$pf_prefix: $set_test" ++	fi ++} ++ ++# INTERNAL ++function record_test { ++	if [ -z "$set_test" ] ; then ++		echo >&2 "DEJAGNU-BASH ERROR: set_test not set" ++		exit 1 ++	fi ++	# Provide the leading whitespace delimiter: ++	echo " $1: $set_test" ++	set_test="" ++} ++ ++function pass() { ++	record_test PASS ++} ++function fail() { ++	record_test FAIL ++} ++ ++ ++# Verify that the gdb output doesn't contain $1. ++function mustNotHave() { ++    local BADWORD=$1 ++    set_test gdb output contains "$BADWORD" ++    if grep -q "$BADWORD" $LOG ; then ++        fail ++        return 1 ++    fi ++    pass ++    return 0 ++} ++ ++# Verify that the gdb output contains exactly $1 $2s. ++function mustHaveCorrectAmount() { ++    local WANTEDNUMBER=$1 ++    local GOODWORD=$2 ++    local ACTUALNUMBER=$(grep "$GOODWORD" $LOG | wc -l) ++    set_test gdb output contained $ACTUALNUMBER \""$GOODWORD"\", not $WANTEDNUMBER as expected ++    if [ $ACTUALNUMBER != $WANTEDNUMBER ] ; then ++        fail ++        return 1 ++    fi ++    pass ++    return 0 ++} ++ ++# Verify that the gdb output contains seven threads ++function mustHaveSevenThreads() { ++    NTHREADS=$(egrep "^Thread [1-7] \(" $LOG | wc -l) ++    set_test gdb output contains $NTHREADS threads, not 7 as expected ++    if [ $NTHREADS != 7 ] ; then ++        fail ++        return 1 ++    fi ++    pass ++    return 0 ++} ++ ++# Verify that the gdb output has all parameters on consecutive lines ++function mustHaveSequence() { ++    SEQUENCE="$*" ++    NPARTS=$# ++    grep "$1" -A$((NPARTS - 1)) $LOG > matches.log ++ ++    while [ $# -gt 1 ] ; do ++        shift ++        ((NPARTS--)) ++        grep "$1" -A$((NPARTS - 1)) matches.log > temp.log ++        mv temp.log matches.log ++    done ++    LASTPART=$1 ++ ++    set_test gdb output does not contain the sequence: $SEQUENCE ++    if ! grep -q "$LASTPART" matches.log ; then ++        fail ++        return 1 ++    fi ++    pass ++    return 0 ++} ++ ++# Verify that $LOG contains all information we want ++function verifyLog() { ++    local FAILURES=0 ++ ++    mustNotHave '??' || ((FAILURES++)) ++    mustHaveCorrectAmount 11 threadcrash.c: || ((FAILURES++)) ++ ++    mustHaveSevenThreads || ((FAILURES++)) ++    mustHaveSequence sleep "makeSyscall (ignored=" || ((FAILURES++)) ++ ++    mustHaveSequence sleep "syscallingSighandler (signo=" "signal handler called" 0x || ((FAILURES++)) ++    mustHaveSequence pthread_kill "makeSyscallFromSighandler (ignored=" || ((FAILURES++)) ++ ++    mustHaveSequence sleep "syscallingAltSighandler (signo=" "signal handler called" 0x || ((FAILURES++)) ++    mustHaveSequence pthread_kill "makeSyscallFromAltSighandler (ignored=" || ((FAILURES++)) ++ ++    mustHaveSequence Thread "spin (ignored=" || ((FAILURES++)) ++ ++    mustHaveSequence "spinningSighandler (signo=" "signal handler called" 0x || ((FAILURES++)) ++    mustHaveSequence pthread_kill "spinFromSighandler (ignored=" || ((FAILURES++)) ++ ++    mustHaveSequence "spinningAltSighandler (signo=" "signal handler called" 0x || ((FAILURES++)) ++    mustHaveSequence pthread_kill "spinFromAltSighandler (ignored=" || ((FAILURES++)) ++ ++    mustHaveSequence Thread "main (argc=1, argv=" || ((FAILURES++)) ++ ++    return $FAILURES ++} ++ ++# Put result of debugging a core file in $LOG ++function getLogFromCore() { ++    # Make sure we get a core file ++    set_test Make sure we get a core file ++    if ! ulimit -c unlimited ; then ++        fail ++        exit 1 ++    fi ++    pass ++ ++    # Run the crasher ++    ./$(basename "$RUNME") ++    EXITCODE=$? ++ ++    # Verify that we actually crashed ++    set_test $RUNME should have been killed by a signal, got non-signal exit code $EXITCODE ++    if [ $EXITCODE -lt 128 ] ; then ++        fail ++        exit 1 ++    fi ++    pass ++ ++    # Verify that we got a core file ++    set_test $RUNME did not create a core file ++    if [ ! -r core* ] ; then ++        fail ++        exit 1 ++    fi ++    pass ++ ++    # Run gdb ++    cat > gdbscript.gdb <<EOF ++set width 0 ++t a a bt 100 ++quit ++EOF ++    cat gdbscript.gdb /dev/zero | $GDB -nx "./$(basename "$RUNME")" core* > $LOG ++    EXITCODE=$? ++ ++    set_test gdb exited with error code ++    if [ $EXITCODE != 0 ] ; then ++        ((FAILURES++)) ++        echo >&2 gdb exited with error code $EXITCODE ++	fail ++    fi ++    pass ++} ++ ++# Put result of debugging a gcore file in $LOG ++function getLogFromGcore() { ++    # Create the core file ++    rm -f core* ++    cat > gdbscript.gdb <<EOF ++handle SIGQUIT pass noprint nostop ++handle SIGUSR1 pass noprint nostop ++handle SIGUSR2 pass noprint nostop ++handle SIGALRM pass noprint nostop ++run ++gcore ++quit ++EOF ++    cat gdbscript.gdb /dev/zero | $GDB -nx "./$(basename "$RUNME")" > /dev/null ++    EXITCODE=$? ++ ++    set_test gdb exited with error code when creating gcore file ++    if [ $EXITCODE != 0 ] ; then ++        ((FAILURES++)) ++        echo >&2 gdb exited with error code $EXITCODE when creating gcore file ++	fail ++    fi ++    pass ++ ++    # Verify that we got a core file from gcore ++    set_test gdb gcore did not create a core file ++    if [ ! -r core* ] ; then ++        fail ++        exit 1 ++    fi ++    pass ++ ++    # Run gdb on the gcore file ++    cat > gdbscript.gdb <<EOF ++set width 0 ++t a a bt 100 ++quit ++EOF ++    cat gdbscript.gdb /dev/zero | $GDB -nx "./$(basename "$RUNME")" core* > $LOG ++    EXITCODE=$? ++ ++    set_test gdb exited with error code when examining gcore file ++    if [ $EXITCODE != 0 ] ; then ++        ((FAILURES++)) ++        echo >&2 gdb exited with error code $EXITCODE when examining gcore file ++	fail ++    fi ++    pass ++} ++ ++# Put result of debugging a core file in $LOG ++function getLogFromLiveProcess() { ++    # Run gdb ++    cat > gdbscript.gdb <<EOF ++handle SIGQUIT pass noprint nostop ++handle SIGUSR1 pass noprint nostop ++handle SIGUSR2 pass noprint nostop ++handle SIGALRM pass noprint nostop ++set width 0 ++run ++t a a bt 100 ++quit ++EOF ++    cat gdbscript.gdb /dev/zero | $GDB -nx "./$(basename "$RUNME")" > $LOG ++    EXITCODE=$? ++ ++    set_test gdb exited with error code ++    if [ $EXITCODE != 0 ] ; then ++        ((FAILURES++)) ++        echo >&2 gdb exited with error code $EXITCODE ++	fail ++    fi ++    pass ++} ++ ++####### Main program follows ##################### ++ ++# Make sure we don't clobber anybody else's (core) file(s) ++WORKDIR=/tmp/$PPID ++mkdir -p $WORKDIR ++cp "$RUNME" $WORKDIR ++cd $WORKDIR ++ ++# Count problems ++FAILURES=0 ++ ++echo === Testing gdb vs core file... ++pf_prefix core file ++getLogFromCore ++verifyLog ++((FAILURES+=$?)) ++pf_prefix ++echo === Core file tests done. ++ ++echo ++ ++echo === Testing gdb vs gcore file... ++pf_prefix gcore file ++getLogFromGcore ++verifyLog ++((FAILURES+=$?)) ++pf_prefix ++echo === Gcore file tests done. ++ ++echo ++ ++echo === Testing gdb vs live process... ++pf_prefix live process ++getLogFromLiveProcess ++verifyLog ++((FAILURES+=$?)) ++pf_prefix ++echo === Live process tests done. ++ ++# Executive summary ++echo ++if [ $FAILURES == 0 ] ; then ++    echo All tests passed! ++else ++    echo $FAILURES tests failed! ++    echo ++    echo Make sure the threadcrash binary contains debugging information \(build with \"gcc -g\"\). ++fi ++ ++# Clean up ++cd / ++rm -rf $WORKDIR ++ ++exit $FAILURES +diff --git a/gdb/testsuite/gdb.threads/threadcrash.sh-orig b/gdb/testsuite/gdb.threads/threadcrash.sh-orig +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.threads/threadcrash.sh-orig +@@ -0,0 +1,248 @@ ++#! /bin/bash ++ ++# NOTE: threadcrash.c *must* be built with debugging symbols ++# ++# The point of this shell script is to crash treadcrash.c, load the ++# resulting core file into gdb and verify that gdb can extract enough ++# information from the core file. ++# ++# The return code from this script is the number of failed tests. ++ ++LOG=gdbresult.log ++ ++if [ $# != 1 ] ; then ++    echo > /dev/stderr Syntax: $0 \<name of threadcrash binary\> ++    exit 1 ++fi ++RUNME="$1" ++ ++# Verify that the gdb output doesn't contain $1. ++function mustNotHave() { ++    local BADWORD=$1 ++    if grep -q "$BADWORD" $LOG ; then ++        echo >> /dev/stderr WARNING: gdb output contains "$BADWORD" ++        return 1 ++    fi ++    return 0 ++} ++ ++# Verify that the gdb output contains exactly $1 $2s. ++function mustHaveCorrectAmount() { ++    local WANTEDNUMBER=$1 ++    local GOODWORD=$2 ++    local ACTUALNUMBER=$(grep "$GOODWORD" $LOG | wc -l) ++    if [ $ACTUALNUMBER != $WANTEDNUMBER ] ; then ++        echo >> /dev/stderr WARNING: gdb output contained $ACTUALNUMBER \""$GOODWORD"\", not $WANTEDNUMBER as expected ++        return 1 ++    fi ++    return 0 ++} ++ ++# Verify that the gdb output contains seven threads ++function mustHaveSevenThreads() { ++    NTHREADS=$(egrep "^Thread [1-7] \(" $LOG | wc -l) ++    if [ $NTHREADS != 7 ] ; then ++        echo >> /dev/stderr WARNING: gdb output contains $NTHREADS threads, not 7 as expected ++        return 1 ++    fi ++    return 0 ++} ++ ++# Verify that the gdb output has all parameters on consecutive lines ++function mustHaveSequence() { ++    SEQUENCE="$*" ++    NPARTS=$# ++    grep "$1" -A$((NPARTS - 1)) $LOG > matches.log ++ ++    while [ $# -gt 1 ] ; do ++        shift ++        ((NPARTS--)) ++        grep "$1" -A$((NPARTS - 1)) matches.log > temp.log ++        mv temp.log matches.log ++    done ++    LASTPART=$1 ++ ++    if ! grep -q "$LASTPART" matches.log ; then ++        echo >> /dev/stderr WARNING: gdb output does not contain the sequence: $SEQUENCE ++        return 1 ++    fi ++    return 0 ++} ++ ++# Verify that $LOG contains all information we want ++function verifyLog() { ++    local FAILURES=0 ++ ++    mustNotHave '??' || ((FAILURES++)) ++    mustHaveCorrectAmount 12 threadcrash.c: || ((FAILURES++)) ++ ++    mustHaveSevenThreads || ((FAILURES++)) ++    mustHaveSequence sleep "makeSyscall (ignored=" || ((FAILURES++)) ++ ++    mustHaveSequence sleep "syscallingSighandler (signo=" "signal handler called" 0x || ((FAILURES++)) ++    mustHaveSequence pthread_kill "makeSyscallFromSighandler (ignored=" || ((FAILURES++)) ++ ++    mustHaveSequence sleep "syscallingAltSighandler (signo=" "signal handler called" 0x || ((FAILURES++)) ++    mustHaveSequence pthread_kill "makeSyscallFromAltSighandler (ignored=" || ((FAILURES++)) ++ ++    mustHaveSequence Thread "spin (ignored=" || ((FAILURES++)) ++ ++    mustHaveSequence "spinningSighandler (signo=" "signal handler called" 0x || ((FAILURES++)) ++    mustHaveSequence pthread_kill "spinFromSighandler (ignored=" || ((FAILURES++)) ++ ++    mustHaveSequence "spinningAltSighandler (signo=" "signal handler called" 0x || ((FAILURES++)) ++    mustHaveSequence pthread_kill "spinFromAltSighandler (ignored=" || ((FAILURES++)) ++ ++    mustHaveSequence Thread "main (argc=1, argv=" || ((FAILURES++)) ++ ++    return $FAILURES ++} ++ ++# Put result of debugging a core file in $LOG ++function getLogFromCore() { ++    # Make sure we get a core file ++    ulimit -c unlimited || exit 1 ++ ++    # Run the crasher ++    ./$(basename "$RUNME") ++    EXITCODE=$? ++ ++    # Verify that we actually crashed ++    if [ $EXITCODE -lt 128 ] ; then ++        echo >> /dev/stderr ERROR: $RUNME should have been killed by a signal, got non-signal exit code $EXITCODE ++        exit 1 ++    fi ++ ++    # Verify that we got a core file ++    if [ ! -r core* ] ; then ++        echo >> /dev/stderr ERROR: $RUNME did not create a core file ++        exit 1 ++    fi ++ ++    # Run gdb ++    cat > gdbscript.gdb <<EOF ++set width 0 ++t a a bt 100 ++quit ++EOF ++    cat gdbscript.gdb /dev/zero | gdb -nx "./$(basename "$RUNME")" core* > $LOG ++    EXITCODE=$? ++ ++    if [ $EXITCODE != 0 ] ; then ++        ((FAILURES++)) ++        echo >> /dev/stderr WARNING: gdb exited with error code $EXITCODE ++    fi ++} ++ ++# Put result of debugging a gcore file in $LOG ++function getLogFromGcore() { ++    # Create the core file ++    rm -f core* ++    cat > gdbscript.gdb <<EOF ++handle SIGQUIT pass noprint nostop ++handle SIGUSR1 pass noprint nostop ++handle SIGUSR2 pass noprint nostop ++handle SIGALRM pass noprint nostop ++run ++gcore ++quit ++EOF ++    cat gdbscript.gdb /dev/zero | gdb -nx "./$(basename "$RUNME")" > /dev/null ++    EXITCODE=$? ++ ++    if [ $EXITCODE != 0 ] ; then ++        ((FAILURES++)) ++        echo >> /dev/stderr WARNING: gdb exited with error code $EXITCODE when creating gcore file ++    fi ++ ++    # Verify that we got a core file from gcore ++    if [ ! -r core* ] ; then ++        echo >> /dev/stderr ERROR: gdb gcore did not create a core file ++        exit 1 ++    fi ++ ++    # Run gdb on the gcore file ++    cat > gdbscript.gdb <<EOF ++set width 0 ++t a a bt 100 ++quit ++EOF ++    cat gdbscript.gdb /dev/zero | gdb -nx "./$(basename "$RUNME")" core* > $LOG ++    EXITCODE=$? ++ ++    if [ $EXITCODE != 0 ] ; then ++        ((FAILURES++)) ++        echo >> /dev/stderr WARNING: gdb exited with error code $EXITCODE when examining gcore file ++    fi ++} ++ ++# Put result of debugging a core file in $LOG ++function getLogFromLiveProcess() { ++    # Run gdb ++    cat > gdbscript.gdb <<EOF ++handle SIGQUIT pass noprint nostop ++handle SIGUSR1 pass noprint nostop ++handle SIGUSR2 pass noprint nostop ++handle SIGALRM pass noprint nostop ++set width 0 ++run ++t a a bt 100 ++quit ++EOF ++    cat gdbscript.gdb /dev/zero | gdb -nx "./$(basename "$RUNME")" > $LOG ++    EXITCODE=$? ++ ++    if [ $EXITCODE != 0 ] ; then ++        ((FAILURES++)) ++        echo >> /dev/stderr WARNING: gdb exited with error code $EXITCODE ++    fi ++} ++ ++####### Main program follows ##################### ++ ++# Make sure we don't clobber anybody else's (core) file(s) ++WORKDIR=/tmp/$PPID ++mkdir -p $WORKDIR ++cp "$RUNME" $WORKDIR ++cd $WORKDIR ++ ++# Count problems ++FAILURES=0 ++ ++echo === Testing gdb vs core file... ++getLogFromCore ++verifyLog ++((FAILURES+=$?)) ++echo === Core file tests done. ++ ++echo ++ ++echo === Testing gdb vs gcore file... ++getLogFromGcore ++verifyLog ++((FAILURES+=$?)) ++echo === Gcore file tests done. ++ ++echo ++ ++echo === Testing gdb vs live process... ++getLogFromLiveProcess ++verifyLog ++((FAILURES+=$?)) ++echo === Live process tests done. ++ ++# Executive summary ++echo ++if [ $FAILURES == 0 ] ; then ++    echo All tests passed! ++else ++    echo $FAILURES tests failed! ++    echo ++    echo Make sure the threadcrash binary contains debugging information \(build with \"gcc -g\"\). ++fi ++ ++# Clean up ++cd / ++rm -rf $WORKDIR ++ ++exit $FAILURES diff --git a/gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch b/gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch new file mode 100644 index 0000000..ab64f7f --- /dev/null +++ b/gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch @@ -0,0 +1,265 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Jan Kratochvil <jan.kratochvil@redhat.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch + +;; Support TLS symbols (+`errno' suggestion if no pthread is found) (BZ 185337). +;;=push+jan: It should be replaced by Infinity project. + +https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=185337 + +2008-02-24  Jan Kratochvil  <jan.kratochvil@redhat.com> + +	Port to GDB-6.8pre. + +currently for trivial nonthreaded helloworld with no debug info up to -ggdb2 you +will get: +        (gdb) p errno +        [some error] + +* with -ggdb2 and less "errno" in fact does not exist anywhere as it was +  compiled to "(*__errno_location ())" and the macro definition is not present. +  Unfortunately gdb will find the TLS symbol and it will try to access it but +  as the program has been compiled without -lpthread the TLS base register +  (%gs on i386) is not setup and it will result in: +        Cannot access memory at address 0x8 + +Attached suggestion patch how to deal with the most common "errno" symbol +for the most common under-ggdb3 compiled programs. + +Original patch hooked into target_translate_tls_address.  But its inferior +call invalidates `struct frame *' in the callers - RH BZ 690908. + +https://bugzilla.redhat.com/show_bug.cgi?id=1166549 + +2007-11-03  Jan Kratochvil  <jan.kratochvil@redhat.com> + +	* ./gdb/dwarf2read.c (read_partial_die, dwarf2_linkage_name): Prefer +	DW_AT_MIPS_linkage_name over DW_AT_name now only for non-C. + +glibc-debuginfo-2.7-2.x86_64: /usr/lib/debug/lib64/libc.so.6.debug: +  <81a2>     DW_AT_name        : (indirect string, offset: 0x280e): __errno_location +  <81a8>     DW_AT_MIPS_linkage_name: (indirect string, offset: 0x2808): *__GI___errno_location + +diff --git a/gdb/printcmd.c b/gdb/printcmd.c +--- a/gdb/printcmd.c ++++ b/gdb/printcmd.c +@@ -1308,6 +1308,11 @@ process_print_command_args (const char *args, value_print_options *print_opts, +  +   if (exp != nullptr && *exp) +     { ++      /* '*((int *(*) (void)) __errno_location) ()' is incompatible with ++	 function descriptors.  */ ++      if (target_has_execution () && strcmp (exp, "errno") == 0) ++	exp = "*(*(int *(*)(void)) __errno_location) ()"; ++ +       /* This setting allows large arrays to be printed by limiting the + 	 number of elements that are loaded into GDB's memory; we only + 	 need to load as many array elements as we plan to print.  */ +diff --git a/gdb/testsuite/gdb.dwarf2/dw2-errno.c b/gdb/testsuite/gdb.dwarf2/dw2-errno.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.dwarf2/dw2-errno.c +@@ -0,0 +1,28 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++   Copyright 2005, 2007 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 <http://www.gnu.org/licenses/>. ++ ++   Please email any bugs, comments, and/or additions to this file to: ++   bug-gdb@prep.ai.mit.edu  */ ++ ++#include <errno.h> ++ ++int main() ++{ ++  errno = 42; ++ ++  return 0;	/* breakpoint */ ++} +diff --git a/gdb/testsuite/gdb.dwarf2/dw2-errno.exp b/gdb/testsuite/gdb.dwarf2/dw2-errno.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.dwarf2/dw2-errno.exp +@@ -0,0 +1,60 @@ ++# Copyright 2007 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 <http://www.gnu.org/licenses/>. ++ ++set testfile dw2-errno ++set srcfile ${testfile}.c ++set binfile [standard_output_file ${testfile}] ++ ++proc prep {} { ++    global srcdir subdir binfile ++    gdb_exit ++    gdb_start ++    gdb_reinitialize_dir $srcdir/$subdir ++    gdb_load ${binfile} ++ ++    runto_main ++ ++    gdb_breakpoint [gdb_get_line_number "breakpoint"] ++    gdb_continue_to_breakpoint "breakpoint" ++} ++ ++if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "additional_flags=-g2"] != "" } { ++    untested "Couldn't compile test program" ++    return -1 ++} ++prep ++gdb_test "print errno" ".* = 42" "errno with macros=N threads=N" ++ ++if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "additional_flags=-g3"] != "" } { ++    untested "Couldn't compile test program" ++    return -1 ++} ++prep ++gdb_test "print errno" ".* = 42" "errno with macros=Y threads=N" ++ ++if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "additional_flags=-g2"] != "" } { ++    return -1 ++} ++prep ++gdb_test "print errno" ".* = 42" "errno with macros=N threads=Y" ++ ++if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "additional_flags=-g3"] != "" } { ++    return -1 ++} ++prep ++gdb_test "print errno" ".* = 42" "errno with macros=Y threads=Y" ++ ++# TODO: Test the error on resolving ERRNO with only libc loaded. ++# Just how to find the current libc filename? +diff --git a/gdb/testsuite/gdb.dwarf2/dw2-errno2.c b/gdb/testsuite/gdb.dwarf2/dw2-errno2.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.dwarf2/dw2-errno2.c +@@ -0,0 +1,28 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++   Copyright 2005, 2007 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 <http://www.gnu.org/licenses/>. ++ ++   Please email any bugs, comments, and/or additions to this file to: ++   bug-gdb@prep.ai.mit.edu  */ ++ ++#include <errno.h> ++ ++int main() ++{ ++  errno = 42; ++ ++  return 0;	/* breakpoint */ ++} +diff --git a/gdb/testsuite/gdb.dwarf2/dw2-errno2.exp b/gdb/testsuite/gdb.dwarf2/dw2-errno2.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.dwarf2/dw2-errno2.exp +@@ -0,0 +1,71 @@ ++# Copyright 2007 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 <http://www.gnu.org/licenses/>. ++ ++set testfile dw2-errno2 ++set srcfile ${testfile}.c ++set binfile [standard_output_file ${testfile}] ++ ++proc prep { message {do_xfail 0} } { with_test_prefix $message { ++    global srcdir subdir binfile variant ++    gdb_exit ++    gdb_start ++    gdb_reinitialize_dir $srcdir/$subdir ++    gdb_load ${binfile}${variant} ++ ++    runto_main ++ ++    gdb_breakpoint [gdb_get_line_number "breakpoint"] ++    gdb_continue_to_breakpoint "breakpoint" ++ ++    gdb_test "gcore ${binfile}${variant}.core" "\r\nSaved corefile .*" "gcore $variant" ++ ++    gdb_test "print errno" ".* = 42" ++ ++    gdb_test "kill" ".*" "kill" {Kill the program being debugged\? \(y or n\) } "y" ++    gdb_test "core-file ${binfile}${variant}.core" "\r\nCore was generated by .*" "core-file" ++    if $do_xfail { ++	setup_xfail "*-*-*" ++    } ++    gdb_test "print (int) errno" ".* = 42" "print errno for core" ++}} ++ ++set variant g2thrN ++if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}${variant}" executable "additional_flags=-g2"] != "" } { ++    untested "Couldn't compile test program" ++    return -1 ++} ++prep "macros=N threads=N" 1 ++ ++set variant g3thrN ++if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}${variant}" executable "additional_flags=-g3"] != "" } { ++    untested "Couldn't compile test program" ++    return -1 ++} ++prep "macros=Y threads=N" 1 ++ ++set variant g2thrY ++if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}${variant}" executable "additional_flags=-g2"] != "" } { ++    return -1 ++} ++prep "macros=N threads=Y" ++ ++set variant g3thrY ++if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}${variant}" executable "additional_flags=-g3"] != "" } { ++    return -1 ++} ++prep "macros=Y threads=Y" 1 ++ ++# TODO: Test the error on resolving ERRNO with only libc loaded. ++# Just how to find the current libc filename? diff --git a/gdb-6.5-bz218379-ppc-solib-trampoline-test.patch b/gdb-6.5-bz218379-ppc-solib-trampoline-test.patch new file mode 100644 index 0000000..db4229d --- /dev/null +++ b/gdb-6.5-bz218379-ppc-solib-trampoline-test.patch @@ -0,0 +1,107 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-6.5-bz218379-ppc-solib-trampoline-test.patch + +;; Test sideeffects of skipping ppc .so libs trampolines (BZ 218379). +;;=fedoratest + +https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=218379 + +diff --git a/gdb/testsuite/gdb.base/step-over-trampoline.c b/gdb/testsuite/gdb.base/step-over-trampoline.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/step-over-trampoline.c +@@ -0,0 +1,28 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++   Copyright 2006 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 2 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, write to the Free Software ++   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ ++   Please email any bugs, comments, and/or additions to this file to: ++   bug-gdb@prep.ai.mit.edu  */ ++ ++#include <stdio.h> ++ ++int main (void) ++{ ++	puts ("hello world"); ++	return 0; ++} +diff --git a/gdb/testsuite/gdb.base/step-over-trampoline.exp b/gdb/testsuite/gdb.base/step-over-trampoline.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/step-over-trampoline.exp +@@ -0,0 +1,59 @@ ++# Copyright 2006 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 2 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, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ ++if {[use_gdb_stub]} { ++    untested "skipping test because of use_gdb_stub" ++    return -1 ++} ++ ++if $tracelevel then { ++    strace $tracelevel ++} ++ ++set testfile step-over-trampoline ++set srcfile ${testfile}.c ++set binfile [standard_output_file ${testfile}] ++if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { ++    untested "Couldn't compile test program" ++    return -1 ++} ++ ++# Get things started. ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${binfile} ++ ++# For C programs, "start" should stop in main(). ++ ++gdb_test "start" \ ++         "main \\(\\) at .*$srcfile.*" \ ++         "start" ++ ++# main () at hello2.c:5 ++# 5		puts("hello world\n"); ++# (gdb) next ++# 0x100007e0 in call___do_global_ctors_aux () ++ ++gdb_test_multiple "next" "invalid `next' output" { ++	-re "\nhello world.*return 0;.*" { ++		pass "stepped over" ++	} ++	-re " in call___do_global_ctors_aux \\(\\).*" { ++		fail "stepped into trampoline" ++	} ++} diff --git a/gdb-6.5-bz243845-stale-testing-zombie-test.patch b/gdb-6.5-bz243845-stale-testing-zombie-test.patch new file mode 100644 index 0000000..2d62949 --- /dev/null +++ b/gdb-6.5-bz243845-stale-testing-zombie-test.patch @@ -0,0 +1,89 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-6.5-bz243845-stale-testing-zombie-test.patch + +;; Test leftover zombie process (BZ 243845). +;;=fedoratest + +diff --git a/gdb/testsuite/gdb.base/tracefork-zombie.exp b/gdb/testsuite/gdb.base/tracefork-zombie.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/tracefork-zombie.exp +@@ -0,0 +1,76 @@ ++# Copyright 2007 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 2 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, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */ ++ ++# are we on a target board ++if {[use_gdb_stub]} { ++    untested "skipping test because of use_gdb_stub" ++    return -1 ++} ++ ++# Start the program running and then wait for a bit, to be sure ++# that it can be attached to. ++ ++gdb_exit ++gdb_start ++gdb_load sleep ++ ++set gdb_pid [exp_pid -i [board_info host fileid]] ++set test "identified the child GDB" ++if {$gdb_pid != "" && $gdb_pid > 0} { ++    pass $test ++    verbose -log "Child GDB PID $gdb_pid" ++} else { ++    fail $test ++} ++ ++set testpid [eval exec sleep 10 &] ++exec sleep 2 ++ ++set test "attach" ++gdb_test_multiple "attach $testpid" "$test" { ++    -re "Attaching to program.*`?.*'?, process $testpid..*$gdb_prompt $" { ++	pass "$test" ++    } ++    -re "Attaching to program.*`?.*\.exe'?, process $testpid.*\[Switching to thread $testpid\..*\].*$gdb_prompt $" { ++	# Response expected on Cygwin ++	pass "$test" ++    } ++} ++ ++# Some time to let GDB spawn its testing child. ++exec sleep 2 ++ ++set found none ++foreach procpid [glob -directory /proc -type d {[0-9]*}] { ++    if {[catch {open $procpid/status} statusfi]} { ++	continue ++    } ++    set status [read $statusfi] ++    close $statusfi ++    if {1 ++         && [regexp -line {^Name:\tgdb$} $status] ++         && [regexp -line {^PPid:\t1$} $status] ++         && [regexp -line "^TracerPid:\t$gdb_pid$" $status]} { ++	set found $procpid ++	verbose -log "Found linux_test_for_tracefork zombie PID $procpid" ++    } ++} ++set test "linux_test_for_tracefork leaves no zombie" ++if {$found eq {none}} { ++    pass $test ++} else { ++    fail $test ++} diff --git a/gdb-6.5-gcore-buffer-limit-test.patch b/gdb-6.5-gcore-buffer-limit-test.patch new file mode 100644 index 0000000..07ba1e9 --- /dev/null +++ b/gdb-6.5-gcore-buffer-limit-test.patch @@ -0,0 +1,154 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-6.5-gcore-buffer-limit-test.patch + +;; Test gcore memory and time requirements for large inferiors. +;;=fedoratest + +diff --git a/gdb/testsuite/gdb.base/gcore-excessive-memory.c b/gdb/testsuite/gdb.base/gcore-excessive-memory.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/gcore-excessive-memory.c +@@ -0,0 +1,37 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++   Copyright 2008 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 2 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, write to the Free Software ++   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ ++   Please email any bugs, comments, and/or additions to this file to: ++   bug-gdb@prep.ai.mit.edu  */ ++ ++#include <unistd.h> ++#include <stdlib.h> ++ ++#define MEGS 64 ++ ++int main() ++{ ++  void *mem; ++ ++  mem = malloc (MEGS * 1024ULL * 1024ULL); ++ ++  for (;;) ++    sleep (1); ++ ++  return 0; ++} +diff --git a/gdb/testsuite/gdb.base/gcore-excessive-memory.exp b/gdb/testsuite/gdb.base/gcore-excessive-memory.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/gcore-excessive-memory.exp +@@ -0,0 +1,99 @@ ++# Copyright 2008 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 2 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, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ ++if {[use_gdb_stub]} { ++    untested "skipping test because of use_gdb_stub" ++    return -1 ++} ++ ++set testfile gcore-excessive-memory ++set srcfile ${testfile}.c ++set shfile [standard_output_file ${testfile}-gdb.sh] ++set corefile [standard_output_file ${testfile}.core] ++set binfile [standard_output_file ${testfile}] ++if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { ++    untested "Couldn't compile test program" ++    return -1 ++} ++ ++set f [open "|getconf PAGESIZE" "r"] ++gets $f pagesize ++close $f ++ ++set pid_of_bin [eval exec $binfile &] ++sleep 2 ++ ++# Get things started. ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${binfile} ++ ++set pid_of_gdb [exp_pid -i [board_info host fileid]] ++ ++gdb_test "attach $pid_of_bin" "Attaching to .*" "attach" ++gdb_test "up 99" "in main .*" "verify we can get to main" ++ ++proc memory_v_pages_get {} { ++    global pid_of_gdb pagesize ++    set fd [open "/proc/$pid_of_gdb/statm"] ++    gets $fd line ++    close $fd ++    # number of pages of virtual memory ++    scan $line "%d" drs ++    return $drs ++} ++ ++set pages_found [memory_v_pages_get] ++ ++# It must be definitely less than `MEGS' of `gcore-excessive-memory.c'. ++set mb_gcore_reserve 4 ++verbose -log "pages_found = $pages_found, mb_gcore_reserve = $mb_gcore_reserve" ++set kb_found [expr $pages_found * $pagesize / 1024] ++set kb_permit [expr $kb_found + 1 * 1024 + $mb_gcore_reserve * 1024] ++verbose -log "kb_found = $kb_found, kb_permit = $kb_permit" ++ ++# Create the ulimit wrapper. ++set f [open $shfile "w"] ++puts $f "#! /bin/sh" ++puts $f "ulimit -v $kb_permit" ++puts $f "exec $GDB \"\$@\"" ++close $f ++remote_exec host "chmod +x $shfile" ++ ++gdb_exit ++set GDBold $GDB ++set GDB "$shfile" ++gdb_start ++set GDB $GDBold ++ ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${binfile} ++ ++set pid_of_gdb [exp_pid -i [board_info host fileid]] ++ ++gdb_test "attach $pid_of_bin" "Attaching to .*" "attach" ++gdb_test "up 99" "in main .*" "verify we can get to main" ++ ++verbose -log "kb_found before gcore = [expr [memory_v_pages_get] * $pagesize / 1024]" ++ ++gdb_test "gcore $corefile" "Saved corefile \[^\n\r\]*" "Save the core file" ++ ++verbose -log "kb_found after gcore = [expr [memory_v_pages_get] * $pagesize / 1024]" ++ ++# Cleanup. ++exec kill -9 $pid_of_bin diff --git a/gdb-6.5-section-num-fixup-test.patch b/gdb-6.5-section-num-fixup-test.patch new file mode 100644 index 0000000..2fa3995 --- /dev/null +++ b/gdb-6.5-section-num-fixup-test.patch @@ -0,0 +1,127 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-6.5-section-num-fixup-test.patch + +;; Test a crash on libraries missing the .text section. +;;=fedoratest + +diff --git a/gdb/testsuite/gdb.base/datalib-lib.c b/gdb/testsuite/gdb.base/datalib-lib.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/datalib-lib.c +@@ -0,0 +1,22 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++   Copyright 2008 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 2 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, write to the Free Software ++   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ ++   Please email any bugs, comments, and/or additions to this file to: ++   bug-gdb@prep.ai.mit.edu  */ ++ ++int var; +diff --git a/gdb/testsuite/gdb.base/datalib-main.c b/gdb/testsuite/gdb.base/datalib-main.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/datalib-main.c +@@ -0,0 +1,26 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++   Copyright 2008 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 2 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, write to the Free Software ++   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ ++   Please email any bugs, comments, and/or additions to this file to: ++   bug-gdb@prep.ai.mit.edu  */ ++ ++int ++main (void) ++{ ++  return 0; ++} +diff --git a/gdb/testsuite/gdb.base/datalib.exp b/gdb/testsuite/gdb.base/datalib.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/datalib.exp +@@ -0,0 +1,56 @@ ++# Copyright 2008 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 2 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, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ ++if {[use_gdb_stub]} { ++    untested "skipping test because of use_gdb_stub" ++    return -1 ++} ++ ++set testfile datalib ++set srcfilemain ${testfile}-main.c ++set srcfilelib ${testfile}-lib.c ++set libfile [standard_output_file ${testfile}-lib.so] ++set binfile [standard_output_file ${testfile}-main] ++if  { [gdb_compile "${srcdir}/${subdir}/${srcfilelib}" "${libfile}" executable [list debug {additional_flags=-shared -nostdlib}]] != "" } { ++    untested "Couldn't compile test program" ++    return -1 ++} ++if  { [gdb_compile "${srcdir}/${subdir}/${srcfilemain}" "${binfile} ${libfile}" executable {debug}] != "" } { ++    untested "Couldn't compile test program" ++    return -1 ++} ++ ++# Get things started. ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${binfile} ++ ++# We must use a separate library as the main executable is compiled to the ++# address 0 by default and it would get fixed up already at the end of ++# INIT_OBJFILE_SECT_INDICES.  We also cannot PRELINK it as PRELINK is missing ++# on ia64.  The library must be NOSTDLIB as otherwise some stub code would ++# create the `.text' section there.  Also DEBUG option is useful as some of ++# the crashes occur in dwarf2read.c. ++ ++# FAIL case: ++# ../../gdb/ia64-tdep.c:2838: internal-error: sect_index_text not initialized ++# A problem internal to GDB has been detected, ++ ++gdb_test "start" \ ++         "main \\(\\) at .*${srcfilemain}.*" \ ++         "start" diff --git a/gdb-6.6-buildid-locate-misleading-warning-missing-debuginfo-rhbz981154.patch b/gdb-6.6-buildid-locate-misleading-warning-missing-debuginfo-rhbz981154.patch new file mode 100644 index 0000000..985cb6a --- /dev/null +++ b/gdb-6.6-buildid-locate-misleading-warning-missing-debuginfo-rhbz981154.patch @@ -0,0 +1,129 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject:  + gdb-6.6-buildid-locate-misleading-warning-missing-debuginfo-rhbz981154.patch + +;; Fix 'gdb gives highly misleading error when debuginfo pkg is present, +;; but not corresponding binary pkg' (RH BZ 981154). +;;=push+jan + +Comments by Sergio Durigan Junior <sergiodj@redhat.com>: + +  This is the fix for RH BZ #981154 + +  It is mainly a testcase addition, but a minor fix in the gdb/build-id.c +  file was also needed. + +  gdb/build-id.c was added by: + +  commit dc294be54c96414035eed7d53dafdea0a6f31a72 +  Author: Tom Tromey <tromey@redhat.com> +  Date:   Tue Oct 8 19:56:15 2013 +0000 + +  and had a little thinko there.  The variable 'filename' needs to be set to +  NULL after it is free'd, otherwise the code below thinks that it is still +  valid and doesn't print the necessary warning ("Try: yum install ..."). + +diff --git a/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp b/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp +@@ -0,0 +1,97 @@ ++#   Copyright (C) 2014  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 <http://www.gnu.org/licenses/>. ++ ++standard_testfile "normal.c" ++ ++if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } { ++    return -1 ++} ++ ++# Get the build-id of the file ++set build_id_debug_file [build_id_debug_filename_get $binfile] ++regsub -all ".debug$" $build_id_debug_file "" build_id_without_debug ++ ++# Run to main ++if { ![runto_main] } { ++    return -1 ++} ++ ++# We first need to generate a corefile ++set escapedfilename [string_to_regexp [standard_output_file gcore.test]] ++set core_supported 0 ++gdb_test_multiple "gcore [standard_output_file gcore.test]" \ ++	"save a corefile" \ ++{ ++  -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" { ++    pass "save a corefile" ++    global core_supported ++    set core_supported 1 ++  } ++  -re "Can't create a corefile\[\r\n\]+$gdb_prompt $" { ++    unsupported "save a corefile" ++    global core_supported ++    set core_supported 0 ++  } ++} ++ ++if {!$core_supported} { ++  return -1 ++} ++ ++# Move the binfile to a temporary name ++remote_exec build "mv $binfile ${binfile}.old" ++ ++# Reinitialize GDB and see if we get a yum/dnf warning ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++ ++with_test_prefix "first run:" { ++    gdb_test "set build-id-verbose 1" "" \ ++	"set build-id-verbose" ++ ++    gdb_test "set debug-file-directory [file dirname [standard_output_file gcore.test]]" "" \ ++	"set debug-file-directory" ++ ++    gdb_test "core-file [standard_output_file gcore.test]" \ ++	"Missing separate debuginfo for the main executable file\r\nTry: (yum|dnf) --enablerepo='\\*debug\\*' install [standard_output_file $build_id_without_debug]\r\n.*" \ ++	"test first yum/dnf warning" ++} ++ ++# Now we define and create our .build-id ++file mkdir [file dirname [standard_output_file ${build_id_without_debug}]] ++# Cannot use "file link" (from TCL) because it requires the target file to ++# exist. ++remote_exec build "ln -s $binfile [standard_output_file ${build_id_without_debug}]" ++ ++# Reinitialize GDB to get the second yum/dnf warning ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++ ++with_test_prefix "second run:" { ++    gdb_test "set build-id-verbose 1" "" \ ++	"set build-id-verbose" ++ ++    gdb_test "set debug-file-directory [file dirname [standard_output_file gcore.test]]" "" \ ++	"set debug-file-directory" ++ ++    gdb_test "core-file [standard_output_file gcore.test]" \ ++	"Missing separate debuginfo for the main executable file\r\nTry: (yum|dnf) --enablerepo='\\*debug\\*' install $binfile\r\n.*" \ ++	"test second yum/dnf warning" ++} ++ ++# Leaving the link there will cause breakage in the next run. ++remote_exec build "rm -f [standard_output_file ${build_id_without_debug}]" diff --git a/gdb-6.6-buildid-locate-rpm-librpm-workaround.patch b/gdb-6.6-buildid-locate-rpm-librpm-workaround.patch new file mode 100644 index 0000000..2b862a0 --- /dev/null +++ b/gdb-6.6-buildid-locate-rpm-librpm-workaround.patch @@ -0,0 +1,19 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-6.6-buildid-locate-rpm-librpm-workaround.patch + +;; Workaround librpm BZ 643031 due to its unexpected exit() calls (BZ 642879). +;;=push+jan + +diff --git a/gdb/proc-service.list b/gdb/proc-service.list +--- a/gdb/proc-service.list ++++ b/gdb/proc-service.list +@@ -37,4 +37,7 @@ +   ps_pstop; +   ps_ptread; +   ps_ptwrite; ++ ++  /* gdb-6.6-buildid-locate-rpm.patch */ ++  rpmsqEnable; + }; diff --git a/gdb-6.6-buildid-locate-rpm.patch b/gdb-6.6-buildid-locate-rpm.patch new file mode 100644 index 0000000..f38fdd5 --- /dev/null +++ b/gdb-6.6-buildid-locate-rpm.patch @@ -0,0 +1,1084 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Kevin Buettner <kevinb@redhat.com> +Date: Wed, 22 Feb 2023 22:30:40 -0700 +Subject: gdb-6.6-buildid-locate-rpm.patch + +;;=push+jan + +diff --git a/gdb/aclocal.m4 b/gdb/aclocal.m4 +--- a/gdb/aclocal.m4 ++++ b/gdb/aclocal.m4 +@@ -11,7 +11,223 @@ + # even the implied warranty of MERCHANTABILITY or FITNESS FOR A + # PARTICULAR PURPOSE. +  ++# pkg.m4 - Macros to locate and utilise pkg-config.            -*- Autoconf -*- ++# serial 1 (pkg-config-0.24) ++# ++# Copyright © 2004 Scott James Remnant <scott@netsplit.com>. ++# ++# 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 2 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, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++# ++# As a special exception to the GNU General Public License, if you ++# distribute this file as part of a program that contains a ++# configuration script generated by Autoconf, you may include it under ++# the same distribution terms that you use for the rest of that program. ++ ++# PKG_PROG_PKG_CONFIG([MIN-VERSION]) ++# ---------------------------------- ++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 ++])# PKG_PROG_PKG_CONFIG ++ ++# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) ++# ++# Check to see whether a particular set of modules exists.  Similar ++# to PKG_CHECK_MODULES(), but does not set variables or print errors. ++# ++# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) ++# only at the first occurence in configure.ac, so if the first place ++# it's called might be skipped (such as if it is within an "if", you ++# 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]) ++ ++# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) ++# --------------------------------------------- ++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 ++])# _PKG_CONFIG ++ ++# _PKG_SHORT_ERRORS_SUPPORTED ++# ----------------------------- ++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 ++])# _PKG_SHORT_ERRORS_SUPPORTED ++ ++ ++# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], ++# [ACTION-IF-NOT-FOUND]) ++# ++# ++# Note that if there is a possibility the first call to ++# PKG_CHECK_MODULES might not happen, you should be sure to include an ++# 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 $1]) ++ ++_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 <http://pkg-config.freedesktop.org/>.])[]dnl ++        ]) ++else ++	$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS ++	$1[]_LIBS=$pkg_cv_[]$1[]_LIBS ++        AC_MSG_RESULT([yes]) ++	$3 ++fi[]dnl ++])# PKG_CHECK_MODULES ++ ++ ++# PKG_INSTALLDIR(DIRECTORY) ++# ------------------------- ++# Substitutes the variable pkgconfigdir as the location where a module ++# should install pkg-config .pc files. By default the directory is ++# $libdir/pkgconfig, but the default can be changed by passing ++# DIRECTORY. The user can override through the --with-pkgconfigdir ++# 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 ++ ++ ++# PKG_NOARCH_INSTALLDIR(DIRECTORY) ++# ------------------------- ++# Substitutes the variable noarch_pkgconfigdir as the location where a ++# module should install arch-independent pkg-config .pc files. By ++# default the directory is $datadir/pkgconfig, but the default can be ++# changed by passing DIRECTORY. The user can override through the ++# --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 ++ ++ ++# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, ++# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) ++# ------------------------------------------- ++# 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 ++])# PKG_CHECK_VAR ++ + m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) ++ + # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*- +  + # Copyright (C) 2001-2017 Free Software Foundation, Inc. +diff --git a/gdb/build-id.c b/gdb/build-id.c +--- a/gdb/build-id.c ++++ b/gdb/build-id.c +@@ -780,10 +780,10 @@ missing_rpm_enlist_1 (const char *filename, int verify_vendor) +   static rpmts (*rpmtsCreate_p) (void); +   extern rpmts rpmtsFree(rpmts ts); +   static rpmts (*rpmtsFree_p) (rpmts ts); +-  extern rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmTag rpmtag, ++  extern rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmDbiTagVal rpmtag, +                                               const void * keyp, size_t keylen); +   static rpmdbMatchIterator (*rpmtsInitIterator_p) (const rpmts ts, +-						    rpmTag rpmtag, ++						    rpmDbiTagVal rpmtag, + 						    const void *keyp, + 						    size_t keylen); + #else	/* !DLOPEN_LIBRPM */ +@@ -838,7 +838,7 @@ missing_rpm_enlist_1 (const char *filename, int verify_vendor) + 	      && (rpmdbNextIterator_p = (Header (*) (rpmdbMatchIterator mi)) dlsym (h, "rpmdbNextIterator")) + 	      && (rpmtsCreate_p = (rpmts (*) (void)) dlsym (h, "rpmtsCreate")) + 	      && (rpmtsFree_p = (rpmts (*) (rpmts ts)) dlsym (h, "rpmtsFree")) +-	      && (rpmtsInitIterator_p = (rpmdbMatchIterator (*) (const rpmts ts, rpmTag rpmtag, const void *keyp, size_t keylen)) dlsym (h, "rpmtsInitIterator")))) ++	      && (rpmtsInitIterator_p = (rpmdbMatchIterator (*) (const rpmts ts, rpmDbiTagVal rpmtag, const void *keyp, size_t keylen)) dlsym (h, "rpmtsInitIterator")))) + 	  { + 	    warning (_("Opened library \"%s\" is incompatible (%s), " + 		      "missing debuginfos notifications will not be displayed"), +@@ -926,7 +926,7 @@ missing_rpm_enlist_1 (const char *filename, int verify_vendor) +  + 	  /* RPMDBI_PACKAGES requires keylen == sizeof (int).  */ + 	  /* RPMDBI_LABEL is an interface for NVR-based dbiFindByLabel().  */ +-	  mi_debuginfo = rpmtsInitIterator_p (ts, (rpmTag) RPMDBI_LABEL, debuginfo, 0); ++	  mi_debuginfo = rpmtsInitIterator_p (ts, (rpmDbiTagVal) RPMDBI_LABEL, debuginfo, 0); + 	  xfree (debuginfo); + 	  if (mi_debuginfo) + 	    { +diff --git a/gdb/config.in b/gdb/config.in +--- a/gdb/config.in ++++ b/gdb/config.in +@@ -42,6 +42,9 @@ + /* Handle .ctf type-info sections */ + #undef ENABLE_LIBCTF +  ++/* librpm version specific library name to dlopen. */ ++#undef DLOPEN_LIBRPM ++ + /* Define to 1 if translation of program messages to the user's native +    language is requested. */ + #undef ENABLE_NLS +@@ -265,6 +268,9 @@ + /* Define to 1 if you have the `m' library (-lm). */ + #undef HAVE_LIBM +  ++/* Define if librpm library is being used. */ ++#undef HAVE_LIBRPM ++ + /* Define to 1 if you have the <libunwind-ia64.h> header file. */ + #undef HAVE_LIBUNWIND_IA64_H +  +diff --git a/gdb/configure b/gdb/configure +--- a/gdb/configure ++++ b/gdb/configure +@@ -778,6 +778,11 @@ AMD_DBGAPI_CFLAGS + ENABLE_BFD_64_BIT_FALSE + ENABLE_BFD_64_BIT_TRUE + subdirs ++RPM_LIBS ++RPM_CFLAGS ++PKG_CONFIG_LIBDIR ++PKG_CONFIG_PATH ++PKG_CONFIG + GDB_DATADIR + DEBUGDIR + MAKEINFO_EXTRA_FLAGS +@@ -911,6 +916,7 @@ with_gdb_datadir + with_relocated_sources + with_auto_load_dir + with_auto_load_safe_path ++with_rpm + enable_targets + enable_64_bit_bfd + with_amd_dbgapi +@@ -988,6 +994,8 @@ AMD_DBGAPI_CFLAGS + AMD_DBGAPI_LIBS + DEBUGINFOD_CFLAGS + DEBUGINFOD_LIBS ++RPM_CFLAGS ++RPM_LIBS + YACC + YFLAGS + ZSTD_CFLAGS +@@ -1679,6 +1687,8 @@ Optional Packages: +   --with-amd-dbgapi       support for the amd-dbgapi target (yes / no / auto) +   --with-debuginfod       Enable debuginfo lookups with debuginfod +                           (auto/yes/no) ++  --with-rpm              query rpm database for missing debuginfos (yes/no, ++                          def. auto=librpm.so) +   --with-libunwind-ia64   use libunwind frame unwinding for ia64 targets +   --with-curses           use the curses library instead of the termcap +                           library +@@ -1759,6 +1769,8 @@ Some influential environment variables: +               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. +               Defaults to the first program found out of: `bison -y', `byacc', +               `yacc'. +@@ -18039,6 +18051,495 @@ _ACEOF + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_auto_load_safe_path" >&5 + $as_echo "$with_auto_load_safe_path" >&6; } +  ++# Integration with rpm library to support missing debuginfo suggestions. ++# --without-rpm: Disable any rpm support. ++# --with-rpm=libname.so: Try to dynamically open `libname.so' during runtime. ++#   Even with runtime missing `libname.so' GDB will still other run correctly. ++#   Missing `libname.so' during ./configure will abort the configuration. ++# --with-rpm=librpm.so: Like `--with-rpm=libname.so' but try to find specific ++#   minor version first such as `librpm-4.6.so' as minor version differences ++#   mean API+ABI incompatibility.  If the specific match versioned library name ++#   could not be found still open dynamically at least `librpm.so'. ++# --with-rpm: Like `--with-rpm=librpm.so' but if any of its detection fails try ++#   to find librpm for compilation-time linking by pkg-config.  GDB binary will ++#   be probably linked with the version specific library (as `librpm-4.6.so'). ++#   Failure to find librpm by pkg-config will abort the configuration. ++# (default) --with-rpm=auto: Like `--with-rpm=librpm.so' but if even pkg-config ++#   cannot find librpm use to the rpmless compilation (like `--without-rpm'). ++ ++ ++# Check whether --with-rpm was given. ++if test "${with_rpm+set}" = set; then : ++  withval=$with_rpm; ++else ++  with_rpm="auto" ++fi ++ ++ ++ ++ ++if test "x$with_rpm" != "xno"; then ++  if test "x$with_rpm" = "xyes"; then ++    LIBRPM="librpm.so" ++    RPM_REQUIRE=true ++    DLOPEN_REQUIRE=false ++  elif test "x$with_rpm" = "xauto"; then ++    LIBRPM="librpm.so" ++    RPM_REQUIRE=false ++    DLOPEN_REQUIRE=false ++  else ++    LIBRPM="$with_rpm" ++    RPM_REQUIRE=true ++    DLOPEN_REQUIRE=true ++  fi ++  LIBRPM_STRING='"'"$LIBRPM"'"' ++ ++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking specific librpm version" >&5 ++$as_echo_n "checking specific librpm version... " >&6; } ++  HAVE_DLOPEN_LIBRPM=false ++  save_LIBS="$LIBS" ++  LIBS="$LIBS -ldl" ++  if test "$cross_compiling" = yes; then : ++  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++as_fn_error "cannot run test program while cross compiling ++See \`config.log' for more details." "$LINENO" 5; } ++else ++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h.  */ ++ ++#include <rpm/rpmlib.h> ++#include <dlfcn.h> ++#include <errno.h> ++#include <string.h> ++ ++int ++main () ++{ ++ ++    void *h; ++    const char *const *rpmverp; ++    FILE *f; ++ ++    f = fopen ("conftest.out", "w"); ++    if (!f) ++      { ++	fprintf (stderr, "Cannot write \"%s\": %s\n", "conftest.out", ++		 strerror (errno)); ++	return 1; ++      } ++    h = dlopen ($LIBRPM_STRING, RTLD_LAZY); ++    if (!h) ++      { ++	fprintf (stderr, "dlopen (\"%s\"): %s\n", $LIBRPM_STRING, dlerror ()); ++	return 1; ++      } ++    rpmverp = dlsym (h, "RPMVERSION"); ++    if (!rpmverp) ++      { ++	fprintf (stderr, "dlsym (\"RPMVERSION\"): %s\n", dlerror ()); ++	return 1; ++      } ++    fprintf (stderr, "RPMVERSION is: \""); ++    fprintf (stderr, "%s\"\n", *rpmverp); ++ ++    /* Try to find the specific librpm version only for "librpm.so" as we do ++       not know how to assemble the version string otherwise.  */ ++ ++    if (strcmp ("librpm.so", $LIBRPM_STRING) != 0) ++      { ++	fprintf (f, "%s\n", $LIBRPM_STRING); ++	return 0; ++      } ++    else ++      { ++	char *h2_name; ++	void *h2; ++	int major, minor; ++ ++	if (sscanf (*rpmverp, "%d.%d", &major, &minor) != 2) ++	  { ++	    fprintf (stderr, "Unable to parse RPMVERSION.\n"); ++	    fprintf (f, "%s\n", $LIBRPM_STRING); ++	    return 0; ++	  } ++	/* Avoid the square brackets by malloc.  */ ++	h2_name = malloc (64); ++	sprintf (h2_name, "librpm-%d.%d.so", major, minor); ++	h2 = dlopen (h2_name, RTLD_LAZY); ++	if (!h2) ++	  { ++	    fprintf (stderr, "dlopen (\"%s\"): %s\n", h2_name, dlerror ()); ++	    fprintf (f, "%s\n", $LIBRPM_STRING); ++	    return 0; ++	  } ++	if (h2 != h) ++	  { ++	    fprintf (stderr, "dlopen of \"%s\" and \"%s\" are different.\n", ++		     $LIBRPM_STRING, h2_name); ++	    fprintf (f, "%s\n", $LIBRPM_STRING); ++	    return 0; ++	  } ++	/* Found the valid .so name with a specific version.  */ ++	fprintf (f, "%s\n", h2_name); ++	return 0; ++      } ++ ++  ; ++  return 0; ++} ++_ACEOF ++if ac_fn_c_try_run "$LINENO"; then : ++ ++    DLOPEN_LIBRPM="`cat conftest.out`" ++    if test "x$DLOPEN_LIBRPM" != "x"; then ++      HAVE_DLOPEN_LIBRPM=true ++      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLOPEN_LIBRPM" >&5 ++$as_echo "$DLOPEN_LIBRPM" >&6; } ++    fi ++ ++fi ++rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ ++  conftest.$ac_objext conftest.beam conftest.$ac_ext ++fi ++ ++  rm -f conftest.out ++ ++ ++ ++  if $HAVE_DLOPEN_LIBRPM; then ++ ++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking rpm library API compatibility" >&5 ++$as_echo_n "checking rpm library API compatibility... " >&6; } ++    # The compilation requires -Werror to verify anything. ++    save_CFLAGS="$CFLAGS" ++    CFLAGS="$CFLAGS -Werror" ++    cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h.  */ ++ ++/* Duplicate here the declarations to verify they match "elfread.c".  */ ++#include <rpm/rpmlib.h> ++#include <rpm/rpmts.h> ++#include <rpm/rpmdb.h> ++#include <rpm/header.h> ++extern char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg); ++extern int rpmReadConfigFiles(const char * file, const char * target); ++extern rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi); ++extern Header rpmdbNextIterator(rpmdbMatchIterator mi); ++extern rpmts rpmtsCreate(void); ++extern rpmts rpmtsFree(rpmts ts); ++extern rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmDbiTagVal rpmtag, ++					    const void * keyp, size_t keylen); ++ ++int ++main () ++{ ++ ++  ; ++  return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ++      LIBRPM_COMPAT=true ++      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ ++else ++ ++      LIBRPM_COMPAT=false ++      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++    CFLAGS="$save_CFLAGS" ++ ++    if ! $LIBRPM_COMPAT; then ++      HAVE_DLOPEN_LIBRPM=false ++    fi ++  fi ++ ++  if $HAVE_DLOPEN_LIBRPM; then ++    DLOPEN_LIBRPM_STRING='"'"$DLOPEN_LIBRPM"'"' ++ ++cat >>confdefs.h <<_ACEOF ++#define DLOPEN_LIBRPM $DLOPEN_LIBRPM_STRING ++_ACEOF ++ ++ ++$as_echo "#define HAVE_LIBRPM 1" >>confdefs.h ++ ++  else ++    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++    LIBS="$save_LIBS" ++    if $DLOPEN_REQUIRE; then ++      as_fn_error "Specific name $LIBRPM was requested but it could not be opened." "$LINENO" 5 ++    fi ++ ++ ++ ++ ++ ++ ++ ++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 test "${ac_cv_path_PKG_CONFIG+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$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 test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$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 ++ ++pkg_failed=no ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for RPM" >&5 ++$as_echo_n "checking for RPM... " >&6; } ++ ++if test -n "$RPM_CFLAGS"; then ++    pkg_cv_RPM_CFLAGS="$RPM_CFLAGS" ++ elif test -n "$PKG_CONFIG"; then ++    if test -n "$PKG_CONFIG" && \ ++    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"rpm\""; } >&5 ++  ($PKG_CONFIG --exists --print-errors "rpm") 2>&5 ++  ac_status=$? ++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++  test $ac_status = 0; }; then ++  pkg_cv_RPM_CFLAGS=`$PKG_CONFIG --cflags "rpm" 2>/dev/null` ++		      test "x$?" != "x0" && pkg_failed=yes ++else ++  pkg_failed=yes ++fi ++ else ++    pkg_failed=untried ++fi ++if test -n "$RPM_LIBS"; then ++    pkg_cv_RPM_LIBS="$RPM_LIBS" ++ elif test -n "$PKG_CONFIG"; then ++    if test -n "$PKG_CONFIG" && \ ++    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"rpm\""; } >&5 ++  ($PKG_CONFIG --exists --print-errors "rpm") 2>&5 ++  ac_status=$? ++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++  test $ac_status = 0; }; then ++  pkg_cv_RPM_LIBS=`$PKG_CONFIG --libs "rpm" 2>/dev/null` ++		      test "x$?" != "x0" && pkg_failed=yes ++else ++  pkg_failed=yes ++fi ++ else ++    pkg_failed=untried ++fi ++ ++ ++ ++if test $pkg_failed = yes; then ++        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ ++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 ++	        RPM_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "rpm" 2>&1` ++        else ++	        RPM_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "rpm" 2>&1` ++        fi ++	# Put the nasty error message in config.log where it belongs ++	echo "$RPM_PKG_ERRORS" >&5 ++ ++	HAVE_LIBRPM=false ++elif test $pkg_failed = untried; then ++        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++	HAVE_LIBRPM=false ++else ++	RPM_CFLAGS=$pkg_cv_RPM_CFLAGS ++	RPM_LIBS=$pkg_cv_RPM_LIBS ++        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++	HAVE_LIBRPM=true ++fi ++ ++    if $HAVE_LIBRPM; then ++ ++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking rpm library API compatibility" >&5 ++$as_echo_n "checking rpm library API compatibility... " >&6; } ++    # The compilation requires -Werror to verify anything. ++    save_CFLAGS="$CFLAGS" ++    CFLAGS="$CFLAGS -Werror" ++    cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h.  */ ++ ++/* Duplicate here the declarations to verify they match "elfread.c".  */ ++#include <rpm/rpmlib.h> ++#include <rpm/rpmts.h> ++#include <rpm/rpmdb.h> ++#include <rpm/header.h> ++extern char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg); ++extern int rpmReadConfigFiles(const char * file, const char * target); ++extern rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi); ++extern Header rpmdbNextIterator(rpmdbMatchIterator mi); ++extern rpmts rpmtsCreate(void); ++extern rpmts rpmtsFree(rpmts ts); ++extern rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmDbiTagVal rpmtag, ++					    const void * keyp, size_t keylen); ++ ++int ++main () ++{ ++ ++  ; ++  return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ++      LIBRPM_COMPAT=true ++      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ ++else ++ ++      LIBRPM_COMPAT=false ++      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++    CFLAGS="$save_CFLAGS" ++ ++      if ! $LIBRPM_COMPAT; then ++	HAVE_LIBRPM=false ++	RPM_PKG_ERRORS="Found $LIBRPM API is incompatibile with this GDB" ++      fi ++    fi ++ ++    if $HAVE_LIBRPM; then ++ ++$as_echo "#define HAVE_LIBRPM 1" >>confdefs.h ++ ++      CFLAGS="$CFLAGS $RPM_CFLAGS" ++      LIBS="$LIBS $RPM_LIBS" ++    else ++      if $RPM_REQUIRE; then ++	as_fn_error "$RPM_PKG_ERRORS" "$LINENO" 5 ++      else ++	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $RPM_PKG_ERRORS" >&5 ++$as_echo "$as_me: WARNING: $RPM_PKG_ERRORS" >&2;} ++      fi ++    fi ++  fi ++fi ++ +  +  + subdirs="$subdirs testsuite" +diff --git a/gdb/configure.ac b/gdb/configure.ac +--- a/gdb/configure.ac ++++ b/gdb/configure.ac +@@ -173,6 +173,200 @@ AC_DEFINE_DIR(AUTO_LOAD_SAFE_PATH, escape_dir, + 	      [Directories safe to hold auto-loaded files.]) + AC_MSG_RESULT([$with_auto_load_safe_path]) +  ++# Integration with rpm library to support missing debuginfo suggestions. ++# --without-rpm: Disable any rpm support. ++# --with-rpm=libname.so: Try to dynamically open `libname.so' during runtime. ++#   Even with runtime missing `libname.so' GDB will still other run correctly. ++#   Missing `libname.so' during ./configure will abort the configuration. ++# --with-rpm=librpm.so: Like `--with-rpm=libname.so' but try to find specific ++#   minor version first such as `librpm-4.6.so' as minor version differences ++#   mean API+ABI incompatibility.  If the specific match versioned library name ++#   could not be found still open dynamically at least `librpm.so'. ++# --with-rpm: Like `--with-rpm=librpm.so' but if any of its detection fails try ++#   to find librpm for compilation-time linking by pkg-config.  GDB binary will ++#   be probably linked with the version specific library (as `librpm-4.6.so'). ++#   Failure to find librpm by pkg-config will abort the configuration. ++# (default) --with-rpm=auto: Like `--with-rpm=librpm.so' but if even pkg-config ++#   cannot find librpm use to the rpmless compilation (like `--without-rpm'). ++ ++AC_ARG_WITH([rpm], ++  [AS_HELP_STRING([--with-rpm], ++                  [query rpm database for missing debuginfos (yes/no, def. auto=librpm.so)])], [], [with_rpm="auto"]) ++ ++m4_pattern_allow([^AC_MSG_ERROR$]) ++m4_pattern_allow([^AC_MSG_WARN$]) ++if test "x$with_rpm" != "xno"; then ++  if test "x$with_rpm" = "xyes"; then ++    LIBRPM="librpm.so" ++    RPM_REQUIRE=true ++    DLOPEN_REQUIRE=false ++  elif test "x$with_rpm" = "xauto"; then ++    LIBRPM="librpm.so" ++    RPM_REQUIRE=false ++    DLOPEN_REQUIRE=false ++  else ++    LIBRPM="$with_rpm" ++    RPM_REQUIRE=true ++    DLOPEN_REQUIRE=true ++  fi ++  LIBRPM_STRING='"'"$LIBRPM"'"' ++ ++  AC_MSG_CHECKING([specific librpm version]) ++  HAVE_DLOPEN_LIBRPM=false ++  save_LIBS="$LIBS" ++  LIBS="$LIBS -ldl" ++  AC_RUN_IFELSE(AC_LANG_PROGRAM([[ ++#include <rpm/rpmlib.h> ++#include <dlfcn.h> ++#include <errno.h> ++#include <string.h> ++  ]], [[ ++    void *h; ++    const char *const *rpmverp; ++    FILE *f; ++ ++    f = fopen ("conftest.out", "w"); ++    if (!f) ++      { ++	fprintf (stderr, "Cannot write \"%s\": %s\n", "conftest.out", ++		 strerror (errno)); ++	return 1; ++      } ++    h = dlopen ($LIBRPM_STRING, RTLD_LAZY); ++    if (!h) ++      { ++	fprintf (stderr, "dlopen (\"%s\"): %s\n", $LIBRPM_STRING, dlerror ()); ++	return 1; ++      } ++    rpmverp = dlsym (h, "RPMVERSION"); ++    if (!rpmverp) ++      { ++	fprintf (stderr, "dlsym (\"RPMVERSION\"): %s\n", dlerror ()); ++	return 1; ++      } ++    fprintf (stderr, "RPMVERSION is: \""); ++    fprintf (stderr, "%s\"\n", *rpmverp); ++ ++    /* Try to find the specific librpm version only for "librpm.so" as we do ++       not know how to assemble the version string otherwise.  */ ++ ++    if (strcmp ("librpm.so", $LIBRPM_STRING) != 0) ++      { ++	fprintf (f, "%s\n", $LIBRPM_STRING); ++	return 0; ++      } ++    else ++      { ++	char *h2_name; ++	void *h2; ++	int major, minor; ++ ++	if (sscanf (*rpmverp, "%d.%d", &major, &minor) != 2) ++	  { ++	    fprintf (stderr, "Unable to parse RPMVERSION.\n"); ++	    fprintf (f, "%s\n", $LIBRPM_STRING); ++	    return 0; ++	  } ++	/* Avoid the square brackets by malloc.  */ ++	h2_name = malloc (64); ++	sprintf (h2_name, "librpm-%d.%d.so", major, minor); ++	h2 = dlopen (h2_name, RTLD_LAZY); ++	if (!h2) ++	  { ++	    fprintf (stderr, "dlopen (\"%s\"): %s\n", h2_name, dlerror ()); ++	    fprintf (f, "%s\n", $LIBRPM_STRING); ++	    return 0; ++	  } ++	if (h2 != h) ++	  { ++	    fprintf (stderr, "dlopen of \"%s\" and \"%s\" are different.\n", ++		     $LIBRPM_STRING, h2_name); ++	    fprintf (f, "%s\n", $LIBRPM_STRING); ++	    return 0; ++	  } ++	/* Found the valid .so name with a specific version.  */ ++	fprintf (f, "%s\n", h2_name); ++	return 0; ++      } ++  ]]), [ ++    DLOPEN_LIBRPM="`cat conftest.out`" ++    if test "x$DLOPEN_LIBRPM" != "x"; then ++      HAVE_DLOPEN_LIBRPM=true ++      AC_MSG_RESULT($DLOPEN_LIBRPM) ++    fi ++  ]) ++  rm -f conftest.out ++ ++  m4_define([CHECK_LIBRPM_COMPAT], [ ++    AC_MSG_CHECKING([rpm library API compatibility]) ++    # The compilation requires -Werror to verify anything. ++    save_CFLAGS="$CFLAGS" ++    CFLAGS="$CFLAGS -Werror" ++    AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[ ++/* Duplicate here the declarations to verify they match "elfread.c".  */ ++#include <rpm/rpmlib.h> ++#include <rpm/rpmts.h> ++#include <rpm/rpmdb.h> ++#include <rpm/header.h> ++extern char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg); ++extern int rpmReadConfigFiles(const char * file, const char * target); ++extern rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi); ++extern Header rpmdbNextIterator(rpmdbMatchIterator mi); ++extern rpmts rpmtsCreate(void); ++extern rpmts rpmtsFree(rpmts ts); ++extern rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmDbiTagVal rpmtag, ++					    const void * keyp, size_t keylen); ++    ]]), [ ++      LIBRPM_COMPAT=true ++      AC_MSG_RESULT(yes) ++    ], [ ++      LIBRPM_COMPAT=false ++      AC_MSG_RESULT(no) ++    ]) ++    CFLAGS="$save_CFLAGS" ++  ]) ++ ++  if $HAVE_DLOPEN_LIBRPM; then ++    CHECK_LIBRPM_COMPAT ++    if ! $LIBRPM_COMPAT; then ++      HAVE_DLOPEN_LIBRPM=false ++    fi ++  fi ++ ++  if $HAVE_DLOPEN_LIBRPM; then ++    DLOPEN_LIBRPM_STRING='"'"$DLOPEN_LIBRPM"'"' ++    AC_DEFINE_UNQUOTED(DLOPEN_LIBRPM, $DLOPEN_LIBRPM_STRING, [librpm version specific library name to dlopen.]) ++    AC_DEFINE(HAVE_LIBRPM, 1, [Define if librpm library is being used.]) ++  else ++    AC_MSG_RESULT(no) ++    LIBS="$save_LIBS" ++    if $DLOPEN_REQUIRE; then ++      AC_MSG_ERROR([Specific name $LIBRPM was requested but it could not be opened.]) ++    fi ++    PKG_CHECK_MODULES(RPM, rpm, [HAVE_LIBRPM=true], [HAVE_LIBRPM=false]) ++ ++    if $HAVE_LIBRPM; then ++      CHECK_LIBRPM_COMPAT ++      if ! $LIBRPM_COMPAT; then ++	HAVE_LIBRPM=false ++	RPM_PKG_ERRORS="Found $LIBRPM API is incompatibile with this GDB" ++      fi ++    fi ++ ++    if $HAVE_LIBRPM; then ++      AC_DEFINE(HAVE_LIBRPM, 1, [Define if librpm library is being used.]) ++      CFLAGS="$CFLAGS $RPM_CFLAGS" ++      LIBS="$LIBS $RPM_LIBS" ++    else ++      if $RPM_REQUIRE; then ++	AC_MSG_ERROR($RPM_PKG_ERRORS) ++      else ++	AC_MSG_WARN($RPM_PKG_ERRORS) ++      fi ++    fi ++  fi ++fi ++ + AC_CONFIG_SUBDIRS(testsuite) +  + # Check whether to support alternative target configurations +diff --git a/gdb/event-top.c b/gdb/event-top.c +--- a/gdb/event-top.c ++++ b/gdb/event-top.c +@@ -43,6 +43,7 @@ + #include "async-event.h" + #include "bt-utils.h" + #include "pager.h" ++#include "symfile.h" +  + /* readline include files.  */ + #include "readline/readline.h" +@@ -404,6 +405,8 @@ display_gdb_prompt (const char *new_prompt) +   /* Reset the nesting depth used when trace-commands is set.  */ +   reset_command_nest_depth (); +  ++  debug_flush_missing (); ++ +   /* Do not call the python hook on an explicit prompt change as +      passed to this function, as this forms a secondary/local prompt, +      IE, displayed but not set.  */ +@@ -788,7 +791,10 @@ command_line_handler (gdb::unique_xmalloc_ptr<char> &&rl) +       command_handler (cmd); +  +       if (ui->prompt_state != PROMPTED) +-	display_gdb_prompt (0); ++	{ ++	  debug_flush_missing (); ++	  display_gdb_prompt (0); ++	} +     } + } +  +diff --git a/gdb/symfile.h b/gdb/symfile.h +--- a/gdb/symfile.h ++++ b/gdb/symfile.h +@@ -367,6 +367,7 @@ extern void generic_load (const char *args, int from_tty); + /* build-id support.  */ + extern struct bfd_build_id *build_id_addr_get (CORE_ADDR addr); + extern void debug_print_missing (const char *binary, const char *debug); ++extern void debug_flush_missing (void); + #define BUILD_ID_MAIN_EXECUTABLE_FILENAME _("the main executable file") +  + /* From minidebug.c.  */ diff --git a/gdb-6.6-buildid-locate-solib-missing-ids.patch b/gdb-6.6-buildid-locate-solib-missing-ids.patch new file mode 100644 index 0000000..e9ec7b5 --- /dev/null +++ b/gdb-6.6-buildid-locate-solib-missing-ids.patch @@ -0,0 +1,238 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-6.6-buildid-locate-solib-missing-ids.patch + +;; Fix loading of core files without build-ids but with build-ids in executables. +;; Load strictly build-id-checked core files only if no executable is specified +;; (Jan Kratochvil, RH BZ 1339862). +;;=push+jan + +gdb returns an incorrect back trace when applying a debuginfo +https://bugzilla.redhat.com/show_bug.cgi?id=1339862 + +diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c +--- a/gdb/solib-svr4.c ++++ b/gdb/solib-svr4.c +@@ -1320,14 +1320,28 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm, + 	} +  +       { +-	struct bfd_build_id *build_id; ++	struct bfd_build_id *build_id = NULL; +  + 	strncpy (newobj->so_original_name, buffer.get (), SO_NAME_MAX_PATH_SIZE - 1); + 	newobj->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; + 	/* May get overwritten below.  */ + 	strcpy (newobj->so_name, newobj->so_original_name); +  +-	build_id = build_id_addr_get (((lm_info_svr4 *) newobj->lm_info)->l_ld); ++	/* In the case the main executable was found according to its build-id ++	   (from a core file) prevent loading a different build of a library ++	   with accidentally the same SO_NAME. ++ ++	   It suppresses bogus backtraces (and prints "??" there instead) if ++	   the on-disk files no longer match the running program version. ++ ++	   If the main executable was not loaded according to its build-id do ++	   not do any build-id checking of the libraries.  There may be missing ++	   build-ids dumped in the core file and we would map all the libraries ++	   to the only existing file loaded that time - the executable.  */ ++	if (current_program_space->symfile_object_file != NULL ++	    && (current_program_space->symfile_object_file->flags ++	         & OBJF_BUILD_ID_CORE_LOADED) != 0) ++	  build_id = build_id_addr_get (li->l_ld); + 	if (build_id != NULL) + 	  { + 	    char *name, *build_id_filename; +@@ -1342,23 +1356,7 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm, + 		xfree (name); + 	      } + 	    else +-	      { +-		debug_print_missing (newobj->so_name, build_id_filename); +- +-		/* In the case the main executable was found according to +-		   its build-id (from a core file) prevent loading +-		   a different build of a library with accidentally the +-		   same SO_NAME. +- +-		   It suppresses bogus backtraces (and prints "??" there +-		   instead) if the on-disk files no longer match the +-		   running program version.  */ +- +-		if (current_program_space->symfile_object_file != NULL +-		    && (current_program_space->symfile_object_file->flags +-			& OBJF_BUILD_ID_CORE_LOADED) != 0) +-		  newobj->so_name[0] = 0; +-	      } ++	      debug_print_missing (newobj->so_name, build_id_filename); +  + 	    xfree (build_id_filename); + 	    xfree (build_id); +diff --git a/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-lib.c b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-lib.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-lib.c +@@ -0,0 +1,21 @@ ++/* Copyright 2010 Free Software Foundation, Inc. ++ ++   This file is part of GDB. ++ ++   This program is free software; you can redistribute it and/or modify ++   it under the terms of the GNU General Public License as published by ++   the Free Software Foundation; either version 3 of the License, or ++   (at your option) any later version. ++ ++   This program is distributed in the hope that it will be useful, ++   but WITHOUT ANY WARRANTY; without even the implied warranty of ++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the ++   GNU General Public License for more details. ++ ++   You should have received a copy of the GNU General Public License ++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ ++ ++void ++lib (void) ++{ ++} +diff --git a/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-main.c b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-main.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-main.c +@@ -0,0 +1,25 @@ ++/* Copyright 2010 Free Software Foundation, Inc. ++ ++   This file is part of GDB. ++ ++   This program is free software; you can redistribute it and/or modify ++   it under the terms of the GNU General Public License as published by ++   the Free Software Foundation; either version 3 of the License, or ++   (at your option) any later version. ++ ++   This program is distributed in the hope that it will be useful, ++   but WITHOUT ANY WARRANTY; without even the implied warranty of ++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the ++   GNU General Public License for more details. ++ ++   You should have received a copy of the GNU General Public License ++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ ++ ++extern void lib (void); ++ ++int ++main (void) ++{ ++  lib (); ++  return 0; ++} +diff --git a/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp +@@ -0,0 +1,105 @@ ++# Copyright 2016 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 <http://www.gnu.org/licenses/>. ++ ++if {[skip_shlib_tests]} { ++    return 0 ++} ++ ++set testfile "gcore-buildid-exec-but-not-solib" ++set srcmainfile ${testfile}-main.c ++set srclibfile ${testfile}-lib.c ++set libfile [standard_output_file ${testfile}-lib.so] ++set objfile [standard_output_file ${testfile}-main.o] ++set executable ${testfile}-main ++set binfile [standard_output_file ${executable}] ++set gcorefile [standard_output_file ${executable}.gcore] ++set outdir [file dirname $binfile] ++ ++if { [gdb_compile_shlib ${srcdir}/${subdir}/${srclibfile} ${libfile} "debug additional_flags=-Wl,--build-id"] != "" ++     || [gdb_compile ${srcdir}/${subdir}/${srcmainfile} ${objfile} object {debug}] != "" } { ++     unsupported "-Wl,--build-id compilation failed" ++     return -1 ++} ++set opts [list debug shlib=${libfile} "additional_flags=-Wl,--build-id"] ++if { [gdb_compile ${objfile} ${binfile} executable $opts] != "" } { ++     unsupported "-Wl,--build-id compilation failed" ++     return -1 ++} ++ ++clean_restart $executable ++gdb_load_shlib $libfile ++ ++# Does this gdb support gcore? ++set test "help gcore" ++gdb_test_multiple $test $test { ++    -re "Undefined command: .gcore.*\r\n$gdb_prompt $" { ++	# gcore command not supported -- nothing to test here. ++	unsupported "gdb does not support gcore on this target" ++	return -1; ++    } ++    -re "Save a core file .*\r\n$gdb_prompt $" { ++	pass $test ++    } ++} ++ ++if { ![runto lib] } then { ++    return -1 ++} ++ ++set escapedfilename [string_to_regexp ${gcorefile}] ++ ++set test "save a corefile" ++gdb_test_multiple "gcore ${gcorefile}" $test { ++    -re "Saved corefile ${escapedfilename}\r\n$gdb_prompt $" { ++	pass $test ++    } ++    -re "Can't create a corefile\r\n$gdb_prompt $" { ++	unsupported $test ++	return -1 ++    } ++} ++ ++# Now restart gdb and load the corefile. ++ ++clean_restart $executable ++gdb_load_shlib $libfile ++ ++set buildid [build_id_debug_filename_get $libfile] ++ ++regsub {\.debug$} $buildid {} buildid ++ ++set debugdir [standard_output_file ${testfile}-debugdir] ++file delete -force -- $debugdir ++ ++file mkdir $debugdir/[file dirname $libfile] ++file copy $libfile $debugdir/${libfile} ++ ++file mkdir $debugdir/[file dirname $buildid] ++file copy $libfile $debugdir/${buildid} ++ ++remote_exec build "ln -s /lib       ${debugdir}/" ++remote_exec build "ln -s /lib64     ${debugdir}/" ++# /usr is not needed, all the libs are in /lib64: libm.so.6 libc.so.6 ld-linux-x86-64.so.2 ++ ++gdb_test "set solib-absolute-prefix $debugdir" ++ ++gdb_test_no_output "set debug-file-directory $debugdir" "set debug-file-directory" ++ ++gdb_test "core ${gcorefile}" "Core was generated by .*" "re-load generated corefile" ++ ++gdb_test "frame" "#0 \[^\r\n\]* lib .*" "library got loaded" ++ ++gdb_test "bt" ++gdb_test "info shared" diff --git a/gdb-6.6-buildid-locate.patch b/gdb-6.6-buildid-locate.patch new file mode 100644 index 0000000..1350051 --- /dev/null +++ b/gdb-6.6-buildid-locate.patch @@ -0,0 +1,1925 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-6.6-buildid-locate.patch + +;; New locating of the matching binaries from the pure core file (build-id). +;;=push+jan + +diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h +--- a/bfd/libbfd-in.h ++++ b/bfd/libbfd-in.h +@@ -110,7 +110,7 @@ static inline char * + bfd_strdup (const char *str) + { +   size_t len = strlen (str) + 1; +-  char *buf = bfd_malloc (len); ++  char *buf = (char *) bfd_malloc (len); +   if (buf != NULL) +     memcpy (buf, str, len); +   return buf; +diff --git a/bfd/libbfd.h b/bfd/libbfd.h +--- a/bfd/libbfd.h ++++ b/bfd/libbfd.h +@@ -116,7 +116,7 @@ static inline char * + bfd_strdup (const char *str) + { +   size_t len = strlen (str) + 1; +-  char *buf = bfd_malloc (len); ++  char *buf = (char *) bfd_malloc (len); +   if (buf != NULL) +     memcpy (buf, str, len); +   return buf; +diff --git a/gdb/build-id.c b/gdb/build-id.c +--- a/gdb/build-id.c ++++ b/gdb/build-id.c +@@ -24,14 +24,72 @@ + #include "gdbsupport/gdb_vecs.h" + #include "symfile.h" + #include "objfiles.h" ++#include <sys/stat.h> ++#include "elf-bfd.h" ++#include "elf/common.h" ++#include "elf/external.h" ++#include "elf/internal.h" + #include "filenames.h" ++#include "gdb_bfd.h" ++#include "gdbcmd.h" + #include "gdbcore.h" + #include "cli/cli-style.h" ++#include "inferior.h" ++#include "objfiles.h" ++#include "observable.h" ++#include "symfile.h" ++ ++#define BUILD_ID_VERBOSE_NONE 0 ++#define BUILD_ID_VERBOSE_FILENAMES 1 ++#define BUILD_ID_VERBOSE_BINARY_PARSE 2 ++static int build_id_verbose = BUILD_ID_VERBOSE_FILENAMES; ++static void ++show_build_id_verbose (struct ui_file *file, int from_tty, ++		       struct cmd_list_element *c, const char *value) ++{ ++  gdb_printf (file, _("Verbosity level of the build-id locator is %s.\n"), ++	      value); ++} ++/* Locate NT_GNU_BUILD_ID and return its matching debug filename. ++   FIXME: NOTE decoding should be unified with the BFD core notes decoding.  */ ++ ++static struct bfd_build_id * ++build_id_buf_get (bfd *templ, gdb_byte *buf, bfd_size_type size) ++{ ++  bfd_byte *p; ++ ++  p = buf; ++  while (p < buf + size) ++    { ++      /* FIXME: bad alignment assumption.  */ ++      Elf_External_Note *xnp = (Elf_External_Note *) p; ++      size_t namesz = H_GET_32 (templ, xnp->namesz); ++      size_t descsz = H_GET_32 (templ, xnp->descsz); ++      bfd_byte *descdata = (gdb_byte *) xnp->name + BFD_ALIGN (namesz, 4); ++ ++      if (H_GET_32 (templ, xnp->type) == NT_GNU_BUILD_ID ++	  && namesz == sizeof "GNU" ++	  && memcmp (xnp->name, "GNU", sizeof "GNU") == 0) ++	{ ++	  size_t sz = descsz; ++	  gdb_byte *data = (gdb_byte *) descdata; ++	  struct bfd_build_id *retval; ++ ++	  retval = (struct bfd_build_id *) xmalloc (sizeof *retval - 1 + sz); ++	  retval->size = sz; ++	  memcpy (retval->data, data, sz); ++ ++	  return retval; ++	} ++      p = descdata + BFD_ALIGN (descsz, 4); ++    } ++  return NULL; ++} +  + /* See build-id.h.  */ +  + const struct bfd_build_id * +-build_id_bfd_get (bfd *abfd) ++build_id_bfd_shdr_get (bfd *abfd) + { +   /* Dynamic objfiles such as ones created by JIT reader API +      have no underlying bfd structure (that is, objfile->obfd +@@ -50,6 +108,348 @@ build_id_bfd_get (bfd *abfd) +   return NULL; + } +  ++/* Core files may have missing (corrupt) SHDR but PDHR is correct there. ++   bfd_elf_bfd_from_remote_memory () has too much overhead by ++   allocating/reading all the available ELF PT_LOADs.  */ ++ ++static struct bfd_build_id * ++build_id_phdr_get (bfd *templ, bfd_vma loadbase, unsigned e_phnum, ++		   Elf_Internal_Phdr *i_phdr) ++{ ++  int i; ++  struct bfd_build_id *retval = NULL; ++ ++  for (i = 0; i < e_phnum; i++) ++    if (i_phdr[i].p_type == PT_NOTE && i_phdr[i].p_filesz > 0) ++      { ++	Elf_Internal_Phdr *hdr = &i_phdr[i]; ++	gdb_byte *buf; ++	int err; ++ ++	buf = (gdb_byte *) xmalloc (hdr->p_filesz); ++	err = target_read_memory (loadbase + i_phdr[i].p_vaddr, buf, ++				  hdr->p_filesz); ++	if (err == 0) ++	  retval = build_id_buf_get (templ, buf, hdr->p_filesz); ++	else ++	  retval = NULL; ++	xfree (buf); ++	if (retval != NULL) ++	  break; ++      } ++  return retval; ++} ++ ++/* First we validate the file by reading in the ELF header and checking ++   the magic number.  */ ++ ++static inline bfd_boolean ++elf_file_p (Elf64_External_Ehdr *x_ehdrp64) ++{ ++  gdb_assert (sizeof (Elf64_External_Ehdr) >= sizeof (Elf32_External_Ehdr)); ++  gdb_assert (offsetof (Elf64_External_Ehdr, e_ident) ++	      == offsetof (Elf32_External_Ehdr, e_ident)); ++  gdb_assert (sizeof (((Elf64_External_Ehdr *) 0)->e_ident) ++	      == sizeof (((Elf32_External_Ehdr *) 0)->e_ident)); ++ ++  return ((x_ehdrp64->e_ident[EI_MAG0] == ELFMAG0) ++	  && (x_ehdrp64->e_ident[EI_MAG1] == ELFMAG1) ++	  && (x_ehdrp64->e_ident[EI_MAG2] == ELFMAG2) ++	  && (x_ehdrp64->e_ident[EI_MAG3] == ELFMAG3)); ++} ++ ++/* Translate an ELF file header in external format into an ELF file header in ++   internal format.  */ ++ ++#define H_GET_WORD(bfd, ptr) (is64 ? H_GET_64 (bfd, (ptr))		\ ++				   : H_GET_32 (bfd, (ptr))) ++#define H_GET_SIGNED_WORD(bfd, ptr) (is64 ? H_GET_S64 (bfd, (ptr))	\ ++					  : H_GET_S32 (bfd, (ptr))) ++ ++static void ++elf_swap_ehdr_in (bfd *abfd, ++		  const Elf64_External_Ehdr *src64, ++		  Elf_Internal_Ehdr *dst) ++{ ++  int is64 = bfd_get_arch_size (abfd) == 64; ++#define SRC(field) (is64 ? src64->field \ ++			 : ((const Elf32_External_Ehdr *) src64)->field) ++ ++  int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma; ++  memcpy (dst->e_ident, SRC (e_ident), EI_NIDENT); ++  dst->e_type = H_GET_16 (abfd, SRC (e_type)); ++  dst->e_machine = H_GET_16 (abfd, SRC (e_machine)); ++  dst->e_version = H_GET_32 (abfd, SRC (e_version)); ++  if (signed_vma) ++    dst->e_entry = H_GET_SIGNED_WORD (abfd, SRC (e_entry)); ++  else ++    dst->e_entry = H_GET_WORD (abfd, SRC (e_entry)); ++  dst->e_phoff = H_GET_WORD (abfd, SRC (e_phoff)); ++  dst->e_shoff = H_GET_WORD (abfd, SRC (e_shoff)); ++  dst->e_flags = H_GET_32 (abfd, SRC (e_flags)); ++  dst->e_ehsize = H_GET_16 (abfd, SRC (e_ehsize)); ++  dst->e_phentsize = H_GET_16 (abfd, SRC (e_phentsize)); ++  dst->e_phnum = H_GET_16 (abfd, SRC (e_phnum)); ++  dst->e_shentsize = H_GET_16 (abfd, SRC (e_shentsize)); ++  dst->e_shnum = H_GET_16 (abfd, SRC (e_shnum)); ++  dst->e_shstrndx = H_GET_16 (abfd, SRC (e_shstrndx)); ++ ++#undef SRC ++} ++ ++/* Translate an ELF program header table entry in external format into an ++   ELF program header table entry in internal format.  */ ++ ++static void ++elf_swap_phdr_in (bfd *abfd, ++		  const Elf64_External_Phdr *src64, ++		  Elf_Internal_Phdr *dst) ++{ ++  int is64 = bfd_get_arch_size (abfd) == 64; ++#define SRC(field) (is64 ? src64->field					\ ++			 : ((const Elf32_External_Phdr *) src64)->field) ++ ++  int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma; ++ ++  dst->p_type = H_GET_32 (abfd, SRC (p_type)); ++  dst->p_flags = H_GET_32 (abfd, SRC (p_flags)); ++  dst->p_offset = H_GET_WORD (abfd, SRC (p_offset)); ++  if (signed_vma) ++    { ++      dst->p_vaddr = H_GET_SIGNED_WORD (abfd, SRC (p_vaddr)); ++      dst->p_paddr = H_GET_SIGNED_WORD (abfd, SRC (p_paddr)); ++    } ++  else ++    { ++      dst->p_vaddr = H_GET_WORD (abfd, SRC (p_vaddr)); ++      dst->p_paddr = H_GET_WORD (abfd, SRC (p_paddr)); ++    } ++  dst->p_filesz = H_GET_WORD (abfd, SRC (p_filesz)); ++  dst->p_memsz = H_GET_WORD (abfd, SRC (p_memsz)); ++  dst->p_align = H_GET_WORD (abfd, SRC (p_align)); ++ ++#undef SRC ++} ++ ++#undef H_GET_SIGNED_WORD ++#undef H_GET_WORD ++ ++static Elf_Internal_Phdr * ++elf_get_phdr (bfd *templ, bfd_vma ehdr_vma, unsigned *e_phnum_pointer, ++              bfd_vma *loadbase_pointer) ++{ ++  /* sizeof (Elf64_External_Ehdr) >= sizeof (Elf32_External_Ehdr)  */ ++  Elf64_External_Ehdr x_ehdr64;	/* Elf file header, external form */ ++  Elf_Internal_Ehdr i_ehdr;	/* Elf file header, internal form */ ++  bfd_size_type x_phdrs_size; ++  gdb_byte *x_phdrs_ptr; ++  Elf_Internal_Phdr *i_phdrs; ++  int err; ++  unsigned int i; ++  bfd_vma loadbase; ++  int loadbase_set; ++ ++  gdb_assert (templ != NULL); ++  gdb_assert (sizeof (Elf64_External_Ehdr) >= sizeof (Elf32_External_Ehdr)); ++ ++  /* Read in the ELF header in external format.  */ ++  err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr64, sizeof x_ehdr64); ++  if (err) ++    { ++      if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) ++        warning (_("build-id: Error reading ELF header at address 0x%lx"), ++		 (unsigned long) ehdr_vma); ++      return NULL; ++    } ++ ++  /* Now check to see if we have a valid ELF file, and one that BFD can ++     make use of.  The magic number must match, the address size ('class') ++     and byte-swapping must match our XVEC entry.  */ ++ ++  if (! elf_file_p (&x_ehdr64) ++      || x_ehdr64.e_ident[EI_VERSION] != EV_CURRENT ++      || !((bfd_get_arch_size (templ) == 64 ++            && x_ehdr64.e_ident[EI_CLASS] == ELFCLASS64) ++           || (bfd_get_arch_size (templ) == 32 ++	       && x_ehdr64.e_ident[EI_CLASS] == ELFCLASS32))) ++    { ++      if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) ++        warning (_("build-id: Unrecognized ELF header at address 0x%lx"), ++		 (unsigned long) ehdr_vma); ++      return NULL; ++    } ++ ++  /* Check that file's byte order matches xvec's */ ++  switch (x_ehdr64.e_ident[EI_DATA]) ++    { ++    case ELFDATA2MSB:		/* Big-endian */ ++      if (! bfd_header_big_endian (templ)) ++	{ ++	  if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) ++	    warning (_("build-id: Unrecognized " ++		       "big-endian ELF header at address 0x%lx"), ++		     (unsigned long) ehdr_vma); ++	  return NULL; ++	} ++      break; ++    case ELFDATA2LSB:		/* Little-endian */ ++      if (! bfd_header_little_endian (templ)) ++	{ ++	  if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) ++	    warning (_("build-id: Unrecognized " ++		       "little-endian ELF header at address 0x%lx"), ++		     (unsigned long) ehdr_vma); ++	  return NULL; ++	} ++      break; ++    case ELFDATANONE:		/* No data encoding specified */ ++    default:			/* Unknown data encoding specified */ ++      if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) ++	warning (_("build-id: Unrecognized " ++		   "ELF header endianity at address 0x%lx"), ++		 (unsigned long) ehdr_vma); ++      return NULL; ++    } ++ ++  elf_swap_ehdr_in (templ, &x_ehdr64, &i_ehdr); ++ ++  /* The file header tells where to find the program headers. ++     These are what we use to actually choose what to read.  */ ++ ++  if (i_ehdr.e_phentsize != (bfd_get_arch_size (templ) == 64 ++                             ? sizeof (Elf64_External_Phdr) ++			     : sizeof (Elf32_External_Phdr)) ++      || i_ehdr.e_phnum == 0) ++    { ++      if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) ++	warning (_("build-id: Invalid ELF program headers from the ELF header " ++		   "at address 0x%lx"), (unsigned long) ehdr_vma); ++      return NULL; ++    } ++ ++  x_phdrs_size = (bfd_get_arch_size (templ) == 64 ? sizeof (Elf64_External_Phdr) ++						: sizeof (Elf32_External_Phdr)); ++ ++  i_phdrs = (Elf_Internal_Phdr *) xmalloc (i_ehdr.e_phnum * (sizeof *i_phdrs + x_phdrs_size)); ++  x_phdrs_ptr = (gdb_byte *) &i_phdrs[i_ehdr.e_phnum]; ++  err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs_ptr, ++			    i_ehdr.e_phnum * x_phdrs_size); ++  if (err) ++    { ++      free (i_phdrs); ++      if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) ++        warning (_("build-id: Error reading " ++		   "ELF program headers at address 0x%lx"), ++		 (unsigned long) (ehdr_vma + i_ehdr.e_phoff)); ++      return NULL; ++    } ++ ++  loadbase = ehdr_vma; ++  loadbase_set = 0; ++  for (i = 0; i < i_ehdr.e_phnum; ++i) ++    { ++      elf_swap_phdr_in (templ, (Elf64_External_Phdr *) ++			       (x_phdrs_ptr + i * x_phdrs_size), &i_phdrs[i]); ++      /* IA-64 vDSO may have two mappings for one segment, where one mapping ++	 is executable only, and one is read only.  We must not use the ++	 executable one (PF_R is the first one, PF_X the second one).  */ ++      if (i_phdrs[i].p_type == PT_LOAD && (i_phdrs[i].p_flags & PF_R)) ++	{ ++	  /* Only the first PT_LOAD segment indicates the file bias. ++	     Next segments may have P_VADDR arbitrarily higher. ++	     If the first segment has P_VADDR zero any next segment must not ++	     confuse us, the first one sets LOADBASE certainly enough.  */ ++	  if (!loadbase_set && i_phdrs[i].p_offset == 0) ++	    { ++	      loadbase = ehdr_vma - i_phdrs[i].p_vaddr; ++	      loadbase_set = 1; ++	    } ++	} ++    } ++ ++  if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) ++    warning (_("build-id: Found ELF header at address 0x%lx, loadbase 0x%lx"), ++	     (unsigned long) ehdr_vma, (unsigned long) loadbase); ++ ++  *e_phnum_pointer = i_ehdr.e_phnum; ++  *loadbase_pointer = loadbase; ++  return i_phdrs; ++} ++ ++/* BUILD_ID_ADDR_GET gets ADDR located somewhere in the object. ++   Find the first section before ADDR containing an ELF header. ++   We rely on the fact the sections from multiple files do not mix. ++   FIXME: We should check ADDR is contained _inside_ the section with possibly ++   missing content (P_FILESZ < P_MEMSZ).  These omitted sections are currently ++   hidden by _BFD_ELF_MAKE_SECTION_FROM_PHDR.  */ ++ ++static CORE_ADDR build_id_addr; ++struct build_id_addr_sect ++  { ++    struct build_id_addr_sect *next; ++    asection *sect; ++  }; ++static struct build_id_addr_sect *build_id_addr_sect; ++ ++static void build_id_addr_candidate (bfd *abfd, asection *sect, void *obj) ++{ ++  if (build_id_addr >= bfd_section_vma (sect)) ++    { ++      struct build_id_addr_sect *candidate; ++ ++      candidate = (struct build_id_addr_sect *) xmalloc (sizeof *candidate); ++      candidate->next = build_id_addr_sect; ++      build_id_addr_sect = candidate; ++      candidate->sect = sect; ++    } ++} ++ ++struct bfd_build_id * ++build_id_addr_get (CORE_ADDR addr) ++{ ++  struct build_id_addr_sect *candidate; ++  struct bfd_build_id *retval = NULL; ++  Elf_Internal_Phdr *i_phdr = NULL; ++  bfd_vma loadbase = 0; ++  unsigned e_phnum = 0; ++ ++  if (core_bfd == NULL) ++    return NULL; ++ ++  build_id_addr = addr; ++  gdb_assert (build_id_addr_sect == NULL); ++  bfd_map_over_sections (core_bfd, build_id_addr_candidate, NULL); ++ ++  /* Sections are sorted in the high-to-low VMAs order. ++     Stop the search on the first ELF header we find. ++     Do not continue the search even if it does not contain NT_GNU_BUILD_ID.  */ ++ ++  for (candidate = build_id_addr_sect; candidate != NULL; ++       candidate = candidate->next) ++    { ++      i_phdr = elf_get_phdr (core_bfd, ++			     bfd_section_vma (candidate->sect), ++			     &e_phnum, &loadbase); ++      if (i_phdr != NULL) ++	break; ++    } ++ ++  if (i_phdr != NULL) ++    { ++      retval = build_id_phdr_get (core_bfd, loadbase, e_phnum, i_phdr); ++      xfree (i_phdr); ++    } ++ ++  while (build_id_addr_sect != NULL) ++    { ++      candidate = build_id_addr_sect; ++      build_id_addr_sect = candidate->next; ++      xfree (candidate); ++    } ++ ++  return retval; ++} ++ + /* See build-id.h.  */ +  + int +@@ -58,7 +458,7 @@ build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check) +   const struct bfd_build_id *found; +   int retval = 0; +  +-  found = build_id_bfd_get (abfd); ++  found = build_id_bfd_shdr_get (abfd); +  +   if (found == NULL) +     warning (_("File \"%s\" has no build-id, file skipped"), +@@ -73,63 +473,166 @@ build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check) +   return retval; + } +  ++static char * ++link_resolve (const char *symlink, int level) ++{ ++  char buf[PATH_MAX + 1], *retval; ++  gdb::unique_xmalloc_ptr<char> target; ++  ssize_t got; ++ ++  if (level > 10) ++    return xstrdup (symlink); ++ ++  got = readlink (symlink, buf, sizeof (buf)); ++  if (got < 0 || got >= sizeof (buf)) ++    return xstrdup (symlink); ++  buf[got] = '\0'; ++ ++  if (IS_ABSOLUTE_PATH (buf)) ++    target = make_unique_xstrdup (buf); ++  else ++    { ++      const std::string dir (ldirname (symlink)); ++ ++      target = xstrprintf ("%s" ++#ifndef HAVE_DOS_BASED_FILE_SYSTEM ++			   "/" ++#else /* HAVE_DOS_BASED_FILE_SYSTEM */ ++			   "\\" ++#endif /* HAVE_DOS_BASED_FILE_SYSTEM */ ++			   "%s", dir.c_str(), buf); ++    } ++ ++  retval = link_resolve (target.get (), level + 1); ++  return retval; ++} ++ + /* Helper for build_id_to_debug_bfd.  LINK is a path to a potential +    build-id-based separate debug file, potentially a symlink to the real file. +    If the file exists and matches BUILD_ID, return a BFD reference to it.  */ +  + static gdb_bfd_ref_ptr +-build_id_to_debug_bfd_1 (const std::string &link, size_t build_id_len, +-			 const bfd_byte *build_id) ++build_id_to_debug_bfd_1 (const std::string &orig_link, size_t build_id_len, ++			 const bfd_byte *build_id, char **link_return) + { ++  gdb_bfd_ref_ptr ret_bfd = {}; ++  std::string ret_link; ++ +   if (separate_debug_file_debug) +     { +-      gdb_printf (gdb_stdlog, _("  Trying %s..."), link.c_str ()); +-      gdb_flush (gdb_stdlog); ++      gdb_printf (gdb_stdlog, _("  Trying %s..."), orig_link.c_str ()); ++      gdb_flush (gdb_stdout); +     } +  +-  /* lrealpath() is expensive even for the usually non-existent files.  */ +-  gdb::unique_xmalloc_ptr<char> filename_holder; +-  const char *filename = nullptr; +-  if (startswith (link, TARGET_SYSROOT_PREFIX)) +-    filename = link.c_str (); +-  else if (access (link.c_str (), F_OK) == 0) ++  for (unsigned seqno = 0;; seqno++) +     { +-      filename_holder.reset (lrealpath (link.c_str ())); +-      filename = filename_holder.get (); +-    } ++      std::string link = orig_link; +  +-  if (filename == NULL) +-    { +-      if (separate_debug_file_debug) +-	gdb_printf (gdb_stdlog, +-		    _(" no, unable to compute real path\n")); ++      if (seqno > 0) ++	{ ++	  /* There can be multiple build-id symlinks pointing to real files ++	     with the same build-id (such as hard links).  Some of the real ++	     files may not be installed.  */ +  +-      return {}; +-    } ++	  string_appendf (link, ".%u", seqno); ++	} +  +-  /* We expect to be silent on the non-existing files.  */ +-  gdb_bfd_ref_ptr debug_bfd = gdb_bfd_open (filename, gnutarget); ++      ret_link = link; +  +-  if (debug_bfd == NULL) +-    { +-      if (separate_debug_file_debug) +-	gdb_printf (gdb_stdlog, _(" no, unable to open.\n")); ++      struct stat statbuf_trash; ++ ++      /* `access' automatically dereferences LINK.  */ ++      if (lstat (link.c_str (), &statbuf_trash) != 0) ++	{ ++	  /* Stop increasing SEQNO.  */ ++	  break; ++	} ++ ++      /* lrealpath() is expensive even for the usually non-existent files.  */ ++      gdb::unique_xmalloc_ptr<char> filename_holder; ++      const char *filename = nullptr; ++      if (startswith (link, TARGET_SYSROOT_PREFIX)) ++	filename = link.c_str (); ++      else if (access (link.c_str (), F_OK) == 0) ++	{ ++	  filename_holder.reset (lrealpath (link.c_str ())); ++	  filename = filename_holder.get (); ++	} ++ ++      if (filename == NULL) ++	{ ++	  if (separate_debug_file_debug) ++	    gdb_printf (gdb_stdlog, ++	                       _(" no, unable to compute real path\n")); ++ ++	  continue; ++	} ++ ++      /* We expect to be silent on the non-existing files.  */ ++      gdb_bfd_ref_ptr debug_bfd = gdb_bfd_open (filename, gnutarget); ++ ++      if (debug_bfd == NULL) ++	{ ++	  if (separate_debug_file_debug) ++	    gdb_printf (gdb_stdlog, _(" no, unable to open.\n")); +  +-      return {}; ++	  continue; ++	} ++ ++      if (!build_id_verify (debug_bfd.get(), build_id_len, build_id)) ++	{ ++	  if (separate_debug_file_debug) ++	    gdb_printf (gdb_stdlog, ++	                _(" no, build-id does not match.\n")); ++ ++	  continue; ++	} ++ ++      ret_bfd = debug_bfd; ++      break; +     } +  +-  if (!build_id_verify (debug_bfd.get(), build_id_len, build_id)) ++  std::string link_all; ++ ++  if (ret_bfd != NULL) +     { +       if (separate_debug_file_debug) +-	gdb_printf (gdb_stdlog, _(" no, build-id does not match.\n")); ++	gdb_printf (gdb_stdlog, _(" yes!\n")); ++    } ++  else ++    { ++      /* If none of the real files is found report as missing file ++	 always the non-.%u-suffixed file.  */ ++      std::string link0 = orig_link; +  +-      return {}; ++      /* If the symlink has target request to install the target. ++	 BASE-debuginfo.rpm contains the symlink but BASE.rpm may be missing. ++	 https://bugzilla.redhat.com/show_bug.cgi?id=981154  */ ++      std::string link0_resolved (link_resolve (link0.c_str (), 0)); ++ ++      if (link_all.empty ()) ++	link_all = link0_resolved; ++      else ++	{ ++	  /* Use whitespace instead of DIRNAME_SEPARATOR to be compatible with ++	     its possible use as an argument for installation command.  */ ++	  link_all += " " + link0_resolved; ++	} +     } +  +-  if (separate_debug_file_debug) +-    gdb_printf (gdb_stdlog, _(" yes!\n")); ++  if (link_return != NULL) ++    { ++      if (ret_bfd != NULL) ++	{ ++	  *link_return = xstrdup (ret_link.c_str ()); ++	} ++      else ++	{ ++	  *link_return = xstrdup (link_all.c_str ()); ++	} ++    } +  +-  return debug_bfd; ++  return ret_bfd; + } +  + /* Common code for finding BFDs of a given build-id.  This function +@@ -138,7 +641,7 @@ build_id_to_debug_bfd_1 (const std::string &link, size_t build_id_len, +  + static gdb_bfd_ref_ptr + build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id, +-			const char *suffix) ++			const char *suffix, char **link_return) + { +   /* Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will +      cause "/.build-id/..." lookups.  */ +@@ -161,16 +664,17 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id, +       if (size > 0) + 	{ + 	  size--; +-	  string_appendf (link, "%02x/", (unsigned) *data++); ++	  string_appendf (link, "%02x", (unsigned) *data++); + 	} +- ++      if (size > 0) ++	link += "/"; +       while (size-- > 0) + 	string_appendf (link, "%02x", (unsigned) *data++); +  +       link += suffix; +  +       gdb_bfd_ref_ptr debug_bfd +-	= build_id_to_debug_bfd_1 (link, build_id_len, build_id); ++	= build_id_to_debug_bfd_1 (link, build_id_len, build_id, link_return); +       if (debug_bfd != NULL) + 	return debug_bfd; +  +@@ -181,7 +685,7 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id, +       if (!gdb_sysroot.empty ()) + 	{ + 	  link = gdb_sysroot + link; +-	  debug_bfd = build_id_to_debug_bfd_1 (link, build_id_len, build_id); ++	  debug_bfd = build_id_to_debug_bfd_1 (link, build_id_len, build_id, NULL); + 	  if (debug_bfd != NULL) + 	    return debug_bfd; + 	} +@@ -190,31 +694,663 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id, +   return {}; + } +  ++char * ++build_id_to_filename (const struct bfd_build_id *build_id, char **link_return) ++{ ++  gdb_bfd_ref_ptr abfd; ++  char *result; ++ ++  abfd = build_id_to_exec_bfd (build_id->size, build_id->data, link_return); ++  if (abfd == NULL) ++    return NULL; ++ ++  result = xstrdup (bfd_get_filename (abfd.get ())); ++  return result; ++} ++ ++void debug_flush_missing (void); ++ ++#ifdef HAVE_LIBRPM ++ ++#include <rpm/rpmlib.h> ++#include <rpm/rpmts.h> ++#include <rpm/rpmdb.h> ++#include <rpm/header.h> ++#ifdef DLOPEN_LIBRPM ++#include <dlfcn.h> ++#endif ++ ++/* Workarodun https://bugzilla.redhat.com/show_bug.cgi?id=643031 ++   librpm must not exit() an application on SIGINT ++ ++   Enable or disable a signal handler.  SIGNUM: signal to enable (or disable ++   if negative).  HANDLER: sa_sigaction handler (or NULL to use ++   rpmsqHandler()).  Returns: no. of refs, -1 on error.  */ ++extern int rpmsqEnable (int signum, /* rpmsqAction_t handler */ void *handler); ++int ++rpmsqEnable (int signum, /* rpmsqAction_t handler */ void *handler) ++{ ++  return 0; ++} ++ ++/* This MISSING_RPM_HASH tracker is used to collect all the missing rpm files ++   and avoid their duplicities during a single inferior run.  */ ++ ++static struct htab *missing_rpm_hash; ++ ++/* This MISSING_RPM_LIST tracker is used to collect and print as a single line ++   all the rpms right before the nearest GDB prompt.  It gets cleared after ++   each such print (it is questionable if we should clear it after the print). ++   */ ++ ++struct missing_rpm ++  { ++    struct missing_rpm *next; ++    char rpm[1]; ++  }; ++static struct missing_rpm *missing_rpm_list; ++static int missing_rpm_list_entries; ++ ++/* Returns the count of newly added rpms.  */ ++ ++static int ++#ifndef GDB_INDEX_VERIFY_VENDOR ++missing_rpm_enlist (const char *filename) ++#else ++missing_rpm_enlist_1 (const char *filename, int verify_vendor) ++#endif ++{ ++  static int rpm_init_done = 0; ++  rpmts ts; ++  rpmdbMatchIterator mi; ++  int count = 0; ++ ++#ifdef DLOPEN_LIBRPM ++  /* Duplicate here the declarations to verify they match.  The same sanity ++     check is present also in `configure.ac'.  */ ++  extern char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg); ++  static char *(*headerFormat_p) (Header h, const char * fmt, errmsg_t *errmsg); ++  extern int rpmReadConfigFiles(const char * file, const char * target); ++  static int (*rpmReadConfigFiles_p) (const char * file, const char * target); ++  extern rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi); ++  static rpmdbMatchIterator (*rpmdbFreeIterator_p) (rpmdbMatchIterator mi); ++  extern Header rpmdbNextIterator(rpmdbMatchIterator mi); ++  static Header (*rpmdbNextIterator_p) (rpmdbMatchIterator mi); ++  extern rpmts rpmtsCreate(void); ++  static rpmts (*rpmtsCreate_p) (void); ++  extern rpmts rpmtsFree(rpmts ts); ++  static rpmts (*rpmtsFree_p) (rpmts ts); ++  extern rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmTag rpmtag, ++                                              const void * keyp, size_t keylen); ++  static rpmdbMatchIterator (*rpmtsInitIterator_p) (const rpmts ts, ++						    rpmTag rpmtag, ++						    const void *keyp, ++						    size_t keylen); ++#else	/* !DLOPEN_LIBRPM */ ++# define headerFormat_p headerFormat ++# define rpmReadConfigFiles_p rpmReadConfigFiles ++# define rpmdbFreeIterator_p rpmdbFreeIterator ++# define rpmdbNextIterator_p rpmdbNextIterator ++# define rpmtsCreate_p rpmtsCreate ++# define rpmtsFree_p rpmtsFree ++# define rpmtsInitIterator_p rpmtsInitIterator ++#endif	/* !DLOPEN_LIBRPM */ ++ ++  gdb_assert (filename != NULL); ++ ++  if (strcmp (filename, BUILD_ID_MAIN_EXECUTABLE_FILENAME) == 0) ++    return 0; ++ ++  if (is_target_filename (filename)) ++    return 0; ++ ++  if (filename[0] != '/') ++    { ++      warning (_("Ignoring non-absolute filename: <%s>"), filename); ++      return 0; ++    } ++ ++  if (!rpm_init_done) ++    { ++      static int init_tried; ++ ++      /* Already failed the initialization before?  */ ++      if (init_tried) ++        return 0; ++      init_tried = 1; ++ ++#ifdef DLOPEN_LIBRPM ++      { ++	void *h; ++ ++	h = dlopen (DLOPEN_LIBRPM, RTLD_LAZY); ++	if (!h) ++	  { ++	    warning (_("Unable to open \"%s\" (%s), " ++		      "missing debuginfos notifications will not be displayed"), ++		     DLOPEN_LIBRPM, dlerror ()); ++	    return 0; ++	  } ++ ++	if (!((headerFormat_p = (char *(*) (Header h, const char * fmt, errmsg_t *errmsg)) dlsym (h, "headerFormat")) ++	      && (rpmReadConfigFiles_p = (int (*) (const char * file, const char * target)) dlsym (h, "rpmReadConfigFiles")) ++	      && (rpmdbFreeIterator_p = (rpmdbMatchIterator (*) (rpmdbMatchIterator mi)) dlsym (h, "rpmdbFreeIterator")) ++	      && (rpmdbNextIterator_p = (Header (*) (rpmdbMatchIterator mi)) dlsym (h, "rpmdbNextIterator")) ++	      && (rpmtsCreate_p = (rpmts (*) (void)) dlsym (h, "rpmtsCreate")) ++	      && (rpmtsFree_p = (rpmts (*) (rpmts ts)) dlsym (h, "rpmtsFree")) ++	      && (rpmtsInitIterator_p = (rpmdbMatchIterator (*) (const rpmts ts, rpmTag rpmtag, const void *keyp, size_t keylen)) dlsym (h, "rpmtsInitIterator")))) ++	  { ++	    warning (_("Opened library \"%s\" is incompatible (%s), " ++		      "missing debuginfos notifications will not be displayed"), ++		     DLOPEN_LIBRPM, dlerror ()); ++	    if (dlclose (h)) ++	      warning (_("Error closing library \"%s\": %s\n"), DLOPEN_LIBRPM, ++		       dlerror ()); ++	    return 0; ++	  } ++      } ++#endif	/* DLOPEN_LIBRPM */ ++ ++      if (rpmReadConfigFiles_p (NULL, NULL) != 0) ++	{ ++	  warning (_("Error reading the rpm configuration files")); ++	  return 0; ++	} ++ ++      rpm_init_done = 1; ++    } ++ ++  ts = rpmtsCreate_p (); ++ ++  mi = rpmtsInitIterator_p (ts, RPMTAG_BASENAMES, filename, 0); ++  if (mi != NULL) ++    { ++#ifndef GDB_INDEX_VERIFY_VENDOR ++      for (;;) ++#else ++      if (!verify_vendor) for (;;) ++#endif ++	{ ++	  Header h; ++	  char *debuginfo, **slot, *s, *s2; ++	  errmsg_t err; ++	  size_t srcrpmlen = sizeof (".src.rpm") - 1; ++	  size_t debuginfolen = sizeof ("-debuginfo") - 1; ++	  rpmdbMatchIterator mi_debuginfo; ++ ++	  h = rpmdbNextIterator_p (mi); ++	  if (h == NULL) ++	    break; ++ ++	  /* Verify the debuginfo file is not already installed.  */ ++ ++	  debuginfo = headerFormat_p (h, "%{sourcerpm}-debuginfo.%{arch}", ++				      &err); ++	  if (!debuginfo) ++	    { ++	      warning (_("Error querying the rpm file `%s': %s"), filename, ++	               err); ++	      continue; ++	    } ++	  /* s = `.src.rpm-debuginfo.%{arch}' */ ++	  s = strrchr (debuginfo, '-') - srcrpmlen; ++	  s2 = NULL; ++	  if (s > debuginfo && memcmp (s, ".src.rpm", srcrpmlen) == 0) ++	    { ++	      /* s2 = `-%{release}.src.rpm-debuginfo.%{arch}' */ ++	      s2 = (char *) memrchr (debuginfo, '-', s - debuginfo); ++	    } ++	  if (s2) ++	    { ++	      /* s2 = `-%{version}-%{release}.src.rpm-debuginfo.%{arch}' */ ++	      s2 = (char *) memrchr (debuginfo, '-', s2 - debuginfo); ++	    } ++	  if (!s2) ++	    { ++	      warning (_("Error querying the rpm file `%s': %s"), filename, ++	               debuginfo); ++	      xfree (debuginfo); ++	      continue; ++	    } ++	  /* s = `.src.rpm-debuginfo.%{arch}' */ ++	  /* s2 = `-%{version}-%{release}.src.rpm-debuginfo.%{arch}' */ ++	  memmove (s2 + debuginfolen, s2, s - s2); ++	  memcpy (s2, "-debuginfo", debuginfolen); ++	  /* s = `XXXX.%{arch}' */ ++	  /* strlen ("XXXX") == srcrpmlen + debuginfolen */ ++	  /* s2 = `-debuginfo-%{version}-%{release}XX.%{arch}' */ ++	  /* strlen ("XX") == srcrpmlen */ ++	  memmove (s + debuginfolen, s + srcrpmlen + debuginfolen, ++		   strlen (s + srcrpmlen + debuginfolen) + 1); ++	  /* s = `-debuginfo-%{version}-%{release}.%{arch}' */ ++ ++	  /* RPMDBI_PACKAGES requires keylen == sizeof (int).  */ ++	  /* RPMDBI_LABEL is an interface for NVR-based dbiFindByLabel().  */ ++	  mi_debuginfo = rpmtsInitIterator_p (ts, (rpmTag) RPMDBI_LABEL, debuginfo, 0); ++	  xfree (debuginfo); ++	  if (mi_debuginfo) ++	    { ++	      rpmdbFreeIterator_p (mi_debuginfo); ++	      count = 0; ++	      break; ++	    } ++ ++	  /* The allocated memory gets utilized below for MISSING_RPM_HASH.  */ ++	  debuginfo = headerFormat_p (h, ++				      "%{name}-%{version}-%{release}.%{arch}", ++				      &err); ++	  if (!debuginfo) ++	    { ++	      warning (_("Error querying the rpm file `%s': %s"), filename, ++	               err); ++	      continue; ++	    } ++ ++	  /* Base package name for `debuginfo-install'.  We do not use the ++	     `yum' command directly as the line ++		 yum --enablerepo='*debug*' install NAME-debuginfo.ARCH ++	     would be more complicated than just: ++		 debuginfo-install NAME-VERSION-RELEASE.ARCH ++	     Do not supply the rpm base name (derived from .src.rpm name) as ++	     debuginfo-install is unable to install the debuginfo package if ++	     the base name PKG binary rpm is not installed while for example ++	     PKG-libs would be installed (RH Bug 467901). ++	     FUTURE: After multiple debuginfo versions simultaneously installed ++	     get supported the support for the VERSION-RELEASE tags handling ++	     may need an update.  */ ++ ++	  if (missing_rpm_hash == NULL) ++	    { ++	      /* DEL_F is passed NULL as MISSING_RPM_LIST's HTAB_DELETE ++		 should not deallocate the entries.  */ ++ ++	      missing_rpm_hash = htab_create_alloc (64, htab_hash_string, ++			       (int (*) (const void *, const void *)) streq, ++						    NULL, xcalloc, xfree); ++	    } ++	  slot = (char **) htab_find_slot (missing_rpm_hash, debuginfo, INSERT); ++	  /* XCALLOC never returns NULL.  */ ++	  gdb_assert (slot != NULL); ++	  if (*slot == NULL) ++	    { ++	      struct missing_rpm *missing_rpm; ++ ++	      *slot = debuginfo; ++ ++	      missing_rpm = (struct missing_rpm *) xmalloc (sizeof (*missing_rpm) + strlen (debuginfo)); ++	      strcpy (missing_rpm->rpm, debuginfo); ++	      missing_rpm->next = missing_rpm_list; ++	      missing_rpm_list = missing_rpm; ++	      missing_rpm_list_entries++; ++	    } ++	  else ++	    xfree (debuginfo); ++	  count++; ++	} ++#ifdef GDB_INDEX_VERIFY_VENDOR ++      else /* verify_vendor */ ++	{ ++	  int vendor_pass = 0, vendor_fail = 0; ++ ++	  for (;;) ++	    { ++	      Header h; ++	      errmsg_t err; ++	      char *vendor; ++ ++	      h = rpmdbNextIterator_p (mi); ++	      if (h == NULL) ++		break; ++ ++	      vendor = headerFormat_p (h, "%{vendor}", &err); ++	      if (!vendor) ++		{ ++		  warning (_("Error querying the rpm file `%s': %s"), filename, ++			   err); ++		  continue; ++		} ++	      if (strcmp (vendor, "Red Hat, Inc.") == 0) ++		vendor_pass = 1; ++	      else ++		vendor_fail = 1; ++	      xfree (vendor); ++	    } ++	  count = vendor_pass != 0 && vendor_fail == 0; ++	} ++#endif ++ ++      rpmdbFreeIterator_p (mi); ++    } ++ ++  rpmtsFree_p (ts); ++ ++  return count; ++} ++ ++#ifdef GDB_INDEX_VERIFY_VENDOR ++missing_rpm_enlist (const char *filename) ++{ ++  return missing_rpm_enlist_1 (filename, 0); ++} ++ ++extern int rpm_verify_vendor (const char *filename); ++int ++rpm_verify_vendor (const char *filename) ++{ ++  return missing_rpm_enlist_1 (filename, 1); ++} ++#endif ++ ++static bool ++missing_rpm_list_compar (const char *ap, const char *bp) ++{ ++  return strcoll (ap, bp) < 0; ++} ++ ++/* It returns a NULL-terminated array of strings needing to be FREEd.  It may ++   also return only NULL.  */ ++ ++static void ++missing_rpm_list_print (void) ++{ ++  struct missing_rpm *list_iter; ++ ++  if (missing_rpm_list_entries == 0) ++    return; ++ ++  std::vector<const char *> array (missing_rpm_list_entries); ++  size_t idx = 0; ++ ++  for (list_iter = missing_rpm_list; list_iter != NULL; ++       list_iter = list_iter->next) ++    { ++      array[idx++] = list_iter->rpm; ++    } ++  gdb_assert (idx == missing_rpm_list_entries); ++ ++  std::sort (array.begin (), array.end (), missing_rpm_list_compar); ++ ++  /* We zero out the number of missing RPMs here because of a nasty ++     bug (see RHBZ 1801974). ++ ++     When we call 'puts_unfiltered' below, if pagination is on and if ++     the number of missing RPMs is big enough to trigger pagination, ++     we will end up in an infinite recursion.  The call chain looks ++     like this: ++ ++     missing_rpm_list_print -> puts_unfiltered -> fputs_maybe_filtered ++     -> prompt_for_continue -> display_gdb_prompt -> ++     debug_flush_missing -> missing_rpm_list_print ... ++ ++     For this reason, we make sure MISSING_RPM_LIST_ENTRIES is zero ++     *before* calling any print function. ++      ++     Note: kevinb/2023-02-22: The code below used to call ++     puts_unfiltered() and printf_unfiltered(), but calls to these ++     functions have been replaced by calls to gdb_printf().  The call ++     chain shown above (probably) used to be the case at one time and ++     hopefully something similar is still the case now that ++     gdb_printf() is being used instead.  */ ++  missing_rpm_list_entries = 0; ++ ++  gdb_printf (_("Missing separate debuginfos, use: %s"), ++#ifdef DNF_DEBUGINFO_INSTALL ++		     "dnf " ++#endif ++		     "debuginfo-install"); ++  for (const char *el : array) ++    { ++      gdb_printf (" %s", el); ++    } ++  gdb_printf ("\n"); ++ ++  while (missing_rpm_list != NULL) ++    { ++      list_iter = missing_rpm_list; ++      missing_rpm_list = list_iter->next; ++      xfree (list_iter); ++    } ++} ++ ++static void ++missing_rpm_change (void) ++{ ++  debug_flush_missing (); ++ ++  gdb_assert (missing_rpm_list == NULL); ++  if (missing_rpm_hash != NULL) ++    { ++      htab_delete (missing_rpm_hash); ++      missing_rpm_hash = NULL; ++    } ++} ++ ++enum missing_exec ++  { ++    /* Init state.  EXEC_BFD also still could be NULL.  */ ++    MISSING_EXEC_NOT_TRIED, ++    /* We saw a non-NULL EXEC_BFD but RPM has no info about it.  */ ++    MISSING_EXEC_NOT_FOUND, ++    /* We found EXEC_BFD by RPM and we either have its symbols (either embedded ++       or separate) or the main executable's RPM is now contained in ++       MISSING_RPM_HASH.  */ ++    MISSING_EXEC_ENLISTED ++  }; ++static enum missing_exec missing_exec = MISSING_EXEC_NOT_TRIED; ++ ++#endif	/* HAVE_LIBRPM */ ++ ++void ++debug_flush_missing (void) ++{ ++#ifdef HAVE_LIBRPM ++  missing_rpm_list_print (); ++#endif ++} ++ ++/* This MISSING_FILEPAIR_HASH tracker is used only for the duplicite messages ++     yum --enablerepo='*debug*' install ... ++   avoidance.  */ ++ ++struct missing_filepair ++  { ++    char *binary; ++    char *debug; ++    char data[1]; ++  }; ++ ++static struct htab *missing_filepair_hash; ++static struct obstack missing_filepair_obstack; ++ ++static void * ++missing_filepair_xcalloc (size_t nmemb, size_t nmemb_size) ++{ ++  void *retval; ++  size_t size = nmemb * nmemb_size; ++ ++  retval = obstack_alloc (&missing_filepair_obstack, size); ++  memset (retval, 0, size); ++  return retval; ++} ++ ++static hashval_t ++missing_filepair_hash_func (const struct missing_filepair *elem) ++{ ++  hashval_t retval = 0; ++ ++  retval ^= htab_hash_string (elem->binary); ++  if (elem->debug != NULL) ++    retval ^= htab_hash_string (elem->debug); ++ ++  return retval; ++} ++ ++static int ++missing_filepair_eq (const struct missing_filepair *elem1, ++		       const struct missing_filepair *elem2) ++{ ++  return strcmp (elem1->binary, elem2->binary) == 0 ++         && ((elem1->debug == NULL) == (elem2->debug == NULL)) ++         && (elem1->debug == NULL || strcmp (elem1->debug, elem2->debug) == 0); ++} ++ ++static void ++missing_filepair_change (void) ++{ ++  if (missing_filepair_hash != NULL) ++    { ++      obstack_free (&missing_filepair_obstack, NULL); ++      /* All their memory came just from missing_filepair_OBSTACK.  */ ++      missing_filepair_hash = NULL; ++    } ++#ifdef HAVE_LIBRPM ++  missing_exec = MISSING_EXEC_NOT_TRIED; ++#endif ++} ++ ++static void ++debug_print_executable_changed (struct program_space *pspace, bool reload_p) ++{ ++#ifdef HAVE_LIBRPM ++  missing_rpm_change (); ++#endif ++  missing_filepair_change (); ++} ++ ++/* Notify user the file BINARY with (possibly NULL) associated separate debug ++   information file DEBUG is missing.  DEBUG may or may not be the build-id ++   file such as would be: ++     /usr/lib/debug/.build-id/dd/b1d2ce632721c47bb9e8679f369e2295ce71be.debug ++   */ ++ ++void ++debug_print_missing (const char *binary, const char *debug) ++{ ++  size_t binary_len0 = strlen (binary) + 1; ++  size_t debug_len0 = debug ? strlen (debug) + 1 : 0; ++  struct missing_filepair missing_filepair_find; ++  struct missing_filepair *missing_filepair; ++  struct missing_filepair **slot; ++ ++  if (build_id_verbose < BUILD_ID_VERBOSE_FILENAMES) ++    return; ++ ++  if (missing_filepair_hash == NULL) ++    { ++      obstack_init (&missing_filepair_obstack); ++      missing_filepair_hash = htab_create_alloc (64, ++	(hashval_t (*) (const void *)) missing_filepair_hash_func, ++	(int (*) (const void *, const void *)) missing_filepair_eq, NULL, ++	missing_filepair_xcalloc, NULL); ++    } ++ ++  /* Use MISSING_FILEPAIR_FIND first instead of calling obstack_alloc with ++     obstack_free in the case of a (rare) match.  The problem is ALLOC_F for ++     MISSING_FILEPAIR_HASH allocates from MISSING_FILEPAIR_OBSTACK maintenance ++     structures for MISSING_FILEPAIR_HASH.  Calling obstack_free would possibly ++     not to free only MISSING_FILEPAIR but also some such structures (allocated ++     during the htab_find_slot call).  */ ++ ++  missing_filepair_find.binary = (char *) binary; ++  missing_filepair_find.debug = (char *) debug; ++  slot = (struct missing_filepair **) htab_find_slot (missing_filepair_hash, ++						      &missing_filepair_find, ++						      INSERT); ++ ++  /* While it may be still printed duplicitely with the missing debuginfo file ++   * it is due to once printing about the binary file build-id link and once ++   * about the .debug file build-id link as both the build-id symlinks are ++   * located in the debuginfo package.  */ ++ ++  if (*slot != NULL) ++    return; ++ ++  missing_filepair = (struct missing_filepair *) obstack_alloc (&missing_filepair_obstack, ++								sizeof (*missing_filepair) - 1 ++								+ binary_len0 + debug_len0); ++  missing_filepair->binary = missing_filepair->data; ++  memcpy (missing_filepair->binary, binary, binary_len0); ++  if (debug != NULL) ++    { ++      missing_filepair->debug = missing_filepair->binary + binary_len0; ++      memcpy (missing_filepair->debug, debug, debug_len0); ++    } ++  else ++    missing_filepair->debug = NULL; ++ ++  *slot = missing_filepair; ++ ++#ifdef HAVE_LIBRPM ++  if (missing_exec == MISSING_EXEC_NOT_TRIED) ++    { ++      const char *execfilename = get_exec_file (0); ++ ++      if (execfilename != NULL) ++	{ ++	  if (missing_rpm_enlist (execfilename) == 0) ++	    missing_exec = MISSING_EXEC_NOT_FOUND; ++	  else ++	    missing_exec = MISSING_EXEC_ENLISTED; ++	} ++    } ++  if (missing_exec != MISSING_EXEC_ENLISTED) ++    if ((binary[0] == 0 || missing_rpm_enlist (binary) == 0) ++	&& (debug == NULL || missing_rpm_enlist (debug) == 0)) ++#endif	/* HAVE_LIBRPM */ ++      { ++	/* We do not collect and flush these messages as each such message ++	   already requires its own separate lines.  */ ++ ++	gdb_printf (gdb_stdlog, ++		    _("Missing separate debuginfo for %s.\n"), binary); ++	if (debug != NULL) ++	{ ++	  if (access (debug, F_OK) == 0) { ++	    gdb_printf (gdb_stdlog, _("Try: %s %s\n"), ++#ifdef DNF_DEBUGINFO_INSTALL ++			"dnf" ++#else ++			"yum" ++#endif ++			" --enablerepo='*debug*' install", debug); ++	  } else ++	    gdb_printf (gdb_stdlog, _("The debuginfo package for this file is probably broken.\n")); ++	} ++      } ++} ++ + /* See build-id.h.  */ +  + gdb_bfd_ref_ptr +-build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id) ++build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id, ++		       char **link_return) + { +-  return build_id_to_bfd_suffix (build_id_len, build_id, ".debug"); ++  return build_id_to_bfd_suffix (build_id_len, build_id, ".debug", ++				 link_return); + } +  + /* See build-id.h.  */ +  + gdb_bfd_ref_ptr +-build_id_to_exec_bfd (size_t build_id_len, const bfd_byte *build_id) ++build_id_to_exec_bfd (size_t build_id_len, const bfd_byte *build_id, ++		      char **link_return) + { +-  return build_id_to_bfd_suffix (build_id_len, build_id, ""); ++  return build_id_to_bfd_suffix (build_id_len, build_id, "", link_return); + } +  + /* See build-id.h.  */ +  + std::string + find_separate_debug_file_by_buildid (struct objfile *objfile, +-				     deferred_warnings *warnings) ++				     deferred_warnings *warnings, ++				     gdb::unique_xmalloc_ptr<char> *build_id_filename_return) + { +   const struct bfd_build_id *build_id; +  +-  build_id = build_id_bfd_get (objfile->obfd.get ()); ++  if (build_id_filename_return) ++    *build_id_filename_return = NULL; ++ ++  build_id = build_id_bfd_shdr_get (objfile->obfd.get ()); +   if (build_id != NULL) +     { +       if (separate_debug_file_debug) +@@ -222,8 +1358,21 @@ find_separate_debug_file_by_buildid (struct objfile *objfile, + 		    _("\nLooking for separate debug info (build-id) for " + 		      "%s\n"), objfile_name (objfile)); +  ++      char *build_id_filename_cstr = NULL; +       gdb_bfd_ref_ptr abfd (build_id_to_debug_bfd (build_id->size, +-						   build_id->data)); ++						   build_id->data, ++	      (!build_id_filename_return ? NULL : &build_id_filename_cstr))); ++      if (build_id_filename_return) ++	{ ++	  if (!build_id_filename_cstr) ++	    gdb_assert (!*build_id_filename_return); ++	  else ++	    { ++	      *build_id_filename_return = gdb::unique_xmalloc_ptr<char> (build_id_filename_cstr); ++	      build_id_filename_cstr = NULL; ++	    } ++	} ++ +       /* Prevent looping on a stripped .debug file.  */ +       if (abfd != NULL + 	  && filename_cmp (bfd_get_filename (abfd.get ()), +@@ -243,3 +1392,22 @@ find_separate_debug_file_by_buildid (struct objfile *objfile, +  +   return std::string (); + } ++ ++void _initialize_build_id (); ++ ++void ++_initialize_build_id () ++{ ++  add_setshow_zinteger_cmd ("build-id-verbose", no_class, &build_id_verbose, ++			    _("\ ++Set debugging level of the build-id locator."), _("\ ++Show debugging level of the build-id locator."), _("\ ++Level 1 (default) enables printing the missing debug filenames,\n\ ++level 2 also prints the parsing of binaries to find the identificators."), ++			    NULL, ++			    show_build_id_verbose, ++			    &setlist, &showlist); ++ ++  gdb::observers::executable_changed.attach (debug_print_executable_changed, ++                                             "build-id"); ++} +diff --git a/gdb/build-id.h b/gdb/build-id.h +--- a/gdb/build-id.h ++++ b/gdb/build-id.h +@@ -23,9 +23,10 @@ + #include "gdb_bfd.h" + #include "gdbsupport/rsp-low.h" +  +-/* Locate NT_GNU_BUILD_ID from ABFD and return its content.  */ ++/* Separate debuginfo files have corrupted PHDR but SHDR is correct there. ++   Locate NT_GNU_BUILD_ID from ABFD and return its content.  */ +  +-extern const struct bfd_build_id *build_id_bfd_get (bfd *abfd); ++extern const struct bfd_build_id *build_id_bfd_shdr_get (bfd *abfd); +  + /* Return true if ABFD has NT_GNU_BUILD_ID matching the CHECK value. +    Otherwise, issue a warning and return false.  */ +@@ -38,14 +39,19 @@ extern int build_id_verify (bfd *abfd, +    can be found, return NULL.  */ +  + extern gdb_bfd_ref_ptr build_id_to_debug_bfd (size_t build_id_len, +-					      const bfd_byte *build_id); ++					      const bfd_byte *build_id, ++					      char **link_return = NULL); ++ ++extern char *build_id_to_filename (const struct bfd_build_id *build_id, ++				   char **link_return); +  + /* Find and open a BFD for an executable file given a build-id.  If no BFD +    can be found, return NULL.  The returned reference to the BFD must be +    released by the caller.  */ +  + extern gdb_bfd_ref_ptr build_id_to_exec_bfd (size_t build_id_len, +-					     const bfd_byte *build_id); ++					     const bfd_byte *build_id, ++					     char **link_return); +  + /* Find the separate debug file for OBJFILE, by using the build-id +    associated with OBJFILE's BFD.  If successful, returns the file name for the +@@ -58,7 +64,8 @@ extern gdb_bfd_ref_ptr build_id_to_exec_bfd (size_t build_id_len, +    will be printed.  */ +  + extern std::string find_separate_debug_file_by_buildid +-  (struct objfile *objfile, deferred_warnings *warnings); ++  (struct objfile *objfile, deferred_warnings *warnings, ++   gdb::unique_xmalloc_ptr<char> *build_id_filename_return); +  + /* Return an hex-string representation of BUILD_ID.  */ +  +diff --git a/gdb/coffread.c b/gdb/coffread.c +--- a/gdb/coffread.c ++++ b/gdb/coffread.c +@@ -729,7 +729,7 @@ coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) +     { +       deferred_warnings warnings; +       std::string debugfile +-	= find_separate_debug_file_by_buildid (objfile, &warnings); ++	= find_separate_debug_file_by_buildid (objfile, &warnings, NULL); +  +       if (debugfile.empty ()) + 	debugfile +diff --git a/gdb/corelow.c b/gdb/corelow.c +--- a/gdb/corelow.c ++++ b/gdb/corelow.c +@@ -22,6 +22,10 @@ + #include <signal.h> + #include <fcntl.h> + #include "frame.h" ++#include "auxv.h" ++#include "build-id.h" ++#include "elf/common.h" ++#include "gdbcmd.h" + #include "inferior.h" + #include "infrun.h" + #include "symtab.h" +@@ -380,6 +384,8 @@ add_to_thread_list (asection *asect, asection *reg_sect, inferior *inf) +     switch_to_thread (thr);			/* Yes, make it current.  */ + } +  ++static bool build_id_core_loads = true; ++ + /* Issue a message saying we have no core to debug, if FROM_TTY.  */ +  + static void +@@ -563,12 +569,14 @@ rename_vmcore_idle_reg_sections (bfd *abfd, inferior *inf) + static void + locate_exec_from_corefile_build_id (bfd *abfd, int from_tty) + { +-  const bfd_build_id *build_id = build_id_bfd_get (abfd); ++  const bfd_build_id *build_id = build_id_bfd_shdr_get (abfd); +   if (build_id == nullptr) +     return; +  ++  char *build_id_filename; +   gdb_bfd_ref_ptr execbfd +-    = build_id_to_exec_bfd (build_id->size, build_id->data); ++    = build_id_to_exec_bfd (build_id->size, build_id->data, ++			    &build_id_filename); +  +   if (execbfd == nullptr) +     { +@@ -596,7 +604,12 @@ locate_exec_from_corefile_build_id (bfd *abfd, int from_tty) +       exec_file_attach (bfd_get_filename (execbfd.get ()), from_tty); +       symbol_file_add_main (bfd_get_filename (execbfd.get ()), + 			    symfile_add_flag (from_tty ? SYMFILE_VERBOSE : 0)); ++      if (current_program_space->symfile_object_file != NULL) ++	current_program_space->symfile_object_file->flags |= ++	  OBJF_BUILD_ID_CORE_LOADED; +     } ++  else ++    debug_print_missing (BUILD_ID_MAIN_EXECUTABLE_FILENAME, build_id_filename); + } +  + /* See gdbcore.h.  */ +@@ -1506,4 +1519,11 @@ _initialize_corelow () + 	   maintenance_print_core_file_backed_mappings, + 	   _("Print core file's file-backed mappings."), + 	   &maintenanceprintlist); ++ ++  add_setshow_boolean_cmd ("build-id-core-loads", class_files, ++			   &build_id_core_loads, _("\ ++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); + } +diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo +--- a/gdb/doc/gdb.texinfo ++++ b/gdb/doc/gdb.texinfo +@@ -22296,6 +22296,27 @@ information files. +  + @end table +  ++You can also adjust the current verbosity of the @dfn{build id} locating. ++ ++@table @code ++ ++@kindex set build-id-verbose ++@item set build-id-verbose 0 ++No additional messages are printed. ++ ++@item set build-id-verbose 1 ++Missing separate debug filenames are printed. ++ ++@item set build-id-verbose 2 ++Missing separate debug filenames are printed and also all the parsing of the ++binaries to find their @dfn{build id} content is printed. ++ ++@kindex show build-id-verbose ++@item show build-id-verbose ++Show the current verbosity value for the @dfn{build id} content locating. ++ ++@end table ++ + @cindex @code{.gnu_debuglink} sections + @cindex debug link sections + A debug link is a special section of the executable file named +diff --git a/gdb/dwarf2/index-cache.c b/gdb/dwarf2/index-cache.c +--- a/gdb/dwarf2/index-cache.c ++++ b/gdb/dwarf2/index-cache.c +@@ -96,7 +96,7 @@ index_cache_store_context::index_cache_store_context (const index_cache &ic, +     return; +  +   /* Get build id of objfile.  */ +-  const bfd_build_id *build_id = build_id_bfd_get (per_bfd->obfd); ++  const bfd_build_id *build_id = build_id_bfd_shdr_get (per_bfd->obfd); +   if (build_id == nullptr) +     { +       index_cache_debug ("objfile %s has no build id", +@@ -111,7 +111,8 @@ index_cache_store_context::index_cache_store_context (const index_cache &ic, +  +   if (dwz != nullptr) +     { +-      const bfd_build_id *dwz_build_id = build_id_bfd_get (dwz->dwz_bfd.get ()); ++      const bfd_build_id *dwz_build_id ++	= build_id_bfd_shdr_get (dwz->dwz_bfd.get ()); +  +       if (dwz_build_id == nullptr) + 	{ +diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c +--- a/gdb/dwarf2/read.c ++++ b/gdb/dwarf2/read.c +@@ -3355,7 +3355,7 @@ get_gdb_index_contents_from_section (objfile *obj, T *section_owner) + static gdb::array_view<const gdb_byte> + get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_bfd *dwarf2_per_bfd) + { +-  const bfd_build_id *build_id = build_id_bfd_get (obj->obfd.get ()); ++  const bfd_build_id *build_id = build_id_bfd_shdr_get (obj->obfd.get ()); +   if (build_id == nullptr) +     return {}; +  +@@ -3368,7 +3368,7 @@ get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_bfd *dwarf2_per_bfd) + static gdb::array_view<const gdb_byte> + get_gdb_index_contents_from_cache_dwz (objfile *obj, dwz_file *dwz) + { +-  const bfd_build_id *build_id = build_id_bfd_get (dwz->dwz_bfd.get ()); ++  const bfd_build_id *build_id = build_id_bfd_shdr_get (dwz->dwz_bfd.get ()); +   if (build_id == nullptr) +     return {}; +  +diff --git a/gdb/elfread.c b/gdb/elfread.c +--- a/gdb/elfread.c ++++ b/gdb/elfread.c +@@ -1220,8 +1220,10 @@ elf_symfile_read_dwarf2 (struct objfile *objfile, +     { +       deferred_warnings warnings; +  ++      gdb::unique_xmalloc_ptr<char> build_id_filename; +       std::string debugfile +-	= find_separate_debug_file_by_buildid (objfile, &warnings); ++	= find_separate_debug_file_by_buildid (objfile, &warnings, ++					       &build_id_filename); +  +       if (debugfile.empty ()) + 	debugfile = find_separate_debug_file_by_debuglink (objfile, &warnings); +@@ -1239,7 +1241,7 @@ elf_symfile_read_dwarf2 (struct objfile *objfile, + 	{ + 	  has_dwarf2 = false; + 	  const struct bfd_build_id *build_id +-	    = build_id_bfd_get (objfile->obfd.get ()); ++	    = build_id_bfd_shdr_get (objfile->obfd.get ()); + 	  const char *filename = bfd_get_filename (objfile->obfd.get ()); +  + 	  if (build_id != nullptr) +@@ -1265,6 +1267,11 @@ elf_symfile_read_dwarf2 (struct objfile *objfile, + 		      has_dwarf2 = true; + 		    } + 		} ++		/* Check if any separate debug info has been extracted out.  */ ++		else if (bfd_get_section_by_name (objfile->obfd.get (), ++		                                  ".gnu_debuglink") ++			 != NULL) ++		  debug_print_missing (objfile_name (objfile), build_id_filename.get ()); + 	    } + 	} +       /* If all the methods to collect the debuginfo failed, print the +diff --git a/gdb/exec.c b/gdb/exec.c +--- a/gdb/exec.c ++++ b/gdb/exec.c +@@ -237,7 +237,7 @@ validate_exec_file (int from_tty) +   current_exec_file = get_exec_file (0); +  +   const bfd_build_id *exec_file_build_id +-    = build_id_bfd_get (current_program_space->exec_bfd ()); ++    = build_id_bfd_shdr_get (current_program_space->exec_bfd ()); +   if (exec_file_build_id != nullptr) +     { +       /* Prepend the target prefix, to force gdb_bfd_open to open the +@@ -250,7 +250,7 @@ validate_exec_file (int from_tty) +       if (abfd != nullptr) + 	{ + 	  const bfd_build_id *target_exec_file_build_id +-	    = build_id_bfd_get (abfd.get ()); ++	    = build_id_bfd_shdr_get (abfd.get ()); +  + 	  if (target_exec_file_build_id != nullptr) + 	    { +diff --git a/gdb/objfiles.h b/gdb/objfiles.h +--- a/gdb/objfiles.h ++++ b/gdb/objfiles.h +@@ -884,6 +884,10 @@ struct objfile +   bool object_format_has_copy_relocs = false; + }; +  ++/* This file was loaded according to the BUILD_ID_CORE_LOADS rules.  */ ++ ++#define OBJF_BUILD_ID_CORE_LOADED static_cast<enum objfile_flag>(1 << 12) ++ + /* A deleter for objfile.  */ +  + struct objfile_deleter +diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c +--- a/gdb/python/py-objfile.c ++++ b/gdb/python/py-objfile.c +@@ -158,7 +158,7 @@ objfpy_get_build_id (PyObject *self, void *closure) +  +   try +     { +-      build_id = build_id_bfd_get (objfile->obfd.get ()); ++      build_id = build_id_bfd_shdr_get (objfile->obfd.get ()); +     } +   catch (const gdb_exception &except) +     { +@@ -629,7 +629,7 @@ gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw) + 	   if (obfd == nullptr) + 	     return 0; +  +-	   const bfd_build_id *obfd_build_id = build_id_bfd_get (obfd); ++	   const bfd_build_id *obfd_build_id = build_id_bfd_shdr_get (obfd); + 	   if (obfd_build_id == nullptr) + 	     return 0; +  +diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c +--- a/gdb/solib-svr4.c ++++ b/gdb/solib-svr4.c +@@ -44,6 +44,7 @@ + #include "auxv.h" + #include "gdb_bfd.h" + #include "probe.h" ++#include "build-id.h" +  + #include <map> +  +@@ -1318,9 +1319,51 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm, + 	  continue; + 	} +  +-      strncpy (newobj->so_name, buffer.get (), SO_NAME_MAX_PATH_SIZE - 1); +-      newobj->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; +-      strcpy (newobj->so_original_name, newobj->so_name); ++      { ++	struct bfd_build_id *build_id; ++ ++	strncpy (newobj->so_original_name, buffer.get (), SO_NAME_MAX_PATH_SIZE - 1); ++	newobj->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; ++	/* May get overwritten below.  */ ++	strcpy (newobj->so_name, newobj->so_original_name); ++ ++	build_id = build_id_addr_get (((lm_info_svr4 *) newobj->lm_info)->l_ld); ++	if (build_id != NULL) ++	  { ++	    char *name, *build_id_filename; ++ ++	    /* Missing the build-id matching separate debug info file ++	       would be handled while SO_NAME gets loaded.  */ ++	    name = build_id_to_filename (build_id, &build_id_filename); ++	    if (name != NULL) ++	      { ++		strncpy (newobj->so_name, name, SO_NAME_MAX_PATH_SIZE - 1); ++		newobj->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; ++		xfree (name); ++	      } ++	    else ++	      { ++		debug_print_missing (newobj->so_name, build_id_filename); ++ ++		/* In the case the main executable was found according to ++		   its build-id (from a core file) prevent loading ++		   a different build of a library with accidentally the ++		   same SO_NAME. ++ ++		   It suppresses bogus backtraces (and prints "??" there ++		   instead) if the on-disk files no longer match the ++		   running program version.  */ ++ ++		if (current_program_space->symfile_object_file != NULL ++		    && (current_program_space->symfile_object_file->flags ++			& OBJF_BUILD_ID_CORE_LOADED) != 0) ++		  newobj->so_name[0] = 0; ++	      } ++ ++	    xfree (build_id_filename); ++	    xfree (build_id); ++	  } ++      } +  +       /* If this entry has no name, or its name matches the name + 	 for the main executable, don't include it in the list.  */ +diff --git a/gdb/source.c b/gdb/source.c +--- a/gdb/source.c ++++ b/gdb/source.c +@@ -1167,7 +1167,7 @@ open_source_file (struct symtab *s) + 	    } +  + 	  const struct bfd_build_id *build_id +-	    = build_id_bfd_get (ofp->obfd.get ()); ++	    = build_id_bfd_shdr_get (ofp->obfd.get ()); +  + 	  /* Query debuginfod for the source file.  */ + 	  if (build_id != nullptr && !srcpath.empty ()) +diff --git a/gdb/symfile.h b/gdb/symfile.h +--- a/gdb/symfile.h ++++ b/gdb/symfile.h +@@ -357,12 +357,18 @@ bool expand_symtabs_matching + void map_symbol_filenames (gdb::function_view<symbol_filename_ftype> fun, + 			   bool need_fullname); +  ++ + /* Target-agnostic function to load the sections of an executable into memory. +  +    ARGS should be in the form "EXECUTABLE [OFFSET]", where OFFSET is an +    optional offset to apply to each section.  */ + extern void generic_load (const char *args, int from_tty); +  ++/* build-id support.  */ ++extern struct bfd_build_id *build_id_addr_get (CORE_ADDR addr); ++extern void debug_print_missing (const char *binary, const char *debug); ++#define BUILD_ID_MAIN_EXECUTABLE_FILENAME _("the main executable file") ++ + /* From minidebug.c.  */ +  + extern gdb_bfd_ref_ptr find_separate_debug_file_in_section (struct objfile *); +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 +@@ -347,3 +347,33 @@ gdb_test_multiple "core-file $corefile" $test { + 	pass $test +     } + } ++ ++ ++# Test auto-loading of binary files through build-id from the core file. ++set buildid [build_id_debug_filename_get $binfile] ++set wholetest "binfile found by build-id" ++if {$buildid == ""} { ++    untested "$wholetest (binary has no build-id)" ++} else { ++    gdb_exit ++    gdb_start ++ ++    regsub {\.debug$} $buildid {} buildid ++    set debugdir [standard_output_file ${testfile}-debugdir] ++    file delete -force -- $debugdir ++    file mkdir $debugdir/[file dirname $buildid] ++    file copy $binfile $debugdir/$buildid ++ ++    set test "show debug-file-directory" ++    gdb_test_multiple $test $test { ++	-re "The directory where separate debug symbols are searched for is \"(.*)\"\\.\r\n$gdb_prompt $" { ++	    set debugdir_orig $expect_out(1,string) ++	    pass $test ++	} ++    } ++    gdb_test_no_output "set debug-file-directory $debugdir:$debugdir_orig" "set debug-file-directory" ++    gdb_test "show build-id-core-loads" {Whether CORE-FILE loads the build-id associated files automatically is on\.} ++    gdb_test "core-file $corefile" "\r\nProgram terminated with .*" "core-file without executable" ++    gdb_test "info files" "Local exec file:\r\n\[ \t\]*`[string_to_regexp $debugdir/$buildid]', file type .*" ++    pass $wholetest ++} +diff --git a/gdb/testsuite/gdb.base/gdbinit-history.exp b/gdb/testsuite/gdb.base/gdbinit-history.exp +--- a/gdb/testsuite/gdb.base/gdbinit-history.exp ++++ b/gdb/testsuite/gdb.base/gdbinit-history.exp +@@ -179,7 +179,8 @@ proc test_empty_history_filename { } { +     global env +     global gdb_prompt +  +-    set common_history [list "set height 0" "set width 0"] ++    set common_history [list "set height 0" "set width 0" \ ++			    "set build-id-verbose 0"] +  +     set test_dir [standard_output_file history_test] +     remote_exec host "mkdir -p $test_dir" +diff --git a/gdb/testsuite/gdb.base/new-ui-pending-input.exp b/gdb/testsuite/gdb.base/new-ui-pending-input.exp +--- a/gdb/testsuite/gdb.base/new-ui-pending-input.exp ++++ b/gdb/testsuite/gdb.base/new-ui-pending-input.exp +@@ -62,6 +62,7 @@ proc test_command_line_new_ui_pending_input {} { +     set options "" +     append options " -iex \"set height 0\"" +     append options " -iex \"set width 0\"" ++    append options " -iex \"set build-id-verbose 0\"" +     append options " -iex \"new-ui console $extra_tty_name\"" +     append options " -ex \"b $bpline\"" +     append options " -ex \"run\"" +diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp +--- a/gdb/testsuite/lib/gdb.exp ++++ b/gdb/testsuite/lib/gdb.exp +@@ -226,7 +226,8 @@ if ![info exists INTERNAL_GDBFLAGS] { + 		   "-nx" \ + 		   "-q" \ + 		   {-iex "set height 0"} \ +-		   {-iex "set width 0"}]] ++		   {-iex "set width 0"} \ ++		   {-iex "set build-id-verbose 0"}]] +  +     # If DEBUGINFOD_URLS is set, gdb will try to download sources and +     # debug info for f.i. system libraries.  Prevent this. +@@ -2434,6 +2435,17 @@ proc default_gdb_start { } { + 	} +     } +  ++    # Turn off the missing warnings as the testsuite does not expect it. ++    send_gdb "set build-id-verbose 0\n" ++    gdb_expect 10 { ++	-re "$gdb_prompt $" { ++	    verbose "Disabled the missing debug infos warnings." 2 ++	} ++	timeout { ++	    warning "Could not disable the missing debug infos warnings.." ++	} ++    } ++ +     gdb_debug_init +     return 0 + } +diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp +--- a/gdb/testsuite/lib/mi-support.exp ++++ b/gdb/testsuite/lib/mi-support.exp +@@ -321,6 +321,16 @@ proc default_mi_gdb_start { { flags {} } } { + 	    warning "Couldn't set the width to 0." + 	} +     } ++    # Turn off the missing warnings as the testsuite does not expect it. ++    send_gdb "190-gdb-set build-id-verbose 0\n" ++    gdb_expect 10 { ++	-re ".*190-gdb-set build-id-verbose 0\r\n190\\\^done\r\n$mi_gdb_prompt$" { ++	    verbose "Disabled the missing debug infos warnings." 2 ++	} ++	timeout { ++	    warning "Could not disable the missing debug infos warnings.." ++	} ++    } +  +     if { $separate_inferior_pty } { + 	mi_create_inferior_pty diff --git a/gdb-6.6-bz229517-gcore-without-terminal.patch b/gdb-6.6-bz229517-gcore-without-terminal.patch new file mode 100644 index 0000000..2c127cc --- /dev/null +++ b/gdb-6.6-bz229517-gcore-without-terminal.patch @@ -0,0 +1,188 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Jan Kratochvil <jan.kratochvil@redhat.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-6.6-bz229517-gcore-without-terminal.patch + +;; Allow running `/usr/bin/gcore' with provided but inaccessible tty (BZ 229517). +;;=fedoratest + +2007-04-22  Jan Kratochvil <jan.kratochvil@redhat.com> + +	* gdb_gcore.sh: Redirect GDB from `</dev/null'. + +2007-04-22  Jan Kratochvil <jan.kratochvil@redhat.com> + +	* gdb.base/gcorebg.exp, gdb.base/gcorebg.c: New files. + +diff --git a/gdb/testsuite/gdb.base/gcorebg.c b/gdb/testsuite/gdb.base/gcorebg.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/gcorebg.c +@@ -0,0 +1,49 @@ ++#include <stdio.h> ++#include <sys/types.h> ++#include <unistd.h> ++#include <stdlib.h> ++#include <signal.h> ++#include <string.h> ++#include <assert.h> ++ ++int main (int argc, char **argv) ++{ ++  pid_t pid = 0; ++  pid_t ppid; ++  char buf[1024*2 + 500]; ++  int gotint; ++ ++  if (argc != 4) ++    { ++      fprintf (stderr, "Syntax: %s {standard|detached} <gcore command> <core output file>\n", ++	       argv[0]); ++      exit (1); ++    } ++ ++  pid = fork (); ++ ++  switch (pid) ++    { ++      case 0: ++        if (strcmp (argv[1], "detached") == 0) ++	  setpgrp (); ++	ppid = getppid (); ++	gotint = snprintf (buf, sizeof (buf), "sh %s -o %s %d", argv[2], argv[3], (int) ppid); ++	assert (gotint < sizeof (buf)); ++	system (buf); ++	fprintf (stderr, "Killing parent PID %d\n", ppid); ++	kill (ppid, SIGTERM); ++	break; ++ ++      case -1: ++	perror ("fork err\n"); ++	exit (1); ++	break; ++ ++      default: ++	fprintf (stderr,"Sleeping as PID %d\n", getpid ()); ++	sleep (60); ++    } ++ ++  return 0; ++} +diff --git a/gdb/testsuite/gdb.base/gcorebg.exp b/gdb/testsuite/gdb.base/gcorebg.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/gcorebg.exp +@@ -0,0 +1,113 @@ ++# Copyright 2007 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 2 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, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ ++# Please email any bugs, comments, and/or additions to this file to: ++# bug-gdb@prep.ai.mit.edu ++ ++# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>. ++# This is a test for `gdb_gcore.sh' functionality. ++# It also tests a regression with `gdb_gcore.sh' being run without its ++# accessible terminal. ++ ++if ![info exists GCORE] { ++    set GCORE "[standard_output_file ../../../../gcore]" ++} ++verbose "using GCORE = $GCORE" 2 ++ ++set testfile "gcorebg" ++set srcfile  ${testfile}.c ++set binfile  [standard_output_file ${testfile}] ++set corefile [standard_output_file ${testfile}.test] ++ ++if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { ++     untested gcorebg.exp ++     return -1 ++} ++ ++# Cleanup. ++ ++proc core_clean {} { ++    global corefile ++ ++    foreach file [glob -nocomplain [join [list $corefile *] ""]] { ++	verbose "Delete file $file" 1 ++	remote_file target delete $file ++    } ++} ++core_clean ++remote_file target delete "./gdb" ++ ++# Generate the core file. ++ ++# Provide `./gdb' for `gdb_gcore.sh' running it as a bare `gdb' command. ++# Setup also `$PATH' appropriately. ++# If GDB was not found let `gdb_gcore.sh' to find the system GDB by `$PATH'. ++if {$GDB != "gdb"} { ++    file link ./gdb $GDB ++} ++global env ++set oldpath $env(PATH) ++set env(PATH) [join [list . $env(PATH)] ":"] ++verbose "PATH = $env(PATH)" 2 ++ ++# Test file body. ++# $detached == "standard" || $detached == "detached" ++ ++proc test_body { detached } { ++    global binfile ++    global GCORE ++    global corefile ++ ++    set res [remote_spawn target "$binfile $detached $GCORE $corefile"] ++    if { $res < 0 || $res == "" } { ++	fail "Spawning $detached gcore" ++	return 1 ++    } ++    pass "Spawning $detached gcore" ++    remote_expect target 20 { ++	timeout { ++	    fail "Spawned $detached gcore finished (timeout)" ++	    remote_exec target "kill -9 -[exp_pid -i $res]" ++	    return 1 ++	} ++	"Saved corefile .*\r\nKilling parent PID " { ++	    pass "Spawned $detached gcore finished" ++	    remote_wait target 20 ++	} ++    } ++ ++    if {1 == [llength [glob -nocomplain [join [list $corefile *] ""]]]} { ++	pass "Core file generated by $detached gcore" ++    } else { ++	fail "Core file generated by $detached gcore" ++    } ++    core_clean ++} ++ ++# First a general `gdb_gcore.sh' spawn with its controlling terminal available. ++ ++test_body standard ++ ++# And now `gdb_gcore.sh' spawn without its controlling terminal available. ++# It is spawned through `gcorebg.c' using setpgrp (). ++ ++test_body detached ++ ++ ++# Cleanup. ++ ++set env(PATH) $oldpath ++remote_file target delete "./gdb" diff --git a/gdb-6.6-bz237572-ppc-atomic-sequence-test.patch b/gdb-6.6-bz237572-ppc-atomic-sequence-test.patch new file mode 100644 index 0000000..4faef13 --- /dev/null +++ b/gdb-6.6-bz237572-ppc-atomic-sequence-test.patch @@ -0,0 +1,278 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Jan Kratochvil <jan.kratochvil@redhat.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-6.6-bz237572-ppc-atomic-sequence-test.patch + +;; Support for stepping over PPC atomic instruction sequences (BZ 237572). +;;=fedoratest + +2007-06-25  Jan Kratochvil  <jan.kratochvil@redhat.com> + +	* gdb.threads/atomic-seq-threaded.c, +	gdb.threads/atomic-seq-threaded.exp: New files. + +diff --git a/gdb/testsuite/gdb.threads/atomic-seq-threaded.c b/gdb/testsuite/gdb.threads/atomic-seq-threaded.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.threads/atomic-seq-threaded.c +@@ -0,0 +1,171 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++   Copyright 2007 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 2 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, write to the Free Software ++   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, ++   MA 02110-1301, USA.  */ ++ ++/* Test stepping over RISC atomic sequences. ++   This variant testcases the code for stepping another thread while skipping ++   over the atomic sequence in the former thread ++   (STEPPING_PAST_SINGLESTEP_BREAKPOINT). ++   Code comes from gcc/testsuite/gcc.dg/sync-2.c  */ ++ ++/* { dg-options "-march=i486" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ ++/* { dg-options "-mcpu=v9" { target sparc*-*-* } } */ ++ ++/* Test functionality of the intrinsics for 'short' and 'char'.  */ ++ ++#include <stdlib.h> ++#include <string.h> ++#include <pthread.h> ++#include <assert.h> ++#include <unistd.h> ++ ++#define LOOPS 2 ++ ++static int unused; ++ ++static char AI[18]; ++static char init_qi[18] = { 3,5,7,9,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0 }; ++static char test_qi[18] = { 3,5,7,9,1,4,22,-12,7,8,9,7,1,-12,7,8,9,7 }; ++ ++static void ++do_qi (void) ++{ ++  if (__sync_fetch_and_add(AI+4, 1) != 0) ++    abort (); ++  if (__sync_fetch_and_add(AI+5, 4) != 0) ++    abort (); ++  if (__sync_fetch_and_add(AI+6, 22) != 0) ++    abort (); ++  if (__sync_fetch_and_sub(AI+7, 12) != 0) ++    abort (); ++  if (__sync_fetch_and_and(AI+8, 7) != (char)-1) ++    abort (); ++  if (__sync_fetch_and_or(AI+9, 8) != 0) ++    abort (); ++  if (__sync_fetch_and_xor(AI+10, 9) != 0) ++    abort (); ++  if (__sync_fetch_and_nand(AI+11, 7) != 0) ++    abort (); ++ ++  if (__sync_add_and_fetch(AI+12, 1) != 1) ++    abort (); ++  if (__sync_sub_and_fetch(AI+13, 12) != (char)-12) ++    abort (); ++  if (__sync_and_and_fetch(AI+14, 7) != 7) ++    abort (); ++  if (__sync_or_and_fetch(AI+15, 8) != 8) ++    abort (); ++  if (__sync_xor_and_fetch(AI+16, 9) != 9) ++    abort (); ++  if (__sync_nand_and_fetch(AI+17, 7) != 7) ++    abort (); ++} ++ ++static short AL[18]; ++static short init_hi[18] = { 3,5,7,9,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0 }; ++static short test_hi[18] = { 3,5,7,9,1,4,22,-12,7,8,9,7,1,-12,7,8,9,7 }; ++ ++static void ++do_hi (void) ++{ ++  if (__sync_fetch_and_add(AL+4, 1) != 0) ++    abort (); ++  if (__sync_fetch_and_add(AL+5, 4) != 0) ++    abort (); ++  if (__sync_fetch_and_add(AL+6, 22) != 0) ++    abort (); ++  if (__sync_fetch_and_sub(AL+7, 12) != 0) ++    abort (); ++  if (__sync_fetch_and_and(AL+8, 7) != -1) ++    abort (); ++  if (__sync_fetch_and_or(AL+9, 8) != 0) ++    abort (); ++  if (__sync_fetch_and_xor(AL+10, 9) != 0) ++    abort (); ++  if (__sync_fetch_and_nand(AL+11, 7) != 0) ++    abort (); ++ ++  if (__sync_add_and_fetch(AL+12, 1) != 1) ++    abort (); ++  if (__sync_sub_and_fetch(AL+13, 12) != -12) ++    abort (); ++  if (__sync_and_and_fetch(AL+14, 7) != 7) ++    abort (); ++  if (__sync_or_and_fetch(AL+15, 8) != 8) ++    abort (); ++  if (__sync_xor_and_fetch(AL+16, 9) != 9) ++    abort (); ++  if (__sync_nand_and_fetch(AL+17, 7) != 7) ++    abort (); ++} ++ ++static void * ++start1 (void *arg) ++{ ++  unsigned loop; ++  sleep(1); ++ ++  for (loop = 0; loop < LOOPS; loop++) ++    { ++      memcpy(AI, init_qi, sizeof(init_qi)); ++ ++      do_qi (); ++ ++      if (memcmp (AI, test_qi, sizeof(test_qi))) ++	abort (); ++    } ++ ++  return arg;						/* _delete1_ */ ++} ++ ++static void * ++start2 (void *arg) ++{ ++  unsigned loop; ++ ++  for (loop = 0; loop < LOOPS; loop++) ++    { ++      memcpy(AL, init_hi, sizeof(init_hi)); ++ ++      do_hi (); ++ ++      if (memcmp (AL, test_hi, sizeof(test_hi))) ++	abort (); ++    } ++ ++  return arg;						/* _delete2_ */ ++} ++ ++int ++main (int argc, char **argv) ++{ ++  pthread_t thread; ++  int i; ++ ++  i = pthread_create (&thread, NULL, start1, NULL);	/* _create_ */ ++  assert (i == 0);					/* _create_after_ */ ++ ++  sleep (1); ++ ++  start2 (NULL); ++ ++  i = pthread_join (thread, NULL);			/* _delete_ */ ++  assert (i == 0); ++ ++  return 0;						/* _exit_ */ ++} +diff --git a/gdb/testsuite/gdb.threads/atomic-seq-threaded.exp b/gdb/testsuite/gdb.threads/atomic-seq-threaded.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.threads/atomic-seq-threaded.exp +@@ -0,0 +1,84 @@ ++# atomic-seq-threaded.exp -- Test case for stepping over RISC atomic code seqs. ++# This variant testcases the code for stepping another thread while skipping ++# over the atomic sequence in the former thread ++# (STEPPING_PAST_SINGLESTEP_BREAKPOINT). ++# Copyright (C) 2007 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 2 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, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */ ++ ++# Please email any bugs, comments, and/or additions to this file to: ++# bug-gdb@prep.ai.mit.edu ++ ++set testfile atomic-seq-threaded ++set srcfile ${testfile}.c ++set binfile [standard_output_file ${testfile}] ++ ++foreach opts {{} {compiler=gcc4} {FAIL}} { ++    if {$opts eq "FAIL"} { ++	return -1 ++    } ++    if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug $opts]] eq "" } { ++	break ++    } ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++ ++gdb_load ${binfile} ++if ![runto_main] then { ++   fail "Can't run to main" ++   return 0 ++} ++ ++# pthread_create () will not pass even on x86_64 with software watchpoint. ++# Pass after pthread_create () without any watchpoint active. ++set line [gdb_get_line_number "_create_after_"] ++gdb_test "tbreak $line" \ ++	 "reakpoint (\[0-9\]+) at .*$srcfile, line $line\..*" \ ++	 "set breakpoint after pthread_create ()" ++gdb_test "c" \ ++	 ".*/\\* _create_after_ \\*/.*" \ ++	 "run till after pthread_create ()" ++ ++# Without a watchpoint being software no single-stepping would be used. ++set test "Start (software) watchpoint" ++gdb_test_multiple "watch unused" $test { ++    -re "Watchpoint \[0-9\]+: unused.*$gdb_prompt $" { ++	pass $test ++    } ++    -re "Hardware watchpoint \[0-9\]+: unused.*$gdb_prompt $" { ++	# We do not test the goal but still the whole testcase should pass. ++	unsupported $test ++    } ++} ++ ++# More thorough testing of the scheduling logic. ++gdb_test "set scheduler-locking step" "" ++ ++# Critical code path is stepped through at this point. ++set line [gdb_get_line_number "_exit_"] ++gdb_test "tbreak $line" \ ++	 "reakpoint \[0-9\]+ at .*$srcfile, line $line\..*" \ ++	 "set breakpoint at _exit_" ++gdb_test "c" \ ++	 ".*/\\* _exit_ \\*/.*" \ ++	 "run till _exit_" ++ ++# Just a nonproblematic program exit. ++gdb_test "c" \ ++	 ".*Program exited normally\\..*" \ ++	 "run till program exit" diff --git a/gdb-6.6-testsuite-timeouts.patch b/gdb-6.6-testsuite-timeouts.patch new file mode 100644 index 0000000..9a31a5b --- /dev/null +++ b/gdb-6.6-testsuite-timeouts.patch @@ -0,0 +1,32 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-6.6-testsuite-timeouts.patch + +;; Avoid too long timeouts on failing cases of "annota1.exp annota3.exp". +;;=fedoratest + +diff --git a/gdb/testsuite/gdb.base/annota1.exp b/gdb/testsuite/gdb.base/annota1.exp +--- a/gdb/testsuite/gdb.base/annota1.exp ++++ b/gdb/testsuite/gdb.base/annota1.exp +@@ -37,6 +37,8 @@ if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb +  + clean_restart ${binfile} +  ++gdb_test "set breakpoint pending off" "" "Avoid lockup on nonexisting functions" ++ + # The commands we test here produce many lines of output; disable "press  + # <return> to continue" prompts. + gdb_test_no_output "set height 0" +diff --git a/gdb/testsuite/gdb.base/annota3.exp b/gdb/testsuite/gdb.base/annota3.exp +--- a/gdb/testsuite/gdb.base/annota3.exp ++++ b/gdb/testsuite/gdb.base/annota3.exp +@@ -36,6 +36,8 @@ if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb +  + clean_restart ${binfile} +  ++gdb_test "set breakpoint pending off" "" "Avoid lockup on nonexisting functions" ++ + # The commands we test here produce many lines of output; disable "press  + # <return> to continue" prompts. + gdb_test_no_output "set height 0" diff --git a/gdb-6.7-ppc-clobbered-registers-O2-test.patch b/gdb-6.7-ppc-clobbered-registers-O2-test.patch new file mode 100644 index 0000000..08ee2f9 --- /dev/null +++ b/gdb-6.7-ppc-clobbered-registers-O2-test.patch @@ -0,0 +1,108 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Jan Kratochvil <jan.kratochvil@redhat.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-6.7-ppc-clobbered-registers-O2-test.patch + +;; Test PPC hiding of call-volatile parameter register. +;;=fedoratest + +2007-11-04  Jan Kratochvil  <jan.kratochvil@redhat.com> + +	* gdb.arch/ppc-clobbered-registers-O2.exp: `powerpc64' changed to +	`powerpc*'. + +Testcase for: + +http://sourceware.org/ml/gdb-patches/2007-09/msg00228.html + +2007-10-21  Luis Machado  <luisgpm@br.ibm.com> + +	* rs6000-tdep.c (ppc_dwarf2_frame_init_reg): New function. +	* (rs6000_gdbarch_init): Install ppc_dwarf2_frame_init_reg as +	default dwarf2_frame_set_init_reg function. + +diff --git a/gdb/testsuite/gdb.arch/ppc-clobbered-registers-O2.c b/gdb/testsuite/gdb.arch/ppc-clobbered-registers-O2.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.arch/ppc-clobbered-registers-O2.c +@@ -0,0 +1,21 @@ ++ ++unsigned * __attribute__((noinline)) ++start_sequence (unsigned * x, unsigned * y) ++{ ++	return (unsigned *)0xdeadbeef; ++}; ++ ++unsigned __attribute__((noinline)) ++gen_movsd (unsigned * operand0, unsigned * operand1) ++{ ++	return *start_sequence(operand0, operand1); ++} ++ ++int main(void) ++{ ++  unsigned x, y; ++ ++  x = 13; ++  y = 14; ++  return (int)gen_movsd (&x, &y); ++} +diff --git a/gdb/testsuite/gdb.arch/ppc-clobbered-registers-O2.exp b/gdb/testsuite/gdb.arch/ppc-clobbered-registers-O2.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.arch/ppc-clobbered-registers-O2.exp +@@ -0,0 +1,54 @@ ++# Copyright 2006 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 2 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, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++# ++# This file is part of the gdb testsuite. ++ ++# Test displaying call clobbered registers in optimized binaries for ppc. ++# GDB should not show incorrect values. ++ ++if ![istarget "powerpc*-*"] then { ++    verbose "Skipping powerpc* call clobbered registers testing." ++    return ++} ++ ++set testfile "ppc-clobbered-registers-O2" ++set srcfile ${testfile}.c ++set binfile [standard_output_file ${testfile}] ++set compile_flags "debug additional_flags=-O2" ++ ++if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable ${compile_flags}] != "" } { ++    unsupported "Testcase compile failed." ++    return -1 ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${binfile} ++ ++if ![runto_main] then { ++    perror "Couldn't run to breakpoint" ++    continue ++} ++ ++gdb_test "b start_sequence" ".*Breakpoint 2 at.*line 6.*" \ ++  "Insert breakpoint at problematic function" ++ ++gdb_test continue ".*Breakpoint 2.*in start_sequence.*" \ ++  "Run until problematic function" ++ ++gdb_test backtrace ".*operand0=<value optimized out>.*operand1=<value optimized out>.*" \ ++  "Check value of call clobbered registers" diff --git a/gdb-6.8-bz466901-backtrace-full-prelinked.patch b/gdb-6.8-bz466901-backtrace-full-prelinked.patch new file mode 100644 index 0000000..39d8947 --- /dev/null +++ b/gdb-6.8-bz466901-backtrace-full-prelinked.patch @@ -0,0 +1,481 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-6.8-bz466901-backtrace-full-prelinked.patch + +;; Fix resolving of variables at locations lists in prelinked libs (BZ 466901). +;;=fedoratest + +Fix resolving of variables at locations lists in prelinked libs (BZ 466901). + +diff --git a/gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked-func.S b/gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked-func.S +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked-func.S +@@ -0,0 +1,328 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++   Copyright 2008 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 <http://www.gnu.org/licenses/>.  */ ++ ++/* ++#include <stdlib.h> ++ ++void ++func (void) ++{ ++  int i; ++ ++  abort (); ++} ++*/ ++	.file	"dw2-loclist-prelinked.c" ++	.section	.debug_abbrev,"",@progbits ++.Ldebug_abbrev0: ++	.section	.debug_info,"",@progbits ++.Ldebug_info0: ++	.section	.debug_line,"",@progbits ++.Ldebug_line0: ++	.text ++.Ltext0: ++.globl func ++	.type	func, @function ++func: ++.LFB2: ++	.file 1 "dw2-loclist-prelinked.c" ++	.loc 1 5 0 ++	pushl	%ebp ++.LCFI0: ++	movl	%esp, %ebp ++.LCFI1: ++	subl	$24, %esp ++.LCFI2: ++	.loc 1 8 0 ++	call	abort ++.LFE2: ++	.size	func, .-func ++	.section	.debug_frame,"",@progbits ++.Lframe0: ++	.long	.LECIE0-.LSCIE0 ++.LSCIE0: ++	.long	0xffffffff ++	.byte	0x1 ++	.string	"" ++	.uleb128 0x1 ++	.sleb128 -4 ++	.byte	0x8 ++	.byte	0xc ++	.uleb128 0x4 ++	.uleb128 0x4 ++	.byte	0x88 ++	.uleb128 0x1 ++	.align 4 ++.LECIE0: ++.LSFDE0: ++	.long	.LEFDE0-.LASFDE0 ++.LASFDE0: ++	.long	.Lframe0 ++	.long	.LFB2 ++	.long	.LFE2-.LFB2 ++	.byte	0x4 ++	.long	.LCFI0-.LFB2 ++	.byte	0xe ++	.uleb128 0x8 ++	.byte	0x85 ++	.uleb128 0x2 ++	.byte	0x4 ++	.long	.LCFI1-.LCFI0 ++	.byte	0xd ++	.uleb128 0x5 ++	.align 4 ++.LEFDE0: ++	.text ++.Letext0: ++	.section	.debug_loc,"",@progbits ++.Ldebug_loc0: ++.LLST0: ++	.long	.LFB2-.Ltext0 ++	.long	.LCFI0-.Ltext0 ++	.value	0x2 ++	.byte	0x74 ++	.sleb128 4 ++	.long	.LCFI0-.Ltext0 ++	.long	.LCFI1-.Ltext0 ++	.value	0x2 ++	.byte	0x74 ++	.sleb128 8 ++	.long	.LCFI1-.Ltext0 ++	.long	.LFE2-.Ltext0 ++	.value	0x2 ++	.byte	0x75 ++	.sleb128 8 ++	.long	0x0 ++	.long	0x0 ++	.section	.debug_info ++	.long	0x94 ++	.value	0x2 ++	.long	.Ldebug_abbrev0 ++	.byte	0x4 ++	.uleb128 0x1 ++	.long	.LASF10 ++	.byte	0x1 ++	.long	.LASF11 ++	.long	.LASF12 ++	.long	.Ltext0 ++	.long	.Letext0 ++	.long	.Ldebug_line0 ++	.uleb128 0x2 ++	.byte	0x4 ++	.byte	0x7 ++	.long	.LASF0 ++	.uleb128 0x3 ++	.byte	0x4 ++	.byte	0x5 ++	.string	"int" ++	.uleb128 0x2 ++	.byte	0x4 ++	.byte	0x5 ++	.long	.LASF1 ++	.uleb128 0x2 ++	.byte	0x1 ++	.byte	0x8 ++	.long	.LASF2 ++	.uleb128 0x2 ++	.byte	0x2 ++	.byte	0x7 ++	.long	.LASF3 ++	.uleb128 0x2 ++	.byte	0x4 ++	.byte	0x7 ++	.long	.LASF4 ++	.uleb128 0x2 ++	.byte	0x1 ++	.byte	0x6 ++	.long	.LASF5 ++	.uleb128 0x2 ++	.byte	0x2 ++	.byte	0x5 ++	.long	.LASF6 ++	.uleb128 0x2 ++	.byte	0x8 ++	.byte	0x5 ++	.long	.LASF7 ++	.uleb128 0x2 ++	.byte	0x8 ++	.byte	0x7 ++	.long	.LASF8 ++	.uleb128 0x4 ++	.byte	0x4 ++	.byte	0x7 ++	.uleb128 0x2 ++	.byte	0x1 ++	.byte	0x6 ++	.long	.LASF9 ++	.uleb128 0x5 ++	.byte	0x1 ++	.long	.LASF13 ++	.byte	0x1 ++	.byte	0x5 ++	.byte	0x1 ++	.long	.LFB2 ++	.long	.LFE2 ++	.long	.LLST0 ++	.uleb128 0x6 ++	.string	"i" ++	.byte	0x1 ++	.byte	0x6 ++	.long	0x2c ++	.byte	0x2 ++	.byte	0x91 ++	.sleb128 -12 ++	.byte	0x0 ++	.byte	0x0 ++	.section	.debug_abbrev ++	.uleb128 0x1 ++	.uleb128 0x11 ++	.byte	0x1 ++	.uleb128 0x25 ++	.uleb128 0xe ++	.uleb128 0x13 ++	.uleb128 0xb ++	.uleb128 0x3 ++	.uleb128 0xe ++	.uleb128 0x1b ++	.uleb128 0xe ++	.uleb128 0x11 ++	.uleb128 0x1 ++	.uleb128 0x12 ++	.uleb128 0x1 ++	.uleb128 0x10 ++	.uleb128 0x6 ++	.byte	0x0 ++	.byte	0x0 ++	.uleb128 0x2 ++	.uleb128 0x24 ++	.byte	0x0 ++	.uleb128 0xb ++	.uleb128 0xb ++	.uleb128 0x3e ++	.uleb128 0xb ++	.uleb128 0x3 ++	.uleb128 0xe ++	.byte	0x0 ++	.byte	0x0 ++	.uleb128 0x3 ++	.uleb128 0x24 ++	.byte	0x0 ++	.uleb128 0xb ++	.uleb128 0xb ++	.uleb128 0x3e ++	.uleb128 0xb ++	.uleb128 0x3 ++	.uleb128 0x8 ++	.byte	0x0 ++	.byte	0x0 ++	.uleb128 0x4 ++	.uleb128 0x24 ++	.byte	0x0 ++	.uleb128 0xb ++	.uleb128 0xb ++	.uleb128 0x3e ++	.uleb128 0xb ++	.byte	0x0 ++	.byte	0x0 ++	.uleb128 0x5 ++	.uleb128 0x2e ++	.byte	0x1 ++	.uleb128 0x3f ++	.uleb128 0xc ++	.uleb128 0x3 ++	.uleb128 0xe ++	.uleb128 0x3a ++	.uleb128 0xb ++	.uleb128 0x3b ++	.uleb128 0xb ++	.uleb128 0x27 ++	.uleb128 0xc ++	.uleb128 0x11 ++	.uleb128 0x1 ++	.uleb128 0x12 ++	.uleb128 0x1 ++	.uleb128 0x40 ++	.uleb128 0x6 ++	.byte	0x0 ++	.byte	0x0 ++	.uleb128 0x6 ++	.uleb128 0x34 ++	.byte	0x0 ++	.uleb128 0x3 ++	.uleb128 0x8 ++	.uleb128 0x3a ++	.uleb128 0xb ++	.uleb128 0x3b ++	.uleb128 0xb ++	.uleb128 0x49 ++	.uleb128 0x13 ++	.uleb128 0x2 ++	.uleb128 0xa ++	.byte	0x0 ++	.byte	0x0 ++	.byte	0x0 ++	.section	.debug_pubnames,"",@progbits ++	.long	0x17 ++	.value	0x2 ++	.long	.Ldebug_info0 ++	.long	0x98 ++	.long	0x75 ++	.string	"func" ++	.long	0x0 ++	.section	.debug_aranges,"",@progbits ++	.long	0x1c ++	.value	0x2 ++	.long	.Ldebug_info0 ++	.byte	0x4 ++	.byte	0x0 ++	.value	0x0 ++	.value	0x0 ++	.long	.Ltext0 ++	.long	.Letext0-.Ltext0 ++	.long	0x0 ++	.long	0x0 ++	.section	.debug_str,"MS",@progbits,1 ++.LASF7: ++	.string	"long long int" ++.LASF0: ++	.string	"unsigned int" ++.LASF11: ++	.string	"dw2-loclist-prelinked.c" ++.LASF12: ++	.string	"gdb-6.8/gdb/testsuite/gdb.dwarf2" ++.LASF4: ++	.string	"long unsigned int" ++.LASF8: ++	.string	"long long unsigned int" ++.LASF2: ++	.string	"unsigned char" ++.LASF9: ++	.string	"char" ++.LASF1: ++	.string	"long int" ++.LASF3: ++	.string	"short unsigned int" ++.LASF5: ++	.string	"signed char" ++.LASF10: ++	.string	"GNU C 4.3.2 20081007 (Red Hat 4.3.2-6)" ++.LASF13: ++	.string	"func" ++.LASF6: ++	.string	"short int" ++	.ident	"GCC: (GNU) 4.3.2 20081007 (Red Hat 4.3.2-6)" ++	.section	.note.GNU-stack,"",@progbits +diff --git a/gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked-main.c b/gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked-main.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked-main.c +@@ -0,0 +1,26 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++   Copyright 2008 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 <http://www.gnu.org/licenses/>.  */ ++ ++/* dw2-loclist-prelinked-func.S */ ++extern void func (void); ++ ++int ++main (void) ++{ ++  func (); ++  return 0; ++} +diff --git a/gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked.exp b/gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked.exp +@@ -0,0 +1,102 @@ ++# Copyright 2008 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 2 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, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ ++# Minimal DWARF-2 unit test ++ ++# This test can only be run on i386/x86_64 targets which support DWARF-2. ++# For now pick a sampling of likely targets. ++if {(![istarget *-*-linux*] ++     && ![istarget *-*-gnu*] ++     && ![istarget *-*-elf*] ++     && ![istarget *-*-openbsd*]) ++    || (![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"])} { ++    return 0 ++} ++ ++set testfile "dw2-loclist-prelinked" ++set srcfuncfile ${testfile}-func.S ++set binsharedfuncfile [standard_output_file ${testfile}.so] ++set srcmainfile ${testfile}-main.c ++set binfile [standard_output_file ${testfile}] ++ ++remote_exec build "rm -f ${binfile}" ++ ++# get the value of gcc_compiled ++if [get_compiler_info ${binfile}] { ++    return -1 ++} ++ ++# This test can only be run on gcc as we use additional_flags=FIXME ++if {$gcc_compiled == 0} { ++    return 0 ++} ++ ++if  { [gdb_compile_shlib "${srcdir}/${subdir}/${srcfuncfile}" "${binsharedfuncfile}" {debug additional_flags=-m32}] != "" } { ++    untested "Couldn't compile test library" ++    return -1 ++} ++ ++# The new separate debug info file will be stored in the .debug subdirectory. ++ ++if [gdb_gnu_strip_debug ${binsharedfuncfile}] { ++    # check that you have a recent version of strip and objcopy installed ++    unsupported "cannot produce separate debug info files" ++    return -1 ++} ++ ++if {[catch "system \"/usr/sbin/prelink -qNR --no-exec-shield ${binsharedfuncfile}\""] != 0} { ++    # Maybe we don't have prelink. ++    return -1 ++} ++ ++if  { [gdb_compile "${srcdir}/${subdir}/${srcmainfile}" \ ++		   "${binfile}" executable [list debug additional_flags=-m32 shlib=${binsharedfuncfile}]] != "" } { ++    return -1 ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${binfile} ++ ++gdb_run_cmd ++ ++gdb_test "" "Program received signal SIGABRT, Aborted..*" "Enter abort()" ++ ++# Incorrect: ++# #0  0x00110430 in __kernel_vsyscall () ++# No symbol table info available. ++# #1  0x003d44c0 in raise () from /lib/libc.so.6 ++# No symbol table info available. ++# #2  0x003d5e88 in abort () from /lib/libc.so.6 ++# No symbol table info available. ++# #3  0x44f10437 in func () at dw2-loclist-prelinked.c:8 ++# 	i = Could not find the frame base for "func". ++ ++# Correct: ++# #0  0x00110430 in __kernel_vsyscall () ++# No symbol table info available. ++# #1  0x003d44c0 in raise () from /lib/libc.so.6 ++# No symbol table info available. ++# #2  0x003d5e88 in abort () from /lib/libc.so.6 ++# No symbol table info available. ++# #3  0x4ae36437 in func () at dw2-loclist-prelinked.c:8 ++# 	i = 3827288 ++# #4  0x0804851a in main () at ../../../gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked-main.c:24 ++# No locals. ++ ++# `abort' can get expressed as `*__GI_abort'. ++gdb_test "bt full" "in \[^ \]*abort \\(.*in func \\(.*\r\n\[\t \]+i = -?\[0-9\].*in main \\(.*" "Backtrace after abort()" diff --git a/gdb-add-index.patch b/gdb-add-index.patch new file mode 100644 index 0000000..5039172 --- /dev/null +++ b/gdb-add-index.patch @@ -0,0 +1,77 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-add-index.patch + +;; Update gdb-add-index.sh such that, when the GDB environment +;; variable is not set, the script is smarter than just looking for +;; 'gdb' in the $PATH. +;; +;; The actual search order is now: /usr/bin/gdb.minimal, gdb (in the +;; $PATH), then /usr/libexec/gdb. +;; +;; For the rationale of looking for gdb.minimal see: +;; +;;   https://fedoraproject.org/wiki/Changes/Minimal_GDB_in_buildroot +;; +;;=fedora + +diff --git a/gdb/contrib/gdb-add-index.sh b/gdb/contrib/gdb-add-index.sh +--- a/gdb/contrib/gdb-add-index.sh ++++ b/gdb/contrib/gdb-add-index.sh +@@ -16,14 +16,52 @@ + # You should have received a copy of the GNU General Public License + # along with this program.  If not, see <http://www.gnu.org/licenses/>. +  +-# This program assumes gdb and objcopy are in $PATH. +-# If not, or you want others, pass the following in the environment +-GDB=${GDB:=gdb} ++# This program assumes objcopy and readelf are in $PATH.  If not, or ++# you want others, pass the following in the environment + OBJCOPY=${OBJCOPY:=objcopy} + READELF=${READELF:=readelf} +  + myname="${0##*/}" +  ++# For GDB itself we need to be a little smarter.  If GDB is set in the ++# environment then we will use that.  But if GDB is not set in the ++# environment then we have a couple of options that we need to check ++# through. ++# ++# Our default choice is for /usr/bin/gdb.minimal.  For an explanation ++# of why this is chosen, check out: ++#   https://bugzilla.redhat.com/show_bug.cgi?id=1695015 ++#   https://fedoraproject.org/wiki/Changes/Minimal_GDB_in_buildroot ++# ++# If gdb.minimal is not found then we look for a 'gdb' executable on ++# the path. ++# ++# And finally, we check for /usr/libexec/gdb. ++# ++# If none of those result in a useable GDB then we give an error and ++# exit. ++if test -z "$GDB"; then ++    for possible_gdb in /usr/bin/gdb.minimal gdb /usr/libexec/gdb; do ++        if ! which "$possible_gdb" >/dev/null 2>&1; then ++            continue ++        fi ++ ++        possible_gdb=$(which "$possible_gdb") ++ ++        if ! test -x "$possible_gdb"; then ++            continue ++        fi ++ ++        GDB="$possible_gdb" ++        break ++    done ++ ++    if test -z "$GDB"; then ++        echo "$myname: Failed to find a useable GDB binary" 1>&2 ++        exit 1 ++    fi ++fi ++ + dwarf5="" + if [ "$1" = "-dwarf-5" ]; then +     dwarf5="$1" diff --git a/gdb-archer-next-over-throw-cxx-exec.patch b/gdb-archer-next-over-throw-cxx-exec.patch new file mode 100644 index 0000000..ba71cd3 --- /dev/null +++ b/gdb-archer-next-over-throw-cxx-exec.patch @@ -0,0 +1,88 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-archer-next-over-throw-cxx-exec.patch + +;; Fix follow-exec for C++ programs (bugreported by Martin Stransky). +;;=fedoratest + +Archer-upstreamed: +http://sourceware.org/ml/archer/2010-q2/msg00031.html + +diff --git a/gdb/testsuite/gdb.cp/cxxexec.cc b/gdb/testsuite/gdb.cp/cxxexec.cc +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.cp/cxxexec.cc +@@ -0,0 +1,25 @@ ++/* This test script is part of GDB, the GNU debugger. ++ ++   Copyright 2010 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 <http://www.gnu.org/licenses/>.  */ ++ ++#include <unistd.h> ++ ++int ++main() ++{ ++  execlp ("true", "true", NULL); ++  return 1; ++} +diff --git a/gdb/testsuite/gdb.cp/cxxexec.exp b/gdb/testsuite/gdb.cp/cxxexec.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.cp/cxxexec.exp +@@ -0,0 +1,42 @@ ++# Copyright 2010 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 <http://www.gnu.org/licenses/>. ++ ++if { [skip_cplus_tests] } { continue } ++ ++set testfile cxxexec ++if { [prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.cc {c++ debug}] } { ++    return -1 ++} ++ ++runto_main ++ ++# We could stop after `continue' again at `main'. ++delete_breakpoints ++ ++set test "p _Unwind_DebugHook" ++gdb_test_multiple $test $test { ++    -re " = .* 0x\[0-9a-f\].*\r\n$gdb_prompt $" { ++	pass $test ++    } ++    -re "\r\nNo symbol .*\r\n$gdb_prompt $" { ++	xfail $test ++	untested ${testfile}.exp ++	return -1 ++    } ++} ++ ++# Run to end.  The buggy GDB failed instead with: ++#  Cannot access memory at address ADDR. ++gdb_continue_to_end "" "continue" 1 diff --git a/gdb-bz634108-solib_address.patch b/gdb-bz634108-solib_address.patch new file mode 100644 index 0000000..58b473f --- /dev/null +++ b/gdb-bz634108-solib_address.patch @@ -0,0 +1,41 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-bz634108-solib_address.patch + +;; Verify GDB Python built-in function gdb.solib_address exists (BZ # 634108). +;;=fedoratest + +Fix gdb.solib_address (fix by Phil Muldoon). + +s/solib_address/solib_name/ during upstreaming. + +diff --git a/gdb/testsuite/gdb.python/rh634108-solib_address.exp b/gdb/testsuite/gdb.python/rh634108-solib_address.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.python/rh634108-solib_address.exp +@@ -0,0 +1,24 @@ ++# Copyright (C) 2008, 2009, 2010 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 <http://www.gnu.org/licenses/>. ++ ++# https://bugzilla.redhat.com/show_bug.cgi?id=634108 ++ ++gdb_exit ++gdb_start ++ ++# Skip all tests if Python scripting is not enabled. ++if { [skip_python_tests] } { continue } ++ ++gdb_test "python print (gdb.solib_name(-1))" "None" "gdb.solib_name exists" diff --git a/gdb-container-rh-pkg.patch b/gdb-container-rh-pkg.patch new file mode 100644 index 0000000..7107e5d --- /dev/null +++ b/gdb-container-rh-pkg.patch @@ -0,0 +1,30 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-container-rh-pkg.patch + +;; Add messages suggesting more recent RHEL gdbserver (RH BZ 1321114). +;;=fedora + +diff --git a/gdb/remote.c b/gdb/remote.c +--- a/gdb/remote.c ++++ b/gdb/remote.c +@@ -14742,7 +14742,17 @@ remote_target::pid_to_exec_file (int pid) +   char *annex = NULL; +  +   if (m_features.packet_support (PACKET_qXfer_exec_file) != PACKET_ENABLE) +-    return NULL; ++    { ++      warning (_("Remote gdbserver does not support determining executable " ++		 "automatically.\n" ++"RHEL <=6.8 and <=7.2 versions of gdbserver do not support such automatic executable detection.\n" ++"The following versions of gdbserver support it:\n" ++"- Upstream version of gdbserver (unsupported) 7.10 or later\n" ++"- Red Hat Developer Toolset (DTS) version of gdbserver from DTS 4.0 or later (only on x86_64)\n" ++"- RHEL-7.3 versions of gdbserver (on any architecture)" ++)); ++      return NULL; ++    } +  +   inferior *inf = find_inferior_pid (this, pid); +   if (inf == NULL) diff --git a/gdb-core-open-vdso-warning.patch b/gdb-core-open-vdso-warning.patch new file mode 100644 index 0000000..fdd06fb --- /dev/null +++ b/gdb-core-open-vdso-warning.patch @@ -0,0 +1,58 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-core-open-vdso-warning.patch + +;; Fix GNU/Linux core open: Can't read pathname for load map: Input/output error. +;; Fix regression of undisplayed missing shared libraries caused by a fix for. +;;=fedoratest: It should be in glibc: libc-alpha: <20091004161706.GA27450@.*> + +http://sourceware.org/ml/gdb-patches/2009-10/msg00142.html +Subject: [patch] Fix GNU/Linux core open: Can't read pathname for load map:  Input/output error. + +[ New patch variant.  ] + +commit 7d760051ffb8a23cdc51342d4e6243fbc462f73f +Author: Ulrich Weigand <uweigand@de.ibm.com> +Date:   Wed Sep 25 11:52:50 2013 +0000 + +diff --git a/gdb/testsuite/gdb.base/solib-symbol.exp b/gdb/testsuite/gdb.base/solib-symbol.exp +--- a/gdb/testsuite/gdb.base/solib-symbol.exp ++++ b/gdb/testsuite/gdb.base/solib-symbol.exp +@@ -27,6 +27,7 @@ set testfile "solib-symbol-main" + set srcfile ${srcdir}/${subdir}/${testfile}.c + set binfile [standard_output_file ${testfile}] + set bin_flags [list debug shlib=${binfile_lib}] ++set executable ${testfile} +  + if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != "" +      || [gdb_compile ${srcfile} ${binfile} executable $bin_flags] != "" } { +@@ -61,4 +62,28 @@ gdb_test "br foo2" \ + 	 "Breakpoint.*: foo2. .2 locations..*" \ + 	 "foo2 in mdlib" +  ++# Test GDB warns for shared libraris which have not been found. ++ ++gdb_test "info sharedlibrary" "/${libname}.*" ++ ++clean_restart ${executable} ++gdb_breakpoint "main" ++gdb_run_cmd ++set test "no warning for missing libraries" ++gdb_test_multiple "" $test { ++    -re "warning: Could not load shared library symbols for \[0-9\]+ libraries,.*\r\n$gdb_prompt $" { ++	fail $test ++    } ++    -re "Breakpoint \[0-9\]+, main .*\r\n$gdb_prompt $" { ++	pass $test ++    } ++} ++ ++clean_restart ${executable} ++gdb_test_no_output "set solib-absolute-prefix /doESnotEXIST" ++gdb_breakpoint "main" ++gdb_run_cmd ++gdb_test "" "warning: Could not load shared library symbols for \[0-9\]+ libraries,.*\r\nBreakpoint \[0-9\]+, main .*" \ ++	 "warning for missing libraries" ++ + gdb_exit diff --git a/gdb-fedora-libncursesw.patch b/gdb-fedora-libncursesw.patch new file mode 100644 index 0000000..1bb640d --- /dev/null +++ b/gdb-fedora-libncursesw.patch @@ -0,0 +1,333 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-fedora-libncursesw.patch + +;; Force libncursesw over libncurses to match the includes (RH BZ 1270534). +;;=push+jan + +Fedora: Force libncursesw over libncurses to match the includes. +https://bugzilla.redhat.com/show_bug.cgi?id=1270534 + +diff --git a/gdb/configure b/gdb/configure +--- a/gdb/configure ++++ b/gdb/configure +@@ -780,9 +780,6 @@ ENABLE_BFD_64_BIT_TRUE + subdirs + RPM_LIBS + RPM_CFLAGS +-PKG_CONFIG_LIBDIR +-PKG_CONFIG_PATH +-PKG_CONFIG + GDB_DATADIR + DEBUGDIR + MAKEINFO_EXTRA_FLAGS +@@ -990,12 +987,12 @@ PKG_CONFIG_PATH + PKG_CONFIG_LIBDIR + MAKEINFO + MAKEINFOFLAGS ++RPM_CFLAGS ++RPM_LIBS + AMD_DBGAPI_CFLAGS + AMD_DBGAPI_LIBS + DEBUGINFOD_CFLAGS + DEBUGINFOD_LIBS +-RPM_CFLAGS +-RPM_LIBS + YACC + YFLAGS + ZSTD_CFLAGS +@@ -1684,11 +1681,11 @@ Optional Packages: +                           [--with-auto-load-dir] +   --without-auto-load-safe-path +                           do not restrict auto-loaded files locations ++  --with-rpm              query rpm database for missing debuginfos (yes/no, ++                          def. auto=librpm.so) +   --with-amd-dbgapi       support for the amd-dbgapi target (yes / no / auto) +   --with-debuginfod       Enable debuginfo lookups with debuginfod +                           (auto/yes/no) +-  --with-rpm              query rpm database for missing debuginfos (yes/no, +-                          def. auto=librpm.so) +   --with-libunwind-ia64   use libunwind frame unwinding for ia64 targets +   --with-curses           use the curses library instead of the termcap +                           library +@@ -1761,6 +1758,8 @@ Some influential environment variables: +   MAKEINFO    Parent configure detects if it is of sufficient version. +   MAKEINFOFLAGS +               Parameters for MAKEINFO. ++  RPM_CFLAGS  C compiler flags for RPM, overriding pkg-config ++  RPM_LIBS    linker flags for RPM, overriding pkg-config +   AMD_DBGAPI_CFLAGS +               C compiler flags for AMD_DBGAPI, overriding pkg-config +   AMD_DBGAPI_LIBS +@@ -1769,8 +1768,6 @@ Some influential environment variables: +               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. +               Defaults to the first program found out of: `bison -y', `byacc', +               `yacc'. +@@ -11495,7 +11492,7 @@ else +   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 +   lt_status=$lt_dlunknown +   cat > conftest.$ac_ext <<_LT_EOF +-#line 11486 "configure" ++#line 11495 "configure" + #include "confdefs.h" +  + #if HAVE_DLFCN_H +@@ -11601,7 +11598,7 @@ else +   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 +   lt_status=$lt_dlunknown +   cat > conftest.$ac_ext <<_LT_EOF +-#line 11592 "configure" ++#line 11601 "configure" + #include "confdefs.h" +  + #if HAVE_DLFCN_H +@@ -18102,8 +18099,8 @@ $as_echo_n "checking specific librpm version... " >&6; } +   if test "$cross_compiling" = yes; then : +   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 + $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error "cannot run test program while cross compiling +-See \`config.log' for more details." "$LINENO" 5; } ++as_fn_error $? "cannot run test program while cross compiling ++See \`config.log' for more details" "$LINENO" 5; } + else +   cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h.  */ +@@ -18275,132 +18272,12 @@ $as_echo "#define HAVE_LIBRPM 1" >>confdefs.h + $as_echo "no" >&6; } +     LIBS="$save_LIBS" +     if $DLOPEN_REQUIRE; then +-      as_fn_error "Specific name $LIBRPM was requested but it could not be opened." "$LINENO" 5 ++      as_fn_error $? "Specific name $LIBRPM was requested but it could not be opened." "$LINENO" 5 +     fi +  +- +- +- +- +- +- +-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 test "${ac_cv_path_PKG_CONFIG+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$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 test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$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 +- + pkg_failed=no +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for RPM" >&5 +-$as_echo_n "checking for RPM... " >&6; } ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rpm" >&5 ++$as_echo_n "checking for rpm... " >&6; } +  + if test -n "$RPM_CFLAGS"; then +     pkg_cv_RPM_CFLAGS="$RPM_CFLAGS" +@@ -18437,6 +18314,30 @@ fi +     pkg_failed=untried + fi +  ++if test $pkg_failed = no; then ++  pkg_save_LDFLAGS="$LDFLAGS" ++  LDFLAGS="$LDFLAGS $pkg_cv_RPM_LIBS" ++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h.  */ ++ ++int ++main () ++{ ++ ++  ; ++  return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ++else ++  pkg_failed=yes ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++    conftest$ac_exeext conftest.$ac_ext ++  LDFLAGS=$pkg_save_LDFLAGS ++fi ++ +  +  + if test $pkg_failed = yes; then +@@ -18531,7 +18432,7 @@ $as_echo "#define HAVE_LIBRPM 1" >>confdefs.h +       LIBS="$LIBS $RPM_LIBS" +     else +       if $RPM_REQUIRE; then +-	as_fn_error "$RPM_PKG_ERRORS" "$LINENO" 5 ++	as_fn_error $? "$RPM_PKG_ERRORS" "$LINENO" 5 +       else + 	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $RPM_PKG_ERRORS" >&5 + $as_echo "$as_me: WARNING: $RPM_PKG_ERRORS" >&2;} +@@ -21164,6 +21065,7 @@ if test x"$prefer_curses" = xyes; then +   # search /usr/local/include, if ncurses is installed in /usr/local.  A +   # default installation of ncurses on alpha*-dec-osf* will lead to such +   # a situation. ++  # Fedora: Force libncursesw over libncurses to match the includes. +   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing waddstr" >&5 + $as_echo_n "checking for library containing waddstr... " >&6; } + if ${ac_cv_search_waddstr+:} false; then : +@@ -21188,7 +21090,7 @@ return waddstr (); +   return 0; + } + _ACEOF +-for ac_lib in '' ncursesw ncurses cursesX curses; do ++for ac_lib in '' ncursesw; do +   if test -z "$ac_lib"; then +     ac_res="none required" +   else +@@ -21260,6 +21162,7 @@ case $host_os in + esac +  + # These are the libraries checked by Readline. ++# Fedora: Force libncursesw over libncurses to match the includes. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing tgetent" >&5 + $as_echo_n "checking for library containing tgetent... " >&6; } + if ${ac_cv_search_tgetent+:} false; then : +@@ -21284,7 +21187,7 @@ return tgetent (); +   return 0; + } + _ACEOF +-for ac_lib in '' termcap tinfow tinfo curses ncursesw ncurses; do ++for ac_lib in '' ncursesw; do +   if test -z "$ac_lib"; then +     ac_res="none required" +   else +diff --git a/gdb/configure.ac b/gdb/configure.ac +--- a/gdb/configure.ac ++++ b/gdb/configure.ac +@@ -749,7 +749,8 @@ if test x"$prefer_curses" = xyes; then +   # search /usr/local/include, if ncurses is installed in /usr/local.  A +   # default installation of ncurses on alpha*-dec-osf* will lead to such +   # a situation. +-  AC_SEARCH_LIBS(waddstr, [ncursesw ncurses cursesX curses], ++  # Fedora: Force libncursesw over libncurses to match the includes. ++  AC_SEARCH_LIBS(waddstr, [ncursesw], +                  [curses_found=yes +                   AC_DEFINE([HAVE_LIBCURSES], [1], +                             [Define to 1 if curses is enabled.]) +@@ -789,7 +790,8 @@ case $host_os in + esac +  + # These are the libraries checked by Readline. +-AC_SEARCH_LIBS(tgetent, [termcap tinfow tinfo curses ncursesw ncurses]) ++# Fedora: Force libncursesw over libncurses to match the includes. ++AC_SEARCH_LIBS(tgetent, [ncursesw]) +  + if test "$ac_cv_search_tgetent" = no; then +   CONFIG_OBS="$CONFIG_OBS stub-termcap.o" diff --git a/gdb-ftbs-swapped-calloc-args.patch b/gdb-ftbs-swapped-calloc-args.patch new file mode 100644 index 0000000..3486c8e --- /dev/null +++ b/gdb-ftbs-swapped-calloc-args.patch @@ -0,0 +1,42 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Kevin Buettner <kevinb@redhat.com> +Date: Wed, 17 Jan 2024 12:53:53 -0700 +Subject: gdb-ftbs-swapped-calloc-args.patch + +Backport upstream commit 54195469c18ec9873cc5ba6907f768509473fa9b +which fixes a build problem in which arguments to calloc were swapped. + +[opcodes] ARC + PPC: Fix -Walloc-size warnings + +Recently, -Walloc-size warnings started to kick in. Fix these two +calloc() calls to match the intended usage pattern. + +opcodes/ChangeLog: + +	* arc-dis.c (init_arc_disasm_info): Fix calloc() call. +	* ppc-dis.c (powerpc_init_dialect): Ditto. + +diff --git a/opcodes/arc-dis.c b/opcodes/arc-dis.c +--- a/opcodes/arc-dis.c ++++ b/opcodes/arc-dis.c +@@ -147,7 +147,7 @@ static bool + init_arc_disasm_info (struct disassemble_info *info) + { +   struct arc_disassemble_info *arc_infop +-    = calloc (sizeof (*arc_infop), 1); ++    = calloc (1, sizeof (*arc_infop)); +  +   if (arc_infop == NULL) +     return false; +diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c +--- a/opcodes/ppc-dis.c ++++ b/opcodes/ppc-dis.c +@@ -348,7 +348,7 @@ powerpc_init_dialect (struct disassemble_info *info) + { +   ppc_cpu_t dialect = 0; +   ppc_cpu_t sticky = 0; +-  struct dis_private *priv = calloc (sizeof (*priv), 1); ++  struct dis_private *priv = calloc (1, sizeof (*priv)); +  +   if (priv == NULL) +     return; diff --git a/gdb-glibc-strstr-workaround.patch b/gdb-glibc-strstr-workaround.patch new file mode 100644 index 0000000..da9c5de --- /dev/null +++ b/gdb-glibc-strstr-workaround.patch @@ -0,0 +1,132 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-glibc-strstr-workaround.patch + +;; Workaround PR libc/14166 for inferior calls of strstr. +;;=fedoratest: Compatibility with RHELs (unchecked which ones). + +diff --git a/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp b/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp +@@ -0,0 +1,119 @@ ++# Copyright (C) 2012 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 <http://www.gnu.org/licenses/>. ++ ++# Workaround for: ++# invalid IFUNC DW_AT_linkage_name: memmove strstr time ++# http://sourceware.org/bugzilla/show_bug.cgi?id=14166 ++ ++if {[skip_shlib_tests]} { ++    return 0 ++} ++ ++set testfile "gnu-ifunc-strstr-workaround" ++set executable ${testfile} ++set srcfile start.c ++set binfile [standard_output_file ${executable}] ++ ++if [prepare_for_testing ${testfile}.exp $executable $srcfile] { ++    return -1 ++} ++ ++if ![runto_main] { ++    return 0 ++} ++ ++set test "ptype atoi" ++gdb_test_multiple $test $test { ++    -re "type = int \\(const char \\*\\)\r\n$gdb_prompt $" { ++	pass $test ++    } ++    -re "type = int \\(\\)\r\n$gdb_prompt $" { ++	untested "$test (no DWARF)" ++	return 0 ++    } ++    -re "type = <unknown return type> \\(\\)\r\n$gdb_prompt $" { ++	untested "$test (no DWARF)" ++	return 0 ++    } ++} ++ ++set addr "" ++set test "print strstr" ++gdb_test_multiple $test $test { ++    -re " = {<text gnu-indirect-function variable, no debug info>} (0x\[0-9a-f\]+) <strstr>\r\n$gdb_prompt $" { ++	set addr $expect_out(1,string) ++	pass $test ++    } ++    -re " = {<text gnu-indirect-function variable, no debug info>} (0x\[0-9a-f\]+) <__strstr>\r\n$gdb_prompt $" { ++	set addr $expect_out(1,string) ++	pass "$test (GDB workaround)" ++    } ++    -re " = {<text gnu-indirect-function variable, no debug info>} (0x\[0-9a-f\]+) <__libc_strstr>\r\n$gdb_prompt $" { ++	set addr $expect_out(1,string) ++	pass "$test (fixed glibc)" ++    } ++    -re " = {<text gnu-indirect-function variable, no debug info>} (0x\[0-9a-f\]+) <__libc_strstr_ifunc>\r\n$gdb_prompt $" { ++	set addr $expect_out(1,string) ++	pass "$test (fixed glibc)" ++    } ++    -re " = {char \\*\\(const char \\*, const char \\*\\)} 0x\[0-9a-f\]+ <strstr>\r\n$gdb_prompt $" { ++	untested "$test (gnu-ifunc not in use by glibc)" ++	return 0 ++    } ++} ++ ++set test "info sym" ++gdb_test_multiple "info sym $addr" $test { ++    -re "strstr in section \\.text of /lib\[^/\]*/libc.so.6\r\n$gdb_prompt $" { ++	pass $test ++    } ++    -re " = {char \\*\\(const char \\*, const char \\*\\)} 0x\[0-9a-f\]+ <strstr>\r\n$gdb_prompt $" { ++	# unexpected ++	xfail "$test (not in libc.so.6)" ++	return 0 ++    } ++} ++ ++set test "info addr strstr" ++gdb_test_multiple $test $test { ++    -re "Symbol \"strstr\" is a function at address $addr\\.\r\n$gdb_prompt $" { ++	fail "$test (DWARF for strstr)" ++    } ++    -re "Symbol \"strstr\" is at $addr in a file compiled without debugging\\.\r\n$gdb_prompt $" { ++	pass "$test" ++    } ++} ++ ++set test "print strstr second time" ++gdb_test_multiple "print strstr" $test { ++    -re " = {<text gnu-indirect-function variable, no debug info>} $addr <strstr>\r\n$gdb_prompt $" { ++	pass $test ++    } ++    -re " = {<text gnu-indirect-function variable, no debug info>} $addr <__strstr>\r\n$gdb_prompt $" { ++	pass "$test (GDB workaround)" ++    } ++    -re " = {<text gnu-indirect-function variable, no debug info>} $addr <__libc_strstr>\r\n$gdb_prompt $" { ++	pass "$test (fixed glibc)" ++    } ++    -re " = {<text gnu-indirect-function variable, no debug info>} $addr <__libc_strstr_ifunc>\r\n$gdb_prompt $" { ++	pass "$test (fixed glibc)" ++    } ++    -re " = {void \\*\\(void\\)} 0x\[0-9a-f\]+ <strstr>\r\n$gdb_prompt $" { ++	fail $test ++    } ++} ++ ++gdb_test {print (char *)strstr("abc","b")} { = 0x[0-9a-f]+ "bc"} ++gdb_test {print (char *)strstr("def","e")} { = 0x[0-9a-f]+ "ef"} diff --git a/gdb-gstack.man b/gdb-gstack.man new file mode 100644 index 0000000..1f4e406 --- /dev/null +++ b/gdb-gstack.man @@ -0,0 +1,48 @@ +.\" +.\" gstack manual page. +.\" Copyright (c) 1999 Ross Thompson +.\" Copyright (c) 2001, 2002, 2004, 2008 Red Hat, Inc. +.\" +.\" Original author: Ross Thompson <ross@whatsis.com> +.\" +.\" 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 2, 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; see the file COPYING.  If not, write to +.\" the Free Software Foundation, 59 Temple Place - Suite 330, +.\" Boston, MA 02111-1307, USA. +.\" +.TH GSTACK 1 "Feb 15 2008" "Red Hat Linux" "Linux Programmer's Manual" + +.SH NAME +gstack \- print a stack trace of a running process + +.SH SYNOPSIS +.B gstack +pid + +.SH DESCRIPTION + +\f3gstack\f1 attaches to the active process named by the \f3pid\f1 on +the command line, and prints out an execution stack trace.  If ELF +symbols exist in the binary (usually the case unless you have run +strip(1)), then symbolic addresses are printed as well. + +If the process is part of a thread group, then \f3gstack\f1 will print +out a stack trace for each of the threads in the group. + +.SH SEE ALSO +nm(1), ptrace(2), gdb(1) + +.SH AUTHORS +Ross Thompson <ross@whatsis.com> + +Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla> diff --git a/gdb-linux_perf-bundle.patch b/gdb-linux_perf-bundle.patch new file mode 100644 index 0000000..bb6fb6a --- /dev/null +++ b/gdb-linux_perf-bundle.patch @@ -0,0 +1,226 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-linux_perf-bundle.patch + +;; [dts+el7] [x86*] Bundle linux_perf.h for libipt (RH BZ 1256513). +;;=fedora + +diff --git a/gdb/gdb.c b/gdb/gdb.c +--- a/gdb/gdb.c ++++ b/gdb/gdb.c +@@ -21,6 +21,10 @@ + #include "interps.h" + #include "run-on-main-thread.h" +  ++#ifdef PERF_ATTR_SIZE_VER5_BUNDLE ++extern "C" void __libipt_init(void); ++#endif ++ + int + main (int argc, char **argv) + { +@@ -32,6 +36,10 @@ main (int argc, char **argv) +  +   struct captured_main_args args; +  ++#ifdef PERF_ATTR_SIZE_VER5_BUNDLE ++  __libipt_init(); ++#endif ++ +   memset (&args, 0, sizeof args); +   args.argc = argc; +   args.argv = argv; +diff --git a/gdb/nat/linux-btrace.h b/gdb/nat/linux-btrace.h +--- a/gdb/nat/linux-btrace.h ++++ b/gdb/nat/linux-btrace.h +@@ -28,6 +28,177 @@ + #  include <linux/perf_event.h> + #endif +  ++#ifdef PERF_ATTR_SIZE_VER5_BUNDLE ++#ifndef HAVE_LINUX_PERF_EVENT_H ++# error "PERF_ATTR_SIZE_VER5_BUNDLE && !HAVE_LINUX_PERF_EVENT_H" ++#endif ++#ifndef PERF_ATTR_SIZE_VER5 ++#define PERF_ATTR_SIZE_VER5 ++#define perf_event_mmap_page perf_event_mmap_page_bundle ++// kernel-headers-3.10.0-493.el7.x86_64/usr/include/linux/perf_event.h ++/* ++ * Structure of the page that can be mapped via mmap ++ */ ++struct perf_event_mmap_page { ++	__u32	version;		/* version number of this structure */ ++	__u32	compat_version;		/* lowest version this is compat with */ ++ ++	/* ++	 * Bits needed to read the hw events in user-space. ++	 * ++	 *   u32 seq, time_mult, time_shift, index, width; ++	 *   u64 count, enabled, running; ++	 *   u64 cyc, time_offset; ++	 *   s64 pmc = 0; ++	 * ++	 *   do { ++	 *     seq = pc->lock; ++	 *     barrier() ++	 * ++	 *     enabled = pc->time_enabled; ++	 *     running = pc->time_running; ++	 * ++	 *     if (pc->cap_usr_time && enabled != running) { ++	 *       cyc = rdtsc(); ++	 *       time_offset = pc->time_offset; ++	 *       time_mult   = pc->time_mult; ++	 *       time_shift  = pc->time_shift; ++	 *     } ++	 * ++	 *     index = pc->index; ++	 *     count = pc->offset; ++	 *     if (pc->cap_user_rdpmc && index) { ++	 *       width = pc->pmc_width; ++	 *       pmc = rdpmc(index - 1); ++	 *     } ++	 * ++	 *     barrier(); ++	 *   } while (pc->lock != seq); ++	 * ++	 * NOTE: for obvious reason this only works on self-monitoring ++	 *       processes. ++	 */ ++	__u32	lock;			/* seqlock for synchronization */ ++	__u32	index;			/* hardware event identifier */ ++	__s64	offset;			/* add to hardware event value */ ++	__u64	time_enabled;		/* time event active */ ++	__u64	time_running;		/* time event on cpu */ ++	union { ++		__u64	capabilities; ++		struct { ++			__u64	cap_bit0		: 1, /* Always 0, deprecated, see commit 860f085b74e9 */ ++				cap_bit0_is_deprecated	: 1, /* Always 1, signals that bit 0 is zero */ ++ ++				cap_user_rdpmc		: 1, /* The RDPMC instruction can be used to read counts */ ++				cap_user_time		: 1, /* The time_* fields are used */ ++				cap_user_time_zero	: 1, /* The time_zero field is used */ ++				cap_____res		: 59; ++		}; ++	}; ++ ++	/* ++	 * If cap_user_rdpmc this field provides the bit-width of the value ++	 * read using the rdpmc() or equivalent instruction. This can be used ++	 * to sign extend the result like: ++	 * ++	 *   pmc <<= 64 - width; ++	 *   pmc >>= 64 - width; // signed shift right ++	 *   count += pmc; ++	 */ ++	__u16	pmc_width; ++ ++	/* ++	 * If cap_usr_time the below fields can be used to compute the time ++	 * delta since time_enabled (in ns) using rdtsc or similar. ++	 * ++	 *   u64 quot, rem; ++	 *   u64 delta; ++	 * ++	 *   quot = (cyc >> time_shift); ++	 *   rem = cyc & (((u64)1 << time_shift) - 1); ++	 *   delta = time_offset + quot * time_mult + ++	 *              ((rem * time_mult) >> time_shift); ++	 * ++	 * Where time_offset,time_mult,time_shift and cyc are read in the ++	 * seqcount loop described above. This delta can then be added to ++	 * enabled and possible running (if index), improving the scaling: ++	 * ++	 *   enabled += delta; ++	 *   if (index) ++	 *     running += delta; ++	 * ++	 *   quot = count / running; ++	 *   rem  = count % running; ++	 *   count = quot * enabled + (rem * enabled) / running; ++	 */ ++	__u16	time_shift; ++	__u32	time_mult; ++	__u64	time_offset; ++	/* ++	 * If cap_usr_time_zero, the hardware clock (e.g. TSC) can be calculated ++	 * from sample timestamps. ++	 * ++	 *   time = timestamp - time_zero; ++	 *   quot = time / time_mult; ++	 *   rem  = time % time_mult; ++	 *   cyc = (quot << time_shift) + (rem << time_shift) / time_mult; ++	 * ++	 * And vice versa: ++	 * ++	 *   quot = cyc >> time_shift; ++	 *   rem  = cyc & (((u64)1 << time_shift) - 1); ++	 *   timestamp = time_zero + quot * time_mult + ++	 *               ((rem * time_mult) >> time_shift); ++	 */ ++	__u64	time_zero; ++	__u32	size;			/* Header size up to __reserved[] fields. */ ++ ++		/* ++		 * Hole for extension of the self monitor capabilities ++		 */ ++ ++	__u8	__reserved[118*8+4];	/* align to 1k. */ ++ ++	/* ++	 * Control data for the mmap() data buffer. ++	 * ++	 * User-space reading the @data_head value should issue an smp_rmb(), ++	 * after reading this value. ++	 * ++	 * When the mapping is PROT_WRITE the @data_tail value should be ++	 * written by userspace to reflect the last read data, after issueing ++	 * an smp_mb() to separate the data read from the ->data_tail store. ++	 * In this case the kernel will not over-write unread data. ++	 * ++	 * See perf_output_put_handle() for the data ordering. ++	 * ++	 * data_{offset,size} indicate the location and size of the perf record ++	 * buffer within the mmapped area. ++	 */ ++	__u64   data_head;		/* head in the data section */ ++	__u64	data_tail;		/* user-space written tail */ ++	__u64	data_offset;		/* where the buffer starts */ ++	__u64	data_size;		/* data buffer size */ ++ ++	/* ++	 * AUX area is defined by aux_{offset,size} fields that should be set ++	 * by the userspace, so that ++	 * ++	 *   aux_offset >= data_offset + data_size ++	 * ++	 * prior to mmap()ing it. Size of the mmap()ed area should be aux_size. ++	 * ++	 * Ring buffer pointers aux_{head,tail} have the same semantics as ++	 * data_{head,tail} and same ordering rules apply. ++	 */ ++	__u64	aux_head; ++	__u64	aux_tail; ++	__u64	aux_offset; ++	__u64	aux_size; ++}; ++#endif // PERF_ATTR_SIZE_VER5 ++#endif // PERF_ATTR_SIZE_VER5_BUNDLE ++ + struct target_ops; +  + #if HAVE_LINUX_PERF_EVENT_H +diff --git a/gdbsupport/common.m4 b/gdbsupport/common.m4 +--- a/gdbsupport/common.m4 ++++ b/gdbsupport/common.m4 +@@ -168,7 +168,7 @@ AC_DEFUN([GDB_AC_COMMON], [ +     AC_PREPROC_IFELSE([AC_LANG_SOURCE([[ +   #include <linux/perf_event.h> +   #ifndef PERF_ATTR_SIZE_VER5 +-  # error ++  // error // PERF_ATTR_SIZE_VER5_BUNDLE is not available here - Fedora+RHEL +   #endif +     ]])], [perf_event=yes], [perf_event=no]) +     if test "$perf_event" != yes; then diff --git a/gdb-rhbz-2232086-cpp-ify-mapped-symtab.patch b/gdb-rhbz-2232086-cpp-ify-mapped-symtab.patch new file mode 100644 index 0000000..1d6e1fb --- /dev/null +++ b/gdb-rhbz-2232086-cpp-ify-mapped-symtab.patch @@ -0,0 +1,264 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Andrew Burgess <aburgess@redhat.com> +Date: Sat, 25 Nov 2023 10:35:37 +0000 +Subject: gdb-rhbz-2232086-cpp-ify-mapped-symtab.patch + +;; Back-port upstream commit acc117b57f7 as part of a fix for +;; non-deterministic gdb-index generation (RH BZ 2232086). + +gdb: C++-ify mapped_symtab from dwarf2/index-write.c + +Make static the functions add_index_entry, find_slot, and hash_expand, +member functions of the mapped_symtab class. + +Fold an additional snippet of code from write_gdbindex into +mapped_symtab::minimize, this code relates to minimisation, so this +seems like a good home for it. + +Make the n_elements, data, and m_string_obstack member variables of +mapped_symtab private.  Provide a new obstack() member function to +provide access to the obstack when needed, and also add member +functions begin(), end(), cbegin(), and cend() so that the +mapped_symtab class can be treated like a contained and iterated +over. + +I've also taken this opportunity to split out the logic for whether +the hash table (m_data) needs expanding, this is the new function +hash_needs_expanding.  This will be useful in a later commit. + +There should be no user visible changes after this commit. + +Approved-By: Tom Tromey <tom@tromey.com> + +diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c +--- a/gdb/dwarf2/index-write.c ++++ b/gdb/dwarf2/index-write.c +@@ -187,86 +187,135 @@ struct mapped_symtab + { +   mapped_symtab () +   { +-    data.resize (1024); ++    m_data.resize (1024); +   } +  +-  /* Minimize each entry in the symbol table, removing duplicates.  */ ++  /* If there are no elements in the symbol table, then reduce the table ++     size to zero.  Otherwise call symtab_index_entry::minimize each entry ++     in the symbol table.  */ ++ +   void minimize () +   { +-    for (symtab_index_entry &item : data) ++    if (m_element_count == 0) ++      m_data.resize (0); ++ ++    for (symtab_index_entry &item : m_data) +       item.minimize (); +   } +  +-  offset_type n_elements = 0; +-  std::vector<symtab_index_entry> data; ++  /* Add an entry to SYMTAB.  NAME is the name of the symbol.  CU_INDEX is ++     the index of the CU in which the symbol appears.  IS_STATIC is one if ++     the symbol is static, otherwise zero (global).  */ ++ ++  void add_index_entry (const char *name, int is_static, ++			gdb_index_symbol_kind kind, offset_type cu_index); ++ ++  /* Access the obstack.  */ ++  struct obstack *obstack () ++  { return &m_string_obstack; } ++ ++private: ++ ++  /* Find a slot in SYMTAB for the symbol NAME.  Returns a reference to ++     the slot. ++ ++     Function is used only during write_hash_table so no index format ++     backward compatibility is needed.  */ ++ ++  symtab_index_entry &find_slot (const char *name); ++ ++  /* Expand SYMTAB's hash table.  */ ++ ++  void hash_expand (); ++ ++  /* Return true if the hash table in data needs to grow.  */ ++ ++  bool hash_needs_expanding () const ++  { return 4 * m_element_count / 3 >= m_data.size (); } ++ ++  /* A vector that is used as a hash table.  */ ++  std::vector<symtab_index_entry> m_data; ++ ++  /* The number of elements stored in the m_data hash.  */ ++  offset_type m_element_count = 0; +  +   /* Temporary storage for names.  */ +   auto_obstack m_string_obstack; +-}; +  +-/* Find a slot in SYMTAB for the symbol NAME.  Returns a reference to +-   the slot. ++public: ++  using iterator = decltype (m_data)::iterator; ++  using const_iterator = decltype (m_data)::const_iterator; +  +-   Function is used only during write_hash_table so no index format backward +-   compatibility is needed.  */ ++  iterator begin () ++  { return m_data.begin (); } +  +-static symtab_index_entry & +-find_slot (struct mapped_symtab *symtab, const char *name) ++  iterator end () ++  { return m_data.end (); } ++ ++  const_iterator cbegin () ++  { return m_data.cbegin (); } ++ ++  const_iterator cend () ++  { return m_data.cend (); } ++}; ++ ++/* See class definition.  */ ++ ++symtab_index_entry & ++mapped_symtab::find_slot (const char *name) + { +   offset_type index, step, hash = mapped_index_string_hash (INT_MAX, name); +  +-  index = hash & (symtab->data.size () - 1); +-  step = ((hash * 17) & (symtab->data.size () - 1)) | 1; ++  index = hash & (m_data.size () - 1); ++  step = ((hash * 17) & (m_data.size () - 1)) | 1; +  +   for (;;) +     { +-      if (symtab->data[index].name == NULL +-	  || strcmp (name, symtab->data[index].name) == 0) +-	return symtab->data[index]; +-      index = (index + step) & (symtab->data.size () - 1); ++      if (m_data[index].name == NULL ++	  || strcmp (name, m_data[index].name) == 0) ++	return m_data[index]; ++      index = (index + step) & (m_data.size () - 1); +     } + } +  +-/* Expand SYMTAB's hash table.  */ ++/* See class definition.  */ +  +-static void +-hash_expand (struct mapped_symtab *symtab) ++void ++mapped_symtab::hash_expand () + { +-  auto old_entries = std::move (symtab->data); ++  auto old_entries = std::move (m_data); +  +-  symtab->data.clear (); +-  symtab->data.resize (old_entries.size () * 2); ++  gdb_assert (m_data.size () == 0); ++  m_data.resize (old_entries.size () * 2); +  +   for (auto &it : old_entries) +     if (it.name != NULL) +       { +-	auto &ref = find_slot (symtab, it.name); ++	auto &ref = this->find_slot (it.name); + 	ref = std::move (it); +       } + } +  +-/* Add an entry to SYMTAB.  NAME is the name of the symbol. +-   CU_INDEX is the index of the CU in which the symbol appears. +-   IS_STATIC is one if the symbol is static, otherwise zero (global).  */ ++/* See class definition.  */ +  +-static void +-add_index_entry (struct mapped_symtab *symtab, const char *name, +-		 int is_static, gdb_index_symbol_kind kind, +-		 offset_type cu_index) ++void ++mapped_symtab::add_index_entry (const char *name, int is_static, ++				gdb_index_symbol_kind kind, ++				offset_type cu_index) + { +-  symtab_index_entry *slot = &find_slot (symtab, name); ++  symtab_index_entry *slot = &this->find_slot (name); +   if (slot->name == NULL) +     { +       /* This is a new element in the hash table.  */ +-      ++symtab->n_elements; ++      ++this->m_element_count; +  +       /* We might need to grow the hash table.  */ +-      if (4 * symtab->n_elements / 3 >= symtab->data.size ()) ++      if (this->hash_needs_expanding ()) + 	{ +-	  hash_expand (symtab); ++	  this->hash_expand (); +  + 	  /* This element will have a different slot in the new table.  */ +-	  slot = &find_slot (symtab, name); ++	  slot = &this->find_slot (name); +  + 	  /* But it should still be a new element in the hash table.  */ + 	  gdb_assert (slot->name == nullptr); +@@ -387,7 +436,7 @@ write_hash_table (mapped_symtab *symtab, data_buf &output, data_buf &cpool) +  +     /* We add all the index vectors to the constant pool first, to +        ensure alignment is ok.  */ +-    for (symtab_index_entry &entry : symtab->data) ++    for (symtab_index_entry &entry : *symtab) +       { + 	if (entry.name == NULL) + 	  continue; +@@ -416,7 +465,7 @@ write_hash_table (mapped_symtab *symtab, data_buf &output, data_buf &cpool) +  +   /* Now write out the hash table.  */ +   std::unordered_map<c_str_view, offset_type, c_str_view_hasher> str_table; +-  for (const auto &entry : symtab->data) ++  for (const auto &entry : *symtab) +     { +       offset_type str_off, vec_off; +  +@@ -1151,7 +1200,7 @@ write_cooked_index (cooked_index *table, +       const auto it = cu_index_htab.find (entry->per_cu); +       gdb_assert (it != cu_index_htab.cend ()); +  +-      const char *name = entry->full_name (&symtab->m_string_obstack); ++      const char *name = entry->full_name (symtab->obstack ()); +  +       if (entry->per_cu->lang () == language_ada) + 	{ +@@ -1159,7 +1208,7 @@ write_cooked_index (cooked_index *table, + 	     gdb, it has to use the encoded name, with any + 	     suffixes stripped.  */ + 	  std::string encoded = ada_encode (name, false); +-	  name = obstack_strdup (&symtab->m_string_obstack, ++	  name = obstack_strdup (symtab->obstack (), + 				 encoded.c_str ()); + 	} +       else if (entry->per_cu->lang () == language_cplus +@@ -1191,8 +1240,8 @@ write_cooked_index (cooked_index *table, +       else + 	kind = GDB_INDEX_SYMBOL_KIND_TYPE; +  +-      add_index_entry (symtab, name, (entry->flags & IS_STATIC) != 0, +-		       kind, it->second); ++      symtab->add_index_entry (name, (entry->flags & IS_STATIC) != 0, ++			       kind, it->second); +     } + } +  +@@ -1267,8 +1316,6 @@ write_gdbindex (dwarf2_per_bfd *per_bfd, cooked_index *table, +   symtab.minimize (); +  +   data_buf symtab_vec, constant_pool; +-  if (symtab.n_elements == 0) +-    symtab.data.resize (0); +  +   write_hash_table (&symtab, symtab_vec, constant_pool); +  diff --git a/gdb-rhbz-2232086-generate-dwarf-5-index-consistently.patch b/gdb-rhbz-2232086-generate-dwarf-5-index-consistently.patch new file mode 100644 index 0000000..e9b0b9e --- /dev/null +++ b/gdb-rhbz-2232086-generate-dwarf-5-index-consistently.patch @@ -0,0 +1,101 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Andrew Burgess <aburgess@redhat.com> +Date: Mon, 27 Nov 2023 13:19:39 +0000 +Subject: gdb-rhbz-2232086-generate-dwarf-5-index-consistently.patch + +;; Back-port upstream commit 3644f41dc80 as part of a fix for +;; non-deterministic gdb-index generation (RH BZ 2232086). + +gdb: generate dwarf-5 index identically as worker-thread count changes + +Similar to the previous commit, this commit ensures that the dwarf-5 +index files are generated identically as the number of worker-threads +changes. + +Building the dwarf-5 index makes use of a closed hash table, the +bucket_hash local within debug_names::build().  Entries are added to +bucket_hash from m_name_to_value_set, which, in turn, is populated +by calls to debug_names::insert() in write_debug_names.  The insert +calls are ordered based on the entries within the cooked_index, and +the ordering within cooked_index depends on the number of worker +threads that GDB is using. + +My proposal is to sort each chain within the bucket_hash closed hash +table prior to using this to build the dwarf-5 index. + +The buckets within bucket_hash will always have the same ordering (for +a given GDB build with a given executable), and by sorting the chains +within each bucket, we can be sure that GDB will see each entry in a +deterministic order. + +I've extended the index creation test to cover this case. + +Approved-By: Tom Tromey <tom@tromey.com> + +diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c +--- a/gdb/dwarf2/index-write.c ++++ b/gdb/dwarf2/index-write.c +@@ -452,6 +452,11 @@ class c_str_view +     return strcmp (m_cstr, other.m_cstr) == 0; +   } +  ++  bool operator< (const c_str_view &other) const ++  { ++    return strcmp (m_cstr, other.m_cstr) < 0; ++  } ++ +   /* Return the underlying C string.  Note, the returned string is +      only a reference with lifetime of this object.  */ +   const char *c_str () const +@@ -771,10 +776,18 @@ class debug_names +       } +     for (size_t bucket_ix = 0; bucket_ix < bucket_hash.size (); ++bucket_ix) +       { +-	const std::forward_list<hash_it_pair> &hashitlist +-	  = bucket_hash[bucket_ix]; ++	std::forward_list<hash_it_pair> &hashitlist = bucket_hash[bucket_ix]; + 	if (hashitlist.empty ()) + 	  continue; ++ ++	/* Sort the items within each bucket.  This ensures that the ++	   generated index files will be the same no matter the order in ++	   which symbols were added into the index.  */ ++	hashitlist.sort ([] (const hash_it_pair &a, const hash_it_pair &b) ++	{ ++	  return a.it->first < b.it->first; ++	}); ++ + 	uint32_t &bucket_slot = m_bucket_table[bucket_ix]; + 	/* The hashes array is indexed starting at 1.  */ + 	store_unsigned_integer (reinterpret_cast<gdb_byte *> (&bucket_slot), +diff --git a/gdb/testsuite/gdb.gdb/index-file.exp b/gdb/testsuite/gdb.gdb/index-file.exp +--- a/gdb/testsuite/gdb.gdb/index-file.exp ++++ b/gdb/testsuite/gdb.gdb/index-file.exp +@@ -47,6 +47,9 @@ remote_exec host "mkdir -p ${dir1}" + with_timeout_factor $timeout_factor { +     gdb_test_no_output "save gdb-index $dir1" \ + 	"create gdb-index file" ++ ++    gdb_test_no_output "save gdb-index -dwarf-5 $dir1" \ ++	"create dwarf-index files" + } +  + # Close GDB. +@@ -143,13 +146,16 @@ if { $worker_threads > 1 } { +     with_timeout_factor $timeout_factor { + 	gdb_test_no_output "save gdb-index $dir2" \ + 	    "create second gdb-index file" ++ ++	gdb_test_no_output "save gdb-index -dwarf-5 $dir2" \ ++	    "create second dwarf-index files" +     } +  +     # Close GDB. +     gdb_exit +  +     # Now check that the index files are identical. +-    foreach suffix { gdb-index  } { ++    foreach suffix { gdb-index debug_names debug_str } { + 	set result \ + 	    [remote_exec host \ + 		 "cmp -s \"$dir1/${index_filename_base}.${suffix}\" \"$dir2/${index_filename_base}.${suffix}\""] diff --git a/gdb-rhbz-2232086-generate-gdb-index-consistently.patch b/gdb-rhbz-2232086-generate-gdb-index-consistently.patch new file mode 100644 index 0000000..d6917ec --- /dev/null +++ b/gdb-rhbz-2232086-generate-gdb-index-consistently.patch @@ -0,0 +1,230 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Andrew Burgess <aburgess@redhat.com> +Date: Fri, 24 Nov 2023 12:04:36 +0000 +Subject: gdb-rhbz-2232086-generate-gdb-index-consistently.patch + +;; Back-port upstream commit aff250145af as part of a fix for +;; non-deterministic gdb-index generation (RH BZ 2232086). + +gdb: generate gdb-index identically regardless of work thread count + +It was observed that changing the number of worker threads that GDB +uses (maintenance set worker-threads NUM) would have an impact on the +layout of the generated gdb-index. + +The cause seems to be how the CU are distributed between threads, and +then symbols that appear in multiple CU can be encountered earlier or +later depending on whether a particular CU moves between threads. + +I certainly found this behaviour was reproducible when generating an +index for GDB itself, like: + +  gdb -q -nx -nh -batch \ +      -eiex 'maint set worker-threads NUM' \ +      -ex 'save gdb-index /tmp/' + +And then setting different values for NUM will change the generated +index. + +Now, the question is: does this matter? + +I would like to suggest that yes, this does matter.  At Red Hat we +generate a gdb-index as part of the build process, and we would +ideally like to have reproducible builds: for the same source, +compiled with the same tool-chain, we should get the exact same output +binary.  And we do .... except for the index. + +Now we could simply force GDB to only use a single worker thread when +we build the index, but, I don't think the idea of reproducible builds +is that strange, so I think we should ensure that our generated +indexes are always reproducible. + +To achieve this, I propose that we add an extra step when building the +gdb-index file.  After constructing the initial symbol hash table +contents, we will pull all the symbols out of the hash, sort them, +then re-insert them in sorted order.  This will ensure that the +structure of the generated hash will remain consistent (given the same +set of symbols). + +I've extended the existing index-file test to check that the generated +index doesn't change if we adjust the number of worker threads used. +Given that this test is already rather slow, I've only made one change +to the worker-thread count.  Maybe this test should be changed to use +a smaller binary, which is quicker to load, and for which we could +then try many different worker thread counts. + +Approved-By: Tom Tromey <tom@tromey.com> + +diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c +--- a/gdb/dwarf2/index-write.c ++++ b/gdb/dwarf2/index-write.c +@@ -210,6 +210,13 @@ struct mapped_symtab +   void add_index_entry (const char *name, int is_static, + 			gdb_index_symbol_kind kind, offset_type cu_index); +  ++  /* When entries are originally added into the data hash the order will ++     vary based on the number of worker threads GDB is configured to use. ++     This function will rebuild the hash such that the final layout will be ++     deterministic regardless of the number of worker threads used.  */ ++ ++  void sort (); ++ +   /* Access the obstack.  */ +   struct obstack *obstack () +   { return &m_string_obstack; } +@@ -296,6 +303,65 @@ mapped_symtab::hash_expand () +       } + } +  ++/* See mapped_symtab class declaration.  */ ++ ++void mapped_symtab::sort () ++{ ++  /* Move contents out of this->data vector.  */ ++  std::vector<symtab_index_entry> original_data = std::move (m_data); ++ ++  /* Restore the size of m_data, this will avoid having to expand the hash ++     table (and rehash all elements) when we reinsert after sorting. ++     However, we do reset the element count, this allows for some sanity ++     checking asserts during the reinsert phase.  */ ++  gdb_assert (m_data.size () == 0); ++  m_data.resize (original_data.size ()); ++  m_element_count = 0; ++ ++  /* Remove empty entries from ORIGINAL_DATA, this makes sorting quicker.  */ ++  auto it = std::remove_if (original_data.begin (), original_data.end (), ++			    [] (const symtab_index_entry &entry) -> bool ++			    { ++			      return entry.name == nullptr; ++			    }); ++  original_data.erase (it, original_data.end ()); ++ ++  /* Sort the existing contents.  */ ++  std::sort (original_data.begin (), original_data.end (), ++	     [] (const symtab_index_entry &a, ++		 const symtab_index_entry &b) -> bool ++	     { ++	       /* Return true if A is before B.  */ ++	       gdb_assert (a.name != nullptr); ++	       gdb_assert (b.name != nullptr); ++ ++	       return strcmp (a.name, b.name) < 0; ++	     }); ++ ++  /* Re-insert each item from the sorted list.  */ ++  for (auto &entry : original_data) ++    { ++      /* We know that ORIGINAL_DATA contains no duplicates, this data was ++	 taken from a hash table that de-duplicated entries for us, so ++	 count this as a new item. ++ ++	 As we retained the original size of m_data (see above) then we ++	 should never need to grow m_data_ during this re-insertion phase, ++	 assert that now.  */ ++      ++m_element_count; ++      gdb_assert (!this->hash_needs_expanding ()); ++ ++      /* Lookup a slot.  */ ++      symtab_index_entry &slot = this->find_slot (entry.name); ++ ++      /* As discussed above, we should not find duplicates.  */ ++      gdb_assert (slot.name == nullptr); ++ ++      /* Move this item into the slot we found.  */ ++      slot = std::move (entry); ++    } ++} ++ + /* See class definition.  */ +  + void +@@ -1311,6 +1377,9 @@ write_gdbindex (dwarf2_per_bfd *per_bfd, cooked_index *table, +   for (auto map : table->get_addrmaps ()) +     write_address_map (map, addr_vec, cu_index_htab); +  ++  /* Ensure symbol hash is built domestically.  */ ++  symtab.sort (); ++ +   /* Now that we've processed all symbols we can shrink their cu_indices +      lists.  */ +   symtab.minimize (); +diff --git a/gdb/testsuite/gdb.gdb/index-file.exp b/gdb/testsuite/gdb.gdb/index-file.exp +--- a/gdb/testsuite/gdb.gdb/index-file.exp ++++ b/gdb/testsuite/gdb.gdb/index-file.exp +@@ -38,6 +38,9 @@ with_timeout_factor $timeout_factor { +     clean_restart $filename + } +  ++# Record how many worker threads GDB is using. ++set worker_threads [gdb_get_worker_threads] ++ + # Generate an index file. + set dir1 [standard_output_file "index_1"] + remote_exec host "mkdir -p ${dir1}" +@@ -116,3 +119,41 @@ proc check_symbol_table_usage { filename } { +  + set index_filename_base [file tail $filename] + check_symbol_table_usage "$dir1/${index_filename_base}.gdb-index" ++ ++# If GDB is using more than 1 worker thread then reduce the number of ++# worker threads, regenerate the index, and check that we get the same ++# index file back.  At one point the layout of the index would vary ++# based on the number of worker threads used. ++if { $worker_threads > 1 } { ++    # Start GDB, but don't load a file yet. ++    clean_restart ++ ++    # Adjust the number of threads to use. ++    set reduced_threads [expr $worker_threads / 2] ++    gdb_test_no_output "maint set worker-threads $reduced_threads" ++ ++    with_timeout_factor $timeout_factor { ++	# Now load the test binary. ++	gdb_file_cmd $filename ++    } ++ ++    # Generate an index file. ++    set dir2 [standard_output_file "index_2"] ++    remote_exec host "mkdir -p ${dir2}" ++    with_timeout_factor $timeout_factor { ++	gdb_test_no_output "save gdb-index $dir2" \ ++	    "create second gdb-index file" ++    } ++ ++    # Close GDB. ++    gdb_exit ++ ++    # Now check that the index files are identical. ++    foreach suffix { gdb-index  } { ++	set result \ ++	    [remote_exec host \ ++		 "cmp -s \"$dir1/${index_filename_base}.${suffix}\" \"$dir2/${index_filename_base}.${suffix}\""] ++	gdb_assert { [lindex $result 0] == 0 } \ ++	    "$suffix files are identical" ++    } ++} +diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp +--- a/gdb/testsuite/lib/gdb.exp ++++ b/gdb/testsuite/lib/gdb.exp +@@ -10033,6 +10033,21 @@ proc is_target_non_stop { {testname ""} } { +     return $is_non_stop + } +  ++# Return the number of worker threads that GDB is currently using. ++ ++proc gdb_get_worker_threads { {testname ""} } { ++    set worker_threads "UNKNOWN" ++    gdb_test_multiple "maintenance show worker-threads" $testname { ++	-wrap -re "The number of worker threads GDB can use is unlimited \\(currently ($::decimal)\\)\\." { ++	    set worker_threads $expect_out(1,string) ++	} ++	-wrap -re "The number of worker threads GDB can use is ($::decimal)\\." { ++	    set worker_threads $expect_out(1,string) ++	} ++    } ++    return $worker_threads ++} ++ + # Check if the compiler emits epilogue information associated + # with the closing brace or with the last statement line. + # diff --git a/gdb-rhbz-2232086-reduce-size-of-gdb-index.patch b/gdb-rhbz-2232086-reduce-size-of-gdb-index.patch new file mode 100644 index 0000000..9eaf615 --- /dev/null +++ b/gdb-rhbz-2232086-reduce-size-of-gdb-index.patch @@ -0,0 +1,222 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Andrew Burgess <aburgess@redhat.com> +Date: Fri, 24 Nov 2023 11:50:35 +0000 +Subject: gdb-rhbz-2232086-reduce-size-of-gdb-index.patch + +;; Back-port upstream commit aa19bc1d259 as part of a fix for +;; non-deterministic gdb-index generation (RH BZ 2232086). + +gdb: reduce size of generated gdb-index file + +I noticed in passing that out algorithm for generating the gdb-index +file is incorrect.  When building the hash table in add_index_entry we +count every incoming entry rehash when the number of entries gets too +large.  However, some of the incoming entries will be duplicates, +which don't actually result in new items being added to the hash +table. + +As a result, we grow the gdb-index hash table far too often. + +With an unmodified GDB, generating a gdb-index for GDB, I see a file +size of 90M, with a hash usage (in the generated index file) of just +2.6%. + +With a patched GDB, generating a gdb-index for the _same_ GDB binary, +I now see a gdb-index file size of 30M, with a hash usage of 41.9%. + +This is a 67% reduction in gdb-index file size. + +Obviously, not every gdb-index file is going to see such big savings, +however, the larger a program, and the more symbols that are +duplicated between compilation units, the more GDB would over count, +and so, over-grow the index. + +The gdb-index hash table we create has a minimum size of 1024, and +then we grow the hash when it is 75% full, doubling the hash table at +that time.  Given this, then we expect that either: + +  a. The hash table is size 1024, and less than 75% full, or +  b. The hash table is between 37.5% and 75% full. + +I've include a test that checks some of these constraints -- I've not +bothered to check the upper limit, and over full hash table isn't +really a problem here, but if the fill percentage is less than 37.5% +then this indicates that we've done something wrong (obviously, I also +check for the 1024 minimum size). + +Approved-By: Tom Tromey <tom@tromey.com> + +diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c +--- a/gdb/dwarf2/index-write.c ++++ b/gdb/dwarf2/index-write.c +@@ -254,20 +254,29 @@ add_index_entry (struct mapped_symtab *symtab, const char *name, + 		 int is_static, gdb_index_symbol_kind kind, + 		 offset_type cu_index) + { +-  offset_type cu_index_and_attrs; ++  symtab_index_entry *slot = &find_slot (symtab, name); ++  if (slot->name == NULL) ++    { ++      /* This is a new element in the hash table.  */ ++      ++symtab->n_elements; +  +-  ++symtab->n_elements; +-  if (4 * symtab->n_elements / 3 >= symtab->data.size ()) +-    hash_expand (symtab); ++      /* We might need to grow the hash table.  */ ++      if (4 * symtab->n_elements / 3 >= symtab->data.size ()) ++	{ ++	  hash_expand (symtab); +  +-  symtab_index_entry &slot = find_slot (symtab, name); +-  if (slot.name == NULL) +-    { +-      slot.name = name; ++	  /* This element will have a different slot in the new table.  */ ++	  slot = &find_slot (symtab, name); ++ ++	  /* But it should still be a new element in the hash table.  */ ++	  gdb_assert (slot->name == nullptr); ++	} ++ ++      slot->name = name; +       /* index_offset is set later.  */ +     } +  +-  cu_index_and_attrs = 0; ++  offset_type cu_index_and_attrs = 0; +   DW2_GDB_INDEX_CU_SET_VALUE (cu_index_and_attrs, cu_index); +   DW2_GDB_INDEX_SYMBOL_STATIC_SET_VALUE (cu_index_and_attrs, is_static); +   DW2_GDB_INDEX_SYMBOL_KIND_SET_VALUE (cu_index_and_attrs, kind); +@@ -279,7 +288,7 @@ add_index_entry (struct mapped_symtab *symtab, const char *name, +      the last entry pushed), but a symbol could have multiple kinds in one CU. +      To keep things simple we don't worry about the duplication here and +      sort and uniquify the list after we've processed all symbols.  */ +-  slot.cu_indices.push_back (cu_index_and_attrs); ++  slot->cu_indices.push_back (cu_index_and_attrs); + } +  + /* See symtab_index_entry.  */ +diff --git a/gdb/testsuite/gdb.gdb/index-file.exp b/gdb/testsuite/gdb.gdb/index-file.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.gdb/index-file.exp +@@ -0,0 +1,118 @@ ++# Copyright 2023 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 <http://www.gnu.org/licenses/>. ++ ++# Load the GDB executable, and then 'save gdb-index', and make some ++# checks of the generated index file. ++ ++load_lib selftest-support.exp ++ ++# Can't save an index with readnow. ++if {[readnow]} { ++    untested "cannot create an index when readnow is in use" ++    return -1 ++} ++ ++# A multiplier used to ensure slow tasks are less likely to timeout. ++set timeout_factor 20 ++ ++set filename [selftest_prepare] ++if { $filename eq "" } { ++    unsupported "${gdb_test_file_name}.exp" ++    return -1 ++} ++ ++with_timeout_factor $timeout_factor { ++    # Start GDB, load FILENAME. ++    clean_restart $filename ++} ++ ++# Generate an index file. ++set dir1 [standard_output_file "index_1"] ++remote_exec host "mkdir -p ${dir1}" ++with_timeout_factor $timeout_factor { ++    gdb_test_no_output "save gdb-index $dir1" \ ++	"create gdb-index file" ++} ++ ++# Close GDB. ++gdb_exit ++ ++# Validate that the index-file FILENAME has made efficient use of its ++# symbol hash table.  Calculate the number of symbols in the hash ++# table and the total hash table size.  The hash table starts with ++# 1024 entries, and then doubles each time it is filled to 75%.  At ++# 75% filled, doubling the size takes it to 37.5% filled. ++# ++# Thus, the hash table is correctly filled if: ++#  1. Its size is 1024 (i.e. it has not yet had its first doubling), or ++#  2. Its filled percentage is over 37% ++# ++# We could check that it is not over filled, but I don't as that's not ++# really an issue.  But we did once have a bug where the table was ++# doubled incorrectly, in which case we'd see a filled percentage of ++# around 2% in some cases, which is a huge waste of disk space. ++proc check_symbol_table_usage { filename } { ++    # Open the file in binary mode and read-only mode. ++    set fp [open $filename rb] ++ ++    # Configure the channel to use binary translation. ++    fconfigure $fp -translation binary ++ ++    # Read the first 8 bytes of the file, which contain the header of ++    # the index section. ++    set header [read $fp [expr 7 * 4]] ++ ++    # Scan the header to get the version, the CU list offset, and the ++    # types CU list offset. ++    binary scan $header iiiiii version \ ++	_ _ _ symbol_table_offset shortcut_offset ++ ++    # The length of the symbol hash table (in entries). ++    set len [expr ($shortcut_offset - $symbol_table_offset) / 8] ++ ++    # Now walk the hash table and count how many entries are in use. ++    set offset $symbol_table_offset ++    set count 0 ++    while { $offset < $shortcut_offset } { ++	seek $fp $offset ++	set entry [read $fp 8] ++	binary scan $entry ii name_ptr flags ++	if { $name_ptr != 0 } { ++	    incr count ++	} ++ ++	incr offset 8 ++    } ++ ++    # Close the file. ++    close $fp ++ ++    # Calculate how full the cache is. ++    set pct [expr (100 * double($count)) / $len] ++ ++    # Write our results out to the gdb.log. ++    verbose -log "Hash table size: $len" ++    verbose -log "Hash table entries: $count" ++    verbose -log "Percentage usage: $pct%" ++ ++    # The minimum fill percentage is actually 37.5%, but we give TCL a ++    # little flexibility in case the FP maths give a result a little ++    # off. ++    gdb_assert { $len == 1024 || $pct > 37 } \ ++	"symbol hash table usage" ++} ++ ++set index_filename_base [file tail $filename] ++check_symbol_table_usage "$dir1/${index_filename_base}.gdb-index" diff --git a/gdb-rhbz-818343-set-solib-absolute-prefix-testcase.patch b/gdb-rhbz-818343-set-solib-absolute-prefix-testcase.patch new file mode 100644 index 0000000..20e5f75 --- /dev/null +++ b/gdb-rhbz-818343-set-solib-absolute-prefix-testcase.patch @@ -0,0 +1,83 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-rhbz-818343-set-solib-absolute-prefix-testcase.patch + +;; Testcase for `Setting solib-absolute-prefix breaks vDSO' (BZ 818343). +;;=fedoratest + +diff --git a/gdb/testsuite/gdb.base/set-solib-absolute-prefix.c b/gdb/testsuite/gdb.base/set-solib-absolute-prefix.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/set-solib-absolute-prefix.c +@@ -0,0 +1,26 @@ ++/* Copyright (C) 2012 Free Software Foundation, Inc. ++ ++   This file is part of GDB. ++ ++   This program is free software; you can redistribute it and/or modify ++   it under the terms of the GNU General Public License as published by ++   the Free Software Foundation; either version 3 of the License, or ++   (at your option) any later version. ++ ++   This program is distributed in the hope that it will be useful, ++   but WITHOUT ANY WARRANTY; without even the implied warranty of ++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the ++   GNU General Public License for more details. ++ ++   You should have received a copy of the GNU General Public License ++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ ++ ++#include <stdio.h> ++#include <stdlib.h> ++ ++int ++main (int argc, char *argv[]) ++{ ++  printf ("Hello, World.\n"); ++  abort (); ++} +diff --git a/gdb/testsuite/gdb.base/set-solib-absolute-prefix.exp b/gdb/testsuite/gdb.base/set-solib-absolute-prefix.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/set-solib-absolute-prefix.exp +@@ -0,0 +1,39 @@ ++# Copyright 2012 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 <http://www.gnu.org/licenses/>. ++ ++set testfile "set-solib-absolute-prefix" ++set srcfile ${testfile}.c ++ ++# It is necessary to verify if the binary is 32-bit, so that the system ++# call `__kernel_vsyscall' originates from vDSO. ++ ++if { ![is_ilp32_target] } { ++    return -1 ++} ++ ++if { [prepare_for_testing $testfile.exp $testfile $srcfile] } { ++    return -1 ++} ++ ++if { ![runto_main] } { ++    return -1 ++} ++ ++gdb_test "continue" "Program received signal SIGABRT, Aborted.*" \ ++    "continue until abort" ++gdb_test "set solib-absolute-prefix /BOGUS_DIRECT" \ ++    ".*warning: Unable to find dynamic linker breakpoint function.*" \ ++    "set solib-absolute-prefix" ++gdb_test "bt" "__kernel_vsyscall.*" "backtrace with __kernel_vsyscall" diff --git a/gdb-rhbz1007614-memleak-infpy_read_memory-test.patch b/gdb-rhbz1007614-memleak-infpy_read_memory-test.patch new file mode 100644 index 0000000..4d05ba5 --- /dev/null +++ b/gdb-rhbz1007614-memleak-infpy_read_memory-test.patch @@ -0,0 +1,170 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-rhbz1007614-memleak-infpy_read_memory-test.patch + +;; Fix 'memory leak in infpy_read_memory()' (RH BZ 1007614) +;;=fedoratest + +Original message by Tom Tromey: + +  <https://sourceware.org/ml/gdb-patches/2012-03/msg00955.html> +  Message-ID: <871uoc1va3.fsf@fleche.redhat.com> + +Comment from Sergio Durigan Junior: + +  In order to correctly test this patch, I wrote a testcase based on Jan +  Kratochvil's <gdb/testsuite/gdb.base/gcore-excessive-memory.exp>.  The +  testcase, which can be seen below, tests GDB in order to see if the +  amount of memory being leaked is minimal, as requested in the bugzilla. +  It is hard to define what "minimum" is, so I ran the testcase on all +  supported RHEL architectures and came up with an average. + +commit cc0265cdda9dc7e8665e8bfcf5b4477489daf27c +Author: Tom Tromey <tromey@redhat.com> +Date:   Wed Mar 28 17:38:08 2012 +0000 + +    	* python/py-inferior.c (infpy_read_memory): Remove cleanups and +    	explicitly free 'buffer' on exit paths.  Decref 'membuf_object' +    	before returning. + +diff --git a/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.c b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.c +@@ -0,0 +1,27 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++   Copyright 2014 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 <http://www.gnu.org/licenses/>.  */ ++ ++static struct x ++  { ++    char unsigned u[4096]; ++  } x, *px = &x; ++ ++int ++main (int argc, char *argv[]) ++{ ++  return 0; ++} +diff --git a/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.exp b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.exp +@@ -0,0 +1,68 @@ ++# Copyright 2014 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 <http://www.gnu.org/licenses/>. ++ ++set testfile py-gdb-rhbz1007614-memleak-infpy_read_memory ++set srcfile ${testfile}.c ++set binfile [standard_output_file ${testfile}] ++ ++if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } { ++    return -1 ++} ++ ++if { [skip_python_tests] } { continue } ++ ++set pid_of_gdb [exp_pid -i [board_info host fileid]] ++ ++proc memory_v_pages_get {} { ++    global pid_of_gdb ++    set fd [open "/proc/$pid_of_gdb/statm"] ++    gets $fd line ++    close $fd ++    # number of pages of virtual memory ++    scan $line "%d" drs ++    return $drs ++} ++ ++if { ![runto_main] } { ++    untested $testfile.exp ++    return -1 ++} ++ ++set remote_python_file [remote_download host ${srcdir}/${subdir}/${testfile}.py] ++ ++gdb_test "source ${remote_python_file}" "" ++ ++gdb_test "hello-world" "" ++ ++set kbytes_before [memory_v_pages_get] ++verbose -log "kbytes_before = $kbytes_before" ++ ++gdb_test "hello-world" "" ++ ++set kbytes_after [memory_v_pages_get] ++verbose -log "kbytes_after = $kbytes_after" ++ ++set kbytes_diff [expr $kbytes_after - $kbytes_before] ++verbose -log "kbytes_diff = $kbytes_diff" ++ ++# The value "1000" was calculated by running a few GDB sessions with this ++# testcase, and seeing how much (in average) the memory consumption ++# increased after the "hello-world" command issued above.  The average ++# was around 500 bytes, so I chose 1000 as a high estimate. ++if { $kbytes_diff > 1000 } { ++    fail "there is a memory leak on GDB (RHBZ 1007614)" ++} else { ++    pass "there is not a memory leak on GDB (RHBZ 1007614)" ++} +diff --git a/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.py b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.py +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.py +@@ -0,0 +1,30 @@ ++# Copyright (C) 2014 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 <http://www.gnu.org/licenses/>. ++ ++class HelloWorld (gdb.Command): ++    """Greet the whole world.""" ++ ++    def __init__ (self): ++        super (HelloWorld, self).__init__ ("hello-world", ++                                           gdb.COMMAND_OBSCURE) ++ ++    def invoke (self, arg, from_tty): ++        px = gdb.parse_and_eval("px") ++        core = gdb.inferiors()[0] ++        for i in range(256 * 1024): ++            chunk = core.read_memory(px, 4096) ++        print "Hello, World!" ++ ++HelloWorld () diff --git a/gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-3of3.patch b/gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-3of3.patch new file mode 100644 index 0000000..d92bfc3 --- /dev/null +++ b/gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-3of3.patch @@ -0,0 +1,235 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-3of3.patch + +;; Fix '[ppc64] and [s390x] wrong prologue skip on -O2 -g code' (Jan +;; Kratochvil, RH BZ 1084404). +;;=fedoratest + +These testcases have been created by compiling glibc-2.17-78 on +RHEL-7.1 s390x/ppc64 boxes, and then taking the "select.o" file +present at $builddir/misc/select.o. + +diff --git a/gdb/testsuite/gdb.arch/ppc64-prologue-skip.exp b/gdb/testsuite/gdb.arch/ppc64-prologue-skip.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.arch/ppc64-prologue-skip.exp +@@ -0,0 +1,34 @@ ++# Copyright 2015 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 <http://www.gnu.org/licenses/>. ++ ++if { ![istarget powerpc64-*linux-*] || ![is_lp64_target] } { ++    verbose "Skipping ppc64-prologue-skip.exp" ++    return ++} ++ ++set testfile "ppc64-prologue-skip" ++set uufile "${srcdir}/${subdir}/${testfile}.o.uu" ++set ofile "${srcdir}/${subdir}/${testfile}.o" ++ ++if { [catch "system \"uudecode -o ${ofile} ${uufile}\"" ] != 0 } { ++    untested "failed uudecode" ++    return -1 ++} ++ ++gdb_exit ++gdb_start ++gdb_load $ofile ++ ++gdb_test "break ___newselect_nocancel" "Breakpoint $decimal at 0xc: file ../sysdeps/unix/syscall-template.S, line 81." "breakpoint on ___newselect_nocancel" +diff --git a/gdb/testsuite/gdb.arch/ppc64-prologue-skip.o.uu b/gdb/testsuite/gdb.arch/ppc64-prologue-skip.o.uu +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.arch/ppc64-prologue-skip.o.uu +@@ -0,0 +1,70 @@ ++begin 644 ppc64-skip-prologue.o.uu ++M?T5,1@("`0`````````````!`!4````!```````````````````````````` ++M``-(``````!```````!``!0`$8%-B-`L"@``0,(`-#@``(Y$```"3.,`('P( ++M`J;X`0`0^"'_D4@```%@````Z`$`@#@A`'!\"`.F3H``(/@A_X%]*`*F^2$` ++MD/CA`-#XP0#(^*$`P/B!`+CX80"P2````6````#X80!PZ.$`T.C!`,CHH0#` ++MZ($`N.AA`+`X``".1````GP``";X80!X^`$`B.AA`'!(```!8````.DA`)#H ++M`0"(Z&$`>'TH`Z9\#_$@."$`@$SC`"!+__]@```````,($``````````O``( ++M7U]S96QE8W0```````````````````````````!6``(````Y!`'[#@T``0$! ++M`0````$```$N+B]S>7-D97!S+W5N:7@``'-Y<V-A;&PM=&5M<&QA=&4N4P`! ++M``````D"```````````#T``!`BT3`@D``0$```"/``(`````"`$````````` ++M`````````````````"XN+W-Y<V1E<',O=6YI>"]S>7-C86QL+71E;7!L871E ++M+E,`+W)O;W0O9VQI8F,O9VQI8F,M,BXQ-RTW."YE;#<N<W)C+V=L:6)C+3(N ++M,3<M8S<U.&$V.#8O;6ES8P!'3E4@05,@,BXR,RXU,BXP+C$`@`$!$0`0!A$! ++M$@$#"!L()0@3!0`````````````````L``(`````"``````````````````` ++M````````V``````````````````````````0``````%Z4@`$>$$!&PP!```` ++M`#`````8`````````+P`20YP$4%^1`X`009!0@Z``4(107Y2$49_20X`!D$& ++M1@``````+G-Y;71A8@`N<W1R=&%B`"YS:'-T<G1A8@`N<F5L82YT97AT`"YD ++M871A`"YB<W,`+G)E;&$N;W!D`"YN;W1E+D=.52US=&%C:P`N<F5L82YD96)U ++M9U]L:6YE`"YR96QA+F1E8G5G7VEN9F\`+F1E8G5G7V%B8G)E=@`N<F5L82YD ++M96)U9U]A<F%N9V5S`"YR96QA+F5H7V9R86UE```````````````````````` ++M```````````````````````````````````````````````````````````` ++M`````````"`````!``````````8```````````````````!``````````-@` ++M```````````````````$```````````````;````!``````````````````` ++M```````````*>`````````!(````$@````$`````````"``````````8```` ++M)@````$``````````P```````````````````1@````````````````````` ++M``````````$``````````````"P````(``````````,````````````````` ++M``$8```````````````````````````````!```````````````V`````0`` ++M```````#```````````````````!&``````````0```````````````````` ++M"```````````````,0````0`````````````````````````````"L`````` ++M````,````!(````%``````````@`````````&````#L````!```````````` ++M``````````````````$H```````````````````````````````!```````` ++M``````!0`````0`````````````````````````````!*`````````!:```` ++M`````````````````0``````````````2P````0````````````````````` ++M````````"O``````````&````!(````(``````````@`````````&````&$` ++M```!``````````````````````````````&"`````````),````````````` ++M```````!``````````````!<````!``````````````````````````````+ ++M"`````````!@````$@````H`````````"``````````8````;0````$````` ++M`````````````````````````A4`````````%`````````````````````$` ++M`````````````(`````!``````````````````````````````(P```````` ++M`#`````````````````````0``````````````![````!``````````````` ++M```````````````+:``````````P````$@````T`````````"``````````8 ++M````E`````$``````````@```````````````````F``````````2``````` ++M``````````````@``````````````(\````$```````````````````````` ++M``````N8`````````!@````2````#P`````````(`````````!@````1```` ++M`P`````````````````````````````"J`````````">```````````````` ++M`````0```````````````0````(`````````````````````````````"$@` ++M```````!L````!,````+``````````@`````````&`````D````#```````` ++M``````````````````````GX`````````'H````````````````````!```` ++M`````````````````````````````````````````````P```0`````````` ++M`````````````````P```P```````````````````````````P``!``````` ++M`````````````````````P``!0```````````````````````````P``"@`` ++M`````````````````````````P``#````````````````````````````P`` ++M"````````````````````````````P``#0`````````````````````````` ++M`P``#P```````````````````````````P``!P`````````````````````` ++M```!$@``!0```````````````````-@````*$@```0`````````,```````` ++M`#`````@$``````````````````````````````P$``````````````````` ++M``````````!*$`````````````````````````````!E(@``!0`````````` ++M`````````-@```!S(@``!0```````````````````-@`7U]S96QE8W0`7U]? ++M;F5W<V5L96-T7VYO8V%N8V5L`%]?<WES8V%L;%]E<G)O<@!?7VQI8F-?96YA ++M8FQE7V%S>6YC8V%N8V5L`%]?;&EB8U]D:7-A8FQE7V%S>6YC8V%N8V5L`%]? ++M;&EB8U]S96QE8W0`<V5L96-T```````````````````D````#0````H````` ++M``````````````!<````#@````H```````````````````"4````#P````H` ++M`````````````````````````0```"8````````````````````(```````` ++M`#,```````````````````!&`````0```"8````````````````````&```` ++M!@````$````````````````````,````!P````$````````````````````0 ++M`````0```"8````````````````````8`````0```"8`````````V``````` ++M```&````!0````$````````````````````0`````0```"8````````````` ++6```````<`````0```!H````````````` ++` ++end +diff --git a/gdb/testsuite/gdb.arch/s390x-prologue-skip.exp b/gdb/testsuite/gdb.arch/s390x-prologue-skip.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.arch/s390x-prologue-skip.exp +@@ -0,0 +1,34 @@ ++# Copyright 2015 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 <http://www.gnu.org/licenses/>. ++ ++if { ![istarget s390x-*linux-*] || ![is_lp64_target] } { ++    verbose "Skipping s390x-prologue-skip.exp" ++    return ++} ++ ++set testfile "s390x-prologue-skip" ++set uufile "${srcdir}/${subdir}/${testfile}.o.uu" ++set ofile "${srcdir}/${subdir}/${testfile}.o" ++ ++if { [catch "system \"uudecode -o ${ofile} ${uufile}\"" ] != 0 } { ++    untested "failed uudecode" ++    return -1 ++} ++ ++gdb_exit ++gdb_start ++gdb_load $ofile ++ ++gdb_test "break select" "Breakpoint $decimal at 0x48: file ../sysdeps/unix/syscall-template.S, line 81." "breakpoint on select" +diff --git a/gdb/testsuite/gdb.arch/s390x-prologue-skip.o.uu b/gdb/testsuite/gdb.arch/s390x-prologue-skip.o.uu +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.arch/s390x-prologue-skip.o.uu +@@ -0,0 +1,64 @@ ++begin 644 s390x-prologue-skip.o.uu ++M?T5,1@("`0`````````````!`!8````!```````````````````````````` ++M``+```````!```````!``!(`#^LE\!``).O?\&@`)+D$`.^G^_]@X^#P```D ++MP.4`````N00``NLE\+``!`J.N00`TKD$`"#`Y0````"Y!``MZ]_Q"``$I_0` ++M"L`0`````+\/$`"G=/_7"HZG2?`!N2$`),"T``````?^````5@`"````.0$! ++M^PX-``$!`0$````!```!+BXO<WES9&5P<R]U;FEX``!S>7-C86QL+71E;7!L ++M871E+E,``0`````)`@```````````]```0)F$P("``$!````CP`"``````@! ++M```````````````````````````N+B]S>7-D97!S+W5N:7@O<WES8V%L;"UT ++M96UP;&%T92Y3`"]R;V]T+V=L:6)C+V=L:6)C+3(N,3<M-S@N96PW+G-R8R]G ++M;&EB8RTR+C$W+6,W-3AA-C@V+VUI<V,`1TY5($%3(#(N,C,N-3(N,"XQ`(`! ++M`1$`$`81`1(!`P@;""4($P4`````````````````+``"``````@````````` ++M`````````````````&@`````````````````````````%``````!>E(``7@. ++M`1L,#Z`!````````&````!P`````````1`!,CP6.!HT'2`[``@```!`````X ++M`````````"```````"YS>6UT86(`+G-T<G1A8@`N<VAS=')T86(`+G)E;&$N ++M=&5X=``N9&%T80`N8G-S`"YN;W1E+D=.52US=&%C:P`N<F5L82YD96)U9U]L ++M:6YE`"YR96QA+F1E8G5G7VEN9F\`+F1E8G5G7V%B8G)E=@`N<F5L82YD96)U ++M9U]A<F%N9V5S`"YR96QA+F5H7V9R86UE```````````````````````````` ++M```````````````````````````````````````````````````````````` ++M````````(`````$`````````!@```````````````````$``````````:``` ++M``````````````````0``````````````!L````$```````````````````` ++M``````````F``````````&`````0`````0`````````(`````````!@````F ++M`````0`````````#````````````````````J``````````````````````` ++M````````!```````````````+`````@``````````P`````````````````` ++M`*@```````````````````````````````0``````````````#$````!```` ++M``````````````````````````"H```````````````````````````````! ++M``````````````!&`````0``````````````````````````````J``````` ++M``!:`````````````````````0``````````````00````0````````````` ++M````````````````">``````````&````!`````&``````````@````````` ++M&````%<````!``````````````````````````````$"`````````),````` ++M```````````````!``````````````!2````!``````````````````````` ++M```````)^`````````!@````$`````@`````````"``````````8````8P`` ++M``$``````````````````````````````94`````````%``````````````` ++M``````$``````````````'8````!``````````````````````````````&P ++M`````````#`````````````````````0``````````````!Q````!``````` ++M```````````````````````*6``````````P````$`````L`````````"``` ++M```````8````B@````$``````````@```````````````````>`````````` ++M2`````````````````````@``````````````(4````$```````````````` ++M``````````````J(`````````#`````0````#0`````````(`````````!@` ++M```1`````P`````````````````````````````"*`````````"4```````` ++M`````````````0```````````````0````(````````````````````````` ++M````!T`````````!L````!$````*``````````@`````````&`````D````# ++M``````````````````````````````CP`````````(X````````````````` ++M```!`````````````````````````````````````````````````P```0`` ++M`````````````````````````P```P```````````````````````````P`` ++M!````````````````````````````P``"``````````````````````````` ++M`P``"@```````````````````````````P``!@`````````````````````` ++M`````P``"P```````````````````````````P``#0`````````````````` ++M`````````P``!0`````````````````````````!$``````````````````` ++M```````````;$``````````````````````````````V$@```0````````!( ++M`````````"`````_$`````````````````````````````!7$@```0`````` ++M``!6`````````!````!I$`````````````````````````````!Y(@```0`` ++M``````!(`````````"````"'(@```0````````!(`````````"``7U]L:6)C ++M7V5N86)L95]A<WEN8V-A;F-E;`!?7VQI8F-?9&ES86)L95]A<WEN8V-A;F-E ++M;`!?7W-E;&5C=`!?7VQI8F-?;75L=&EP;&5?=&AR96%D<P!?7W-E;&5C=%]N ++M;V-A;F-E;`!?7W-Y<V-A;&Q?97)R;W(`7U]L:6)C7W-E;&5C=`!S96QE8W0` ++M````````````'`````H````3``````````(`````````-@````L````3```` ++M``````(`````````2@````T````3``````````(`````````8@````\````3 ++M``````````(`````````1@````$````6````````````````````!@````4` ++M```$````````````````````#`````8````$````````````````````$``` ++M``$````6````````````````````&`````$````6`````````&@````````` ++M!@````0````$````````````````````$`````$````6```````````````` ++L````(`````$````%````````````````````/`````$````%`````````$@` ++` ++end diff --git a/gdb-rhbz1149205-catch-syscall-after-fork-test.patch b/gdb-rhbz1149205-catch-syscall-after-fork-test.patch new file mode 100644 index 0000000..63c4051 --- /dev/null +++ b/gdb-rhbz1149205-catch-syscall-after-fork-test.patch @@ -0,0 +1,123 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-rhbz1149205-catch-syscall-after-fork-test.patch + +;; Fix '`catch syscall' doesn't work for parent after `fork' is called' +;; (Philippe Waroquiers, RH BZ 1149205). +;;=fedoratest + +URL: <https://sourceware.org/ml/gdb-patches/2013-05/msg00364.html> +Message-ID: <1368136582.30058.7.camel@soleil> + +  From: Philippe Waroquiers <philippe dot waroquiers at skynet dot be> +  To: gdb-patches at sourceware dot org +  Subject: RFA: fix gdb_assert caused by 'catch signal ...' and fork +  Date: Thu, 09 May 2013 23:56:22 +0200 + +  The attached patch fixes a gdb_assert caused by the combination of catch +  signal and fork: +    break-catch-sig.c:152: internal-error: signal_catchpoint_remove_location: Assertion `signal_catch_counts[iter] > 0' failed. + +  The problem is that the signal_catch_counts is decremented by detach_breakpoints. +  The fix consists in not detaching breakpoint locations of type bp_loc_other. +  The patch introduces a new test. + +Comments by Sergio Durigan Junior: + +  I addded a specific testcase for this patch, which tests exactly the +  issue that the customer is facing.  This patch does not solve the +  whole problem of catching a syscall and forking (for more details, +  see <https://sourceware.org/bugzilla/show_bug.cgi?id=13457>, +  specifically comment #3), but it solves the issue reported by the +  customer. + +  I also removed the original testcase of this patch, because it +  relied on "catch signal", which is a command that is not implemented +  in this version of GDB. + +commit bd9673a4ded96ea5c108601501c8e59003ea1be6 +Author: Philippe Waroquiers <philippe@sourceware.org> +Date:   Tue May 21 18:47:05 2013 +0000 + +    Fix internal error caused by interaction between catch signal and fork + +diff --git a/gdb/testsuite/gdb.base/gdb-rhbz1149205-catch-syscall-fork.c b/gdb/testsuite/gdb.base/gdb-rhbz1149205-catch-syscall-fork.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/gdb-rhbz1149205-catch-syscall-fork.c +@@ -0,0 +1,11 @@ ++#include <stdio.h> ++#include <unistd.h> ++ ++int ++main (int argc, char **argv) ++{ ++  if (fork () == 0) ++    sleep (1); ++  chdir ("."); ++  return 0; ++} +diff --git a/gdb/testsuite/gdb.base/gdb-rhbz1149205-catch-syscall-fork.exp b/gdb/testsuite/gdb.base/gdb-rhbz1149205-catch-syscall-fork.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/gdb-rhbz1149205-catch-syscall-fork.exp +@@ -0,0 +1,58 @@ ++# Copyright 2015 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 <http://www.gnu.org/licenses/>. ++ ++if { [is_remote target] || ![isnative] } then { ++    continue ++} ++ ++set testfile "gdb-rhbz1149205-catch-syscall-fork" ++set srcfile ${testfile}.c ++set binfile [standard_output_file ${testfile}] ++ ++# Until "catch syscall" is implemented on other targets... ++if {![istarget "hppa*-hp-hpux*"] && ![istarget "*-linux*"]} then { ++    continue ++} ++ ++# This shall be updated whenever 'catch syscall' is implemented ++# on some architecture. ++#if { ![istarget "i\[34567\]86-*-linux*"] ++if { ![istarget "x86_64-*-linux*"] && ![istarget "i\[34567\]86-*-linux*"] ++     && ![istarget "powerpc-*-linux*"] && ![istarget "powerpc64-*-linux*"] ++     && ![istarget "sparc-*-linux*"] && ![istarget "sparc64-*-linux*"] } { ++     continue ++} ++ ++if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { ++    untested ${testfile}.exp ++    return -1 ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load $binfile ++ ++if { ![runto_main] } { ++    return -1 ++} ++ ++gdb_test "catch syscall chdir" \ ++  "Catchpoint $decimal \\\(syscall (.)?chdir(.)? \\\[$decimal\\\]\\\)" \ ++  "catch syscall chdir" ++ ++gdb_test "continue" \ ++  "Continuing\.\r\n.*\r\nCatchpoint $decimal \\\(call to syscall .?chdir.?.*" \ ++  "continue from catch syscall after fork" diff --git a/gdb-rhbz1156192-recursive-dlopen-test.patch b/gdb-rhbz1156192-recursive-dlopen-test.patch new file mode 100644 index 0000000..96b93ae --- /dev/null +++ b/gdb-rhbz1156192-recursive-dlopen-test.patch @@ -0,0 +1,371 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-rhbz1156192-recursive-dlopen-test.patch + +;; Testcase for '[SAP] Recursive dlopen causes SAP HANA installer to +;; crash.' (RH BZ 1156192). +;;=fedoratest + +diff --git a/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen-libbar.c b/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen-libbar.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen-libbar.c +@@ -0,0 +1,30 @@ ++/* Testcase for recursive dlopen calls. ++ ++   Copyright (C) 2014 Free Software Foundation, Inc. ++ ++   This file is part of GDB. ++ ++   This program is free software; you can redistribute it and/or modify ++   it under the terms of the GNU General Public License as published by ++   the Free Software Foundation; either version 3 of the License, or ++   (at your option) any later version. ++ ++   This program is distributed in the hope that it will be useful, ++   but WITHOUT ANY WARRANTY; without even the implied warranty of ++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the ++   GNU General Public License for more details. ++ ++   You should have received a copy of the GNU General Public License ++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ ++ ++/* This test was copied from glibc's testcase called ++   <dlfcn/tst-rec-dlopen.c> and related files.  */ ++ ++#include <stdio.h> ++#include <stdlib.h> ++ ++void ++bar (void) ++{ ++  printf ("Called bar.\n"); ++} +diff --git a/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen-libfoo.c b/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen-libfoo.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen-libfoo.c +@@ -0,0 +1,30 @@ ++/* Testcase for recursive dlopen calls. ++ ++   Copyright (C) 2014 Free Software Foundation, Inc. ++ ++   This file is part of GDB. ++ ++   This program is free software; you can redistribute it and/or modify ++   it under the terms of the GNU General Public License as published by ++   the Free Software Foundation; either version 3 of the License, or ++   (at your option) any later version. ++ ++   This program is distributed in the hope that it will be useful, ++   but WITHOUT ANY WARRANTY; without even the implied warranty of ++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the ++   GNU General Public License for more details. ++ ++   You should have received a copy of the GNU General Public License ++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ ++ ++/* This test was copied from glibc's testcase called ++   <dlfcn/tst-rec-dlopen.c> and related files.  */ ++ ++#include <stdio.h> ++#include <stdlib.h> ++ ++void ++foo (void) ++{ ++  printf ("Called foo.\n"); ++} +diff --git a/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen.c b/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen.c +@@ -0,0 +1,125 @@ ++/* Testcase for recursive dlopen calls. ++ ++   Copyright (C) 2014 Free Software Foundation, Inc. ++ ++   This file is part of GDB. ++ ++   This program is free software; you can redistribute it and/or modify ++   it under the terms of the GNU General Public License as published by ++   the Free Software Foundation; either version 3 of the License, or ++   (at your option) any later version. ++ ++   This program is distributed in the hope that it will be useful, ++   but WITHOUT ANY WARRANTY; without even the implied warranty of ++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the ++   GNU General Public License for more details. ++ ++   You should have received a copy of the GNU General Public License ++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ ++ ++/* This test was copied from glibc's testcase called ++   <dlfcn/tst-rec-dlopen.c> and related files.  */ ++ ++#include <stdio.h> ++#include <stdlib.h> ++#include <malloc.h> ++#include <dlfcn.h> ++ ++#define DSO "gdb-rhbz1156192-recursive-dlopen-libfoo.so" ++#define FUNC "foo" ++ ++#define DSO1 "gdb-rhbz1156192-recursive-dlopen-libbar.so" ++#define FUNC1 "bar" ++ ++/* Prototype for my hook.  */ ++void *custom_malloc_hook (size_t, const void *); ++ ++/* Pointer to old malloc hooks.  */ ++void *(*old_malloc_hook) (size_t, const void *); ++ ++/* Call function func_name in DSO dso_name via dlopen.  */ ++void ++call_func (const char *dso_name, const char *func_name) ++{ ++  int ret; ++  void *dso; ++  void (*func) (void); ++  char *err; ++ ++  /* Open the DSO.  */ ++  dso = dlopen (dso_name, RTLD_NOW|RTLD_GLOBAL); ++  if (dso == NULL) ++    { ++      err = dlerror (); ++      fprintf (stderr, "%s\n", err); ++      exit (1); ++    } ++  /* Clear any errors.  */ ++  dlerror (); ++ ++  /* Lookup func.  */ ++  *(void **) (&func) = dlsym (dso, func_name); ++  if (func == NULL) ++    { ++      err = dlerror (); ++      if (err != NULL) ++        { ++  fprintf (stderr, "%s\n", err); ++  exit (1); ++        } ++    } ++  /* Call func twice.  */ ++  (*func) (); ++ ++  /* Close the library and look for errors too.  */ ++  ret = dlclose (dso); ++  if (ret != 0) ++    { ++      err = dlerror (); ++      fprintf (stderr, "%s\n", err); ++      exit (1); ++    } ++ ++} ++ ++/* Empty hook that does nothing.  */ ++void * ++custom_malloc_hook (size_t size, const void *caller) ++{ ++  void *result; ++  /* Restore old hooks.  */ ++  __malloc_hook = old_malloc_hook; ++  /* First call a function in another library via dlopen.  */ ++  call_func (DSO1, FUNC1); ++  /* Called recursively.  */ ++  result = malloc (size); ++  /* Restore new hooks.  */ ++  old_malloc_hook = __malloc_hook; ++  __malloc_hook = custom_malloc_hook; ++  return result; ++} ++ ++int ++main (void) ++{ ++ ++  /* Save old hook.  */ ++  old_malloc_hook = __malloc_hook; ++  /* Install new hook.  */ ++  __malloc_hook = custom_malloc_hook; ++ ++  /* Attempt to dlopen a shared library. This dlopen will ++     trigger an access to the ld.so.cache, and that in turn ++     will require a malloc to duplicate data in the cache. ++     The malloc will call our malloc hook which calls dlopen ++     recursively, and upon return of this dlopen the non-ref ++     counted ld.so.cache mapping will be unmapped. We will ++     return to the original dlopen and crash trying to access ++     dlopened data.  */ ++  call_func (DSO, FUNC); ++ ++  /* Restore old hook.  */ ++  __malloc_hook = old_malloc_hook; ++ ++  return 0; ++} +diff --git a/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen.exp b/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen.exp +@@ -0,0 +1,157 @@ ++# Copyright 2014 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 <http://www.gnu.org/licenses/>. ++ ++if {[skip_shlib_tests]} { ++    untested "skipping shlib tests" ++    return 0 ++} elseif {[use_gdb_stub]} { ++    untested "skipping tests because of stub" ++    return 0 ++} ++ ++# Library foo ++set libname1 "gdb-rhbz1156192-recursive-dlopen-libfoo" ++set srcfile_lib1 ${srcdir}/${subdir}/${libname1}.c ++set binfile_lib1 [standard_output_file ${libname1}.so] ++# Library bar ++set libname2 "gdb-rhbz1156192-recursive-dlopen-libbar" ++set srcfile_lib2 ${srcdir}/${subdir}/${libname2}.c ++set binfile_lib2 [standard_output_file ${libname2}.so] ++ ++set testfile "gdb-rhbz1156192-recursive-dlopen" ++set srcfile ${testfile}.c ++set executable ${testfile} ++set binfile [standard_output_file ${executable}] ++ ++if { [gdb_compile_shlib ${srcfile_lib1} ${binfile_lib1} \ ++	{ debug "additional_flags=-fPIC" }] != "" } { ++    untested "Could not compile ${binfile_lib1}" ++    return -1 ++} ++ ++if { [gdb_compile_shlib ${srcfile_lib2} ${binfile_lib2} \ ++	{ debug "additional_flags=-fPIC" }] != "" } { ++    untested "Could not compile ${binfile_lib2}" ++    return -1 ++} ++ ++if { [prepare_for_testing ${testfile}.exp ${executable} ${srcfile} \ ++	[ list debug shlib_load "additional_flags=-Wno-deprecated-declarations" ]] } { ++    untested "Could not compile ${executable}" ++    return -1 ++} ++ ++set supported 0 ++gdb_test_multiple "run" "initial trial run" { ++    -re -wrap "exited normally.*" { ++	set supported 1 ++	pass $gdb_test_name ++    } ++    -re -wrap "exited with code.*" { ++	untested "failed at $gdb_test_name" ++    } ++} ++ ++if { $supported == 0 } { ++    return -1 ++} ++ ++proc do_test { has_libfoo has_libbar } { ++  global hex binfile_lib2 binfile_lib1 gdb_prompt ++  set libbar_match "[string_to_regexp $binfile_lib2]" ++  set libfoo_match "[string_to_regexp $binfile_lib1]" ++ ++  gdb_test_multiple "info shared" "info shared" { ++    -re ".*$libfoo_match\r\n.*$libbar_match\(\r\n.*Shared library is missing\)?.*\r\n${gdb_prompt} $" { ++      if { $has_libfoo && $has_libbar } { ++	pass "matched libfoo and libbar" ++      } else { ++	fail "matched libfoo and libbar (has_libfoo = $has_libfoo, has_libbar = $has_libbar)" ++      } ++    } ++    -re ".*$libfoo_match\(\r\n.*Shared library is missing\)?.*\r\n${gdb_prompt} $" { ++      if { $has_libfoo && !$has_libbar } { ++	pass "matched libfoo" ++      } else { ++	fail "matched libfoo (has_libfoo = $has_libfoo, has_libbar = $has_libbar)" ++      } ++    } ++    -re ".*$libbar_match\(\r\n.*Shared library is missing\)?.*\r\n${gdb_prompt} $" { ++      if { $has_libbar && !$has_libfoo } { ++	pass "matched libbar" ++      } else { ++	fail "matched libbar (has_libfoo = $has_libfoo, has_libbar = $has_libbar)" ++      } ++    } ++    "\r\n${gdb_prompt} $" { ++      if { !$has_libfoo && !$has_libbar } { ++	pass "did not match libfoo nor libbar" ++      } else { ++	fail "did not match libfoo nor libbar (has_libfoo = $has_libfoo, has_libbar = $has_libbar)" ++      } ++    } ++  } ++} ++ ++proc test_stop_on_solib_events { } { ++  set pass 0 ++  # This variable holds the information about whether libfoo and ++  # libbar (respectively) are expected in the "info shared" output. ++  set solib_event_order { { 0 0 } { 0 0   } { 0 0   } { 0 1 } \ ++			  { 0 1 } { 0 0   } { 0 0   } { 0 1 } \ ++			  { 0 1 } { 0 0   } { 0 0   } { 0 1 } \ ++			  { 0 1 } { 0 0   } { 0 0 1 } { 1 1 } \ ++			  { 1 1 } { 1 0   } { 1 0   } { 1 1 } \ ++			  { 1 1 } { 1 0 1 } { 1 0   } { 1 0 } } ++ ++  with_test_prefix "stop-on-solib-events" { ++    gdb_test_no_output "set stop-on-solib-events 1" "setting stop-on-solib-events" ++ ++    gdb_run_cmd ++    gdb_test "" "Wait for first prompt" ++    foreach l $solib_event_order { ++      incr pass ++      with_test_prefix "pass #$pass" { ++	set should_be_corrupted [expr 0+0[lindex $l 2]] ++	do_test [lindex $l 0] [lindex $l 1] ++	set test "continue" ++	global gdb_prompt ++	gdb_test_multiple $test $test { ++	  -re "\r\nwarning: Corrupted shared library list:.*\r\nStopped due to shared library event.*\r\n$gdb_prompt $" { ++	    set corrupted 1 ++	    pass $test ++	  } ++	  -re "\r\nStopped due to shared library event.*\r\n$gdb_prompt $" { ++	    set corrupted 0 ++	    pass $test ++	  } ++	} ++	set test "corrupted=$corrupted but should_be_corrupted=$should_be_corrupted" ++	if {$corrupted == $should_be_corrupted} { ++	  pass $test ++	} else { ++	  fail $test ++	} ++      } ++    } ++    # In the last pass we do not expect to see libfoo or libbar. ++    incr pass ++    with_test_prefix "pass #$pass" { ++      do_test 0 0 ++    } ++  } ++} ++ ++test_stop_on_solib_events diff --git a/gdb-rhbz1261564-aarch64-hw-watchpoint-test.patch b/gdb-rhbz1261564-aarch64-hw-watchpoint-test.patch new file mode 100644 index 0000000..a0eb440 --- /dev/null +++ b/gdb-rhbz1261564-aarch64-hw-watchpoint-test.patch @@ -0,0 +1,104 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-rhbz1261564-aarch64-hw-watchpoint-test.patch + +;; [aarch64] Fix hardware watchpoints (RH BZ 1261564). +;;=fedoratest + +diff --git a/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.c b/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.c +@@ -0,0 +1,33 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++   Copyright 2016 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 <http://www.gnu.org/licenses/>.  */ ++ ++__attribute__((aligned(16))) struct ++{ ++  int var0, var4, var8; ++} aligned; ++ ++int ++main (void) ++{ ++  aligned.var0 = 1; ++  aligned.var4 = 2; ++  aligned.var8 = 3; ++ ++  aligned.var4 = aligned.var0; ++ ++  return 0; ++} +diff --git a/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.exp b/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.exp +@@ -0,0 +1,53 @@ ++# Copyright (C) 2016 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 <http://www.gnu.org/licenses/>. ++ ++if { [prepare_for_testing rhbz1261564-aarch64-watchpoint.exp "rhbz1261564-aarch64-watchpoint"] } { ++    return -1 ++} ++ ++if { ! [ runto main ] } then { return 0 } ++ ++set test "rwatch aligned.var4" ++if [istarget "s390*-*-*"] { ++    gdb_test $test {Target does not support this type of hardware watchpoint\.} ++    untested "s390* does not support hw read watchpoint" ++    return ++} ++gdb_test $test "Hardware read watchpoint \[0-9\]+: aligned.var4" ++ ++proc checkvar { address } { ++    global gdb_prompt ++ ++    set test "p &aligned.var$address" ++    gdb_test_multiple $test $test { ++	-re " = \\(int \\*\\) 0x\[0-9a-f\]+$address <aligned(\\+\[0-9\]+)?>\r\n$gdb_prompt $" { ++	    pass $test ++	} ++	-re "\r\n$gdb_prompt $" { ++	    untested "$test (unexpected ELF layout)" ++	    return 0 ++	} ++    } ++    return 1 ++} ++if ![checkvar "0"] { return } ++if ![checkvar "4"] { return } ++if ![checkvar "8"] { return } ++ ++# Assumes: PPC_PTRACE_GETHWDBGINFO::data_bp_alignment == 8 ++# 'lwz' does read only 4 bytes but the hw watchpoint is 8 bytes wide. ++setup_xfail "powerpc*-*-*" ++ ++gdb_continue_to_end diff --git a/gdb-rhbz2232086-refactor-selftest-support.patch b/gdb-rhbz2232086-refactor-selftest-support.patch new file mode 100644 index 0000000..e9febf7 --- /dev/null +++ b/gdb-rhbz2232086-refactor-selftest-support.patch @@ -0,0 +1,77 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Andrew Burgess <aburgess@redhat.com> +Date: Fri, 24 Nov 2023 11:10:08 +0000 +Subject: gdb-rhbz2232086-refactor-selftest-support.patch + +;; Back-port upstream commit 1f0fab7ff86 as part of a fix for +;; non-deterministic gdb-index generation (RH BZ 2232086). + +gdb/testsuite: small refactor in selftest-support.exp + +Split out the code that makes a copy of the GDB executable ready for +self testing into a new proc.  A later commit in this series wants to +load the GDB executable into GDB (for creating an on-disk debug +index), but doesn't need to make use of the full do_self_tests proc. + +There should be no changes in what is tested after this commit. + +Approved-By: Tom Tromey <tom@tromey.com> + +diff --git a/gdb/testsuite/lib/selftest-support.exp b/gdb/testsuite/lib/selftest-support.exp +--- a/gdb/testsuite/lib/selftest-support.exp ++++ b/gdb/testsuite/lib/selftest-support.exp +@@ -92,11 +92,13 @@ proc selftest_setup { executable function } { +     return 0 + } +  +-# A simple way to run some self-tests. +- +-proc do_self_tests {function body} { +-    global GDB tool +- ++# Prepare for running a self-test by moving the GDB executable to a ++# location where we can use it as the inferior.  Return the filename ++# of the new location. ++# ++# If the current testing setup is not suitable for running a ++# self-test, then return an empty string. ++proc selftest_prepare {} { +     # Are we testing with a remote board?  In that case, the target +     # won't have access to the GDB's auxilliary data files +     # (data-directory, etc.).  It's simpler to just skip. +@@ -120,19 +122,31 @@ proc do_self_tests {function body} { +     # Run the test with self.  Copy the file executable file in case +     # this OS doesn't like to edit its own text space. +  +-    set GDB_FULLPATH [find_gdb $GDB] ++    set gdb_fullpath [find_gdb $::GDB] +  +     if {[is_remote host]} { +-	set xgdb x$tool ++	set xgdb x$::tool +     } else { +-	set xgdb [standard_output_file x$tool] ++	set xgdb [standard_output_file x$::tool] +     } +  +     # Remove any old copy lying around. +     remote_file host delete $xgdb +  ++    set filename [remote_download host $gdb_fullpath $xgdb] ++ ++    return $filename ++} ++ ++# A simple way to run some self-tests. ++ ++proc do_self_tests {function body} { ++    set file [selftest_prepare] ++    if { $file eq "" } { ++	return ++    } ++ +     gdb_start +-    set file [remote_download host $GDB_FULLPATH $xgdb] +  +     # When debugging GDB with GDB, some operations can take a relatively long +     # time, especially if the build is non-optimized.  Bump the timeout for the diff --git a/gdb-rhbz2250652-avoid-PyOS_ReadlineTState.patch b/gdb-rhbz2250652-avoid-PyOS_ReadlineTState.patch new file mode 100644 index 0000000..1997ef9 --- /dev/null +++ b/gdb-rhbz2250652-avoid-PyOS_ReadlineTState.patch @@ -0,0 +1,48 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= <ahajkova@redhat.com> +Date: Mon, 8 Jan 2024 13:24:05 +0100 +Subject: gdb-rhbz2250652-avoid-PyOS_ReadlineTState.patch + +gdb/python: avoid use of _PyOS_ReadlineTState + +In python/py-gdb-readline.c we make use of _PyOS_ReadlineTState, +however, this variable is no longer public in Python 3.13, and so GDB +no longer builds. + +We are making use of _PyOS_ReadlineTState in order to re-acquire the +Python Global Interpreter Lock (GIL).  The _PyOS_ReadlineTState +variable is set in Python's outer readline code prior to calling the +user (GDB) supplied readline callback function, which for us is +gdbpy_readline_wrapper.  The gdbpy_readline_wrapper function is called +without the GIL held. + +Instead of using _PyOS_ReadlineTState, I propose that we switch to +calling PyGILState_Ensure() and PyGILState_Release().  These functions +will acquire the GIL based on the current thread.  I think this should +be sufficient; I can't imagine why we'd be running +gdbpy_readline_wrapper on one thread on behalf of a different Python +thread.... that would be unexpected I think. + +Approved-By: Tom Tromey <tom@tromey.com> + +diff --git a/gdb/python/py-gdb-readline.c b/gdb/python/py-gdb-readline.c +--- a/gdb/python/py-gdb-readline.c ++++ b/gdb/python/py-gdb-readline.c +@@ -56,13 +56,11 @@ gdbpy_readline_wrapper (FILE *sys_stdin, FILE *sys_stdout, +       if (except.reason == RETURN_QUIT) + 	return NULL; +  +-      /* The thread state is nulled during gdbpy_readline_wrapper, +-	 with the original value saved in the following undocumented +-	 variable (see Python's Parser/myreadline.c and +-	 Modules/readline.c).  */ +-      PyEval_RestoreThread (_PyOS_ReadlineTState); ++ ++      /* This readline callback is called without the GIL held.  */ ++      gdbpy_gil gil; ++ +       gdbpy_convert_exception (except); +-      PyEval_SaveThread (); +       return NULL; +     } +  diff --git a/gdb-rhbz2250652-gdbpy_gil.patch b/gdb-rhbz2250652-gdbpy_gil.patch new file mode 100644 index 0000000..a72c350 --- /dev/null +++ b/gdb-rhbz2250652-gdbpy_gil.patch @@ -0,0 +1,81 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= <ahajkova@redhat.com> +Date: Mon, 8 Jan 2024 13:12:15 +0100 +Subject: gdb-rhbz2250652-gdbpy_gil.patch + +gdb: move gdbpy_gil into python-internal.h + +Move gdbpy_gil class into python-internal.h, the next +commit wants to make use of this class from a file other +than python.c. + +Approved-By: Tom Tromey <tom@tromey.com> + +diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h +--- a/gdb/python/python-internal.h ++++ b/gdb/python/python-internal.h +@@ -754,6 +754,30 @@ class gdbpy_allow_threads +   PyThreadState *m_save; + }; +  ++/* A helper class to save and restore the GIL, but without touching ++   the other globals that are handled by gdbpy_enter.  */ ++ ++class gdbpy_gil ++{ ++public: ++ ++  gdbpy_gil () ++    : m_state (PyGILState_Ensure ()) ++  { ++  } ++ ++  ~gdbpy_gil () ++  { ++    PyGILState_Release (m_state); ++  } ++ ++  DISABLE_COPY_AND_ASSIGN (gdbpy_gil); ++ ++private: ++ ++  PyGILState_STATE m_state; ++}; ++ + /* Use this after a TRY_EXCEPT to throw the appropriate Python +    exception.  */ + #define GDB_PY_HANDLE_EXCEPTION(Exception)	\ +diff --git a/gdb/python/python.c b/gdb/python/python.c +--- a/gdb/python/python.c ++++ b/gdb/python/python.c +@@ -257,30 +257,6 @@ gdbpy_enter::finalize () +   python_gdbarch = target_gdbarch (); + } +  +-/* A helper class to save and restore the GIL, but without touching +-   the other globals that are handled by gdbpy_enter.  */ +- +-class gdbpy_gil +-{ +-public: +- +-  gdbpy_gil () +-    : m_state (PyGILState_Ensure ()) +-  { +-  } +- +-  ~gdbpy_gil () +-  { +-    PyGILState_Release (m_state); +-  } +- +-  DISABLE_COPY_AND_ASSIGN (gdbpy_gil); +- +-private: +- +-  PyGILState_STATE m_state; +-}; +- + /* Set the quit flag.  */ +  + static void diff --git a/gdb-rhbz2257562-cp-namespace-null-ptr-check.patch b/gdb-rhbz2257562-cp-namespace-null-ptr-check.patch new file mode 100644 index 0000000..f868e6f --- /dev/null +++ b/gdb-rhbz2257562-cp-namespace-null-ptr-check.patch @@ -0,0 +1,113 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Kevin Buettner <kevinb@redhat.com> +Date: Tue, 16 Jan 2024 20:07:53 -0700 +Subject: gdb-rhbz2257562-cp-namespace-null-ptr-check.patch + +;; Backport potential fix for RH BZ 2257562. + +Fix printing of global variable stubs if no inferior is running + +Since 3c45e9f915ae4aeab7312d6fc55a947859057572 gdb crashes when trying +to print a global variable stub without a running inferior, because of +a missing nullptr-check (the block_scope function took care of that +check before it was converted to a method). + +With this check it works again: +``` +(gdb) print s +$1 = <incomplete type> +``` + +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31128 +Approved-By: Tom Tromey <tom@tromey.com> +(cherry picked from commit 576745e26c0ec76a53ba45b20af464628a50b3e4) + +diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c +--- a/gdb/cp-namespace.c ++++ b/gdb/cp-namespace.c +@@ -1026,7 +1026,11 @@ cp_lookup_transparent_type (const char *name) +  +   /* If that doesn't work and we're within a namespace, look there +      instead.  */ +-  scope = get_selected_block (0)->scope (); ++  const block *block = get_selected_block (0); ++  if (block == nullptr) ++    return nullptr; ++ ++  scope = block->scope (); +  +   if (scope[0] == '\0') +     return NULL; +diff --git a/gdb/testsuite/gdb.cp/print-global-stub.cc b/gdb/testsuite/gdb.cp/print-global-stub.cc +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.cp/print-global-stub.cc +@@ -0,0 +1,31 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++   Copyright 2023 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 <http://www.gnu.org/licenses/>.  */ ++ ++struct S ++{ ++  S (int); ++  virtual ~S (); ++ ++  int m_i; ++}; ++ ++S s (5); ++ ++int main () ++{ ++  return 0; ++} +diff --git a/gdb/testsuite/gdb.cp/print-global-stub.exp b/gdb/testsuite/gdb.cp/print-global-stub.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.cp/print-global-stub.exp +@@ -0,0 +1,32 @@ ++# Copyright (C) 2023 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 <http://www.gnu.org/licenses/>. ++ ++# This file is part of the GDB testsuite. ++# It tests printing of a global stub without inferior. ++ ++require allow_cplus_tests ++ ++standard_testfile .cc ++set objfile [standard_output_file ${testfile}.o] ++ ++if { [gdb_compile $srcdir/$subdir/$srcfile $objfile object \ ++	  {c++ debug}] != "" } { ++    untested "failed to compile" ++    return -1 ++} ++ ++clean_restart $objfile ++ ++gdb_test "print s" " = <incomplete type>" diff --git a/gdb-rhbz947564-findvar-assertion-frame-failed-testcase.patch b/gdb-rhbz947564-findvar-assertion-frame-failed-testcase.patch new file mode 100644 index 0000000..0df5ee5 --- /dev/null +++ b/gdb-rhbz947564-findvar-assertion-frame-failed-testcase.patch @@ -0,0 +1,147 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-rhbz947564-findvar-assertion-frame-failed-testcase.patch + +;; Import regression test for `gdb/findvar.c:417: internal-error: +;; read_var_value: Assertion `frame' failed.' (RH BZ 947564) from RHEL 6.5. +;;=fedoratest + +diff --git a/gdb/testsuite/gdb.threads/tls-rhbz947564.cc b/gdb/testsuite/gdb.threads/tls-rhbz947564.cc +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.threads/tls-rhbz947564.cc +@@ -0,0 +1,53 @@ ++#include <iostream> ++#include <pthread.h> ++ ++class x ++  { ++  public: ++    int n; ++ ++    x() : n(0) {} ++  }; ++ ++class y ++  { ++  public: ++    int v; ++ ++    y() : v(0) {} ++    static __thread x *xp; ++  }; ++ ++__thread x *y::xp; ++ ++static void ++foo (y *yp) ++{ ++  yp->v = 1;   /* foo_marker */ ++} ++ ++static void * ++bar (void *unused) ++{ ++  x xinst; ++  y::xp= &xinst; ++ ++  y yy; ++  foo(&yy); ++ ++  return NULL; ++} ++ ++int ++main(int argc, char *argv[]) ++{ ++  pthread_t t[2]; ++ ++  pthread_create (&t[0], NULL, bar, NULL); ++  pthread_create (&t[1], NULL, bar, NULL); ++ ++  pthread_join (t[0], NULL); ++  pthread_join (t[1], NULL); ++ ++  return 0; ++} +diff --git a/gdb/testsuite/gdb.threads/tls-rhbz947564.exp b/gdb/testsuite/gdb.threads/tls-rhbz947564.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.threads/tls-rhbz947564.exp +@@ -0,0 +1,75 @@ ++# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.  */ ++ ++set testfile tls-rhbz947564 ++set srcfile ${testfile}.cc ++set binfile [standard_output_file ${testfile}] ++ ++if [istarget "*-*-linux"] then { ++    set target_cflags "-D_MIT_POSIX_THREADS" ++} else { ++    set target_cflags "" ++} ++ ++if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list c++ debug]] != "" } { ++    return -1 ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++ ++gdb_load ${binfile} ++ ++if { ![runto_main] } { ++    fail "Can't run to function main" ++    return 0 ++} ++ ++gdb_breakpoint "foo" ++gdb_continue_to_breakpoint "foo" ".* foo_marker .*" ++ ++proc get_xp_val {try} { ++    global expect_out ++    global gdb_prompt ++    global hex ++ ++    set xp_val "" ++    gdb_test_multiple "print *yp" "print yp value" { ++	-re { = \{v = 0, static xp = (0x[0-9a-f]+)\}.* } { ++	    pass "print $try value of *yp" ++	    set xp_val $expect_out(1,string) ++	} ++	-re "$gdb_prompt $" { ++	    fail "print $try value of *yp" ++	} ++	timeout { ++	    fail "print $try value of *yp (timeout)" ++	} ++    } ++    return $xp_val ++} ++ ++set first_run [get_xp_val "first"] ++ ++gdb_test "continue" "Breakpoint \[0-9\]+, foo \\\(yp=$hex\\\) at.*" ++ ++set second_run [get_xp_val "second"] ++ ++if { $first_run != $second_run } { ++    pass "different values for TLS variable" ++} else { ++    fail "different values for TLS variable" ++} diff --git a/gdb-simultaneous-step-resume-breakpoint-test.patch b/gdb-simultaneous-step-resume-breakpoint-test.patch new file mode 100644 index 0000000..5e1315b --- /dev/null +++ b/gdb-simultaneous-step-resume-breakpoint-test.patch @@ -0,0 +1,162 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-simultaneous-step-resume-breakpoint-test.patch + +;; New test for step-resume breakpoint placed in multiple threads at once. +;;=fedoratest + +diff --git a/gdb/testsuite/gdb.threads/simultaneous-step-resume-breakpoint.c b/gdb/testsuite/gdb.threads/simultaneous-step-resume-breakpoint.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.threads/simultaneous-step-resume-breakpoint.c +@@ -0,0 +1,79 @@ ++/* Copyright 2009 Free Software Foundation, Inc. ++ ++   Written by Fred Fish of Cygnus Support ++   Contributed by Cygnus Support ++ ++   This file is part of GDB. ++ ++   This program is free software; you can redistribute it and/or modify ++   it under the terms of the GNU General Public License as published by ++   the Free Software Foundation; either version 3 of the License, or ++   (at your option) any later version. ++ ++   This program is distributed in the hope that it will be useful, ++   but WITHOUT ANY WARRANTY; without even the implied warranty of ++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the ++   GNU General Public License for more details. ++ ++   You should have received a copy of the GNU General Public License ++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ ++ ++/* Test multiple threads stepping into a .debug_line-less function with ++   a breakpoint placed on its return-to-caller point.  */ ++ ++#include <pthread.h> ++#include <assert.h> ++#include <unistd.h> ++#include <errno.h> ++#include <stdio.h> ++ ++#define THREADS 3 ++ ++static void * ++func (void *unused) ++{ ++  int i; ++ ++  errno = 0; ++  i = 0xdeadf00d; ++  i = sleep (THREADS);	/* sleep-call */ ++  if (errno != 0)	/* sleep-after */ ++    perror ("sleep"); ++ ++  /* The GDB bug with forgotten step-resume breakpoint could leave stale ++     breakpoint on the I assignment making it a nop.  */ ++  if (i == 0xdeadf00d) ++    assert (0); ++ ++  assert (i == 0); ++ ++  pthread_exit (NULL); ++} ++ ++int ++main (void) ++{ ++  pthread_t threads[THREADS]; ++  int threadi; ++ ++  for (threadi = 0; threadi < THREADS; threadi++) ++    { ++      int i; ++ ++      i = pthread_create (&threads[threadi], NULL, func, NULL); ++      assert (i == 0); ++ ++      i = sleep (1); ++      assert (i == 0); ++    } ++ ++  for (threadi = 0; threadi < THREADS; threadi++) ++    { ++      int i; ++ ++      i = pthread_join (threads[threadi], NULL); ++      assert (i == 0); ++    } ++ ++  return 0;	/* final-exit */ ++} +diff --git a/gdb/testsuite/gdb.threads/simultaneous-step-resume-breakpoint.exp b/gdb/testsuite/gdb.threads/simultaneous-step-resume-breakpoint.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.threads/simultaneous-step-resume-breakpoint.exp +@@ -0,0 +1,65 @@ ++# Copyright (C) 2009 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 <http://www.gnu.org/licenses/>.  */ ++ ++# Test multiple threads stepping into a .debug_line-less function with ++# a breakpoint placed on its return-to-caller point. ++ ++set testfile simultaneous-step-resume-breakpoint ++set srcfile ${testfile}.c ++set binfile [standard_output_file ${testfile}] ++ ++if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { ++    return -1 ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++ ++# Ensure we have no debuginfo for the `sleep' call itself (=for libc). ++gdb_test "set debug-file-directory /DoesNotExist" ++ ++gdb_load ${binfile} ++if ![runto_main] { ++   return -1 ++} ++ ++# Red Hat vendor patch does set it to "step" by default. ++gdb_test "set scheduler-locking off" ++ ++gdb_breakpoint [gdb_get_line_number "final-exit"] ++ ++gdb_breakpoint [gdb_get_line_number "sleep-call"] ++gdb_continue_to_breakpoint "sleep-call" ++ ++gdb_test "step" "sleep-call.*" "step thread 1" ++gdb_test "step" "sleep-call.*" "step thread 2" ++gdb_test "step" "sleep-after.*" "step thread 3" ++ ++set test "first continue" ++gdb_test_multiple "continue" $test { ++    -re "final-exit.*$gdb_prompt $" { ++	# gdb-7.0. ++	pass $test ++	return ++    } ++    -re "sleep-after.*$gdb_prompt $" { ++	# Fedora/RHEL branch. ++	pass $test ++    } ++} ++ ++gdb_test "continue" "sleep-after.*" "second continue" ++gdb_test "continue" "final-exit.*" "third continue" diff --git a/gdb-test-bt-cfi-without-die.patch b/gdb-test-bt-cfi-without-die.patch new file mode 100644 index 0000000..6167c14 --- /dev/null +++ b/gdb-test-bt-cfi-without-die.patch @@ -0,0 +1,214 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-test-bt-cfi-without-die.patch + +;; [delayed-symfile] Test a backtrace regression on CFIs without DIE (BZ 614604). +;;=fedoratest + +http://sourceware.org/ml/archer/2010-q3/msg00028.html + +On Wed, 25 Feb 2009 00:14:29 +0100, Jan Kratochvil wrote: +> commit 6a37c2b9962258ecf9299cc34a650e64a06acaa5 +> +> There was a regression on gdb.base/savedregs.exp. +> +> quick_addrmap/require_partial_symbols should be used even for the unwind debug +> info checking as its load has been also delayed by this branch. +[...] +> --- a/gdb/dwarf2-frame.c +> +++ b/gdb/dwarf2-frame.c +[...] +> @@ -1499,6 +1500,14 @@ dwarf2_frame_find_fde (CORE_ADDR *pc) +>        struct dwarf2_fde *fde; +>        CORE_ADDR offset; +> +> +      if (objfile->quick_addrmap) +> +	{ +> +	  if (!addrmap_find (objfile->quick_addrmap, *pc)) +> +	    continue; +> +	} +> +      /* FIXME: Read-in only .debug_frame/.eh_frame without .debug_info?  */ +> +      require_partial_symbols (objfile); +> + + +but this has caused a different regression (as discussed in the confcall). + +QUICK_ADDRMAP is built only from .debug_aranges.  But we can have existing +built .debug_aranges for CUs in OBJFILE but still some CUs do not need to have +DWARF at all while they can feature CFIs (.eh_frame or .debug_frame). +It has been described by Daniel Jacobowitz at: +	Re: [2/4] RFC: check psymtabs_addrmap before reading FDEs +	http://sourceware.org/ml/gdb-patches/2010-07/msg00012.html + +Sorry for this regression by me (in that fix of a different regression). + +Fixed it the "slow way" as this branch is now obsoleted by .gdb-index. + +No regressions on {x86_64,x86_64-m32,i686}-fedora13-linux-gnu. + +Checked-in. + +Thanks, +Jan + +eb8df8566acc1ed963e3e9b77c13b9c2c3db03fb + +Test CFI is parsed even for range (function) not described by any DIE. + +https://bugzilla.redhat.com/show_bug.cgi?id=614028 + +gdb/ +	* dwarf2-frame.c (dwarf2_frame_find_fde): Remove the +	OBJFILE->QUICK_ADDRMAP check.  New comment why. + +gdb/testsuite/ +	* gdb.base/cfi-without-die.exp, gdb.base/cfi-without-die-main.c, +	gdb.base/cfi-without-die-caller.c: New files. + +diff --git a/gdb/testsuite/gdb.base/cfi-without-die-caller.c b/gdb/testsuite/gdb.base/cfi-without-die-caller.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/cfi-without-die-caller.c +@@ -0,0 +1,28 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++   Copyright 2005, 2007, 2008, 2009, 2010 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 <http://www.gnu.org/licenses/>.  */ ++ ++typedef int (*callback_t) (void); ++ ++int ++caller (callback_t callback) ++{ ++  /* Ensure some frame content to push away the return address.  */ ++  volatile const long one = 1; ++ ++  /* Modify the return value to prevent any tail-call optimization.  */ ++  return (*callback) () - one; ++} +diff --git a/gdb/testsuite/gdb.base/cfi-without-die-main.c b/gdb/testsuite/gdb.base/cfi-without-die-main.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/cfi-without-die-main.c +@@ -0,0 +1,32 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++   Copyright 2005, 2007, 2008, 2009, 2010 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 <http://www.gnu.org/licenses/>.  */ ++ ++typedef int (*callback_t) (void); ++ ++extern int caller (callback_t callback); ++ ++int ++callback (void) ++{ ++  return 1; ++} ++ ++int ++main (void) ++{ ++  return caller (callback); ++} +diff --git a/gdb/testsuite/gdb.base/cfi-without-die.exp b/gdb/testsuite/gdb.base/cfi-without-die.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/cfi-without-die.exp +@@ -0,0 +1,71 @@ ++# Copyright 2010 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 <http://www.gnu.org/licenses/>. ++ ++# Test CFI is parsed even for range (function) not described by any DIE. ++ ++set testfile cfi-without-die ++set srcmainfile ${testfile}-main.c ++set srccallerfile ${testfile}-caller.c ++set executable ${testfile} ++set objmainfile [standard_output_file ${testfile}-main.o] ++set objcallerfile [standard_output_file ${testfile}-caller.o] ++set binfile [standard_output_file ${executable}] ++ ++if { [gdb_compile "${srcdir}/${subdir}/${srccallerfile}" ${objcallerfile} \ ++      object [list {additional_flags=-fomit-frame-pointer -fno-unwind-tables -fno-asynchronous-unwind-tables}]] != "" ++     || [gdb_compile "${srcdir}/${subdir}/${srcmainfile}" ${objmainfile} object {debug}] != "" ++     || [gdb_compile "${objmainfile} ${objcallerfile}" ${binfile} executable {}] != "" } { ++     untested ${testfile}.exp ++     return -1 ++} ++ ++clean_restart $executable ++ ++if ![runto callback] then { ++   fail "verify unwinding: Can't run to callback" ++   return 0 ++} ++set test "verify unwinding breaks without CFI" ++gdb_test_multiple "bt" $test { ++    -re " in \[?\]\[?\] .*\r\n$gdb_prompt $" { ++	# It may backtrace through some random frames even to main(). ++	pass $test ++    } ++    -re " in main .*\r\n$gdb_prompt $" { ++	fail $test ++    } ++    -re "\r\n$gdb_prompt $" { ++	pass $test ++    } ++} ++ ++if { [gdb_compile "${srcdir}/${subdir}/${srccallerfile}" ${objcallerfile} \ ++      object [list {additional_flags=-fomit-frame-pointer -funwind-tables -fasynchronous-unwind-tables}]] != "" ++     || [gdb_compile "${srcdir}/${subdir}/${srcmainfile}" ${objmainfile} object {debug}] != "" ++     || [gdb_compile "${objmainfile} ${objcallerfile}" ${binfile} executable {}] != "" } { ++     untested ${testfile}.exp ++     return -1 ++} ++ ++clean_restart $executable ++ ++if ![runto callback] then { ++   fail "test CFI without DIEs: Can't run to callback" ++   return 0 ++} ++# #0  callback () at ... ++# #1  0x00000000004004e9 in caller () ++# #2  0x00000000004004cd in main () at ... ++gdb_test "bt" "#0 +callback \[^\r\n\]+\r\n#1 \[^\r\n\]+ in caller \[^\r\n\]+\r\n#2 \[^\r\n\]+ in main \[^\r\n\]+" "verify unwindin works for CFI without DIEs" diff --git a/gdb-test-dw2-aranges.patch b/gdb-test-dw2-aranges.patch new file mode 100644 index 0000000..458e8ba --- /dev/null +++ b/gdb-test-dw2-aranges.patch @@ -0,0 +1,220 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Fedora GDB patches <invalid@email.com> +Date: Fri, 27 Oct 2017 21:07:50 +0200 +Subject: gdb-test-dw2-aranges.patch + +;; [archer-tromey-delayed-symfile] New test gdb.dwarf2/dw2-aranges.exp. +;;=fedoratest + +[archer-tromey-delayed-symfile] + +commit 77fa7778a37b0d28a7e4e5235f074a10ecf1815d +Author: Jan Kratochvil <jkratoch@host1.dyn.jankratochvil.net> +Date:   Sat Aug 15 15:05:54 2009 +0200 + +    Test for "handle incorrect aranges". + +    readelf: +    Contents of the .debug_aranges section: + +      Length:                   8 +      Version:                  2 +      Offset into .debug_info:  0x0 +      Pointer Size:             0 +      Segment Size:             0 + +        Address    Length +    Floating point exception + +    	* gdb.dwarf2/dw2-aranges.exp, gdb.dwarf2/dw2-aranges.S: New files. + +diff --git a/gdb/testsuite/gdb.dwarf2/dw2-aranges.S b/gdb/testsuite/gdb.dwarf2/dw2-aranges.S +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.dwarf2/dw2-aranges.S +@@ -0,0 +1,140 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++   Copyright 2004, 2007, 2008, 2009 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 <http://www.gnu.org/licenses/>.  */ ++ ++/* Test .debug_aranges containing zero address_size.  */ ++ ++/* Dummy function to provide debug information for.  */ ++ ++	.text ++.Lbegin_text1: ++	.globl main ++	.type main, %function ++main: ++.Lbegin_main: ++	.int 0 ++.Lend_main: ++	.size main, .-main ++.Lend_text1: ++ ++/* Debug information */ ++ ++	.section .debug_info ++.Lcu1_begin: ++	/* CU header */ ++	.4byte	.Lcu1_end - .Lcu1_start		/* Length of Compilation Unit */ ++.Lcu1_start: ++	.2byte	2				/* DWARF Version */ ++	.4byte	.Labbrev1_begin			/* Offset into abbrev section */ ++	.byte	4				/* Pointer size */ ++ ++	/* CU die */ ++	.uleb128 1				/* Abbrev: DW_TAG_compile_unit */ ++	.4byte	.Lend_text1			/* DW_AT_high_pc */ ++	.4byte	.Lbegin_text1			/* DW_AT_low_pc */ ++	.ascii	"file1.txt\0"			/* DW_AT_name */ ++	.ascii	"GNU C 3.3.3\0"			/* DW_AT_producer */ ++	.byte	1				/* DW_AT_language (C) */ ++ ++	/* main */ ++	.uleb128	2			/* Abbrev: DW_TAG_subprogram */ ++	.byte		1			/* DW_AT_external */ ++	.byte		1			/* DW_AT_decl_file */ ++	.byte		2			/* DW_AT_decl_line */ ++	.ascii		"main\0"		/* DW_AT_name */ ++	.4byte		.Ltype_int-.Lcu1_begin	/* DW_AT_type */ ++	.4byte		.Lbegin_main	/* DW_AT_low_pc */ ++	.4byte		.Lend_main		/* DW_AT_high_pc */ ++	.byte		1			/* DW_AT_frame_base: length */ ++	.byte		0x55			/* DW_AT_frame_base: DW_OP_reg5 */ ++ ++.Ltype_int: ++	.uleb128	3			/* Abbrev: DW_TAG_base_type */ ++	.ascii		"int\0"			/* DW_AT_name */ ++	.byte		4			/* DW_AT_byte_size */ ++	.byte		5			/* DW_AT_encoding */ ++ ++	.byte		0			/* End of children of CU */ ++ ++.Lcu1_end: ++ ++/* Abbrev table */ ++	.section .debug_abbrev ++.Labbrev1_begin: ++	.uleb128	1			/* Abbrev code */ ++	.uleb128	0x11			/* DW_TAG_compile_unit */ ++	.byte		1			/* has_children */ ++	.uleb128	0x12			/* DW_AT_high_pc */ ++	.uleb128	0x1			/* DW_FORM_addr */ ++	.uleb128	0x11			/* DW_AT_low_pc */ ++	.uleb128	0x1			/* DW_FORM_addr */ ++	.uleb128	0x3			/* DW_AT_name */ ++	.uleb128	0x8			/* DW_FORM_string */ ++	.uleb128	0x25			/* DW_AT_producer */ ++	.uleb128	0x8			/* DW_FORM_string */ ++	.uleb128	0x13			/* DW_AT_language */ ++	.uleb128	0xb			/* DW_FORM_data1 */ ++	.byte		0x0			/* Terminator */ ++	.byte		0x0			/* Terminator */ ++ ++	.uleb128	2			/* Abbrev code */ ++	.uleb128	0x2e			/* DW_TAG_subprogram */ ++	.byte		0			/* has_children */ ++	.uleb128	0x3f			/* DW_AT_external */ ++	.uleb128	0xc			/* DW_FORM_flag */ ++	.uleb128	0x3a			/* DW_AT_decl_file */ ++	.uleb128	0xb			/* DW_FORM_data1 */ ++	.uleb128	0x3b			/* DW_AT_decl_line */ ++	.uleb128	0xb			/* DW_FORM_data1 */ ++	.uleb128	0x3			/* DW_AT_name */ ++	.uleb128	0x8			/* DW_FORM_string */ ++	.uleb128	0x49			/* DW_AT_type */ ++	.uleb128	0x13			/* DW_FORM_ref4 */ ++	.uleb128	0x11			/* DW_AT_low_pc */ ++	.uleb128	0x1			/* DW_FORM_addr */ ++	.uleb128	0x12			/* DW_AT_high_pc */ ++	.uleb128	0x1			/* DW_FORM_addr */ ++	.uleb128	0x40			/* DW_AT_frame_base */ ++	.uleb128	0xa			/* DW_FORM_block1 */ ++	.byte		0x0			/* Terminator */ ++	.byte		0x0			/* Terminator */ ++ ++	.uleb128	3			/* Abbrev code */ ++	.uleb128	0x24			/* DW_TAG_base_type */ ++	.byte		0			/* has_children */ ++	.uleb128	0x3			/* DW_AT_name */ ++	.uleb128	0x8			/* DW_FORM_string */ ++	.uleb128	0xb			/* DW_AT_byte_size */ ++	.uleb128	0xb			/* DW_FORM_data1 */ ++	.uleb128	0x3e			/* DW_AT_encoding */ ++	.uleb128	0xb			/* DW_FORM_data1 */ ++	.byte		0x0			/* Terminator */ ++	.byte		0x0			/* Terminator */ ++ ++	.byte		0x0			/* Terminator */ ++	.byte		0x0			/* Terminator */ ++ ++/* aranges table */ ++	.section .debug_aranges ++	.long	.Laranges_end - 1f ++1: ++	.2byte	2				/* aranges Version */ ++	.4byte	.Lcu1_begin - .debug_info	/* Offset into .debug_info section */ ++	/* The GDB crasher is this zero value.  */ ++	.byte		0			/* aranges address_size */ ++	.byte		0			/* aranges segment_size */ ++ ++.Laranges_end: +diff --git a/gdb/testsuite/gdb.dwarf2/dw2-aranges.exp b/gdb/testsuite/gdb.dwarf2/dw2-aranges.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.dwarf2/dw2-aranges.exp +@@ -0,0 +1,40 @@ ++# Copyright 2004, 2005, 2007, 2008, 2009 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 <http://www.gnu.org/licenses/>. ++ ++# Test .debug_aranges containing zero address_size. ++ ++# This test can only be run on targets which support DWARF-2 and use gas. ++# For now pick a sampling of likely targets. ++if {![istarget *-*-linux*] ++    && ![istarget *-*-gnu*] ++    && ![istarget *-*-elf*] ++    && ![istarget *-*-openbsd*] ++    && ![istarget arm-*-eabi*] ++    && ![istarget powerpc-*-eabi*]} { ++    return 0 ++} ++ ++set testfile "dw2-aranges" ++set srcfile ${testfile}.S ++set binfile [standard_output_file ${testfile}] ++ ++if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {nodebug}] != "" } { ++    return -1 ++} ++ ++clean_restart $testfile ++ ++# Failed gdb_load would abort the testcase execution earlier. ++pass "file loaded" diff --git a/gdb.spec b/gdb.spec new file mode 100644 index 0000000..c1d17b9 --- /dev/null +++ b/gdb.spec @@ -0,0 +1,482 @@ +%bcond_with guile +Name: gdb +Version: 14.1 +Release: 4 + +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-1.3 +Source: https://ftp.gnu.org/gnu/gdb/gdb-%{version}.tar.xz +URL: http://gnu.org/software/gdb/ + +Source1: gdb-gstack.man +Source2: gdbinit + +# patch from Fedora +Patch1: gdb-6.3-rh-testversion-20041202.patch +Patch2: gdb-6.3-gstack-20050411.patch +Patch3: gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch +Patch4: gdb-6.5-BEA-testsuite.patch +Patch5: gdb-6.5-bz218379-ppc-solib-trampoline-test.patch +Patch6: gdb-6.6-bz229517-gcore-without-terminal.patch +Patch7: gdb-6.6-testsuite-timeouts.patch +Patch8: gdb-6.6-bz237572-ppc-atomic-sequence-test.patch +Patch9: gdb-6.3-attach-see-vdso-test.patch +Patch10: gdb-6.5-bz243845-stale-testing-zombie-test.patch +Patch11: gdb-6.6-buildid-locate.patch +Patch12: gdb-6.6-buildid-locate-solib-missing-ids.patch +Patch13: gdb-6.6-buildid-locate-rpm.patch +Patch14: gdb-6.7-ppc-clobbered-registers-O2-test.patch +Patch15: gdb-6.5-gcore-buffer-limit-test.patch +Patch16: gdb-6.3-mapping-zero-inode-test.patch +Patch17: gdb-6.5-section-num-fixup-test.patch +Patch18: gdb-6.8-bz466901-backtrace-full-prelinked.patch +Patch19: gdb-simultaneous-step-resume-breakpoint-test.patch +Patch20: gdb-core-open-vdso-warning.patch +Patch21: gdb-archer-next-over-throw-cxx-exec.patch +Patch22: gdb-6.6-buildid-locate-rpm-librpm-workaround.patch +Patch23: gdb-test-bt-cfi-without-die.patch +Patch24: gdb-bz634108-solib_address.patch +Patch25: gdb-test-dw2-aranges.patch +Patch26: gdb-glibc-strstr-workaround.patch +Patch27: gdb-rhbz-818343-set-solib-absolute-prefix-testcase.patch +Patch28: gdb-rhbz947564-findvar-assertion-frame-failed-testcase.patch +Patch29: gdb-rhbz1007614-memleak-infpy_read_memory-test.patch +Patch30: gdb-6.6-buildid-locate-misleading-warning-missing-debuginfo-rhbz981154.patch +Patch31: gdb-rhbz1156192-recursive-dlopen-test.patch +Patch32: gdb-rhbz1149205-catch-syscall-after-fork-test.patch +Patch33: gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-3of3.patch +Patch34: gdb-fedora-libncursesw.patch +Patch35: gdb-rhbz1261564-aarch64-hw-watchpoint-test.patch +Patch36: gdb-container-rh-pkg.patch +Patch37: gdb-linux_perf-bundle.patch +Patch38: gdb-add-index.patch +Patch39: gdb-rhbz2232086-refactor-selftest-support.patch +Patch40: gdb-rhbz-2232086-reduce-size-of-gdb-index.patch +Patch41: gdb-rhbz-2232086-cpp-ify-mapped-symtab.patch +Patch42: gdb-rhbz-2232086-generate-gdb-index-consistently.patch +Patch43: gdb-rhbz-2232086-generate-dwarf-5-index-consistently.patch +Patch44: gdb-rhbz2250652-gdbpy_gil.patch +Patch45: gdb-rhbz2250652-avoid-PyOS_ReadlineTState.patch +Patch46: gdb-rhbz2257562-cp-namespace-null-ptr-check.patch +Patch47: gdb-ftbs-swapped-calloc-args.patch +# Fedra patch end + +Patch9000: 0001-set-entry-point-when-text-segment-is-missing.patch + +%global gdb_src gdb-%{version} +%global gdb_build build-%{_target_platform} +%global __python %{__python3} + +%undefine _debuginfo_subpackages + +Summary: GNU Project debugger + +Recommends: gcc-gdb-plugin +Recommends: dnf-command(debuginfo-install) +Conflicts: gdb-headless < 7.12-29 +Requires: gdb-headless = %{version}-%{release} + +%description +GDB, the GNU Project debugger, allows you to see what is going on inside +another program while it executes -- or what another program was doing +at the moment it crashed. + +This package is only a stub to install gcc-gdb-plugin for 'compile' commands. +See package 'gdb-headless'. + +%package headless +Summary: The GNU Project debugger for C, C++, Fortran, Go and other languages + +Conflicts: elfutils < 0.149 +Provides: bundled(libiberty) = 20180828 +Provides: bundled(gnulib) = 20161115 +Provides: bundled(binutils) = 20180828 +Provides: bundled(md5-gcc) = 20180828 + +%global librpmso librpm.so.9 + +Recommends: default-yama-scope +Recommends: %{librpmso}()(64bit) + +BuildRequires: rpm-libs autoconf +BuildRequires: readline-devel >= 6.2-4 +BuildRequires: gcc-c++ ncurses-devel texinfo gettext flex bison +BuildRequires: expat-devel xz-devel rpm-devel zlib-devel libselinux-devel +BuildRequires: python3-devel texinfo-tex +BuildRequires: perl-podlators libbabeltrace-devel mpfr-devel gmp-devel +%if %{with guile} +BuildRequires: guile-devel +%endif +%ifarch %{ix86} x86_64 +BuildRequires: libipt-devel +%endif + +%description headless +GDB, the GNU Project debugger, allows you to see what is going on inside +another program while it executes -- or what another program was doing +at the moment it crashed. + +%package gdbserver +Summary: A standalone server for GDB (the GNU source-level debugger) + +%description gdbserver +GDB, the GNU Project debugger, allows you to see what is going on inside +another program while it executes -- or what another program was doing +at the moment it crashed. + +This package provides a program that allows you to run GDB on a different +machine than the one which is running the program being debugged. + +%package help +Summary: Documentation for GDB (the GNU Project debugger) +License: GFDL-1.3-or-later +BuildArch: noarch + +%description help +GDB, the GNU Project debugger, allows you to see what is going on inside +another program while it executes -- or what another program was doing +at the moment it crashed. + +This package provides INFO, HTML and PDF user manual for GDB. + +%prep +%autosetup -n %{gdb_src} -p1 + +(cd gdb;rm -fv $(perl -pe 's/\\\n/ /' <Makefile.in|sed -n 's/^YYFILES = //p')) + +find -name "*.info*"|xargs rm -f + +find -name "*.orig" | xargs rm -f + +cat > gdb/version.in << _FOO +openEuler %{version}-%{release} +_FOO + +rm -f libdecnumber/gstdint.h +rm -f bfd/doc/*.info +rm -f bfd/doc/*.info-* +rm -f gdb/doc/*.info +rm -f gdb/doc/*.info-* +mv -f readline/readline/doc readline-doc +rm -rf readline/readline/* +mv -f readline-doc readline/readline/doc +rm -rf zlib texinfo + +%build +rm -rf %{buildroot} +test -e %{_libdir}/%{librpmso} + +mkdir %{gdb_build} +cd %{gdb_build} + +export CFLAGS="$RPM_OPT_FLAGS -DDNF_DEBUGINFO_INSTALL -fPIC" +export LDFLAGS="%{?__global_ldflags}" +export CXXFLAGS="$CFLAGS" + +../configure							\ +	--prefix=%{_prefix}					\ +	--libdir=%{_libdir}					\ +	--sysconfdir=%{_sysconfdir}				\ +	--mandir=%{_mandir}					\ +	--infodir=%{_infodir}					\ +	--with-system-gdbinit=%{_sysconfdir}/gdbinit		\ +	--with-gdb-datadir=%{_datadir}/gdb			\ +	--enable-gdb-build-warnings=,-Wno-unused		\ +	--enable-build-with-cxx					\ +	--enable-werror						\ +	--with-separate-debug-dir=/usr/lib/debug		\ +	--disable-sim						\ +	--disable-rpath						\ +	--without-stage1-ldflags				\ +	--disable-libmcheck					\ +	--with-babeltrace					\ +%if %{with guile} +	--with-guile						\ +%else +	--without-guile						\ +%endif +	--with-system-readline					\ +	--with-expat						\ +	--without-libexpat-prefix				\ +	--enable-tui						\ +	--with-python=%{__python3}				\ +	--with-rpm=%{librpmso}			\ +	--with-lzma						\ +	--without-libunwind					\ +	--enable-64-bit-bfd					\ +%ifnarch riscv64 loongarch64 +	--enable-inprocess-agent				\ +%endif +	--with-system-zlib					\ +%ifarch %{ix86} x86_64 +	--with-intel-pt						\ +%else +	--without-intel-pt					\ +%endif +	--with-auto-load-dir='$debugdir:$datadir/auto-load'	\ +	--with-auto-load-safe-path='$debugdir:$datadir/auto-load'	\ +	--enable-targets=aarch64-linux-gnu %{_target_platform} + +make %{?_smp_mflags} CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS" V=1 maybe-configure-gdb +perl -i.relocatable -pe 's/^(D\[".*_RELOCATABLE"\]=" )1(")$/${1}0$2/' gdb/config.status + +make %{?_smp_mflags} CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS" V=1 + +! grep '_RELOCATABLE.*1' gdb/config.h + +cd .. + +cd %{gdb_build} +make %{?_smp_mflags} \ +     -C gdb/doc {gdb,annotate}{.info,/index.html,.pdf} MAKEHTMLFLAGS=--no-split MAKEINFOFLAGS=--no-split V=1 + +cp $RPM_BUILD_DIR/%{gdb_src}/gdb/NEWS $RPM_BUILD_DIR/%{gdb_src} + +%check + +%install +cd %{gdb_build} +rm -rf $RPM_BUILD_ROOT + +make %{?_smp_mflags} install DESTDIR=$RPM_BUILD_ROOT + +mkdir -p $RPM_BUILD_ROOT%{_prefix}/libexec +mv -f $RPM_BUILD_ROOT%{_bindir}/gdb $RPM_BUILD_ROOT%{_prefix}/libexec/gdb +ln -s -r $RPM_BUILD_ROOT%{_prefix}/libexec/gdb  $RPM_BUILD_ROOT%{_bindir}/gdb + +mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/gdbinit.d +touch -r %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/gdbinit.d +sed 's#%%{_sysconfdir}#%{_sysconfdir}#g' <%{SOURCE2} >$RPM_BUILD_ROOT%{_sysconfdir}/gdbinit +touch -r %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/gdbinit + +for i in `find $RPM_BUILD_ROOT%{_datadir}/gdb/python/gdb -name "*.py"` +do +  touch -r $RPM_BUILD_DIR/%{gdb_src}/gdb/version.in $i  +done + +%if 0%{?_enable_debug_packages:1} +mkdir -p $RPM_BUILD_ROOT/usr/lib/debug%{_bindir} +cp -p ./gdb/gdb-gdb.py $RPM_BUILD_ROOT/usr/lib/debug%{_bindir}/ +for pyo in "" "-O";do +  %{__python3} $pyo -c 'import compileall, re, sys; sys.exit (not compileall.compile_dir("'"$RPM_BUILD_ROOT/usr/lib/debug%{_bindir}"'", 1, "'"/usr/lib/debug%{_bindir}"'"))' +done +%endif # 0%{?_enable_debug_packages:1} + +for i in $(echo bin lib $(basename %{_libdir}) sbin|tr ' ' '\n'|sort -u);do +  mkdir -p $RPM_BUILD_ROOT%{_datadir}/gdb/auto-load/%{_prefix}/$i +  ln -s $(echo %{_prefix}|sed 's#^/*##')/$i \ +        $RPM_BUILD_ROOT%{_datadir}/gdb/auto-load/$i +done + +for i in `find $RPM_BUILD_ROOT%{_datadir}/gdb -name "*.py"`; do +  touch -r $RPM_BUILD_DIR/%{gdb_src}/gdb/version.in $i +done + +# Remove part of binutils files +rm -rf $RPM_BUILD_ROOT%{_datadir}/locale/ +rm -f $RPM_BUILD_ROOT%{_infodir}/bfd* +rm -f $RPM_BUILD_ROOT%{_infodir}/standard* +rm -f $RPM_BUILD_ROOT%{_infodir}/configure* +rm -f $RPM_BUILD_ROOT%{_infodir}/sframe-spec* +rm -rf $RPM_BUILD_ROOT%{_includedir}/*.h +rm -rf $RPM_BUILD_ROOT/%{_libdir}/lib{bfd*,opcodes*,iberty*,ctf*,sframe*} + +cp -p %{SOURCE2} $RPM_BUILD_ROOT%{_mandir}/man1/gstack.1 +ln -s gstack.1 $RPM_BUILD_ROOT%{_mandir}/man1/pstack.1 +ln -s gstack $RPM_BUILD_ROOT%{_bindir}/pstack + +# Packaged GDB is not a cross-target one. +(cd $RPM_BUILD_ROOT%{_datadir}/gdb/syscalls + rm -f mips*.xml + rm -f sparc*.xml +%ifnarch x86_64 + rm -f amd64-linux.xml +%endif +%ifnarch %{ix86} x86_64 + rm -f i386-linux.xml +%endif +) + +# Remove. +rm -f $RPM_BUILD_ROOT%{_infodir}/gdbint* +rm -f $RPM_BUILD_ROOT%{_infodir}/stabs* +rm -f $RPM_BUILD_ROOT%{_infodir}/dir +rm -f $RPM_BUILD_ROOT%{_datadir}/gdb/system-gdbinit/elinos.py +rm -f $RPM_BUILD_ROOT%{_datadir}/gdb/system-gdbinit/wrs-linux.py +rmdir $RPM_BUILD_ROOT%{_datadir}/gdb/system-gdbinit +rm -f $RPM_BUILD_ROOT%{_datadir}/gdb/python/gdb/FrameWrapper.py +rm -f $RPM_BUILD_ROOT%{_datadir}/gdb/python/gdb/backtrace.py +rm -f $RPM_BUILD_ROOT%{_datadir}/gdb/python/gdb/command/backtrace.py + +%files +%license COPYING3 COPYING COPYING.LIB COPYING3.LIB +%doc README NEWS +%{_bindir}/gdb +%{_bindir}/gcore +%{_bindir}/gstack +%{_bindir}/pstack +%{_includedir}/gdb + +%files headless +%{_prefix}/libexec/gdb +%config(noreplace) %{_sysconfdir}/gdbinit +%{_sysconfdir}/gdbinit.d +%{_bindir}/gdb-add-index +%{_datadir}/gdb + +%files gdbserver +%{_bindir}/gdbserver +%ifnarch riscv64 loongarch64 +%{_libdir}/libinproctrace.so +%endif + +%files help +%{_mandir}/*/gcore.1* +%{_mandir}/*/gstack.1* +%{_mandir}/*/pstack.1* +%{_mandir}/*/gdb.1* +%{_mandir}/*/gdbinit.5* +%{_mandir}/*/gdb-add-index.1* +%{_mandir}/*/gdbserver.1* +%doc %{gdb_build}/gdb/doc/{gdb,annotate}.{html,pdf} +%{_infodir}/annotate.info* +%{_infodir}/gdb.info* +%{_infodir}/ctf-spec.info* + +%changelog +* Tue Aug 06 2024 Funda Wang <fundawang@yeah.net> - 14.1-4 +- make guile requirment conditioned + +* Thu Jun 13 2024 wangxiao <wangxiao184@h-partners.com> - 14.1-3 +- modify gdb-help package's license GFDL to GFDL-1.3-or-later + +* Wed Mar  6 2024 Wenlong Zhang <zhangwenlong@loongson.cn> - 14.1-2 +- Fix build error for loongarch64 + +* Wed Jan 24 2024 liuchao <liuchao173@huawei.com> - 14.1-1 +- upgrade GDB version to 14.1: +  - GDB no longer support AiX 4.x, 5.x and 6.x. The minimum version supported is AiX 7.1. +  - GDB/MI version 1 support has been removed +  - Initial built-in support for Debugger Adapter Protocol (DAP) +  - GDB now recognizes the NO_COLOR environment variable +  - Initial support for integer types larger than 64 bits +  - Breakpoints can now be inferior-specific +  - New convenience function "$_shell", to execute a shell command and return its result. +  - Python support +  - Support for enabling or disabling individual remote target features +  - New 'no-history' stop reason +  - Support for inferior-specific breakpoints +  - The bkpt tuple, which appears in breakpoint-created notifications, and in the result of the -break-insert command can now include an optional 'inferior' field for both the main breakpoint, and each location, when the breakpoint is inferior-specific. +  - Trying to create a thread-specific breakpoint using a non-existent thread ID now results in an error +  - New "simple-values-ref-types" -list-feature value indicating how the --simple-values option in various commands take reference types into account. +  - Initial support for Scalable Matrix Extension (SME) and for Scalable Matrix Extension 2 (SME2) +  - The 'org.gnu.gdb.aarch64.pauth' Pointer Authentication feature is now deprecated in favor of the 'org.gnu.gdb.aarch64.pauth_v2' feature string +  - Support for the Ada 2022 target name symbol ('@') +  - Support for the The Ada 2022 'Enum_Rep and 'Enum_Val attributes +  - The 'list' command now accepts '.' as an argument, telling GDB to print the location around the point of execution within the current frame +  - New '%V' output format for printf and dprintf commands. +  - The printf command now limits the size of strings fetched from the inferior to the value of the 'max-value-size' setting. +  - Support for extending at configure time the default value of the 'debug-file-directory' GDB parameter via the new --additional-debug-dirs=PATHs configure option. +  - New command "info main" +  - New command "set tui mouse-events [on|off]" (on by default) +  - New command "set always-read-ctf on|off" (off by default) +  - Various new debug and maitenance commands + +* Tue Nov 21 2023 Wenyu Liu <liuwenyu7@huawei.com> - 12.1-10 +- fix CVE-2023-39130 + +* Tue Nov 21 2023 Wenyu Liu <liuwenyu7@huawei.com> - 12.1-9 +- some follow-up patches of CVE-2023-39129 + +* Thu Oct 12 2023 liningjie <liningjie@xfusion.com> - 12.1-8 +- fix CVE-2023-39129 + +* Sat Sep 2 2023 liningjie <liningjie@xfusion.com> - 12.1-7 +- fix CVE-2023-39128 + +* Thu Aug 3 2023 Wenyu Liu <liuwenyu7@huawei.com> - 12.1-6 +- libctf: update regexp to allow makeinfo to build document + +* Thu Jul 27 2023 Wenyu Liu <liuwenyu7@huawei.com> - 12.1-5 +- Handle Python 3.11 deprecation of PySys_SetPath and Py_SetProgramName + +* Thu Jul 27 2023 Wenyu Liu <liuwenyu7@huawei.com> - 12.1-4 +- initialize the data_head variable to eliminate compilation warnings + +* Tue Feb 14 2023 Wenyu Liu <liuwenyu7@huawei.com> - 12.1-3 +- Rectify the spec file. + +* Mon Feb 6 2023 Wenyu Liu <liuwenyu7@huawei.com> - 12.1-2 +- Add support for readline 8.2 + +* Fri Nov 18 2022 yaowenbin <yaowenbin1@huawei.com> - 12.1-1 +- upgrade GDB version to 12.1 + +* Mon Aug 15 2022 laokz <laokz@foxmail.com> - 11.1-4 +- fix riscv64 relevant config + +* Fri Jul  8 2022 cenhuilin <cenhuilin@kylinos.cn> - 11.1-3 +- set entry point when text segment is missing + +* Tue Apr 12 2022 zhouwenpei <zhouwenpei1@h-partners.com> - 11.1-2 +- fix gdb build error via cherry-pick upstream patch + +* Wed Dec 8 2021 zhouwenpei <zhouwenpei1@huawei.com> - 11.1-1 +- upgrade GDB version to 11.1 + +* Fri Aug 13 2021 zhouwenpei <zhouwenpei1@huawei.com> - 9.2-7 +- adjust include order to avoid gnulib error + +* Fri Jul 23 2021 zhouwenpei <zhouwenpei1@huawei.com> - 9.2-6 +- remove unnecessary build require. + +* Mon Apr 19 2021 yuxiangyang <yuxiangyang4@huawei.com> - 9.2-5 +- remove unnecessary build require. + +* Mon Apr 19 2021 yuxiangyang <yuxiangyang4@huawei.com> - 9.2-5 +- remove unnecessary build require. + +* Wed Mar 31 2021 xinghe <xinghe1@huawei.com> - 9.2-4 +- fix typo for name + +* Sat Nov 7 2020 Qingqing Li<liqingqing3@huawei.com> - 9.2-3 +- cause riscv64 do not support gdbserver, create a empty package for it. +- add -fPIC option. + +* Sun Sep 13 2020 licihua<licihua@huawei.com> - 9.2-2 +- Change the sequence of patch and sources + +* Wed Jul 22 2020 qinyu<qinyu16@huawei.com> - 9.2-1 +- upgrade GDB version to 9.2 + +* Wed Apr  8 2020 Yunfeng Ye<yeyunfeng@huawei.com> - 8.3.1-12 +- remove some useless information for cleancode + +* Wed Mar 11 2020 yuxiangyang<yuxiangyang4@huawei.com> - 8.3.1-11 +- backport upstream patch to fix hang in stop_all_stop + +* Mon Feb  3 2020 yuxiangyang<yuxiangyang4@huawei.com> - 8.3.1-10 +- fix CVE-2017-9778 + +* Thu Jan 16 2020 openEuler Buildteam <buildteam@openeuler.org> - 8.3.1-9 +- rpm upgrade successful, delete the dependence to librpm8 + +* Tue Jan 14 2020 openEuler Buildteam <buildteam@openeuler.org> - 8.3.1-8 +- add build requirement librpm8 + +* Wed Jan  8 2020 openEuler Buildteam <buildteam@openeuler.org> - 8.3.1-7 +- Upgrade GDB version to 8.3.1 + +* Tue Dec 24 2019 yuxiangyang<yuxiangyang4@huawei.com> - 8.2-6 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC: Modify the requirement about python2/3 when compilation rpm. + +* Thu Dec 19 2019 yeyunfeng<yeyunfeng@huawei.com> - 8.2-5 +- Type:cves +- ID:CVE-2017-9778 +- SUG:NA +- DESC: fix CVE-2017-9778 + +* Wed Sep 11 2019 openEuler Buildteam <buildteam@openeuler.org> - 8.2-4 +- Package init @@ -0,0 +1,9 @@ +# System-wide GDB initialization file. +python +import glob +# glob.iglob is not available in python-2.4 (RHEL-5). +for f in glob.glob('%{_sysconfdir}/gdbinit.d/*.gdb'): +  gdb.execute('source %s' % f) +for f in glob.glob('%{_sysconfdir}/gdbinit.d/*.py'): +  gdb.execute('source %s' % f) +end @@ -0,0 +1 @@ +4a084d03915b271f67e9b8ea2ab24972  gdb-14.1.tar.xz  | 
