如何在符号表中添加共享库版本信息

时间:2016-05-04 19:19:38

标签: c linux linker

我写了一个使用libz的小型简单测试程序。我用

编译了它
$gcc -o test test.c -lz

要查看如何将libz函数添加到符号表中,我运行了以下命令

$ readelf -s test | grep inflate

这是输出

 1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND inflateEnd
 8: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND inflate
13: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND inflateInit_
51: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND inflateEnd
62: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND inflate
73: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND inflateInit_

我使用的libz的.gnu.version_d部分定义如下

Version definition section '.gnu.version_d' contains 7 entries:
Addr: 0x0000003175e014c0  Offset: 0x0014c0  Link: 4 (.dynstr)
000000: Rev: 1  Flags: BASE   Index: 1  Cnt: 1  Name: libz.so.1
0x001c: Rev: 1  Flags: none  Index: 2  Cnt: 1  Name: ZLIB_1.2.0
0x0038: Rev: 1  Flags: none  Index: 3  Cnt: 2  Name: ZLIB_1.2.0.2
0x0054: Parent 1: ZLIB_1.2.0
0x005c: Rev: 1  Flags: none  Index: 4  Cnt: 2  Name: ZLIB_1.2.0.8
0x0078: Parent 1: ZLIB_1.2.0.2
0x0080: Rev: 1  Flags: none  Index: 5  Cnt: 2  Name: ZLIB_1.2.2
0x009c: Parent 1: ZLIB_1.2.0.8
0x00a4: Rev: 1  Flags: none  Index: 6  Cnt: 2  Name: ZLIB_1.2.2.3
0x00c0: Parent 1: ZLIB_1.2.2
0x00c8: Rev: 1  Flags: none  Index: 7  Cnt: 2  Name: ZLIB_1.2.2.4
0x00e4: Parent 1: ZLIB_1.2.2.3

那么为什么libz版本不是我的符号表中的libz函数符号的一部分。我希望看到类似的东西 -

1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND inflateEnd@@ZLIB_1.2.0
...

我的二进制文件的.gnu.version_r部分也没有列出libz版本作为要求。如何在这里添加libz版本依赖?

$readelf -V test

...
Version needs section '.gnu.version_r' contains 1 entries:
Addr: 0x0000000000400618  Offset: 0x000618  Link: 6 (.dynstr)
000000: Version: 1  File: libc.so.6  Cnt: 1
 0x0010:   Name: GLIBC_2.2.5  Flags: none  Version: 2

1 个答案:

答案 0 :(得分:1)

仅仅因为你的libz包含版本控制信息并不意味着其中的每个符号都是版本化的。在我的libz(版本1.2.3(是的,真的))中,一些外部符号是版本化的,有些则不是,我可以通过readelf来确定。具体来说,您询问的所有符号都是由我的DSO定义的,但没有一个是版本化的。

如果链接到无版本符号,则既不希望也不希望对二进制文件中的相应符号引用进行版本控制。