1 /* Bcj2.h -- BCJ2 Converter for x86 code 2 2014-11-10 : Igor Pavlov : Public domain */ 3 4 #ifndef __BCJ2_H 5 #define __BCJ2_H 6 7 #include "7zTypes.h" 8 9 EXTERN_C_BEGIN 10 11 #define BCJ2_NUM_STREAMS 4 12 13 enum 14 { 15 BCJ2_STREAM_MAIN, 16 BCJ2_STREAM_CALL, 17 BCJ2_STREAM_JUMP, 18 BCJ2_STREAM_RC 19 }; 20 21 enum 22 { 23 BCJ2_DEC_STATE_ORIG_0 = BCJ2_NUM_STREAMS, 24 BCJ2_DEC_STATE_ORIG_1, 25 BCJ2_DEC_STATE_ORIG_2, 26 BCJ2_DEC_STATE_ORIG_3, 27 28 BCJ2_DEC_STATE_ORIG, 29 BCJ2_DEC_STATE_OK 30 }; 31 32 enum 33 { 34 BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS, 35 BCJ2_ENC_STATE_OK 36 }; 37 38 39 #define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP) 40 41 /* 42 CBcj2Dec / CBcj2Enc 43 bufs sizes: 44 BUF_SIZE(n) = lims[n] - bufs[n] 45 bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be mutliply of 4: 46 (BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0 47 (BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0 48 */ 49 50 /* 51 CBcj2Dec: 52 dest is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions: 53 bufs[BCJ2_STREAM_MAIN] >= dest && 54 bufs[BCJ2_STREAM_MAIN] - dest >= tempReserv + 55 BUF_SIZE(BCJ2_STREAM_CALL) + 56 BUF_SIZE(BCJ2_STREAM_JUMP) 57 tempReserv = 0 : for first call of Bcj2Dec_Decode 58 tempReserv = 4 : for any other calls of Bcj2Dec_Decode 59 overlap with offset = 1 is not allowed 60 */ 61 62 typedef struct 63 { 64 const Byte *bufs[BCJ2_NUM_STREAMS]; 65 const Byte *lims[BCJ2_NUM_STREAMS]; 66 Byte *dest; 67 const Byte *destLim; 68 69 unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */ 70 71 UInt32 ip; 72 Byte temp[4]; 73 UInt32 range; 74 UInt32 code; 75 UInt16 probs[2 + 256]; 76 } CBcj2Dec; 77 78 void Bcj2Dec_Init(CBcj2Dec *p); 79 80 /* Returns: SZ_OK or SZ_ERROR_DATA */ 81 SRes Bcj2Dec_Decode(CBcj2Dec *p); 82 83 #define Bcj2Dec_IsFinished(_p_) ((_p_)->code == 0) 84 85 86 87 typedef enum 88 { 89 BCJ2_ENC_FINISH_MODE_CONTINUE, 90 BCJ2_ENC_FINISH_MODE_END_BLOCK, 91 BCJ2_ENC_FINISH_MODE_END_STREAM 92 } EBcj2Enc_FinishMode; 93 94 typedef struct 95 { 96 Byte *bufs[BCJ2_NUM_STREAMS]; 97 const Byte *lims[BCJ2_NUM_STREAMS]; 98 const Byte *src; 99 const Byte *srcLim; 100 101 unsigned state; 102 EBcj2Enc_FinishMode finishMode; 103 104 Byte prevByte; 105 106 Byte cache; 107 UInt32 range; 108 UInt64 low; 109 UInt64 cacheSize; 110 111 UInt32 ip; 112 113 /* 32-bit ralative offset in JUMP/CALL commands is 114 - (mod 4 GB) in 32-bit mode 115 - signed Int32 in 64-bit mode 116 We use (mod 4 GB) check for fileSize. 117 Use fileSize up to 2 GB, if you want to support 32-bit and 64-bit code conversion. */ 118 UInt32 fileIp; 119 UInt32 fileSize; /* (fileSize <= ((UInt32)1 << 31)), 0 means no_limit */ 120 UInt32 relatLimit; /* (relatLimit <= ((UInt32)1 << 31)), 0 means desable_conversion */ 121 122 UInt32 tempTarget; 123 unsigned tempPos; 124 Byte temp[4 * 2]; 125 126 unsigned flushPos; 127 128 UInt16 probs[2 + 256]; 129 } CBcj2Enc; 130 131 void Bcj2Enc_Init(CBcj2Enc *p); 132 void Bcj2Enc_Encode(CBcj2Enc *p); 133 134 #define Bcj2Enc_Get_InputData_Size(p) ((SizeT)((p)->srcLim - (p)->src) + (p)->tempPos) 135 #define Bcj2Enc_IsFinished(p) ((p)->flushPos == 5) 136 137 138 #define BCJ2_RELAT_LIMIT_NUM_BITS 26 139 #define BCJ2_RELAT_LIMIT ((UInt32)1 << BCJ2_RELAT_LIMIT_NUM_BITS) 140 141 /* limit for CBcj2Enc::fileSize variable */ 142 #define BCJ2_FileSize_MAX ((UInt32)1 << 31) 143 144 EXTERN_C_END 145 146 #endif 147