[Ltrace-devel] ltrace and .opd section

Petr Machata pmachata at redhat.com
Fri Apr 21 03:06:52 UTC 2006

Petr Machata wrote:
> Hi
> I included automated testsuite into RH ltrace build, and it showed up
> some problems. The strangest one is this happening on ia64:
> $ ./ltrace -x display testsuite/ltrace.main/main-internal
> ./ltrace: static plt not in .opd
> The problem is that ia64 binaries have .opd section. (I didn't see .opd
> on any other platform.) I was trying to look up some documentation, but
> found nothing valuable. So I can't even tell if ltrace's way of
> handling .opd is ok or not.  Anyway... turning off the code that
> loads .opd seemingly cures the problem.  This is obviously a workaround,
> so anyone with more intimate knowledge of elf might have more apropriate
> fix handy.

I'm sending description of the progress I did.  Most probably, I will
say obvious things.  This low-level stuff, let alone itanium low-level
stuff, is all new for me, and I don't know what's obvious.

I did some digging.  Even IA64 ABI doesn't mention .opd section.
However, it seems that function descriptors are stored here (ABI does
describe what descriptor is, just doesn't mention that they are stored
in .opd).  Following snippet might be of interest:

Testing program:
$ cat y.c
#include <stdio.h>
void foo () {}
int main (void) {
        printf ("descript addr = %p\n", foo);
        printf ("function addr = %p\n", ((long*)foo)[0]);

$ gcc y.c && ./a.out
descript addr = 0x4000000000000a70
function addr = 0x40000000000006e0

Objdump shows that address a70 is inside .opd section, and that 6e0 is
really address of foo:

Idx Name  Size      VMA               LMA               File off  Algn
 14 .opd  00000080  4000000000000a30  4000000000000a30  00000a30  2**4

40000000000006e0 g     F .text  0000000000000020              foo
4000000000000a30 l    d  .opd   0000000000000000

So the lowlevel bit-n-byte stuff seems to be sane.  Enter ltrace.  I
modified problematic function elf_plt2ltrace to be non-static, and ran
ltrace in gdb:

$ gdb ./ltrace
(gdb) break elf_plt2addr
Breakpoint 1 at 0x4000000000008070: file elf.c, line 341.
(gdb) run -x foo ./a.out
Starting program: ltrace -x foo ./a.out
Reading symbols from shared object read from target memory...done.
Loaded system supplied DSO at 0xa000000000000000

Breakpoint 1, elf_plt2addr (lte=Variable "lte" is not available.
) at elf.c:341
341             if (!lte->opd)
(gdb) print addr
$1 = (void *) 0x40000000000006e0

Aha! The thing wants to translate already translated address!  No wonder
it chokes.  So... next step is discover *why*.  At first, if it should
hack around with descriptors at all, and if yes, why does it think that
the address is descriptor, when if fact it's real address.

I'm not going to investigate on it now, it's almost 5 am here :)

> PM


More information about the Ltrace-devel mailing list