Without modifying these two source files, is there a way to take the object files produced by compiling them, and convincing a linker to link foo
in main_v1.c to bar
in bar.c?
main_v1.c
void foo(void);
int main(void)
{
foo();
}
bar.c
#include <stdio.h>
void bar(void)
{
puts("bar()!");
}
Modifying the object files themselves is fair game but assume that we might not even have the source code available. The platform is Linux.
By insisting on a modest change to main_v1.c, and linking in an additional "mapping" object file, here's a way to almost get the desired result with just standard C.
main_v2.c
extern void (*const foo)(void);
int main(void)
{
foo();
}
bar.c is unchanged.
map.c
void bar(void);
void (*const foo)(void) = bar;
If the object files are compiled with lto, the function pointer dereference is even elided (using a recent gcc). This is a pretty good result but if main()
is modified to have a direct call to bar()
, then bar()
itself is inlined after linking so there's room for improvement.
This would be a job for the GNU
ld
--wrap
optionYou have, we assume, a
main_v1.o
compiled and perhaps unchangeable from yourmain_v1.c
and likewise abar.o
compiled from yourbar.c
.Now write another source file:
wrap.c
Compile it to
wrap.o
and link it with the prior object files like so:Then: