Как ldd знает это в зависимости от libc.so.6, а не libc.so.5 или libc.so.7?
libc.so.6 => /lib64/libc.so.6 (0x00000034f4000000)
/lib64/ld-linux-x86-64.so.2 (0x00000034f3c00000)
Как ldd знает это в зависимости от libc.so.6, а не libc.so.5 или libc.so.7?
libc.so.6 => /lib64/libc.so.6 (0x00000034f4000000)
/lib64/ld-linux-x86-64.so.2 (0x00000034f3c00000)
Он записывается внутри самого двоичного приложения (указанный во время компиляции, точнее на этапе ссылки, выполненном с помощью ld):
$ readelf -d /bin/echo
Dynamic section at offset 0x5f1c contains 21 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libc.so.6]
...
(есть несколько дополнительных столбцов для того, как эльф хранит информацию в динамическом разделе, но вы можете видеть, что libc.so.6 жестко закодирован с суффиксом .6 из-за SONAME)
или даже без знания формата файла ELF:
$ strings /bin/echo |grep libc.so
libc.so.6
Чтобы найти, как компоновщик находит библиотеку (это делается на последнем этапе компиляции), используйте gcc option -Wl,--verbose (это запрашивает gcc для передачи опции --verbose в ld):
$ gcc a.c -Wl,--verbose
...
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.so failed
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.a failed
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.so failed
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/libc.a failed
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/../../../libc.so succeeded
opened script file /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/../../../libc.so
opened script file /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/../../../libc.so
attempt to open /lib/libc.so.6 succeeded
/lib/libc.so.6
Linker ничего не знает о суффиксе .digit, он просто перебирает все каталоги поиска библиотек, пытаясь открыть libLIBNAME.so и libLIBNAME.a, где LIBNAME - это строка после опции -l. (-lc добавляется по умолчанию).
Первый успех - это /usr/lib/libc.so, который сам по себе не является библиотекой, а компоновщиком script (текстовый файл). Вот содержание от типичного libc.so script:
$ cat /usr/lib/libc.so
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf32-i386)
GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux.so.2 ) )
Итак, script /usr/lib/libc.so найден раньше, чем фактическая библиотека, и этот script говорит, какой файл будет связан, libc.so.6 в этом случае.
В более общем случае lib___.so символически ссылается на некоторую версию, например lib___.so.3.4.5, и есть поле SONAME, заполненное в lib___.so.3.4.5, которое указывает на ld ссылку не на lib___.so, а на lib___.so.3.4, которая является другой символическая ссылка на lib___.so.3.4.5. Имя .3.4 будет записано в поле NEEDED двоичного файла.
http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#dynamic_section
Имеет смысл каждого динамического тега. 1 указывает, что это тэг DT_NEEDED, означающий в этом случае
typedef struct {
Elf32_Sword d_tag;
union {
Elf32_Word d_val;
Elf32_Addr d_ptr;
} d_un;
} Elf32_Dyn;
Структура имеет d_val union valid и ищет смещение, указанное членом thi union в таблице DT_STRTAB, чтобы найти имя библиотеки, от которой зависит этот двоичный файл/SO.