一.GCC编译工具集介绍
1.gcc简介
gcc原指GNU C compiler ,即由GNU开发的C语言编译器,但经过许多年发展后gcc含义变成了GNU C Collection,扩展成了支持多种编程语言的历史上最优秀的编译器。gcc编译工具集则由以下3部分组成:
(1).GCC编译器
gcc-core:即gcc编译器,用于完成预处理和编译过程,把C代码转换成汇编代码。
(2).Binutils工具集
Binutils是gcc内的一组二进制工具集,其包含着许多在开发和调试中常用的工具:
as:汇编器,把汇编语言代码转换为机器码,即目标文件。
ld:链接器,把编译生成的多个目标文件组织成最终的可执行程序文件。
readelf:可用于查看目标文件或可执行程序文件的信息。
objdump:可用于查看目标文件的信息,最主要的作用是反汇编。
objcopy: 可用于目标文件格式转换,如.bin 转换成 .elf 或.elf 转换成 .bin等。
size:可用于查看目标文件不同部分的尺寸和总尺寸,例如代码段大小、数据段大小、使用的静态内存、总大小等。
(3).glibc库
glibc库是GNU组织为GNU系统以及Linux系统编写的C语言标准函数库,在Linux系统下的极大多数C语言函数都依赖此函数库运行。
二.ELF文件介绍
1.准备阶段
众所周知,编译过程分为四个阶段进行,预处理,编译,汇编与连接,下面以基础的hello.c程序进行相关演示
hello.c:
#include<stdio.h>
int main(){
printf("Hell World!\n");
return 0;
}
2.预处理
使用命令:gcc -E hello.c -o hello.i
此时成功生成预处理后的文件hello.i
hello.i文件可作为普通文件点击查看内容,部分代码段如下:
3.编译
预处理后的hello.i文件可直接使用命令生成汇编代码文件。
采用命令:gcc -S hello.i -o hello.s
此时成功生成hello.s文件
hello.s文件也可作为普通文本文件查看其内容,部分代码片段如下:
4.汇编
hello.s文件可通过汇编生成目标文件hello.o,为后面的连接作准备。
采用命令:gcc -c hello.s -o hello.o
此时成功生成目标文件hello.o
5.连接
最后需要将所需目标文件hello.c连接库文件生成可执行ELF文件hello
使用命令:gcc hello.o -o hello
目标文件生成,此时使用命令./hello即可执行可执行文件
6.分析ELF文件
ELF文件格式如图:
在ELF header与Section header table间即为ELF文件的段,通常ELF文件的段分为如下几种:
1.text:已编译程序的指令代码段。
2.rodata:ro,即read-only,代表只读数据。
3.data:已初始化的C程序全局变量和静态局部变量。
4.bss:未初始化的C程序全局变量和静态局部变量。
5.debug:调试符号段。
可采用readelf工具查看elf文件内各段内容,hello文件部分段内容如下:
此外,还可使用objdump工具对elf文件进行反汇编: