我有一个应用程序,使用dlopen()
构建环境在x86硬件上运行,但是正在为另一个平台交叉编译应用程序。
如果我能(作为自动构建过程的一部分)进行检查以确保.so文件和应用程序的组合中没有任何未解析的符号,而不必实际部署,那将是很好的申请。
在我使用nm
的输出编写脚本来测试符号之前,我想知道是否有人知道已经执行此操作的实用程序?
编辑1:稍微改变了描述 - 我不只是试图在.so中测试符号,而是在几个.so和应用程序本身的组合中测试 - 即。在应用程序加载了所有.so之后是否仍然存在未解析的符号。
正如答案中所建议的那样(感谢Martin诉Löwis和tgamblin),nm
将轻松识别单个文件中的缺失符号,但不会轻易识别哪一个符号已在其中一个中解析过。其他加载的模块。
答案 0 :(得分:2)
理想情况下,跨nm工具是交叉编译器套件的一部分。例如,如果您构建用于交叉编译的GNU binutils,则还将提供交叉nm(以及交叉对象)。
答案 1 :(得分:1)
你能为此使用递归版的ldd吗?似乎有人written a script可能有所帮助。这至少告诉你所有的依赖库都可以被解析,如果它们首先在.so中正确指定的话。您可以保证在.so中使用链接器选项引用所有依赖项,并且这个加递归ldd将保证您没有未解析的符号。
链接器通常可以选择在共享库中使未解析的符号出错,您可以使用它来避免必须检查。对于GNU ld,您只需传递--no-allow-shlib-undefined,并保证如果它生成.so,它将没有未解析的符号。来自GNU ld docs:
--no-undefined
Report unresolved symbol references from regular object files.
This is done even if the linker is creating a non-symbolic shared
library. The switch --[no-]allow-shlib-undefined controls the
behaviour for reporting unresolved references found in shared
libraries being linked in.
--allow-shlib-undefined
--no-allow-shlib-undefined
Allows (the default) or disallows undefined symbols in shared
libraries. This switch is similar to --no-undefined except
that it determines the behaviour when the undefined symbols are
in a shared library rather than a regular object file. It does
not affect how undefined symbols in regular object files are
handled.
The reason that --allow-shlib-undefined is the default is that the
shared library being specified at link time may not be the
same as the one that is available at load time, so the symbols might
actually be resolvable at load time. Plus there are some systems,
(eg BeOS) where undefined symbols in shared libraries is normal.
(The kernel patches them at load time to select which function is most
appropriate for the current architecture. This is used for example to
dynamically select an appropriate memset function). Apparently it is
also normal for HPPA shared libraries to have undefined symbols.
如果您要进行后链接检查,我同意Martin的观点,nm可能是您最好的选择。我通常只是在输出中使用'U'来检查未解析的符号,所以我认为这将是一个非常简单的脚本。
答案 2 :(得分:1)
nm
中的限制结果意味着无法使用全面的符号检查器。
特别是,nm
只会列出导出的符号。
但是,readelf
将生成一个完整的列表,以及所有库依赖项。
使用readelf
可以构建一个脚本:
创建所有使用的库的列表,
在可执行文件(或.so)中构建符号列表
构建一个未解析的符号列表 - 如果此时有任何未解析的符号,则加载时会出现错误。
然后重复这一过程,直到找不到新的库。
如果对可执行文件和所有dlopen()
ed .so文件进行了此操作,则可以很好地检查在运行时遇到的未解析的依赖项。