2017-09-27 2 views
3

La page de manuel de gcc 6.3 dit:Comment emballer correctement les fonctions avec l'option `--wrap`?

--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. 

Je créé un exemple simple:

#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; 
} 

et compilé avec:

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

Cela m'a donné un avertissement:

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

Bien. Maintenant, je suggère une sortie comme ceci:

foo:wrap foo 
wrapfoo:wrap foo 
realfoo:foo 

Au lieu de cela je reçois ceci:

foo:foo 
wrapfoo:wrap foo 
realfoo:foo 

J'espère que la chose est claire. Je suis confus au sujet de l'avertissement. Normalement, la fonction __real doit être liée par l'éditeur de liens à foo(). En outre, un appel au foo() doit être lié à __wrap_foo. Mais la sortie montre que foo() est en cours d'exécution à la place. Comment utiliser correctement le --wrap?

+4

Il a fait le travail. Mais parce que vous avez une seule unité de traduction et' foo' est présent, l'appel à 'foo' n'est pas une ** référence indéfinie ** à' foo' – StoryTeller

+0

Eh bien, je ne comprends pas La sortie de l'exemple ci-dessus me semble erronée. 'foo()' devrait sortir '' wrap foo' ' ! Qu'est-ce que je fais mal? – eDeviser

+2

Vous ignorez l'exigence "référence non définie" **. – StoryTeller

Répondre

2

Comme StoryTeller m'a dit, je l'ai ignoré l'exigence de « référence indéfinie », qui je l'ai déjà posté ci-dessus:

... Toute référence non définie au symbole sera résolu à « __wrap_symbol ». Toute référence non définie à "__real_symbol" sera résolue en symbole.

Pour utiliser l'option --wrap je réarrangé mon exemple de code comme ceci:

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; 
} 

compilez:

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

Et la sortie étonnante après l'exécution ./main:

foo:wrap foo 
wrapfoo:wrap foo 
realfoo:foo 

L'astuce est (corrigez-moi si je me trompe) que la référence de foo() et __real_foo() n'est pas défini au moment de la compilation. IE ils ont ** références non définies », qui est le requierement pour l'éditeur de liens pour lier foo()-__wrap_foo() et __real_foo()-foo().