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);
}