Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I remove a symbol from a shared object?

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
like image 531
Ross Rogers Avatar asked Mar 28 '12 14:03

Ross Rogers


2 Answers

You should be able to use the -N (--strip-symbol) option of objcopy to achieve what you want:

$ objcopy -N foo a.so
like image 112
Frédéric Hamidi Avatar answered Oct 21 '22 18:10

Frédéric Hamidi


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 .

like image 2
jørgensen Avatar answered Oct 21 '22 17:10

jørgensen