mach-o文件中的符号可以标记为'间接' (I
输出中的{nm
,使用常量N_INDR
在标头中定义。似乎这种类型的符号在实践中很少使用(或者可能具有非常具体的,有限的用途)。我遇到的唯一例子是macOS系统库/usr/lib/system/liblaunch.dylib
。这是在该文件上运行nm
的部分输出:
U __spawn_via_launchd
0000000000000018 I __spawn_via_launchd
U __vproc_get_last_exit_status
0000000000000049 I __vproc_get_last_exit_status
U __vproc_grab_subset
000000000000007a I __vproc_grab_subset
如此输出所示,相同的符号列出两次,一次列为U
,另一次列为I
。对于文件中的所有I
符号都是如此。
更详细地检查符号表条目表明,虽然U
条目引用另一个链接库(libxpc.dylib),但I
条目不引用任何内容。
搜索" mach-o间接符号"似乎没有产生许多有用的结果。大多数(包括Apple的文档)涵盖了用于实现惰性弱符号的存根。我不认为这与I
间接符号有关,主要是因为其他文件中的懒弱弱链接符号未标记为I
,但我很乐意被告知不同。
Darwin档案中的源文件也缺乏有用的评论。
所以我有3个问题:
什么是间接符号的规范解释?
编译时链接器和加载时链接加载器如何解释和处理这些符号?
如何将源文件中的符号定义为间接符号? (我最感兴趣的是C / Clang答案,但我确定未来的读者也会欢迎其他语言的答案。)
(对于它的价值,我目前最好的猜测是,这是一种允许在保持兼容性的同时从库中删除符号的方法,只要这些符号在别处可用。一种保持符号的方法。链接器在编译时感到高兴,并在加载时将链接加载器指向移动的实现。但这只是猜测。)
更新
经过一些研究后,我可以回答问题3.当然,这是由链接器控制的,我正在寻找的选项是-reexport_symbol
。这将在符号表中创建I
条目(如果符号已经存在,它也将创建U
条目)。还有-reexport_symbols_list
选项,它接受符号名称文件并为每个符号名称创建间接符号。