GCC编译器原理(二)------编译原理一:目标文件

时间:2021-03-19 02:38:37

一、目标文件

在 UNIX® 和 Linux® 中,任何事物都是文件。UNIX 和 Linux 编程实际上是编写处理各种文件的代码。系统由许多类型的文件组成,但目标文件具有一种特殊的设计,提供了灵活和多样的用途。

目标文件是包含带有附加地址和值的助记符号的路线图。这些符号可以用来对各种代码段和数据段进行命名,包括经过初始化的和未初始化的。它们也可以用来定位嵌入的调试信息,就像语义 Web,非常适合由程序进行阅读。

编译器可以将我们在代码编辑器中创建的文本转换为目标文件。最初,目标文件被称为代码的中间表示形式,因为它用作连接编辑器(即连接器)的输入,而连接编辑器最终完成整个任务并生成可执行的程序作为输出。

从代码到可执行代码的转换过程经过了良好的定义并实现了自动化,而目标文件是这个链中有机的连接性环节。在这个转换过程中,目标文件作为连接编辑器所使用的映象,使得它们能够解析各种符号并将不同的代码和数据段连接在一起形成统一的整体。

1.1 目标文件的格式

计算机编程领域中存在许多著名的目标文件格式。DOS 系列包括 COM、OBJ 和 EXE 格式。UNIX 和 Linux 使用 a.out、COFF 和 ELF。Microsoft® Windows® 使用可移植的执行文件 (PE) 格式,而 Macintosh 使用 PEF、Mach-O 和其他文件格式。

最初,各种类型的计算机具有自己独特的目标文件格式,但随着 UNIX 和其他在不同硬件平台上提供可移植性的操作系统的出现,一些常用的文件格式上升为通用的标准。其中包括 a.out、COFF 和 ELF 格式。

要了解目标文件,需要一组可以读取目标文件中不同部分并以更易于读取的格式显示这些内容的工具。

1.2 UNIX 目标文件

写一个简单的程序:hello.c

GCC编译器原理(二)------编译原理一:目标文件

C 编译器的正常输出是用于所指定的目标处理器的汇编代码。汇编代码是汇编器的输入,在缺省情况下,汇编器将生成所有目标文件的祖先,即 a.out 文件。这个名称本身表示汇编输出 (Assembler Output)。要创建 a.out 文件,可以在 shell 窗口中输入下面的命令:gcc hello.c

最新的 C 编译器将编译和汇编步骤组合成一个步骤。我们可以指定不同开关选项以查看 C 编译器的汇编输出。通过输入下面的命令,我们可以看到 C 编译器的汇编输出:gcc -S hello.c

GCC编译器原理(二)------编译原理一:目标文件

在当前目录下会生成 hello.s 文件,即为汇编输入文本。

  • 接下来研究目标文件,其中使用的有价值的工具有:
    • nm:列出目标文件中的符号。
    • objdump:显示目标文件中的详细信息。
    • readelf:显示关于 ELF 目标文件的信息。

1.2.1 nm:列出目标文件中的符号

执行命令:nm a.out

GCC编译器原理(二)------编译原理一:目标文件

这些包含可执行代码的段称为正文段。同样地,数据段包含了不可执行的信息或数据。另一种类型的段,称为 BSS 段,它包含以符号数据开头的块。

对于 nm 命令列出的每个符号,它们的值使用十六进制来表示(缺省行为),并且在该符号前面加上了一个表示符号类型的编码字符。

  • 常见的各种编码包括:
    • A 表示绝对 (absolute),这意味着不能将该值更改为其他的连接;
    • B 表示 BSS 段中的符号;
    • C 表示引用未初始化的数据的一般符号。

可以将目标文件中所包含的不同的部分划分为段。段可以包含可执行代码、符号名称、初始数据值和许多其他类型的数据。

1.2.2 objdump:显示目标文件中的详细信息

通过输入下面的命令,可以看到目标文件中包含可执行代码的每个段的汇编清单。

objdump -d a.out

命令生成的代码如下所示:

