如何从共享对象中删除符号?

时间:2012-03-28 14:23:17

标签: c linux gcc shared-libraries

使用GCC,如何在创建共享对象后从共享对象中删除符号?如果我在C中有三个文件操作符号foo(),如:

// a.c
int foo() { return 0xdead; }
int baz() { return 1; }

// b.c
int foo() { return 0xbeef; }
int bar() { return 0; }

// c.c
#include "stdio.h"
extern int foo();
extern int bar();
extern int baz();
int main() { printf("0x%x, 0x%x, 0x%x\n",foo(),bar(),baz()); return 0; }

然后我编译并运行如下:

% gcc a.c --shared -fPIC -o a.so
% gcc b.c --shared -fPIC -o b.so
% setenv LD_LIBRARY_PATH . # export LD_LIBRARY_PATH=. for bash systems
% gcc c.c a.so b.so -o c
% ./c
0xdead, 0x0, 0x1

如何创建a.sofoo()不再有符号a.so?我希望通过删除foo() 中的b.so符号来使用a.so中定义的foo()代替a.so 。从foo()删除a.so后,重新运行c会生成以下内容的打印输出:

0xbeef, 0x0, 0x1

在这个玩具示例中,我知道我可以在使用c.ca.so编译b.so时简单地重新命名库名称,但我怎样才能真正删除a.so中的符号{1}}?我想在从foo()删除a.so后,nm输出的这个grep将不会产生任何结果:

nm -a a.so | grep foo

现在它返回:

000000000000063c T foo

2 个答案:

答案 0 :(得分:14)

您应该可以使用objcopy-N--strip-symbol)选项来实现您的目标:

$ objcopy -N foo a.so

答案 1 :(得分:2)

符号可见性似乎是一种优秀的解决方案,可以选择哪些函数用于运行时链接,哪些函数是库本地的,但仍然“extern”声明允许使用构成库的其他.c文件 - http://gcc.gnu.org/wiki/Visibility