TOPS
Contents
1. 描述
2. 目标文件格式
Describes
链接脚本主要用于规定如何把输入文件内的section放到输出文件内,并控制输出文件内各部分在程序地址空间的分布,不过也可以使用链接脚本做一些其他的事。
链接器内有个默认的链接脚本,可用 ld-verbose 查看,链接选项 -r 和 -N 都会影响默认的链接脚本。-T 选项用以指定自己的链接脚本,代替默认的脚本。
链接器将 .o 文件中使用的函数和其他 .o 文件或者库文件中的相关符号进行合并,对所有文件中的符号进行重新安排(重定位),并链接系统的相关文件(程序启动文件等)最终生成可执行程序。Linux中,共享库文件格式通常为"ELF"格式,共享库已经具备了可执行条件。
链接器把一个或者多个输入文件合并为一个输出文件:
输入文件:目标文件或链接脚本文件
输出文件:目标文件或者可执行文件
目标文件一般有固定的格式,linux 下一般为 ELF 格式。
目标文件的格式
ELF 文件标准里面把系统中采用 ELF 格式的文件归纳如下:
- 可重定位文件 (Relocatable File)
这类文件包含了代码和数据,可以被用来链接成可执行文件或者共享目标文件,静态链接库也归为这一类
比如,Linux 的 .o Windows 的 .obj - 可执行文件 (Executable File)
这类文件包含了直接可以执行的程序,它的代表就是 ELF 可执行文件,一般没有扩展名
比如,/bin/bash windows 的 .exe - 共享目标文件 (Share Object File)
这种文件包含了代码和数据,可以在以下的两种情况下使用:一种链接器使用这种文件跟其他的可重定位文件和共享目标文件链接,产生新的目标文件;另一种是动态链接器可以将几个这种共享文件和可执行文件结合,作为进程映像的一部分来运行
比如,Linux 的 .so /lib/glibc-2.5.so Windows 的 DLL - 核心转储文件 (Core Dump File)
当进程意外终止时,系统可以将该进程的地址空间的内容及终止时一些其他的信息转储到核心转储文件
比如,Linux 下的 Core Dump
目标文件的每个 section 至少包含两个信息:名字和大小,还会包括一些其他与目标文件相关联的数据,可以使用 objdump 工具查看目标文件。
上图中 ** Idx Name ** 就是段名,
.text(代码段) 存放代码
** .data(数据段) ** 存放初始化了的全局静态变量和局部静态变量
.rodata(只读数据段) 存放的是只读数据,一般是指程序里面的只读变量(const修饰的)和字符串常量
.bss段 存放的是未初始化的全局变量和局部静态变量
还有其他段
除了 ELF 文件中的段,也可以自定义(有的目标文件不能自定义段,ELF 可以)
自定义段
正常情况下,GCC 编译出来的都是按照 ELF 文件的标准格式排版,但是GCC 也支持扩展机制,可以使用属性定义来把变量或者函数放到自定义段;
"__attribute__(section("name"))"
例如:
__attribute__(section("FOO")) int global = 520;
__attribute__(section("BAR")) void foo()
{
}
参考文献
《程序员的自我修养》
《Linux下的lds链接脚本基础》