This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Mapping Addresses for Shared Library Routines to Code


On 02/04/2010 06:25 PM, John Reiser wrote:
My question is: How can I figure out what
dynamically loaded routine corresponds to
those addresses in the trace? Is there some
utility to "preload" and give me a symbol
table?
It depends on when you want to do the mapping: at run time, or later?
I think we do do it either way but later might work out
to be less intrusive because we could do that as part of
the analysis like we run nm now.   But if we have to
do it when the program is run, that would be OK.  We
already have to do this to run say echo.

qemu-i386 -d in_asm /bin/echo Hello World

So if we had to insert a wedge to catch dlopen calls, we could
write a file at run-time with the information.  But that sounds
more intrusive.

If there turns out to be a reliable way to logically get a "dynamic nm"
table at any time, that would be OK.  In fact it is likely better
from a procedural view since we tend to think of running a test
case.

FWIW there is a project to add compact trace output to qemu
do we wouldn't have to rely on qemu's verbose debug output
but the information we get from the run is the same.  So we
would need the output of a "dynamic nm".
The result of dlopen() is really a struct link_map * [see<link.h>]
and the link_map struct is a member of a doubly-linked list which
describes all the modules that are present in memory.
The .l_addr is the relocation constant for that module.  Add this
value to every address that is given in Elf32_.* structs in the file,
in order to get the corresponding address in memory.  If prelinking
has not been done, then the relocation constant equals the base address.

This sounds easy to deal with if we have to go dynamic and
catch info from a wedge.
The base address of a loaded module can be found by inspecting
the output from "cat /proc/PID/maps" where PID is the decimal
process ID.  The base address for modules that were present
when a "core" file was generated, is given by
     readelf --segments core
and perhaps by
     (gdb) info memory
     (gdb) info shared
In standard cases, the relocation constant for a module
equals (base_address - Elf32_Phdr[0].p_vaddr) which is different
from base_address if prelinking has been done.

In some cases you must tell gdb about loaded modules that gdb
does not realize are there:
    (gdb) add-symbol-file FILE ADDR
where ADDR is the memory address of the base of .text:
     objdump --section-headers FILE  |  grep '\.text'
and then add the base address of the module.

Thanks.  So there are ways to do it.  I suppose worst case
we could dynamically write a gdb script, run it and process
the output. Speed is not a factor unless it becomes too long
to run to be practical. :-D

But it sure would be nice to have a utility somewhere between
ldd and nm which gave a symbol table.

--joel


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