Linux gcc论应用程序是如何跑起来的

【版权申明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) 

Linux gcc论应用程序是如何跑起来的

相信我, 我真的只写了file.c这一个文件.
代码及编译指令交代:

#include<stdio.h>

void func(void)
{
        printf("hello\n");
}

int  main(void)
{
        func();

        return 0;
}
$gcc -c file.c -o file.o
$gcc file.o -o file

未链接前:

$nm file.o 
0000000000000000 T func
                 U _GLOBAL_OFFSET_TABLE_
0000000000000013 T main
                 U puts

链接后:

$nm file
0000000000000830 t atexit
0000000000201010 B __bss_start
0000000000201010 b called.4604
0000000000201014 b completed.7698
                 U __cxa_atexit@@GLIBC_2.2.5
                 w __cxa_finalize@@GLIBC_2.2.5
0000000000201000 D __data_start
0000000000201000 W data_start
00000000000006a0 t deregister_tm_clones
0000000000000690 T _dl_relocate_static_pie
0000000000000730 t __do_global_dtors_aux
0000000000200da8 t __do_global_dtors_aux_fini_array_entry
0000000000201008 D __dso_handle
0000000000200db0 d _DYNAMIC
0000000000201010 D _edata
0000000000201018 B _end
0000000000000849 T etext
0000000000000840 T _fini
0000000000000770 t frame_dummy
0000000000200da0 t __frame_dummy_init_array_entry
0000000000000a1c r __FRAME_END__
000000000000077a T func
0000000000200fa0 d _GLOBAL_OFFSET_TABLE_
0000000000000640 T __gmon_start__
0000000000000858 r __GNU_EH_FRAME_HDR
00000000000005a0 T _init
0000000000200da8 t __init_array_end
0000000000200da0 t __init_array_start
000000000000084c R _IO_stdin_used
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000000820 T __libc_csu_fini
00000000000007b0 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
0000000000000793 T main
                 U _mcleanup@@GLIBC_2.2.5
                 U mcount@@GLIBC_2.2.5
                 U __monstartup@@GLIBC_2.2.5
                 U puts@@GLIBC_2.2.5
00000000000006e0 t register_tm_clones
0000000000000610 T _start
0000000000201010 D __TMC_END__

因为链接器的缘故, func.o的0000000000000000 T func0000000000000013 T main被成功整合到了最终的可执行文件中, 且由相对地址变成了绝对地址(即当程序运行时会被放置的地址): 000000000000077a T func0000000000000793 T main.

但是相对于file.o的寥寥几行, 为什么被链接之后多了这么多呢?
  在链接过程中, 链接器将我们的file.o与众多我们所依赖的库链接到了一起, 使得我们的程序可以正常且正确地运行!

那么, 其他同在代码段的函数会被执行吗? 会的, 将在main函数被执行的之前或之后!

论应用程序是如何跑起来的:

  在默认的Linux gcc编译出来的应用程序, 程序加载后, _init()是第一个被调用执行的函数. 具体的流程如下: (我们可以使用objdump来验证我们的说法)
$objdump -d file
file:     file format elf64-x86-64

Disassembly of section .init:

00000000000005a0 <_init>:
 5a0:	48 83 ec 08          	sub    $0x8,%rsp
 5a4:	48 8d 05 95 00 00 00 	lea    0x95(%rip),%rax        # 640 <__gmon_start__>
 5ab:	48 85 c0             	test   %rax,%rax
 5ae:	74 02                	je     5b2 <_init+0x12>
 5b0:	ff d0                	callq  *%rax
 5b2:	48 83 c4 08          	add    $0x8,%rsp
 5b6:	c3                   	retq   

Disassembly of section .plt:

00000000000005c0 <.plt>:
 5c0:	ff 35 e2 09 20 00    	pushq  0x2009e2(%rip)        # 200fa8 <_GLOBAL_OFFSET_TABLE_+0x8>
 5c6:	ff 25 e4 09 20 00    	jmpq   *0x2009e4(%rip)        # 200fb0 <_GLOBAL_OFFSET_TABLE_+0x10>
 5cc:	0f 1f 40 00          	nopl   0x0(%rax)