GCC编译器原理(二)------编译原理一:目标文件GCC编译器原理(二)------编译原理一:目标文件
  1 a.out:     file format elf64-x86-64
  2 
  3 
  4 Disassembly of section .init:
  5 
  6 00000000004003c8 <_init>:
  7   4003c8:   48 83 ec 08             sub    $0x8,%rsp
  8   4003cc:   48 8b 05 25 0c 20 00    mov    0x200c25(%rip),%rax        # 600ff8 <_DYNAMIC+0x1d0>
  9   4003d3:   48 85 c0                test   %rax,%rax
 10   4003d6:   74 05                   je     4003dd <_init+0x15>
 11   4003d8:   e8 43 00 00 00          callq  400420 <__libc_start_main@plt+0x10>
 12   4003dd:   48 83 c4 08             add    $0x8,%rsp
 13   4003e1:   c3                      retq   
 14 
 15 Disassembly of section .plt:
 16 
 17 00000000004003f0 <puts@plt-0x10>:
 18   4003f0:   ff 35 12 0c 20 00       pushq  0x200c12(%rip)        # 601008 <_GLOBAL_OFFSET_TABLE_+0x8>
 19   4003f6:   ff 25 14 0c 20 00       jmpq   *0x200c14(%rip)        # 601010 <_GLOBAL_OFFSET_TABLE_+0x10>
 20   4003fc:   0f 1f 40 00             nopl   0x0(%rax)
 21 
 22 0000000000400400 <puts@plt>:
 23   400400:   ff 25 12 0c 20 00       jmpq   *0x200c12(%rip)        # 601018 <_GLOBAL_OFFSET_TABLE_+0x18>
 24   400406:   68 00 00 00 00          pushq  $0x0
 25   40040b:   e9 e0 ff ff ff          jmpq   4003f0 <_init+0x28>
 26 
 27 0000000000400410 <__libc_start_main@plt>:
 28   400410:   ff 25 0a 0c 20 00       jmpq   *0x200c0a(%rip)        # 601020 <_GLOBAL_OFFSET_TABLE_+0x20>
 29   400416:   68 01 00 00 00          pushq  $0x1
 30   40041b:   e9 d0 ff ff ff          jmpq   4003f0 <_init+0x28>
 31 
 32 Disassembly of section .plt.got:
 33 
 34 0000000000400420 <.plt.got>:
 35   400420:   ff 25 d2 0b 20 00       jmpq   *0x200bd2(%rip)        # 600ff8 <_DYNAMIC+0x1d0>
 36   400426:   66 90                   xchg   %ax,%ax
 37 
 38 Disassembly of section .text:
 39 
 40 0000000000400430 <_start>:
 41   400430:   31 ed                   xor    %ebp,%ebp
 42   400432:   49 89 d1                mov    %rdx,%r9
 43   400435:   5e                      pop    %rsi
 44   400436:   48 89 e2                mov    %rsp,%rdx
 45   400439:   48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
 46   40043d:   50                      push   %rax
 47   40043e:   54                      push   %rsp
 48   40043f:   49 c7 c0 c0 05 40 00    mov    $0x4005c0,%r8
 49   400446:   48 c7 c1 50 05 40 00    mov    $0x400550,%rcx
 50   40044d:   48 c7 c7 26 05 40 00    mov    $0x400526,%rdi
 51   400454:   e8 b7 ff ff ff          callq  400410 <__libc_start_main@plt>
 52   400459:   f4                      hlt    
 53   40045a:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
 54 
 55 0000000000400460 <deregister_tm_clones>:
 56   400460:   b8 3f 10 60 00          mov    $0x60103f,%eax
 57   400465:   55                      push   %rbp
 58   400466:   48 2d 38 10 60 00       sub    $0x601038,%rax
 59   40046c:   48 83 f8 0e             cmp    $0xe,%rax
 60   400470:   48 89 e5                mov    %rsp,%rbp
 61   400473:   76 1b                   jbe    400490 <deregister_tm_clones+0x30>
 62   400475:   b8 00 00 00 00          mov    $0x0,%eax
 63   40047a:   48 85 c0                test   %rax,%rax
 64   40047d:   74 11                   je     400490 <deregister_tm_clones+0x30>
 65   40047f:   5d                      pop    %rbp
 66   400480:   bf 38 10 60 00          mov    $0x601038,%edi
 67   400485:   ff e0                   jmpq   *%rax
 68   400487:   66 0f 1f 84 00 00 00    nopw   0x0(%rax,%rax,1)
 69   40048e:   00 00 
 70   400490:   5d                      pop    %rbp
 71   400491:   c3                      retq   
 72   400492:   0f 1f 40 00             nopl   0x0(%rax)
 73   400496:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
 74   40049d:   00 00 00 
 75 
 76 00000000004004a0 <register_tm_clones>:
 77   4004a0:   be 38 10 60 00          mov    $0x601038,%esi
 78   4004a5:   55                      push   %rbp
 79   4004a6:   48 81 ee 38 10 60 00    sub    $0x601038,%rsi
 80   4004ad:   48 c1 fe 03             sar    $0x3,%rsi
 81   4004b1:   48 89 e5                mov    %rsp,%rbp
 82   4004b4:   48 89 f0                mov    %rsi,%rax
 83   4004b7:   48 c1 e8 3f             shr    $0x3f,%rax
 84   4004bb:   48 01 c6                add    %rax,%rsi
 85   4004be:   48 d1 fe                sar    %rsi
 86   4004c1:   74 15                   je     4004d8 <register_tm_clones+0x38>
 87   4004c3:   b8 00 00 00 00          mov    $0x0,%eax
 88   4004c8:   48 85 c0                test   %rax,%rax
 89   4004cb:   74 0b                   je     4004d8 <register_tm_clones+0x38>
 90   4004cd:   5d                      pop    %rbp
 91   4004ce:   bf 38 10 60 00          mov    $0x601038,%edi
 92   4004d3:   ff e0                   jmpq   *%rax
 93   4004d5:   0f 1f 00                nopl   (%rax)
 94   4004d8:   5d                      pop    %rbp
 95   4004d9:   c3                      retq   
 96   4004da:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
 97 
 98 00000000004004e0 <__do_global_dtors_aux>:
 99   4004e0:   80 3d 51 0b 20 00 00    cmpb   $0x0,0x200b51(%rip)        # 601038 <__TMC_END__>
