http://blog.chinaunix.net/uid-9525959-id-2001833.html
readelf <option(s)> elf-file(s)
[功能]
用於顯示elf格式檔案的資訊。
[描述]
readelf用來顯示一個或者多個elf格式的目標檔案的資訊,可以通過它的選項來控制顯示哪些資訊。這裡的elf-file(s)就表示那些被檢查的檔案。可以支援32位,64位的elf格式檔案,也支援包含elf檔案的文檔(這裡一般指的是使用ar命令將一些elf檔案打包之後產生的例如lib*.a之類的“靜態庫”檔案)。
這個程式和objdump提供的功能類似,但是它顯示的資訊更為具體,並且它不依賴BFD庫(BFD庫是一個GNU項目,它的目標就是希望通過一種統一的介面來處理不同的目標檔案),所以即使BFD庫有什麼bug存在的話也不會影響到readelf程式。
運行readelf的時候,除了-v和-H之外,其它的選項必須有一個被指定。 ELF檔案介紹
ELF檔案類型:
a)可重定位檔案:使用者和其他目標檔案一起建立可執行檔或者共用目標檔案,例如lib*.a檔案。
b)可執行檔:用於產生進程映像,載入記憶體執行,例如編譯好的可執行檔a.out。
c)共用目標檔案:用於和其他共用目標檔案或者可重定位檔案一起產生elf目標檔案或者和執行檔案一起建立進程映像,例如lib*.so檔案。
ELF檔案作用:
ELF檔案參與程式的串連(建立一個程式)和程式的執行(運行一個程式),所以可以從不同的角度來看待elf格式的檔案:
a)如果用於編譯和連結(可重定位檔案),則編譯器和連結器將把elf檔案看作是節頭表描述的節的集合,程式頭表可選。
b)如果用於載入執行(可執行檔),則載入器將把elf檔案看作是程式頭表描述的段的集合,一個段可能包含多個節,節頭表可選。
c)如果是共用檔案,則兩者都含有。
ELF檔案總體組成:
elf檔案頭描述elf檔案的總體資訊。包括:
系統相關,類型相關,載入相關,連結相關。
系統相關表示:elf檔案標識的魔術數,以及硬體和平台等相關資訊,增加了elf檔案的移植性,使交叉編譯成為可能。
類型相關:就是前面說的elf檔案類型。
載入相關:包括程式頭表相關資訊。
連結相關:節頭表相關資訊。
readelf命令選項(分別以長格式和短格式給出了):
-a
--all 顯示全部資訊,等價於 -h -l -S -s -r -d -V -A -I.
-h
--file-header 顯示elf檔案開始的檔案頭資訊.
-l
--program-headers
--segments 顯示程式頭(段頭)資訊(如果有的話)。
-S
--section-headers
--sections 顯示節頭資訊(如果有的話)。
-g
--section-groups 顯示節組資訊(如果有的話)。
-t
--section-details 顯示節的詳細資料(-S的)。
-s
--syms
--symbols 顯示符號表段中的項(如果有的話)。
-e
--headers 顯示全部頭資訊,等價於: -h -l -S
-n
--notes 顯示note段(核心注釋)的資訊。
-r
--relocs 顯示可重定位段的資訊。
-u
--unwind 顯示unwind段資訊。當前只支援IA64 ELF的unwind段資訊。
-d
--dynamic 顯示動態段的資訊。
-V
--version-info 顯示版本段的資訊。
-A
--arch-specific 顯示CPU構架資訊。
-D
--use-dynamic 使用動態段中的符號表顯示符號,而不是使用符號段。
-x <number or name>
--hex-dump=<number or name> 以16進位方式顯示指定段內內容。number指定段表中段的索引,或字串指定檔案中的段名。
-w[liaprmfFsoR] or
--debug-dump[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges]
顯示調試段中指定的內容。
-I
--histogram 顯示符號的時候,顯示bucket list長度的柱狀圖。
-v
--version 顯示readelf的版本資訊。
-H
--help 顯示readelf所支援的命令列選項。
-W
--wide 寬行輸出。
@file 可以將選項集中到一個檔案中,然後使用這個@file選項載入。
[舉例]
先給出如下例子:
1,對於可執行檔形式的elf格式檔案:
1)查看可執行程式的原始碼如下:
[quietheart@lv-k cppDemo]$ cat main.cpp
#include <iostream>
using std::cout;
using std::endl;
void my_print();
int main(int argc, char *argv[])
{
my_print();
cout<<"hello!"<<endl;
return 0;
}
void my_print()
{
cout<<"print!"<<endl;
}
2)編譯如下:
[quietheart@lv-k cppDemo]$ g++ main.cpp -o main
[quietheart@lv-k cppDemo]$ g++ -g main.cpp -o main.debug
3)編譯之後,查看產生的檔案:
[quietheart@lv-k cppDemo]$ ls -l
總計 64
-rwxr-xr-x 1 quietheart quietheart 6700 07-07 18:04 main
-rw-r--r-- 1 quietheart quietheart 201 07-07 18:02 main.cpp
-rwxr-xr-x 1 quietheart quietheart 38932 07-07 18:04 main.debug
這裡,main.debug是帶有調試資訊的可執行檔,main是一般的可執行檔。
2,對於庫檔案形式的elf格式檔案:
1)查看庫的原始碼如下:
//myfile.h
#ifndef __MYFILE_H
#define __MYFILE_H
void printInfo();
#endif
//myfile.cpp
#include "myfile.h"
#include <iostream>
using std::cout;
using std::endl;
void printInfo()
{
cout<<"hello"<<endl;
}
2)編譯如下:
[quietheart@lv-k bak]$ g++ -c myfile.cpp
[quietheart@lv-k bak]$ g++ -shared -fPCI -o libmy.so myfile.o
[quietheart@lv-k bak]$ ar -r libmy.a myfile.o
ar: creating libmy.a
3)編譯之後,查看產生的檔案:
[quietheart@lv-k bak]$ ls -l
總計 44
-rw-r--r-- 1 quietheart quietheart 2154 07-08 16:14 libmy.a
-rwxr-xr-x 1 quietheart quietheart 5707 07-08 16:08 libmy.so
-rwxr-xr-x 1 quietheart quietheart 117 07-08 16:06 myfile.cpp
-rwxr-xr-x 1 quietheart quietheart 63 07-08 16:08 myfile.h
-rw-r--r-- 1 quietheart quietheart 2004 07-08 16:08 myfile.o
libmy.a libmy.so myfile.cpp myfile.h myfile.o
這裡,分別產生目標檔案myfile.o,共用庫檔案libmy.so,和靜態庫檔案libmy.a。
基於以上可執行檔和庫,這裡給出一些常用的命令。
*讀取可執行檔形式的elf檔案頭資訊:
[quietheart@lv-k cppDemo]$ readelf -h main
輸入之後,輸出資訊如下:
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: 0x8048580
Start of program headers: 52 (bytes into file)
Start of section headers: 3232 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 8
Size of section headers: 40 (bytes)
Number of section headers: 29
Section header string table index: 26
這裡,可見可執行檔的elf檔案,其類型為EXEC(可執行檔)。另外,含調試資訊的"main.debug"和不含調試資訊的"main"除了一些大小資訊之外,其內容是一樣的。並且由此可見檔案的體繫結構為Intel 80386。
*讀取目標檔案形式的elf檔案頭資訊:
[quietheart@lv-k bak]$ readelf -h myfile.o
輸入之後,輸出資訊大致如下:
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: REL (Relocatable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 516 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)