Binary code optimization method and system, electronic equipment, medium and program product
By performing topological sorting and rewriting of the function call graph and basic block control flow graph of the ARM64 architecture binary code, the complexity problem in binary code optimization under the ARM64 architecture is solved, achieving efficient code rewriting and inline expansion, and improving code execution efficiency and logical integrity.
Patent Information
- Application Number
- CN202511595093.1
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- Filing Date
- 2025-11-03
- Publication Date
- 2026-02-10
AI Technical Summary
Existing technologies cannot effectively handle the complex branch instructions and memory access patterns under the ARM64 architecture. Function call inlining and unrolling can easily disrupt the original control flow of the program. The lack of a systematic basic block topology sorting algorithm leads to low code rewriting efficiency and makes it difficult to achieve efficient optimization while maintaining the program semantics.
By determining the function call graph and basic block control flow graph of the binary code, topological sorting is performed, memory addresses and function addresses are rewritten, function inlining expansion is performed, and the binary code is re-encoded using assembly instructions to generate optimized binary code.
The code execution order was optimized, branch prediction errors were reduced, instruction cache hit rate was improved, and a precise rewrite of the ARM64 architecture was achieved, ensuring program logic integrity and execution efficiency.
Smart Images

Figure CN121501289A_ABST
Abstract
Description
Technical Field
[0001] This disclosure relates to computer technology, and in particular to a binary code optimization method, system, electronic device, medium, and program product. Background Technology
[0002] In fields such as binary code analysis, software protection, and vulnerability patching, it is often necessary to modify and optimize binary programs. Traditional static binary rewriting techniques face several challenges: First, they cannot effectively handle the complex branch instructions and memory access patterns under the ARM64 (Advanced RISC Machine 64-bit) architecture; second, the inlining and unrolling of function calls can easily disrupt the original control flow of the program; third, the lack of a systematic basic block topology sorting algorithm leads to low execution efficiency after code rewriting; and finally, existing techniques struggle to achieve efficient optimization while maintaining the program's semantics. Therefore, it is necessary to propose an efficient binary code rewriting and optimization method for the ARM64 architecture to address the aforementioned technical problems. Summary of the Invention
[0003] To address the technical problems in related technologies, embodiments of this disclosure provide a binary code optimization method, system, electronic device, medium, and program product.
[0004] According to a first aspect of the present disclosure, a binary code optimization method is provided, the method comprising:
[0005] Based on the first binary code, determine the function call graph and basic block control flow graph of the first binary code;
[0006] The control flow graph of each basic block is topologically sorted to obtain the basic block layout.
[0007] Based on the basic block layout, the first binary code is rewritten to update the memory addresses and function addresses in all instructions of the first binary code, thereby obtaining the second binary code;
[0008] Based on the function call graph, the target function call in the second binary code is inlined and expanded to obtain the third binary code;
[0009] The third binary code is re-encoded using assembly instructions to obtain the fourth binary code, which is the optimized target binary code.
[0010] As an optional embodiment, the step of performing topological sorting on the basic block control flow graphs to obtain the basic block layout includes:
[0011] For each basic block control flow, the basic block control flow is traversed starting from the entry basic block of the function corresponding to the basic block control flow, so that when the recursion returns, the basic blocks traversed in the basic block control flow are pushed into the preset target stack.
[0012] In response to traversing all the basic blocks in the basic block control flow, all the basic blocks in the preset target stack are sequentially added to the preset topology list in order from top to bottom of the stack to obtain the first sorting result;
[0013] Based on the first sorting result, determine whether the basic block control flow includes basic blocks referenced by external mechanisms;
[0014] In response to whether the basic block control flow includes basic blocks referenced by external mechanisms, the basic blocks referenced by external mechanisms are added to a preset position in the first sorting result to obtain a second sorting result, which is the basic block layout.
[0015] As an optional embodiment, the step of traversing the basic block control flow starting from the entry basic block of the function corresponding to each basic block control flow, so as to push the traversed basic blocks in the basic block control flow onto a preset target stack upon recursion return, includes:
[0016] Initialize a preset target stack and a preset basic block set. The preset target stack is used to sequentially store the basic blocks traversed in the basic block control flow. The preset basic block set is used to mark the basic blocks traversed in the basic block control flow and store the marked basic blocks.
[0017] The entry block of the function is used as the root node of the depth-first search traversal. The recursive depth-first search function is called to traverse the control flow of the basic block, so as to add any basic block traversed to the preset basic block set and push the basic block onto the preset target stack.
[0018] As an optional embodiment, the step of rewriting the first binary code based on the basic block layout to update the memory addresses and function addresses in all instructions of the first binary code to obtain the second binary code includes:
[0019] For each basic block in the basic block layout, all machine instructions in each basic block are traversed to decode each machine instruction and identify the instruction type of the machine instruction.
[0020] Based on the instruction type of each machine instruction, the machine instructions in all basic blocks of the first binary code are rewritten according to the preset instruction rewriting rules corresponding to the instruction type, so as to update the memory addresses and function addresses in all instructions of the first binary code, and thus obtain the second binary code.
[0021] As an optional embodiment, the step of rewriting the machine instructions in all basic blocks of the first binary code according to the instruction type of each machine instruction and a preset instruction rewriting rule corresponding to the instruction type, to update the memory addresses and function addresses in all instructions of the first binary code, to obtain the second binary code, includes:
[0022] In response to any of the machine instructions being a load data instruction, the load data instruction is modified into a first instruction combination, the first instruction combination including an address read instruction and a load data instruction;
[0023] In response to any of the machine instructions being a linked branch jump instruction, the linked branch jump instruction is modified into a second instruction combination, the second instruction combination including an address read instruction and a linked register jump instruction;
[0024] In response to any of the machine instructions being of the first unconditional jump instruction or the first conditional jump instruction, calculate the offset from the source memory address of the current machine instruction to the target memory address of the target basic block.
[0025] In response to determining that the offset is within the instruction encoding range, a second unconditional jump instruction or a second conditional jump instruction is generated to point to the target memory address of the target basic block.
[0026] As an optional embodiment, the step of inlining and expanding the target function calls in the second binary code according to the function call graph to obtain the third binary code includes:
[0027] The complexity of the target function is determined based on the function call graph to determine whether the target function meets the calling conditions.
[0028] In response to determining that the target function meets the calling conditions, the target function is inlined and expanded to obtain the third binary code.
[0029] As an optional embodiment, determining the complexity of the target calling function based on the function call graph to determine whether the target calling function meets the calling conditions includes:
[0030] The complexity of the target call function is determined by analyzing the number of basic blocks, number of instructions, control flow depth, loop depth, in-degree, out-degree, and function side effects of the target call function based on the function call graph.
[0031] The complexity of the target function determines whether the target function meets the calling conditions.
[0032] As an optional embodiment, in response to determining that the target calling function meets the calling conditions, the target calling function is inlined to obtain a third binary code, including:
[0033] In response to determining that the target function being called meets the calling conditions, the instruction sequence of the target function being called is obtained;
[0034] The instruction sequence of the target function is inserted into the target call point, and the returned memory address and register state are stored to obtain the third binary code.
[0035] As an optional embodiment, the third binary code is re-encoded using assembly instructions to obtain a fourth binary code, wherein the fourth binary code is the optimized target binary code, including:
[0036] The third binary code is optimized by using preset code optimization instructions to delete consecutive and identical machine code instructions in the third binary code, and in response to determining that the value of any register is a constant value, the values of all such registers in the third binary code are replaced with such constant values to obtain the optimized third binary code.
[0037] The third binary code is encoded into machine code of a preset code format using assembly instructions and arranged according to a preset code layout order to obtain the fourth binary code, which is the optimized target binary code.
[0038] According to a second aspect of the present disclosure, a binary code optimization system is provided, the system comprising:
[0039] The binary code analysis module is used to determine the function call graph and basic block control flow graph of the first binary code based on the first binary code.
[0040] The topology sorting module is used to perform topology sorting on each of the basic block control flow graphs to obtain the basic block layout.
[0041] The instruction rewriting module is used to rewrite the first binary code based on the basic block layout to update the memory addresses and function addresses in all instructions of the first binary code, so as to obtain the second binary code.
[0042] The inline expansion module is used to inline expand the target function calls in the second binary code according to the function call graph to obtain the third binary code;
[0043] The code generation module is used to re-encode the third binary code using assembly instructions to obtain a fourth binary code, which is the optimized target binary code.
[0044] As an optional embodiment, the topology sorting module includes:
[0045] The basic block traversal unit is used to traverse the basic block control flow for each basic block control flow, starting from the entry basic block of the function corresponding to the basic block control flow, so as to push the basic blocks traversed in the basic block control flow onto the preset target stack when recursion returns.
[0046] The first basic block sorting unit is used to, in response to traversing all basic blocks in the basic block control flow, sequentially add all basic blocks in the preset target stack to the preset topology list in order from the top of the stack to the bottom of the stack, to obtain the first sorting result;
[0047] The first determining unit is configured to determine, based on the first sorting result, whether the basic block control flow includes basic blocks referenced by external mechanisms;
[0048] The second basic block sorting unit is used to add the basic block referenced by the external mechanism to a preset position in the first sorting result in response to whether the basic block control flow includes a basic block referenced by an external mechanism, so as to obtain a second sorting result, wherein the second sorting result is the basic block layout.
[0049] As an optional embodiment, the basic block traversal unit is specifically used for:
[0050] Initialize a preset target stack and a preset basic block set. The preset target stack is used to sequentially store the basic blocks traversed in the basic block control flow. The preset basic block set is used to mark the basic blocks traversed in the basic block control flow and store the marked basic blocks.
[0051] The entry block of the function is used as the root node of the depth-first search traversal. The recursive depth-first search function is called to traverse the control flow of the basic block, so as to add any basic block traversed to the preset basic block set and push the basic block onto the preset target stack.
[0052] As an optional embodiment, the instruction rewriting module includes:
[0053] The instruction traversal unit is used to traverse all machine instructions in each basic block of the basic block layout to decode each machine instruction and identify the instruction type of the machine instruction.
[0054] The instruction rewriting unit is used to rewrite the machine instructions in all basic blocks of the first binary code according to the instruction type of each machine instruction and a preset instruction rewriting rule corresponding to the instruction type, so as to update the memory addresses and function addresses in all instructions of the first binary code to obtain the second binary code.
[0055] As an optional embodiment, the instruction rewriting unit is specifically used for:
[0056] In response to any of the machine instructions being a load data instruction, the load data instruction is modified into a first instruction combination, the first instruction combination including an address read instruction and a load data instruction;
[0057] In response to any of the machine instructions being a linked branch jump instruction, the linked branch jump instruction is modified into a second instruction combination, the second instruction combination including an address read instruction and a linked register jump instruction;
[0058] In response to any of the machine instructions being of the first unconditional jump instruction or the first conditional jump instruction, calculate the offset from the source memory address of the current machine instruction to the target memory address of the target basic block.
[0059] In response to determining that the offset is within the instruction encoding range, a second unconditional jump instruction or a second conditional jump instruction is generated to point to the target memory address of the target basic block.
[0060] As an optional embodiment, the inline expansion module includes:
[0061] The condition judgment unit is used to determine the complexity of the target calling function based on the function call graph, so as to determine whether the target calling function meets the calling conditions;
[0062] The inline expansion unit is used to perform inline expansion on the target call function in response to determining that the target call function meets the call conditions, to obtain the third binary code.
[0063] As an optional embodiment, the condition judgment unit is specifically used for:
[0064] The complexity of the target call function is determined by analyzing the number of basic blocks, number of instructions, control flow depth, loop depth, in-degree, out-degree, and function side effects of the target call function based on the function call graph.
[0065] The complexity of the target function determines whether the target function meets the calling conditions.
[0066] As an optional embodiment, the inline expansion unit is specifically used for:
[0067] In response to determining that the target function being called meets the calling conditions, the instruction sequence of the target function being called is obtained;
[0068] The instruction sequence of the target function is inserted into the target call point, and the returned memory address and register state are stored to obtain the third binary code.
[0069] As an optional embodiment, the code generation module includes:
[0070] The code optimization unit is used to optimize the third binary code by means of preset code optimization instructions, so as to delete the machine code instructions that appear consecutively and are the same in the third binary code, and in response to determining that the value of any register is a constant value, to replace the value of all such registers in the third binary code with such constant value, so as to obtain the optimized third binary code.
[0071] The code encoding unit is used to encode the third binary code into machine code of a preset code format through assembly instructions, and arrange them according to a preset code layout order to obtain the fourth binary code, which is the optimized target binary code.
[0072] According to a third aspect of the present disclosure, an electronic device is provided, comprising:
[0073] Memory, used to store computer program products;
[0074] A processor is configured to execute a computer program product stored in the memory, and when the computer program product is executed, to implement the method described in the first aspect above.
[0075] According to a fourth aspect of the present disclosure, a computer-readable storage medium is provided that stores computer program instructions thereon, which, when executed by a processor, implement the method described in the first aspect.
[0076] According to a fifth aspect of the present disclosure, a computer program product is provided, including computer program instructions that, when executed by a processor, implement the method described in the first aspect above.
[0077] The technical solution of this disclosure determines the function call graph and basic block control flow graph from the source binary code to be optimized. Then, each basic block control flow graph is topologically sorted, optimizing the code execution order, reducing branch prediction errors, and improving instruction cache hit rate. Furthermore, based on the topological sorting results, the binary code to be optimized is rewritten, updating the memory addresses and function addresses in all instructions. This allows for precise rewriting of critical instructions tailored to specific system architectures (e.g., ARM64 architecture), ensuring accurate address calculations. Inlining and expanding the target function calls in the binary code based on the function call graph allows for selective inlining of functions (i.e., target function calls) through strict context management, reducing function call overhead and eliminating control flow confusion and register pollution problems that inlining might introduce, while ensuring the integrity of the original program logic. Finally, the inlined and expanded code is re-encoded to generate the final optimized target binary code. This allows for deep optimization of binary code by comprehensively utilizing inlining, code layout, and instruction-level optimization while maintaining strict semantic integrity.
[0078] The technical solutions of this disclosure will be further described in detail below with reference to the accompanying drawings and embodiments. Attached Figure Description
[0079] The accompanying drawings, which form part of this specification, illustrate embodiments of this disclosure and, together with the description, serve to explain the principles of this disclosure.
[0080] This disclosure will become clearer with reference to the accompanying drawings and the following detailed description, wherein:
[0081] Figure 1 This is a schematic flowchart illustrating a binary code optimization method according to an embodiment of the method disclosed herein.
[0082] Figure 2 This is a schematic diagram of a basic block control flow graph according to an embodiment of the present disclosure.
[0083] Figure 3 This is a schematic structural block diagram of a binary code optimization system according to one embodiment of the system disclosed herein.
[0084] Figure 4 This is a schematic structural block diagram of an electronic device according to an embodiment of the present disclosure. Detailed Implementation
[0085] In fields such as software security, performance analysis, and system optimization, directly modifying and optimizing compiled binary programs is a core and challenging technique. With the booming development of mobile internet and embedded systems, the ARM64 architecture has become mainstream. The core characteristics of ARM64 binary code include, but are not limited to, the following:
[0086] First, it uses a fixed-length 32-bit instruction encoding. This characteristic means that a single instruction cannot hold a 64-bit absolute address immediate value. Therefore, ARM64 employs a complex and sophisticated address calculation model that heavily relies on PC (Personal Computer) relative addressing and page address loading: ① PC relative addressing: Instructions such as B (jump) and BL (call or linked jump) have operands that are offsets relative to the current program counter; ② Page address loading: Instructions such as ADRP (address read instruction) load the base address (4KB aligned) of the page containing the current PC or the page containing the target address into a register. Then, an ADD (addition instruction) or LDR (memory access instruction) is used to add the page offset to form the complete 64-bit address. Because of this characteristic, any movement of a code segment (such as insertion, deletion, or reordering instructions) will change the instruction's own PC value, thus rendering all PC-based relative offset and page address calculations ineffective. The rewriter must accurately and without omission identify and correct all these address-related instructions; otherwise, the program will immediately crash or behave abnormally.
[0087] Secondly, ARM64 has 31 general-purpose registers and has established a very regular procedure call standard, which clearly defines the purpose of parameter passing, return values, temporary registers and callee save registers. Thus, when performing advanced optimizations such as function inlining, without fine-grained context management, they may simply "copy and paste" the instruction sequence of the called function to the calling point, thereby breaking the program semantics.
[0088] Furthermore, the ARM64 architecture provides a rich set of conditional branch instructions, and its loop and exception handling structures are highly complex at the binary level. Traditional basic block sorting algorithms based on linear scanning or simple heuristics struggle to generate a code layout that maximizes the sequential execution efficiency of the CPU (Central Processing Unit), leading to frequent instruction cache misses and decreased branch predictor accuracy. This severely offsets the performance gains from rewriting and may even cause performance degradation.
[0089] To address the technical problems in related technologies, this disclosure provides a binary code optimization method, system, electronic device, medium, and program product. The technical solutions of the embodiments of this disclosure are described in detail below with reference to the appendix, so that those skilled in the art can clearly and accurately understand the technical solutions of the embodiments of this disclosure.
[0090] Figure 1 This is a schematic flowchart illustrating a binary code optimization method according to one embodiment of the method disclosed herein. Figure 1 As shown, a binary code optimization method according to an embodiment of this disclosure may include the following steps:
[0091] Step 101: Based on the first binary code, determine the function call graph and basic block control flow graph of the first binary code.
[0092] The first binary code is the binary code that needs optimization, such as binary code based on the ARM64 architecture. Taking ARM64 binary code as an example, it is a sequence of bytes that can be directly executed by the ARM64 processor, consisting of machine instructions (e.g., ADD X0, X1, X2) and data from the ARM64 instruction set. A function is a reusable sequence of instructions with a specific function in the binary code. In the context of ARM64, a function is usually defined by a standard prologue and epilogue. A basic block is the largest, continuous sequence of instructions within a function, where only the first instruction can serve as the entry point and only the last instruction can serve as the exit point. In general, a function consists of one or more basic blocks, which are the internal implementation details of the function; a function is the logical unit of code organization, while a basic block is the atomic unit of control flow analysis.
[0093] In this embodiment of the disclosure, a first binary code is used as the raw input, from which structured units such as functions and basic blocks are extracted to construct a basic block control flow graph and a function call graph. The basic block control flow graph describes the execution path within a function, and each basic block is a node in the basic block control flow graph.
[0094] The jump relationships between basic blocks form directed edges in the basic block control flow graph; while the function call graph describes the calling relationships between functions and is the program's "module dependency graph". Each function is a node in the function call graph. The BL (linked branch jump instruction, i.e., function call) instruction in one function points to another function, thus forming a directed edge from the caller to the callee in the function call graph.
[0095] For example, functions can be divided from the first binary code by identifying function prologues and epilogues (i.e., identifying function boundaries), and then basic blocks can be divided by identifying branch instructions. For any given function, a control flow graph (i.e., a basic block control flow graph) is constructed based on all the basic blocks within the function and their jump relationships, revealing the internal logical structure of the function (loops, conditional statements, etc.). For the first binary code, a function call graph of the entire program is constructed based on all its functions and the call relationships established through BL instructions, revealing the modular structure of the program and the dependencies between functions.
[0096] Step 102: Perform topological sorting on the control flow graph of each basic block to obtain the basic block layout.
[0097] In this embodiment of the disclosure, in order to enable the CPU to read instructions in memory order in most execution scenarios and reduce jumps, the basic blocks in the basic block control flow graph are rearranged linearly. As one implementation of this embodiment, for each basic block control flow, the basic block control flow is traversed starting from the entry basic block of the function corresponding to that basic block control flow, so that the traversed basic blocks in the basic block control flow are pushed onto a preset target stack upon recursion return; in response to traversing all basic blocks in the basic block control flow, all basic blocks in the preset target stack are sequentially added to a preset topology list in order from top to bottom of the stack, resulting in a first sorting result; based on the first sorting result, it is determined whether the basic block control flow includes basic blocks referenced by external mechanisms; in response to whether the basic block control flow includes basic blocks referenced by external mechanisms, the basic blocks referenced by external mechanisms are added to a preset position in the first sorting result, resulting in a second sorting result, which is the basic block layout. In this embodiment, the basic block layout is a linear list of basic blocks, which defines the physical memory order in which these basic blocks are placed in the rewritten binary file.
[0098] Furthermore, for each basic block control flow, the basic block control flow is traversed starting from the entry basic block of the function corresponding to that basic block control flow, so that the basic blocks traversed in the basic block control flow are pushed into the preset target stack when the recursion returns. This can be further implemented as follows: the preset target stack and the preset basic block set are initialized. The preset target stack is used to sequentially store the basic blocks traversed in the basic block control flow, and the preset basic block set is used to mark and store the marked basic blocks in the basic block control flow. The entry basic block of the function is used as the root node of the depth-first search traversal. The recursive depth-first search function is called to traverse the basic block control flow, so that any basic block traversed is added to the preset basic block set and pushed into the preset target stack.
[0099] It is understood that the topological sorting in this embodiment relies solely on the structural information of the control flow graph, namely the set of basic blocks and the set of directed edges between them. Specifically, taking the basic block control flow graph of any function and its entry basic block as input, an empty stack and an empty set visited (i.e., a preset target stack and a preset set of basic blocks) are initialized. Starting from the entry basic block, for example, a DFS (Depth-First Search) recursive function is called. The DFS recursive process for the current basic block B:
[0100] First, you can mark B as visited (visited.add(B)), which means adding it to the preset basic block set.
[0101] Then, iterate through all the successor basic blocks of B (i.e., all blocks pointed to by edges originating from B). For each unvisited successor S, recursively call DFS to process S.
[0102] Finally, after all the successors of B have been processed, B itself is pushed onto the preset target stack (stack.append(B)).
[0103] After the entire DFS process is completed, the order from the bottom to the top of the target stack is the reverse of the topological sort. By reversing the target stack or popping the blocks in sequence, the final topological sort result, i.e., the basic block layout, can be obtained.
[0104] In order to enable those skilled in the art to clearly and accurately understand this embodiment, the topological sorting process of this disclosure embodiment is described below through an example.
[0105] Suppose a basic block control flow graph of a function has the following structure: Figure 2 As shown, a topological sort is performed, starting from the entry basic block A:
[0106] Visiting A: Mark A as visited. It has a successor B, so visit B recursively.
[0107] Visiting B: Mark B as visited. It has a successor C, so visit C recursively.
[0108] Accessing C: Marks C as visited. It has successors D and F;
[0109] First visit D: Mark D as visited. D is a conditional branch, with successors E and B;
[0110] Visiting E: Mark E as visited. If E has a successor G, recursively visit G.
[0111] Accessing G: Marks G as visited. If G has no successor, push G onto the stack. The default target stack is [G].
[0112] After all subsequent processing of E is completed, E is pushed onto the stack, and the default target stack is [G, E].
[0113] D's other successor is B, but B has already been visited, so we'll skip it.
[0114] Once D is processed, push D onto the stack. The default target stack is: [G, E, D].
[0115] Returning to C, visit another successor F: mark F as visited. If F has no successor, push F onto the stack, then the default target stack is [G, E, D, F].
[0116] After all subsequent processing of C is completed, C is pushed onto the stack. The default target stack is: [G, E, D, F, C].
[0117] Returning to B, after all subsequent processing of B is completed, B is pushed onto the stack, and the default target stack is: [G, E, D, F, C, B];
[0118] Returning to A, after all subsequent processing of A is completed, push A onto the stack. The default target stack is: [G, E, D, F, C, B, A].
[0119] Final topological sorting result (preset target stack reversal / pop order): A->B->C->F->D->E->G.
[0120] Through this embodiment, reference Figure 2 The basic block control flow graph obtained by topological sorting has a main path A->B->C->D in the original execution order that is mostly continuous. Although the loop B->C->D->B is broken, the loop bodies B, C, and D are tightly arranged together. The target F of the conditional branch C->F is placed after C. If this branch is false, the execution flow can smoothly enter D. Compared with the layout in the original basic block control flow graph, the basic block layout obtained by topological sorting greatly reduces long-distance jumps, allowing the CPU to better utilize the cache and predictor during execution.
[0121] Step 103: Based on the basic block layout, rewrite the instructions of the first binary code to update the memory addresses and function addresses in all instructions of the first binary code, and obtain the second binary code.
[0122] Topological sorting changes the physical location of the first binary code in memory. Since all addresses in the first binary code (whether jump target addresses or data load addresses) are calculated based on the original layout, topological sorting assigns a new address to each basic block. All instructions referencing their old addresses become "pointers to the wrong location." Furthermore, taking the ARM64 architecture as an example, its instruction length is fixed at 4 bytes, making it impossible to embed 64-bit absolute addresses. It heavily relies on PC-relative addressing. When the code is moved, the PC (program counter) value of the instruction itself changes, and all relative offsets calculated based on the old PC become invalid. Therefore, without instruction rewriting, the program's control flow will be disordered, data access will fail, and the program may crash immediately or exhibit unpredictable behavior.
[0123] In this embodiment of the disclosure, step 103 can be implemented as follows: for each basic block in the basic block layout, traverse all machine instructions in each basic block to decode each machine instruction, identify the instruction type of the machine instruction, and then rewrite the machine instructions in all basic blocks of the first binary code according to the instruction type of each machine instruction and the preset instruction rewriting rules corresponding to the instruction type, so as to update the memory address and function address in all instructions of the first binary code to obtain the second binary code.
[0124] Furthermore, based on the instruction type of each machine instruction, the machine instructions in all basic blocks of the first binary code are rewritten according to the preset instruction rewriting rules corresponding to the instruction type, so as to update the memory address and function address in all instructions of the first binary code, and the second binary code can be implemented as follows: in response to any of the machine instructions being a load data instruction, the load data instruction is modified into a first instruction combination, wherein the first instruction combination includes an address read instruction and a load data instruction;
[0125] In response to any machine instruction whose instruction type is a linked branch jump instruction, the linked branch jump instruction is modified into a second instruction combination, the second instruction combination including an address read instruction and a linked register jump instruction; in response to any machine instruction whose instruction type is a first unconditional jump instruction or a first conditional jump instruction, the offset from the source memory address of the current machine instruction to the target memory address of the target basic block is calculated; in response to determining that the offset is within the instruction encoding range, a second unconditional jump instruction or a second conditional jump instruction is generated to point to the target memory address of the target basic block.
[0126] Specifically, this step can take a topologically sorted linear list of basic blocks (i.e., the basic block layout obtained in step 102, which provides a new address for each basic block), a global layout mapping table (providing new addresses for functions and data), and the original instruction sequence as input. Then, it sequentially traverses each basic block of the linear list and decodes each machine instruction within the block, identifying its instruction type (i.e., opcode, such as LDR, BL, B, etc.) and operands. Based on the instruction type, it rewrites the instruction according to the rewriting rules corresponding to the instruction type (preset instruction rewriting rules), distributing it to different rewriting rules for processing, including:
[0127] 1. Rewrite LDR (Load Data Instruction)
[0128] Assuming LDR X0, where 0x12345 in [0x12345] is the old data address, then the ADRP+LDR combination can be used to rewrite the data. Specific steps are as follows:
[0129] ① Query the global layout mapping table to find the new address 0x23456 corresponding to the old data address 0x12345;
[0130] ② Generate ADRPXt, [page_address] (i.e., address read instruction): Calculate the base address (i.e., 0x23000) of the 4KB page where the new address 0x23456 is located, and generate an ADRP instruction to load it into a temporary register Xt;
[0131] ③ Generate LDR X0, [Xt,#offset] (i.e., load data instruction): Calculate the offset of the new address within the page (i.e., 0x456) and generate an LDR instruction to load data from [Xt+0x456].
[0132] In this way, an instruction that depends on an absolute address is rewritten into two position-independent instructions, enabling correct access to data at the new location.
[0133] 2. Rewrite the BL (function call or linked branch jump instruction).
[0134] Assuming that `target_func` in `BL target_func` is the old function entry address, then the rewrite can be implemented using the ADRP+BLR combination. Specific steps are as follows:
[0135] ① Locate the new entry address of target_func by querying the function call graph or global layout mapping table;
[0136] ② Generate ADRP Xt, [func_page_address] (i.e., address read instruction): Calculate the base address of the page where the new function address is located;
[0137] ③ Generate BLR Xt (linked register jump instruction): indirectly jump to the new function address via register.
[0138] This ensures that function calls can accurately jump to the new function after the move.
[0139] 3. Rewrite the branch instructions (B (first unconditional jump instruction), B.cond (first conditional jump instruction)).
[0140] Assume that block_C in block_C of block B is the old base block address. Then calculate the new relative offset and generate a new branch instruction. Specific steps are as follows:
[0141] ① Determine the new PC value for the current branch instruction (i.e., its position in the rewritten binary);
[0142] ② Determine the new starting address of the target basic block block_C;
[0143] ③ Calculate the new offset from the current instruction to the target address;
[0144] ④ Generate a new B new_offset or B.cond new_offset instruction.
[0145] This ensures that all jumps between basic blocks remain correctly connected in the rearranged code.
[0146] This embodiment solves the problem of invalid address references caused by code movement, ensuring that the optimized program (binary code) is completely consistent with the original program in logic and function. Furthermore, this embodiment uses instructions such as ADRP to make the rewritten code insensitive to its absolute position in memory, improving the flexibility and relocatability of the code. This lays the foundation for optimizing function inlining, ensuring that function inlining expansion does not break the semantics of the program.
[0147] For example, suppose that after topological sorting, basic block B is moved to a new address 0x4000. One instruction within basic block B needs to be rewritten. Before the rewrite, at address 0x4000, the original instruction was: LDR X1, [0x8000] / / Load data from the original data address 0x8000 into X1. Assume that according to the global layout mapping table, the new data address corresponding to the original data address 0x8000 is 0x9000. Then the instruction is rewritten as:
[0148] ① Identification and Decoding: Identify (e.g., through a rewriter) that this is an LDR instruction, the destination register is X1, and the source operand is the absolute address 0x8000;
[0149] ② Query the new address: Query the mapping table (e.g., through the rewriter) to find that the new address corresponding to 0x8000 is 0x9000.
[0150] ③ Apply rewrite rules (ADRP+LDR):
[0151] Calculate the page base address: The 4KB page base address where the new address 0x9000 is located is 0x9000 & ~0xFFF = 0x9000; Calculate the page offset: The offset is 0x9000 - 0x9000 = 0; Select the temporary register: Assume that X16 is used as the temporary register;
[0152] Finally, a new instruction sequence is generated:
[0153] ADRP X16, 0x9000 / / Loads page base address 0x9000 into X16;
[0154] LDR X1, [X16] / / Load data from the address pointed to by X16 (i.e., 0x9000). Because the offset is 0, #0 is omitted.
[0155] Thus, after rewriting, at address 0x4000, the original single instruction is replaced by two instructions: namely ADRPX16, 0x9000 and LDR X1, [X16].
[0156] Step 104: Perform inline expansion of the target function calls in the second binary code according to the function call graph to obtain the third binary code.
[0157] Inlining (function inlining) directly "copies" the complete code body of a function (the callee) to every place that calls it (the call point), removing the original function call instructions. This involves: eliminating call instructions, inserting all instructions of the called function into the calling function, and fine-tuning the basic block control flow and register states to ensure seamless integration of the inserted code with the original code of the calling function. Each function call requires a series of additional operations, including but not limited to saving the return address, jumping to the target function, setting up a stack frame at the beginning of the function, restoring the stack frame at the end of the function, and jumping back. For small and frequently called functions, this fixed overhead accounts for a significant portion of the total execution time. This disclosure uses inlining to reduce these overheads.
[0158] In this embodiment of the disclosure, the function call graph can be analyzed to determine, but is not limited to, call relationships (identifying the "caller" and "callee" functions (i.e., the target calling function)) and whether candidate inline functions (callee functions) are suitable for inlining (i.e., whether they meet the calling conditions). As an optional embodiment, step 104 can be implemented as follows: determining the complexity of the target calling function based on the function call graph to determine whether the target calling function meets the calling conditions; in response to determining that the target calling function meets the calling conditions, performing inline expansion on the target calling function to obtain the third binary code.
[0159] Furthermore, determining the complexity of the target function based on the function call graph to determine whether the target function meets the calling conditions can be implemented as follows: Based on the function call graph, determine the number of basic blocks, number of instructions, control flow depth, loop depth, in-degree, out-degree, and function side effects of the target function to determine its complexity; and based on the complexity of the target function, determine whether the target function meets the calling conditions. In response to determining that the target function meets the calling conditions, perform inline expansion on the target function to obtain the third binary code. Specifically, this can be implemented as follows: In response to determining that the target function meets the calling conditions, obtain the instruction sequence of the target function, insert the instruction sequence of the target function into the target call point, and store the returned memory address and register state to obtain the third binary code.
[0160] The evaluation metrics for the complexity of the function are as follows:
[0161] Number of basic blocks: The more basic blocks a function contains, the more complex its code and structure are usually, and the higher the complexity of the function.
[0162] Instruction count: This refers to the total number of instructions inside a function. It is the most direct indicator of function complexity. The more instructions there are, the higher the complexity of the function.
[0163] Control flow depth: The maximum nesting level of control structures such as if, for, and while. The greater the control flow depth, the higher the complexity of the function.
[0164] Loop depth: This refers to the maximum number of nested loops in a function. It is an important factor in judging the performance complexity of a function. The greater the loop depth, the higher the complexity of the function.
[0165] In-degree: refers to the number of other functions that call this function. A high in-degree means that the function is a widely used "core" function, and the higher the complexity of the function.
[0166] Out-degree: refers to the number of other functions called by the function. A high out-degree means that the function depends on a lot of external logic, and the higher the complexity of the function.
[0167] Function side effects refer to whether a function modifies global state, static variables, or memory locations other than its input parameters via pointers. Functions with side effects are more complex, meaning their complexity is higher.
[0168] As an optional embodiment, the complexity evaluation metrics of the two or more functions mentioned above can be weighted and scored to obtain a score result. The score result is then compared with a complexity threshold (which can be preset). If the score result is lower than the complexity threshold, the target function is determined to meet the calling conditions.
[0169] For example, suppose we want to determine whether the function `calc` meets the calling condition and is suitable for inlining, where the function `calc` is:
[0170] Number of basic blocks = 4;
[0171] Number of instructions = 12;
[0172] Control flow depth = 3 (assuming number of edges E = 5, number of nodes N = 4, M = 5 - 4 + 2 = 3);
[0173] Loop depth = 0 (no loop);
[0174] In-degree = 3 (called by 3 different caller functions);
[0175] Out-degree = 1 (it internally calls one helper function);
[0176] Function side effects = False (no access to global memory, no I / O);
[0177] Further weighted scoring was performed to obtain the scoring results:
[0178] score = 12 * 0.1 + 4 * 0.5 = 1.2 + 2.0 = 3.2 (number of instructions and number of basic blocks);
[0179] score += 0 (low complexity, no penalty);
[0180] score += 0 (no loop);
[0181] score += 1 * 15 = 15 (a function was called);
[0182] score += 0 (no side effects);
[0183] Total score = (3.2+15) / min(3,5) = 18.2 / 3≈6.07 (assuming application call frequency incentive). Assuming the complexity threshold is 50, the total score of 6.07 is much lower than the complexity threshold of 50. The function calc meets the call conditions and is suitable for inlining.
[0184] In this way, making decisions about function inlining and expansion using quantitative metrics can automate and make inlining decisions reliable, thereby achieving a balance between performance improvement and code bloat.
[0185] As another optional embodiment, if the number of instructions in the target function is less than 10, and the header of the target function is not a normal function header (e.g., the function does not start with push and pop instructions on the stack), and the target function has side effects on the caller function, then the target function is determined to meet the calling conditions.
[0186] The following examples further illustrate the function inlining expansion embodiments of this disclosure in detail, so that those skilled in the art can clearly and accurately understand the technical solutions of this disclosure. Continuing with the previous example of the function `calc`, which was previously determined to meet the calling conditions and be suitable for inlining, function inlining expansion is then performed based on its function call graph analysis:
[0187] First, inline candidates are selected. The function call graph of function calc is traversed, and "caller-callee" edges suitable for inlining are marked based on the decision criteria mentioned above. For example, it is decided to inline function calc at all its call points (i.e., caller functions, such as in main and worker).
[0188] Then, inlining is implemented at the call point. For each selected call point (e.g., BLcalc in the main function), the following is done:
[0189] ① Extraction and Copying. Extract the entire instruction sequence of the target calling function calc (excluding its prologue and closing instructions), copy these instructions to the call point, and replace the original BL calc instructions;
[0190] ② Handling control flow. The inlined target function `calc` usually ends with a `RET` instruction. However, after inlining, it should not return to the caller of `main`, but should continue executing the code after `BL calc` in the `main` function. Therefore, all `RET` instructions in the target function `calc` are rewritten as `B return_block` instructions that jump to the basic block after the call point.
[0191] ③ Handling register states. The inlined target function `calc` uses some registers (e.g., X0 for parameter passing and return values, X1-X18 as temporary registers). These registers may be used by the calling function `main`. Therefore, embodiments of this disclosure analyze the active registers of the `main` function around the call point. If the code of the inlined target function `calc` would corrupt registers that the `main` function still needs to use (active registers), then at the beginning of the inserted code, instructions are generated to save the values of these registers onto the stack, and at the end of the inserted code (before jumping to `return_block`), instructions are generated to restore the values of these registers from the stack.
[0192] ④ Parameter binding: Associate the instruction that sets the parameter at the calling point (main function) (e.g., MOV X0,#10) with the instruction that uses the parameter in the inlined target calling function calc.
[0193] As one implementation of this disclosure, the program results are finally updated:
[0194] Update the control flow graph: Integrate the control flow graph of the target calling function calc into the basic block control flow graph of the caller function or the calling point main function to form a larger and more complex basic block control flow graph;
[0195] Triggering re-optimization: Due to changes in code layout, the basic block layout may change. Therefore, the basic blocks in the main function are reordered to maximize performance gains.
[0196] Step 105: The third binary code is re-encoded using assembly instructions to obtain the fourth binary code, which is the optimized target binary code.
[0197] In this embodiment, the inlined binary code is re-encoded and re-integrated and optimized to generate correct and efficient final machine code, thus avoiding problems such as control flow breaks, register conflicts, and invalid address references after inlining. As an optional embodiment, the third binary code is optimized using constant propagation and redundant instruction elimination, and then the optimized third binary code is encoded. Specifically, the third binary code can be optimized using preset code optimization instructions (e.g., constant propagation, redundant instruction elimination, etc.) to delete consecutively occurring and identical machine code instructions in the third binary code, and in response to determining that the value of any register is a constant, all values of that register in the third binary code are replaced with that constant value, resulting in the optimized third binary code. Finally, the third binary code is encoded into machine code of a preset code format using assembly instructions and arranged according to a preset code layout order to obtain the fourth binary code, which is the optimized target binary code.
[0198] For example, the third binary code obtained from inline expansion is optimized using preset code optimization instructions, such as:
[0199] ① Constant propagation:
[0200] Suppose an instruction (e.g., MOV X0, #10) assigns a constant value to register X0, and subsequent instructions (e.g., ADD X1, X0, X2) use X0. In this embodiment, X0 is replaced with the constant #10. Therefore, the instructions ADD X1, X0, X2 are optimized to ADD X1, #10, X2.
[0201] ② Redundant instruction elimination, i.e., identifying and deleting duplicate or useless instructions:
[0202] Scenario 1 (Duplicate Storage): If there are two consecutive STR X0, [SP] records, then the first one can be deleted, leaving only one record.
[0203] Scenario 2 (Invalid operation): MOV X1, X1 (moves X1 to X1, which is an empty operation), then delete the instruction.
[0204] ③ Dead code elimination: If the result of some instruction is never used (for example, some branches become unreachable due to inlining or constant propagation), then the instruction is deleted.
[0205] After optimization using the aforementioned preset code optimization instructions, a more streamlined and optimized sequence of assembly instructions can be output. Finally, an assembler (possibly a module built into the rewriter) translates each assembly instruction into its corresponding 32-bit ARM64 machine code (e.g., encoding ADD X1, X2, X3 as 0x8B030041), and arranges all the encoded machine codes closely together according to the final layout order to form a new binary code segment, which is the fourth binary code (target binary code).
[0206] In this way, by recoding to fix the basic block control flow and register problems introduced by inlining, utilizing the optimization opportunities created by inlining for constant propagation and redundancy elimination, a deeply optimized final machine code is generated, thereby ensuring the semantic preservation of the entire process.
[0207] In one alternative embodiment, the fourth binary code also needs to be verified to ensure consistency with the source code. This verification can be performed through semantic equivalence checks, basic block control flow graph integrity checks, etc., to determine consistency with the original binary code (first binary code).
[0208] Another alternative embodiment can maximize the reliability and usability of binary rewriting technology through layered, defensive verification. Specifically, verification can be performed using a combination of static verification during code generation, dynamic verification during code runtime, and formal verification. For example:
[0209] First, static validation is performed during the code generation phase. This allows for the identification of potential problems through static analysis before the program runs.
[0210] ① Semantic equivalence check
[0211] The basic blocks are converted into intermediate representations, that is, the original and rewritten basic blocks are converted into an intermediate representation that is independent of specific machine instructions, such as based on SSA (Static Single Assignment). Then, tools (such as Angr, BAP) are used to perform symbolic execution on the two instruction registers (IR), assigning symbolic values to the inputs (registers, memory states) of the two code blocks, simulating the execution of the two code blocks respectively, and checking whether their outputs (registers, memory states) are consistent under all possible symbolic inputs. If they are consistent, the semantics of the original and rewritten basic blocks remain unchanged.
[0212] ②Basic block control flow graph integrity check
[0213] By comparing the basic block control flow graphs and function call graphs of the original binary and the rewritten binary, and checking items such as whether the number of all functions is consistent, whether the entry point, number of basic blocks, and edges (jump relationships) of each function are consistent, and whether the call relationships between functions are the same, major structural damage caused by rewriting errors can be quickly discovered, such as missing basic blocks or incorrect jump targets.
[0214] Secondly, dynamic verification is performed at runtime. This includes:
[0215] ① Deterministic test suite. This involves verifying whether the output is consistent with predefined inputs.
[0216] First, prepare test cases by collecting or generating a set of input test cases with clearly defined expected outputs. These include, but are not limited to, unit tests, command-line arguments, standard input data, and file operations. Then, perform synchronous execution and comparison: run the original program (first binary code) and the rewritten program (fourth binary code) in parallel under the same environment and initial state, capturing and comparing return values, outputs (standard output and standard error), and system call sequences (e.g., using strace or ptrace tools to capture and compare the system call sequences and their parameters).
[0217] ② Fuzz testing. This can be used to discover errors in cases that ① test cases fail to cover.
[0218] Tools such as AFL and LibFuzzer can be used to automatically generate a large amount of random and semi-random input data. The same random input data can be sent to the original program and the rewritten program at the same time. The behavior (output, system calls) of the two programs can be continuously monitored to see if they are consistent. If they are inconsistent, the input data that caused the inconsistency in output can be recorded for subsequent debugging.
[0219] ③ Dynamic instrumentation and recording playback. This can be used for fine-grained comparison of runtime states.
[0220] During the execution of the original program, logging code is inserted at key points (such as the entry / exit points of each basic block) to record the current register state and memory contents. Code is then inserted at the same locations in the rewritten program to compare the current register state and memory contents with the previously recorded snapshots. This ensures that, under the same input, the key states of the original and rewritten programs are completely synchronized during execution. This provides an extremely rigorous proof of runtime equivalence, which, in this embodiment, can be used for partial verification or debugging to reduce overhead.
[0221] Finally, formal verification is performed. The correctness of the entire rewriting process is mathematically proven.
[0222] ① First, we can define a rewriting specification. That is, we can define strict, formal rules for each rewriting operation (such as instruction substitution, basic block movement, and function inlining).
[0223] ② Construct a verifiable rewriter: The implementation of the rewriter itself needs to follow the rules of rewriting operations, and its core algorithm can be verified by theorem provers (such as Coq, Isabelle).
[0224] ③ Prove semantic preservation. That is, by proving that each rule of a rewrite operation preserves the semantics of the program, it is further proven that the entire rewrite process consisting of these rules of rewrite operations also preserves semantics.
[0225] Thus, it is proven that the rewritten program behaves identically to the original program for all possible inputs, guaranteeing the correctness of the binary code rewrite.
[0226] In summary, the technical solution of this disclosure determines the function call graph and basic block control flow graph from the source binary code to be optimized. Then, topological sorting is performed on each basic block control flow graph, optimizing the code execution order, reducing branch prediction errors, and improving instruction cache hit rate. Furthermore, based on the topological sorting results, the binary code to be optimized is rewritten, updating the memory addresses and function addresses in all instructions. This allows for precise rewriting of critical instructions tailored to specific system architectures (e.g., ARM64 architecture), ensuring accurate address calculations. Inline expansion of target function calls in the binary code, based on the function call graph, allows for selective inline expansion of functions (i.e., target function calls) through strict context management, reducing function call overhead and eliminating control flow confusion and register pollution issues that inlining might introduce, while ensuring the integrity of the original program logic. Finally, the inline-expanded code is re-encoded to generate the final optimized target binary code. This allows for deep optimization of binary code by comprehensively utilizing inlining, code layout, and instruction-level optimization while maintaining strict semantic integrity.
[0227] Figure 3 This is a schematic structural block diagram of a binary code optimization system according to one embodiment of the system disclosed herein. Figure 3 As shown, a binary code optimization system according to an embodiment of this disclosure may include:
[0228] The binary code analysis module 201 is used to determine the function call graph and basic block control flow graph of the first binary code based on the first binary code.
[0229] Topology sorting module 202 is used to perform topology sorting on each of the basic block control flow graphs to obtain the basic block layout;
[0230] Instruction rewriting module 203 is used to rewrite the first binary code based on the basic block layout to update the memory addresses and function addresses in all instructions of the first binary code to obtain the second binary code;
[0231] The inline expansion module 204 is used to inline expand the target function call in the second binary code according to the function call graph to obtain the third binary code;
[0232] The code generation module 205 is used to re-encode the third binary code using assembly instructions to obtain a fourth binary code, which is the optimized target binary code.
[0233] As an optional embodiment, the topology sorting module includes:
[0234] The basic block traversal unit is used to traverse the basic block control flow for each basic block control flow, starting from the entry basic block of the function corresponding to the basic block control flow, so as to push the basic blocks traversed in the basic block control flow onto the preset target stack when recursion returns.
[0235] The first basic block sorting unit is used to, in response to traversing all basic blocks in the basic block control flow, sequentially add all basic blocks in the preset target stack to the preset topology list in order from the top of the stack to the bottom of the stack, to obtain the first sorting result;
[0236] The first determining unit is configured to determine, based on the first sorting result, whether the basic block control flow includes basic blocks referenced by external mechanisms;
[0237] The second basic block sorting unit is used to add the basic block referenced by the external mechanism to a preset position in the first sorting result in response to whether the basic block control flow includes a basic block referenced by an external mechanism, so as to obtain a second sorting result, wherein the second sorting result is the basic block layout.
[0238] As an optional embodiment, the basic block traversal unit is specifically used for:
[0239] Initialize a preset target stack and a preset basic block set. The preset target stack is used to sequentially store the basic blocks traversed in the basic block control flow. The preset basic block set is used to mark the basic blocks traversed in the basic block control flow and store the marked basic blocks.
[0240] The entry block of the function is used as the root node of the depth-first search traversal. The recursive depth-first search function is called to traverse the control flow of the basic block, so as to add any basic block traversed to the preset basic block set and push the basic block onto the preset target stack.
[0241] As an optional embodiment, the instruction rewriting module includes:
[0242] The instruction traversal unit is used to traverse all machine instructions in each basic block of the basic block layout to decode each machine instruction and identify the instruction type of the machine instruction.
[0243] The instruction rewriting unit is used to rewrite the machine instructions in all basic blocks of the first binary code according to the instruction type of each machine instruction and a preset instruction rewriting rule corresponding to the instruction type, so as to update the memory addresses and function addresses in all instructions of the first binary code to obtain the second binary code.
[0244] As an optional embodiment, the instruction rewriting unit is specifically used for:
[0245] In response to any of the machine instructions being a load data instruction, the load data instruction is modified into a first instruction combination, the first instruction combination including an address read instruction and a load data instruction;
[0246] In response to any of the machine instructions being a linked branch jump instruction, the linked branch jump instruction is modified into a second instruction combination, the second instruction combination including an address read instruction and a linked register jump instruction;
[0247] In response to any of the machine instructions being of the first unconditional jump instruction or the first conditional jump instruction, calculate the offset from the source memory address of the current machine instruction to the target memory address of the target basic block.
[0248] In response to determining that the offset is within the instruction encoding range, a second unconditional jump instruction or a second conditional jump instruction is generated to point to the target memory address of the target basic block.
[0249] As an optional embodiment, the inline expansion module includes:
[0250] The condition judgment unit is used to determine the complexity of the target calling function based on the function call graph, so as to determine whether the target calling function meets the calling conditions;
[0251] The inline expansion unit is used to perform inline expansion on the target call function in response to determining that the target call function meets the call conditions, to obtain the third binary code.
[0252] As an optional embodiment, the condition judgment unit is specifically used for:
[0253] The complexity of the target call function is determined by analyzing the number of basic blocks, number of instructions, control flow depth, loop depth, in-degree, out-degree, and function side effects of the target call function based on the function call graph.
[0254] The complexity of the target function determines whether the target function meets the calling conditions.
[0255] As an optional embodiment, the inline expansion unit is specifically used for:
[0256] In response to determining that the target function being called meets the calling conditions, the instruction sequence of the target function being called is obtained;
[0257] The instruction sequence of the target function is inserted into the target call point, and the returned memory address and register state are stored to obtain the third binary code.
[0258] As an optional embodiment, the code generation module includes:
[0259] The code optimization unit is used to optimize the third binary code by means of preset code optimization instructions, so as to delete the machine code instructions that appear consecutively and are the same in the third binary code, and in response to determining that the value of any register is a constant value, to replace the value of all such registers in the third binary code with such constant value, so as to obtain the optimized third binary code.
[0260] The code encoding unit is used to encode the third binary code into machine code of a preset code format through assembly instructions, and arrange them according to a preset code layout order to obtain the fourth binary code, which is the optimized target binary code.
[0261] In summary, the technical solution of this disclosure determines the function call graph and basic block control flow graph of the source binary code to be optimized, and then performs topological sorting on each basic block control flow graph to optimize the code execution order, reduce branch prediction errors, and improve instruction cache hit rate. Furthermore, based on the topological sorting results, the binary code to be optimized is rewritten, updating the memory addresses and function addresses in all instructions. This allows for precise rewriting of critical instructions tailored to specific system architectures (e.g., ARM64 architecture), ensuring the accuracy of address calculations. Inline expansion of the target function calls in the binary code, based on the function call graph, allows for selective inline expansion of functions (i.e., target function calls) through strict context management, reducing function call overhead and eliminating control flow chaos and register pollution problems that inlining may introduce, while ensuring the integrity of the original program logic. Finally, the inline-expanded code is re-encoded to generate the final optimized target binary code. This allows for deep optimization of binary code by comprehensively utilizing multiple methods such as inlining, code layout, and instruction-level optimization while maintaining strict semantic integrity.
[0262] Those skilled in the art will clearly understand that, for the sake of convenience and brevity, the above-described division of functional units and modules is merely an example. In practical applications, the above functions can be assigned to different functional units and modules as needed, that is, the internal structure of the device can be divided into different functional units or modules to complete all or part of the functions described above. The functional units and modules in the embodiments can be integrated into one processing unit, or each unit can exist physically separately, or two or more units can be integrated into one unit. The integrated unit can be implemented in hardware or as a software functional unit. Furthermore, the specific names of the functional units and modules are only for easy differentiation and are not intended to limit the scope of protection of this disclosure. The specific working process of the units and modules in the above system can be referred to the corresponding process in the foregoing method embodiments, and will not be repeated here.
[0263] Below, for reference Figure 4 This describes an electronic device according to embodiments of the present disclosure. The electronic device may be either or both of a first device and a second device, or a standalone device independent of them, which may communicate with the first device and the second device to receive acquired input signals from them.
[0264] Figure 4 A block diagram of an electronic device according to an embodiment of the present disclosure is shown.
[0265] like Figure 4 As shown, the electronic device includes one or more processors and memory.
[0266] A processor can be a central processing unit (CPU) or other form of processing unit with data processing and / or instruction execution capabilities, and can control other components in an electronic device to perform desired functions.
[0267] The memory can store one or more computer program products, and the memory can include various forms of computer-readable storage media, such as volatile memory and / or non-volatile memory. The volatile memory may include, for example, random access memory (RAM) and / or cache memory. The non-volatile memory may include, for example, read-only memory (ROM), hard disk, flash memory, etc. One or more computer program products can be stored on the computer-readable storage medium, and the processor can run the computer program products to implement the binary code optimization methods of the various embodiments of this disclosure described above and / or other desired functions.
[0268] In one example, the electronic device may also include input devices and output devices, which are interconnected via a bus system and / or other forms of connection mechanism (not shown).
[0269] In addition, the input device may also include, for example, a keyboard, a mouse, etc.
[0270] This output device can output various information to the outside, including determined distance information, direction information, etc. The output device may include, for example, a display, a speaker, a printer, and a communication network and its connected remote output devices, etc.
[0271] Of course, for the sake of simplicity, Figure 4 Only some of the components of the electronic device relevant to this disclosure are shown, omitting components such as buses, input / output interfaces, etc. In addition, the electronic device may include any other suitable components depending on the specific application.
[0272] In addition to the methods and apparatus described above, embodiments of this disclosure may also be computer program products comprising computer program instructions that, when executed by a processor, cause the processor to perform the steps in the binary code optimization methods according to various embodiments of this disclosure as described in the foregoing portion of this specification.
[0273] The computer program product can be written in any combination of one or more programming languages to perform the operations of the embodiments of this disclosure. The programming languages include object-oriented programming languages such as Java and C++, as well as conventional procedural programming languages such as C or similar languages. The program code can be executed entirely on a user's computing device, partially on a user's computing device, as a standalone software package, partially on a user's computing device and partially on a remote computing device, or entirely on a remote computing device or server.
[0274] Furthermore, embodiments of this disclosure may also be computer-readable storage media storing computer program instructions that, when executed by a processor, cause the processor to perform the steps in the binary code optimization methods according to various embodiments of this disclosure described in the foregoing portion of this specification.
[0275] The computer-readable storage medium may be any combination of one or more readable media. A readable medium may be a readable signal medium or a readable storage medium. A readable storage medium may, for example, include, but is not limited to, electrical, magnetic, optical, electromagnetic, infrared, or semiconductor systems, apparatuses, or devices, or any combination thereof. More specific examples of readable storage media (a non-exhaustive list) include: electrical connections having one or more wires, portable disks, hard disks, random access memory (RAM), read-only memory (ROM), erasable programmable read-only memory (EPROM or flash memory), optical fibers, portable compact disk read-only memory (CD-ROM), optical storage devices, magnetic storage devices, or any suitable combination thereof.
[0276] The basic principles of this disclosure have been described above with reference to specific embodiments. However, it should be noted that the advantages, benefits, and effects mentioned in this disclosure are merely examples and not limitations, and should not be considered as essential features of each embodiment of this disclosure. Furthermore, the specific details disclosed above are for illustrative and facilitative purposes only, and are not limitations. These details do not limit the scope of this disclosure to the necessity of employing the aforementioned specific details for implementation.
[0277] The various embodiments in this specification are described in a progressive manner, with each embodiment focusing on its differences from other embodiments. Similar or identical parts between embodiments can be referred to interchangeably. For system embodiments, since they largely correspond to method embodiments, the description is relatively simple; relevant parts can be referred to the descriptions in the method embodiments.
[0278] The block diagrams of devices, apparatuses, devices, and systems disclosed herein are merely illustrative examples and are not intended to require or imply that they must be connected, arranged, or configured in the manner shown in the block diagrams. As those skilled in the art will recognize, these devices, apparatuses, devices, and systems can be connected, arranged, and configured in any manner. Words such as “comprising,” “including,” “having,” etc., are open-ended terms meaning “including but not limited to,” and are used interchangeably with them. The terms “or” and “and” as used herein refer to the terms “and / or,” and are used interchangeably with them unless the context clearly indicates otherwise. The term “such as” as used herein refers to the phrase “such as but not limited to,” and is used interchangeably with it.
[0279] The methods and apparatus of this disclosure may be implemented in many ways. For example, they may be implemented by software, hardware, firmware, or any combination of software, hardware, and firmware. The above-described order of steps for the methods is for illustrative purposes only, and the steps of the methods of this disclosure are not limited to the order specifically described above unless otherwise specifically stated. Furthermore, in some embodiments, this disclosure may also be implemented as a program recorded on a recording medium, the program including machine-readable instructions for implementing the methods according to this disclosure. Thus, this disclosure also covers recording media storing programs for performing the methods according to this disclosure.
[0280] It should also be noted that in the apparatus, devices, and methods of this disclosure, the components or steps can be disassembled and / or recombined. These disassemblies and / or recombinations should be considered as equivalent solutions to this disclosure.
[0281] The above description of the disclosed aspects is provided to enable any person skilled in the art to make or use this disclosure. Various modifications to these aspects will be readily apparent to those skilled in the art, and the general principles defined herein may be applied to other aspects without departing from the scope of this disclosure. Therefore, this disclosure is not intended to be limited to the aspects shown herein, but rather to be carried out within the widest scope consistent with the principles and novel features disclosed herein.
[0282] The above description has been given for purposes of illustration and description. Furthermore, this description is not intended to limit the embodiments of this disclosure to the forms disclosed herein. Although numerous exemplary aspects and embodiments have been discussed above, those skilled in the art will recognize certain variations, modifications, alterations, additions, and sub-combinations therein.
Claims
1. A binary code optimization method, characterized in that, The method includes: Based on the first binary code, determine the function call graph and basic block control flow graph of the first binary code; The control flow graph of each basic block is topologically sorted to obtain the basic block layout. Based on the basic block layout, the first binary code is rewritten to update the memory addresses and function addresses in all instructions of the first binary code, thereby obtaining the second binary code; Based on the function call graph, the target function call in the second binary code is inlined and expanded to obtain the third binary code; The third binary code is re-encoded using assembly instructions to obtain the fourth binary code, which is the optimized target binary code.
2. The method according to claim 1, characterized in that, The step of performing topological sorting on the basic block control flow graphs to obtain the basic block layout includes: For each basic block control flow, the basic block control flow is traversed starting from the entry basic block of the function corresponding to the basic block control flow, so that when the recursion returns, the basic blocks traversed in the basic block control flow are pushed into the preset target stack. In response to traversing all the basic blocks in the basic block control flow, all the basic blocks in the preset target stack are sequentially added to the preset topology list in order from top to bottom of the stack to obtain the first sorting result; Based on the first sorting result, determine whether the basic block control flow includes basic blocks referenced by external mechanisms; In response to whether the basic block control flow includes basic blocks referenced by external mechanisms, the basic blocks referenced by external mechanisms are added to a preset position in the first sorting result to obtain a second sorting result, which is the basic block layout.
3. The method according to claim 2, characterized in that, The step of traversing the basic block control flow for each basic block control flow, starting from the entry basic block of the function corresponding to that basic block control flow, and pushing the traversed basic blocks in the basic block control flow onto a preset target stack upon recursion return, includes: Initialize a preset target stack and a preset basic block set. The preset target stack is used to sequentially store the basic blocks traversed in the basic block control flow. The preset basic block set is used to mark the basic blocks traversed in the basic block control flow and store the marked basic blocks. The entry block of the function is used as the root node of the depth-first search traversal. The recursive depth-first search function is called to traverse the control flow of the basic block, so as to add any basic block traversed to the preset basic block set and push the basic block onto the preset target stack.
4. The method according to claim 1, characterized in that, The step of rewriting the first binary code based on the basic block layout to update the memory addresses and function addresses in all instructions of the first binary code to obtain the second binary code includes: For each basic block in the basic block layout, all machine instructions in each basic block are traversed to decode each machine instruction and identify the instruction type of the machine instruction. Based on the instruction type of each machine instruction, the machine instructions in all basic blocks of the first binary code are rewritten according to the preset instruction rewriting rules corresponding to the instruction type, so as to update the memory addresses and function addresses in all instructions of the first binary code, and thus obtain the second binary code.
5. The method according to claim 4, characterized in that, The step of rewriting the machine instructions in all basic blocks of the first binary code according to the instruction type of each machine instruction and a preset instruction rewriting rule corresponding to the instruction type, to update the memory addresses and function addresses in all instructions of the first binary code, to obtain the second binary code, includes: In response to any of the machine instructions being a load data instruction, the load data instruction is modified into a first instruction combination, the first instruction combination including an address read instruction and a load data instruction; In response to any of the machine instructions being a linked branch jump instruction, the linked branch jump instruction is modified into a second instruction combination, the second instruction combination including an address read instruction and a linked register jump instruction; In response to any of the machine instructions being of the first unconditional jump instruction or the first conditional jump instruction, calculate the offset from the source memory address of the current machine instruction to the target memory address of the target basic block. In response to determining that the offset is within the instruction encoding range, a second unconditional jump instruction or a second conditional jump instruction is generated to point to the target memory address of the target basic block.
6. The method according to claim 1, characterized in that, The step of inlining and expanding the target function calls in the second binary code according to the function call graph to obtain the third binary code includes: The complexity of the target function is determined based on the function call graph to determine whether the target function meets the calling conditions. In response to determining that the target function meets the calling conditions, the target function is inlined and expanded to obtain the third binary code.
7. The method according to claim 6, characterized in that, The step of determining the complexity of the target function based on the function call graph, in order to determine whether the target function meets the calling conditions, includes: The complexity of the target call function is determined by analyzing the number of basic blocks, number of instructions, control flow depth, loop depth, in-degree, out-degree, and function side effects of the target call function based on the function call graph. The complexity of the target function determines whether the target function meets the calling conditions.
8. The method according to claim 6 or 7, characterized in that, In response to determining that the target calling function meets the calling conditions, the target calling function is inlined to obtain a third binary code, including: In response to determining that the target function meets the calling conditions, the instruction sequence of the target function is obtained; The instruction sequence of the target function is inserted into the target call point, and the returned memory address and register state are stored to obtain the third binary code.
9. The method according to claim 1, characterized in that, The third binary code is re-encoded using assembly instructions to obtain a fourth binary code, which is the optimized target binary code, including: The third binary code is optimized by using preset code optimization instructions to delete consecutive and identical machine code instructions in the third binary code, and in response to determining that the value of any register is a constant value, the values of all such registers in the third binary code are replaced with such constant values to obtain the optimized third binary code. The third binary code is encoded into machine code of a preset code format using assembly instructions and arranged according to a preset code layout order to obtain the fourth binary code, which is the optimized target binary code.
10. A binary code optimization system, characterized in that, The system includes: The binary code analysis module is used to determine the function call graph and basic block control flow graph of the first binary code based on the first binary code. The topology sorting module is used to perform topology sorting on each of the basic block control flow graphs to obtain the basic block layout. The instruction rewriting module is used to rewrite the first binary code based on the basic block layout to update the memory addresses and function addresses in all instructions of the first binary code, so as to obtain the second binary code. The inline expansion module is used to inline expand the target function calls in the second binary code according to the function call graph to obtain the third binary code; The code generation module is used to re-encode the third binary code using assembly instructions to obtain a fourth binary code, which is the optimized target binary code.
11. An electronic device, characterized in that, include: Memory, used to store computer program products; A processor for executing a computer program product stored in the memory, wherein when the computer program product is executed, it implements the method described in any one of claims 1-9.
12. A computer-readable storage medium having computer program instructions stored thereon, characterized in that, When the computer program instructions are executed by the processor, they implement the method described in any one of claims 1-9.
13. A computer program product comprising computer program instructions, characterized in that, When the computer program instructions are executed by the processor, they implement the method described in any one of claims 1-9.