This is the mail archive of the
libc-hacker@sourceware.cygnus.com
mailing list for the glibc project.
Re: dlsym() annoyance
- To: zack@rabi.phys.columbia.edu
- Subject: Re: dlsym() annoyance
- From: Geoff Keating <geoffk@ozemail.com.au>
- Date: Thu, 3 Sep 1998 23:30:31 +1000
- CC: roland@frob.com, libc-hacker@cygnus.com
- References: <199809021714.NAA20204@rabi.phys.columbia.edu>
> Date: Wed, 02 Sep 1998 13:14:31 -0400
> From: Zack Weinberg <zack@rabi.phys.columbia.edu>
> If I call dlsym(NULL, "sym") and sym is a function in libc that's referred
> to directly in the program, dlsym returns an address in the PLT, same as
> writing ptr = sym. If sym is not referred to directly, I get the actual
> address inside the shared library. Is there any way to force dlsym to give
> me the real address in all cases? (This is for testing purposes, so I don't
> mind calling internal entry points.)
Have you tried dlsym(RTLD_NEXT, "sym")? Or the same thing with the
handle for libc.so?
> (Incidentally, backtracesyms() is useless because it can only determine
> symbol names for exported symbols in shared libraries. You can't make up
> the difference with addr2line because it doesn't know about libraries or
> dynamically loaded objects.)
Use it like this:
[geoffk@geoffk /tmp]$ ldd `which make`
libc.so.6 => /lib/libc.so.6 (0x016d0000)
/lib/ld.so.1 => /lib/ld.so.1 (0x2aaab000)
Then suppose you want to know where 0x17195c8 is:
[geoffk@geoffk libc-ppc]$ addr2line -e /lib/libc.so.6 \
> `echo 'ibase=16 ; obase=10 ; 017195C8-016D0000' | bc`
/var/src/BUILD/glibc-2.0.94/stdio-common/fprintf.c:31
Note the annoying way you have to use capital letters for bc.
With really current glibc, you can find out where most things are by
looking at l_map_start and l_map_end in struct link_map; then l_addr
tells you the bias you need for addr2line. If l_map_* is ~0, you can
assume it's not calculated.
You can find the link_map structures by looking at _r_debug in
<link.h>. I don't know if this will work from an application, you may
need to have a small shared object to return &_r_debug---I'm not sure
if ld.so can handle shifting its variables into the executable.
Hmmm. I think I can see a bug in dl_addr. Shouldn't it be using
l_map_* rather than l_addr? For example, it can happen that l_addr==0
always, because it just happens that all the shared objects don't
overlap.
--
Geoffrey Keating <geoffk@ozemail.com.au>