100   4004e7:   75 11                   jne    4004fa <__do_global_dtors_aux+0x1a>
101   4004e9:   55                      push   %rbp
102   4004ea:   48 89 e5                mov    %rsp,%rbp
103   4004ed:   e8 6e ff ff ff          callq  400460 <deregister_tm_clones>
104   4004f2:   5d                      pop    %rbp
105   4004f3:   c6 05 3e 0b 20 00 01    movb   $0x1,0x200b3e(%rip)        # 601038 <__TMC_END__>
106   4004fa:   f3 c3                   repz retq 
107   4004fc:   0f 1f 40 00             nopl   0x0(%rax)
108 
109 0000000000400500 <frame_dummy>:
110   400500:   bf 20 0e 60 00          mov    $0x600e20,%edi
111   400505:   48 83 3f 00             cmpq   $0x0,(%rdi)
112   400509:   75 05                   jne    400510 <frame_dummy+0x10>
113   40050b:   eb 93                   jmp    4004a0 <register_tm_clones>
114   40050d:   0f 1f 00                nopl   (%rax)
115   400510:   b8 00 00 00 00          mov    $0x0,%eax
116   400515:   48 85 c0                test   %rax,%rax
117   400518:   74 f1                   je     40050b <frame_dummy+0xb>
118   40051a:   55                      push   %rbp
119   40051b:   48 89 e5                mov    %rsp,%rbp
120   40051e:   ff d0                   callq  *%rax
121   400520:   5d                      pop    %rbp
122   400521:   e9 7a ff ff ff          jmpq   4004a0 <register_tm_clones>
123 
124 0000000000400526 <main>:
125   400526:   55                      push   %rbp
126   400527:   48 89 e5                mov    %rsp,%rbp
127   40052a:   48 83 ec 10             sub    $0x10,%rsp
128   40052e:   89 7d fc                mov    %edi,-0x4(%rbp)
129   400531:   48 89 75 f0             mov    %rsi,-0x10(%rbp)
130   400535:   bf d4 05 40 00          mov    $0x4005d4,%edi
131   40053a:   e8 c1 fe ff ff          callq  400400 <puts@plt>
132   40053f:   b8 00 00 00 00          mov    $0x0,%eax
133   400544:   c9                      leaveq 
134   400545:   c3                      retq   
135   400546:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
136   40054d:   00 00 00 
137 
138 0000000000400550 <__libc_csu_init>:
139   400550:   41 57                   push   %r15
140   400552:   41 56                   push   %r14
141   400554:   41 89 ff                mov    %edi,%r15d
142   400557:   41 55                   push   %r13
143   400559:   41 54                   push   %r12
144   40055b:   4c 8d 25 ae 08 20 00    lea    0x2008ae(%rip),%r12        # 600e10 <__frame_dummy_init_array_entry>
145   400562:   55                      push   %rbp
146   400563:   48 8d 2d ae 08 20 00    lea    0x2008ae(%rip),%rbp        # 600e18 <__init_array_end>
147   40056a:   53                      push   %rbx
148   40056b:   49 89 f6                mov    %rsi,%r14
149   40056e:   49 89 d5                mov    %rdx,%r13
150   400571:   4c 29 e5                sub    %r12,%rbp
151   400574:   48 83 ec 08             sub    $0x8,%rsp
152   400578:   48 c1 fd 03             sar    $0x3,%rbp
153   40057c:   e8 47 fe ff ff          callq  4003c8 <_init>
154   400581:   48 85 ed                test   %rbp,%rbp
155   400584:   74 20                   je     4005a6 <__libc_csu_init+0x56>
156   400586:   31 db                   xor    %ebx,%ebx
157   400588:   0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)
158   40058f:   00 
159   400590:   4c 89 ea                mov    %r13,%rdx
160   400593:   4c 89 f6                mov    %r14,%rsi
161   400596:   44 89 ff                mov    %r15d,%edi
162   400599:   41 ff 14 dc             callq  *(%r12,%rbx,8)
163   40059d:   48 83 c3 01             add    $0x1,%rbx
164   4005a1:   48 39 eb                cmp    %rbp,%rbx
165   4005a4:   75 ea                   jne    400590 <__libc_csu_init+0x40>
166   4005a6:   48 83 c4 08             add    $0x8,%rsp
167   4005aa:   5b                      pop    %rbx
168   4005ab:   5d                      pop    %rbp
169   4005ac:   41 5c                   pop    %r12
170   4005ae:   41 5d                   pop    %r13
171   4005b0:   41 5e                   pop    %r14
172   4005b2:   41 5f                   pop    %r15
173   4005b4:   c3                      retq   
174   4005b5:   90                      nop
175   4005b6:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
176   4005bd:   00 00 00 
177 
178 00000000004005c0 <__libc_csu_fini>:
179   4005c0:   f3 c3                   repz retq 
180 
181 Disassembly of section .fini:
182 
183 00000000004005c4 <_fini>:
184   4005c4:   48 83 ec 08             sub    $0x8,%rsp
185   4005c8:   48 83 c4 08             add    $0x8,%rsp
186   4005cc:   c3                      retq 
View Code

 

 

