6a0ae4a
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
6a0ae4a
From: Kevin Buettner <kevinb@redhat.com>
6a0ae4a
Date: Tue, 1 Feb 2022 11:32:48 -0700
6a0ae4a
Subject: gdb-rhbz2042664-fix-sect_index_data-internal-error
6a0ae4a
6a0ae4a
;; Backport fix which fixes internal error due to libcc_s lacking a
6a0ae4a
;; .data section.
6a0ae4a
6a0ae4a
Fix GDB internal error by using text (instead of data) section offset
6a0ae4a
6a0ae4a
Fedora Rawhide is now using gcc-12.0.  As part of updating to the
6a0ae4a
gcc-12.0 package set, Rawhide is also now using a version of libgcc_s
6a0ae4a
which lacks a .data section.  This causes gdb to fail in the following
6a0ae4a
fashion while debugging a program (such as gdb) which uses libgcc_s:
6a0ae4a
6a0ae4a
    (top-gdb) run
6a0ae4a
    Starting program: rawhide-master/bld/gdb/gdb
6a0ae4a
    ...
6a0ae4a
    objfiles.h:467: internal-error: sect_index_data not initialized
6a0ae4a
    A problem internal to GDB has been detected,
6a0ae4a
    further debugging may prove unreliable.
6a0ae4a
    ...
6a0ae4a
6a0ae4a
I snipped the backtrace from the above output.  Instead, here's a
6a0ae4a
portion of a backtrace obtained using GDB's backtrace command.
6a0ae4a
(Obviously, in order to obtain it, I used a GDB which has been patched
6a0ae4a
with this commit.)
6a0ae4a
6a0ae4a
    #0  internal_error (
6a0ae4a
	file=0xc6a508 "gdb/objfiles.h", line=467,
6a0ae4a
	fmt=0xc6a4e8 "sect_index_data not initialized")
6a0ae4a
	at gdbsupport/errors.cc:51
6a0ae4a
    #1  0x00000000005f9651 in objfile::data_section_offset (this=0x4fa48f0)
6a0ae4a
	at gdb/objfiles.h:467
6a0ae4a
    #2  0x000000000097c5f8 in relocate_address (address=0x17244, objfile=0x4fa48f0)
6a0ae4a
	at gdb/stap-probe.c:1333
6a0ae4a
    #3  0x000000000097c630 in stap_probe::get_relocated_address (this=0xa1a17a0,
6a0ae4a
	objfile=0x4fa48f0)
6a0ae4a
	at gdb/stap-probe.c:1341
6a0ae4a
    #4  0x00000000004d7025 in create_exception_master_breakpoint_probe (
6a0ae4a
	objfile=0x4fa48f0)
6a0ae4a
	at gdb/breakpoint.c:3505
6a0ae4a
    #5  0x00000000004d7426 in create_exception_master_breakpoint ()
6a0ae4a
	at gdb/breakpoint.c:3575
6a0ae4a
    #6  0x00000000004efcc1 in breakpoint_re_set ()
6a0ae4a
	at gdb/breakpoint.c:13407
6a0ae4a
    #7  0x0000000000956998 in solib_add (pattern=0x0, from_tty=0, readsyms=1)
6a0ae4a
	at gdb/solib.c:1001
6a0ae4a
    #8  0x00000000009576a8 in handle_solib_event ()
6a0ae4a
	at gdb/solib.c:1269
6a0ae4a
    ...
6a0ae4a
6a0ae4a
The function 'relocate_address' in gdb/stap-probe.c attempts to do
6a0ae4a
its "relocation" by using objfile->data_section_offset().  That
6a0ae4a
method, data_section_offset() is defined as follows in objfiles.h:
6a0ae4a
6a0ae4a
  CORE_ADDR data_section_offset () const
6a0ae4a
  {
6a0ae4a
    return section_offsets[SECT_OFF_DATA (this)];
6a0ae4a
  }
