D’où provient le fichier object “Références de version”?

Actuellement, je suis dans un répertoire qui contient un fichier libshared-object.so (nom changé pour la généralité).

Quand je cours

 $ objdump -p libshared-object.so 

Je reçois la sortie suivante:

 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 rx 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 

La toute dernière de ces informations, les références de version , est particulièrement intéressante :

 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 

Question: D’où proviennent ces références de version? Prenez, par exemple, la ligne required from libQt5Gui.so.5: .. Qt_5 et Qt_5_PRIVATE_API .

Les références aux versions Qt_5 et Qt_5_PRIVATE_API proviennent-elles du code C qui a généré libQt5Gui.so.5 ? Ou d’une option de l’éditeur de liens passée à gcc ou ld ? Ou de quelque chose d’autre?

Ou de quelque chose d’autre?

De quelque chose d’autre.

Lorsque vous construisez une bibliothèque partagée (par exemple, libfoo.so ), vous pouvez (bien que cela ne soit pas libfoo.so ) fournir un script de version de l’éditeur de liens atsortingbuant une balise de version à certains symboles.

Lorsque vous libbar.so ultérieurement un exécutable ou une bibliothèque partagée (par exemple, libbar.so ) à libfoo.so , si vous utilisez un symbole versionné, le tag version de ce symbole est enregistré dans libbar.so (c’est ce que vous avez observé dans votre question). .

Cette configuration permet à libfoo.so de modifier ses symboles de manière incompatible avec ABI, tout en libfoo.so en charge les anciens programmes clients liés aux anciens symboles.

Par exemple, libc.so.6 sur x86_64 a les versions suivantes de memcpy :

 0000000000091620 g iD .text 000000000000003d GLIBC_2.14 memcpy 000000000008c420 g iD .text 0000000000000047 (GLIBC_2.2.5) memcpy 

Les programmes liés à glibc-2.13 ou version antérieure utiliseront la version GLIBC_2.2.5 , GLIBC_2.2.5 que les programmes liés à glibc-2.14 ou plus récents utiliseront la version GLIBC_2.14 .

Si vous essayez d’exécuter un programme lié à glibc-2.14 sur un système doté de glibc-2.13, vous obtiendrez une erreur (version du symbole manquante), similaire à celle-ci .

Avant l’introduction de la version des symboles, la modification de l’IAC d’un symbole existant nécessitait l’envoi d’une bibliothèque entièrement distincte. Ceci s’appelle le contrôle de version externe de bibliothèque. Vous pouvez en lire plus ici .