每个可执行代码段将在需要特定的事件时执行,这些事件包括库的初始化和该程序本身主入口点。

对于着迷于底层编程细节的程序员来说,这是一个功能非常强大的工具,可用于研究编译器和汇编器的输出。细节信息,比如这段代码中所显示的这些信息,可以揭示有关本地处理器本身运行方式的很多内容。对该处理器制造商提供的技术文档进行深入的研究,我们可以收集关于一些有价值的信息,通过这些信息可以深入地了解内部的运行机制,因为功能程序提供了清晰的输出。

1.2.3 readelf:显示关于 ELF 目标文件的信息

readelf 程序也可以清楚地列出目标文件中的内容。输入下面的命令,可以看到这一点:

readelf -all a.out

输出如下:

GCC编译器原理(二)------编译原理一:目标文件GCC编译器原理(二)------编译原理一:目标文件
  1 ELF Header:
  2   Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  3   Class:                             ELF64
  4   Data:                              2's complement, little endian
  5   Version:                           1 (current)
  6   OS/ABI:                            UNIX - System V
  7   ABI Version:                       0
  8   Type:                              EXEC (Executable file)
  9   Machine:                           Advanced Micro Devices X86-64
 10   Version:                           0x1
 11   Entry point address:               0x400430
 12   Start of program headers:          64 (bytes into file)
 13   Start of section headers:          6616 (bytes into file)
 14   Flags:                             0x0
 15   Size of this header:               64 (bytes)
 16   Size of program headers:           56 (bytes)
 17   Number of program headers:         9
 18   Size of section headers:           64 (bytes)
 19   Number of section headers:         31
 20   Section header string table index: 28
 21 
 22 Section Headers:
 23   [Nr] Name              Type             Address           Offset
 24        Size              EntSize          Flags  Link  Info  Align
 25   [ 0]                   NULL             0000000000000000  00000000
 26        0000000000000000  0000000000000000           0     0     0
 27   [ 1] .interp           PROGBITS         0000000000400238  00000238
 28        000000000000001c  0000000000000000   A       0     0     1
 29   [ 2] .note.ABI-tag     NOTE             0000000000400254  00000254
 30        0000000000000020  0000000000000000   A       0     0     4
 31   [ 3] .note.gnu.build-i NOTE             0000000000400274  00000274
 32        0000000000000024  0000000000000000   A       0     0     4
 33   [ 4] .gnu.hash         GNU_HASH         0000000000400298  00000298
 34        000000000000001c  0000000000000000   A       5     0     8
 35   [ 5] .dynsym           DYNSYM           00000000004002b8  000002b8
 36        0000000000000060  0000000000000018   A       6     1     8
 37   [ 6] .dynstr           STRTAB           0000000000400318  00000318
 38        000000000000003d  0000000000000000   A       0     0     1
 39   [ 7] .gnu.version      VERSYM           0000000000400356  00000356
 40        0000000000000008  0000000000000002   A       5     0     2
 41   [ 8] .gnu.version_r    VERNEED          0000000000400360  00000360
 42        0000000000000020  0000000000000000   A       6     1     8
 43   [ 9] .rela.dyn         RELA             0000000000400380  00000380
 44        0000000000000018  0000000000000018   A       5     0     8
 45   [10] .rela.plt         RELA             0000000000400398  00000398
 46        0000000000000030  0000000000000018  AI       5    24     8
 47   [11] .init             PROGBITS         00000000004003c8  000003c8
 48        000000000000001a  0000000000000000  AX       0     0     4
 49   [12] .plt              PROGBITS         00000000004003f0  000003f0
 50        0000000000000030  0000000000000010  AX       0     0     16
 51   [13] .plt.got          PROGBITS         0000000000400420  00000420
 52        0000000000000008  0000000000000000  AX       0     0     8
 53   [14] .text             PROGBITS         0000000000400430  00000430
 54        0000000000000192  0000000000000000  AX       0     0     16
 55   [15] .fini             PROGBITS         00000000004005c4  000005c4
 56        0000000000000009  0000000000000000  AX       0     0     4
 57   [16] .rodata           PROGBITS         00000000004005d0  000005d0
 58        0000000000000011  0000000000000000   A       0     0     4
 59   [17] .eh_frame_hdr     PROGBITS         00000000004005e4  000005e4
 60        0000000000000034  0000000000000000   A       0     0     4
 61   [18] .eh_frame         PROGBITS         0000000000400618  00000618
 62        00000000000000f4  0000000000000000   A       0     0     8
 63   [19] .init_array       INIT_ARRAY       0000000000600e10  00000e10
 64        0000000000000008  0000000000000000  WA       0     0     8
 65   [20] .fini_array       FINI_ARRAY       0000000000600e18  00000e18
 66        0000000000000008  0000000000000000  WA       0     0     8
 67   [21] .jcr              PROGBITS         0000000000600e20  00000e20
 68        0000000000000008  0000000000000000  WA       0     0     8
 69   [22] .dynamic          DYNAMIC          0000000000600e28  00000e28
 70        00000000000001d0  0000000000000010  WA       6     0     8
 71   [23] .got              PROGBITS         0000000000600ff8  00000ff8
 72        0000000000000008  0000000000000008  WA       0     0     8
 73   [24] .got.plt          PROGBITS         0000000000601000  00001000
 74        0000000000000028  0000000000000008  WA       0     0     8
 75   [25] .data             PROGBITS         0000000000601028  00001028
 76        0000000000000010  0000000000000000  WA       0     0     8
 77   [26] .bss              NOBITS           0000000000601038  00001038
 78        0000000000000008  0000000000000000  WA       0     0     1
 79   [27] .comment          PROGBITS         0000000000000000  00001038
 80        0000000000000035  0000000000000001  MS       0     0     1
 81   [28] .shstrtab         STRTAB           0000000000000000  000018cc
 82        000000000000010c  0000000000000000           0     0     1
 83   [29] .symtab           SYMTAB           0000000000000000  00001070
 84        0000000000000648  0000000000000018          30    47     8
 85   [30] .strtab           STRTAB           0000000000000000  000016b8
 86        0000000000000214  0000000000000000           0     0     1
 87 Key to Flags:
 88   W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
 89   I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
 90   O (extra OS processing required) o (OS specific), p (processor specific)
 91 
 92 There are no section groups in this file.
 93 
 94 Program Headers:
 95   Type           Offset             VirtAddr           PhysAddr
 96                  FileSiz            MemSiz              Flags  Align
 97   PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
 98                  0x00000000000001f8 0x00000000000001f8  R E    8
 99   INTERP         0x0000000000000238 0x0000000000400238 0x0000000000400238
