【发布时间】:2012-03-28 14:23:16
【问题描述】:
使用 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.so 在我创建a.so 后不再具有符号foo()?我希望使用b.so 中定义的foo() 而不是a.so 通过从a.so 中删除foo() 符号。从a.so 中删除foo() 后,重新运行c 应该会生成以下内容的打印输出:
0xbeef, 0x0, 0x1
在这个玩具示例中,我知道当我用a.so 和b.so 编译c.c 时,我可以简单地重新排序库名称,但是我怎样才能真正从a.so 中删除符号呢?我想在从a.so 中删除foo() 之后,nm 输出的这个 grep 将不会产生任何结果:
nm -a a.so | grep foo
而现在它返回:
000000000000063c T foo
【问题讨论】:
-
你为什么告诉你的 GCC 用你的 c.c 编译 a.so 和 b.so ?共享库不应该链接到您的二进制文件,这就是
LD_LIBRARY_PATH的用途。 -
也许
objcopy有一些你需要的功能? -
您是否更全面地查看了
strip?我相信您可以使用-R... 定位文件中的特定符号 -
嗨,埃瑞格里斯。你说得对,我应该使用
-la -lb。
标签: c linux gcc shared-libraries