ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

22/8/10 深入理解计算机系统第七章笔记

2022-08-10 22:04:18  阅读:150  来源: 互联网

标签:10 22 符号 修正 地址 内存 第七章 定位 引用


7.7重定位

建立定义和引用对应关系之后,就可以进行重定位了,合并输入模块,并为每个符号分配运行时内存。
重定位包括两步:
重定位节和符号定义:合并所有目标文件的类型相同的节,同时链接器把运行时内存的地址赋给新的节和输入模块定义的每个符号。这一步完成之后程序的每条指令和全局变量都有唯一的运行时内存地址了(虚拟内存)
重定位节中的符号引用:
这一步,链接器修改代码节和数据节中每个符号的引用,使它们指向正确的运行时地址。这一步链接器依赖与可重定位目标模块中的重定位条目的数据结构。

7.7.1 重定位条目

重定位条目:由于汇编器不知道代码和数据最终将放在内存的什么地方,也不清楚模块引用的外部定义的函数和全局变量的位置。所以当汇编器遇到最终位置位置的目标引用时,它会生成一个重定位条目。
重定位条目存放在.rel.xxx中,xxx可以为text或者data。

typedef struct
{
    long offset;
    long type:32,symbol:32;
    long addend;
}Elf64_Rela;

offset是需要被修改的引用的节偏移,symbol标识被修改引用应该指向的符号。

7.7.2重定位符号的引用

x86基本重定位类型

宏定义 重定位修正方法 地址计算方式
R_386_32 1 绝对寻址修正 S+A
R_386_PC32 2 相对寻址修正 S+A-P

A = 保存在被修正位置的值(重定位入口)
P = 被修正的位置(相对于段开始的偏移量或者虚拟地址)
S = 符号的实际地址,即由r_info的高24位指定的符号的实际地址。

R_386_PC32 是一条相对位移调用指令。
R_386_32 是把修正一条传输指令的源,该传输指令的源是立即数(符号的绝对地址)。

相对地址修正的地址为被修正位置的地址差
绝对地址修正的地址为符号的实际地址。

书中refaddr为引用的运行时地址。
refptr为程序的实际地址。

7.8 可执行目标文件

ELF可执行文件的结构:P483
ELF头包含程序的入口点,就是程序运行时要执行的第一条指令。
可执行文件的内容初始化两个内存段:
代码段
数据段

7.9 加载可执行目标文件

每个linux程序都有一个运行时内存映像:
先后为只读代码段,.data .bss数据段,运行时堆,堆后面的区域是为了共享模块保留的。
用户栈总是从最大合法用户地址(2^48 - 1)开始,向较小内存地址增长。
如表所示:

地址 区域 其他
2^48 - 1 内核内存 对用户代码不可见
用户栈(运行时创建) <--%rsp(栈指针)
共享库的内存映射区域
运行时堆(由malloc创建) <--brk
读/写段(.data .bss)
0x400000 只读代码段(.init .text .rodata)

由于.data段有对齐要求,所以代码段和.data段是有间隙的。
在分配栈、共享库和堆段运行时地址的时候,链接器还会使用地址空间布局随机化(3.10.4节)

要求:梳理编译链接到可执行文件初始化运行的过程

标签:10,22,符号,修正,地址,内存,第七章,定位,引用
来源: https://www.cnblogs.com/hy227/p/16574035.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有