import gdb-8.2-15.el8

This commit is contained in:
CentOS Sources 2021-05-18 02:49:14 -04:00 committed by Andrew Lukoshko
parent 2c3a1a6557
commit 0b0e7ac2d9
23 changed files with 3474 additions and 5 deletions

View File

@ -674,3 +674,80 @@ Patch164: gdb-rhbz1768593-s390x-arch13-03.patch
# Andreas Arnaz, RH BZ 1659535
Patch165: gdb-rhbz1659535-z15-record-replay.patch
# Fix terminal problems when error() is called
# Alan Hayward (RH BZ 1852580)
Patch166: gdb-rhbz1852580-terminal-woes.patch
# Remove hack for GDB which sets the section size to 0
# Kevin Buettner, RH BZ 1842691
Patch167: gdb-rhbz1842691-corefile-mem-access-1of15.patch
# Adjust corefile.exp test to show regression after bfd hack removal
# Kevin Buettner, RH BZ 1842691
Patch168: gdb-rhbz1842691-corefile-mem-access-2of15.patch
# section_table_xfer_memory: Replace section name with callback predicate
# Kevin Buettner, RH BZ 1842691
Patch169: gdb-rhbz1842691-corefile-mem-access-3of15.patch
# Provide access to non SEC_HAS_CONTENTS core file sections
# Kevin Buettner, RH BZ 1842961
Patch170: gdb-rhbz1842691-corefile-mem-access-4of15.patch
# Test ability to access unwritten-to mmap data in core file
# Kevin Buettner, RH BZ 1842961
Patch171: gdb-rhbz1842691-corefile-mem-access-5of15.patch
# Update binary_get_section_contents to seek using section's file position
# Kevin Buettner, RH BZ 1842961
Patch172: gdb-rhbz1842691-corefile-mem-access-6of15.patch
# Add new gdbarch method, read_core_file_mappings
# Kevin Buettner, RH BZ 1842961
Patch173: gdb-rhbz1842691-corefile-mem-access-7of15.patch
# Use NT_FILE note section for reading core target memory
# Kevin Buettner, RH BZ 1842961
Patch174: gdb-rhbz1842691-corefile-mem-access-8of15.patch
# Add test for accessing read-only mmapped data in a core file
# Kevin Buettner, RH BZ 1842691
Patch175: gdb-rhbz1842691-corefile-mem-access-9of15.patch
# gcore command: Place all file-backed mappings in NT_FILE note
# Kevin Buettner, RH BZ 1842961
Patch176: gdb-rhbz1842691-corefile-mem-access-10of15.patch
# Adjust coredump-filter.exp to account for NT_FILE note handling
# Kevin Buettner, RH BZ 1842961
Patch177: gdb-rhbz1842691-corefile-mem-access-11of15.patch
# Add new command "maint print core-file-backed-mappings"
# Kevin Buettner, RH BZ 1842961
Patch178: gdb-rhbz1842691-corefile-mem-access-12of15.patch
# Add documentation for "maint print core-file-backed-mappings"
# Kevin Buettner, RH BZ 1842961
Patch179: gdb-rhbz1842691-corefile-mem-access-13of15.patch
# New core file tests with mappings over existing program memory
# Kevin Buettner, RH BZ 1842961
Patch180: gdb-rhbz1842691-corefile-mem-access-14of15.patch
# Add period to help text for maint print core-file-backed-mappings
# Kevin Buettner, RH BZ 1842961
Patch181: gdb-rhbz1842691-corefile-mem-access-15of15.patch
# Backport "Stop the BFD library from issuing a warning message when
# processing allocated sections in debuginfo files that lie outside of
# Nick Clifton and Keith Seitz, RH BZ 1878810
Patch182: gdb-rhbz1878810-bfd-suppress-loadable-section-outside-ELF-sections.patch
# Backport "fortran dynamic type related fixes"
# Andrew Burgess (RH BZ 1905701)
Patch183: gdb-rhbz1905701-DWARF-data_location.patch
# Backport of "Correct recording of 'store on condition' insns"
# Andreas Arnaz (RH BZ 1903374)
Patch184: gdb-rhbz1903374-s390x-store-on-condition.patch

View File

@ -163,3 +163,22 @@
%patch163 -p1
%patch164 -p1
%patch165 -p1
%patch166 -p1
%patch167 -p1
%patch168 -p1
%patch169 -p1
%patch170 -p1
%patch171 -p1
%patch172 -p1
%patch173 -p1
%patch174 -p1
%patch175 -p1
%patch176 -p1
%patch177 -p1
%patch178 -p1
%patch179 -p1
%patch180 -p1
%patch181 -p1
%patch182 -p1
%patch183 -p1
%patch184 -p1

View File

@ -1,10 +1,14 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Tue, 12 May 2020 15:38:27 -0400
Subject: gdb-rhbz1659535-z15-record-replay.patch
;; Backport z15 record/replay
;; Andreas Arnaz, RH BZ 1659535
commit 6d9d6da48e84a65871a9d72fa785105d603990a6
Author: Andreas Arnez <arnez@linux.ibm.com>
Date: Wed Oct 9 11:09:22 2019 +0200
commit 6d9d6da48e84a65871a9d72fa785105d603990a6
Author: Andreas Arnez <arnez@linux.ibm.com>
Date: Wed Oct 9 11:09:22 2019 +0200
s390: Add record/replay support for arch13 instructions
Enable recording most of the new "arch13" instructions on z/Architecture

View File

