Onde os executáveis ​​procuram objetos compartilhados em tempo de execução?

102

Eu entendo como definir objetos compartilhados no momento da vinculação / compilação. No entanto, ainda me pergunto como os executáveis ​​procuram o objeto compartilhado ( *.sobibliotecas) no tempo de execução.

Por exemplo, meu aplicativo a.outchama funções definidas na lib.sobiblioteca. Após a compilação, eu passo lib.sopara um novo diretório no meu $HOME.

Como posso dizer a.outpara procurar por lá?

rahmu
fonte

Respostas:

102

A biblioteca compartilhada HOWTO explica a maioria dos mecanismos envolvidos, e o manual do carregador dinâmico entra em mais detalhes. Cada variante unix tem seu próprio caminho, mas a maioria usa o mesmo formato executável ( ELF ) e possui vinculadores dinâmicos semelhantes (derivados do Solaris). Abaixo, resumirei o comportamento comum com foco no Linux; verifique os manuais do seu sistema para a história completa.

Em poucas palavras, quando procura uma biblioteca dinâmica ( .soarquivo), o vinculador tenta:

  • diretórios listados na LD_LIBRARY_PATHvariável de ambiente ( DYLD_LIBRARY_PATHno OSX);
  • diretórios listados no rpath do executável ;
  • diretórios no caminho de pesquisa do sistema, que (pelo menos no Linux) consiste nas entradas em /etc/ld.so.confmais /libe /usr/lib.

O rpath é armazenado no executável (é o DT_RPATHou DT_RUNPATHatributo dinâmico). Ele pode conter caminhos absolutos ou caminhos começando com $ORIGINpara indicar um caminho relativo ao local do executável (por exemplo, se o executável estiver dentro /opt/myapp/bine seu rpath for $ORIGIN/../lib:$ORIGIN/../plugins, o vinculador dinâmico procurará /opt/myapp/libe /opt/myapp/plugins). O rpath é normalmente determinado quando o executável é compilado, com a -rpathopção para ld, mas você pode alterá-lo posteriormente com chrpath.

No cenário que você descreve, se você é o desenvolvedor ou acondicionador do aplicativo e pretendemos para que possa ser instalado em um …/bin, …/libestrutura, em seguida, ligar com -rpath='$ORIGIN/../lib'. Se você estiver instalando um binário pré-criado em seu sistema, coloque a biblioteca em um diretório no caminho de pesquisa ( /usr/local/libse você é o administrador do sistema, caso contrário, um diretório ao qual você adiciona $LD_LIBRARY_PATH) ou tente chrpath.

Gilles
fonte
3
Em alguns sistemas, /lib64e /usr/lib64são usados ​​para binários de 64 bits /libe /usr/libsão usados ​​para binários de 32 bits.
precisa saber é o seguinte
Por que essa resposta correta não fala nada sobre o ldconfig ?
Loves Probability
1
@LovesProbability Porque a pergunta era sobre onde os executáveis ​​procuram bibliotecas, o que não envolve ldconfig. ldconfigse envolve quando você instala uma biblioteca.
Gilles
1
Observe que o "caminho de pesquisa do sistema" para *.sobibliotecas não é o mesmo que $PATH. O caminho de pesquisa é o indicado pelo @enzotib em sua resposta. Para imprimir os caminhos que serão pesquisados, execute ldconfig -v 2>/dev/null | grep -v ^$'\t'.
Andrew Bate
para mim, para executar o ldconfig, eu precisava /sbin/ldconfige aquela outra mágica do Andrew Bate para fazê-lo rodar sem raiz
Robert Lugg
16

No Linux, o comportamento é explicitado na ld(1)página do manual

       The linker uses the following search paths to locate required
       shared libraries:

       1.  Any directories specified by -rpath-link options.

       2.  Any directories specified by -rpath options.  The difference
           between -rpath and -rpath-link is that directories specified by
           -rpath options are included in the executable and used at
           runtime, whereas the -rpath-link option is only effective at
           link time. Searching -rpath in this way is only supported by
           native linkers and cross linkers which have been configured
           with the --with-sysroot option.

       3.  On an ELF system, for native linkers, if the -rpath and
           -rpath-link options were not used, search the contents of the
           environment variable "LD_RUN_PATH".

       4.  On SunOS, if the -rpath option was not used, search any
           directories specified using -L options.

       5.  For a native linker, the search the contents of the environment
           variable "LD_LIBRARY_PATH".

       6.  For a native ELF linker, the directories in "DT_RUNPATH" or
           "DT_RPATH" of a shared library are searched for shared
           libraries needed by it. The "DT_RPATH" entries are ignored if
           "DT_RUNPATH" entries exist.

       7.  The default directories, normally /lib and /usr/lib.

       8.  For a native linker on an ELF system, if the file
           /etc/ld.so.conf exists, the list of directories found in that
           file.

       If the required shared library is not found, the linker will issue
       a warning and continue with the link.
enzotib
fonte
1
"Os diretórios padrão, normalmente / lib e / usr / lib." -> como posso descobrir se meu sistema está normal?
Thorsten Staerk
2
A questão é sobre o tempo de execução e não ligação
Talespin_Kit
2

Tenho certeza de que a resposta aqui é ldconfig.

O ldconfig cria os links e o cache necessários para as bibliotecas compartilhadas mais recentes encontradas nos diretórios especificados na linha de comandos, no arquivo /etc/ld.so.conf e nos diretórios confiáveis ​​(/ lib e / usr / lib). O cache é usado pelo vinculador em tempo de execução, ld.so ou ld-linux.so. O ldconfig verifica o cabeçalho e os nomes dos arquivos das bibliotecas que encontra ao determinar quais versões devem ter seus links atualizados.

http://linux.die.net/man/8/ldconfig

Sean C.
fonte
0

Para aplicativos em execução, o arquivo /proc/1234/mapscontém todas as bibliotecas vinculadas dinamicamente reais.

Onde 1234está o pid do executável em execução.

O Linux segue LD_LIBRARY_PATH e outras variáveis, como apontado na resposta de Gilles.

user138692
fonte
4
É bom que você confirme em sua segunda frase que a resposta de Gilles ajuda. A primeira parte, no entanto, não contribui para explicar como informar a.out onde estão os arquivos, apenas de onde foram obtidos se eles já foram encontrados. Tudo isso deve ser apenas um comentário, não uma resposta.
Anthon