/src/lzma-fuzz/sdk/C/Bcj2.c
Line | Count | Source (jump to first uncovered line) |
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 | 249 | #define CProb UInt16 |
10 | | |
11 | 373 | #define kTopValue ((UInt32)1 << 24) |
12 | 23.6k | #define kNumModelBits 11 |
13 | 23.4k | #define kBitModelTotal (1 << kNumModelBits) |
14 | 249 | #define kNumMoveBits 5 |
15 | | |
16 | 249 | #define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound) |
17 | 213 | #define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); |
18 | 36 | #define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits)); |
19 | | |
20 | | void Bcj2Dec_Init(CBcj2Dec *p) |
21 | 90 | { |
22 | 90 | unsigned i; |
23 | | |
24 | 90 | p->state = BCJ2_DEC_STATE_OK; |
25 | 90 | p->ip = 0; |
26 | 90 | p->temp[3] = 0; |
27 | 90 | p->range = 0; |
28 | 90 | p->code = 0; |
29 | 23.3k | for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++) |
30 | 23.2k | p->probs[i] = kBitModelTotal >> 1; |
31 | 90 | } |
32 | | |
33 | | SRes Bcj2Dec_Decode(CBcj2Dec *p) |
34 | 90 | { |
35 | 90 | if (p->range <= 5) |
36 | 90 | { |
37 | 90 | p->state = BCJ2_DEC_STATE_OK; |
38 | 536 | for (; p->range != 5; p->range++) |
39 | 447 | { |
40 | 447 | if (p->range == 1 && p->code != 0) |
41 | 1 | return SZ_ERROR_DATA; |
42 | | |
43 | 446 | if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) |
44 | 0 | { |
45 | 0 | p->state = BCJ2_STREAM_RC; |
46 | 0 | return SZ_OK; |
47 | 0 | } |
48 | | |
49 | 446 | p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; |
50 | 446 | } |
51 | | |
52 | 89 | if (p->code == 0xFFFFFFFF) |
53 | 1 | return SZ_ERROR_DATA; |
54 | | |
55 | 88 | p->range = 0xFFFFFFFF; |
56 | 88 | } |
57 | 0 | else if (p->state >= BCJ2_DEC_STATE_ORIG_0) |
58 | 0 | { |
59 | 0 | while (p->state <= BCJ2_DEC_STATE_ORIG_3) |
60 | 0 | { |
61 | 0 | Byte *dest = p->dest; |
62 | 0 | if (dest == p->destLim) |
63 | 0 | return SZ_OK; |
64 | 0 | *dest = p->temp[(size_t)p->state - BCJ2_DEC_STATE_ORIG_0]; |
65 | 0 | p->state++; |
66 | 0 | p->dest = dest + 1; |
67 | 0 | } |
68 | 0 | } |
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 | 88 | for (;;) |
106 | 301 | { |
107 | 301 | if (BCJ2_IS_32BIT_STREAM(p->state)) |
108 | 0 | p->state = BCJ2_DEC_STATE_OK; |
109 | 301 | else |
110 | 301 | { |
111 | 301 | if (p->range < kTopValue) |
112 | 6 | { |
113 | 6 | if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) |
114 | 6 | { |
115 | 6 | p->state = BCJ2_STREAM_RC; |
116 | 6 | return SZ_OK; |
117 | 6 | } |
118 | 0 | p->range <<= 8; |
119 | 0 | p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; |
120 | 0 | } |
121 | | |
122 | 295 | { |
123 | 295 | const Byte *src = p->bufs[BCJ2_STREAM_MAIN]; |
124 | 295 | const Byte *srcLim; |
125 | 295 | Byte *dest; |
126 | 295 | SizeT num = p->lims[BCJ2_STREAM_MAIN] - src; |
127 | | |
128 | 295 | if (num == 0) |
129 | 4 | { |
130 | 4 | p->state = BCJ2_STREAM_MAIN; |
131 | 4 | return SZ_OK; |
132 | 4 | } |
133 | | |
134 | 291 | dest = p->dest; |
135 | 291 | if (num > (SizeT)(p->destLim - dest)) |
136 | 0 | { |
137 | 0 | num = p->destLim - dest; |
138 | 0 | if (num == 0) |
139 | 0 | { |
140 | 0 | p->state = BCJ2_DEC_STATE_ORIG; |
141 | 0 | return SZ_OK; |
142 | 0 | } |
143 | 0 | } |
144 | | |
145 | 291 | srcLim = src + num; |
146 | | |
147 | 291 | if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80) |
148 | 0 | *dest = src[0]; |
149 | 291 | else for (;;) |
150 | 4.33k | { |
151 | 4.33k | Byte b = *src; |
152 | 4.33k | *dest = b; |
153 | 4.33k | if (b != 0x0F) |
154 | 3.88k | { |
155 | 3.88k | if ((b & 0xFE) == 0xE8) |
156 | 184 | break; |
157 | 3.69k | dest++; |
158 | 3.69k | if (++src != srcLim) |
159 | 3.65k | continue; |
160 | 40 | break; |
161 | 3.69k | } |
162 | 447 | dest++; |
163 | 447 | if (++src == srcLim) |
164 | 2 | break; |
165 | 445 | if ((*src & 0xF0) != 0x80) |
166 | 380 | continue; |
167 | 65 | *dest = *src; |
168 | 65 | break; |
169 | 445 | } |
170 | | |
171 | 291 | num = src - p->bufs[BCJ2_STREAM_MAIN]; |
172 | | |
173 | 291 | if (src == srcLim) |
174 | 42 | { |
175 | 42 | p->temp[3] = src[-1]; |
176 | 42 | p->bufs[BCJ2_STREAM_MAIN] = src; |
177 | 42 | p->ip += (UInt32)num; |
178 | 42 | p->dest += num; |
179 | 42 | p->state = |
180 | 42 | p->bufs[BCJ2_STREAM_MAIN] == |
181 | 42 | p->lims[BCJ2_STREAM_MAIN] ? |
182 | 42 | (unsigned)BCJ2_STREAM_MAIN : |
183 | 42 | (unsigned)BCJ2_DEC_STATE_ORIG; |
184 | 42 | return SZ_OK; |
185 | 42 | } |
186 | | |
187 | 249 | { |
188 | 249 | UInt32 bound, ttt; |
189 | 249 | CProb *prob; |
190 | 249 | Byte b = src[0]; |
191 | 249 | Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]); |
192 | | |
193 | 249 | p->temp[3] = b; |
194 | 249 | p->bufs[BCJ2_STREAM_MAIN] = src + 1; |
195 | 249 | num++; |
196 | 249 | p->ip += (UInt32)num; |
197 | 249 | p->dest += num; |
198 | | |
199 | 249 | prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0)); |
200 | | |
201 | 249 | _IF_BIT_0 |
202 | 213 | { |
203 | 213 | _UPDATE_0 |
204 | 213 | continue; |
205 | 213 | } |
206 | 36 | _UPDATE_1 |
207 | | |
208 | 36 | } |
209 | 36 | } |
210 | 36 | } |
211 | | |
212 | 36 | { |
213 | 36 | UInt32 val; |
214 | 36 | unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP; |
215 | 36 | const Byte *cur = p->bufs[cj]; |
216 | 36 | Byte *dest; |
217 | 36 | SizeT rem; |
218 | | |
219 | 36 | if (cur == p->lims[cj]) |
220 | 36 | { |
221 | 36 | p->state = cj; |
222 | 36 | break; |
223 | 36 | } |
224 | | |
225 | 0 | val = GetBe32(cur); |
226 | 0 | p->bufs[cj] = cur + 4; |
227 | |
|
228 | 0 | p->ip += 4; |
229 | 0 | val -= p->ip; |
230 | 0 | dest = p->dest; |
231 | 0 | rem = p->destLim - dest; |
232 | | |
233 | 0 | if (rem < 4) |
234 | 0 | { |
235 | 0 | p->temp[0] = (Byte)val; if (rem > 0) dest[0] = (Byte)val; val >>= 8; |
236 | 0 | p->temp[1] = (Byte)val; if (rem > 1) dest[1] = (Byte)val; val >>= 8; |
237 | 0 | p->temp[2] = (Byte)val; if (rem > 2) dest[2] = (Byte)val; val >>= 8; |
238 | 0 | p->temp[3] = (Byte)val; |
239 | 0 | p->dest = dest + rem; |
240 | 0 | p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; |
241 | 0 | break; |
242 | 0 | } |
243 | | |
244 | 0 | SetUi32(dest, val); |
245 | 0 | p->temp[3] = (Byte)(val >> 24); |
246 | 0 | p->dest = dest + 4; |
247 | 0 | } |
248 | 0 | } |
249 | | |
250 | 36 | if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC]) |
251 | 0 | { |
252 | 0 | p->range <<= 8; |
253 | 0 | p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; |
254 | 0 | } |
255 | | |
256 | 36 | return SZ_OK; |
257 | 88 | } |