程序员的自我修养6

并不是创建空间而是创建映射函数所需要的相应的数据结构,在i386的linux下,创建虚拟地址空间实际上只是分配一个页目录(page-directory),甚至不设置页映射关系,这些映射等到后面程序发生页错误时再进行设置。

 

当程序执行发生页错误时,操作系统将从物理内存中分配一个物理页,然后将该“缺页”从磁盘中读取到内存中,再设置缺页的虚拟页和物理页的映射关系,这样程序才得以正常运行

 

这种映射关系只是保存在操作系统内部的一个数据结构,linux中将进程虚拟空间中的一个段叫做虚拟内存区域(vma,virtual memory),在windows中将这个叫虚拟段(virtual section),其实是同一概念

“segment”的概念实际上是从装载的角度重新划分了ELF的各个段

 

在将目标文件链接成可执行文件的时候,链接器会尽量把相同权限属性的段分配在同一空间

 

在内存中,共享一个目标文件模块的好处是不仅仅是节省内存,它还可以减少物理页面的换入换出,也可以增加CPU缓存的命中率,因为不同进程间的数据和指令访问都集中在了同一个共享模块上

 

一个程序在不同的平台上运行时,可以动态地由操作系统提供动态链接库,这些动态链接库相当于在程序和操作系统之间增加了一个中间层,从而消除了程序对不同平台之间的依赖的差异性

 

在使用动态链接库的情况下,程序本身被分为了程序主要模块,(program)和动态链接库(lib.so),但实际上他们都可以是整个程序的一个模块

 

当程序被加载时,系统的动态链接器会将程序所所需要的所有动态链接库(最基本的就是lib.so)装载到进程的地址空间,并且将程序中所有未决议的符号绑定到相应的动态链接库中,并进行重定位工作

 

共享对象的最终装载地址在编译时是不确定的

 

地址无关代码(PIL,position-independent code)技术:将指令中要被修改的部分分离出来,跟数据部分放在一起,这样指令部分就可以保持不变,而数据部分可以在每个进程中拥有一个副本

 

其他模块的全局变量的地址是跟模块装载的地址有关的,ELF的做法是在数据段里面建立一个指向这些变量的指针数组,也被称为全局偏移表(global offset table),当代码需要引用该全局变量时,可以通过GOT中相对应的项间接引用

 

地址无关代码技术除了用在共享对象技术上面,它也可以用于可执行文件,一个以地址无关方式编译的可执行文件被称作地址无关可执行文件(Pie,position-independent executable)

 

动态链接器本身不依赖于其他任何共享对象;其次是动态链接器本身所需要的全局和静态变量的重定位工作由它本身完成。对于第二个条件,这种具有一定限制条件的启动代码往往被称为自举(bootstrap)

 

完成基本自举后,动态链接器将可执行文件和链接器本身的符号表都合并到一个符号表当中,我们可以称他为全局符号表(global symbol table)当一个新的共享对象被装载进来的时候,他的符号表会被合并到全局符号表中

 

一个共享对象里面的全局符号被另一个共享对象的同名全局符号覆盖的现象又被称为共享对象全局符号接入(global symbol interpose)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值