什么2007做视频网站,第三方专业网站制作公司有哪些,中国建设教育协会培训中心官网,蚌埠建设学校网站LinuxC目标文件 宗旨#xff1a;技术的学习是有限的#xff0c;分享的精神是无限的。 一、目标文件格式#xff08;ELF格式#xff09;
编译器编译源代码后生成的文件叫做目标文件。目标文件是已经编译后的可执行文件#xff0c;只是还没有经过链接的过程。
PC平台流行…LinuxC目标文件 宗旨技术的学习是有限的分享的精神是无限的。 一、目标文件格式ELF格式
编译器编译源代码后生成的文件叫做目标文件。目标文件是已经编译后的可执行文件只是还没有经过链接的过程。
PC平台流行的可执行文件格式windows下的PE和Linux下的ELF。
动态链接库和静态链接库也是按照可执行文件存储的。
1、ELF文件归于4类 ELF文讲类型 说明 举例 可重定位文件 目标文件.o Linux的.o windows下的.obj 可执行文件 直接可执行的文件 /bin/bash windows的.exe 共享目标文件 .so DLL 核心转储文件 进程意外终止 core dump
Linux下的file命令查看相应的文件格式 2、目标文件
编译后的机器指令代码、数据、符号表、调试信息、字符串等。
一般目标文件将这些文件信息按不同的属性以“节”的形式存储。
机器指令放在代码段.text已初始化全局变量和静态变量放在数据段里.data未初始化全局变量和静态变量放在数据段里.bss。.bss只是为变量预留的位置而已并没有内容不占据空间。 二、剖析目标文件section.o // section.c
#includestdio.hint init_var 84;
int uninit_var;void fun(int i)
{printf( %d \n, i);
}int main(void)
{static int static_var 85;static int static_var2;int a 1;int b;fun(init_var uninit_var a b);return 0;
} gcc -c section.c生成section.o——只编译不链接
objdump -h section.o// ELF文件的各个段的基本信息打印出来。 除了最基本的代码段、数据段、BSS段还有三个段只读数据段.rodata、注释信息段.comment和堆栈提示段.note.GNU-stack。
段的属性最容易理解的就是段的长度Size和段所在的位置File off偏移量。每个段第二行的“CONTENTS”表示该段在文件中存在——BSS段没有“CONTENTS “实际上在ELF中不存在”note.GNU-stack“有“CONTENTS”但大小为0奇怪。 size命令查看ELF文件中的代码段、数据段和BSS段长度。
rootcolinux:~/mystudy# size section.o text data bss dec hex filename 88 8 4 100 64 section.o 1、代码段 objdump的“-s”十六进制方式打印“-d”反汇编。提取出代码段的内容 “Contents of section.text”就是.text的数据以十六进制方式打印出来的内容0x58字节与size命令的长度符合。对照反汇编结果.text包含两个函数fun()和main()。.text的第一个字节就是”0x55”就是fun()函数的第一条“push %ebp”指令而最后一个字节0xc3正是main()函数的最后一条指令“ret”。 2、数据段和只读数据段 .data段保存的是初始化的全局变量和静态变量section.c中有这样两个变量init_var和static_var都是int型刚好8字节。所以.data的大小是8字节。
Contents of section .data: 0000 54000000 55000000 T...U...
Contents of section .rodata: 0000 20256420 0a00 %d ..
.data前四个字节0x54、0x00、0x00、0x00 —— 0x54 84——大端机 3、BSS段 .bss段保存的是未化的全局变量和静态变量section.c中有这样两个变量uninit_var和static_var2。但是通过size命令看到.bss只有4字节。通过符号表后面说看到只有static_var2被放入了.bss段uninit_var没有。与不同的语言和不同的编译器有关。 4、其他段 常用段名 说明 .rodata 只读数据如字符串常量const只读变量 .comment 编译器版本信息 .debug 调试信息 .dynamic 动态链接信息 .hash 符号哈希表 .line 行号表 .note 额外的编译器信息公司名发布版本号等 .strtab 字符串表 .symtab 符号表 .shstrtab 段名表 .plt .got 动态链接的跳转表和全局入口表 .init .fini 程序初始化与终结代码段 三、ELF文件结构 提取重要的结构ELFHeaderELF文件头、.text、.data、.bss、其他段、段表、字符串表、符号表等。
ELF文件头——描述了整个文件的文件属性是否可执行、是静态还是动态连接及入口地址、目标硬件、目标操作系统等信息。
段表——所有段的信息段名、段的长度、在文件中的偏移、读写权限及段的其他属性。 1、文件头readelf命令 ELF文件头定义ELF魔数、文件机器字节长度、文件存储方式、版本、运行平台、ABI版本、ELF重定位类型、硬件平台、硬件平台版本、入口地址、程序头入口地址和长度、段表的位置和长度及段的数量等。
ELF文件头结构及相关常数被定义在”/usr/include/elf.h”,32位“ELF32_Ehdr” #define EI_NIDENT(16)typedef struct
{unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */Elf32_Half e_type; /* Objectfile type */Elf32_Half e_machine; /*Architecture */Elf32_Word e_version; /* Object file version */Elf32_Addr e_entry; /* Entrypoint virtual address */Elf32_Off e_phoff; /* Programheader table file offset */Elf32_Off e_shoff; /* Sectionheader table file offset */Elf32_Word e_flags; /*Processor-specific flags */Elf32_Half e_ehsize; /* ELFheader size in bytes */Elf32_Half e_phentsize; /* Programheader table entry size */Elf32_Half e_phnum; /* Program header table entrycount */Elf32_Half e_shentsize; /* Sectionheader table entry size */Elf32_Half e_shnum; /* Sectionheader table entry count */Elf32_Half e_shstrndx; /* Sectionheader string table index */
} Elf32_Ehdr; 结构与readelf输出的ELF文件头信息相比只有e_ident对应了readelf输出中的“Class Data Version OS/ABI ABI Version”5个参数剩下的参数一一对应。
ELF魔数Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
16字节对应了Elf32_Ehdr的e_ident这个16字节成员。这16字节被ELF标准规定来标识ELF文件的平台属性如字长、字节序、版本等。16字节含义
前4字节是所有ELF文件都必须相同的标识码0x7F、0X45、0X4C、0X46这四个字节就是ELF文件的魔数。几乎所有的可执行文件的开始的几个字节都是魔数如a.out最开始两个字节是0x01、0x07PE最开始两个字节是0x4d、0x5a。这个魔数用来确认文件类型。第5个字节用来标识ELF文件类的0x01表示是32位的0x02表示64位的。第6字节是字节序规定ELF文件是大端的还是小端的。第7字节规定ELF文件的主版本号一般是1.后面的九个字节ELF标准没有定义一般写0。
e_type文件类型ET_REL—— 1 ——可重定位文件一般是.o文件ET_EXEC—— 2 —— 可执行文件 ET_DYN —— 2 ——共享目标文件一般是.so文件。
e_machine机器类型ELF文件的平台属性EM_386 —— 3 —— x86 2、段表
ELF的段结构就是由段表决定的编译器、连接器和装载器都是靠段表来定位和访问各个段的属性的。段表在ELF文件中的位置由ELF文件头Elf32_Ehdr结构中的” e_shoff” 成员决定。section.o中段表位于偏移0x104260字节处。
前面用”objdump -h”查看ELF文件中的段此命令只是把ELF文件中的关键段显示出来了省略了其他辅助性的段符号表、字符串表、重定位表等。
readelf -S命令 段表是以“Elf32_Shdr”结构体为元素的数组数组元素的个数等于段的个数每个“Elf32_Shdr”结构体对应一个段。section.o11个元素的数组。/usr/include/elf.h typedef struct
{Elf32_Word sh_name; /* Section name (string tblindex) */Elf32_Word sh_type; /* Section type */Elf32_Word sh_flags; /* Section flags */Elf32_Addr sh_addr; /* Section virtual addr atexecution */Elf32_Off sh_offset; /* Section file offset */Elf32_Word sh_size; /* Section size in bytes */Elf32_Word sh_link; /* Link to another section */Elf32_Word sh_info; /* Additional sectioninformation */Elf32_Word sh_addralign; /* Section alignment */Elf32_Word sh_entsize; /* Entry size if section holdstable */
} Elf32_Shdr; 总结section.o段表的位置 起始地址 大小 ELF Header e_shoff 0x104 0 0x34 .text 0x34 0x52 .data 0x88 0x08 .rodata 0x90 0x06 .comment 0x96 0x1d .shstrtab 0xB3 0x51 Section Table 0x104 0x1b8 .symtab 0x2bc 0xf0 .rel.text 0x3fc 0x28
长度为0x424 1060这个长度正好是section.o文件的大小。
段的类型sh_type段的名字只有在编译和链接的过程中有意义。SHT_NULL – 0 – 无效段 SHT_PROGBITS– 1 – 程序段 SHT_SYMTAB – 2 – 表示该段的内容为符号表, SHT_STRTAB – 3 – 字符串表 SHT_RELA –4 – 重定位表 SHT_HASH – 5 – 符号表的哈希表SHT_DYNAMIC – 6 – 动态链接信息 SHT_NOTE – 7 – 提示性信息 SHT_NOBITS– 8 –该段在文件中没内容 SHT_REL – 9 –该段包含了重定位信息SHT_SHLIB – 10 – 保留SHT_DNYSYM – 11 – 动态链接的符号表。
段的标志位sh_flag表示该段在进程虚拟地址空间中的属性可写可执行等。SHF_WRITE – 1 – 该段在进程空间中可写 SHF_ALLOC– 2 – 在进程空间中要分配空间 SHF_EXECINSTR– 4 –该段在进程空间中可以被执行一般指代码段。 段的链接信息sh_link、sh_info sh_type sh_link sh_info SHT_DYNAMIC 字符串表在段表的下标 0 SHT_HASH 符号表在段表中的下标 0 SHT_REL 相应符号表在段表中的下标 该重定位表所作用的段在段表中的下标 SHT_RELA SHT_SYMTAB 操作系统相关 操作系统相关 SHTDYNSYM other SHN_UNDEF 0 3、重定位表 section.o中有一个“rel.text”的段类型是“SHT_REL”——重定位表。
代码段和数据段中那些对绝对地址的引用的位置——相应的重定位表。section.o中的“rel.text”就是对“.text”段的重定位表——printf函数的调用而“.data”段没有对绝对地址的引用只包含了几个常量故没有“.rel.data”。 4、字符串表——段名变量名等 四、链接的接口——符号 可以使用很多工具查看ELF文件的符号表readelfobjdumpnm等 1、ELF符号表结构 ELF符号表是文件中的一个段“.symtab” /* Symbol table entry. */
typedef struct
{Elf32_Word st_name; /* Symbol name (string tblindex) */Elf32_Addr st_value; /* Symbol value */Elf32_Word st_size; /* Symbol size */unsigned char st_info; /* Symbol type and binding */unsigned char st_other; /* Symbol visibility */Elf32_Section st_shndx; /* Section index */
} Elf32_Sym;