100                  0x000000000000001c 0x000000000000001c  R      1
101       [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
102   LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
103                  0x000000000000070c 0x000000000000070c  R E    200000
104   LOAD           0x0000000000000e10 0x0000000000600e10 0x0000000000600e10
105                  0x0000000000000228 0x0000000000000230  RW     200000
106   DYNAMIC        0x0000000000000e28 0x0000000000600e28 0x0000000000600e28
107                  0x00000000000001d0 0x00000000000001d0  RW     8
108   NOTE           0x0000000000000254 0x0000000000400254 0x0000000000400254
109                  0x0000000000000044 0x0000000000000044  R      4
110   GNU_EH_FRAME   0x00000000000005e4 0x00000000004005e4 0x00000000004005e4
111                  0x0000000000000034 0x0000000000000034  R      4
112   GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
113                  0x0000000000000000 0x0000000000000000  RW     10
114   GNU_RELRO      0x0000000000000e10 0x0000000000600e10 0x0000000000600e10
115                  0x00000000000001f0 0x00000000000001f0  R      1
116 
117  Section to Segment mapping:
118   Segment Sections...
119    00     
120    01     .interp 
121    02     .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame 
122    03     .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss 
123    04     .dynamic 
124    05     .note.ABI-tag .note.gnu.build-id 
125    06     .eh_frame_hdr 
126    07     
127    08     .init_array .fini_array .jcr .dynamic .got 
128 
129 Dynamic section at offset 0xe28 contains 24 entries:
130   Tag        Type                         Name/Value
131  0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
132  0x000000000000000c (INIT)               0x4003c8
133  0x000000000000000d (FINI)               0x4005c4
134  0x0000000000000019 (INIT_ARRAY)         0x600e10
135  0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
136  0x000000000000001a (FINI_ARRAY)         0x600e18
137  0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
138  0x000000006ffffef5 (GNU_HASH)           0x400298
139  0x0000000000000005 (STRTAB)             0x400318
140  0x0000000000000006 (SYMTAB)             0x4002b8
141  0x000000000000000a (STRSZ)              61 (bytes)
142  0x000000000000000b (SYMENT)             24 (bytes)
143  0x0000000000000015 (DEBUG)              0x0
144  0x0000000000000003 (PLTGOT)             0x601000
145  0x0000000000000002 (PLTRELSZ)           48 (bytes)
146  0x0000000000000014 (PLTREL)             RELA
147  0x0000000000000017 (JMPREL)             0x400398
148  0x0000000000000007 (RELA)               0x400380
149  0x0000000000000008 (RELASZ)             24 (bytes)
150  0x0000000000000009 (RELAENT)            24 (bytes)
151  0x000000006ffffffe (VERNEED)            0x400360
152  0x000000006fffffff (VERNEEDNUM)         1
153  0x000000006ffffff0 (VERSYM)             0x400356
154  0x0000000000000000 (NULL)               0x0
155 
156 Relocation section '.rela.dyn' at offset 0x380 contains 1 entries:
157   Offset          Info           Type           Sym. Value    Sym. Name + Addend
158 000000600ff8  000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
159 
160 Relocation section '.rela.plt' at offset 0x398 contains 2 entries:
161   Offset          Info           Type           Sym. Value    Sym. Name + Addend
162 000000601018  000100000007 R_X86_64_JUMP_SLO 0000000000000000 puts@GLIBC_2.2.5 + 0
163 000000601020  000200000007 R_X86_64_JUMP_SLO 0000000000000000 __libc_start_main@GLIBC_2.2.5 + 0
164 
165 The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
166 
167 Symbol table '.dynsym' contains 4 entries:
168    Num:    Value          Size Type    Bind   Vis      Ndx Name
169      0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
170      1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND puts@GLIBC_2.2.5 (2)
171      2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)
172      3: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
173 
174 Symbol table '.symtab' contains 67 entries:
175    Num:    Value          Size Type    Bind   Vis      Ndx Name
176      0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
177      1: 0000000000400238     0 SECTION LOCAL  DEFAULT    1 
178      2: 0000000000400254     0 SECTION LOCAL  DEFAULT    2 
179      3: 0000000000400274     0 SECTION LOCAL  DEFAULT    3 
180      4: 0000000000400298     0 SECTION LOCAL  DEFAULT    4 
181      5: 00000000004002b8     0 SECTION LOCAL  DEFAULT    5 
182      6: 0000000000400318     0 SECTION LOCAL  DEFAULT    6 
183      7: 0000000000400356     0 SECTION LOCAL  DEFAULT    7 
184      8: 0000000000400360     0 SECTION LOCAL  DEFAULT    8 
185      9: 0000000000400380     0 SECTION LOCAL  DEFAULT    9 
186     10: 0000000000400398     0 SECTION LOCAL  DEFAULT   10 
187     11: 00000000004003c8     0 SECTION LOCAL  DEFAULT   11 
188     12: 00000000004003f0     0 SECTION LOCAL  DEFAULT   12 
189     13: 0000000000400420     0 SECTION LOCAL  DEFAULT   13 
190     14: 0000000000400430     0 SECTION LOCAL  DEFAULT   14 
191     15: 00000000004005c4     0 SECTION LOCAL  DEFAULT   15 
192     16: 00000000004005d0     0 SECTION LOCAL  DEFAULT   16 
193     17: 00000000004005e4     0 SECTION LOCAL  DEFAULT   17 
194     18: 0000000000400618     0 SECTION LOCAL  DEFAULT   18 
195     19: 0000000000600e10     0 SECTION LOCAL  DEFAULT   19 
196     20: 0000000000600e18     0 SECTION LOCAL  DEFAULT   20 
197     21: 0000000000600e20     0 SECTION LOCAL  DEFAULT   21 
198     22: 0000000000600e28     0 SECTION LOCAL  DEFAULT   22 
199     23: 0000000000600ff8     0 SECTION LOCAL  DEFAULT   23 
200     24: 0000000000601000     0 SECTION LOCAL  DEFAULT   24 
201     25: 0000000000601028     0 SECTION LOCAL  DEFAULT   25 
202     26: 0000000000601038     0 SECTION LOCAL  DEFAULT   26 
203     27: 0000000000000000     0 SECTION LOCAL  DEFAULT   27 
204     28: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
205     29: 0000000000600e20     0 OBJECT  LOCAL  DEFAULT   21 __JCR_LIST__
206     30: 0000000000400460     0 FUNC    LOCAL  DEFAULT   14 deregister_tm_clones
207     31: 00000000004004a0     0 FUNC    LOCAL  DEFAULT   14 register_tm_clones
208     32: 00000000004004e0     0 FUNC    LOCAL  DEFAULT   14 __do_global_dtors_aux
209     33: 0000000000601038     1 OBJECT  LOCAL  DEFAULT   26 completed.7594
210     34: 0000000000600e18     0 OBJECT  LOCAL  DEFAULT   20 __do_global_dtors_aux_fin
211     35: 0000000000400500     0 FUNC    LOCAL  DEFAULT   14 frame_dummy
212     36: 0000000000600e10     0 OBJECT  LOCAL  DEFAULT   19 __frame_dummy_init_array_
213     37: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS hello.c
214     38: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
215     39: 0000000000400708     0 OBJECT  LOCAL  DEFAULT   18 __FRAME_END__
216     40: 0000000000600e20     0 OBJECT  LOCAL  DEFAULT   21 __JCR_END__
217     41: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 
218     42: 0000000000600e18     0 NOTYPE  LOCAL  DEFAULT   19 __init_array_end
219     43: 0000000000600e28     0 OBJECT  LOCAL  DEFAULT   22 _DYNAMIC
220     44: 0000000000600e10     0 NOTYPE  LOCAL  DEFAULT   19 __init_array_start
221     45: 00000000004005e4     0 NOTYPE  LOCAL  DEFAULT   17 __GNU_EH_FRAME_HDR
222     46: 0000000000601000     0 OBJECT  LOCAL  DEFAULT   24 _GLOBAL_OFFSET_TABLE_
223     47: 00000000004005c0     2 FUNC    GLOBAL DEFAULT   14 __libc_csu_fini
224     48: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTab
225     49: 0000000000601028     0 NOTYPE  WEAK   DEFAULT   25 data_start
226     50: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND puts@@GLIBC_2.2.5
227     51: 0000000000601038     0 NOTYPE  GLOBAL DEFAULT   25 _edata
228     52: 00000000004005c4     0 FUNC    GLOBAL DEFAULT   15 _fini
229     53: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_
230     54: 0000000000601028     0 NOTYPE  GLOBAL DEFAULT   25 __data_start
231     55: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
232     56: 0000000000601030     0 OBJECT  GLOBAL HIDDEN    25 __dso_handle
233     57: 00000000004005d0     4 OBJECT  GLOBAL DEFAULT   16 _IO_stdin_used
234     58: 0000000000400550   101 FUNC    GLOBAL DEFAULT   14 __libc_csu_init
235     59: 0000000000601040     0 NOTYPE  GLOBAL DEFAULT   26 _end
236     60: 0000000000400430    42 FUNC    GLOBAL DEFAULT   14 _start
237     61: 0000000000601038     0 NOTYPE  GLOBAL DEFAULT   26 __bss_start
238     62: 0000000000400526    32 FUNC    GLOBAL DEFAULT   14 main
239     63: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
240     64: 0000000000601038     0 OBJECT  GLOBAL HIDDEN    25 __TMC_END__
241     65: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable
242     66: 00000000004003c8     0 FUNC    GLOBAL DEFAULT   11 _init
243 
244 Version symbols section '.gnu.version' contains 4 entries:
245  Addr: 0000000000400356  Offset: 0x000356  Link: 5 (.dynsym)
246   000:   0 (*local*)       2 (GLIBC_2.2.5)   2 (GLIBC_2.2.5)   0 (*local*)    
247 
248 Version needs section '.gnu.version_r' contains 1 entries:
249  Addr: 0x0000000000400360  Offset: 0x000360  Link: 6 (.dynstr)
250   000000: Version: 1  File: libc.so.6  Cnt: 1
251   0x0010:   Name: GLIBC_2.2.5  Flags: none  Version: 2
252 
253 Displaying notes found at file offset 0x00000254 with length 0x00000020:
254   Owner                 Data size   Description
255   GNU                  0x00000010   NT_GNU_ABI_TAG (ABI version tag)
256     OS: Linux, ABI: 2.6.32
257 
258 Displaying notes found at file offset 0x00000274 with length 0x00000024:
259   Owner                 Data size   Description
260   GNU                  0x00000014   NT_GNU_BUILD_ID (unique build ID bitstring)
261     Build ID: c0f3db4f9706877127ed96aa53ddd338e1632814
View Code

 

 

ELF Header 为该文件中所有段入口显示了详细的摘要。在列举出这些 Header 中的内容之前,可以看到 Header 的具体数目。在研究一个较大的目标文件时,该信息可能非常有用。

从该输出中看到的,简单的 a.out Hello World 文件中包含了大量有价值的细节信息,包括版本信息、柱状图、各种符号类型的表格,等等。

除了所有这些段之外,编译器可以将调试信息放入到目标文件中,并且还可以显示这些信息。输入下面的命令,仔细分析编译器的输出(假设您扮演了调试程序的角色):readelf --debug-dump a.out | less

1.3 目标文件

在 UNIX 中,可执行文件是目标文件,并且我们可以像对 a.out 文件那样对它们进行分析。

如果倾向于使用编译器和其他的语言工具,那么您可以对组成计算机系统的各种目标文件进行仔细研究。UNIX 操作系统具有许多层次,那些通过工具查看目标文件所公开的层次,非常接近底层硬件。通过这种方式,可以真实地接触到系统。