I'm trying to mock a static function without modifying the source code. This is because we have a large legacy base of code and we would like to add test code without requiring developers to go through and change a bunch of the original code.
Using objcopy, I can play with functions between object files, but I can't affect internal linkages. In other words, in the code below, I can get main.cpp to call a mocked up foo() from bar.c, but I cannot get UsesFoo() to call the mocked up foo() from bar.c.
I understand this is because foo() is already defined within foo.c. Aside from changing the source code, is there any way I can use ld or another tool to rip out foo() so that final linking pulls it in from my bar.c?
foo.c
#include <stdio.h>
static void foo()
{
printf("static foo\n");
}
void UsesFoo()
{
printf("UsesFoo(). Calling foo()\n");
foo();
}
bar.c
#include <stdio.h>
void foo()
{
printf("I am the foo from bar.c\n");
}
main.cpp
#include <iostream>
extern "C" void UsesFoo();
extern "C" void foo();
using namespace std;
int main()
{
cout << "Calling UsesFoo()\n\n";
UsesFoo();
cout << "Calling foo() directly\n";
foo();
return 0;
}
compiling:
gcc -c foo.c
gcc -c bar.c
g -c main.c
(Below simulates how we consume code in the final output)
ar cr libfoo.a foo.o
ar cr libbar.a bar.o
g -o prog main.o -L. -lbar -lfoo
This works because the foo() from libbar.a gets included first, but doesn't affect the internal foo() in foo.o
I have also tried:
gcc -c foo.c
gcc -c bar.c
g -c main.c
(Below simulates how we consume code in the final output)
ar cr libfoo.a foo.o
ar cr libbar.a bar.o
objcopy --redefine-sym foo=_redefinedFoo libfoo.a libfoo-mine.a
g -o prog main.o -L. -lbar -lfoo-mine
This produces the same effect. main will call foo() from bar, but UsesFoo() still calls foo() from within foo.o
CodePudding user response:
The usual trick is to compile them as shared libraries and then use LD_PRELOAD to preload a version that will replace the functions you are targeting.
Here is a decent tutorial:
https://catonmat.net/simple-ld-preload-tutorial
CodePudding user response:
I think you can try --wrap flag in gcc. An example for using the flag: How to wrap functions with the `--wrap` option correctly?