elf格式详解

elf是linux下一种常见的可执行文件格式。其内容如下:
这里写图片描述
主要包括一个64byte的elf header,一个程序头表,一个段头表,其余真实有用的东西,如code section,data section等等。
先说elf 头
这里写图片描述
先说段头表(section header table)
这个段头表位于位于上面位置呢?其实刚刚elf头中的start of section headers就表明了,段头表位于文件起始处6824处。
这个段头表的内容为:
这里写图片描述
这个段头表描述的就是elf文件中所有section的信息。
elf文件中存在很多section
这里写图片描述
常见的有text section ,用于放代码,.data section用于放全局变量,bss section 用于放为初始化变量。还有比较重要的symble table section,存放由变量,函数生成的符号,通过mn命令可以看到。还有debug section,这个字段要在编译的时候-g才会有。
具体如下图;
这里写图片描述
接下来说程序头表。这个程序头表的位置就是elf头部中的程序头起点字段64,所以可知,程序头表就是位于elf头的下方。
这里写图片描述
为什么会有这个东西呢?我们又section不就够了,装载程序时,直接将text,data,bss等等section按部就班装到内存不就够了吗?
这是因为,elf中实在太多section了,多达三十个,我们上面只是列举了一小部分很重要的section而已,像字符串段,符号表段,调试段都没有列出来,而我们知道,内存是以页为单位的,如果一个section装不满一页,仍然要装一页,而这三十个section中,很多是不够一页的,所以会造成很大的空间浪费。
其实我们想想,存放到内存中,更看重的是权限(只读,可读可写等等),而非功能,意思就是,我们可以把权限相同的section放在一起组成一个segment,然后把这个segment放到页中,而不是一个一个section这样放到页中。
所以,我们可以把以代码段代表的可读section归结为一个segment;把数据段和bss段代表的可读可写归结为另一个segment;把只读段代表的section归结为一个segment。
上面的程序头表中每个segment 都有offset,和virtAddr,offet代表该segment在文件中的位置,virtAddr代表该segment在程序运行时必须存在在内存地址。所以简单来讲,程序加载时,只要将文件中相应的segment放到其该在的内存地址,然后出现指针调到人口地址即可执行,如上elf头中所示,该elf的入口 0x400890。由上程序头表 图可知,text段位于第一个LOAD中,而data位于第二个LOAD中。
这里写图片描述
linux内核装载elf文件过程,bash进程会调用fork系统调用,fork再调用execve。这个execve会先提取文件的前128字节,通过elf头的magic字段判断文件格式,再调用相应的函数处理,如判断为elf格式,则调用load_elf_handle。然后根据程序头表的描述,对elf进行映射,即将文件中的segment读到内存中,然后将pc指针修改为可执行文件的入口地址,这个入口地址,如果是静态链接的话,就是elf文件的文件头中的入口点地址字段,如果是动态链接的话,这个入口就是动态链接器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值