Pregunta

Algunas plataformas exigen que proporcione una lista de símbolos externos de una biblioteca compartida al vinculador. Sin embargo, en la mayoría de los sistemas unixish eso no es necesario: todos los símbolos no estáticos estarán disponibles de forma predeterminada.

Entiendo que la cadena de herramientas GNU puede restringir opcionalmente la visibilidad solo a los símbolos declarados explícitamente. ¿Cómo se puede lograr eso usando GNU ld?

¿Fue útil?

Solución

GNU ld puede hacer eso en plataformas ELF.

Aquí se explica cómo hacerlo con un script de versión de enlazador:

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

Por defecto, todos los símbolos se exportan:

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

Supongamos que desea exportar solo bar () y baz () . Crear un " script de versión " libfoo.version :

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

Pásalo al enlazador:

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

Observe los símbolos exportados:

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

Otros consejos

Creo que la forma más fácil de hacerlo es agregar -fvisibility = hidden a las opciones de gcc y hacer explícitamente la visibilidad de algunos símbolos públicos en el código (por __attribute __ ((visibilidad (" ; predeterminado "))) ). Consulte la documentación aquí .

Puede haber una manera de lograrlo mediante scripts de ld linker, pero no sé mucho al respecto.

El código generado para llamar a cualquier función exportada o usar cualquier global exportado es menos eficiente que aquellos que no se exportan. Hay un nivel adicional de indirección involucrado. Esto se aplica a cualquier función que se pueda exportar en el momento de compilación . gcc seguirá produciendo indirección adicional para una función que luego no se exportará mediante un script vinculador. Por lo tanto, el uso del atributo de visibilidad producirá un código mejor que el script del vinculador.

Si está usando libtool, hay otra opción muy similar a la respuesta de Employed Russian.

Usando su ejemplo, sería algo como:

cat export.sym
bar
baz

Luego ejecute libtool con la siguiente opción:

libtool -export-symbols export.sym ...

Tenga en cuenta que cuando se usan los símbolos -export-export todos los símbolos NO se exportan de manera predeterminada, y solo se exportan aquellos en export.sym (por lo que la línea " local: * " en libfoo.version está implícita en este enfoque) .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top