没有合适的资源?快使用搜索试试~ 我知道了~
gnu ld链接脚本浅析,网上转的,不错
4星 · 超过85%的资源 需积分: 9 28 下载量 36 浏览量
2010-04-19
23:45:30
上传
评论
收藏 338KB PDF 举报
温馨提示
试读
35页
一直看bootloader中的链接脚本,似懂似认识,但又不认识,看完这个可以有比较好的了解
资源推荐
资源详情
资源评论
GNU LD 脚本解析
0. Contents
1. 概论
2. 基本概念
3. 脚本格式
4. 简单例子
5. 简单脚本命令
6. 对符号的赋值
7. SECTIONS 命令
8. MEMORY 命令
9. PHDRS 命令
10. VERSION 命令
11. 脚本内的表达式
12. 暗含的连接脚本
1. 概论
每一个链接过程都由链接脚本(linker script, 一般以 lds 作为文件的后缀名)控制. 链接脚本主要用于规定
如何把输入文件内的 section 放入输出文件内, 并控制输出文件内各部分在程序地址空间内的布局. 但你也
可以用连接命令做一些其他事情.
连接器有个默认的内置连接脚本, 可用 ld --verbose 查看. 连接选项-r 和-N 可以影响默认的连接脚本(如
何影响?).
-T 选项用以指定自己的链接脚本, 它将代替默认的连接脚本。你也可以使用以增加自定义的链接命令.
以下没有特殊说明,连接器指的是静态连接器.
2. 基本概念
链接器把一个或多个输入文件合成一个输出文件.
输入文件: 目标文件或链接脚本文件.
输出文件: 目标文件或可执行文件.
目标文件(包括可执行文件)具有固定的格式, 在 UNIX 或 GNU/Linux 平台下, 一般为 ELF 格式. 若想了解
更多, 可参考
UNIX/Linux 平台可执行文件格式分析
有时把输入文件内的 section 称为输入 section(input section), 把输出文件内的 section 称为输出
section(output sectin).
目
标文件的每个 section 至少包含两个信息: 名字和大小. 大部分 section 还包含与它相关联的一块数据, 称
为 section
contents(section 内容).
一个 section 可被标记为“loadable(可加载的)”或“allocatable(可分配的)”.
loadable section: 在输出文件运行时, 相应的 section 内容将被载入进程地址空间中.
allocatable section: 内容为空的 section 可被标记为“可分配的”. 在输出文件运行时, 在进程地址空间中
空出大小同 section 指定大小的部分. 某些情况下, 这块内存必须被置零.
如果一个 section 不是“可加载的”或“可分配的”, 那么该 section 通常包含了调试信息. 可用 objdump -h
命令查看相关信息.
每
个“可加载的”或“可分配的”输出 section 通常包含两个地址: VMA(virtual memory
address 虚拟内存地址或程序地址空间地址)和 LMA(load memory address 加载内存地址或进程地址空
间地址).
通常 VMA 和 LMA 是相同的.
在目标文件中, loadable 或 allocatable 的输出 section 有两种地址: VMA(virtual Memory
Address)和 LMA(Load Memory Address). VMA 是执行输出文件时 section 所在的地址,
而 LMA 是加载输出文件时 section 所在的地址. 一般而言, 某 section 的 VMA == LMA. 但在嵌入式系统
中,
经常存在加载地址和执行地址不同的情况: 比如将输出文件加载到开发板的 flash 中(由 LMA 指定),
而在运行时将位于 flash 中的输出文件复制到 SDRAM 中(由 VMA 指定).
可这样来理解 VMA 和 LMA, 假设:
(1) .data section 对应的 VMA 地址是 0x08050000, 该 section 内包含了 3 个 32 位全局变量, i、j 和
k, 分别为 1,2,3.
(2) .text section 内包含由"printf( "j=%d ", j );"程序片段产生的代码.
连接时指定.data section 的 VMA 为 0x08050000, 产生的 printf 指令是将地址为 0x08050004 处的 4
字节内容作为一个整数打印出来。
如果.data section 的 LMA 为 0x08050000,显然结果是 j=2
如果.data section 的 LMA 为 0x08050004,显然结果是 j=1
还可这样理解 LMA:
.text section 内容的开始处包含如下两条指令(intel i386 指令是 10 字节,每行对应 5 字节):
jmp 0x08048285movl $0x1,%eax
如
果.text section 的 LMA 为 0x08048280, 那么在进程地址空间内 0x08048280 处为“jmp
0x08048285”指令, 0x08048285 处为 movl $0x1,%eax 指令. 假设某指令跳转到地址 0x08048280,
显然它的执行将导致%eax 寄存器被赋值为 1.
如果.text section 的 LMA 为 0x08048285,
那么在进程地址空间内 0x08048285 处为“jmp 0x08048285”指令, 0x0804828a 处为 movl
$0x1,%eax 指令.
假设某指令跳转到地址 0x08048285, 显然它的执行又跳转到进程地址空间内 0x08048285 处, 造成死循
环.
符号(symbol): 每个目标文件都有符号表(SYMBOL TABLE), 包含已定义的符号(对应全局变量和 static
变量和定义的函数的名字)和未定义符号(未定义的函数的名字和引用但没定义的符号)信息.
符号值: 每个符号对应一个地址, 即符号值(这与 c 程序内变量的值不一样, 某种情况下可以把它看成变量
的地址). 可用 nm 命令查看它们. (nm 的使用方法可参考本 blog 的
GNU binutils 笔记
)
3. 脚本格式
链接脚本由一系列命令组成, 每个命令由一个关键字(一般在其后紧跟相关参数)或一条对符号的赋值语句组
成. 命令由分号„;‟分隔开.
文件名或格式名内如果包含分号';'或其他分隔符, 则要用引号„"‟将名字全称引用起来. 无法处理含引号的文
件名.
/* */之间的是注释。
4. 简单例子
在介绍链接描述文件的命令之前, 先看看下述的简单例子:
以下脚本将输出文件的 text section 定位在 0x10000, data section 定位在 0x8000000:
SECTIONS
{
. = 0x10000;
.text : { *(.text) }
. = 0x8000000;
.data : { *(.data) }
.bss : { *(.bss) }
}
解释一下上述的例子:
. = 0x10000 : 把定位器符号置为 0x10000 (若不指定, 则该符号的初始值为 0).
.text : { *(.text) } : 将所有(*符号代表任意输入文件)输入文件的.text section 合并成一个.text
section, 该 section 的地址由定位器符号的值指定, 即 0x10000.
. = 0x8000000 :把定位器符号置为 0x8000000
.data : { *(.data) } : 将所有输入文件的.text section 合并成一个.data section, 该 section 的地址被
置为 0x8000000.
.bss : { *(.bss) } : 将所有输入文件的.bss section 合并成一个.bss section,该 section 的地址被置为
0x8000000+.data section 的大小.
连接器每读完一个 section 描述后, 将定位器符号的值*增加*该 section 的大小. 注意: 此处没有考虑对齐
约束.
5. 简单脚本命令
- 1 -
ENTRY(SYMBOL) : 将符号 SYMBOL 的值设置成入口地址。
入口地址(entry point): 进程执行的第一条用户空间的指令在进程地址空间的地址)
ld 有多种方法设置进程入口地址, 按一下顺序: (编号越前, 优先级越高)
1, ld 命令行的-e 选项
2, 连接脚本的 ENTRY(SYMBOL)命令
3, 如果定义了 start 符号, 使用 start 符号值
4, 如果存在.text section, 使用.text section 的第一字节的位置值
5, 使用值 0
- 2 -
INCLUDE filename : 包含其他名为 filename 的链接脚本
相当于 c 程序内的的#include 指令, 用以包含另一个链接脚本.
脚本搜索路径由-L 选项指定. INCLUDE 指令可以嵌套使用, 最大深度为 10. 即: 文件 1 内 INCLUDE 文件
2, 文件 2 内 INCLUDE 文件 3... , 文件 10 内 INCLUDE 文件 11. 那么文件 11 内不能再出现 INCLUDE
指令了.
- 3 -
INPUT(files): 将括号内的文件做为链接过程的输入文件
ld 首先在当前目录下寻找该文件, 如果没找到, 则在由-L 指定的搜索路径下搜索. file 可以为 -lfile 形式,
就象命令行的-l 选项一样. 如果该命令出现在暗含的脚本内, 则该命令内的 file 在链接过程中的顺序由该暗
含的脚本在命令行内的顺序决定.
剩余34页未读,继续阅读
资源评论
- sx123sx3212015-04-01内容对于初学者已经足够了,想深入的话还是得看英文材料!
- operands2015-03-13不错,有帮助。
- bluesnail19862013-08-12还可以,和CSDN上另一份235KB的资料是一样的,格式不同而已。对ld的讲解比较详细,入门者可以看下~~
merkey
- 粉丝: 1
- 资源: 35
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功