在 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

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

  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

相关文章: