Blame SOURCES/gdb-rhbz1842691-corefile-mem-access-Xof15.patch

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