[笔记二]探究编译与链接之目标文件
来源:互联网 发布:淘宝零销量能买吗 编辑:程序博客网 时间:2024/06/14 06:10
目标文件
目标文件的格式
目标文件在Linux下面以ELF格式存储,ELF文件标准里面把系统中采用ELF格式的文件归为以下4类:
在Linux下我们查看文件格式的方式可以如此:
$file hello.ohello.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped$file /bin/bash/bin/bash: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped$file /lib/ld-2.12.so/lib/ld-2.12.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped
目标文件的构成
程序源代码编译后的机器指令经常被放在代码段(Code Section)里,代码段常见的名字有“.text”或“.code”;全局变量和局部静态变量数据经常放在数据段(Data Section),数据段的一般名字都叫“.data”。
真正了不起的程序员对自己的程序的每一个字节都了如指掌。 -共勉之
实例解析
示例代码如下(SimpleSection.c)
int printf(const char *format, ...);//__attribute__((section("Demon"))) int global_init_var = 84;int global_init_var = 84;int global_uninit_var;void func1(int i){ printf("%d\n",i);}int main(void){ static int static_var = 85; static int static_var2; int a = 1; int b; func1(static_var + static_var2 + a + b); return 0;}
编译获取.o文件:
$gcc -c SimpleSection.c
我们来看看该目标文件(SimpleSection.o)内部的结构:
$objdump -h SimpleSection.oSimpleSection.o: file format elf64-x86-64Sections:Idx Name Size VMA LMA File off Algn0 .text 00000056 0000000000000000 0000000000000000 00000040 2**2 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE1 .data 00000008 0000000000000000 0000000000000000 00000098 2**2 CONTENTS, ALLOC, LOAD, DATA2 .bss 00000004 0000000000000000 0000000000000000 000000a0 2**2 ALLOC3 .rodata 00000004 0000000000000000 0000000000000000 000000a0 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA4 .comment 00000012 0000000000000000 0000000000000000 000000a4 2**0 CONTENTS, READONLY5 .note.GNU-stack 00000000 0000000000000000 0000000000000000 000000b6 2**0 CONTENTS, READONLY6 .eh_frame 00000058 0000000000000000 0000000000000000 000000b8 2**3 CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
这样来看的话,目标文件不只之前提到的代码段和数据段,还有存放未初始化变量的BSS段、只读数据段(.rodata)、注释信息段(.comment)和堆栈提示段(.note.GNU-stack)。
Size代表段的大小,File off 代表段所在的位置;
每个段的第二行中的“CONTENTS”、“ALLOC”等表示段的各种属性,比较重要的是“CONTENTS”表示该段在文件中存在,对比上面目标文件的结构,你会发现.bss段没有CONTENTS属性,即.bss段并不会在文件中存在。
有一个专门的命令“size”用来查看ELF文件的代码段、数据段和BSS段的长度(dec表示三个段长度和的十进制,hex表示长度和的十六进制)
$size SimpleSection.otext data bss dec hex filename178 8 4 190 be SimpleSection.o
段的说明
来查看下目标文件SimpleSection.o的段信息:
$objdump -x -s -d SimpleSection.oSimpleSection.o: file format elf64-x86-64SimpleSection.oarchitecture: i386:x86-64, flags 0x00000011:HAS_RELOC, HAS_SYMSstart address 0x0000000000000000Sections:Idx Name Size VMA LMA File off Algn0 .text 00000056 0000000000000000 0000000000000000 00000040 2**2 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE1 .data 00000008 0000000000000000 0000000000000000 00000098 2**2 CONTENTS, ALLOC, LOAD, DATA2 .bss 00000004 0000000000000000 0000000000000000 000000a0 2**2 ALLOC3 .rodata 00000004 0000000000000000 0000000000000000 000000a0 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA4 .comment 00000012 0000000000000000 0000000000000000 000000a4 2**0 CONTENTS, READONLY5 .note.GNU-stack 00000000 0000000000000000 0000000000000000 000000b6 2**0 CONTENTS, READONLY6 .eh_frame 00000058 0000000000000000 0000000000000000 000000b8 2**3 CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATASYMBOL TABLE:0000000000000000 l df *ABS* 0000000000000000 SimpleSection.c0000000000000000 l d .text 0000000000000000 .text0000000000000000 l d .data 0000000000000000 .data0000000000000000 l d .bss 0000000000000000 .bss0000000000000000 l d .rodata 0000000000000000 .rodata0000000000000004 l O .data 0000000000000004 static_var.17130000000000000000 l O .bss 0000000000000004 static_var2.17140000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack0000000000000000 l d .eh_frame 0000000000000000 .eh_frame0000000000000000 l d .comment 0000000000000000 .comment0000000000000000 g O .data 0000000000000004 global_init_var0000000000000004 O *COM* 0000000000000004 global_uninit_var0000000000000000 g F .text 0000000000000021 func10000000000000000 *UND* 0000000000000000 printf0000000000000021 g F .text 0000000000000035 mainContents of section .text:0000 554889e5 4883ec10 897dfc8b 45fc89c6 UH..H....}..E...0010 bf000000 00b80000 0000e800 000000c9 ................0020 c3554889 e54883ec 10c745fc 01000000 .UH..H....E.....0030 8b150000 00008b05 00000000 01c28b45 ...............E0040 fc01c28b 45f801d0 89c7e800 000000b8 ....E...........0050 00000000 c9c3 ......Contents of section .data:0000 54000000 55000000 T...U...Contents of section .rodata:0000 25640a00 %d..Contents of section .comment:0000 00474343 3a202847 4e552920 342e372e .GCC: (GNU) 4.7.0010 3300 3.Contents of section .eh_frame:0000 14000000 00000000 017a5200 01781001 .........zR..x..0010 1b0c0708 90010000 1c000000 1c000000 ................0020 00000000 21000000 00410e10 8602430d ....!....A....C.0030 065c0c07 08000000 1c000000 3c000000 .\..........<...0040 00000000 35000000 00410e10 8602430d ....5....A....C.0050 06700c07 08000000 .p......Disassembly of section .text:0000000000000000 <func1>:0: 55 push %rbp1: 48 89 e5 mov %rsp,%rbp4: 48 83 ec 10 sub $0x10,%rsp8: 89 7d fc mov %edi,-0x4(%rbp)b: 8b 45 fc mov -0x4(%rbp),%eaxe: 89 c6 mov %eax,%esi10: bf 00 00 00 00 mov $0x0,%edi 11: R_X86_64_32 .rodata15: b8 00 00 00 00 mov $0x0,%eax1a: e8 00 00 00 00 callq 1f <func1+0x1f> 1b: R_X86_64_PC32 printf-0x41f: c9 leaveq20: c3 retq0000000000000021 <main>:21: 55 push %rbp22: 48 89 e5 mov %rsp,%rbp25: 48 83 ec 10 sub $0x10,%rsp29: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%rbp)30: 8b 15 00 00 00 00 mov 0x0(%rip),%edx # 36 <main+0x15> 32: R_X86_64_PC32 .data36: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 3c <main+0x1b> 38: R_X86_64_PC32 .bss-0x43c: 01 c2 add %eax,%edx3e: 8b 45 fc mov -0x4(%rbp),%eax41: 01 c2 add %eax,%edx43: 8b 45 f8 mov -0x8(%rbp),%eax46: 01 d0 add %edx,%eax48: 89 c7 mov %eax,%edi4a: e8 00 00 00 00 callq 4f <main+0x2e> 4b: R_X86_64_PC32 func1-0x44f: b8 00 00 00 00 mov $0x0,%eax54: c9 leaveq55: c3 retq
0 0
- [笔记二]探究编译与链接之目标文件
- 编译、链接学习笔记(二)目标文件的构成
- [笔记一]探究编译与链接
- [编译链接装载系列]之聊聊目标文件与ELF格式
- 编译链接之一 目标文件
- 编译链接之一 目标文件
- C语言笔记之头文件与链接(二)
- 程序员的自我修养摘要之二---编译与链接
- 静态链接之目标文件的内容
- 【编译链接】探究编译链接过程
- Web入侵安全测试与对策学习笔记之(二)——获取目标信息之猜测文件与目录
- 编译链接中的-可重定位目标文件
- 编译链接中的-可重定位目标文件
- Android深入探究笔记之十 -- 使用 ContentProvider 共享数据(二),访问与添加通讯录
- Android深入探究笔记之十 -- 使用 ContentProvider 共享数据(二),访问与添加通讯录
- 目标文件的链接
- C语言笔记之头文件与链接(一)
- linux学习笔记之文件处理命令与链接命令
- 欢迎使用CSDN-markdown编辑器
- error: variable '__this_module' has initializer but incomplete type错误解决
- java发送https post请求实例
- Android Java概念、关键词理解应用总结-----/*自己编写*/
- 企业大数据体系图
- [笔记二]探究编译与链接之目标文件
- 暑期第一弹<搜索> E - Find The Multiple(DFS)
- Viewpager的使用简单认识-1
- python学习进阶(一)------学习contents_xml.py
- HDU 2824 The Euler function
- Android Binder机制(二) Binder中的数据结构
- osgi开篇
- Android Volley完全解析(一),初识Volley的基本用法
- Nginx源码分析 - 主流程篇 - 全局变量cycle初始化