LinkScript

LD 是gnu标准的link工具,link时的代码分配和一些设置由命令行参数或者,更复杂的情况下,由脚本指定,称为LinkScript.
在LD的用户手册中有专门的一章介绍LinkScript语法及使用,本文以此为参考,对一些要点作些笔记.

LinkScript 使用

  1. 使用gcc时,默认会进行compile+link的动作,此时的link会使用gnu自带的默认脚本,如果需要自定义LinkScript,则可使用-c指定gcc只做compile,而手动调用ld来自定义link过程
  2. 使用ld时,以-T <LinkScript>指定脚本,且可指定多个脚本,ld会按指定的先后顺序逐个分析(可用以实现类似include的功能)
  3. 根据ASSEMBER定义,一个头文件可同时用于汇编和C.

语法

1. ENTRY(TEXT_BASE) 设置程序入口
2. MEMORY 定义内存属性
内存块名可用于后面的内存分配,尺寸可用于检查分配的正确性。
3. 变量定义
VAR = VALUE; 可用 ?: 进行选择,条件可用 DEFINED(VAR)

与程序的交互

  1. 汇编中可直接使用LinkScript中定义的变量(做为常数使用)
  2. C中将LinkScript变量声明为extern后即可当常数使用,但涉及指针时可能会出错,要小心核实
  3. LinkScript中可引用文件名,段名,汇编中的global名,并可对程序中的变量,函数等重新定位。但这里的重定位需要注意,虽然地址变动了,但原地址处的数据或代码并不会随之拷贝,所以不要对有初始值的变量重定位。不过可以用来强制修改某个函数使其指向另一版本
  4. .text TEXT_BASE : AT(TEXT_BASE_LMA)

TEXT_BASE指定物理地址,TEXT_BASE_LMA指定实际载入到的地址
另有 NOLOAD属性可指定某段无需载入

  1. 要注意对齐的要求:有些段的开始必须要用 .ALIGN对齐到某个边界,否则内存操作可能出错!

程序空间分布

.text 代码段
.data 有初始值的数据段
.bss 无初始值的数据段(初始化为0)
.heap 堆空间(自低向高)
.stack 栈空间(自高向低)

注意:

# 堆和栈的空间是重叠的,分别从两端开始分配。
# bss段存放的变量未指定初始值,在c代码初始化前会zerobss(将整个bss段清为0)
但有些函数会依赖bss段内的初始0,例如malloc,如果bss未正常清0,其执行会出错!

函数

# LOADADDR(.text) 返回装载地址
# ADDR(.text) 返回物理地址
# SIZEOF(.text) 返回段的尺寸

评论


rating: 0+x

Add a New Comment
or Sign in as Wikidot user
(will not be published)
- +
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-Share Alike 2.5 License.