苹果在 iOS16 之后运用 dyld4 取代了 dyld3, 可是目前网上的资料都是介绍dyld3发动流程, 本文讲解最新的dyld4的原理和中心流程

官网dyld4介绍 github.com/apple-oss-d…

dyld4

dyld(the dynamic link editor)是苹果的动态链接器,是苹果操作体系一个重要组成部分,在体系内核 XNU 完结 Mach-O 文件的加载,做好程序准备作业之后,交由 dyld 担任余下的作业如动态库加载, 进程信息初始化

dyld 最新版本是dyld4

dyld4 一起支持pre-built loader(提早缓存) 来提高发动速度 也支持 just-in-time loader(实时加载)来应对App或体系信息改变的情况

iOS启动优化-dyld4流程介绍

发动

内核将一切KernelArgs(内核参数)推送到堆栈上并跳转到 dyld 的入口点start()来发动进程。

void start(const KernelArgs* kernArgs, void* prevDyldMH)

KernelArgs(内核参数)

KernelArgs指向内核在堆栈上传递给 dyld 信息的指针(例如 argcargvenvpapple parameter等)。

iOS启动优化-dyld4流程介绍

进程状况

分为两类

  • DyldProcessConfig

    保存进程的固定状况信息(例如安全策略,dyld缓存,日志记录标志,平台等)。

    iOS启动优化-dyld4流程介绍

  • DyldRuntimeState

    保存在进程生命周期内改变的状况信息。它包括Loader、注册的告诉函数和一切锁。

iOS启动优化-dyld4流程介绍

Loader objects

每个加载的 mach-o 文件(可履行程序, 动态库) 对应一个 dyld4::Loader 目标盯梢。

分为如下四类mach-o

  • 可履行程序
  • libsystem.dylib
  • libdyld.dylib
  • 其他dylib
// Loader 加载器(Prebuilt or JustInTime 两种 loader)
    const Loader*                   mainExecutableLoader = nullptr; // 主程序加载办法
    Vector<ConstAuthLoader>         loaded; // 其他动态库加载办法
    const Loader*                   libSystemLoader      = nullptr; // libsystem.dylib 加载办法
    const Loader*                   libdyldLoader        = nullptr; // libdyld.dylib 加载办法

Loader 运用 loadAddress() 来获取 mach_o信息 .

Loader 有两种

  • PrebuiltLoader: 运用 dyld cache和缓存文件, 速度更快。
  • JustInTimeLoader: 速度慢, 可是更新及时

PrebuiltLoader

包括 mach-o 文件的预先核算(缓存)的信息,包括途径、验证信息、依靠的 dylib 和预先核算的绑定方针数组。

PrebuiltLoaderSet

一个进程中最多有两个 PrebuiltLoaderSet

  • 一个在 dyld 缓存中,包括每个 dylib 的PrebuiltLoader,该 dylib 是 dyld 同享缓存的一部分。
  • 另一个是App的PrebuiltLoaderSet, 包括mainLoader
    • App的PrebuiltLoaderSet来自两个方位:dyld 缓存或文件

JustInTimeLoader

JustInTimeLoader 经过MachOAnalyzer根据需要实时解析mach-o文件。

加载一切images之后,dyld 将 JustInTimeLoader 目标“克隆”到 PrebuiltLoader 目标,然后将这些目标打包到 PrebuiltLoaderSet 中并写入磁盘, 之后就可以运用 PrebuiltLoader 加载缓存了,提高了App运转速度。

App Loader 进程

  1. 发动时,dyld 查找 PrebuiltLoader, 假如找到,则调用其 isValid()判断有用, 则运用Prebuilt。
  2. 假如没有,则创立一个新 JustInTimeLoader, JustInTimeLoader 经过解析 mach-o 来查找其依靠项。
  3. 对于每个依靠项,都会履行上面相同的过程。

SyscallDelgate

SyscallDelgate 处理一切syscal(如翻开或映射文件)。

  • 初级(即posix级)办法: 如翻开,封闭,mmap。
  • 更高级别的办法: withReadOnlyMappedFile等