【计算机系统基础】目标文件格式

一、引言

目标代码(Object Code) :指编译器或汇编器处理源代码后所生成的机器语言目标代码
目标文件(Object File) :存放目标代码的文件

目标文件分为:.o文件(代码、数据的地址从0开始)、可执行目标文件(地址为虚拟地址)、共享的目标文件(共享库文件,在Windows里称为DLLs)。

Linux的目标文件格式是ELF格式,即可执行可链接格式。

 

二、ELF格式

两种视图:链接视图/执行视图(具体解释看下面)。链接视图的程序头表可选,节头表必须;而执行视图的程序头表必须,节头表可选。

【注】节头表里有各个“节”的信息,如名字、大小等,在ELF文件末;程序头表描述节怎样映射到存储器映像,在ELF头的紧下方

 

1、链接视图(重点关注ELF头和节头表)

 

【重点1:ELF头】

1、用readelf -h a.o

就可以用来在linux下读取a.o的ELF头文件

2、32位下,占52字节。

3、一个ELF头文件例子(了解)

ehsize是节头表大小,phentsize是程序(program)头表大小。

解析完成之后,得到下图:

【考试题】已知start of section headers = 516, size of this header = 52,求从.text到.line所有节所占大小。

解:start of section headers = 516意思是从节头表往前是516字节,而EIF头占了52,所以剩余部分占了516-52个字节。(注意区分header和section header)

【考试题】有下图数据。求节头表所占字节数

节头表里有15个表项,每个表项占40个字节(实际上,32位下,所有.o文件的表项都是占40字节)。故节头表占600字节。

【注】一般最后最后还会给出string table是第几个表项等等

①可以“被用作链接”,也就是说它们是.o文件。它们还可能是.so文件。

②.o文件里包括代码、数据等等。

如图:代码在.text节,已初始化的全局变量在.data节,未初始化的全局变量在.bss(回顾上节课知识:.data和.bss最后会映射到数据读写区),非静态局部变量放在栈帧中,不会放在ELF文件中。

 

【重点2:以一个完整的链接视图ELF文件为例】

【补充】

1、字符串、跳转表(见switch-case)是只读数据

2、未初始化的变量不占空间,只是占位符!

3、.symtab节是符号表(把全局函数名、变量名放入其中);

.rel.txt节是和.text相关的可重定位信息(如函数的调用关系等);

.rel.data节是和.data相关的可重定位信息;

.debug用作调试;.

.strtab节是字符串表;

.line节就是C语言中的行号和.text机器指令中的对应。

 

【精髓:节头表】(链接视图下,节头表是精髓)

1、查看节头表的指令:

$ readelf -S test.o

2、不必记格式,仅需要理解

3、节头表里有若干表项,每个表项描述对应节在文件中的偏移、大小、访问属性、对齐方式等

 

4、【例子:一个真实的节头表】注意:节头表描述了各个节的属性、信息

There are 11 section headers, starting at offset 0x120:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 00005b 00 AX 0 0 4
[ 2] .rel.text REL 00000000 000498 000028 08 9 1 4
[ 3] .data PROGBITS 00000000 000090 00000c 00 WA 0 0 4
[ 4] .bss NOBITS 00000000 00009c 00000c 00 WA 0 0 4
[ 5] .rodata PROGBITS 00000000 00009c 000004 00 A 0 0 1
[ 6] .comment PROGBITS 00000000 0000a0 00002e 00 0 0 1
[ 7] .note.GNU-stack PROGBITS 00000000 0000ce 000000 00 0 0 1
[ 8] .shstrtab STRTAB 00000000 0000ce 000051 00 0 0 1
[ 9] .symtab SYMTAB 00000000 0002d8 000120 10 10 13 4
[10] .strtab STRTAB 00000000 0003f8 00009e 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)

(从下往上偏移量从大到小)

【解读】1、此节头表起始位置位120(ELF和所有前面的节共占了120字节),共11个节

2、.o文件中,每个可装入节的起始地址总是0(Addr),但是每个节的偏移量不同,如.data的偏移量为000090.只有装入内存时才会分配

3、AX WA WA A是A空间,此表中有4个节分配(A)空间,这个分配空间指的将来在存储器分配空间。

4、特殊地,.bss和.rodata的偏移都是9c,这说明对于.bss节,在ELF文件并未给它分配空间。

【注意】.bss里全是未初始化全局变量。.bss的大小和符号,分别由节头表和符号表(.symtab)描述,且.bss里面变量的默认初值是0;.bss里在文件(如.o/可执行文件)中不占空间,但在存储器映像中占空间。这样做的目的是节省磁盘空间。

5、必要的节一般放前面,其他的一些节可以放在节头表后面

 

 

2、执行视图

【重点1:ELF头】

查看ELF头文件的指令

$ readelf -h main(还是它)

解读:

①程序头表的起始地址:0x8048580+52

②程序头表占32*8个字节

