ld --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.
This can be used to provide a wrapper for a system function.
The wrapper function should be called __wrap_symbol.
If it wishes to call the system function, it should call __real_symbol.
链接器会在符号解析的时候将 symbol 替换成 __wrap_symbol 。注意这里提到了未定义的符号才会被替换掉,也就是说如果 symbol 和调用方在同一个编译单元的话,这个符号不会被替换。
int foo(void);
int foo(void)
{
return 1;
}
int main()
{
return foo();
}
int foo(void);
int __wrap_foo(void)
{
return 2;
}
int bar(void)
{
return foo();
}
$ gcc wrap_foo.c main.c -Wl,--wrap=foo
结果如下,由于 main 和 foo 在同一个编译单元,main 调用的依然是 foo 本身。bar 中则被替换成了 __warp_foo 。
00000000004004a8 <main>:
4004a8: 55 push %rbp
4004a9: 48 89 e5 mov %rsp,%rbp
4004ac: e8 ec ff ff ff callq 40049d <foo>
4004b1: 5d pop %rbp
4004b2: c3 retq
4004b3: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
4004ba: 00 00 00
4004bd: 0f 1f 00 nopl (%rax)
0000000000400492 <bar>:
400492: 55 push %rbp
400493: 48 89 e5 mov %rsp,%rbp
400496: e8 ec ff ff ff callq 400487 <__wrap_foo>
40049b: 5d pop %rbp
40049c: c3 retq
用处
这个选项有什么场景使用呢?像单元测试框架 cmocka 函数打桩的实现原理就使用了这个特性。
|