GCC編譯器原理(一)------GCC 工具:addr2line、ar、as、c++filt和elfedit


1.3 GCC 工具

1.3.1 binutils 工具集

工具

描述

addr2line

給出一個可執行文件的內部地址,addr2line 使用文件中的調試信息將地址翻譯成源代碼文件名和行號。

ar

這是一個程序,可通過從文檔中增加、刪除和析取文件來維護庫文件。通常使用該工具是為了創建和管理連接程序使用的目標庫文檔。

as

GNU 匯編器。實際上它是一族匯編器,因為它可以被編譯或能夠在各種不同平台上工作。

c++filt

程序接受被 C++編譯程序轉換過的名字(不是被重載的) ,而且將該名字翻譯成初始形式。

elfedit

更新 ELF 文件的 ELF 頭。

gprof

該程序會監督編譯程序的執行過程,並報告程序中各個函數的運行時間,可以根據所提供的配置文件來優化程序。

ld

GNU 連接程序。該程序將目標文件的集合組合成可執行程序。

ld.bfd

到 ld 的硬鏈接。

libbfd

二進制文件描述器庫。該程序是 binutils 包的一部分

libiberty

包含多個 GNU 程序會使用的途徑,包括 getoptobstackstrerrorstrtol 和 strtoul。

libopcodes

一個庫,用於處理 opcodes——處理器指令的 "可讀文本" 版本;用於編制 objdump 這樣的工具。

nlmconv

將可重定位的目標文件轉換成 NetWare 可加載模塊(NetWare Loadable ModuleNLM) 。

nm

列出目標文件中定義的符號。

objcopy

將目標文件從一種二進制格式復制和翻譯到另外一種。

objdump

顯示一個或多個目標文件中保存的多種不同信息。

ranlib

創建和添加到 ar 文檔的索引。該索引被 ld 使用來定位庫中的模塊。

readelf

ELF 格式的目標文件顯示信息

size

列出目標文件中每個部分的名字和尺寸。

strings

瀏覽所有類型的文件,析取出用於顯示的字符串。

strip

從目標文件或文檔庫中去掉符號表,以及其他調試所需的信息。

windres

Window 資源文件編譯程序。

 

1.3.2 addr2line:地址翻譯工具

addr2line用於得到程序指令地址所對應的函數,以及函數所在的源文件名和行號。

參照對應工具的man和info信息,可以查找到詳細信息。或者運行相應的工具並指定--help參數,可以獲得該工具的簡單幫助信息。

用法:addr2line [選項] [地址]

將地址轉換成文件名/行號對。

如果沒有在命令行中給出地址,就從標准輸入中讀取它們

選項是:@<file> 讀取選項從 <file>

選項

描述

-a

--addresses 顯示地址

-b

--target=<bfdname> 設置二進位文件格式

-e

--exe=<executable><name> 設置輸入文件名稱(默認為 a.out)

-i

--inlines 解開內聯函數

-j

--section=<name> 讀取相對於段的偏移而非地址

-p

--pretty-print 讓輸出對人類更可讀

-s

--basenames 去除目錄名

-f

--functions 顯示函數名

-C

--demangle[=style] 解碼函數名

-h

--help 顯示本幫助

 

測試代碼:main.c

1

2

3

4

5

6

7

8

9

10

11

12

13

#include <stdio.h>

#include <stdlib.h>

 

void func(void)

{

printf("func() address is %p\n", func);

}

 

int main(int argc, char *argv[])

{

func();

return 0;

}

編譯:gcc -g main.c -o main -Wall

執行:./main

根據地址找到對應的代碼位置

1.3.3 ar:創建和管理連接程序使用的目標庫文檔

ar 命令的語法如下:ar [options] [positionname] [count] archive objectfile [objectfile ...]

  • options:選項標簽,選項的字母表示之間沒有空格,選項可通過(也可不通過)連字符來表達。
  • 可選的命令行項目 positionname count 只有當用到了某些需要它們的選項時才會出現。
  • ar 命令的選項分為兩類:命令行選項告訴 ar 應該采取什么樣的操作(有效命令行選項中的一個) ,以及修改子(modifier) 選項指出如何執行該命令操作

指明操作的ar 選項:

選項

描述

d

