Hi,

 It seems that ELF shared library functions treat LM_ADDR (the base
address) as a memory address.  According to the ELF ABI, the base address,
despite its name, is not a memory address but a difference between the
link-time address and the load address.  Therefore it cannot be treated as
the shared object's start address, as this assumption fails whenever its
link-time address is non-zero.  Due to this bogus assumptions I've
observed such nonsense as a shared library starting at about 0xc0000000
and ending at about 0x20000000 (in an output of `info sharedlibrary) in
user level on a MIPS!

 The following patch fixes the problem for me.  It makes LM_ADDR be
treated according to the ABI (and reality) and also makes shared object's
start be calculated similarly to the way its end is.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: [EMAIL PROTECTED], PGP key available        +

diff -u --recursive --new-file gdb-5.0.macro/gdb/solib.c gdb-5.0/gdb/solib.c
--- gdb-5.0.macro/gdb/solib.c   Wed Apr  5 20:40:22 2000
+++ gdb-5.0/gdb/solib.c Sat Jun 17 13:10:40 2000
@@ -169,6 +171,7 @@
        are initialized when we actually add it to our symbol tables.  */
 
     bfd *abfd;
+    CORE_ADDR lmstart;         /* lower addr bound of mapped object */
     CORE_ADDR lmend;           /* upper addr bound of mapped object */
     char symbols_loaded;       /* flag: symbols read in yet? */
     char from_tty;             /* flag: print msgs? */
@@ -367,6 +370,7 @@
          object's file by the base address to which the object was actually
          mapped. */
       p->addr += LM_ADDR (so);
+      so->lmstart = min (p->addr, so->lmstart);
       p->endaddr += LM_ADDR (so);
       so->lmend = max (p->endaddr, so->lmend);
       if (STREQ (p->the_bfd_section->name, ".text"))
@@ -1092,6 +1096,7 @@
        = (struct so_list *) xmalloc (sizeof (struct so_list));
       struct cleanup *old_chain = make_cleanup (free, new);
       memset (new, 0, sizeof (*new));
+      new->lmstart = -1;
 
       new->lmaddr = lm;
       read_memory (lm, (char *) &(new->lm), sizeof (struct link_map));
@@ -1505,7 +1510,7 @@
            }
 
          printf_unfiltered ("%-*s", addr_width,
-                     local_hex_string_custom ((unsigned long) LM_ADDR (so),
+                     local_hex_string_custom ((unsigned long) so->lmstart,
                                               addr_fmt));
          printf_unfiltered ("%-*s", addr_width,
                         local_hex_string_custom ((unsigned long) so->lmend,
@@ -1552,7 +1557,7 @@
 
   for (so = so_list_head; so; so = so->next)
     {
-      if (LM_ADDR (so) <= address && address < so->lmend)
+      if (so->lmstart <= address && address < so->lmend)
        return (so->so_name);
     }
 

Reply via email to