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. OpenGL ES for Android 环境搭建

    在Android上运行OpenGL ES程序需要用到GLSurfaceView控件,GLSurfaceView继承自SurfaceView并实现了GLThread,通过OpenGL ES进行绘制. O ...

  2. 解决 VS Code 中 golang.org 被墙导致的 Go 插件安装失败问题

    微软官方开发的 Go for Visual Studio Code 插件为 Go 语言 提供了丰富的支持.在 VS Code 中首次打开 Go 工作区后,VS Code 会自动检测当前开发环境为 Go ...

  3. Error connecting to the Service Control Manager: 拒绝访问 Mongodb问题-解决

    原文地址:https://blog.csdn.net/carrot5032/article/details/74742888 发现在mongodb.log里出现  2017-07-07T17:01:5 ...

  4. 6、python基本数据类型之序列类型

    前言:python的基本数据类型可以分为三类:数值类型.序列类型.散列类型,本文主要介绍序列类型及其通用操作. 一.序列类型 1)字符串(str):用单引号('),双引号("),三引号(三单 ...

  5. 通过示例学习rholang(下部:课程8-13)

    课程8——状态通道和方法 保存数据 到现在为止,你已经很擅长于发送数据到元组空间和从元组空间中获取数据.但是无论你在什么时候进行计算,你有时需要把一些数据放在一边晚点才使用.几乎所有编程语言都有变量的 ...

  6. AOP编程实践总结

    AOP编程实践总结 AOP概述 AOP(Aspect-Oriented Programming,面向方面编程)是OOP(Object-Oriented Programing,面向对象编程)的补充和完善 ...

  7. ogg trail文件序列号不一致

    一.Cause 在某些情况下,对于一个已经running的OGG进程,对已同步的数据(正确的同步或者错误的同步)做修改,修改完之后,需要保持一个一致点,从一致点继续同步. 这时需要人工干涉产生一个新的 ...

  8. django中navie time 和 aware time的使用和转换

    在django中有关时间被分为navie time 和 aware time两种,前者指的是不带时区标记的时间格式,后者被认为是带有时区标记的时间格式.在django框架的setting.py文件中 ...

  9. logstash split插件的使用(将一个事件拆分成多个事件)

    kafka中的原始数据格式(1条数据) { "body": { "cwd": "/home/test/", "monitor&qu ...

  10. [Python]获取win平台文件的详细信息

    import win32api def getFileProperties(fname): """ 读取给定文件的所有属性, 返回一个字典. ""&q ...