libdyld.dylib 作为 应用程序 和 dyld 之间的桥接层,几乎每次大版本的系统更新都会有很多变化。在 iOS 18 系统中 __dyld4 section 所在的 segment 发生了变化。

在之前的文章中,讨论过 dyld 的变化:

iOS 13 中对 dyld 3 的改进和优化

在 iOS 18 系统中 dyld 也发生了一些变化。

LibdyldDyld4Section 的变化

LibdyldDyld4Section 是指向 dyld_all_image_infos 的结构体,在 dyld4 中声明如下:

struct LibdyldDyld4Section {
	void* apis;
	void* allImageInfos;  // set by dyld to point to the dyld_all_image_infos struct
};

这个结构体的地址是通过 libdyld.dylib 的 __dyld4 section 指示的。在 iOS 18 之前的系统,__dyld4 属于 _DATA_DIRTY segment,而在 iOS 18 中则属于 __TPRO_CONST segment。iOS 18.0.1 使用的 dyld-1231.3 中的相关代码如下:

LibdyldDyld4Section* libdyld4Section = (LibdyldDyld4Section*)libdyldML->findSectionContent("__TPRO_CONST", "__dyld4", sectSize);

Thread Performance Checker 和 libRPAC.dylib

Xcode 中开启 Thread Performance Checker 后调试 App,会被自动注入名称为:

/usr/lib/libRPAC.dylib

的动态库。没有执行更多测试,但可以确定的是这个特性是在 iOS 18 更早的版本引入的。在 iOS 18.0.1 中验证,Xcode 中开启 Thread Performance Checker,libRPAC.dylib 注入后,将 HOOK 很多系统原生 API,对应的符号会被替换为_interposed_replacement 开头的符号。比如:

_replacement_NSData_initWithContentsOfFile
_interposed_dispatch_semaphore_create

相关讨论:

Investigating a Dynamic Linking Crash with Xcode 16

这个特性也会影响到 dyld 相关符号的解析,如果代码中有硬编码的符号查找,需要做兼容适配。