6a0ae4a
6a0ae4a
The internal error occurs when the SECT_OFF_DATA macro finds that the
6a0ae4a
'sect_index_data' field is -1:
6a0ae4a
6a0ae4a
    #define SECT_OFF_DATA(objfile) \
6a0ae4a
	 ((objfile->sect_index_data == -1) \
6a0ae4a
	  ? (internal_error (__FILE__, __LINE__, \
6a0ae4a
			     _("sect_index_data not initialized")), -1)	\
6a0ae4a
	  : objfile->sect_index_data)
6a0ae4a
6a0ae4a
relocate_address() is obtaining the section offset in order to compute
6a0ae4a
a relocated address.  For some ABIs, such as the System V ABI, the
6a0ae4a
section offsets will all be the same.  So for those ABIs, it doesn't
6a0ae4a
matter which offset is used.  However, other ABIs, such as the FDPIC
6a0ae4a
ABI, will have different offsets for the various sections.  Thus, for
6a0ae4a
those ABIs, it is vital that this and other relocation code use the
6a0ae4a
correct offset.
6a0ae4a
6a0ae4a
In stap_probe::get_relocated_address, the address to which to add the
6a0ae4a
offset (thus forming the relocated address) is obtained via
6a0ae4a
this->get_address (); get_address is a getter for m_address in
6a0ae4a
probe.h.  It's documented/defined as follows (also in probe.h):
6a0ae4a
6a0ae4a
  /* The address where the probe is inserted, relative to
6a0ae4a
     SECT_OFF_TEXT.  */
6a0ae4a
  CORE_ADDR m_address;
6a0ae4a
6a0ae4a
(Thanks to Tom Tromey for this observation.)
6a0ae4a
6a0ae4a
So, based on this, the current use of data_section_offset /
6a0ae4a
SECT_OFF_DATA is wrong.  This relocation code should have been using
6a0ae4a
text_section_offset / SECT_OFF_TEXT all along.  That being the
6a0ae4a
case, I've adjusted the stap-probe.c relocation code accordingly.
6a0ae4a
6a0ae4a
Searching the sources turned up one other use of data_section_offset,
6a0ae4a
in gdb/dtrace-probe.c, so I've updated that code as well.  The same
6a0ae4a
reasoning presented above applies to this case too.
6a0ae4a
6a0ae4a
Summary:
6a0ae4a
6a0ae4a
	* gdb/dtrace-probe.c (dtrace_probe::get_relocated_address):
6a0ae4a
	Use method text_section_offset instead of data_section_offset.
6a0ae4a
	* gdb/stap-probe.c (relocate_address): Likewise.
6a0ae4a
6a0ae4a
diff --git a/gdb/dtrace-probe.c b/gdb/dtrace-probe.c
6a0ae4a
--- a/gdb/dtrace-probe.c
6a0ae4a
+++ b/gdb/dtrace-probe.c
6a0ae4a
@@ -684,7 +684,7 @@ dtrace_probe::is_enabled () const
6a0ae4a
 CORE_ADDR
6a0ae4a
 dtrace_probe::get_relocated_address (struct objfile *objfile)
6a0ae4a
 {
6a0ae4a
-  return this->get_address () + objfile->data_section_offset ();
6a0ae4a
+  return this->get_address () + objfile->text_section_offset ();
6a0ae4a
 }
6a0ae4a
 
6a0ae4a
 /* Implementation of the get_argument_count method.  */
6a0ae4a
diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c
6a0ae4a
--- a/gdb/stap-probe.c
6a0ae4a
+++ b/gdb/stap-probe.c
6a0ae4a
@@ -1330,7 +1330,7 @@ stap_probe::parse_arguments (struct gdbarch *gdbarch)
6a0ae4a
 static CORE_ADDR
6a0ae4a
 relocate_address (CORE_ADDR address, struct objfile *objfile)
6a0ae4a
 {
6a0ae4a
-  return address + objfile->data_section_offset ();
6a0ae4a
+  return address + objfile->text_section_offset ();
6a0ae4a
 }
6a0ae4a
 
6a0ae4a
 /* Implementation of the get_relocated_address method.  */