Por que existem `/ lib` e` / lib64`, mas apenas `/ bin`?

27

No meu laptop:

$ cat /etc/issue  
Ubuntu 18.04 LTS \n \l

Existem duas pastas diferentes para bibliotecas x86e x86_64:

~$ ls -1 /  
bin
lib
lib64
sbin
...

Por que para binários existe apenas um diretório?

PS: Também estou interessado no Android, mas espero que a resposta seja a mesma.

Gluttton
fonte
11
Apenas em um? Eu vejo os dois /bine /sbinlá. Qual é a pergunta? Você está perguntando sobre a diferença entre /libe /lib64?
Kusalananda
2
@ Kusalananda, quero dizer que não existe uma pasta independente para x86_64(nem para /binnão /sbin).
Gluttton
7
O IMO OP quer saber por que não existe /bin64.
Arkadiusz Drabczyk
O aproximadamente um aplicativo que se beneficia de ter as versões de 32 e 64 bits (WINE) contorna isso, tendo binários com nomes diferentes ( wine*32e wine*64).
Ignacio Vazquez-Abrams
11
@ IgnacioVazquez-Abrams: também é preciso dizer que você vincula binários a bibliotecas, e não vice-versa. Portanto, os binários não precisam ser particionados por 32/64-bitness.
SMCI

Respostas:

25

Primeiro, por que existem separados /libe /lib64:

O padrão de hierarquia do sistema de arquivos menciona que se separam /libe /lib64existem porque:

10.1 Pode haver uma ou mais variantes do diretório / lib em sistemas que suportam mais de um formato binário que requer bibliotecas separadas. (...) Geralmente é usado para suporte de 64 ou 32 bits em sistemas que suportam vários formatos binários, mas requerem bibliotecas com o mesmo nome. Nesse caso, / lib32 e / lib64 podem ser os diretórios da biblioteca e / lib um link simbólico para um deles.

No meu Slackware 14.2, por exemplo, existem /libe /lib64 diretórios para bibliotecas de 32 e 64 bits, respectivamente, mesmo que /libnão sejam um link simbólico, como sugere o snippet do FHS:

$ ls -l /lib/libc.so.6
lrwxrwxrwx 1 root root 12 Aug 11  2016 /lib/libc.so.6 -> libc-2.23.so
$ ls -l /lib64/libc.so.6
lrwxrwxrwx 1 root root 12 Aug 11  2016 /lib64/libc.so.6 -> libc-2.23.so

Existem duas libc.so.6bibliotecas em /libe /lib64.

Cada binário ELF construído dinamicamente contém um caminho codificado para o intérprete, neste caso /lib/ld-linux.so.2ou /lib64/ld-linux-x86-64.so.2:

$ file main
main: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, not stripped
$ readelf  -a main  | grep 'Requesting program interpreter'
      [Requesting program interpreter: /lib/ld-linux.so.2]

$ file ./main64
./main64: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, not stripped
$ readelf  -a main64  | grep 'Requesting program interpreter'
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]

O trabalho do intérprete é carregar as bibliotecas compartilhadas necessárias. Você pode perguntar a um intérprete GNU que bibliotecas ele carregaria sem nem mesmo executar um uso binário LD_TRACE_LOADED_OBJECTS=1ou um lddwrapper:

$ LD_TRACE_LOADED_OBJECTS=1 ./main
        linux-gate.so.1 (0xf77a9000)
        libc.so.6 => /lib/libc.so.6 (0xf760e000)
        /lib/ld-linux.so.2 (0xf77aa000)
$ LD_TRACE_LOADED_OBJECTS=1 ./main64
        linux-vdso.so.1 (0x00007ffd535b3000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f56830b3000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f568347c000)

Como você pode ver, um determinado intérprete sabe exatamente onde procurar bibliotecas - a versão de 32 bits procura por bibliotecas /libe a versão de 64 bits procura por bibliotecas /lib64.

O padrão FHS diz o seguinte sobre /bin:

/ bin contém comandos que podem ser usados ​​pelo administrador do sistema e pelos usuários, mas que são necessários quando nenhum outro sistema de arquivos é montado (por exemplo, no modo de usuário único). Também pode conter comandos que são usados ​​indiretamente por scripts.

IMO a razão pela qual não há separada /bine /bin64é que, se tivéssemos o arquivo com o mesmo nome em ambos os diretórios que não poderia chamar um deles indiretamente, porque teríamos de colocar /binou /bin64pela primeira vez em $PATH.

No entanto, observe que o exposto acima é apenas a convenção - o kernel do Linux realmente não se importa se você tiver separado /bine /bin64. Se você os quiser, poderá criá-los e configurar seu sistema de acordo.

Você também mencionou o Android - observe que, exceto para a execução de um kernel Linux modificado, ele não tem nada a ver com sistemas GNU como o Ubuntu - no glibc, no bash (por padrão, é claro que você pode compilar e implantar manualmente) e também a estrutura de diretórios é completamente diferente.

Arkadiusz Drabczyk
fonte
Seus ls -lexemplos não são particularmente relevantes. O que seria útil é a saída de ls -l /lib /lib64, o que provavelmente mostra que /libele próprio é um link simbólico.
usar o seguinte comando
Você quis dizer ls -ld, e não, /libnão é um link simbólico no meu Slackware 14.2sistema.
Arkadiusz Drabczyk
As bibliotecas têm md5sums diferentes: dfd029d25c58831bc5db671aec99a36f /lib64/libc.so.6, 987e7b736f316cc8da87ca2f38dae93e /lib/libc.so.6.
Arkadiusz Drabczyk
2
Nesse caso, mostrar os links simbólicos no diretório não se conecta à citação.
usar o seguinte comando
11
LD_TRACE_LOADED_OBJECTS = 1 está obsoleto devido a uma falha de segurança e o ldd não o usa mais. Razão: ldd / path / to / binário-estático-malicioso foi usado para assumir o controle dos sistemas porque os administradores do sistema esperavam que o ldd olhasse apenas para o binário e não o executasse. Além disso, a verificação estática ou não é inadequada, pois um binário pode ser construído para usar um carregador mal-intencionado.
Joshua
22

O motivo é que os diretórios lib / lib64 podem conter arquivos com o mesmo nome, porque são bibliotecas compartilhadas com diversos programas. Colocá-los em diretórios separados resolve o conflito. Não há (normalmente ...) uma boa razão para distribuir executáveis ​​com o mesmo nome no mesmo sistema com 32/64 bits, mas como pode haver uma mistura de executáveis, as bibliotecas compartilhadas precisam ser fornecidas.

Thomas Dickey
fonte