Cross-architecture program simulation execution method and apparatus, and storage medium

CN122044757BActive Publication Date: 2026-08-21SHANGHAI LINGRUI INTELLIGENT CORE COMPUTING TECHNOLOGY CO LTD
View PDF 1 Cites 0 Cited by

Patent Information

Application Number
CN202610517286.3
Authority / Receiving Office
CN · China
Patent Type
Patents(China)
Current Assignee / Owner
Filing Date
2026-04-20
Publication Date
2026-08-21
Estimated Expiration
2046-04-20

AI Technical Summary

Technical Problem

然而,现有技术一方面主要依赖动态二进制翻译,虽然部分间接跳转目标地址需要在运行时确定,但程序中大量控制流跳转完全依赖动态翻译,造成额外的翻译计算开销

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN122044757B_ABST
    Figure CN122044757B_ABST
Patent Text Reader

Abstract

The application discloses a cross-architecture program simulation execution method and device and a storage medium. The method comprises the following steps: establishing a register resource mapping relationship between a target guest register resource and a host register resource; defining a calling rule corresponding to the register resource mapping relationship, the calling rule being used for transmitting target guest state information between simulation functions executed on the host; performing static translation on a target guest executable file based on the register resource mapping relationship and the calling rule, and generating a corresponding host executable file; loading the target guest executable file and the corresponding host executable file; and performing simulation execution on the target guest executable file based on the register resource mapping relationship and the calling rule in the process of simulating the host executable file. The application has the technical effect of improving the simulation execution efficiency of an instruction simulator.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] This disclosure relates to the field of cross-architecture program simulation technology, and in particular to a cross-architecture program simulation execution method, apparatus and storage medium. Background Technology

[0002] With the increasing demand for cross-processor architecture program execution, using open-source instruction simulators to simulate the execution of target guest programs on a host machine has become a common practice for software compatibility, system verification, and cross-platform operation. Existing instruction simulators typically employ dynamic binary translation to parse and translate target guest instructions in real time to achieve cross-architecture program simulation. However, existing technologies rely heavily on dynamic binary translation. While some indirect jump target addresses need to be determined at runtime, a large number of control flow jumps in the program depend entirely on dynamic translation, resulting in additional translation computational overhead. Furthermore, existing instruction simulators often use memory variables to simulate the target guest's register resources, requiring the host machine to frequently read and write register states during the execution of simulated instruction blocks, increasing additional memory access overhead. Moreover, when the host and target guest memory models are inconsistent, additional memory barrier instructions must be inserted to ensure data consistency, further reducing the efficiency of program simulation execution. Therefore, improving the efficiency of current instruction simulators in simulating cross-architecture programs is a crucial issue. Summary of the Invention

[0003] In view of this, embodiments of this disclosure provide a cross-architecture program simulation execution method, apparatus, and storage medium to improve the simulation execution efficiency of an instruction simulator. In a first aspect, a cross-architecture program simulation execution method is provided, applied to an instruction simulator simulating the execution of a target client executable file on a host machine, comprising: establishing a register resource mapping relationship between the target client register resources and the host machine register resources; defining calling rules corresponding to the register resource mapping relationship, the calling rules being used to pass target client state information between simulated functions executed on the host machine; performing static translation of the target client executable file based on the register resource mapping relationship and the calling rules to generate a corresponding host machine executable file; loading the target client executable file and its corresponding host machine executable file; and simulating the execution of the target client executable file based on the register resource mapping relationship and the calling rules during the simulation execution of the host machine executable file.

[0004] Optionally, a register resource mapping relationship is established between the target client register resources and the host register resources, including: mapping the target client's general-purpose registers to the host's general-purpose registers in a one-to-one and fixed-binding manner; fixing at least some internal state variables in the instruction simulator used to simulate the per-processor context state of the target client to the host register resources; mapping the target client's program counter to the host register resources, and having the host software logic maintain the program counter; and mapping some of the target client's vector registers to the host's vector registers. For the remaining unmapped vector registers, global memory variables are used for simulation. The same vector register mapping mode is used for the same host executable file.

[0005] Optionally, the calling rules are configured to include: each simulated function executed on the host machine to simulate the target guest instruction contains: all general-purpose registers of the target guest, internal state variables mapped to host machine register resources according to the register resource mapping relationship, the target guest program counter, and the mapped target guest vector register; auxiliary function parameters and the address of the next function to be executed are passed using host machine register resources not occupied by the register resource mapping relationship, and a fixed host machine register resource is reserved to store the environment pointer to the metadata area inside the instruction simulator used to simulate the processor context environment; and calls between any two functions defined by the calling rules corresponding to the register resource mapping relationship are performed through tail calls, including: calls between functions from the target guest executable file used for register simulation are performed through tail calls.

[0006] Optionally, when a simulated function executed based on the calling rules needs to call a runtime helper function executed according to the host calling convention, the following steps are taken: before the call, write the target client state information mapped to the host register resources according to the register resource mapping relationship back to the metadata area, and save the environment pointer to the current function stack; initialize the parameters of the runtime helper function according to the host calling convention; after the runtime helper function returns, reload the environment pointer using the value saved in the current function stack, and then reload the target client state information from the metadata area.

[0007] Optionally, based on register resource mapping relationships and calling rules, static translation is performed on the target guest executable file to generate the corresponding host executable file. This includes: preprocessing the auxiliary function source code of the instruction simulator to determine the inline auxiliary function template; obtaining the target guest executable file as mandatory input information and obtaining the indirect jump target addresses recorded during instruction simulation execution as optional input information; collecting a set of program jump target addresses based on the mandatory and optional input information; identifying whether a jump table is used for each indirect jump instruction and recording the corresponding jump table information; generating a translation block described by the simulator's intermediate language based on the set of program jump target addresses; generating a translation block function described by the host compiler's intermediate language for each translation block; generating corresponding inline auxiliary functions based on the inline auxiliary function template for translation blocks that call auxiliary functions; and generating the host executable file based on the host compiler, translation block functions, and inline auxiliary functions.

[0008] Optionally, the program jump target address set includes at least one of the following addresses: the starting address of the target guest executable file, the function address in the function symbol table, the target address of the direct jump instruction, the target address of the direct call instruction, the end address of the code section, and the recorded indirect jump target address.

[0009] Optionally, a translation block for the intermediate language description of the simulator is generated based on the set of program jump target addresses, including: using the set of program jump target addresses as the boundary information of the translation block, using all program jump target addresses as the end point of the old translation block and the start point of the new translation block, and using all jump instructions as the end point of the translation block; defining the starting address of the translation block as the valid entry point of the host executable file.

[0010] Optionally, the auxiliary function source code of the instruction simulator is preprocessed to determine the inline auxiliary function template, including: extracting the auxiliary function source code from the instruction simulator's source code tree and determining the target auxiliary function; rewriting the call process of the target auxiliary function and other functions called by the target auxiliary function into a call process that conforms to the calling rules; converting the operation of accessing register status values ​​based on environment pointers in the target auxiliary function into direct operation on host register resources; updating the return of the target auxiliary function and the call return related to the target auxiliary function to a call to a preset return handling function; determining the rewritten and updated auxiliary function code as the inline auxiliary function template; and generating a fallback process logic to the original auxiliary function at the instruction simulator runtime when the target auxiliary function calls a function outside the auxiliary function source code or accesses a variable defined by the instruction simulator runtime environment.

[0011] Optionally, it also includes: modifying the runtime environment of the instruction simulator, including: setting up a shadow stack, instruction mapping hash table, and instruction range red-black tree in the runtime environment; determining and recording the addresses of runtime helper functions in the current process during runtime environment initialization; configuring the runtime environment to load host executable files; after loading the target client executable file, loading the host executable file corresponding to the target client executable file, and writing the correspondence between the target client instruction address and the host instruction address into the instruction mapping hash table.

[0012] Optionally, the shadow stack is a data structure set parallel to the target guest program stack, and the storage space of the shadow stack or the pointer to the storage space of the shadow stack is located in the metadata area inside the instruction simulator used to simulate the processor context environment. When the target guest's call instruction is executed, the return address mapping pair is pushed onto the shadow stack. The return address mapping pair includes the return address of the target guest instruction and the host instruction address corresponding to the return address of the target guest instruction. When the target guest's return instruction is executed, the return address mapping pair is popped from the shadow stack, and the popped target guest instruction return address is compared with the return address corresponding to the current target guest return instruction. When the comparison result is consistent, the control flow is transferred to the popped host instruction address. When the comparison result is inconsistent, the instruction mapping hash table is queried.

