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]

dynamic relocations against stabs in a shared library



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.

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.


Justification:

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.

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.

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.


Evidence:

$ cat dyn.c
dyn ()
{
  puts ("Hello.");
}
$ cat main.c
main ()
{
  puts ("before");
  dyn ();
  puts ("after");
}
$ make clean
rm -rf *.o *.so main bar
$ make main
gcc -g -save-temps   -c main.c -o main.o
gcc -g -save-temps -c -fpic -ffunction-sections dyn.c
gcc -g -save-temps -shared dyn.o -o libdyn.so
gcc -g -save-temps main.o libdyn.so -o main
$ LD_LIBRARY_PATH=`pwd` ./main
before
Hello.
after
$ gdb main
GNU gdb 4.17-gnupro-98r1 [...]
This GDB was configured as "sparc-sun-solaris2.5"...
(gdb) break main
Breakpoint 1 at 0x105ec: file main.c, line 3.
(gdb) run
Starting program: /mill/home/jimb/pr-world/100522-990316/mytestcase/main 
 
Breakpoint 1, main () at main.c:3
3         puts ("before");
(gdb) next
before
4         dyn ();
(gdb) step
Hello.
5         puts ("after");
(gdb) next
after
6       }
(gdb) 

At offset 0x114 in .stab, we have: 00000349 24000002 00000000
Or: { "dyn:F(0,1)", N_FUN, 0, 2, 0x000000 }
The address there is at offset 0x11c.

There's a reloc for it:
$ objdump -R libdyn.so | grep 11c
0000011c R_SPARC_32        dyn

And the address for the symbol is known:
$ objdump -T libdyn.so | grep dyn
libdyn.so:     file format elf32-sparc
00001764 g    DF .text  00000030 dyn

The value 0x1764 should just be stuck in the stabs entry directly,
and have an R_SPARC_RELATIVE *ABS* attached to it.  (Not actually
having a reference for the SPARC relocs in front of me, that's a total
guess.)

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