Mirror of the gdb mailing list
 help / color / mirror / Atom feed
* RE: relocation of shared libs not based at 0
@ 2003-02-12 18:37 Peter van der Veen
  0 siblings, 0 replies; 19+ messages in thread
From: Peter van der Veen @ 2003-02-12 18:37 UTC (permalink / raw)
  To: 'Kevin Buettner', 'Paul Koning'
  Cc: Kris Warkentin, 'gdb@sources.redhat.com',
	Peter van der Veen, Colin Burgess

> From: Kevin Buettner [mailto:kevinb@redhat.com]
> 
> On Feb 10,  5:45pm, Paul Koning wrote:
> 
> >  >> 2. Hack gdb so it looks at the section headers in the shared
> >  >> library file, to extract the start and length of the three
> >  >> regions.  Use that to identify the *ABS* symbols (i.e., p is bss
> >  >> since it's within the vaddr range of the bss section in the
> >  >> section headers), and then figure the correct relocation from
> >  >> that.
> >  >>
> >  >> I can do (2), and that has the advantage of working with existing
> >  >> binaries, but it seems ugly.  (1) sounds right.  There are two
> >  >> issues there, though.  One is that I don't know ld.  The other is
> >  >> that I'm guessing there must be SOME reason why *ABS* is used for
> >  >> the mips case, though I can't imagine any reason.
> >
> >  Kevin> (1) sounds right to me too, though I share your concern that
> >  Kevin> there may be some reason that ABS must be used the way it is
> >  Kevin> for mips.  I think you ought to ask about this on the binutils
> >  Kevin> list...
> >
> >  Kevin> If you have to do (2), I strongly encourage you to create a
> >  Kevin> new solib backend for it.
> >
> > I was looking at solib-svr4.c and found this interesting comment (in
> > svr4_relocate_main_executable):
> >
> >       /* It is necessary to relocate the objfile.  The amount to
> > 	 relocate by is simply the address at which we are stopped
> > 	 minus the starting address from the executable.
> >
> > 	 We relocate all of the sections by the same amount.  This
> > 	 behavior is mandated by recent editions of the System V ABI.
> > 	 According to the System V Application Binary Interface,
> > 	 Edition 4.1, page 5-5:
> >
> > 	   ...  Though the system chooses virtual addresses for
> > 	   individual processes, it maintains the segments' relative
> > 	   positions.  Because position-independent code uses relative
> > 	   addressesing between segments, the difference between
> > 	   virtual addresses in memory must match the difference
> > 	   between virtual addresses in the file.  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.  One use of the base address is to relocate the
> > 	   memory image of the program during dynamic linking.
> >
> > 	 The same language also appears in Edition 4.0 of the System V
> > 	 ABI and is left unspecified in some of the earlier editions.  */
> >
> > So if I read that right, it sounds like the NetBSD practice of doing
> > separate mappings for the text, data, and bss sections (rather than
> > leaving them at the same relative offset they were in the library
> > file) violates the SVR4 spec.
> 
> Yes, upon rereading that comment, I agree with you.
> 
> If you haven't already done so, you may want to take a look at the ABI
> yourself to make sure that the comment quotes the ABI correctly and
> to understand the context of the quote.  I wrote that comment, and
> I believe it to be accurate with sufficient context, but it doesn't
> hurt for someone else to double check.
> 
> You should also take a look at the processor specific supplement.  I
> don't think that the processor supplement will override the text
> quoted above from the generic part of the specification, but this
> possibility should be checked before declaring the NetBSD
> implementation wrong.
> 
> > Very interesting.  I'm not sure what to make of this.  It doesn't feel
> > like a bug; the NetBSD behavior certainly makes sense.
> >
> > That suggests at least two other approaches:
> >
> > 3. Change NetBSD ld.elf_so to do what the ABI spec requires, which
> >    means just one mapped region rather than three.
> >
> > 4. Change the linker so ld.elf_so can still use three regions, i.e.,
> >    align the start of each region on a page boundary.
> >
> > Yikes.  Now what?  I may end up just doing (2) for the sake of
> > in-house expedience, and hope someone more skilled in the art will
> > tackle the "right" solution.
> 
> If NetBSD wants to comply with the System V ABI (and if I've
> interpreted the text of the ABI correctly), then the dynamic linker
> needs fixing.
I'm not sure if this is what you are referring to, but here is what I have
observed. The System V ABI makes statements about base address, and relative
to that document base address is consistent. But the base address in the
l_addr field in link.h is not the same base address that the system V abi is
talking about. I think problems started when someone saw these both referred
to as "base address" and assumed they both where the same value. l_addr is
the address of the library at load time, but not the same value as the base
address in the ABI. I would think your comment that the NETBSD behaviour
does not feel like a bug is correct. I think the linux ld.so may treat both
base addresses as being the same thing, but I am not sure. 

