Как правильно обернуть функции с параметром --wrap?

Справочная страница gcc 6.3 гласит:

--wrap=symbol
           Use a wrapper function for symbol.  Any undefined reference to
           symbol will be resolved to "__wrap_symbol".  Any undefined
           reference to "__real_symbol" will be resolved to symbol.
           ...
           If you link other code with this file using --wrap malloc, then all
           calls to "malloc" will call the function "__wrap_malloc" instead.
           The call to "__real_malloc" in "__wrap_malloc" will call the real
           "malloc" function.

Итак, я создал простой пример:

#include <stdio.h>

int foo() {
    printf("foo\n");
    return 0;
}

int __wrap_foo() {
    printf("wrap foo\n");
    return 0;
}

int main () {
    printf("foo:");foo();
    printf("wrapfoo:");__wrap_foo();
    printf("realfoo:");__real_foo();
    return 0;
}

И скомпилировал это с:

gcc main.c -Wl,--wrap=foo -o main

Это дало мне предупреждение:

main.c:18:21: warning: implicit declaration of function ‘__real_foo’ [-Wimplicit-function-declaration]
  printf("realfoo:");__real_foo();
                     ^~~~~~~~~~

Ну что ж Теперь я хотел бы предложить такой вывод:

foo:wrap foo
wrapfoo:wrap foo
realfoo:foo

Вместо этого я получаю это:

foo:foo
wrapfoo:wrap foo
realfoo:foo

Я надеюсь, что все ясно. Я смущен по поводу предупреждения. Обычно __real функция должна быть связана с компоновщиком foo(), Кроме того, призыв к foo() должны быть связаны с __wrap_foo, Но вывод показывает, что foo() выполняется вместо

Как пользоваться --wrap правильно?

1 ответ

Решение

Как сказал мне StoryTeller, я проигнорировал требование "неопределенная ссылка", которое я уже разместил выше:

... Любая неопределенная ссылка на символ будет преобразована в "__wrap_symbol". Любая неопределенная ссылка на "__real_symbol" будет преобразована в символ.

Чтобы использовать --wrap вариант я переставил мой пример кода следующим образом:

main.c:

#include <stdio.h>
extern int foo();
extern int __real_foo();

int __wrap_foo() {
    printf("wrap foo\n");
    return 0;
}

int main () {
    printf("foo:");foo();
    printf("wrapfoo:");__wrap_foo();
    printf("realfoo:");__real_foo();
    return 0;
}

foo.c:

#include <stdio.h>
int foo() {
    printf("foo\n");
    return 0;
}

Затем скомпилируйте:

gcc main.c foo.c -Wl,--wrap=foo -o main

И удивительный выход после запуска ./main:

foo:wrap foo
wrapfoo:wrap foo
realfoo:foo

Хитрость в том (поправьте меня, если я ошибаюсь), что ссылка foo() а также __real_foo() не определяется во время компиляции. То есть они имеют ** неопределенные ссылки ", что является обязательным требованием для компоновщика ссылки foo() в __wrap_foo() а также __real_foo() в foo(),

Другие вопросы по тегам