目标文件的格式
- 目标文件:源码编译后但还未链接的文件
- 在linux平台下目标文件,可执行文件,动态链接库及静态链接库具有相似的文件结构,统称为ELF文件,在windows平台下是PE-COFF格式
目标文件的构成
ELF文件由文件头、代码段(.text)、数据段(.data)及.bss段,具体作用见下图
未初始化的全局变量和局部静态变量默认值都为0,故没必要放在.data段.bss段只是为未初始化的全局变量和局部静态变量预留位置,并没有内容,在文件中不占用空间(仅需记录预留位置的大小)数据和代码分离的好处
- 权限保护。指令区设置为只读, 数据区可读写
- 提高缓存命中率
- 便于资源分隔与共享
举例&工具
测试代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18int printf(const char *format, ...);
int global_init_var = 84; //.data段
int global_uninit_var;
void func1(int i)
{
printf("%d\n", i);
}
int main(void)
{
static int static_var = 85; //.data段
static int static_var2;
int a = 1;
int b;
func1(static_var + static_var2 + a + b);
return a;
}编译:
gcc -c test.c -o test.o查看段大小:
size test.o查看各段简短信息:
objdump -h test.o查看各段详细信息:
objdump -s -x -d test.o如下.data段存储的
global_init_var和static_var两个值,对应16进制0x54和0x55
1 | Contents of section .data: |
- 使用
objcopy将一个二进制文件写入一个elf文件段内1
objcopy -I binary -O elf64-x86-64 -B i386 test.jpeg test.o
- 在代码中指定变量或函数存储的段
1
2__attribute__((section("FOO"))) int global = 42;
__attribute__((section("BAR"))) void foo(){}