ELF文件整体布局

下图是后来例子中main.o和main.elf的布局。

其中,只有elf header的位置是固定的,固定在文件开始,其它部分的位置都不确定。

比如下面的main.o布局中,.text .comment .shstrtab两个节在前面,而section header table在后面

正常流程应该是由elf header找到section header table,然后,基于该表,定位其它的节。

main.o是Reloc文件,没有program header;main.elf是exec文件,有program header。

main.elf文件的symtab和strtab多了一些内容,这些内容是因为ld阶段没有指定链接脚本,使用了默认链接脚本的原因,默认链接脚本中有一些symbol。

main.elf的text段比main.o的text段多了28字节,这个还没搞清楚?

ELF Header layout

e_ident format

实际工程输出结果

main.c

int main()
{
    ;
}

main.o elf header

编译sparc-elf-gcc.exe -c main.c -o main.o

e_ident部分(前16字节)可以看出,是01-32位,02-大端,01-ELF01版本

其余部分,第二行

红色为e_type,01表示Reloc(01-Reloc,02-Exe,03-Shared)

黄色为e_machine,02表示sparc

蓝色为e_version,版本为1

绿色为e_entry,入口点虚拟地址为0

黑色为e_phoff,program header table file offset,为0,表示没有

其余部分,第三行

红色为e_shoff,section header table file offset,为0x90=144

黄色为e_flags,处理器相关标识

蓝色为e_ehsize,ELF header size in bytes,32位的为0x34=52

绿色为e_phentsize,Program header table entry size,程序头表的大小,因为没有,所以为0

黑色为e_phnum,Program header table entry count,程序头表项目数量,没有,为0

白色为e_shentsize,Section header table entry size,分区头表表项的大小,0x28=40,是每个项目40字节,一共8个项目,那么共320字节

其余部分,第四行

红色为e_shnum,Section header table entry count,分区头表项目数量,为8

黄色为e_shstrndx,Section header string table index,分区头字符表索引,为5,表示shstrtab在section header中的索引,用处?

main.o elf header简略版

下面是简略版,只关注重要的信息

0x18为e_entry,入口点虚拟地址,为0,因为是o文件,所以没有?是的

0x1c黄色为e_phoff,program header table file offset,为0,表示没有,因为是o文件?对于Reloc文件,program头表是可选的;而对于Exec文件,是强制的。

0x2a黄色高2字节为e_phentsize,Program header table entry size,程序头表的大小,因为没有,所以为0

0x2c黄色低2字节为e_phnum,Program header table entry count,程序头表项目数量,没有,为0

0x20蓝色为e_shoff,section header table file offset,为0x90=144

0x2e蓝色为e_shentsize,Section header table entry size,分区头表的大小,0x28=40

0x30蓝色为e_shnum,Section header table entry count,分区头表项目数量,为8

main.o的text节

elf header后紧跟的是text节,一共5条机器指令,共20个字节

下图是反汇编结果:

main.o的comment节

main.o没有data和bss节,后面紧跟comment节,如何知道是commnet节呢?这是从readelf结果中看出来的

这个段主要是版本控制信息This section holds version control information.

main.o的shstrtab节

comment节后是section header string table节,包含所有节名的字符串

main.o的section header

由elf header可知,section header偏移为0x90,每个entry的大小固定为0x28=40字节,每个entry占4字节,共10个enty。

第一个entry是固定为空的,第二个entry是text节。

红色为sh_name,这里其实是shstrtab中字符串的索引,0x1B正好对应.text字符串,字符串以\0结尾,上图0x00和0x2E的右侧字符表示都为.,但其中一个.为\0。

黄色为sh_type,01表示PROGBITS

蓝色为sh_flags,是一个位量,表示allocatable和executable

蓝色后4个字节为sh_addr,表示执行时的虚拟地址

绿色为sh_offset,表示在本文件中的偏移,为0x34。

黑色为sh_size,表示本节的大小为0x14=20,5条机器指令

绿色下面的四个字节表示sh_addralign,为4字节对齐