從文檔中刪除模塊 objectfiles。利用 v 修改子,列出的所有模塊都要被刪除

m

將模塊移入文檔內部。默認情況下,列舉的所有 objectfiles 成員都會移到文檔尾部。利用修改子 ab i 可將指定模塊移到其他位置

p

將指定的目標文件 objectfiles 的二進制內容打印到標准輸出上。如果沒有指定目標文件objectfiles,就打印所有目標文件。修改子 v 會打印所有列在其內容之前的名字

q

將指定目標文件 objectfiles 快速附加到文檔末尾,而不檢查是否可以取代而不是一味添加。不會更新索引,因此 ranlib 必須在連接庫之前使用

r

將指定目標文件 objectfiles 插入文檔。如果指定的所有目標文件都已經在文檔中了,就用新的替換老的。如果指定文檔不存在,就會創建此文檔。默認條件下,新的模塊會添加到文件的末尾,但是修改子 ab i 可用來指定新模塊的位置

t

顯示一列文檔文件的內容。修改子 v 會為該列表加上時間戳、所有者、組、以及每個模塊的大小。如果沒有指定目標文件 objectfiles,就會列出整個文檔

x

將指定目標文件展開成正常的磁盤文件。如果沒有指定目標文件,就會展開所有文件

 

修改子選項:

選項

描述

a

將新文件添加到命令行指定文件位置之后,該文件是作為位置文件的

b

將新文件添加到命令行指定文件位置之前,該文件是作為位置文件的。這和選項 i 一樣

c

如果必要就創建文檔。只要需要總會創建新的文檔,但使用該選項會禁止警告消息

f

截斷文檔內的文件名。通常 ar 允許任意長度的文件名,可是這樣會導致文檔的創建過程在某些系統中不能相互兼容

i

立即將所有新文件添加到命令行指定的文件位置之前。這和選項 b 一樣

N

