Dynamic link call conversion method and device
By generating and filling the table entries of the call conversion table in the dynamic linker, the problem of human intervention in the existing technology of cross-calling convention function calls is solved, and automated dynamic link calling conversion is realized, simplifying the process and improving efficiency.
Patent Information
- Application Number
- CN202510622370.7
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- Filing Date
- 2025-05-15
- Publication Date
- 2025-06-10
- Estimated Expiration
- 2045-05-15
AI Technical Summary
The prior art requires manual intervention by programmers when implementing function calls across calling conventions and is not suitable for dynamic links automatically completed by dynamic linkers.
The dynamic linker generates table entries that call conversion tables and fills them into the default GOT table to realize call conversions across calling conventions, avoiding the need for programmers to intervene and recompile.
It implements call conversion across calling conventions without manual intervention and recompiling the program, simplifying the dynamic linking process.
Smart Images

Figure CN120123023A_ABST
Abstract
Description
Technical Field
[0001] This application relates to the field of computer technologies, and in particular, to a method and device for dynamic link call conversion. Background Art
[0002] During the running process of a program, it depends on many function libraries, and the dynamic linker can link the program to the dynamic link work of each function library. When a program calls a function in a certain function library, but the calling convention used by the program is different from the calling convention used by the function library, the dynamic linker cannot link the dynamic link libraries with different calling conventions together, or even if they are linked together, they cannot be used normally, and cross-calling convention function calls cannot be achieved.
[0003] To achieve cross-calling convention function calls, a call converter needs to be introduced. For example, function 1 in program A needs to call function 2 in function library B, where the former follows calling convention α and the latter follows calling convention β. In this case, function 1 cannot directly call function 2. Even if forced to call, it will cause program errors. The call conversion can be achieved through a call converter, that is, function 1 calls the call converter with calling convention α, the call converter calls function 2 with calling convention β, and then similarly passes the return value according to the calling convention later. In the prior art, since the call converter cannot actively intercept cross-calling convention function calls, but requires the programmer to actively change the call to function 2 to a call to the call converter to complete it circuitously, and this process must also actively pass the relevant information of function 2 to the call converter. It can be seen that this call conversion method requires manual intervention by the programmer, such as actively writing how to pass parameters to the call converter or recompiling the program to embed the call converter. In particular, when this call conversion method is used for dynamic linking, it is particularly cumbersome, and it is necessary to manually open the dynamic link library with inconsistent calling conventions and pass it to the call converter to generate the call entry (handle) after call conversion, and it is not applicable to the dynamic linking automatically completed by the dynamic linker. Summary of the Invention
[0004] Embodiments of this application provide a method and device for dynamic link call conversion, which are used to achieve cross-calling convention call conversion without manual intervention by the programmer and without recompiling the program.
[0005] In a first aspect, an embodiment of the present application provides a dynamic link call conversion method. This method can be executed by a dynamic link call conversion device, which can be a terminal device or a component in a terminal device, or a server or a component in a server. The present application does not limit the execution entity of this method. The method includes: If, when performing symbol resolution and binding for a first component, the first component is dynamically linked to a first symbol in a first dynamic link library, and the first symbol has not established a dynamic link symbol binding relationship with the first component, and the first component and the first dynamic link library use different calling conventions, then a first entry of a call conversion table is generated by a dynamic linker. The first entry includes a first instruction and a second instruction. The first instruction is used to indicate loading a first address of the first symbol in memory into a specified first storage container, and the second instruction is used to indicate jumping to a call converter; The second address of the first entry in memory is filled by the dynamic linker into a second entry in the default GOT table; where the default GOT table belongs to the first component.
[0006] In the above solution, when performing symbol resolution and binding for the first component, in the case where the first component needs to cross the calling convention to call the first symbol in the first dynamic link library and the first symbol has not established a dynamic link symbol binding relationship with the first component, by modifying the binding process of the dynamic linker and changing the address filled by the dynamic linker into the default GOT table to the address of the corresponding entry (i.e., the first entry) of the call conversion table in memory, the call of the first component to the first symbol can be converted into a call to the first entry, thus achieving the effect of call conversion across the calling convention without the need for manual intervention by the programmer and without recompiling the program.
[0007] In a possible implementation, after the second address of the first entry in memory is filled by the dynamic linker into the second entry in the default GOT table, it further includes: Triggering the execution of a third instruction by the dynamic linker or the first component; where the third instruction uses the second address stored in the second entry of the default GOT table as an indication and jumps to the first entry in the call conversion table according to this indication; Executing the third instruction and jumping to the first entry in the call conversion table; Executing the first instruction in the first entry to load the first address of the first symbol in memory into the first storage container; Executing the second instruction and jumping to the call converter; The call converter is used to receive the call of the first component using the first calling convention and call the first symbol using the second calling convention according to the first address stored in the first storage container.
[0008] In the above solution, since the second entry of the default GOT table points to the second address in memory of the first entry of the call conversion table, the call of the first component to the first symbol is converted into a call to the first entry. Therefore, the second entry can load the first address of the first symbol in memory and instruct the call converter to complete the final call and call conversion, so as to achieve the effect of call conversion across calling conventions without manual intervention by the programmer and without recompiling the program.
[0009] In a possible implementation, after the call converter calls the first symbol using the second calling convention according to the first address stored in the first storage container, it further includes: when the first symbol finishes execution and returns, it returns to the call converter; the call converter obtains the first return value using the second calling convention; the call converter stores the first return value in the second storage container using the first calling convention; after the call converter finishes execution, it returns to the first component; the first component uses the first calling convention to take out the first return value from the second storage container and determines it as the return value of the first symbol. Among them, the second storage container can be a register, memory (such as the stack in memory) or other storage. In a possible implementation, if the second storage container is a register, it should belong to the return value register specified in the first calling convention; this implementation can ensure that the first component can correctly obtain the return value of the first symbol and ensure the correct transfer of data.
[0010] In a possible implementation, the dynamic linker further includes a dynamic linker runtime resolution component for establishing dynamic link symbol binding relationships; the initial value of the second entry in the default GOT table is a default value when the first component is initialized; the first component includes a third instruction; filling the second address of the first entry in memory into the second entry of the default GOT table by the dynamic linker includes: when the first component first triggers the execution of the third instruction, the third instruction uses the default value in the second entry of the default GOT table as an indication and jumps to the fourth instruction according to this indication; among them, the fourth instruction may be located in the default PLT table or the stub table; execute the fourth instruction and jump to the dynamic linker runtime resolution component; fill the second address into the second entry of the default GOT table through the dynamic linker runtime resolution component.
[0011] In a possible implementation, generating the first entry of the call conversion table by the dynamic linker and filling the second address of the first entry in memory into the second entry of the default GOT table includes: when the first component is initialized, generating the first entry of the call conversion table by the dynamic linker and filling the second address of the first entry in memory into the second entry of the default GOT table.
[0012] In a possible implementation, the dynamic linker further includes a dynamic linker runtime resolution component for establishing the binding relationship of dynamic link symbols; the method further includes: when the first component is initialized, pre-filling a convention value in the fifth entry of the real address table through the dynamic linker, where the convention value is used to indicate that the first symbol is not bound; triggering the execution of a third instruction by the dynamic linker or the first component; wherein, the third instruction uses the second address stored in the second entry of the default GOT table as an indication and jumps to the first entry of the call conversion table according to this indication; executing the third instruction to jump to the first entry of the call conversion table; executing the first instruction in the first entry to load the convention value indicating that the first symbol is not bound from the fifth entry of the real address table into the first storage container; executing the second instruction to jump to the call converter; determining through the call converter that the first symbol is not bound according to the convention value in the first storage container and jumping to the dynamic linker runtime resolution component.
[0013] In a possible implementation, after jumping to the dynamic linker runtime resolution component, it further includes: filling the first address of the first symbol in memory into the fifth entry of the real address table through the dynamic linker runtime resolution component.
[0014] In a possible implementation, before filling the first address of the first symbol in memory into the fifth entry of the real address table through the dynamic linker runtime resolution component, it further includes: determining the first address of the first symbol in memory through the dynamic linker runtime resolution component according to the third address to which the first dynamic library is loaded and the address offset of the first symbol in the first dynamic library.
[0015] In a possible implementation, after filling the first address of the first symbol in memory into the fifth entry of the real address table through the dynamic linker runtime resolution component, it further includes: triggering the execution of a third instruction by the dynamic linker or the first component; executing the third instruction to jump to the first entry of the call conversion table; executing the first instruction in the first entry to load the first address of the first symbol from the fifth entry of the real address table into the first storage container; executing the second instruction to jump to the call converter; accepting a call from the first component using the first calling convention through the call converter and calling the first symbol using the second calling convention according to the first address stored in the first storage container.
[0016] In a possible implementation, filling the second address of the first entry in memory into the second entry of the default GOT table through the dynamic linker includes: when the first component is initialized, completing the immediate binding process of all symbols dynamically linked to the first component through the dynamic linker and filling the second address of the first entry in memory into the second entry of the default GOT table.
[0017] In a possible implementation, the first instruction is used to indicate loading the first address of the first symbol directly using an immediate value; the method further includes: executing the first instruction in the first entry, and loading the first address of the first symbol in the memory into the first storage container using the immediate value.
[0018] In a possible implementation, the method further includes: determining whether to load the first dynamic link library; if it is determined by the dynamic linker that the first dynamic link library has not been loaded, then searching for the first dynamic link library in the search paths that conform to the first calling convention used by the first component and all foreign calling conventions supported by call conversion; after the first dynamic link library is found, loading the first dynamic link library into the memory.
[0019] In a possible implementation, the method further includes: after the call conversion table is generated, setting the call conversion table to be readable, executable, and non-writable.
[0020] In a possible implementation, the addresses of the entries in the call conversion table are consecutive in the memory, or, the addresses of the entries in the call conversion table are not consecutive in the memory.
[0021] In a possible implementation, for the real address table implementing lazy binding, setting the real address table to be readable, writable, and non-executable, where the real address table is used to fill in the first address of the first symbol in the memory, or is used to fill in a convention value indicating that the first symbol is not bound; or, for the real address table implementing immediate binding, setting the real address table to be readable, non-writable, and non-executable, where the real address table is used to fill in the first address of the first symbol in the memory.
[0022] In a possible implementation, the addresses of the entries in the real address table are consecutive in the memory, or, the addresses of the entries in the real address table are not consecutive in the memory.
[0023] In a possible implementation, the first component is a program, or, the first component is a second dynamic link library.
[0024] In a second aspect, an embodiment of the present application provides a dynamic link call conversion device, including: A generating unit, configured to, if a first component dynamically links to a first symbol in a first dynamic link library during symbol resolution and binding for the first component, and the first symbol has not established a dynamic link symbol binding relationship with the first component, and the first component and the first dynamic link library use different calling conventions, generate a first entry of a call conversion table through a dynamic linker, where the first entry includes a first instruction and a second instruction, the first instruction is used to indicate loading a first address of the first symbol in memory into a specified first storage container, and the second instruction is used to indicate jumping to a call converter; A filling unit, configured to fill a second address of the first entry in memory into a second entry in a default GOT table through a dynamic linker; where the default GOT table belongs to the first component.
[0025] In a third aspect, an embodiment of the present application further provides a computer device, including: A memory, configured to store program instructions; A processor, configured to call the program instructions stored in the memory and execute any method of the first aspect above according to the obtained program.
[0026] In a fourth aspect, an embodiment of the present application further provides a computer-readable storage medium, where the computer-readable storage medium stores computer-executable instructions, and the computer-executable instructions are used to cause a computer to execute any method of the first aspect above.
[0027] In a fifth aspect, an embodiment of the present application provides a computer program product, including a computer program executable by a computer device. When the program runs on the computer device, the computer device is caused to execute any method of the first aspect above. Description of the Drawings
[0028] Figure 1 It is a schematic flowchart of a dynamic link call conversion method provided by an embodiment of the present application; Figure 2 It is a schematic flowchart of symbol resolution and binding work provided by an embodiment of the present application; Figure 3 It is a schematic flowchart of the loading process of a dynamic link library provided by an embodiment of the present application; Figure 4 It is a schematic diagram before a program starts provided by an embodiment of the present application; Figure 5 It is a schematic diagram when a program just starts provided by an embodiment of the present application; Figure 6 It is a schematic diagram when the first call to the PLT table entry 1 function 1 is bound provided by an embodiment of the present application; Figure 7 It is a schematic diagram when the function 1 has been completely bound provided by an embodiment of the present application; Figure 8 A schematic diagram of a non-simplified PLT table and GOT table provided by an embodiment of the present application, and without a real address table; Figure 9 A schematic diagram of a call scenario provided by an embodiment of the present application; Figure 10 A schematic structural diagram of a dynamic link call conversion device provided by an embodiment of the present application; Figure 11 A schematic structural diagram of a dynamic link call conversion device provided by an embodiment of the present application. Detailed implementation manners
[0029] In order to make the objectives, technical solutions and advantages of the present application clearer, the present application will be further described in detail below with reference to the accompanying drawings. Obviously, the described embodiments are only a part of the embodiments of the present application, rather than all of the embodiments. Based on the embodiments in the present application, all other embodiments obtained by those of ordinary skill in the art without creative efforts shall fall within the protection scope of the present application.
[0030] The following explains some professional terms used in the present application.
[0031] Link: Generally speaking, to compile a program from source code until obtaining an executable file (program) or a function library, several processes are required. These processes usually include compilation (compile), assembly (assemble), and link (link). Usually, if there is no ambiguity, the term "compilation" includes all the above processes. We call this definition of "compilation" broad. Unless otherwise specified later, it should also be understood as broad. Narrow compilation refers to converting source code written in a programming language into assembly language code. The assembly language code is still human-readable but cannot be executed by the processor, but can be easily converted into machine code; assembly refers to converting the assembly language code into machine code (machine code, also called instruction stream or instruction later) that can be executed by the processor and storing it in the object file (object file). Generally speaking, for a software of a certain scale, there will be many source code files, thus generating many object files and depending on many function libraries. The linker (linker, note: the linker is not the dynamic linker) will be responsible for linking these object files and the dependent function libraries together to form an executable file or a function library; this process is called linking.
[0032] Sometimes, terms such as compile time, link time, and run time (also known as execution time, runtime, or running time. To avoid ambiguity, it will be often referred to as "when the program is running / executing" hereinafter) are used to represent the process of a program from source code to object files (compile time, including compilation and assembly in the narrow sense), from object files to executable files or libraries (link time), and from executable files or libraries in storage space to processes actually executed on the processor (run time).
[0033] There are two ways to "link these object files and the dependent libraries together to form an executable file or library": dynamic linking or static linking.
[0034] When the linker completes dynamic linking, it only writes some characteristic information of the dynamic link library into the above-mentioned executable file or library, rather than writing the dynamic link library itself into the latter. These characteristic information are used to guide the dynamic linker. Therefore, the actual linking work (loading and binding) is left to the dynamic linker to complete when the program is running.
[0035] When the linker completes static linking, it first merges each object file and static library into a binary file (similar to the loading in dynamic linking), and then modifies the address references in the machine code according to the offset positions of each object file and static library after merging (similar to the binding in dynamic linking).
[0036] Dynamic linking and static linking are not mutually exclusive. An executable file (program) or library can use only dynamic linking, only static linking, or both. Taking a software project or library project of a certain scale as an example, which has several source code files, there may be but are not limited to the following situations: Situation 1: The object files obtained by compiling these source code files are often statically linked together to form a single executable file (single product) or library (single product). These object files become part of the single product.
[0037] Situation 2: In a few cases, some object files are also statically linked into a library (dynamic link library, product 1), and then the remaining object files are statically linked into an executable program (product 2), and the latter (product 2) is then dynamically linked to the former (product 1).
[0038] Case 3. For such a software, in addition to its own source code, it may also depend on some external function libraries. According to the linking options passed to the linker, some of the function libraries may be statically linked and become part of one or more of the above products (which may be the single product in Case 1, or Product 1 and / or Product 2 in Case 2); some may be dynamically linked to one or more of the above products (same as above). According to the linking options passed to the linker, it is also possible that all external function libraries are statically linked or dynamically linked.
[0039] Linker and dynamic linker: The linker is not the dynamic linker. In terms of the period of action: The linker acts during the linking period, and the dynamic linker acts during the execution period. In terms of the input received and the output produced: The linker accepts object files, static link libraries, and dynamic link libraries (where the object file must be passed in, and the remaining two are optional), and produces an executable file or a dynamic link library (generally, the linker is not used to generate a static link library, and the static link library is directly made by indexing and archiving object files); the dynamic linker accepts the executable file and searches for the required dynamic link libraries by itself. It does not produce a real product, but only affects the content in memory during program execution: it completes the loading and binding of the dynamic link library in memory, resolves the dependency between the program and the dynamic link library, and enables the program to execute correctly.
[0040] Function library (also known as library, i.e., library): It is a collection of subroutines used for software development in computer science. The difference between a library and an executable file is that it is not an independent computer program but provides services to other programs. The main purpose of a function library is to provide a code reuse mechanism so that developers can save time and effort and avoid writing the same code repeatedly. Function libraries can be compiled and linked into dynamic link libraries or static link libraries.
[0041] Symbol table: In computer science, a symbol table is a data structure used in language translators (such as compilers and interpreters). In the symbol table, each identifier in the program source code is bound to its declaration or usage information, such as its data type, scope, and memory address. There is usually a symbol table in the object file that contains all externally visible identifiers. When linking different object files, the linker uses the symbol tables in these files to resolve all unresolved symbol references. The symbol table may only exist during the compilation and linking phases, or may be embedded in the output files (such as executable files, dynamic / static link libraries) of this phase for subsequent phases to use. For example, it can be used in an interactive debugger or provide a formatted diagnostic report during or after program execution.
[0042] The symbol table that stores all symbols is called.symtab and is mainly used for debugging purposes.
[0043] A special symbol table is the dynamic symbol table (usually.dynsym), which is used to store the import and export symbols related to dynamic linking and does not include the symbols inside the module. The symbol names corresponding to the symbols contained in the dynamic symbol table are stored in the dynamic symbol string table (usually.dynstr). It can be understood that the dynamic symbol table refers to the table that stores the information of the import and export symbols related to dynamic linking. The dynamic symbol table is generated by the linker.
[0044] Import symbols refer to the symbols that the current executable file or dynamic link library depends on; export symbols refer to the symbols provided by the current executable file or dynamic link library. Obviously, to complete the binding of an import symbol, its corresponding export symbol must be found. Generally speaking, the dynamic linker can find the required export symbol in the dynamic link libraries linked by the current program or dynamic link library.
[0045] The dynamic symbol table may also contain some symbols of a program or dynamic link library itself, even if these symbols are not used for export or import. This is well understood for dynamic link libraries: the dynamic link library may be loaded at an uncertain address. Therefore, the references to some of its own functions and global symbols may need to wait until the runtime to determine the address, and these symbols will also be bound by the dynamic linker, even if they are not really used for dynamic linking (not import or export symbols). For executable files, this is usually because the position-independent execution feature of the executable file is enabled, resulting in these executable files becoming programs that are allowed to be loaded and executed at any address, that is, position-independent executables PIE, position-independent executable, which is often used to implement address space layout randomization ASLR, address space layout randomization. Such executable files will also have the above problems of dynamic link libraries (the positions of some symbols must be determined until the runtime), so they also need to include their own symbols in the dynamic symbol table, even if these symbols are not used for export or import.
[0046] Figure 1 An exemplary flowchart of a dynamic link call conversion method provided by an embodiment of the present application is shown. This method process can be executed by a dynamic link call conversion device, which can be a terminal device or a component inside the terminal device, or a server or a component inside the server; where the component is, for example, a processor.
[0047] As Figure 1 shown, the method process includes the following steps: Step 101, when performing symbol resolution and binding for the first component, if the first component is dynamically linked to the first symbol in the first dynamic link library, and the first symbol has not established a dynamic link symbol binding relationship with the first component, and the calling convention used by the first component is different from that of the first dynamic link library, then the dynamic linker generates the first entry of the call conversion table. The first entry includes a first instruction and a second instruction. The first instruction is used to indicate loading the first address of the first symbol in memory to a specified first storage container, and the second instruction is used to indicate jumping to the call converter.
[0048] In one implementation, the first component is a program. In another implementation, the first component is a second dynamic link library linked to the first dynamic link library. In the above two implementations, the first symbol can be a function. For ease of description, in the following, it is described by taking the first component as program A, the second component as the first dynamic link library, and the first symbol as a function as an example.
[0049] The following explains the difference in the calling convention used by the first component and the first dynamic link library in Step 101 above. For example, the calling convention used by program A is calling convention , and the calling convention used by the first dynamic link library is calling convention β. If function 2 in the first dynamic link library to which program A is linked during symbol resolution and binding for program A, and function 2 has not established a binding relationship with program A, then the dynamic linker generates the first entry of the call conversion table.
[0050] The first storage container in Step 101 above can be a register, memory (such as the stack in memory), or other storage. In one possible implementation, if the first storage container is a register, it should belong to the caller-saved registers specified in the calling convention (the first calling convention); this implementation can ensure that the context of the first component is not damaged by the first instruction, ensure the correctness of execution, and avoid causing incorrect crashes.
[0051] Step 102, the dynamic linker fills the second address of the first entry in memory into the second entry of the default GOT table; the default GOT table belongs to the first component.
[0052] Before Step 101, the dynamic linker parses the dynamic symbol table of the first component, obtains the symbol information to which the first component is dynamically linked and the address of the GOT table entry to be filled, and then performs symbol resolution and binding work according to the symbol information. For details, see Figure 2 the flow schematic diagram shown.
[0053] The symbol information to which the first component is dynamically linked includes multiple symbols. In this application, the first symbol is used as an example for description. AsFigure 2 As shown, first, according to the symbol information, find the first dynamic link library where the first symbol is located, and then determine whether the first dynamic library has been loaded. If not, that is, the dynamic linker has not loaded the first dynamic link library, then execute the loading process of the dynamic link library. The specific loading process of the dynamic link library can be found in Figure 3 the process schematic diagram shown. If so, that is, the dynamic linker has loaded the first dynamic link library into memory, then parse the symbol table of the first dynamic link library to find the offset of the first symbol. Then, combine the above offset with the memory address where the first dynamic link library is loaded to calculate the actual address of the first symbol in memory.
[0054] Then, determine whether the first symbol is a function with an external calling convention. If the first symbol is a function with an external calling convention, the actual address of the first symbol in memory (the "symbol address") cannot be directly filled into the GOT table, but the corresponding call conversion PLT table entry must be filled into the GOT table. Specifically, it can be divided into two cases: Case 1, fill the actual address of the first symbol in memory into the corresponding real address table entry, that is, the fifth table entry (if the corresponding table entry does not exist, a new one can be added); Case 2, in the scheme without a real address table, generate a call conversion table entry, that is, the first table entry, and fill the actual address of the first symbol in memory into the immediate number field of the instruction (or instruction cluster) used to directly load the symbol address in the table entry. Based on any of the above cases, fill the actual address of the call conversion table entry corresponding to the first symbol (that is, the first table entry, if the corresponding call conversion table entry does not exist, a new one can be added) in memory into the corresponding GOT table entry, that is, the second table entry. If the first symbol is not a function with an external calling convention, but a local calling convention, that is, the first component and the first dynamic link library use the same calling convention, then fill the actual address of the first symbol in memory into the corresponding table entry in the default GOT table, that is, the second table entry, to complete the establishment of the dynamic link symbol binding relationship between the first symbol and the first component. In the case where the first symbol is a function with a local calling convention, there is no need to execute Figure 1 the dynamic link call conversion method shown.
[0055] Next, see Figure 3 for an introduction to the loading process of the dynamic link library.
[0056] First, determine whether the input is the name or the path of the first dynamic link library. If the input is a path, check whether the path exists. If it does, that is, the path exists, then determine the path of the dynamic link library. If not, that is, the path does not exist, then determine that the loading fails (usually causing the program to crash) and end the process. If the input is a name, sequentially search for the first dynamic link library in the search paths of each dynamic link library that conforms to the current calling convention (i.e., the first calling convention used by the first component, i.e., the native calling convention) and all foreign calling conventions supported by call conversion. Then, determine whether the first dynamic link library is found. If it is, that is, the first dynamic link library is found, then determine the path of the first dynamic link library. If not, that is, the first dynamic link library is not found, it means that the loading fails (usually causing the program to crash) and end the process. After determining the path of the dynamic link library, determine whether the first dynamic link library has been loaded. If it has, then the first dynamic link library has been loaded into memory and the loading process ends. If it has not, it means that the first dynamic link library has not been loaded, then load the first dynamic link library from this path into memory and end the loading process.
[0057] Generally, dynamic link libraries with different calling conventions are installed in different directories (paths). When searching for a dynamic library using the dynamic library name, search for the dynamic library in the search paths of the current calling convention (「native」) and all calling conventions supported by call conversion (「foreign」). In this way, it can be ensured that dynamic link libraries across calling conventions are included in the search scope, ensuring that the required symbols can be found in both native and foreign calling convention dynamic link libraries. And the problem of missing native calling convention dynamic link libraries can be solved by using foreign calling convention dynamic link libraries.
[0058] When the same symbol is found in both the native and foreign calling convention dynamic link libraries, there is no limit on which one to prefer for binding. One possible implementation is to prefer the symbol of the native calling convention to avoid the overhead of call conversion. Another possible implementation is that when it is known that the performance of the symbol of the foreign calling convention is good enough to offset the overhead of call conversion, the symbol of the foreign calling convention can be preferred. Another possible implementation is to count the other symbols it depends on and / or the symbols that depend on it for this symbol, and use the most common calling convention among these dependencies and / or dependents to determine the version of the calling convention selected for binding for this symbol.
[0059] After the above step 102, that is, after the dynamic linker fills the second address of the first entry in memory into the second entry of the default GOT table, the execution of the third instruction can be triggered by the dynamic linker or the first component; it should be noted that here it can be a jump to the third instruction or a sequential execution to the third instruction. Among them, the third instruction uses the second address stored in the second entry of the default GOT table as an indication and jumps to the first entry in the call conversion table according to this indication; execute the third instruction and jump to the first entry in the call conversion table; execute the first instruction in the first entry and load the first address of the first symbol into the first storage container; execute the second instruction and jump to the call converter; the call converter is used to accept the call of the first component using the first calling convention and call the first symbol using the second calling convention according to the first address. The execution of the third instruction triggered by the dynamic linker or the first component may occur because after the dynamic linker finishes binding the first symbol, it continues to complete the call to the first symbol that triggered this binding. At this time, it is the execution of the third instruction triggered by the dynamic linker; it may also be because the first component calls the first symbol again after the binding has been completed. At this time, it is the execution of the third instruction triggered by the first component.
[0060] It should be noted that after the dynamic linker fills the second address of the first entry in memory into the second entry of the default GOT table, the execution of the third instruction triggered is different in the lazy binding scenario and the immediate binding scenario: in the lazy binding scenario, the execution of the third instruction can be triggered by the dynamic linker or the first component; in the immediate binding scenario, the execution of the third instruction can be triggered by the first component, and there is no situation where the dynamic linker triggers the execution of the third instruction, which will not be elaborated later.
[0061] Here, the call conversion process implemented by the call converter is further described, which can specifically include the following steps S1~S7: S1, accept the call of the first component using the first calling convention and obtain the first return address from the second storage container; among them, the second storage container is the storage container specified by the first calling convention for storing the return address, and the first return address is used to return to the first component.
[0062] S2, deposit the second return address into the third storage container; among them, the second return address is used to return to the call converter, and the third storage container is the storage container specified by the second calling convention for storing the return address.
[0063] S3, obtain the first address from the first storage container and call the first symbol located at the first address using the second calling convention.
[0064] S4. After the first symbol is executed, the first symbol stores its return value in the fourth storage container and returns to the second return address using the return address stored in the third storage container as an indication; wherein, the fourth storage container is the storage container specified by the second calling convention for storing return values.
[0065] S5. After returning to the call converter, the call converter obtains the return value from the fourth storage container and stores the return value in the fifth storage container; wherein the fifth storage container is the storage container specified by the first calling convention for storing return values.
[0066] S6. Using the first return address as an indication, return to the first component.
[0067] S7. The first component can obtain the return value from the fifth storage container according to the first calling convention.
[0068] The above step 102 can have multiple possible implementation manners.
[0069] Embodiment 1. In the case where the default GOT table is not pre-filled, the dynamic linker further includes a dynamic linker runtime resolution component for establishing dynamic link symbol binding relationships; the initial value of the second entry in the default GOT table is a default value when the first component is initialized; the first component includes a third instruction; when the first component first triggers the execution of the third instruction, the third instruction uses the default value in the second entry of the default GOT table as an indication and jumps to the fourth instruction according to this indication; wherein, the fourth instruction may be located in the default PLT table or the stub table; execute the fourth instruction and jump to the dynamic linker runtime resolution component; fill the second address into the second entry of the default GOT table through the dynamic linker runtime resolution component.
[0070] Embodiment 2. In the case where the default GOT table is pre-filled, when the first component is initialized, the dynamic linker generates the first entry of the call conversion table and fills the second address in the memory of the first entry into the second entry of the default GOT table.
[0071] Based on the second embodiment, the dynamic linker further includes a dynamic library runtime resolution component for establishing the dynamic link symbol binding relationship; when the first component is initialized, the dynamic linker pre-fills a default value in the fifth entry of the real address table, and the default value is used to indicate that the first symbol is not bound; the execution of the third instruction is triggered by the dynamic linker or the first component; wherein, the third instruction uses the second address stored in the second entry of the default GOT table as an indication and jumps to the first entry of the call conversion table according to this indication; execute the third instruction and jump to the first entry of the call conversion table; execute the first instruction in the first entry, and load the default value indicating unbound from the fifth entry of the real address table into the first storage container; execute the second instruction and jump to the call converter; through the call converter, it is determined that the first symbol is not bound according to the default value in the first storage container, and then jump to the dynamic library runtime resolution component.
[0072] After jumping to the dynamic library runtime resolution component, the dynamic library runtime resolution component fills the first address of the first symbol in the memory into the fifth entry of the real address table.
[0073] Before the dynamic library runtime resolution component fills the first address of the first symbol in the memory into the fifth entry of the real address table, the dynamic library runtime resolution component also determines the first address of the first symbol in the memory according to the third address to which the first dynamic library is loaded and the address offset of the first symbol in the first dynamic library.
[0074] After generating the first entry of the call conversion table by the dynamic linker, there are two ways to jump to the call converter: Method 1: The dynamic linker embeds the third address of the call converter in the memory into the second instruction in the call conversion table; execute the second instruction, load the third address embedded in the second instruction, and jump to the call converter based on the third address, where the third address is the address of the call converter in the memory. In a possible implementation, the second instruction can directly jump to the third address according to its own indication, that is, jump to the call converter, without specifically loading the third address. Through Method 1, it is possible to directly jump to the call converter.
[0075] Method 2: The dynamic linker fills the third address of the call converter in the memory into the sixth entry of the real address table; execute the second instruction, load the third address from the sixth entry of the real address table, and jump to the call converter based on the third address. Through Method 2, it is possible to indirectly jump to the call converter.
[0076] After the above step 102, when the delayed binding is completed, if the default PLT entry is called again, it can be implemented in the following way: the dynamic linker or the first component triggers the execution of the third instruction; execute the third instruction and jump to the first entry in the call conversion table; execute the first instruction in the first entry, load the first address of the first symbol from the fifth entry in the real address table to the first storage container; execute the second instruction and jump to the call converter; the call converter accepts the call from the first component using the first calling convention and calls the first symbol using the second calling convention according to the first address stored in the first storage container.
[0077] The following combines specific examples and Figures 4 to 7 , taking the first component as a program and the first symbol as a function as an example to illustrate the call conversion process in the delayed binding scenario. It should be noted that only one dynamically linked function is exemplified in this example. If there are more functions dynamically linked, then Figures 4 to 7 the default PLT table, default GOT table, call conversion table, and real address table in Figures 4 to 7 only need to grow accordingly (such as adding entries). Additionally, it should be noted that in some real-world scenarios, there may be no PLT table. In this case, the third instruction ("the instruction (cluster) that jumps to the address pointed to by GOT entry 3") is moved into the instruction stream of the first component to replace the "instruction (cluster) that calls PLT entry 1" described later and in the figure, and the table formed by the remaining PLT entry content (including the fourth instruction and entry 0) is called a stub table (if it is immediate binding, no stub table is required). The reader can understand that regardless of whether there is a PLT table,
[0078] Figure 4 shows a schematic diagram before the program starts. Before the program starts, that is, when it is still on the hard disk, it is impossible to know in advance which address the dynamically linked function will be loaded to. Therefore, most of the data in the default GOT table remains unfilled. Among them, the second entry in the default GOT table is Figure 4 entry 3 of the original GOT table in
[0079] such as Figure 4As shown, the original GOT table also includes entries 0 to 2. The value of entry 0 is used to fill in the.dynamic address. Entry 1 is marked as "(link_map address)", and the parentheses () are intended to indicate that the program originally expected to fill in the link_map address in entry 1, but at this time (i.e., before the program starts), it has not been filled in yet. Similarly, in entry 2, "(the address of _dl_runtime_resolve)" is intended to indicate that the program originally expected to fill in the address of _dl_runtime_resolve in entry 2, but at this time (i.e., before the program starts), it has not been filled in yet.
[0080] As Figure 4 shown, the instruction stream of the "first component" includes multiple instructions. The instruction stream includes instructions (clusters) that call PLT entry 1. These instructions are in the order from bottom to top in the instruction stream, unless a jump occurs. When the instructions (clusters) that call PLT entry 1 in this instruction stream are first executed, the corresponding process is executed according to the dotted arrow in the figure.
[0081] As Figure 4 shown, the original PLT table includes entry 0 and entry 1. Entry 0 includes: "instructions (clusters) that load the link_map address into a specified register or push it onto the stack" and "instructions (clusters) that jump to the address pointed to by entry 2 in the GOT table"; Entry 1 in the PLT table (i.e., the third entry in the following text), which includes the third instruction and the fourth instruction. The third instruction is Figure 4 the "instructions (clusters) that jump to the address pointed to by entry 3 in the GOT table" in Figure 4 and the fourth instruction is
[0082] It should be understood that for the same content in Figures 5 to 8 as that in Figure 4 below, reference can be made to the description of Figure 4 and it will not be repeated hereinafter. In addition, the default GOT in this article can be understood as the original GOT, and the default PLT can be understood as the original PLT, which will not be elaborated elsewhere.
[0083] Figure 5 It shows a schematic diagram when the program has just started. At this time, the dynamic linker has completed its initial work.
[0084] Among them, the initial work of the dynamic linker mainly includes: S51, Bootstrap or self-binding. The dynamic linker itself is a special dynamic library. It does not load itself, but it must bind itself. The specific process of self-binding is relatively conventional and will not be elaborated here.
[0085] S52, Parse the dynamic symbol table of this program to obtain the list of symbols to which this program is dynamically linked. Parse the.dynamic section of this program to obtain the list of dynamically linked dynamic libraries and some options for specifying dynamic linking behavior.
[0086] S53, Complete the initial work of lazy binding, and / or, complete immediate binding.
[0087] (1) Initial work of lazy binding: Using the above information, generate the link_map of this program. Fill the address of the link_map into entry 1 of the original GOT table as shown in Figure 4, and fill the address of _dl_runtime_resolve (that is, the dynamic linker runtime resolution component mentioned above, used to establish dynamic link symbol binding relationships, the same below, not noted again) into entry 2 of the original GOT table. After filling, it is like entry 1 and entry 2 of the GOT table in Figure 5 Sometimes it is also necessary to repair the initial value of the entry in the default GOT table (add the address where the current program / dynamic library is loaded to it).
[0088] (2) Immediate binding: Using the above information, complete immediate binding.
[0089] It should be noted that: _dl_runtime_resolve is part of the dynamic linker. Since the dynamic linker has been loaded, _dl_runtime_resolve is naturally also loaded. In addition, the dynamic link library is very likely to have its own PLT / GOT table and is very likely to be linked to other dynamic link libraries. Therefore, each time a dynamic link library is loaded (or a symbol is bound to a dynamic link library for the first time), it is very likely that the operations in S52 - S53 above also need to be performed on this dynamic link library. In some implementations, the initial work of lazy binding performed by the dynamic linker may also include preloading the dynamic link libraries linked by the program (but not binding them) and performing some pre-resolution. The reason is that the dynamic linker can minimize the overhead of preloading by using the mechanisms provided by the operating system. In this case, these dynamic link libraries do not need to be loaded later. The following still takes the example where the initial work performed by the dynamic linker does not include preloading dynamic link libraries. It should be understood that even if the dynamic linker preloads dynamic link libraries, it has no substantial impact on the subsequent process. This is because dynamic link libraries can always be loaded on demand, and will only be loaded when not loaded, otherwise the loading can be directly skipped.
[0090] In addition to handling the above initial work, the dynamic linker also needs to handle the following work: S54, parse the PLT table and GOT table of the program, determine how many functions are dynamically linked, and based on this number, generate a call transformation table and a real address table. For example, the first entry in the call transformation table in this article is entry 1 in the call transformation table as shown in Figure 5 Then the first instruction can be Figure 5 "Load real address table entry 3 to a specified register or the stack instruction (cluster)" in entry 1 of the call transformation table as shown in the call transformation table, and the second instruction can be Figure 5 "Jump to the call converter instruction (cluster)" in entry 1 of the call transformation table as shown in the call transformation table. Entry 1 in the call transformation table can also include "instructions (cluster) for preparatory work". For example, the fifth entry in the real address table in this article is entry 3 in the real address table as shown in Figure 5 Its label is "(function 1 address)", indicating that the initial value of entry 3 in the real address table is the default address.
[0091] Since both the call conversion table and the real address table are generated after the program starts and are generated by the dynamic linker, and at this time (especially after the dynamic linker completes self-bootstrapping), the address of the call converter in memory is known, it is possible to directly embed the address of the call converter in memory into the "instruction (cluster) that jumps to the call converter" in the call conversion table (referred to as a direct jump), without the need to first load the bound address from the default GOT table like the original default PLT table and then perform a jump (referred to as an indirect jump). Of course, it is still feasible to adopt the latter methodology. For example, an item can be created in the real address table to store the address of the call converter, and the address of the call converter can be obtained from the real address table first and then jumped to in the call conversion table entry. This will not be elaborated further later.
[0092] Depending on whether the entries of the default GOT are pre-filled during initialization (specifically referring to the entries numbered 3 or greater in this example, and entries 1-2 have already been filled as necessary preparations for lazy binding), there are two slightly different implementation methods: First, when the default GOT table is not pre-filled, due to lazy binding, during initialization, it is not necessary to fill the corresponding entries of the call conversion table into the entries numbered 3 or greater in the original GOT table, and its default value is maintained. As a result, when the corresponding PLT table entry is first called later, it will enter _dl_runtime_resolve, and _dl_runtime_resolve will complete the filling (binding) of the corresponding GOT table entry and real address table entry together. In this implementation method, the initial values of the entries in the real address table are not used at all, so any value it takes does not affect the subsequent process.
[0093] Second, when the original GOT table (i.e., the aforementioned default GOT table) is pre-filled: Since the call conversion table is generated dynamically, the addresses of its various entries are known after generation. Therefore, during initialization, the corresponding entries of the call conversion table can be pre-filled into the entries numbered 3 or greater in the original GOT table, so that it is not necessary to fill the entries of the GOT table again later. However, due to lazy binding, the dynamic link library has not been loaded during initialization, so it is still necessary to enter _dl_runtime_resolve when the entry of the PLT table is first called. Therefore, in this implementation method, the initial value of the entry in the real address table ultimately determines the execution flow when the PLT table entry is first called. Therefore, it is necessary to pre-fill the agreed values into the entries of the real address table at the same time to ensure the normal operation of lazy binding. The following will take the aforementioned first implementation method as an example for explanation.
[0094] It should be noted that _dl_runtime_resolve and the call converter do not necessarily need to be dynamically generated or loaded. They can be part of a modified dynamic linker. Additionally, Figure 5 The entry numbers of the call conversion table and the real address table in Figure 5 do not start from 0. Here, it is only for the convenience of expressing the correspondence between these table entries and the original PLT table and GOT table. The selection of the starting value of the numbering has no practical significance, and non-consecutive numbers also have no special meaning. They do not have to correspond one by one. This can be analogized in other examples.
[0095] Figure 6 Figure 6 shows a schematic diagram of the first binding of the function 1 in the PLT table entry 1.
[0096] As Figure 6 shown, when the PLT table entry 1 in the instruction stream of the "first component" is called for the first time, it jumps to the table entry 1 of the original PLT table and executes the instruction "jump to the address executed by the GOT table entry 3" in the table entry 1 of the original PLT table to jump to the table entry 3 in the GOT table. The value in the table entry 3 of the GOT table is the default address, which will load the value of the default GOT table entry 3, jump to the table entry 1 of the PLT table, and execute the instruction (or instruction cluster) "load the function number into a certain register of the instruction or push it onto the stack" and the instruction cluster "jump to the PLT table entry 0" in the table entry 1. Subsequently, it will jump to the PLT table entry 0 and then jump to _dl_runtime_resolve via the PLT table entry 0.
[0097] Since the original _dl_runtime_resolve is modified in this application, the behavior of _dl_runtime_resolve at this time is as follows: S61, if the dynamic link library where the function 1 is located has not been loaded, load it. If it has already been loaded, there is no need to load it again. The key is to obtain the address of the function 1, which is obtained by adding the address offset of the function 1 in the symbol table of the dynamic link library where the function 1 is located after parsing to the address where the function 1 is loaded.
[0098] S62, fill the corresponding entry in the real address table (the entry 3 in the real address table shown in Figure 6 in this example) with the address of the function 1. Figure 6 in Figure 6 .
[0099] S63, fill the corresponding entry in the original GOT table (the entry 3 in the original GOT table shown in Figure 6 in this example) with the address of the corresponding entry in the call conversion table (the entry 1 in the call conversion table shown in Figure 6 in this example). Figure 6 in Figure 6 . Figure 6 in Figure 6 .
[0100] S64, the binding has been completed. Since the instruction that triggered the lazy binding ultimately aims to call Function 1, after the lazy binding is completed, Function 1 should also be called through the call converter in some way.
[0101] In some implementations, the dynamic linker can directly jump to Entry 1 of the call conversion table at this time. Subsequently, Entry 1 of the call conversion table can load the real address of the function from Entry 3 of the real address table and jump to the call converter. After jumping to the call converter, the call converter obtains the function address from a specified register or the stack and can then call this function using the corresponding calling convention.
[0102] In some other implementations, the dynamic linker jumps to Entry 1 of the PLT table. Since the address of Entry 1 of the call conversion table has been correctly filled in Entry 3 of the original GOT table, Entry 1 of the PLT table will not jump to _dl_runtime_resolve via Entry 0 of the PLT table again, but can jump to Entry 1 of the call conversion table. Subsequently, the process can refer to the aforementioned implementation method.
[0103] Figure 7 A schematic diagram showing that the binding of Function 1 has been completed.
[0104] After the binding of Function 1 is completed, as Figure 7 shown, after each jump to Entry 1 of the PLT table (i.e., the original Entry 1 of the PLT table), the address of Entry 1 of the call conversion table can be directly loaded from Entry 3 of the default GOT table. Thus, Entry 1 of the PLT table can directly jump to Entry 1 of the call conversion table. Further, Entry 1 of the call conversion table can directly load the address of Function 1 from Entry 3 of the real address table and place it in a certain register or on the stack, so as to be able to pass the address of Function 1 to the call converter. Thus, the call converter will be able to obtain the address of Function 1 from a specific register or the stack and complete the call conversion.
[0105] Embodiment 3. In the case of immediate binding, the binding process of all symbols is completed during program initialization. This embodiment is applicable to the case where the default PLT table and the default GOT table are not simplified, and also applicable to the case where the default PLT table and the default GOT table are simplified. When the first component is initialized, the dynamic linker completes the immediate binding process of all symbols dynamically linked to the first component and fills the second address of the first entry in memory into the second entry of the default GOT table; when the third entry in the default PLT table is called, it jumps to the third entry in the default PLT and executes the third instruction in the third entry to jump to the second entry in the default GOT.
[0106] Embodiment 4. In the case of no real address table, the first instruction is used to indicate loading the first address of the first symbol directly using an immediate number; execute the first instruction in the first entry, and load the first address of the first symbol in the memory to the first storage container using an immediate number.
[0107] In this embodiment, as long as immediate binding is used, the address to which the dynamically linked symbol is loaded has been known when generating the call conversion table. Therefore, it is entirely possible to generate an instruction (cluster) to directly load (including but not limited to: loading an immediate number into a register and / or the stack) the symbol address, and embed such an instruction (cluster) into the call conversion table, thereby completely eliminating the need for a real address table. At this time, security can be achieved by locking the generated call conversion PLT table to be readable, executable, and non-writable.
[0108] See Figure 8 For a schematic diagram without simplifying the PLT table and the GOT table and without a real address table. As Figure 8 shown, directly embed the first instruction, that is, "an instruction (cluster) that loads the function 1 address to a specified register or the stack using an immediate number" in the call conversion table, without using a real address table, so that the symbol address can be directly loaded through the call conversion table. It should be understood that the case of simplifying the original PLT table and the original GOT table and without a real address table is also feasible, which will not be elaborated here.
[0109] Based on any of the above embodiments, after generating the call conversion table, set the call conversion table to be readable, executable, and non-writable. In a specific implementation, it can be to first write the call conversion table to a writable memory area, and then lock it to be readable, executable, but non-writable.
[0110] The real address table for implementing delayed binding is set to be readable, writable, and non-executable. In this case, the real address table is used to fill in the first address of the first symbol in the memory, or to fill in a convention value indicating that the first symbol is not bound.
[0111] For the real address table for implementing immediate binding, it should be initially readable, writable, and non-executable until immediate binding is completed and then becomes readable, non-writable, and non-executable. In this case, the real address table is used to fill in the first address of the first symbol in the memory.
[0112] In some possible implementations, it may be allowed to call the conversion PLT table and the real address table to generate and expand as needed. For example, when implementing lazy binding, the dynamic linker may not generate the call conversion table and the real address table during the initial work, but leave it until the first time a function that needs to insert a call conversion is lazily bound. Whenever it is generated, it is not necessary to immediately determine its size and generate all the table entries when generating the call conversion table and the real address table, but it can be expanded as needed (add table entries). For example, each time a function that needs to insert a call conversion is lazily bound, if the corresponding table entry does not exist yet, a new one can be added. Based on this, the call conversion table and the real address table do not necessarily need to be continuous, and the individual table entries may not be continuous in memory addresses.
[0113] Based on any of the above embodiments, the addresses of the individual table entries in the call conversion table are continuous in memory, or the addresses of the individual table entries in the call conversion table are not continuous in memory. The addresses of the individual table entries in the real address table are continuous in memory, or the addresses of the individual table entries in the real address table are not continuous in memory.
[0114] In some possible cases, not all functions existing in the original PLT and GOT tables have corresponding table entries in the call conversion table and the real address table. Sometimes, there may even be no call conversion table and real address table.
[0115] In one example, all dynamically linked functions are not cross-call convention: Obviously, there is no need for call conversion in this case, so there is no need to have a call conversion table and a real address table.
[0116] In another example, some of the dynamically linked functions are not cross-call convention: Obviously, there is no need for call conversion for these functions, and their behavior when bound is the same as in the prior art, so they do not need to have corresponding table entries in the call conversion table and the real address table.
[0117] It should be noted that the "native" and "foreign" involved in this application are a relative and limited description. It is not fixed as the perspective changes. The dynamic linker needs to dialectically consider the native / foreign nature of the call convention based on who it is currently performing symbol linking and binding for.
[0118] Such as Figure 9In the call scenario shown, program (executable file) A is dynamically linked to library B and library C, and library B itself is also dynamically linked to library C. Among them, program A uses calling convention α, and libraries B and C use calling convention β. When the dynamic link library performs symbol resolution and binding for program A, the symbols from libraries B and C are in a foreign calling convention, so the function calls need to be redirected to the call converter; when the dynamic link library performs symbol resolution and binding for library B, the symbols from library C are in the native calling convention, so there is no need to redirect the function calls to the call converter. For the same function from library C, although its calling convention is β, due to different referrers (program A / library B), the native / foreign nature of its calling convention varies from different perspectives.
[0119] In the embodiments of the present application, the binding of the dynamically linked function completely depends on the dynamic linker. That is to say, when the program calls a function in the dynamic link library, which address it will finally call to completely depends on what address the dynamic linker fills in the default GOT table. Based on this, by modifying the binding process of the dynamic linker and changing the address filled in the default GOT table by the dynamic linker to the address of the corresponding entry (the first entry) in the call conversion table in memory, the call of the first component to the first symbol can be converted into a call to the first entry, thus achieving the effect of inserting call conversion without manual intervention by the programmer and without recompiling the program.
[0120] In the embodiments of the present application, by redirecting function calls to the call converter, problems in multiple scenarios can be solved. In some scenarios, even if the calling conventions do not match, there is no need to modify or recompile the existing executable file (program) and dynamic link library, and the executable file can be loaded with the required dynamic link library. For example, in scenarios where there is no source code for the program or dynamic link library (not delivered or lost, etc.), and it is simply impossible to recompile them to make the calling conventions match, the embodiments of the present application can solve this problem. In other scenarios, some calling conventions have significantly better performance, but some calling conventions have better compatibility. Therefore, a performance-sensitive part of the software can be formed into a dynamic link library (using a calling convention with better performance), and the remaining part can be formed into an executable file (using a calling convention with better compatibility), and the latter is dynamically linked to the former. The present application is also applicable to this scenario and can take into account the requirements for both performance and compatibility.
[0121] Based on the same technical concept, Figure 10 Exemplarily shows a schematic structural diagram of a dynamic link call conversion device provided by an embodiment of the present invention, and this device can execute the above method process.
[0122] As Figure 10As shown in the figure, the dynamic link call conversion device specifically includes: A generating unit 1001, configured to, if when performing symbol resolution and binding for a first component, the first component is dynamically linked to a first symbol in a first dynamic link library, and the first symbol has not established a dynamic link symbol binding relationship with the first component, and the first component and the first dynamic link library use different calling conventions, then generate a first entry of a call conversion table through a dynamic linker, where the first entry includes a first instruction and a second instruction, the first instruction is used to indicate loading a first address of the first symbol in memory to a specified first storage container, and the second instruction is used to indicate jumping to a call converter; A filling unit 1002, configured to fill a second address of the first entry in memory to a second entry in a default GOT table through the dynamic linker; where the default GOT table belongs to the first component.
[0123] In a possible implementation, the dynamic link call conversion device further includes a triggering unit 1003 and an execution unit 1004; the triggering unit 1003 is configured to: trigger the execution of a third instruction by the dynamic linker or the first component; where the third instruction uses a second address stored in the second entry in the default GOT table as an indication and jumps to the first entry in the call conversion table according to this indication; The execution unit 1004 is configured to: execute the third instruction, jump to the first entry in the call conversion table; execute the first instruction in the first entry, load the first address of the first symbol in memory to the first storage container; execute the second instruction, jump to the call converter; the call converter is configured to receive a call from the first component using a first calling convention and call the first symbol using a second calling convention according to the first address stored in the first storage container.
[0124] In a possible implementation, the dynamic linker further includes a dynamic link library runtime resolution component for establishing a dynamic link symbol binding relationship; the initial value of the second entry in the default GOT table during the initialization of the first component is a default value; the first component includes a third instruction; the execution unit 1004 is configured to: when the first component first triggers the execution of the third instruction, the third instruction uses the default value in the second entry in the default GOT table as an indication and jumps to a fourth instruction according to this indication; where the fourth instruction may be located in a default PLT table or a stub table; execute the fourth instruction, jump to the dynamic link library runtime resolution component; the filling unit 1002 is configured to fill the second address to the second entry in the default GOT table through the dynamic link library runtime resolution component.
[0125] In a possible implementation manner, a generating unit 1001 is configured to generate a first entry of a call conversion table through a dynamic linker when a first component is initialized; a filling unit 1002 is configured to fill a second address of the first entry in a memory into a second entry of a default GOT table.
[0126] In a possible implementation manner, the dynamic linker further includes a dynamic-link library runtime resolution component for establishing a dynamic-link symbol binding relationship; the filling unit 1002 is further configured to: when the first component is initialized, pre-fill a convention value into a fifth entry of a real address table through the dynamic linker, where the convention value is used to indicate that a first symbol is not bound; a triggering unit 1003 is further configured to: trigger the execution of a third instruction through the dynamic linker or the first component; wherein, the third instruction uses the second address stored in the second entry of the default GOT table as an indication and jumps to the first entry of the call conversion table according to the indication; an execution unit 1004 is further configured to: execute the third instruction, jump to the first entry in the call conversion table; execute a first instruction in the first entry, load the convention value indicating that the first symbol is not bound from the fifth entry of the real address table into a first storage container; execute a second instruction, jump to a call converter; determine, by the call converter according to the convention value in the first storage container, that the first symbol is not bound, and jump to the dynamic-link library runtime resolution component.
[0127] In a possible implementation manner, the filling unit 1002 is further configured to: fill a first address of the first symbol in a memory into the fifth entry of the real address table through the dynamic-link library runtime resolution component.
[0128] In a possible implementation manner, the execution unit 1004 is further configured to: determine a first address of the first symbol in a memory through the dynamic-link library runtime resolution component according to a third address to which a first dynamic-link library is loaded and an address offset of the first symbol in the first dynamic-link library.
[0129] In a possible implementation manner, the triggering unit 1003 is further configured to: trigger the execution of the third instruction through the dynamic linker or the first component; the execution unit 1004 is further configured to: execute the third instruction, jump to the first entry in the call conversion table; execute a first instruction in the first entry, load the first address of the first symbol from the fifth entry of the real address table into a first storage container; execute a second instruction, jump to the call converter; the dynamic-link call conversion device further includes a calling unit 1005 configured to accept a call of the first component using a first calling convention through the call converter and call the first symbol using a second calling convention according to the first address stored in the first storage container.
[0130] In a possible implementation, the execution unit 1004 is specifically configured to: when the first component is initialized, complete the immediate binding process for all symbols dynamically linked to by the first component through the dynamic linker, and fill the second address of the first entry in memory into the second entry of the default GOT table.
[0131] In a possible implementation, the first instruction is used to indicate directly loading the first address of the first symbol using an immediate number; the execution unit 1004 is further configured to: execute the first instruction in the first entry, and load the first address of the first symbol in memory into the first storage container using an immediate number.
[0132] In a possible implementation, the dynamic link call conversion device further includes a loading unit 1006, configured to: determine whether to load the first dynamic link library; if it is determined by the dynamic linker that the first dynamic link library has not been loaded, search for the first dynamic link library in the search paths that conform to the first calling convention used by the first component and all foreign calling conventions supported by call conversion; after the first dynamic link library is found, load the first dynamic link library into memory.
[0133] In a possible implementation, the generation unit 1001 is further configured to: after generating the call conversion table, set the call conversion table to be readable, executable, and non-writable.
[0134] In a possible implementation, the addresses of the entries in the call conversion table are consecutive in memory, or the addresses of the entries in the call conversion table are not consecutive in memory.
[0135] In a possible implementation, the generation unit 1001 is further configured to: for the real address table implementing lazy binding, set the real address table to be readable, writable, and non-executable, where the real address table is used to fill in the first address of the first symbol in memory, or is used to fill in a convention value indicating that the first symbol is not bound; or, for the real address table implementing immediate binding, set the real address table to be readable, non-writable, and non-executable, where the real address table is used to fill in the first address of the first symbol in memory.
[0136] In a possible implementation, the addresses of the entries in the real address table are consecutive in memory, or the addresses of the entries in the real address table are not consecutive in memory.
[0137] In a possible implementation, the first component is a program, or the first component is a second dynamic link library.
[0138] Based on the same inventive concept, an embodiment of the present application provides a dynamic link call conversion device 1100, and the dynamic link call conversion device 1100 may be, for example, a computing device. As Figure 11 shown, the dynamic link call conversion device 1100 includes at least one processor 1101 and a memory 1102 connected to the at least one processor. In the embodiment of the present application, the specific connection medium between the processor 1101 and the memory 1102 is not limited. Figure 11 Taking the example that the processor 1101 and the memory 1102 are connected through a bus. The bus can be divided into an address bus, a data bus, a control bus, etc.
[0139] In the embodiment of the present application, the memory 1102 stores instructions executable by the at least one processor 1101. By executing the instructions stored in the memory 1102, the at least one processor 1101 can implement the above-mentioned dynamic link call conversion method.
[0140] Among them, the processor 1101 is the control center of a processing device 1100 for exception instructions. It can connect various parts of the computer device through various interfaces and lines, and perform resource settings by running or executing instructions stored in the memory 1102 and calling data stored in the memory 1102. Optionally, the processor 1101 may include one or more determination units. The processor 1101 may integrate an application processor and a modulation and demodulation processor. Among them, the application processor mainly processes the operating system, user interface, application programs, etc., and the modulation and demodulation processor mainly processes wireless communication. It can be understood that the above-mentioned modulation and demodulation processor may not be integrated into the processor 1101. In some embodiments, the processor 1101 and the memory 1102 may be implemented on the same chip, and in some embodiments, they may also be separately implemented on independent chips.
[0141] The processor 1101 may be a general-purpose processor, such as a central processing unit (CPU), a digital signal processor, an application specific integrated circuit (ASIC), a field programmable gate array, or other programmable logic devices, discrete gate or transistor logic devices, discrete hardware components, and can implement or execute the various methods, steps, and logic block diagrams disclosed in the embodiments of the present application. The general-purpose processor may be a microprocessor or any conventional processor, etc. The steps of the method disclosed in combination with the embodiments of the present application can be directly embodied as being executed by a hardware processor, or executed by a combination of hardware and software modules in the processor.
[0142] The memory 1102, as a non-volatile computer-readable storage medium, can be used to store non-volatile software programs, non-volatile computer-executable programs, and modules. The memory 1102 can include at least one type of storage medium. For example, it can include flash memory, hard disks, multimedia cards, card-type memories, random access memory (RAM), static random access memory (SRAM), programmable read-only memory (PROM), read-only memory (ROM), electrically erasable programmable read-only memory (EEPROM), magnetic memories, magnetic disks, optical disks, and so on. The memory 1102 is any other medium that can be used to carry or store the desired program code in the form of instructions or data structures and can be accessed by a computer, but is not limited thereto. The memory 1102 in the embodiments of the present application can also be a circuit or any other device capable of implementing a storage function, for storing program instructions and / or data.
[0143] Based on the same technical concept, the embodiments of the present application also provide a computer-readable storage medium storing a computer-executable program for causing a computer to execute the dynamic link call conversion method in any of the above manners.
[0144] The embodiments of the present application provide a computer program product including a computer program executable by a computer device. When the program runs on the computer device, it causes the computer device to execute the dynamic link call conversion method in any of the above manners.
[0145] Those skilled in the art should understand that the embodiments of the present application can be provided as a method, a system, or a computer program product. Therefore, the present application can take the form of a complete hardware embodiment, a complete software embodiment, or an embodiment combining software and hardware aspects. Moreover, the present application can take the form of a computer program product implemented on one or more computer-usable storage media (including but not limited to disk memories, CD-ROMs, optical memories, etc.) containing computer-usable program code.
[0146] This application is described with reference to the flowcharts and / or block diagrams of methods, apparatus (systems), and computer program products according to the application. It should be understood that each flow and / or block in the flowchart and / or block diagram, and the combination of flows and / or blocks in the flowchart and / or block diagram, can be implemented by computer program instructions. These computer program instructions can be provided to the processor of a general purpose computer, special purpose computer, embedded processor, or other programmable data processing device to produce a machine, such that the instructions executed by the processor of the computer or other programmable data processing device produce means for implementing the functions specified in the flow Figure 1 one flow or multiple flows and / or blocks Figure 1 means for implementing the functions specified in one block or multiple blocks.
[0147] These computer program instructions can also be stored in a computer-readable memory that can direct a computer or other programmable data processing device to work in a specific manner, such that the instructions stored in the computer-readable memory produce a manufactured article including instruction means that implement the functions specified in the flow Figure 1 one flow or multiple flows and / or blocks Figure 1 means for implementing the functions specified in one block or multiple blocks.
[0148] These computer program instructions can also be loaded onto a computer or other programmable data processing device, such that a series of operation steps are executed on the computer or other programmable device to produce a computer-implemented process, so that the instructions executed on the computer or other programmable device provide steps for implementing the functions specified in the flow Figure 1 one flow or multiple flows and / or blocks Figure 1 means for implementing the functions specified in one block or multiple blocks.
[0149] Obviously, those skilled in the art can make various changes and modifications to this application without departing from the spirit and scope of this application. Thus, if these modifications and variations of this application fall within the scope of the claims of this application and their equivalent technologies, this application is also intended to include these changes and variations.
Claims
1. A dynamic link call conversion method, characterized in that: include: If, when performing symbol resolution and binding for a first component, the first component is dynamically linked to a first symbol in a first dynamic link library, and the first symbol has not established a dynamic link symbol binding relationship with the first component, and the first component and the first dynamic link library use different calling conventions, then a first table entry of a call conversion table is generated by a dynamic linker, the first table entry includes a first instruction and a second instruction, the first instruction is used to instruct to load a first address of the first symbol in a memory to a specified first storage container, and the second instruction is used to instruct to jump to a call converter; The second address of the first table entry in the memory is filled into the second table entry in the default GOT table through the dynamic linker; wherein the default GOT table belongs to the first component.
2. The method according to claim 1, characterized in that After the dynamic linker fills the second address of the first entry in the memory into the second entry in the default GOT table, the method further includes: The execution of a third instruction is triggered by the dynamic linker or the first component; wherein the third instruction uses the second address stored in the second table entry in the default GOT table as an indication, and jumps to the first table entry in the call conversion table according to the indication; Execute the third instruction and jump to the first table entry in the call conversion table; Execute a first instruction in the first table entry to load a first address of the first symbol in the memory into the first storage container; The second instruction is executed to jump to the call converter; the call converter is used to accept the call of the first component using the first calling convention, and call the first symbol using the second calling convention according to the first address stored in the first storage container.
3. The method according to claim 1, characterized in that The dynamic linker also includes a dynamic link library runtime parsing component for establishing a dynamic link symbol binding relationship; the initial value of the second table entry in the default GOT table when the first component is initialized is a default value; The first component includes a third instruction; The step of filling the second address of the first entry in the memory into the second entry in the default GOT table by the dynamic linker includes: When the first component triggers the execution of the third instruction for the first time, the third instruction uses the default value in the second table entry in the default GOT table as an indication, and jumps to the fourth instruction according to the indication; wherein the fourth instruction is located in the default PLT table or the stub table; Execute the fourth instruction to jump to the dynamic link library runtime parsing component; The second address is filled into the second table entry in the default GOT table through the dynamic link library runtime parsing component.
4. The method according to claim 1, characterized in that The step of generating a first table entry of a call conversion table by a dynamic linker, and filling a second address of the first table entry in a memory into a second table entry in a default GOT table by the dynamic linker, comprises: When the first component is initialized, a first table entry of a call conversion table is generated by the dynamic linker, and a second address of the first table entry in the memory is filled into a second table entry in a default GOT table.
5. The method according to claim 4, characterized in that The dynamic linker also includes a dynamic link library runtime parsing component for establishing a dynamic link symbol binding relationship; the method also includes: When the first component is initialized, pre-filling a fifth table entry of the real address table with a predetermined value through the dynamic linker, wherein the predetermined value is used to indicate that the first symbol is not bound; The execution of a third instruction is triggered by the dynamic linker or the first component; wherein the third instruction uses the second address stored in the second table entry in the default GOT table as an indication, and jumps to the first table entry in the call conversion table according to the indication; Execute the third instruction and jump to the first table entry in the call conversion table; executing a first instruction in the first table entry to load the agreed value indicating that the first symbol is not bound from a fifth table entry of the real address table into a first storage container; Execute the second instruction and jump to the calling converter; The calling converter determines that the first symbol is not bound according to the agreed value in the first storage container, and jumps to the dynamic link library runtime parsing component.
6. The method according to claim 3 or 5, characterized in that After jumping to the dynamic link library runtime parsing component, the method further includes: The first address of the first symbol in the memory is filled into the fifth table entry in the real address table through the dynamic link library runtime parsing component.
7. The method according to claim 6, characterized in that Before the dynamic link library runtime parsing component fills the first address of the first symbol in the memory into the fifth table entry in the real address table, the method further includes: The first address of the first symbol in the memory is determined by the dynamic link library runtime parsing component according to the third address to which the first dynamic link library is loaded and the address offset of the first symbol in the first dynamic link library.
8. The method according to claim 6, characterized in that After the dynamic link library runtime parsing component fills the first address of the first symbol in the memory into the fifth table entry in the real address table, the method further includes: triggering execution of a third instruction through the dynamic linker or the first component; Execute the third instruction and jump to the first table entry in the call conversion table; executing the first instruction in the first table entry to load the first address of the first symbol from the fifth table entry in the real address table into the first storage container; Execute the second instruction and jump to the calling converter; The call translator accepts a call from the first component using a first calling convention, and calls the first symbol using a second calling convention according to the first address stored in the first storage container.
9. The method according to claim 2, characterized in that The step of filling the second address of the first entry in the memory into the second entry in the default GOT table by the dynamic linker includes: When the first component is initialized, the dynamic linker completes an immediate binding process for all symbols dynamically linked to the first component, and fills the second address of the first table entry in the memory into the second table entry in the default GOT table.
10. The method according to claim 1, characterized in that The first instruction is used to instruct to directly load the first address of the first symbol using immediate load; the method further includes: A first instruction in the first table entry is executed to load a first address of the first symbol in the memory into the first storage container using an immediate value.
11. The method according to claim 1, characterized in that The method further comprises: Determine whether to load the first dynamic link library; If it is determined through the dynamic linker that the first dynamic link library has not been loaded, searching for the first dynamic link library in a search path that conforms to a first calling convention used by the first component and all foreign calling conventions that can be supported by call conversion, according to the name or path of the first dynamic link library; After searching for the first dynamic link library, the first dynamic link library is loaded into the memory.
12. The method according to claim 1, characterized in that The method further comprises: After the call conversion table is generated, the call conversion table is set to be readable, executable, and non-writable.
13. The method according to claim 1, characterized in that The addresses of the entries in the call conversion table in the memory are continuous, or the addresses of the entries in the call conversion table in the memory are discontinuous.
14. The method according to claim 2, characterized in that The method further comprises: For a real address table implementing delayed binding, the real address table is set to be readable and writable but not executable, and the real address table is used to fill in the first address of the first symbol in the memory, or to fill in a conventional value indicating that the first symbol is not bound; or, For the real address table for implementing immediate binding, the real address table is set to be readable, non-writable, and non-executable, and the real address table is used to fill in the first address of the first symbol in the memory.
15. The method according to claim 5, characterized in that The addresses of the entries in the real address table in the memory are continuous, or the addresses of the entries in the real address table in the memory are discontinuous.
16. The method according to claim 1, wherein: The first component is a program, or the first component is a second dynamic link library.
17. A computer device, characterized in that: include: A memory for storing program instructions; A processor, configured to call the program instructions stored in the memory, and execute the method according to any one of claims 1 to 16 according to the obtained program.
18. A computer-readable storage medium, characterized in that: The computer-readable storage medium stores computer-executable instructions, and the computer-executable instructions are used to enable a computer to execute any one of the methods of claims 1 to 16.
19. A computer program product, characterized in that The invention comprises a computer program executed by a computer device, and when the program is run on the computer device, the computer device is caused to execute the steps of any one of the methods of claims 1 to 16.
Citation Information
Patent Citations
Defect detection method and system for cross-architecture firmware heap memory
CN111597109A
Memory statistical method, memory statistical device and computer readable storage medium
CN114968702A
Method for linking in advance during compiling
CN115543332A
Function calling method and device, equipment and medium
CN117093281A
Stack backtracking method and device, electronic equipment and storage medium
CN117093391A