黑色下面的四个字节表示sh_entsize,若节中包含一个表格,那么,表示表格entry的大小,比如symtab节的这个值为0x10=16,即每个symbol的大小为16字节。对于strtab和shstrtab两个虽然也是表格,但该值为0,推测是由于string可以由\0区分,不需要表格的行。

readelf的结果:

symtab

symbol table符号表,每个符号占16字节

每个符号格式如下:


main.o共有8个符号,第1个符号为空,第8个符号为main

红色为name,4字节,数值为name在strtab中的索引

红色后面为value,4字节

黄色为size,4字节,main符号大小为20字节,即main函数的大小

绿色的高4bit为bind,低4位为type,bind表示符号是全局的1、局部的0等属性,type表示符号是文件4、函数2、段3等属性

黑色的为st_shndx,这个为该符号在节头表中的所属节的索引,1表示属于节头表索引1,即text

readelf的结果,下图最后一列即为st_shndx,有些是ABS绝对地址,就不属于任意节,像main函数属于索引1,即text

nm的结果

sparc-elf-nm main.o
 a *ABS*
 T main

main.elf

链接生成sparc-elf-ld.exe main.o -nostartfiles -o main.elf

elf header部分:

红色为program header offset,0x34,program header entry size=0x20,num=1

program header部分:

黄色为type,1=LOAD加载类型,

黄色后面4字节为segment段偏移(关于节section和段segment,reloc文件里叫节,exec将各reloc文件的节合并在一起叫段,节包含在段里面)

绿色为虚拟地址,后面4字节为物理地址

黑色为filesz,黑色后面4字节为memsz

main.elf的text段的大小变为0x30了,不知道为什么,后面增加的部分全为0。

symtab和strtab增加了许多,是因为使用了默认的链接脚本(因为没有指定链接脚本,所以使用了默认的,-vobose可以看到),多了很多符号。

program header readelf output

section header readelf output,可以看出main.elf相比main.o文件的节头表中text data bss节的地址增加了4000 0000的起始。

附录:

main.o

reference:

https://www.cnblogs.com/gatsby123/p/9750187.html

https://segmentfault.com/a/1190000016766079

http://refspecs.linuxbase.org/elf/elf.pdf

