【嵌牛导读】什么是ELF文件
【嵌牛鼻子】什么是ELF文件
【嵌牛提问】什么是ELF文件,它有哪些部分组成、每部分包含哪些信息
ELF文件分为四个部分:elf header,program header table,section header table,dynamic symbol table。其中节头表(section header table) 和 段头表(program header table) 中用到的数据相同,只是组织方式不同。
一、ELF header
每个ELF文件都必须存在一个ELF_Header,这里存放了很多重要的信息用来描述整个文件的组织,如: 版本信息,入口信息,偏移信息等,程序执行也必须依靠其提供的信息:
数据结构如下:
e_xxx 和上面对应表如下图:
其中数据类型如下:
二、Program header table 程序头表
存储so文件运行时所需要的信息,这部分信息会直接被linker使用,用于加载so文件,告诉系统如何在内存中创建映像,在图中也可以看出来,有程序头部表才有段,有段就必须有程序头部表,其中存放各个段的基本信息(包括地址指针)
节到段的映射:
链接视图是以节(section)为单位,执行视图是以乱姿配段(segment)为单位。链接视图就是在链接时用到的视图,而执行视图则是哗指在执行时用到的视图。上图左侧的视角是从链接来看的,右侧的视角是册改执行来看的。
段(Segment): 就是将文件分成一段一段映射到内存中,段中通常包括一个或多个节区。
那么为什么需要节和段两种视图? 当ELF文件被加载到内存中后,系统会将多个具有相同权限(flg值)section合并一个segment。 *** 作系统往往以页为基本单位来管理内存分配,一般页的大小为4096B,即4KB的大小。同时,内存的权限管理的粒度也是以页为单位,页内的内存是具有同样的权限等属性,并且 *** 作系统对内存的管理往往追求高效和高利用率这样的目标。ELF文件在被映射时,是以系统的页长度为单位的,那么每个section在映射时的长度都是系统页长度的整数倍,如果section的长度不是其整数倍,则导致多余部分也将占用一个页。而我们从上面的例子中知道,一个ELF文件具有很多的section,那么会导致内存浪费严重。这样可以减少页面内部的碎片,节省了空间,显著提高内存利用率。
readelf -S xxx # 用来查看可执行文件中有哪些section,如下图:
readelf --segments xxx # 可以查看该文件的执行视图,下图红框部分为上图的节信息在段中的显示:
最后加载进内存的只有program header table 程序头表里的load段,其他都只是描述信息,加载过程中用到,但是最后加载进去内存的只有load段。
三、Section header table 节头部表
类似与程序头部表,但与其相对应的是节区(Section);节区(Section): 将文件分成一个个节区,每个节区都有其对应的功能,如符号表,哈 希 表 等。
.relname和.relaname: 010Editor打开so,展现形式为下图,.rel.dyn 和 .rel.plt ,是用来重定向dyn和plt的,也就是静态情况下,存放偏移值,如果进行动态调试的时候,就会加上基址变成绝对地址(重定向)。
下面第二张图中,左边红框就是偏移值,右边红框只要把基址加进来,就是绝对地址,把基址加进来的过程就是重定向的过程:
.plt 程序链接表,用于做映射关系,拿到依赖so的绝对地址,做重定向的:
四、Dynamic symbol table
这里是符号表,也就是会用到的所有函数名称表,包括自己写的函数和依赖的系统so中的函数,到时候.plt会对这部分重定向 。
SO文件格式即ELF文件格式,它是Linux下可执行文件,共享库颂改文件和目标文件的统一格式。
根据看待ELF文件的不同方式,ELF文件可以分为链接视指樱仔图和装载视图。链接视图是链接器从链接的角度看待静态的ELF文件。
从链接视图看ELF文件,ELF文件由多个section组成,不同的section拥有不同的名称,权限。而装载视图是 *** 作系统从加载ELF文件到内存的角度看待动态的ELF文件。
从装载视图看ELF文件,ELF文件由多个segment,每一个segment都拥有不同的权限,名称。实际上,一个segment是对多个具有相同权限的section的集合。
扩展资料:
由于Android *** 作系统的底层基于Linux系统,所以SO文件可以唯汪运行在Android平台上。Android系统也同样开放了C/C++接口供开发者开发Native程序。
由于基于虚拟机的编程语言JAVA更容易被人反编译,因此越来越多的应用将其中的核心代码以C/C++为编程语言,并且以SO文件的形式供上层JAVA代码调用,以保证安全性。
而ELF头表记录了ELF文件的基本信息,包括魔数,目标文件类型(可执行文件,共享库文件或者目标文件),文件的目标体系结构,程序入口地址(共享库文件为此值为0),然后是section表大小和数目,程序头表的大小和数目,分别对应的是链接视图和装载视图。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)