@ -0,0 +1,114 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Mon, 27 Jul 2020 19:38:20 -0400
Subject: gdb-rhbz1842691-corefile-mem-access-10of15.patch
;; gcore command: Place all file-backed mappings in NT_FILE note
;; Kevin Buettner, RH BZ 1842961
Author: Kevin Buettner <kevinb@redhat.com>
Date: Wed Jul 1 06:34:50 2020 -0700
gcore command: Place all file-backed mappings in NT_FILE note
When making a core file with the GDB's gcore command on Linux,
the same criteria used for determining which mappings should be
dumped were also being used for determining which entries should
be placed in the NT_FILE note. This is wrong; we want to place
all file-backed mappings in this note.
The predicate function, dump_mapping_p, was used to determine whether
or not to dump a mapping from within linux_find_memory_regions_full.
This commit leaves this predicate in place, but adds a new parameter,
should_dump_mapping_p, to linux_find_memory_regions_full. It then
calls should_dump_mapping_p instead of dump_mapping_p. dump_mapping_p
is passed to linux_find_memory_regions_full at one call site; at the
other call site, dump_note_entry_p is passed instead.
gdb/ChangeLog:
* linux-tdep.c (dump_note_entry_p): New function.
(linux_dump_mapping_p_ftype): New typedef.
(linux_find_memory_regions_full): Add new parameter,
should_dump_mapping_p.
(linux_find_memory_regions): Adjust call to
linux_find_memory_regions_full.
(linux_make_mappings_core_file_notes): Use dump_note_entry_p in
call to linux_find_memory_regions_full.
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -710,6 +710,25 @@ dump_mapping_p (filter_flags filterflags, const struct smaps_vmflags *v,
}
}
+/* As above, but return true only when we should dump the NT_FILE
+ entry. */
+
+static int
+dump_note_entry_p (filter_flags filterflags, const struct smaps_vmflags *v,
+ int maybe_private_p, int mapping_anon_p, int mapping_file_p,
+ const char *filename)
+{
+ /* vDSO and vsyscall mappings will end up in the core file. Don't
+ put them in the NT_FILE note. */
+ if (strcmp ("[vdso]", filename) == 0
+ || strcmp ("[vsyscall]", filename) == 0)
+ return 0;
+
+ /* Otherwise, any other file-based mapping should be placed in the
+ note. */
+ return filename != nullptr;
+}
+
/* Implement the "info proc" command. */
static void
@@ -1224,10 +1243,18 @@ typedef int linux_find_memory_region_ftype (ULONGEST vaddr, ULONGEST size,
const char *filename,
void *data);
+typedef int linux_dump_mapping_p_ftype (filter_flags filterflags,
+ const struct smaps_vmflags *v,
+ int maybe_private_p,
+ int mapping_anon_p,
+ int mapping_file_p,
+ const char *filename);
+
/* List memory regions in the inferior for a corefile. */
static int
linux_find_memory_regions_full (struct gdbarch *gdbarch,
+ linux_dump_mapping_p_ftype *should_dump_mapping_p,
linux_find_memory_region_ftype *func,
void *obfd)
{
@@ -1378,7 +1405,7 @@ linux_find_memory_regions_full (struct gdbarch *gdbarch,
}
if (has_anonymous)
- should_dump_p = dump_mapping_p (filterflags, &v, priv,
+ should_dump_p = should_dump_mapping_p (filterflags, &v, priv,
mapping_anon_p, mapping_file_p,
filename);
else
@@ -1444,6 +1471,7 @@ linux_find_memory_regions (struct gdbarch *gdbarch,
data.obfd = obfd;
return linux_find_memory_regions_full (gdbarch,
+ dump_mapping_p,
linux_find_memory_regions_thunk,
&data);
}
@@ -1606,7 +1634,9 @@ linux_make_mappings_corefile_notes (struct gdbarch *gdbarch, bfd *obfd,
pack_long (buf, long_type, 1);
obstack_grow (&data_obstack, buf, TYPE_LENGTH (long_type));
- linux_find_memory_regions_full (gdbarch, linux_make_mappings_callback,
+ linux_find_memory_regions_full (gdbarch,
+ dump_note_entry_p,
+ linux_make_mappings_callback,
&mapping_data);
if (mapping_data.file_count != 0)

View File

@ -0,0 +1,87 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Tue, 28 Jul 2020 09:26:44 -0400
Subject: gdb-rhbz1842691-corefile-mem-access-11of15.patch
;; Adjust coredump-filter.exp to account for NT_FILE note handling
;; Kevin Buettner, RH BZ 1842961
Author: Kevin Buettner <kevinb@redhat.com>
Date: Fri Jul 3 20:10:22 2020 -0700
Adjust coredump-filter.exp to account for NT_FILE note handling
This commit makes adjustments to coredump-filter.exp to account
for the fact that NT_FILE file-backed mappings are now available
when a core file is loaded. Thus, a test which was expected
to PASS when a memory region was determined to be unavailable
(due to no file-backed mappings being available) will now FAIL
due to those mappings being available from having loaded the
NT_FILE note.
I had originally marked the test as XFAIL, but Mihails Strasuns
suggested a much better approach:
1) First test that it still works if file is accessible in the
filesystem.
2) Temporarily move / rename the file and test that disassembly
doesn't work anymore.
That's what this commit implements.
gdb/testsuite/ChangeLog:
* gdb.base/coredump-filter.exp: Add second
non-Private-Shared-Anon-File test.
(test_disasm): Rename binfile for test which is expected
to fail.
diff --git a/gdb/testsuite/gdb.base/coredump-filter.exp b/gdb/testsuite/gdb.base/coredump-filter.exp
--- a/gdb/testsuite/gdb.base/coredump-filter.exp
+++ b/gdb/testsuite/gdb.base/coredump-filter.exp
@@ -80,15 +80,26 @@ proc do_load_and_test_core { core var working_var working_value dump_excluded }
# disassemble of a function (i.e., the binary's .text section). GDB
# should fail in this case. However, it must succeed if the binary is
# provided along with the corefile. This is what we test here.
+#
+# A further complication is that Linux NT_FILE notes are now read from
+# the corefile. This note allows GDB to find the binary for file
+# backed mappings even though the binary wasn't loaded by GDB in the
+# conventional manner. In order to see the expected failure for this
+# case, we rename the binary in order to perform this test.
proc test_disasm { core address should_fail } {
- global testfile hex
+ global testfile hex binfile
# Restart GDB without loading the binary.
with_test_prefix "no binary" {
gdb_exit
gdb_start
+ set hide_binfile [standard_output_file "${testfile}.hide"]
+ if { $should_fail == 1 } {
+ remote_exec host "mv -f $binfile $hide_binfile"
+ }
+
set core_loaded [gdb_core_cmd "$core" "load core"]
if { $core_loaded == -1 } {
fail "loading $core"
@@ -96,6 +107,7 @@ proc test_disasm { core address should_fail } {
}
if { $should_fail == 1 } {
+ remote_exec host "mv -f $hide_binfile $binfile"
gdb_test "x/i \$pc" "=> $hex:\tCannot access memory at address $hex" \
"disassemble function with corefile and without a binary"
} else {
@@ -225,5 +237,9 @@ foreach item $all_anon_corefiles {
}
with_test_prefix "loading and testing corefile for non-Private-Shared-Anon-File" {
+ test_disasm $non_private_shared_anon_file_core $main_addr 0
+}
+
+with_test_prefix "loading and testing corefile for non-Private-Shared-Anon-File with renamed binary" {
test_disasm $non_private_shared_anon_file_core $main_addr 1
}

View File

@ -0,0 +1,169 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Tue, 28 Jul 2020 09:32:50 -0400
Subject: gdb-rhbz1842691-corefile-mem-access-12of15.patch
;; Add new command "maint print core-file-backed-mappings"
;; Kevin Buettner, RH BZ 1842961
Author: Kevin Buettner <kevinb@redhat.com>
Date: Fri Jul 3 21:55:51 2020 -0700
Add new command "maint print core-file-backed-mappings"
I wrote a read_core_file_mappings method for FreeBSD and then registered
this gdbarch method. I saw some strange behavior while testing it and
wanted a way to make sure that mappings were being correctly loaded
into corelow.c, so I wrote the new command which is the topic of this
commit. I think it might be occasionally useful for debugging strange
corefile behavior.
With regard to FreeBSD, my work isn't ready yet. Unlike Linux,
FreeBSD puts all mappings into its core file note. And, unlike Linux,
it doesn't dump load segments which occupy no space in the file. So
my (perhaps naive) implementation of a FreeBSD read_core_file_mappings
didn't work all that well: I saw more failures in the corefile2.exp
tests than without it. I think it should be possible to make FreeBSD
work as well as Linux, but it will require doing something with all of
the mappings, not just the file based mappings that I was considering.
In the v4 series, Pedro asked the following:
I don't understand what this command provides that "info proc
mappings" doesn't? Can you give an example of when you'd use this
command over "info proc mappings" ?
On Linux, "info proc mappings" and "maint print core-file-backed-mappings"
will produce similar, possibly identical, output. This need not be
the case for other OSes. E.g. on FreeBSD, had I finished the
implementation, the output from these commands would have been very
different. The FreeBSD "info proc mappings" command would show
additional (non-file-backed) mappings in addition to at least one
additional field (memory permissions) for each mapping.
As noted earlier, I was seeing some unexpected behavior while working
on the FreeBSD implementation and wanted to be certain that the
mappings were being correctly loaded by corelow.c. "info proc
mappings" prints the core file mappings, but doesn't tell us anything
about whether they've been loaded by corelow.c This new maintenance
command directly interrogates the data structures and prints the
values found there.
gdb/ChangeLog:
* corelow.c (gdbcmd.h): Include.
(core_target::info_proc_mappings): New method.
(get_current_core_target): New function.
(maintenance_print_core_file_backed_mappings): New function.
(_initialize_corelow): Add core-file-backed-mappings to
"maint print" commands.
diff --git a/gdb/corelow.c b/gdb/corelow.c
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -118,6 +118,9 @@ public:
const char *human_name,
bool required);
+ /* See definition. */
+ void info_proc_mappings (struct gdbarch *gdbarch);
+
private: /* per-core data */
/* The core's section table. Note that these target sections are
@@ -1292,6 +1295,86 @@ core_target::info_proc (const char *args, enum info_proc_what request)
return true;
}
+/* Get a pointer to the current core target. If not connected to a
+ core target, return NULL. */
+
+static core_target *
+get_current_core_target ()
+{
+ target_ops *proc_target = find_target_at (process_stratum);
+ return dynamic_cast<core_target *> (proc_target);
+}
+
+/* Display file backed mappings from core file. */
+
+void
+core_target::info_proc_mappings (struct gdbarch *gdbarch)
+{
+ if (m_core_file_mappings.sections != m_core_file_mappings.sections_end)
+ {
+ printf_filtered (_("Mapped address spaces:\n\n"));
+ if (gdbarch_addr_bit (gdbarch) == 32)
+ {
+ printf_filtered ("\t%10s %10s %10s %10s %s\n",
+ "Start Addr",
+ " End Addr",
+ " Size", " Offset", "objfile");
+ }
+ else
+ {
+ printf_filtered (" %18s %18s %10s %10s %s\n",
+ "Start Addr",
+ " End Addr",
+ " Size", " Offset", "objfile");
+ }
+ }
+
+ for (const struct target_section *tsp = m_core_file_mappings.sections;
+ tsp < m_core_file_mappings.sections_end;
+ tsp++)
+ {
+ ULONGEST start = tsp->addr;
+ ULONGEST end = tsp->endaddr;
+ ULONGEST file_ofs = tsp->the_bfd_section->filepos;
+ const char *filename = bfd_get_filename (tsp->the_bfd_section->owner);
+
+ if (gdbarch_addr_bit (gdbarch) == 32)
+ printf_filtered ("\t%10s %10s %10s %10s %s\n",
+ paddress (gdbarch, start),
+ paddress (gdbarch, end),
+ hex_string (end - start),
+ hex_string (file_ofs),
+ filename);
+ else
+ printf_filtered (" %18s %18s %10s %10s %s\n",
+ paddress (gdbarch, start),
+ paddress (gdbarch, end),
+ hex_string (end - start),
+ hex_string (file_ofs),
+ filename);
+ }
+}
+
+/* Implement "maintenance print core-file-backed-mappings" command.
+
+ If mappings are loaded, the results should be similar to the
+ mappings shown by "info proc mappings". This command is mainly a
+ debugging tool for GDB developers to make sure that the expected
+ mappings are present after loading a core file. For Linux, the
+ output provided by this command will be very similar (if not
+ identical) to that provided by "info proc mappings". This is not
+ necessarily the case for other OSes which might provide
+ more/different information in the "info proc mappings" output. */
+
+static void
+maintenance_print_core_file_backed_mappings (const char *args, int from_tty)
+{
+ core_target *targ = get_current_core_target ();
+ if (targ != nullptr)
+ targ->info_proc_mappings (targ->core_gdbarch ());
+}
+
+void _initialize_corelow ();
void
_initialize_corelow (void)
{
@@ -1303,4 +1386,8 @@ Set whether CORE-FILE loads the build-id associated files automatically."), _("\
Show whether CORE-FILE loads the build-id associated files automatically."),
NULL, NULL, NULL,
&setlist, &showlist);
+ add_cmd ("core-file-backed-mappings", class_maintenance,
+ maintenance_print_core_file_backed_mappings,
+ _("Print core file's file-backed mappings"),
+ &maintenanceprintlist);
}

View File

@ -0,0 +1,41 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Tue, 28 Jul 2020 09:44:04 -0400
Subject: gdb-rhbz1842691-corefile-mem-access-13of15.patch
;; Add documentation for "maint print core-file-backed-mappings"
;; Kevin Buettner, RH BZ 1842961
Author: Kevin Buettner <kevinb@redhat.com>
Date: Fri Jul 3 22:09:20 2020 -0700
Add documentation for "maint print core-file-backed-mappings"
gdb/ChangeLog:
* NEWS (New commands): Mention new command
"maintenance print core-file-backed-mappings".
gdb/doc/ChangeLog:
* gdb.texinfo (Maintenance Commands): Add documentation for
new command "maintenance print core-file-backed-mappings".
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -35633,6 +35633,14 @@ library. This exercises all @code{libthread_db} functionality used by
@code{libthread_db} uses. Note that parts of the test may be skipped
on some platforms when debugging core files.
+@kindex maint print core-file-backed-mappings
+@cindex memory address space mappings
+@item maint print core-file-backed-mappings
+Print the file-backed mappings which were loaded from a core file note.
+This output represents state internal to @value{GDBN} and should be
+similar to the mappings displayed by the @code{info proc mappings}
+command.
+
@kindex maint print dummy-frames
@item maint print dummy-frames
Prints the contents of @value{GDBN}'s internal dummy-frame stack.

View File

@ -0,0 +1,439 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Tue, 28 Jul 2020 09:46:44 -0400
Subject: gdb-rhbz1842691-corefile-mem-access-14of15.patch
;; New core file tests with mappings over existing program memory
;; Kevin Buettner, RH BZ 1842961
Author: Kevin Buettner <kevinb@redhat.com>
Date: Wed Jun 17 19:25:47 2020 -0700
New core file tests with mappings over existing program memory
This test case was inspired by Pedro's demonstration of a problem
with my v2 patches. It can be found here:
https://sourceware.org/pipermail/gdb-patches/2020-May/168826.html
In a nutshell, my earlier patches could not handle the case in
which a read-only mapping created with mmap() was created at
an address used by other file-backed read-only memory in use by
the process.
This problem has been fixed (for Linux, anyway) by the commit "Use
NT_FILE note section for reading core target memory".
When I run this test without any of my recent corefile patches,
I see these failures:
FAIL: gdb.base/corefile2.exp: kernel core: print/x mbuf_ro[0]@4
FAIL: gdb.base/corefile2.exp: kernel core: print/x mbuf_ro[pagesize-4]@4
FAIL: gdb.base/corefile2.exp: kernel core: print/x mbuf_ro[-3]@6
FAIL: gdb.base/corefile2.exp: kernel core: print/x mbuf_rw[pagesize-3]@6
FAIL: gdb.base/corefile2.exp: kernel core: print/x mbuf_ro[pagesize-3]@6
FAIL: gdb.base/corefile2.exp: maint print core-file-backed-mappings
FAIL: gdb.base/corefile2.exp: gcore core: print/x mbuf_ro[-3]@6
The ones involving mbuf_ro will almost certainly fail when run on
non-Linux systems; I've used setup_xfail on those tests to prevent
them from outright FAILing when not run on Linux. For a time, I
had considered skipping these tests altogether when not run on
Linux, but I changed my mind due to this failure...
FAIL: gdb.base/corefile2.exp: print/x mbuf_rw[pagesize-3]@6
I think it *should* pass without my recent corefile patches. The fact
that it doesn't is likely due to a bug in GDB. The following
interaction with GDB demonstrates the problem:
(gdb) print/x mbuf_rw[pagesize-3]@6
$1 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
(gdb) print/x mbuf_rw[pagesize]@3
$2 = {0x6b, 0x6b, 0x6b}
The last three values in display of $1 should be the same as those
shown by $2. Like this...
(gdb) print/x mbuf_rw[pagesize-3]@6
$1 = {0x0, 0x0, 0x0, 0x6b, 0x6b, 0x6b}
(gdb) print/x mbuf_rw[pagesize]@3
$2 = {0x6b, 0x6b, 0x6b}
That latter output was obtained with the use of all of my current
corefile patches. I see no failures on Linux when running this test
with my current set of corefile patches. I tested 3 architectures:
x86_64, s390x, and aarch64.
I also tested on FreeBSD 12.1-RELEASE. I see the following results
both with and without the current set of core file patches:
# of expected passes 26
# of expected failures 8
Of particular interest is that I did *not* see the problematic mbuf_rw
failure noted earlier (both with and without the core file patches).
I still don't have an explanation for why this failure occurred on
Linux. Prior to running the tests, I had hypothesized that I'd see
this failure on FreeBSD too, but testing shows that this is not the
case.
Also of importance is that we see no FAILs with this test on FreeBSD
which indicates that I XFAILed the correct tests.
This version runs the interesting tests twice, once with a kernel
created core file and another time with a gcore created core file.
It also does a very minimal test of the new command "maint print
core-file-backed-mappings".
gdb/testsuite/ChangeLog:
* gdb.base/corefile2.exp: New file.
* gdb.base/coremaker2.exp: New file.
diff --git a/gdb/testsuite/gdb.base/corefile2.exp b/gdb/testsuite/gdb.base/corefile2.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/corefile2.exp
@@ -0,0 +1,185 @@
+# Copyright 2020 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Tests of core file memory accesses when mmap() has been used to
+# create a "hole" of zeroes over pre-existing memory regions. See
+# coremaker2.c for details.
+
+# are we on a target board
+if ![isnative] then {
+ return
+}
+
+# Some of these tests will only work on GNU/Linux due to the
+# fact that Linux core files includes a section describing
+# memory address to file mappings. We'll use set_up_xfail for the
+# affected tests. As other targets become supported, the condition
+# can be changed accordingly.
+
+set xfail 0
+if { ![istarget *-linux*] } {
+ set xfail 1
+}
+
+standard_testfile coremaker2.c
+
+if {[build_executable $testfile.exp $testfile $srcfile debug] == -1} {
+ untested "failed to compile"
+ return -1
+}
+
+set corefile [core_find $binfile {}]
+if {$corefile == ""} {
+ return 0
+}
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Attempt to load the core file.
+
+gdb_test_multiple "core-file $corefile" "core-file command" {
+ -re ".* program is being debugged already.*y or n. $" {
+ # gdb_load may connect us to a gdbserver.
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re "Core was generated by .*corefile.*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" {
+ pass "core-file command"
+ }
+ -re "Core was generated by .*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" {
+ pass "core-file command (with bad program name)"
+ }
+ -re ".*registers from core file: File in wrong format.* $" {
+ fail "core-file command (could not read registers from core file)"
+ }
+}
+
+# Perform the "interesting" tests which check the contents of certain
+# memory regions.
+
+proc do_tests { } {
+ global xfail
+
+ # Check contents of beginning of buf_rw and buf_ro.
+
+ gdb_test {print/x buf_rw[0]@4} {\{0x6b, 0x6b, 0x6b, 0x6b\}}
+ gdb_test {print/x buf_ro[0]@4} {\{0xc5, 0xc5, 0xc5, 0xc5\}}
+
+ # Check for correct contents at beginning of mbuf_rw and mbuf_ro.
+
+ gdb_test {print/x mbuf_rw[0]@4} {\{0x0, 0x0, 0x0, 0x0\}}
+
+ if { $xfail } { setup_xfail "*-*-*" }
+ gdb_test {print/x mbuf_ro[0]@4} {\{0x0, 0x0, 0x0, 0x0\}}
+
+ # Check contents of mbuf_rw and mbuf_ro at the end of these regions.
+
+ gdb_test {print/x mbuf_rw[pagesize-4]@4} {\{0x0, 0x0, 0x0, 0x0\}}
+
+ if { $xfail } { setup_xfail "*-*-*" }
+ gdb_test {print/x mbuf_ro[pagesize-4]@4} {\{0x0, 0x0, 0x0, 0x0\}}
+
+ # Check contents of mbuf_rw and mbuf_ro, right before the hole,
+ # overlapping into the beginning of these mmap'd regions.
+
+ gdb_test {print/x mbuf_rw[-3]@6} {\{0x6b, 0x6b, 0x6b, 0x0, 0x0, 0x0\}}
+
+ if { $xfail } { setup_xfail "*-*-*" }
+ gdb_test {print/x mbuf_ro[-3]@6} {\{0xc5, 0xc5, 0xc5, 0x0, 0x0, 0x0\}}
+
+ # Likewise, at the end of the mbuf_rw and mbuf_ro, with overlap.
+
+ # If this test FAILs, it's probably a genuine bug unrelated to whether
+ # the core file includes a section describing memory address to file
+ # mappings or not. (So don't xfail it!)
+ gdb_test {print/x mbuf_rw[pagesize-3]@6} {\{0x0, 0x0, 0x0, 0x6b, 0x6b, 0x6b\}}
+
+ if { $xfail } { setup_xfail "*-*-*" }
+ gdb_test {print/x mbuf_ro[pagesize-3]@6} {\{0x0, 0x0, 0x0, 0xc5, 0xc5, 0xc5\}}
+
+ # Check contents of (what should be) buf_rw and buf_ro immediately after
+ # mbuf_rw and mbuf_ro holes.
+
+ gdb_test {print/x mbuf_rw[pagesize]@4} {\{0x6b, 0x6b, 0x6b, 0x6b\}}
+ gdb_test {print/x mbuf_ro[pagesize]@4} {\{0xc5, 0xc5, 0xc5, 0xc5\}}
+
+ # Check contents at ends of buf_rw and buf_rw.
+
+ gdb_test {print/x buf_rw[sizeof(buf_rw)-4]@4} {\{0x6b, 0x6b, 0x6b, 0x6b\}}
+ gdb_test {print/x buf_ro[sizeof(buf_ro)-4]@4} {\{0xc5, 0xc5, 0xc5, 0xc5\}}
+}
+
+# Run tests with kernel-produced core file.
+
+with_test_prefix "kernel core" {
+ do_tests
+}
+
+# Verify that "maint print core-file-backed-mappings" exists and does
+# not crash GDB. If it produces any output at all, make sure that
+# that output at least mentions binfile.
+
+set test "maint print core-file-backed-mappings"
+gdb_test_multiple $test "" {
+ -re ".*$binfile.*$gdb_prompt $" {
+ pass $test
+ }
+ -re "^$test\[\r\n\]*$gdb_prompt $" {
+ pass "$test (no output)"
+ }
+}
+
+# Restart and run to the abort call.
+
+clean_restart $binfile
+
+if ![runto_main] then {
+ fail "can't run to main"
+ return
+}
+
+gdb_breakpoint [gdb_get_line_number "abort"]
+gdb_continue_to_breakpoint "at abort"
+
+# Do not execute abort call; instead, invoke gcore command to make a
+# gdb-produced core file.
+
+set corefile [standard_output_file gcore.test]
+set core_supported [gdb_gcore_cmd "$corefile" "save a corefile"]
+if {!$core_supported} {
+ return
+}
+
+# maint print-core-file-backed-mappings shouldn't produce any output
+# when not debugging a core file.
+
+gdb_test_no_output "maint print core-file-backed-mappings" \
+ "maint print core-file-backed-mapping with no core file"
+
+clean_restart $binfile
+
+set core_loaded [gdb_core_cmd "$corefile" "re-load generated corefile"]
+if { $core_loaded == -1 } {
+ # No use proceeding from here.
+ return
+}
+
+# Run tests using gcore-produced core file.
+
+with_test_prefix "gcore core" {
+ do_tests
+}
diff --git a/gdb/testsuite/gdb.base/coremaker2.c b/gdb/testsuite/gdb.base/coremaker2.c
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/coremaker2.c
@@ -0,0 +1,150 @@
+/* Copyright 1992-2020 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* This test has two large memory areas buf_rw and buf_ro.
+
+ buf_rw is written to by the program while buf_ro is initialized at
+ compile / load time. Thus, when a core file is created, buf_rw's
+ memory should reside in the core file, but buf_ro probably won't be.
+ Instead, the contents of buf_ro are available from the executable.
+
+ Now, for the wrinkle: We create a one page read-only mapping over
+ both of these areas. This will create a one page "hole" of all
+ zeros in each area.
+
+ Will GDB be able to correctly read memory from each of the four
+ (or six, if you count the regions on the other side of each hole)
+ memory regions? */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+/* These are globals so that we can find them easily when debugging
+ the core file. */
+long pagesize;
+unsigned long long addr;
+char *mbuf_ro;
+char *mbuf_rw;
+
+/* 24 KiB buffer. */
+char buf_rw[24 * 1024];
+
+/* 24 KiB worth of data. For this test case, we can't allocate a
+ buffer and then fill it; we want GDB to have to read this data
+ from the executable; it should NOT find it in the core file. */
+
+#define C5_16 \
+ 0xc5, 0xc5, 0xc5, 0xc5, \
+ 0xc5, 0xc5, 0xc5, 0xc5, \
+ 0xc5, 0xc5, 0xc5, 0xc5, \
+ 0xc5, 0xc5, 0xc5, 0xc5
+
+#define C5_256 \
+ C5_16, C5_16, C5_16, C5_16, \
+ C5_16, C5_16, C5_16, C5_16, \
+ C5_16, C5_16, C5_16, C5_16, \
+ C5_16, C5_16, C5_16, C5_16
+
+#define C5_1k \
+ C5_256, C5_256, C5_256, C5_256
+
+#define C5_24k \
+ C5_1k, C5_1k, C5_1k, C5_1k, \
+ C5_1k, C5_1k, C5_1k, C5_1k, \
+ C5_1k, C5_1k, C5_1k, C5_1k, \
+ C5_1k, C5_1k, C5_1k, C5_1k, \
+ C5_1k, C5_1k, C5_1k, C5_1k, \
+ C5_1k, C5_1k, C5_1k, C5_1k
+
+const char buf_ro[] = { C5_24k };
+
+int
+main (int argc, char **argv)
+{
+ int i, bitcount;
+
+#ifdef _SC_PAGESIZE
+ pagesize = sysconf (_SC_PAGESIZE);
+#else
+ pagesize = 8192;
+#endif
+
+ /* Verify that pagesize is a power of 2. */
+ bitcount = 0;
+ for (i = 0; i < 4 * sizeof (pagesize); i++)
+ if (pagesize & (1 << i))
+ bitcount++;
+
+ if (bitcount != 1)
+ {
+ fprintf (stderr, "pagesize is not a power of 2.\n");
+ exit (1);
+ }
+
+ /* Compute an address that should be within buf_ro. Complain if not. */
+ addr = ((unsigned long long) buf_ro + pagesize) & ~(pagesize - 1);
+
+ if (addr <= (unsigned long long) buf_ro
+ || addr >= (unsigned long long) buf_ro + sizeof (buf_ro))
+ {
+ fprintf (stderr, "Unable to compute a suitable address within buf_ro.\n");
+ exit (1);
+ }
+
+ mbuf_ro = mmap ((void *) addr, pagesize, PROT_READ,
+ MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
+
+ if (mbuf_ro == MAP_FAILED)
+ {
+ fprintf (stderr, "mmap #1 failed: %s.\n", strerror (errno));
+ exit (1);
+ }
+
+ /* Write (and fill) the R/W region. */
+ for (i = 0; i < sizeof (buf_rw); i++)
+ buf_rw[i] = 0x6b;
+
+ /* Compute an mmap address within buf_rw. Complain if it's somewhere
+ else. */
+ addr = ((unsigned long long) buf_rw + pagesize) & ~(pagesize - 1);
+
+ if (addr <= (unsigned long long) buf_rw
+ || addr >= (unsigned long long) buf_rw + sizeof (buf_rw))
+ {
+ fprintf (stderr, "Unable to compute a suitable address within buf_rw.\n");
+ exit (1);
+ }
+
+ mbuf_rw = mmap ((void *) addr, pagesize, PROT_READ,
+ MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
+
+ if (mbuf_rw == MAP_FAILED)
+ {
+ fprintf (stderr, "mmap #2 failed: %s.\n", strerror (errno));
+ exit (1);
+ }
+
+ /* With correct ulimit, etc. this should cause a core dump. */
+ abort ();
+}

View File

@ -0,0 +1,30 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Tue, 28 Jul 2020 09:49:56 -0400
Subject: gdb-rhbz1842691-corefile-mem-access-15of15.patch
;; Add period to help text for maint print core-file-backed-mappings
;; Kevin Buettner, RH BZ 1842961
Author: Kevin Buettner <kevinb@redhat.com>
Date: Thu Jul 23 13:26:44 2020 -0700
Fix BZ 26294 - Add period to help text for maint print core-file-backed-mappings
gdb/ChangeLog:
PR corefiles/26294
* corelow.c (_initialize_corelow): Add period to help text
for "maintenance print core-file-backed-mappings".
diff --git a/gdb/corelow.c b/gdb/corelow.c
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -1388,6 +1388,6 @@ Show whether CORE-FILE loads the build-id associated files automatically."),
&setlist, &showlist);
add_cmd ("core-file-backed-mappings", class_maintenance,
maintenance_print_core_file_backed_mappings,
- _("Print core file's file-backed mappings"),
+ _("Print core file's file-backed mappings."),
&maintenanceprintlist);
}

View File

@ -0,0 +1,60 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Mon, 27 Jul 2020 16:34:37 -0400
Subject: gdb-rhbz1842691-corefile-mem-access-1of15.patch
;; Remove hack for GDB which sets the section size to 0
;; Kevin Buettner, RH BZ 1842691
Author: Kevin Buettner <kevinb@redhat.com>
Remove hack for GDB which sets the section size to 0
This commit removes a hack for GDB which was introduced in 2007.
See:
https://sourceware.org/ml/binutils/2007-08/msg00044.html
That hack mostly allowed GDB's handling of core files to continue to
work without any changes to GDB.
The problem with setting the section size to zero is that GDB won't
know how big that section is/was. Often, this doesn't matter because
the data in question are found in the exec file. But it can happen
that the section describes memory that had been allocated, but never
written to. In this instance, the contents of that memory region are
not written to the core file. Also, since the region in question was
dynamically allocated, it won't appear in the exec file. We don't
want these regions to appear as inaccessible to GDB (since they *were*
accessible when the process was live), so it's important that GDB know
the size of the region.
I've made changes to GDB which correctly handles this case. When
attempting to access memory, GDB will first consider core file data
for which both SEC_ALLOC and SEC_HAS_CONTENTS is set. Next, if that
fails, GDB will attempt to find the data in the exec file. Finally,
if that also fails, GDB will attempt to access memory in the sections
which are flagged as SEC_ALLOC, but not SEC_HAS_CONTENTS.
bfd/ChangeLog:
* elf.c (_bfd_elf_make_section_from_phdr): Remove hack for GDB.
diff --git a/bfd/elf.c b/bfd/elf.c
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -2975,14 +2975,6 @@ _bfd_elf_make_section_from_phdr (bfd *abfd,
newsect->alignment_power = bfd_log2 (align);
if (hdr->p_type == PT_LOAD)
{
- /* Hack for gdb. Segments that have not been modified do
- not have their contents written to a core file, on the
- assumption that a debugger can find the contents in the
- executable. We flag this case by setting the fake
- section size to zero. Note that "real" bss sections will
- always have their contents dumped to the core file. */
- if (bfd_get_format (abfd) == bfd_core)
- newsect->size = 0;
newsect->flags |= SEC_ALLOC;
if (hdr->p_flags & PF_X)
newsect->flags |= SEC_CODE;

View File

@ -0,0 +1,129 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Mon, 27 Jul 2020 16:47:19 -0400
Subject: gdb-rhbz1842691-corefile-mem-access-2of15.patch
;; Adjust corefile.exp test to show regression after bfd hack removal
;; Kevin Buettner, RH BZ 1842691
Author: Kevin Buettner <kevinb@redhat.com>
Date: Tue May 12 17:44:19 2020 -0700
Adjust corefile.exp test to show regression after bfd hack removal
In his review of my BZ 25631 patch series, Pedro was unable to
reproduce the regression which should occur after patch #1, "Remove
hack for GDB which sets the section size to 0", is applied.
Pedro was using an ld version older than 2.30. Version 2.30
introduced the linker option -z separate-code. Here's what the man
page has to say about it:
Create separate code "PT_LOAD" segment header in the object. This
specifies a memory segment that should contain only instructions
and must be in wholly disjoint pages from any other data.
In ld version 2.31, use of separate-code became the default for
Linux/x86. So, really, 2.31 or later is required in order to see the
regression that occurs in recent Linux distributions when only the
bfd hack removal patch is applied.
For the test case in question, use of the separate-code linker option
means that the global variable "coremaker_ro" ends up in a separate
load segment (though potentially with other read-only data). The
upshot of this is that when only patch #1 is applied, GDB won't be
able to correctly access coremaker_ro. The reason for this is due
to the fact that this section will now have a non-zero size, but
will not have contents from the core file to find this data.
So GDB will ask BFD for the contents and BFD will respond with
zeroes for anything from those sections. GDB should instead be
looking in the executable for this data. Failing that, it can
then ask BFD for a reasonable value. This is what a later patch
in this series does.
When using ld versions earlier than 2.31 (or 2.30 w/ the
-z separate-code option explicitly provided to the linker), there is
the possibility that coremaker_ro ends up being placed near other data
which is recorded in the core file. That means that the correct value
will end up in the core file, simply because it resides on a page that
the kernel chooses to put in the core file. This is why Pedro wasn't
able to reproduce the regression that should occur after fixing the
BFD hack.
This patch places a big chunk of memory, two pages worth on x86, in
front of "coremaker_ro" to attempt to force it onto another page
without requiring use of that new-fangled linker switch.
Speaking of which, I considered changing the test to use
-z separate-code, but this won't work because it didn't
exist prior to version 2.30. The linker would probably complain
of an unrecognized switch. Also, it likely won't be available in
other linkers not based on current binutils. I.e. it probably won't
work in FreeBSD, NetBSD, etc.
To make this more concrete, this is what *should* happen when
attempting to access coremaker_ro when only patch #1 is applied:
Core was generated by `/mesquite2/sourceware-git/f28-coresegs/bld/gdb/testsuite/outputs/gdb.base/coref'.
Program terminated with signal SIGABRT, Aborted.
#0 0x00007f68205deefb in raise () from /lib64/libc.so.6
(gdb) p coremaker_ro
$1 = 0
Note that this result is wrong; 201 should have been printed instead.
But that's the point of the rest of the patch series.
However, without this commit, or when using an old Linux distro with
a pre-2.31 ld, this is what you might see instead:
Core was generated by `/mesquite2/sourceware-git/f28-coresegs/bld/gdb/testsuite/outputs/gdb.base/coref'.
Program terminated with signal SIGABRT, Aborted.
#0 0x00007f63dd658efb in raise () from /lib64/libc.so.6
(gdb) p coremaker_ro
$1 = 201
I.e. it prints the right answer, which sort of makes it seem like the
rest of the series isn't required.
Now, back to the patch itself... what should be the size of the memory
chunk placed before coremaker_ro?
It needs to be at least as big as the page size (PAGE_SIZE) from
the kernel. For x86 and several other architectures this value is
4096. I used MAPSIZE which is defined to be 8192 in coremaker.c.
So it's twice as big as what's currently needed for most Linux
architectures. The constant PAGE_SIZE is available from <sys/user.h>,
but this isn't portable either. In the end, it seemed simpler to
just pick a value and hope that it's big enough. (Running a separate
program which finds the page size via sysconf(_SC_PAGESIZE) and then
passes it to the compilation via a -D switch seemed like overkill
for a case which is rendered moot by recent linker versions.)
Further information can be found here:
https://sourceware.org/pipermail/gdb-patches/2020-May/168168.html
https://sourceware.org/pipermail/gdb-patches/2020-May/168170.html
Thanks to H.J. Lu for telling me about the '-z separate-code' linker
switch.
gdb/testsuite/ChangeLog:
* gdb.base/coremaker.c (filler_ro): New global constant.
diff --git a/gdb/testsuite/gdb.base/coremaker.c b/gdb/testsuite/gdb.base/coremaker.c
--- a/gdb/testsuite/gdb.base/coremaker.c
+++ b/gdb/testsuite/gdb.base/coremaker.c
@@ -42,6 +42,12 @@ char *buf2;
int coremaker_data = 1; /* In Data section */
int coremaker_bss; /* In BSS section */
+/* Place a chunk of memory before coremaker_ro to improve the chances
+ that coremaker_ro will end up on it's own page. See:
+
+ https://sourceware.org/pipermail/gdb-patches/2020-May/168168.html
+ https://sourceware.org/pipermail/gdb-patches/2020-May/168170.html */
+const unsigned char filler_ro[MAPSIZE] = {1, 2, 3, 4, 5, 6, 7, 8};
const int coremaker_ro = 201; /* In Read-Only Data section */
/* Note that if the mapping fails for any reason, we set buf2

View File

@ -0,0 +1,174 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Mon, 27 Jul 2020 16:52:18 -0400
Subject: gdb-rhbz1842691-corefile-mem-access-3of15.patch
;; section_table_xfer_memory: Replace section name with callback predicate
;; Kevin Buettner, RH BZ 1842691
Author: Kevin Buettner <kevinb@redhat.com>
Date: Wed Mar 4 17:42:41 2020 -0700
section_table_xfer_memory: Replace section name with callback predicate
This patch is motivated by the need to be able to select sections
that section_table_xfer_memory_partial should consider for memory
transfers. I'll use this facility in the next patch in this series.
section_table_xfer_memory_partial() can currently be passed a section
name which may be used to make name-based selections. This is similar
to what I want to do, except that I want to be able to consider
section flags instead of the name.
I'm replacing the section name parameter with a predicate that,
when passed a pointer to a target_section struct, will return
true if that section should be further considered, or false which
indicates that it shouldn't.
I've converted the one existing use where a non-NULL section
name is passed to section_table_xfer_memory_partial(). Instead
of passing the section name, it now looks like this:
auto match_cb = [=] (const struct target_section *s)
{
return (strcmp (section_name, s->the_bfd_section->name) == 0);
};
return section_table_xfer_memory_partial (readbuf, writebuf,
memaddr, len, xfered_len,
table->sections,
table->sections_end,
match_cb);
The other callers all passed NULL; they've been simplified somewhat
in that they no longer need to pass NULL.
gdb/ChangeLog:
* exec.h (section_table_xfer_memory): Revise declaration,
replacing section name parameter with an optional callback
predicate.
* exec.c (section_table_xfer_memory): Likewise.
* bfd-target.c, exec.c, target.c, corelow.c: Adjust all callers
of section_table_xfer_memory.
diff --git a/gdb/bfd-target.c b/gdb/bfd-target.c
--- a/gdb/bfd-target.c
+++ b/gdb/bfd-target.c
@@ -75,8 +75,7 @@ target_bfd::xfer_partial (target_object object,
return section_table_xfer_memory_partial (readbuf, writebuf,
offset, len, xfered_len,
m_table.sections,
- m_table.sections_end,
- NULL);
+ m_table.sections_end);
}
default:
return TARGET_XFER_E_IO;
diff --git a/gdb/corelow.c b/gdb/corelow.c
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -820,8 +820,7 @@ core_target::xfer_partial (enum target_object object, const char *annex,
(readbuf, writebuf,
offset, len, xfered_len,
m_core_section_table.sections,
- m_core_section_table.sections_end,
- NULL));
+ m_core_section_table.sections_end));
case TARGET_OBJECT_AUXV:
if (readbuf)
diff --git a/gdb/exec.c b/gdb/exec.c
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -805,7 +805,8 @@ section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
ULONGEST *xfered_len,
struct target_section *sections,
struct target_section *sections_end,
- const char *section_name)
+ gdb::function_view<bool
+ (const struct target_section *)> match_cb)
{
int res;
struct target_section *p;
@@ -821,7 +822,7 @@ section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
struct bfd_section *asect = p->the_bfd_section;
bfd *abfd = asect->owner;
- if (section_name && strcmp (section_name, asect->name) != 0)
+ if (match_cb != nullptr && !match_cb (p))
continue; /* not the section we need. */
if (memaddr >= p->addr)
{
@@ -894,8 +895,7 @@ exec_target::xfer_partial (enum target_object object,
return section_table_xfer_memory_partial (readbuf, writebuf,
offset, len, xfered_len,
table->sections,
- table->sections_end,
- NULL);
+ table->sections_end);
else
return TARGET_XFER_E_IO;
}
diff --git a/gdb/exec.h b/gdb/exec.h
--- a/gdb/exec.h
+++ b/gdb/exec.h
@@ -58,8 +58,13 @@ extern enum target_xfer_status
Request to transfer up to LEN 8-bit bytes of the target sections
defined by SECTIONS and SECTIONS_END. The OFFSET specifies the
starting address.
- If SECTION_NAME is not NULL, only access sections with that same
- name.
+
+ The MATCH_CB predicate is optional; when provided it will be called
+ for each section under consideration. When MATCH_CB evaluates as
+ true, the section remains under consideration; a false result
+ removes it from consideration for performing the memory transfers
+ noted above. See memory_xfer_partial_1() in target.c for an
+ example.
Return the number of bytes actually transfered, or zero when no
data is available for the requested range.
@@ -76,7 +81,9 @@ extern enum target_xfer_status
ULONGEST, ULONGEST, ULONGEST *,
struct target_section *,
struct target_section *,
- const char *);
+ gdb::function_view<bool
+ (const struct target_section *)> match_cb
+ = nullptr);
/* Read from mappable read-only sections of BFD executable files.
Similar to exec_read_partial_read_only, but return
diff --git a/gdb/target.c b/gdb/target.c
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -1098,11 +1098,17 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
const char *section_name = section->the_bfd_section->name;
memaddr = overlay_mapped_address (memaddr, section);
+
+ auto match_cb = [=] (const struct target_section *s)
+ {
+ return (strcmp (section_name, s->the_bfd_section->name) == 0);
+ };
+
return section_table_xfer_memory_partial (readbuf, writebuf,
memaddr, len, xfered_len,
table->sections,
table->sections_end,
- section_name);
+ match_cb);
}
}
@@ -1122,8 +1128,7 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
return section_table_xfer_memory_partial (readbuf, writebuf,
memaddr, len, xfered_len,
table->sections,
- table->sections_end,
- NULL);
+ table->sections_end);
}
}

View File

@ -0,0 +1,227 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Mon, 27 Jul 2020 17:11:49 -0400
Subject: gdb-rhbz1842691-corefile-mem-access-4of15.patch
;; Provide access to non SEC_HAS_CONTENTS core file sections
;; Kevin Buettner, RH BZ 1842961
Author: Kevin Buettner <kevinb@redhat.com>
Date: Wed Mar 4 17:42:42 2020 -0700
Provide access to non SEC_HAS_CONTENTS core file sections
Consider the following program:
- - - mkmmapcore.c - - -
static char *buf;
int
main (int argc, char **argv)
{
buf = mmap (NULL, 8192, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
abort ();
}
- - - end mkmmapcore.c - - -
Compile it like this:
gcc -g -o mkmmapcore mkmmapcore.c
Now let's run it from GDB. I've already placed a breakpoint on the
line with the abort() call and have run to that breakpoint.
Breakpoint 1, main (argc=1, argv=0x7fffffffd678) at mkmmapcore.c:11
11 abort ();
(gdb) x/x buf
0x7ffff7fcb000: 0x00000000
Note that we can examine the memory allocated via the call to mmap().
Now let's try debugging a core file created by running this program.
Depending on your system, in order to make a core file, you may have to
run the following as root (or using sudo):
echo core > /proc/sys/kernel/core_pattern
It may also be necessary to do:
ulimit -c unlimited
I'm using Fedora 31. YMMV if you're using one of the BSDs or some other
(non-Linux) system.
This is what things look like when we debug the core file:
[kev@f31-1 tmp]$ gdb -q ./mkmmapcore core.304767
Reading symbols from ./mkmmapcore...
[New LWP 304767]
Core was generated by `/tmp/mkmmapcore'.
Program terminated with signal SIGABRT, Aborted.
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 return ret;
(gdb) x/x buf
0x7ffff7fcb000: Cannot access memory at address 0x7ffff7fcb000
Note that we can no longer access the memory region allocated by mmap().
Back in 2007, a hack for GDB was added to _bfd_elf_make_section_from_phdr()
in bfd/elf.c:
/* Hack for gdb. Segments that have not been modified do
not have their contents written to a core file, on the
assumption that a debugger can find the contents in the
executable. We flag this case by setting the fake
section size to zero. Note that "real" bss sections will
always have their contents dumped to the core file. */
if (bfd_get_format (abfd) == bfd_core)
newsect->size = 0;
You can find the entire patch plus links to other discussion starting
here:
https://sourceware.org/ml/binutils/2007-08/msg00047.html
This hack sets the size of certain BFD sections to 0, which
effectively causes GDB to ignore them. I think it's likely that the
bug described above existed even before this hack was added, but I
have no easy way to test this now.
The output from objdump -h shows the result of this hack:
25 load13 00000000 00007ffff7fcb000 0000000000000000 00013000 2**12
ALLOC
(The first field, after load13, shows the size of 0.)
Once the hack is removed, the output from objdump -h shows the correct
size:
25 load13 00002000 00007ffff7fcb000 0000000000000000 00013000 2**12
ALLOC
(This is a digression, but I think it's good that objdump will now show
the correct size.)
If we remove the hack from bfd/elf.c, but do nothing to GDB, we'll
see the following regression:
FAIL: gdb.base/corefile.exp: print coremaker_ro
The reason for this is that all sections which have the BFD flag
SEC_ALLOC set, but for which SEC_HAS_CONTENTS is not set no longer
have zero size. Some of these sections have data that can (and should)
be read from the executable. (Sections for which SEC_HAS_CONTENTS
is set should be read from the core file; sections which do not have
this flag set need to either be read from the executable or, failing
that, from the core file using whatever BFD decides is the best value
to present to the user - it uses zeros.)
At present, due to the way that the target strata are traversed when
attempting to access memory, the non-SEC_HAS_CONTENTS sections will be
read as zeroes from the process_stratum (which in this case is the
core file stratum) without first checking the file stratum, which is
where the data might actually be found.
What we should be doing is this:
- Attempt to access core file data for SEC_HAS_CONTENTS sections.
- Attempt to access executable file data if the above fails.
- Attempt to access core file data for non SEC_HAS_CONTENTS sections, if
both of the above fail.
This corresponds to the analysis of Daniel Jacobowitz back in 2007
when the hack was added to BFD:
https://sourceware.org/legacy-ml/binutils/2007-08/msg00045.html
The difference, observed by Pedro in his review of my v1 patches, is
that I'm using "the section flags as proxy for the p_filesz/p_memsz
checks."
gdb/ChangeLog:
PR corefiles/25631
* corelow.c (core_target:xfer_partial): Revise
TARGET_OBJECT_MEMORY case to consider non-SEC_HAS_CONTENTS
case after first checking the stratum beneath the core
target.
(has_all_memory): Return true.
* target.c (raw_memory_xfer_partial): Revise comment
regarding use of has_all_memory.
diff --git a/gdb/corelow.c b/gdb/corelow.c
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -816,12 +816,47 @@ core_target::xfer_partial (enum target_object object, const char *annex,
switch (object)
{
case TARGET_OBJECT_MEMORY:
- return (section_table_xfer_memory_partial
- (readbuf, writebuf,
- offset, len, xfered_len,
- m_core_section_table.sections,
- m_core_section_table.sections_end));
+ {
+ enum target_xfer_status xfer_status;
+
+ /* Try accessing memory contents from core file data,
+ restricting consideration to those sections for which
+ the BFD section flag SEC_HAS_CONTENTS is set. */
+ auto has_contents_cb = [] (const struct target_section *s)
+ {
+ return ((s->the_bfd_section->flags & SEC_HAS_CONTENTS) != 0);
+ };
+ xfer_status = section_table_xfer_memory_partial
+ (readbuf, writebuf,
+ offset, len, xfered_len,
+ m_core_section_table.sections,
+ m_core_section_table.sections_end,
+ has_contents_cb);
+ if (xfer_status == TARGET_XFER_OK)
+ return TARGET_XFER_OK;
+
+ /* Now check the stratum beneath us; this should be file_stratum. */
+ xfer_status = this->beneath ()->xfer_partial (object, annex, readbuf,
+ writebuf, offset, len,
+ xfered_len);
+ if (xfer_status == TARGET_XFER_OK)
+ return TARGET_XFER_OK;
+ /* Finally, attempt to access data in core file sections with
+ no contents. These will typically read as all zero. */
+ auto no_contents_cb = [&] (const struct target_section *s)
+ {
+ return !has_contents_cb (s);
+ };
+ xfer_status = section_table_xfer_memory_partial
+ (readbuf, writebuf,
+ offset, len, xfered_len,
+ m_core_section_table.sections,
+ m_core_section_table.sections_end,
+ no_contents_cb);
+
+ return xfer_status;
+ }
case TARGET_OBJECT_AUXV:
if (readbuf)
{
diff --git a/gdb/target.c b/gdb/target.c
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -1043,8 +1043,11 @@ raw_memory_xfer_partial (struct target_ops *ops, gdb_byte *readbuf,
if (res == TARGET_XFER_UNAVAILABLE)
break;
- /* We want to continue past core files to executables, but not
- past a running target's memory. */
+ /* Don't continue past targets which have all the memory.
+ At one time, this code was necessary to read data from
+ executables / shared libraries when data for the requested
+ addresses weren't available in the core file. But now the
+ core target handles this case itself. */
if (ops->has_all_memory ())
break;

View File

@ -0,0 +1,68 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Mon, 27 Jul 2020 17:27:39 -0400
Subject: gdb-rhbz1842691-corefile-mem-access-5of15.patch
;; Test ability to access unwritten-to mmap data in core file
;; Kevin Buettner, RH BZ 1842961
Author: Kevin Buettner <kevinb@redhat.com>
Date: Wed Mar 4 17:42:43 2020 -0700
Test ability to access unwritten-to mmap data in core file
gdb/testsuite/ChangeLog:
PR corefiles/25631
* gdb.base/corefile.exp (accessing anonymous, unwritten-to mmap data):
New test.
* gdb.base/coremaker.c (buf3): New global.
(mmapdata): Add mmap call which uses MAP_ANONYMOUS and MAP_PRIVATE
flags.
diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp
--- a/gdb/testsuite/gdb.base/corefile.exp
+++ b/gdb/testsuite/gdb.base/corefile.exp
@@ -175,6 +175,15 @@ gdb_test_multiple "x/8bd buf2" "$test" {
}
}
+# Test ability to read anonymous and, more importantly, unwritten-to
+# mmap'd data.
+
+if { ![istarget *-linux*] } {
+ setup_xfail "*-*-*"
+}
+gdb_test "x/wx buf3" "$hex:\[ \t\]+0x00000000" \
+ "accessing anonymous, unwritten-to mmap data"
+
# test reinit_frame_cache
gdb_load ${binfile}
diff --git a/gdb/testsuite/gdb.base/coremaker.c b/gdb/testsuite/gdb.base/coremaker.c
--- a/gdb/testsuite/gdb.base/coremaker.c
+++ b/gdb/testsuite/gdb.base/coremaker.c
@@ -38,6 +38,7 @@
char *buf1;
char *buf2;
+char *buf3;
int coremaker_data = 1; /* In Data section */
int coremaker_bss; /* In BSS section */
@@ -104,6 +105,15 @@ mmapdata ()
}
/* Touch buf2 so kernel writes it out into 'core'. */
buf2[0] = buf1[0];
+
+ /* Create yet another region which is allocated, but not written to. */
+ buf3 = mmap (NULL, MAPSIZE, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ if (buf3 == (char *) -1)
+ {
+ perror ("mmap failed");
+ return;
+ }
}
void

View File

@ -0,0 +1,62 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Mon, 27 Jul 2020 17:32:50 -0400
Subject: gdb-rhbz1842691-corefile-mem-access-6of15.patch
;; Update binary_get_section_contents to seek using section's file position
;; Kevin Buettner, RH BZ 1842961
Author: Kevin Buettner <kevinb@redhat.com>
Date: Thu Jun 11 18:58:49 2020 -0700
Update binary_get_section_contents to seek using section's file position
I have a patch for GDB which opens and reads from BFDs using the
"binary" target. However, for it to work, we need to be able to get a
section's contents based from the file position of that section.
At the moment, reading a section's contents will always read from the
start of the file regardless of where that section is located. While
this was fine for the original use of the "binary" target, it won't
work for my use case. This change shouldn't impact any existing
callers due to the fact that the single .data section is initialized
with a filepos of 0.
bfd/ChangeLog:
* binary.c (binary_get_section_contents): Seek using offset
from section's file position.
diff --git a/bfd/binary.c b/bfd/binary.c
--- a/bfd/binary.c
+++ b/bfd/binary.c
@@ -19,10 +19,10 @@
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
-/* This is a BFD backend which may be used to write binary objects.
- It may only be used for output, not input. The intention is that
- this may be used as an output format for objcopy in order to
- generate raw binary data.
+/* This is a BFD backend which may be used to read or write binary
+ objects. Historically, it was used as an output format for objcopy
+ in order to generate raw binary data, but is now used for other
+ purposes as well.
This is very simple. The only complication is that the real data
will start at some address X, and in some cases we will not want to
@@ -97,12 +97,12 @@ binary_object_p (bfd *abfd)
static bfd_boolean
binary_get_section_contents (bfd *abfd,
- asection *section ATTRIBUTE_UNUSED,
+ asection *section,
void * location,
file_ptr offset,
bfd_size_type count)
{
- if (bfd_seek (abfd, offset, SEEK_SET) != 0
+ if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
|| bfd_bread (location, count, abfd) != count)
return FALSE;
return TRUE;

View File

@ -0,0 +1,180 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Mon, 27 Jul 2020 18:01:32 -0400
Subject: gdb-rhbz1842691-corefile-mem-access-7of15.patch
;; Add new gdbarch method, read_core_file_mappings
;; Kevin Buettner, RH BZ 1842961
Author: Kevin Buettner <kevinb@redhat.com>
Date: Fri Jul 3 13:32:08 2020 -0700
Add new gdbarch method, read_core_file_mappings
The new gdbarch method, read_core_file_mappings, will be used for
reading file-backed mappings from a core file. It'll be used
for two purposes: 1) to construct a table of file-backed mappings
in corelow.c, and 2) for display of core file mappings.
For Linux, I tried a different approach in which knowledge of the note
format was placed directly in corelow.c. This seemed okay at first;
it was only one note format and the note format was fairly simple.
After looking at FreeBSD's note/mapping reading code, I concluded
that it's best to leave architecture specific details for decoding
the note in (architecture specific) tdep files.
With regard to display of core file mappings, I experimented with
placing the mappings display code in corelow.c. It has access to the
file-backed mappings which were read in when the core file was loaded.
And, better, still common code could be used for all architectures.
But, again, the FreeBSD mapping code convinced me that this was not
the best approach since it has even more mapping info than Linux.
Display code which would work well for Linux will leave out mappings
as well as protection info for mappings.
So, for these reasons, I'm introducing a new gdbarch method for
reading core file mappings.
gdb/ChangeLog:
* arch-utils.c (default_read_core_file_mappings): New function.
* arch-utils.c (default_read_core_file_mappings): Declare.
* gdbarch.sh (read_core_file_mappings): New gdbarch method.
* gdbarch.h, gdbarch.c: Regenerate.
diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c
--- a/gdb/arch-utils.c
+++ b/gdb/arch-utils.c
@@ -997,6 +997,22 @@ default_type_align (struct gdbarch *gdbarch, struct type *type)
return type_length_units (check_typedef (type));
}
+/* See arch-utils.h. */
+void
+default_read_core_file_mappings (struct gdbarch *gdbarch,
+ struct bfd *cbfd,
+ gdb::function_view<void (ULONGEST count)>
+ pre_loop_cb,
+ gdb::function_view<void (int num,
+ ULONGEST start,
+ ULONGEST end,
+ ULONGEST file_ofs,
+ const char *filename,
+ const void *other)>
+ loop_cb)
+{
+}
+
void
_initialize_gdbarch_utils (void)
{
diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h
--- a/gdb/arch-utils.h
+++ b/gdb/arch-utils.h
@@ -271,4 +271,16 @@ extern bool default_in_indirect_branch_thunk (gdbarch *gdbarch,
extern ULONGEST default_type_align (struct gdbarch *gdbarch,
struct type *type);
+/* Default implementation of gdbarch read_core_file_mappings method. */
+extern void default_read_core_file_mappings (struct gdbarch *gdbarch,
+ struct bfd *cbfd,
+ gdb::function_view<void (ULONGEST count)>
+ pre_loop_cb,
+ gdb::function_view<void (int num,
+ ULONGEST start,
+ ULONGEST end,
+ ULONGEST file_ofs,
+ const char *filename,
+ const void *other)>
+ loop_cb);
#endif
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -354,6 +354,7 @@ struct gdbarch
char ** disassembler_options;
const disasm_options_and_args_t * valid_disassembler_options;
gdbarch_type_align_ftype *type_align;
+ gdbarch_read_core_file_mappings_ftype *read_core_file_mappings;
};
/* Create a new ``struct gdbarch'' based on information provided by
@@ -466,6 +467,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
gdbarch->gnu_triplet_regexp = default_gnu_triplet_regexp;
gdbarch->addressable_memory_unit_size = default_addressable_memory_unit_size;
gdbarch->type_align = default_type_align;
+ gdbarch->read_core_file_mappings = default_read_core_file_mappings;
/* gdbarch_alloc() */
return gdbarch;
@@ -712,6 +714,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of disassembler_options, invalid_p == 0 */
/* Skip verify of valid_disassembler_options, invalid_p == 0 */
/* Skip verify of type_align, invalid_p == 0 */
+ /* Skip verify of read_core_file_mappings, invalid_p == 0 */
if (!log.empty ())
internal_error (__FILE__, __LINE__,
_("verify_gdbarch: the following are invalid ...%s"),
@@ -1275,6 +1278,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
fprintf_unfiltered (file,
"gdbarch_dump: ravenscar_ops = %s\n",
host_address_to_string (gdbarch->ravenscar_ops));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: read_core_file_mappings = <%s>\n",
+ host_address_to_string (gdbarch->read_core_file_mappings));
fprintf_unfiltered (file,
"gdbarch_dump: gdbarch_read_pc_p() = %d\n",
gdbarch_read_pc_p (gdbarch));
@@ -5117,6 +5123,23 @@ set_gdbarch_type_align (struct gdbarch *gdbarch,
gdbarch->type_align = type_align;
}
+void
+gdbarch_read_core_file_mappings (struct gdbarch *gdbarch, struct bfd *cbfd,gdb::function_view<void (ULONGEST count)> pre_loop_cb,gdb::function_view<void (int num, ULONGEST start, ULONGEST end, ULONGEST file_ofs, const char *filename, const void *other)> loop_cb)
+{
+ gdb_assert (gdbarch != NULL);
+ gdb_assert (gdbarch->read_core_file_mappings != NULL);
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_read_core_file_mappings called\n");
+ gdbarch->read_core_file_mappings (gdbarch, cbfd, pre_loop_cb, loop_cb);
+}
+
+void
+set_gdbarch_read_core_file_mappings (struct gdbarch *gdbarch,
+ gdbarch_read_core_file_mappings_ftype read_core_file_mappings)
+{
+ gdbarch->read_core_file_mappings = read_core_file_mappings;
+}
+
/* Keep a registry of per-architecture data-pointers required by GDB
modules. */
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -1566,6 +1566,12 @@ typedef ULONGEST (gdbarch_type_align_ftype) (struct gdbarch *gdbarch, struct typ
extern ULONGEST gdbarch_type_align (struct gdbarch *gdbarch, struct type *type);
extern void set_gdbarch_type_align (struct gdbarch *gdbarch, gdbarch_type_align_ftype *type_align);
+/* Read core file mappings */
+
+typedef void (gdbarch_read_core_file_mappings_ftype) (struct gdbarch *gdbarch, struct bfd *cbfd,gdb::function_view<void (ULONGEST count)> pre_loop_cb,gdb::function_view<void (int num, ULONGEST start, ULONGEST end, ULONGEST file_ofs, const char *filename, const void *other)> loop_cb);
+extern void gdbarch_read_core_file_mappings (struct gdbarch *gdbarch, struct bfd *cbfd,gdb::function_view<void (ULONGEST count)> pre_loop_cb,gdb::function_view<void (int num, ULONGEST start, ULONGEST end, ULONGEST file_ofs, const char *filename, const void *other)> loop_cb);
+extern void set_gdbarch_read_core_file_mappings (struct gdbarch *gdbarch, gdbarch_read_core_file_mappings_ftype *read_core_file_mappings);
+
/* Definition for an unknown syscall, used basically in error-cases. */
#define UNKNOWN_SYSCALL (-1)
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -1164,6 +1164,9 @@ v;const disasm_options_and_args_t *;valid_disassembler_options;;;0;0;;0;host_add
# Type alignment.
m;ULONGEST;type_align;struct type *type;type;;default_type_align;;0
+# Read core file mappings
+m;void;read_core_file_mappings;struct bfd *cbfd,gdb::function_view<void (ULONGEST count)> pre_loop_cb,gdb::function_view<void (int num, ULONGEST start, ULONGEST end, ULONGEST file_ofs, const char *filename, const void *other)> loop_cb;cbfd, pre_loop_cb, loop_cb;;default_read_core_file_mappings;;0
+
EOF
}

View File

@ -0,0 +1,532 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Mon, 27 Jul 2020 18:51:07 -0400
Subject: gdb-rhbz1842691-corefile-mem-access-8of15.patch
;; Use NT_FILE note section for reading core target memory
;; Kevin Buettner, RH BZ 1842961
Author: Kevin Buettner <kevinb@redhat.com>
Date: Thu Jun 11 19:20:03 2020 -0700
Use NT_FILE note section for reading core target memory
In his reviews of my v1 and v2 corefile related patches, Pedro
identified two cases which weren't handled by those patches.
In https://sourceware.org/pipermail/gdb-patches/2020-May/168826.html,
Pedro showed that debugging a core file in which mmap() is used to
create a new mapping over an existing file-backed mapping will
produce incorrect results. I.e, for his example, GDB would
show:
(gdb) disassemble main
Dump of assembler code for function main:
0x00000000004004e6 <+0>: push %rbp
0x00000000004004e7 <+1>: mov %rsp,%rbp
=> 0x00000000004004ea <+4>: callq 0x4003f0 <abort@plt>
End of assembler dump.
This sort of looks like it might be correct, but is not due to the
fact that mmap(...MAP_FIXED...) was used to create a mapping (of all
zeros) on top of the .text section. So, the correct result should be:
(gdb) disassemble main
Dump of assembler code for function main:
0x00000000004004e6 <+0>: add %al,(%rax)
0x00000000004004e8 <+2>: add %al,(%rax)
=> 0x00000000004004ea <+4>: add %al,(%rax)
0x00000000004004ec <+6>: add %al,(%rax)
0x00000000004004ee <+8>: add %al,(%rax)
End of assembler dump.
The other case that Pedro found involved an attempted examination of a
particular section in the test case from gdb.base/corefile.exp. On
Fedora 27 or 28, the following behavior may be observed:
(gdb) info proc mappings
Mapped address spaces:
Start Addr End Addr Size Offset objfile
...
0x7ffff7839000 0x7ffff7a38000 0x1ff000 0x1b5000 /usr/lib64/libc-2.27.so
...
(gdb) x/4x 0x7ffff7839000
0x7ffff7839000: Cannot access memory at address 0x7ffff7839000
FYI, this section appears to be unrelocated vtable data. See
https://sourceware.org/pipermail/gdb-patches/2020-May/168331.html for
a detailed analysis.
The important thing here is that GDB should be able to access this
address since it should be backed by the shared library. I.e. it
should do this:
(gdb) x/4x 0x7ffff7839000
0x7ffff7839000: 0x0007ddf0 0x00000000 0x0007dba0 0x00000000
Both of these cases are fixed with this commit.
In a nutshell, this commit opens a "binary" target BFD for each of the
files that are mentioned in an NT_FILE / .note.linuxcore.file note
section. It then uses these mappings instead of the file stratum
mappings that GDB has used in the past.
If this note section doesn't exist or is mangled for some reason, then
GDB will use the file stratum as before. Should this happen, then
we can expect both of the above problems to again be present.
See the code comments in the commit for other details.
gdb/ChangeLog:
* corelow.c (solist.h, unordered_map): Include.
(class core_target): Add field m_core_file_mappings and
method build_file_mappings.
(core_target::core_target): Call build_file_mappings.
(core_target::~core_target): Free memory associated with
m_core_file_mappings.
(core_target::build_file_mappings): New method.
(core_target::xfer_partial): Use m_core_file_mappings
for memory transfers.
* linux-tdep.c (linux_read_core_file_mappings): New
function.
(linux_core_info_proc_mappings): Rewrite to use
linux_read_core_file_mappings.
(linux_init_abi): Register linux_read_core_file_mappings.
diff --git a/gdb/corelow.c b/gdb/corelow.c
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -39,6 +39,7 @@
#include "exec.h"
#include "readline/readline.h"
#include "solib.h"
+#include "solist.h"
#include "filenames.h"
#include "progspace.h"
#include "objfiles.h"
@@ -49,6 +50,8 @@
#include "elf/common.h"
#include "gdbcmd.h"
#include "build-id.h"
+#include "common/pathstuff.h"
+#include <unordered_map>
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
@@ -129,6 +132,13 @@ private: /* per-core data */
core file currently open on core_bfd. */
core_fns *m_core_vec = NULL;
+ /* File-backed address space mappings: some core files include
+ information about memory mapped files. */
+ target_section_table m_core_file_mappings {};
+
+ /* Build m_core_file_mappings. Called from the constructor. */
+ void build_file_mappings ();
+
/* FIXME: kettenis/20031023: Eventually this field should
disappear. */
struct gdbarch *m_core_gdbarch = NULL;
@@ -149,11 +159,120 @@ core_target::core_target ()
&m_core_section_table.sections_end))
error (_("\"%s\": Can't find sections: %s"),
bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ()));
+
+ build_file_mappings ();
}
core_target::~core_target ()
{
xfree (m_core_section_table.sections);
+ xfree (m_core_file_mappings.sections);
+}
+
+/* Construct the target_section_table for file-backed mappings if
+ they exist.
+
+ For each unique path in the note, we'll open a BFD with a bfd
+ target of "binary". This is an unstructured bfd target upon which
+ we'll impose a structure from the mappings in the architecture-specific
+ mappings note. A BFD section is allocated and initialized for each
+ file-backed mapping.
+
+ We take care to not share already open bfds with other parts of
+ GDB; in particular, we don't want to add new sections to existing
+ BFDs. We do, however, ensure that the BFDs that we allocate here
+ will go away (be deallocated) when the core target is detached. */
+
+void
+core_target::build_file_mappings ()
+{
+ std::unordered_map<std::string, struct bfd *> bfd_map;
+
+ /* See linux_read_core_file_mappings() in linux-tdep.c for an example
+ read_core_file_mappings method. */
+ gdbarch_read_core_file_mappings (m_core_gdbarch, core_bfd,
+
+ /* After determining the number of mappings, read_core_file_mappings
+ will invoke this lambda which allocates target_section storage for
+ the mappings. */
+ [&] (ULONGEST count)
+ {
+ m_core_file_mappings.sections = XNEWVEC (struct target_section, count);
+ m_core_file_mappings.sections_end = m_core_file_mappings.sections;
+ },
+
+ /* read_core_file_mappings will invoke this lambda for each mapping
+ that it finds. */
+ [&] (int num, ULONGEST start, ULONGEST end, ULONGEST file_ofs,
+ const char *filename, const void *other)
+ {
+ /* Architecture-specific read_core_mapping methods are expected to
+ weed out non-file-backed mappings. */
+ gdb_assert (filename != nullptr);
+
+ struct bfd *bfd = bfd_map[filename];
+ if (bfd == nullptr)
+ {
+ /* Use exec_file_find() to do sysroot expansion. It'll
+ also strip the potential sysroot "target:" prefix. If
+ there is no sysroot, an equivalent (possibly more
+ canonical) pathname will be provided. */
+ gdb::unique_xmalloc_ptr<char> expanded_fname
+ = exec_file_find (filename, NULL);
+ if (expanded_fname == nullptr)
+ {
+ warning (_("Can't open file %s during file-backed mapping "
+ "note processing"),
+ expanded_fname.get ());
+ return;
+ }
+
+ bfd = bfd_map[filename] = bfd_openr (expanded_fname.get (),
+ "binary");
+
+ if (bfd == nullptr || !bfd_check_format (bfd, bfd_object))
+ {
+ /* If we get here, there's a good chance that it's due to
+ an internal error. We issue a warning instead of an
+ internal error because of the possibility that the
+ file was removed in between checking for its
+ existence during the expansion in exec_file_find()
+ and the calls to bfd_openr() / bfd_check_format().
+ Output both the path from the core file note along
+ with its expansion to make debugging this problem
+ easier. */
+ warning (_("Can't open file %s which was expanded to %s "
+ "during file-backed mapping note processing"),
+ filename, expanded_fname.get ());
+ if (bfd != nullptr)
+ bfd_close (bfd);
+ return;
+ }
+ /* Ensure that the bfd will be closed when core_bfd is closed.
+ This can be checked before/after a core file detach via
+ "maint info bfds". */
+ gdb_bfd_record_inclusion (core_bfd, bfd);
+ }
+
+ /* Make new BFD section. All sections have the same name,
+ which is permitted by bfd_make_section_anyway(). */
+ asection *sec = bfd_make_section_anyway (bfd, "load");
+ if (sec == nullptr)
+ error (_("Can't make section"));
+ sec->filepos = file_ofs;
+ bfd_set_section_flags (sec->owner, sec, SEC_READONLY | SEC_HAS_CONTENTS);
+ bfd_set_section_size (sec->owner, sec, end - start);
+ bfd_set_section_vma (sec->owner, sec, start);
+ sec->lma = start;
+ bfd_set_section_alignment (sec->owner, sec, 2);
+
+ /* Set target_section fields. */
+ struct target_section *ts = m_core_file_mappings.sections_end++;
+ ts->addr = start;
+ ts->endaddr = end;
+ ts->owner = nullptr;
+ ts->the_bfd_section = sec;
+ });
}
/* List of all available core_fns. On gdb startup, each core file
@@ -835,10 +954,21 @@ core_target::xfer_partial (enum target_object object, const char *annex,
if (xfer_status == TARGET_XFER_OK)
return TARGET_XFER_OK;
- /* Now check the stratum beneath us; this should be file_stratum. */
- xfer_status = this->beneath ()->xfer_partial (object, annex, readbuf,
- writebuf, offset, len,
- xfered_len);
+ /* Check file backed mappings. If they're available, use
+ core file provided mappings (e.g. from .note.linuxcore.file
+ or the like) as this should provide a more accurate
+ result. If not, check the stratum beneath us, which should
+ be the file stratum. */
+ if (m_core_file_mappings.sections != nullptr)
+ xfer_status = section_table_xfer_memory_partial
+ (readbuf, writebuf,
+ offset, len, xfered_len,
+ m_core_file_mappings.sections,
+ m_core_file_mappings.sections_end);
+ else
+ xfer_status = this->beneath ()->xfer_partial (object, annex, readbuf,
+ writebuf, offset, len,
+ xfered_len);
if (xfer_status == TARGET_XFER_OK)
return TARGET_XFER_OK;
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -1002,106 +1002,174 @@ linux_info_proc (struct gdbarch *gdbarch, const char *args,
}
}
-/* Implement "info proc mappings" for a corefile. */
+/* Implementation of `gdbarch_read_core_file_mappings', as defined in
+ gdbarch.h.
+
+ This function reads the NT_FILE note (which BFD turns into the
+ section ".note.linuxcore.file"). The format of this note / section
+ is described as follows in the Linux kernel sources in
+ fs/binfmt_elf.c:
+
+ long count -- how many files are mapped
+ long page_size -- units for file_ofs
+ array of [COUNT] elements of
+ long start
+ long end
+ long file_ofs
+ followed by COUNT filenames in ASCII: "FILE1" NUL "FILE2" NUL...
+
+ CBFD is the BFD of the core file.
+
+ PRE_LOOP_CB is the callback function to invoke prior to starting
+ the loop which processes individual entries. This callback will
+ only be executed after the note has been examined in enough
+ detail to verify that it's not malformed in some way.
+
+ LOOP_CB is the callback function that will be executed once
+ for each mapping. */
static void
-linux_core_info_proc_mappings (struct gdbarch *gdbarch, const char *args)
+linux_read_core_file_mappings (struct gdbarch *gdbarch,
+ struct bfd *cbfd,
+ gdb::function_view<void (ULONGEST count)>
+ pre_loop_cb,
+ gdb::function_view<void (int num,
+ ULONGEST start,
+ ULONGEST end,
+ ULONGEST file_ofs,
+ const char *filename,
+ const void *other)>
+ loop_cb)
{
- asection *section;
- ULONGEST count, page_size;
- unsigned char *descdata, *filenames, *descend;
- size_t note_size;
- unsigned int addr_size_bits, addr_size;
- struct gdbarch *core_gdbarch = gdbarch_from_bfd (core_bfd);
- /* We assume this for reading 64-bit core files. */
+ /* Ensure that ULONGEST is big enough for reading 64-bit core files. */
gdb_static_assert (sizeof (ULONGEST) >= 8);
- section = bfd_get_section_by_name (core_bfd, ".note.linuxcore.file");
- if (section == NULL)
- {
- warning (_("unable to find mappings in core file"));
- return;
- }
+ /* It's not required that the NT_FILE note exists, so return silently
+ if it's not found. Beyond this point though, we'll complain
+ if problems are found. */
+ asection *section = bfd_get_section_by_name (cbfd, ".note.linuxcore.file");
+ if (section == nullptr)
+ return;
- addr_size_bits = gdbarch_addr_bit (core_gdbarch);
- addr_size = addr_size_bits / 8;
- note_size = bfd_get_section_size (section);
+ unsigned int addr_size_bits = gdbarch_addr_bit (gdbarch);
+ unsigned int addr_size = addr_size_bits / 8;
+ size_t note_size = bfd_section_size (section->abfd, section);
if (note_size < 2 * addr_size)
- error (_("malformed core note - too short for header"));
+ {
+ warning (_("malformed core note - too short for header"));
+ return;
+ }
- gdb::def_vector<unsigned char> contents (note_size);
+ gdb::def_vector<gdb_byte> contents (note_size);
if (!bfd_get_section_contents (core_bfd, section, contents.data (),
- 0, note_size))
- error (_("could not get core note contents"));
+ 0, note_size))
+ {
+ warning (_("could not get core note contents"));
+ return;
+ }
- descdata = contents.data ();
- descend = descdata + note_size;
+ gdb_byte *descdata = contents.data ();
+ char *descend = (char *) descdata + note_size;
if (descdata[note_size - 1] != '\0')
- error (_("malformed note - does not end with \\0"));
+ {
+ warning (_("malformed note - does not end with \\0"));
+ return;
+ }
- count = bfd_get (addr_size_bits, core_bfd, descdata);
+ ULONGEST count = bfd_get (addr_size_bits, core_bfd, descdata);
descdata += addr_size;
- page_size = bfd_get (addr_size_bits, core_bfd, descdata);
+ ULONGEST page_size = bfd_get (addr_size_bits, core_bfd, descdata);
descdata += addr_size;
if (note_size < 2 * addr_size + count * 3 * addr_size)
- error (_("malformed note - too short for supplied file count"));
-
- printf_filtered (_("Mapped address spaces:\n\n"));
- if (gdbarch_addr_bit (gdbarch) == 32)
{
- printf_filtered ("\t%10s %10s %10s %10s %s\n",
- "Start Addr",
- " End Addr",
- " Size", " Offset", "objfile");
- }
- else
- {
- printf_filtered (" %18s %18s %10s %10s %s\n",
- "Start Addr",
- " End Addr",
- " Size", " Offset", "objfile");
+ warning (_("malformed note - too short for supplied file count"));
+ return;
}
- filenames = descdata + count * 3 * addr_size;
- while (--count > 0)
+ char *filenames = (char *) descdata + count * 3 * addr_size;
+
+ /* Make sure that the correct number of filenames exist. Complain
+ if there aren't enough or are too many. */
+ char *f = filenames;
+ for (int i = 0; i < count; i++)
{
- ULONGEST start, end, file_ofs;
+ if (f >= descend)
+ {
+ warning (_("malformed note - filename area is too small"));
+ return;
+ }
+ f += strnlen (f, descend - f) + 1;
+ }
+ /* Complain, but don't return early if the filename area is too big. */
+ if (f != descend)
+ warning (_("malformed note - filename area is too big"));
- if (filenames == descend)
- error (_("malformed note - filenames end too early"));
+ pre_loop_cb (count);
- start = bfd_get (addr_size_bits, core_bfd, descdata);
+ for (int i = 0; i < count; i++)
+ {
+ ULONGEST start = bfd_get (addr_size_bits, core_bfd, descdata);
descdata += addr_size;
- end = bfd_get (addr_size_bits, core_bfd, descdata);
+ ULONGEST end = bfd_get (addr_size_bits, core_bfd, descdata);
descdata += addr_size;
- file_ofs = bfd_get (addr_size_bits, core_bfd, descdata);
+ ULONGEST file_ofs
+ = bfd_get (addr_size_bits, core_bfd, descdata) * page_size;
descdata += addr_size;
+ char * filename = filenames;
+ filenames += strlen ((char *) filenames) + 1;
- file_ofs *= page_size;
-
- if (gdbarch_addr_bit (gdbarch) == 32)
- printf_filtered ("\t%10s %10s %10s %10s %s\n",
- paddress (gdbarch, start),
- paddress (gdbarch, end),
- hex_string (end - start),
- hex_string (file_ofs),
- filenames);
- else
- printf_filtered (" %18s %18s %10s %10s %s\n",
- paddress (gdbarch, start),
- paddress (gdbarch, end),
- hex_string (end - start),
- hex_string (file_ofs),
- filenames);
-
- filenames += 1 + strlen ((char *) filenames);
+ loop_cb (i, start, end, file_ofs, filename, nullptr);
}
}
+/* Implement "info proc mappings" for a corefile. */
+
+static void
+linux_core_info_proc_mappings (struct gdbarch *gdbarch, const char *args)
+{
+ linux_read_core_file_mappings (gdbarch, core_bfd,
+ [=] (ULONGEST count)
+ {
+ printf_filtered (_("Mapped address spaces:\n\n"));
+ if (gdbarch_addr_bit (gdbarch) == 32)
+ {
+ printf_filtered ("\t%10s %10s %10s %10s %s\n",
+ "Start Addr",
+ " End Addr",
+ " Size", " Offset", "objfile");
+ }
+ else
+ {
+ printf_filtered (" %18s %18s %10s %10s %s\n",
+ "Start Addr",
+ " End Addr",
+ " Size", " Offset", "objfile");
+ }
+ },
+ [=] (int num, ULONGEST start, ULONGEST end, ULONGEST file_ofs,
+ const char *filename, const void *other)
+ {
+ if (gdbarch_addr_bit (gdbarch) == 32)
+ printf_filtered ("\t%10s %10s %10s %10s %s\n",
+ paddress (gdbarch, start),
+ paddress (gdbarch, end),
+ hex_string (end - start),
+ hex_string (file_ofs),
+ filename);
+ else
+ printf_filtered (" %18s %18s %10s %10s %s\n",
+ paddress (gdbarch, start),
+ paddress (gdbarch, end),
+ hex_string (end - start),
+ hex_string (file_ofs),
+ filename);
+ });
+}
+
/* Implement "info proc" for a corefile. */
static void
@@ -2501,6 +2569,7 @@ linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_info_proc (gdbarch, linux_info_proc);
set_gdbarch_core_info_proc (gdbarch, linux_core_info_proc);
set_gdbarch_core_xfer_siginfo (gdbarch, linux_core_xfer_siginfo);
+ set_gdbarch_read_core_file_mappings (gdbarch, linux_read_core_file_mappings);
set_gdbarch_find_memory_regions (gdbarch, linux_find_memory_regions);
set_gdbarch_make_corefile_notes (gdbarch, linux_make_corefile_notes);
set_gdbarch_has_shared_address_space (gdbarch,

View File

@ -0,0 +1,101 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Mon, 27 Jul 2020 19:21:54 -0400
Subject: gdb-rhbz1842691-corefile-mem-access-9of15.patch
;; Add test for accessing read-only mmapped data in a core file
;; Kevin Buettner, RH BZ 1842691
Author: Kevin Buettner <kevinb@redhat.com>
Date: Tue Jun 16 11:39:22 2020 -0700
Add test for accessing read-only mmapped data in a core file
This test passes when run using a GDB with my corefile patches. When
run against a GDB without my patches, I see the following failures,
the first of which is due to the test added by this commit:
FAIL: gdb.base/corefile.exp: accessing read-only mmapped data in core file (
FAIL: gdb.base/corefile.exp: accessing anonymous, unwritten-to mmap data
gdb/testsuite/ChangeLog:
* gdb.base/corefile.exp: Add test "accessing read-only mmapped
data in core file".
* gdb.base/coremaker.c (buf2ro): New global.
(mmapdata): Add a read-only mmap mapping.
diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp
--- a/gdb/testsuite/gdb.base/corefile.exp
+++ b/gdb/testsuite/gdb.base/corefile.exp
@@ -34,7 +34,10 @@ if {[build_executable $testfile.exp $testfile $srcfile debug] == -1} {
return -1
}
-set corefile [core_find $binfile {coremmap.data}]
+# Do not delete coremap.data when calling core_find. This file is
+# required for GDB to find mmap'd data in the "accessing read-only
+# mmapped data in core file" test.
+set corefile [core_find $binfile {}]
if {$corefile == ""} {
return 0
}
@@ -175,6 +178,19 @@ gdb_test_multiple "x/8bd buf2" "$test" {
}
}
+set test "accessing read-only mmapped data in core file"
+gdb_test_multiple "x/8bd buf2ro" "$test" {
+ -re ".*:.*0.*1.*2.*3.*4.*5.*6.*7.*$gdb_prompt $" {
+ pass "$test"
+ }
+ -re "0x\[f\]*:.*Cannot access memory at address 0x\[f\]*.*$gdb_prompt $" {
+ fail "$test (mapping failed at runtime)"
+ }
+ -re "0x.*:.*Cannot access memory at address 0x.*$gdb_prompt $" {
+ fail "$test (mapping address not found in core file)"
+ }
+}
+
# Test ability to read anonymous and, more importantly, unwritten-to
# mmap'd data.
diff --git a/gdb/testsuite/gdb.base/coremaker.c b/gdb/testsuite/gdb.base/coremaker.c
--- a/gdb/testsuite/gdb.base/coremaker.c
+++ b/gdb/testsuite/gdb.base/coremaker.c
@@ -38,6 +38,7 @@
char *buf1;
char *buf2;
+char *buf2ro;
char *buf3;
int coremaker_data = 1; /* In Data section */
@@ -90,16 +91,25 @@ mmapdata ()
return;
}
+ /* Map in another copy, read-only. We won't write to this copy so it
+ will likely not end up in the core file. */
+ buf2ro = (char *) mmap (0, MAPSIZE, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (buf2ro == (char *) -1)
+ {
+ perror ("mmap failed");
+ return;
+ }
+
/* Verify that the original data and the mapped data are identical.
If not, we'd rather fail now than when trying to access the mapped
data from the core file. */
for (j = 0; j < MAPSIZE; ++j)
{
- if (buf1[j] != buf2[j])
+ if (buf1[j] != buf2[j] || buf1[j] != buf2ro[j])
{
fprintf (stderr, "mapped data is incorrect");
- buf2 = (char *) -1;
+ buf2 = buf2ro = (char *) -1;
return;
}
}

View File

@ -0,0 +1,164 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Alan Hayward <alan.hayward@arm.com>
Date: Tue, 28 May 2019 10:07:54 +0100
Subject: gdb-rhbz1852580-terminal-woes.patch
;; Fix terminal problems when error() is called
;; Alan Hayward (RH BZ 1852580)
Suppress SIGTTOU when handling errors
Calls to error () can cause SIGTTOU to send gdb to the background.
For example, on an Arm build:
(gdb) b main
Breakpoint 1 at 0x10774: file /build/gdb/testsuite/../../../src/binutils-gdb/gdb/testsuite/gdb.base/watchpoint.c, line 174.
(gdb) r
Starting program: /build/gdb/testsuite/outputs/gdb.base/watchpoint/watchpoint
[1]+ Stopped ../gdb ./outputs/gdb.base/watchpoint/watchpoint
localhost$ fg
../gdb ./outputs/gdb.base/watchpoint/watchpoint
Cannot parse expression `.L1199 4@r4'.
warning: Probes-based dynamic linker interface failed.
Reverting to original interface.
The SIGTTOU is raised whilst inside a syscall during the call to tcdrain.
Fix is to use scoped_ignore_sigttou to ensure SIGTTOU is blocked.
In addition fix include comments - job_control is not included via terminal.h
gdb/ChangeLog:
* event-top.c: Remove include comment.
* inflow.c (class scoped_ignore_sigttou): Move from here...
* inflow.h (class scoped_ignore_sigttou): ...to here.
* ser-unix.c (hardwire_drain_output): Block SIGTTOU during drain.
* top.c: Remove include comment.
diff --git a/gdb/event-top.c b/gdb/event-top.c
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -24,7 +24,7 @@
#include "inferior.h"
#include "infrun.h"
#include "target.h"
-#include "terminal.h" /* for job_control */
+#include "terminal.h"
#include "event-loop.h"
#include "event-top.h"
#include "interps.h"
diff --git a/gdb/inflow.c b/gdb/inflow.c
--- a/gdb/inflow.c
+++ b/gdb/inflow.c
@@ -103,35 +103,6 @@ static serial_ttystate initial_gdb_ttystate;
static struct terminal_info *get_inflow_inferior_data (struct inferior *);
-/* RAII class used to ignore SIGTTOU in a scope. */
-
-class scoped_ignore_sigttou
-{
-public:
- scoped_ignore_sigttou ()
- {
-#ifdef SIGTTOU
- if (job_control)
- m_osigttou = signal (SIGTTOU, SIG_IGN);
-#endif
- }
-
- ~scoped_ignore_sigttou ()
- {
-#ifdef SIGTTOU
- if (job_control)
- signal (SIGTTOU, m_osigttou);
-#endif
- }
-
- DISABLE_COPY_AND_ASSIGN (scoped_ignore_sigttou);
-
-private:
-#ifdef SIGTTOU
- sighandler_t m_osigttou = NULL;
-#endif
-};
-
/* While the inferior is running, we want SIGINT and SIGQUIT to go to the
inferior only. If we have job control, that takes care of it. If not,
we save our handlers in these two variables and set SIGINT and SIGQUIT
diff --git a/gdb/inflow.h b/gdb/inflow.h
--- a/gdb/inflow.h
+++ b/gdb/inflow.h
@@ -21,5 +21,36 @@
#define INFLOW_H
#include <unistd.h>
+#include <signal.h>
+#include "common/job-control.h"
+
+/* RAII class used to ignore SIGTTOU in a scope. */
+
+class scoped_ignore_sigttou
+{
+public:
+ scoped_ignore_sigttou ()
+ {
+#ifdef SIGTTOU
+ if (job_control)
+ m_osigttou = signal (SIGTTOU, SIG_IGN);
+#endif
+ }
+
+ ~scoped_ignore_sigttou ()
+ {
+#ifdef SIGTTOU
+ if (job_control)
+ signal (SIGTTOU, m_osigttou);
+#endif
+ }
+
+ DISABLE_COPY_AND_ASSIGN (scoped_ignore_sigttou);
+
+private:
+#ifdef SIGTTOU
+ sighandler_t m_osigttou = NULL;
+#endif
+};
#endif /* inflow.h */
diff --git a/gdb/ser-unix.c b/gdb/ser-unix.c
--- a/gdb/ser-unix.c
+++ b/gdb/ser-unix.c
@@ -32,6 +32,7 @@
#include "gdbcmd.h"
#include "filestuff.h"
#include <termios.h>
+#include "inflow.h"
struct hardwire_ttystate
{
@@ -164,6 +165,9 @@ hardwire_print_tty_state (struct serial *scb,
static int
hardwire_drain_output (struct serial *scb)
{
+ /* Ignore SIGTTOU which may occur during the drain. */
+ scoped_ignore_sigttou ignore_sigttou;
+
return tcdrain (scb->fd);
}
diff --git a/gdb/top.c b/gdb/top.c
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -34,8 +34,8 @@
#include "expression.h"
#include "value.h"
#include "language.h"
-#include "terminal.h" /* For job_control. */
-#include "job-control.h"
+#include "terminal.h"
+#include "common/job-control.h"
#include "annotate.h"
#include "completer.h"
#include "top.h"

View File

@ -0,0 +1,108 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Fri, 23 Oct 2020 17:12:26 -0400
Subject:
gdb-rhbz1878810-bfd-suppress-loadable-section-outside-ELF-sections.patch
;; Backport "Stop the BFD library from issuing a warning message when
;; processing allocated sections in debuginfo files that lie outside of
;; Nick Clifton and Keith Seitz, RH BZ 1878810
Stop the BFD library from issuing a warning message when processing allocated sections in debuginfo files that lie outside of any loadable segment.
bfd/ChangeLog
PR 24717
* elf.c (is_debuginfo_file): New function.
(assign_file_positions_for_non_load_sections): Do not warn about
allocated sections outside of loadable segments if they are found
in a debuginfo file.
* elf-bfd.h (is_debuginfo_file): Prototype.
gdb/ChangeLog
https://bugzilla.redhat.com/show_bug.cgi?id=1553086
* elfread.c (elf_symfile_segments): Omit "Loadable section ...
outside of ELF segments" warning for debugin
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2740,6 +2740,8 @@ extern bfd_vma elf64_r_sym (bfd_vma);
extern bfd_vma elf32_r_info (bfd_vma, bfd_vma);
extern bfd_vma elf32_r_sym (bfd_vma);
+extern bfd_boolean is_debuginfo_file (bfd *);
+
/* Large common section. */
extern asection _bfd_elf_large_com_section;
diff --git a/bfd/elf.c b/bfd/elf.c
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -5725,6 +5725,35 @@ assign_file_positions_for_load_sections (bfd *abfd,
return TRUE;
}
+/* Determine if a bfd is a debuginfo file. Unfortunately there
+ is no defined method for detecting such files, so we have to
+ use heuristics instead. */
+
+bfd_boolean
+is_debuginfo_file (bfd *abfd)
+{
+ if (abfd == NULL || bfd_get_flavour (abfd) != bfd_target_elf_flavour)
+ return FALSE;
+
+ Elf_Internal_Shdr **start_headers = elf_elfsections (abfd);
+ Elf_Internal_Shdr **end_headers = start_headers + elf_numsections (abfd);
+ Elf_Internal_Shdr **headerp;
+
+ for (headerp = start_headers; headerp < end_headers; headerp ++)
+ {
+ Elf_Internal_Shdr *header = * headerp;
+
+ /* Debuginfo files do not have any allocated SHT_PROGBITS sections.
+ The only allocated sections are SHT_NOBITS or SHT_NOTES. */
+ if ((header->sh_flags & SHF_ALLOC) == SHF_ALLOC
+ && header->sh_type != SHT_NOBITS
+ && header->sh_type != SHT_NOTE)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
/* Assign file positions for the other sections. */
static bfd_boolean
@@ -5758,7 +5787,13 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
BFD_ASSERT (hdr->sh_offset == hdr->bfd_section->filepos);
else if ((hdr->sh_flags & SHF_ALLOC) != 0)
{
- if (hdr->sh_size != 0)
+ if (hdr->sh_size != 0
+ /* PR 24717 - debuginfo files are known to be not strictly
+ compliant with the ELF standard. In particular they often
+ have .note.gnu.property sections that are outside of any
+ loadable segment. This is not a problem for such files,
+ so do not warn about them. */
+ && ! is_debuginfo_file (abfd))
_bfd_error_handler
/* xgettext:c-format */
(_("%pB: warning: allocated section `%s' not in segment"),
diff --git a/gdb/elfread.c b/gdb/elfread.c
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -143,7 +143,12 @@ elf_symfile_segments (bfd *abfd)
RealView) use SHT_NOBITS for uninitialized data. Since it is
uninitialized, it doesn't need a program header. Such
binaries are not relocatable. */
- if (bfd_get_section_size (sect) > 0 && j == num_segments
+
+ /* Exclude debuginfo files from this warning, too, since those
+ are often not strictly compliant with the standard. See, e.g.,
+ ld/24717 for more discussion. */
+ if (!is_debuginfo_file (abfd)
+ && bfd_get_section_size (sect) > 0 && j == num_segments
&& (bfd_get_section_flags (abfd, sect) & SEC_LOAD) != 0)
warning (_("Loadable section \"%s\" outside of ELF segments"),
bfd_section_name (abfd, sect));

View File

@ -0,0 +1,64 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Andreas Arnez <arnez@linux.ibm.com>
Date: Thu, 19 Nov 2020 19:10:58 +0100
Subject: gdb-rhbz1903374-s390x-store-on-condition.patch
;; Backport of "Correct recording of 'store on condition' insns"
;; Andreas Arnaz (RH BZ 1903374)
gdb/s390: Correct recording of "store on condition" insns
The "store on condition" instructions STOC, STOCG, and STOCFH are recorded
as if their instruction formats resembled that of STG. This is wrong,
usually resulting in "failed to record execution log" errors when trying
to record code with any of these instructions.
This patch fixes the recording of these instructions.
gdb/ChangeLog:
PR tdep/26916
* s390-tdep.c (s390_process_record): Fix recording of STOC, STOCG,
and STOCFH.
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -5332,7 +5332,6 @@ ex:
case 0xe325: /* NTSTG - nontransactional store */
case 0xe326: /* CVDY - convert to decimal */
case 0xe32f: /* STRVG - store reversed */
- case 0xebe3: /* STOCG - store on condition */
case 0xed67: /* STDY - store */
oaddr = s390_record_calc_disp (gdbarch, regcache, inib[3], insn[1], ibyte[4]);
if (record_full_arch_list_add_mem (oaddr, 8))
@@ -5361,8 +5360,6 @@ ex:
case 0xe33e: /* STRV - store reversed */
case 0xe350: /* STY - store */
case 0xe3cb: /* STFH - store high */
- case 0xebe1: /* STOCFH - store high on condition */
- case 0xebf3: /* STOC - store on condition */
case 0xed66: /* STEY - store */
oaddr = s390_record_calc_disp (gdbarch, regcache, inib[3], insn[1], ibyte[4]);
if (record_full_arch_list_add_mem (oaddr, 4))
@@ -6075,6 +6072,20 @@ ex:
/* 0xeb9c-0xebbf undefined */
/* 0xebc1-0xebdb undefined */
+
+ case 0xebe1: /* STOCFH - store high on condition */
+ case 0xebf3: /* STOC - store on condition */
+ oaddr = s390_record_calc_disp (gdbarch, regcache, 0, insn[1], ibyte[4]);
+ if (record_full_arch_list_add_mem (oaddr, 4))
+ return -1;
+ break;
+
+ case 0xebe3: /* STOCG - store on condition */
+ oaddr = s390_record_calc_disp (gdbarch, regcache, 0, insn[1], ibyte[4]);
+ if (record_full_arch_list_add_mem (oaddr, 8))
+ return -1;
+ break;
+
/* 0xebe5 undefined */
/* 0xebe9 undefined */
/* 0xebeb-0xebf1 undefined */

View File

@ -0,0 +1,573 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Keith Seitz <keiths@redhat.com>
Date: Wed, 2 Dec 2020 17:39:33 -0500
Subject: gdb-rhbz1905701-DWARF-data_location.patch
;; Backport "fortran dynamic type related fixes"
;; Andrew Burgess (RH BZ 1905701)
commit e79eb02f2f09baecffb144bac6804f975065466f
gdb/fortran: resolve dynamic types when readjusting after an indirection
After dereferencing a pointer (in value_ind) or following a
reference (in coerce_ref) we call readjust_indirect_value_type to
"fixup" the type of the resulting value object.
This fixup handles cases relating to the type of the resulting object
being different (a sub-class) of the original pointers target type.
If we encounter a pointer to a dynamic type then after dereferencing a
pointer (in value_ind) the type of the object created will have had
its dynamic type resolved. However, in readjust_indirect_value_type,
we use the target type of the original pointer to "fixup" the type of
the resulting value. In this case, the target type will be a dynamic
type, so the resulting value object, once again has a dynamic type.
This then triggers an assertion later within GDB.
The solution I propose here is that we call resolve_dynamic_type on
the pointer's target type (within readjust_indirect_value_type) so
that the resulting value is not converted back to a dynamic type.
The test case is based on the original test in the bug report.
gdb/ChangeLog:
PR fortran/23051
PR fortran/26139
* valops.c (value_ind): Pass address to
readjust_indirect_value_type.
* value.c (readjust_indirect_value_type): Make parameter
non-const, and add extra address parameter. Resolve original type
before using it.
* value.h (readjust_indirect_value_type): Update function
signature and comment.
gdb/testsuite/ChangeLog:
PR fortran/23051
PR fortran/26139
* gdb.fortran/class-allocatable-array.exp: New file.
* gdb.fortran/class-allocatable-array.f90: New file.
* gdb.fortran/pointer-to-pointer.exp: New file.
* gdb.fortran/pointer-to-pointer.f90: New file.
diff --git a/gdb/testsuite/gdb.dwarf2/graalvm-data-loc2.c b/gdb/testsuite/gdb.dwarf2/graalvm-data-loc2.c
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/graalvm-data-loc2.c
@@ -0,0 +1,63 @@
+/* Copyright 2014-2020 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* This C file simulates the implementation of object pointers in
+ GraalVM Java native images where the object data is not addressed
+ directly. It serves as a regression test for a bug where printing
+ of such redirected data structures suffers from a gdb exception.
+
+ Debugging information on how to decode an object pointer to
+ identify the address of the underlying data will be generated
+ separately by the testcase using that file. */
+
+#include <stdlib.h>
+#include <string.h>
+
+struct Object {
+ struct Object *next;
+ int val;
+};
+
+struct Object *testOop;
+
+extern int debugMe() {
+ return 0;
+}
+
+struct Object *newObject() {
+ char *bytes = malloc(sizeof(struct Object));
+ return (struct Object *)bytes;
+}
+
+int
+main (void)
+{
+ struct Object *obj1 = newObject();
+ struct Object *obj2 = newObject();
+ struct Object *obj3 = newObject();
+ obj1->val = 0;
+ obj2->val = 1;
+ obj3->val = 2;
+
+ obj1->next = obj2;
+ obj2->next = obj3;
+ obj3->next = obj1;
+
+ testOop = obj1;
+
+ return debugMe();
+}
diff --git a/gdb/testsuite/gdb.dwarf2/graalvm-data-loc2.exp b/gdb/testsuite/gdb.dwarf2/graalvm-data-loc2.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/graalvm-data-loc2.exp
@@ -0,0 +1,122 @@
+# Copyright 2014-2020 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if {![dwarf2_support]} {
+ return 0
+}
+
+standard_testfile .c -dw.S
+
+if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } {
+ return -1
+}
+
+# Make some DWARF for the test.
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+
+ cu {} {
+ DW_TAG_compile_unit {
+ {DW_AT_language @DW_LANG_C99}
+ {DW_AT_name data-loc2.c}
+ {DW_AT_comp_dir /tmp}
+ } {
+ declare_labels integer_label struct_label pointer_label
+
+ integer_label: DW_TAG_base_type {
+ {DW_AT_byte_size 4 DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_signed}
+ {DW_AT_name integer}
+ }
+
+ struct_label: DW_TAG_structure_type {
+ {DW_AT_name "Object"}
+ {DW_AT_byte_size 20 DW_FORM_sdata}
+ {DW_AT_data_location {
+ DW_OP_push_object_address
+ } SPECIAL_expr}
+ } {
+ member {
+ {name next}
+ {type :$pointer_label}
+ {data_member_location 0 data1}
+ }
+ member {
+ {name val}
+ {type :$integer_label}
+ {data_member_location 8 data1}
+ }
+ }
+ pointer_label: DW_TAG_pointer_type {
+ {DW_AT_byte_size 4 DW_FORM_sdata}
+ {DW_AT_type :$struct_label}
+ }
+ DW_TAG_variable {
+ {DW_AT_name testOop}
+ {DW_AT_type :$pointer_label}
+ {DW_AT_location {
+ DW_OP_addr [gdb_target_symbol testOop]
+ } SPECIAL_expr}
+ {external 1 flag}
+ }
+ }
+ }
+}
+
+# Now that we've generated the DWARF debugging info, rebuild our
+# program using our debug info instead of the info generated by
+# the compiler.
+
+if { [prepare_for_testing "failed to prepare" ${testfile} \
+ [list $srcfile $asm_file] {nodebug}] } {
+ return -1
+}
+
+if ![runto_main] {
+ return -1
+}
+
+# ensure the object network is set up as expected and check that
+# printing of structs which employ the data_location does not
+# fail with a gdb exception
+
+gdb_test "break debugMe" \
+ "Breakpoint .*" \
+ "set breakpoint at debugMe"
+
+gdb_continue_to_breakpoint "continue to debugMe"
+
+gdb_test "print testOop->val" \
+ ".* = 0"
+
+gdb_test "print testOop->next->val" \
+ ".* = 1"
+
+gdb_test "print testOop->next->next->val" \
+ ".* = 2"
+
+gdb_test "print *testOop" \
+ ".* = {next = .*, val = 0}" \
+ "print contents of struct"
+
+gdb_test "print *testOop->next" \
+ ".* = {next = .*, val = 1}" \
+ "print contents of an indirect struct"
+
+gdb_test "print *testOop->next->next" \
+ ".* = {next = .*, val = 2}" \
+ "print contents of a double indirect struct"
diff --git a/gdb/testsuite/gdb.fortran/class-allocatable-array.exp b/gdb/testsuite/gdb.fortran/class-allocatable-array.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/class-allocatable-array.exp
@@ -0,0 +1,43 @@
+# Copyright 2020 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/> .
+
+# Test that GDB can print an allocatable array that is a data field
+# within a class like type.
+
+if {[skip_fortran_tests]} { return -1 }
+
+standard_testfile ".f90"
+load_lib fortran.exp
+
+if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \
+ {debug f90}]} {
+ return -1
+}
+
+if {![runto MAIN__]} {
+ untested main"could not run to main"
+ return -1
+}
+
+gdb_breakpoint [gdb_get_line_number "Break Here"]
+gdb_continue_to_breakpoint "Break Here"
+
+# If this first test fails then the Fortran compiler being used uses
+# different names, or maybe a completely different approach, for
+# representing class like structures. The following tests are
+# cetainly going to fail.
+gdb_test "print this" " = \\( _data = \[^\r\n\]+, _vptr = \[^\r\n\]+\\)"
+gdb_test "print this%_data" " = \\(PTR TO -> \\( Type test_type \\)\\) \[^\r\n\]+"
+gdb_test "print this%_data%b" " = \\(\\( 1, 2, 3\\) \\( 4, 5, 6\\) \\)"
diff --git a/gdb/testsuite/gdb.fortran/class-allocatable-array.f90 b/gdb/testsuite/gdb.fortran/class-allocatable-array.f90
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/class-allocatable-array.f90
@@ -0,0 +1,54 @@
+! Copyright 2020 Free Software Foundation, Inc.
+!
+! This program is free software; you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation; either version 3 of the License, or
+! (at your option) any later version.
+!
+! This program is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+module test_module
+ type test_type
+ integer a
+ real, allocatable :: b (:, :)
+ contains
+ procedure :: test_proc
+ end type test_type
+
+contains
+
+ subroutine test_proc (this)
+ class(test_type), intent (inout) :: this
+ allocate (this%b (3, 2))
+ call fill_array_2d (this%b)
+ print *, "" ! Break Here
+ contains
+ ! Helper subroutine to fill 2-dimensional array with unique
+ ! values.
+ subroutine fill_array_2d (array)
+ real, dimension (:,:) :: array
+ real :: counter
+
+ counter = 1.0
+ do i=LBOUND (array, 2), UBOUND (array, 2), 1
+ do j=LBOUND (array, 1), UBOUND (array, 1), 1
+ array (j,i) = counter
+ counter = counter + 1
+ end do
+ end do
+ end subroutine fill_array_2d
+ end subroutine test_proc
+end module
+
+program test
+ use test_module
+ implicit none
+ type(test_type) :: t
+ call t%test_proc ()
+end program test
diff --git a/gdb/testsuite/gdb.fortran/pointer-to-pointer.exp b/gdb/testsuite/gdb.fortran/pointer-to-pointer.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/pointer-to-pointer.exp
@@ -0,0 +1,46 @@
+# Copyright 2020 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/> .
+
+# Test for GDB printing a pointer to a type containing a buffer.
+
+if {[skip_fortran_tests]} { return -1 }
+
+standard_testfile ".f90"
+load_lib fortran.exp
+
+if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \
+ {debug f90}]} {
+ return -1
+}
+
+if {![runto MAIN__]} {
+ untested "could not run to main"
+ return -1
+}
+
+gdb_breakpoint [gdb_get_line_number "Break Here"]
+gdb_continue_to_breakpoint "Break Here"
+
+gdb_test "print *buffer" \
+ " = \\( alpha = \\(1\\.5, 2\\.5, 3\\.5, 4\\.5, 5\\.5\\) \\)"
+
+set l_buffer_type [multi_line \
+ "Type l_buffer" \
+ " real\\(kind=4\\) :: alpha\\(.\\)" \
+ "End Type l_buffer" ]
+
+gdb_test "ptype buffer" "type = PTR TO -> \\( ${l_buffer_type} \\)"
+gdb_test "ptype *buffer" "type = ${l_buffer_type}"
+gdb_test "ptype buffer%alpha" "type = real\\(kind=4\\) \\(5\\)"
diff --git a/gdb/testsuite/gdb.fortran/pointer-to-pointer.f90 b/gdb/testsuite/gdb.fortran/pointer-to-pointer.f90
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/pointer-to-pointer.f90
@@ -0,0 +1,34 @@
+! Copyright 2020 Free Software Foundation, Inc.
+!
+! This program is free software; you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation; either version 3 of the License, or
+! (at your option) any later version.
+!
+! This program is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+program allocate_array
+
+ type l_buffer
+ real, dimension(:), pointer :: alpha
+ end type l_buffer
+ type(l_buffer), pointer :: buffer
+
+ allocate (buffer)
+ allocate (buffer%alpha (5))
+
+ buffer%alpha (1) = 1.5
+ buffer%alpha (2) = 2.5
+ buffer%alpha (3) = 3.5
+ buffer%alpha (4) = 4.5
+ buffer%alpha (5) = 5.5
+
+ print *, buffer%alpha ! Break Here.
+
+end program allocate_array
diff --git a/gdb/valops.c b/gdb/valops.c
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -1573,42 +1573,34 @@ value_ind (struct value *arg1)
if (TYPE_CODE (base_type) == TYPE_CODE_PTR)
{
struct type *enc_type;
- CORE_ADDR addr;
-
- if (type_not_associated (base_type))
- error (_("Attempt to take contents of a not associated pointer."));
-
- if (NULL != TYPE_DATA_LOCATION (TYPE_TARGET_TYPE (base_type)))
- addr = value_address (arg1);
- else
- addr = value_as_address (arg1);
-
- if (addr != 0)
- TYPE_TARGET_TYPE (base_type) =
- resolve_dynamic_type (TYPE_TARGET_TYPE (base_type), NULL, addr);
/* We may be pointing to something embedded in a larger object.
Get the real type of the enclosing object. */
enc_type = check_typedef (value_enclosing_type (arg1));
enc_type = TYPE_TARGET_TYPE (enc_type);
+ CORE_ADDR base_addr;
if (TYPE_CODE (check_typedef (enc_type)) == TYPE_CODE_FUNC
|| TYPE_CODE (check_typedef (enc_type)) == TYPE_CODE_METHOD)
- /* For functions, go through find_function_addr, which knows
- how to handle function descriptors. */
- arg2 = value_at_lazy (enc_type,
- find_function_addr (arg1, NULL));
+ {
+ /* For functions, go through find_function_addr, which knows
+ how to handle function descriptors. */
+ base_addr = find_function_addr (arg1, NULL);
+ }
else
- /* Retrieve the enclosing object pointed to. */
- arg2 = value_at_lazy (enc_type,
- (addr - value_pointed_to_offset (arg1)));
+ {
+ /* Retrieve the enclosing object pointed to. */
+ base_addr = (value_as_address (arg1)
+ - value_pointed_to_offset (arg1));
+ }
+ arg2 = value_at_lazy (enc_type, base_addr);
enc_type = value_type (arg2);
- return readjust_indirect_value_type (arg2, enc_type, base_type, arg1);
+ return readjust_indirect_value_type (arg2, enc_type, base_type,
+ arg1, base_addr);
}
error (_("Attempt to take contents of a non-pointer value."));
- return 0; /* For lint -- never reached. */
}
/* Create a value for an array by allocating space in GDB, copying the
diff --git a/gdb/value.c b/gdb/value.c
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -3611,10 +3611,19 @@ coerce_ref_if_computed (const struct value *arg)
struct value *
readjust_indirect_value_type (struct value *value, struct type *enc_type,
const struct type *original_type,
- const struct value *original_value)
+ struct value *original_value,
+ CORE_ADDR original_value_address)
{
+ gdb_assert (TYPE_CODE (original_type) == TYPE_CODE_PTR
+ || TYPE_IS_REFERENCE (original_type));
+
+ struct type *original_target_type = TYPE_TARGET_TYPE (original_type);
+ struct type *resolved_original_target_type
+ = resolve_dynamic_type (original_target_type, NULL,
+ original_value_address);
+
/* Re-adjust type. */
- deprecated_set_value_type (value, TYPE_TARGET_TYPE (original_type));
+ deprecated_set_value_type (value, resolved_original_target_type);
/* Add embedding info. */
set_value_enclosing_type (value, enc_type);
@@ -3641,12 +3650,11 @@ coerce_ref (struct value *arg)
enc_type = check_typedef (value_enclosing_type (arg));
enc_type = TYPE_TARGET_TYPE (enc_type);
- retval = value_at_lazy (enc_type,
- unpack_pointer (value_type (arg),
- value_contents (arg)));
+ CORE_ADDR addr = unpack_pointer (value_type (arg), value_contents (arg));
+ retval = value_at_lazy (enc_type, addr);
enc_type = value_type (retval);
- return readjust_indirect_value_type (retval, enc_type,
- value_type_arg_tmp, arg);
+ return readjust_indirect_value_type (retval, enc_type, value_type_arg_tmp,
+ arg, addr);
}
struct value *
diff --git a/gdb/value.h b/gdb/value.h
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -487,7 +487,9 @@ extern struct value *coerce_ref_if_computed (const struct value *arg);
/* Setup a new value type and enclosing value type for dereferenced value VALUE.
ENC_TYPE is the new enclosing type that should be set. ORIGINAL_TYPE and
- ORIGINAL_VAL are the type and value of the original reference or pointer.
+ ORIGINAL_VAL are the type and value of the original reference or
+ pointer. ORIGINAL_VALUE_ADDRESS is the address within VALUE, that is
+ the address that was dereferenced.
Note, that VALUE is modified by this function.
@@ -496,7 +498,8 @@ extern struct value *coerce_ref_if_computed (const struct value *arg);
extern struct value * readjust_indirect_value_type (struct value *value,
struct type *enc_type,
const struct type *original_type,
- const struct value *original_val);
+ struct value *original_val,
+ CORE_ADDR original_value_address);
/* Convert a REF to the object referenced. */

