读书-程序员的自我修养-链接、封装与库(6: 第三章:目标文件里有什么(1)目标文件,objdump,file,size等命令)

1. 什么是目标文件?

1.1 目标文件

目标文件: 就是源代码编译之后未进行链接的那些中间文件(.obj和.o)。
目标文件从结构上说,他是已经编译后的可执行文件格式,只是还没有经过链接的过程。其中可能有些符号或者地址还没有被调整。

1.2 PE、ELF、COFF

PE、ELF: 现在PC下的可执行文件格式(Executable)主要是windows下的PE(Portable)和linux下的ELF(Executable Linkable Format)

COFF:(Common file format),COFF是Unix提出的并且使用的格式规范,后来微软基于COFF定制了PE;后面System V在COFF基础上引入了ELF格式。所以他们如此相似。

注: 其中动态链接库和静态链接库都是按照可执行文件格式存储的。
其中,静态链接库是把很多目标文件捆绑在一起形成一个文件,再加上一些索引。
可以把它理解为一个包含很多目标文件的文件包。

2. 目标文件是什么样?

2.1 simple.c 代码

root@ubuntu-admin-a1:/home# cat simple.c

#include<stdio.h>

int g_init_var = 100;
int g_uinit_var;

void func1(int i)
{
	printf("%d\n",i);
}

int main()
{
	static int iStaticVar = 101;
	static int iStaticVar2;
	
	int a = 1;
	int b;
	func1(iStaticVar + iStaticVar2 + a + b);
	return 0;
}

2.2 simple.c 各个时期的文件类型,file 命令

gcc -E simple.c -o simple.i
gcc -S simple.i -o simple.s
gcc -c simple.s -o simple.o
gcc simple.c -o simple

file命令是用来检测并显示文件类型

root@ubuntu-admin-a1:/home# file simple.c
simple.c: C source, ASCII text
root@ubuntu-admin-a1:/home# file simple.i
simple.i: C source, ASCII text
root@ubuntu-admin-a1:/home# file simple.s
simple.s: assembler source, ASCII text
root@ubuntu-admin-a1:/home# file simple.o
simple.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
root@ubuntu-admin-a1:/home# file simple
simple: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=279476da281567f4e1fef5d790f133516d498bbd, not stripped
root@ubuntu-admin-a1:/home# ./simple
102

2.3 图解 simple.c 代码目标文件字段

在这里插入图片描述
总体来说,程序源代码被编译以后主要分成两种段:程序指令和程序数据。
代码段属于程序指令,而数据段和.bss段属于程序数据。

2.4 数据和指令分段的好处

  1. 程序被装载后,分别被映射到两个虚存区域;防止改写;
  2. 提高CPU缓存效率;
  3. 内存中只需要保存一份该程序部分;共享指令;

2.5 objdump -h simple.o

2.5.1 objdump命令

readelf 和 objdump 例子详解及区别
参考我的博客:
https://blog.csdn.net/lqy971966/article/details/106905237

  1. objdump命令是用查看目标文件或者可执行的目标文件的构成的gcc工具
  2. 参数:-h
    –section-headers
    –headers
    显示目标文件各个section的头部摘要信息。
  3. 参数:–d
    –disassemble
    从objfile中反汇编那些特定指令机器码的section。
  4. 参数: -s
    –full-contents
    显示指定section的完整内容。以十六进制打印出来
  5. -x
    –all-headers
    显示所可用的头信息,包括符号表、重定位入口。-x 等价于-a -f -h -r -t 同时指定。

2.5.2 objdump -h simple.o

root@ubuntu-admin-a1:/home# objdump -h simple.o

simple.o:     file format elf64-x86-64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
0 .text         00000057  0000000000000000  0000000000000000  00000040  2**0
				CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data         00000008  0000000000000000  0000000000000000  00000098  2**2
				CONTENTS, ALLOC, LOAD, DATA
2 .bss          00000004  0000000000000000  0000000000000000  000000a0  2**2
				ALLOC
3 .rodata       00000004  0000000000000000  0000000000000000  000000a0  2**0
				CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .comment      00000035  0000000000000000  0000000000000000  000000a4  2**0
				CONTENTS, READONLY
