歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Unix知識 >> Unix基礎知識 >> UNIX目標文件初探

UNIX目標文件初探

日期:2017/3/3 15:25:46   编辑:Unix基礎知識

UNIX(R)系統中運行的程序遵守一種稱為目標文件格式的精心設計。了解更多關於目標文件格式的內容,以及可以用來研究系統中目標文件的工具。

計算機編程的最新技術將一種特殊的人性與一組特殊的工具結合在一起,用以生產出對其他人非常有幫助的一種神奇的產品,即軟件。計算機程序員是一群注重細節的人,他們可以處理計算機中各種各樣的困難。計算機的要求非常苛刻,並且不能容忍其中存在任何的偏差。毫無疑問,無論您的個性如何以及在工作中使用了何種輔助工具,計算機程序的編寫都是非常困難的。

在UNIX®和Linux®中,任何事物都是文件。您可以認為,UNIX和Linux編程實際上是編寫處理各種文件的代碼。系統由許多類型的文件組成,但目標文件具有一種特殊的設計,提供了靈活和多樣的用途。

目標文件是包含帶有附加地址和值的助記符號的路線圖。這些符號可以用來對各種代碼段和數據段進行命名,包括經過初始化的和未初始化的。它們也可以用來定位嵌入的調試信息,就像語義Web,非常適合由程序進行閱讀。

行業工具

計算機編程中使用的工具包括代碼編輯器,如vi或Emacs,您可以使用這些工具輸入和編輯希望計算機在完成所需任務時執行的指令,以及編譯器和連接器,它們可以生成真正實現這些目標的機器代碼。

高級的工具,稱為集成調試環境(IDE),它以統一的外觀集成了不同工具的功能。IDE使得編輯器、編譯器、連接器和調試器之間的界限變得很模糊。因此,為了更深入地研究和了解系統,在使用集成的套件之前,最好先單獨地使用這些工具。(注意:IDE也通常被稱為集成開發環境。)

編譯器可以將您在代碼編輯器中創建的文本轉換為目標文件。最初,目標文件被稱為代碼的中間表示形式,因為它用作連接編輯器(即連接器)的輸入,而連接編輯器最終完成整個任務並生成可執行的程序作為輸出。

從代碼到可執行代碼的轉換過程經過了良好的定義並實現了自動化,而目標文件是這個鏈中有機的連接性環節。在這個轉換過程中,目標文件作為連接編輯器所使用的映象,使得它們能夠解析各種符號並將不同的代碼和數據段連接在一起形成統一的整體。

歷史

計算機編程領域中存在許多著名的目標文件格式。DOS系列包括COM、OBJ和EXE格式。UNIX和Linux使用a.out、COFF和ELF。Microsoft® Windows® 使用可移植的執行文件(PE)格式,而Macintosh使用PEF、Mach-O和其他文件格式。

最初,各種類型的計算機具有自己獨特的目標文件格式,但隨著UNIX和其他在不同硬件平台上提供可移植性的操作系統的出現,一些常用的文件格式上升為通用的標准。其中包括a.out、COFF和ELF格式。

要了解目標文件,需要一組可以讀取目標文件中不同部分並以更易於讀取的格式顯示這些內容的工具。本文將討論這些工具中比較重要的方面。但首先,您必須創建一個工作台,並在其中建立一個研究對象。

工作台

啟動一個xterm會話,讓我們先創建一個空白的工作台,並開始對目標文件進行研究。下面的命令創建了一個目錄,可以將目標文件放到該目錄中進行研究:

cd
mkdir src
cd src
mkdir hw
cd hw

然後,使用您最喜歡的代碼編輯器,在$HOME/src/hw 目錄中輸入清單1中的程序,並命名為hw.c。

清單 1. hw.c 程序#include <stdio.h>
int main(void)
{
 printf("Hello World!\n");
 return 0;
}

要使用UNIX工具庫中提供的各種工具,可以將這個簡單的“Hello World”程序作為研究的對象。您將學習構建和查看目標文件的輸出,而不是使用任何快捷方法直接創建可執行文件(的確有許多這樣的快捷方法)。

文件格式

C編譯器的正常輸出是用於您所指定的目標處理器的匯編代碼。匯編代碼是匯編器的輸入,在缺省情況下,匯編器將生成所有目標文件的祖先,即a.out文件。這個名稱本身表示匯編輸出 (Assembler Output)。要創建 a.out 文件,可以在 xterm 窗口中輸入下面的命令:

cc hw.c

注意:如果出現了任何錯誤或者沒有創建a.out文件,那麼您可能需要檢查自己的系統或源文件(hw.c),以找出其中的錯誤。還需要檢查是否已將cc定義為運行您的C/C++編譯器。

最新的C編譯器將編譯和匯編步驟組合成一個步驟。您可以指定不同開關選項以查看C編譯器的匯編輸出。通過輸入下面的命令,您可以看到C編譯器的匯編輸出:

cc -S hw.c

這個命令生成了一個新的文件hw.s,其中包含您通常無法看到的匯編輸入文本,因為編譯器在缺省情況下將生成a.out文件。正如所預期的,UNIX匯編程序可以對這種輸入文件進行匯編,以生成a.out文件。

UNIX特定的工具

