分类: LINUX
2012-05-29 22:37:57
9.1 目标文件解析
通常目标文件包含五类信息:
头信息:文件的整体信息,例如代码的大小,源文件的名称以及创建的日期等。
目标代码:由编译汇编器产生的二进制指令和数据。
重定位信息:目标文件中的一个位置列表,链接器在修改目标代码的地址时会对它进行调整。
符号:该模块中定义的全局符号,以及从其它模块导入的或者有链接器定义的符号。
调试信息:目标代码中与链接无关但会被使用的其它信息。这包括源代码文件和行号信息,本地符号,被目标代码使用的数据结构描述信息。
9.2库
静态库和动态库的差别,静态库是可执行文件的物理组成部分;动态库是可执行文件只包含文件名,让加载器在执行的时候寻找程序所用的函数库。动态库的优势是,使用它的可执行文件和相同功能的可执行文件比较体积更小。所有的动态链接到某个特定的可执行的文件在运行时共享该函数库的一个单独拷贝,并且动态链接库允许用户在运行时加载或卸载函数库。
9.2.1 静态库
静态库是文档文件(archive file),其中包含编译程序产生的目标文件集合,目标文件中所有的内容均可以放在库中。静态库的后缀是.a。
C/C++语言中生成静态库的方法:
gcc -c -o test1.o test1.c //生成目标文件1
gcc -c -o test2.o test2.c //生成目标文件2
ar -r -o test.a test1.o test2.o //利用归档工具生成静态链接库
使用方法:
gcc -o a.c test.a a
9.2.2 动态库
它也是目标文件的集合,不过这些文件由编译程序按照特殊方式生成:对象模块的每个地址(包括变量的引用和函数的调用)都是相对地址,这就可以是正在运行的额程序动态加载和执行。动态库的后缀是.so。
C/C++生成动态库的方法:
gcc -fpic -shared one.c two.c -o sun.so
使用方法:
gcc -o result three.c sun.so
注意:-fpic使得输出的对象模块是按照可重定位地址生成的。
-shared表示创建共享库
9.3 调用动态库使用的函数
在使用动态库时,源程序必须包含dlfcn.h头文件,该文件定义调用动态链接库的函数的原型。
(1)_打开动态链接库:dlopen,函数原型void *dlopen (const char *filename, int flag);dlopen用于打开指定名字(filename)的动态链接库,并返回操作句柄。
(2)取函数执行地址:dlsym,函数原型为: void *dlsym(void *handle, char *symbol);dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的函数的执行代码地址。
(3)关闭动态链接库:dlclose,函数原型为: int dlclose (void *handle);dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。
(4)动态库错误函数:dlerror,函数原型为: const char *dlerror(void); 当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。
在取到函数执行地址后,就可以在动态库的使用程序里面根据动态库提供的函数接口声明调用动态库里面的函数。
9.4 库工具
9.4.1 ldconfig:配置查找共享库
它主要有两个功能,首先就是创建最新的链接,这样共享库的引用总是最新版本。其次就是在/etc/ld.so.cache保存有效共享库的完整列表。
9.4.2 strip:去除目标文件或库中指定的符号表信息。
9.4.3.3 ldd:列出共享库的依赖关系
用ldd能够确定程序使用的共享库版本,并能确定到共享库的所有为解析引用。
9.4.4 nm工具的使用
nm可以列出目标文件,静态库以及动态库中定义的符号。
9.4.5 objdump工具
objdump用于展开目标文件,静态库和共享库的信息,然后将其设置成可读模式。
常用命令如下:
-d 可执行代码的汇编语言形式
-D 包含可执行代码和数据段的汇编语言形式
-g 调试信息
-G 包含所有stabs信息的原始形式
-r 重定位信息
-R 动态链接中的重定位信息
-S 混合源代码的可执行汇编语言
-s 混合源代码和数据的可执行汇编语言
-t 符号表信息
-T 动态符号表信息
-h 节头表信息
-H 本选项的额列表
9.4.6 编译器选项顺序对生成结果的影响
命令行的解析一般情况下是由左至右的,每个选项会设定一个值或标记,因此命令行中设置好
的内容可能在其后被修改。如果后面的参数依靠前面参数的解析,顺序颠倒会导致出错。