linux kernel动态库,kernel 加载动态链接库问题

一个动态链接库,及从它在文件系统一个文件夹下开始到真正加载到内存中,其它进程可以访问,再到其卸载移出内存的过程是怎样的。

要求用实际代码说明

首先,一个xxx.so是在应用层被什么处理的,哪个程序?

其次,这个xxx.so进一步如何加载到内核的?

再次,在内核中哪一部分是处理动态链接库的代码?

最后,内核中对动态链接库的卸载代码在哪里?

谢谢了,各位xdjm,  谢谢了。

|

1.首先是编译阶段,这就涉及到ELF文件的相关知识,如果某个可执行程序依赖一个动态库里面的函数,那么编译生成的ELF会记录这个动态库的名字以及这个程序调用的符号,这就区别于静态链接。也就是这个可执行程序并不存xxx的实际代码。

int xxx(int x, int y)

{

printf("x is %d, y is %dn");

}

把这个编成一个.so的话,然后

int main()

{

xxx(3,5);

}

2.执行这个程序,跟其他的ELF执行没什么两样,只是执行到这个函数的时候会有区别,这块有GOT和PLT等概念,对于普通函数的调用,编译器生成代码为call addr。其中addr是被调用函数的地址。调用来自动态链接库的函数时,其addr无法在link阶段确定,编译器只能生成call PLT[n]。PLT[n]指PLT表的第n个表项。

PLT每个表项有三行代码:

line1: jump GOT[n]

line2: push "func name"

line3: jump dl_runtime_resolve

因此当程序执行到call PLT[n]时,就跳到line1了,初始情况下,GOT[n]的值就是line2的地址。因此这条语句相当于nop。后两个语句就是调用dl_runtime_resolve去一个叫link map的结构中查找真正要调用的函数地址。这个过程完成后,GOT[n]的内容就被修改成真正要调用的函数的地址。这样下次程序再次走到call PLT[n]时,line1就直接跳到真正的来自动态链接库的函数地址,而不需要走line2和line3了。 (这也是为什么程序刚加载的时候执行比较慢,而后来执行就快起来的原因了。)

3.这些东西在glibc中实现,跟kernel有关的就是执行ELF文件的过程以及相关的syscall。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值