第一个程序
”hello world
“出自祖师爷那本K&R、它是所有程序员的必敲代码,我的第一个程序是用vc++6.0敲得hello world,当时什么也不懂,胡乱照着敲,error
比行数都多,真是嘤嘤嘤了;
hello world包含的意义也绝不仅仅是这短短6行这么简单;
#include <stdio.h>
int main(void)
{
printf("Hello world!\n");
return 0;
}
return 0
这六行存在争议的就是第五行了,为什么要返回0?为什么不是一二三四五六七八九?
这里就不得不提到一个shell命令了
#echo $?
查看上一步执行任务是否成功
如果为0则代表成功、如果不为0表示失败。
比如执行一个不存在的命令
#haha
返回的是127;
执行hello
返回的是0,当然,这个0是我自己在hello.c源程序中写的
如果把源程第五行序改为return 127
呢?
编译执行:
可以看到程序明明运行成功了,但是返回的却不是0,这就可以理解了,返回值是程序员自己设定的、而Linux的程序都是约定认为返回0代表程序运行成功的。
在/usr/include/stdlib.h可以看到这样的宏
定义了0 为成功的退出状态。
主函数也可以不用返回值,网上说会由垃圾值,所以我删掉返回重新编译了,执行了十次左右,未见垃圾值:
所以,即使写了int main(),
主函数也可以不返回值。
一个程序从无到有再到运行它过程往往需要如下几步:编辑
、编译
(预处理、翻译、汇编、链接。最终生成二进制目标文件)、运行
。
windows下都习惯了靠编译器为我们除了编码意外做所有的事情,到了Linux环境如何更好的了解程序编辑、编译、运行的机制呢?
let‘s go
编辑
使用vim新建hello.c文件
#vim hello.c
插入hello world代码
编译之 预处理
预处理器是编译过程中单独执行的第一个步骤。使用#include的行在编译的第一个阶段被替换成了所包含的文件,其中”“和<>的区别:”“在源文件所在位置找,如果找不到就去系统目录中查找,而<>直接到系统目录下查找头文件。
由于hello 程序过于短小精悍,所以往往手动使用gcc编译即可了,但是,对于平时编程来说,一个工程往往有很多的源文件、头文件,手动敲就变得耗时耗力且出错率低,所以,编写makefile文件变得十分必要了。
在当前文件夹中新建makefile文件
#vim makefile
由于需要得到预处理文件,所以插入一个规则,并重定向到一个.i文件中去
inc:
gcc -E hello.c>hello.i
make
#make inc
查看下当前目录文件
#ls
查看.i文件
#cat hello.i
文件中果然包含了其他内容,这就是include的内容,所以,第一个步骤预处理完成。
编译之 翻译
这个阶段编译器将预处理过的文本翻译成汇编程序hello.s
将这个步骤添加到makefile
exc:
gcc -S hello.i -o hello.s
执行
#make exc
查看下这个翻译出来的文件
.file "hello.c"
.text
.section .rodata
.LC0:
.string "Hello world!"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
leaq .LC0(%rip), %rdi
call puts@PLT
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Debian 8.3.0-6) 8.3.0"
.section .note.GNU-stack,"",@progbits
编译之 汇编
makefile中加入
asm:
gcc -c hello.s -o hello.o
执行make
#make asm
如果想要查看这个编译出来的.o文件,也很方便,Linux提供了readelf程序来查看二进制文件,因为此时这个.o文件是汇编编译出来的,距离可执行文件只差一步链接啦,所以使用readelf也可以打开;
#readelf -a hello.o
其内容为:
ELF 头:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
类别: ELF64
数据: 2 补码,小端序 (little endian)
版本: 1 (current)
OS/ABI: UNIX - System V
ABI 版本: 0
类型: REL (可重定位文件)
系统架构: Advanced Micro Devices X86-64
版本: 0x1
入口点地址: 0x0
程序头起点: 0 (bytes into file)
Start of section headers: 704 (bytes into file)
标志: 0x0
本头的大小: 64 (字节)
程序头大小: 0 (字节)
Number of program headers: 0
节头大小: 64 (字节)
节头数量: 13
字符串表索引节头: 12
节头:
[号] 名称 类型 地址 偏移量
大小 全体大小 旗标 链接 信息 对齐
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000000000000 00000040
0000000000000017 0000000000000000 AX 0 0 1
[ 2] .rela.text RELA 0000000000000000 00000210
0000000000000030 0000000000000018 I 10 1 8
[ 3] .data PROGBITS 0000000000000000 00000057
0000000000000000 0000000000000000 WA 0 0 1
[ 4] .bss NOBITS 0000000000000000 00000057
0000000000000000 0000000000000000 WA 0 0 1
[ 5] .rodata PROGBITS 0000000000000000 00000057
000000000000000d 0000000000000000 A 0 0 1
[ 6] .comment PROGBITS 0000000000000000 00000064
000000000000001d 0000000000000001 MS 0 0 1
[ 7] .note.GNU-stack PROGBITS 0000000000000000 00000081
0000000000000000 0000000000000000 0 0 1
[ 8] .eh_frame PROGBITS 0000000000000000 00000088
0000000000000038 0000000000000000 A 0 0 8
[ 9] .rela.eh_frame RELA 0000000000000000 00000240
0000000000000018 0000000000000018 I 10 8 8
[10] .symtab SYMTAB 0000000000000000 000000c0
0000000000000120 0000000000000018 11 9 8
[11] .strtab STRTAB 0000000000000000 000001e0
0000000000000029 0000000000000000 0 0 1
[12] .shstrtab STRTAB 0000000000000000 00000258
0000000000000061 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
l (large), p (processor specific)
There are no section groups in this file.
本文件中没有程序头。
There is no dynamic section in this file.
重定位节 '.rela.text' at offset 0x210 contains 2 entries:
偏移量 信息 类型 符号值 符号名称 + 加数
000000000007 000500000002 R_X86_64_PC32 0000000000000000 .rodata - 4
00000000000c 000b00000004 R_X86_64_PLT32 0000000000000000 puts - 4
重定位节 '.rela.eh_frame' at offset 0x240 contains 1 entry:
偏移量 信息 类型 符号值 符号名称 + 加数
000000000020 000200000002 R_X86_64_PC32 0000000000000000 .text + 0
The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
Symbol table '.symtab' contains 12 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS hello.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 SECTION LOCAL DEFAULT 4
5: 0000000000000000 0 SECTION LOCAL DEFAULT 5
6: 0000000000000000 0 SECTION LOCAL DEFAULT 7
7: 0000000000000000 0 SECTION LOCAL DEFAULT 8
8: 0000000000000000 0 SECTION LOCAL DEFAULT 6
9: 0000000000000000 23 FUNC GLOBAL DEFAULT 1 main
10: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _GLOBAL_OFFSET_TABLE_
11: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND puts
编译之 链接
最后一步 链接 ,在makefile中加入
link:
gcc hell.o -o hello
执行!
#make link
查看目录文件
#ls
绿色的hello就是由hello.c一步一步编译出来的可执行程序啦,
#./hello
让这一串出现在屏幕上实属不易。
查看ELF
Linux下可执行的二进制文件一般为ELF格式,查看下hello:
#readelf -a hello
内容
ELF 头:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
类别: ELF64
数据: 2 补码,小端序 (little endian)
版本: 1 (current)
OS/ABI: UNIX - System V
ABI 版本: 0
类型: DYN (共享目标文件)
系统架构: Advanced Micro Devices X86-64
版本: 0x1
入口点地址: 0x1050
程序头起点: 64 (bytes into file)
Start of section headers: 14688 (bytes into file)
标志: 0x0
本头的大小: 64 (字节)
程序头大小: 56 (字节)
Number of program headers: 11
节头大小: 64 (字节)
节头数量: 30
字符串表索引节头: 29
节头:
[号] 名称 类型 地址 偏移量
大小 全体大小 旗标 链接 信息 对齐
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 00000000000002a8 000002a8
000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.ABI-tag NOTE 00000000000002c4 000002c4
0000000000000020 0000000000000000 A 0 0 4
[ 3] .note.gnu.build-i NOTE 00000000000002e4 000002e4
0000000000000024 0000000000000000 A 0 0 4
[ 4] .gnu.hash GNU_HASH 0000000000000308 00000308
0000000000000024 0000000000000000 A 5 0 8
[ 5] .dynsym DYNSYM 0000000000000330 00000330
00000000000000a8 0000000000000018 A 6 1 8
[ 6] .dynstr STRTAB 00000000000003d8 000003d8
0000000000000082 0000000000000000 A 0 0 1
[ 7] .gnu.version VERSYM 000000000000045a 0000045a
000000000000000e 0000000000000002 A 5 0 2
[ 8] .gnu.version_r VERNEED 0000000000000468 00000468
0000000000000020 0000000000000000 A 6 1 8
[ 9] .rela.dyn RELA 0000000000000488 00000488
00000000000000c0 0000000000000018 A 5 0 8
[10] .rela.plt RELA 0000000000000548 00000548
0000000000000018 0000000000000018 AI 5 23 8
[11] .init PROGBITS 0000000000001000 00001000
0000000000000017 0000000000000000 AX 0 0 4
[12] .plt PROGBITS 0000000000001020 00001020
0000000000000020 0000000000000010 AX 0 0 16
[13] .plt.got PROGBITS 0000000000001040 00001040
0000000000000008 0000000000000008 AX 0 0 8
[14] .text PROGBITS 0000000000001050 00001050
0000000000000161 0000000000000000 AX 0 0 16
[15] .fini PROGBITS 00000000000011b4 000011b4
0000000000000009 0000000000000000 AX 0 0 4
[16] .rodata PROGBITS 0000000000002000 00002000
0000000000000011 0000000000000000 A 0 0 4
[17] .eh_frame_hdr PROGBITS 0000000000002014 00002014
000000000000003c 0000000000000000 A 0 0 4
[18] .eh_frame PROGBITS 0000000000002050 00002050
0000000000000108 0000000000000000 A 0 0 8
[19] .init_array INIT_ARRAY 0000000000003de8 00002de8
0000000000000008 0000000000000008 WA 0 0 8
[20] .fini_array FINI_ARRAY 0000000000003df0 00002df0
0000000000000008 0000000000000008 WA 0 0 8
[21] .dynamic DYNAMIC 0000000000003df8 00002df8
00000000000001e0 0000000000000010 WA 6 0 8
[22] .got PROGBITS 0000000000003fd8 00002fd8
0000000000000028 0000000000000008 WA 0 0 8
[23] .got.plt PROGBITS 0000000000004000 00003000
0000000000000020 0000000000000008 WA 0 0 8
[24] .data PROGBITS 0000000000004020 00003020
0000000000000010 0000000000000000 WA 0 0 8
[25] .bss NOBITS 0000000000004030 00003030
0000000000000008 0000000000000000 WA 0 0 1
[26] .comment PROGBITS 0000000000000000 00003030
000000000000001c 0000000000000001 MS 0 0 1
[27] .symtab SYMTAB 0000000000000000 00003050
0000000000000600 0000000000000018 28 45 8
[28] .strtab STRTAB 0000000000000000 00003650
0000000000000203 0000000000000000 0 0 1
[29] .shstrtab STRTAB 0000000000000000 00003853
0000000000000107 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
l (large), p (processor specific)
There are no section groups in this file.
程序头:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
0x0000000000000268 0x0000000000000268 R 0x8
INTERP 0x00000000000002a8 0x00000000000002a8 0x00000000000002a8
0x000000000000001c 0x000000000000001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000560 0x0000000000000560 R 0x1000
LOAD 0x0000000000001000 0x0000000000001000 0x0000000000001000
0x00000000000001bd 0x00000000000001bd R E 0x1000
LOAD 0x0000000000002000 0x0000000000002000 0x0000000000002000
0x0000000000000158 0x0000000000000158 R 0x1000
LOAD 0x0000000000002de8 0x0000000000003de8 0x0000000000003de8
0x0000000000000248 0x0000000000000250 RW 0x1000
DYNAMIC 0x0000000000002df8 0x0000000000003df8 0x0000000000003df8
0x00000000000001e0 0x00000000000001e0 RW 0x8
NOTE 0x00000000000002c4 0x00000000000002c4 0x00000000000002c4
0x0000000000000044 0x0000000000000044 R 0x4
GNU_EH_FRAME 0x0000000000002014 0x0000000000002014 0x0000000000002014
0x000000000000003c 0x000000000000003c R 0x4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x10
GNU_RELRO 0x0000000000002de8 0x0000000000003de8 0x0000000000003de8
0x0000000000000218 0x0000000000000218 R 0x1
Section to Segment mapping:
段节...
00
01 .interp
02 .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt
03 .init .plt .plt.got .text .fini
04 .rodata .eh_frame_hdr .eh_frame
05 .init_array .fini_array .dynamic .got .got.plt .data .bss
06 .dynamic
07 .note.ABI-tag .note.gnu.build-id
08 .eh_frame_hdr
09
10 .init_array .fini_array .dynamic .got
Dynamic section at offset 0x2df8 contains 26 entries:
标记 类型 名称/值
0x0000000000000001 (NEEDED) 共享库:[libc.so.6]
0x000000000000000c (INIT) 0x1000
0x000000000000000d (FINI) 0x11b4
0x0000000000000019 (INIT_ARRAY) 0x3de8
0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
0x000000000000001a (FINI_ARRAY) 0x3df0
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x308
0x0000000000000005 (STRTAB) 0x3d8
0x0000000000000006 (SYMTAB) 0x330
0x000000000000000a (STRSZ) 130 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x4000
0x0000000000000002 (PLTRELSZ) 24 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x548
0x0000000000000007 (RELA) 0x488
0x0000000000000008 (RELASZ) 192 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffffb (FLAGS_1) 标志: PIE
0x000000006ffffffe (VERNEED) 0x468
0x000000006fffffff (VERNEEDNUM) 1
0x000000006ffffff0 (VERSYM) 0x45a
0x000000006ffffff9 (RELACOUNT) 3
0x0000000000000000 (NULL) 0x0
重定位节 '.rela.dyn' at offset 0x488 contains 8 entries:
偏移量 信息 类型 符号值 符号名称 + 加数
000000003de8 000000000008 R_X86_64_RELATIVE 1130
000000003df0 000000000008 R_X86_64_RELATIVE 10f0
000000004028 000000000008 R_X86_64_RELATIVE 4028
000000003fd8 000100000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_deregisterTMClone + 0
000000003fe0 000300000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.2.5 + 0
000000003fe8 000400000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
000000003ff0 000500000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_registerTMCloneTa + 0
000000003ff8 000600000006 R_X86_64_GLOB_DAT 0000000000000000 __cxa_finalize@GLIBC_2.2.5 + 0
重定位节 '.rela.plt' at offset 0x548 contains 1 entry:
偏移量 信息 类型 符号值 符号名称 + 加数
000000004018 000200000007 R_X86_64_JUMP_SLO 0000000000000000 puts@GLIBC_2.2.5 + 0
The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
Symbol table '.dynsym' contains 7 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.2.5 (2)
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
5: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
6: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.2.5 (2)
Symbol table '.symtab' contains 64 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000000002a8 0 SECTION LOCAL DEFAULT 1
2: 00000000000002c4 0 SECTION LOCAL DEFAULT 2
3: 00000000000002e4 0 SECTION LOCAL DEFAULT 3
4: 0000000000000308 0 SECTION LOCAL DEFAULT 4
5: 0000000000000330 0 SECTION LOCAL DEFAULT 5
6: 00000000000003d8 0 SECTION LOCAL DEFAULT 6
7: 000000000000045a 0 SECTION LOCAL DEFAULT 7
8: 0000000000000468 0 SECTION LOCAL DEFAULT 8
9: 0000000000000488 0 SECTION LOCAL DEFAULT 9
10: 0000000000000548 0 SECTION LOCAL DEFAULT 10
11: 0000000000001000 0 SECTION LOCAL DEFAULT 11
12: 0000000000001020 0 SECTION LOCAL DEFAULT 12
13: 0000000000001040 0 SECTION LOCAL DEFAULT 13
14: 0000000000001050 0 SECTION LOCAL DEFAULT 14
15: 00000000000011b4 0 SECTION LOCAL DEFAULT 15
16: 0000000000002000 0 SECTION LOCAL DEFAULT 16
17: 0000000000002014 0 SECTION LOCAL DEFAULT 17
18: 0000000000002050 0 SECTION LOCAL DEFAULT 18
19: 0000000000003de8 0 SECTION LOCAL DEFAULT 19
20: 0000000000003df0 0 SECTION LOCAL DEFAULT 20
21: 0000000000003df8 0 SECTION LOCAL DEFAULT 21
22: 0000000000003fd8 0 SECTION LOCAL DEFAULT 22
23: 0000000000004000 0 SECTION LOCAL DEFAULT 23
24: 0000000000004020 0 SECTION LOCAL DEFAULT 24
25: 0000000000004030 0 SECTION LOCAL DEFAULT 25
26: 0000000000000000 0 SECTION LOCAL DEFAULT 26
27: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
28: 0000000000001080 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
29: 00000000000010b0 0 FUNC LOCAL DEFAULT 14 register_tm_clones
30: 00000000000010f0 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
31: 0000000000004030 1 OBJECT LOCAL DEFAULT 25 completed.7325
32: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __do_global_dtors_aux_fin
33: 0000000000001130 0 FUNC LOCAL DEFAULT 14 frame_dummy
34: 0000000000003de8 0 OBJECT LOCAL DEFAULT 19 __frame_dummy_init_array_
35: 0000000000000000 0 FILE LOCAL DEFAULT ABS hello.c
36: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
37: 0000000000002154 0 OBJECT LOCAL DEFAULT 18 __FRAME_END__
38: 0000000000000000 0 FILE LOCAL DEFAULT ABS
39: 0000000000003df0 0 NOTYPE LOCAL DEFAULT 19 __init_array_end
40: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 _DYNAMIC
41: 0000000000003de8 0 NOTYPE LOCAL DEFAULT 19 __init_array_start
42: 0000000000002014 0 NOTYPE LOCAL DEFAULT 17 __GNU_EH_FRAME_HDR
43: 0000000000004000 0 OBJECT LOCAL DEFAULT 23 _GLOBAL_OFFSET_TABLE_
44: 0000000000001000 0 FUNC LOCAL DEFAULT 11 _init
45: 00000000000011b0 1 FUNC GLOBAL DEFAULT 14 __libc_csu_fini
46: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab
47: 0000000000004020 0 NOTYPE WEAK DEFAULT 24 data_start
48: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@@GLIBC_2.2.5
49: 0000000000004030 0 NOTYPE GLOBAL DEFAULT 24 _edata
50: 00000000000011b4 0 FUNC GLOBAL HIDDEN 15 _fini
51: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_
52: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 24 __data_start
53: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
54: 0000000000004028 0 OBJECT GLOBAL HIDDEN 24 __dso_handle
55: 0000000000002000 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used
56: 0000000000001150 93 FUNC GLOBAL DEFAULT 14 __libc_csu_init
57: 0000000000004038 0 NOTYPE GLOBAL DEFAULT 25 _end
58: 0000000000001050 43 FUNC GLOBAL DEFAULT 14 _start
59: 0000000000004030 0 NOTYPE GLOBAL DEFAULT 25 __bss_start
60: 0000000000001135 23 FUNC GLOBAL DEFAULT 14 main
61: 0000000000004030 0 OBJECT GLOBAL HIDDEN 24 __TMC_END__
62: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
63: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@@GLIBC_2.2
Histogram for `.gnu.hash' bucket list length (total of 2 buckets):
Length Number % of total Coverage
0 1 ( 50.0%)
1 1 ( 50.0%) 100.0%
Version symbols section '.gnu.version' contains 7 entries:
地址:000000000000045a Offset: 0x00045a Link: 5 (.dynsym)
000: 0 (*本地*) 0 (*本地*) 2 (GLIBC_2.2.5) 2 (GLIBC_2.2.5)
004: 0 (*本地*) 0 (*本地*) 2 (GLIBC_2.2.5)
Version needs section '.gnu.version_r' contains 1 entry:
地址:0x0000000000000468 Offset: 0x000468 Link: 6 (.dynstr)
000000: Version: 1 文件:libc.so.6 计数:1
0x0010: Name: GLIBC_2.2.5 标志:无 版本:2
Displaying notes found in: .note.ABI-tag
所有者 Data size Description
GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
OS: Linux, ABI: 3.2.0
Displaying notes found in: .note.gnu.build-id
所有者 Data size Description
GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
Build ID: eca94c2c32a2d5ccdd6097ee889e3470df276c47
显然比链接之前长了许多,增加了程序头等内容。
GDB
程序写完如果输入不符合预期的话就需要用到调试,断点。单步跟踪等可以快速定位到问题,当然,如果靠往程序中加入printf()也能达到调试的目的,这里就需要用到GDB(当然,图形化的高级编译器要方便的多)
GDB调试的是可执行文件,使用gcc编译的话要为可执行程序包含调试信息
#gcc -g hello.c -o hello
GDB调试hello
#gdb hello
表示读取完成。
gdb中常用的命令
break 设置断点 可以使行号、函数名称等
kill 终止当前调试的程序
print 显示变量或者表达式的值
delete 删除断点
run 运行
make 编译程序
continue 从断点继续执行
set args 设置运行参数
next 单步执行程序
step 进入函数内部
以上只是一部分常用命令、如果需要更多的操作、则查看gdb的帮助文件。
help all
反编译
至此好像对于hello程序所有的内容都看了一遍,但是如果只拿到一个可执行文件,想研究下该程序,就需要用到反汇编了,Linux提供了反汇编程序objdump
反汇编hello并重定向到txt文件中
objdump -s -d hello > hello.txt
得到:
hello: 文件格式 elf64-x86-64
Contents of section .interp:
02a8 2f6c6962 36342f6c 642d6c69 6e75782d /lib64/ld-linux-
02b8 7838362d 36342e73 6f2e3200 x86-64.so.2.
Contents of section .note.ABI-tag:
02c4 04000000 10000000 01000000 474e5500 ............GNU.
02d4 00000000 03000000 02000000 00000000 ................
Contents of section .note.gnu.build-id:
02e4 04000000 14000000 03000000 474e5500 ............GNU.
02f4 eca94c2c 32a2d5cc dd6097ee 889e3470 ..L,2....`....4p
0304 df276c47 .'lG
Contents of section .gnu.hash:
0308 02000000 06000000 01000000 06000000 ................
0318 00008100 00000000 06000000 00000000 ................
0328 d165ce6d .e.m
Contents of section .dynsym:
0330 00000000 00000000 00000000 00000000 ................
0340 00000000 00000000 3d000000 20000000 ........=... ...
0350 00000000 00000000 00000000 00000000 ................
0360 0b000000 12000000 00000000 00000000 ................
0370 00000000 00000000 1f000000 12000000 ................
0380 00000000 00000000 00000000 00000000 ................
0390 59000000 20000000 00000000 00000000 Y... ...........
03a0 00000000 00000000 68000000 20000000 ........h... ...
03b0 00000000 00000000 00000000 00000000 ................
03c0 10000000 22000000 00000000 00000000 ...."...........
03d0 00000000 00000000 ........
Contents of section .dynstr:
03d8 006c6962 632e736f 2e360070 75747300 .libc.so.6.puts.
03e8 5f5f6378 615f6669 6e616c69 7a65005f __cxa_finalize._
03f8 5f6c6962 635f7374 6172745f 6d61696e _libc_start_main
0408 00474c49 42435f32 2e322e35 005f4954 .GLIBC_2.2.5._IT
0418 4d5f6465 72656769 73746572 544d436c M_deregisterTMCl
0428 6f6e6554 61626c65 005f5f67 6d6f6e5f oneTable.__gmon_
0438 73746172 745f5f00 5f49544d 5f726567 start__._ITM_reg
0448 69737465 72544d43 6c6f6e65 5461626c isterTMCloneTabl
0458 6500 e.
Contents of section .gnu.version:
045a 00000000 02000200 00000000 0200 ..............
Contents of section .gnu.version_r:
0468 01000100 01000000 10000000 00000000 ................
0478 751a6909 00000200 31000000 00000000 u.i.....1.......
Contents of section .rela.dyn:
0488 e83d0000 00000000 08000000 00000000 .=..............
0498 30110000 00000000 f03d0000 00000000 0........=......
04a8 08000000 00000000 f0100000 00000000 ................
04b8 28400000 00000000 08000000 00000000 (@..............
04c8 28400000 00000000 d83f0000 00000000 (@.......?......
04d8 06000000 01000000 00000000 00000000 ................
04e8 e03f0000 00000000 06000000 03000000 .?..............
04f8 00000000 00000000 e83f0000 00000000 .........?......
0508 06000000 04000000 00000000 00000000 ................
0518 f03f0000 00000000 06000000 05000000 .?..............
0528 00000000 00000000 f83f0000 00000000 .........?......
0538 06000000 06000000 00000000 00000000 ................
Contents of section .rela.plt:
0548 18400000 00000000 07000000 02000000 .@..............
0558 00000000 00000000 ........
Contents of section .init:
1000 4883ec08 488b05dd 2f000048 85c07402 H...H.../..H..t.
1010 ffd04883 c408c3 ..H....
Contents of section .plt:
1020 ff35e22f 0000ff25 e42f0000 0f1f4000 .5./...%./....@.
1030 ff25e22f 00006800 000000e9 e0ffffff .%./..h.........
Contents of section .plt.got:
1040 ff25b22f 00006690 .%./..f.
Contents of section .text:
1050 31ed4989 d15e4889 e24883e4 f050544c 1.I..^H..H...PTL
1060 8d054a01 0000488d 0de30000 00488d3d ..J...H......H.=
1070 c1000000 ff15662f 0000f40f 1f440000 ......f/.....D..
1080 488d3da9 2f000048 8d05a22f 00004839 H.=./..H.../..H9
1090 f8741548 8b053e2f 00004885 c07409ff .t.H..>/..H..t..
10a0 e00f1f80 00000000 c30f1f80 00000000 ................
10b0 488d3d79 2f000048 8d35722f 00004829 H.=y/..H.5r/..H)
10c0 fe48c1fe 034889f0 48c1e83f 4801c648 .H...H..H..?H..H
10d0 d1fe7414 488b0515 2f000048 85c07408 ..t.H.../..H..t.
10e0 ffe0660f 1f440000 c30f1f80 00000000 ..f..D..........
10f0 803d392f 00000075 2f554883 3df62e00 .=9/...u/UH.=...
1100 00004889 e5740c48 8b3d1a2f 0000e82d ..H..t.H.=./...-
1110 ffffffe8 68ffffff c605112f 0000015d ....h....../...]
1120 c30f1f80 00000000 c30f1f80 00000000 ................
1130 e97bffff ff554889 e5488d3d c40e0000 .{...UH..H.=....
1140 e8ebfeff ffb80000 00005dc3 0f1f4000 ..........]...@.
1150 41574c8d 3d8f2c00 00415649 89d64155 AWL.=.,..AVI..AU
1160 4989f541 544189fc 55488d2d 802c0000 I..ATA..UH.-.,..
1170 534c29fd 4883ec08 e883feff ff48c1fd SL).H........H..
1180 03741b31 db0f1f00 4c89f24c 89ee4489 .t.1....L..L..D.
1190 e741ff14 df4883c3 014839dd 75ea4883 .A...H...H9.u.H.
11a0 c4085b5d 415c415d 415e415f c30f1f00 ..[]A\A]A^A_....
11b0 c3 .
Contents of section .fini:
11b4 4883ec08 4883c408 c3 H...H....
Contents of section .rodata:
2000 01000200 48656c6c 6f20776f 726c6421 ....Hello world!
2010 00 .
Contents of section .eh_frame_hdr:
2014 011b033b 38000000 06000000 0cf0ffff ...;8...........
2024 84000000 2cf0ffff ac000000 3cf0ffff ....,.......<...
2034 54000000 21f1ffff c4000000 3cf1ffff T...!.......<...
2044 e4000000 9cf1ffff 2c010000 ........,...
Contents of section .eh_frame:
2050 14000000 00000000 017a5200 01781001 .........zR..x..
2060 1b0c0708 90010710 14000000 1c000000 ................
2070 e0efffff 2b000000 00000000 00000000 ....+...........
2080 14000000 00000000 017a5200 01781001 .........zR..x..
2090 1b0c0708 90010000 24000000 1c000000 ........$.......
20a0 80efffff 20000000 000e1046 0e184a0f .... ......F..J.
20b0 0b770880 003f1a3b 2a332422 00000000 .w...?.;*3$"....
20c0 14000000 44000000 78efffff 08000000 ....D...x.......
20d0 00000000 00000000 1c000000 5c000000 ............\...
20e0 55f0ffff 17000000 00410e10 8602430d U........A....C.
20f0 06520c07 08000000 44000000 7c000000 .R......D...|...
2100 50f0ffff 5d000000 00420e10 8f02490e P...]....B....I.
2110 188e0345 0e208d04 450e288c 05440e30 ...E. ..E.(..D.0
2120 8606480e 38830747 0e406a0e 38410e30 ..H.8..G.@j.8A.0
2130 410e2842 0e20420e 18420e10 420e0800 A.(B. B..B..B...
2140 10000000 c4000000 68f0ffff 01000000 ........h.......
2150 00000000 00000000 ........
Contents of section .init_array:
3de8 30110000 00000000 0.......
Contents of section .fini_array:
3df0 f0100000 00000000 ........
Contents of section .dynamic:
3df8 01000000 00000000 01000000 00000000 ................
3e08 0c000000 00000000 00100000 00000000 ................
3e18 0d000000 00000000 b4110000 00000000 ................
3e28 19000000 00000000 e83d0000 00000000 .........=......
3e38 1b000000 00000000 08000000 00000000 ................
3e48 1a000000 00000000 f03d0000 00000000 .........=......
3e58 1c000000 00000000 08000000 00000000 ................
3e68 f5feff6f 00000000 08030000 00000000 ...o............
3e78 05000000 00000000 d8030000 00000000 ................
3e88 06000000 00000000 30030000 00000000 ........0.......
3e98 0a000000 00000000 82000000 00000000 ................
3ea8 0b000000 00000000 18000000 00000000 ................
3eb8 15000000 00000000 00000000 00000000 ................
3ec8 03000000 00000000 00400000 00000000 .........@......
3ed8 02000000 00000000 18000000 00000000 ................
3ee8 14000000 00000000 07000000 00000000 ................
3ef8 17000000 00000000 48050000 00000000 ........H.......
3f08 07000000 00000000 88040000 00000000 ................
3f18 08000000 00000000 c0000000 00000000 ................
3f28 09000000 00000000 18000000 00000000 ................
3f38 fbffff6f 00000000 00000008 00000000 ...o............
3f48 feffff6f 00000000 68040000 00000000 ...o....h.......
3f58 ffffff6f 00000000 01000000 00000000 ...o............
3f68 f0ffff6f 00000000 5a040000 00000000 ...o....Z.......
3f78 f9ffff6f 00000000 03000000 00000000 ...o............
3f88 00000000 00000000 00000000 00000000 ................
3f98 00000000 00000000 00000000 00000000 ................
3fa8 00000000 00000000 00000000 00000000 ................
3fb8 00000000 00000000 00000000 00000000 ................
3fc8 00000000 00000000 00000000 00000000 ................
Contents of section .got:
3fd8 00000000 00000000 00000000 00000000 ................
3fe8 00000000 00000000 00000000 00000000 ................
3ff8 00000000 00000000 ........
Contents of section .got.plt:
4000 f83d0000 00000000 00000000 00000000 .=..............
4010 00000000 00000000 36100000 00000000 ........6.......
Contents of section .data:
4020 00000000 00000000 28400000 00000000 ........(@......
Contents of section .comment:
0000 4743433a 20284465 6269616e 20382e33 GCC: (Debian 8.3
0010 2e302d36 2920382e 332e3000 .0-6) 8.3.0.
Disassembly of section .init:
0000000000001000 <_init>:
1000: 48 83 ec 08 sub $0x8,%rsp
1004: 48 8b 05 dd 2f 00 00 mov 0x2fdd(%rip),%rax # 3fe8 <__gmon_start__>
100b: 48 85 c0 test %rax,%rax
100e: 74 02 je 1012 <_init+0x12>
1010: ff d0 callq *%rax
1012: 48 83 c4 08 add $0x8,%rsp
1016: c3 retq
Disassembly of section .plt:
0000000000001020 <.plt>:
1020: ff 35 e2 2f 00 00 pushq 0x2fe2(%rip) # 4008 <_GLOBAL_OFFSET_TABLE_+0x8>
1026: ff 25 e4 2f 00 00 jmpq *0x2fe4(%rip) # 4010 <_GLOBAL_OFFSET_TABLE_+0x10>
102c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000001030 <puts@plt>:
1030: ff 25 e2 2f 00 00 jmpq *0x2fe2(%rip) # 4018 <puts@GLIBC_2.2.5>
1036: 68 00 00 00 00 pushq $0x0
103b: e9 e0 ff ff ff jmpq 1020 <.plt>
Disassembly of section .plt.got:
0000000000001040 <__cxa_finalize@plt>:
1040: ff 25 b2 2f 00 00 jmpq *0x2fb2(%rip) # 3ff8 <__cxa_finalize@GLIBC_2.2.5>
1046: 66 90 xchg %ax,%ax
Disassembly of section .text:
0000000000001050 <_start>:
1050: 31 ed xor %ebp,%ebp
1052: 49 89 d1 mov %rdx,%r9
1055: 5e pop %rsi
1056: 48 89 e2 mov %rsp,%rdx
1059: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
105d: 50 push %rax
105e: 54 push %rsp
105f: 4c 8d 05 4a 01 00 00 lea 0x14a(%rip),%r8 # 11b0 <__libc_csu_fini>
1066: 48 8d 0d e3 00 00 00 lea 0xe3(%rip),%rcx # 1150 <__libc_csu_init>
106d: 48 8d 3d c1 00 00 00 lea 0xc1(%rip),%rdi # 1135 <main>
1074: ff 15 66 2f 00 00 callq *0x2f66(%rip) # 3fe0 <__libc_start_main@GLIBC_2.2.5>
107a: f4 hlt
107b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
0000000000001080 <deregister_tm_clones>:
1080: 48 8d 3d a9 2f 00 00 lea 0x2fa9(%rip),%rdi # 4030 <__TMC_END__>
1087: 48 8d 05 a2 2f 00 00 lea 0x2fa2(%rip),%rax # 4030 <__TMC_END__>
108e: 48 39 f8 cmp %rdi,%rax
1091: 74 15 je 10a8 <deregister_tm_clones+0x28>
1093: 48 8b 05 3e 2f 00 00 mov 0x2f3e(%rip),%rax # 3fd8 <_ITM_deregisterTMCloneTable>
109a: 48 85 c0 test %rax,%rax
109d: 74 09 je 10a8 <deregister_tm_clones+0x28>
109f: ff e0 jmpq *%rax
10a1: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
10a8: c3 retq
10a9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
00000000000010b0 <register_tm_clones>:
10b0: 48 8d 3d 79 2f 00 00 lea 0x2f79(%rip),%rdi # 4030 <__TMC_END__>
10b7: 48 8d 35 72 2f 00 00 lea 0x2f72(%rip),%rsi # 4030 <__TMC_END__>
10be: 48 29 fe sub %rdi,%rsi
10c1: 48 c1 fe 03 sar $0x3,%rsi
10c5: 48 89 f0 mov %rsi,%rax
10c8: 48 c1 e8 3f shr $0x3f,%rax
10cc: 48 01 c6 add %rax,%rsi
10cf: 48 d1 fe sar %rsi
10d2: 74 14 je 10e8 <register_tm_clones+0x38>
10d4: 48 8b 05 15 2f 00 00 mov 0x2f15(%rip),%rax # 3ff0 <_ITM_registerTMCloneTable>
10db: 48 85 c0 test %rax,%rax
10de: 74 08 je 10e8 <register_tm_clones+0x38>
10e0: ff e0 jmpq *%rax
10e2: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
10e8: c3 retq
10e9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
00000000000010f0 <__do_global_dtors_aux>:
10f0: 80 3d 39 2f 00 00 00 cmpb $0x0,0x2f39(%rip) # 4030 <__TMC_END__>
10f7: 75 2f jne 1128 <__do_global_dtors_aux+0x38>
10f9: 55 push %rbp
10fa: 48 83 3d f6 2e 00 00 cmpq $0x0,0x2ef6(%rip) # 3ff8 <__cxa_finalize@GLIBC_2.2.5>
1101: 00
1102: 48 89 e5 mov %rsp,%rbp
1105: 74 0c je 1113 <__do_global_dtors_aux+0x23>
1107: 48 8b 3d 1a 2f 00 00 mov 0x2f1a(%rip),%rdi # 4028 <__dso_handle>
110e: e8 2d ff ff ff callq 1040 <__cxa_finalize@plt>
1113: e8 68 ff ff ff callq 1080 <deregister_tm_clones>
1118: c6 05 11 2f 00 00 01 movb $0x1,0x2f11(%rip) # 4030 <__TMC_END__>
111f: 5d pop %rbp
1120: c3 retq
1121: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
1128: c3 retq
1129: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
0000000000001130 <frame_dummy>:
1130: e9 7b ff ff ff jmpq 10b0 <register_tm_clones>
0000000000001135 <main>:
1135: 55 push %rbp
1136: 48 89 e5 mov %rsp,%rbp
1139: 48 8d 3d c4 0e 00 00 lea 0xec4(%rip),%rdi # 2004 <_IO_stdin_used+0x4>
1140: e8 eb fe ff ff callq 1030 <puts@plt>
1145: b8 00 00 00 00 mov $0x0,%eax
114a: 5d pop %rbp
114b: c3 retq
114c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000001150 <__libc_csu_init>:
1150: 41 57 push %r15
1152: 4c 8d 3d 8f 2c 00 00 lea 0x2c8f(%rip),%r15 # 3de8 <__frame_dummy_init_array_entry>
1159: 41 56 push %r14
115b: 49 89 d6 mov %rdx,%r14
115e: 41 55 push %r13
1160: 49 89 f5 mov %rsi,%r13
1163: 41 54 push %r12
1165: 41 89 fc mov %edi,%r12d
1168: 55 push %rbp
1169: 48 8d 2d 80 2c 00 00 lea 0x2c80(%rip),%rbp # 3df0 <__init_array_end>
1170: 53 push %rbx
1171: 4c 29 fd sub %r15,%rbp
1174: 48 83 ec 08 sub $0x8,%rsp
1178: e8 83 fe ff ff callq 1000 <_init>
117d: 48 c1 fd 03 sar $0x3,%rbp
1181: 74 1b je 119e <__libc_csu_init+0x4e>
1183: 31 db xor %ebx,%ebx
1185: 0f 1f 00 nopl (%rax)
1188: 4c 89 f2 mov %r14,%rdx
118b: 4c 89 ee mov %r13,%rsi
118e: 44 89 e7 mov %r12d,%edi
1191: 41 ff 14 df callq *(%r15,%rbx,8)
1195: 48 83 c3 01 add $0x1,%rbx
1199: 48 39 dd cmp %rbx,%rbp
119c: 75 ea jne 1188 <__libc_csu_init+0x38>
119e: 48 83 c4 08 add $0x8,%rsp
11a2: 5b pop %rbx
11a3: 5d pop %rbp
11a4: 41 5c pop %r12
11a6: 41 5d pop %r13
11a8: 41 5e pop %r14
11aa: 41 5f pop %r15
11ac: c3 retq
11ad: 0f 1f 00 nopl (%rax)
00000000000011b0 <__libc_csu_fini>:
11b0: c3 retq
Disassembly of section .fini:
00000000000011b4 <_fini>:
11b4: 48 83 ec 08 sub $0x8,%rsp
11b8: 48 83 c4 08 add $0x8,%rsp
11bc: c3 retq
总结
hello world这短短的六行代码不能说明c所有机制,确让人从本质上理解了程序的基本构成,不禁感叹前辈们的智慧;
如果有一天因为自己的程序得不到满意的输出,回来看看hello world。
山僧不解数甲子, 一叶落知天下秋。