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?

Foi útil?

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>

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top