TcShadowWalker
TcShadowWalker

Reputation: 76

Linux function redirect

Hey, I'm trying to wrap a function in my program without using LD_PRELOAD.

I have two functions with the same signature:

void someFunc () {
    puts ("someFunc");
}

void someFunc_wrapper () {
    puts ("someFunc_wrapper");
}

And I want to redirect any function call to someFunc with a call to the wrapper function. Of course I could do that with defining macros or put the wrapper function into a shared library and then call the program like this:

LD_PRELOAD=./mylib.so my_program

However, I want to redirect the function calls at runtime, without modifying the program call.
As I understand, it should be possible to redirect these calls by modifying the executable's symbol table at runtime.

Any help will be appreciated :)

Upvotes: 2

Views: 1247

Answers (2)

Jens Gustedt
Jens Gustedt

Reputation: 78923

ld has the option --wrap=symbol that should do what you want. The manual page has an example how it works.

Upvotes: 2

Mat
Mat

Reputation: 206765

Even if it is doable, modifying your program's symbol table might not be enough in the general case - think about the compiler inlining your function.

You could do this without dirty tricks by using an indirect function call though (always call that function via a pointer-to-function, update that pointer when you want to switch implementations).

Note that this has some runtime overhead (one more indirection). Whether that's important or not depends on the use case. And it can be turned off at compile time with macro tricks if that's just a debug feature you're implementing.

#include <stdio.h>

void foo(void) {
    printf("Hello from foo\n");
}

void bar(void) {
    printf("Hello from bar\n");
}

#ifdef INTERCEPT

typedef void(*myfunptr)(void);

myfunptr thingy = foo;

void turnonbar(void)
{
    thingy = bar;
}

#else
#define turnonbar()
#define thingy foo
#endif

int main(void) {
    thingy();
    turnonbar();
    thingy();
    return 0;
}

Upvotes: 0

Related Questions