00000000000005d0 <puts@plt>:
 5d0:	ff 25 e2 09 20 00    	jmpq   *0x2009e2(%rip)        # 200fb8 <puts@GLIBC_2.2.5>
 5d6:	68 00 00 00 00       	pushq  $0x0
 5db:	e9 e0 ff ff ff       	jmpq   5c0 <.plt>

00000000000005e0 <__monstartup@plt>:
 5e0:	ff 25 da 09 20 00    	jmpq   *0x2009da(%rip)        # 200fc0 <__monstartup@GLIBC_2.2.5>
 5e6:	68 01 00 00 00       	pushq  $0x1
 5eb:	e9 d0 ff ff ff       	jmpq   5c0 <.plt>

00000000000005f0 <__cxa_atexit@plt>:
 5f0:	ff 25 d2 09 20 00    	jmpq   *0x2009d2(%rip)        # 200fc8 <__cxa_atexit@GLIBC_2.2.5>
 5f6:	68 02 00 00 00       	pushq  $0x2
 5fb:	e9 c0 ff ff ff       	jmpq   5c0 <.plt>

Disassembly of section .plt.got:

0000000000000600 <__cxa_finalize@plt>:
 600:	ff 25 f2 09 20 00    	jmpq   *0x2009f2(%rip)        # 200ff8 <__cxa_finalize@GLIBC_2.2.5>
 606:	66 90                	xchg   %ax,%ax

Disassembly of section .text:

0000000000000610 <_start>:
 610:	31 ed                	xor    %ebp,%ebp
 612:	49 89 d1             	mov    %rdx,%r9
 615:	5e                   	pop    %rsi
 616:	48 89 e2             	mov    %rsp,%rdx
 619:	48 83 e4 f0          	and    $0xfffffffffffffff0,%rsp
 61d:	50                   	push   %rax
 61e:	54                   	push   %rsp
 61f:	4c 8d 05 fa 01 00 00 	lea    0x1fa(%rip),%r8        # 820 <__libc_csu_fini>
 626:	48 8d 0d 83 01 00 00 	lea    0x183(%rip),%rcx        # 7b0 <__libc_csu_init>
 62d:	48 8d 3d 5f 01 00 00 	lea    0x15f(%rip),%rdi        # 793 <main>
 634:	ff 15 a6 09 20 00    	callq  *0x2009a6(%rip)        # 200fe0 <__libc_start_main@GLIBC_2.2.5>
 63a:	f4                   	hlt    
 63b:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)

0000000000000640 <__gmon_start__>:
 640:	8b 05 ca 09 20 00    	mov    0x2009ca(%rip),%eax        # 201010 <__TMC_END__>
 646:	85 c0                	test   %eax,%eax
 648:	74 06                	je     650 <__gmon_start__+0x10>
 64a:	f3 c3                	repz retq 
 64c:	0f 1f 40 00          	nopl   0x0(%rax)
 650:	48 83 ec 08          	sub    $0x8,%rsp
 654:	48 8d 3d b5 ff ff ff 	lea    -0x4b(%rip),%rdi        # 610 <_start>
 65b:	48 8d 35 e7 01 00 00 	lea    0x1e7(%rip),%rsi        # 849 <etext>
 662:	c7 05 a4 09 20 00 01 	movl   $0x1,0x2009a4(%rip)        # 201010 <__TMC_END__>
 669:	00 00 00 
 66c:	e8 6f ff ff ff       	callq  5e0 <__monstartup@plt>
 671:	48 8b 3d 60 09 20 00 	mov    0x200960(%rip),%rdi        # 200fd8 <_mcleanup@GLIBC_2.2.5>
 678:	48 83 c4 08          	add    $0x8,%rsp
 67c:	e9 af 01 00 00       	jmpq   830 <atexit>
 681:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
 688:	00 00 00 
 68b:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)

0000000000000690 <_dl_relocate_static_pie>:
 690:	f3 c3                	repz retq 
 692:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
 699:	00 00 00 
 69c:	0f 1f 40 00          	nopl   0x0(%rax)

