Почему существуют `/ lib` и` / lib64`, а есть только `/ bin`?

27

В моем ноутбуке:

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

Есть две разные папки для библиотек x86и x86_64:

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

Почему для двоичных файлов существует только один каталог?

PS Я также заинтересован в Android, но я надеюсь, что ответ должен быть таким же.

Gluttton
источник
1
Только в одном? Я вижу /binи /sbinтам, и там. В чем вопрос? Вы спрашиваете о разнице между /libи /lib64?
Кусалананда
2
@Kusalananda, я имею в виду, что нет независимой папки для x86_64(ни для /binне для /sbin).
Обжора
7
ИМО ОП хочет знать, почему нет /bin64.
Аркадиуш Драбчик,
Примерно одно приложение, которое выигрывает от наличия как 32-битных, так и 64-битных версий (WINE), обходит его, имея двоичные файлы с разными именами ( wine*32и wine*64).
Игнасио Васкес-Абрамс
1
@ IgnacioVazquez-Abrams: нужно также сказать, что вы связываете двоичные файлы с библиотеками, а не наоборот. Таким образом, двоичные файлы не должны быть разделены на 32/64-битность.
SMCI

Ответы:

25

Во-первых, почему существуют отдельные /libи /lib64:

Filesystem Hierarchy Standard отмечает , что отдельные /libи /lib64существуют , потому что:

10.1. В системах может быть один или несколько вариантов каталога / lib, которые поддерживают более одного двоичного формата, требующего отдельных библиотек. (...) Это обычно используется для поддержки 64-битных или 32-битных систем, которые поддерживают несколько двоичных форматов, но требуют библиотек с одинаковым именем. В этом случае / lib32 и / lib64 могут быть каталогами библиотеки, а / lib - символической ссылкой на один из них.

На моем Slackware 14.2, например, есть /libи /lib64 каталоги для 32-битных и 64-битных библиотек соответственно, хотя /libэто и не символическая ссылка, как предполагает фрагмент кода 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

Есть две libc.so.6библиотеки /libи /lib64.

Каждый динамически построена ELF двоичный содержит жестко запрограммированный путь к интерпретатору, в этом случае либо /lib/ld-linux.so.2или /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]

Работа переводчика заключается в загрузке необходимых общих библиотек. Вы можете спросить интерпретатор GNU, какие библиотеки он будет загружать, даже не запуская бинарный файл LD_TRACE_LOADED_OBJECTS=1или lddоболочку:

$ 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)

Как видите, данный интерпретатор точно знает, где искать библиотеки - 32-битная версия ищет библиотеки в, /libа 64-битная версия ищет библиотеки в /lib64.

Стандарт FHS гласит следующее /bin:

/ bin содержит команды, которые могут использоваться как системным администратором, так и пользователями, но требуются, если не смонтированы другие файловые системы (например, в однопользовательском режиме) Он также может содержать команды, которые косвенно используются скриптами.

IMO причина, по которой не существует отдельных /binи /bin64состоит в том, что если бы у нас был файл с одинаковым именем в обоих этих каталогах, мы не могли бы вызвать один из них косвенно, потому что мы должны были бы поместить /binили /bin64сначала в $PATH.

Тем не менее, обратите внимание, что вышесказанное является всего лишь соглашением - ядру Linux на самом деле все равно, если у вас есть отдельные /binи /bin64. Если вы хотите их, вы можете создать их и настроить свою систему соответственно.

Вы также упомянули Android - обратите внимание, что кроме запуска модифицированного ядра Linux, он не имеет ничего общего с системами GNU, такими как Ubuntu - без glibc, без bash (по умолчанию вы, конечно, можете скомпилировать и развернуть его вручную), а также со структурой каталогов. совершенно другой.

Аркадиуш Драбчик
источник
Ваши ls -lпримеры не особенно уместны. Что было бы полезно, так это вывод ls -l /lib /lib64, который, вероятно, показывает, что /libон является символической ссылкой.
Хрилис - на забастовку -
Вы имели в виду ls -ld, и нет, /libэто не символическая ссылка в моей Slackware 14.2системе.
Аркадиуш Драбчик
В библиотеках разные md5sums: dfd029d25c58831bc5db671aec99a36f /lib64/libc.so.6, 987e7b736f316cc8da87ca2f38dae93e /lib/libc.so.6.
Аркадиуш Драбчик
2
В этом случае показ ссылок в каталоге не приводит к цитированию.
Хрилис - на забастовке -
1
LD_TRACE_LOADED_OBJECTS = 1 устарел из-за дыры в безопасности, и ldd больше его не использует. Причина: ldd / path / to / malware-static-binary использовался для захвата систем, потому что системные администраторы ожидали, что ldd будет смотреть только на двоичный файл, а не запускать его. Кроме того, проверка на статическую или нет неадекватна, поскольку двоичный файл может быть создан для использования вместо этого вредоносного загрузчика.
Джошуа
22

Причина в том, что каталоги lib / lib64 могут содержать файлы с одинаковыми именами, потому что это библиотеки, используемые в разных программах. Размещение их в отдельных каталогах решает конфликт. Нет (обычно ...) веских причин для распределения исполняемых файлов с одинаковыми именами в одной и той же системе, которые являются 32/64-битными, но, поскольку может быть смесь исполняемых файлов, необходимо предоставить общие библиотеки.

Томас Дики
источник