-symbolic和-shared GCC标志之间有什么区别?

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

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

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

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

摘要:-symbolic防止内部共享对象function插入

与共享对象链接允许称为符号插入的function。 我们的想法是,您可以“插入”全局符号的新定义,以便调用它而不是“常规”定义。

一个典型的例子是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()相同的共享对象中定义,并绑定调用,使其无法插入。 这样,您就知道从共享对象中的一个函数到同一共享对象中的另一个函数的任何调用都不会被插入。