Using GCC, how can I remove a symbol from a shared object after I've created the shared object? If I have three files in C manipulating symbol foo()
like:
// a.c
int foo() { return 0xdead; }
int baz() { return 1; }
and
// b.c
int foo() { return 0xbeef; }
int bar() { return 0; }
and
// 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; }
Then I compile and run like:
% 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
How can I make it so that a.so
no longer has symbol foo()
after I've created a.so
? I want the foo()
defined in b.so
to be used instead of a.so
by deleting the foo()
symbol from a.so
. After foo()
is deleted from a.so
, rerunning c
should generate a printout of:
0xbeef, 0x0, 0x1
In this toy example, I know I can simply re-order the libary names when I compile c.c
with a.so
and b.so
, but how can I actually delete the symbol from a.so
? I imagine that after deleting foo()
from a.so
, this grep of the nm output would yield nothing:
nm -a a.so | grep foo
Whereas right now it returns:
000000000000063c T foo
You should be able to use the -N
(--strip-symbol
) option of objcopy to achieve what you want:
$ objcopy -N foo a.so
Symbol visibility seems like a superior solution to select which functions are up for runtime linking and which are local to the library but still "extern" declared to allow usage from other .c files that comprise the library - http://gcc.gnu.org/wiki/Visibility .
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With