This is the mail archive of the gdb@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: relocation of shared libs not based at 0


I've been spending some time chasing this issue since it's fairly important
to us.  It looks to me like Paul is correct in his assessment that the
shared library loader is the problem.  Apparently, on NetBSD and QNX, the
loader uses the load address of the section as the base address.  Linux (and
perhaps others) use the difference between the link address and the load
address.

What I had done to examine this was build shared libs with the normal 0
v_addr and also created some with an ld that had
"SHLIB_TEXT_START_ADDR=0xb0300000" (or some such) defined in its linker
script.  This would give me a library with characteristics like so:

kewarken@stimpy:~/test$ objdump -p libodd.so

libodd.so:     file format elf32-i386

Program Header:
    LOAD off    0x00000000 vaddr 0xb0300000 paddr 0xb0300000 align 2**12
         filesz 0x00000804 memsz 0x00000804 flags r-x

Now I wasn't able to get this test to work on Solaris - programs linked to a
lib built this way would always crash when the loader ran.  On Linux,
however, I could link a program to one of these libs and check it out in the
debugger.  Just as Paul suggested, the run-time linker had filled in the
l_addr field in the link_map with 0 so "info shared" would show something
like:

>From        To          Syms Read   Shared Object Library
0x00000640  0x000007e0  Yes         ./libodd.so
0x40037f80  0x40119260  Yes         /lib/libc.so.6

instead of:

>From        To          Syms Read   Shared Object Library
0xb0300640  0xb03007e0  Yes         ./libodd.so
0x40037f80  0x40119260  Yes         /lib/libc.so.6

This works fine on QNX and (I assume) NetBSD so it looks rather like we just
have a difference of opinion on how the shared object loader should fill
things in.  We wanted to keep our linker's behaviour for some future
enhancements (pre-relocating shared objects on flash memory, etc.) so I was
hoping the fix below (Paul's code with some extra comments) might be
acceptable.  That way Paul and I could just define LM_ADDR_IS_NOT_LOAD_BASE
in our tm-<host>.h and we'd be off to the races.

static void
svr4_relocate_section_addresses (struct so_list *so,
                                 struct section_table *sec)
{
#if LM_ADDR_IS_NOT_LOAD_BASE
  /* On some platforms, (ie. QNX, NetBSD) LM_ADDR is the assigned
     address, not the offset.
     The addresses are formed as follows:
     LM_ADDR is the target address where the shared library file
     is mapped, so the actual section start address is LM_ADDR plus
     the section offset within the shared library file.  The end
     address is that plus the section length.  Note that we pay no
     attention to the section start address as recorded in the
     library header.
  */
   sec->endaddr = svr4_truncate_ptr (sec->endaddr - sec->addr +
      sec->the_bfd_section->filepos +
      LM_ADDR (so));
   sec->addr    = svr4_truncate_ptr (sec->the_bfd_section->filepos +
      LM_ADDR (so));
#else
  sec->addr    = svr4_truncate_ptr (sec->addr    + LM_ADDR (so));
  sec->endaddr = svr4_truncate_ptr (sec->endaddr + LM_ADDR (so));
#endif
}

----- Original Message -----
From: "Paul Koning" <pkoning@equallogic.com>
To: <kevinb@redhat.com>
Cc: <kewarken@qnx.com>; <gdb@sources.redhat.com>
Sent: Tuesday, December 17, 2002 7:47 PM
Subject: Re: relocation of shared libs not based at 0


> >>>>> "Kevin" == Kevin Buettner <kevinb@redhat.com> writes:
>
>  Kevin> ...
>  Kevin> So, as I understand it, the "base address" is *not* an
>  Kevin> absolute location, but is actually the difference between
>  Kevin> where the segment ended up and the location assigned to it in
>  Kevin> the executable file.  Thus the "base address" is the proper
>  Kevin> value to use to relocate the segment's start and end
>  Kevin> addresses.
>
> That interpretation certainly matches the code.  The document you
> quoted is not all that clearly worded, but it seems to take the same
> view of things.
>
> On the other hand, the shared library loader in NetBSD doesn't.  It
> sets the "base address" in the link_map to the load address of the
> section, not the bias from the link address to the load address.
> That's why I changed solib-svr4.c in my copy of gdb.
>
> Perhaps a better fix is to change the loader in NetBSD to set "base
> address" to match gdb's expectations.
>
>  Kevin> Now, it's possible that my understanding is flawed.  If so, I
>  Kevin> await enlightenment.  I think it's also possible that the
>  Kevin> shared library implementation that you're using might not
>  Kevin> conform to the above definition of "base address".  If that's
>  Kevin> the case, then you can either attempt to get it fixed in the
>  Kevin> code which implements the dynamic loader, or, if that's not
>  Kevin> possible, create a new solib backend for gdb which implements
>  Kevin> support for your shared library machinery.  I suspect it would
>  Kevin> be very similar to solib-svr4.c.
>
>  Kevin> With regard to the two patches that have been posted for
>  Kevin> fixing this problem, I don't think that either one is correct
>  Kevin> in light of the above definition of "base address".
>
> It would be interesting to hear from a NetBSD wizard.  I'd be happy
> with any fix that makes shared libs work in gdb for my platform.
>
> Part of the reason why I patched gdb rather than ldd.elf_so is so I
> could process coredumps from already shipped systems.  Then again,
> there are few enough of those that this isn't a big consideration.
>
>       paul
>
>


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