出于好奇,想了解一下linux的存档文件(*.a)的格式。在网上大概找了一下,没找到比较好的(没细找),所以想自己摸索
一下,把它的文件格式弄清楚。结构发现这个文件的格式竟然那么简单。在这里和大家分享一下,有错误的地方希望大家指正。
一下,把它的文件格式弄清楚。结构发现这个文件的格式竟然那么简单。在这里和大家分享一下,有错误的地方希望大家指正。
1.存档文件(archive)简介
存档文件(*.a)文件相当于windows的静态链接库,他把很多的目标文件(*.o)文件打包为单一的库文件。在链接程序
的时候,需要用到库里面的函数时,只需在链接时加上-lX (X表示库的名字),链接器会自动得根据要调用函数,找到相应的
目标文件,链接到可执行程序中,不需要的目标不会被链接到可执行程序中。
的时候,需要用到库里面的函数时,只需在链接时加上-lX (X表示库的名字),链接器会自动得根据要调用函数,找到相应的
目标文件,链接到可执行程序中,不需要的目标不会被链接到可执行程序中。
2.archive文件的格式[参考/usr/include/ar.h中的说明]
archive文件的格式主要保护两个部分,主要是:
一个头部标志ARMAG,
多个数据区。
多个数据区。
['头部标志'和'数据区'是我自己为了方便说明起的名字,跟官方的说法应该是有出入的]。
2.1 头部标志
头部标志的作用仅用于说明这是一个archive文件
在ar.h中定义了两个宏:
#define ARMAG "!<arch>\n" /* String that begins an archive file. */
#define SARMAG 8 /* Size of that string. */
#define SARMAG 8 /* Size of that string. */
ARMAG指明了头部标志的内容,SARMAG说明了头部标志的长度。
2.2 数据区
一个archive文件有多个数据区,每个数据区包含一个头部(ar_hdr)和一段数据段,他们是紧跟在一起的。
在ar.h中ar_hdr的声明是这样的
在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. */
};
{
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)都会被分配一个数据区,数据区的数据段是该目标文件(*.o)原封不动的拷贝,ar_hdr
则存放了对该目标文件的说明。
则存放了对该目标文件的说明。
ar_name文件说明了目标文件的名字(以/作为终止符),
ar_date说明了该文件的日期,
ar_uid、ar_gid指明了该目标文件的用户ID和组ID,
ar_mode指明了文件的访问属性(权限),
ar_size指明了目标文件的大小,同时是该数据区数据段的大小
ar_fmag总是包含ARFMAG,该宏被定义为#define ARFMAG "`\n" , 用户指明ar_hdr的尾部。
除了为每个目标文件分配一个数据区之外,archive文件还添加一个特殊的数据区,它位于第一个数据区,它的数据段
包含了该archive文件的符号数(函数/全局变量)、符号名称、符号所在目标文件的偏移量。
ar_date说明了该文件的日期,
ar_uid、ar_gid指明了该目标文件的用户ID和组ID,
ar_mode指明了文件的访问属性(权限),
ar_size指明了目标文件的大小,同时是该数据区数据段的大小
ar_fmag总是包含ARFMAG,该宏被定义为#define ARFMAG "`\n" , 用户指明ar_hdr的尾部。
除了为每个目标文件分配一个数据区之外,archive文件还添加一个特殊的数据区,它位于第一个数据区,它的数据段
包含了该archive文件的符号数(函数/全局变量)、符号名称、符号所在目标文件的偏移量。
3.archive文件的分析
首先,建立两个测试文件,并把它们加到archive文件中:
[root:/root/test/ar]cat test_ar.c
int test(void) <---------------------定义一个函数和一个变量
{
return 0;
};
int error;
[root:/root/test/ar]gcc -o test_ar.o -c test_ar.c
[root:/root/test/ar]cat test_ar_1.c
int test(void) <------------------------定义一个函数
{
return 1;
}
[root:/root/test/ar]gcc -o test_ar_1.o -c test_ar_1.c
[root:/root/test/ar]ar -rv libtest_ar.a test_ar.o test_ar_1.o
r - test_ar.o
r - test_ar_1.o
[root:/root/test/ar]ar -vt libtest_ar.a
rw-rw-r-- 0/0 706 Jul 17 15:45 2008 test_ar.o
rw-rw-r-- 0/0 686 Jul 17 15:45 2008 test_ar_1.o
int test(void) <---------------------定义一个函数和一个变量
{
return 0;
};
int error;
[root:/root/test/ar]gcc -o test_ar.o -c test_ar.c
[root:/root/test/ar]cat test_ar_1.c
int test(void) <------------------------定义一个函数
{
return 1;
}
[root:/root/test/ar]gcc -o test_ar_1.o -c test_ar_1.c
[root:/root/test/ar]ar -rv libtest_ar.a test_ar.o test_ar_1.o
r - test_ar.o
r - test_ar_1.o
[root:/root/test/ar]ar -vt libtest_ar.a
rw-rw-r-- 0/0 706 Jul 17 15:45 2008 test_ar.o
rw-rw-r-- 0/0 686 Jul 17 15:45 2008 test_ar_1.o
这样,我们把test_ar.o test_ar_1.o放到了libtest_ar.a中。我们用hexdump对libtest_ar.a进程剖析
(不熟悉hexdump用法的参见man hexdump)
(不熟悉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 |!<arch>.| <----头部标志
00000008
00000000 21 3c 61 72 63 68 3e 0a |!<arch>.| <----头部标志
00000008
上面是头部标志部分,位于文件最前面。
[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
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
上面是第一个数据区的头部ar_hdr,名字为空, '/'是终止符,1216280796是文件的时间,是被字符串化
的time_t类型的数据,三个0中前两个分别为uid和gid,后面一个标志目标文件属性,在这忽略,32是该数据
区后面数据段的长度, `.是终止符。
[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.|
的time_t类型的数据,三个0中前两个分别为uid和gid,后面一个标志目标文件属性,在这忽略,32是该数据
区后面数据段的长度, `.是终止符。
[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.|
上面是特殊数据区的数据段,第一行中00 00 00 03表示的是该archive文件向外
导出的符号数,这里为3(注意,这里的数据都是按大尾的编码方式的)。00 00 00 64 、
00 00 00 64、 00 00 03 62分别是三个符号所在目标文件的ar_hdr在该archive文件中的
偏移量,分别是0x64、0x64、0x362,紧接着是符号名称的字符串表。
导出的符号数,这里为3(注意,这里的数据都是按大尾的编码方式的)。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
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中,第二个test定义在test_ar_1.o中,这和我们之前写的文件是相符的。
上面第一命令,同样test_ar.o/是目标文件的名字,1216280718是时间,两个0分别是uid和gid,100644表示文件
权限(rw_rw_r__), 706是该目标文件的大小,也是下面数据段的大小。
权限(rw_rw_r__), 706是该目标文件的大小,也是下面数据段的大小。
[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
-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文件中的数据相符的。
接下来我们对比一下存档中的内容和目标文件的内容。
[root:/root/test/ar]hexdump -C -s 0xa0 -n 706 libtest_ar.a <-------0xa0是紧接着test_ar.o的ar_hdr之后的地址
000000a0 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
000000b0 01 00 03 00 01 00 00 00 00 00 00 00 00 00 00 00 |................|
000000c0 b4 00 00 00 00 00 00 00 34 00 00 00 00 00 28 00 |........4.....(.|
000000d0 09 00 06 00 55 89 e5 b8 00 00 00 00 5d c3 00 00 |....U.......]...|
000000e0 00 47 43 43 3a 20 28 47 4e 55 29 20 34 2e 31 2e |.GCC: (GNU) 4.1.|
000000f0 32 20 32 30 30 37 30 39 32 35 20 28 52 65 64 20 |2 20070925 (Red |
00000100 48 61 74 20 34 2e 31 2e 32 2d 33 33 29 00 00 2e |Hat 4.1.2-33)...|
00000110 73 79 6d 74 61 62 00 2e 73 74 72 74 61 62 00 2e |symtab..strtab..|
00000120 73 68 73 74 72 74 61 62 00 2e 74 65 78 74 00 2e |shstrtab..text..|
00000130 64 61 74 61 00 2e 62 73 73 00 2e 63 6f 6d 6d 65 |data..bss..comme|
00000140 6e 74 00 2e 6e 6f 74 65 2e 47 4e 55 2d 73 74 61 |nt..note.GNU-sta|
00000150 63 6b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |ck..............|
00000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000170 00 00 00 00 00 00 00 00 00 00 00 00 1b 00 00 00 |................|
00000180 01 00 00 00 06 00 00 00 00 00 00 00 34 00 00 00 |............4...|
00000190 0a 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |................|
000001a0 00 00 00 00 21 00 00 00 01 00 00 00 03 00 00 00 |....!...........|
000001b0 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........|
000001c0 00 00 00 00 04 00 00 00 00 00 00 00 27 00 00 00 |............'...|
000001d0 08 00 00 00 03 00 00 00 00 00 00 00 40 00 00 00 |............@...|
000001e0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |................|
000001f0 00 00 00 00 2c 00 00 00 01 00 00 00 00 00 00 00 |....,...........|
00000200 00 00 00 00 40 00 00 00 2e 00 00 00 00 00 00 00 |....@...........|
00000210 00 00 00 00 01 00 00 00 00 00 00 00 35 00 00 00 |............5...|
00000220 01 00 00 00 00 00 00 00 00 00 00 00 6e 00 00 00 |............n...|
00000230 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................|
00000240 00 00 00 00 11 00 00 00 03 00 00 00 00 00 00 00 |................|
00000250 00 00 00 00 6e 00 00 00 45 00 00 00 00 00 00 00 |....n...E.......|
00000260 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 |................|
00000270 02 00 00 00 00 00 00 00 00 00 00 00 1c 02 00 00 |................|
00000280 90 00 00 00 08 00 00 00 07 00 00 00 04 00 00 00 |................|
00000290 10 00 00 00 09 00 00 00 03 00 00 00 00 00 00 00 |................|
000002a0 00 00 00 00 ac 02 00 00 16 00 00 00 00 00 00 00 |................|
000002b0 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |................|
000002c0 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................|
000002d0 00 00 00 00 00 00 00 00 04 00 f1 ff 00 00 00 00 |................|
000002e0 00 00 00 00 00 00 00 00 03 00 01 00 00 00 00 00 |................|
000002f0 00 00 00 00 00 00 00 00 03 00 02 00 00 00 00 00 |................|
00000300 00 00 00 00 00 00 00 00 03 00 03 00 00 00 00 00 |................|
00000310 00 00 00 00 00 00 00 00 03 00 05 00 00 00 00 00 |................|
00000320 00 00 00 00 00 00 00 00 03 00 04 00 0b 00 00 00 |................|
00000330 00 00 00 00 0a 00 00 00 12 00 01 00 10 00 00 00 |................|
00000340 04 00 00 00 04 00 00 00 11 00 f2 ff 00 74 65 73 |.............tes|
00000350 74 5f 61 72 2e 63 00 74 65 73 74 00 65 72 72 6f |t_ar.c.test.erro|
00000360 72 00 |r.|
00000362
[root:/root/test/ar]hexdump -C -s 0x0 -n 706 test_ar.o
00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 01 00 03 00 01 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020 b4 00 00 00 00 00 00 00 34 00 00 00 00 00 28 00 |........4.....(.|
00000030 09 00 06 00 55 89 e5 b8 00 00 00 00 5d c3 00 00 |....U.......]...|
00000040 00 47 43 43 3a 20 28 47 4e 55 29 20 34 2e 31 2e |.GCC: (GNU) 4.1.|
00000050 32 20 32 30 30 37 30 39 32 35 20 28 52 65 64 20 |2 20070925 (Red |
00000060 48 61 74 20 34 2e 31 2e 32 2d 33 33 29 00 00 2e |Hat 4.1.2-33)...|
00000070 73 79 6d 74 61 62 00 2e 73 74 72 74 61 62 00 2e |symtab..strtab..|
00000080 73 68 73 74 72 74 61 62 00 2e 74 65 78 74 00 2e |shstrtab..text..|
00000090 64 61 74 61 00 2e 62 73 73 00 2e 63 6f 6d 6d 65 |data..bss..comme|
000000a0 6e 74 00 2e 6e 6f 74 65 2e 47 4e 55 2d 73 74 61 |nt..note.GNU-sta|
000000b0 63 6b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |ck..............|
000000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000d0 00 00 00 00 00 00 00 00 00 00 00 00 1b 00 00 00 |................|
000000e0 01 00 00 00 06 00 00 00 00 00 00 00 34 00 00 00 |............4...|
000000f0 0a 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |................|
00000100 00 00 00 00 21 00 00 00 01 00 00 00 03 00 00 00 |....!...........|
00000110 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........|
00000120 00 00 00 00 04 00 00 00 00 00 00 00 27 00 00 00 |............'...|
00000130 08 00 00 00 03 00 00 00 00 00 00 00 40 00 00 00 |............@...|
00000140 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |................|
00000150 00 00 00 00 2c 00 00 00 01 00 00 00 00 00 00 00 |....,...........|
00000160 00 00 00 00 40 00 00 00 2e 00 00 00 00 00 00 00 |....@...........|
00000170 00 00 00 00 01 00 00 00 00 00 00 00 35 00 00 00 |............5...|
00000180 01 00 00 00 00 00 00 00 00 00 00 00 6e 00 00 00 |............n...|
00000190 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................|
000001a0 00 00 00 00 11 00 00 00 03 00 00 00 00 00 00 00 |................|
000001b0 00 00 00 00 6e 00 00 00 45 00 00 00 00 00 00 00 |....n...E.......|
000001c0 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 |................|
000001d0 02 00 00 00 00 00 00 00 00 00 00 00 1c 02 00 00 |................|
000001e0 90 00 00 00 08 00 00 00 07 00 00 00 04 00 00 00 |................|
000001f0 10 00 00 00 09 00 00 00 03 00 00 00 00 00 00 00 |................|
00000200 00 00 00 00 ac 02 00 00 16 00 00 00 00 00 00 00 |................|
00000210 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |................|
00000220 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................|
00000230 00 00 00 00 00 00 00 00 04 00 f1 ff 00 00 00 00 |................|
00000240 00 00 00 00 00 00 00 00 03 00 01 00 00 00 00 00 |................|
00000250 00 00 00 00 00 00 00 00 03 00 02 00 00 00 00 00 |................|
00000260 00 00 00 00 00 00 00 00 03 00 03 00 00 00 00 00 |................|
00000270 00 00 00 00 00 00 00 00 03 00 05 00 00 00 00 00 |................|
00000280 00 00 00 00 00 00 00 00 03 00 04 00 0b 00 00 00 |................|
00000290 00 00 00 00 0a 00 00 00 12 00 01 00 10 00 00 00 |................|
000002a0 04 00 00 00 04 00 00 00 11 00 f2 ff 00 74 65 73 |.............tes|
000002b0 74 5f 61 72 2e 63 00 74 65 73 74 00 65 72 72 6f |t_ar.c.test.erro|
000002c0 72 00 |r.|
000002c2
000000a0 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
000000b0 01 00 03 00 01 00 00 00 00 00 00 00 00 00 00 00 |................|
000000c0 b4 00 00 00 00 00 00 00 34 00 00 00 00 00 28 00 |........4.....(.|
000000d0 09 00 06 00 55 89 e5 b8 00 00 00 00 5d c3 00 00 |....U.......]...|
000000e0 00 47 43 43 3a 20 28 47 4e 55 29 20 34 2e 31 2e |.GCC: (GNU) 4.1.|
000000f0 32 20 32 30 30 37 30 39 32 35 20 28 52 65 64 20 |2 20070925 (Red |
00000100 48 61 74 20 34 2e 31 2e 32 2d 33 33 29 00 00 2e |Hat 4.1.2-33)...|
00000110 73 79 6d 74 61 62 00 2e 73 74 72 74 61 62 00 2e |symtab..strtab..|
00000120 73 68 73 74 72 74 61 62 00 2e 74 65 78 74 00 2e |shstrtab..text..|
00000130 64 61 74 61 00 2e 62 73 73 00 2e 63 6f 6d 6d 65 |data..bss..comme|
00000140 6e 74 00 2e 6e 6f 74 65 2e 47 4e 55 2d 73 74 61 |nt..note.GNU-sta|
00000150 63 6b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |ck..............|
00000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000170 00 00 00 00 00 00 00 00 00 00 00 00 1b 00 00 00 |................|
00000180 01 00 00 00 06 00 00 00 00 00 00 00 34 00 00 00 |............4...|
00000190 0a 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |................|
000001a0 00 00 00 00 21 00 00 00 01 00 00 00 03 00 00 00 |....!...........|
000001b0 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........|
000001c0 00 00 00 00 04 00 00 00 00 00 00 00 27 00 00 00 |............'...|
000001d0 08 00 00 00 03 00 00 00 00 00 00 00 40 00 00 00 |............@...|
000001e0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |................|
000001f0 00 00 00 00 2c 00 00 00 01 00 00 00 00 00 00 00 |....,...........|
00000200 00 00 00 00 40 00 00 00 2e 00 00 00 00 00 00 00 |....@...........|
00000210 00 00 00 00 01 00 00 00 00 00 00 00 35 00 00 00 |............5...|
00000220 01 00 00 00 00 00 00 00 00 00 00 00 6e 00 00 00 |............n...|
00000230 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................|
00000240 00 00 00 00 11 00 00 00 03 00 00 00 00 00 00 00 |................|
00000250 00 00 00 00 6e 00 00 00 45 00 00 00 00 00 00 00 |....n...E.......|
00000260 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 |................|
00000270 02 00 00 00 00 00 00 00 00 00 00 00 1c 02 00 00 |................|
00000280 90 00 00 00 08 00 00 00 07 00 00 00 04 00 00 00 |................|
00000290 10 00 00 00 09 00 00 00 03 00 00 00 00 00 00 00 |................|
000002a0 00 00 00 00 ac 02 00 00 16 00 00 00 00 00 00 00 |................|
000002b0 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |................|
000002c0 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................|
000002d0 00 00 00 00 00 00 00 00 04 00 f1 ff 00 00 00 00 |................|
000002e0 00 00 00 00 00 00 00 00 03 00 01 00 00 00 00 00 |................|
000002f0 00 00 00 00 00 00 00 00 03 00 02 00 00 00 00 00 |................|
00000300 00 00 00 00 00 00 00 00 03 00 03 00 00 00 00 00 |................|
00000310 00 00 00 00 00 00 00 00 03 00 05 00 00 00 00 00 |................|
00000320 00 00 00 00 00 00 00 00 03 00 04 00 0b 00 00 00 |................|
00000330 00 00 00 00 0a 00 00 00 12 00 01 00 10 00 00 00 |................|
00000340 04 00 00 00 04 00 00 00 11 00 f2 ff 00 74 65 73 |.............tes|
00000350 74 5f 61 72 2e 63 00 74 65 73 74 00 65 72 72 6f |t_ar.c.test.erro|
00000360 72 00 |r.|
00000362
[root:/root/test/ar]hexdump -C -s 0x0 -n 706 test_ar.o
00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 01 00 03 00 01 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020 b4 00 00 00 00 00 00 00 34 00 00 00 00 00 28 00 |........4.....(.|
00000030 09 00 06 00 55 89 e5 b8 00 00 00 00 5d c3 00 00 |....U.......]...|
00000040 00 47 43 43 3a 20 28 47 4e 55 29 20 34 2e 31 2e |.GCC: (GNU) 4.1.|
00000050 32 20 32 30 30 37 30 39 32 35 20 28 52 65 64 20 |2 20070925 (Red |
00000060 48 61 74 20 34 2e 31 2e 32 2d 33 33 29 00 00 2e |Hat 4.1.2-33)...|
00000070 73 79 6d 74 61 62 00 2e 73 74 72 74 61 62 00 2e |symtab..strtab..|
00000080 73 68 73 74 72 74 61 62 00 2e 74 65 78 74 00 2e |shstrtab..text..|
00000090 64 61 74 61 00 2e 62 73 73 00 2e 63 6f 6d 6d 65 |data..bss..comme|
000000a0 6e 74 00 2e 6e 6f 74 65 2e 47 4e 55 2d 73 74 61 |nt..note.GNU-sta|
000000b0 63 6b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |ck..............|
000000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000d0 00 00 00 00 00 00 00 00 00 00 00 00 1b 00 00 00 |................|
000000e0 01 00 00 00 06 00 00 00 00 00 00 00 34 00 00 00 |............4...|
000000f0 0a 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |................|
00000100 00 00 00 00 21 00 00 00 01 00 00 00 03 00 00 00 |....!...........|
00000110 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........|
00000120 00 00 00 00 04 00 00 00 00 00 00 00 27 00 00 00 |............'...|
00000130 08 00 00 00 03 00 00 00 00 00 00 00 40 00 00 00 |............@...|
00000140 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |................|
00000150 00 00 00 00 2c 00 00 00 01 00 00 00 00 00 00 00 |....,...........|
00000160 00 00 00 00 40 00 00 00 2e 00 00 00 00 00 00 00 |....@...........|
00000170 00 00 00 00 01 00 00 00 00 00 00 00 35 00 00 00 |............5...|
00000180 01 00 00 00 00 00 00 00 00 00 00 00 6e 00 00 00 |............n...|
00000190 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................|
000001a0 00 00 00 00 11 00 00 00 03 00 00 00 00 00 00 00 |................|
000001b0 00 00 00 00 6e 00 00 00 45 00 00 00 00 00 00 00 |....n...E.......|
000001c0 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 |................|
000001d0 02 00 00 00 00 00 00 00 00 00 00 00 1c 02 00 00 |................|
000001e0 90 00 00 00 08 00 00 00 07 00 00 00 04 00 00 00 |................|
000001f0 10 00 00 00 09 00 00 00 03 00 00 00 00 00 00 00 |................|
00000200 00 00 00 00 ac 02 00 00 16 00 00 00 00 00 00 00 |................|
00000210 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |................|
00000220 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................|
00000230 00 00 00 00 00 00 00 00 04 00 f1 ff 00 00 00 00 |................|
00000240 00 00 00 00 00 00 00 00 03 00 01 00 00 00 00 00 |................|
00000250 00 00 00 00 00 00 00 00 03 00 02 00 00 00 00 00 |................|
00000260 00 00 00 00 00 00 00 00 03 00 03 00 00 00 00 00 |................|
00000270 00 00 00 00 00 00 00 00 03 00 05 00 00 00 00 00 |................|
00000280 00 00 00 00 00 00 00 00 03 00 04 00 0b 00 00 00 |................|
00000290 00 00 00 00 0a 00 00 00 12 00 01 00 10 00 00 00 |................|
000002a0 04 00 00 00 04 00 00 00 11 00 f2 ff 00 74 65 73 |.............tes|
000002b0 74 5f 61 72 2e 63 00 74 65 73 74 00 65 72 72 6f |t_ar.c.test.erro|
000002c0 72 00 |r.|
000002c2
对比上面两个输出,内容是完全一致的,正是我之前期盼的那样。
4.链接
在上面的例子中,我故意在test_ar.c、test_ar_1.c中定义了同名的函数。但一个返回0,
一个返回1,主要是为了检查符号的解析。
一个返回1,主要是为了检查符号的解析。
我又写了一个测试文件。
[root:/root/test/ar]cat main.c
#include <stdio.h>
#include <stdio.h>
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
{
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
输出结果为0,也就是它调用的时test_ar.o中的test()函数而不是调用test_ar_1.o中的函数。
我们看上面符号表中的数据
我们看上面符号表中的数据
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.|
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.函数遇到一个未解析的符号,它在-l指定的连接归档库中查找。
2.当查找到第一个符合的符号时,他即停止搜索。
3.根据符号获得目标文件在archive中的偏移量,把相关的目标文件(*.o)从库中复制一份出来,
链接到可执行程序中。
链接到可执行程序中。