在不修改这两个源文件的情况下,有没有办法获取编译它们生成的目标文件,并说服链接器链接foo
在 main_v1.c 中bar
在bar.c?
main_v1.c
void foo(void);
int main(void)
{
foo();
}
bar.c
#include <stdio.h>
void bar(void)
{
puts("bar()!");
}
修改目标文件本身是公平的游戏,但假设我们甚至可能没有可用的源代码。平台是Linux。
通过坚持对 main_v1.c 进行适度的更改,并链接到一个附加的“映射”目标文件,这里有一种几乎只用标准 C 就可以获得所需结果的方法。
main_v2.c
extern void (*const foo)(void);
int main(void)
{
foo();
}
bar.c是不变的。
map.c
void bar(void);
void (*const foo)(void) = bar;
如果目标文件是用 lto 编译的,则函数指针取消引用甚至会被省略(使用最近的 gcc)。这是一个相当不错的结果,但如果main()
修改为直接调用bar()
, then bar()
本身是在链接后内联的,因此还有改进的空间。
这将是一份工作GNU ld
--wrap option
我们假设你有一个main_v1.o
已编译并且可能无法从您的main_v1.c
同样还有一个bar.o
从你的编译bar.c
.
现在编写另一个源文件:
wrap.c
extern void bar(void);
void __wrap_foo(void)
{
bar();
}
将其编译为wrap.o
并将其与之前的目标文件链接起来,如下所示:
$ gcc -c wrap.c
$ gcc -o prog -Wl,--wrap=foo main_v1.o bar.o wrap.o
Then:
$ ./prog
bar()!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)