dyld: 神秘的 __dso_handle

news/2024/11/19 3:03:26/文章来源:https://www.cnblogs.com/chaoguo1234/p/18554081

iOS动态链接器dyld中有一个神秘的变量__dso_handle:

// dyld/dyldMain.cpp
static const MachOAnalyzer* getDyldMH()
{
#if __LP64__// 声明 __dso_handleextern const MachOAnalyzer __dso_handle;return &__dso_handle;
#else...
#endif // __LP64__
}

这个函数内部声明了一个变量__dso_handle,其类型是struct MachOAnalyzer

查看struct MachOAnalyzer的定义,它继承自struct mach_header:

image

struct mach_header正是XNU内核里面,定义的Mach-O文件头:

// EXTENERL_HEADERS/mach-o/loader.h
struct mach_header {uint32_t	magic;		/* mach magic number identifier */cpu_type_t	cputype;	/* cpu specifier */cpu_subtype_t	cpusubtype;	/* machine specifier */uint32_t	filetype;	/* type of file */uint32_t	ncmds;		/* number of load commands */uint32_t	sizeofcmds;	/* the size of all the load commands */uint32_t	flags;		/* flags */
};

从上面函数getDyldMH的名字来看,它返回dyld这个Mach-O文件的文件头,而这确实也符合变量__dso_handle的类型定义。

但是奇怪的事情发生了,搜遍整个dyld源码库,都无法找到变量__dso_handle的定义。所有能搜到的地方,都只是对这个变量__dso_handle的声明。

众所周知,动态连接器dyld本身是静态链接的。

也就是说,动态连接器dyld本身是不依赖任何其他动态库的。

因此,这个变量__dso_handle不可能定义在其他动态库。

既然这样,动态链接器dyld本身是如何静态链接通过的呢?

答案只可能是静态链接器ld在链接过程中做了手脚。

查看静态链接器ld的源码,也就是llvm的源码,可以找到如下代码:

// lld/MachO/SyntheticSections.cpp
void macho::createSyntheticSymbols() {// addHeaderSymbol 的 lamba 表达式auto addHeaderSymbol = [](const char *name) {symtab->addSynthetic(name, in.header->isec, /*value=*/0,/*isPrivateExtern=*/true, /*includeInSymtab=*/false,/*referencedDynamically=*/false);};...// The Itanium C++ ABI requires dylibs to pass a pointer to __cxa_atexit// which does e.g. cleanup of static global variables. The ABI document// says that the pointer can point to any address in one of the dylib's// segments, but in practice ld64 seems to set it to point to the header,// so that's what's implemented here.addHeaderSymbol("___dso_handle");
}

上面代码定义了一个addHeaderSymbollamda表达式,然后使用它添加了一个符号,这个符号正是__dso_handle

调用addHeaderSymbol上方的注释使用chatGPT翻译过来如下:

Itanium C++ ABI 要求动态库传递一个指向 __cxa_atexit 的指针,该函数负责例如静态全局变量的清理。ABI 文档指出,指针可以指向动态库的某个段中的任意地址,但实际上,ld64(苹果的链接器)似乎将其设置为指向头部,所以这里实现了这种做法。

注释中提到的Itanium C++ ABI最初是为英特尔和惠普联合开发的Itanium处理器架构设计的。

但其影响已经超过了最初设计的架构范围,并被广泛用于其他架构,比如x86x86-64上的多种编译器,包括GCCClang

而且,注释中还提到,__dso_handle在苹果的实现里,是指向了Mach-O的头部。

至此,谜底解开~。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/836493.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

攻防世界-转轮机加密

解法1:参考:https://blog.csdn.net/weixin_45556441/article/details/110851390解法2:book = ["NACZDTRXMJQOYHGVSFUWIKPBEL","FHTEQGYXPLOCKBDMAIZVRNSJUW","QGWTHSPYBXIZULVKMRAFDCEONJ","KCPMNZQWXYIHFRLABEUOTSGJVD","SXCD…

攻防世界-栅栏密码

原理加密分为经典型和W型题目解题 W型解密(多数默认)链接: https://www.a.tools/Tool.php?Id=264 https://ctf.bugku.com/tool/railfence

攻防世界-safer_than_rot13(替代密码)

题目解题解密链接:http://quipqiup.com/ 参考:https://blog.csdn.net/xiao__1bai/article/details/121692829

如何在notion中复制表格

Notion有个非常二货的地方: 不能直接复制表格,如果想把表格A中内容复制到表格B中,需要先把A中想复制的内容放到excel中,再从excel中放入B中,且需要在B中指定放置范围。 例如:表格A直接在notion中复制该表格A后,无法在下面的表格B中直接粘贴:表格B 如何才能将A中内容复制…

考研打卡(21)

开局(21) 开始时间 2024-11-18 20:08:09 结束时间 2024-11-19 01:07:55今天凌晨两点渴醒了,然后起床喝水,耍手机刷到两点多才睡着数据结构在一棵二叉树中有30个叶子结点,仅有一个孩子的结点有20个, 则该二叉树共有_____ 个结点(北京师范大学 2017年) A 79 B 76 C 56 D 81…

DQL(1)

多重条件查询 select*from 表名 where 列名 条件 (如like‘ ’) 连接词(and ,or等)条件排序查询 select * from 表名 order by 列名 asc|desc,列名 asc|desc;(正序|倒序)聚集函数(一般用作统计) count([distinct]*)统计所有的行数(distinct表示去重再统计) count (…

福气满满-冲刺日志(第六天)

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/SE2024作业要求 https://edu.cnblogs.com/campus/fzu/SE2024/homework/13305团队名称 福气满满团队成员学号-名字 052203132童潇剑,102201226陈潇健,102201235曾炜坤,102201234洪庆杨,102201224 陈博涵,18220031…

福气满满-冲刺日志(第五天)

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/SE2024作业要求 https://edu.cnblogs.com/campus/fzu/SE2024/homework/13305团队名称 福气满满团队成员学号-名字 052203132童潇剑,102201226陈潇健,102201235曾炜坤,102201234洪庆杨,102201224 陈博涵,18220031…

像VS Code一样,设置用Cursor打开 / 为Cursor添加右键菜单

背景 我一直是sublime text的忠实用户,然而sublime用于写代码还是过于简陋,哪怕是在一些简单的临时编辑场景。sublime的插件也很久不更新,比起vscode差了一大截。 但是总是用vscode打开项目心中总是有些膈应,因为我更希望vscode作为一个项目开发的工具,而不是把一些临时文…