Domanda

Alcune piattaforme richiedono di fornire un elenco dei simboli esterni di una libreria condivisa al linker. Tuttavia, sulla maggior parte dei sistemi unixish non è necessario: tutti i simboli non statici saranno disponibili per impostazione predefinita.

La mia comprensione è che la toolchain GNU può opzionalmente limitare la visibilità solo ai simboli esplicitamente dichiarati. Come si può ottenere ciò usando GNU ld?

È stato utile?

Soluzione

GNU ld può farlo su piattaforme ELF.

Ecco come farlo con uno script della versione del linker:

/* foo.c */
int foo() { return 42; }
int bar() { return foo() + 1; }
int baz() { return bar() - 1; }

gcc -fPIC -shared -o libfoo.so foo.c && nm -D libfoo.so | grep ' T '

Per impostazione predefinita, tutti i simboli vengono esportati:

0000000000000718 T _fini
00000000000005b8 T _init
00000000000006b7 T bar
00000000000006c9 T baz
00000000000006ac T foo

Supponiamo che tu voglia esportare solo bar () e baz () . Crea un " script di versione " libfoo.version :

FOO {
  global: bar; baz; # explicitly list symbols to be exported
  local: *;         # hide everything else
};

Passalo al linker:

gcc -fPIC -shared -o libfoo.so foo.c -Wl,--version-script=libfoo.version

Osserva i simboli esportati:

nm -D libfoo.so | grep ' T '
00000000000005f7 T bar
0000000000000609 T baz

Altri suggerimenti

Penso che il modo più semplice per farlo sia quello di aggiungere -fvisibility = hidden alle opzioni gcc e rendere esplicitamente pubblica la visibilità di alcuni simboli nel codice (con __attribute __ ((visibilità (" ; predefinito "))) ). Consulta la documentazione qui .

Potrebbe esserci un modo per farlo con gli script di linker LD, ma non ne so molto.

Il codice generato per chiamare qualsiasi funzione esportata o utilizzare qualsiasi globalità esportata è meno efficiente di quelli non esportati. C'è un ulteriore livello di riferimento indiretto. Questo vale per qualsiasi funzione che potrebbe essere esportata al momento della compilazione . gcc produrrà ancora una indiretta extra per una funzione che in seguito non sarà esportata da uno script di linker. Pertanto, l'utilizzo dell'attributo di visibilità produrrà un codice migliore rispetto allo script del linker.

Se stai usando libtool, c'è un'altra opzione molto simile alla risposta di Employed Russian.

Usando il suo esempio, sarebbe qualcosa del tipo:

cat export.sym
bar
baz

Quindi esegui libtool con la seguente opzione:

libtool -export-symbols export.sym ...

Nota che quando si usano -export-simboli tutti i simboli NON vengono esportati per impostazione predefinita e vengono esportati solo quelli in export.sym (quindi la riga " local: * " in libfoo.version è effettivamente implicita in questo approccio) .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top