程序员自我修养第三章__ELF文件

ELF格式完全解释

一,四种ELF文件格式

可重定位文件   linux下的.o文件
可执行文件       比如/bin/bash
共享目标文件    linux的.so文件
核心存储文件    linux下的core dump文件

linux下可以通过file命令查看文件的类型,比如 file test.o

gcc -c test.c test.o

二,目标文件的格式

点击打开链接

点击打开链接


可以通过objdump和readelf工具来分析目标文件

1. ELF头文件

包含了描述整个文件的基本属性,如ELF版本、目标机器型号、程序入口地址等。

$readelf –h test.o

定义在/usr/include/elf.h
typedef struct{
    unsigned char e_ident[16];
    Elf32_Half e_type;  //ELF文件类型
    Elf32_Half e_machine; //ELf文件的CPU平台属性
    Elf32_Word e_version;
    Ellf32_Addr e_entry; //入口地址, 规定ELF程序的入口虚地址
    Elf32_Off e_ohoff;
    Elf32_Off e_shoff; //段表在在这个文件中的偏移
    Elf32_Word e_flags;
    Elf32_Half e_ehsize; //ELF文件头本身的大小
    Elf32_Half e_phentsize;
    Elf32_half e_phnum;
    Elf32_Half e_shentsize; //段表描述符的大小
    Elf32_Half e_shnum; //段表描述符数量
    Elf32_Half e_shstrndx; //段表字符串表所在的段在段表中的下标
}Elf32_Ehdr;



2. 段表

该表描述了所有段的信息,如每个段的段名、段的长度、在文件中的偏移、读写权限和段的其他属性。

$readelf –S Stest.o

定义在/usr/include/elf.h
typedef struct{
    Elf_Word sh_name; //段名(是段名字符串在.shstrtab中的偏移)
    Elf_Word sh_type; //段的类型
    Elf_Word sh_flags; //段的标志位
    Elf_Addr sh_addr; //段虚拟地址
    Elf_Off sh_offset; //段偏移
    Elf_Word sh_size; //段的长度
    Elf_Word sh_link;
    Elf_Word sh_info;
    Elf_Word sh_addralign; //段地址对齐
    Elf_Word sh_entsize; //项的长度
 }Elf32_Shdr;



3. 符号表

目标文件的链接实际上目标文件地址的相互引用,在链接中奖函数和变量统称为符号(Symbol),函数名和变量名就是符号名(Symbol Name)

定义在/usr/include/elf.h
typedef struct{
    Elf32_Word st_name; //符号名(符号名在字符串表中的下标)
    Elf32_Addr st_value; //符号对应的值
    Elf32_Word st_size; //符号大小
    unsigned st_info;
    unsigned st_other;
    Elf32_Half st_shndx; //符号所在的段
}Elf32_Sym;

其中st_name包含指向符号表字符串表(strtab)中的索引,从而可以获得符号名。St_value指出符号的值,可能是一个绝对值、地址等。St_size指出符号相关的内存大小,比如一个数据结构包含的字节数等。St_info规定了符号的类型和绑定属性,指出这个符号是一个数据名、函数名、section名还是源文件名;并且指出该符号的绑定属性是local、global还是weak。

一些特殊的符号:
_start :程序的开始地址,不是入口函数,是最开始的地方
__bss_start:bss段开始的地方
data_start:数据段开始的地方
_edata :数据段结束的地方
这些符号可以再程序中直接使用,比如:

#include "stdio.h"  
extern char _start[];  
extern char data_start[];  
int main()  
{  
    printf("start %X\n",_start);  
    printf("data_start %X\n",data_start);  
    return 0;  
}    




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值