2012-03-28 4 views
9

Wie kann ich mit GCC ein Symbol aus einem gemeinsamen Objekt entfernen, nachdem ich das gemeinsame Objekt erstellt habe? Wenn ich drei Dateien in C Symbol Manipulation foo() wie:Wie kann ich ein Symbol aus einem gemeinsamen Objekt entfernen?

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

und

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

und

// 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; } 

Dann kompilieren ich und renne wie:

% 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 

Wie Kann ich es so machen? t a.so hat nicht mehr Symbol foo() nachdem ich a.so erstellt habe? Ich möchte die foo() definiert in b.so anstelle von a.sodurch Löschen der foo() Symbol aus. Nach foo() von a.so gelöscht wird, c rerunning einen Ausdruck erzeugen soll:

0xbeef, 0x0, 0x1 

In diesem Spielzeug Beispiel, ich weiß, ich kann einfach die libary Namen neu anordnen, wenn ich kompilieren c.c mit a.so und b.so, aber wie kann Ich lösche das Symbol tatsächlich von a.so? Ich stelle mir vor, dass foo() von a.so, diese grep des nm Ausgabe nach dem Löschen ergäbe nichts:

nm -a a.so | grep foo 

Während jetzt ist es zurück:

000000000000063c T foo 
+0

Warum sagst du deinem GCC, a.so und b.so mit deinem c.c zu kompilieren? Shared Libraries sollen nicht mit Ihrer Binärdatei verknüpft sein, dafür steht "LD_LIBRARY_PATH". – Eregrith

+1

Vielleicht hat 'objcopy' einige Funktionen, die Sie brauchen? –

+0

Haben Sie sich 'Strip' genauer angesehen? Ich glaube, dass Sie bestimmte Symbole in einer Datei mit "-R" ... – timlukins

Antwort

11

Sie sollten die -N (--strip-symbol) nutzen können Option von objcopy zu erreichen, was Sie wollen:

$ objcopy -N foo a.so 
+0

Perfekt! Danke Frederic. –

2

Symbolsichtbarkeit scheint eine überlegene Lösung zu sein, um auszuwählen, welche Funktionen für die Laufzeitverknüpfung und welche lokal für die Bibliothek sind, aber "extern" deklariert sind, um die Verwendung von anderen .c-Dateien zu ermöglichen, die die Bibliothek umfassen - http://gcc.gnu.org/wiki/Visibility.