zoukankan      html  css  js  c++  java
  • 目标文件格式分析工具: 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命令,以后再进行详细学习,在此省略。

  • 相关阅读:
    使用git笔记
    linux 进程管理的一些命令使用
    [zz]XML DOM 教程
    [zz]std::string 和 c 的字符串
    [zz]grep 命令的使用
    [zz]XercesC++ 参考
    [zz]Windows WordPress本地安装教程
    今天调出来的关于cello的bug
    shell 编程的一些问题
    关于java中边界值校验的问题
  • 原文地址:https://www.cnblogs.com/xuxm2007/p/2309331.html
Copyright © 2011-2022 走看看