程序员的自我修养(一)

2019-01-12  本文已影响0人  LSteven

目标文件

全局变量和局部静态变量在数据段即.data
未初始化的全局变量和局部静态变量在.bss段

elf文件

readelf -s 查看段表

段的类型:

标**都代表与链接有关。

分别代表sh_link,sh_info

strip去除调试信息

ld

ld时会生成shstrtab symtab strtab可以ld -s 禁止产生符号表

out格式

静态链接

目标文件被链接成最终可执行文件时,

segment

相同权限的段被合并到一个段映射变成Segment,Segment是执行视图,Section是链接视图

动态链接

静态链接将整个文件作为一个整体映射到虚存。而动态链接其实还是分模块, 尤其是动态链接器也作为一个模块映射到虚存,程序开始后先完成所有的动态链接工作。用/proc/maps查看可以看到主程序和共享模块分布在不同的地址中。

重定位

静态链接的重定位叫链接重定位,动态链接的重定位叫装载重定位。对于动态链接的共享库而言,它假定自己装载时在0x1000,如果正式装载时在0x3000那么所有绝对引用集体加0x2000即可。当然动态链接也可以用静态链接的方式,但这样就做不到共享了,因为要改指令部分,不同进程因为虚存的存在不可能同时改一份代码的指令。(数据拷贝共享)

--shared

是否用装载重定位方式。

-fPIC

动态链接作为多个进程共享模块,所以需要解决前面提到的不同进程因为虚存的存在不可能同时改一份代码的指令的问题。

首先模块内的数据指令不用考虑,用相对访问即可。问题在于模块间的数据访问,需要把跟地址相关的部分放到数据段里面,在数据段里建立一个指向这些变量的指针数组got(全局偏离表),got在数据段中,互不影响(因为每个进程独立副本啊)

所以很简单访问got写入读取最终需要访问的绝对地址即可。

ps: 分析上层累了, 纯记录自己的学习。

上一篇 下一篇

猜你喜欢

热点阅读