當文檔中存在多個指定的目標文件時,count 參數可用來當作指定目標文件的選擇子(selector

o

當文件是從文檔中展開時,原始日期可以得到保留

s

即使沒有改動文檔,也會創建新的文檔索引。在 ar 中會單獨使用修改子,這和使用 ranlib 的結果一樣

u

當文件加入文檔時,該選項說明只有比文檔中現有文件更新的文件才會被添加。該修改子只有和選項 r 在一起才有效

v

按照詳細模式運行,在運行處理過程中顯示附加信息

V

顯示版本信息,然后退出

1.3.4 as:GNU匯編器

它是 GNU 匯編器,主要用來編譯 GNU C 編譯器 gcc 輸出的匯編文件,它將匯編代碼轉換成二進制代碼,並存放到一個 object 文件中,該目標文件將由連接器 ld 連接

  • as的內部預處理主要包括三個方面的工作
    • 調整和去除額外的間隔符,保留每行的關鍵字前的一個空格或者TAB,其他任意的間隔符都轉換為一個空格。
    • 去除所有注釋,代之以一個空格,或者新行的合適的數字。
    • 把字符常量轉換成相應的數字值。
  • 它不能做宏處理和文件包含處理,如果需要用,可以交給 C 預處理器來處理

語法:as(選項)(參數)

常用選項如下:

選項

描述

-ac

忽略失敗條件;

-ad

忽略調試指令;

-ah

包括高級源;

-al

包括裝配;

-am

包括宏擴展;

-an

忽略形式處理;

-as

包括符號;

=file

設置列出文件的名字;

--alternate

以交互宏模式開始;

-f

跳過空白和注釋預處理;

-g

產生調試信息;

-J

對於有符號溢出不顯示警告信息;

-L

在符號表中保留本地符號;

-o

指定要生成的目標文件;

--statistics

打印匯編所用的最大空間和總時間。

例子:as -o main.o main.s –32,編譯32位的匯編代碼

1.3.5 c++filt:修復 C++ 和 Java 符號

主要是為了防止 C++ 和 Java 中的多個函數名重復產生的重載問題。由於每個重載函數都使用與原函數相同的名稱,因此,支持函數重載的語言必須擁有一種機制,以區分同一個函數的許多重載版本。

c++filt 將每個輸入的名稱看成是改編后的名稱,並設法確定用於生成該名稱的編譯器。

如果這個名稱是一個合法的改編名稱,那么,c++filt 就輸出改編之前的名稱; 如果c++filt無法識別一個改編名稱,那它就按原樣輸出該名稱。

不關注除 C 語言之外的語言,命令選項查看 man 手冊

1.3.6 elfedit:檢查或編輯 ELF 文件

elfedit 是一個用於檢查或修改現有 ELF 目標文件內容的工具。可以訪問目標文件中包含的大多數 ELF 數據,這些數據包括 ELF 頭、節頭表、程序頭表、動態節、硬件和軟件功能、字符串表和符號表。

elfedit 可以處理來自命令行(–e 選項)或標准輸入的命令。如果標准輸入是一個終端,elfedit 可提供終端編輯功能以及涵蓋大量命令的命令補齊功能。ELF 對特殊整數值和位掩碼使用許多標准符號名稱。elfedit 可識別此類名稱的最有可能的完整形式。在輸入 elfedit 命令時,可以隨時按 TAB 鍵,令 elfedit 顯示用法消息以及當前光標處文本的任意已知完整形式。

elfedit 功能以模塊形式組織。每個模塊提供一組命令,這些命令針對相關功能。通過使用冒號 (:) 分隔符將模塊和命令名稱組合到一起(中間無空格)來指定命令。例如,dyn:runpath 指的是由 dyn 模塊提供的 runpath 命令。模塊名稱必須是唯一的。給定模塊中的命令名稱在該模塊中必須唯一,但可在多個模塊中使用相同的命令名稱。

某些模塊將模塊內的某個命令指定為該模塊的缺省命令。用戶只需指定模塊名稱,就可運行此命令。大多數 elfedit 模塊均提供一個名為 dump 的命令,它針對模塊涵蓋的 ELF 文件部分生成的信息與 elfdump 實用程序所顯示的信息相同。通常,模塊會將 dump 指定為其缺省命令。

用於執行 elfedit 命令的語法在設計上采用類似 UNIX 命令行實用程序的語法,這樣任何會使用 UNIX 命令行實用程序的人都可以方便地使用 elfedit 命令。該語法由空格分隔的標記組成:第一個標記是命令名稱。選項(即以連字符 (-) 開頭的參數)跟在命令后面。純參數(操作數)跟在選項后面。一個給定的命令可以有 0 個或多個選項和操作數,但是如果它們同時存在,選項始終位於純參數前面。可使用特殊選項 --(兩個連字符)來限定選項的結尾。如果遇到此選項,其余所有參數均被視為純參數,即使它們以 - 開頭。

elfedit 標記中的字符的解釋取決於所用的引用格式:

引用格式

描述

非引用

單引號 (') 或雙引號 (") 外面的反斜杠 (\) 充當轉義符。elfedit 發現反斜杠字符時會將其忽略,並按字面意思處理反斜杠后面的字符(即使它后面的字符為反斜杠)。此功能可用於在命令的字符串參數中插入一個空白字符,從而無需將一個字符串分為兩個單獨的標記。同樣,它可用於插入一個引號或反斜杠作為文本字符。

單引號

在單引號 (') 中,空白字符不用於分隔標記,且會被解釋為標記內部的文本字符。雙引號 (") 和反斜杠 (\) 字符會被解釋為文本字符,無特殊意義。

雙引號

在雙引號 (") 中,空白字符不用於分隔標記。單引號字符會被解釋為文本,不具有引用功能。反斜杠 (\) 是一個轉義字符,在字符串文本中,其作用與 C 編程語言中反斜杠的作用類似:

\a        警報(響鈴)

\b        退格鍵

\f        換頁符

\n        換行符

\r        回車

\t        水平制表符

\v        垂直制表符

\\        反斜杠

\'        單引號

\"        雙引號

\ooo    八進制常量,其中 ooo 是 1 到 3 個八進制位 (0...7)

在反斜杠后面跟有任何其他字符,均會出錯。

 

核心命令均屬於一個名為 sys 的內部模塊。所有其他模塊均打包為可動態裝入的可共享目標文件。當執行需要某個模塊的命令時或者當執行 sys:load 命令時,elfedit 會按需裝入模塊。由於 sys 模塊特殊的內置狀態,而且其命令使用頻繁,所以 elfedit 命令允許在不加 sys: 前綴的情況下指定 sys 模塊中的命令,例如,使用 load 而非 sys:load。要訪問任何其他模塊中的命令,必須采用 module:cmd 完整格式指定。

elfedit 隨以下標准模塊一起提供:

模塊

描述

cap

功能節

dyn

動態節

ehdr

ELF 頭

reloc

重定位節

phdr

程序頭數組

shdr

節頭數組

str

字符串表節

sym

符號表節

syminfo

Syminfo 節

sys

內置的核心 elfedit 命令

 

命令用法:elfedit [-adr] [-e cmd] [-L path] [-o default | simple | num] [infile] [outfile]

選項

描述

–a

啟用 autoprint 模式。啟用 autoprint 后,elfedit 將輸出修改 ELF 文件后所生成的修改值。此輸出以當前輸出樣式顯示,可使用 –o 選項更改此樣式。缺省輸出樣式是 elfdump(1) 實用程序使用的樣式。以交互方式使用 elfedit 時,autoprint 模式為缺省模式(當 stdin 和 stdout 為終端時)。因此,僅當在非交互式上下文中使用 elfedit 時,–a 選項才有意義。要在交互式會話中禁用 autoprint,請使用 elfedit 命令:> set a off

–d

如果已設置,此選項可使 elfedit 發布信息性消息,說明其內部操作和要處理的 ELF 目標文件的詳細信息。這在需要深入了解所執行的操作時非常有用。

–e cmd

指定一個編輯命令。可以指定多個 –e 選項。如果在命令行上指定了多個編輯命令,elfedit 將在批處理模式下運行。打開文件后,elfedit 按給定的順序執行每個命令,然后保存修改的文件,最后 elfedit 退出。從 shell 腳本和 makefile 執行簡單操作時,批處理模式非常有用。

–L path

設置用於定位 elfedit 模塊的缺省路徑。本手冊頁的"模塊搜索路徑"部分介紹了各個模塊。

–o default | simple | num

用於顯示 ELF 數據的樣式。此選項用於確立會話的當前樣式。可在 elfedit 會話中更改此樣式,方法是使用 set (sys:set) 命令或向會話中執行的各個命令提供 –o 選項。

default

缺省樣式是以適合用戶查看的格式顯示輸出。此樣式與 elfdump 實用程序使用的樣式類似。

num

整數值始終以整數格式顯示。字符串顯示為在內含的字符串表中定位所用的整數偏移量。

simple

顯示 ELF 文件中的字符串時,僅顯示字符串。如果可能,整數值顯示為符號常量,否則以整數格式顯示。不顯示任何標題、頭或其他補充輸出。

–r

只讀模式。輸入文件以只讀訪問模式打開,編輯會話的結果不會保存。指定了 –r 時,elfedit 不允許使用 outfile 參數。如果不打算修改文件,強烈建議使用只讀模式。除了提供額外保護以防止意外修改外,該選項還允許檢查用戶沒有寫入權限的文件。

 

操作數支持:

操作數

描述

infile

包含要處理的 ELF 目標文件的輸入文件。

此文件可以為可執行文件 (ET_EXEC)、共享目標文件 (ET_DYN) 或可重定位目標文件 (ET_REL)。不直接支持歸檔文件。要編輯歸檔中的目標文件,必須提取目標文件,編輯副本,然后將其重新插入到該歸檔文件。

如果未提供 infile,elfedit 將在限定模式下運行,此模式僅允許執行 sys: 模塊中的命令。此模式主要用於訪問 help (sys:help) 命令提供的命令文檔。

如果提供了 infile,但未給定任何 outfile,elfedit 將就地編輯文件並將結果寫入同一文件,這會導致原始文件內容被覆蓋。通常,不建議以此模式使用 elfedit,建議指定輸出文件。生成的文件經過測試和驗證后,可將其移動到原始文件所在的位置。

–r 選項可用於以只讀訪問模式打開 infile。在檢查不希望修改的現有文件時,此選項非常有用。

outfile

輸出文件。如果同時提供了 infile 和 outfile,infile 將以只讀訪問模式打開,修改的目標文件內容會寫入到 outfile 中。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM