This is the mail archive of the binutils@sourceware.cygnus.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: dynamic relocations against stabs in a shared library


   Date: Sat, 15 May 1999 14:32:37 -0500 (EST)
   From: Jim Blandy <jimb@cygnus.com>

   What kinds of relocations is the linker supposed to produce for .stab
   sections in an ELF shared object file?  GCC seems to produce relocs
   that GDB doesn't know how to handle, unnecessarily.  I'd like some
   help from this list in deciding whether this is a linker bug, or a GDB
   bug.

Before I address your actual questions, let me note that the current
situation is confused.  I modified the linker to generate relocs for
.stab and .stabstr sections in shared libraries a couple of years ago.
However, I believe this may have been reverted for the i386 linker
only by a patch Ulrich checked in on December 1, 1998.  I'm not sure
about the current status.

My original conception was that when the linker saw a reloc to a .stab
or .stabstr section, and it was creating a shared library, it would
simply copy the reloc into the shared library.  That would permit gdb
to resolve the reloc at debug time in order to determine the correct
value.

This was intended to handle a case in which g++ emitted debugging
references to a symbol which was not defined in the shared library.
Copying the reloc was the only way to correctly record the debugging
information.

However, at the time gdb did not handle relocations, so was a
theoretical exercise.  The idea was to make it possible for gdb to do
the right thing, but gdb did not in fact do the right thing.

   In GDB, I'm trying to step into a call to a function in a shared
   object.  However, GDB steps *over* the call instead, as if I'd typed
   `next'.  (The call does execute correctly.)  Investigation reveals
   that GDB can't find the line number info for that function.  Since GDB
   can't step without line number info, it just lets the call finish.

   However, the shared object actually was compiled with debugging; GDB
   just hasn't gotten the addresses in the .stab entries right, so it
   can't find the relevant line number entry.  This is because the line
   number stabs in the shared object file have non-trivial relocs, when
   they should simply contain the code address relative to the shared
   object's text segment's VMA.

   I think this is a linker bug.  To relocate a shared object's stab
   section, GDB should simply need to add the right section's VMA to the
   appropriate values.  It knows which ones to relocate, and what they
   are relative to, from looking at the type of the .stab entry.  The
   linker should make things easy for GDB, since applying relocs is its
   area of expertise, and not GDB's.

I presume, based on your example, that this is for SPARC ELF.

   As I understand it, an ELF shared object's .stab section needs to have
   a .rel.stab or .rela.stab section, because function and line number
   STAB entries have pointers into the code, whose address isn't known
   until load time.  Similar for data.

I'm not sure that's quite right.  We need the relocations to handle a
somewhat unusual case, in which the debugging information refers to a
symbol which is not defined in the shared object.

If debugging information always referred to symbols defined in the
shared object, then no relocation entries would be needed.  Instead,
the linker would resolve all relocations as though the shared object
were loaded at address zero (or whatever address was specified in the
linker script).  It would then be gdb's responsibility to adjust the
debugging information by the load address of the shared object.

   To read the .stab section, GDB simply asks BFD for the contents of the
   .stab section (unrelocated --- using bfd_seek and bfd_read), and then
   scans the stabs entries.  When it finds a stabs entry whose value
   should be a text address, it simply adds in the base address of the
   text section.  And so on.

Yes, exactly.

   So, GDB seems to be assuming that relocations for the .stab section
   will all be REL-style (addend in the thing being relocated), not
   RELA-style, and *ABS* --- relative to no symbol.  These restrictions
   should be okay:
   - REL-style is all you need, since the only things you're relocating
     are simple 32-bit words --- you know the addend can fit in the
     relocatee.
   - *ABS* is all you need.  If there's any symbol involved, it's one
     from the shared object, whose value relative to the load address you
     already know, so you can just stick it in the relocatee.

   I concede the linker isn't *incorrect* in using more complicated
   relocs.  But it does mean that GDB has to get into the business of
   applying relocs to data in memory at debug time, which I think is
   icky.  That should be the linker's job.

I think that besides copying over the relocation entries, the linker
should also be resolving them.  I believe that is what happens on the
i386.  You seem to be saying that this is not happening.

Try the appended patch.  It doesn't address the general confusion, but
it may handle your case correctly.  I frankly don't know whether it is
a good idea or not.

Ian

Index: elf32-sparc.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf32-sparc.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 elf32-sparc.c
--- elf32-sparc.c	1999/05/03 07:28:56	1.1.1.1
+++ elf32-sparc.c	1999/05/17 03:54:39
@@ -1526,11 +1526,13 @@
 	      ++sreloc->reloc_count;
 
 	      /* This reloc will be computed at runtime, so there's no
-                 need to do anything now, unless this is a RELATIVE
-                 reloc in an unallocated section.  */
+                 need to do anything now.  However, if this is a
+                 RELATIVE or 32 reloc in an unallocated section, we
+                 resolve it now for the benefit of gdb.  */
 	      if (skip
 		  || (input_section->flags & SEC_ALLOC) != 0
-		  || ELF32_R_TYPE (outrel.r_info) != R_SPARC_RELATIVE)
+		  || (ELF32_R_TYPE (outrel.r_info) != R_SPARC_RELATIVE
+		      && ELF32_R_TYPE (outrel.r_info) != R_SPARC_32))
 		continue;
 	    }
 	  break;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]