This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.


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

Re: dlsym() annoyance


> 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>


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