CN117009308B - 基于兼容层的可执行文件加载方法及系统 - Google Patents

基于兼容层的可执行文件加载方法及系统 Download PDF

Info

Publication number
CN117009308B
CN117009308B CN202311278044.6A CN202311278044A CN117009308B CN 117009308 B CN117009308 B CN 117009308B CN 202311278044 A CN202311278044 A CN 202311278044A CN 117009308 B CN117009308 B CN 117009308B
Authority
CN
China
Prior art keywords
file
shared
executable file
mapping
executable
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Active
Application number
CN202311278044.6A
Other languages
English (en)
Other versions
CN117009308A (zh
Inventor
陈江仪
谢威
赵志鹏
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Uniontech Software Technology Co Ltd
Original Assignee
Uniontech Software Technology Co Ltd
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Uniontech Software Technology Co Ltd filed Critical Uniontech Software Technology Co Ltd
Priority to CN202311278044.6A priority Critical patent/CN117009308B/zh
Publication of CN117009308A publication Critical patent/CN117009308A/zh
Application granted granted Critical
Publication of CN117009308B publication Critical patent/CN117009308B/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F16/00Information retrieval; Database structures therefor; File system structures therefor
    • G06F16/10File systems; File servers
    • G06F16/17Details of further file system functions
    • G06F16/176Support for shared access to files; File sharing support
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F16/00Information retrieval; Database structures therefor; File system structures therefor
    • G06F16/10File systems; File servers
    • G06F16/17Details of further file system functions
    • G06F16/1737Details of further file system functions for reducing power consumption or coping with limited storage space, e.g. in mobile devices

Abstract

本公开提供一种基于兼容层的可执行文件加载方法及系统,在兼容层跨系统打开可执行文件创建对应的映射对象并初始化映射对象中的参数时,对将要加载的可执行文件的有效性通过预设标志进行识别,对于有效的可执行文件,通过在对应的共享文件中保存有效可执行文件中的所有属性段的数据的方式,可以实现在基于映射对象加载对应的可执行文件时,将共享文件中保存的有效可执行文件中所有属性段的数据都映射到进程空间中,使得可执行文件中所有属性段的数据通过兼容层在跨系统加载的情况下能够进程间共享,避免可执行文件通过兼容层跨系统加载时在进程间的重复拷贝导致的兼容层运行速度低下,并且可以减少跨系统应用的内存占用量。

Description

基于兼容层的可执行文件加载方法及系统
技术领域
本公开涉及操作系统技术领域,具体涉及一种基于兼容层的可执行文件加载方法、系统、电子设备及存储介质。
背景技术
由于Linux系统和Windows系统的内核及用户层接口差异,Windows应用无法直接在Linux系统上运行。为了在Linux发行版系统上运行Windows应用,目前广泛采用的方案是:使用Wine作为Windows应用和Linux系统的中间兼容层,使Windows应用作为Wine的客户程序最终可以运行在Linux系统上。
而Wine应用在Linux系统上存在内存占用量远大于Windows系统的问题。
发明内容
本公开的示例性实施例提供的基于兼容层的可执行文件加载方法、系统、电子设备及存储介质,至少解决上述技术问题和上文未提及的其它技术问题。
根据本公开的一个方面,提供一种基于兼容层的可执行文件加载方法,所述方法包括:创建与所述可执行文件对应的映射对象;在所述可执行文件为映像文件的情况下,初始化所述映射对象中的第一预设参数;基于所述映射对象加载所述可执行文件;其中,所述基于所述映射对象加载所述可执行文件,包括:在所述可执行文件的文件头信息中不包含第一预设标志的情况下,根据所述可执行文件对应的共享文件中的共享对象初始化所述映射对象中的第二预设参数,并基于所述映射对象加载所述可执行文件;其中,所述共享文件中包括对应的所述可执行文件中所有属性段的数据。
可选的,所述基于所述映射对象加载所述可执行文件,还包括:在所述可执行文件的文件头信息中包含所述第一预设标志的情况下,设置所述映射对象中所述第一预设参数中的第二预设标志,并基于所述映射对象加载所述可执行文件。可选的,在所述可执行文件的文件头信息中不包含第一预设标志的情况下,所述方法还包括:在全局共享对象列表中查找出与所述可执行文件对应的所述共享文件中的所述共享对象;在所述查找失败的情况下,执行如下步骤:基于所述可执行文件中所有属性段的数据映射到进程空间后所占的总字节数创建所述共享文件,将所述可执行文件中所有属性段的数据拷贝到所述共享文件中;在所述共享文件中创建并初始化所述共享对象;将创建的所述共享对象插入到所述全局共享对象列表中。
可选的,所述可执行文件中所有属性段的数据,包括:所述可执行文件中的共享属性段及非共享属性段的数据。
可选的,所述基于所述映射对象加载所述可执行文件,还包括:在所述映射对象中包含所述第一预设标志的情况下,结束所述文件加载方法;在所述映射对象中不包含所述第一预设标志的情况下,执行如下步骤:在所述映射对象对应的所述可执行文件为映像文件的情况下,将所述映射对象对应的所述可执行文件的文件头信息和所述共享文件分开映射到进程空间;在所述映射对象对应的所述可执行文件不为映像文件的情况下,将所述可执行文件整体映射到进程空间。
可选的,所述映射对象对应的所述可执行文件为映像文件的情况,包括:所述映射对象对应的所述可执行文件为Flat类型或非Flat类型的可执行文件。
可选的,所述将所述映射对象对应的所述可执行文件的文件头信息和所述共享文件分开映射到进程空间,包括:结合文件映射接口的文件后端机制将所述映射对象对应的所述可执行文件的文件头信息和所述共享文件分开映射到进程空间。
可选的,所述映射对象对应的所述可执行文件为映像文件的情况,包括:所述映射对象中,由用户端传递的sec_flags参数初始化得到的flags标志包含SEC_IMAGE标志。
可选的,所述方法还包括:将所述共享文件的映射类型设置为私有类型。
可选的,所述方法还包括:在映射失败的情况下,将待映射文件数据拷贝到进程空间中重新分配的匿名映射空间中,其中,所述待映射文件数据不包括所述共享文件。
可选的,所述共享文件中的段数据按照内存页对齐的方式存放;所述可执行文件中的段数据按照文件对齐的方式存放。
可选的,所述方法还包括:在所述可执行文件不为映像文件的情况下,初始化所述映射对象中的第三预设参数后结束对所述映射对象的参数初始化。
可选的,所述可执行文件为映像文件的情况,包括:兼容层中创建所述映射对象时,用户端传递到兼容层服务进程的sec_flags参数中包含SEC_IMAGE标志。
可选的,所述第一预设标志包括:fakedll。
根据本公开的另一方面,提供一种基于兼容层的可执行文件加载系统,所述系统包括:映射对象创建单元,被配置为:创建与所述可执行文件对应的映射对象;初始化单元,被配置为:在所述可执行文件为映像文件的情况下,初始化所述映射对象中的第一预设参数;加载单元,被配置为:基于所述映射对象加载所述可执行文件;其中,所述加载单元被配置为:在所述可执行文件的文件头信息中不包含第一预设标志的情况下,根据所述可执行文件对应的共享文件中的共享对象初始化所述映射对象中的第二预设参数,并基于所述映射对象加载所述可执行文件;其中,所述共享文件中包括对应的所述可执行文件中所有属性段的数据。
可选的,所述加载单元还被配置为:在所述可执行文件的文件头信息中包含所述第一预设标志的情况下,设置所述映射对象中所述第一预设参数中的第二预设标志,并基于所述映射对象加载所述可执行文件。
可选的,所述初始化单元还被配置为:在全局共享对象列表中查找出与所述可执行文件对应的所述共享文件中的所述共享对象;在所述查找失败的情况下,执行如下配置:基于所述可执行文件中所有属性段的数据映射到进程空间后所占的总字节数创建所述共享文件,将所述可执行文件中所有属性段的数据拷贝到所述共享文件中;在所述共享文件中创建并初始化所述共享对象;将创建的所述共享对象插入到所述全局共享对象列表中。
可选的,所述可执行文件中所有属性段的数据,包括:所述可执行文件中的共享属性段及非共享属性段的数据。
可选的,所述加载单元还被配置为:在所述映射对象中包含所述第一预设标志的情况下,结束所述文件加载系统的文件加载过程;在所述映射对象中不包含所述第一预设标志的情况下,执行如下配置:在所述映射对象对应的所述可执行文件为映像文件的情况下,将所述映射对象对应的所述可执行文件的文件头信息和所述共享文件分开映射到进程空间;在所述映射对象对应的所述可执行文件不为映像文件的情况下,将所述可执行文件整体映射到进程空间。
可选的,所述映射对象对应的所述可执行文件为映像文件的情况,包括:所述映射对象对应的所述可执行文件为Flat类型或非Flat类型的可执行文件。
可选的,所述加载单元被配置为:结合文件映射接口的文件后端机制将所述映射对象对应的所述可执行文件的文件头信息和所述共享文件分开映射到进程空间。
可选的,所述映射对象对应的所述可执行文件为映像文件的情况,包括:所述映射对象中,由用户端传递的sec_flags参数初始化得到的flags标志包含SEC_IMAGE标志。
可选的,所述加载单元还被配置为:将所述共享文件的映射类型设置为私有类型。
可选的,所述系统还包括拷贝单元,被配置为:在映射失败的情况下,将待映射文件数据拷贝到进程空间中重新分配的匿名映射空间中,其中,所述待映射文件数据不包括所述共享文件。
可选的,所述共享文件中的段数据按照内存页对齐的方式存放;所述可执行文件中的段数据按照文件对齐的方式存放。
可选的,所述系统还包括:第一参数初始化单元,被配置为:在所述可执行文件不为映像文件的情况下,初始化所述映射对象中的第三预设参数后结束对所述映射对象的参数初始化。
可选的,所述可执行文件为映像文件的情况,包括:兼容层中创建所述映射对象时,用户端传递到兼容层服务进程的sec_flags参数中包含SEC_IMAGE标志。
可选的,所述第一预设标志包括:fakedll。
根据本公开实施例的另一方面,还提供一种电子设备,其中,包括:至少一个处理器;至少一个存储计算机可执行指令的存储器,其中,所述计算机可执行指令在被所述至少一个处理器运行时,促使所述至少一个处理器执行如上所述的基于兼容层的可执行文件加载方法。
根据本公开实施例的另一方面,还提供一种存储指令的计算机可读存储介质,其中,当所述指令被至少一个处理器运行时,促使所述至少一个处理器执行如上所述的基于兼容层的可执行文件加载方法。
本公开实施例提供的技术方案至少带来以下有益效果:
根据本公开的基于兼容层的可执行文件加载方法、系统、电子设备及存储介质,在兼容层跨系统打开可执行文件创建对应的映射对象并初始化映射对象中的参数时,对将要加载的可执行文件的有效性通过预设标志进行识别,对于有效的可执行文件,通过在对应的共享文件中保存有效可执行文件中的所有属性段的数据的方式,可以实现在基于映射对象加载对应的可执行文件时,将共享文件中保存的有效可执行文件中所有属性段的数据都映射到进程空间中,使得可执行文件中所有属性段的数据通过兼容层在跨系统加载的情况下能够进程间共享,避免可执行文件通过兼容层跨系统加载时在进程间的重复拷贝导致的兼容层运行速度低下,并且可以减少跨系统应用的内存占用量。
另外,通过映射对象进行进程空间的映射时,通过预设标志识别出映射对象对应的可执行文件是无效的可执行文件后,直接结束加载,能够减少无效可执行文件的加载,进一步减少跨系统应用内存占用、提高运行速度。
另外,在映射时识别文件类型,可以通过公共的文件映射接口执行映射,并且不改变非可执行文件的映射逻辑。
另外,将Flat类型或非Flat类型的映像文件都采用文件头信息和存有属性段数据的共享文件分开映射的方式,可以保证Flat类型的可执行文件映射成功。
另外,将共享文件的映射类型设置为私有类型再进行映射可以确保共享文件中不被进程修改的数据可共享、需要修改的数据会被拷贝为进程私有数据以实现写时复制的目的。
附图说明
此处的附图被并入说明书中并构成本说明书的一部分,示出了符合本公开的实施例,并与说明书一起用于解释本公开的原理,并不构成对本公开的不当限定。
图1示出本公开示例性实施例的相关技术中可执行文件加载过程的流程图;
图2示出本公开示例性实施例的基于兼容层的可执行文件加载方法的流程图;
图3示出本公开示例性实施例的基于兼容层的可执行文件加载方法的示例性实施方式的流程图;
图4示出本公开示例性实施例的基于兼容层的可执行文件加载系统的框图;
图5示出本公开示例性实施例的电子设备的框图。
具体实施方式
为了使本领域普通人员更好地理解本公开的技术方案,下面将结合附图,对本公开实施例中的技术方案进行清楚、完整地描述。
需要说明的是,本公开的说明书和权利要求书及上述附图中的术语“第一”、“第二”等是用于区别类似的对象,而不必用于描述特定的顺序或先后次序。应该理解这样使用的数据在适当情况下可以互换,以便这里描述的本公开的实施例能够以除了在这里图示或描述的那些以外的顺序实施。以下实施例中所描述的实施方式并不代表与本公开相一致的所有实施方式。相反,它们仅是与如所附权利要求书中所详述的、本公开的一些方面相一致的装置和方法的例子。
在此需要说明的是,在本公开中出现的“若干项之中的至少一项”均表示包含“该若干项中的任意一项”、“该若干项中的任意多项的组合”、“该若干项的全体”这三类并列的情况。例如“包括A和B之中的至少一个”即包括如下三种并列的情况:(1)包括A;(2)包括B;(3)包括A和B。又例如“执行步骤一和步骤二之中的至少一个”,即表示如下三种并列的情况:(1)执行步骤一;(2)执行步骤二;(3)执行步骤一和步骤二。
本公开所提到的可执行文件指Windows系统上可执行文件的总称,可以表示为PE文件;DLL指一种可执行的PE文件;Wine是指Windows应用软件和Linux内核(或其他系统内核,如macOS及BSD等)之间的兼容适配层,体现为一个Wine服务进程(wineserver,又称兼容层服务进程)和一组动态链接库(相当于Windows的众多DLL);Wine应用指依靠Wine运行在Linux系统(或其他系统,如macOS及BSD等)上的Windows程序。
可以理解的是,本公开仅以Linux系统为例,但还可以将Linux系统替换为其他系统,如macOS及BSD等。
由于Linux系统和Windows系统的内核及用户层接口存在的差异,Windows应用无法直接在Linux系统上运行。为了在Linux发行版系统上运行Windows应用,采用的相关方案如下:使用Wine作为Windows应用和Linux系统的中间兼容层,使Windows应用作为Wine的客户程序最终可以运行在Linux系统上。
对于运行在Linux系统上的Windows应用而言,Wine充当了虚拟Windows内核的角色。由于Windows系统不开源,且Wine是在Linux用户空间使用“核内差异核外补”的方式基于Linux内核现有功能补充和填平两内核之间的差异的,使得Wine模拟实现的Windows兼容层在功能、运行性能、内存占用等方面都存在缺陷。
比如,Windows系统上PE文件和ntdll模块的加载由Windows内核完成,DLL的链接由APC(Asynchronous Procedure Call,异步过程调用)函数LdrInitializeThunk在用户空间完成,而Wine都是在Linux用户空间模拟实现上述功能的。
并且,Windows通过将PE映像所在物理内存映射到各进程私有虚拟内存空间的方式实现了多个进程共享PE(如DLL/EXE代码段共享)的功能。而Wine中各进程都会独立加载PE映像(PE映像仅在线程间共享),仅在PE映像将段属性设置为共享时同一个应用的各个进程才能实现共享。
由上可知,依靠Wine运行的Wine应用在运行性能和内存占用方面都存在缺陷。事实也确实如此,通过实践可以发现多种应用程序在Linux系统上用wine启动后占用的物理内存远比Windows上多,且在运行过程中随着进程数量的增加内存占用量增长较大。为了使通过Wine运行的应用在Linux系统上的表现更佳,可以进行如下分析:
Wine应用在Linux系统上内存占用量远大于Windows系统的主要原因包括:1)除了Windows应用本身占内存外,Wine、Wineserver及Wine启动的其它辅助程序也需要占据一定的内存;2)由于Wine的实现机制问题,Wine应用运行所需链接的共享库并不能在进程间共享,而这部分正是内存占用量大的关键原因。
Wine目前并未提供共享库进程间共享的通用方案,仅实现了可共享段(共享库中指定为可共享且可读的段)能被共享的功能。因此,可以基于这个共享功能进行扩展,实现PE文件在进程间共享的通用方案,从而达到优化Wine应用内存占用的目的。
图1示出本公开示例性实施例的相关技术中可执行文件加载过程的流程图。
参照图1,Wine加载PE文件到进程空间的主要过程可以如下:
按PE文件搜索列表中的路径查找对应名称的PE文件,查找到则打开PE文件;查找不到,则提示错误信息并返回失败。
向Wineserver(兼容层服务进程)发送create_mapping请求(映射对象创建请求)并传递上述请求所需的参数;Wineserver处理上述请求时会创建一个mapping对象(映射对象),并根据client端(用户端)传递过来的参数初始化mapping对象的部分成员数据(如将映射对象中的参数fd设置为client端打开的PE文件、参数flags设置为client端传递过来的sec_flags参数),并可以通过判断client端传递过来的sec_flags参数中是否包含SEC_IMAGE标志,来判断mapping对象要操作的文件是否是PE映像文件(简称为映像文件);如果是则初始化mapping对象的image成员,如果不是,就在初始化mapping对象的size成员后结束create_mapping请求。
具体的,可以通过如下代码创建mapping对象:
struct mapping
{
struct object obj; /object header/>/
mem_size_t size; /mapping size/>/
unsigned int flags; /SEC_/>flags/>/
struct fdfd; //>fd for mapped file/>/
pe_image_info_t image; /image info (for PE image mapping)/>/
struct rangescommitted; //>list of committed ranges in this mapping/>/
struct shared_mapshared; //>temp file for shared PE mapping/>/
};
若需要初始化mapping对象的image成员,Wineserver会根据读取到的PE文件的头部信息初始化image成员数据。image成员是一个pe_image_info_t结构对象,若PE文件头中包含fakedll字符串标志,则可以设置image成员的image_flags标志。然后开始构建PE文件对应的共享文件。需要说明的是:包含fakedll字符串标志的PE文件是由Wine编译时自动构建生成的,这种PE文件并不包含真实的代码数据,仅用于引导Wine应用运行过程中加载对应名称的so文件,而so文件则包含真实的代码数据。如XXX.dll对应的so文件为XXX.dll.so。
具体的,可以通过如下代码初始化image成员:
typedef struct
{
……
unsigned short image_charact;
unsigned short dll_charact;
……
unsigned char image_flags;
……
} pe_image_info_t;
构建PE文件对应的共享文件的规则为:如果PE文件中不存在可共享且可读的段,直接跳过构建PE文件对应的共享文件;反之,如果PE文件中存在可共享且可读的段,则统计出可共享的段映射到内存后占据的总字节数。如果全局共享对象列表中存在PE文件对应的共享文件,则使用共享文件对应的共享对象初始化mapping对象的shared成员。如果全局共享对象列表中不能根据共享对象进行查找以获得PE文件对应的共享文件,则根据统计出的总字节数创建一个相同尺寸的共享文件,并将PE文件中可共享且可读的段数据拷贝到创建的共享文件中,且共享文件中的各段按照内存页对齐的方式存放(而原PE文件中的各段按照文件对齐方式存放)。然后创建并初始化一个共享对象,上述共享对象用于将PE文件和共享文件关联起来,建立一一对应关系。最后,将新建的共享对象插入到全局共享对象列表中,并且初始化mapping对象的shared成员。
具体的,可以通过如下代码初始化mapping对象的shared成员:
struct shared_map
{
struct object obj; /object header/>/
struct fdfd; //>file descriptor of the mapped PE file/>/
struct filefile; //>temp file holding the shared data/>/
struct list entry; /entry in global shared maps list/>/
};
client端的mapping对象创建并完成参数初始化后,client端开始将mapping对象关联的数据映射到当前进程空间。
首先,可以通过判断mapping对象的flags标志(实际上是client端发送create_mapping请求时传递过来的sec_flags参数)是否包含SEC_IMAGE标志,来判断mapping对象关联的文件是否是PE映像文件。如果mapping对象关联的文件是PE映像文件,则开始按映像文件装载的方式进行映射,反之,如果mapping对象关联的文件不是PE映像文件,则按普通文件的加载方式一次性将文件中要加载的数据映射到进程空间中。对于Flat类型的映像文件(即映像中内存对齐和文件对齐大小相同,各段指向的内存虚拟地址以文件对齐方式对齐),也是按照一次性将整个文件数据映射到进程空间中的方式进行映射。而普通PE文件则是分段进行映射,对于可共享可读的段,将对应的共享文件中对应的可共享可读段按共享映射的方式映射到进程空间中(导出表所在页按私有映射的方式进行映射);对于非共享的段,则将PE文件中段数据按私有映射的方式进行映射。
上述过程中,不论是哪种类型的映射,都是使用mmap(文件映射接口)进行实现,仅仅是传递给mmap的参数有差异。如果mmap映射失败,会在进程空间中重新分配一段匿名类型的映射空间,并将需要映射的数据从文件中拷贝到该映射空间。
由于mmap要求被映射的文件段起始地址和段大小都需要按内存页对齐,因此只有PE文件对应的共享文件才能被成功映射,从而实现同一个共享文件被映射到不同进程空间并在不同进程间进行数据共享的功能;而PE文件映射会失败,后续将数据拷贝一份到进程空间后会导致内存开销变大。
由上述过程可知,在构建PE文件的mapping对象时会根据段属性是否为共享来确定是否建立对应的共享文件,后续将mapping对象关联的数据映射到进程空间时,会再次根据段属性确定是否使用共享文件进行映射。
实际上,几乎很少有PE文件的段属性会被设置为可读且可共享。即便有一些PE文件的段属性被设置为可读且可共享,对内存的优化比率也非常小。并且,可共享段能被共享最多只能保证可共享段部分内存占用不会比Windows系统高,并没有从根本上解决因PE文件不能共享而导致Wine应用内存占用比Windows系统高的问题。因此,本方案并没有达到有效优化Wine应用内存占用的目的。
另外,由于PE文件中大部分数据不能实现共享,重复拷贝PE文件到各进程空间会导致Wine运行速度降低。
为了解决上述问题,本公开提供了一种基于兼容层的可执行文件加载方法、系统、电子设备及存储介质,在兼容层跨系统打开可执行文件创建对应的映射对象并初始化映射对象中的参数时,对将要加载的可执行文件的有效性通过预设标志进行识别,对于有效的可执行文件,通过在对应的共享文件中保存有效可执行文件中的所有属性段的数据的方式,可以实现在基于映射对象加载对应的可执行文件时,将共享文件中保存的有效可执行文件中所有属性段的数据都映射到进程空间中,使得可执行文件中所有属性段的数据通过兼容层在跨系统加载的情况下能够进程间共享,避免可执行文件通过兼容层跨系统加载时在进程间的重复拷贝导致的兼容层运行速度低下,并且可以减少跨系统应用的内存占用量。
下面,将参照图2至图5具体描述本公开的基于兼容层的可执行文件加载方法、系统、电子设备及存储介质。
图2示出本公开示例性实施例的基于兼容层的可执行文件加载方法的流程图。
参照图2,在步骤201,可以创建与可执行文件对应的映射对象。
根据本公开的示例性实施例,可以按PE文件(可执行文件)搜索列表中的路径查找对应名称的PE文件并打开;如果查找不到,可以提示错误信息并可以返回失败通知。
根据本公开的示例性实施例,PE文件的加载可以从打开PE文件开始,在加载PE文件的过程中,可以由Wine client端(兼容层的用户端)向Wineserver(兼容层服务进程)发送create_mapping请求(映射对象创建请求)并传递上述请求所需的参数;Wineserver处理上述请求时可以创建一个mapping对象(映射对象),并可以根据client端(用户端)传递过来的参数初始化mapping对象的部分参数 (如将映射对象中的参数fd设置为client端打开的PE文件、参数flags设置为client端传递过来的sec_flags参数)。
在步骤202,在可执行文件为映像文件的情况下,可以初始化映射对象中的第一预设参数。
根据本公开的示例性实施例,可执行文件为映像文件的情况,可以包括但不限于以下判断方式:兼容层中创建映射对象时,用户端传递到兼容层服务进程的sec_flags参数中包含SEC_IMAGE标志。
根据本公开的示例性实施例,Wineserver可以通过判断client端传递过来的sec_flags参数中是否包含SEC_IMAGE标志,来判断当前的可执行文件是否是PE映像文件(简称为映像文件);如果当前的可执行文件是映像文件,则可以初始化mapping对象的相关参数,具体的,相关参数可以为第一预设参数,上述第一预设参数可以是image成员。
可以理解的是,也可以通过其他可行的方式判断当前的可执行文件是否是映像文件,例如,通过文件后缀或自定义的文件标识等。
根据本公开的示例性实施例,在可执行文件不为映像文件的情况下,可以初始化映射对象中的第三预设参数后结束对映射对象的参数初始化。
根据本公开的示例性实施例,如果当前的可执行文件不是映像文件,就可以在初始化mapping对象的相关参数,具体的,相关参数可以为第三预设参数,接着可以通过结束对映射对象的参数初始化的方式结束create_mapping请求,或者说结束mapping对象创建请求,或者说结束mapping对象的创建过程,上述第三预设参数可以为size成员。
在步骤203,可以基于映射对象加载可执行文件;其中,基于映射对象加载可执行文件,可以包括以下步骤:可以在可执行文件的文件头信息中不包含第一预设标志的情况下,根据可执行文件对应的共享文件中的共享对象初始化映射对象中的第二预设参数,并基于映射对象加载可执行文件;其中,共享文件中包括对应的可执行文件中所有属性段的数据。
根据本公开的示例性实施例,第一预设标志可以包括但不限于:fakedll。
根据本公开的示例性实施例,第一预设标志用于判断当前的PE文件是否为有效可执行文件,可以理解的是,也可以通过其他可行的方式判断当前的可执行文件是否是有效的可执行文件,例如,通过文件后缀或自定义的文件标识等。
根据本公开的示例性实施例,Wineserver识别到当前将要加载的文件类型为PE文件类型后可以读取当前文件的文件头信息,接着可以根据文件头信息识别当前要加载的文件头信息中是否包含fakedll标志。因为文件头信息中包含fakedll标志的PE文件是由Wine编译时自动构建生成的,这种PE文件并不包含真实的代码数据,仅用于引导Wine应用运行过程中加载对应名称的so文件,而so文件则包含真实的代码数据。如XXX.dll对应的so文件为XXX.dll.so;可以认为文件头信息中包含fakedll标志的PE文件并不包含有效的代码和数据且后续过程中会重新加载其真实数据,因此识别到要加载的PE文件的文件头信息中不包含fakedll标志,则可以认为当前的PE文件为存储有有效的代码和数据的有效PE文件。接着可以根据PE文件对应的共享文件中的共享对象初始化mapping对象中的相关参数,具体的,相关参数可以为第二预设参数,上述第二预设参数可以为mapping对象中的Shared成员。
具体的,可以通过以下代码去除文件头信息中带fakedll标志的PE文件:
if (mz_size == sizeof(mz)&&!memcmp( mz.buffer, fakedll_signature,sizeof(fakedll_signature) ))
{
mapping->image.image_flags |= IMAGE_FLAGS_WineFakeDll;
return STATUS_INVALID_IMAGE_FORMAT;
}
根据本公开的示例性实施例,在可执行文件的文件头信息中不包含第一预设标志的情况下,上述方法还可以包括如下步骤:在全局共享对象列表中查找出与可执行文件对应的共享文件中的共享对象;在查找失败的情况下,可以执行如下步骤:基于可执行文件中所有属性段的数据映射到进程空间后所占的总字节数创建共享文件,将可执行文件中所有属性段的数据拷贝到共享文件中;在共享文件中创建并初始化共享对象;将创建的共享对象插入到全局共享对象列表中。
根据本公开的示例性实施例,如果要加载的PE文件的文件头信息中不包含fakedll标志,则可以在全局共享对象列表中查找出与当前的PE文件对应的共享文件中的共享对象;在查找失败的情况下,则可以根据PE文件中的对应信息初始化mapping对象中对应的相关参数并进一步创建对应的共享文件。能进入到创建共享文件的过程可以说明当前加载的是一个有效的PE文件,因此可以去掉原PE文件中属性段的可共享可读等的限制,为PE文件的所有属性段创建共享文件,从而可以使PE文件具备通用共享的能力。具体的,可以通过执行如下步骤创建所有属性段通用共享的共享文件:基于PE文件中所有属性段的数据映射到进程空间后所占的总字节数创建共享文件,接着可以将PE文件中所有属性段的数据拷贝到创建的共享文件中;在共享文件中创建并初始化对应的共享对象;最后可以将创建的共享对象插入到全局共享对象列表中,以方便查找。
具体的,可以通过如下代码为PE文件创建共享文件或直接获取已有的共享文件:
total_size = max_size = 0;
/统计所有段映射后的总字节数/>/
for (i = 0; i< nb_sec; i++)
{
- if ((sec[i].Characteristics&IMAGE_SCN_MEM_SHARED)&&
- (sec[i].Characteristics&IMAGE_SCN_MEM_WRITE))
{
get_section_sizes(&sec[i],&map_size,&read_pos,&file_size );
if (file_size> max_size) max_size = file_size;
total_size += map_size;
}
}
if (!total_size) return 1; /nothing to do/>/
/已存在对应共享文件则获取原有共享文件并返回/>/
if ((mapping->shared = get_shared_file( mapping->fd ))){
fprintf( stderr,"%d 023000\n",mapping->fd);
return 1;
}
/创建共享文件/>/
if ((shared_fd = create_temp_file( total_size )) == -1) return 0;
……
/将所有段的数据拷贝到共享文件中/>/
shared_pos = 0;
for (i = 0; i< nb_sec; i++)
{
- if (!(sec[i].Characteristics&IMAGE_SCN_MEM_SHARED)) continue;
- if (!(sec[i].Characteristics&IMAGE_SCN_MEM_WRITE)) continue;
……
if (pwrite( shared_fd, buffer, file_size, write_pos ) != file_size)goto error;
}
/新建共享对象并建立起PE文件和共享文件的联系/>/
if (!(shared = alloc_object(&shared_map_ops ))) goto error;
shared->fd = (struct fd)grab_object( mapping->fd );/>
shared->file = file;
/将共享对象添加到全局共享列表中/>/
list_add_head(&shared_map_list,&shared->entry );
mapping->shared = shared;
根据本公开的示例性实施例,共享文件中的段数据可以按照内存页对齐的方式存放;可执行文件中的段数据可以按照文件对齐的方式存放。
根据本公开的示例性实施例,可执行文件中所有属性段的数据,可以包括但不限于:可执行文件中的共享属性段及非共享属性段的数据。
根据本公开的示例性实施例,非共享属性段包括可读、只读属性段等。
根据本公开的示例性实施例,可以基于映射对象加载可执行文件;其中,基于映射对象加载可执行文件,可以包括:在可执行文件的文件头信息中包含第一预设标志的情况下,设置映射对象中第一预设参数中的第二预设标志,并基于映射对象加载可执行文件。
根据本公开的示例性实施例,在识别到当前打开的PE文件的文件头信息中包含fakedll标志的情况下,此当前打开的PE文件并不包含有效的代码和数据且后续过程中会重新加载其真实数据,因此识别到要加载的PE文件的文件头信息中包含fakedll标志的情况下,则可以认为当前的PE文件为不存储有效的代码和数据的无效PE文件。接着可以直接设置对应mapping对象中的相关参数,具体的,相关参数可以为第一预设参数中的第二预设标志,接着,可以基于映射对象加载可执行文件;上述第一预设参数可以包括但不限于image成员,上述第二预设标志可以包括但不限于image_flags标志。
根据本公开的示例性实施例,基于映射对象加载可执行文件,还可以包括如下步骤:可以在映射对象中包含第一预设标志的情况下,结束映射对象对应的可执行文件的加载过程,结束整个文件加载方法;可以在映射对象中不包含第一预设标志的情况下,执行如下步骤:可以在映射对象对应的可执行文件为映像文件的情况下,将映射对象对应的可执行文件的文件头信息和共享文件分开映射到进程空间;可以在映射对象对应的可执行文件不为映像文件的情况下,将可执行文件整体映射到进程空间;接着可以结束映射对象对应的可执行文件的加载。
根据本公开的示例性实施例,对打开的PE文件对应的mapping对象中的相关参数初始化完成后,就可以基于mapping对象加载对应的PE文件。具体的,在基于mapping对象加载对应的PE文件时,可以首先判断mapping对象中是否包含fakedll标志,在mapping对象中包含fakedll标志的情况下,可以认为当前mapping对象对应的PE文件为无效PE文件,因此可以直接结束当前mapping对象对应的无效PE文件的加载。在mapping对象中不包含fakedll标志的情况下,可以认为当前mapping对象对应的PE文件为有效PE文件,因此可以继续执行以下步骤:具体的,可以在mapping对象对应的PE文件为映像文件的情况下,将mapping对象对应的PE文件的文件头信息和保存属性段数据的共享文件分开映射到进程空间;可以在mapping对象对应的当前PE文件不为映像文件的情况下,将当前不为映像文件的PE文件一次性地整体映射到进程空间;接着就可以结束mapping对象对应的PE文件的加载过程。
根据本公开的示例性实施例,映射对象对应的可执行文件为映像文件的情况,可以通过包括以下情况进行确定:在mapping对象中,由wine client端请求wineserver创建mapping对象时传递的sec_flags参数初始化得到的flags标志中包含SEC_IMAGE标志。
根据本公开的示例性实施例,数据映射的过程都可以使用mmap(文件映射接口)进行实现,仅仅是传递给mmap的参数有差异。此mmap为公共的文件映射接口,非PE文件的映射也可以通过mmap实现,而非PE文件的映射大多是应用主动发起,情况复杂多变;因此,为了避免影响应用原有运行逻辑,可以在使用公共的mmap接口进行映射之前、或在mmap接口中识别当前待映射的文件的类型,以确保若后续对共享文件的映射的修改不会对非PE文件的映射造成影响。具体的,mapping对象的flags参数由wine client端请求wineserver创建mapping对象时传递过来的sec_flags初始化,可以作为识别当前待映射的文件是否为PE文件类型的关键性标志。
根据本公开的示例性实施例,映射对象对应的可执行文件为映像文件的情况,可以具体包括如下情况:映射对象对应的可执行文件为Flat类型或非Flat类型的可执行文件。
根据本公开的示例性实施例,因为mmap接口要求被映射的文件中段数据起始地址和段大小都需要按内存页对齐,因此只有PE文件对应的按内存页对齐的共享文件才能被成功映射。而Flat类型的PE文件中各段数据按文件对齐方式对齐,即便为其建立了内存页对齐的共享文件,若按照原Flat类型的PE文件将其整个文件数据一次性映射到进程空间的方式进行映射(可以认为传递给mmap的文件起始地址为0),会映射失败;对于这种情况,可以将Flat类型的PE文件的映射方式设置为和非Flat类型的PE文件一样,将PE文件头和段数据分开映射,具体的,可以将Flat类型和非Flat类型的PE文件的文件头信息和保存属性段数据的共享文件分开映射到进程空间。
根据本公开的示例性实施例,上述方法还包括:将共享文件的映射类型设置为私有类型。
根据本公开的示例性实施例,将映射对象对应的可执行文件的文件头信息和共享文件分开映射到进程空间,可以具体包括以下步骤:结合文件映射接口的文件后端机制将映射对象对应的可执行文件的文件头信息和共享文件分开映射到进程空间。
根据本公开的示例性实施例,可以使用mmap接口将共享文件映射到进程虚拟空间,此时,由于不再受到段属性的限制,所有段都可使用原有可读可共享段的映射方式进行映射(内存映射类型为MAP_SHARED,即共享类型),可能会导致导入表所在内存页可被其它进程修改,进而导致Wine应用运行异常。为解决上述问题,可以将PE共享文件的内存映射类型统一设置为MAP_PRIVATE私有类型,并可以利用mmap接口的file backend机制(文件后端机制),以达到共享文件中不被进程修改的数据可共享,需要修改的数据会被拷贝为进程私有数据(可以认为是写时复制)的目的。
根据本公开的示例性实施例,上述方法还包括:在映射失败的情况下,可以将待映射文件数据拷贝到进程空间中重新分配的匿名映射空间中,其中,待映射文件数据不包括共享文件。
根据本公开的示例性实施例,由于mmap接口要求被映射的文件段起始地址和段大小都需要按内存页对齐,因此只有PE文件对应的共享文件才能被成功映射,而非共享文件类型的文件由于并非如共享文件类型那样按内存页对齐,会导致通过mmap接口映射失败。因此,对于通过mmap接口映射失败的非共享文件类型的文件,例如PE文件、非PE文件等数据,可以在进程空间中重新分配一段匿名类型的映射空间,并将需要映射但通过mmap接口映射失败的数据从文件中拷贝到该映射空间。最后结束文件的加载过程。
根据本公开的示例性实施例,可以基于Wine实现的可共享段(共享库中指定为可共享且可读的段)能被共享的功能进行扩展,以进一步实现PE文件在进程间共享的通用共享功能,并且还可以简化部分加载流程。
具体的,可以通过以下代码实现基于mmap接口实现文件映射:
static NTSTATUS virtual_map_section( HANDLE handle, PVOIDaddr_ptr,unsigned sh
+if (mapping->flags&SEC_IMAGE)
{
res = map_image_into_view( view, unix_handle, base, image_info->header_size,
- image_info->image_flags, shared_fd, needs_close );
+ image_info->image_flags, shared_fd, needs_close ,TRUE );
}
static NTSTATUS map_image_into_view( struct file_viewview, int fd,void/>orig_base,
- ……, ULONG image_flags, int shared_fd, BOOL removable )
+ ……, ULONG image_flags, int shared_fd, BOOL removable,BOOLisSecImage )
if (map_file_into_view( view, shared_fd, sec->VirtualAddress, map_size, pos,
- ……, FALSE ) != STATUS_SUCCESS)
+ ……, isSecImage ) != STATUS_SUCCESS)
static NTSTATUS map_file_into_view( struct file_viewview, int fd,size_t start, size_t size,
- off_t offset, unsigned int vprot, BOOL removable )
+ off_t offset, unsigned int vprot, BOOL removable , BOOLisSecImage)
可以理解的是,上述所有代码部分仅提供了实现方式的主要内容,并不对实现细节进行不当限定,此外,上述所有代码部分所反映的代码思想也可以使用其他计算机语言实现。
图3示出本公开示例性实施例的基于兼容层的可执行文件加载方法的示例性实施方式的流程图。
参照图3,根据本公开的示例性实施例,加载PE文件时,首先可以根据文件路径打开PE文件,接着可以创建与当前的PE文件对应的mapping对象;在当前的PE文件不是映像文件的情况下,可以结束mapping对象的创建;在当前的PE文件是映像文件的情况下,可以根据PE文件的文件头信息初始化mapping对象中的对应参数;接着,在当前的PE文件头信息中包含fakedll标志的情况下,可以在设置mapping对象对应的相关参数后结束对mapping对象的参数初始化;在当前的PE文件头信息中不包含fakedll标志的情况下,若共享对象列表中有当前PE文件对应的共享对象,则根据对应的共享对象初始化mapping对象中的相关参数;若共享对象列表中没有当前PE文件对应的共享对象,则根据当前PE文件中所有属性段的数据构建对应的共享对象并将构建的共享对象添加到共享对象列表中;mapping对象中的参数初始化完成后,就可以根据mapping对象中的信息执行后续步骤,具体的,在mapping对象中包含fakedll标志的情况下,可以直接结束当前PE文件的加载;在mapping对象中不包含fakedll标志的情况下,可以开始执行内存映射过程,具体的,在当前的PE文件为映像文件的情况下,可以将mmap接口中共享文件的映射类型设置为私有映射后,将共享文件通过mmap映射到进程空间;在当前文件不为映像文件的情况下,可以将原文件整体映射到进程空间;在映射成功的情况下,意味着PE文件加载过程结束;在映射失败的情况下,分配匿名内存并将映射失败的数据拷贝到匿名内存中以结束文件加载过程。
图4示出本公开示例性实施例的基于兼容层的可执行文件加载系统的框图。
参照图4,根据本公开的示例性实施例,还提供一种基于兼容层的可执行文件加载系统400。基于兼容层的可执行文件加载系统400可以包括映射对象创建单元401、初始化单元402及加载单元403。
映射对象创建单元401可以创建与可执行文件对应的映射对象。
初始化单元402可以在可执行文件为映像文件的情况下,初始化映射对象中的第一预设参数。
加载单元403可以基于映射对象加载可执行文件;其中,加载单元403可以在可执行文件的文件头信息中不包含第一预设标志的情况下,可以根据可执行文件对应的共享文件中的共享对象初始化映射对象中的第二预设参数,并基于映射对象加载可执行文件;其中,共享文件中包括对应的可执行文件中所有属性段的数据。
根据本公开的示例性实施例,加载单元403还可以在可执行文件的文件头信息中包含第一预设标志的情况下,设置映射对象中第一预设参数中的第二预设标志,并基于映射对象加载可执行文件。
根据本公开的示例性实施例,初始化单元402还可以在全局共享对象列表中查找出与可执行文件对应的共享文件中的共享对象;在查找失败的情况下,可以执行如下配置:基于可执行文件中所有属性段的数据映射到进程空间后所占的总字节数创建共享文件,将可执行文件中所有属性段的数据拷贝到共享文件中;在共享文件中创建并初始化共享对象;将创建的共享对象插入到全局共享对象列表中。
根据本公开的示例性实施例,可执行文件中所有属性段的数据,可以包括但不限于:可执行文件中的共享属性段及非共享属性段的数据。
根据本公开的示例性实施例,加载单元403还可以在映射对象中包含第一预设标志的情况下,结束文件加载系统的文件加载过程;在映射对象中不包含第一预设标志的情况下,可以执行如下配置:在映射对象对应的可执行文件为映像文件的情况下,将映射对象对应的可执行文件的文件头信息和共享文件分开映射到进程空间;在映射对象对应的可执行文件不为映像文件的情况下,将可执行文件整体映射到进程空间。
根据本公开的示例性实施例,映射对象对应的可执行文件为映像文件的情况,可以包括:映射对象对应的可执行文件为Flat类型或非Flat类型的可执行文件。
根据本公开的示例性实施例,加载单元403可以结合文件映射接口的文件后端机制将映射对象对应的可执行文件的文件头信息和共享文件分开映射到进程空间。
根据本公开的示例性实施例,映射对象对应的可执行文件为映像文件的情况,可以包括但不限于:映射对象中,由用户端传递的sec_flags参数初始化得到的flags标志包含SEC_IMAGE标志。
根据本公开的示例性实施例,加载单元403还可以将共享文件的映射类型设置为私有类型。
根据本公开的示例性实施例,上述基于兼容层的可执行文件加载系统400还可以包括拷贝单元(未在图4中示出),拷贝单元可以在映射失败的情况下,将待映射文件数据拷贝到进程空间中重新分配的匿名映射空间中,其中,待映射文件数据不包括共享文件。
根据本公开的示例性实施例,共享文件中的段数据按照内存页对齐的方式存放;可执行文件中的段数据按照文件对齐的方式存放。
根据本公开的示例性实施例,上述基于兼容层的可执行文件加载系统400还可以包括第一参数初始化单元(未在图4中示出),第一参数初始化单元可以在可执行文件不为映像文件的情况下,初始化映射对象中的第三预设参数后结束对映射对象的参数初始化。
根据本公开的示例性实施例,可执行文件为映像文件的情况,可以包括:兼容层中创建映射对象时,用户端传递到兼容层服务进程的sec_flags参数中包含SEC_IMAGE标志。
根据本公开的示例性实施例,第一预设标志可以包括但不限于:fakedll。
可以理解的是,上述基于兼容层的可执行文件加载系统400中的各单元用于实现上述基于兼容层的可执行文件加载方法。
示例性实施例中具体的实现过程的与上述基于兼容层的可执行文件加载方法中的示例性实施例大致相同,在此不作重复描述。基于兼容层的可执行文件加载系统400可被分别配置为执行特定功能的软件、硬件、固件或上述项的任意组合。例如,系统中的这些装置可对应于专用的集成电路,也可对应于纯粹的软件代码,还可对应于软件与硬件相结合的模块。此外,系统中的这些装置所实现的一个或多个功能也可由物理实体设备(例如,处理器、客户端或服务器等)中的组件来统一执行。
图5示出本公开示例性实施例的电子设备的框图。
参照图5,电子设备500包括至少一个存储器501和至少一个处理器502,所述至少一个存储器501中存储有计算机可执行指令集合,当计算机可执行指令集合被至少一个处理器502执行时,执行根据本公开的示例性实施例的基于兼容层的可执行文件加载方法。
根据本公开的示例性实施例,存储器501中包括操作系统503。操作系统503可以控制电子设备500的操作。操作系统503可以为Linux操作系统或其他操作系统,如macOS、BSD及UOS等。操作系统503中可以部署兼容层(Wine),并可以由兼容层执行根据本公开的示例性实施例的基于兼容层的可执行文件加载方法。
作为示例,电子设备500可以是PC计算机、平板装置、个人数字助理、智能手机、或其他能够执行上述指令集合的装置。这里,电子设备500并非必须是单个的电子设备,还可以是任何能够单独或联合执行上述指令(或指令集)的装置或电路的集合体。电子设备500还可以是集成控制系统或系统管理器的一部分,或者可被配置为与本地或远程(例如,经由无线传输)以接口互联的便携式电子设备。
在电子设备500中,处理器502可包括中央处理器(CPU)、图形处理器(GPU)、可编程逻辑装置、专用处理器系统、微控制器或微处理器。作为示例而非限制,处理器还可包括模拟处理器、数字处理器、微处理器、多核处理器、处理器阵列、网络处理器等。
处理器502可运行存储在存储器501中的指令或代码,其中,存储器501还可以存储数据。指令和数据还可经由网络接口装置而通过网络被发送和接收,其中,网络接口装置可采用任何已知的传输协议。
存储器501可与处理器502集成为一体,例如,将RAM或闪存布置在集成电路微处理器等之内。此外,存储器501可包括独立的装置,诸如,外部盘驱动、存储阵列或任何数据库系统可使用的其他存储装置。存储器501和处理器502可在操作上进行耦合,或者可例如通过I/O端口、网络连接等互相通信,使得处理器502能够读取存储在存储器中的文件。
此外,电子设备500还可包括视频显示器(诸如,液晶显示器)和用户交互接口(诸如,键盘、鼠标、触摸输入装置等)。电子设备500的所有组件可经由总线和/或网络而彼此连接。此外,上述基于兼容层的可执行文件加载方法可通过记录在计算机可读存储介质上的指令来实现,例如,根据本公开的示例性实施例,可提供一种存储指令的计算机可读存储介质,其中,当所述指令被至少一个计算装置运行时,促使所述至少一个计算装置执行上述基于兼容层的可执行文件加载方法。这里的计算机可读存储介质的示例包括:只读存储器(ROM)、随机存取可编程只读存储器(PROM)、电可擦除可编程只读存储器(EEPROM)、随机存取存储器(RAM)、动态随机存取存储器(DRAM)、静态随机存取存储器(SRAM)、闪存、非易失性存储器、CD-ROM、CD-R、CD+R、CD-RW、CD+RW、DVD-ROM、DVD-R、DVD+R、DVD-RW、DVD+RW、DVD-RAM、BD-ROM、BD-R、BD-R LTH、BD-RE、蓝光或光盘存储器、硬盘驱动器(HDD)、固态硬盘(SSD)、卡式存储器(诸如,多媒体卡、安全数字(SD)卡或极速数字(XD)卡)、磁带、软盘、磁光数据存储装置、光学数据存储装置、硬盘、固态盘以及任何其他装置,所述任何其他装置被配置为以非暂时性方式存储计算机程序以及任何相关联的数据、数据文件和数据结构并将所述计算机程序以及任何相关联的数据、数据文件和数据结构提供给处理器或计算机使得处理器或计算机能执行所述计算机程序。上述计算机可读存储介质中的计算机程序可在诸如客户端、主机、代理装置、服务器等计算机设备中部署的环境中运行,此外,在一个示例中,计算机程序以及任何相关联的数据、数据文件和数据结构分布在联网的计算机系统上,使得计算机程序以及任何相关联的数据、数据文件和数据结构通过一个或多个处理器或计算机以分布式方式存储、访问和执行。应注意,所述指令还可用于执行除了上述步骤以外的附加步骤或者在执行上述步骤时执行更为具体的处理,这些附加步骤和进一步处理的内容已经在进行相关方法的描述过程中提及,因此这里为了避免重复将不再进行赘述。
应注意,根据本公开示例性实施例的基于兼容层的可执行文件加载系统可完全依赖计算机程序或指令的运行来实现相应的功能,即,各个模块在计算机程序的功能架构中与各步骤相应,使得整个装置通过专门的软件包(例如,lib库)而被调用,以实现相应的功能。
另一方面,当上述基于兼容层的可执行文件加载系统以软件、固件、中间件或微代码实现时,用于执行相应操作的程序代码或者代码段可以存储在诸如存储介质的计算机可读介质中,使得至少一个处理器或至少一个计算装置可通过读取并运行相应的程序代码或者代码段来执行相应的操作。
根据本公开示例性的实施例,存储装置可与计算装置集成为一体,例如,将RAM或闪存布置在集成电路微处理器等之内。此外,存储装置可包括独立的装置,诸如,外部盘驱动、存储阵列或任何数据库系统可使用的其他存储装置。存储装置和计算装置可在操作上进行耦合,或者可例如通过I/O端口、网络连接等互相通信,使得计算装置能够读取存储在存储装置中的指令。
根据本公开的基于兼容层的可执行文件加载方法、系统、电子设备及存储介质,在兼容层跨系统打开可执行文件创建对应的映射对象并初始化映射对象中的参数时,对将要加载的可执行文件的有效性通过预设标志进行识别,对于有效的可执行文件,通过在对应的共享文件中保存有效可执行文件中的所有属性段的数据的方式,可以实现在基于映射对象加载对应的可执行文件时,将共享文件中保存的有效可执行文件中所有属性段的数据都映射到进程空间中,使得可执行文件中所有属性段的数据通过兼容层在跨系统加载的情况下能够进程间共享,避免可执行文件通过兼容层跨系统加载时在进程间的重复拷贝导致的兼容层运行速度低下,并且可以减少跨系统应用的内存占用量。
另外,通过映射对象进行进程空间的映射时,通过预设标志识别出映射对象对应的可执行文件是无效的可执行文件后,直接结束加载,能够减少无效可执行文件的加载,进一步减少跨系统应用内存占用、提高运行速度。
另外,在映射时识别文件类型,可以通过公共的文件映射接口执行映射,并且不改变非可执行文件的映射逻辑。
另外,将Flat类型或非Flat类型的映像文件都采用文件头信息和存有属性段数据的共享文件分开映射的方式,可以保证Flat类型的可执行文件映射成功。
另外,将共享文件的映射类型设置为私有类型再进行映射可以确保共享文件中不被进程修改的数据可共享、需要修改的数据会被拷贝为进程私有数据以实现写时复制的目的。
以上描述了本公开的各示例性实施例,应理解,上述描述仅是示例性的,并非穷尽性的,本公开不限于所披露的各示例性实施例。在不偏离本公开的范围和精神的情况下,对于本技术领域的普通技术人员来说许多修改和变更都是显而易见的。因此,本公开的保护范围应该以权利要求的范围为准。

