静态库动态库的编译、链接, binutils工具集, 代码段\数据段\bss段解释

时间:2022-09-19 03:55:01

#1. 如何使用静态库

制作静态库

(1)gcc *.c -c -I../include得到o文件

(2)

ar rcs libMyTest.a *.o 将所有.o文件打包为静态库,r将文件插入静态库中,c创建静态库,不管库是否存在,s写入一个目标文件索引到库中,或者更新一个存在的目标文件索引。
mv libMyTest.a ../lib 将静态库文件放置lib文件夹下
nm libMyTest.a 查看库中包含的函数等信息

第一种方法:
gcc + 源文件 + -L 静态库路径 + -l静态库名 + -I头文件目录 + -o 可执行文件名
gcc main.c -L lib -l MyTest -I include -o app
./app

第二种方法:
gcc + 源文件 + -I头文件 + libxxx.a + -o 可执行文件名
gcc main.c -I include lib/libMyTest.a -o app

#2. 如何使用动态库

动态库制作:

gcc -fPIC *.c -I ../include -c   参数-fPIC表示生成与位置无关代码

第一种方法:
gcc + 源文件 + -L 动态库路径 + -l动态库名 + -I头文件目录 + -o 可执行文件名
gcc main.c -L lib -l MyTest -I include -o app
./app
(执行失败,找不到链接库,没有给动态链接器(ld-linux.so.2)指定好动态库 libmytest.so 的路径)

使用命令ldd app可以查看当前的链接库情况

第一种方法:
export LD_LIBRARY_PATH=自定义动态库的路径
(只能起到临时作用,关闭终端后失效)
LD_LIBRARY_PATH : 指定查找共享库(动态链接库)时除了默认路径之外的其他路径,该路径在默认路径之前查找

第二种方法:
将上述命令写入home目录下的.bashrc文件中,保存后重启终端生效(永久)

第三种方法:
直接将动态库拷贝到user/lib的系统目录下(强烈不推荐!!)

第四种方法:
将libmytest.so所在绝对路径追加入到/etc/ld.so.conf文件,使用sudo ldconfig -v 更新

第二种方法:
gcc + 源文件 + -I头文件 + libxxx.so + -o 可执行文件名
gcc main.c -I include lib/libMyTest.so -o app
(执行成功,已经指明了动态库的路径)

#3. nm可以列出ELF文件的符号,变量

1. 不论一个静态变量是定义在函数内的,或是函数外的,其在程序段中的分配方式是一样的。

如果这一静态变量是初始化好的,那么被分配在.data段中,否则被分配在.bss段中。

2. 非静态的全局变量,其所分配的段也是只与其是否被初始化有关。如果是初始化了的全局变量其将被分配在.data段中,

否则是.bss段中。

3. 函数无论是静态还是非静态的其总是被分配在.text段的,但T(t)的大小写表示了这一符号所对应的函数是否是静态函数。

4. 函数内的局部变量并不被分配在.data  .bss  和 .text段中,分配在栈,nm看不出信息

代码段   -------.text  可执行代码段,用来放代码

     -------.rodata  只读数据段,如const修饰符, (归类到.text中)

数据段

    -------.data  初始化数据段,用来放初始化好的数据,.idata 归类到.data段中

      --------.bss  未初始化数据段,用来放未初始化好的数据

+-------------+-----------
| .bss |
+-------------+-- 数据段
| .data |
+-------------+-----------
| .rodata |
|_____________| 代码段
| .text |
+-------------+-----------

#4. objdump -h a.out

Idx Name          Size      VMA               LMA               File off  Algn

23 .data 00000010 0000000000601030 0000000000601030 00001030 2**3
CONTENTS, ALLOC, LOAD, DATA
24 .bss 00000008 0000000000601040 0000000000601040 00001040 2**0
ALLOC
25 .comment 0000002b 0000000000000000 0000000000000000 00001040 2**0
CONTENTS, READONLY

VMA (Virtual Memory Address,虚拟内存地址)  指示的段在程序运行时的开始地址

LMA(Load Memorry Address,加载内存地址) 指段的存放首地址

File off  指示每一个段在代码文件中的存储位置

DWARF(Debugging With Attributed Record Formats)  refers to www.dwarfstd.org(objdump -W a.out)

objdump -d a.out  反汇编,显示程序的汇编代码

objdump -S -d a.out  反汇编,同时显示C\C++源程序和与之对应的汇编代码, 此时加上--demangle可增加可读性

objdump -f 显示目标文件的头信息,主要是start address

objdump -s -j .data a.out  查看某一个段中的具体内容

#5. objcopy

objcopy -j .text -j .data -j .bss a.out onlytest  提取多个段内容到onlytest

objcopy --strip-debug a.out; 类似strip工具,将程序中的调试信息去除

#6 size a.out

size -A a.out

#7. strings a.out  查看可显示的字符串

#8. strip 去除程序文件中的调试信息以便减小文件的大小, 与objcopy --strip-debug功能一样

#9. ranlib 在档案中生成文件索引。 ar的s参数也具有同样功能, 对文件存取速度更快。