ld是GNU binutils工具集中的一个,是众多Linkers(链接器)的一种。把各种目标文件和库文件链接起来,并重定向它们的数据,完成符号解析。Linking其实主要就是完成四个方面的工作:storage allocation,symbol management, libraries,relocation。
LMA (load memory address 加载内存地址或进程地址空间地址)
VMA (virtual memory address 虚拟内存地址或程序地址空间地址)
VMA 是执行输出文件时 section 所在的地址,而 LMA 是加载输出文件时 section 所在的地址。一般而言,某 section 的 VMA == LMA. 但在嵌入式系统中,经常存在加载地址和执行地址不同的情况:比如将输出文件加载到开发板的 flash 中(由 LMA 指定), 而在运行时将位于 flash 中的输出文件复制到 SDRAM 中(由 VMA 指定)。
SECTION-COMMAND 有四种:
Linker 及 ld 脚本分析 | (breezetemple.github.io)
LLD 是 LLVM 项目的链接器,是直接替代品 对于系统链接器,并且运行速度比它们快得多
LLD - LLVM 链接器 — lld 19.0.0git 文档
Cross compiling
GNU binutils / gcc
Ubuntu provides the package gcc-arm-none-eabi with the ARM cross compiler based on gcc. To cross compile for the ARM Cortex-M0 use
arm-none-eabi-gcc -mcpu=cortex-m0 -mthumb -o foo.arm foo.c -nostdlib -laeabi-cortexm0
clang / LLVM
Clang is a native cross compiler, but the standard linker /usr/bin/ld is not able to link ARM binaries. Therefore use LLD (ubuntu package lld-7):
clang -target armv6m-none-eabi -fuse-ld=lld-7 -o foo.arm foo.c -nostdlib -laeabi-cortexm0
GitHub - bobbl/libaeabi-cortexm0: ARM Run-Time ABI for the Cortex-M0 processor>
- LLD 是 GNU 链接器的直接替代品,它接受 与 GNU 相同的命令行参数和链接器脚本。
- 您所要做的就是构建对象文件 和命令行参数,就像调用 外部链接器,然后从代码中调用链接器的 main 函数 。lld::lldMain
- 默认情况下支持链路时间优化 (LTO)。本质上 要执行 LTO,您所要做的就是将选项传递给 clang。 然后,clang 创建非本机对象文件格式的对象文件 但采用 LLVM 位码格式。LLD读取bitcode对象文件,编译 他们使用 LLVM 并发出输出文件。因为通过这种方式,LLD可以 看到整个程序,它可以做整个程序的优化。-flto
- 符号赋值
- 对符号的赋值只对全局变量起作用
- 赋值语句包含 4 个语法元素:符号名、操作符、表达式、分号;一个也不能少
- . 是一个特殊的符号,它是定位器,一个位置指针,指向程序地址空间内的某位置。该符号只能在 SECTIONS 命令内使用
- ENTRY 命令
- 符号赋值语句
- 一个输出 section 的描述 (output section description)
- 一个 section 叠加描述 (overlay description)
- SECTIONS 命令:
- LMA vs VMA
- SECTIONS 脚本各段组成及位置
- . 定位器符号
- Linker Script File - 控制链接器行为的脚本文件
- - Symbol Resolution - 符号解析(多文件声明与调用,调用替换为具体函数入口)
- Relocation - 重定位(相同段合并,例如 .text;Section Placement, 各段在内存中的位置)
- 在链接过程中执行如下操作: