1 /* Bcj2.c -- BCJ2 Decoder (Converter for x86 code) 2 2015-08-01 : 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[p->state++ - BCJ2_DEC_STATE_ORIG_0]; 65 p->dest = dest + 1; 66 } 67 } 68 69 /* 70 if (BCJ2_IS_32BIT_STREAM(p->state)) 71 { 72 const Byte *cur = p->bufs[p->state]; 73 if (cur == p->lims[p->state]) 74 return SZ_OK; 75 p->bufs[p->state] = cur + 4; 76 77 { 78 UInt32 val; 79 Byte *dest; 80 SizeT rem; 81 82 p->ip += 4; 83 val = GetBe32(cur) - p->ip; 84 dest = p->dest; 85 rem = p->destLim - dest; 86 if (rem < 4) 87 { 88 SizeT i; 89 SetUi32(p->temp, val); 90 for (i = 0; i < rem; i++) 91 dest[i] = p->temp[i]; 92 p->dest = dest + rem; 93 p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; 94 return SZ_OK; 95 } 96 SetUi32(dest, val); 97 p->temp[3] = (Byte)(val >> 24); 98 p->dest = dest + 4; 99 p->state = BCJ2_DEC_STATE_OK; 100 } 101 } 102 */ 103 104 for (;;) 105 { 106 if (BCJ2_IS_32BIT_STREAM(p->state)) 107 p->state = BCJ2_DEC_STATE_OK; 108 else 109 { 110 if (p->range < kTopValue) 111 { 112 if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) 113 { 114 p->state = BCJ2_STREAM_RC; 115 return SZ_OK; 116 } 117 p->range <<= 8; 118 p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; 119 } 120 121 { 122 const Byte *src = p->bufs[BCJ2_STREAM_MAIN]; 123 const Byte *srcLim; 124 Byte *dest; 125 SizeT num = p->lims[BCJ2_STREAM_MAIN] - src; 126 127 if (num == 0) 128 { 129 p->state = BCJ2_STREAM_MAIN; 130 return SZ_OK; 131 } 132 133 dest = p->dest; 134 if (num > (SizeT)(p->destLim - dest)) 135 { 136 num = p->destLim - dest; 137 if (num == 0) 138 { 139 p->state = BCJ2_DEC_STATE_ORIG; 140 return SZ_OK; 141 } 142 } 143 144 srcLim = src + num; 145 146 if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80) 147 *dest = src[0]; 148 else for (;;) 149 { 150 Byte b = *src; 151 *dest = b; 152 if (b != 0x0F) 153 { 154 if ((b & 0xFE) == 0xE8) 155 break; 156 dest++; 157 if (++src != srcLim) 158 continue; 159 break; 160 } 161 dest++; 162 if (++src == srcLim) 163 break; 164 if ((*src & 0xF0) != 0x80) 165 continue; 166 *dest = *src; 167 break; 168 } 169 170 num = src - p->bufs[BCJ2_STREAM_MAIN]; 171 172 if (src == srcLim) 173 { 174 p->temp[3] = src[-1]; 175 p->bufs[BCJ2_STREAM_MAIN] = src; 176 p->ip += (UInt32)num; 177 p->dest += num; 178 p->state = 179 p->bufs[BCJ2_STREAM_MAIN] == 180 p->lims[BCJ2_STREAM_MAIN] ? 181 (unsigned)BCJ2_STREAM_MAIN : 182 (unsigned)BCJ2_DEC_STATE_ORIG; 183 return SZ_OK; 184 } 185 186 { 187 UInt32 bound, ttt; 188 CProb *prob; 189 Byte b = src[0]; 190 Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]); 191 192 p->temp[3] = b; 193 p->bufs[BCJ2_STREAM_MAIN] = src + 1; 194 num++; 195 p->ip += (UInt32)num; 196 p->dest += num; 197 198 prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0)); 199 200 _IF_BIT_0 201 { 202 _UPDATE_0 203 continue; 204 } 205 _UPDATE_1 206 207 } 208 } 209 } 210 211 { 212 UInt32 val; 213 unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP; 214 const Byte *cur = p->bufs[cj]; 215 Byte *dest; 216 SizeT rem; 217 218 if (cur == p->lims[cj]) 219 { 220 p->state = cj; 221 break; 222 } 223 224 val = GetBe32(cur); 225 p->bufs[cj] = cur + 4; 226 227 p->ip += 4; 228 val -= p->ip; 229 dest = p->dest; 230 rem = p->destLim - dest; 231 232 if (rem < 4) 233 { 234 SizeT i; 235 SetUi32(p->temp, val); 236 for (i = 0; i < rem; i++) 237 dest[i] = p->temp[i]; 238 p->dest = dest + rem; 239 p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; 240 break; 241 } 242 243 SetUi32(dest, val); 244 p->temp[3] = (Byte)(val >> 24); 245 p->dest = dest + 4; 246 } 247 } 248 249 if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC]) 250 { 251 p->range <<= 8; 252 p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; 253 } 254 255 return SZ_OK; 256 } 257