Limitando a visibilidade dos símbolos quando ligar bibliotecas compartilhadas
-
10-07-2019 - |
Pergunta
Algumas plataformas mandato que lhe fornecer uma lista de símbolos externos de uma biblioteca compartilhada para o vinculador. No entanto, na maioria dos sistemas unixish isso não é necessário:. Todos os símbolos não-estáticos estará disponível por padrão
O meu entendimento é que o conjunto de ferramentas GNU pode opcionalmente restringir a visibilidade apenas para símbolos explicitamente declarados. Como isso pode ser conseguido usando GNU ld?
Solução
GNU ld
pode fazer isso em plataformas ELF.
Aqui está como fazê-lo com um script versão vinculador:
/* 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 padrão, todos os símbolos são exportados:
0000000000000718 T _fini
00000000000005b8 T _init
00000000000006b7 T bar
00000000000006c9 T baz
00000000000006ac T foo
Vamos dizer que você quer única bar()
e baz()
para exportar. Criar um libfoo.version
"roteiro versão":
FOO {
global: bar; baz; # explicitly list symbols to be exported
local: *; # hide everything else
};
passá-lo para o vinculador:
gcc -fPIC -shared -o libfoo.so foo.c -Wl,--version-script=libfoo.version
Observe símbolos exportados:
nm -D libfoo.so | grep ' T '
00000000000005f7 T bar
0000000000000609 T baz
Outras dicas
Eu acho que a maneira mais fácil de fazer isso é adicionar o -fvisibility=hidden
às opções do CCG e explicitamente fazer a visibilidade de alguns símbolos pública no código (por __attribute__((visibility("default")))
). Consulte a documentação do aqui .
Pode haver uma maneira de conseguir isso por scripts vinculador ld, mas eu não sei muito sobre ele.
O código gerado para chamar quaisquer funções exportadas ou usar qualquer globals exportados é menos eficiente do que aqueles que não são exportados. Há um nível extra de engano envolvidos. Isso se aplica a qualquer função que pode ser exportados em compilação tempo. gcc ainda irá produzir engano extra para uma função que é depois un-exportados por um script vinculador. Então, usando o atributo de visibilidade irá produzir um código melhor do que o script vinculador.
Se você estiver usando libtool, não há outra opção muito parecido Employed resposta do russo.
Usando o seu exemplo, seria algo como:
cat export.sym
bar
baz
libtool Em seguida, execute com a opção a seguir:
libtool -export-symbols export.sym ...
Observe que ao usar -Exportar-símbolos todos os símbolos não são exportados por padrão, e somente aqueles em export.sym são exportados (por isso o "local: *" linha no libfoo.version é realmente implícita nesta abordagem) <. / p>