View File

@ -26,7 +26,7 @@ Version: 8.2
# The release always contains a leading reserved number, start it at 1.
# `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing.
Release: 12%{?dist}
Release: 15%{?dist}
License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and LGPLv3+ and BSD and Public Domain and GFDL
Group: Development/Debuggers
@ -57,8 +57,21 @@ Recommends: dnf-command(debuginfo-install)
# below, but it cannot hurt either -- rdieter
Conflicts: gdb-headless < 7.12-29
# Do not permit installations of 32-bit package. RH BZ 1853140
%ifarch %{ix86}
Conflicts: libc.so.6()(64bit)
%endif
Summary: A stub package for GNU source-level debugger
Requires: gdb-headless%{?_isa} = %{version}-%{release}
# Obsolete previous versions with this version, which should force users
# of the i686 package to update/install the x86_64 version.
# RH BZ 1853140
%ifarch x86_64
Provides: gdb = %{version}-%{release}
Obsoletes: gdb < %{version}-%{release}
%endif
%endif
%description
'gdb' package is only a stub to install gcc-gdb-plugin for 'compile' commands.
@ -66,6 +79,13 @@ See package 'gdb-headless'.
%package headless
Group: Development/Debuggers
# Obsolete previous versions with this version, which should force users
# of the i686 package to update/install the x86_64 version.
# RH BZ 1853140
%ifarch x86_64
Provides: gdb-headless = %{version}-%{release}
Obsoletes: gdb-headless < %{version}-%{release}
%endif
Summary: A GNU source-level debugger for C, C++, Fortran, Go and other languages
@ -379,6 +399,14 @@ and printing their data.
Summary: A standalone server for GDB (the GNU source-level debugger)
Group: Development/Debuggers
# Obsolete previous versions with this version, which should force users
# of the i686 package to update/install the x86_64 version.
# RH BZ 1853140
%ifarch x86_64
Provides: gdb-gdbserver = %{version}-%{release}
Obsoletes: gdb-gdbserver < %{version}-%{release}
%endif
%description gdbserver
GDB, the GNU debugger, allows you to debug programs written in C, C++,
Java, and other languages, by executing them in a controlled fashion
@ -1034,6 +1062,25 @@ fi
%endif
%changelog
* Fri Dec 11 2020 Keith Seitz <keiths@redhat.com> - 8.2-15.el8
- Backport "Correct recording of 'store on condition' insns"
(Andreas Arnaz, RH BZ 1903374)
- Backport "Fortran dynamic type related fixes"
(Andrew Burgess, RH BZ 1905701)
* Fri Nov 13 2020 Keith Seitz <keiths@redhat.com> - 8.2-14.el8
- Obsolete earlier versions on x86_64 and conflict with 64-bit
glibc on ix86. (Keith Seitz, RH BZ 1853140)
- Really fix 1878810 (Keith Seitz, RH BZ 1878810)
* Wed Nov 4 2020 Keith Seitz <keiths@redhat.com> - 8.2-13.el8
- Backport "Fix terminal problems when error() is called."
(Alan Hayward RH BZ 1852580)
- Backport "core file memory access problem."
(Kevin Buettner, RH BZ 1785126)
- Backport "Stop the BFD library from issuing a warning message..."
(Nick Clifton, RH BZ 1878810)
* Tue May 12 2020 Keith Seitz <keiths@redhat.com> - 8.2-12.el8
- Include support for z15 record/replay (RH BZ 1659535)