背景技术
为运行在特定计算平台上设计的应用程序并不工作在不同的计算平台上。一般而言,软件不能避免地连到特定的计算平台,它被设计以工作在该平台上。例如,为了在运行Unix操作系统的小型计算机内工作而编写和编译的软件不会在使用私有操作系统的手提电脑内起作用。
计算平台一般包括操作系统(OS)和计算硬件结构。操作系统的例子包括以下
操作系统:
计算硬件结构的例子包括与以下
微处理器相关的硬件结构:80286、
和Itanium
TM。
计算平台的例子包括16位平台(比如
和
32位平台(比如
和
以及64位平台(比如
和例如
64位版本)。计算平台也称为平台、计算环境或环境。
设计了特定的应用程序版本以工作在特定的平台下。当这些应用程序在它们特定的平台执行时,它们可以被称为“本地的”。例如,
2000是为工作在32位平台上而设计的应用程序。换言之,
2000是与其32位平台有关的本地应用程序。然而,当这些32位的应用程序在不同平台下执行时,比如64位平台,它们可以被称为“非本地的”。
程序模块目标平台(或简称为“目标平台”)的例子是可执行程序(如程序模块、应用程序、程序)在其上运行的平台。对于程序模块而言,其目标平台也是其本地平台。例如,如果构造
应用程序运行在
32位X86操作系统环境下,则对于该映射目标平台会是32位的x86。
应用程序是这里作为术语使用的“程序模块”的主要例子。然而,术语“程序模块”包括可能不被标记为应用程序的其它可执行软件。
典型的计算机结构
典型的计算机结构是多层的。从底层往上依次包括硬件层、操作系统(OS)层以及应用层。或者,这些层可以被描述为硬件层、内核模式层以及用户模式层。
图1说明了典型计算机结构100的各层。层的顶部是用户模式110。它包括应用程序,比如应用程序112a-e。这些应用程序与一组API 120通信。一般而言,该组API被视为操作系统的一部分,并因此是计算平台的一部分。
该结构的下一层是内核模式130。这一般可以被称为操作系统的“内核”。由于它是操作系统的一部分,因此它是计算平台的一部分。
操作系统的内核是操作系统的特许部分——操作系统最可信的部分。它是内部代码层。它一般运行I/O 132、安全性134、显示控制(即对屏幕的存取)136、内存管理138以及其它特许功能139。内核通过设备驱动器142及其他硬件接口144对硬件层150内的硬件具有唯一存取。
内核API 140是内核中的那些API,它们任意存取内核功能。应用程序一般不直接调用内核,而是调用API 120,而API又可以调用内核(特别是内核API 140)。
尽管图1未示出内核130的组件132-144之间有连接,然而这些组件可以根据需要而连接。为了简洁从图中省略了耦合线。
在内核模式130下是硬件层150。该层包括实际计算机的所有硬件。包括处理器、内存、磁盘I/O、其它I/O等等。平台也包括硬件层。
因此,计算平台包括硬件层、内核层,还一般包括用户模式API 120。
互用性和兼容性
由于计算平台不断发展,应用程序兼容性一直是主要问题。人们希望在理想中在他们所选的平台下运行他们期望的应用程序。然而在现实中,难以使一应用程序在与它被设计所用的平台不同的主机平台上运行。例如,32位的x86应用程序不能在64位的Itanium(IA64)环境中运行。当人们购买了更强大的机器其中的平台与他们以前使用的不同时,这个问题更加恶化。旧平台的所有应用程序立即变得无用。
各平台具有其相应的本地应用程序主体,它们被设计成在该平台下运行。当公布了新一代平台时,软件开发商一般会升级他们的产品使其运行在新一代平台下。软件开发商这样做有许多原因,包括市场、技术和经济原因。
为了类似的原因,操作系统开发商希望他们的产品向后兼容。这样,较旧代的应用程序可以运行在最新一代的操作系统(因此是最新一代的平台)上。换言之,如果非本地应用程序可以运行在本地平台下(包括新的操作系统),则因为用户不必一定要丢弃他们目前的应用程序而购买新版本,这就鼓励了用户购买新的操作系统。这还给软件开发商以时间来开发对其应用程序的升级。
这里,兼容性的例子是一非本地程序模块,该模块运行正常并且与本地计算环境(如操作系统)内的本地程序模块和平共处。
如这里所使用的,互用性的例子是本地和非本地程序模块都能共享资源(比如存取彼此内存空间或共享内存空间内的数据)以及/或者一起协同工作。
为了简洁,这里使用一示例来说明非本地应用程序的不兼容性以及本地和非本地应用程序间的非互用性的问题。在该例中,非本地程序模块被称为32位应用程序,因为它们被设计成工作在32位平台上。在该例中,本地应用程序被称为64位应用程序,因为它们被设计成工作在本地平台上,本地平台是64位的。提供的只是一个例子而不是限制性的。本领域的普通技术人员可以理解,存在本地和非本地应用程序与本地平台的其它组合。
在本地平台上运行非本地应用程序
设想:在本地平台上运行非本地应用程序。更具体地说,设想这个例子:在64位环境中运行32位的应用程序。对于该例,假定该64位平台是对现有的通用32位平台(其上设计运行32位的应用程序)的升级。
在计算机结构中,数字位的平台(如32位平台)一般是指平台可寻址内存的字长。一般而言,一个字是一个内存到处理器寄存器的单次操作内被移动的数据单位。在过去几十年的最熟悉的结构中,一个字曾经是长度为四字节,即32位。标准PC内使用的IBM的大型处理器和Intel的处理器都使用了32位的字。Intel及其他公司最近的处理器规定了64位的字。
64位平台相对于32位平台的一个优点是可以寻址大得多的内存空间。首先,这是因为内存的地址在64位平台内可以是64位长,而在32位平台内一般是32位长的地址。
数据对齐
对齐是把数据在使平台更有效存取的地址处输入到计算机内存中。一般而言,这是通过把数据保存在内存的字边界而完成的。这点完成的代价是当被保存的数据长度小于一个字时浪费了一些内存。然而,对齐的好处是速度。对保存在内存中的数据进行对齐加快了这种数据的内存存取,因为最有效地使用了计算机平台。
例如,现代RISC平台以多字节的大块从内存读取,一般是4或8字节长,这些大块必须在大块大小的倍数的地址处开始。对未对齐地址的内存存取由多个对齐的存取来仿真,并且慢得多,或者会产生总线差错并中断程序。其它平台可以更得体地处理未对齐的(即字节对齐的)内存存取,但这使性能降级。
本领域的普通技术人员熟悉数据对齐以及这样做的成本和好处。
由本地和非本地共享的内存
互用性和兼容性的一个问题是对非本地(如32位)应用程序和本地(如64位)应用程序间共享的内存进行管理。另一问题是对非本地(如32位)应用程序和本地(如64位)操作系统间共享的内存进行管理。
当本地和非本地间的内存地址对齐不相同时尤其如此。例如,在32位环境中,所有数据以四(4)字节递增在内存中对齐,而所有数据以八(8)字节递增对齐。在这种情况下,非本地应用程序的数据可能以本地环境的不对齐方式被保存。
图2说明了这一点。内存块210代表基于32位字寻址方案的内存结构。实心垂线表示字边界。在两个字长内存单元212和214中保存了64位的数据,标为“A1”到“A8”,而在单个字长内存单元216中保存了32位的数据,标为“B1”到“A4”。
图2中,内存块230和250表示基于64位字寻址方案的内存结构。同样,实心垂线表示字边界。
当块210的A1-A8数据和B1-B4数据被转换以用于64位内存寻址方案时,可以以内存块230描述的方式来保存和寻址。更具体地说,该方式是不对齐的。然而,以对齐方式把相同的数据保存在内存块250中。
因此,当面临是否对齐数据的决定时,一个选项是忽略该问题并允许硬件来补偿它。如上所述并且由图2的内存块230所述,通过对来自不止一个连续内存地址单元的重复数据进行寻址,硬件可以进行补偿。该方法的代价是从内存存取数据所需的额外时间。只有当(多存取的)损失时间是可容忍的时该方法才是可行的。
如果为了补偿内存中的数据不对齐而浪费的时间变得不可容忍那将怎么办?
另一问题是是否总是有必要强制对齐。有时对齐自然地发生。
具体实施方式
在下列描述中,为了说明,给出了特定的数字、材料和配置以便提供对本发明的彻底理解。然而,对于本领域技术人员显而易见的是,本发明可以无须特定的示例性细节而实现。在其它情况下,省略或简化了公知的特征以简化本发明示例性实施的描述,从而更好地说明了本发明。而且,为了理解容易,把特定的方法步骤描述为分开的步骤;然而,这些分开描述的步骤不必要一定为该顺序,这取决于它们的性能。
下列描述提出了在本地和非本地共享数据结构间进行数据对齐的一个或多个示例性实现。发明人把这些示例性实现作为示例。发明人不认为这些示例性实现会限制本发明的范围。而认为本发明可以以结合其它现有或将来技术以其它方式体现和实现。
本地和非本地共享数据结构间数据对齐的实施例示例可以被称为“示例性的数据整直器”。
结合引用
以下美国专利申请通过引用被结合于此:美国专利申请序列号09/847,535,题为“Kernel Emulator for Non-Native Program Modules”,于2001年5月1日提交。
简介
这里所述的示例性数据整直器的一个或多个示例性实现可以由本地/非本地格式转换系统400和/或由像图6所示的计算环境来(全部或部分)实现。
这里所述的示例性数据整直器提供了一种机制,其非本地应用程序可以透明且有效地运行在本地平台上。例如,通过使用示例性内核仿真器,32位应用程序可以运行在64位平台上。更具体地说,这里所述的示例性数据整直器提供了一种机制,用于根据需要对不同平台(如本地和非本地)的应用程序和/或操作系统所共享的数据结构进行对齐。
内核仿真综述
这里所述的示例性数据整直器可以作为(例如)内核仿真的一部分来实现,比如在以下申请中描述的:美国专利申请序列号09/847,535,题为“Kernel Emulatorfor Non-Native Program Modules”,于2001年5月1日提交(该申请通过引用被结合于此)。
在这种内核仿真中,非本地应用程序表现为运行在带有其非本地内核的操作系统(OS)上。它们的非本地内核被仿真。非本地内核仿真器截断由非本地应用程序作出的内核调用,并把它们转化成本地内核调用。
适当计算机结构的例子
图3说明了适用于实现示例性数据整直器的计算机结构300的例子。本领域的普通技术人员可以理解可适用于实施的其它可能的计算机结构。
该结构包括一本地平台,该平台包括硬件350、内核模式330以及用户模式310的一组本地API 320。结构300的顶部是用户模式310。它包括应用程序。更具体地说,它包括本地应用程序(比如应用程序312a-c)和非本地应用程序(比如应用程序314a和314b)。
本地应用程序与一组本地API 320通信。一般而言,该组API 320被视为本地操作系统的一部分,因此是本地计算平台的一部分。非本地应用程序与一组非本地API 322通信。一般而言,该组非本地API 320被视为非本地操作系统的一部分,因此不是本地计算平台的一部分。
结构300的下一层是本地内核模式330。这一般被称为本地操作系统的本地“内核”。由于它是本地操作系统的一部分,因此它是本地计算平台的一部分。
这个本地内核330包括本地内核API 340和各种内核功能333,比如I/O、安全性、显示控制(即对屏幕的存取)、内存管理及其他特许功能。本地内核330通过设备驱动器342及其他硬件接口344对硬件层350内的硬件具有唯一存取。本地内核API 340是在内核中的那些裁决对内核功能的存储的API。
在内核模式330下是硬件层350。该层包括实际计算机的所有硬件。包括处理器、内存、磁盘I/O、其它I/O等等。本地平台也包括硬件层。
因此,本地计算平台包括硬件层350、内核层350,还一般包括用户模式本地API 320。本地平台不包括非本地API 322或非本地内核仿真器400。
内核仿真器的例子
图4说明了非本地内核仿真器400,它是可采用示例性数据整直器的实施例的示例性内核仿真器的实现。它包括非本地内核API的仿真器410,也称为非本地CPU模拟器(或简称为“CPU”模拟器)。为了避免与术语混淆,这将称为CPU模拟器410。
CPU模拟器410包括:变换器412,用于把非本地指令组变换成本地CPU指令组;转换器414,用于把非本地字长转换成本地字长;以及内存约束器416,用于把非本地应用程序可存取的内存限制为这些应用程序能寻址的内存。
非本地应用程序对内核的调用
CPU模拟器410从非本地应用程序接收内核调用。更具体地说,CPU模拟器410从非本地API接收内核调用。
内核仿真器400不执行内核的功能,而是把非本地调用从其非本地格式变换为本地格式。然后把经变换的调用传递到本地内核给本地内核处理,就好像该调用来自本地应用程序。然而,为了做到这一点会不仅仅包括语言的简单变换。它会包括非本地和本地平台间范例的转换。
变换器412执行指令仿真。它处理非本地处理器的指令组的仿真。
转换器414管理自变量格式和字长。它把自变量格式从非本地变为本地,把字长从非本地变为本地。
变换器412和转换器414一起管理32位平台的自变量通过堆栈惯例到64位平台的自变量通过寄存器惯例。这是自变量值怎样传递的范例变化示例。CPU模拟器410用变换器412对CPU指令组的变换说明了该变化。
在另一例中,在32位平台中,字长为32位长。因此,地址和数据一般以32位长的字被写入内存中。在64位平台中,字长为64位长。因此,地址和数据一般以64位长的字被写入内存中。
参数(即自变量)一般长度为一个字。因此,64位内核API的参数长度为64位;而不是对于32位内核API的32位长。
转换器把非本地应用程序(和API)所传递的32位自变量从32位展宽到64位。怎样做到这一点的一例是通过用32个前导零填充自变量。在示例性实现中,转换器414主要工作在用户层内。
如上所述,不同的平台一般会有不同的字长。因而,可寻址的内存空间大小也不同。因此,转换器414把地址(尤其是指针)作为其字转换的一部分来转换。
例如,32位平台的内存地址可以高达32位长;因此,最大可寻址的内存约为4GB(如果保留一位,则最大值约为2GB)。64位平台的内存地址可以高达64位长;因此,最大可寻址的内存以兆兆字节来度量。因此,32位和64位平台间的可寻址内存大小是不同的。
本地和非本地间共享的数据结构
互用性和兼容性的一个问题是管理非本地(如32位)应用程序和本地(如64位)应用程序或本地(如64位)操作系统间共享的内存。特别是,当在非本地应用程序和本地应用程序或本地操作系统间(保存在内存中的)共享数据结构时是有问题的。
对齐
数据对齐是共享数据结构成问题的一种方式。当把共享数据结构的数据从非本地格式转换成本地格式时,期望重新定义字边界而不是复制和移动内存中的数据。这种数据的复制和移动耗费宝贵的时间和资源。
有时,本地和非本地间的字长差异是另一方的倍数。例如,64位字平台是32位字平台的倍数。因而,当重新定义字边界时,这种边界会自发地落在已经是这种倍数的数据间(如64位长的数据)。
考虑内存块210和250以及其中包含的数据,读者可以看到一种情况,它被视为这种自发字边界重定义的例子。换言之,如果块210(包括数据结构212和214以及数据A1-A8)的字边界被重新映射,它们可能作为内存块250的数据结构252。该数据结构252包括对齐的数据262。在该情况中,内存边界自发地降低,使数据对齐。
不对齐
相反,当字边界被重新定义时,这种边界可以自发地落在数据内——因而使数据不对齐。考虑内存块210和230以及其中包含的数据,读者可以看见一种情况,它被视为其中数据不对齐的这种自发字边界重定义的例子。换言之,如果块210(包括数据结构212和214以及数据A1-A8)的字边界被重新映射,它们可能作为内存块230的块232和234。块232和234包括不对齐的数据242。在该情况中,内存边界自发地降低,使数据不对齐。
对齐动机
因此,当面临是否对齐数据的决定时,一个选项是忽略该问题并允许硬件来补偿它。在某些情况下,硬件可以通过对来自不止一个连续内存地址单元的重复数据进行存取而进行补偿。该方法的代价是从内存存取数据所需的额外时间。该方法仅当(多次存取的)损失时间是可容忍的时候才是可行的。
可容忍的不对齐代价一例是
处理器的不对齐代价。存取对齐数据的代价是一个时间单位(比如一个周期),而存取不对齐数据的代价大约为三个时间单位。因而,
平台设计的软件的编程者不考虑数据的不对齐,因为性能影响一般是可容忍的。
然而,存在对于存取对齐数据最佳的平台。因此,进程在试图存取不对齐数据时会显著地停转。这看来像是系统崩溃。在这种情况下,不对齐的代价是不可容忍的。
不对齐代价的另一例是
处理器的不对齐代价。存取对齐数据的代价是一个时间单位(比如一个周期),而存取不对齐数据的代价大约为一万(10000)或更多。因而,如果
平台设计的软件的编程者不考虑数据的不对齐,这会产生完全不可容忍的性能影响。
在至少一方面,示例性数据整直器对本地和非本地应用程序和/或操作系统共享的内存中保存的数据进行强制对齐。
数据对齐子系统
如图4所示,非本地内核仿真器400包括数据对齐子系统460,该子系统460协调本地和非本地应用程序(或非本地应用程序和本地操作系统之间)之间的数据对齐。在示例性实现中,数据对齐子系统460可以是示例性数据整直器的实施例。
如上所述,转换器414根据需要重新调整数据结构的大小,从而从非本地格式转换成本地格式(反之亦然)。例如,块210的块216包括数据B1-B4。转换器可以扩大为块250的块254以包括数据264。
尽管转换器414可以成功地重新调整数据大小,然而这种数据不会被对齐。一些数据结构(如LARGE INTEGER)可以被正确地调整大小(如64位)用于本地环境,但可能不会正确地对齐用于本地环境。图2的内存块210和230中示出这样一例。强制对齐的一个选项是把数据结构复制到新位置并使其对齐。由于复制比不复制采用多得多的时间,并且由于可以正确地对齐数据结构,因此希望有一种方式来确定数据结构在复制前是否被对齐。
数据对齐子系统460检查数据结构的特定预先标识的类型,以确定它是否被对齐。
如果它不对齐,则数据对齐子系统460把数据结构复制到对齐的内存块,并且把本地环境指向该副本。在调用了可能作用于共享数据结构的功能之后,块中的数据被复制回原始不对齐的空间。
然而,如果数据结构对齐,则把本地环境指向该原始空间。
根据数据对齐子系统460,数据结构类型被正确地调整大小(用于本地环境),但已经确定它可能是不对齐的。这种数据结构的一例是LARGE INTEGER。
示例性数据整直器的方法实现
图5A示出内核仿真器400(或其某部分)所执行的示例性数据整直器的方法实现。该方法实现可以用软件、硬件或它们的组合来执行。
在图5的510处,数据对齐子系统460观察特殊预先标识的数据结构类型,其中包括可能不对齐的参数。在512处,子系统检查参数以确定这些参数是否是对齐的。如果是,则进程继续到方块530并且不执行对齐。如果它是不对齐的,则进程继续到方块514。
在图5的514处,数据对齐子系统460重新分配一缓存以保留该参数。在516处,子系统把参数(可能是整个数据结构)复制到对齐的内存块。在518处,把本地环境指向所分配缓存中的副本。在调用了可能采用共享数据结构(因此采用参数)的功能后,块中的数据被复制回原始不对齐的空间(在520处)。进程在522结束。
然而,如果数据结构的参数是对齐的,则把本地环境指向原始空间(如方块530中所指示)。
附加细节
通常,内核仿真器(或等价物)是一中间层,它协调执行进程,而同时非本地应用程序(如32位应用程序)需要向本地操作系统索求一些支持,像对磁盘上的文件信息、安全性信息、事件通知等的存取。该中间层能够监视在非本地应用程序(如32位应用程序)和本地操作系统(如64位操作系统)间来回传递的任何信息。
处理回调勾连问题:
有时,非本地应用程序可能安装一操作系统到应用程序的回调(通常称为“勾连”),这可能影响总系统的稳定性。勾连会是非本地程序模块中的一些指令。那些非本地指令可能会有不可应用于本地代码(如函数指针)的一些不同的信息结构。虽然从本地执行路径调用了它们,然而本地模块并不知道它正在作出到非本地勾连的回调。
为了解决非本地勾连调用中的数据对齐问题,为勾连标记一属性来标识该勾连是为一类特定的非本地应用程序而设置的。该属性稍后会用于确定哪条执行路径可以执行该勾连(即会根据所设的属性对勾连链进行过滤)。这样,不兼容的执行路径就不能通过特定的勾连。
有时所仿真的指令可能调用内核中的本地代码。虽然作出那些调用,然而所仿真的指令还填充某些回调结构,其包含返回到何处的信息。那些结构在本地环境和所仿真的环境间共享,并且可能存取不对齐的数据。在形式转换程序层中,数据对齐子系统460可以在作出任何内核调用前修补该结构。
共享数据结构:
可能有在本地操作系统和运行的仿真应用程序之间共享的信息。本地操作系统会要求这种信息为特定格式。例如,共享信息会包含某些函数指针,它们在操作系统作用于其上之前为8字节对齐的。然而,运行的应用程序并不关心这一点,因为4字节对齐对于非本地应用程序(如32位应用程序)就足够了。在这种情况下,数据对齐子系统460会标识这种结构,并且当API来回传递共享信息时自动为那些信息产生形式转换程序。
对齐问题:
需要对齐的数据类型的例子有:LARGE INTEGER、具有64位整数作为一个成员的共用型以及用户模式和操作系统共享的可共享的64位指针。如果这种数据未正确对齐,则由于性能恶化,操作系统就不能接受它们。它会选择不再运行。或者,在更坏的情况下,操作系统会崩溃。
在内核仿真器内,数据对齐子系统460监视可能属于那些数据类型或者可能是结构中一员的任何参数。如果数据对齐子系统460找到这种类型,它就检验该对齐。如果它不对齐,数据对齐子系统460就重新分配缓存(即所分配的缓存)以保留该参数,并且用该缓存作出OS API调用而不是传递为作出该调用而传递的原始缓存。当OS API成功地返回时,数据对齐子系统460把所分配缓存的输出复制到应用程序缓存。
在上面的情况下,参数修补也许不起作用,其中应用程序把一些参数作为指针传递至缓存,操作系统会把这些参数解释为结构的指针。在该情况下,内核仿真器尤其需要知道哪个API传递该类数据。在某些情况下,操作系统会根据API内传递的某些其它参数把该缓存解释为对某些结构的指针。数据对齐子系统460可以根据某些规则而产生某些中间指令,这些规则可用于任何API或者需要内核仿真器内的对齐修补的特殊API。
LARGE INTEGER个体数据的规则
这是说明怎样使数据类型重新对齐的LARGE INTEGER例子。从该模板中产生的指令位于本地部分,而这个模板会应用于传递LARGE-INTEGER的所有API。非本地代码可能传递4字节对齐的LARGE-INTEGER。在本地部分中,数据对齐子系统460保留该数据类型的一个副本,并在作出本地调用时传递该数据类型。在离开的路上,数据对齐子系统460把结果复制回客户机空间。
TemplateName=LARGE_INTEGER
Locals=
//@ArgNIame(@ArgType)is an LARGE_INTEGER*(might be unaligned)@NL
LARGE_INTEGER@ArgVal_Copy;@NL
End=
PreCall=
//FIXUP_LARGE_INTEGER @NL
if((SIZE_T)@Arg HostName&0x07){
@ArgName=&@ArgVal_Copy;
@ArgVal_Copy=*(UNALIGNED LARGE_INTEGER*)@ArgHostName;
}else@ArgName=@ArgHostName;
End=
PostCall=
if(@ArgName!=@ArgHostName)
*(UNALIGNED LARGE_INTEGER*)@ArgHostName=
@ArgVal_Copy;
End=
某些其它类型的规则:
可以为某些特殊的场景优化数据的不对齐副本。例如,非本地应用程序(如32位应用程序)可能为像LARGE-INTEGER这样的某些大数据保证有4字节对齐的数据。虽然在需要8字节对齐单元的本地操作系统(如64位OS)上进行仿真,而不是产生可能需要8个指令来执行的整个不对齐副本,数据对齐子系统460可以用两个指令来完成它,这两个指令如下并且用于下列模板中:
*(LONG*)((PBYTE)@ArgValCopy)=*(LONG*)((PBYTE)@ArgHostName);@NL
*(LONG*)(4+(PBYTE)@ArgValCopy)=*(LONG*)(4+(PBYTE)@ArgHostName);
@NL
MacroName=PointerIN
NumArgs=0
Begin=
@IfPointerToPtrDep(
@IflsArray(
//Note:@ArgName(@ArgType)is an array of pointers to pointer dependent
types.@NL
#error Error:don′t know how to thunk an array of pointers to ptr dep.@NL
)
@IfNotlsArray(
//Note:@ArgName(@ArgType)is a pointer to a pointer dependent type.
@NL
if(THE KERNEL EMULATOR_ISPTR(@ArgHostName)){
@NL
@Indent(
@IfInt64DepUnion(
//Special Case union having LARGE_INTEGER member @N L
@ArgName=(@ArgType)@ArgValCopy;@NL
*(LONG*)((PBYTE)@ArgValCopy)=*(LONG
*)((PBYTE)@ArgHostName);@NL
*(LONG*)(4+(PBYTE)@ArgValCopy)=*(LONG
*)(4+(PBYTE)@ArgHostName);@NL
)
@IfNotInt64DepUnion(
@ArgName=(@ArgType)@ArgValCopy; @NL
*((@ArgType)@ArgValCopy)=(@ArgTypeInd)*((@ArgHostTypeInd
*)@ArgHostName);@NL
)
)
} @NL
e1se{ @NL
@Indent(
@ArgName=(@ArgType)@ArgHostName; @NL
)
} @NL
)
)
API的规则:
在该例中,API可能具有到另一参数所定义的不同结构的指针。这种扩展能够根据定义类型的其它参数来对那些结构进行形式转换。
TemplateName=ApiNamePassingBadBuffer
Case=(ParamThatDetermineType,THE_REAL_TYPE1)
Case=(ParamThatDetermineType,THE_REAL_TYPE2)
Case=(ParamThatDetermineType,THE_REAL_TYPEn)
Locals=
BOOL bRealigned=FALSE;
PVOID*pTempFileInfo;
End=
PreCall=
if((SIZE_T)(FileInformation)&(0x07)){
//allocate a buffer with correct alignment,to pass to the Win64 API
pTempFileInfo=FileInformation;
FileInformation=The kernel emulatorAllocateTemp(Length);
RtlCopyMemory(FileInformation,pTempFileInfo,Length);
bRealigned=TRUE;
}
End=
Begin=
@GenDebugNonPtrDepCases(@ApiName,FileInformationClass)
End=
PostCall=
if(NT_SUCCESS(RetVal)&&bRealigned){
RtlCopyMemory((PVOID)pTempFileInfo,FileInformation,Length);
}
End=
成员复制的规则:
在复制一些结构时,数据对齐子系统460添加了不对齐的标记,使得编译器会产生正确的代码,并且在执行期间不引起任何对齐错误。
MacroName=StdH2NCopy
NumArgs=0
Begin=
@ArgName=@IfNotlsBitfield(@UnalignedTag64)(@ArgType)(@ArgHostName);
@NL
End=
示例件的计算系统和环境
图6说明了适当计算环境900的例子,其中可以(或完全或部分地)实现这里所述的示例性数据整直器。计算环境900可以用于这里所述的计算机和网络结构。
示例性计算环境900仅仅是计算环境的一个例子,而不意图对计算机和网络结构的使用范围和功能作出任何限制。计算环境900也不应被理解为具有与示例性计算环境900中所述的任一组件或组件的组合有关的任何相关性或要求。
示例性数据整直器可以用多种其它通用或专用计算系统环境或配置来实现。可能适合使用的公知计算系统、环境和/或配置的示例包括、但不限于:个人计算机、服务器计算机、薄客户机、厚客户机、手提或便携式设备、多处理器系统、基于微处理器的系统、机顶盒、可编程用户电子设备、网络PC、小型计算机、大型计算机、包括任一上述系统的分布式计算环境等等。
示例性数据整直器可以用计算机可执行指令的一般上下文来描述,譬如由计算机执行的程序模块。一般而言,程序模块包括例程、程序、对象、组件、数据结构等,它们执行特定任务或实现特定的抽象数据类型。示例性数据整直器还可以实际用于分布式计算环境中,其中由通过通信网络连接的远程处理设备来执行任务。在分布式计算环境中,程序模块可以位于本地和远程存储媒质中,包括内存存储设备。
计算环境900包括形式为计算机902的通用计算设备。计算机902的组件可能包括、但不限于:一个或多个处理器或处理单元904、系统内存906以及把包括处理器904在内的各种系统组件耦合至系统内存906的系统总线908。
系统总线908表示多种类型总线结构的任一种或多种,包括内存总线或内存控制器、外围设备总线加速的图像端口以及使用任一多种总线结构的处理器或和本地总线。例如,这种结构可以包括工业标准结构(ISA)总线、微通道结构(MCA)总线、增强型ISA(EISA)总线、视频电子标准联盟(VESA)局域总线以及外围组件互连(PCI)总线(也称为Mezzanine总线)。
计算机902一般包括各种计算机可读媒质。这些媒质可以是能由计算机902访问的任何可用媒质并包括易失性和非易失性的媒质、可移动和不可移动的媒质。
系统内存906包括:形式为易失性内存的计算机可读媒质,譬如随机存取内存(RAM)910,以及/或者包括非易失性内存,比如只读内存(ROM)912。基本输入/输出系统(BIOS)914一般被保存在ROM 912中,它包含例如启动期间帮助在计算机902内的组件间传输信息的基本例程。RAM 910一般包含数据和/或程序模块,它们可以被立即访问并且/或者当前由处理单元904在其上操作。
计算机902还包括其它可移动和不可移动、易失性和非易失性的媒质。例如,图6说明了对不可移动、非易失性磁性媒质(未示出)进行读写的硬盘驱动器916、对可移动、非易失性磁盘920(如“软盘”)进行读写的磁盘驱动器918以及对可移动、非易失性光盘924进行读写的光盘驱动器922,譬如CD-RROM、DVD-RROM或其它光学媒质。硬盘驱动器916、磁盘驱动器918和光盘驱动器922各自通过一个或多个数据媒质接口926与系统总线908相连。或者,硬盘驱动器916、磁盘驱动器918和光盘驱动器922可以通过一个或多个接口(未示出)与系统总线908相连。
驱动器和它们的相关计算机可读媒质为计算机902提供了计算机可读指令、数据结构、程序模块和其它数据提供存储。尽管该例说明了硬盘916、可移动磁盘920以及可移动光盘924,然而可以理解,为了实现示例性的计算系统和环境,也可以使用其它类型的计算机可读媒质,它们可保存由计算机存取的数据,这些媒质有:磁带盒或其它磁性存储设备、闪存卡、CD-ROM、数字化视频光盘(DVD)或其它光学存储器、随机存取内存(RAM)、只读内存(ROM)、电可擦除可编程只读内存(EEPROM)等等。
硬盘916、磁盘920、光盘924、ROM 912和/或RAM 910上可以存储任何数量的程序模块,包括例如:操作系统926、一个或多个应用程序928、其它程序模块930和程序数据932。这种操作系统926、一个或多个应用程序928、其它程序模块930和程序数据932中的每一个(或者某些的组合)都可以包括以下的实施例:拦截器、调用转换器、自变量转换器、变换器、共享内存管理器、指令变换器、地址变换器、数据整直器以及目标平台确定器。
用户可以通过诸如键盘934和指示设备936(如“鼠标”)这样的输入设备把命令和信息输入到计算机920中。其它输入设备938(未具体示出)可以包括麦克风、游戏杆、游戏板、卫星式转盘、扫描仪等等。这些和其它输入设备通过与系统总线908耦合的输入/输出接口940与处理单元904相连,但也可能用其它接口和总线结构连接,譬如并行端口、游戏端口或通用串行总线(USB)。
监视器942或其它类型的显示设备也通过诸如视频接口944这样的接口与系统总线908相连。除了监视器942之外,其它输出外部设备可以包括如扬声器(未示出)和打印机946这样的组件,它们可以通过输入/输出接口940连接到计算机902。
计算机902可以工作在网络化环境中,该环境使用与诸如远程计算设备948这样的一台或多台远程计算机之间的逻辑连接。远程计算机948可以是个人计算机、便携式计算机、服务器、路由器、网络PC、对等设备或其它公共网络节点等等。作为便携式计算机说明的远程计算设备948可以包括上述关于计算机902描述的许多或全部元件。
计算机902和远程计算机948之间的逻辑连接被描述为局域网(LAN)950和一般广域网(WAN)952。这种网络环境在办公室、企业范围计算机网络、企业内部网和互联网中是常见的。
当在LAN网络环境中实现时,计算机902通过网络接口或适配器954与局域网950相连。当在WAN网络环境中实现时,计算机902一般包括用于在广域网952上建立通信的调制解调器956或其它装置。调制解调器956可以在计算机902内部或外部,它可以通过输入/输出接口940或其它适当机制与系统总线908相连。应该理解,所述的网络连接是示例性的,可以采用用于在计算机902和948之间建立通信连接的其它装置。
在网络化环境中,比如关于计算环境900所述的网络环境,关于计算机902所述的程序模块或其部分可以被保存在远程内存存储设备中。例如,远程应用程序958指令组远程计算机948的内存设备上。为了说明,这里把应用程序和像操作系统这样的其它可执行程序描述为离散的块,然而可以认识到,这种程序和组件在不同时刻驻留在计算设备902的不同存储组件中,并且由计算机的数据处理器所执行。
计算机可执行指令
示例性数据整直器的实现可以以计算机可执行指令环境来描述,比如由一台或多台计算机或其它设备执行的程序模块。一般而言,程序模块包括执行特定任务或实现特定抽象数据类型的例程、程序、对象、组件、数据结构等等。一般而言,根据各个实施例中的期望,程序模块的功能可以组合或分布。
示例性操作环境
图6说明了其中可实现示例性数据整直器的适当操作环境900的示例。特别是,这里所述的示例性数据整直器可以用图6中的任何程序模块928-930和/或操作系统926或者其中的部分来(全部或部分地)实现。
操作环境仅仅是适当操作系统的一个例子,并非对这里所述示例性数据整直器的使用范围或功能有任何限制。其它适合使用的公知计算系统、环境和/或配置的示例包括、但不限于:个人计算机(PC)、服务器计算机、手提或便携式设备、多处理器系统、基于微处理器的系统、可编程用户电子设备、无线电话和设备、通用和专用设备、专用集成电路(ASIC)、网络PC、小型计算机、大型计算机、包括任一上述系统的分布式计算环境等等。
计算机可读媒质
示例性数据整直器的实现可以被保存在某些形式的计算机可读媒质上,或者在其间被发送。计算机可读媒质可以是能由计算机存取的任何可用媒质。例如但非限制,计算机可读媒质可以包括“计算机存储媒质”和“通信媒质”。
“计算机存储媒质”包括易失性和非易失性、可移动和不可移动媒质,它们以用于存储诸如计算机可读指令、数据结构、程序模块或其它数据等信息的任意方法或技术来实现。计算机存储媒质包括、但不限于:RAM、ROM、EEPROM、闪存或其它存储技术、CDROM、数字化视频光盘(DVD)或其它光盘存储器、磁带盒、磁带、磁盘存储器或其它磁性存储设备、或者用于存储期望信息并能由计算机存取的任意其它媒质。
“通信媒质”一般在诸如载波或其它传输机制等已调数据信号中包含计算机可读指令、数据结构、程序模块或其它数据。通信媒质还包括任何信息传送媒质。
术语“已调数据信号”意指其一个或多个特性以对信号内信息进行编码的方式被设置或改变的信号。例如但非限制,通信媒质包括诸如有线网络或直线连接这样的有线媒质,还包括诸如声、RF、红外及其它无线媒质这样的无线媒质。上述的任意组合也应被包括在计算机可读媒质的范围内。
结论
虽然以对于结构特征和/或方法步骤特定的语言描述了本发明,然而应该理解,所附权利要求中定义的发明不必限于所述的特定特征或步骤。而是把特定的特征或步骤公开作为用于实现本发明的优选形式。