Como o próprio vinculador / carregador dinâmico pode ser vinculado dinamicamente conforme relatado por `file`?


12

Considere as dependências de objetos compartilhados de /bin/bash, que incluem /lib64/ld-linux-x86-64.so.2(vinculador / carregador dinâmico):

ldd /bin/bash
    linux-vdso.so.1 (0x00007fffd0887000)
    libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f57a04e3000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f57a04de000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f57a031d000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f57a0652000)

A inspeção /lib64/ld-linux-x86-64.so.2mostra que é um link simbólico para /lib/x86_64-linux-gnu/ld-2.28.so:

ls -la /lib64/ld-linux-x86-64.so.2 
lrwxrwxrwx 1 root root 32 May  1 19:24 /lib64/ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-2.28.so

Além disso, os filerelatórios /lib/x86_64-linux-gnu/ld-2.28.sosão dinamicamente vinculados:

file -L /lib64/ld-linux-x86-64.so.2
/lib64/ld-linux-x86-64.so.2: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=f25dfd7b95be4ba386fd71080accae8c0732b711, stripped

Eu gostaria de saber:

  1. Como o próprio linker / loader ( /lib64/ld-linux-x86-64.so.2) dinamicamente pode ser vinculado dinamicamente? Ele se vincula em tempo de execução?
  2. /lib/x86_64-linux-gnu/ld-2.28.soestá documentado para manipular a.out binários ( man ld.so), mas /bin/bashé um ELF executável?

O programa ld.so lida com binários a.out, um formato usado há muito tempo; O ld-linux.so * (/lib/ld-linux.so.1 para libc5, /lib/ld-linux.so.2 para glibc2) identifica o ELF, que todo mundo usa há anos.


O kernel não se importa com essas sutilezas taxonômicas (e você também não deve ;-)). O kernel apenas faz a diferença entre ELFs que precisam de um intérprete e aqueles que não precisam . E o AFAIK, você não pode usar um intérprete que precise dele.
— mosvy

@StephenKitt mine não tem ( /lib/x86_64-linux-gnu/ld-2.28.so, debian 10 buster)
— mosvy

@mosvy sim, desculpe, eu me envolvi no filecomentário errado de como ele define binários estáticos e a realidade de ld-2.28.so... O diferencial é PT_DYNAMIC.
— Stephen Kitt

Respostas:


17
  1. Sim, ele se liga quando é inicializado. Tecnicamente, o vinculador dinâmico não precisa de resolução e realocação de objetos, pois é totalmente resolvido como está, mas define símbolos e precisa cuidar deles ao resolver o binário que está "interpretando", e esses símbolos são atualizados para apontar para suas implementações nas bibliotecas carregadas. Em particular, isso afeta malloc- o vinculador possui uma versão mínima integrada, com o símbolo correspondente, mas é substituída pela versão da biblioteca C quando carregada e realocada (ou mesmo por uma versão interposta, se houver), com algum cuidado tomadas para garantir que isso não aconteça em um ponto em que possa interromper o vinculador.

    Os detalhes sangrentos estão rtld.c, nodl_main função.

    Observe no entanto que ld.sonão possui dependências externas. Você pode ver os símbolos envolvidos nm -D; nenhum deles é indefinido.

  2. A página de manual refere-se apenas às entradas diretamente em /lib, ie /lib/ld.so (o vinculador dinâmico libc 5, que suporta a.out) e /lib*/ld-linux*.so*(o vinculador dinâmico libc 6, que suporta ELF). A página de manual é muito específica e ld.sonão é ld-2.28.so.

    O vinculador dinâmico encontrado na grande maioria dos sistemas atuais não inclui a.outsuporte.

filee lddrelata coisas diferentes para o vinculador dinâmico porque elas têm definições diferentes do que constitui um binário vinculado estaticamente. Pois ldd, um binário está estaticamente vinculado se não tiver DT_NEEDEDsímbolos, ou seja , sem símbolos indefinidos. Pois file, um binário ELF é estaticamente vinculado se não tiver uma PT_DYNAMICseção (isso será alterado na versão file5.37 a seguir; agora usa a presença de uma PT_INTERPseção como o indicador de um binário vinculado dinamicamente, que corresponde ao comentário em o código).

O vinculador dinâmico da biblioteca GNU C não possui DT_NEEDEDsímbolos, mas possui uma PT_DYNAMICseção (já que é tecnicamente uma biblioteca compartilhada). Como resultado, ldd(que é o vinculador dinâmico) indica que ele está vinculado estaticamente, mas fileindica que ele está vinculado dinamicamente. Ele não possui uma PT_INTERPseção, portanto, a próxima versão do filetambém indicará que está vinculada estaticamente.

$ ldd /lib64/ld-linux-x86-64.so.2
        statically linked

$ file $(readlink /lib64/ld-linux-x86-64.so.2)
/lib/x86_64-linux-gnu/ld-2.28.so: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=f25dfd7b95be4ba386fd71080accae8c0732b711, stripped

(com file5.35)

$ file $(readlink /lib64/ld-linux-x86-64.so.2)
/lib/x86_64-linux-gnu/ld-2.28.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=f25dfd7b95be4ba386fd71080accae8c0732b711, stripped

(com a versão atualmente em desenvolvimento de file).


Por que a palavra "interpretação" é usada no contexto da vinculação dinâmica? Essa palavra é geralmente usada no contexto de linguagens de programação.
— Shuzheng

O que você quer dizer com "vinculador dinâmico da biblioteca GNU C"? Você está se referindo a /lib*/ld-linux*.so*um terceiro vinculador dinâmico?
— Shuzheng

Onde você pode ver os lddrelatórios do vinculador dinâmico como vinculado estaticamente? Porque sua lista de dependências de objetos compartilhados está vazia?
— Shuzheng

Os programas vinculados dinamicamente precisam de algum trabalho feito antes que possam ser executados; esse trabalho é realizado pelo vinculador dinâmico, que acaba desempenhando uma função semelhante a um intérprete - ele interpreta as tabelas de realocação etc. para produzir algo que o computador possa executar.
— Stephen Kitt

Quando digo "vinculador dinâmico da biblioteca GNU C", refiro-me à implementação incluída na biblioteca GNU C, normalmente enviada como /lib*/ld-linux*.so*. Especifiquei a origem do vinculador dinâmico porque existem outras implementações disponíveis para Linux.
— Stephen Kitt

0
  1. Suspeito que o fileprograma esteja errado sobre o vinculador / carregador dinâmico ser vinculado dinamicamente. O lddprograma não concorda. Pelo menos não no meu sistema (Debian Stretch):

    ldd /lib/x86_64-linux-gnu/ld-2.24.so
        statically linked
    
  2. man ld.sotambém lê: "ld-linux.so * lida com ELF" . No seu sistema (e também no meu também), ambos são links simbólicos para o mesmo binário que deduzi que é capaz de lidar com o ELF e o formato a.out (obsoleto antigo).


que informações você adiciona à resposta aceita?
— miracle173

2
@ miracle173 esta resposta é mais antiga que a resposta aceita ;-).
— Stephen Kitt

você está certo. Eu perdi isso. Eu pensei que a pergunta e a resposta aceita eram muito antigas e essa resposta foi publicada nas últimas horas. Não posso desfazer meu voto negativo até que alguém modifique a postagem.
— miracle173
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.