程序编译过程 & ELF格式 静态库 动态库

代码的编译过程

ELF文件的头是用于描述整个文件的,这个文件格式在内核中有定义 struct elf64_hlr。

1. 可重定位文件 *.o

2. 可执行文件 *

3. 共享对象文件(shared object) *.so

gcc -c a.c (输出是 a.o)  可重定位(ELF第一种格式)
gcc a.c     (输出是 a.out) 可执行 (ELF第二种格式)

 .text 代码

.data 初始化的全局变量

.rodata 只读数据,字符串常量,const变量

.bss 未初始化的全局变量(运行时置0)

.symtab 符号表(函数和变量)

.strtab 字符串表,字符串常量和变量名

NOTE: 局部变量是运行时在stack里。这个文件是编译时。

我们刚才说了可重定位,为啥叫可重定位呢?我们可以想象一下,这
个编译好的代码和变量,将来加载到内存里面的时候,都是要加载到
一定位置的。比如说,调用一个函数,其实就是跳到这个函数所在的
代码位置执行;再比如修改一个全局变量,也是要到变量的位置那里
去修改。但是现在这个时候,还是.o文件,不是一个可以直接运行的
程序,这里面只是部分代码片段。

假设我的场景是 func.c   main.c

那么在main.c里面调用了func这个函数,但这个函数在另一个.o里面,main.o根本不知道这个被调用函数的位置,只好在 rel.text里标注,这个func是需要重定位的。

gcc -c func.c
gcc -c main.c
ar r func.a func.o
gcc -o chun main.o -L. -lfunc

-L表示在当前目录下找.a文件,-lfunc会自动补全文件名,比如加前缀lib,后缀.a,变成libfunc.a,找到这个.a文件后,将里面的func.o取出来,和main.o做一个链接,形成二进制执行文件chun。

在ELF的头里面,有一项e_entry,也就是虚拟地址,是这个程序运行的入口,可以用readelf -h 查看头

 动态链接

gcc -c main.c
gcc -c func.c -fpic                # -fpic (position independent code)
gcc func.o -shared -o libfunc.so
gcc -o main main.o -L. -lfunc

./main  # error loading shared libraries: libfunc.so no such file or directory
cp xxx.so /usr/lib
export LD_LIBRARY_PATH=:/home/chun/lib
./main    
ldd main # find related dynamic so


 

linux默认使用的是动态链接,使用 gcc main.c -o out -static 使用-static 可能会因为没有安装静态库而报错

apt-get install glibc-static

libc.so

-lc

cd  /usr/lib & ls | grep libc.so

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值