[Ltrace-devel] MIPS o32

Petr Machata pmachata at redhat.com
Fri Sep 21 15:57:42 UTC 2012


"Edgar E. Iglesias" <edgar.iglesias at gmail.com> writes:
> I've been trying to run ltrace on a MIPS 32r2 little endian system.
> I've got a set of patches that work AFAICT. (I'll clean those up
> and post them soon).

Great, thank you.

> Is anyone else working on this btw? (I should probably have asked
> before trying to fix things)

Sedat Dilek did some work on MIPS recently.  I'm not sure if he's still
pursuing this, but I CC'd him just in case.

> A question at this stage is, what was expected to work on MIPS?

Nothing.  As far as I know, MIPS support is broken.  Sedat Dilek reached
a state that ltrace compiled on MIPS, but there were bugs in elementary
tracing.  From the logs that he posted it seemed that entry breakpoint
(initial breakpoint that we put to ELF entry address) hits, but then we
somehow fail to either figure out all the mapped-in objects, or
otherwise fail to distribute breakpoints in them.

I seem to recall that when used in degenerate scenario of tracing one
static symbol (-x main), ltrace could place that breakpoint, it would
hit, but then ltrace couldn't disable it again, and tracing would end in
endless loop of hitting the same breakpoint, eventually overflowing
internal stack and aborting.  That might be caused by double enablement,
but I don't recall seeing any evidence of that in the logs.  Does basic
tracing work for you?

I suspect MIPS dynamic linker overwrites PLT entries after the first
call, and MIPS backend will need to implement reenablement.  The old
trick that PowerPC (and MIPS) used is that after the first call returns,
we check if breakpoint is still present, and if it was overwritten, we
reenable it.  While neat and simple (and general), that's not
sufficient, because any calls made in the window after the first call is
resolved, but before it returns, are missed by ltrace.  That could
happen in a multi-threaded program, or when the call itself is recursive
and passes through PLT second time.  So this generic (i.e. present in
ltrace core) re-enablement support was dropped, and reimplemented in
PowerPC backend in a way that doesn't miss any calls.

The PowerPC case is pretty involved overall, but the gist is that when
PLT entry is called for the first time, we stop all threads and then
single-step through the resolver, waiting for PLT entry to change.  We
then start all threads again.  As an optimization, we remember which
instruction changed the PLT entry, put breakpoint there, and then just
let it hit instead of single-stepping through half the dynamic linker.

So, that's for core tracing.  If this all works fine, then the next nice
addition would be to implement the fetch backend for MIPS.  This would
allow full support for parameter passing (passing structures in
registers in particular, but I see also special rules for vararg
functions and of course double doesn't fit into 32-bit long).

> Can I assume o32 ABI in the backend for now and we can extended
> the support for the other ABIs either by adding new mips64 etc
> ports or by updating the current backend later?

It's fine for now.  Long-term, I would like to see support for MIPS64
ABI's as well (n32, n64), but that was never in ltrace to begin with, so
it's fine if you ignore it for now.

For when this gets done, it is desirable to have both MIPS32 and MIPS64
backend in the same file, so that cross tracing (MIPS64 ltrace tracing
MIPS32 binary) is trivially supported.  I recently even merged i386 and
x86_64 into a single backend, because x86_64 needs to handle i386 case
anyway.

(At some point in future I would like to support the case of n32 ltrace
tracing n64 binaries (and similarly ppc32/ppc64, x32/x86_64), but for
that we first need to wean ltrace off the fallacy that arch_addr_t is
void*.  Unfortunately ltrace is heavily infested by that idiom.)

Thank you,
PM



More information about the Ltrace-devel mailing list