Question

Certaines plateformes exigent que vous fournissiez une liste des symboles externes d’une bibliothèque partagée à l’éditeur de liens. Cependant, sur la plupart des systèmes unix, cela n’est pas nécessaire: tous les symboles non statiques seront disponibles par défaut.

D'après ce que je comprends, la chaîne d'outils GNU peut éventuellement limiter la visibilité aux symboles explicitement déclarés. Comment peut-on y parvenir avec GNU ld?

Était-ce utile?

La solution

GNU ld peut le faire sur les plateformes ELF.

Voici comment procéder avec un script de version de l'éditeur de liens:

/* 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 '

Par défaut, tous les symboles sont exportés:

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

Supposons que vous souhaitiez exporter uniquement bar () et baz () . Créer un " version script " libfoo.version :

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

Transmettez-le à l'éditeur de liens:

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

Observez les symboles exportés:

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

Autres conseils

Je pense que la solution la plus simple consiste à ajouter -fvisibility = hidden aux options gcc et à rendre explicitement public la visibilité de certains symboles dans le code (par __ attribut __ ((visibilité (" ; défaut "))) ). Consultez la documentation ici .

Il existe peut-être un moyen de réaliser cela avec les scripts de l'éditeur de liens, mais je ne sais pas grand chose à ce sujet.

Le code généré pour appeler les fonctions exportées ou utiliser les éléments globaux exportés est moins efficace que ceux qui ne sont pas exportés. Il y a un niveau supplémentaire d'indirection impliqué. Ceci s’applique à toute fonction que pourrait être exporté au moment de compiler . gcc produira toujours une indirection supplémentaire pour une fonction qui sera ultérieurement exportée par un script de l'éditeur de liens. Donc, utiliser l'attribut de visibilité produira un meilleur code que le script de l'éditeur de liens.

Si vous utilisez libtool, il existe une autre option qui ressemble beaucoup à la réponse de Employed Russian.

En utilisant son exemple, ce serait quelque chose comme:

cat export.sym
bar
baz

Exécutez ensuite libtool avec l'option suivante:

libtool -export-symbols export.sym ...

Notez que lorsque vous utilisez -export-symboles, tous les symboles NE sont PAS exportés par défaut et seuls ceux de export.sym sont exportés (la ligne "local: *" dans libfoo.version est donc implicite dans cette approche). .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top