[0013] Optionally, when the instruction simulator simulates the execution of indirect jump instructions identified as using jump tables, a shadow jump table corresponding to the target client jump table is set in the host executable file; a jump table helper function is called, and the jump table entry index, shadow jump table base address, and number of shadow jump table entries are input to the jump table helper function; when the corresponding jump table entry is accessed for the first time, the correspondence between the target client instruction address and the host instruction address is queried through the instruction mapping hash table, and the queried target client instruction address and host instruction address are written into the corresponding entries of the shadow jump table; when the corresponding jump table entry is accessed subsequently, the target client instruction address to be jumped to is compared with the target client instruction address recorded in the corresponding entry of the shadow jump table, and the jump is executed using the host instruction address recorded in the shadow jump table when the comparison result is consistent.

[0014] Optionally, when the instruction simulator processes the indirect jump target address, if the corresponding host instruction address is not determined through the shadow stack or shadow jump table, the instruction mapping hash table is queried; if the corresponding host instruction address is not found in the instruction mapping hash table, the instruction range red-black tree is queried to determine the target client executable file that covers the indirect jump target address, and the corresponding host executable file is loaded; if the corresponding host instruction address is still not determined, the runtime dynamic binary translation is called to continue the simulation execution.

[0015] Secondly, a cross-architecture program simulation execution device is provided, applied to an instruction simulator on a host machine to simulate the execution of a target client executable file. The device includes: a mapping unit for establishing a register resource mapping relationship between the target client register resources and the host machine register resources; a rule unit for defining calling rules corresponding to the register resource mapping relationship, the calling rules being used to pass target client state information between simulated functions executed on the host machine; a generation unit for statically translating the target client executable file based on the register resource mapping relationship and the calling rules to generate a corresponding host machine executable file; a loading unit for loading the target client executable file and its corresponding host machine executable file; and an execution unit for simulating the execution of the target client executable file based on the register resource mapping relationship and the calling rules during the simulated execution of the host machine executable file.

[0016] Thirdly, a computer-readable storage medium is provided on which instructions are stored, which, when read by a processor, implement the cross-architecture program simulation execution method provided in the first aspect above. Attached Figure Description

[0017] The accompanying drawings used in the description of the embodiments of this disclosure are briefly introduced below: Figure 1 The diagram illustrates a flowchart of a cross-architecture program simulation execution method provided in some embodiments of this application; Figure 2 This illustration shows a flowchart of a method for generating a corresponding host executable file according to some embodiments of this application; Figure 3 This application provides a flowchart illustrating a method for determining an inline auxiliary function template in some embodiments. Figure 4 A schematic diagram of the structure of a cross-architecture program simulation execution device provided in some embodiments of this application is shown. Detailed Implementation

[0018] To more clearly illustrate the technical solutions in the embodiments of this disclosure, examples of implementation methods of this disclosure will be described below with reference to the accompanying drawings. The accompanying drawings described below are merely some embodiments of this disclosure. For those skilled in the art, other drawings and other implementation methods can be obtained based on these drawings without creative effort. Adjustments and improvements made without departing from the concept of this disclosure are all within the protection scope of this disclosure.

[0019] To keep the drawings simple, each figure only schematically shows the parts relevant to the embodiment, and they do not represent the actual structure of the product. In addition, for the sake of clarity and ease of understanding, some figures only schematically show parts of components with the same structure or function, and there may actually be more or fewer components with the same structure or function.

[0020] In this disclosure, unless otherwise expressly specified and limited, ordinal numbers, such as “first”, “second”, etc., are used only to distinguish and describe related objects, and should not be construed as indicating or implying the relative importance or order between related objects; furthermore, they do not represent the quantity of related objects. “Multiple” includes two or more, and other quantifiers are similar. “ / ” is used to describe the relationship between related objects, indicating an “or” relationship between them. “And / or” is used to describe the relationship between related objects, including any combination relationship between them, such as “a and / or b” including: “a alone”, “b alone”, or “a and b”. “One or more” or “at least one” of multiple objects refers to any object or any combination of multiple objects, such as “one or more of a1, a2, a3” or “at least one of a1, a2, a3” including: “a1 alone”, “a2 alone”, “a3 alone”, “a1 and a2”, “a1 and a3”, “a2 and a3”, or “a1, a2 and a3”.

[0021] In cross-architecture program simulation execution scenarios, three types of objects are typically involved: the host machine, the target client machine, and the instruction simulator. The host machine is the processing platform that actually provides computing resources and runs the simulation environment; the target client machine is the original processing platform to which the target program belongs, and its program files, instruction set, register states, and runtime semantics are all based on the target client machine's architecture definition; the instruction simulator is the software system running on the host machine, used to load, parse, translate, and simulate the execution of the target client program. Therefore, the target client program does not run directly on the target client machine hardware, but rather the instruction simulator on the host machine translates the target client machine's instructions into an instruction form that the host machine can execute, thus enabling the host machine to simulate the execution process of the target client program. In existing cross-architecture program simulation execution technologies, open-source instruction simulators typically translate the target client machine's instructions to enable the target client program to run on heterogeneous hardware platforms. One common open-source instruction simulator for the entire system employs a dynamic binary translation mechanism. For example, during the first run of the program, the target client instructions are translated into an intermediate language in basic blocks, and then the intermediate language is translated into instruction blocks that the host machine can directly execute. After a host instruction block finishes execution, the simulator continues to determine whether the next target client instruction has been translated, and chooses to jump directly or start a new translation process based on the result. While the above-mentioned existing technologies can achieve cross-architecture program simulation execution, they have the following shortcomings in practical applications. First, existing solutions rely primarily on dynamic binary translation to complete instruction conversion during program execution, meaning that the translation mainly occurs at runtime. In reality, some control flows in the program, especially a large number of direct jumps and direct call relationships, can often be statically determined by pre-analyzing the entire ELF file. Therefore, if this part still relies entirely on runtime translation, it will waste computational resources and increase overall execution latency. Second, existing instruction simulators typically use global variables located in memory to simulate the register resources of the target client. When the host executes the simulated instruction block, instructions involving register read access need to fetch the corresponding register state from memory, and instructions involving register write access need to write the updated register state back to memory. Compared to the target client directly using physical registers on its local hardware, this additional memory access significantly reduces execution efficiency. Third, when the host and target client use different memory models, especially when simulating a strong memory model with a weak memory model, existing technologies usually require inserting additional memory barrier instructions after simulating memory write access instructions to ensure data consistency in multi-threaded programs. These additional instructions also further slow down program execution.For the reasons mentioned above, existing cross-architecture simulation execution solutions often suffer from high translation overhead, high register state maintenance costs, and high memory consistency guarantee costs when dealing with large-scale target programs or complex control flows. This results in overall simulation execution speeds failing to meet the demands of higher-performance scenarios. Especially when most execution paths of the target program can be determined in advance through static analysis, existing solutions fail to fully utilize this feature, still primarily relying on runtime dynamic translation and memory variables to maintain register states, thus limiting the potential for improving simulator execution efficiency.

[0022] In view of this, this application provides a method, apparatus, and storage medium for simulating cross-architecture program execution. By defining the mapping relationship between the target client's register resources and the host's register resources, and in conjunction with corresponding function call rules, the executable file of the target client is statically translated into the executable file of the host, thereby reducing the burden of dynamic translation. Furthermore, shadow stacks, instruction mapping hash tables, and instruction range red-black trees can be set in the runtime environment to support the loading of the host executable file and the rapid location of the control flow, thereby improving the simulation execution speed of cross-processor architecture programs by the open-source instruction simulator.

[0023] The following description is in conjunction with the accompanying drawings: Please refer to Figure 1 This document illustrates a flowchart of a cross-architecture program simulation execution method provided in some embodiments of this application. This cross-architecture program simulation execution method is applied to an instruction simulator simulating the execution of a target client executable file on a host machine, and includes at least the following steps: S110: Establish the register resource mapping relationship between the target client register resources and the host register resources; S120: Defines the calling rules corresponding to the register resource mapping relationship. The calling rules are used to pass target client state information between simulated functions executed on the host machine. S130: Based on register resource mapping relationships and calling rules, statically translate the target guest executable file to generate the corresponding host executable file; S140: Load the target client executable file and its corresponding host executable file; S150: During the process of simulating the execution of the host machine executable file, the target client executable file is simulated and executed based on the register resource mapping relationship and calling rules.