00000000000006a0 <deregister_tm_clones>:
 6a0:	48 8d 3d 69 09 20 00 	lea    0x200969(%rip),%rdi        # 201010 <__TMC_END__>
 6a7:	55                   	push   %rbp
 6a8:	48 8d 05 61 09 20 00 	lea    0x200961(%rip),%rax        # 201010 <__TMC_END__>
 6af:	48 39 f8             	cmp    %rdi,%rax
 6b2:	48 89 e5             	mov    %rsp,%rbp
 6b5:	74 19                	je     6d0 <deregister_tm_clones+0x30>
 6b7:	48 8b 05 12 09 20 00 	mov    0x200912(%rip),%rax        # 200fd0 <_ITM_deregisterTMCloneTable>
 6be:	48 85 c0             	test   %rax,%rax
 6c1:	74 0d                	je     6d0 <deregister_tm_clones+0x30>
 6c3:	5d                   	pop    %rbp
 6c4:	ff e0                	jmpq   *%rax
 6c6:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
 6cd:	00 00 00 
 6d0:	5d                   	pop    %rbp
 6d1:	c3                   	retq   
 6d2:	0f 1f 40 00          	nopl   0x0(%rax)
 6d6:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
 6dd:	00 00 00 

00000000000006e0 <register_tm_clones>:
 6e0:	48 8d 3d 29 09 20 00 	lea    0x200929(%rip),%rdi        # 201010 <__TMC_END__>
 6e7:	48 8d 35 22 09 20 00 	lea    0x200922(%rip),%rsi        # 201010 <__TMC_END__>
 6ee:	55                   	push   %rbp
 6ef:	48 29 fe             	sub    %rdi,%rsi
 6f2:	48 89 e5             	mov    %rsp,%rbp
 6f5:	48 c1 fe 03          	sar    $0x3,%rsi
 6f9:	48 89 f0             	mov    %rsi,%rax
 6fc:	48 c1 e8 3f          	shr    $0x3f,%rax
 700:	48 01 c6             	add    %rax,%rsi
 703:	48 d1 fe             	sar    %rsi
 706:	74 18                	je     720 <register_tm_clones+0x40>
 708:	48 8b 05 e1 08 20 00 	mov    0x2008e1(%rip),%rax        # 200ff0 <_ITM_registerTMCloneTable>
 70f:	48 85 c0             	test   %rax,%rax
 712:	74 0c                	je     720 <register_tm_clones+0x40>
 714:	5d                   	pop    %rbp
 715:	ff e0                	jmpq   *%rax
 717:	66 0f 1f 84 00 00 00 	nopw   0x0(%rax,%rax,1)
 71e:	00 00 
 720:	5d                   	pop    %rbp
 721:	c3                   	retq   
 722:	0f 1f 40 00          	nopl   0x0(%rax)
 726:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
 72d:	00 00 00 

0000000000000730 <__do_global_dtors_aux>:
 730:	80 3d dd 08 20 00 00 	cmpb   $0x0,0x2008dd(%rip)        # 201014 <completed.7698>
 737:	75 2f                	jne    768 <__do_global_dtors_aux+0x38>
 739:	48 83 3d b7 08 20 00 	cmpq   $0x0,0x2008b7(%rip)        # 200ff8 <__cxa_finalize@GLIBC_2.2.5>
 740:	00 
 741:	55                   	push   %rbp
 742:	48 89 e5             	mov    %rsp,%rbp
 745:	74 0c                	je     753 <__do_global_dtors_aux+0x23>
 747:	48 8b 3d ba 08 20 00 	mov    0x2008ba(%rip),%rdi        # 201008 <__dso_handle>
 74e:	e8 ad fe ff ff       	callq  600 <__cxa_finalize@plt>
 753:	e8 48 ff ff ff       	callq  6a0 <deregister_tm_clones>
 758:	c6 05 b5 08 20 00 01 	movb   $0x1,0x2008b5(%rip)        # 201014 <completed.7698>
 75f:	5d                   	pop    %rbp
 760:	c3                   	retq   
 761:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)
 768:	f3 c3                	repz retq 
 76a:	66 0f 1f 44 00 00    	nopw   0x0(%rax,%rax,1)

0000000000000770 <frame_dummy>:
 770:	55                   	push   %rbp
 771:	48 89 e5             	mov    %rsp,%rbp
 774:	5d                   	pop    %rbp
 775:	e9 66 ff ff ff       	jmpq   6e0 <register_tm_clones>

