iOS启动优化-dyld4流程介绍

苹果在 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或系统信息变化的情况

image.png

启动

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

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

KernelArgs(内核参数)

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

进程状态

分为两类

  • DyldProcessConfig

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

  • DyldRuntimeState

    保存在进程生命周期内变化的状态信息。它包括Loader、注册的通知函数和所有锁。

image.png

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等

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYrfOycy' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片