[Ltrace-devel] MIPS o32
Edgar E. Iglesias
edgar.iglesias at gmail.com
Mon Sep 24 17:35:40 UTC 2012
On Fri, Sep 21, 2012 at 05:57:42PM +0200, Petr Machata wrote:
> "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
> (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.)
Thanks for the info!
Yeah, MIPS o32 is a bit different than other archs. The issue with
the PLT is that it is only used when the symbol hasn't been resolved
yet. All code jumps indirectly via GOT entries. At build time, the GOT
entires are built to point into the PLT/stubs but as soon as a symbol
gets resolved, code will jump directly (via GOT entries) to the various
functions without jumping via the PLT. So we need to put breakpoints
to the functions themselves as symbols get resolved.
For function pointers, GOT entries are created with correspoding
relocations that get resolved before the program starts, those
need special treatment too.
I had not considered the multithreaded issues yet. Anyway, I'll start
by posting patches for to get the basic tracing going once I'm done with
that and then we can discuss the various solutions to the multithreaded
More information about the Ltrace-devel