目前我在一个目录中,其中有一个文件 libshared-object.so
(为了通用而更改了名称).
Currently I'm in a directory which has a file libshared-object.so
(name changed for generality).
当我跑步时
$ 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
特别感兴趣的是此信息的最后,版本参考:
Of particular interest is the very last of this information, the Version References:
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
问题:这些版本引用来自哪里?以 libQt5Gui.so.5 中的 required: .. Qt_5
和 Qt_5_PRIVATE_API
行为例.
Question: Where do these version references come from? Take, for example, the line required from libQt5Gui.so.5: .. Qt_5
and Qt_5_PRIVATE_API
.
对版本 Qt_5
和 Qt_5_PRIVATE_API
的引用是否来自生成 libQt5Gui.so.5
的 C 代码?或者从某些链接器选项传递给 gcc
或 ld
?还是来自其他方面?
Are references to version Qt_5
and Qt_5_PRIVATE_API
coming from the C code that generated libQt5Gui.so.5
? Or from some linker option passed to to gcc
or ld
? Or from something else?
还是来自其他方面?
Or from something else?
来自别的东西.
当你构建一个共享库(比如 libfoo.so
)时,你可以(虽然不是必须)提供一个链接器版本脚本,给某些符号一个版本标签.
When you build a shared library (say libfoo.so
), you can (though don't have to) supply a linker version script giving certain symbols a version tag.
当您稍后针对 libfoo.so
链接可执行文件或共享库(例如 libbar.so
)时,iff 您使用了版本化的符号,该符号的版本标记记录在 libbar.so
中(这是您在问题中观察到的).
When you later link an executable or a shared library (say libbar.so
) against libfoo.so
, iff you use a versioned symbol, the version tag of that symbol is recorded in libbar.so
(that is what you observed in your question).
此设置允许 libfoo.so
以与 ABI 不兼容的方式更改其符号,并且仍然支持针对旧符号链接的旧客户端程序.
This setup allows libfoo.so
to change its symbols in ABI-incompatible way, and still support old client programs that were linked against the old symbols.
例如,x86_64
上的 libc.so.6
具有以下版本的 memcpy
:
For example, libc.so.6
on x86_64
has the following versions of 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
> 版本.
Programs that were linked against glibc-2.13 or older will use the GLIBC_2.2.5
version, programs that were linked against glibc-2.14 or newer will use the GLIBC_2.14
version.
如果您尝试在带有 glibc-2.13 的系统上运行链接到 glibc-2.14 的程序,您将收到一个错误(缺少符号版本),类似于 这个.
If you try to run a program linked against glibc-2.14 on a system with glibc-2.13, you will get an error (missing symbol version), similar to this.
在引入符号版本控制之前,更改现有符号的 ABI 需要您提供一个完全独立的库.这称为外部库版本控制.您可以在此处阅读更多相关信息.
Before the introduction of symbol versioning, changing the ABI of an existing symbol required that you ship an entirely separate library. This is called external library versioning. You can read more about it here.
这篇关于目标文件“版本参考"在哪里?来自?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!