2012-03-28 2 views
9

Utilizzo di GCC, come è possibile rimuovere un simbolo da un oggetto condiviso dopo aver creato l'oggetto condiviso? Se ho tre file in C manipolare simbolo foo() come:Come posso rimuovere un simbolo da un oggetto condiviso?

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

e

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

e

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

Poi ho compilare ed eseguire come:

% 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 

Come posso farcela così t a.so non ha più il simbolo foo() dopo aver creato a.so? Voglio il foo() definito in b.so da utilizzare invece di a.soeliminando il simbolo foo() da a.so. Dopo foo() viene eliminato dal a.so, eseguire nuovamente c dovrebbe generare una stampa di:

0xbeef, 0x0, 0x1 

In questo esempio giocattolo, so che posso semplicemente ri-ordinare i nomi libary Quando compilo c.c con a.so e b.so, ma come può In realtà cancello il simbolo da a.so? Immagino che dopo l'eliminazione foo() da a.so, questo grep del nm uscita produrrebbe nulla:

nm -a a.so | grep foo 

Mentre adesso ritorna:

000000000000063c T foo 
+0

Perché dici al tuo GCC di compilare a.so e b.so con il tuo c.c? Le librerie condivise non dovrebbero essere collegate al tuo binario, ecco a cosa serve 'LD_LIBRARY_PATH'. – Eregrith

+1

Forse 'objcopy' ha alcune funzionalità di cui hai bisogno? –

+0

Hai guardato più a fondo su 'strip'? Credo che tu possa indirizzare particolari simboli in un file con '-R' ... – timlukins

risposta

11

Si dovrebbe essere in grado di utilizzare il -N (--strip-symbol) opzione di objcopy per ottenere ciò che desideri:

$ objcopy -N foo a.so 
+0

Perfetto! Grazie, Frederic. –

2

La visibilità dei simboli sembra una soluzione superiore per selezionare quali funzioni sono attive per il collegamento di runtime e quali sono locali per la libreria, ma ancora "extern" dichiarate per consentire l'utilizzo da altri file .c che costituiscono la libreria - http://gcc.gnu.org/wiki/Visibility.