③节头表之前的数据,共占了3232个字节

③节头表占40*29个字节

【注意】所有代码位置连续,所有只读数据位置连续,所有可读可写数据位置连续。

 

【重点2:以一个完整的执行视图ELF文件为例】

查看程序头表的指令:readelf -l(L的小写) main

执行视图图解

①注意:在链接视图里的节,在执行视图中依旧存在,这是多个.o文件的相同节合并后的产物,而且,在可执行目标文件中有的概念(相同访问属性的节构成)。.o文件虽然也有段,但很少用。

(从下往上地址从高到低)

在可执行文件中,多了.init和.fini节,这俩分别做初始化工作和结束工作。少了两个.rel节,因为无需再重定位。

后面还有许多节和一个节头表,它们无需在存储器中存储(映射)。

执行视图中,所有符号(变量和函数)、指令等等都有了确定的地址(虚拟地址)

②可执行目标文件,相当于Windows的.exe文件

 

【精髓:程序头表】(执行视图下,程序头表是精髓)

【解读】(关注虚拟地址【可执行文件有确定的虚拟地址】、两个Siz、Flg和Align)

1、Flg表示权限,R E表示只读,R W表示可读可写。如红LOAD是只读,蓝LOAD是读写

2、Align表示映射到虚拟地址后的对齐方式。占据的空间看MemSiz,而不看Filesiz(这是在可执行文件中占的空间,有些节在可执行文件中没占空间,但映射到存储器中需要占字节,如.bss节)

【再次注意】.bss里全是未初始化全局变量。.bss的大小和符号,分别由节头表和符号表(.symtab)描述,且.bss里面变量的默认初值是0;.bss里在文件(如.o/可执行文件)中不占空间,但在存储器映像中占空间。这样做的目的是节省磁盘空间

3、物理地址 与 虚拟地址一般一样

4、LOAD的FileSiz和MemSiz不同原因是:可读写数据段包括data和bss,在文件中,bss是空的,不占空间。在存储器里面要分配空间。这110-108 = 8个字节,是要给bss分配的空间!这也解释了为什么光第2个LOAD段的两个Size出现不同!

 

上述例子的可执行文件(32位系统)】

1、可执行文件执行时,必须把可装入段映射到存储空间。程序头表描述这种映射关系。特定系统平台中的每个可执行目标文件都采用统一的存储器映像,映射到一个统一的虚拟地址空间(上图右)

2、如图:ELF头文件到.rodata都映射到存储器的只读代码段(内存中,其起始地址是0x08048000)

蓝色区域映射到读写数据段(内存中,其起始地址是0x08049000)

3、对于本例,在存储器中,被装入数据的只读代码段,是从:0x08048000到0x080484d3,剩余空间未使用。

被装入数据的数据读写区要特殊注意!由刚才的程序头表可以知道,存储器中,可读写数据段从0x08049f0c开始(不是0x08049000),连续110(16进制)个字节,给.bss节也分配了空间【对.bss而言,它在文件中不占空间(.o/可执行),但在存储器映像中占空间】。

而在原可执行文件中,我们可以看出,f0c+108就正好到1014(.bss节末端),可见在可执行文件中,未给bss分配空间。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
西安工业大学计算机操作系统实验中,解析ELF文件是一个重要的任务。ELF(Executable and Linkable Format,可执行与可链接格式)是一种通用的二进制文件格式,用于存储可执行程序、共享库和目标文件的相应信息和数据。 解析ELF文件的目的是了解文件的结构、各个部分的功能和含义,以便能够正确加载和执行程序。具体而言,解析ELF文件包括以下几个方面的内容: 1. ELF头部解析:ELF文件以一个固定的头部开始,其中包含了文件类型、目标体系结构、入口地址等基本信息。通过解析ELF头部,可以获取这些重要的文件属性,从而对文件进行正确的解析和处理。 2. 程序头表解析:ELF文件的程序头表记录了可执行文件在虚拟内存中的各个段的信息,如代码段、数据段、BSS段等。通过解析程序头表,可以获取程序的加载和运行所需的内存布局信息,便于操作系统正确加载和映射这些段到内存中。 3. 节头表解析:ELF文件的节头表记录了各个节(section)的信息,包括各个节的起始地址、大小、类型和属性等。常见的节有代码节、数据节、符号表等。通过解析节头表,可以获取各个节的具体信息,便于操作系统进行链接、重定位和符号解析等操作。 4. 符号表解析:ELF文件的符号表记录了程序中定义和引用的符号(如函数名、变量名)以及它们的地址和类型等信息。通过解析符号表,可以实现符号的动态链接和重定位等功能,确保程序能正确地运行。 通过对ELF文件的解析,操作系统可以准确理解和处理可执行程序中的各个组成部分,为程序的加载和执行提供必要的支持。同时,对ELF文件的解析也为进程间的通信和共享提供了基础,实现了程序的模块化和可复用性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值