gcc 简单的 hello-world 到底连接了什么

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. 动态链接器在共享库中查找这些符号的定义,完成链接过程。
objdump -x -d crt1.o
详细过程待叙。
------------------------------------------------------------
反汇编代码分析
------------------------------------------------------------
[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 ~]$

------------------------------------------------------------
代码执行分析.待叙。
------------------------------------------------------------


你可能感兴趣的:(gcc 简单的 hello-world 到底连接了什么)