[0024] The above cross-architecture program simulation execution method can be executed by an instruction simulator running on the host machine to simulate the execution of the target client executable file (Executable and Linkable Format, ELF). This method mainly revolves around register state carrying, state transfer between simulated functions, static translation of the target program, and execution on the host side, enabling the target client program to achieve cross-architecture simulation execution on the host machine. Before simulation execution begins, a register resource mapping relationship can be established between the target client's register resources and the host machine's register resources to determine how the register states involved in the execution of the target client program are expressed and carried on the host machine side. After this mapping is completed, the register semantics in the target client program have a clear corresponding basis on the host machine side, and subsequent state transfer and code translation can be carried out based on this basis. Therefore, even when there are differences between the target client architecture and the host machine architecture, the execution state of the target client program can still be consistently represented on the host machine side. Based on this approach, the target client's register state can be carried at least partially by the host machine's register resources, thus providing a stable state carrying foundation for the simulated functions executed subsequently on the host machine.

[0025] After establishing the register resource mapping relationship, calling rules adapted to this mapping relationship can be further defined. Since the target client program completes semantic simulation on the host machine through a series of simulated functions, the calling rules ensure the continuous transmission of target client state information between multiple simulated functions. When a simulated function completes its processing, its corresponding target client state information can be passed to the next simulated function in a unified manner, thus maintaining contextual continuity throughout the simulation execution process. With the help of these calling rules, although multiple simulated functions execute sequentially on the host machine side, they can still collectively describe the execution process of the same target client program. After preparing the register resource mapping relationship and calling rules, static translation can be performed on the target client executable file to generate the corresponding host machine executable file. The static translation stage can combine the instruction simulator's ability to parse target client instructions with the code generation capabilities of a traditional compiler to convert the target client program into a file format executable by the host machine. In this process, the register resource mapping relationship is used to determine the expression of the target client state on the host machine side, and the calling rules are used to determine the connection method between simulated functions on the host machine side. Based on this, the target client executable file can be translated into a host executable file in advance, thus providing a code foundation for subsequent simulated execution on the host side.

[0026] After obtaining the host executable file, the target client executable file and the corresponding host executable file can be loaded into the instruction simulator's runtime environment. The target client executable file preserves the target program's content and execution semantics under the original architecture, while the host executable file serves as the execution carrier on the host side for subsequent execution. With both types of files entering the runtime environment, the host side obtains the actual execution entry point and maintains the correspondence with the target client program's semantics, ensuring that subsequent execution processes on the host continue to correspond to the original execution semantics of the target client program.

[0027] Subsequently, during the execution of the host executable, the target client's register state is carried on the host side through the previously established register resource mapping relationship. The target client's state information is passed between multiple simulated functions according to the previously defined calling rules. As the host executable is executed step by step, the execution state of the target client program is also progressively advanced on the host side, thus completing the simulated execution of the target client executable. In some scenarios, when the host hardware supports the target client memory model, the host executable can also be executed directly, further improving the overall simulation speed. It should be noted that although the host side actually executes the host executable obtained after static translation, the state maintenance and state transfer during this execution process always rely on the aforementioned register resource mapping relationship and calling rules. Therefore, the execution process of the host executable can correspondingly achieve semantic simulation of the target client executable.

[0028] The cross-architecture program simulation execution method provided in this application establishes a register resource mapping relationship between the target client's register resources and the host's register resources, and defines the calling rules corresponding to this register resource mapping relationship. This enables the target client's state information to be uniformly carried and continuously transmitted on the host side. Simultaneously, by statically translating the target client's executable file to generate a corresponding host executable file, the instruction simulator no longer needs to rely solely on dynamic binary translation to complete cross-architecture program simulation during runtime. This reduces the additional computational overhead of runtime translation and lowers the additional access burden caused by traditionally maintaining register states with memory variables, thereby effectively improving the instruction simulator's efficiency in simulating cross-architecture programs.

[0029] In some embodiments of this application, step S110 establishes a register resource mapping relationship between the target client register resources and the host register resources, including: mapping the target client's general-purpose registers to the host's general-purpose registers in a one-to-one and fixed-binding manner; fixing at least some internal state variables in the instruction simulator used to simulate the per-processor context state of the target client to the host register resources; mapping the target client's program counter to the host register resources, and having the host software logic maintain the program counter; and mapping some of the target client's vector registers to the host's vector registers. For the remaining unmapped vector registers, global memory variables are used for simulation. The same vector register mapping mode is used for the same host executable file.

[0030] The register resource mapping relationship can be further refined into mapping settings for the target client's general-purpose registers, simulator internal state variables, target client's program counter, and target client's partial vector registers. In this way, key state information involved in the execution of the target client program can form a unified expression basis on the host side, facilitating subsequent reading, passing, and updating of relevant states by simulated functions on the host. For cross-architecture program simulation execution, this register resource mapping relationship not only provides a foundation for carrying register states but also supports the establishment of subsequent calling rules and the determination of state organization methods during static translation.

[0031] For example, let's take a target client architecture of x86-64, a host architecture of RISCv64, and a host vector register length of 128 bits as an example to illustrate the register resource mapping relationship. For the target client's general-purpose registers, a one-to-one and fixed binding method can be used to map them to the host's general-purpose registers. For example, the general-purpose registers RAX, RCX, RDX, and RBX in the target client's x86-64 architecture can be mapped to the general-purpose registers X16, X17, X18, and X19 in the host's RISCv64 architecture, respectively. Through this fixed binding relationship, the general-purpose register states involved in the target client program can obtain a clear and stable carrying location on the host side.

[0032] In addition to the target guest's general-purpose registers, at least some of the internal state variables in the instruction simulator used to describe the per-processor context state of the target guest can also be mapped to host register resources. For example, the simulator's internal state variables cc_src, cc_dst, and cc_op can be mapped to general-purpose registers X15, X5, and X6 in the host RISCv64 architecture, respectively. In this way, the relevant internal state variables can also be expressed in conjunction with host register resources during simulation execution, which helps maintain the continuity of the target guest's context state on the host side. For the target guest's program counter, in this example, host register resources can also be used. For example, the general-purpose register X10 in the host RISCv64 architecture can be used to simulate the program counter in the target guest's x86-64 architecture, and the program counter can be maintained by host software logic. For the target guest's vector registers, a partial mapping approach can also be used, that is, mapping some of the target guest's vector registers to the host's vector registers, while the remaining unmapped vector registers continue to be simulated through global memory variables, and the same vector register mapping mode is used in the same host executable file. Continuing with the example above, the vector registers XMM0 to XMM14 and YMM0_H to YMM14_H in the target client's x86-64 architecture can be mapped to vector registers V0 to V29 in the host machine's RISCv64 architecture, respectively. The target client's vector registers XMM15 and YMM15_H are then simulated using global memory variables. This partial mapping method allows for the utilization of host machine vector register resources to carry part of the target client's vector state while balancing implementation complexity and resource usage requirements.

[0033] In some embodiments of this application, the calling rules are configured to include: each simulated function executed on the host machine for simulating target client instructions includes: all general-purpose registers of the target client, internal state variables mapped to host machine register resources according to register resource mapping relationships, the target client program counter, and the mapped target client vector register; auxiliary function parameters and the address of the next function to be executed are passed using host machine register resources not occupied by register resource mapping relationships, and a fixed host machine register resource is reserved to store an environment pointer pointing to the metadata area inside the instruction simulator used to simulate the processor context environment; and calls between any two functions defined by the calling rules corresponding to the register resource mapping relationships are performed through tail calls, including: calls between functions originating from the target client executable file for register simulation are performed through tail calls.

[0034] After the register resource mapping relationship is established, the calling rules can include the organization of simulated function parameters, the passing of auxiliary function parameters, the storage of environment pointers, and the connection between functions. In this way, the state information involved in the target client program running on the host machine can be passed between multiple simulated functions according to a unified rule, thereby ensuring the continuity of context during simulation execution. For cross-architecture program simulation execution, the calling rules work in conjunction with the previously established register resource mapping relationship. On the one hand, they determine which target client states need to be used as input / output content for the simulated functions; on the other hand, they determine how these states are connected and advanced between different simulated functions. Each simulated function executed on the host machine to simulate target client instructions can include all general-purpose registers of the target client, internal state variables already mapped to host machine register resources, the target client program counter, and the target client vector register that has been mapped. In this way, the main state information involved in the execution of the target client program can directly enter the processing scope of the simulated functions, enabling the simulated functions on the host side to complete semantic simulation around a unified set of states during execution. For multiple simulated functions executed sequentially, this state information can be continuously passed between functions as the basis for connection between them.

