f535537f |
1 | /* Bra.h -- Branch converters for executables |
2 | 2024-01-20 : Igor Pavlov : Public domain */ |
3 | |
4 | #ifndef ZIP7_INC_BRA_H |
5 | #define ZIP7_INC_BRA_H |
6 | |
7 | #include "7zTypes.h" |
8 | |
9 | EXTERN_C_BEGIN |
10 | |
11 | /* #define PPC BAD_PPC_11 // for debug */ |
12 | |
13 | #define Z7_BRANCH_CONV_DEC_2(name) z7_ ## name ## _Dec |
14 | #define Z7_BRANCH_CONV_ENC_2(name) z7_ ## name ## _Enc |
15 | #define Z7_BRANCH_CONV_DEC(name) Z7_BRANCH_CONV_DEC_2(BranchConv_ ## name) |
16 | #define Z7_BRANCH_CONV_ENC(name) Z7_BRANCH_CONV_ENC_2(BranchConv_ ## name) |
17 | #define Z7_BRANCH_CONV_ST_DEC(name) z7_BranchConvSt_ ## name ## _Dec |
18 | #define Z7_BRANCH_CONV_ST_ENC(name) z7_BranchConvSt_ ## name ## _Enc |
19 | |
20 | #define Z7_BRANCH_CONV_DECL(name) Byte * name(Byte *data, SizeT size, UInt32 pc) |
21 | #define Z7_BRANCH_CONV_ST_DECL(name) Byte * name(Byte *data, SizeT size, UInt32 pc, UInt32 *state) |
22 | |
23 | typedef Z7_BRANCH_CONV_DECL( (*z7_Func_BranchConv)); |
24 | typedef Z7_BRANCH_CONV_ST_DECL((*z7_Func_BranchConvSt)); |
25 | |
26 | #define Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL 0 |
27 | Z7_BRANCH_CONV_ST_DECL (Z7_BRANCH_CONV_ST_DEC(X86)); |
28 | Z7_BRANCH_CONV_ST_DECL (Z7_BRANCH_CONV_ST_ENC(X86)); |
29 | |
30 | #define Z7_BRANCH_FUNCS_DECL(name) \ |
31 | Z7_BRANCH_CONV_DECL (Z7_BRANCH_CONV_DEC_2(name)); \ |
32 | Z7_BRANCH_CONV_DECL (Z7_BRANCH_CONV_ENC_2(name)); |
33 | |
34 | Z7_BRANCH_FUNCS_DECL (BranchConv_ARM64) |
35 | Z7_BRANCH_FUNCS_DECL (BranchConv_ARM) |
36 | Z7_BRANCH_FUNCS_DECL (BranchConv_ARMT) |
37 | Z7_BRANCH_FUNCS_DECL (BranchConv_PPC) |
38 | Z7_BRANCH_FUNCS_DECL (BranchConv_SPARC) |
39 | Z7_BRANCH_FUNCS_DECL (BranchConv_IA64) |
40 | Z7_BRANCH_FUNCS_DECL (BranchConv_RISCV) |
41 | |
42 | /* |
43 | These functions convert data that contain CPU instructions. |
44 | Each such function converts relative addresses to absolute addresses in some |
45 | branch instructions: CALL (in all converters) and JUMP (X86 converter only). |
46 | Such conversion allows to increase compression ratio, if we compress that data. |
47 | |
48 | There are 2 types of converters: |
49 | Byte * Conv_RISC (Byte *data, SizeT size, UInt32 pc); |
50 | Byte * ConvSt_X86(Byte *data, SizeT size, UInt32 pc, UInt32 *state); |
51 | Each Converter supports 2 versions: one for encoding |
52 | and one for decoding (_Enc/_Dec postfixes in function name). |
53 | |
54 | In params: |
55 | data : data buffer |
56 | size : size of data |
57 | pc : current virtual Program Counter (Instruction Pointer) value |
58 | In/Out param: |
59 | state : pointer to state variable (for X86 converter only) |
60 | |
61 | Return: |
62 | The pointer to position in (data) buffer after last byte that was processed. |
63 | If the caller calls converter again, it must call it starting with that position. |
64 | But the caller is allowed to move data in buffer. So pointer to |
65 | current processed position also will be changed for next call. |
66 | Also the caller must increase internal (pc) value for next call. |
67 | |
68 | Each converter has some characteristics: Endian, Alignment, LookAhead. |
69 | Type Endian Alignment LookAhead |
70 | |
71 | X86 little 1 4 |
72 | ARMT little 2 2 |
73 | RISCV little 2 6 |
74 | ARM little 4 0 |
75 | ARM64 little 4 0 |
76 | PPC big 4 0 |
77 | SPARC big 4 0 |
78 | IA64 little 16 0 |
79 | |
80 | (data) must be aligned for (Alignment). |
81 | processed size can be calculated as: |
82 | SizeT processed = Conv(data, size, pc) - data; |
83 | if (processed == 0) |
84 | it means that converter needs more data for processing. |
85 | If (size < Alignment + LookAhead) |
86 | then (processed == 0) is allowed. |
87 | |
88 | Example code for conversion in loop: |
89 | UInt32 pc = 0; |
90 | size = 0; |
91 | for (;;) |
92 | { |
93 | size += Load_more_input_data(data + size); |
94 | SizeT processed = Conv(data, size, pc) - data; |
95 | if (processed == 0 && no_more_input_data_after_size) |
96 | break; // we stop convert loop |
97 | data += processed; |
98 | size -= processed; |
99 | pc += processed; |
100 | } |
101 | */ |
102 | |
103 | EXTERN_C_END |
104 | |
105 | #endif |