承接上一篇。我们来看看可执行文件和重定位文件的不同点。
readelf -h test
相比较重定位文件,可执行文件的ELF header中入口地址是0x8048320.而且除了section header外,还存在program header.program header起始于第52个字节,因此program header应该是紧接着ELF header。
可执行文件的ELF 布局如下:
我们来看一下0x8048320地址是什么。
objdump -d test
0x8048320是_start的地址,是程序执行开始的地方。
我们知道可重定位文件的ELF中有section的概念。但在可执行文件中变成了segment.
section和segment的关系是,一个segment是一个或多个属性类似的section合并而成。
为什么要将section进行合并呢?这样做的好处是可以减少页面碎片。可执行文件是要装载到内存中运行的。如果不进行合并,假设页面大小为4096,如果.text 为4097,.init为512,那么将占有3个页面,而合并后只有2个页面。
再看一下可执行文件的section header:
readelf -S test
由于可执行文件动态链接了libc,所以增加了许多section。而且也为.bss分配了空间。.dynamic,.dynsym,.dynstr.got,.got.plt都与动态链接相关。
通过readelf -l test查看section到segment的映射关系,
30个section映射到9个segment。在可执行文件运行时,并非所有的segment都需要装载到内存,只有“LOAD”类型的segment才需要装载。
INTERP是动态链接器的路径。
查看可执行文件的符号,readelf -s test
可执行文件的符号增加了很多,包括编译器加入的和libc的符号。main.o中调用的add不是UND类型的。而libc中的一些需要动态链接进来的符号是UND.