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]

Tracing shared libraries (how to find link map)


I would like to add support to ltrace for dependent and dlopen'ed
libraries, but I have quickly discovered that I am in way over my
head. I'll describe what I *think* is happening, but I'm really just
spewing stuff out in the hopes that somebody will tell me where I went
wrong.

As I understand it, ltrace currently parses the ELF information in the
file that it is about to run, recording the load address of the .plt
section (or is it .rel.plt?) as well as remembering the address of
each entry in the PLT. (The load address of .plt is recorded in the
ELF headers, and does not vary at runtime, I guess?) Then it ptraces
the program, and when it reports back that it has loaded (I guess the
dynamic linker has run at this point), it sets "breakpoints" at each
symbol by rewriting the machine code at each symbol's offset with
instructions to trigger a breakpoint trap. A symbol's offset is the
same as its PLT entry's address. (Or maybe that's arch-specific.)

When a library is loaded by the dynamic linker, it gets a randomized
VMA as its start address. This doesn't seem to matter for the above
procedure, because the PLT entries stay put, and control has to go
through them first. But the PLT only contains entries for symbols
referred to directly by the main program; if main() calls a() in
'libA.so' calls b() in 'libB.so', then the call to b() will not be
recorded by ltrace() because it has no record of it.

If I somehow knew that libA.so were getting loaded and got a trap
after that, then I still wouldn't know how to find b() to set a
breakpoint in it because the PLT of libA.so looks like it is stored as
a relative address in the ELF header.

So, assuming my understanding of what's going on isn't completely off:

1. How can I trap the load of a dependent library? My vague idea was
to run ld-linux.so directly and set a breakpoint on some internal
symbol (_dl_map_object or _dl_read_whole_file or _dl_map_object_deps
or ...?) But that seems rather unportable. Which isn't the kiss of
death; ltrace() may very well need to muck with some amount of
architecture/whatever-dependent code. But even with this trap, I need
to know the filename of the library.

2. How can I find the PLT of a loaded library? When I get the trap
back from the call to a(), can I look at what address it was resolved
to and convert it to an offset, thus deriving the load address of
libA.so and using that to find the PLT?

I have a sneaking suspicion that nothing I'm saying makes any sense whatsoever.


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