Suppose a function int foo(int x)
is made available in library libfoo
, which I don't control. I do control a codebase which calls foo()
many times, in many files.
Now, I would like to insert some logic before actually making a call to foo()
. Let's say its "if condition holds call foo, otherwise do something else" (and never mind the details). So far - not a problem. I write a int foo_wrapper(int x)
put my logic in there, and call that one instead.
Now for the hard part: I want to not change the code at the call sites. i.e. I still want there to be foo()
calls. So:
foo_
almost-same-name functionsEssentially I want most of my compilation units to "not look" at libfoo, but at some translation unit I provide with a wrapper int foo()
; and have the implementation in that translation unit actually call libfoo's foo()
function. How achievable is this (without twisting myself into knots too hard)?
Additional information about libfoo
:
libfoo
itself, load it, and have the original foo
symbol available for use when necessary.Note: A solution which also works for C code is preferable but not required.
How achievable is this (without twisting myself into knots too hard)?
Trivially achievable given the Linux-only constraint.
If libfoo
was a shared library, this is exactly what library interposers do using LD_PRELOAD
and similar tricks.
But since libfoo
is an archive library, all you need to do is rename all your unresolved references from foo
to foo_wrapper
. You can do that by running objcopy --redefine-sym foo=foo_wrapper caller.o new_caller.o
, where caller.o
is your object file that was originally calling foo
, and linking your binary using new_caller.o
.
(Obviously your can do "update in place" with something like objcopy ... caller.o /tmp/$$.o && mv /tmp/$$.o caller.o
, so you don't have to actually modify your link line.)
You will have to repeat this for every object in your codebase.
P.S. Using a macro to achieve the exact same result is probably much simpler -- all you have to do is use -Dfoo=foo_wrapper
on compilation command line. Not sure whether that counts as "macro trickery" in your book.