5 .note.GNU-stack 00000000  0000000000000000  0000000000000000  000000d9  2**0
				CONTENTS, READONLY
6 .eh_frame     00000058  0000000000000000  0000000000000000  000000e0  2**3
				CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
root@ubuntu-admin-a1:/home#

由上可知,目标文件里面包含:
.text 代码段
.data 数据段
.bss 未初始化的数据段
.rodata 只读数据段
.comment 注释段
.note.GNU 堆栈提示段

2.5.3 simple.o的ELF结构图

在这里插入图片描述

2.5.4 size命令 simple.o //查看各个段的长度

size命令:显示一个目标文件或者链接库文件中的目标文件的各个段的大小

root@ubuntu-admin-a1:/home# size simple.o
text	 data	 bss	dec	    hex	filename
179	      8	      4	    191	     bf	simple.o
root@ubuntu-admin-a1:/home# 

2.5.5 objdump -s -d simple.o

root@ubuntu-admin-a1:/home# objdump -s -d simple.o

simple.o:     file format elf64-x86-64

Contents of section .text:
0000 554889e5 4883ec10 897dfc8b 45fc89c6  UH..H....}..E...
0010 bf000000 00b80000 0000e800 00000090  ................
0020 c9c35548 89e54883 ec10c745 f8010000  ..UH..H....E....
0030 008b1500 0000008b 05000000 0001c28b  ................
0040 45f801c2 8b45fc01 d089c7e8 00000000  E....E..........
0050 b8000000 00c9c3                      .......         
Contents of section .data:
0000 64000000 65000000                    d...e...        
Contents of section .rodata:
0000 25640a00                             %d..            
Contents of section .comment:
0000 00474343 3a202855 62756e74 7520352e  .GCC: (Ubuntu 5.
0010 342e302d 36756275 6e747531 7e31362e  4.0-6ubuntu1~16.
0020 30342e34 2920352e 342e3020 32303136  04.4) 5.4.0 2016
0030 30363039 00                          0609.           
Contents of section .eh_frame:
0000 14000000 00000000 017a5200 01781001  .........zR..x..
0010 1b0c0708 90010000 1c000000 1c000000  ................
0020 00000000 22000000 00410e10 8602430d  ...."....A....C.
0030 065d0c07 08000000 1c000000 3c000000  .]..........<...
0040 00000000 35000000 00410e10 8602430d  ....5....A....C.
0050 06700c07 08000000                    .p......        

Disassembly of section .text:

0000000000000000 <func1>:
0:	55                   	push   %rbp
1:	48 89 e5             	mov    %rsp,%rbp
4:	48 83 ec 10          	sub    $0x10,%rsp
8:	89 7d fc             	mov    %edi,-0x4(%rbp)
b:	8b 45 fc             	mov    -0x4(%rbp),%eax
e:	89 c6                	mov    %eax,%esi
10:	bf 00 00 00 00       	mov    $0x0,%edi
15:	b8 00 00 00 00       	mov    $0x0,%eax
1a:	e8 00 00 00 00       	callq  1f <func1+0x1f>
1f:	90                   	nop
20:	c9                   	leaveq 
21:	c3                   	retq   

0000000000000022 <main>:
22:	55                   	push   %rbp
23:	48 89 e5             	mov    %rsp,%rbp
26:	48 83 ec 10          	sub    $0x10,%rsp
2a:	c7 45 f8 01 00 00 00 	movl   $0x1,-0x8(%rbp)
31:	8b 15 00 00 00 00    	mov    0x0(%rip),%edx        # 37 <main+0x15>
37:	8b 05 00 00 00 00    	mov    0x0(%rip),%eax        # 3d <main+0x1b>
3d:	01 c2                	add    %eax,%edx
3f:	8b 45 f8             	mov    -0x8(%rbp),%eax
42:	01 c2                	add    %eax,%edx
44:	8b 45 fc             	mov    -0x4(%rbp),%eax
47:	01 d0                	add    %edx,%eax
49:	89 c7                	mov    %eax,%edi
4b:	e8 00 00 00 00       	callq  50 <main+0x2e>
50:	b8 00 00 00 00       	mov    $0x0,%eax
55:	c9                   	leaveq 
56:	c3                   	retq   
root@ubuntu-admin-a1:/home#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值