[0035] In addition to the aforementioned status parameters, host register resources not currently occupied by register resource mappings can be used to pass auxiliary function parameters and the address of the next function to be executed. Therefore, during the execution of the simulated function, if it is necessary to combine auxiliary functions to complete corresponding processing, or to determine the entry point of the subsequent function to be executed, the unoccupied host register resources can continue to carry relevant information, avoiding interference with the host register resources that have already carried the target client's state. Simultaneously, fixed host register resources can be reserved to store environment pointers pointing to the instruction simulator's internal metadata area. This metadata area can be used to describe the simulated processor's context environment; therefore, by permanently reserving environment pointers, it is convenient for the simulated function to continuously access environment information related to the current context during execution.

[0036] Functions derived from the target client executable and used for register emulation can be linked using tail calls. This means that once the current emulated function has finished processing the semantics of the current target client instruction, it can directly jump to the next emulated function without maintaining multiple layers of ordinary call return relationships between functions. This allows multiple emulated functions to form a continuous execution chain on the host side, thus helping to maintain the sequential transmission of the target client program's execution state on the host side. For cross-architecture emulation, tail calls further ensure that the linking between functions more closely resembles the sequential execution characteristics of the target client program.

[0037] Through the above calling rules, the key state information of the target client program can be uniformly transferred between multiple simulation functions on the host side. The auxiliary function parameters, subsequent function addresses, and environment information can also be organized in an orderly manner, which is conducive to maintaining context consistency and execution continuity in the cross-architecture program simulation execution process.

[0038] In some embodiments of this application, when a simulated function executed based on calling rules needs to call a runtime helper function executed according to the host calling convention, the following steps are taken: before the call, the target client state information mapped to the host register resources according to the register resource mapping relationship is written back to the metadata area, and the environment pointer is saved to the current function stack; the parameters of the runtime helper function are initialized according to the host calling convention; after the runtime helper function returns, the environment pointer is reloaded using the value saved in the current function stack, and then the target client state information is reloaded from the metadata area.

[0039] When the aforementioned calling rules have been established and used for state transfer between simulated functions on the host side, the simulated function may also need to call runtime helper functions executed according to the host calling convention during execution. In this case, to ensure that the target client's state information remains consistent before and after the call, the target client's state, already carried by the host register resources, can be organized and saved before entering the runtime helper function calling process. After the runtime helper function completes its processing, the relevant state is restored to the host register resources so that subsequent simulated functions can continue to advance the simulated execution of the target client program according to the calling rules.

[0040] Specifically, before calling the runtime helper function, the target client state information, which has already been mapped to the host register resources according to the register resource mapping relationship, can be written back to the metadata area. In this way, the target client state, originally stored in the host register resources, can be centrally saved before calling the runtime helper function, thus avoiding state loss due to changes in register usage when subsequently calling the host calling convention function. Simultaneously, the environment pointer can also be saved to the current function stack. This way, even if the runtime helper function subsequently overwrites the host register resource where the environment pointer resides, the current simulation function can still restore the corresponding environment information based on the value saved in the function stack after returning.

[0041] After completing the above preparations, since the runtime helper functions themselves follow the existing calling conventions on the host side, the parameters to be passed can be organized into a form that conforms to the host calling conventions before entering such functions, and then the corresponding helper function call can be executed. In this way, the runtime helper functions can complete the corresponding processing normally under the existing calling system on the host side, while not disrupting the previously established target client state carrying and passing mechanism.

[0042] After the runtime helper function returns, the environment pointer is first reloaded using the values ​​previously saved in the current function stack. Then, the target client state information is reloaded from the metadata area, restoring the previously written-back target client state to the host machine's register resources. After this reloading process, the critical state held by the simulation function before calling the runtime helper function can be restored on the host side, allowing subsequent simulation functions to continue simulating the execution process of the target client program according to the previously defined calling rules.

[0043] Through the above processing method, when a simulated function executed based on the calling rules needs to call a runtime helper function executed according to the host machine calling convention, the target client's state information can be saved before the call and restored after the call, and the environment pointer can also maintain continuity before and after the call. Therefore, although the runtime helper function executes according to the host machine calling convention, its intervention will not disrupt the previously established target client state transfer relationship, which is conducive to maintaining context consistency and execution continuity during cross-architecture program simulation execution.

[0044] Figure 2 The illustration shows a flowchart of a method for generating a corresponding host executable file according to some embodiments of this application. The method includes: S210: Preprocess the source code of the auxiliary functions of the instruction simulator to determine the inline auxiliary function template; S220: Obtain the target client executable file as required input information, and obtain the indirect jump target address recorded during instruction simulation execution as optional input information; S230: Based on the collection of required and optional input information, the program jumps to a set of target addresses; S240: For each indirect jump instruction, identify whether a jump table is used and record the corresponding jump table information; S250: Generates a translation block for the simulator's intermediate language description based on the set of program jump target addresses; S260: A function that generates a translation block description of the intermediate language of the host compiler for each translation block; S270: For translation blocks that call helper functions, generate corresponding inline helper functions based on inline helper function templates; S280: Generates a host executable file based on the host compiler, translation block functions, and inline auxiliary functions.

[0045] The static translation of the target client program involves more than just the sequential conversion of ordinary instructions; it also includes more complex processing logic, such as vector instructions, flag calculations, or other runtime-related operations. These typically require the use of helper functions. By pre-extracting and processing the source code of these helper functions, subsequent translation blocks can directly expand the corresponding logic using pre-prepared templates when generating host-side function representations. This lays the foundation for the generation of subsequent translation block functions and inline helper functions. Therefore, the helper function source code of the instruction simulator can be pre-processed to obtain reusable inline helper function templates.

[0046] After preparing the auxiliary function templates, the input information required for static translation can be further obtained. The target client executable file serves as the basic input information, providing the executable content of the program itself. Indirect jump target addresses recorded during instruction simulation execution serve as supplementary input information. After obtaining the above input information, a set of program jump target addresses can be collected around the program control flow, characterizing the locations in the target client program that may become control flow entry points, providing a boundary basis for subsequent translation block segmentation. These program jump target addresses can come from the target client executable file itself, such as the executable file's starting address, function addresses in the function symbol table, and the target addresses of direct jump instructions and direct call instructions, or from indirect jump target addresses recorded during execution. With this address information, subsequent code segmentation is no longer simply unfolded sequentially, but can be organized around the actual control flow structure of the target client program.

[0047] Furthermore, each indirect jump instruction in the target client program can be further analyzed to determine whether it uses a jump table, and the corresponding jump table information can be recorded. Not all indirect jumps have the same control flow characteristics; some indirect jumps actually rely on jump tables to complete branch location. Identifying these jump table-related indirect jumps in advance and saving the corresponding entry information is beneficial for generating more suitable jump processing logic on the host side later.

[0048] Once the control flow entry information and jump table information are available, the instruction flow in the target client executable file can be segmented and converted into translation blocks described by the emulator's intermediate language. The translation blocks in this application can be understood as processing units formed around the control flow boundaries. Their segmentation is not based on simple sequential positions, but rather on the boundary relationships determined by the program jump target address and jump instructions. In this way, the code flow of the target client program can be divided into multiple independently convertible and organized units. Simultaneously, the connection logic between each translation block can be established synchronously during the segmentation process, thus providing a clear control flow skeleton for subsequent host-side code generation.

[0049] After obtaining the translation blocks described in the simulator's intermediate language, each translation block can be further converted into translation block functions described in the host compiler's intermediate language. Through this conversion, the translation blocks, originally oriented towards the target client's semantics, gradually transform into function forms that the host compiler can understand and process. In this way, the host compiler can continue code generation and optimization around these translation block functions, enabling the target client program to obtain a functional expression suitable for execution on the host side. For translation blocks containing auxiliary function calls, the previously obtained inline auxiliary function templates can be further combined to generate corresponding inline auxiliary functions. Thus, the main semantics of the translation block itself and the additional semantics related to auxiliary processing can together form a complete code organization on the host side.

[0050] After the translation block functions and inline helper functions have been formed, host machine object files can be generated based on the host machine compiler. These object files are then further linked to obtain the final host machine executable file. The generated host machine executable file is the result of the combined effects of the aforementioned register resource mapping relationships, calling rules, control flow boundaries, helper function templates, and translation block functions. It is precisely because of this that subsequent execution of this host machine executable file on the host side can continuously correspond to the original execution semantics of the target client program.

[0051] Through the static translation process described above, the target client executable can be converted into the corresponding host executable before the actual simulation execution. The instruction simulator can then build upon the pre-generated host code during subsequent operation, without relying entirely on runtime dynamic binary translation to gradually generate all executable content. This reduces the computational overhead of runtime translation and provides a more direct code foundation for subsequent control flow localization and host-side execution, thereby improving the overall efficiency of cross-architecture program simulation execution.

