import gdb-8.2-15.el8
This commit is contained in:
parent
2c3a1a6557
commit
0b0e7ac2d9
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
114
SOURCES/gdb-rhbz1842691-corefile-mem-access-10of15.patch
Normal file
114
SOURCES/gdb-rhbz1842691-corefile-mem-access-10of15.patch
Normal 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)
|
87
SOURCES/gdb-rhbz1842691-corefile-mem-access-11of15.patch
Normal file
87
SOURCES/gdb-rhbz1842691-corefile-mem-access-11of15.patch
Normal 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
|
||||
}
|
169
SOURCES/gdb-rhbz1842691-corefile-mem-access-12of15.patch
Normal file
169
SOURCES/gdb-rhbz1842691-corefile-mem-access-12of15.patch
Normal 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);
|
||||
}
|
41
SOURCES/gdb-rhbz1842691-corefile-mem-access-13of15.patch
Normal file
41
SOURCES/gdb-rhbz1842691-corefile-mem-access-13of15.patch
Normal 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.
|
439
SOURCES/gdb-rhbz1842691-corefile-mem-access-14of15.patch
Normal file
439
SOURCES/gdb-rhbz1842691-corefile-mem-access-14of15.patch
Normal 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 ();
|
||||
+}
|
30
SOURCES/gdb-rhbz1842691-corefile-mem-access-15of15.patch
Normal file
30
SOURCES/gdb-rhbz1842691-corefile-mem-access-15of15.patch
Normal 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);
|
||||
}
|
60
SOURCES/gdb-rhbz1842691-corefile-mem-access-1of15.patch
Normal file
60
SOURCES/gdb-rhbz1842691-corefile-mem-access-1of15.patch
Normal 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;
|
129
SOURCES/gdb-rhbz1842691-corefile-mem-access-2of15.patch
Normal file
129
SOURCES/gdb-rhbz1842691-corefile-mem-access-2of15.patch
Normal 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
|
174
SOURCES/gdb-rhbz1842691-corefile-mem-access-3of15.patch
Normal file
174
SOURCES/gdb-rhbz1842691-corefile-mem-access-3of15.patch
Normal 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);
|
||||
}
|
||||
}
|
||||
|
227
SOURCES/gdb-rhbz1842691-corefile-mem-access-4of15.patch
Normal file
227
SOURCES/gdb-rhbz1842691-corefile-mem-access-4of15.patch
Normal 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;
|
||||
|
68
SOURCES/gdb-rhbz1842691-corefile-mem-access-5of15.patch
Normal file
68
SOURCES/gdb-rhbz1842691-corefile-mem-access-5of15.patch
Normal 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
|
62
SOURCES/gdb-rhbz1842691-corefile-mem-access-6of15.patch
Normal file
62
SOURCES/gdb-rhbz1842691-corefile-mem-access-6of15.patch
Normal 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;
|
180
SOURCES/gdb-rhbz1842691-corefile-mem-access-7of15.patch
Normal file
180
SOURCES/gdb-rhbz1842691-corefile-mem-access-7of15.patch
Normal 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
|
||||
}
|
||||
|
532
SOURCES/gdb-rhbz1842691-corefile-mem-access-8of15.patch
Normal file
532
SOURCES/gdb-rhbz1842691-corefile-mem-access-8of15.patch
Normal 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,
|
101
SOURCES/gdb-rhbz1842691-corefile-mem-access-9of15.patch
Normal file
101
SOURCES/gdb-rhbz1842691-corefile-mem-access-9of15.patch
Normal 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;
|
||||
}
|
||||
}
|
164
SOURCES/gdb-rhbz1852580-terminal-woes.patch
Normal file
164
SOURCES/gdb-rhbz1852580-terminal-woes.patch
Normal 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"
|
@ -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));
|
64
SOURCES/gdb-rhbz1903374-s390x-store-on-condition.patch
Normal file
64
SOURCES/gdb-rhbz1903374-s390x-store-on-condition.patch
Normal 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 */
|
573
SOURCES/gdb-rhbz1905701-DWARF-data_location.patch
Normal file
573
SOURCES/gdb-rhbz1905701-DWARF-data_location.patch
Normal 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. */
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user