public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Mapping Addresses for Shared Library Routines to Code
@ 2010-02-04 22:46 Joel Sherrill
  2010-02-05  0:25 ` John Reiser
  0 siblings, 1 reply; 3+ messages in thread
From: Joel Sherrill @ 2010-02-04 22:46 UTC (permalink / raw)
  To: binutils; +Cc: Chris Johns

Hi,

This may not be the perfect place to ask
but you guys are likely to know the answer. :)

I am looking into using qemu to get trace
data on native Linux executables.  qemu
generates the output and includes instructions
from shared libraries.  Since we are
already analysing this data to do coverage
for RTEMS, I know how to do it for
statically linked executables.

For dynamically linked executables, the traces
include the indirect call to the shared
library routine and the assembly statements
executed in the share library.  So the trace
data is OK.

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?

Any ideas at all would be appreciated.

Thanks.

-- 
Joel Sherrill, Ph.D.             Director of Research&  Development
joel.sherrill@OARcorp.com        On-Line Applications Research
Ask me about RTEMS: a free RTOS  Huntsville AL 35805
    Support Available             (256) 722-9985


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Mapping Addresses for Shared Library Routines to Code
  2010-02-04 22:46 Mapping Addresses for Shared Library Routines to Code Joel Sherrill
@ 2010-02-05  0:25 ` John Reiser
  2010-02-05 14:13   ` Joel Sherrill
  0 siblings, 1 reply; 3+ messages in thread
From: John Reiser @ 2010-02-05  0:25 UTC (permalink / raw)
  To: binutils

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

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.

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.

-- 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Mapping Addresses for Shared Library Routines to Code
  2010-02-05  0:25 ` John Reiser
@ 2010-02-05 14:13   ` Joel Sherrill
  0 siblings, 0 replies; 3+ messages in thread
From: Joel Sherrill @ 2010-02-05 14:13 UTC (permalink / raw)
  To: John Reiser; +Cc: binutils

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

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-02-05 14:13 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-02-04 22:46 Mapping Addresses for Shared Library Routines to Code Joel Sherrill
2010-02-05  0:25 ` John Reiser
2010-02-05 14:13   ` Joel Sherrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).