假定編譯過程一切順利,那麼在該目錄中就有了一個a.out文件,下面讓我們來對其進行研究。有許多可用於研究目標文件的有價值的工具,下面便是其中一組:

  • nm:列出目標文件中的符號。
  • objdump:顯示目標文件中的詳細信息。
  • readelf:顯示關於ELF目標文件的信息。

    列表中的第一個工具是nm,它可以列出目標文件中的符號。如果您輸入nm命令,您將注意到在缺省情況下,它會尋找一個名為a.out的文件。如果沒有找到該文件,這個工具會給出相應的提示。然而,如果該工具找到了編譯器創建的a.out文件,它將顯示類似清單2的清單。

    清單 2. nm 命令的輸出08049594 A __bss_start
    080482e4 t call_gmon_start
    08049594 b completed.4463
    08049498 d __CTOR_END__
    08049494 d __CTOR_LIST__
    08049588 D __data_start
    08049588 W data_start
    0804842c t __do_global_ctors_aux
    0804830c t __do_global_dtors_aux
    0804958c D __dso_handle
    080494a0 d __DTOR_END__
    0804949c d __DTOR_LIST__
    080494a8 d _DYNAMIC
    08049594 A _edata
    08049598 A _end
    08048458 T _fini
    08049494 a __fini_array_end
    08049494 a __fini_array_start
    08048478 R _fp_hw
    0804833b t frame_dummy
    08048490 r __FRAME_END__
    08049574 d _GLOBAL_OFFSET_TABLE_
         w __gmon_start__
    08048308 T __i686.get_pc_thunk.bx
    08048278 T _init
    08049494 a __init_array_end
    08049494 a __init_array_start
    0804847c R _IO_stdin_used
    080494a4 d __JCR_END__
    080494a4 d __JCR_LIST__
         w _Jv_RegisterClasses
    080483e1 T __libc_csu_fini
    08048390 T __libc_csu_init
         U __libc_start_main@@GLIBC_2.0
    08048360 T main
    08049590 d p.4462
         U puts@@GLIBC_2.0
    080482c0 T _start

    這些包含可執行代碼的段稱為正文段。同樣地,數據段包含了不可執行的信息或數據。另一種類型的段,稱為BSS段,它包含以符號數據開頭的塊。

    對於nm命令列出的每個符號,它們的值使用十六進制來表示(缺省行為),並且在該符號前面加上了一個表示符號類型的編碼字符。常見的各種編碼包括:A表示絕對(absolute),這意味著不能將該值更改為其他的連接;B表示BSS段中的符號;而C表示引用未初始化的數據的一般符號。

    可以將目標文件中所包含的不同的部分劃分為段。段可以包含可執行代碼、符號名稱、初始數據值和許多其他類型的數據。有關這些類型的數據的詳細信息,可以閱讀UNIX中nm的man頁面,其中按照該命令輸出中的字符編碼分別對每種類型進行了描述。

    細節,細節…

    在目標文件階段,即使是一個簡單的Hello World程序,其中也包含了大量的細節信息。nm程序可用於列舉符號及其類型和值,但是,要更仔細地研究目標文件中這些命名段的內容,需要使用功能更強大的工具。

    其中兩種功能強大的工具是objdump和readelf程序。通過輸入下面的命令,您可以看到目標文件中包含可執行代碼的每個段的匯編清單。對於這麼一個小的程序,編譯器生成了這麼多的代碼,真的很令人驚異!

    objdump -d a.out

    這個命令生成的輸出如清單3所示。每個可執行代碼段將在需要特定的事件時執行,這些事件包括庫的初始化和該程序本身主入口點。

    清單3. objdump命令的輸出

    a.out:   file format elf32-i386
    Disassembly of section .init:
    08048278 〈_init>:
    8048278:    55           push  %ebp
    8048279:    89 e5          mov  %esp,%ebp
    804827b:    83 ec 08        sub  $0x8,%esp
    804827e:    e8 61 00 00 00     call  80482e4 〈call_gmon_start>
    8048283:    e8 b3 00 00 00     call  804833b 〈frame_dummy>
    8048288:    e8 9f 01 00 00     call  804842c 〈__do_global_ctors_aux>
    804828d:    c9           leave
    804828e:    c3           ret
    Disassembly of section .plt:
    08048290 〈puts@plt-0x10>:
    8048290:    ff 35 78 95 04 08    pushl 0x8049578
    8048296:    ff 25 7c 95 04 08    jmp  *0x804957c
    804829c:    00 00          add  %al,(%eax)
        ...
    080482a0 〈puts@plt>:
    80482a0:    ff 25 80 95 04 08    jmp  *0x8049580
    80482a6:    68 00 00 00 00     push  $0x0
    80482ab:    e9 e0 ff ff ff     jmp  8048290 〈_init+0x18>
    080482b0 〈__libc_start_main@plt>:
    80482b0:    ff 25 84 95 04 08    jmp  *0x8049584
    80482b6:    68 08 00 00 00     push  $0x8
    80482bb:    e9 d0 ff ff ff     jmp  8048290 〈_init+0x18>
    Disassembly of section .text:
    080482c0 〈_start>:
    80482c0:    31 ed          xor  %ebp,%ebp
    80482c2:    5e           pop  %esi
    80482c3:    89 e1          mov  %esp,%ecx
    80482c5:    83 e4 f0        and  $0xfffffff0,%esp
    80482c8:    50           push  %eax
    80482c9:    54           push  %esp
    80482ca:    52           push  %edx
    80482cb:    68 e1 83 04 08     push  $0x80483e1
    80482d0:    68 90 83 04 08     push  $0x8048390
    80482d5:    51           push  %ecx
    80482d6:    56           push  %esi
    80482d7:    68 60 83 04 08     push  $0x8048360
    80482dc:    e8 cf ff ff ff     call  80482b0 〈__libc_start_main@plt>
    80482e1:    f4           hlt
    80482e2:    90           nop
    80482e3:    90           nop
    080482e4 〈call_gmon_start>:
    80482e4:    55           push  %ebp
    80482e5:    89 e5          mov  %esp,%ebp
    80482e7:    53           push  %ebx
    80482e8:    e8 1b 00 00 00     call  8048308 〈__i686.get_pc_thunk.bx>
    80482ed:    81 c3 87 12 00 00    add  $0x1287,%ebx
    80482f3:    83 ec 04        sub  $0x4,%esp
    80482f6:    8b 83 fc ff ff ff    mov  0xfffffffc(%ebx),%eax
    80482fc:    85 c0          test  %eax,%eax
    80482fe:    74 02          je   8048302 
    8048300:    ff d0          call  *%eax
    8048302:    83 c4 04        add  $0x4,%esp
    8048305:    5b           pop  %ebx
    8048306:    5d           pop  %ebp
    8048307:    c3           ret
    08048308 〈__i686.get_pc_thunk.bx>:
    8048308:    8b 1c 24        mov  (%esp),%ebx
    804830b:    c3           ret
    0804830c 〈__do_global_dtors_aux>:
    804830c:    55           push  %ebp
    804830d:    89 e5          mov  %esp,%ebp
    804830f:    83 ec 08        sub  $0x8,%esp
    8048312:    80 3d 94 95 04 08 00  cmpb  $0x0,0x8049594
    8048319:    74 0c          je   8048327 〈__do_global_dtors_aux+0x1b>
    804831b:    eb 1c          jmp  8048339 〈__do_global_dtors_aux+0x2d>
    804831d:    83 c0 04        add  $0x4,%eax
    8048320:    a3 90 95 04 08     mov  %eax,0x8049590
    8048325:    ff d2          call  *%edx
    8048327:    a1 90 95 04 08     mov  0x8049590,%eax
    804832c:    8b 10          mov  (%eax),%edx
    804832e:    85 d2          test  %edx,%edx
    8048330:    75 eb          jne  804831d 〈__do_global_dtors_aux+0x11>
    8048332:    c6 05 94 95 04 08 01  movb  $0x1,0x8049594
    8048339:    c9           leave
    804833a:    c3           ret
    0804833b 〈frame_dummy>:
    804833b:    55           push  %ebp
    804833c:    89 e5          mov  %esp,%ebp
    804833e:    83 ec 08        sub  $0x8,%esp
    8048341:    a1 a4 94 04 08     mov  0x80494a4,%eax
    8048346:    85 c0          test  %eax,%eax
    8048348:    74 12          je   804835c 
    804834a:    b8 00 00 00 00     mov  $0x0,%eax
    804834f:    85 c0          test  %eax,%eax
    8048351:    74 09          je   804835c 
    8048353:    c7 04 24 a4 94 04 08  movl  $0x80494a4,(%esp)
    804835a:    ff d0          call  *%eax
    804835c:    c9           leave
    804835d:    c3           ret
    804835e:    90           nop
    804835f:    90           nop
    08048360 〈main>:
    8048360:    55           push  %ebp
    8048361:    89 e5          mov  %esp,%ebp
    8048363:    83 ec 08        sub  $0x8,%esp
    8048366:    83 e4 f0        and  $0xfffffff0,%esp
    8048369:    b8 00 00 00 00     mov  $0x0,%eax
    804836e:    83 c0 0f        add  $0xf,%eax
    8048371:    83 c0 0f        add  $0xf,%eax
    8048374:    c1 e8 04        shr  $0x4,%eax
    8048377:    c1 e0 04        shl  $0x4,%eax
    804837a:    29 c4          sub  %eax,%esp
    804837c:    c7 04 24 80 84 04 08  movl  $0x8048480,(%esp)
    8048383:    e8 18 ff ff ff     call  80482a0 
    8048388:    b8 00 00 00 00     mov  $0x0,%eax
    804838d:    c9           leave
    804838e:    c3           ret
    804838f:    90           nop
    08048390 〈__libc_csu_init>:
    8048390:    55           push  %ebp
    8048391:    89 e5          mov  %esp,%ebp
    8048393:    57           push  %edi
    8048394:    56           push  %esi
    8048395:    31 f6          xor  %esi,%esi
    8048397:    53           push  %ebx
    8048398:    e8 6b ff ff ff     call  8048308 〈__i686.get_pc_thunk.bx>
    804839d:    81 c3 d7 11 00 00    add  $0x11d7,%ebx
    80483a3:    83 ec 0c        sub  $0xc,%esp
    80483a6:    e8 cd fe ff ff     call  8048278 〈_init>
    80483ab:    8d 83 20 ff ff ff    lea  0xffffff20(%ebx),%eax
    80483b1:    8d 93 20 ff ff ff    lea  0xffffff20(%ebx),%edx
    80483b7:    89 45 f0        mov  %eax,0xfffffff0(%ebp)
    80483ba:    29 d0          sub  %edx,%eax
    80483bc:    c1 f8 02        sar  $0x2,%eax
    80483bf:    39 c6          cmp  %eax,%esi
    80483c1:    73 16          jae  80483d9 〈__libc_csu_init+0x49>
    80483c3:    89 d7          mov  %edx,%edi
    80483c5:    ff 14 b2        call  *(%edx,%esi,4)
    80483c8:    8b 45 f0        mov  0xfffffff0(%ebp),%eax
    80483cb:    83 c6 01        add  $0x1,%esi
    80483ce:    29 f8          sub  %edi,%eax
    80483d0:    89 fa          mov  %edi,%edx
    80483d2:    c1 f8 02        sar  $0x2,%eax
    80483d5:    39 c6          cmp  %eax,%esi
    80483d7:    72 ec          jb   80483c5 〈__libc_csu_init+0x35>
    80483d9:    83 c4 0c        add  $0xc,%esp
    80483dc:    5b           pop  %ebx
    80483dd:    5e           pop  %esi
    80483de:    5f           pop  %edi
    80483df:    5d           pop  %ebp
    80483e0:    c3           ret
    080483e1 〈__libc_csu_fini>:
    80483e1:    55           push  %ebp
    80483e2:    89 e5          mov  %esp,%ebp
    80483e4:    83 ec 18        sub  $0x18,%esp
    80483e7:    89 5d f4        mov  %ebx,0xfffffff4(%ebp)
    80483ea:    e8 19 ff ff ff     call  8048308 〈__i686.get_pc_thunk.bx>
    80483ef:    81 c3 85 11 00 00    add  $0x1185,%ebx
    80483f5:    89 75 f8        mov  %esi,0xfffffff8(%ebp)
    80483f8:    89 7d fc        mov  %edi,0xfffffffc(%ebp)
    80483fb:    8d b3 20 ff ff ff    lea  0xffffff20(%ebx),%esi
    8048401:    8d bb 20 ff ff ff    lea  0xffffff20(%ebx),%edi
    8048407:    29 fe          sub  %edi,%esi
    8048409:    c1 fe 02        sar  $0x2,%esi
    804840c:    eb 03          jmp  8048411 〈__libc_csu_fini+0x30>
    804840e:    ff 14 b7        call  *(%edi,%esi,4)
    8048411:    83 ee 01        sub  $0x1,%esi
    8048414:    83 fe ff        cmp  $0xffffffff,%esi
    8048417:    75 f5          jne  804840e 〈__libc_csu_fini+0x2d>
    8048419:    e8 3a 00 00 00     call  8048458 〈_fini>
    804841e:    8b 5d f4        mov  0xfffffff4(%ebp),%ebx
    8048421:    8b 75 f8        mov  0xfffffff8(%ebp),%esi
    8048424:    8b 7d fc        mov  0xfffffffc(%ebp),%edi
    8048427:    89 ec          mov  %ebp,%esp
    8048429:    5d           pop  %ebp
    804842a:    c3           ret
    804842b:    90           nop
    0804842c 〈__do_global_ctors_aux>:
    804842c:    55           push  %ebp
    804842d:    89 e5          mov  %esp,%ebp
    804842f:    53           push  %ebx
    8048430:    83 ec 04        sub  $0x4,%esp
    8048433:    a1 94 94 04 08     mov  0x8049494,%eax
    8048438:    83 f8 ff        cmp  $0xffffffff,%eax
    804843b:    74 12          je   804844f 〈__do_global_ctors_aux+0x23>
    804843d:    bb 94 94 04 08     mov  $0x8049494,%ebx
    8048442:    ff d0          call  *%eax
    8048444:    8b 43 fc        mov  0xfffffffc(%ebx),%eax
    8048447:    83 eb 04        sub  $0x4,%ebx
    804844a:    83 f8 ff        cmp  $0xffffffff,%eax
    804844d:    75 f3          jne  8048442 〈__do_global_ctors_aux+0x16>
    804844f:    83 c4 04        add  $0x4,%esp
    8048452:    5b           pop  %ebx
    8048453:    5d           pop  %ebp
    8048454:    c3           ret
    8048455:    90           nop
    8048456:    90           nop
    8048457:    90           nop
    Disassembly of section .fini:
    08048458 〈_fini>:
    8048458:    55           push  %ebp
    8048459:    89 e5          mov  %esp,%ebp
    804845b:    53           push  %ebx
    804845c:    e8 a7 fe ff ff     call  8048308 〈__i686.get_pc_thunk.bx>
    8048461:    81 c3 13 11 00 00    add  $0x1113,%ebx
    8048467:    83 ec 04        sub  $0x4,%esp
    804846a:    e8 9d fe ff ff     call  804830c 〈__do_global_dtors_aux>
    804846f:    83 c4 04        add  $0x4,%esp
    8048472:    5b           pop  %ebx
    8048473:    5d           pop  %ebp
    8048474:    c3           ret

    對於那些著迷於底層編程細節的程序員來說,這是一個功能非常強大的工具,可用於研究編譯器和匯編器的輸出。細節信息,比如這段代碼中所顯示的這些信息,可以揭示有關本地處理器本身運行方式的很多內容。對該處理器制造商提供的技術文檔進行深入的研究,您可以收集關於一些有價值的信息,通過這些信息可以深入地了解內部的運行機制,因為功能程序提供了清晰的輸出。

    類似地,readelf程序也可以清楚地列出目標文件中的內容。輸入下面的命令,您將可以看到這一點:

    readelf -all a.out

    這個命令生成的輸出如清單4所示。ELF Header為該文件中所有段入口顯示了詳細的摘要。在列舉出這些Header中的內容之前,您可以看到Header的具體數目。在研究一個較大的目標文件時,該信息可能非常有用。

    清單4. readelf命令的輸出

    ELF Header:
     Magic:  7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
     Class:               ELF32
     Data:               2's complement, little endian
     Version:              1 (current)
     OS/ABI:              UNIX - System V
     ABI Version:            0
     Type:               EXEC (Executable file)
     Machine:              Intel 80386
     Version:              0x1
     Entry point address:        0x80482c0
     Start of program headers:     52 (bytes into file)
     Start of section headers:     3504 (bytes into file)
     Flags:               0x0
     Size of this header:        52 (bytes)
     Size of program headers:      32 (bytes)
     Number of program headers:     7
     Size of section headers:      40 (bytes)
     Number of section headers:     34
     Section header string table index: 31
    Section Headers:
     [Nr] Name       Type      Addr   Off  Size  ES Flg Lk Inf Al
     [ 0]          NULL      00000000 000000 000000 00   0  0 0
     [ 1] .interp      PROGBITS    08048114 000114 000013 00  A 0  0 1
     [ 2] .note.ABI-tag   NOTE      08048128 000128 000020 00  A 0  0 4
     [ 3] .hash       HASH      08048148 000148 00002c 04  A 4  0 4
     [ 4] .dynsym      DYNSYM     08048174 000174 000060 10  A 5  1 4
     [ 5] .dynstr      STRTAB     080481d4 0001d4 00005e 00  A 0  0 1
     [ 6] .gnu.version   VERSYM     08048232 000232 00000c 02  A 4  0 2
     [ 7] .gnu.version_r  VERNEED     08048240 000240 000020 00  A 5  1 4
     [ 8] .rel.dyn     REL       08048260 000260 000008 08  A 4  0 4
     [ 9] .rel.plt     REL       08048268 000268 000010 08  A 4 11 4
     [10] .init       PROGBITS    08048278 000278 000017 00 AX 0  0 1
     [11] .plt       PROGBITS    08048290 000290 000030 04 AX 0  0 4
     [12] .text       PROGBITS    080482c0 0002c0 000198 00 AX 0  0 4
     [13] .fini       PROGBITS    08048458 000458 00001d 00 AX 0  0 1
     [14] .rodata      PROGBITS    08048478 000478 000015 00  A 0  0 4
     [15] .eh_frame     PROGBITS    08048490 000490 000004 00  A 0  0 4
     [16] .ctors      PROGBITS    08049494 000494 000008 00 WA 0  0 4
     [17] .dtors      PROGBITS    0804949c 00049c 000008 00 WA 0  0 4
     [18] .jcr       PROGBITS    080494a4 0004a4 000004 00 WA 0  0 4
     [19] .dynamic     DYNAMIC     080494a8 0004a8 0000c8 08 WA 5  0 4
     [20] .got       PROGBITS    08049570 000570 000004 04 WA 0  0 4
     [21] .got.plt     PROGBITS    08049574 000574 000014 04 WA 0  0 4
     [22] .data       PROGBITS    08049588 000588 00000c 00 WA 0  0 4
     [23] .bss       NOBITS     08049594 000594 000004 00 WA 0  0 4
     [24] .comment     PROGBITS    00000000 000594 000126 00   0  0 1
     [25] .debug_aranges  PROGBITS    00000000 0006c0 000088 00   0  0 8
     [26] .debug_pubnames  PROGBITS    00000000 000748 000025 00   0  0 1
     [27] .debug_info    PROGBITS    00000000 00076d 00022b 00   0  0 1
     [28] .debug_abbrev   PROGBITS    00000000 000998 000076 00   0  0 1
     [29] .debug_line    PROGBITS    00000000 000a0e 0001bb 00   0  0 1
     [30] .debug_str    PROGBITS    00000000 000bc9 0000bf 01 MS 0  0 1
     [31] .shstrtab     STRTAB     00000000 000c88 000127 00   0  0 1
     [32] .symtab      SYMTAB     00000000 001300 000520 10   33 63 4
     [33] .strtab      STRTAB     00000000 001820 0002d2 00   0  0 1
    Key to Flags:
     W (write), A (alloc), X (execute), M (merge), S (strings)
     I (info), L (link order), G (group), x (unknown)
     O (extra OS processing required) o (OS specific), p (processor specific)
    There are no section groups in this file.
    Program Headers:
     Type      Offset  VirtAddr  PhysAddr  FileSiz MemSiz Flg Align
     PHDR      0x000034 0x08048034 0x08048034 0x000e0 0x000e0 R E 0x4
     INTERP     0x000114 0x08048114 0x08048114 0x00013 0x00013 R  0x1
       [Requesting program interpreter: /lib/ld-linux.so.2]
     LOAD      0x000000 0x08048000 0x08048000 0x00494 0x00494 R E 0x1000
     LOAD      0x000494 0x08049494 0x08049494 0x00100 0x00104 RW 0x1000
     DYNAMIC    0x0004a8 0x080494a8 0x080494a8 0x000c8 0x000c8 RW 0x4
     NOTE      0x000128 0x08048128 0x08048128 0x00020 0x00020 R  0x4
     GNU_STACK   0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4
    Section to Segment mapping:
     Segment Sections...
      00
      01   .interp
      02   .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version
         .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame
      03   .ctors .dtors .jcr .dynamic .got .got.plt .data .bss
      04   .dynamic
      05   .note.ABI-tag
      06
    Dynamic section at offset 0x4a8 contains 20 entries:
     Tag    Type             Name/Value
    0x00000001 (NEEDED)           Shared library: [libc.so.6]
    0x0000000c (INIT)            0x8048278
    0x0000000d (FINI)            0x8048458
    0x00000004 (HASH)            0x8048148
    0x00000005 (STRTAB)           0x80481d4
    0x00000006 (SYMTAB)           0x8048174
    0x0000000a (STRSZ)           94 (bytes)
    0x0000000b (SYMENT)           16 (bytes)
    0x00000015 (DEBUG)           0x0
    0x00000003 (PLTGOT)           0x8049574
    0x00000002 (PLTRELSZ)          16 (bytes)
    0x00000014 (PLTREL)           REL
    0x00000017 (JMPREL)           0x8048268
    0x00000011 (REL)            0x8048260
    0x00000012 (RELSZ)           8 (bytes)
    0x00000013 (RELENT)           8 (bytes)
    0x6ffffffe (VERNEED)          0x8048240
    0x6fffffff (VERNEEDNUM)         1
    0x6ffffff0 (VERSYM)           0x8048232
    0x00000000 (NULL)            0x0
    Relocation section '.rel.dyn' at offset 0x260 contains 1 entries:
    Offset   Info  Type      Sym.Value Sym. Name
    08049570 00000506 R_386_GLOB_DAT  00000000  __gmon_start__
    Relocation section '.rel.plt' at offset 0x268 contains 2 entries:
    Offset   Info  Type      Sym.Value Sym. Name
    08049580 00000107 R_386_JUMP_SLOT  00000000  puts
    08049584 00000207 R_386_JUMP_SLOT  00000000  __libc_start_main
    There are no unwind sections in this file.
    Symbol table '.dynsym' contains 6 entries:
      Num:  Value Size Type  Bind  Vis   Ndx Name
       0: 00000000   0 NOTYPE LOCAL DEFAULT UND
       1: 00000000  378 FUNC  GLOBAL DEFAULT UND puts@GLIBC_2.0 (2)
       2: 00000000  230 FUNC  GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.0 (2)
       3: 0804847c   4 OBJECT GLOBAL DEFAULT  14 _IO_stdin_used
       4: 00000000   0 NOTYPE WEAK  DEFAULT UND _Jv_RegisterClasses
       5: 00000000   0 NOTYPE WEAK  DEFAULT UND __gmon_start__
    Symbol table '.symtab' contains 82 entries:
      Num:  Value Size Type  Bind  Vis   Ndx Name
       0: 00000000   0 NOTYPE LOCAL DEFAULT UND
       1: 08048114   0 SECTION LOCAL DEFAULT  1
       2: 08048128   0 SECTION LOCAL DEFAULT  2
       3: 08048148   0 SECTION LOCAL DEFAULT  3
       4: 08048174   0 SECTION LOCAL DEFAULT  4
       5: 080481d4   0 SECTION LOCAL DEFAULT  5
       6: 08048232   0 SECTION LOCAL DEFAULT  6
       7: 08048240   0 SECTION LOCAL DEFAULT  7
       8: 08048260   0 SECTION LOCAL DEFAULT  8
       9: 08048268   0 SECTION LOCAL DEFAULT  9
      10: 08048278   0 SECTION LOCAL DEFAULT  10
      11: 08048290   0 SECTION LOCAL DEFAULT  11
      12: 080482c0   0 SECTION LOCAL DEFAULT  12
      13: 08048458   0 SECTION LOCAL DEFAULT  13
      14: 08048478   0 SECTION LOCAL DEFAULT  14
      15: 08048490   0 SECTION LOCAL DEFAULT  15
      16: 08049494   0 SECTION LOCAL DEFAULT  16
      17: 0804949c   0 SECTION LOCAL DEFAULT  17
      18: 080494a4   0 SECTION LOCAL DEFAULT  18
      19: 080494a8   0 SECTION LOCAL DEFAULT  19
      20: 08049570   0 SECTION LOCAL DEFAULT  20
      21: 08049574   0 SECTION LOCAL DEFAULT  21
      22: 08049588   0 SECTION LOCAL DEFAULT  22
      23: 08049594   0 SECTION LOCAL DEFAULT  23
      24: 00000000   0 SECTION LOCAL DEFAULT  24
      25: 00000000   0 SECTION LOCAL DEFAULT  25
      26: 00000000   0 SECTION LOCAL DEFAULT  26
      27: 00000000   0 SECTION LOCAL DEFAULT  27
      28: 00000000   0 SECTION LOCAL DEFAULT  28
      29: 00000000   0 SECTION LOCAL DEFAULT  29
      30: 00000000   0 SECTION LOCAL DEFAULT  30
      31: 00000000   0 SECTION LOCAL DEFAULT  31
      32: 00000000   0 SECTION LOCAL DEFAULT  32
      33: 00000000   0 SECTION LOCAL DEFAULT  33
      34: 00000000   0 FILE  LOCAL DEFAULT ABS abi-note.S
      35: 00000000   0 FILE  LOCAL DEFAULT ABS ../sysdeps/i386/elf/start
      36: 00000000   0 FILE  LOCAL DEFAULT ABS init.c
      37: 00000000   0 FILE  LOCAL DEFAULT ABS initfini.c
      38: 00000000   0 FILE  LOCAL DEFAULT ABS /build/buildd/glibc-2.3.6
      39: 080482e4   0 FUNC  LOCAL DEFAULT  12 call_gmon_start
      40: 00000000   0 FILE  LOCAL DEFAULT ABS crtstuff.c
      41: 08049494   0 OBJECT LOCAL DEFAULT  16 __CTOR_LIST__
      42: 0804949c   0 OBJECT LOCAL DEFAULT  17 __DTOR_LIST__
      43: 080494a4   0 OBJECT LOCAL DEFAULT  18 __JCR_LIST__
      44: 08049594   1 OBJECT LOCAL DEFAULT  23 completed.4463
      45: 08049590   0 OBJECT LOCAL DEFAULT  22 p.4462
      46: 0804830c   0 FUNC  LOCAL DEFAULT  12 __do_global_dtors_aux
      47: 0804833b   0 FUNC  LOCAL DEFAULT  12 frame_dummy
      48: 00000000   0 FILE  LOCAL DEFAULT ABS crtstuff.c
      49: 08049498   0 OBJECT LOCAL DEFAULT  16 __CTOR_END__
      50: 080494a0   0 OBJECT LOCAL DEFAULT  17 __DTOR_END__
      51: 08048490   0 OBJECT LOCAL DEFAULT  15 __FRAME_END__
      52: 080494a4   0 OBJECT LOCAL DEFAULT  18 __JCR_END__
      53: 0804842c   0 FUNC  LOCAL DEFAULT  12 __do_global_ctors_aux
      54: 00000000   0 FILE  LOCAL DEFAULT ABS initfini.c
      55: 00000000   0 FILE  LOCAL DEFAULT ABS /build/buildd/glibc-2.3.6
      56: 00000000   0 FILE  LOCAL DEFAULT ABS hw.c
      57: 080494a8   0 OBJECT LOCAL HIDDEN  19 _DYNAMIC
      58: 08049494   0 NOTYPE LOCAL HIDDEN ABS __fini_array_end
      59: 08049494   0 NOTYPE LOCAL HIDDEN ABS __fini_array_start
      60: 08049494   0 NOTYPE LOCAL HIDDEN ABS __init_array_end
      61: 08049574   0 OBJECT LOCAL HIDDEN  21 _GLOBAL_OFFSET_TABLE_
      62: 08049494   0 NOTYPE LOCAL HIDDEN ABS __init_array_start
      63: 08048478   4 OBJECT GLOBAL DEFAULT  14 _fp_hw
      64: 0804958c   0 OBJECT GLOBAL HIDDEN  22 __dso_handle
      65: 080483e1  74 FUNC  GLOBAL DEFAULT  12 __libc_csu_fini
      66: 00000000  378 FUNC  GLOBAL DEFAULT UND puts@@GLIBC_2.0
      67: 08048278   0 FUNC  GLOBAL DEFAULT  10 _init
      68: 080482c0   0 FUNC  GLOBAL DEFAULT  12 _start
      69: 08048390  81 FUNC  GLOBAL DEFAULT  12 __libc_csu_init
      70: 08049594   0 NOTYPE GLOBAL DEFAULT ABS __bss_start
      71: 08048360  47 FUNC  GLOBAL DEFAULT  12 main
      72: 00000000  230 FUNC  GLOBAL DEFAULT UND __libc_start_main@@GLIBC_
      73: 08049588   0 NOTYPE WEAK  DEFAULT  22 data_start
      74: 08048458   0 FUNC  GLOBAL DEFAULT  13 _fini
      75: 08049594   0 NOTYPE GLOBAL DEFAULT ABS _edata
      76: 08048308   0 FUNC  GLOBAL HIDDEN  12 __i686.get_pc_thunk.bx
      77: 08049598   0 NOTYPE GLOBAL DEFAULT ABS _end
      78: 0804847c   4 OBJECT GLOBAL DEFAULT  14 _IO_stdin_used
      79: 08049588   0 NOTYPE GLOBAL DEFAULT  22 __data_start
      80: 00000000   0 NOTYPE WEAK  DEFAULT UND _Jv_RegisterClasses
      81: 00000000   0 NOTYPE WEAK  DEFAULT UND __gmon_start__
    Histogram for bucket list length (total of 3 buckets):
    Length Number   % of total Coverage
       0 0     ( 0.0%)
       1 1     ( 33.3%)   20.0%
       2 2     ( 66.7%)  100.0%
    Version symbols section '.gnu.version' contains 6 entries:
    Addr: 0000000008048232 Offset: 0x000232 Link: 4 (.dynsym)
     000:  0 (*local*)    2 (GLIBC_2.0)   2 (GLIBC_2.0)   1 (*global*)
     004:  0 (*local*)    0 (*local*)
    Version needs section '.gnu.version_r' contains 1 entries:
    Addr: 0x0000000008048240 Offset: 0x000240 Link to section: 5 (.dynstr)
     000000: Version: 1 File: libc.so.6 Cnt: 1
     0x0010:  Name: GLIBC_2.0 Flags: none Version: 2
    Notes at offset 0x00000128 with length 0x00000020:
     Owner     Data size    Description
     GNU      0x00000010   NT_VERSION (version)

    正如從該輸出中看到的,簡單的a.out Hello World文件中包含了大量有價值的細節信息,包括版本信息、柱狀圖、各種符號類型的表格,等等。通過使用本文中介紹的這幾種工具分析目標文件,您可以慢慢地對可執行程序進行研究。

    除了所有這些段之外,編譯器可以將調試信息放入到目標文件中,並且還可以顯示這些信息。輸入下面的命令,仔細分析編譯器的輸出(假設您扮演了調試程序的角色):

    readelf --debug-dump a.out | less

    這個命令生成的輸出如清單5所示。調試工具,如GDB,可以讀取這些調試信息,並且當程序在調試器中運行的同時,您可以使用該工具顯示更具描述性的標記,而不是對代碼進行反匯編時的原始地址值。

    清單 5. 該程序中的調試信息

    The section .debug_aranges contains:
    Length: 28
    Version: 2
    Offset into .debug_info: 0
    Pointer Size: 4
    Segment Size: 0
    Address Length
    080482c0 34
    Length: 52
    Version: 2
    Offset into .debug_info: 10b
    Pointer Size: 4
    Segment Size: 0
    Address Length
    08048308 4
    08048458 18
    08048278 11
    080482e4 36
    Length: 44
    Version: 2
    Offset into .debug_info: 19b
    Pointer Size: 4
    Segment Size: 0
    Address Length
    08048308 4
    0804846f 6
    0804828d 2
    Contents of the .debug_pubnames section:
    Length: 33
    Version: 2
    Offset into .debug_info section: 122
    Size of area in .debug_info section: 145
    Offset Name
    121 _IO_stdin_used
    The section .debug_info contains:
    Compilation Unit @ offset 0x0:
    Length: 118
    Version: 2
    Abbrev Offset: 0
    Pointer Size: 4
    <0>: Abbrev Number: 1 (DW_TAG_compile_unit)
    DW_AT_stmt_list : 0
    DW_AT_low_pc : 0x80482c0
    DW_AT_high_pc : 0x80482e2
    DW_AT_name : ../sysdeps/i386/elf/start.S
    DW_AT_comp_dir : /build/buildd/glibc-2.3.6/build-tree/glibc-2.3.6/csu
    DW_AT_producer : GNU AS 2.16.91
    DW_AT_language : 32769 (MIPS assembler)
    Compilation Unit @ offset 0x7a:
    Length: 141
    Version: 2
    Abbrev Offset: 20
    Pointer Size: 4
    <0><85>: Abbrev Number: 1 (DW_TAG_compile_unit)
    DW_AT_stmt_list : 0x5b
    DW_AT_high_pc : 0x80482e4
    DW_AT_low_pc : 0x80482e4
    DW_AT_producer : (indirect string, offset: 0x62): GNU C 3.4.6
    DW_AT_language : 1 (ANSI C)
    DW_AT_name : (indirect string, offset: 0x0): init.c
    DW_AT_comp_dir : (indirect string, offset: 0x11): /build/buildd/...
    <1><9f>: Abbrev Number: 2 (DW_TAG_base_type)
    DW_AT_name : (indirect string, offset: 0x90): unsigned int
    DW_AT_byte_size : 4
    DW_AT_encoding : 7 (unsigned)
    <1>: Abbrev Number: 2 (DW_TAG_base_type)
    DW_AT_name : (indirect string, offset: 0x54): unsigned char
    DW_AT_byte_size : 1
    DW_AT_encoding : 8 (unsigned char)
    <1>: Abbrev Number: 2 (DW_TAG_base_type)
    DW_AT_name : (indirect string, offset: 0x9d): short unsigned int
    DW_AT_byte_size : 2
    DW_AT_encoding : 7 (unsigned)
    <1>: Abbrev Number: 2 (DW_TAG_base_type)
    DW_AT_name : (indirect string, offset: 0x8b): long unsigned int
    DW_AT_byte_size : 4
    DW_AT_encoding : 7 (unsigned)
    <1>: Abbrev Number: 2 (DW_TAG_base_type)
    DW_AT_name : (indirect string, offset: 0x56): signed char
    DW_AT_byte_size : 1
    DW_AT_encoding : 6 (signed char)
    <1>: Abbrev Number: 2 (DW_TAG_base_type)
    DW_AT_name : (indirect string, offset: 0x7): short int
    DW_AT_byte_size : 2
    DW_AT_encoding : 5 (signed)
    <1>: Abbrev Number: 3 (DW_TAG_base_type)
    DW_AT_name : int
    DW_AT_byte_size : 4
    DW_AT_encoding : 5 (signed)
    <1>: Abbrev Number: 2 (DW_TAG_base_type)
    DW_AT_name : (indirect string, offset: 0x46): long long int
    DW_AT_byte_size : 8
    DW_AT_encoding : 5 (signed)
    <1>: Abbrev Number: 2 (DW_TAG_base_type)
    DW_AT_name : (indirect string, offset: 0x86): long long unsigned int
    DW_AT_byte_size : 8
    DW_AT_encoding : 7 (unsigned)
    <1>: Abbrev Number: 2 (DW_TAG_base_type)
    DW_AT_name : (indirect string, offset: 0x4b): long int
    DW_AT_byte_size : 4
    DW_AT_encoding : 5 (signed)
    <1>: Abbrev Number: 2 (DW_TAG_base_type)
    DW_AT_name : (indirect string, offset: 0x90): unsigned int
    DW_AT_byte_size : 4
    DW_AT_encoding : 7 (unsigned)
    <1>: Abbrev Number: 2 (DW_TAG_base_type)
    DW_AT_name : (indirect string, offset: 0x5d): char
    DW_AT_byte_size : 1
    DW_AT_encoding : 6 (signed char)
    <1>: Abbrev Number: 4 (DW_TAG_variable)
    DW_AT_name : (indirect string, offset: 0xb0): _IO_stdin_used
    DW_AT_decl_file : 1
    DW_AT_decl_line : 25
    DW_AT_type : <105>
    DW_AT_external : 1
    DW_AT_location : 5 byte block: 3 7c 84 4 8 (DW_OP_addr: 804847c)
    <1><105>: Abbrev Number: 5 (DW_TAG_const_type)
    DW_AT_type : 
    Compilation Unit @ offset 0x10b:
    Length: 140
    Version: 2
    Abbrev Offset: 86
    Pointer Size: 4
    <0><116>: Abbrev Number: 1 (DW_TAG_compile_unit)
    DW_AT_stmt_list : 0x82
    DW_AT_name : /build/buildd/glibc-2.3.6/build-tree/i386-libc/csu/crti.S
    DW_AT_comp_dir : /build/buildd/glibc-2.3.6/build-tree/glibc-2.3.6/csu
    DW_AT_producer : GNU AS 2.16.91
    DW_AT_language : 32769 (MIPS assembler)
    Compilation Unit @ offset 0x19b:
    Length: 140
    Version: 2
    Abbrev Offset: 102
    Pointer Size: 4
    <0><1a6>: Abbrev Number: 1 (DW_TAG_compile_unit)
    DW_AT_stmt_list : 0x12f
    DW_AT_name : /build/buildd/glibc-2.3.6/build-tree/i386-libc/csu/crtn.S
    DW_AT_comp_dir : /build/buildd/glibc-2.3.6/build-tree/glibc-2.3.6/csu
    DW_AT_producer : GNU AS 2.16.91
    DW_AT_language : 32769 (MIPS assembler)
    Contents of the .debug_abbrev section:
    Number TAG
    1 DW_TAG_compile_unit [no children]
    DW_AT_stmt_list DW_FORM_data4
    DW_AT_low_pc DW_FORM_addr
    DW_AT_high_pc DW_FORM_addr
    DW_AT_name DW_FORM_string
    DW_AT_comp_dir DW_FORM_string
    DW_AT_producer DW_FORM_string
    DW_AT_language DW_FORM_data2
    Number TAG
    1 DW_TAG_compile_unit [has children]
    DW_AT_stmt_list DW_FORM_data4
    DW_AT_high_pc DW_FORM_addr
    DW_AT_low_pc DW_FORM_addr
    DW_AT_producer DW_FORM_strp
    DW_AT_language DW_FORM_data1
    DW_AT_name DW_FORM_strp
    DW_AT_comp_dir DW_FORM_strp
    2 DW_TAG_base_type [no children]
    DW_AT_name DW_FORM_strp
    DW_AT_byte_size DW_FORM_data1
    DW_AT_encoding DW_FORM_data1
    3 DW_TAG_base_type [no children]
    DW_AT_name DW_FORM_string
    DW_AT_byte_size DW_FORM_data1
    DW_AT_encoding DW_FORM_data1
    4 DW_TAG_variable [no children]
    DW_AT_name DW_FORM_strp
    DW_AT_decl_file DW_FORM_data1
    DW_AT_decl_line DW_FORM_data1
    DW_AT_type DW_FORM_ref4
    DW_AT_external DW_FORM_flag
    DW_AT_location DW_FORM_block1
    5 DW_TAG_const_type [no children]
    DW_AT_type DW_FORM_ref4
    Number TAG
    1 DW_TAG_compile_unit [no children]
    DW_AT_stmt_list DW_FORM_data4
    DW_AT_name DW_FORM_string
    DW_AT_comp_dir DW_FORM_string
    DW_AT_producer DW_FORM_string
    DW_AT_language DW_FORM_data2
    Number TAG
    1 DW_TAG_compile_unit [no children]
    DW_AT_stmt_list DW_FORM_data4
    DW_AT_name DW_FORM_string
    DW_AT_comp_dir DW_FORM_string
    DW_AT_producer DW_FORM_string
    DW_AT_language DW_FORM_data2
    Dump of debug contents of section .debug_line:
    Length: 87
    DWARF Version: 2
    Prologue Length: 50
    Minimum Instruction Length: 1
    Initial value of 'is_stmt': 1
    Line Base: -5
    Line Range: 14
    Opcode Base: 13
    (Pointer size: 4)
    Opcodes:
    Opcode 1 has 0 args
    Opcode 2 has 1 args
    Opcode 3 has 1 args
    Opcode 4 has 1 args
    Opcode 5 has 1 args
    Opcode 6 has 0 args
    Opcode 7 has 0 args
    Opcode 8 has 0 args
    Opcode 9 has 1 args
    Opcode 10 has 0 args
    Opcode 11 has 0 args
    Opcode 12 has 1 args
    The Directory Table:
    ../sysdeps/i386/elf
    The File Name Table:
    Entry Dir Time Size Name
    1 1 0 0 start.S
    Line Number Statements:
    Extended opcode 2: set Address to 0x80482c0
    Advance Line by 64 to 65
    Copy
    Special opcode 38: advance Address by 2 to 0x80482c2 and Line by 5 to 70
    Special opcode 20: advance Address by 1 to 0x80482c3 and Line by 1 to 71
    Special opcode 39: advance Address by 2 to 0x80482c5 and Line by 6 to 77
    Special opcode 48: advance Address by 3 to 0x80482c8 and Line by 1 to 78
    Special opcode 24: advance Address by 1 to 0x80482c9 and Line by 5 to 83
    Special opcode 21: advance Address by 1 to 0x80482ca and Line by 2 to 85
    Advance Line by 24 to 109
    Special opcode 19: advance Address by 1 to 0x80482cb and Line by 0 to 109
    Special opcode 76: advance Address by 5 to 0x80482d0 and Line by 1 to 110
    Special opcode 77: advance Address by 5 to 0x80482d5 and Line by 2 to 112
    Special opcode 20: advance Address by 1 to 0x80482d6 and Line by 1 to 113
    Special opcode 21: advance Address by 1 to 0x80482d7 and Line by 2 to 115
    Special opcode 79: advance Address by 5 to 0x80482dc and Line by 4 to 119
    Special opcode 78: advance Address by 5 to 0x80482e1 and Line by 3 to 122
    Advance PC by 1 to 0x80482e2
    Extended opcode 1: End of Sequence
    Length: 35
    DWARF Version: 2
    Prologue Length: 29
    Minimum Instruction Length: 1
    Initial value of 'is_stmt': 1
    Line Base: -5
    Line Range: 14
    Opcode Base: 13
    (Pointer size: 4)
    Opcodes:
    Opcode 1 has 0 args
    Opcode 2 has 1 args
    Opcode 3 has 1 args
    Opcode 4 has 1 args
    Opcode 5 has 1 args
    Opcode 6 has 0 args
    Opcode 7 has 0 args
    Opcode 8 has 0 args
    Opcode 9 has 1 args
    Opcode 10 has 0 args
    Opcode 11 has 0 args
    Opcode 12 has 1 args
    The Directory Table is empty.
    The File Name Table:
    Entry Dir Time Size Name
    1 0 0 0 init.c
    Line Number Statements:
    Length: 169
    DWARF Version: 2
    Prologue Length: 80
    Minimum Instruction Length: 1
    Initial value of 'is_stmt': 1
    Line Base: -5
    Line Range: 14
    Opcode Base: 13
    (Pointer size: 4)
    Opcodes:
    Opcode 1 has 0 args
    Opcode 2 has 1 args
    Opcode 3 has 1 args
    Opcode 4 has 1 args
    Opcode 5 has 1 args
    Opcode 6 has 0 args
    Opcode 7 has 0 args
    Opcode 8 has 0 args
    Opcode 9 has 1 args
    Opcode 10 has 0 args
    Opcode 11 has 0 args
    Opcode 12 has 1 args
    The Directory Table:
    /build/buildd/glibc-2.3.6/build-tree/i386-libc/csu
    The File Name Table:
    Entry Dir Time Size Name
    1 1 0 0 crti.S
    Line Number Statements:
    Extended opcode 2: set Address to 0x8048308
    Advance Line by 64 to 65
    Copy
    Special opcode 48: advance Address by 3 to 0x804830b and Line by 1 to 66
    Advance PC by 1 to 0x804830c
    Extended opcode 1: End of Sequence
    Extended opcode 2: set Address to 0x8048458
    Advance Line by 46 to 47
    Copy
    Special opcode 20: advance Address by 1 to 0x8048459 and Line by 1 to 48
    Special opcode 34: advance Address by 2 to 0x804845b and Line by 1 to 49
    Special opcode 20: advance Address by 1 to 0x804845c and Line by 1 to 50
    Special opcode 76: advance Address by 5 to 0x8048461 and Line by 1 to 51
    Special opcode 90: advance Address by 6 to 0x8048467 and Line by 1 to 52
    Advance PC by 3 to 0x804846a
    Extended opcode 1: End of Sequence
    Extended opcode 2: set Address to 0x8048278
    Advance Line by 31 to 32
    Copy
    Special opcode 20: advance Address by 1 to 0x8048279 and Line by 1 to 33
    Special opcode 34: advance Address by 2 to 0x804827b and Line by 1 to 34
    Special opcode 48: advance Address by 3 to 0x804827e and Line by 1 to 35
    Advance PC by 5 to 0x8048283
    Extended opcode 1: End of Sequence
    Extended opcode 2: set Address to 0x80482e4
    Advance Line by 10 to 11
    Copy
    Special opcode 20: advance Address by 1 to 0x80482e5 and Line by 1 to 12
    Special opcode 34: advance Address by 2 to 0x80482e7 and Line by 1 to 13
    Special opcode 20: advance Address by 1 to 0x80482e8 and Line by 1 to 14
    Special opcode 76: advance Address by 5 to 0x80482ed and Line by 1 to 15
    Special opcode 90: advance Address by 6 to 0x80482f3 and Line by 1 to 16
    Special opcode 48: advance Address by 3 to 0x80482f6 and Line by 1 to 17
    Special opcode 90: advance Address by 6 to 0x80482fc and Line by 1 to 18
    Special opcode 34: advance Address by 2 to 0x80482fe and Line by 1 to 19
    Special opcode 34: advance Address by 2 to 0x8048300 and Line by 1 to 20
    Special opcode 35: advance Address by 2 to 0x8048302 and Line by 2 to 22
    Special opcode 48: advance Address by 3 to 0x8048305 and Line by 1 to 23
    Special opcode 20: advance Address by 1 to 0x8048306 and Line by 1 to 24
    Special opcode 20: advance Address by 1 to 0x8048307 and Line by 1 to 25
    Advance PC by 1 to 0x8048308
    Extended opcode 1: End of Sequence
    Length: 136
    DWARF Version: 2
    Prologue Length: 80
    Minimum Instruction Length: 1
    Initial value of 'is_stmt': 1
    Line Base: -5
    Line Range: 14
    Opcode Base: 13
    (Pointer size: 4)
    Opcodes:
    Opcode 1 has 0 args
    Opcode 2 has 1 args
    Opcode 3 has 1 args
    Opcode 4 has 1 args
    Opcode 5 has 1 args
    Opcode 6 has 0 args
    Opcode 7 has 0 args
    Opcode 8 has 0 args
    Opcode 9 has 1 args
    Opcode 10 has 0 args
    Opcode 11 has 0 args
    Opcode 12 has 1 args
    The Directory Table:
    /build/buildd/glibc-2.3.6/build-tree/i386-libc/csu
    The File Name Table:
    Entry Dir Time Size Name
    1 1 0 0 crtn.S
    Line Number Statements:
    Extended opcode 2: set Address to 0x8048308
    Advance Line by 33 to 34
    Copy
    Special opcode 48: advance Address by 3 to 0x804830b and Line by 1 to 35
    Advance PC by 1 to 0x804830c
    Extended opcode 1: End of Sequence
    Extended opcode 2: set Address to 0x804846f
    Advance Line by 18 to 19
    Copy
    Special opcode 48: advance Address by 3 to 0x8048472 and Line by 1 to 20
    Special opcode 20: advance Address by 1 to 0x8048473 and Line by 1 to 21
    Special opcode 20: advance Address by 1 to 0x8048474 and Line by 1 to 22
    Advance PC by 1 to 0x8048475
    Extended opcode 1: End of Sequence
    Extended opcode 2: set Address to 0x804828d
    Advance Line by 9 to 10
    Copy
    Special opcode 20: advance Address by 1 to 0x804828e and Line by 1 to 11
    Advance PC by 1 to 0x804828f
    Extended opcode 1: End of Sequence
    Contents of the .debug_str section:
    0x00000000 696e6974 2e630073 686f7274 20696e74 init.c.short int
    0x00000010 002f6275 696c642f 6275696c 64642f67 ./build/buildd/g
    0x00000020 6c696263 2d322e33 2e362f62 75696c64 libc-2.3.6/build
    0x00000030 2d747265 652f676c 6962632d 322e332e -tree/glibc-2.3.
    0x00000040 362f6373 75006c6f 6e67206c 6f6e6720 6/csu.long long
    0x00000050 696e7400 756e7369 676e6564 20636861 int.unsigned cha
    0x00000060 7200474e 55204320 332e342e 36202855 r.GNU C 3.4.6 (U
    0x00000070 62756e74 7520332e 342e362d 31756275 buntu 3.4.6-1ubu
    0x00000080 6e747532 29006c6f 6e67206c 6f6e6720 ntu2).long long
    0x00000090 756e7369 676e6564 20696e74 0073686f unsigned int.sho
    0x000000a0 72742075 6e736967 6e656420 696e7400 rt unsigned int.
    0x000000b0 5f494f5f 73746469 6e5f7573 656400 _IO_stdin_used.

    可執行文件是目標文件

    在 UNIX 中,可執行文件是 目標文件,並且您可以像對 a.out 文件那樣對它們進行分析。可以進行一次有益的練習,更改到 /bin 或 /local/bin 目錄,然後針對一些您最常用的命令,如 pwd、ps、cat 或 rm,運行 nm、objdump 和 readelf。通常,在您編寫需要某種功能的程序時,如果標准的工具已經提供了這個功能,那麼通過運行 objdump -d <command>,可以查看這些工具究竟如何完成這項任務。

    如果您傾向於使用編譯器和其他的語言工具,那麼您可以對組成計算機系統的各種目標文件進行仔細研究,並且您將會發現這項工作是非常值得的。UNIX 操作系統具有許多層次,那些通過工具查看目標文件所公開的層次,非常接近底層硬件。通過這種方式,您可以真實地接觸到系統。

    結束語

    研究目標文件可以極大地加深您對 UNIX 操作系統的認識,並且可以更深入地了解如何對軟件的源代碼進行匯編。我鼓勵您使用本文中介紹的目標文件工具對系統中 /bin 或 /local/bin 目錄中的程序進行分析,仔細研究其輸出結果,並找出您的硬件制造商所提供的系統文檔。

Copyright © Linux教程網 All Rights Reserved