Claims (13)

1.一种基于兼容层的可执行文件加载方法,其特征在于,所述方法包括:
创建与所述可执行文件对应的映射对象;
在所述可执行文件为映像文件的情况下,初始化所述映射对象中的第一预设参数;其中,所述第一预设参数为image成员;
基于所述映射对象加载所述可执行文件;
其中,所述基于所述映射对象加载所述可执行文件,包括:
在所述可执行文件的文件头信息中不包含第一预设标志的情况下,根据所述可执行文件对应的共享文件中的共享对象初始化所述映射对象中的第二预设参数,并基于所述映射对象加载所述可执行文件;其中,所述共享文件中包括对应的所述可执行文件中所有属性段的数据,所述共享对象基于所述可执行文件中所有属性段的数据构建得到,所述第二预设参数为Shared成员。
2.如权利要求1所述的文件加载方法,其特征在于,所述基于所述映射对象加载所述可执行文件,还包括:
在所述可执行文件的文件头信息中包含所述第一预设标志的情况下,设置所述映射对象中所述第一预设参数中的第二预设标志,并基于所述映射对象加载所述可执行文件。
3.如权利要求1所述的文件加载方法,其特征在于,在所述可执行文件的文件头信息中不包含第一预设标志的情况下,所述方法还包括:
在全局共享对象列表中查找出与所述可执行文件对应的所述共享文件中的所述共享对象;
在所述查找失败的情况下,执行如下步骤:
基于所述可执行文件中所有属性段的数据映射到进程空间后所占的总字节数创建所述共享文件,将所述可执行文件中所有属性段的数据拷贝到所述共享文件中;
在所述共享文件中创建并初始化所述共享对象;
将创建的所述共享对象插入到所述全局共享对象列表中。
4.如权利要求1-3中任意一项所述的文件加载方法,其特征在于,所述可执行文件中所有属性段的数据,包括:所述可执行文件中的共享属性段及非共享属性段的数据。
5.如权利要求1所述的文件加载方法,其特征在于,所述基于所述映射对象加载所述可执行文件,还包括:
在所述映射对象中包含所述第一预设标志的情况下,结束所述文件加载方法;
在所述映射对象中不包含所述第一预设标志的情况下,执行如下步骤:
在所述映射对象对应的所述可执行文件为映像文件的情况下,将所述映射对象对应的所述可执行文件的文件头信息和所述共享文件分开映射到进程空间;
在所述映射对象对应的所述可执行文件不为映像文件的情况下,将所述可执行文件整体映射到进程空间。
6.如权利要求5所述的文件加载方法,其特征在于,所述映射对象对应的所述可执行文件为映像文件的情况,包括:
所述映射对象对应的所述可执行文件为Flat类型或非Flat类型的可执行文件。
7.如权利要求5所述的文件加载方法,其特征在于,所述将所述映射对象对应的所述可执行文件的文件头信息和所述共享文件分开映射到进程空间,包括:
结合文件映射接口的文件后端机制将所述映射对象对应的所述可执行文件的文件头信息和所述共享文件分开映射到进程空间。
8.如权利要求5所述的文件加载方法,其特征在于,所述方法还包括:
将所述共享文件的映射类型设置为私有类型。
9.如权利要求1所述的文件加载方法,其特征在于,所述方法还包括:
在所述可执行文件不为映像文件的情况下,初始化所述映射对象中的第三预设参数后结束对所述映射对象的参数初始化。
10.如权利要求1所述的文件加载方法,其特征在于,所述第一预设标志包括:fakedll。
11.一种基于兼容层的可执行文件加载系统,其特征在于,所述系统包括:
映射对象创建单元,被配置为:创建与所述可执行文件对应的映射对象;
初始化单元,被配置为:在所述可执行文件为映像文件的情况下,初始化所述映射对象中的第一预设参数;其中,所述第一预设参数为image成员;
加载单元,被配置为:基于所述映射对象加载所述可执行文件;
其中,所述加载单元被配置为:在所述可执行文件的文件头信息中不包含第一预设标志的情况下,根据所述可执行文件对应的共享文件中的共享对象初始化所述映射对象中的第二预设参数,并基于所述映射对象加载所述可执行文件;其中,所述共享文件中包括对应的所述可执行文件中所有属性段的数据,所述共享对象基于所述可执行文件中所有属性段的数据构建得到,所述第二预设参数为Shared成员。
12.一种电子设备,其特征在于,包括:
至少一个处理器;
至少一个存储计算机可执行指令的存储器,
其中,所述计算机可执行指令在被所述至少一个处理器运行时,促使所述至少一个处理器执行如权利要求1到10中的任一项权利要求所述的基于兼容层的可执行文件加载方法。
13.一种存储指令的计算机可读存储介质,其特征在于,当所述指令被至少一个处理器运行时,促使所述至少一个处理器执行如权利要求1到10中的任一项权利要求所述的基于兼容层的可执行文件加载方法。
CN202311278044.6A 2023-09-28 2023-09-28 基于兼容层的可执行文件加载方法及系统 Active CN117009308B (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN202311278044.6A CN117009308B (zh) 2023-09-28 2023-09-28 基于兼容层的可执行文件加载方法及系统

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN202311278044.6A CN117009308B (zh) 2023-09-28 2023-09-28 基于兼容层的可执行文件加载方法及系统

Publications (2)

Publication Number Publication Date
CN117009308A CN117009308A (zh) 2023-11-07
CN117009308B true CN117009308B (zh) 2023-12-22

Family

ID=88567573

Family Applications (1)

Application Number Title Priority Date Filing Date
CN202311278044.6A Active CN117009308B (zh) 2023-09-28 2023-09-28 基于兼容层的可执行文件加载方法及系统

Country Status (1)

Country Link
CN (1) CN117009308B (zh)

Citations (6)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US6052778A (en) * 1997-01-13 2000-04-18 International Business Machines Corporation Embedded system having dynamically linked dynamic loader and method for linking dynamic loader shared libraries and application programs
JP2005216282A (ja) * 2004-01-30 2005-08-11 Eitokui Sui Kagi Kofun Yugenkoshi オペレーションシステムのアプリケーションプログラム共有の構造と方法
CN1731347A (zh) * 2004-08-06 2006-02-08 梁肇新 基于Linux的Windows软件兼容层体系结构
CN112148411A (zh) * 2020-09-29 2020-12-29 深圳市哈哈丫丫互联网有限公司 一种平衡本地电脑和云服务器运算能力的创新云套件技术
CN115080114A (zh) * 2022-08-23 2022-09-20 中科方德软件有限公司 应用程序的移植处理方法、装置和介质
CN115374017A (zh) * 2022-10-26 2022-11-22 统信软件技术有限公司 一种仿真运行可执行文件时抓取现场的方法及计算设备

Family Cites Families (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US8522205B2 (en) * 2004-05-18 2013-08-27 Oracle International Corporation Packaging multiple groups of read-only files of an application's components into multiple shared libraries
US20230266984A1 (en) * 2022-02-23 2023-08-24 Red Hat, Inc. Container-based operating system translation

Patent Citations (6)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US6052778A (en) * 1997-01-13 2000-04-18 International Business Machines Corporation Embedded system having dynamically linked dynamic loader and method for linking dynamic loader shared libraries and application programs
JP2005216282A (ja) * 2004-01-30 2005-08-11 Eitokui Sui Kagi Kofun Yugenkoshi オペレーションシステムのアプリケーションプログラム共有の構造と方法
CN1731347A (zh) * 2004-08-06 2006-02-08 梁肇新 基于Linux的Windows软件兼容层体系结构
CN112148411A (zh) * 2020-09-29 2020-12-29 深圳市哈哈丫丫互联网有限公司 一种平衡本地电脑和云服务器运算能力的创新云套件技术
CN115080114A (zh) * 2022-08-23 2022-09-20 中科方德软件有限公司 应用程序的移植处理方法、装置和介质
CN115374017A (zh) * 2022-10-26 2022-11-22 统信软件技术有限公司 一种仿真运行可执行文件时抓取现场的方法及计算设备

Also Published As

Publication number Publication date
CN117009308A (zh) 2023-11-07

Similar Documents

Publication Publication Date Title
US8171278B2 (en) Booting a computer system from central storage
US10445122B2 (en) Effective and efficient virtual machine template management for cloud environments
US7934209B2 (en) Method for firmware variable storage with eager compression, fail-safe extraction and restart time compression scan
EP2843552B1 (en) Method and system for executing callback functions delivered via a communication between a user-space application and the operating system kernel
KR20140018316A (ko) 가상 디스크 스토리지 기술
US9792075B1 (en) Systems and methods for synthesizing virtual hard drives
US20190227995A1 (en) Layer-Based File Access Method and Apparatus of Virtualization Instance
TW201220049A (en) A string cache file for optimizing memory usage in a Java virtual machine
CN115390996B (zh) 虚拟机迁移方法和装置、计算设备和存储介质
US20180144062A1 (en) Computer device and method for facilitating user to manage containers
US10185573B2 (en) Caching based operating system installation
CN112306581A (zh) 一种基板管理控制器管理bios配置的方法及介质
US11182346B2 (en) File sharing among virtual containers with fast recovery and self-consistency
CN114830085A (zh) 用于文件系统虚拟化环境中的操作系统引导的分层复合引导设备和文件系统
WO2017045272A1 (zh) 虚拟机迁移方法和装置
US11861349B2 (en) Modular firmware updates in an information handling system
US20240004832A1 (en) System and method for providing a container environment in a single file
CN117009308B (zh) 基于兼容层的可执行文件加载方法及系统
US8566512B2 (en) Automatic alignment of write requests in virtualization systems
CN110327626B (zh) 虚拟服务器创建方法及装置
US8769182B1 (en) Virtual tape library with the ability to perform multiple, simultaneous reads of a single virtual tape
TWI733157B (zh) 一種加快嵌入式系統啟動速度的方法及其嵌入式系統
CN117369905B (zh) 闪存平台的开机方法、系统、电子设备及存储介质
US20220391353A1 (en) Deduplicating data integrity checks across systems
WO2024041351A1 (en) Disabling processor facility on new processor generation without breaking binary compatibility

Legal Events

Date Code Title Description
PB01 Publication
PB01 Publication
SE01 Entry into force of request for substantive examination
SE01 Entry into force of request for substantive examination
GR01 Patent grant
GR01 Patent grant