ELF文件之一——的更多相关文章

  1. ELF文件

    ELF文件格式是一个开发标准,各种UNIX系统的可执行文件都采用ELF格式,它有三种不同的类型: 可重定位的目标文件 可执行文件 共享库 现在分析一下上一篇文章中经过汇编之后生成的目标文件max.o和 ...

  2. linux实践之ELF文件分析

    linux实践之ELF文件分析 下面开始elf文件的分析. 我们首先编写一个简单的C代码. 编译链接生成可执行文件. 首先,查看scn15elf.o文件的详细信息. 以16进制形式查看scn15elf ...

  3. elf文件中的.plt .rel.dyn .rel.plt .got .got.plt的关系

    .plt的作用是一个跳板,保存了某个符号在重定位表中的偏移量(用来第一次查找某个符号)和对应的.got.plt的对应的地址 .rel.dyn重定向表,在程序启动时就需要重定位完成. .rel.plt保 ...

  4. 实例分析ELF文件动态链接

    参考文献: <ELF V1.2> <程序员的自我修养---链接.装载与库>第6章 可执行文件的装载与进程 第7章 动态链接 <Linux GOT与PLT> 开发平台 ...

  5. 实例分析ELF文件静态链接

    参考文献: <ELF V1.2> <程序员的自我修养---链接.装载与库>第4章 静态链接 开发平台: [thm@tanghuimin static_link]$ uname ...

  6. ldconfig报错 :libstdc++.so.6.0.18-gdb.py不是一个elf文件

    今天安装wxWidgets,输入ldconfig竟然提示 /usr/lib64/libstdc++.so.6.0.18-gdb.py 不是一个elf文件,开头魔数错误 摸不着头脑,上网搜了一下,有说是 ...

  7. axf、elf文件转换成bin、hex脚本工具

    在嵌入式开发过程中常常遇到将axf或elf文件转换成bin的情况,大家都知道通过gnu toolchain中的objcopy和keil中的fromelf能做到.可是为了这么一个小事而记住复杂的选项以及 ...

  8. 为什么ELF文件的加载地址是0x8048000

    在一个进程的虚拟地址空间中,ELF文件是从0x8048000这个地址开始加载的,为什么会是这个地址? 回答:用命令ld --verbose可以看到0x08048000,ld的默认脚本用这个地址作为EL ...

  9. ELF文件数据布局探索(1)

    作为一名Linux小白,第一次看到a.out这个名字,感觉实在是奇怪,搜了一下才知道这是编译器输出的默认可执行文件名 然后vi一下,哇,各种乱码,仔细看看,发现了三个清晰的字符ELF.继续搜索, 第一 ...

  10. bin文件和elf文件

    ELF文件格式是一个开放标准,各种UNIX系统的可执行文件都采用ELF格式,它有三种不同的类型: 可重定位的目标文件(Relocatable,或者Object File) 可执行文件(Executab ...

随机推荐

  1. 图解kubernetes调度器预选设计实现学习

    Scheduler中在进行node选举的时候会首先进行一轮预选流程,即从当前集群中选择一批node节点,本文主要分析k8s在预选流程上一些优秀的筛选设计思想,欢迎大佬们指正 1. 基础设计 1.1 预 ...

  2. cogs 728. [网络流24题] 最小路径覆盖问题 匈牙利算法

    728. [网络流24题] 最小路径覆盖问题 ★★★☆   输入文件:path3.in   输出文件:path3.out   评测插件时间限制:1 s   内存限制:128 MB 算法实现题8-3 最 ...

  3. springboot 报错nested exception is java.lang.IllegalStateException: Failed to check the status of the service xxxService No provider available for the service

    spring: dubbo:#关闭所有服务的启动时检查:(没有提供者时报错) consumer: check: false timeout: 3000

  4. B-Tree 和 B+Tree 结构及应用,InnoDB 引擎, MyISAM 引擎

    1.什么是B-Tree 和 B+Tree,他们是做什么用的? B-Tree是为了磁盘或其它存储设备而设计的一种多叉平衡查找树,B-Tree 和 B+Tree 广泛应用于文件存储系统以及数据库系统中. ...

  5. 2017-10-28 noip模拟赛by WISCO 信息组

    第一次做模拟赛,自我感觉良好(大概是这套题比较简单) T1 名称为“数据结构”,这也太坑了点……233 要维护一个数列(初始为零),支持区间加与查询. 查询的是一个区间中有多少数满足min<=( ...

  6. Ceph 之RGW Cache

    Overview 缓存是为达到系统快速响应的一项关键技术,Ceph 作为一个复杂的分布式存储系统,有多种.多级缓存存在.缓存按照位置分为: 客户端缓存 服务端缓存 网络中缓存 按照部署方式分为: 单体 ...

  7. XSS Challenges学习笔记 Stage#1~ Stage#19

    开门见山 Stage #1 http://xss-quiz.int21h.jp/?sid=2a75ff06e0147586b7ceb0fe68ee443b86a6e7b9 这一道题发现我们写入的内容直 ...

  8. flutter 与 android 混合开发

    现有的混合开发方式,都是存flutter项目在android系统或者iOS上面跑. 但是,实际情况是,我们需要在一个成熟的native项目上面,跑几个flutter页面,逐步的进行flutter的融合 ...

  9. Ubuntu固定多个静态ip

    步骤: 1.sudo vim /etc/network/interfaces 加入下列内容 auto eth0#此处查看自己的ip信息是eth0还是eth1等等 iface eth0 inet sta ...

  10. flask插件全家桶集成学习---持续更新ing

    不得不说flask的设计要比django要小巧精妙的多了,没有那么臃肿,只保留核心功能,其他的都需要自己引入,即各种各样的插件来满足我们的需求,我这里记录一下自己学习项目中用的插件使用方法和一些技巧总 ...