Skip to content
Klemens Morgenstern edited this page Mar 23, 2018 · 5 revisions

This tool provides a convenient way to use the wrap function of the linker, though currently only ld is supported. This means that a function call can be intercepted and redirected during link time. This tool will take care of the name mangling, that makes the pure wrap functionality difficult to use with C++.

This only works for function calls accross compile units, i.e. has external linkage.

So as simple example, we want to intercept the call of bar(int)

//foo.cpp
void foo(int i) { bar(i); } 
//bar.cpp
void bar(int i) { }

Now for our test we want to redirect the call of bar from foo during link-time. This can advantageous, because the produced binary code is the same, while only the sections and labels are changed.

//wrap.cpp
#include <cpp/wrap.hpp>
#include <cassert>

struct stubber
{
    int call_cnt = 0;
    int i_in = 0;

    CPP_WRAP_FN(bar, void, (int i))
    {
        i_in = i;
        call_cnt++;
    }
};

int main(int argc, char* argv[])
{
    stubber s;
    assert(s.call_cnt == 0);
    assert(s.i_in == 0);

    foo(42);

    assert(s.call_cnt == 1);
    assert(s.i_in == 42);

    return 0;
}

In order for that too work, we need to generate an extra source file from the generated objects. This is done with our tool, so the name mangling is taken care of.

g++ -c foo.cpp -o foo.o
g++ -c bar.cpp -o bar.o
g++ -c wrap.cpp -o wrap.o
cppwrap foo.o bar.o wrap.o --wrapper=wrap.opt --output=wrap_gen.cpp --indirect
g++ -c wrap_gen.cpp -o wrap_gen.o
g++ foo.o bar.o wrap.o wrap_gen.o -o test @wrap.opt
./test

The file wrap.opt contains the options for the wrap (-Wl,--wrap=_ZN3barEKi) and is passed via respond-file to the linker. The --indirect option denotes that we want to use g++ and not ld directly, so the tool prepends -Wl,.