[0052] In some embodiments of this application, generating a translation block for the intermediate language description of the simulator based on the set of program jump target addresses includes: using the set of program jump target addresses as the boundary information of the translation block, using all program jump target addresses as the end point of the old translation block and the start point of the new translation block, and using all jump instructions as the end point of the translation block; defining the starting address of the translation block as the valid entry point of the host executable file.

[0053] The set of program jump target addresses can serve as the basis for code segmentation and control flow organization. Since the target client program undergoes control flow transfers at function entry points, direct jump target addresses, direct call target addresses, and some indirect jump target addresses during execution, the target client instruction flow can be divided around these potential control flow entry points when generating translation blocks. This ensures that the code range corresponding to each translation block matches the actual control flow structure of the target client program, thus providing a foundation for subsequent host-side function representation. In the specific segmentation process, the set of program jump target addresses can be used as translation block boundary information. When an address in the target client instruction flow belongs to the set of program jump target addresses, that address can serve as both the end boundary of the previous translation block and the start boundary of the next translation block; for various jump instructions, including direct jumps, direct calls, indirect jumps, and return instructions, it can serve as the end boundary of the current translation block. Based on this boundary organization method, the control flow entry points and control flow transfer locations in the target client program can be clearly represented at the translation block level, facilitating the subsequent generation of corresponding intermediate language descriptions around each translation block.

[0054] After the translation blocks are generated, the starting address of each translation block can be further defined as the valid entry point of the host executable file. This way, when the host execution process needs to transfer control flow to a new code segment based on the target client program, the corresponding host entry point can be located around the determined starting addresses of these translation blocks. Therefore, the segmentation of translation blocks is not only used to organize the code structure during the static translation phase, but also establishes the entry point foundation for subsequent runtime control flow transfers.

[0055] Figure 3 A flowchart illustrating a method for determining an inline auxiliary function template according to some embodiments of this application is shown. The method includes: S310: Extract auxiliary function source code from the source code tree of the instruction simulator and determine the target auxiliary function; S320: Rewrite the call process of the target auxiliary function and other functions called by the target auxiliary function into a call process that conforms to the calling rules; S330: Converts the operation of accessing register status values ​​based on environment pointers in the target auxiliary function into a direct operation on the host register resources; S340: Update the return value of the target helper function and the call return value related to the target helper function to a call to the preset return handling function; S350: The rewritten and updated helper function code is identified as an inline helper function template; S360: When the target helper function calls a function outside the helper function's source code, or accesses a variable defined by the instruction simulator runtime environment, generate a fallback logic that returns to the original helper function at the instruction simulator runtime.

[0056] The preprocessing of auxiliary function source code can be understood as a preliminary preparation for the complex semantic processing capabilities required in the static translation stage. Since the target client program, when converted into executable code on the host machine, involves not only the sequential translation of general instructions but also complex operational processing logic, the auxiliary function source code upon which this complex processing logic depends can be organized into a template form that can be directly reused later, before formally organizing the translation block functions. Subsequently, when a translation block generates a function representation on the host machine side, if it contains auxiliary processing logic, it can be directly implemented by combining the prepared template.

[0057] First, we can extract the source code of auxiliary functions from the instruction simulator's source code tree and identify the target auxiliary function within this code. This target auxiliary function can be understood as the auxiliary function entity that needs to be focused on during subsequent static translation. Around this target auxiliary function, we need to pay attention not only to its own code logic but also to other functions involved in its call chain, as these functions collectively determine how the auxiliary processing logic is ultimately unfolded on the host side. After the target auxiliary function is determined, the call process of the target auxiliary function and its other called functions can be rewritten to conform to the previously established call rules. Since the entire cross-architecture simulation execution process is organized around register resource mapping relationships and call rules, the auxiliary function and its related call process also need to be included in the same call framework. Through this rewriting, when the auxiliary function is subsequently incorporated into translation block functions or generated as an inline auxiliary function, it can maintain a consistent state passing method with other simulated functions on the host side, ensuring the semantic continuity of the entire host-side function chain. In addition to the call process, the operations in the target auxiliary function that originally relied on environment pointers to access register state values ​​can also be further converted into direct operations on host register resources. After this processing, the register states, previously obtained indirectly through environment pointers, can now be directly expressed in conjunction with host machine register resources after preprocessing. This ensures that the execution method of the auxiliary function on the host side remains consistent with the state carrying method throughout the simulation execution process. Furthermore, the return of the target auxiliary function and the return of calls related to the target auxiliary function can also be updated to calls to preset return handling functions. Thus, after the auxiliary function and its call chain finish execution, the return path can be uniformly organized according to a pre-defined processing method, facilitating the smooth integration of the auxiliary function logic into the host machine-side function structure during subsequent static translation.

[0058] Furthermore, fallback logic can be established simultaneously during the auxiliary function preprocessing. When the target auxiliary function calls functions outside its source code or accesses variables defined by the instruction simulator runtime environment during processing, fallback logic can be generated to revert to the original auxiliary function at runtime. Therefore, while the auxiliary function templates in the host-side static translation process can cover most preprocessed logic scenarios, for situations exceeding the current preprocessing scope, a path back to the original runtime auxiliary function is still retained. This helps ensure the semantic integrity and execution stability of the auxiliary processing logic.

[0059] In some embodiments of this application, the method further includes: modifying the runtime environment of the instruction simulator, including: setting a shadow stack, an instruction mapping hash table, and an instruction range red-black tree in the runtime environment; determining and recording the addresses of runtime auxiliary functions in the current process during runtime environment initialization; configuring the runtime environment to load host executable files; after loading the target client executable file, loading the host executable file corresponding to the target client executable file, and writing the correspondence between the target client instruction address and the host instruction address into the instruction mapping hash table.

[0060] In some embodiments of this application, the shadow stack is a data structure set parallel to the target client program stack, and the storage space of the shadow stack or the pointer to the storage space of the shadow stack is located in the metadata area inside the instruction simulator used to simulate the processor context environment. When the target client's call instruction is executed, a return address mapping pair is pushed onto the shadow stack. The return address mapping pair includes the target client instruction return address and the host instruction address corresponding to the target client instruction return address. When the target client's return instruction is executed, the return address mapping pair is popped from the shadow stack, and the popped target client instruction return address is compared with the return address corresponding to the current target client return instruction. When the comparison result is consistent, the control flow is transferred to the popped host instruction address. When the comparison result is inconsistent, the instruction mapping hash table is queried.

[0061] The shadow stack stores the mapping between the target client's return address and the host's entry point address. This structure allows the runtime environment to avoid re-determining the return target through a generic lookup path each time it processes the call and return control flow, providing a more direct way to locate the return path. When the target client program executes a call instruction, it pushes the return address mapping pair onto the shadow stack. This return address mapping pair consists of two parts: the target client instruction return address that the target client program should return to after the call, according to the original execution semantics; and the corresponding host instruction address. Thus, the address mapping relationship required for the return path is simultaneously saved to the shadow stack when the call relationship is established. For the runtime environment, the shadow stack stores not just simple return addresses, but paired mapping information between the target client's return location and the host's execution entry point.

[0062] When the target client program executes a return instruction, it can pop the corresponding return address mapping pair from the shadow stack and compare the target client instruction return address stored therein with the return address corresponding to the current return instruction. If the comparison result matches, it means that the current return path matches the return path recorded when the call relationship was established. At this time, the control flow can be directly transferred to the popped host instruction address. In this way, the return control flow can preferentially complete the jump along the address mapping relationship already cached in the shadow stack, thereby reducing the overhead of looking up the address mapping relationship again. If it is found that the popped target client instruction return address does not match the return address corresponding to the current return instruction, it means that the current return path does not match the mapping relationship stored in the shadow stack. In this case, execution can not continue directly using the host instruction address in the shadow stack entry, but instead jump to the instruction mapping hash table to look up the path, and the hash table further determines the host instruction address corresponding to the current target client instruction address. Thus, the shadow stack is equivalent to a preferred fast return path in the runtime environment, while the instruction mapping hash table continues to serve as a supplementary processing mechanism in scenarios where the shadow stack misses or does not match.

[0063] In some embodiments of this application, when the instruction simulator simulates the execution of indirect jump instructions identified as using jump tables, a shadow jump table corresponding to the target client jump table is set in the host executable file; a jump table helper function is called, and the jump table entry index, shadow jump table base address, and number of shadow jump table entries are input to the jump table helper function; when the corresponding jump table entry is accessed for the first time, the correspondence between the target client instruction address and the host instruction address is queried through the instruction mapping hash table, and the queried target client instruction address and host instruction address are written into the corresponding entries of the shadow jump table; when the corresponding jump table entry is accessed subsequently, the target client instruction address to be jumped to is compared with the target client instruction address recorded in the corresponding entry of the shadow jump table, and the jump is performed using the host instruction address recorded in the shadow jump table when the comparison result is consistent.

