2

LD-2

 5 years ago
source link: http://satanwoo.github.io/2019/01/26/LD-2/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

了解苹果的LD

其实文章关于传统 Section Based Linker 那块我还没怎么读懂,有兴趣的欢迎互相探讨。

之前研究 Xcode 10 兼容 libstdc++ 的时候,稍微把玩了下苹果的 LD ,借这个机会正好通读了下苹果的 LD 设计,本文做一下总结。

Atom & FixUp

苹果的 LD ,核心理念就是基于 AtomFixUp ,拿着两个术语是啥意思呢?

  • Atom 就是一块代码(函数)或者数据(全局变量)之类的,每个 Atom 都有一些属性,比如名称、作用域、内容类型、字节对齐之类的。
  • Fixup 可以理解为一个包含种类、便宜、辅助加数以及目标 Atom 的数据结构。

有点抽象对吧?概要来说,苹果 LD 通过 AtomFixUP 构建一张图,图中的节点都是 Atom ,连接 Atom 的则是 FixUP

通过构建这样一张图,苹果就可以在链接期间进行一系列的优化,比如死代码剔除,怎么做呢?比如一段代码也会被抽象成 Atom ,如果没有 FixUP 连接的 Atom 就可以进行剔除

举一个简单的小例子 main.c

#include <stdio.h>

int main()
{
    printf("hello world");
    return 0;
}

会被抽象出如下行为:

ZZruAfU.png!web

单独编译这个 .c 文件生成的 .o 会包含两个 atom ,一个是 main 函数,另外一个是 C 字符串 "hello world"

printf 本质上也会一个 atom ,但是在这个编译单元内他还没加入图中。

fixup 也存在两个,一个是去调用不知道在哪的函数 printf 的调用 fixup ,一个是去加载字符串的 fixup

链接过程

  • 链接过程的第一步就是要处理输入文件,构建一张初始图。

    • 如果输入文件是 .o ,那么所有的 atom 都会被加入到初始图当中。
    • 如果输入文件是静态库(静态库基本上就是一组 .o 文件包含一个目录),初始状态下这里面的 atom 都默认 不会加入到里面 ,当 LD 不断初始图中有没被决议的 fixup ,如果fixup对应的目标 atom 在这个静态库里面的话,就会把找到的 atom 的加入到图内。
    • 动态库其实在链接期间不会添加任何的 atom ,同静态库一样,如果有没被决议的 fixup 对应的 atom 在动态库内找到(比如 tbd 声明的那些),就就提供一个代理, 这个代理标记了这个符号来自哪个动态库

本质上来说,链接期间动态库的作用就是参与标记一下。

  • 考虑完符号决议,还要考虑符号合并之类的,比如根据字符串表的设计,来自不同文件的相同字符串,比如 "haha" ,不可能保留两份,需要合并。此外还有诸如 C 中的 tentative definitionsC++ Weak Symbol

  • 处理 fixup 的时候,也需要分几种类型,见下图:

BZFVRrn.png!web

其他

虽然苹果的 LD 已经抽象成了 Atom-FixUP 的架构,但是它的可执行文件 Mach-O 还是传统的基于 section 的结构,这限制了 Atom-FixUP 的能力。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK