smc*_*ron 9 c gcc ld objcopy interposing
有没有办法在对象模块中覆盖静态范围的函数?
如果我从这样的东西开始,带有全局符号"foo"的模块是一个调用本地符号"bar"的函数,它调用本地符号"baz"
[scameron@localhost ~]$ cat foo.c
#include <stdio.h>
static void baz(void)
{
printf("baz\n");
}
static void bar(void)
{
printf("bar\n");
baz();
}
void foo(void)
{
printf("foo\n");
bar();
}
[scameron@localhost ~]$ gcc -g -c foo.c
[scameron@localhost ~]$ objdump -x foo.o | egrep 'foo|bar|baz'
foo.o: file format elf32-i386
foo.o
00000000 l df *ABS* 00000000 foo.c
00000000 l F .text 00000014 baz
00000014 l F .text 00000019 bar
0000002d g F .text 00000019 foo
Run Code Online (Sandbox Code Playgroud)
它有一个全球性的"foo"和两个当地人"bar"和"baz".
假设我想编写一些运动条和baz的单元测试,我可以这样做:
[scameron@localhost ~]$ cat barbaz
bar
baz
[scameron@localhost ~]$ objcopy --globalize-symbols=barbaz foo.o foo2.o
[scameron@localhost ~]$ objdump -x foo2.o | egrep 'foo|bar|baz'
foo2.o: file format elf32-i386
foo2.o
00000000 l df *ABS* 00000000 foo.c
00000000 g F .text 00000014 baz
00000014 g F .text 00000019 bar
0000002d g F .text 00000019 foo
[scameron@localhost ~]$
Run Code Online (Sandbox Code Playgroud)
现在bar和baz是全局符号,可从模块外部访问.到现在为止还挺好.
但是,如果我想在"baz"之上设置我自己的功能,并且让"bar"调用我插入的"baz",该怎么办?
有没有办法做到这一点?
--wrap选项似乎没有这样做......
[scameron@localhost ~]$ cat ibaz.c
#include <stdio.h>
extern void foo();
extern void bar();
void __wrap_baz()
{
printf("wrapped baz\n");
}
int main(int argc, char *argv[])
{
foo();
baz();
}
[scameron@localhost ~]$ gcc -o ibaz ibaz.c foo2.o -Xlinker --wrap -Xlinker baz
[scameron@localhost ~]$ ./ibaz
foo
bar
baz
wrapped baz
[scameron@localhost ~]$
Run Code Online (Sandbox Code Playgroud)
从main()调用的baz被包裹了,但是bar仍然调用当地的baz而不是包裹的baz.
有没有办法让酒吧打电话给被包裹的巴兹?
即使它需要修改目标代码以修改函数调用的地址,如果可以以自动方式完成,这可能已经足够好了,但在这种情况下它至少需要处理i386和x86_64.
- 史蒂夫
由于static是向 C 编译器承诺该函数或变量是文件的本地函数或变量,因此如果编译器可以在没有它的情况下获得相同的结果,则可以自由地删除该代码。
这可能是内联函数调用。这可能意味着用常量替换变量。如果代码位于if始终为 false 的语句内,则该函数甚至可能不存在于编译结果中。
所有这些意味着您无法可靠地将调用重定向到该函数。
如果使用新-lto选项进行编译,情况会更糟,因为编译器可以自由地重新排序、删除或内联整个项目中的所有代码。
| 归档时间: |
|
| 查看次数: |
2369 次 |
| 最近记录: |