[0064] In some embodiments of this application, when the instruction simulator processes the indirect jump target address, if the corresponding host instruction address is not determined through the shadow stack or shadow jump table, the instruction mapping hash table is queried; if the corresponding host instruction address is not found in the instruction mapping hash table, the instruction range red-black tree is queried to determine the target client executable file that covers the indirect jump target address, and the corresponding host executable file is loaded; if the corresponding host instruction address is still not determined, the runtime dynamic binary translation is called to continue the simulation execution.

[0065] Runtime processing of indirect jumps to target addresses can be divided into two cases: jump table-based indirect jump processing and general indirect jump processing. For indirect jump instructions identified as using jump tables, a shadow jump table corresponding to the target client's jump table can be set in the host executable file. At runtime, a jump table helper function is called, inputting the jump table entry index, the shadow jump table base address, and the number of shadow jump table entries. If the current index is out of range, the shadow jump table processing path is exited; if the current index is within range, the corresponding entry in the shadow jump table is accessed.

[0066] When a valid mapping relationship has not yet been established for the corresponding entries, the mapping hash table can be used to query the correspondence between the current target client instruction address and the host instruction address. If the query is successful, the target client instruction address and the host instruction address are written into the shadow jump table entry, and the jump is executed using the host instruction address. If the query fails, the general indirect jump target address processing procedure is entered. When a mapping relationship has been established for the corresponding entries, the target client instruction address to be jumped to can be compared with the target client instruction address recorded in the entry. If the comparison result matches, the jump is executed directly using the host instruction address recorded in the entry. If the comparison result does not match, the general indirect jump target address processing procedure is also entered.

[0067] For general indirect jump target address processing, the instruction mapping hash table can be queried first; if the corresponding host instruction address is not found in the instruction mapping hash table, the instruction range red-black tree is further queried to determine the target client executable file that covers the indirect jump target address, and the corresponding host executable file is loaded; if the corresponding host instruction address is still not determined, the runtime dynamic binary translation is called to continue the simulated execution.

[0068] In this way, the runtime environment can prioritize the use of shadow jump tables and instruction mapping hash tables to quickly determine the host instruction address corresponding to the indirect jump target address, and continue to use instruction range red-black trees and runtime dynamic binary translation to complete the processing when a miss occurs, thereby improving the runtime processing efficiency of indirect jump control flow.

[0069] In some embodiments, the processing object of the auxiliary function can be the source code after compiler preprocessing. Besides the compiler-preprocessed source code, it may also include the target auxiliary function name, and the normal return function name and abnormal return function name used as template parameters. In this process, the preprocessed source code can be analyzed using a parser to obtain basic location information related to subsequent template generation. This location information may include, for example: the function name, parameters, and function body corresponding to each function definition; the reference position of the environment pointer in each function body; the called function name and function parameters corresponding to the function call statements in each function body; and the position of the return statement in each function body. After obtaining this information, the parsing results can be further traversed to collect function definition information, function call information, function parameter type information, environment pointer-based access status information, and information related to whether the function return goes back to the target auxiliary function caller. Subsequently, all collected information is filtered according to the function call relationship, eliminating content that has no direct or indirect call relationship with the target auxiliary function, and the remaining functions are organized into a function list according to their order in the preprocessed source code.

[0070] After the function list is formed, background information related to the current template can be output first. For example, the text information in the preprocessed source code, excluding the function declarations and definitions corresponding to the function list, can be output to the result file. At this time, the template generation result not only retains the function content that needs to be processed later, but also retains the background information that together with these functions constitutes the source code context. When the function definition list is empty, it means that the function processing related to the target auxiliary function has been completed, and the result file can then be used as the template output for the target auxiliary function.

[0071] When there are still functions to be processed in the function definition list, the current function can be retrieved from the list, and processing can continue around that function. First, all call parameters involved in the current register resource mapping can be added to the current function's parameter list. These call parameters can include parameters corresponding to the target guest general-purpose registers, internal status variables, program counter, and vector registers, and these parameters are placed at the beginning of the current function's parameter list. Simultaneously, normal return functions and abnormal return functions can be added to the end of the parameter list. This ensures that the current function is formally compatible with the previously established calling rules, laying the foundation for organizing auxiliary function calls in a unified manner on the host side.

[0072] If the current function parameter contains a vector area pointer, then the vector area pointer can be further removed from the current function parameter list, and the macro definition with the same name as the pointer can be output to the result file, so that it can be further instantiated as a host vector register when the host side code is actually generated later.

[0073] If the current function directly or indirectly calls an undefined function, the parameter organization can be further adjusted for such cases. For example, for a function definition that is not the target auxiliary function itself, a TRIG_EXP_PTR pointer can be added as a parameter to pass the relevant flag information needed to trigger the exception path during subsequent calls. After completing the parameter organization, the function name and parameters corresponding to the current function definition can be output to the result file first, and then the function body itself can be updated.

[0074] During the function body update phase, several rewrites can be performed on the target helper function and its call chain. For target helper functions that directly or indirectly call undefined functions, a TRIG_EXP variable can be added to the function body header, and backups can be created for all state information accessed based on environment pointers. Then, the access method corresponding to the original ENV_VAR can be replaced with the state variable in the parameters, changing the access to state information within the function body from being based on environment pointers to directly revolving around the call parameters. Simultaneously, all function call parameters in the function body can be updated; any location involving TRIG_EXP_PTR can be changed to pass the address of TRIG_EXP as the parameter. For scenarios involving calls to undefined functions, the TRIG_EXP flag can be further set to determine whether an exception handling path is needed in the subsequent return path.

[0075] Inside the target helper function, if a function call's return might trigger the TRIG_EXP flag, the TRIG_EXP flag can be checked at that return point. If the flag is set, the previously saved ENV_VAR backup information can be used to restore the target client state information passed through the calling rules, and the exception return function template can be executed. For all call points that can return normally to the target helper function, the normal return function can be called uniformly. In this way, both the normal and exception return paths within the helper function can be organized in advance during the template stage, ensuring a relatively stable return processing logic when the inline helper function generated based on the template is executed on the host machine.

[0076] For functions in the function list whose parameter type is pointer, further expansion can be performed based on the actual situation at each call point. If the same function uses multiple different ENV_VAR addresses as parameters at different call points, the function can be copied and expanded into multiple versions according to the ENV_VAR information at different call points, and the function list can be updated accordingly. If the current function itself is based on a copy of a certain ENV_VAR variable, the corresponding variable and its access method can be further replaced with the target client state information corresponding to the ENV_VAR variable. After this processing, the differences formed by different environment variable addresses at different call points can also be expanded in the template stage, thereby reducing the additional dispatch burden in the subsequent host-side execution process.

[0077] Once the parameter organization, function body rewriting, return path updating, and necessary copy-and-expansion processing are all completed, the current function body can be output to the result file, and the next function to be retrieved from the function list can be processed in the same way. After all functions in the function list have been processed, the result file can be output as the inline helper function template corresponding to the target helper function.

[0078] Step S240 involves identifying which indirect jumps in the target client program belong to jump table-related jumps and extracting key information related to the jump table. Specifically, the target client instruction sequence can be used as input, and a current instruction can be set to traverse the entire instruction sequence sequentially. Simultaneously, an instruction readback stack can be maintained to store the most recently occurring instructions preceding the current instruction. Each current instruction is processed and pushed onto the top of the instruction readback stack. When the number of instructions in the stack exceeds a preset number N, the bottom instruction can be popped. In this way, a segment of local instruction context preceding the current indirect jump can be preserved, thus providing a basis for subsequent backtracking analysis of its address formation path.

[0079] When the current instruction encountered during iteration is not an indirect jump instruction, the next instruction can be set as the current instruction until the entire target client instruction sequence has been traversed. When the current instruction is an indirect jump instruction, the destination register of that indirect jump instruction can be recorded first and designated as JUMP_DEST. Next, the addition instruction with JUMP_DEST as its destination register can be searched from top to bottom in the instruction readback stack. The significance of this approach is that the target address of indirect jumps related to the jump table is usually not directly given, but calculated from a base address and an offset. Therefore, we can start by tracing back the address formation process of the addition operation that forms JUMP_DEST.

