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