学习编译和启动时链接器所做的事

连接器,我的理解是将高级语言编译成二进制文件在内存中运行的中间桥梁,最主要的作用是将符号绑定到地址上.

IOS用的是LLVM(Low Level Virtual Machine)编译器,编译器可以将代码编译成二进制并在内存中运行,这样可以极大提升程序运行的速度.同时缺点在于调试周期比较长.每次都需要重新启动才能看得到代码运行效果,所以才有了基于runtime机制产生的RN flutter 等跨端解决方案.

我一开始接触ios开发的时候用的是xcode5当时Apple还在使用GCC编译器,后来就换成LLVM,编译器会将oc源码编译成match-o文件,其中的lld内置连接器会将多个match-o文件给合并成一个.

LLVM编译过程:源码->AST-IR-Mactch-O(ios)

编译时连接器做了哪些工作:

Mach-o文件中主要还是代码和数据.代码数函数,数据是全局变量,连接器是将这些符号绑定在运行地址中.

我们写的代码编译器是将其翻译成一个个机器码,需要连接器将其串起来才能运行.就好比珍珠和线一样.

连接过程中要对代码进行检查,因为咱们在写代码的时候不同文件之间会有相互引用的代码,连接器会检查不同文件的相互引用,一些变量有没有定义,对项目中不同的文件变量进行地址重定位.随着项目不断迭代很多无用业务代码,链接去会检测函数调用关系,以main为源头,跟随每个引用,将引用的函数标记活的.自动将无用的代码去掉.

说完自己书写的代码,接下来看看在项目中会引用各种系统库和三方库,链接去是怎样处理他们的呢?

导入的库有静态库和动态库,静态库是在编程过程中连接到mach-o文件中,而动态库是在运行时通过dyld实现动态加载.但是在mach-o文件中包含了动态库的名字和地址,dlopen 和 dlsym 导入动态库时就可以实现动态运行它们;

dyld 会先执行mach-o文件 根据文件中的undefined标记的符号来加载对应的动态库,系统会开辟一个共享空间来解决递归依赖问题;加载后将undefined的符号绑定到动态库的地址上;最后再处理+load方法.main函数执行.

参考文献:

https://time.geekbang.org/column/article/86840

http://llvm.org/pubs/2004-01-30-CGO-LLVM.html

http://llvm.org/docs/LangRef.html?highlight=dead%20code%20stripping

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值