1. 源程序与程序的映射
- BSS段:存放未初始化的全局变量或静态变量,Block Started by Symbol;
- DATA段:存放已初始化的变量;
- TEXT段:存放二进制代码。
2. 程序到进程的映射
- 程序代码区:存放函数体二进制代码;
- 常量区:存放常量、字符串等,只读;
- 全局数据区:存放全局变量、静态变量等,可读可写;
- 堆区:存放进程运行中被动态分配的内存段,可动态扩展或缩减;
- 动态链接库:用于在程序运行期间加载和卸载动态链接库;
- 栈区:存放函数的参数值局部变量的值等。
#include<stdio.h>
int s1;
int s2 = 0;
static int s3 = 0;
static int s4 = 4;
int main(void)
{
int s5;
return 0;
}
- 其中s1、s2、s3都是未初始化的全局变量,所以在bss段;
- s4为已初始化的全局变量,所以在data段;
- s5位局部变量,存储在栈中。
3. 使用readelf指令
在Linux中,可以使用readelf指令来查看相应的信息。
ELF的英文全称是The Executable and Linking Format,是Linux的主要可执行文件格式,包含三种:
- 可执行文件(.out)
- 可重定位文件(.o文件)
- 共享目标文件(.so)
gcc -g bss.c -o bss //-g为编译 -o为指定目标名称,gcc默认编译出来的文件为a.out
readrlf -a bss
其中gcc和readelf都有很多的指令,以readelf为例:
- readelf -h:elf header,头文件信息;
- readelf -l:program headers,显示程序头 (段头) 信息;
- readelf -S:section headers,显示节头信息;
- readelf -s:symbols,显示符号表段中的项;
- readelf -r:relocs,显示可重定位段的信息;
- readelf -d:dynamic,显示动态段的信息;
- readelf -V:version-info,显示版本段的信息;
- readelf -A:arch-specific,显示CPU构架信息;
- readelf -I:histogram,显示符号的时候,显示bucket list长度的柱状图;
- readelf -a,all 显示全部信息,等价于 -h -l -S -s -r -d -V -A -I。
头文件信息:
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x400400
Start of program headers: 64 (bytes into file)
Start of section headers: 5200 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 9
Size of section headers: 64 (bytes)
Number of section headers: 35
Section header string table index: 32
可以看到Number of section headers为35,从文件地址5200开始,每个Section Header占64字节,文件开头第一个字节的地址是0x400400。
节头信息:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 0000000000400238 00000238
000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.ABI-tag NOTE 0000000000400254 00000254
0000000000000020 0000000000000000 A 0 0 4
[ 3] .note.gnu.build-i NOTE 0000000000400274 00000274
0000000000000024 0000000000000000 A 0 0 4
[ 4] .gnu.hash GNU_HASH 0000000000400298 00000298
000000000000001c 0000000000000000 A 5 0 8
[ 5] .dynsym DYNSYM 00000000004002b8 000002b8
0000000000000048 0000000000000018 A 6 1 8
[ 6] .dynstr STRTAB 0000000000400300 00000300
0000000000000038 0000000000000000 A 0 0 1
[ 7] .gnu.version VERSYM 0000000000400338 00000338
0000000000000006 0000000000000002 A 5 0 2
[ 8] .gnu.version_r VERNEED 0000000000400340 00000340
0000000000000020 0000000000000000 A 6 1 8
[ 9] .rela.dyn RELA 0000000000400360 00000360
0000000000000018 0000000000000018 A 5 0 8
[10] .rela.plt RELA 0000000000400378 00000378
0000000000000030 0000000000000018 A 5 12 8
[11] .init PROGBITS 00000000004003a8 000003a8
000000000000001a 0000000000000000 AX 0 0 4
[12] .plt PROGBITS 00000000004003d0 000003d0
0000000000000030 0000000000000010 AX 0 0 16
[13] .text PROGBITS 0000000000400400 00000400 // 代码区
0000000000000172 0000000000000000 AX 0 0 16
[14] .fini PROGBITS 0000000000400574 00000574
0000000000000009 0000000000000000 AX 0 0 4
[15] .rodata PROGBITS 0000000000400580 00000580 // 常量区
0000000000000004 0000000000000004 AM 0 0 4
[16] .eh_frame_hdr PROGBITS 0000000000400584 00000584
0000000000000034 0000000000000000 A 0 0 4
[17] .eh_frame PROGBITS 00000000004005b8 000005b8
00000000000000f4 0000000000000000 A 0 0 8
[18] .init_array INIT_ARRAY 0000000000600e10 00000e10
0000000000000008 0000000000000000 WA 0 0 8
[19] .fini_array FINI_ARRAY 0000000000600e18 00000e18
0000000000000008 0000000000000000 WA 0 0 8
[20] .jcr PROGBITS 0000000000600e20 00000e20
0000000000000008 0000000000000000 WA 0 0 8
[21] .dynamic DYNAMIC 0000000000600e28 00000e28
00000000000001d0 0000000000000010 WA 6 0 8
[22] .got PROGBITS 0000000000600ff8 00000ff8
0000000000000008 0000000000000008 WA 0 0 8
[23] .got.plt PROGBITS 0000000000601000 00001000
0000000000000028 0000000000000008 WA 0 0 8
[24] .data PROGBITS 0000000000601028 00001028 // 已初始化变量
0000000000000014 0000000000000000 WA 0 0 8
[25] .bss NOBITS 000000000060103c 0000103c // 未初始化变量
0000000000000014 0000000000000000 WA 0 0 4
[26] .comment PROGBITS 0000000000000000 0000103c
0000000000000056 0000000000000001 MS 0 0 1
[27] .debug_aranges PROGBITS 0000000000000000 00001092
0000000000000030 0000000000000000 0 0 1
[28] .debug_info PROGBITS 0000000000000000 000010c2
00000000000000f0 0000000000000000 0 0 1
[29] .debug_abbrev PROGBITS 0000000000000000 000011b2
0000000000000073 0000000000000000 0 0 1
[30] .debug_line PROGBITS 0000000000000000 00001225
0000000000000039 0000000000000000 0 0 1
[31] .debug_str PROGBITS 0000000000000000 0000125e
00000000000000a8 0000000000000001 MS 0 0 1
[32] .shstrtab STRTAB 0000000000000000 00001306
0000000000000148 0000000000000000 0 0 1
[33] .symtab SYMTAB 0000000000000000 00001d10
00000000000006d8 0000000000000018 34 52 8
[34] .strtab STRTAB 0000000000000000 000023e8
000000000000022f 0000000000000000 0 0 1
符号表段中的项:
Symbol table '.symtab' contains 73 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000400238 0 SECTION LOCAL DEFAULT 1
2: 0000000000400254 0 SECTION LOCAL DEFAULT 2
3: 0000000000400274 0 SECTION LOCAL DEFAULT 3
4: 0000000000400298 0 SECTION LOCAL DEFAULT 4
5: 00000000004002b8 0 SECTION LOCAL DEFAULT 5
6: 0000000000400300 0 SECTION LOCAL DEFAULT 6
7: 0000000000400338 0 SECTION LOCAL DEFAULT 7
8: 0000000000400340 0 SECTION LOCAL DEFAULT 8
9: 0000000000400360 0 SECTION LOCAL DEFAULT 9
10: 0000000000400378 0 SECTION LOCAL DEFAULT 10
11: 00000000004003a8 0 SECTION LOCAL DEFAULT 11
12: 00000000004003d0 0 SECTION LOCAL DEFAULT 12
13: 0000000000400400 0 SECTION LOCAL DEFAULT 13
14: 0000000000400574 0 SECTION LOCAL DEFAULT 14
15: 0000000000400580 0 SECTION LOCAL DEFAULT 15
16: 0000000000400584 0 SECTION LOCAL DEFAULT 16
17: 00000000004005b8 0 SECTION LOCAL DEFAULT 17
18: 0000000000600e10 0 SECTION LOCAL DEFAULT 18
19: 0000000000600e18 0 SECTION LOCAL DEFAULT 19
20: 0000000000600e20 0 SECTION LOCAL DEFAULT 20
21: 0000000000600e28 0 SECTION LOCAL DEFAULT 21
22: 0000000000600ff8 0 SECTION LOCAL DEFAULT 22
23: 0000000000601000 0 SECTION LOCAL DEFAULT 23
24: 0000000000601028 0 SECTION LOCAL DEFAULT 24
25: 000000000060103c 0 SECTION LOCAL DEFAULT 25
26: 0000000000000000 0 SECTION LOCAL DEFAULT 26
27: 0000000000000000 0 SECTION LOCAL DEFAULT 27
28: 0000000000000000 0 SECTION LOCAL DEFAULT 28
29: 0000000000000000 0 SECTION LOCAL DEFAULT 29
30: 0000000000000000 0 SECTION LOCAL DEFAULT 30
31: 0000000000000000 0 SECTION LOCAL DEFAULT 31
32: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
33: 0000000000600e20 0 OBJECT LOCAL DEFAULT 20 __JCR_LIST__
34: 0000000000400430 0 FUNC LOCAL DEFAULT 13 deregister_tm_clones
35: 0000000000400460 0 FUNC LOCAL DEFAULT 13 register_tm_clones
36: 00000000004004a0 0 FUNC LOCAL DEFAULT 13 __do_global_dtors_aux
37: 000000000060103c 1 OBJECT LOCAL DEFAULT 25 completed.6982
38: 0000000000600e18 0 OBJECT LOCAL DEFAULT 19 __do_global_dtors_aux_fin
39: 00000000004004c0 0 FUNC LOCAL DEFAULT 13 frame_dummy
40: 0000000000600e10 0 OBJECT LOCAL DEFAULT 18 __frame_dummy_init_array_
41: 0000000000000000 0 FILE LOCAL DEFAULT ABS bss.c
42: 0000000000601044 4 OBJECT LOCAL DEFAULT 25 s3
43: 0000000000601038 4 OBJECT LOCAL DEFAULT 24 s4
44: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
45: 00000000004006a8 0 OBJECT LOCAL DEFAULT 17 __FRAME_END__
46: 0000000000600e20 0 OBJECT LOCAL DEFAULT 20 __JCR_END__
47: 0000000000000000 0 FILE LOCAL DEFAULT ABS
48: 0000000000600e18 0 NOTYPE LOCAL DEFAULT 18 __init_array_end
49: 0000000000600e28 0 OBJECT LOCAL DEFAULT 21 _DYNAMIC
50: 0000000000600e10 0 NOTYPE LOCAL DEFAULT 18 __init_array_start
51: 0000000000601000 0 OBJECT LOCAL DEFAULT 23 _GLOBAL_OFFSET_TABLE_
52: 0000000000400570 2 FUNC GLOBAL DEFAULT 13 __libc_csu_fini
53: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab
54: 0000000000601028 0 NOTYPE WEAK DEFAULT 24 data_start
55: 0000000000601040 4 OBJECT GLOBAL DEFAULT 25 s2
56: 000000000060103c 0 NOTYPE GLOBAL DEFAULT 24 _edata
57: 0000000000400574 0 FUNC GLOBAL DEFAULT 14 _fini
58: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_
59: 0000000000601028 0 NOTYPE GLOBAL DEFAULT 24 __data_start
60: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
61: 0000000000601030 0 OBJECT GLOBAL HIDDEN 24 __dso_handle
62: 0000000000400580 4 OBJECT GLOBAL DEFAULT 15 _IO_stdin_used
63: 0000000000400500 101 FUNC GLOBAL DEFAULT 13 __libc_csu_init
64: 0000000000601050 0 NOTYPE GLOBAL DEFAULT 25 _end
65: 0000000000400400 0 FUNC GLOBAL DEFAULT 13 _start
66: 0000000000601048 4 OBJECT GLOBAL DEFAULT 25 s1
67: 000000000060103c 0 NOTYPE GLOBAL DEFAULT 25 __bss_start
68: 00000000004004ed 11 FUNC GLOBAL DEFAULT 13 main
69: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
70: 0000000000601040 0 OBJECT GLOBAL HIDDEN 24 __TMC_END__
71: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
72: 00000000004003a8 0 FUNC GLOBAL DEFAULT 11 _init
截取我们需要的四条信息:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
......
[13] .text PROGBITS 0000000000400400 00000400
0000000000000172 0000000000000000 AX 0 0 16
......
[15] .rodata PROGBITS 0000000000400580 00000580
0000000000000004 0000000000000004 AM 0 0 4
......
[24] .data PROGBITS 0000000000601028 00001028
0000000000000014 0000000000000000 WA 0 0 8
[25] .bss NOBITS 000000000060103c 0000103c
0000000000000014 0000000000000000 WA 0 0 4
......
Num: Value Size Type Bind Vis Ndx Name
......
42: 0000000000601044 4 OBJECT LOCAL DEFAULT 25 s3
43: 0000000000601038 4 OBJECT LOCAL DEFAULT 24 s4
......
55: 0000000000601040 4 OBJECT GLOBAL DEFAULT 25 s2
......
66: 0000000000601048 4 OBJECT GLOBAL DEFAULT 25 s1
#include<stdio.h>
int s1;
int s2 = 0;
static int s3 = 0;
static int s4 = 4;
int main(void)
{
int s5;
return 0;
}
- s1:未初始化变量,是一个GLOBAL符号,地址为0000000000601048,从Section Headers可以看到这个地址位于bss段;
- s2:未初始化变量,是一个GLOBAL符号,地址为0000000000601040,从Section Headers可以看到这个地址位于bss段;
- s3:未初始化变量,但是被static修饰,所以为LOCAL,地址为0000000000601044,从Section Headers可以看到这个地址位于bss段;
- s4:初始化变量,但是被static修饰,所以为LOCAL,地址为0000000000601038,从Section Headers可以看到这个地址位于data段。