GNU gcc/ld - 用在同一个目标文件中定义的调用者和被调用者包装对符号的调用 [英] GNU gcc/ld - wrapping a call to symbol with caller and callee defined in the same object file

查看:26
本文介绍了GNU gcc/ld - 用在同一个目标文件中定义的调用者和被调用者包装对符号的调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

澄清一下,我的问题是指包装/拦截从一个函数/符号到另一个函数/符号的调用当调用者和被调用者在 GCC 编译器和链接器的同一编译单元中定义时.

我有类似以下的情况:

/* foo.c */无效 foo(void){/* ...一些东西*/酒吧();}空栏(空){/* ...一些其他的东西*/}

我想包装对这些函数的调用,我可以用 ,但这只是重命名符号及其引用.

我想将对 foobar(在 foo.o 中)的调用替换为 __wrap_foo__wrap_bar (就像它们通过链接器的 --wrap 选项在其他目标文件中解析一样)在我将 *.o 文件传递​​给链接器的 --wrap 选项之前,以及无需修改 foo.c 的源代码.

这样,所有对 foobar 的调用都会发生包装/拦截,而不仅仅是在 foo.o 之外发生的调用.

这可能吗?

解决方案

你必须使用 objcopy 来弱化和全球化符号.

-W 符号名--weaken-symbol=符号名使符号symbolname 变弱.可以多次给出此选项.--globalize-symbol=符号名赋予符号 symbolname 全局范围,使其在定义它的文件之外可见.可以多次给出此选项.

这对我有用

bar.c:

#include int foo(){printf("Wrap-FU
");}

foo.c:

#include 无效的 foo(){printf("foo
");}int main(){printf("主
");富();}

编译

$ gcc -c foo.c bar.c

弱化 foo 符号并使其全局化,以便它再次可用于链接器.

$ objcopy foo.o --globalize-symbol=foo --weaken-symbol=foo foo2.o

现在您可以将新 obj 与 bar.c 中的包装链接起来

$ gcc -o nowrap foo.o #供参考$ gcc -o wrapme foo2.o bar.o

测试

$ ./nowrap主要的富

还有包装好的:

$ ./wrapme主要的包裹-FU

to clarify, my question refers to wrapping/intercepting calls from one function/symbol to another function/symbol when the caller and the callee are defined in the same compilation unit with the GCC compiler and linker.

I have a situation resembling the following:

/* foo.c */
void foo(void)
{
  /* ... some stuff */
  bar();
}

void bar(void)
{
  /* ... some other stuff */
}

I would like to wrap calls to these functions, and I can do that (to a point) with ld's --wrap option (and then I implement __wrap_foo and __wrap_bar which in turn call __real_foo and __real_bar as expected by the result of ld's --wrap option).

gcc -Wl,--wrap=foo -Wl,--wrap=bar ...

The problem I'm having is that this only takes effect for references to foo and bar from outside of this compilation unit (and resolved at link time). That is, calls to foo and bar from other functions within foo.c do not get wrapped.

I tried using objcopy --redefine-sym, but that only renames the symbols and their references.

I would like to replace calls to foo and bar (within foo.o) to __wrap_foo and __wrap_bar (just as they get resolved in other object files by the linker's --wrap option) BEFORE I pass the *.o files to the linker's --wrap options, and without having to modify foo.c's source code.

That way, the wrapping/interception takes place for all calls to foo and bar, and not just the ones taking place outside of foo.o.

Is this possible?

解决方案

You have to weaken and globalize the symbol using 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.

This worked for me

bar.c:

#include <stdio.h>
int foo(){
  printf("Wrap-FU
");
}

foo.c:

#include <stdio.h>

void foo(){
printf("foo
");
}

int main(){
printf("main
");
foo();
}

Compile it

$ gcc -c foo.c bar.c 

Weaken the foo symbol and make it global, so it's available for linker again.

$ objcopy foo.o --globalize-symbol=foo --weaken-symbol=foo foo2.o

Now you can link your new obj with the wrap from bar.c

$ gcc -o nowrap foo.o #for reference
$ gcc -o wrapme foo2.o bar.o

Test

$ ./nowrap 
main
foo

And the wrapped one:

$ ./wrapme 
main
Wrap-FU

这篇关于GNU gcc/ld - 用在同一个目标文件中定义的调用者和被调用者包装对符号的调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