1 /* Bcj2.c -- BCJ2 Decoder (Converter for x86 code) 2 2018-04-28 : Igor Pavlov : Public domain */ 3 4 #include "Precomp.h" 5 6 #include "Bcj2.h" 7 #include "CpuArch.h" 8 9 #define CProb UInt16 10 11 #define kTopValue ((UInt32)1 << 24) 12 #define kNumModelBits 11 13 #define kBitModelTotal (1 << kNumModelBits) 14 #define kNumMoveBits 5 15 16 #define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound) 17 #define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); 18 #define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits)); 19 Bcj2Dec_Init(CBcj2Dec * p)20void Bcj2Dec_Init(CBcj2Dec *p) 21 { 22 unsigned i; 23 24 p->state = BCJ2_DEC_STATE_OK; 25 p->ip = 0; 26 p->temp[3] = 0; 27 p->range = 0; 28 p->code = 0; 29 for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++) 30 p->probs[i] = kBitModelTotal >> 1; 31 } 32 Bcj2Dec_Decode(CBcj2Dec * p)33SRes Bcj2Dec_Decode(CBcj2Dec *p) 34 { 35 if (p->range <= 5) 36 { 37 p->state = BCJ2_DEC_STATE_OK; 38 for (; p->range != 5; p->range++) 39 { 40 if (p->range == 1 && p->code != 0) 41 return SZ_ERROR_DATA; 42 43 if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) 44 { 45 p->state = BCJ2_STREAM_RC; 46 return SZ_OK; 47 } 48 49 p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; 50 } 51 52 if (p->code == 0xFFFFFFFF) 53 return SZ_ERROR_DATA; 54 55 p->range = 0xFFFFFFFF; 56 } 57 else if (p->state >= BCJ2_DEC_STATE_ORIG_0) 58 { 59 while (p->state <= BCJ2_DEC_STATE_ORIG_3) 60 { 61 Byte *dest = p->dest; 62 if (dest == p->destLim) 63 return SZ_OK; 64 *dest = p->temp[(size_t)p->state - BCJ2_DEC_STATE_ORIG_0]; 65 p->state++; 66 p->dest = dest + 1; 67 } 68 } 69 70 /* 71 if (BCJ2_IS_32BIT_STREAM(p->state)) 72 { 73 const Byte *cur = p->bufs[p->state]; 74 if (cur == p->lims[p->state]) 75 return SZ_OK; 76 p->bufs[p->state] = cur + 4; 77 78 { 79 UInt32 val; 80 Byte *dest; 81 SizeT rem; 82 83 p->ip += 4; 84 val = GetBe32(cur) - p->ip; 85 dest = p->dest; 86 rem = p->destLim - dest; 87 if (rem < 4) 88 { 89 SizeT i; 90 SetUi32(p->temp, val); 91 for (i = 0; i < rem; i++) 92 dest[i] = p->temp[i]; 93 p->dest = dest + rem; 94 p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; 95 return SZ_OK; 96 } 97 SetUi32(dest, val); 98 p->temp[3] = (Byte)(val >> 24); 99 p->dest = dest + 4; 100 p->state = BCJ2_DEC_STATE_OK; 101 } 102 } 103 */ 104 105 for (;;) 106 { 107 if (BCJ2_IS_32BIT_STREAM(p->state)) 108 p->state = BCJ2_DEC_STATE_OK; 109 else 110 { 111 if (p->range < kTopValue) 112 { 113 if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) 114 { 115 p->state = BCJ2_STREAM_RC; 116 return SZ_OK; 117 } 118 p->range <<= 8; 119 p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; 120 } 121 122 { 123 const Byte *src = p->bufs[BCJ2_STREAM_MAIN]; 124 const Byte *srcLim; 125 Byte *dest; 126 SizeT num = p->lims[BCJ2_STREAM_MAIN] - src; 127 128 if (num == 0) 129 { 130 p->state = BCJ2_STREAM_MAIN; 131 return SZ_OK; 132 } 133 134 dest = p->dest; 135 if (num > (SizeT)(p->destLim - dest)) 136 { 137 num = p->destLim - dest; 138 if (num == 0) 139 { 140 p->state = BCJ2_DEC_STATE_ORIG; 141 return SZ_OK; 142 } 143 } 144 145 srcLim = src + num; 146 147 if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80) 148 *dest = src[0]; 149 else for (;;) 150 { 151 Byte b = *src; 152 *dest = b; 153 if (b != 0x0F) 154 { 155 if ((b & 0xFE) == 0xE8) 156 break; 157 dest++; 158 if (++src != srcLim) 159 continue; 160 break; 161 } 162 dest++; 163 if (++src == srcLim) 164 break; 165 if ((*src & 0xF0) != 0x80) 166 continue; 167 *dest = *src; 168 break; 169 } 170 171 num = src - p->bufs[BCJ2_STREAM_MAIN]; 172 173 if (src == srcLim) 174 { 175 p->temp[3] = src[-1]; 176 p->bufs[BCJ2_STREAM_MAIN] = src; 177 p->ip += (UInt32)num; 178 p->dest += num; 179 p->state = 180 p->bufs[BCJ2_STREAM_MAIN] == 181 p->lims[BCJ2_STREAM_MAIN] ? 182 (unsigned)BCJ2_STREAM_MAIN : 183 (unsigned)BCJ2_DEC_STATE_ORIG; 184 return SZ_OK; 185 } 186 187 { 188 UInt32 bound, ttt; 189 CProb *prob; 190 Byte b = src[0]; 191 Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]); 192 193 p->temp[3] = b; 194 p->bufs[BCJ2_STREAM_MAIN] = src + 1; 195 num++; 196 p->ip += (UInt32)num; 197 p->dest += num; 198 199 prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0)); 200 201 _IF_BIT_0 202 { 203 _UPDATE_0 204 continue; 205 } 206 _UPDATE_1 207 208 } 209 } 210 } 211 212 { 213 UInt32 val; 214 unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP; 215 const Byte *cur = p->bufs[cj]; 216 Byte *dest; 217 SizeT rem; 218 219 if (cur == p->lims[cj]) 220 { 221 p->state = cj; 222 break; 223 } 224 225 val = GetBe32(cur); 226 p->bufs[cj] = cur + 4; 227 228 p->ip += 4; 229 val -= p->ip; 230 dest = p->dest; 231 rem = p->destLim - dest; 232 233 if (rem < 4) 234 { 235 p->temp[0] = (Byte)val; if (rem > 0) dest[0] = (Byte)val; val >>= 8; 236 p->temp[1] = (Byte)val; if (rem > 1) dest[1] = (Byte)val; val >>= 8; 237 p->temp[2] = (Byte)val; if (rem > 2) dest[2] = (Byte)val; val >>= 8; 238 p->temp[3] = (Byte)val; 239 p->dest = dest + rem; 240 p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; 241 break; 242 } 243 244 SetUi32(dest, val); 245 p->temp[3] = (Byte)(val >> 24); 246 p->dest = dest + 4; 247 } 248 } 249 250 if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC]) 251 { 252 p->range <<= 8; 253 p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; 254 } 255 256 return SZ_OK; 257 } 258