Linux, GNU GCC, ld, scripts de versão e o formato binário ELF - Como funciona?

10

Estou tentando aprender mais sobre versionamento de bibliotecas no Linux e como colocar tudo isso para funcionar. Aqui está o contexto:

- Eu tenho duas versões de uma biblioteca dinâmica que expõem o mesmo conjunto de interfaces, digamos libsome1.so e libsome2.so .

- Um aplicativo está vinculado a libsome1.so .

- Este aplicativo usa libdl.so para carregar dinamicamente outro módulo, digamos libmagic.so .

- Agora libmagic.so está vinculado a libsome2.so . Obviamente, sem usar scripts de vinculador para ocultar símbolos em libmagic.so , no tempo de execução, todas as chamadas para interfaces em libsome2.so são resolvidas para libsome1.so . Isso pode ser confirmado, verificando o valor retornado por libVersion() em relação ao valor da macro LIB_VERSION .

- Então eu tento compilar e vincular libmagic.so com um script de vinculador que oculta todos os símbolos, exceto 3, que são definidos em libmagic.so e são exportados por ele. Isso funciona ... Ou pelo menos libVersion() e LIB_VERSION valores correspondem (e ele relata a versão 2 não 1).

- No entanto, quando algumas estruturas de dados são serializadas em disco, notei alguma corrupção. No diretório do aplicativo, se eu excluir libsome1.so e criar um link temporário em seu lugar para apontar para libsome2.so , tudo funcionará como esperado e a mesma corrupção não ocorrerá.

Não posso deixar de pensar que isso pode ser causado devido a algum conflito na resolução de símbolos do link de tempo de execução. Eu tentei muitas coisas, como tentar vincular libsome2.so para que todos os símbolos fiquem alised para symbol@@VER_2 (o que eu ainda estou confuso porque o comando nm -CD libsome2.so ainda lista símbolos como symbol e não symbol@@VER_2 ) ... Nada parece funcionar !!! Ajuda !!!!!!

    
por themoondothshine 12.01.2011 / 05:31

1 resposta

10

Isso não responde exatamente à sua pergunta, mas ...

Em primeiro lugar, o ELF é o uso de especificação do Linux para arquivos executáveis (programas), bibliotecas compartilhadas e também arquivos de objetos, que são os arquivos intermediários encontrados durante a compilação do software. Os arquivos de objetos terminam em .o, as bibliotecas compartilhadas terminam com .so seguidos por zero ou mais dígitos separados por pontos, e os arquivos executáveis não possuem nenhuma extensão normalmente.

Normalmente existem três formulários para nomear uma biblioteca compartilhada, o primeiro formulário simplesmente termina em .so. Por exemplo, uma biblioteca chamada readline é armazenada em um arquivo chamado libreadline.so e está localizada em uma das bibliotecas / lib, / usr / lib ou / usr / local / lib normalmente. Esse arquivo está localizado ao compilar o software com uma opção como -lreadline. -l diz ao compilador para vincular-se à biblioteca a seguir. Como as bibliotecas mudam de tempos em tempos, elas podem se tornar obsoletas, de modo que as bibliotecas incorporam algo chamado SONAME. O SONAME para readline pode parecer com libreadline.so.2 para a versão principal da segunda versão do libreadline. Também pode haver muitas versões secundárias de readline compatíveis e que não exigem que o software seja recompilado. Uma versão secundária da readline pode ser denominada libreadline.so.2.14. Normalmente o libreadline.so é apenas um link simbólico para a versão principal mais recente do readline, libreadline.so.2 neste caso. libreadline.so.2 é também um link simbólico para libreadline.so.2.14 que é, na verdade, o arquivo que está sendo usado.

O SONAME de uma biblioteca é incorporado dentro do próprio arquivo da biblioteca. Em algum lugar dentro do arquivo libreadline.so.2.14 está a string libreadline.so.2. Quando um programa é compilado e vinculado à readline, ele procurará o arquivo libreadline.so e lerá o SONAME incorporado nele. Mais tarde, quando o programa for realmente executado, ele carregará libreadline.so.2, não apenas libreadline.so, já que foi o SONAME que foi lido quando foi vinculado pela primeira vez. Isso permite que um sistema tenha várias versões incompatíveis de readline instaladas, e cada programa carregará a versão principal apropriada com a qual ele foi vinculado. Além disso, ao atualizar o readline, digamos, para o 2.17, posso instalar o libreadline.so.2.17 junto com a biblioteca existente, e assim que eu mover o link simbólico libreadline.so.2 do libreadline.so.2.13 para o libreadline.so.2.17, Todos os softwares que usam essa mesma versão principal agora verão a nova atualização menor.

    
por 30.03.2011 / 17:54