OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Native Client Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include <vector> | |
6 | |
7 #include "common/dwarf/bytereader-inl.h" | |
8 #include "common/dwarf/bytereader.h" | |
9 #include "common/dwarf/dwarf2enums.h" | |
10 | |
11 #include "common/types.h" | |
12 #include "dwarf_reader/dwarf_parse.h" | |
13 #include "dwarf_reader/dwarf_vm.h" | |
14 | |
15 #ifdef WIN32 | |
16 #pragma warning (disable:4244) | |
17 #endif | |
18 | |
19 using namespace dwarf2reader; | |
20 | |
21 #define Error(x) do { vm->ErrorString(x); return 0; } while(0) | |
22 #define NEEDS(n) if (stack.size() < (n)) Error("Stack underflow"); | |
23 | |
24 namespace dwarf_reader { | |
25 | |
26 #define address_t uint32 | |
27 #define signed_address_t int32 | |
28 #define StackTop() (&stack.back()) | |
29 #define StackSecond() (&stack[stack.size()-2]) | |
30 #define StackThird() (&stack[stack.size()-3]) | |
31 #define SignedStackTop() ((signed_address_t*) StackTop()) | |
32 #define SignedStackSecond() ((signed_address_t*) StackSecond()) | |
33 #define SignedStackThird() ((signed_address_t*) StackThird()) | |
34 | |
35 uint32_t DwarfRun32(IDwarfVM *vm, | |
36 ByteReader *reader, | |
37 const char *program, | |
38 int length) { | |
39 std::vector<uint32> stack; | |
40 const char *program_end = program + length; | |
41 | |
42 stack.push_back(0); | |
43 while (program < program_end) { | |
44 uint8 opcode = reader->ReadOneByte(program); | |
45 program++; | |
46 switch (opcode) { | |
47 | |
48 // Register name operators | |
49 case DW_OP_reg0: | |
50 case DW_OP_reg1: | |
51 case DW_OP_reg2: | |
52 case DW_OP_reg3: | |
53 case DW_OP_reg4: | |
54 case DW_OP_reg5: | |
55 case DW_OP_reg6: | |
56 case DW_OP_reg7: | |
57 case DW_OP_reg8: | |
58 case DW_OP_reg9: | |
59 case DW_OP_reg10: | |
60 case DW_OP_reg11: | |
61 case DW_OP_reg12: | |
62 case DW_OP_reg13: | |
63 case DW_OP_reg14: | |
64 case DW_OP_reg15: | |
65 case DW_OP_reg16: | |
66 case DW_OP_reg17: | |
67 case DW_OP_reg18: | |
68 case DW_OP_reg19: | |
69 case DW_OP_reg20: | |
70 case DW_OP_reg21: | |
71 case DW_OP_reg22: | |
72 case DW_OP_reg23: | |
73 case DW_OP_reg24: | |
74 case DW_OP_reg25: | |
75 case DW_OP_reg26: | |
76 case DW_OP_reg27: | |
77 case DW_OP_reg28: | |
78 case DW_OP_reg29: | |
79 case DW_OP_reg30: | |
80 case DW_OP_reg31: | |
81 stack.push_back(opcode - DW_OP_reg0); | |
82 break; | |
83 | |
84 case DW_OP_regX: { | |
85 size_t len; | |
86 stack.push_back(reader->ReadUnsignedLEB128(program, &len)); | |
87 program += len; | |
88 break; | |
89 } | |
90 | |
91 // Literal encodings | |
92 | |
93 case DW_OP_lit0: | |
94 case DW_OP_lit1: | |
95 case DW_OP_lit2: | |
96 case DW_OP_lit3: | |
97 case DW_OP_lit4: | |
98 case DW_OP_lit5: | |
99 case DW_OP_lit6: | |
100 case DW_OP_lit7: | |
101 case DW_OP_lit8: | |
102 case DW_OP_lit9: | |
103 case DW_OP_lit10: | |
104 case DW_OP_lit11: | |
105 case DW_OP_lit12: | |
106 case DW_OP_lit13: | |
107 case DW_OP_lit14: | |
108 case DW_OP_lit15: | |
109 case DW_OP_lit16: | |
110 case DW_OP_lit17: | |
111 case DW_OP_lit18: | |
112 case DW_OP_lit19: | |
113 case DW_OP_lit20: | |
114 case DW_OP_lit21: | |
115 case DW_OP_lit22: | |
116 case DW_OP_lit23: | |
117 case DW_OP_lit24: | |
118 case DW_OP_lit25: | |
119 case DW_OP_lit26: | |
120 case DW_OP_lit27: | |
121 case DW_OP_lit28: | |
122 case DW_OP_lit29: | |
123 case DW_OP_lit30: | |
124 case DW_OP_lit31: | |
125 stack.push_back(opcode - DW_OP_lit0); | |
126 break; | |
127 | |
128 case DW_OP_addr: | |
129 stack.push_back(reader->ReadAddress(program)); | |
130 program += reader->AddressSize(); | |
131 break; | |
132 | |
133 case DW_OP_const1u: | |
134 stack.push_back(reader->ReadOneByte(program)); | |
135 program++; | |
136 break; | |
137 | |
138 case DW_OP_const1s: | |
139 stack.push_back(static_cast<int8>(reader->ReadOneByte(program))); | |
140 program++; | |
141 break; | |
142 | |
143 case DW_OP_const2u: | |
144 stack.push_back(reader->ReadTwoBytes(program)); | |
145 program += 2; | |
146 break; | |
147 | |
148 case DW_OP_const2s: | |
149 stack.push_back(static_cast<int16>(reader->ReadTwoBytes(program))); | |
150 program += 2; | |
151 break; | |
152 | |
153 case DW_OP_const4u: | |
154 stack.push_back(reader->ReadFourBytes(program)); | |
155 program += 4; | |
156 break; | |
157 | |
158 case DW_OP_const4s: | |
159 stack.push_back(static_cast<int32>(reader->ReadFourBytes(program))); | |
160 program += 4; | |
161 break; | |
162 | |
163 case DW_OP_const8u: | |
164 stack.push_back(reader->ReadEightBytes(program)); | |
165 program += 8; | |
166 break; | |
167 | |
168 case DW_OP_const8s: | |
169 stack.push_back(static_cast<int64>(reader->ReadEightBytes(program))); | |
170 program += 8; | |
171 break; | |
172 | |
173 case DW_OP_constu: { | |
174 size_t len; | |
175 stack.push_back(reader->ReadUnsignedLEB128(program, &len)); | |
176 program += len; | |
177 break; | |
178 } | |
179 | |
180 case DW_OP_consts: { | |
181 size_t len; | |
182 stack.push_back(reader->ReadSignedLEB128(program, &len)); | |
183 program += len; | |
184 break; | |
185 } | |
186 | |
187 // Register based addressing | |
188 | |
189 case DW_OP_fbreg: { | |
190 size_t len; | |
191 stack.push_back(reader->ReadSignedLEB128(program, &len) + | |
192 vm->ReadFrameBase()); | |
193 program += len; | |
194 break; | |
195 } | |
196 | |
197 case DW_OP_breg0: | |
198 case DW_OP_breg1: | |
199 case DW_OP_breg2: | |
200 case DW_OP_breg3: | |
201 case DW_OP_breg4: | |
202 case DW_OP_breg5: | |
203 case DW_OP_breg6: | |
204 case DW_OP_breg7: | |
205 case DW_OP_breg8: | |
206 case DW_OP_breg9: | |
207 case DW_OP_breg10: | |
208 case DW_OP_breg11: | |
209 case DW_OP_breg12: | |
210 case DW_OP_breg13: | |
211 case DW_OP_breg14: | |
212 case DW_OP_breg15: | |
213 case DW_OP_breg16: | |
214 case DW_OP_breg17: | |
215 case DW_OP_breg18: | |
216 case DW_OP_breg19: | |
217 case DW_OP_breg20: | |
218 case DW_OP_breg21: | |
219 case DW_OP_breg22: | |
220 case DW_OP_breg23: | |
221 case DW_OP_breg24: | |
222 case DW_OP_breg25: | |
223 case DW_OP_breg26: | |
224 case DW_OP_breg27: | |
225 case DW_OP_breg28: | |
226 case DW_OP_breg29: | |
227 case DW_OP_breg30: | |
228 case DW_OP_breg31: { | |
229 size_t len; | |
230 stack.push_back(reader->ReadSignedLEB128(program, &len) + | |
231 vm->ReadRegister(opcode - DW_OP_breg0)); | |
232 program += len; | |
233 break; | |
234 } | |
235 | |
236 case DW_OP_bregX: { | |
237 size_t len; | |
238 uint64 reg = reader->ReadUnsignedLEB128(program, &len); | |
239 program += len; | |
240 stack.push_back(reader->ReadSignedLEB128(program, &len) + | |
241 vm->ReadRegister(reg)); | |
242 program += len; | |
243 break; | |
244 } | |
245 | |
246 // Stack operations | |
247 | |
248 case DW_OP_dup: | |
249 NEEDS(1) | |
250 stack.push_back(*StackTop()); | |
251 break; | |
252 | |
253 case DW_OP_drop: | |
254 NEEDS(1) | |
255 stack.pop_back(); | |
256 break; | |
257 | |
258 case DW_OP_pick: { | |
259 int ofs = stack.size() - 1 - reader->ReadOneByte(program); | |
260 program++; | |
261 if (ofs < 0) Error("DW_OP_pick: bad offset"); | |
262 stack.push_back(stack[ofs]); | |
263 break; | |
264 } | |
265 | |
266 case DW_OP_over: | |
267 NEEDS(2) | |
268 stack.push_back(*StackSecond()); | |
269 break; | |
270 | |
271 case DW_OP_swap: { | |
272 NEEDS(2) | |
273 address_t tmp = *StackTop(); | |
274 *StackTop() = *StackSecond(); | |
275 *StackSecond() = tmp; | |
276 break; | |
277 } | |
278 | |
279 case DW_OP_rot: { | |
280 NEEDS(3) | |
281 address_t tmp = *StackTop(); | |
282 *StackTop() = *StackThird(); | |
283 *StackThird() = *StackSecond(); | |
284 *StackSecond() = tmp; | |
285 break; | |
286 } | |
287 | |
288 case DW_OP_deref: | |
289 NEEDS(1) | |
290 *StackTop() = vm->ReadMemory(*StackTop(), reader->AddressSize()); | |
291 break; | |
292 | |
293 case DW_OP_deref_size: | |
294 NEEDS(1) | |
295 *StackTop() = vm->ReadMemory(*StackTop(), *program++); | |
296 break; | |
297 | |
298 // DW_OP_xderef and DW_OP_xderef_size not supported. | |
299 | |
300 // Arithmetic and logical operations | |
301 | |
302 case DW_OP_abs: | |
303 NEEDS(1) | |
304 *StackTop() = abs(*SignedStackTop()); | |
305 break; | |
306 | |
307 case DW_OP_and: | |
308 NEEDS(2) | |
309 *StackSecond() &= *StackTop(); | |
310 stack.pop_back(); | |
311 break; | |
312 | |
313 case DW_OP_div: | |
314 NEEDS(2) | |
315 *SignedStackSecond() /= *SignedStackTop(); | |
316 stack.pop_back(); | |
317 break; | |
318 | |
319 case DW_OP_minus: | |
320 NEEDS(2) | |
321 *StackSecond() -= *StackTop(); | |
322 stack.pop_back(); | |
323 break; | |
324 | |
325 case DW_OP_mod: | |
326 NEEDS(2) | |
327 *StackSecond() %= *StackTop(); | |
328 stack.pop_back(); | |
329 break; | |
330 | |
331 case DW_OP_mul: | |
332 NEEDS(2) | |
333 *StackSecond() *= *StackTop(); | |
334 stack.pop_back(); | |
335 break; | |
336 | |
337 case DW_OP_neg: | |
338 NEEDS(1) | |
339 *SignedStackTop() = -*SignedStackTop(); | |
340 break; | |
341 | |
342 case DW_OP_not: | |
343 NEEDS(1) | |
344 *StackTop() = ~*StackTop(); | |
345 break; | |
346 | |
347 case DW_OP_or: | |
348 NEEDS(2) | |
349 *StackSecond() |= *StackTop(); | |
350 stack.pop_back(); | |
351 break; | |
352 | |
353 case DW_OP_plus: | |
354 NEEDS(2) | |
355 *StackSecond() += *StackTop(); | |
356 stack.pop_back(); | |
357 break; | |
358 | |
359 case DW_OP_plus_uconst: { | |
360 NEEDS(1) | |
361 size_t len; | |
362 *StackTop() += reader->ReadUnsignedLEB128(program, &len); | |
363 program += len; | |
364 break; | |
365 } | |
366 | |
367 case DW_OP_shl: | |
368 NEEDS(2) | |
369 *StackSecond() <<= *StackTop(); | |
370 stack.pop_back(); | |
371 break; | |
372 | |
373 case DW_OP_shr: | |
374 NEEDS(2) | |
375 *StackSecond() >>= *StackTop(); | |
376 stack.pop_back(); | |
377 break; | |
378 | |
379 case DW_OP_shra: | |
380 NEEDS(2) | |
381 *SignedStackSecond() >>= *StackTop(); | |
382 stack.pop_back(); | |
383 break; | |
384 | |
385 case DW_OP_xor: | |
386 NEEDS(2) | |
387 *StackSecond() ^= *StackTop(); | |
388 stack.pop_back(); | |
389 break; | |
390 | |
391 // Control flow operators | |
392 | |
393 case DW_OP_le: | |
394 NEEDS(2) | |
395 *StackSecond() = *SignedStackSecond() <= *SignedStackTop(); | |
396 stack.pop_back(); | |
397 break; | |
398 | |
399 case DW_OP_ge: | |
400 NEEDS(2) | |
401 *StackSecond() = *SignedStackSecond() >= *SignedStackTop(); | |
402 stack.pop_back(); | |
403 break; | |
404 | |
405 case DW_OP_eq: | |
406 NEEDS(2) | |
407 *StackSecond() = *SignedStackSecond() == *SignedStackTop(); | |
408 stack.pop_back(); | |
409 break; | |
410 | |
411 case DW_OP_lt: | |
412 NEEDS(2) | |
413 *StackSecond() = *SignedStackSecond() < *SignedStackTop(); | |
414 stack.pop_back(); | |
415 break; | |
416 | |
417 case DW_OP_gt: | |
418 NEEDS(2) | |
419 *StackSecond() = *SignedStackSecond() > *SignedStackTop(); | |
420 stack.pop_back(); | |
421 break; | |
422 | |
423 case DW_OP_ne: | |
424 NEEDS(2) | |
425 *StackSecond() = *SignedStackSecond() != *SignedStackTop(); | |
426 stack.pop_back(); | |
427 break; | |
428 | |
429 case DW_OP_skip: | |
430 program += 2 + static_cast<int16>(reader->ReadTwoBytes(program)); | |
431 break; | |
432 | |
433 case DW_OP_bra: { | |
434 NEEDS(1) | |
435 if (*StackTop()) { | |
436 program += static_cast<int16>(reader->ReadTwoBytes(program)); | |
437 } | |
438 program += 2; | |
439 stack.pop_back(); | |
440 break; | |
441 } | |
442 | |
443 // Special operations | |
444 | |
445 case DW_OP_piece: | |
446 // The result at the top of the stack has a 'piece size' given | |
447 // by the argument. We do not currently do anything with this number. | |
448 size_t len; | |
449 reader->ReadUnsignedLEB128(program, &len); | |
450 program += len; | |
451 break; | |
452 | |
453 case DW_OP_nop: | |
454 break; | |
455 | |
456 default: | |
457 Error("Unknown opcode"); | |
458 } | |
459 } | |
460 | |
461 if (program != program_end) Error("Invalid program length"); | |
462 return *StackTop(); | |
463 } | |
464 | |
465 #undef address_t | |
466 #undef signed_address_t | |
467 #undef StackTop | |
468 #undef StackSecond | |
469 #undef StackThird | |
470 #undef SignedStackTop | |
471 #undef SignedStackSecond | |
472 #undef SignedStackThird | |
473 | |
474 #define address_t uint64 | |
475 #define signed_address_t int64 | |
476 #define StackTop() (&stack.back()) | |
477 #define StackSecond() (&stack[stack.size()-2]) | |
478 #define StackThird() (&stack[stack.size()-3]) | |
479 #define SignedStackTop() ((signed_address_t*) StackTop()) | |
480 #define SignedStackSecond() ((signed_address_t*) StackSecond()) | |
481 #define SignedStackThird() ((signed_address_t*) StackThird()) | |
482 | |
483 uint64_t DwarfRun64(IDwarfVM *vm, | |
484 ByteReader *reader, | |
485 const char *program, | |
486 int length) { | |
487 std::vector<uint32> stack; | |
488 const char *program_end = program + length; | |
489 | |
490 stack.push_back(0); | |
491 while (program < program_end) { | |
492 uint8 opcode = reader->ReadOneByte(program); | |
493 program++; | |
494 switch (opcode) { | |
495 | |
496 // Register name operators | |
497 case DW_OP_reg0: | |
498 case DW_OP_reg1: | |
499 case DW_OP_reg2: | |
500 case DW_OP_reg3: | |
501 case DW_OP_reg4: | |
502 case DW_OP_reg5: | |
503 case DW_OP_reg6: | |
504 case DW_OP_reg7: | |
505 case DW_OP_reg8: | |
506 case DW_OP_reg9: | |
507 case DW_OP_reg10: | |
508 case DW_OP_reg11: | |
509 case DW_OP_reg12: | |
510 case DW_OP_reg13: | |
511 case DW_OP_reg14: | |
512 case DW_OP_reg15: | |
513 case DW_OP_reg16: | |
514 case DW_OP_reg17: | |
515 case DW_OP_reg18: | |
516 case DW_OP_reg19: | |
517 case DW_OP_reg20: | |
518 case DW_OP_reg21: | |
519 case DW_OP_reg22: | |
520 case DW_OP_reg23: | |
521 case DW_OP_reg24: | |
522 case DW_OP_reg25: | |
523 case DW_OP_reg26: | |
524 case DW_OP_reg27: | |
525 case DW_OP_reg28: | |
526 case DW_OP_reg29: | |
527 case DW_OP_reg30: | |
528 case DW_OP_reg31: | |
529 stack.push_back(opcode - DW_OP_reg0); | |
530 break; | |
531 | |
532 case DW_OP_regX: { | |
533 size_t len; | |
534 stack.push_back(reader->ReadUnsignedLEB128(program, &len)); | |
535 program += len; | |
536 break; | |
537 } | |
538 | |
539 // Literal encodings | |
540 | |
541 case DW_OP_lit0: | |
542 case DW_OP_lit1: | |
543 case DW_OP_lit2: | |
544 case DW_OP_lit3: | |
545 case DW_OP_lit4: | |
546 case DW_OP_lit5: | |
547 case DW_OP_lit6: | |
548 case DW_OP_lit7: | |
549 case DW_OP_lit8: | |
550 case DW_OP_lit9: | |
551 case DW_OP_lit10: | |
552 case DW_OP_lit11: | |
553 case DW_OP_lit12: | |
554 case DW_OP_lit13: | |
555 case DW_OP_lit14: | |
556 case DW_OP_lit15: | |
557 case DW_OP_lit16: | |
558 case DW_OP_lit17: | |
559 case DW_OP_lit18: | |
560 case DW_OP_lit19: | |
561 case DW_OP_lit20: | |
562 case DW_OP_lit21: | |
563 case DW_OP_lit22: | |
564 case DW_OP_lit23: | |
565 case DW_OP_lit24: | |
566 case DW_OP_lit25: | |
567 case DW_OP_lit26: | |
568 case DW_OP_lit27: | |
569 case DW_OP_lit28: | |
570 case DW_OP_lit29: | |
571 case DW_OP_lit30: | |
572 case DW_OP_lit31: | |
573 stack.push_back(opcode - DW_OP_lit0); | |
574 break; | |
575 | |
576 case DW_OP_addr: | |
577 stack.push_back(reader->ReadAddress(program)); | |
578 program += reader->AddressSize(); | |
579 break; | |
580 | |
581 case DW_OP_const1u: | |
582 stack.push_back(reader->ReadOneByte(program)); | |
583 program++; | |
584 break; | |
585 | |
586 case DW_OP_const1s: | |
587 stack.push_back(static_cast<int8>(reader->ReadOneByte(program))); | |
588 program++; | |
589 break; | |
590 | |
591 case DW_OP_const2u: | |
592 stack.push_back(reader->ReadTwoBytes(program)); | |
593 program += 2; | |
594 break; | |
595 | |
596 case DW_OP_const2s: | |
597 stack.push_back(static_cast<int16>(reader->ReadTwoBytes(program))); | |
598 program += 2; | |
599 break; | |
600 | |
601 case DW_OP_const4u: | |
602 stack.push_back(reader->ReadFourBytes(program)); | |
603 program += 4; | |
604 break; | |
605 | |
606 case DW_OP_const4s: | |
607 stack.push_back(static_cast<int32>(reader->ReadFourBytes(program))); | |
608 program += 4; | |
609 break; | |
610 | |
611 case DW_OP_const8u: | |
612 stack.push_back(reader->ReadEightBytes(program)); | |
613 program += 8; | |
614 break; | |
615 | |
616 case DW_OP_const8s: | |
617 stack.push_back(static_cast<int64>(reader->ReadEightBytes(program))); | |
618 program += 8; | |
619 break; | |
620 | |
621 case DW_OP_constu: { | |
622 size_t len; | |
623 stack.push_back(reader->ReadUnsignedLEB128(program, &len)); | |
624 program += len; | |
625 break; | |
626 } | |
627 | |
628 case DW_OP_consts: { | |
629 size_t len; | |
630 stack.push_back(reader->ReadSignedLEB128(program, &len)); | |
631 program += len; | |
632 break; | |
633 } | |
634 | |
635 // Register based addressing | |
636 | |
637 case DW_OP_fbreg: { | |
638 size_t len; | |
639 stack.push_back(reader->ReadSignedLEB128(program, &len) + | |
640 vm->ReadFrameBase()); | |
641 program += len; | |
642 break; | |
643 } | |
644 | |
645 case DW_OP_breg0: | |
646 case DW_OP_breg1: | |
647 case DW_OP_breg2: | |
648 case DW_OP_breg3: | |
649 case DW_OP_breg4: | |
650 case DW_OP_breg5: | |
651 case DW_OP_breg6: | |
652 case DW_OP_breg7: | |
653 case DW_OP_breg8: | |
654 case DW_OP_breg9: | |
655 case DW_OP_breg10: | |
656 case DW_OP_breg11: | |
657 case DW_OP_breg12: | |
658 case DW_OP_breg13: | |
659 case DW_OP_breg14: | |
660 case DW_OP_breg15: | |
661 case DW_OP_breg16: | |
662 case DW_OP_breg17: | |
663 case DW_OP_breg18: | |
664 case DW_OP_breg19: | |
665 case DW_OP_breg20: | |
666 case DW_OP_breg21: | |
667 case DW_OP_breg22: | |
668 case DW_OP_breg23: | |
669 case DW_OP_breg24: | |
670 case DW_OP_breg25: | |
671 case DW_OP_breg26: | |
672 case DW_OP_breg27: | |
673 case DW_OP_breg28: | |
674 case DW_OP_breg29: | |
675 case DW_OP_breg30: | |
676 case DW_OP_breg31: { | |
677 size_t len; | |
678 stack.push_back(reader->ReadSignedLEB128(program, &len) + | |
679 vm->ReadRegister(opcode - DW_OP_breg0)); | |
680 program += len; | |
681 break; | |
682 } | |
683 | |
684 case DW_OP_bregX: { | |
685 size_t len; | |
686 uint64 reg = reader->ReadUnsignedLEB128(program, &len); | |
687 program += len; | |
688 stack.push_back(reader->ReadSignedLEB128(program, &len) + | |
689 vm->ReadRegister(reg)); | |
690 program += len; | |
691 break; | |
692 } | |
693 | |
694 // Stack operations | |
695 | |
696 case DW_OP_dup: | |
697 NEEDS(1) | |
698 stack.push_back(*StackTop()); | |
699 break; | |
700 | |
701 case DW_OP_drop: | |
702 NEEDS(1) | |
703 stack.pop_back(); | |
704 break; | |
705 | |
706 case DW_OP_pick: { | |
707 int ofs = stack.size() - 1 - reader->ReadOneByte(program); | |
708 program++; | |
709 if (ofs < 0) Error("DW_OP_pick: bad offset"); | |
710 stack.push_back(stack[ofs]); | |
711 break; | |
712 } | |
713 | |
714 case DW_OP_over: | |
715 NEEDS(2) | |
716 stack.push_back(*StackSecond()); | |
717 break; | |
718 | |
719 case DW_OP_swap: { | |
720 NEEDS(2) | |
721 address_t tmp = *StackTop(); | |
722 *StackTop() = *StackSecond(); | |
723 *StackSecond() = tmp; | |
724 break; | |
725 } | |
726 | |
727 case DW_OP_rot: { | |
728 NEEDS(3) | |
729 address_t tmp = *StackTop(); | |
730 *StackTop() = *StackThird(); | |
731 *StackThird() = *StackSecond(); | |
732 *StackSecond() = tmp; | |
733 break; | |
734 } | |
735 | |
736 case DW_OP_deref: | |
737 NEEDS(1) | |
738 *StackTop() = vm->ReadMemory(*StackTop(), reader->AddressSize()); | |
739 break; | |
740 | |
741 case DW_OP_deref_size: | |
742 NEEDS(1) | |
743 *StackTop() = vm->ReadMemory(*StackTop(), *program++); | |
744 break; | |
745 | |
746 // DW_OP_xderef and DW_OP_xderef_size not supported. | |
747 | |
748 // Arithmetic and logical operations | |
749 | |
750 case DW_OP_abs: | |
751 NEEDS(1) | |
752 *StackTop() = abs(*SignedStackTop()); | |
753 break; | |
754 | |
755 case DW_OP_and: | |
756 NEEDS(2) | |
757 *StackSecond() &= *StackTop(); | |
758 stack.pop_back(); | |
759 break; | |
760 | |
761 case DW_OP_div: | |
762 NEEDS(2) | |
763 *SignedStackSecond() /= *SignedStackTop(); | |
764 stack.pop_back(); | |
765 break; | |
766 | |
767 case DW_OP_minus: | |
768 NEEDS(2) | |
769 *StackSecond() -= *StackTop(); | |
770 stack.pop_back(); | |
771 break; | |
772 | |
773 case DW_OP_mod: | |
774 NEEDS(2) | |
775 *StackSecond() %= *StackTop(); | |
776 stack.pop_back(); | |
777 break; | |
778 | |
779 case DW_OP_mul: | |
780 NEEDS(2) | |
781 *StackSecond() *= *StackTop(); | |
782 stack.pop_back(); | |
783 break; | |
784 | |
785 case DW_OP_neg: | |
786 NEEDS(1) | |
787 *SignedStackTop() = -*SignedStackTop(); | |
788 break; | |
789 | |
790 case DW_OP_not: | |
791 NEEDS(1) | |
792 *StackTop() = ~*StackTop(); | |
793 break; | |
794 | |
795 case DW_OP_or: | |
796 NEEDS(2) | |
797 *StackSecond() |= *StackTop(); | |
798 stack.pop_back(); | |
799 break; | |
800 | |
801 case DW_OP_plus: | |
802 NEEDS(2) | |
803 *StackSecond() += *StackTop(); | |
804 stack.pop_back(); | |
805 break; | |
806 | |
807 case DW_OP_plus_uconst: { | |
808 NEEDS(1) | |
809 size_t len; | |
810 *StackTop() += reader->ReadUnsignedLEB128(program, &len); | |
811 program += len; | |
812 break; | |
813 } | |
814 | |
815 case DW_OP_shl: | |
816 NEEDS(2) | |
817 *StackSecond() <<= *StackTop(); | |
818 stack.pop_back(); | |
819 break; | |
820 | |
821 case DW_OP_shr: | |
822 NEEDS(2) | |
823 *StackSecond() >>= *StackTop(); | |
824 stack.pop_back(); | |
825 break; | |
826 | |
827 case DW_OP_shra: | |
828 NEEDS(2) | |
829 *SignedStackSecond() >>= *StackTop(); | |
830 stack.pop_back(); | |
831 break; | |
832 | |
833 case DW_OP_xor: | |
834 NEEDS(2) | |
835 *StackSecond() ^= *StackTop(); | |
836 stack.pop_back(); | |
837 break; | |
838 | |
839 // Control flow operators | |
840 | |
841 case DW_OP_le: | |
842 NEEDS(2) | |
843 *StackSecond() = *SignedStackSecond() <= *SignedStackTop(); | |
844 stack.pop_back(); | |
845 break; | |
846 | |
847 case DW_OP_ge: | |
848 NEEDS(2) | |
849 *StackSecond() = *SignedStackSecond() >= *SignedStackTop(); | |
850 stack.pop_back(); | |
851 break; | |
852 | |
853 case DW_OP_eq: | |
854 NEEDS(2) | |
855 *StackSecond() = *SignedStackSecond() == *SignedStackTop(); | |
856 stack.pop_back(); | |
857 break; | |
858 | |
859 case DW_OP_lt: | |
860 NEEDS(2) | |
861 *StackSecond() = *SignedStackSecond() < *SignedStackTop(); | |
862 stack.pop_back(); | |
863 break; | |
864 | |
865 case DW_OP_gt: | |
866 NEEDS(2) | |
867 *StackSecond() = *SignedStackSecond() > *SignedStackTop(); | |
868 stack.pop_back(); | |
869 break; | |
870 | |
871 case DW_OP_ne: | |
872 NEEDS(2) | |
873 *StackSecond() = *SignedStackSecond() != *SignedStackTop(); | |
874 stack.pop_back(); | |
875 break; | |
876 | |
877 case DW_OP_skip: | |
878 program += 2 + static_cast<int16>(reader->ReadTwoBytes(program)); | |
879 break; | |
880 | |
881 case DW_OP_bra: { | |
882 NEEDS(1) | |
883 if (*StackTop()) { | |
884 program += static_cast<int16>(reader->ReadTwoBytes(program)); | |
885 } | |
886 program += 2; | |
887 stack.pop_back(); | |
888 break; | |
889 } | |
890 | |
891 // Special operations | |
892 | |
893 case DW_OP_piece: | |
894 // The result at the top of the stack has a 'piece size' given | |
895 // by the argument. We do not currently do anything with this number. | |
896 size_t len; | |
897 reader->ReadUnsignedLEB128(program, &len); | |
898 program += len; | |
899 break; | |
900 | |
901 case DW_OP_nop: | |
902 break; | |
903 | |
904 default: | |
905 Error("Unknown opcode"); | |
906 } | |
907 } | |
908 | |
909 if (program != program_end) Error("Invalid program length"); | |
910 return *StackTop(); | |
911 } | |
912 | |
913 | |
914 #undef NEEDS | |
915 | |
916 } | |
OLD | NEW |