静态链接
来源:互联网 发布:发型软件 编辑:程序博客网 时间:2024/04/28 20:58
最近在阅读《程序员的自我修养》,在阅读到静态链接一章发现其中的阐述过于的杂乱,导致本人在看完之后还是一头雾水,在反复的看了几遍后,整理了一些的要点,其中有理解偏差的地方希望阅读者能够通知本人。
首先是两个示例程序(主要示例,不具有任何功能)
a.cextern int shared;int main(){ int a = 10; swap(&a, &shared);}
b.cint shared = 9;int swap( int *pa, int *pb ){ *pa ^=*pb ^=*pa ^=*pb;}
上述的两个源文件编译生成目标文件,并链接生成可执行文件ab
gcc -c a.c b.c
gcc -o ab -e main a.o b.o
其中上面生成的可执行文件包括了一下的三个步骤:
- 相似段合并:
a.o的.text与b.o的.text合并,即:main函数相对的偏移量为0,swap函数相对的偏移量:00000027
a.o的.data与b.o的.data合并,即:全局变量shared相对于.data的偏移量为0 - 确定符号的虚拟地址
如可执行文件的.text段虚拟地址开始于:08048094,则计算出的main的地址为08048094,swap的地址为:80480BB(08048094+00000027),地址对齐则变成:80480BC
可执行文件的.data段虚拟地址开始于:08049154,则计算出的全局变量shared的虚拟地址为:08049154 - 指令地址修正
命令:readelf -r a.o查看需要修正的地址类型,其中
shared绝对地址修正:R_386_32,
swap为相对地址修正:R_386_PC32
绝对地址修正:S+A,
相对地址修正:S+A-P
S为可执行文件中的实际虚拟地址,
A为被修正的位置值(反汇编 objdump -d a.o可查看),
P为被修正的位置(指令的开始处)
shared的修正地址为:S+A=08049154+00000000=08049154
swap的修正地址为:S+A-P=80480BC+(-4)-(08048094+00000021)=80480B8-80480B5=3(其中的21在查看是何种修正方式的重定位表的偏移量,相对于最开始指令的偏移量)
可以通过查看ab的反汇编知道是否正确:这里需要说明的是:swap是相对于下一条指令的偏移地址。
上述的地址值可以通过下面的一些命令进行查看
- 查看符号在段中的偏移量:readelf -s a.o value为偏移量(查看符号表)
- 查看输入的目标文件的段大小:objdump -h a.o的size(查看section)
- 查看实际的段的虚拟地址:objdump -h ab
- 查看地址的修正方式和相对于指令的偏移量:readelf -r a.o其中的Type和Offset(查看重定位表)
- 查看修正的值A,可通过反汇编的方式查看到:objdump -d a.o
接下来还会陆续更新本人的一些学习所得。
0 0
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接
- 静态链接之静态链接
- 静态链接&动态链接
- 2017届毕业生安卓面试题-计算机网络篇
- Codeforces-239A-Two Bags of Potatoes
- Java 代理学习笔记 —— 详解Java原生动态代理
- BoneCP-Spring详细配置
- 我的博客之路
- 静态链接
- 02-线性结构3 Reversing Linked List
- 集合和数组
- 在安卓中实现Zigbee串口设备采集模块
- WP8.1的Flyout控件
- java Map及Map.Entry详解
- 18. JSON 操作
- 导入MySQL数据库数据出现错误
- 基于机器学习的高价值用户简历自动分类