Откуда берется объектный файл "Ссылки на версии"?
В настоящее время я нахожусь в каталоге, в котором есть файл libshared-object.so
(имя изменено для общности).
Когда я бегу
$ objdump -p libshared-object.so
Я получаю следующий вывод:
libshared-object.so: file format elf64-x86-64
Program Header:
LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**21
filesz 0x00000000000828ee memsz 0x00000000000828ee flags r-x
LOAD off 0x0000000000083768 vaddr 0x0000000000283768 paddr 0x0000000000283768 align 2**21
filesz 0x00000000000048e0 memsz 0x0000000000004af0 flags rw-
DYNAMIC off 0x0000000000084af0 vaddr 0x0000000000284af0 paddr 0x0000000000284af0 align 2**3
filesz 0x00000000000002a0 memsz 0x00000000000002a0 flags rw-
NOTE off 0x00000000000001c8 vaddr 0x00000000000001c8 paddr 0x00000000000001c8 align 2**2
filesz 0x0000000000000024 memsz 0x0000000000000024 flags r--
EH_FRAME off 0x0000000000072c6c vaddr 0x0000000000072c6c paddr 0x0000000000072c6c align 2**2
filesz 0x0000000000002ed4 memsz 0x0000000000002ed4 flags r--
STACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
RELRO off 0x0000000000083768 vaddr 0x0000000000283768 paddr 0x0000000000283768 align 2**0
filesz 0x0000000000001898 memsz 0x0000000000001898 flags r--
Dynamic Section:
NEEDED libQt5Widgets.so.5
NEEDED libQt5Compositor.so.5
NEEDED libQt5Quick.so.5
NEEDED libQt5Qml.so.5
NEEDED libQt5Network.so.5
NEEDED libQt5Gui.so.5
NEEDED libQt5Core.so.5
NEEDED libGL.so.1
NEEDED libpthread.so.0
NEEDED libstdc++.so.6
NEEDED libm.so.6
NEEDED libgcc_s.so.1
NEEDED libc.so.6
SONAME libshared-object.so.1
RPATH /opt/qt5/lib
INIT 0x000000000003fc68
FINI 0x000000000006c234
INIT_ARRAY 0x0000000000283768
INIT_ARRAYSZ 0x00000000000000e8
FINI_ARRAY 0x0000000000283850
FINI_ARRAYSZ 0x0000000000000008
GNU_HASH 0x00000000000001f0
STRTAB 0x00000000000101e8
SYMTAB 0x00000000000036d8
STRSZ 0x0000000000022072
SYMENT 0x0000000000000018
PLTGOT 0x0000000000285000
PLTRELSZ 0x0000000000008df0
PLTREL 0x0000000000000007
JMPREL 0x0000000000036e78
RELA 0x0000000000033458
RELASZ 0x0000000000003a20
RELAENT 0x0000000000000018
VERNEED 0x0000000000033348
VERNEEDNUM 0x0000000000000006
VERSYM 0x000000000003225a
RELACOUNT 0x0000000000000052
Version References:
required from libm.so.6:
0x09691a75 0x00 09 GLIBC_2.2.5
required from libgcc_s.so.1:
0x0b792650 0x00 08 GCC_3.0
required from libc.so.6:
0x06969194 0x00 10 GLIBC_2.14
0x09691a75 0x00 07 GLIBC_2.2.5
required from libQt5Core.so.5:
0x00058a25 0x00 06 Qt_5
required from libQt5Gui.so.5:
0x0dcbd2c9 0x00 12 Qt_5_PRIVATE_API
0x00058a25 0x00 03 Qt_5
required from libstdc++.so.6:
0x0bafd178 0x00 11 CXXABI_1.3.8
0x056bafd3 0x00 05 CXXABI_1.3
0x0297f871 0x00 04 GLIBCXX_3.4.21
0x08922974 0x00 02 GLIBCXX_3.4
Особый интерес представляет самая последняя информация, версия Ссылки:
Version References:
required from libm.so.6:
0x09691a75 0x00 09 GLIBC_2.2.5
required from libgcc_s.so.1:
0x0b792650 0x00 08 GCC_3.0
required from libc.so.6:
0x06969194 0x00 10 GLIBC_2.14
0x09691a75 0x00 07 GLIBC_2.2.5
required from libQt5Core.so.5:
0x00058a25 0x00 06 Qt_5
required from libQt5Gui.so.5:
0x0dcbd2c9 0x00 12 Qt_5_PRIVATE_API
0x00058a25 0x00 03 Qt_5
required from libstdc++.so.6:
0x0bafd178 0x00 11 CXXABI_1.3.8
0x056bafd3 0x00 05 CXXABI_1.3
0x0297f871 0x00 04 GLIBCXX_3.4.21
0x08922974 0x00 02 GLIBCXX_3.4
Вопрос: Откуда эти ссылки на версии? Взять, к примеру, строку required from libQt5Gui.so.5: .. Qt_5
а также Qt_5_PRIVATE_API
,
Есть ссылки на версию Qt_5
а также Qt_5_PRIVATE_API
исходя из кода C, который сгенерировал libQt5Gui.so.5
? Или из какой-либо опции компоновщика, переданной в gcc
или же ld
? Или из чего-то еще?
1 ответ
Или из чего-то еще?
Из чего-то еще.
Когда вы создаете общую библиотеку (скажем, libfoo.so
), вы можете (хотя и не обязаны) предоставить скрипт версии компоновщика, дающий определенным символам тег версии.
Когда вы позже свяжете исполняемый файл или общую библиотеку (скажем, libbar.so
) против libfoo.so
, если вы используете версионный символ, тег версии этого символа записывается в libbar.so
(это то, что вы заметили в своем вопросе).
Эта настройка позволяет libfoo.so
изменять свои символы несовместимым с ABI способом и при этом поддерживать старые клиентские программы, которые были связаны со старыми символами.
Например, libc.so.6
на x86_64
имеет следующие версии memcpy
:
0000000000091620 g iD .text 000000000000003d GLIBC_2.14 memcpy
000000000008c420 g iD .text 0000000000000047 (GLIBC_2.2.5) memcpy
Программы, которые были связаны с glibc-2.13 или старше, будут использовать GLIBC_2.2.5
версии, программы, которые были связаны с glibc-2.14 или новее, будут использовать GLIBC_2.14
версия.
Если вы попытаетесь запустить программу, связанную с glibc-2.14, в системе с glibc-2.13, вы получите ошибку (отсутствует версия символа), подобную этой.
Перед введением управления версиями символов изменение ABI существующего символа потребовало, чтобы вы поставили совершенно отдельную библиотеку. Это называется управлением версиями внешней библиотеки. Вы можете прочитать больше об этом здесь.