linker and loader这本书是目前介绍连接器跟加载器最全面的书了。毕业之前在学校的时候就看过一遍,不过由于这本书过于理论、晦涩,当时并没有理解透,如今结合实际来读,来彻底的完成对这本书的学习。
这篇笔记并不是想全面介绍什么是连接器和加载器,只是记下自己读这本书的理解过程,结合一些实际来加深理解。
对广大程序员来说,连接器跟加载器也并不是什么特别陌生的东西,虽然并不是很多人都会非常了解编译连接技术,不过没见过猪跑,难道还没吃过猪肉吗,写程序写多了总会对连接器有点了解。下面从一个简单的“hello world”程序开始,一步一步的了解整个连接过程。
ex01.cpp
#include "iostream"
int times = 9;
int main()
{
const char* str = "hello world";
for(int i = 0; i < times; i++)
{
std::cout<<str<<std::endl;
}
}
g++ ex01.cpp -c 生成可重定位的ex01.o ELF目标文件。先用objdump -D -x ex01.o来查看目标文件的内容。
区信息:
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 000000af 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000004 00000000 00000000 000000e4 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000001 00000000 00000000 000000e8 2**2
ALLOC
3 .rodata 0000000c 00000000 00000000 000000e8 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .ctors 00000004 00000000 00000000 000000f4 2**2
CONTENTS, ALLOC, LOAD, RELOC, DATAi
5 .comment 00000024 00000000 00000000 000000f8 2**0
CONTENTS, READONLY
6 .note.GNU-stack 00000000 00000000 00000000 0000011c 2**0
CONTENTS, READONLY
7 .eh_frame 00000070 00000000 00000000 0000011c 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
该可重定位的目标文件有8个区。.text代码区,大小0xaf,VMA,LMA表示虚拟内存地址,线性内存地址,由于这是可重定义文件,所以这两个域一般都为0,File off文件偏移量是Ox34,前面还有52个字节的ELF头,用readelf -a ex01.o就能很详细的看见。Algn=4,.text区是4字节对齐的。.data只有4个字节,就一个times。.bss是未初始化数据区,有1个size,main里面并没有用到,是libc的静态初始化函数里用的,以后再介绍。由于是全0,所以并不占文件的空间,所以下面的.rodata只读数据区的文件偏移量跟.bss相同,大小0x0c,就是存放“hello world”的段。
接下来是符号表
SYMBOL TABLE:
00000000 l df *ABS* 00000000 ex01.cpp
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l O .bss 00000001 _ZStL8__ioinit
00000000 l d .rodata 00000000 .rodata
00000053 l F .text 00000040 _Z41__static_initialization_and_destruction_0ii
00000093 l F .text 0000001c _GLOBAL__I_times
00000000 l d .ctors 00000000 .ctors
00000000 l d .note.GNU-stack 00000000 .note.GNU-stack
00000000 l d .eh_frame 00000000 .eh_frame
00000000 l d .comment 00000000 .comment
00000000 g O .data 00000004 times
00000000 g F .text 00000053 main
00000000 *UND*