000000000000077a <func>:
 77a:	55                   	push   %rbp
 77b:	48 89 e5             	mov    %rsp,%rbp
 77e:	ff 15 64 08 20 00    	callq  *0x200864(%rip)        # 200fe8 <mcount@GLIBC_2.2.5>
 784:	48 8d 3d c5 00 00 00 	lea    0xc5(%rip),%rdi        # 850 <_IO_stdin_used+0x4>
 78b:	e8 40 fe ff ff       	callq  5d0 <puts@plt>
 790:	90                   	nop
 791:	5d                   	pop    %rbp
 792:	c3                   	retq   

0000000000000793 <main>:
 793:	55                   	push   %rbp
 794:	48 89 e5             	mov    %rsp,%rbp
 797:	ff 15 4b 08 20 00    	callq  *0x20084b(%rip)        # 200fe8 <mcount@GLIBC_2.2.5>
 79d:	e8 d8 ff ff ff       	callq  77a <func>
 7a2:	b8 00 00 00 00       	mov    $0x0,%eax
 7a7:	5d                   	pop    %rbp
 7a8:	c3                   	retq   
 7a9:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)

00000000000007b0 <__libc_csu_init>:
 7b0:	41 57                	push   %r15
 7b2:	41 56                	push   %r14
 7b4:	49 89 d7             	mov    %rdx,%r15
 7b7:	41 55                	push   %r13
 7b9:	41 54                	push   %r12
 7bb:	4c 8d 25 de 05 20 00 	lea    0x2005de(%rip),%r12        # 200da0 <__frame_dummy_init_array_entry>
 7c2:	55                   	push   %rbp
 7c3:	48 8d 2d de 05 20 00 	lea    0x2005de(%rip),%rbp        # 200da8 <__init_array_end>
 7ca:	53                   	push   %rbx
 7cb:	41 89 fd             	mov    %edi,%r13d
 7ce:	49 89 f6             	mov    %rsi,%r14
 7d1:	4c 29 e5             	sub    %r12,%rbp
 7d4:	48 83 ec 08          	sub    $0x8,%rsp
 7d8:	48 c1 fd 03          	sar    $0x3,%rbp
 7dc:	e8 bf fd ff ff       	callq  5a0 <_init>
 7e1:	48 85 ed             	test   %rbp,%rbp
 7e4:	74 20                	je     806 <__libc_csu_init+0x56>
 7e6:	31 db                	xor    %ebx,%ebx
 7e8:	0f 1f 84 00 00 00 00 	nopl   0x0(%rax,%rax,1)
 7ef:	00 
 7f0:	4c 89 fa             	mov    %r15,%rdx
 7f3:	4c 89 f6             	mov    %r14,%rsi
 7f6:	44 89 ef             	mov    %r13d,%edi
 7f9:	41 ff 14 dc          	callq  *(%r12,%rbx,8)
 7fd:	48 83 c3 01          	add    $0x1,%rbx
 801:	48 39 dd             	cmp    %rbx,%rbp
 804:	75 ea                	jne    7f0 <__libc_csu_init+0x40>
 806:	48 83 c4 08          	add    $0x8,%rsp
 80a:	5b                   	pop    %rbx
 80b:	5d                   	pop    %rbp
 80c:	41 5c                	pop    %r12
 80e:	41 5d                	pop    %r13
 810:	41 5e                	pop    %r14
 812:	41 5f                	pop    %r15
 814:	c3                   	retq   
 815:	90                   	nop
 816:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
 81d:	00 00 00 

0000000000000820 <__libc_csu_fini>:
 820:	f3 c3                	repz retq 
 822:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
 829:	00 00 00 
 82c:	0f 1f 40 00          	nopl   0x0(%rax)

0000000000000830 <atexit>:
 830:	48 8b 15 d1 07 20 00 	mov    0x2007d1(%rip),%rdx        # 201008 <__dso_handle>
 837:	31 f6                	xor    %esi,%esi
 839:	e9 b2 fd ff ff       	jmpq   5f0 <__cxa_atexit@plt>

Disassembly of section .fini:

0000000000000840 <_fini>:
 840:	48 83 ec 08          	sub    $0x8,%rsp
 844:	48 83 c4 08          	add    $0x8,%rsp
 848:	c3                   	retq   

_init
	__gmon_start__
		_start
			main
			....

可见, 链接器为我们main()函数的正确运行做了许多工作, 使得我们不需要在意这些通用且重要的事情, 这也告诉了我们, 为什么我们的主程序需要是main(), 因为链接器在链接时, 只会找这个main()函数!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安河桥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值