[時間:2017-06] [狀態:Open]
[關鍵詞:GNU, binutils, as, ld, ar, 基礎工具,linux,鏈接器,匯編器]
0 簡介
GNU Binary Utilities或binutils是一整套的編程語言工具程序,用來處理許多格式的目標文件。當前的版本原本由在Cygnus Solutions的程序員以Binary File Descriptor library(libbfd)所撰寫。這個工具程序通常搭配GCC、make、和GDB這些程序來使用。
剛開始時,這個包內只有幾個程序,但后來,由於功能需求近似,陸續加入了GNU匯編器(GAS)和GNU鏈接器(GLD)。一般來說,這些程序都很簡單,大部分的復雜性都存在於Binary File Descriptor library和libopcodes這些庫里頭。
原來的BFD版本由David Henkel-Wallace和Steve Chamberlain所撰寫。Ken Raeburn和Ian Lance Taylor曾維護過。目前則是由Nick Clifton負責維護此版本。至於Linux上的版本,由H.J. Lu在維護。
注:以上內存摘自wiki
GNU Binutils是一系列二進制工具的集合。主要包括:
- ld —— GNU鏈接器
- as—— GNU匯編器
但也包括以下二進制工具:
- addr2line:從目標文件的虛擬地址獲取文件的行號或符號。
- ar:可以對靜態庫做創建、修改和提取的操作。
- c++filt:反編譯(反混淆,demangle)C++符號的工具。
- dlltool:創建創建Windows動態庫。
- gold:另一種新的、更快的僅支持ELF的鏈接器。
- gprof:性能分析(profiling)工具程序。
- nlmconv:可以轉換成NetWare Loadable Module(NLM)目標文件格式。
- nm:顯示目標文件內的符號信息。
- objcopy:復制和轉譯目標文件。
- objdump:顯示目標文件的相關信息,亦可反匯編。
- ranlib:產生靜態庫的索引。(和
nm -s
功能類似) - readelf: 顯示ELF文件的內容。
- size:列出目標文件或庫文件的section大小。
- strings:列出文件中可打印的字符串信息。
- strip:從目標文件中移除符號信息。
- windmc:Windows消息資源編譯器。
- windres:Windows資源文件編譯器。
其中多數程序使用BFD(Binary File Descriptor庫)實現底層操作。其中多數也使用opcodes庫來匯編及反匯編機器指令。
Binutils已被移植到大多數助理的unix/linux系統中,同時也支持Wintel系統,它們存在的主要目標是為GNU系統提供編譯和鏈接程序的機制。
注:以上內容翻譯自GNU Binutils
下面逐個介紹下上面提到的工具集。
這里說明下,所有文檔都可以在documentation for binutils 2.28找到。
1 目標文件處理及分析
nm
nm用來列出目標文件中的符號,可以幫助程序員定位和分析執行程序和目標文件中的符號信息和它的屬性。比如我用以下代碼編譯之后,編譯指令gcc main.cpp
#include <cstdio>
int main(int argc, char **argv)
{
printf("enter checking\n");
return 0;
}
使用nm輸出結果如下:(部分刪減,不是全部)
$ nm a.out
0000000000601040 B __bss_start
0000000000601040 b completed.7291
0000000000601030 D __data_start
0000000000601030 W data_start
0000000000400560 T __libc_csu_init
U __libc_start_main@@GLIBC_2.2.5
0000000000400536 T main
U puts@@GLIBC_2.2.5
00000000004004b0 t register_tm_clones
0000000000400440 T _start
0000000000601040 D __TMC_END__
objcopy
objcopy可以將一種格式的目標文件轉化為另外一種格式的目標文件. 它使用GNU BFD庫進行讀/寫目標文件。objcopy就能將原格式的目標文件轉化為不同格式的目標文件。
objcopy用於將object的部分或全部內容拷貝到另一個object,從而可以實現格式的變換。
objcopy可用用於將文件轉換成S-record格式或者raw二進制格式。objcopy還可以實現將圖像編譯到目標文件中。
objdump
objdump用來顯示目標文件的信息。可以通過選項控制顯示那些特定信息。objdump一個最大的用處恐怕就是將C/C++代碼反匯編了. 在嵌入式軟件開發過程中, 也可以用它查看執行文件或庫文件的信息。
readelf
readelf用來顯示ELF格式目標文件的信息。可通過參數選項來控制顯示哪些特定信息。(注意: readelf不支持顯示靜態庫, 也不支持64位的ELF文件)。
2 編譯鏈接工具
ar
ar用於建立、修改、提取靜態庫文件(archive)。archive是一個包含多個被包含文件的單一文件(也稱之為庫文件),其結構保證了可以從中檢索並得到原始的被包含文件(稱之為archive中的member)。member的原始文件內容、模式(權限)、時間戳、所有者和組等屬性都被保存在 archive中。member被提取后,他們的屬性被恢復到初始狀態。
ar主要用於創建C庫文件。
典型用法如下:
$ ar rv libNAME.a file1.o file2.o
ld
ld是鏈接器,通常由GCC/G++調用。外部基本不可見。
addr2line
在崩庫或者存在需要分析程序調用堆棧的情況下非常有用,addr2line可以反編譯到代碼的特定行。
c++filt
用於反混淆c++變量或函數名稱的,可以還原為人類可讀的格式。通常這個過程稱為反混淆-demangle。
dlltool
生成windows動態鏈接庫在編譯時依賴的lib索引,典型的應用如下:
$ gcc -c dll.c # 編譯
$ dlltool -e exports.o -l dll.lib dll.o # 生成lib
$ gcc dll.o exports.o -o dll.dll
$ gcc program.o dll.lib -o program # 生成調用dll的可執行文件
3 小結
本文內容不是什么新的知識。只是我近期閱讀書籍是看到的。從這些基礎工具來看,基本上可以構建一個類似vs的IDE環境,也可以基本拋開復雜的底層實現邏輯,直接基於高級編程語言進行處理。
撰寫本文的目的主要是整理下我對GNU基礎框架的理解,對基本工具有所了解,對於后續更深入的學習是有所幫助的。