链接与Symbol

104 阅读3分钟

链接与Symbol

多环境配置 & Mach-O与链接器 & Symbol

  • 多环境配置
  • 静态链接与动态链接
  • 符合的种类与作用
  • strip命令与MachO体积
  • llvm-strip详解
  • 动态库初探

多环境配置

  • Project:包含了项目所有的代码,资源文件,所有信息。
  • Target:对指定代码和资源文件的具体构建方式
  • Scheme:对指定Target的环境配置

Big endian or little endian??

  • 16849141 = 0x0A0B0C0D

image.png

image.png

image.png

image.png

Mach-O

  • Mach-O(Mach Object)是macOS、iOS、iPadOS存储程序和库的文件格式。对应系统通过应用二进制接口(application binary interface,缩写为ABI)来运行该格式的文件
  • Mach-O格式用来替代BSD系统系统的a.out格式。Mach-O文件格式保存了在编译过程和链接过程中产生的机器代码和数据,从而为静态链接和动态链接的代码提供了单一文件格式
Mach-O File Format
  • 'int main(){}'comliled for x86_64-apple-macosx with clang
  • 0x55, // offset 0 -- pushq %rbq
  • 0x48,0x89,0xe5 // 0ffest 1 -- movq %rsp,%rbq
  • 0x31,0xc0, // offset 4 -- xorl %eax,%eax
  • 0x5d, // offset 6 -- popq %rbp
  • 0xc3 // offset 7 -- retq
生成目标文件的过程

image.png

  1. 连接器(llvm-ld)并没有被执行
  2. 目标文件不会包含Unix程序在被装载和执行时所必须包含的信息
生成最终文件的过程

image.png

image.png

静态链接

image.png

静态/动态链接:

image.png

可执行文件调用过程:
  1. 调用fork函数,创建一个process
  2. 调用execve或其衍生函数,在该进程上加载,执行我们的Mach-O文件
当我们调用时execve(程序加载器),内核实际上在执行以下操作:
  1. 将文件加载到内存
  2. 开始分析Mach-O中的mach_header,以确认它是有效的Mach-O文件
链接的本质就是把多个目标文件组合成一个文件

image.png

Symbol Table

  • Symbol Table:就是用来保存符号
  • String Table:就是用来保存符号的名称
  • Indirect Symbol Table:间接符号表。保存使用的外部符号。更准确一点就是使用的外部动态库的符号。是Symbol Table的子集。
  • Symbol Table到底有什么作用呢?
  • 程序运行的时候需不需要Symbol Table?

Symbol

符号到底有哪些种类?怎么区分?
按照存在的空间区分:
  • non private external
  • weak private external
按照模块区分
  • weak global
  • weak local
按照功能分:

image.png

按照符号种类划分 (小写代表local symbol)

image.png

导入(Import)导出(Export)符号:
  • export symbol:导出符号意味着,告诉别的模块,我有一个这样的符号,你可以将其导入(Import)。
two_levelnamespace & flat_namespace:
  • 二级命名空间与一级命名空间。连接器默认采用二级命名空间,也就是除了会记录符号名称,还有记录符号属于哪个动态库的,比如会记录下来_NSLog来自Foundation。
Weak Symbol
  • Weak Reference Symbol:表示此未定义符号是弱引用。如果动态连接器找不到该符号的定义,则将其赋为0.静态链接器会将此符号设置弱链接标志。
  • Weak definition Symbol:表示此符号位弱定义符号。如果静态链接器或动态链接器为此符号找到另一个(非弱)定义,则弱定义将被忽略。只能将合并部分中的符号标记为弱定义。
Common Symbol:
  • 在定义时,未初始化的全局符号。
链接器设置:
  • -d:强制定义Common Symbol
  • -commons:指定对待Common Symbol如何响应
程序在执行的时候需不需要符号表?
Strip:移除或者修改符号表中的符号。
Strip Style
  • Debugging Symbols
  • All Symbols
  • Non-Global Symbols
Strip
  1. -x: non_global
  2. 无参数:代表全部符号
  3. -S:调试符号

image.png

Strip Style
  • Debugging Symbols

image.png

  • All Symbols

image.png

  • Non-Global Symbols

image.png