列出ld链接器可用的所有符号。

4
我有一个小的静态库,由(linux)gcc 4.8.2编译,并带有-fvisibility=hidden选项,它链接到一个共享库上(我有两个版本,一个是用C代码的gcc版本,另一个是用Fortran代码的ifort版本)。这个静态库由一些内部函数组成,所有函数都以“ST_LIB_”为前缀。
我想确保在链接到共享库的任何可执行文件/库中都不能使用静态库中声明的函数。在Linux上,最好的命令是什么来检查具有某些前缀的函数是否可以被任何外部库使用?
我已经尝试过:
nm --dynamic shared_lib | grep -i "ST_LIB_" | wc -l (输出0)
readelf -d shared_lib | grep -i "ST_LIB_" | wc -l (输出0)
nm -g shared_lib | grep -i "ST_LIB_" | wc -l (输出26或0,取决于共享库)
readelf -s shared_lib | grep -i "ST_LIB_" | wc -l (输出26或0,取决于共享库)
readelf -Ws shared_lib | grep -i "ST_LIB_" | grep -i "HIDDEN" | wc -l (输出26或0,取决于共享库)

1
为什么 nm -g 会给你26个结果? -g(或 --extern-only)应该只给出外部可见符号(正是你所要求的)。因此,你可能有26个不是静态的 ST_LIB_* 函数。 - Shahbaz
静态库由gcc编译,但我有一个由gcc编译的共享库和一个由ifort编译的共享库。nm -g对于gcc链接的共享库输出为0,而对于ifort链接的共享库输出为26。这就是为什么我要求一个真正显示链接器读取内容的命令。 - Peter Petrik
我不是在谈论静态库与共享库的问题,而是在谈论C语言中的“static”关键字。如果一个函数是静态的,那么它应该对链接器来说是外部不可见的。如果gcc正确地告诉你没有外部可见的函数(带有“ST_LIB_”前缀),但ifort链接器使这些函数外部可见,那么可能是ifort出了问题,或者你调用它的方式有问题。 - Shahbaz
如果静态库中的函数没有使用 static 关键字进行前缀修饰,那么它们在共享库中将无法使用。我想在共享库中使用 ST_LIB_ 函数,但是我不希望共享库进一步暴露它们。 - Peter Petrik
明白了。那么也许您正在寻找这个 - Shahbaz
我已经在使用fvisibility选项。我只是想测试一下它是否按预期工作(例如,在编译过程中可能会使用错误的gcc版本,我想编写一个单元测试来检查共享库中的符号)。 - Peter Petrik
1个回答

3

nm --dynamic应该是您要寻找的选项,因为它显示了您可以链接到的符号(来自共享库)。readelf --dyn-syms应该显示相同的信息(不同的输出)。

使用 nm 时,请检查具有"T"属性的符号。从手册页面上看:

The symbol type.  At least the following types are used; others are, as well, depending 
on the object file format.  If lowercase, the symbol is usually local; if uppercase, the
symbol is global (external).  There are however a few lowercase symbols that are shown
for special global symbols ("u", "v" and "w").
[...]
"T"
"t" The symbol is in the text (code) section.

如果你想要100%确定,可以编写一个测试程序,链接到你的共享库并尝试使用其中一个ST_LIB_符号。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接