Commit 2bb8e93a authored by Leonard Mosescu's avatar Leonard Mosescu
Browse files

A more civilized approach to bytecode instrumentation.

We already have the foundation for doing arbitrary bytecode transformations,
although using lir::CodeIr and ir:Builder directly is verbose and prone to subtle
mistakes. From the beginning, a key goal was to provide an easy to use interface
for applying common instrumentation patterns: entry/exit hooks and wrapping
method calls.

This change implements an extensible yet simpler interface that hides away the
direct code IR manipulation and it's what most dexter/slicer users are expected
to use.

For example, if we want to add both entry and exit hooks to a Hello.Test(int) method,
the instrumentation code would look like this:

    ...
    slicer::MethodInstrumenter mi(dex_ir);
    mi.AddTransformation<slicer::EntryHook>(ir::MethodId("LTracer;", "OnEntry"));
    mi.AddTransformation<slicer::ExitHook>(ir::MethodId("LTracer;", "OnExit"));
    if (!mi.InstrumentMethod(ir::MethodId("LHello;", "Test", "(I)I"))) {
      // error handling: instrumentation failed ...
    }
    ...

Why not just a set of helper functions like "InjectEntryHook(...), ..." ?
Using the MethodInstrumenter class we can batch multiple transformations that
are applied while looking up the target method, creating and encoding the code IR
just once regardless of how many transformation are applied to a method.

This is important today, and will be even more critical if we add transformations
which require additional data structures (CFG, SSA) and algorithms.

Test: bazel test :dexter_tests

Change-Id: I6a65ac9bc7e26f4eb6281c2054b881f9e666da54
parent 16c4ec7f
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment