blob: be343f0f218c57981aa5bae4d082ed910cad5dcb [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Andy McFadden3a1aedb2009-05-07 13:30:23 -070016
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080017/*
18 * Dalvik instruction utility functions.
Dan Bornstein84244322010-11-17 12:05:04 -080019 *
20 * IMPORTANT NOTE: Much of the contents of this file are generated
21 * automatically by the opcode-gen tool. Any edits to the generated
22 * sections will get wiped out the next time the tool is run.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080023 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080024
Dan Bornstein84244322010-11-17 12:05:04 -080025#include "InstrUtils.h"
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080026#include <stdlib.h>
27
Dan Bornstein84244322010-11-17 12:05:04 -080028/*
29 * Table that maps each opcode to the full width of instructions that
30 * use that opcode, in (16-bit) code units. Unimplemented opcodes as
31 * well as the "breakpoint" opcode have a width of zero.
32 */
Dan Bornsteinccaab182010-12-03 15:32:40 -080033static InstructionWidth gInstructionWidthTable[kNumPackedOpcodes] = {
Dan Bornstein84244322010-11-17 12:05:04 -080034 // BEGIN(libdex-widths); GENERATED AUTOMATICALLY BY opcode-gen
35 1, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 1, 1, 1, 1, 1,
36 1, 1, 1, 2, 3, 2, 2, 3, 5, 2, 2, 3, 2, 1, 1, 2,
37 2, 1, 2, 2, 3, 3, 3, 1, 1, 2, 3, 3, 3, 2, 2, 2,
38 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0,
39 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
40 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
41 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3,
42 3, 3, 3, 0, 3, 3, 3, 3, 3, 0, 0, 1, 1, 1, 1, 1,
43 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
44 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
45 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
46 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
47 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
48 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
49 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 3, 3,
50 3, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 0,
51 // END(libdex-widths)
52};
53
54/*
55 * Table that maps each opcode to the flags associated with that
56 * opcode.
57 */
Dan Bornsteinccaab182010-12-03 15:32:40 -080058static u1 gOpcodeFlagsTable[kNumPackedOpcodes] = {
Dan Bornstein84244322010-11-17 12:05:04 -080059 // BEGIN(libdex-flags); GENERATED AUTOMATICALLY BY opcode-gen
60 kInstrCanContinue,
61 kInstrCanContinue,
62 kInstrCanContinue,
63 kInstrCanContinue,
64 kInstrCanContinue,
65 kInstrCanContinue,
66 kInstrCanContinue,
67 kInstrCanContinue,
68 kInstrCanContinue,
69 kInstrCanContinue,
70 kInstrCanContinue,
71 kInstrCanContinue,
72 kInstrCanContinue,
73 kInstrCanContinue,
74 kInstrCanReturn,
75 kInstrCanReturn,
76 kInstrCanReturn,
77 kInstrCanReturn,
78 kInstrCanContinue,
79 kInstrCanContinue,
80 kInstrCanContinue,
81 kInstrCanContinue,
82 kInstrCanContinue,
83 kInstrCanContinue,
84 kInstrCanContinue,
85 kInstrCanContinue,
86 kInstrCanContinue|kInstrCanThrow,
87 kInstrCanContinue|kInstrCanThrow,
88 kInstrCanContinue|kInstrCanThrow,
89 kInstrCanContinue|kInstrCanThrow,
90 kInstrCanContinue|kInstrCanThrow,
91 kInstrCanContinue|kInstrCanThrow,
92 kInstrCanContinue|kInstrCanThrow,
93 kInstrCanContinue|kInstrCanThrow,
94 kInstrCanContinue|kInstrCanThrow,
95 kInstrCanContinue|kInstrCanThrow,
96 kInstrCanContinue|kInstrCanThrow,
97 kInstrCanContinue|kInstrCanThrow,
98 kInstrCanContinue,
99 kInstrCanThrow,
100 kInstrCanBranch,
101 kInstrCanBranch,
102 kInstrCanBranch,
103 kInstrCanContinue|kInstrCanSwitch,
104 kInstrCanContinue|kInstrCanSwitch,
105 kInstrCanContinue,
106 kInstrCanContinue,
107 kInstrCanContinue,
108 kInstrCanContinue,
109 kInstrCanContinue,
110 kInstrCanContinue|kInstrCanBranch,
111 kInstrCanContinue|kInstrCanBranch,
112 kInstrCanContinue|kInstrCanBranch,
113 kInstrCanContinue|kInstrCanBranch,
114 kInstrCanContinue|kInstrCanBranch,
115 kInstrCanContinue|kInstrCanBranch,
116 kInstrCanContinue|kInstrCanBranch,
117 kInstrCanContinue|kInstrCanBranch,
118 kInstrCanContinue|kInstrCanBranch,
119 kInstrCanContinue|kInstrCanBranch,
120 kInstrCanContinue|kInstrCanBranch,
121 kInstrCanContinue|kInstrCanBranch,
122 0,
123 0,
124 0,
125 0,
126 0,
127 0,
128 kInstrCanContinue|kInstrCanThrow,
129 kInstrCanContinue|kInstrCanThrow,
130 kInstrCanContinue|kInstrCanThrow,
131 kInstrCanContinue|kInstrCanThrow,
132 kInstrCanContinue|kInstrCanThrow,
133 kInstrCanContinue|kInstrCanThrow,
134 kInstrCanContinue|kInstrCanThrow,
135 kInstrCanContinue|kInstrCanThrow,
136 kInstrCanContinue|kInstrCanThrow,
137 kInstrCanContinue|kInstrCanThrow,
138 kInstrCanContinue|kInstrCanThrow,
139 kInstrCanContinue|kInstrCanThrow,
140 kInstrCanContinue|kInstrCanThrow,
141 kInstrCanContinue|kInstrCanThrow,
142 kInstrCanContinue|kInstrCanThrow,
143 kInstrCanContinue|kInstrCanThrow,
144 kInstrCanContinue|kInstrCanThrow,
145 kInstrCanContinue|kInstrCanThrow,
146 kInstrCanContinue|kInstrCanThrow,
147 kInstrCanContinue|kInstrCanThrow,
148 kInstrCanContinue|kInstrCanThrow,
149 kInstrCanContinue|kInstrCanThrow,
150 kInstrCanContinue|kInstrCanThrow,
151 kInstrCanContinue|kInstrCanThrow,
152 kInstrCanContinue|kInstrCanThrow,
153 kInstrCanContinue|kInstrCanThrow,
154 kInstrCanContinue|kInstrCanThrow,
155 kInstrCanContinue|kInstrCanThrow,
156 kInstrCanContinue|kInstrCanThrow,
157 kInstrCanContinue|kInstrCanThrow,
158 kInstrCanContinue|kInstrCanThrow,
159 kInstrCanContinue|kInstrCanThrow,
160 kInstrCanContinue|kInstrCanThrow,
161 kInstrCanContinue|kInstrCanThrow,
162 kInstrCanContinue|kInstrCanThrow,
163 kInstrCanContinue|kInstrCanThrow,
164 kInstrCanContinue|kInstrCanThrow,
165 kInstrCanContinue|kInstrCanThrow,
166 kInstrCanContinue|kInstrCanThrow,
167 kInstrCanContinue|kInstrCanThrow,
168 kInstrCanContinue|kInstrCanThrow,
169 kInstrCanContinue|kInstrCanThrow,
170 kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
171 kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
172 kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
173 kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
174 kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
175 0,
176 kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
177 kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
178 kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
179 kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
180 kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
181 0,
182 0,
183 kInstrCanContinue,
184 kInstrCanContinue,
185 kInstrCanContinue,
186 kInstrCanContinue,
187 kInstrCanContinue,
188 kInstrCanContinue,
189 kInstrCanContinue,
190 kInstrCanContinue,
191 kInstrCanContinue,
192 kInstrCanContinue,
193 kInstrCanContinue,
194 kInstrCanContinue,
195 kInstrCanContinue,
196 kInstrCanContinue,
197 kInstrCanContinue,
198 kInstrCanContinue,
199 kInstrCanContinue,
200 kInstrCanContinue,
201 kInstrCanContinue,
202 kInstrCanContinue,
203 kInstrCanContinue,
204 kInstrCanContinue,
205 kInstrCanContinue,
206 kInstrCanContinue,
207 kInstrCanContinue|kInstrCanThrow,
208 kInstrCanContinue|kInstrCanThrow,
209 kInstrCanContinue,
210 kInstrCanContinue,
211 kInstrCanContinue,
212 kInstrCanContinue,
213 kInstrCanContinue,
214 kInstrCanContinue,
215 kInstrCanContinue,
216 kInstrCanContinue,
217 kInstrCanContinue,
218 kInstrCanContinue|kInstrCanThrow,
219 kInstrCanContinue|kInstrCanThrow,
220 kInstrCanContinue,
221 kInstrCanContinue,
222 kInstrCanContinue,
223 kInstrCanContinue,
224 kInstrCanContinue,
225 kInstrCanContinue,
226 kInstrCanContinue,
227 kInstrCanContinue,
228 kInstrCanContinue,
229 kInstrCanContinue,
230 kInstrCanContinue,
231 kInstrCanContinue,
232 kInstrCanContinue,
233 kInstrCanContinue,
234 kInstrCanContinue,
235 kInstrCanContinue,
236 kInstrCanContinue,
237 kInstrCanContinue,
238 kInstrCanContinue,
239 kInstrCanContinue|kInstrCanThrow,
240 kInstrCanContinue|kInstrCanThrow,
241 kInstrCanContinue,
242 kInstrCanContinue,
243 kInstrCanContinue,
244 kInstrCanContinue,
245 kInstrCanContinue,
246 kInstrCanContinue,
247 kInstrCanContinue,
248 kInstrCanContinue,
249 kInstrCanContinue,
250 kInstrCanContinue|kInstrCanThrow,
251 kInstrCanContinue|kInstrCanThrow,
252 kInstrCanContinue,
253 kInstrCanContinue,
254 kInstrCanContinue,
255 kInstrCanContinue,
256 kInstrCanContinue,
257 kInstrCanContinue,
258 kInstrCanContinue,
259 kInstrCanContinue,
260 kInstrCanContinue,
261 kInstrCanContinue,
262 kInstrCanContinue,
263 kInstrCanContinue,
264 kInstrCanContinue,
265 kInstrCanContinue,
266 kInstrCanContinue,
267 kInstrCanContinue,
268 kInstrCanContinue,
269 kInstrCanContinue,
270 kInstrCanContinue,
271 kInstrCanContinue|kInstrCanThrow,
272 kInstrCanContinue|kInstrCanThrow,
273 kInstrCanContinue,
274 kInstrCanContinue,
275 kInstrCanContinue,
276 kInstrCanContinue,
277 kInstrCanContinue,
278 kInstrCanContinue,
279 kInstrCanContinue|kInstrCanThrow,
280 kInstrCanContinue|kInstrCanThrow,
281 kInstrCanContinue,
282 kInstrCanContinue,
283 kInstrCanContinue,
284 kInstrCanContinue,
285 kInstrCanContinue,
286 kInstrCanContinue,
287 kInstrCanContinue|kInstrCanThrow,
288 kInstrCanContinue|kInstrCanThrow,
289 kInstrCanContinue|kInstrCanThrow,
290 kInstrCanContinue|kInstrCanThrow,
291 kInstrCanContinue|kInstrCanThrow,
292 kInstrCanContinue|kInstrCanThrow,
293 kInstrCanContinue|kInstrCanThrow,
294 kInstrCanContinue|kInstrCanThrow,
295 kInstrCanContinue|kInstrCanThrow,
296 0,
297 kInstrCanThrow,
298 kInstrCanContinue|kInstrCanThrow,
299 kInstrCanContinue|kInstrCanThrow,
Carl Shapiro3475f9c2011-03-21 13:35:24 -0700300 kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
Dan Bornstein84244322010-11-17 12:05:04 -0800301 kInstrCanReturn,
302 kInstrCanContinue|kInstrCanThrow,
303 kInstrCanContinue|kInstrCanThrow,
304 kInstrCanContinue|kInstrCanThrow,
305 kInstrCanContinue|kInstrCanThrow,
306 kInstrCanContinue|kInstrCanThrow,
307 kInstrCanContinue|kInstrCanThrow,
308 kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
309 kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
310 kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
311 kInstrCanContinue|kInstrCanThrow|kInstrInvoke,
312 kInstrCanContinue|kInstrCanThrow,
313 kInstrCanContinue|kInstrCanThrow,
314 kInstrCanContinue|kInstrCanThrow,
315 0,
316 // END(libdex-flags)
317};
318
319/*
320 * Table that maps each opcode to the instruction format associated
321 * that opcode.
322 */
Dan Bornsteinccaab182010-12-03 15:32:40 -0800323static u1 gInstructionFormatTable[kNumPackedOpcodes] = {
Dan Bornstein84244322010-11-17 12:05:04 -0800324 // BEGIN(libdex-formats); GENERATED AUTOMATICALLY BY opcode-gen
325 kFmt10x, kFmt12x, kFmt22x, kFmt32x, kFmt12x, kFmt22x, kFmt32x,
326 kFmt12x, kFmt22x, kFmt32x, kFmt11x, kFmt11x, kFmt11x, kFmt11x,
327 kFmt10x, kFmt11x, kFmt11x, kFmt11x, kFmt11n, kFmt21s, kFmt31i,
328 kFmt21h, kFmt21s, kFmt31i, kFmt51l, kFmt21h, kFmt21c, kFmt31c,
329 kFmt21c, kFmt11x, kFmt11x, kFmt21c, kFmt22c, kFmt12x, kFmt21c,
330 kFmt22c, kFmt35c, kFmt3rc, kFmt31t, kFmt11x, kFmt10t, kFmt20t,
331 kFmt30t, kFmt31t, kFmt31t, kFmt23x, kFmt23x, kFmt23x, kFmt23x,
332 kFmt23x, kFmt22t, kFmt22t, kFmt22t, kFmt22t, kFmt22t, kFmt22t,
333 kFmt21t, kFmt21t, kFmt21t, kFmt21t, kFmt21t, kFmt21t, kFmt00x,
334 kFmt00x, kFmt00x, kFmt00x, kFmt00x, kFmt00x, kFmt23x, kFmt23x,
335 kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x,
336 kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt22c, kFmt22c,
337 kFmt22c, kFmt22c, kFmt22c, kFmt22c, kFmt22c, kFmt22c, kFmt22c,
338 kFmt22c, kFmt22c, kFmt22c, kFmt22c, kFmt22c, kFmt21c, kFmt21c,
339 kFmt21c, kFmt21c, kFmt21c, kFmt21c, kFmt21c, kFmt21c, kFmt21c,
340 kFmt21c, kFmt21c, kFmt21c, kFmt21c, kFmt21c, kFmt35c, kFmt35c,
341 kFmt35c, kFmt35c, kFmt35c, kFmt00x, kFmt3rc, kFmt3rc, kFmt3rc,
342 kFmt3rc, kFmt3rc, kFmt00x, kFmt00x, kFmt12x, kFmt12x, kFmt12x,
343 kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x,
344 kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x,
345 kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt23x, kFmt23x, kFmt23x,
346 kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x,
347 kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x,
348 kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x,
349 kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x, kFmt23x,
350 kFmt23x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x,
351 kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x,
352 kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x,
353 kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x,
354 kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt12x, kFmt22s, kFmt22s,
355 kFmt22s, kFmt22s, kFmt22s, kFmt22s, kFmt22s, kFmt22s, kFmt22b,
356 kFmt22b, kFmt22b, kFmt22b, kFmt22b, kFmt22b, kFmt22b, kFmt22b,
357 kFmt22b, kFmt22b, kFmt22b, kFmt22c, kFmt22c, kFmt21c, kFmt21c,
358 kFmt22c, kFmt22c, kFmt22c, kFmt21c, kFmt21c, kFmt00x, kFmt20bc,
359 kFmt35mi, kFmt3rmi, kFmt35c, kFmt10x, kFmt22cs, kFmt22cs, kFmt22cs,
360 kFmt22cs, kFmt22cs, kFmt22cs, kFmt35ms, kFmt3rms, kFmt35ms, kFmt3rms,
Elliott Hughesab35b502012-01-04 15:38:58 -0800361 kFmt22c, kFmt21c, kFmt21c, kFmt00x,
Dan Bornstein84244322010-11-17 12:05:04 -0800362 // END(libdex-formats)
363};
364
365/*
366 * Table that maps each opcode to the index type implied by that
367 * opcode.
368 */
Dan Bornsteinccaab182010-12-03 15:32:40 -0800369static u1 gInstructionIndexTypeTable[kNumPackedOpcodes] = {
Dan Bornstein84244322010-11-17 12:05:04 -0800370 // BEGIN(libdex-index-types); GENERATED AUTOMATICALLY BY opcode-gen
371 kIndexNone, kIndexNone, kIndexNone,
372 kIndexNone, kIndexNone, kIndexNone,
373 kIndexNone, kIndexNone, kIndexNone,
374 kIndexNone, kIndexNone, kIndexNone,
375 kIndexNone, kIndexNone, kIndexNone,
376 kIndexNone, kIndexNone, kIndexNone,
377 kIndexNone, kIndexNone, kIndexNone,
378 kIndexNone, kIndexNone, kIndexNone,
379 kIndexNone, kIndexNone, kIndexStringRef,
380 kIndexStringRef, kIndexTypeRef, kIndexNone,
381 kIndexNone, kIndexTypeRef, kIndexTypeRef,
382 kIndexNone, kIndexTypeRef, kIndexTypeRef,
383 kIndexTypeRef, kIndexTypeRef, kIndexNone,
384 kIndexNone, kIndexNone, kIndexNone,
385 kIndexNone, kIndexNone, kIndexNone,
386 kIndexNone, kIndexNone, kIndexNone,
387 kIndexNone, kIndexNone, kIndexNone,
388 kIndexNone, kIndexNone, kIndexNone,
389 kIndexNone, kIndexNone, kIndexNone,
390 kIndexNone, kIndexNone, kIndexNone,
391 kIndexNone, kIndexNone, kIndexUnknown,
392 kIndexUnknown, kIndexUnknown, kIndexUnknown,
393 kIndexUnknown, kIndexUnknown, kIndexNone,
394 kIndexNone, kIndexNone, kIndexNone,
395 kIndexNone, kIndexNone, kIndexNone,
396 kIndexNone, kIndexNone, kIndexNone,
397 kIndexNone, kIndexNone, kIndexNone,
398 kIndexNone, kIndexFieldRef, kIndexFieldRef,
399 kIndexFieldRef, kIndexFieldRef, kIndexFieldRef,
400 kIndexFieldRef, kIndexFieldRef, kIndexFieldRef,
401 kIndexFieldRef, kIndexFieldRef, kIndexFieldRef,
402 kIndexFieldRef, kIndexFieldRef, kIndexFieldRef,
403 kIndexFieldRef, kIndexFieldRef, kIndexFieldRef,
404 kIndexFieldRef, kIndexFieldRef, kIndexFieldRef,
405 kIndexFieldRef, kIndexFieldRef, kIndexFieldRef,
406 kIndexFieldRef, kIndexFieldRef, kIndexFieldRef,
407 kIndexFieldRef, kIndexFieldRef, kIndexMethodRef,
408 kIndexMethodRef, kIndexMethodRef, kIndexMethodRef,
409 kIndexMethodRef, kIndexUnknown, kIndexMethodRef,
410 kIndexMethodRef, kIndexMethodRef, kIndexMethodRef,
411 kIndexMethodRef, kIndexUnknown, kIndexUnknown,
412 kIndexNone, kIndexNone, kIndexNone,
413 kIndexNone, kIndexNone, kIndexNone,
414 kIndexNone, kIndexNone, kIndexNone,
415 kIndexNone, kIndexNone, kIndexNone,
416 kIndexNone, kIndexNone, kIndexNone,
417 kIndexNone, kIndexNone, kIndexNone,
418 kIndexNone, kIndexNone, kIndexNone,
419 kIndexNone, kIndexNone, kIndexNone,
420 kIndexNone, kIndexNone, kIndexNone,
421 kIndexNone, kIndexNone, kIndexNone,
422 kIndexNone, kIndexNone, kIndexNone,
423 kIndexNone, kIndexNone, kIndexNone,
424 kIndexNone, kIndexNone, kIndexNone,
425 kIndexNone, kIndexNone, kIndexNone,
426 kIndexNone, kIndexNone, kIndexNone,
427 kIndexNone, kIndexNone, kIndexNone,
428 kIndexNone, kIndexNone, kIndexNone,
429 kIndexNone, kIndexNone, kIndexNone,
430 kIndexNone, kIndexNone, kIndexNone,
431 kIndexNone, kIndexNone, kIndexNone,
432 kIndexNone, kIndexNone, kIndexNone,
433 kIndexNone, kIndexNone, kIndexNone,
434 kIndexNone, kIndexNone, kIndexNone,
435 kIndexNone, kIndexNone, kIndexNone,
436 kIndexNone, kIndexNone, kIndexNone,
437 kIndexNone, kIndexNone, kIndexNone,
438 kIndexNone, kIndexNone, kIndexNone,
439 kIndexNone, kIndexNone, kIndexNone,
440 kIndexNone, kIndexNone, kIndexNone,
441 kIndexNone, kIndexNone, kIndexNone,
442 kIndexNone, kIndexNone, kIndexNone,
443 kIndexNone, kIndexNone, kIndexNone,
444 kIndexNone, kIndexNone, kIndexNone,
445 kIndexNone, kIndexNone, kIndexNone,
446 kIndexNone, kIndexNone, kIndexFieldRef,
447 kIndexFieldRef, kIndexFieldRef, kIndexFieldRef,
448 kIndexFieldRef, kIndexFieldRef, kIndexFieldRef,
449 kIndexFieldRef, kIndexFieldRef, kIndexUnknown,
450 kIndexVaries, kIndexInlineMethod, kIndexInlineMethod,
451 kIndexMethodRef, kIndexNone, kIndexFieldOffset,
452 kIndexFieldOffset, kIndexFieldOffset, kIndexFieldOffset,
453 kIndexFieldOffset, kIndexFieldOffset, kIndexVtableOffset,
454 kIndexVtableOffset, kIndexVtableOffset, kIndexVtableOffset,
455 kIndexFieldRef, kIndexFieldRef, kIndexFieldRef,
Elliott Hughesab35b502012-01-04 15:38:58 -0800456 kIndexUnknown,
Dan Bornstein84244322010-11-17 12:05:04 -0800457 // END(libdex-index-types)
458};
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800459
460/*
Dan Bornstein54322392010-11-17 14:16:56 -0800461 * Global InstructionInfoTables struct.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800462 */
Dan Bornstein54322392010-11-17 14:16:56 -0800463InstructionInfoTables gDexOpcodeInfo = {
Dan Bornsteine4852762010-12-02 12:45:00 -0800464 gInstructionFormatTable,
465 gInstructionIndexTypeTable,
Dan Bornstein54322392010-11-17 14:16:56 -0800466 gOpcodeFlagsTable,
Dan Bornsteine4852762010-12-02 12:45:00 -0800467 gInstructionWidthTable
Dan Bornstein54322392010-11-17 14:16:56 -0800468};
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800469
470/*
Dan Bornstein44a38f42010-11-10 17:34:32 -0800471 * Handy macros for helping decode instructions.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800472 */
473#define FETCH(_offset) (insns[(_offset)])
Dan Bornstein44a38f42010-11-10 17:34:32 -0800474#define FETCH_u4(_offset) (fetch_u4_impl((_offset), insns))
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800475#define INST_A(_inst) (((u2)(_inst) >> 8) & 0x0f)
476#define INST_B(_inst) ((u2)(_inst) >> 12)
477#define INST_AA(_inst) ((_inst) >> 8)
478
Dan Bornstein44a38f42010-11-10 17:34:32 -0800479/* Helper for FETCH_u4, above. */
480static inline u4 fetch_u4_impl(u4 offset, const u2* insns) {
481 return insns[offset] | ((u4) insns[offset+1] << 16);
482}
483
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800484/*
485 * Decode the instruction pointed to by "insns".
486 *
487 * Fills out the pieces of "pDec" that are affected by the current
488 * instruction. Does not touch anything else.
489 */
Dan Bornstein54322392010-11-17 14:16:56 -0800490void dexDecodeInstruction(const u2* insns, DecodedInstruction* pDec)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800491{
492 u2 inst = *insns;
Dan Bornstein9a1f8162010-12-01 17:02:26 -0800493 Opcode opcode = dexOpcodeFromCodeUnit(inst);
Dan Bornsteine4852762010-12-02 12:45:00 -0800494 InstructionFormat format = dexGetFormatFromOpcode(opcode);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800495
Dan Bornstein9a1f8162010-12-01 17:02:26 -0800496 pDec->opcode = opcode;
Dan Bornsteine4852762010-12-02 12:45:00 -0800497 pDec->indexType = dexGetIndexTypeFromOpcode(opcode);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800498
Dan Bornsteinff70f762010-11-10 11:26:52 -0800499 switch (format) {
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700500 case kFmt10x: // op
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800501 /* nothing to do; copy the AA bits out for the verifier */
502 pDec->vA = INST_AA(inst);
503 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700504 case kFmt12x: // op vA, vB
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800505 pDec->vA = INST_A(inst);
506 pDec->vB = INST_B(inst);
507 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700508 case kFmt11n: // op vA, #+B
Carl Shapirode750892010-06-08 16:37:12 -0700509 pDec->vA = INST_A(inst);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800510 pDec->vB = (s4) (INST_B(inst) << 28) >> 28; // sign extend 4-bit value
511 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700512 case kFmt11x: // op vAA
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800513 pDec->vA = INST_AA(inst);
514 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700515 case kFmt10t: // op +AA
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800516 pDec->vA = (s1) INST_AA(inst); // sign-extend 8-bit value
517 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700518 case kFmt20t: // op +AAAA
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800519 pDec->vA = (s2) FETCH(1); // sign-extend 16-bit value
520 break;
Andy McFaddend3250112010-11-03 14:32:42 -0700521 case kFmt20bc: // [opt] op AA, thing@BBBB
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700522 case kFmt21c: // op vAA, thing@BBBB
523 case kFmt22x: // op vAA, vBBBB
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800524 pDec->vA = INST_AA(inst);
525 pDec->vB = FETCH(1);
526 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700527 case kFmt21s: // op vAA, #+BBBB
528 case kFmt21t: // op vAA, +BBBB
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800529 pDec->vA = INST_AA(inst);
530 pDec->vB = (s2) FETCH(1); // sign-extend 16-bit value
531 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700532 case kFmt21h: // op vAA, #+BBBB0000[00000000]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800533 pDec->vA = INST_AA(inst);
534 /*
535 * The value should be treated as right-zero-extended, but we don't
536 * actually do that here. Among other things, we don't know if it's
537 * the top bits of a 32- or 64-bit value.
538 */
539 pDec->vB = FETCH(1);
540 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700541 case kFmt23x: // op vAA, vBB, vCC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800542 pDec->vA = INST_AA(inst);
543 pDec->vB = FETCH(1) & 0xff;
544 pDec->vC = FETCH(1) >> 8;
545 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700546 case kFmt22b: // op vAA, vBB, #+CC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800547 pDec->vA = INST_AA(inst);
548 pDec->vB = FETCH(1) & 0xff;
549 pDec->vC = (s1) (FETCH(1) >> 8); // sign-extend 8-bit value
550 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700551 case kFmt22s: // op vA, vB, #+CCCC
552 case kFmt22t: // op vA, vB, +CCCC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800553 pDec->vA = INST_A(inst);
554 pDec->vB = INST_B(inst);
555 pDec->vC = (s2) FETCH(1); // sign-extend 16-bit value
556 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700557 case kFmt22c: // op vA, vB, thing@CCCC
558 case kFmt22cs: // [opt] op vA, vB, field offset CCCC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800559 pDec->vA = INST_A(inst);
560 pDec->vB = INST_B(inst);
561 pDec->vC = FETCH(1);
562 break;
Dan Bornsteinff70f762010-11-10 11:26:52 -0800563 case kFmt30t: // op +AAAAAAAA
Dan Bornstein44a38f42010-11-10 17:34:32 -0800564 pDec->vA = FETCH_u4(1); // signed 32-bit value
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800565 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700566 case kFmt31t: // op vAA, +BBBBBBBB
Andy McFaddend3250112010-11-03 14:32:42 -0700567 case kFmt31c: // op vAA, string@BBBBBBBB
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800568 pDec->vA = INST_AA(inst);
Dan Bornstein44a38f42010-11-10 17:34:32 -0800569 pDec->vB = FETCH_u4(1); // 32-bit value
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800570 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700571 case kFmt32x: // op vAAAA, vBBBB
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800572 pDec->vA = FETCH(1);
573 pDec->vB = FETCH(2);
574 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700575 case kFmt31i: // op vAA, #+BBBBBBBB
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800576 pDec->vA = INST_AA(inst);
Dan Bornstein44a38f42010-11-10 17:34:32 -0800577 pDec->vB = FETCH_u4(1); // signed 32-bit value
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800578 break;
Dan Bornstein7b3e9b02010-11-09 17:15:10 -0800579 case kFmt35c: // op {vC, vD, vE, vF, vG}, thing@BBBB
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700580 case kFmt35ms: // [opt] invoke-virtual+super
Dan Bornsteinff70f762010-11-10 11:26:52 -0800581 case kFmt35mi: // [opt] inline invoke
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800582 {
583 /*
Dan Bornstein7b3e9b02010-11-09 17:15:10 -0800584 * Note that the fields mentioned in the spec don't appear in
585 * their "usual" positions here compared to most formats. This
586 * was done so that the field names for the argument count and
587 * reference index match between this format and the corresponding
588 * range formats (3rc and friends).
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800589 *
Dan Bornstein7b3e9b02010-11-09 17:15:10 -0800590 * Bottom line: The argument count is always in vA, and the
Dan Bornsteinff70f762010-11-10 11:26:52 -0800591 * method constant (or equivalent) is always in vB.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800592 */
593 u2 regList;
594 int i, count;
595
Dan Bornstein7b3e9b02010-11-09 17:15:10 -0800596 pDec->vA = INST_B(inst); // This is labeled A in the spec.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800597 pDec->vB = FETCH(1);
598 regList = FETCH(2);
599
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800600 count = pDec->vA;
Dan Bornsteinff70f762010-11-10 11:26:52 -0800601
602 /*
603 * Copy the argument registers into the arg[] array, and
604 * also copy the first argument (if any) into vC. (The
605 * DecodedInstruction structure doesn't have separate
606 * fields for {vD, vE, vF, vG}, so there's no need to make
607 * copies of those.) Note that cases 5..2 fall through.
608 */
609 switch (count) {
610 case 5: {
611 if (format == kFmt35mi) {
612 /* A fifth arg is verboten for inline invokes. */
Steve Blocke8e1ddc2012-01-05 23:21:27 +0000613 ALOGW("Invalid arg count in 35mi (5)");
Dan Bornsteinff70f762010-11-10 11:26:52 -0800614 goto bail;
615 }
Dan Bornstein7b3e9b02010-11-09 17:15:10 -0800616 /*
Dan Bornsteinff70f762010-11-10 11:26:52 -0800617 * Per note at the top of this format decoder, the
618 * fifth argument comes from the A field in the
Dan Bornstein7b3e9b02010-11-09 17:15:10 -0800619 * instruction, but it's labeled G in the spec.
620 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800621 pDec->arg[4] = INST_A(inst);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800622 }
Dan Bornsteinff70f762010-11-10 11:26:52 -0800623 case 4: pDec->arg[3] = (regList >> 12) & 0x0f;
624 case 3: pDec->arg[2] = (regList >> 8) & 0x0f;
625 case 2: pDec->arg[1] = (regList >> 4) & 0x0f;
626 case 1: pDec->vC = pDec->arg[0] = regList & 0x0f; break;
627 case 0: break; // Valid, but no need to do anything.
628 default:
Steve Blocke8e1ddc2012-01-05 23:21:27 +0000629 ALOGW("Invalid arg count in 35c/35ms/35mi (%d)", count);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800630 goto bail;
631 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800632 }
633 break;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800634 case kFmt3rc: // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB
635 case kFmt3rms: // [opt] invoke-virtual+super/range
Dan Bornstein7b3e9b02010-11-09 17:15:10 -0800636 case kFmt3rmi: // [opt] execute-inline/range
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800637 pDec->vA = INST_AA(inst);
638 pDec->vB = FETCH(1);
639 pDec->vC = FETCH(2);
640 break;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800641 case kFmt51l: // op vAA, #+BBBBBBBBBBBBBBBB
642 pDec->vA = INST_AA(inst);
Dan Bornstein44a38f42010-11-10 17:34:32 -0800643 pDec->vB_wide = FETCH_u4(1) | ((u8) FETCH_u4(3) << 32);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800644 break;
645 default:
Steve Blocke8e1ddc2012-01-05 23:21:27 +0000646 ALOGW("Can't decode unexpected format %d (op=%d)", format, opcode);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800647 assert(false);
648 break;
649 }
650
651bail:
652 ;
653}
654
655/*
656 * Return the width of the specified instruction, or 0 if not defined. Also
657 * works for special OP_NOP entries, including switch statement data tables
658 * and array data.
659 */
Dan Bornsteine4852762010-12-02 12:45:00 -0800660size_t dexGetWidthFromInstruction(const u2* insns)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800661{
Andy McFadden228a6b02010-05-04 15:02:32 -0700662 size_t width;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800663
664 if (*insns == kPackedSwitchSignature) {
665 width = 4 + insns[1] * 2;
666 } else if (*insns == kSparseSwitchSignature) {
667 width = 2 + insns[1] * 4;
668 } else if (*insns == kArrayDataSignature) {
669 u2 elemWidth = insns[1];
670 u4 len = insns[2] | (((u4)insns[3]) << 16);
Dan Bornstein11122162010-12-01 12:30:21 -0800671 // The plus 1 is to round up for odd size and width.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800672 width = 4 + (elemWidth * len + 1) / 2;
673 } else {
Dan Bornsteine4852762010-12-02 12:45:00 -0800674 width = dexGetWidthFromOpcode(dexOpcodeFromCodeUnit(insns[0]));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800675 }
Dan Bornstein4b6e9ba2010-12-02 10:35:48 -0800676
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800677 return width;
678}