gcc hello 到底连接了什么
------------------------------------------------------------
源代码:
------------------------------------------------------------
[hjj@hjj ~]$ cat test.c
#include <stdio.h>
unsigned char d[]={
0x12,0x34,0x56,0x78
};
int main(int argc, char *argv[])
{
printf("data: %x\n", (*(int *)d));
return 0;
}
------------------------------------------------------------
编译为.o
gcc -c -o test.o test.c
------------------------------------------------------------
ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o test /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/crtn.o /usr/lib/gcc/x86_64-redhat-linux/4.4.7/crtbegin.o /usr/lib/gcc/x86_64-redhat-linux/4.4.7/crtend.o test.o -L/usr/lib64 -lc
至于第二行命令的来历,是如下实验,简化来的。
gcc -v -o test test.o
它有详细的输出,我们去掉无用部分,尝试修改一部分。简化得到
对hello 而言, crtbegin.o crtend.o 可以省略,如下示:
------------------------------------------------------------
简化的连接:
[hjj@hjj ~]$ ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o test /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/crtn.o test.o -L/usr/lib64 -lc
------------------------------------------------------------
运行:
[hjj@hjj ~]$ ./test
data: 78563412
------------------------------------------------------------
删除crt1.o 连接错,找不到_start
------------------------------------------------------------
[hjj@hjj ~]$ ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o test /usr/lib64/crti.o /usr/lib64/crtn.o test.o -L/usr/lib64 -lc
ld: warning: cannot find entry symbol _start; defaulting to 00000000004002d0
------------------------------------------------------------
删除crti.o 连接错,找不到_init
------------------------------------------------------------
[hjj@hjj ~]$ ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o test /usr/lib64/crt1.o /usr/lib64/crtn.o test.o -L/usr/lib64 -lc
/usr/lib64/libc_nonshared.a(elf-init.oS): In function `__libc_csu_init':
(.text+0x51): undefined reference to `_init'
------------------------------------------------------------
删除crtn.o 运行错, segmentation fault
------------------------------------------------------------
[hjj@hjj ~]$ ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o test /usr/lib64/crt1.o /usr/lib64/crti.o test.o -L/usr/lib64 -lc
[hjj@hjj ~]$ ./test
Segmentation fault (core dumped)
------------------------------------------------------------
删除libc 库, 连接错, 找不到__libc_start_main 等
------------------------------------------------------------
[hjj@hjj ~]$ ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o test /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/crtn.o test.o -L/usr/lib64
/usr/lib64/crt1.o: In function `_start':
(.text+0x12): undefined reference to `__libc_csu_fini'
/usr/lib64/crt1.o: In function `_start':
(.text+0x19): undefined reference to `__libc_csu_init'
/usr/lib64/crt1.o: In function `_start':
(.text+0x25): undefined reference to `__libc_start_main'
test.o: In function `main':
test.c:(.text+0x26): undefined reference to `printf'
------------------------------------------------------------
不用dynamic-linker, 因找不到连接解释器,不能运行
------------------------------------------------------------
[hjj@hjj ~]$ ld -o test /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/crtn.o test.o -L/usr/lib64 -lc
[hjj@hjj ~]$ ./test
bash: ./test: /lib/ld64.so.1: bad ELF interpreter: No such file or directory
------------------------------------------------------------
c runtime obj 分析
------------------------------------------------------------
[hjj@hjj /usr/lib64]$ ls crt*
crt1.o crti.o crtn.o
[Hjjhjj /usr/lib64]$ nm crt1.o
0000000000000000 R _IO_stdin_used
0000000000000000 D __data_start
U __libc_csu_fini
U __libc_csu_init
U __libc_start_main
0000000000000000 T _start
0000000000000000 W data_start
U main
[hjj@hjj /usr/lib64]$ nm crti.o
U _GLOBAL_OFFSET_TABLE_
w __gmon_start__
0000000000000000 T _fini
0000000000000000 T _init
0000000000000000 t call_gmon_start
[hjj@hjj /usr/lib64]$ nm crtn.o
nm: crtn.o: no symbols
crt1.o中的未定义符号main在main.o中定义了,所以链接在一起就没问题了。
crt1.o还有未定义符号__libc_start_main .__libc_... 这些符号是在libc中定义的,
libc并不像其它目标文件一样链接到可执行文件main中,而是在运行时做动态链接:
1. 操作系统在加载执行main这个程序时,首先查看它有没有需要动态链接的符号。
2. 如果需要做动态链接,就查看这个程序指定了哪些共享库(我们用-lc指定了libc)
以及用什么动态链接器来做动态链接(我们用-dynamic-linker /lib/ld-linux.so.2指定了动态链接器)。
3. 动态链接器在共享库中查找这些符号的定义,完成链接过程。
在crt1.o 中, 包含有代码的运行入口_start:
crt1.o 的前身叫crt0.o, 它的作用是作为连接的首个模块。
为了实现C++的全局构造和析构。改进crt0.o 为crt1.o
运行库在目标文件后引入了.init和.finit段,
.init在main函数前运行
.finit在main函数后运行
链接器将所有目标文件的init段和finit段合并,并产生两个函数:_init()和_finit()。
.init段,.finit 段需要的一些辅助代码,分别位于crti.o和crtn.o。
开始是来自crti.o的,而末尾是来自crtn.o的,中间才是真正程序的全局构造或者析构函数,
也就是说程序的全局构造和析构仅仅是_init和_finit的中间部分.
_start 函数调用: __libc_start_main 函数
__libc_start_main 会调用 __libc_csu_init, __libc_csu_fini,及main 函数
简单表示为如下:
__libc_start_main (main,__libc_csu_init,__libc_csu_fini)
__libc_csu_init, 负责调用_init()
crti.o 反汇编, 考虑上重定位xinx
可见_init 就是调用__gmon_start__, 而_fini 只是恢复堆栈平衡.
glic只是一个c语言库, crti.o和crtn.o只是提供了main之前和之后执行代码的机制,
真正C++全局构造和析构是由crtbegin.o和crtend.o实现的。
GCC是C++的真正实现者。这两个文件是用于配合glibc实现C++全局构造和析构的。
构造过程:
_start-->__lib_start_main-->__libc_csu_init-->_init--> __do_global_ctors
析构过程: 执行与构造相反的过程
反汇编代码分析
------------------------------------------------------------
[hjj@hjj ~]$ objdump -d test
test: file format elf64-x86-64
Disassembly of section .init:
0000000000400330 <_init>:
400330: 48 83 ec 08 sub $0x8,%rsp
400334: e8 63 00 00 00 callq 40039c <call_gmon_start>
400339: 48 83 c4 08 add $0x8,%rsp
40033d: c3 retq
Disassembly of section .plt:
0000000000400340 <printf@plt-0x10>:
400340: ff 35 7a 03 20 00 pushq 0x20037a(%rip) # 6006c0 <_GLOBAL_OFFSET_TABLE_+0x8>
400346: ff 25 7c 03 20 00 jmpq *0x20037c(%rip) # 6006c8 <_GLOBAL_OFFSET_TABLE_+0x10>
40034c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000400350 <printf@plt>:
400350: ff 25 7a 03 20 00 jmpq *0x20037a(%rip) # 6006d0 <_GLOBAL_OFFSET_TABLE_+0x18>
400356: 68 00 00 00 00 pushq $0x0
40035b: e9 e0 ff ff ff jmpq 400340 <_init+0x10>
0000000000400360 <__libc_start_main@plt>:
400360: ff 25 72 03 20 00 jmpq *0x200372(%rip) # 6006d8 <_GLOBAL_OFFSET_TABLE_+0x20>
400366: 68 01 00 00 00 pushq $0x1
40036b: e9 d0 ff ff ff jmpq 400340 <_init+0x10>
Disassembly of section .text:
0000000000400370 <_start>:
400370: 31 ed xor %ebp,%ebp
400372: 49 89 d1 mov %rdx,%r9
400375: 5e pop %rsi
400376: 48 89 e2 mov %rsp,%rdx
400379: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
40037d: 50 push %rax
40037e: 54 push %rsp
40037f: 49 c7 c0 f0 03 40 00 mov $0x4003f0,%r8
400386: 48 c7 c1 00 04 40 00 mov $0x400400,%rcx
40038d: 48 c7 c7 b4 03 40 00 mov $0x4003b4,%rdi
400394: e8 c7 ff ff ff callq 400360 <__libc_start_main@plt>
400399: f4 hlt
40039a: 90 nop
40039b: 90 nop
000000000040039c <call_gmon_start>:
40039c: 48 83 ec 08 sub $0x8,%rsp
4003a0: 48 8b 05 09 03 20 00 mov 0x200309(%rip),%rax # 6006b0 <_DYNAMIC+0x190>
4003a7: 48 85 c0 test %rax,%rax
4003aa: 74 02 je 4003ae <call_gmon_start+0x12>
4003ac: ff d0 callq *%rax
4003ae: 48 83 c4 08 add $0x8,%rsp
4003b2: c3 retq
4003b3: 90 nop
00000000004003b4 <main>:
4003b4: 55 push %rbp
4003b5: 48 89 e5 mov %rsp,%rbp
4003b8: 48 83 ec 10 sub $0x10,%rsp
4003bc: 89 7d fc mov %edi,-0x4(%rbp)
4003bf: 48 89 75 f0 mov %rsi,-0x10(%rbp)
4003c3: b8 e4 06 60 00 mov $0x6006e4,%eax
4003c8: 8b 10 mov (%rax),%edx
4003ca: b8 9c 04 40 00 mov $0x40049c,%eax
4003cf: 89 d6 mov %edx,%esi
4003d1: 48 89 c7 mov %rax,%rdi
4003d4: b8 00 00 00 00 mov $0x0,%eax
4003d9: e8 72 ff ff ff callq 400350 <printf@plt>
4003de: b8 00 00 00 00 mov $0x0,%eax
4003e3: c9 leaveq
4003e4: c3 retq
4003e5: 90 nop
4003e6: 90 nop
4003e7: 90 nop
4003e8: 90 nop
4003e9: 90 nop
4003ea: 90 nop
4003eb: 90 nop
4003ec: 90 nop
4003ed: 90 nop
4003ee: 90 nop
4003ef: 90 nop
00000000004003f0 <__libc_csu_fini>:
4003f0: f3 c3 repz retq
4003f2: 66 66 66 66 66 2e 0f data32 data32 data32 data32 nopw %cs:0x0(%rax,%rax,1)
4003f9: 1f 84 00 00 00 00 00
0000000000400400 <__libc_csu_init>:
400400: 48 89 6c 24 d8 mov %rbp,-0x28(%rsp)
400405: 4c 89 64 24 e0 mov %r12,-0x20(%rsp)
40040a: 48 8d 2d 0f 01 20 00 lea 0x20010f(%rip),%rbp # 600520 <_DYNAMIC>
400411: 4c 8d 25 08 01 20 00 lea 0x200108(%rip),%r12 # 600520 <_DYNAMIC>
400418: 4c 89 6c 24 e8 mov %r13,-0x18(%rsp)
40041d: 4c 89 74 24 f0 mov %r14,-0x10(%rsp)
400422: 4c 89 7c 24 f8 mov %r15,-0x8(%rsp)
400427: 48 89 5c 24 d0 mov %rbx,-0x30(%rsp)
40042c: 48 83 ec 38 sub $0x38,%rsp
400430: 4c 29 e5 sub %r12,%rbp
400433: 41 89 fd mov %edi,%r13d
400436: 49 89 f6 mov %rsi,%r14
400439: 48 c1 fd 03 sar $0x3,%rbp
40043d: 49 89 d7 mov %rdx,%r15
400440: e8 eb fe ff ff callq 400330 <_init>
400445: 48 85 ed test %rbp,%rbp
400448: 74 1c je 400466 <__libc_csu_init+0x66>
40044a: 31 db xor %ebx,%ebx
40044c: 0f 1f 40 00 nopl 0x0(%rax)
400450: 4c 89 fa mov %r15,%rdx
400453: 4c 89 f6 mov %r14,%rsi
400456: 44 89 ef mov %r13d,%edi
400459: 41 ff 14 dc callq *(%r12,%rbx,8)
40045d: 48 83 c3 01 add $0x1,%rbx
400461: 48 39 eb cmp %rbp,%rbx
400464: 72 ea jb 400450 <__libc_csu_init+0x50>
400466: 48 8b 5c 24 08 mov 0x8(%rsp),%rbx
40046b: 48 8b 6c 24 10 mov 0x10(%rsp),%rbp
400470: 4c 8b 64 24 18 mov 0x18(%rsp),%r12
400475: 4c 8b 6c 24 20 mov 0x20(%rsp),%r13
40047a: 4c 8b 74 24 28 mov 0x28(%rsp),%r14
40047f: 4c 8b 7c 24 30 mov 0x30(%rsp),%r15
400484: 48 83 c4 38 add $0x38,%rsp
400488: c3 retq
Disassembly of section .fini:
000000000040048c <_fini>:
40048c: 48 83 ec 08 sub $0x8,%rsp
400490: 48 83 c4 08 add $0x8,%rsp
400494: c3 retq
[hjj@hjj ~]
------------------------------------------------------------
源代码:
------------------------------------------------------------
[hjj@hjj ~]$ cat test.c
#include <stdio.h>
unsigned char d[]={
0x12,0x34,0x56,0x78
};
int main(int argc, char *argv[])
{
printf("data: %x\n", (*(int *)d));
return 0;
}
------------------------------------------------------------
编译为.o
gcc -c -o test.o test.c
------------------------------------------------------------
ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o test /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/crtn.o /usr/lib/gcc/x86_64-redhat-linux/4.4.7/crtbegin.o /usr/lib/gcc/x86_64-redhat-linux/4.4.7/crtend.o test.o -L/usr/lib64 -lc
至于第二行命令的来历,是如下实验,简化来的。
gcc -v -o test test.o
它有详细的输出,我们去掉无用部分,尝试修改一部分。简化得到
对hello 而言, crtbegin.o crtend.o 可以省略,如下示:
------------------------------------------------------------
简化的连接:
[hjj@hjj ~]$ ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o test /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/crtn.o test.o -L/usr/lib64 -lc
------------------------------------------------------------
运行:
[hjj@hjj ~]$ ./test
data: 78563412
------------------------------------------------------------
删除crt1.o 连接错,找不到_start
------------------------------------------------------------
[hjj@hjj ~]$ ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o test /usr/lib64/crti.o /usr/lib64/crtn.o test.o -L/usr/lib64 -lc
ld: warning: cannot find entry symbol _start; defaulting to 00000000004002d0
------------------------------------------------------------
删除crti.o 连接错,找不到_init
------------------------------------------------------------
[hjj@hjj ~]$ ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o test /usr/lib64/crt1.o /usr/lib64/crtn.o test.o -L/usr/lib64 -lc
/usr/lib64/libc_nonshared.a(elf-init.oS): In function `__libc_csu_init':
(.text+0x51): undefined reference to `_init'
------------------------------------------------------------
删除crtn.o 运行错, segmentation fault
------------------------------------------------------------
[hjj@hjj ~]$ ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o test /usr/lib64/crt1.o /usr/lib64/crti.o test.o -L/usr/lib64 -lc
[hjj@hjj ~]$ ./test
Segmentation fault (core dumped)
------------------------------------------------------------
删除libc 库, 连接错, 找不到__libc_start_main 等
------------------------------------------------------------
[hjj@hjj ~]$ ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o test /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/crtn.o test.o -L/usr/lib64
/usr/lib64/crt1.o: In function `_start':
(.text+0x12): undefined reference to `__libc_csu_fini'
/usr/lib64/crt1.o: In function `_start':
(.text+0x19): undefined reference to `__libc_csu_init'
/usr/lib64/crt1.o: In function `_start':
(.text+0x25): undefined reference to `__libc_start_main'
test.o: In function `main':
test.c:(.text+0x26): undefined reference to `printf'
------------------------------------------------------------
不用dynamic-linker, 因找不到连接解释器,不能运行
------------------------------------------------------------
[hjj@hjj ~]$ ld -o test /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/crtn.o test.o -L/usr/lib64 -lc
[hjj@hjj ~]$ ./test
bash: ./test: /lib/ld64.so.1: bad ELF interpreter: No such file or directory
------------------------------------------------------------
c runtime obj 分析
------------------------------------------------------------
[hjj@hjj /usr/lib64]$ ls crt*
crt1.o crti.o crtn.o
[Hjjhjj /usr/lib64]$ nm crt1.o
0000000000000000 R _IO_stdin_used
0000000000000000 D __data_start
U __libc_csu_fini
U __libc_csu_init
U __libc_start_main
0000000000000000 T _start
0000000000000000 W data_start
U main
[hjj@hjj /usr/lib64]$ nm crti.o
U _GLOBAL_OFFSET_TABLE_
w __gmon_start__
0000000000000000 T _fini
0000000000000000 T _init
0000000000000000 t call_gmon_start
[hjj@hjj /usr/lib64]$ nm crtn.o
nm: crtn.o: no symbols
crt1.o中的未定义符号main在main.o中定义了,所以链接在一起就没问题了。
crt1.o还有未定义符号__libc_start_main .__libc_... 这些符号是在libc中定义的,
libc并不像其它目标文件一样链接到可执行文件main中,而是在运行时做动态链接:
1. 操作系统在加载执行main这个程序时,首先查看它有没有需要动态链接的符号。
2. 如果需要做动态链接,就查看这个程序指定了哪些共享库(我们用-lc指定了libc)
以及用什么动态链接器来做动态链接(我们用-dynamic-linker /lib/ld-linux.so.2指定了动态链接器)。
3. 动态链接器在共享库中查找这些符号的定义,完成链接过程。
objdump -x -d crt1.o
还可以结合ida 分析.
在crt1.o 中, 包含有代码的运行入口_start:
crt1.o 的前身叫crt0.o, 它的作用是作为连接的首个模块。
为了实现C++的全局构造和析构。改进crt0.o 为crt1.o
运行库在目标文件后引入了.init和.finit段,
.init在main函数前运行
.finit在main函数后运行
链接器将所有目标文件的init段和finit段合并,并产生两个函数:_init()和_finit()。
.init段,.finit 段需要的一些辅助代码,分别位于crti.o和crtn.o。
开始是来自crti.o的,而末尾是来自crtn.o的,中间才是真正程序的全局构造或者析构函数,
也就是说程序的全局构造和析构仅仅是_init和_finit的中间部分.
_start 函数调用: __libc_start_main 函数
__libc_start_main 会调用 __libc_csu_init, __libc_csu_fini,及main 函数
简单表示为如下:
__libc_start_main (main,__libc_csu_init,__libc_csu_fini)
__libc_csu_init, 负责调用_init()
__libc_csu_fini, 负责调用_finit()
------------------------------------------------------------
crt1.o 反编译.考虑上重定位信息
------------------------------------------------------------
public _start
_start proc near
31 ED xor ebp, ebp
49 89 D1 mov r9, rdx ; rtld_fini
5E pop rsi ; argc
48 89 E2 mov rdx, rsp ; ubp_av
48 83 E4 F0 and rsp, 0FFFFFFFFFFFFFFF0h
50 push rax
54 push rsp ; stack_end
49 C7 C0 68 00 00 00 mov r8, offset __libc_csu_fini ; fini
48 C7 C1 6C 00 00 00 mov rcx, offset __libc_csu_init ; init
48 C7 C7 70 00 00 00 mov rdi, offset main ; main
E8 4B 00 00 00 call __libc_start_main
crti.o 反汇编, 考虑上重定位xinx
; ===========================================================================
; Segment type: Pure code
; Segment permissions: Read/Execute
_init segment dword public 'CODE' use64
assume cs:_init
;org 4
assume es:nothing, ss:nothing, ds:_text, fs:nothing, gs:nothing
; =============== S U B R O U T I N E =======================================
public _init_proc
_init_proc proc near
48 83 EC 08 sub rsp, 8 ; _init
48 8B 05 19 00 00 00 mov rax, cs:__gmon_start___ptr
48 85 C0 test rax, rax
74 05 jz short near ptr 19h
E8 07 00 00 00 call __gmon_start__ ; PIC mode
_init_proc endp
_init ends
; ===========================================================================
; Segment type: Pure code
; Segment permissions: Read/Execute
_fini segment dword public 'CODE' use64
assume cs:_fini
;org 1Ch
assume es:nothing, ss:nothing, ds:_text, fs:nothing, gs:nothing
; =============== S U B R O U T I N E =======================================
public _term_proc
_term_proc proc near
48 83 EC 08 sub rsp, 8 ; _fini
_term_proc endp ; sp-analysis failed
_fini ends
可见_init 就是调用__gmon_start__, 而_fini 只是恢复堆栈平衡.
------------------------------------------------------------
crtn.o 反编译. 直接用objdump 查看, 其符号是.init, .fini, 仅用来维护堆栈.
objdump -d crtn.o
crtn.o: file format elf64-x86-64
Disassembly of section .init:
0000000000000000 <.init>:
0: 48 83 c4 08 add $0x8,%rsp
4: c3 retq
Disassembly of section .fini:
0000000000000000 <.fini>:
0: 48 83 c4 08 add $0x8,%rsp
4: c3 retq
glic只是一个c语言库, crti.o和crtn.o只是提供了main之前和之后执行代码的机制,
真正C++全局构造和析构是由crtbegin.o和crtend.o实现的。
GCC是C++的真正实现者。这两个文件是用于配合glibc实现C++全局构造和析构的。
构造过程:
_start-->__lib_start_main-->__libc_csu_init-->_init--> __do_global_ctors
析构过程: 执行与构造相反的过程
以下分析可执行文件test.
反汇编代码分析
------------------------------------------------------------
[hjj@hjj ~]$ objdump -d test
test: file format elf64-x86-64
Disassembly of section .init:
0000000000400330 <_init>:
400330: 48 83 ec 08 sub $0x8,%rsp
400334: e8 63 00 00 00 callq 40039c <call_gmon_start>
400339: 48 83 c4 08 add $0x8,%rsp
40033d: c3 retq
Disassembly of section .plt:
0000000000400340 <printf@plt-0x10>:
400340: ff 35 7a 03 20 00 pushq 0x20037a(%rip) # 6006c0 <_GLOBAL_OFFSET_TABLE_+0x8>
400346: ff 25 7c 03 20 00 jmpq *0x20037c(%rip) # 6006c8 <_GLOBAL_OFFSET_TABLE_+0x10>
40034c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000400350 <printf@plt>:
400350: ff 25 7a 03 20 00 jmpq *0x20037a(%rip) # 6006d0 <_GLOBAL_OFFSET_TABLE_+0x18>
400356: 68 00 00 00 00 pushq $0x0
40035b: e9 e0 ff ff ff jmpq 400340 <_init+0x10>
0000000000400360 <__libc_start_main@plt>:
400360: ff 25 72 03 20 00 jmpq *0x200372(%rip) # 6006d8 <_GLOBAL_OFFSET_TABLE_+0x20>
400366: 68 01 00 00 00 pushq $0x1
40036b: e9 d0 ff ff ff jmpq 400340 <_init+0x10>
Disassembly of section .text:
0000000000400370 <_start>:
400370: 31 ed xor %ebp,%ebp
400372: 49 89 d1 mov %rdx,%r9
400375: 5e pop %rsi
400376: 48 89 e2 mov %rsp,%rdx
400379: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
40037d: 50 push %rax
40037e: 54 push %rsp
40037f: 49 c7 c0 f0 03 40 00 mov $0x4003f0,%r8
400386: 48 c7 c1 00 04 40 00 mov $0x400400,%rcx
40038d: 48 c7 c7 b4 03 40 00 mov $0x4003b4,%rdi
400394: e8 c7 ff ff ff callq 400360 <__libc_start_main@plt>
400399: f4 hlt
40039a: 90 nop
40039b: 90 nop
000000000040039c <call_gmon_start>:
40039c: 48 83 ec 08 sub $0x8,%rsp
4003a0: 48 8b 05 09 03 20 00 mov 0x200309(%rip),%rax # 6006b0 <_DYNAMIC+0x190>
4003a7: 48 85 c0 test %rax,%rax
4003aa: 74 02 je 4003ae <call_gmon_start+0x12>
4003ac: ff d0 callq *%rax
4003ae: 48 83 c4 08 add $0x8,%rsp
4003b2: c3 retq
4003b3: 90 nop
00000000004003b4 <main>:
4003b4: 55 push %rbp
4003b5: 48 89 e5 mov %rsp,%rbp
4003b8: 48 83 ec 10 sub $0x10,%rsp
4003bc: 89 7d fc mov %edi,-0x4(%rbp)
4003bf: 48 89 75 f0 mov %rsi,-0x10(%rbp)
4003c3: b8 e4 06 60 00 mov $0x6006e4,%eax
4003c8: 8b 10 mov (%rax),%edx
4003ca: b8 9c 04 40 00 mov $0x40049c,%eax
4003cf: 89 d6 mov %edx,%esi
4003d1: 48 89 c7 mov %rax,%rdi
4003d4: b8 00 00 00 00 mov $0x0,%eax
4003d9: e8 72 ff ff ff callq 400350 <printf@plt>
4003de: b8 00 00 00 00 mov $0x0,%eax
4003e3: c9 leaveq
4003e4: c3 retq
4003e5: 90 nop
4003e6: 90 nop
4003e7: 90 nop
4003e8: 90 nop
4003e9: 90 nop
4003ea: 90 nop
4003eb: 90 nop
4003ec: 90 nop
4003ed: 90 nop
4003ee: 90 nop
4003ef: 90 nop
00000000004003f0 <__libc_csu_fini>:
4003f0: f3 c3 repz retq
4003f2: 66 66 66 66 66 2e 0f data32 data32 data32 data32 nopw %cs:0x0(%rax,%rax,1)
4003f9: 1f 84 00 00 00 00 00
0000000000400400 <__libc_csu_init>:
400400: 48 89 6c 24 d8 mov %rbp,-0x28(%rsp)
400405: 4c 89 64 24 e0 mov %r12,-0x20(%rsp)
40040a: 48 8d 2d 0f 01 20 00 lea 0x20010f(%rip),%rbp # 600520 <_DYNAMIC>
400411: 4c 8d 25 08 01 20 00 lea 0x200108(%rip),%r12 # 600520 <_DYNAMIC>
400418: 4c 89 6c 24 e8 mov %r13,-0x18(%rsp)
40041d: 4c 89 74 24 f0 mov %r14,-0x10(%rsp)
400422: 4c 89 7c 24 f8 mov %r15,-0x8(%rsp)
400427: 48 89 5c 24 d0 mov %rbx,-0x30(%rsp)
40042c: 48 83 ec 38 sub $0x38,%rsp
400430: 4c 29 e5 sub %r12,%rbp
400433: 41 89 fd mov %edi,%r13d
400436: 49 89 f6 mov %rsi,%r14
400439: 48 c1 fd 03 sar $0x3,%rbp
40043d: 49 89 d7 mov %rdx,%r15
400440: e8 eb fe ff ff callq 400330 <_init>
400445: 48 85 ed test %rbp,%rbp
400448: 74 1c je 400466 <__libc_csu_init+0x66>
40044a: 31 db xor %ebx,%ebx
40044c: 0f 1f 40 00 nopl 0x0(%rax)
400450: 4c 89 fa mov %r15,%rdx
400453: 4c 89 f6 mov %r14,%rsi
400456: 44 89 ef mov %r13d,%edi
400459: 41 ff 14 dc callq *(%r12,%rbx,8)
40045d: 48 83 c3 01 add $0x1,%rbx
400461: 48 39 eb cmp %rbp,%rbx
400464: 72 ea jb 400450 <__libc_csu_init+0x50>
400466: 48 8b 5c 24 08 mov 0x8(%rsp),%rbx
40046b: 48 8b 6c 24 10 mov 0x10(%rsp),%rbp
400470: 4c 8b 64 24 18 mov 0x18(%rsp),%r12
400475: 4c 8b 6c 24 20 mov 0x20(%rsp),%r13
40047a: 4c 8b 74 24 28 mov 0x28(%rsp),%r14
40047f: 4c 8b 7c 24 30 mov 0x30(%rsp),%r15
400484: 48 83 c4 38 add $0x38,%rsp
400488: c3 retq
Disassembly of section .fini:
000000000040048c <_fini>:
40048c: 48 83 ec 08 sub $0x8,%rsp
400490: 48 83 c4 08 add $0x8,%rsp
400494: c3 retq
[hjj@hjj ~]