[0080] Once an addition instruction with JUMP_DEST as the destination register is found in the instruction readback stack, its first operand register can be recorded and designated as TABLE_BASE. Then, the search can continue downwards from the current addition instruction's position in the instruction readback stack to find a memory read instruction with TABLE_BASE as the base address and JUMP_DEST as the destination register. This process further confirms that JUMP_DEST is not simply obtained from ordinary arithmetic instructions, but is related to a memory read operation with TABLE_BASE as the base address, thus making the identification of the jump table entry address more targeted.

[0081] Once the aforementioned memory read instruction is found, its index register can be recorded and designated as INDEX. Subsequently, the search can continue downwards from the current memory read instruction's position on the instruction read stack, looking for a comparison instruction between INDEX and the immediate value. During the search, if a register copy instruction with INDEX as the destination register is encountered, INDEX can be updated to the source register of that register copy instruction, and the search for the corresponding comparison instruction can continue downwards. This process ensures that even if the index value undergoes one or more register passes before reaching the memory read instruction, the search can still continue along the register pass chain to the comparison position related to the index range determination.

[0082] Once the comparison instruction between INDEX and the immediate value is found, the immediate value in that instruction can be recorded and designated as RANGE. At this point, the key information of the jump table related to the current indirect jump can be extracted, including the jump table entry index INDEX, the jump table base address TABLE_BASE, and the jump table entry range RANGE. Based on these three types of information, the current indirect jump can be identified as an indirect jump using the jump table, and the corresponding jump table information can be recorded for subsequent generation of corresponding jump processing logic on the host side.

[0083] If no corresponding addition, memory read, or comparison instruction is found during any of the aforementioned backtracking phases, the current indirect jump is considered not to meet the jump table's relevant characteristics. In this case, the jump table information is not recorded, and the next instruction is set as the current instruction until the entire target client instruction sequence has been traversed. In this way, the static translation phase can filter and identify jump table-related indirect jumps while traversing the instruction sequence, thereby distinguishing between general indirect jumps and jump table-related indirect jumps.

[0084] In step S250, when generating the translation block of the simulator intermediate language description, the input may include the target client executable file and its corresponding set of program jump target addresses. Specifically, the region information list of code sections can be obtained from the section header table of the target client executable file, and the current instruction pointer can be set to the first instruction in the first code section. Subsequently, the target client program is traversed along the instruction sequence in the code sections. During the traversal, the current translation block can be maintained synchronously, and the current instruction can be converted into the simulator intermediate language description one by one and output to the current translation block. In this way, the formation process of the translation block is consistent with the traversal process of the target client code sections, thereby enabling the translation block to accurately reflect the local control flow structure of the target client program.

[0085] During the traversal, the set of program jump target addresses can be used as translation block boundary information. When the current instruction pointer belongs to the set of program jump target addresses, that address can be used as the translation block segmentation boundary. In other words, all program jump target addresses can serve as the end point of the old translation block and the start point of the new translation block. At the same time, various jump instructions themselves can also serve as the end point of the translation block. After this processing, the division of translation blocks no longer depends on simple sequential segmentation, but can be consistent with the function entry points, direct jump target addresses, direct call target addresses, and some indirect jump target addresses in the target client program, thereby making the control flow entry and exit points clearly expressed at the translation block level.

[0086] When the current instruction is not a control flow transfer instruction, the `translate_code` function of the instruction simulator can be called to parse the current instruction and output the parsing result to the current translation block. Then, the instruction pointer is updated to the next instruction in sequence, and the same processing continues for subsequent instructions. In this way, multiple instructions executed sequentially in the target client program can be merged into the same translation block, thereby improving the efficiency of subsequent translation and execution organization.

[0087] When encountering a direct jump instruction or a direct call instruction, the logic for updating the program counter can be output first in the current translation block, followed by the JMP_DIRECT logic, thus ending the current translation block. For call instructions, the address of the next instruction and the relocation symbol of the next instruction's entry function can be pushed onto the shadow stack using PUSH_RET_ADDR. This allows the sequential return relationships corresponding to the call path to be preserved in advance at the translation block level, providing a foundation for subsequent handling of the return control flow.

[0088] When encountering an indirect jump instruction or indirect call instruction, the logic for updating the program counter can be output first. Then, depending on whether the indirect jump uses a jump table, either `HELPER_JMP_IND` or `HELPER_JUMP_TABLE` can be output, and this serves as the end logic for the current translation block. In this way, ordinary indirect jumps and jump table-related indirect jumps can be distinguished at the translation block level, thus providing a foundation for subsequent runtime control flow location and jump table processing.

[0089] When a return instruction is encountered, the logic for updating the program counter can be output in the current translation block, and RET can be output as the end logic of the current translation block. In this way, the return path in the target client program is explicitly expressed at the translation block level, and the subsequent runtime environment can process the return control flow by combining the shadow stack and address mapping relationship.

[0090] After traversing a code section, the current instruction pointer can be updated to the first instruction of the next code section, and the same process can continue. Once all code sections have been traversed, the translation block generation process ends. After this process, the instruction flow in the target client executable can be organized into multiple translation blocks described by the emulator's intermediate language, and the direct jumps, indirect jumps, calls, and return relationships between these translation blocks are expressed at the translation block level. Simultaneously, the starting address of each translation block can be defined as a valid entry point for the host executable, thus establishing a clear entry point foundation for subsequent host-side control flow transfers.

[0091] In step S260, the previously obtained simulator intermediate language description translation blocks can be further converted into host compiler intermediate language description translation block functions. For example, in a translation block, the original logic may include: first loading a temporary variable Tmp0, then calling the helper function helper_pslldq_xmm, then writing Tmp0 to another storage location, updating the program counter, and then moving to the next translation block. For this type of case where the translation block contains helper function calls, the organization method of a single translation block function simply calling the helper function in the middle and then returning to continue execution can be abandoned. Instead, the translation block can be split into multiple new translation block functions based on the instructions before and after the aforementioned helper function call. Specifically, the logic before the helper function call can be organized into the first half of the translation block functions, the helper function itself can be organized into an independent function, and the logic after the helper function call can be organized into the second half of the translation block functions. After loading the temporary variable Tmp0, the first half of the translation block function can save Tmp0 to the shadow stack, then transfer to the helper function via a tail call, passing the subsequent second half of the translation block function as the next call entry point to the helper function. After completing its own logic processing, the helper function can directly transfer to the second half of the translation block function via a tail call instead of returning to the first half of the translation block function in a normal way. When the second half of the translation block function starts executing, it can first restore Tmp0 from the shadow stack, and then continue executing the processing logic of writing Tmp0 to another storage location, updating the program counter, and transferring to the next translation block. In this way, the helper function call, which was originally located in the middle of the translation block, is organized into a continuous tail call chain, and the temporary variables that still need to be used before and after the helper function call are saved and restored through the shadow stack. This maintains both the continuity of tail call connections between translation blocks and ensures the consistency of intermediate states before and after the helper function intervention.

[0092] Figure 4The diagram illustrates a cross-architecture program simulation execution device according to some embodiments of this application. This cross-architecture program simulation execution device 400 is used by an instruction simulator to simulate the execution of a target client executable file on a host machine. It includes: a mapping unit 410 for establishing a register resource mapping relationship between the target client register resources and the host machine register resources; a rule unit 420 for defining calling rules corresponding to the register resource mapping relationship, the calling rules being used to pass target client state information between simulated functions executed on the host machine; a generation unit 430 for statically translating the target client executable file based on the register resource mapping relationship and the calling rules to generate a corresponding host machine executable file; a loading unit 440 for loading the target client executable file and its corresponding host machine executable file; and an execution unit 450 for simulating the execution of the target client executable file based on the register resource mapping relationship and the calling rules during the simulated execution of the host machine executable file.

[0093] Based on the same technical concept, this application also provides a computer-readable storage medium having instructions stored thereon, which, when read by a processor, implement the cross-architecture program simulation execution method provided in the first aspect above.

[0094] In the above embodiments, the descriptions of each embodiment have their own emphasis. Parts not described in detail or in a particular embodiment can be referred to in the relevant descriptions of other embodiments. Furthermore, the above embodiments can be freely combined as needed.

Claims

