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