目标文件格式分析工具: ar,nm,objdump,objcopy,readelf

 http://www.ibm.com/developerworks/cn/aix/library/au-unixtools.html

 http://www.ibm.com/developerworks/aix/library/au-unixtools.html?S_TACT=105AGX52&S_CMP=cn-a-aix

 http://www.cnblogs.com/amethyst623/articles/1946499.html

 

库文档的开发与使用

软件开发者可以使用某种语言的库函数,这些库函数通常放在/lib和/usr/lib目录中,而大多数的库函数放在/usr/lib中,比如标准C库函数文件/usr/lib/libc.a和标准C++库函数/usr/lib/libstdc++.a。
库对应的头文件有两种,包括公有头文件和私有头文件。公有头文件声明的资源对其他程序是有效的,而私有头文件声明的资源只能被对应的库代码使用。为了使库成为公有的,应将它安装在目录/usr/lib中,并将它的头文件放在/usr/include中,并在用户程序中使用#include <>的方式引入库头文件。将头文件的路径名放置在引号中,就可将私有头文件放入程序中,比如#include "hello.h",预处理程序会首先在当前目录查找hello.h头文件,如果写成#include "-/include/hello.h",预处理程序就会在目录~/include中搜索头文件hello.h。
库文档必须以.a扩展名结束,一旦为一组目标模块创建了一个库文件,通过制定库文档作为参数,这些模块就可以被C程序根据-l*链接使用。对于标准库,例如C中的libc.a,只需要在用户程序中添加相应的头文件比如stdio.h、stdlib.h、ctype.h等,而不需要明确地用-l编译程序选项去链接该库;但还有许多库不是标准库,例如数学库libm.a,除了需要添加相应头文件之外,还必须明确地用编译程序选项-lm链接该库,其中-l编译选项在lib和.a之间指定子串,不明确指定的话会在编译器产生错误。
注意:
1.标准C语言库libc.a在编译程序的链接阶段自动被链接。
2.一些常见的与库相关的编程错误:
没有为库加入头文件
没有明确链接一个库,而这个库不能被程序自动链接
使用了错误版本的库
链接了不兼容的库

------------------------------------------------------------------------------------------------------

库的开发

使用ar程序可以执行各种与库相关的任务,比如在库文件中创建、修改和提取模块等。与linux命令不同,ar命令的关键字不需要使用-连字符。
ar 关键字 库文档名 文件列表
d    在库文档中删除一个文件
q    在现有库文档中添加一个文件,若库文档不存在,则创建之
r     新建一个库文档或覆盖一个现有库文档
t     显示一个库文档目录
s    强制生成库文档符号表
x     从一个库文档中提取一个或多个文件,并将它们保存在当前的工作目录中
v    生成一个详细的输出

假设已存在main.c、compute.c、input.c、main.h、compute.h、input.h这些文件,且compute.c使用了数学库libm.a,下面的例子用于库文档的创建和追加等。
ar r libmath.a input.o compute.o
该命令创建了文件input.o和compute.o的库文档文件libmath.a,如果该库文档已存在则会被覆盖。上述命令当libmath不存在时,可以使用ar q libmath.a input.o compute.o代替,该命令在libmath.a中追加新文件,当libmath.a不存在时自动创建;当想将当前目录中所有目标文件都放入库文件中,也可以使用ar r libmath.a *.o或者ar r libmath.a `ls *.o`这样的命令。
gcc main.c libmath.a -o power -lm
该命令将库文档中的input.o和compute.o链接到main.o上,使用-lm链接数学库libm.a,因为在compute.o中使用了pow函数。将libmath.a安装到/usr/lib后,就可以通过-lmath的方式使用了。
rm compute.o input.o
创建目标模块的库文档后,就可以删除原有模块。
ar t libmath.a
该命令用于显示库文档libmath.a的目录,同理可以使用ar vt libmath.a命令获得更详细的输出。
ar d libmath.a input.o
该命令用于从库文档libmath.a中删除一个或多个目标模块。
ar x libmath.a compute.o
该命令下哦那个库文档libmath.o中提取一个或多个目标模块,并放在当前目录中。

在makefile中也可以使用ar命令,这样创建了软件的可执行文件之后,也可以创建目标文档的库文档,具体方法如下:
CC=gcc
OPTIONS=-03
OBJECTS=main.o input.o compute.o
SOURCES=main.c input.c compute.c
HEADERS=main.h input.h compute.h
ARCHIVE=compute.o input.o
LIBRARY=libmath.a
AR_KEYS=qv
complete : power
    @echo "Build complete"
power : $(OBJECTS)
    $(CC) $(OPTIONS) -o $@ $^ -lm
    @echo "The executable is in the 'power' file"
main.o : main.h input.h compute.h
compute.o : compute.h
input.o : input.h
buldle : 
    @echo "Archiving object modules..."
    ar $(AR_KEYS) $(LIBRARY) $(ARCHIVE)
    @echo "Archiving is complete."
power.tar : makefile $(HEADERS) $(SOURCES)
    tar -cvf $@ $^
clean :
    rm -f *.o

---------------------------------------------------------------------------------------------

库的使用

在安装库文档之前,需要给库文档生成和添加一个目录索引。库文档中的目标文件不是以任意顺序排列的,而是依赖于模块被插入到库文档中的顺序。带有目录的库文档在链接阶段是必要的,它允许库文档中的函数互相调用,而无论这些函数在库文档中的位置如何。
ranlib 库文档列表
该命令可以为库文档列表中的每个库文档生成和添加一个目录,该命令与如下命令相同:
ar s 库文档

一旦添加了目录之后,就可以安装该库使其成为公有,主要采取两个步骤:
1.创建库的头文件并把它放在/usr/include目录中,头文件包含库中资源的声明。一个库文档可以对应多个头文件,例如libmath.a可以对应input.h和compute.h。
2.在/usr/lib目录中放置该库文档,例如/usr/lib/libmath.a。
3.在使用该库时,在程序中加入对应头文件,并用带有-lmath的编译命令即可。

可以用nm命令显示一个库、目标或可执行文件的符号表,表中包括名称、类型、大小和进入点等信息。它的输出告知该库的属性,输出的每一行是每一个标识符,例如文件中的某个函数名或者变量名。nm命令显示的信息用于调试库和可执行文件,对于库文档中的每个文件或成员,nm命令至少会将下面的信息发送到标准输出:每个符号的地址、符号的值以及其类型。根据选项,也可能输出库或目标的名称以及符号的大小等。

nm [选项] [文件列表(库文件/目标文件/可执行文件)]
-D    只显示动态符号,当使用动态库时很有用
-V    nm命令版本号
-g    只显示全局符号的相关信息
-l     为每一个符号查找和显示文件名和行号
-n    用地址给外部符号分类
-u    只显示未定义的符号,即每个目标模块的外部符号
-w   给出更多警告信息
-f 格式    以不同格式输出,可以是bsd、sysv、posix等,默认是bsd

对nm命令,以后再进行详细学习,在此省略。

 

 

posted on 2012-01-01 11:04  阿笨猫  阅读(2124)  评论(0编辑  收藏  举报