分享
 
 
 

Win32动态连接库基址重置技术

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

理论

要加载动态链接库操作系统必须完成以下各步:

在磁盘上定位动态链接库可执行文件。

仔细查看已经加载进应用程序地址空间中的动态链接库列表,判断动态链接库是否已经加载了。

为动态链接库分配驻留内存,并将动态链接库二进制文件映射到内存中(在Windows NT中,映射跨越了段对象)。

为使动态链接库正常运行,执行一系列必要的处理(例如,解析动态链接库中做过的修正,等等)。

不同的参数决定了动态链接库的加载时间不同。以下给出了需要考虑的各种因素,事实上可能还有一些因素也会影响到动态链接库的加载时间:

底层软硬件:计算机本身的速度以及运行哪一种操作系统。

当前系统和应用程序的状态:在虚拟内存中系统的紧密情况,以及动态链接库是否可以被加载在首选基地址。

动态链接库本身:动态链接库本身有多大,动态链接库中有多少位置需要修正(结合两者综合考虑),此动态链接库是否隐式链接到另一个同样需要加载的动态链接库中。

由上述分析可知,对某一动态链接库进行基址重置绝不是影响动态链接库加载时间的唯一决定因素。在本文中,作者使用了很多数据,说明了动态链接库加载时间的变化范围以及应用程序可能对加载时间的影响程度。

读者应该注意到,对某一动态链接库进行基址重置,不仅可能造成加载时间的大幅度增加,还需要增加页文件(pagefile)的开销。加载动态链接库的第一步,需要创建区段对象(section object),区段对象是由动态链接库可执行文件支持的、内存中的一个相邻的区段。一旦动态链接库的某一页被从应用程序工作集中移去了,在下一次访问此页时,操作系统就会从动态链接库可执行文件中重新加载这一页。

当然,当动态链接库进行基址重置时,这一策略不再起作用,这主要是因为包含重定位地址的页与动态链接库可执行文件映射中的相应页不同。因此,一旦在加载可执行文件时,操作系统企图修正地址,就会拷贝相应的页(由于区段是通过COPY_ON_WRITE标志打开的)。在拷贝中进行的所有的修改,操作系统都会记住,从现在开始,页将在系统页文件中换入换出,而不再在可执行映象中进行页交换。

采用这种机制,潜在的性能命中有两种:首先,每个包含需要重定位地址的页都占用一页系统页文件(其结果是,减少了所有应用程序可用的虚拟内存数);另外,由于操作系统执行动态链接库页中的第一次修正操作,新的页必须从页文件中分配,并将整个页拷贝下来。

尽管扫描动态链接库重定位区段以及进行内存修正的算法都有很高的效率,执行修正操作还是会增加动态链接库的加载时间。(跨段操作的复杂性是需要修复地址数量的线性函数。)

地址修正

关于动态链接库基址重置的一类经常问到的问题是,“地址修正究竟是什么含义?程序员是否有办法调整代码,以减少可执行程序中的地址修正?”对于这两个问题的回答是,这一切在很大程度上依赖于可执行程序建立在哪一种平台上。在本文中,我们将平台限制在Intel 386,、486、和奔腾(Pentium)处理器上,讨论相应的可执行程序。(注意:为其他平台建立的可执行程序,相应的地址修复概念与本文讨论的概念不同。)

在386、486、或奔腾处理器上,两种情况可能导致某地址被标识为“可重定位”的状态:一是静态对象(static objects),另一种情况是绝对跳转(absolute jumps)。

首先,如果动态链接库引用了静态对象,就会使用对象的绝对地址(假设动态链接库被加载到首选地址中)。例如,在如下的代码段中:

LPSTR lpName="Name";

动态链接库的载入程序就会将“Name”字串分配到动态链接库数据段中,并将此字串的起始地址填写到lpName变量对应的位置中去。如果由于DLL不能被加载到基地址而使得“Name”字串必须重定位,lpName必须相应地进行调整。注意,在这种情况下,代码段中每个引用lpName的变量也必须作相应的地址修正。

可以重定位的对象包括文字字串(例如,在上例中的“Name”字串)、任何一种类型的全局或静态数据、包含静态分配的C++对象。应该注意到,特别是在C++中,可能存在着许多从一个静态对象到另一个静态对象的交叉索引。未初始化的数据不需要在重定位过程中修正地址,但指向未初始化静态数据的索引需要进行地址修正。

在i386可执行代码中,另一类可以进行重定位的项是绝对跳转和函数调用,包括系统函数调用。注意到程序开发人员很难通过修改程序代码来避免地址重定位,唯一可以采用的办法就是缩减静态分配数据的数目。要缩减静态分配数据,一种办法就是尽量避免使用名字进行资源索引,而应该通过坐标进行资源索引(因为,程序员在代码中显式使用的每一个名字都会自动变成一个可重定位的项)。

尽管如此,作者并不建议程序开发人员带着减少加载时间这一特殊目的开发动态链接库代码,除非存在以下两种情况:(1)静态分配对象的数据可以大幅度减少;(2)程序员依据此种方式进行编程时,不会影响其他编程中需要考虑到的因素。

除此之外,程序开发人员还可以通过简单的优化方法,减少加载时间。例如,可以将所有可以重新定位的数据集中到几页中。很显然,如果动态链接库需要进行基址重置,每页含有一个重定位项的两页,都需要有页文件来支持。如果所有的重定位项都出现在同一页中,只有一页需要页文件来支持,因此只有一页会受到影响。在必要的情况下,读者可以使用pragma (data_seg,数据段)伪指令,确保尽可能多的可重定位项被分配到尽可能少的页中去。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有