亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区
Chinaunix
標題:
linux存檔文件(archive)分析
[打印本頁]
作者:
jitashan
時間:
2008-11-28 16:53
標題:
linux存檔文件(archive)分析
出于好奇,想了解一下linux的存檔文件(*.a)的格式。在網(wǎng)上大概找了一下,沒找到比較好的(沒細找),所以想自己摸索
一下,把它的文件格式弄清楚。結(jié)構(gòu)發(fā)現(xiàn)這個文件的格式竟然那么簡單。在這里和大家分享一下,有錯誤的地方希望大家指正。
1.存檔文件(archive)簡介
存檔文件(*.a)文件相當于windows的靜態(tài)鏈接庫,他把很多的目標文件(*.o)文件打包為單一的庫文件。在鏈接程序
的時候,需要用到庫里面的函數(shù)時,只需在鏈接時加上-lX (X表示庫的名字),鏈接器會自動得根據(jù)要調(diào)用函數(shù),找到相應的
目標文件,鏈接到可執(zhí)行程序中,不需要的目標不會被鏈接到可執(zhí)行程序中。
2.archive文件的格式[參考/usr/include/ar.h中的說明]
archive文件的格式主要保護兩個部分,主要是:
一個頭部標志ARMAG,
多個數(shù)據(jù)區(qū)。
['頭部標志'和'數(shù)據(jù)區(qū)'是我自己為了方便說明起的名字,跟官方的說法應該是有出入的]。
2.1 頭部標志
頭部標志的作用僅用于說明這是一個archive文件
在ar.h中定義了兩個宏:
#define ARMAG "!\n" /* String that begins an archive file. */
#define SARMAG 8 /* Size of that string. */
ARMAG指明了頭部標志的內(nèi)容,SARMAG說明了頭部標志的長度。
2.2 數(shù)據(jù)區(qū)
一個archive文件有多個數(shù)據(jù)區(qū),每個數(shù)據(jù)區(qū)包含一個頭部(ar_hdr)和一段數(shù)據(jù)段,他們是緊跟在一起的。
在ar.h中ar_hdr的聲明是這樣的
struct ar_hdr
{
char ar_name[16]; /* Member file name, sometimes / terminated. */
char ar_date[12]; /* File date, decimal seconds since Epoch. */
char ar_uid[6], ar_gid[6]; /* User and group IDs, in ASCII decimal. */
char ar_mode[8]; /* File mode, in ASCII octal. */
char ar_size[10]; /* File size, in ASCII decimal. */
char ar_fmag[2]; /* Always contains ARFMAG. */
};
在archive中每個目標文件(*.o)都會被分配一個數(shù)據(jù)區(qū),數(shù)據(jù)區(qū)的數(shù)據(jù)段是該目標文件(*.o)原封不動的拷貝,ar_hdr
則存放了對該目標文件的說明。
ar_name文件說明了目標文件的名字(以/作為終止符),
ar_date說明了該文件的日期,
ar_uid、ar_gid指明了該目標文件的用戶ID和組ID,
ar_mode指明了文件的訪問屬性(權(quán)限),
ar_size指明了目標文件的大小,同時是該數(shù)據(jù)區(qū)數(shù)據(jù)段的大小
ar_fmag總是包含ARFMAG,該宏被定義為#define ARFMAG "`\n" , 用戶指明ar_hdr的尾部。
除了為每個目標文件分配一個數(shù)據(jù)區(qū)之外,archive文件還添加一個特殊的數(shù)據(jù)區(qū),它位于第一個數(shù)據(jù)區(qū),它的數(shù)據(jù)段
包含了該archive文件的符號數(shù)(函數(shù)/全局變量)、符號名稱、符號所在目標文件的偏移量。
3.archive文件的分析
首先,建立兩個測試文件,并把它們加到archive文件中:
[root:/root/test/ar]cat test_ar.c
int test(void)
這樣,我們把test_ar.o test_ar_1.o放到了libtest_ar.a中。我們用hexdump對libtest_ar.a進程剖析
(不熟悉hexdump用法的參見man hexdump)
[root:/root/test/ar]hexdump -C -s 0x0 -n 8 libtest_ar.a
00000000 21 3c 61 72 63 68 3e 0a |!.|
上面是頭部標志部分,位于文件最前面。
[root:/root/test/ar]hexdump -C -s 0x8 -n 60 libtest_ar.a
00000008 2f 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 |/ |
00000018 31 32 31 36 32 38 30 37 39 36 20 20 30 20 20 20 |1216280796 0 |
00000028 20 20 30 20 20 20 20 20 30 20 20 20 20 20 20 20 | 0 0 |
00000038 33 32 20 20 20 20 20 20 20 20 60 0a |32 `.|
00000044
上面是第一個數(shù)據(jù)區(qū)的頭部ar_hdr,名字為空, '/'是終止符,1216280796是文件的時間,是被字符串化
的time_t類型的數(shù)據(jù),三個0中前兩個分別為uid和gid,后面一個標志目標文件屬性,在這忽略,32是該數(shù)據(jù)
區(qū)后面數(shù)據(jù)段的長度, `.是終止符。
[root:/root/test/ar]hexdump -C -s 0x44 -n 32 libtest_ar.a
00000044 00 00 00 03 00 00 00 64 00 00 00 64 00 00 03 62 |.......d...d...b|
00000054 74 65 73 74 00 65 72 72 6f 72 00 74 65 73 74 00 |test.error.test.|
上面是特殊數(shù)據(jù)區(qū)的數(shù)據(jù)段,第一行中00 00 00 03表示的是該archive文件向外
導出的符號數(shù),這里為3(注意,這里的數(shù)據(jù)都是按大尾的編碼方式的)。00 00 00 64 、
00 00 00 64、 00 00 03 62分別是三個符號所在目標文件的ar_hdr在該archive文件中的
偏移量,分別是0x64、0x64、0x362,緊接著是符號名稱的字符串表。
[root:/root/test/ar]hexdump -C -s 0x64 -n 60 libtest_ar.a
00000064 74 65 73 74 5f 61 72 2e 6f 2f 20 20 20 20 20 20 |test_ar.o/ |
00000074 31 32 31 36 32 38 30 37 31 38 20 20 30 20 20 20 |1216280718 0 |
00000084 20 20 30 20 20 20 20 20 31 30 30 36 36 34 20 20 | 0 100664 |
00000094 37 30 36 20 20 20 20 20 20 20 60 0a |706 `.|
000000a0
[root:/root/test/ar]hexdump -C -s 0x362 -n 60 libtest_ar.a
00000362 74 65 73 74 5f 61 72 5f 31 2e 6f 2f 20 20 20 20 |test_ar_1.o/ |
00000372 31 32 31 36 32 38 30 37 35 30 20 20 30 20 20 20 |1216280750 0 |
00000382 20 20 30 20 20 20 20 20 31 30 30 36 36 34 20 20 | 0 100664 |
00000392 36 38 36 20 20 20 20 20 20 20 60 0a |686 `.|
0000039e
上面驗證了0x64、0x362是目標文件的ar_hdr在該archive文件中的偏移量,可以看出,第一個test和error定義在
test_ar.o中,第二個test定義在test_ar_1.o中,這和我們之前寫的文件是相符的。
上面第一命令,同樣test_ar.o/是目標文件的名字,1216280718是時間,兩個0分別是uid和gid,100644表示文件
權(quán)限(rw_rw_r__), 706是該目標文件的大小,也是下面數(shù)據(jù)段的大小。
[root:/root/test/ar]ls -l *.o
-rw-rw-r-- 1 root root 686 07-17 15:45 test_ar_1.o
-rw-rw-r-- 1 root root 706 07-17 15:45 test_ar.o
和archive文件中的數(shù)據(jù)相符的。
接下來我們對比一下存檔中的內(nèi)容和目標文件的內(nèi)容。
[root:/root/test/ar]hexdump -C -s 0xa0 -n 706 libtest_ar.a
對比上面兩個輸出,內(nèi)容是完全一致的,正是我之前期盼的那樣。
4.鏈接
在上面的例子中,我故意在test_ar.c、test_ar_1.c中定義了同名的函數(shù)。但一個返回0,
一個返回1,主要是為了檢查符號的解析。
我又寫了一個測試文件。
[root:/root/test/ar]cat main.c
#include
int main()
{
int i = test();
printf("%d\n", i);
return 0;
}
[root:/root/test/ar]gcc -o main main.c -L. -ltest_ar
[root:/root/test/ar]./main
0
輸出結(jié)果為0,也就是它調(diào)用的時test_ar.o中的test()函數(shù)而不是調(diào)用test_ar_1.o中的函數(shù)。
我們看上面符號表中的數(shù)據(jù)
00000044 00 00 00 03 00 00 00 64 00 00 00 64 00 00 03 62 |.......d...d...b|
00000054 74 65 73 74 00 65 72 72 6f 72 00 74 65 73 74 00 |test.error.test.|
test_ar.o中test在前面,鏈接的過程我猜想是這樣的[如有錯誤請糾正]:
1.函數(shù)遇到一個未解析的符號,它在-l指定的連接歸檔庫中查找。
2.當查找到第一個符合的符號時,他即停止搜索。
3.根據(jù)符號獲得目標文件在archive中的偏移量,把相關的目標文件(*.o)從庫中復制一份出來,
鏈接到可執(zhí)行程序中。
本文來自ChinaUnix博客,如果查看原文請點:
http://blog.chinaunix.net/u2/73874/showart_1671167.html
歡迎光臨 Chinaunix (http://www.72891.cn/)
Powered by Discuz! X3.2