1. A cross-architecture program simulation execution method, applied to an instruction simulator on a host machine to simulate the execution of executable files on a target client machine, characterized in that, include: Establish a register resource mapping relationship between the target client register resources and the host register resources; Define calling rules corresponding to the register resource mapping relationship, and the calling rules are used to pass target client state information between simulated functions executed on the host machine; The calling rules are configured to include: each simulation function executed on the host machine to simulate target client instructions includes: all general-purpose registers of the target client, internal state variables mapped to host machine register resources according to the register resource mapping relationship, the target client program counter, and the mapped target client vector register; auxiliary function parameters and the address of the next function to be executed are passed using host machine register resources not occupied by the register resource mapping relationship, and fixed host machine register resources are reserved to store environment pointers pointing to the metadata area inside the instruction simulator used to simulate the processor context environment; and calls between any two functions defined by the calling rules corresponding to the register resource mapping relationship are performed through tail calls, including: calls between functions from the target client executable file used for register simulation are performed through tail calls. Based on the register resource mapping relationship and the calling rules, the target client executable file is statically translated to generate the corresponding host executable file; Load the target client executable file and its corresponding host executable file; During the simulated execution of the host executable file, the target client executable file is simulated to be executed based on the register resource mapping relationship and the calling rules.

2. The cross-architecture program simulation execution method according to claim 1, characterized in that, The establishment of the register resource mapping relationship between the target client register resources and the host register resources includes: Map the target client's general-purpose registers to the host's general-purpose registers in a one-to-one and fixed-binding manner; At least a portion of the internal state variables in the instruction simulator used to simulate the per-processor context state of the target client are fixedly mapped to the host register resources; The program counter of the target client is mapped to the host machine register resource, and the program counter is maintained by the host machine software logic; In addition, some vector registers of the target client are mapped to vector registers of the host machine. For the remaining unmapped vector registers, global memory variables are used for simulation. The same vector register mapping mode is used for the same host machine executable file.

3. The cross-architecture program simulation execution method according to claim 1, characterized in that, When a simulated function executed based on the aforementioned calling rules needs to call a runtime helper function executed according to the host machine calling convention, it includes: Before the call, the target client state information mapped to the host machine register resources according to the register resource mapping relationship is written back to the metadata area, and the environment pointer is saved to the current function stack; the parameters of the runtime helper function are initialized according to the host machine calling convention. After the runtime helper function returns, the environment pointer is reloaded using the value stored in the current function stack, and then the target client state information is reloaded from the metadata area.

4. The cross-architecture program simulation execution method according to claim 1, characterized in that, Based on the register resource mapping relationship and the calling rules, the target client executable file is statically translated to generate a corresponding host executable file, including: The source code of the auxiliary functions of the instruction simulator is preprocessed to determine the inline auxiliary function template; Obtain the target client executable file as mandatory input information, and obtain the indirect jump target address recorded during instruction simulation execution as optional input information; Based on the required input information and the optional input information, the program jumps to the set of target addresses; For each indirect jump instruction, identify whether a jump table is used and record the corresponding jump table information; Based on the set of program jump target addresses, a translation block for the simulator's intermediate language description is generated; For each of the translation blocks, a translation block function is generated to describe the intermediate language of the host compiler. For the translation block that calls the helper function, a corresponding inline helper function is generated based on the inline helper function template; The host executable file is generated based on the host compiler, the translation block function, and the inline helper function.

5. The cross-architecture program simulation execution method according to claim 4, characterized in that, The program jump target address set includes at least one of the following addresses: the starting address of the target client executable file, the function address in the function symbol table, the target address of the direct jump instruction, the target address of the direct call instruction, the end address of the code section, and the recorded indirect jump target address.

6. The cross-architecture program simulation execution method according to claim 4, characterized in that, The step of generating the translation block for the simulator intermediate language description based on the set of program jump target addresses includes: Using the set of program jump target addresses as translation block boundary information, all program jump target addresses are simultaneously used as the end point of the old translation block and the start point of the new translation block, and all jump instructions are used as the end point of the translation block; The starting address of the translation block is defined as the valid entry point of the host executable file.

7. The cross-architecture program simulation execution method according to claim 4, characterized in that, The preprocessing of the auxiliary function source code of the instruction simulator to determine the inline auxiliary function template includes: Extract the source code of the auxiliary function from the source code tree of the instruction simulator and determine the target auxiliary function; The calling process of the target auxiliary function and other functions called by the target auxiliary function is rewritten to conform to the calling rules. The operation of accessing register status values ​​based on environment pointers in the target auxiliary function is converted into a direct operation on the host machine register resources; The return value of the target auxiliary function and the call return value related to the target auxiliary function are updated to a call to a preset return processing function; The rewritten and updated helper function code is identified as the inline helper function template; and when the target helper function calls a function outside the helper function source code, or accesses a variable defined by the instruction simulator runtime environment, a fallback process logic is generated to fall back to the original helper function of the instruction simulator runtime.

8. The cross-architecture program simulation execution method according to any one of claims 1 to 7, characterized in that, Also includes: Modify the runtime environment of the instruction simulator, including: In the runtime environment, a shadow stack, an instruction mapping hash table, and an instruction range red-black tree are set up. During the runtime environment initialization process, the addresses of runtime helper functions in the current process are determined and recorded; Configure the runtime environment to load executable files from the host machine; After loading the target client executable file, the host executable file corresponding to the target client executable file is loaded, and the correspondence between the target client instruction address and the host instruction address is written into the instruction mapping hash table.

9. The cross-architecture program simulation execution method according to claim 8, characterized in that, The shadow stack is a data structure set parallel to the target client program stack, and the storage space of the shadow stack or the pointer to the storage space of the shadow stack is located in the metadata area inside the instruction simulator used to simulate the processor context environment. When the target client's call instruction is executed, the return address mapping pair is pushed onto the shadow stack. The return address mapping pair includes the target client instruction return address and the host machine instruction address corresponding to the target client instruction return address. When the target client's return instruction is executed, the return address mapping pair is popped from the shadow stack, and the popped target client instruction return address is compared with the return address corresponding to the current target client return instruction. If the comparison results match, the control flow is transferred to the popped host instruction address; if the comparison results do not match, the instruction mapping hash table is queried.

10. The cross-architecture program simulation execution method according to claim 8, characterized in that, When the instruction simulator simulates the execution of indirect jump instructions identified as using jump tables, a shadow jump table corresponding to the target client's jump table is set in the host executable file. Call the jump table helper function and input the jump table entry index, shadow jump table base address, and shadow jump table entry number into the jump table helper function; When accessing the corresponding jump table entry for the first time, the correspondence between the target client instruction address and the host instruction address is queried through the instruction mapping hash table, and the queried target client instruction address and host instruction address are written into the corresponding entry of the shadow jump table; When accessing the corresponding jump table entry in a subsequent step, the target client instruction address to be jumped to is compared with the target client instruction address recorded in the corresponding entry of the shadow jump table, and the jump is performed using the host instruction address recorded in the shadow jump table if the comparison result is consistent.

11. The cross-architecture program simulation execution method according to claim 10, characterized in that, When the instruction simulator processes the indirect jump target address, if the corresponding host instruction address cannot be determined through the shadow stack or the shadow jump table, the instruction mapping hash table is queried. If the corresponding host machine instruction address is not found in the instruction mapping hash table, the instruction range red-black tree is queried to determine the target client executable file that covers the indirect jump target address, and the corresponding host machine executable file is loaded. If the corresponding host instruction address is still not determined, then runtime dynamic binary translation is invoked to continue the simulated execution.

12. A cross-architecture program emulation execution device, used by an instruction simulator to simulate the execution of executable files on a target client machine on a host machine, characterized in that, include: The mapping unit is used to establish the register resource mapping relationship between the target client register resources and the host register resources; The rule unit is used to define the calling rules corresponding to the register resource mapping relationship. The calling rules are used to pass target client status information between simulated functions executed on the host machine. The calling rules are configured to include: each simulated function executed on the host machine to simulate target client instructions includes: all general-purpose registers of the target client, internal state variables mapped to host machine register resources according to the register resource mapping relationship, the target client program counter, and the mapped target client vector register; auxiliary function parameters and the address of the next function to be executed are passed using host machine register resources not occupied by the register resource mapping relationship, and fixed host machine register resources are reserved to store environment pointers pointing to the metadata area inside the instruction simulator used to simulate the processor context environment; and calls between any two functions defined by the calling rules corresponding to the register resource mapping relationship are performed through tail calls, including: calls between functions from the target client executable file used for register simulation are performed through tail calls. The generation unit is used to perform static translation of the target client executable file based on the register resource mapping relationship and the calling rules, and generate the corresponding host executable file; The loading unit is used to load the target client executable file and its corresponding host executable file; An execution unit is used to simulate the execution of the target client executable file based on the register resource mapping relationship and the calling rules during the process of simulating the execution of the host executable file.

13. A computer-readable storage medium, characterized in that, It stores instructions that, when read by a processor, implement the cross-architecture program simulation execution method as described in any one of claims 1 to 11.

Citation Information

Patent Citations

  • Floating-point operation process for X8b in binary translation

    CN1746850A