summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2024-08-06 05:48:09 +0000
committerCoprDistGit <infra@openeuler.org>2024-08-06 05:48:09 +0000
commitab322c77aab87050c6ca0ce58e18f31e269e519b (patch)
tree7ff9c6a18efd867f35cb6f8fb08893c6b655376f
parent19677e130f0cd283f7884cc4b6b3d52f8812dae5 (diff)
automatic import of gdbopeneuler24.03_LTS
-rw-r--r--.gitignore1
-rw-r--r--0001-set-entry-point-when-text-segment-is-missing.patch30
-rw-r--r--gdb-6.3-attach-see-vdso-test.patch120
-rw-r--r--gdb-6.3-gstack-20050411.patch258
-rw-r--r--gdb-6.3-mapping-zero-inode-test.patch247
-rw-r--r--gdb-6.3-rh-testversion-20041202.patch34
-rw-r--r--gdb-6.5-BEA-testsuite.patch938
-rw-r--r--gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch265
-rw-r--r--gdb-6.5-bz218379-ppc-solib-trampoline-test.patch107
-rw-r--r--gdb-6.5-bz243845-stale-testing-zombie-test.patch89
-rw-r--r--gdb-6.5-gcore-buffer-limit-test.patch154
-rw-r--r--gdb-6.5-section-num-fixup-test.patch127
-rw-r--r--gdb-6.6-buildid-locate-misleading-warning-missing-debuginfo-rhbz981154.patch129
-rw-r--r--gdb-6.6-buildid-locate-rpm-librpm-workaround.patch19
-rw-r--r--gdb-6.6-buildid-locate-rpm.patch1084
-rw-r--r--gdb-6.6-buildid-locate-solib-missing-ids.patch238
-rw-r--r--gdb-6.6-buildid-locate.patch1925
-rw-r--r--gdb-6.6-bz229517-gcore-without-terminal.patch188
-rw-r--r--gdb-6.6-bz237572-ppc-atomic-sequence-test.patch278
-rw-r--r--gdb-6.6-testsuite-timeouts.patch32
-rw-r--r--gdb-6.7-ppc-clobbered-registers-O2-test.patch108
-rw-r--r--gdb-6.8-bz466901-backtrace-full-prelinked.patch481
-rw-r--r--gdb-add-index.patch77
-rw-r--r--gdb-archer-next-over-throw-cxx-exec.patch88
-rw-r--r--gdb-bz634108-solib_address.patch41
-rw-r--r--gdb-container-rh-pkg.patch30
-rw-r--r--gdb-core-open-vdso-warning.patch58
-rw-r--r--gdb-fedora-libncursesw.patch333
-rw-r--r--gdb-ftbs-swapped-calloc-args.patch42
-rw-r--r--gdb-glibc-strstr-workaround.patch132
-rw-r--r--gdb-gstack.man48
-rw-r--r--gdb-linux_perf-bundle.patch226
-rw-r--r--gdb-rhbz-2232086-cpp-ify-mapped-symtab.patch264
-rw-r--r--gdb-rhbz-2232086-generate-dwarf-5-index-consistently.patch101
-rw-r--r--gdb-rhbz-2232086-generate-gdb-index-consistently.patch230
-rw-r--r--gdb-rhbz-2232086-reduce-size-of-gdb-index.patch222
-rw-r--r--gdb-rhbz-818343-set-solib-absolute-prefix-testcase.patch83
-rw-r--r--gdb-rhbz1007614-memleak-infpy_read_memory-test.patch170
-rw-r--r--gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-3of3.patch235
-rw-r--r--gdb-rhbz1149205-catch-syscall-after-fork-test.patch123
-rw-r--r--gdb-rhbz1156192-recursive-dlopen-test.patch371
-rw-r--r--gdb-rhbz1261564-aarch64-hw-watchpoint-test.patch104
-rw-r--r--gdb-rhbz2232086-refactor-selftest-support.patch77
-rw-r--r--gdb-rhbz2250652-avoid-PyOS_ReadlineTState.patch48
-rw-r--r--gdb-rhbz2250652-gdbpy_gil.patch81
-rw-r--r--gdb-rhbz2257562-cp-namespace-null-ptr-check.patch113
-rw-r--r--gdb-rhbz947564-findvar-assertion-frame-failed-testcase.patch147
-rw-r--r--gdb-simultaneous-step-resume-breakpoint-test.patch162
-rw-r--r--gdb-test-bt-cfi-without-die.patch214
-rw-r--r--gdb-test-dw2-aranges.patch220
-rw-r--r--gdb.spec482
-rw-r--r--gdbinit9
-rw-r--r--sources1
53 files changed, 11384 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..67153d3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
diff --git a/gdbinit b/gdbinit
new file mode 100644
index 0000000..b59fb0d
--- /dev/null
+++ b/gdbinit
@@ -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
diff --git a/sources b/sources
new file mode 100644
index 0000000..bf6e129
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+4a084d03915b271f67e9b8ea2ab24972 gdb-14.1.tar.xz