程序员的自我修养(四)目标文件格式

//2019.5.2
PC平台流行的可执行文件存储格式:
Windows:PE
Linux:ELF

可执行文件(Windows的.exe和Linux的ELF可执行文件)、动态链接库(Windows的.dll和Linux的.so)、静态链接库(Windows的.lib和Linux的.a)都是按照可执行文件格式存储

在Windows平台下,按照PE-COFF格式存储
在Linux平台下,按照ELF格式存储

程序源代码被编译后主要分为两种段:程序指令和程序数据

真正了不起的程序员对自己的程序每一个字节都了如指掌。

EFL结构:
在这里插入图片描述

  • 代码段
  • 数据段和只读数据段
    .data:保存已经初始化了的全局静态变量和局部静态变量
    .rodata:保存只读数据(比如const变量)和字符串变量
    有时候编译器会把字符串变量放到.data段而不会单独放到.rodata
  • BSS段
    .bss:存放未初始化的全局变量和局部静态变量
  • 其他段
    在这里插入图片描述

//2019.5.3
在这里插入图片描述

objdump查看object内部的结构

运行obidump -h XXX.o可以查看各个段的信息,比如:
在这里插入图片描述
图中:
0:代码段
1:数据段
2:BSS段
3:只读数据段
4:注释信息段
5:堆栈提示段

用size可以查看elf文件的代码段、数据段和BSS段的长度(dec:三个段长度的十进制,hex长度和的十六进制)
在这里插入图片描述

查看具体内容:
-s:将所有段的内容以十六进制的方式打印出来
-d:将所有包含指令的段反汇编
在这里插入图片描述

elf文件头

在这里插入图片描述
elf的文件头定义了elf魔数、文件机器字节长度、数据存储方式、版本、运行平台、ABI版本、elf重定位类型、硬件平台、硬件平台版本、入口地址、程序头入口和长度、段表的位置和长度及段的数量等。

这些字段的相关常量都定义在elf.h里面。

elf魔数
在这里插入图片描述
Magic的16个字节对应的是e_ident成员。
这16个字节被elf标准规定用来标识elf文件的平台属性。
最开始的4个字节是所有elf文件都必须相同的标识码,分别为:0x7f、0x45、0x4c、0x46,第一个字节对应ASCII字符里的DEL控制符,后面3个字节是ELF这3个字母的ASCII码。这4个字节又被称为elf文件的魔数,几乎所有的可执行文件格式的最开始的几个字节都是魔数。
魔数通常用来确认文件的类型,操作系统在夹杂可执行文件的时候会确认魔数是否正确,如果不正确会拒绝加载。
PE/COFF文件最开始的两个字节为0x4d、0x5a,即ASCII码字符MZ

//2019.5.4
段表:
在这里插入图片描述

重定位表
链接器在处理目标文件的时候,需要对目标文件中的某些部位进行重定位,即代码段和数据段中那些对绝对地址的引用的位置。
这些重定位的信息被记录在elf表中,对于每个需要重定位的代码段或数据段,都会有一个相应地重定位表。

符号表

readelf -s XXX.o

elf文件中符号表往往是文件中的一个段,段名:.symtab
符号所在表:如果符号定义在本目标文件中,那么这个成员标识符号所在的段在段表的下表;如果符号不是定义在本目标文件中,或者对于某些特殊符号。sh_shndx的值如下:
在这里插入图片描述

符号值:每个符号都有一个对应的值,如果这个符号是一个函数或变量的定义,那么符号的值就是这个函数或变量的地址。

特殊符号:
__executable_start:程序的起始地址(不是入口地址)
__etext、_exext、etext:代码段结束地址
_edata、edata:数据段的结束地址
_end、end:程序的结束地址

函数签名 :包含了一个函数的信息,包括函数名、参数类型、所在的类和名称空间以及其他信息。用于标识不同的函数。

extern “C”:把内部代码当做C语言代码处理

  • 弱符号和强符号
  • 弱引用和强引用
调试信息

在gcc编译时加上-g参数,编译器就会在产生的目标文件里加上调试信息。
ELF文件采用一个叫DWARF(Debug With Arbitrary Record Format)的标准调试信息格式

在Linux下,去掉调试信息:

$strip foo

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值