9

从文档的描述来看,它们似乎做同样的事情,除了“并非所有系统”支持共享和“只有一些系统”支持符号(不清楚这些是否是同一组系统):

-shared 生成一个共享对象,然后可以将其与其他对象链接以形成可执行文件。并非所有系统都支持此选项。为了获得可预测的结果,您还必须在指定此选项时指定用于生成代码的同一组选项(-fpic、-fPIC 或模型子选项)。 [1]

-symbolic 在构建共享对象时绑定对全局符号的引用。警告任何未解析的引用(除非被链接编辑器选项 -Xlinker -z -Xlinker defs 覆盖)。只有少数系统支持此选项。

我怀疑区别在于“生成一个共享对象,然后可以将其与其他对象链接以形成可执行文件”部分,但这听起来像是任何库都适用的东西。这是否意味着生成的共享对象也可以静态链接?

4

1 回答 1

8

总结:-symbolic 防止内部共享对象函数插入

与共享对象的链接允许使用一种称为符号插入的功能。这个想法是您可以“插入”全局符号的新定义,以便调用它而不是“常规”定义。

一个典型的例子是 malloc()。在最常见的情况下,malloc() 是在 libc 中定义的。但是您可以通过在加载 libc 之前加载定义该符号的库来插入您自己的 malloc 版本(大多数运行时链接器允许您使用 LD_PRELOAD 到特定库以在可执行文件之前加载)。

默认情况下,共享对象中的任何非静态函数都是全局符号。因此,可以插入共享对象中的任何函数。考虑一个共享对象具有函数 high_level() 和 low_level() 并且 high_level() 调用 low_level() 作为其实现的一部分并且 high_level() 和 low_level() 都不是静态函数的场景。

可以插入 low_level() 以便 high_level() 从不同的共享对象调用 low_level()。

这就是 -symbolic 的用武之地。在创建共享对象时,链接器将看到 low_level() 与 high_level() 在同一个共享对象中定义,并绑定调用以使其无法插入。这样,您就知道从共享对象中的一个函数到同一共享对象中的另一个函数的任何调用都不会被插入。

于 2009-10-20T00:36:22.907 回答