This is the mail archive of the gdb-patches@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]

Re: [RFA] shared library address patch


On Feb 19,  3:33pm, Martin M. Hunt wrote:

> The following patch keeps GDB from relocating shared libraries on
> mipsel-linux-gnu out of the 32-bit address space.  On researching this, I
> noticed Maciej W. Rozycki proposed a similar fix back in July
> (see http://sources.redhat.com/ml/gdb-patches/2000-07/msg00260.html)
> 
> 2001-02-19  Martin M. Hunt  <hunt@redhat.com>
> 
> 	* solib-svr4.c (LM_ADDR): LM_ADDR is a signed offset, so
> 	extract_signed_integer() should be called instead of
> 	extract_address().

This change is approved.

I stared at this one a while because it looked wrong to me.  So I'm
going to provide here the additional details which convinced me it was
right.

First, I can find no reference to the ``l_addr'' field, nor even to
struct link_map in any of my SysV ABI documents.  I searched abi386-4.pdf,
gabi40.pdf, gabi41.pdf, and mipsabi.pdf which may be found at

    http://www.sco.com/developer/devspecs/

I would very much like to know where struct link_map is documented.

When you can't find a document, you fall back to the code (though
sometimes it's the other way around ;-) . Anyway, I looked at link.h
on my Linux box and see the following declaration for the ``l_addr''
member:

    ElfW(Addr) l_addr;		/* Base address shared object is loaded at.  */

It turns out that this declaration of l_addr is unsigned.  This is one
of the reasons why Martin's/Maciej's change looked wrong to me.  OTOH,
if you read the comment, it clearly uses the words "base address".  Base
addresses *are* discussed in chapter 5 of the SysV ABI.  In gabi41, on
page 5-5 it says the following:

    ...  The difference between the virtual address of any segment in
    memory and the corresponding virtual address in the file is thus a
    single constant value for any one executable or shared object in a
    given process.  This difference is the base address.

As we all know, differences can sometimes be negative, so it doesn't
sense for the base address to be considered as an unsigned value.

Finally, I looked to see how glibc computed the l_addr value.  It is
indeed computed as the difference between where the segment gets
loaded and (presumably - I got a bit confused at this point) the file
address.

The one concern I have regarding this change is that (unfortunately)
SVR4 and SunOS support are still tangled together in solib-svr4.c.
Thus, my concern is that this change will break SunOS (and some *BSD)
shared library support.

Kevin


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