为了澄清,我的问题是指包裹/截取从一个功能/符号到另一个函数/符号调用当主叫用户和被叫在相同的编译单元中定义与GCC编译器和链接。
我有一个类似的情况如下:
/* foo.c */
void foo(void)
{
/* ... some stuff */
bar();
}
void bar(void)
{
/* ... some other stuff */
}
我想换到这些函数的调用,而我能做到这一点(一个点)与LD的--wrap
选项 (然后我实现__wrap_foo和__wrap_bar这反过来又调用__real_foo和__real_bar预期由劳工处的结果--wrap
选项)。
gcc -Wl,--wrap=foo -Wl,--wrap=bar ...
我遇到的问题是,这只是生效的引用foo和从该编译单元之外酒吧(和链接时解析)。 也就是说,调用foo和来自内部的foo.c等功能栏没有得到包裹。
我尝试使用objcopy把--redefine-符号 ,但只重命名符号及其引用。
我想更换调用foo
和bar
(foo.o的范围内),以__wrap_foo
和__wrap_bar
(就像他们获得其他目标文件链接程序的解决--wrap
之前我通过了* .o文件的链接器的选项) --wrap
选项,而无需修改foo.c中的源代码。
这样一来,包装/拦截发生的所有调用foo
和bar
,而不仅仅是那些发生foo.o.之外
这可能吗?
你必须削弱和使用objcopy把全球化的象征。
-W symbolname
--weaken-symbol=symbolname
Make symbol symbolname weak. This option may be given more than once.
--globalize-symbol=symbolname
Give symbol symbolname global scoping so that it is visible outside of the file in which it is defined. This option may be given more than once.
这为我工作
bar.c:
#include <stdio.h>
int foo(){
printf("Wrap-FU\n");
}
foo.c的:
#include <stdio.h>
void foo(){
printf("foo\n");
}
int main(){
printf("main\n");
foo();
}
编译
$ gcc -c foo.c bar.c
削弱foo的符号,使之全球化的,它再次可供连接。
$ objcopy foo.o --globalize-symbol=foo --weaken-symbol=foo foo2.o
现在,您可以从bar.c包裹链接新的OBJ
$ gcc -o nowrap foo.o #for reference
$ gcc -o wrapme foo2.o bar.o
测试
$ ./nowrap
main
foo
和一个包裹:
$ ./wrapme
main
Wrap-FU
#include <stdio.h>
#include <stdlib.h>
//gcc -ggdb -o test test.c -Wl,-wrap,malloc
void* __real_malloc(size_t bytes);
int main()
{
int *p = NULL;
int i = 0;
p = malloc(100*sizeof(int));
for (i=0; i < 100; i++)
p[i] = i;
free(p);
return 0;
}
void* __wrap_malloc(size_t bytes)
{
return __real_malloc(bytes);
}
然后只需编译此代码和调试。 当你调用malloc的雷尔,叫会--wrap malloc中调用和__real_malloc将调用malloc函数。
我认为这是拦截来电的方式。
主要是因为在--wrap选项由劳工处提供。
您可以使用__attribute__((weak))
被调用执行之前,为了让别人重新实现它没有GCC大喊大叫有关多。定义。
例如,假设你想嘲笑world
在下面的hello.c代码单元的功能。 您可以以预先设置属性能够覆盖它。
#include "hello.h"
#include <stdio.h>
__attribute__((weak))
void world(void)
{
printf("world from lib\n");
}
void hello(void)
{
printf("hello\n");
world();
}
然后你可以重写它在另一个单元文件。 单元测试/嘲笑非常有用的:
#include <stdio.h>
#include "hello.h"
/* overrides */
void world(void)
{
printf("world from main.c"\n);
}
void main(void)
{
hello();
return 0;
}
这似乎是工作的记载:
--wrap=symbol
Use a wrapper function for symbol.
Any undefined reference to symbol will be resolved to "__wrap_symbol". ...
注意上面的定义 。 当链接器处理foo.o
,所述bar()
不是未定义,所以链接器不包裹。 我不知道为什么它这样做的方式,但也有可能是需要这样的使用情况。
你可以实现你想要的,如果你用什么--undefined
与--wrap
-u SYMBOL, --undefined SYMBOL
Start with undefined reference to SYMBOL
文章来源: GNU gcc/ld - wrapping a call to symbol with caller and callee defined in the same object file