> 
> I can understand wanting to do (2) for expediency's sake.  If you do
> so, please create a new solib backend.  Basically, this will consist
> of making a copy of solib-svr4.c and hacking on it 'til it works as
> desired.  (Some small configury changes will also be needed.)


^ permalink raw reply	[flat|nested] 19+ messages in thread
* RE: relocation of shared libs not based at 0
@ 2004-01-05 17:39 Paul Koning
  2004-01-09 22:48 ` Kevin Buettner
  0 siblings, 1 reply; 19+ messages in thread
From: Paul Koning @ 2004-01-05 17:39 UTC (permalink / raw)
  To: gdb

Continuing a thread from a long time ago...

On NetBSD/MIPS I was having trouble with shared library references,
which is caused by wrong relocation processing in solib-svr4.c.

Back in February 2003, I proposed a patch for this, but the reaction
wasn't really encouraging and I wasn't happy with the diagnosis I had
made at that time, anyway.

Recently I went back to this and analyzed the problem better.

The issue is very simple: solib-svr4.c assumes that the LM_ADDR
entries in the library file headers are offsets from the start VMA of
the library to the start VMA of that section.  In fact, they are not;
they are the start VMA of the section before relocation.

If the library VMA (as linked) is zero, as is the case on many targets
such as x86, then these two interpretations are identical.  On MIPS,
the as-linked base VMA is 0x5ffe0000, so the existing code produces
the wrong answer.

At the end of the earlier discussion it was pointed out that the SysV
ABI requires all sections of a library to be relocated by the same
amount, and it seemed that NetBSD wasn't obeying that.

It turns out that it is; I was confused about this and muddled the
picture.  And that's what was wrong with my earlier patch.

So the real answer is simple: the LM_ADDR entries have to be adjusted
by the as-linked start VMA of the library.  The only problem I ran
into is that I couldn't find a clean way to obtain that value in gdb.
I did come up with something that worked; if there are better ways to
do this I would be interested.

My fix is in a modified 5.3, but the relevant source is unchanged from
5.3 to 6.0.  So attached is a diff for 6.0 that shows the fix I
described.  

	    paul

--- gdb/solib-svr4.c.orig	Fri Jun 13 17:56:27 2003
+++ gdb/solib-svr4.c	Mon Jan  5 12:29:49 2004
@@ -1375,8 +1375,29 @@
 svr4_relocate_section_addresses (struct so_list *so,
                                  struct section_table *sec)
 {
-  sec->addr    = svr4_truncate_ptr (sec->addr    + LM_ADDR (so));
-  sec->endaddr = svr4_truncate_ptr (sec->endaddr + LM_ADDR (so));
+  CORE_ADDR reloc;
+  
+  /* On NetBSD/MIPS at least, the library is mapped in two pieces.
+     The section headers describe this: each shows the unrelocated
+     virtual address of the section.  To figure out the relocated
+     address, we have to adjust these by the base VMA of the library.
+     
+     There isn't a really clean way to figure out the offset of each
+     section.  "filepos" doesn't do it, because that is the 
+     file-relative offset, not the VMA offset.
+
+     So what we do is this: 
+     Pick up the VMA (given by the header) of the first section,
+     and subtract from that its filepos.  That's the unrelocated VMA
+     of the library.  Subtract that from the unrelocated VMA
+     of each section to get its relocation bias; add that to the
+     library load address to get the relocated address.
+  */
+  reloc = so->sections->the_bfd_section->vma -
+          so->sections->the_bfd_section->filepos;
+
+  sec->endaddr = svr4_truncate_ptr (sec->endaddr - reloc + LM_ADDR (so));
+  sec->addr    = svr4_truncate_ptr (sec->addr - reloc + LM_ADDR (so));
 }
 
 


^ permalink raw reply	[flat|nested] 19+ messages in thread
* Re: relocation of shared libs not based at 0
@ 2002-12-17 13:39 David Anderson
  0 siblings, 0 replies; 19+ messages in thread
From: David Anderson @ 2002-12-17 13:39 UTC (permalink / raw)
  To: gdb

"Kris Warkentin" <kewarken@qnx.com> writes:
>Can anyone with more knowledge than I enlighten me as to a) whether it is
>proper to allow shared objects to be non zero-based and b) a better way to
>do this.  I looked at putting it in solib-svr4.c but I don't have access to
>the bfd in there, at least in svr4_relocate_section_addresses().

While I cannot speak for gdb requirements, I can say
that there is no requirement in generic-SYSV that shared
objects start at a zero address.

SGI IRIX (which is SYSV based) has never used zero as the base
address for shared objects, but always pre-assigns a non-zero
base address at static link time (intending that the shared
object will start up faster if it can run at that address).

Regards
David B. Anderson davea@sgi.com http://reality.sgiweb.org/davea
[  "What could go wrong?"   -- Calvin  ]


^ permalink raw reply	[flat|nested] 19+ messages in thread
* relocation of shared libs not based at 0
@ 2002-12-17 12:23 Kris Warkentin
  2002-12-17 12:31 ` Paul Koning
  2002-12-17 16:28 ` Kevin Buettner
  0 siblings, 2 replies; 19+ messages in thread
From: Kris Warkentin @ 2002-12-17 12:23 UTC (permalink / raw)
  To: gdb

I recently came across a problem debugging a core file with some of our
older shared libs.  Info shared showed the relocations of the shared libs to
be mangled (offset to 0x60... range rather than 0xb0... range).  We had
recently changed our tools to always set the vaddr of shared libs to be zero
because of this but I was speaking to one of our architects and he says that
this shouldn't be.

One of the future optimizations we're looking at is pre-relocating shared
libs so that they can be executed in place (on flash for instance) and the
fact that the SysV stuff seems to assume that everything is based at zero is
not particularily compatable with that.  I've attached an ugly patch that
shows a fix.  This is for illustration only since solib.c is the wrong place
to put this but it makes it clear what the issue is.

Can anyone with more knowledge than I enlighten me as to a) whether it is
proper to allow shared objects to be non zero-based and b) a better way to
do this.  I looked at putting it in solib-svr4.c but I don't have access to
the bfd in there, at least in svr4_relocate_section_addresses().

cheers,

Kris

Index: solib.c
===================================================================
RCS file: /product/tools/gdb/gdb/solib.c,v
retrieving revision 1.4
diff -c -r1.4 solib.c
*** solib.c 14 Nov 2002 20:57:23 -0000 1.4
--- solib.c 17 Dec 2002 20:10:14 -0000
***************
*** 26,31 ****
--- 26,34 ----
  #include <fcntl.h>
  #include "gdb_string.h"
  #include "symtab.h"
+ #ifdef __QNXTARGET__
+ #include "elf-bfd.h"
+ #endif
  #include "bfd.h"
  #include "symfile.h"
  #include "objfiles.h"
***************
*** 206,211 ****
--- 209,229 ----
     expansion stuff?).
   */

+ #ifdef __QNXTARGET__
+ Elf_Internal_Phdr *find_load_phdr( bfd *abfd )
+ {
+ Elf32_Internal_Phdr *phdr;
+ unsigned int i;
+
+     phdr = elf_tdata (abfd)->phdr;
+     for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++) {
+  if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X))
+      return phdr;
+     }
+     return NULL;
+ }
+ #endif
+
  static int
  solib_map_sections (PTR arg)
  {
***************
*** 263,268 ****
--- 281,296 ----
           object's file by the base address to which the object was
actually
           mapped. */
        TARGET_SO_RELOCATE_SECTION_ADDRESSES (so, p);
+ #ifdef __QNXTARGET__
+       /* hack for solibs not based at 0 */
+       {
+        Elf32_Internal_Phdr *phdr = find_load_phdr(abfd);
+        if(phdr){
+          p->addr -= phdr->p_vaddr;
+          p->endaddr -= phdr->p_vaddr;
+        }
+       }
+ #endif
        if (STREQ (p->the_bfd_section->name, ".text"))
   {
     so->textsection = p;


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2004-01-09 22:48 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-02-12 18:37 relocation of shared libs not based at 0 Peter van der Veen
  -- strict thread matches above, loose matches on Subject: below --
2004-01-05 17:39 Paul Koning
2004-01-09 22:48 ` Kevin Buettner
2002-12-17 13:39 David Anderson
2002-12-17 12:23 Kris Warkentin
2002-12-17 12:31 ` Paul Koning
2002-12-17 13:36   ` Kris Warkentin
2002-12-17 16:28 ` Kevin Buettner
2002-12-17 16:47   ` Paul Koning
2003-01-08 21:52     ` Kris Warkentin
2003-01-08 22:24       ` Kevin Buettner
2003-01-09 14:35         ` Colin Burgess
2003-01-09 15:06           ` Kris Warkentin
2003-02-05 18:40       ` Paul Koning
2003-02-05 19:08         ` Kris Warkentin
2003-02-05 19:11         ` Kevin Buettner
2003-02-10 21:45           ` Paul Koning
2003-02-12 18:06             ` Kevin Buettner
2003-02-12 18:19               ` Kris Warkentin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox