1

As mentioned here, we can wrap a function using the -Wl,--wrap switch. Consider the following program:

#include <stdio.h>

void __wrap_f()
{
        puts("wrapped");
}

void f()
{
        puts("original");
}

int main(void)
{
        f();
}

The program was written to a.c and compiled as gcc -Wl,--wrap=f a.c. When I run the executable (using ./a.out), I get original as the output.

My expectation was that on invoking f(), the wrapped version would be called and the program would print wrapped. Please let me know what I am missing here.

GCC version: 9.1.0

babon
  • 3,615
  • 2
  • 20
  • 20
  • 1
    See the first comment on that question. In fact, look at the answers. It's exactly the same problem. – Thomas Jager Aug 28 '19 at 17:37
  • 1
    As mentioned in comments on and answers to the question you linked to, you are ignoreing the "undefined references" requirement. – Ian Abbott Aug 28 '19 at 17:38

2 Answers2

2

I don't think this'll work with a single translation unit. AFAIK, the f function needs to be in a separate file.

This works for me (prints wrapped):

#!/bin/sh -eu

cat > main.c <<EOF
#include <stdio.h>

void __wrap_f()
{
        puts("wrapped");
}

void f();
int main(void)
{
        f();
}
EOF

cat > f.c <<EOF
#include <stdio.h>
void f()
{
        puts("original");
}
EOF

gcc wrap.c f.c -Wl,--wrap=f && ./a.out
Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • 1
    It works with a single TU, since the real `f()` won't be called. – Acorn Aug 28 '19 at 17:39
  • Yeah, I'm kind of eagerly expecting the user to transition to actual wrapping (using `__real_f`) instead of a simple symbol replacement. Then an actual `f` will be needed as well. – Petr Skocik Aug 28 '19 at 17:41
1

Like in the answer you mention, you are ignoring the fact that you need to have an undefined reference to f().

Try this instead:

#include <stdio.h>

void __wrap_f()
{
        puts("wrapped");
}

void f();

int main(void)
{
        f();
}
Acorn
  • 24,970
  • 5
  • 40
  • 69