【发布时间】:2017-04-25 15:29:38
【问题描述】:
在不修改这两个源文件的情况下,有没有办法获取通过编译它们产生的目标文件,并说服链接器将 main_v1.c 中的 foo 链接到 bar.c 中的 bar?
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(),那么bar() 本身在链接后内联,因此还有改进的余地。
【问题讨论】: