| Index: obsolete/gdb-utils/src/dwarf_reader/dwarf_vm_decode.cc
|
| diff --git a/obsolete/gdb-utils/src/dwarf_reader/dwarf_vm_decode.cc b/obsolete/gdb-utils/src/dwarf_reader/dwarf_vm_decode.cc
|
| deleted file mode 100644
|
| index ce2e9f9e5673c4353158ce2cdae8838b81ca13a4..0000000000000000000000000000000000000000
|
| --- a/obsolete/gdb-utils/src/dwarf_reader/dwarf_vm_decode.cc
|
| +++ /dev/null
|
| @@ -1,930 +0,0 @@
|
| -// Copyright 2010 Google, Inc. All Rights reserved
|
| -//
|
| -// Redistribution and use in source and binary forms, with or without
|
| -// modification, are permitted provided that the following conditions are
|
| - // met:
|
| -//
|
| -// * Redistributions of source code must retain the above copyright
|
| -// notice, this list of conditions and the following disclaimer.
|
| -// * Redistributions in binary form must reproduce the above
|
| -// copyright notice, this list of conditions and the following disclaimer
|
| -// in the documentation and/or other materials provided with the
|
| -// distribution.
|
| -// * Neither the path of Google Inc. nor the paths of its
|
| -// contributors may be used to endorse or promote products derived from
|
| -// this software without specific prior written permission.
|
| -//
|
| -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| -
|
| -#include <vector>
|
| -
|
| -#include "common/dwarf/bytereader-inl.h"
|
| -#include "common/dwarf/bytereader.h"
|
| -#include "common/dwarf/dwarf2enums.h"
|
| -
|
| -#include "common/types.h"
|
| -#include "dwarf_reader/dwarf_parse.h"
|
| -#include "dwarf_reader/dwarf_vm.h"
|
| -
|
| -#ifdef WIN32
|
| -#pragma warning (disable:4244)
|
| -#endif
|
| -
|
| -using namespace dwarf2reader;
|
| -
|
| -#define Error(x) do { vm->ErrorString(x); return 0; } while(0)
|
| -#define NEEDS(n) if (stack_.size() < (n)) Error("Stack underflow");
|
| -
|
| -namespace dwarf_reader {
|
| -
|
| -#define address_t uint32
|
| -#define signed_address_t int32
|
| -#define StackTop() (&stack_.back())
|
| -#define StackSecond() (&stack_[stack_.size()-2])
|
| -#define StackThird() (&stack_[stack_.size()-3])
|
| -#define SignedStackTop() ((signed_address_t*) StackTop())
|
| -#define SignedStackSecond() ((signed_address_t*) StackSecond())
|
| -#define SignedStackThird() ((signed_address_t*) StackThird())
|
| -
|
| -uint32_t DwarfRun32(IDwarfVM *vm, ByteReader *reader, const char *program, int length) {
|
| - std::vector<uint32> stack_;
|
| - const char *program_end = program + length;
|
| -
|
| - stack_.push_back(0);
|
| - while (program < program_end) {
|
| - uint8 opcode = reader->ReadOneByte(program);
|
| - program++;
|
| - switch (opcode) {
|
| -
|
| - // Register name operators
|
| - case DW_OP_reg0:
|
| - case DW_OP_reg1:
|
| - case DW_OP_reg2:
|
| - case DW_OP_reg3:
|
| - case DW_OP_reg4:
|
| - case DW_OP_reg5:
|
| - case DW_OP_reg6:
|
| - case DW_OP_reg7:
|
| - case DW_OP_reg8:
|
| - case DW_OP_reg9:
|
| - case DW_OP_reg10:
|
| - case DW_OP_reg11:
|
| - case DW_OP_reg12:
|
| - case DW_OP_reg13:
|
| - case DW_OP_reg14:
|
| - case DW_OP_reg15:
|
| - case DW_OP_reg16:
|
| - case DW_OP_reg17:
|
| - case DW_OP_reg18:
|
| - case DW_OP_reg19:
|
| - case DW_OP_reg20:
|
| - case DW_OP_reg21:
|
| - case DW_OP_reg22:
|
| - case DW_OP_reg23:
|
| - case DW_OP_reg24:
|
| - case DW_OP_reg25:
|
| - case DW_OP_reg26:
|
| - case DW_OP_reg27:
|
| - case DW_OP_reg28:
|
| - case DW_OP_reg29:
|
| - case DW_OP_reg30:
|
| - case DW_OP_reg31:
|
| - stack_.push_back(opcode - DW_OP_reg0);
|
| - break;
|
| -
|
| - case DW_OP_regX: {
|
| - size_t len;
|
| - stack_.push_back(reader->ReadUnsignedLEB128(program, &len));
|
| - program += len;
|
| - break;
|
| - }
|
| -
|
| - // Literal encodings
|
| -
|
| - case DW_OP_lit0:
|
| - case DW_OP_lit1:
|
| - case DW_OP_lit2:
|
| - case DW_OP_lit3:
|
| - case DW_OP_lit4:
|
| - case DW_OP_lit5:
|
| - case DW_OP_lit6:
|
| - case DW_OP_lit7:
|
| - case DW_OP_lit8:
|
| - case DW_OP_lit9:
|
| - case DW_OP_lit10:
|
| - case DW_OP_lit11:
|
| - case DW_OP_lit12:
|
| - case DW_OP_lit13:
|
| - case DW_OP_lit14:
|
| - case DW_OP_lit15:
|
| - case DW_OP_lit16:
|
| - case DW_OP_lit17:
|
| - case DW_OP_lit18:
|
| - case DW_OP_lit19:
|
| - case DW_OP_lit20:
|
| - case DW_OP_lit21:
|
| - case DW_OP_lit22:
|
| - case DW_OP_lit23:
|
| - case DW_OP_lit24:
|
| - case DW_OP_lit25:
|
| - case DW_OP_lit26:
|
| - case DW_OP_lit27:
|
| - case DW_OP_lit28:
|
| - case DW_OP_lit29:
|
| - case DW_OP_lit30:
|
| - case DW_OP_lit31:
|
| - stack_.push_back(opcode - DW_OP_lit0);
|
| - break;
|
| -
|
| - case DW_OP_addr:
|
| - stack_.push_back(reader->ReadAddress(program));
|
| - program += reader->AddressSize();
|
| - break;
|
| -
|
| - case DW_OP_const1u:
|
| - stack_.push_back(reader->ReadOneByte(program));
|
| - program++;
|
| - break;
|
| -
|
| - case DW_OP_const1s:
|
| - stack_.push_back(static_cast<int8>(reader->ReadOneByte(program)));
|
| - program++;
|
| - break;
|
| -
|
| - case DW_OP_const2u:
|
| - stack_.push_back(reader->ReadTwoBytes(program));
|
| - program += 2;
|
| - break;
|
| -
|
| - case DW_OP_const2s:
|
| - stack_.push_back(static_cast<int16>(reader->ReadTwoBytes(program)));
|
| - program += 2;
|
| - break;
|
| -
|
| - case DW_OP_const4u:
|
| - stack_.push_back(reader->ReadFourBytes(program));
|
| - program += 4;
|
| - break;
|
| -
|
| - case DW_OP_const4s:
|
| - stack_.push_back(static_cast<int32>(reader->ReadFourBytes(program)));
|
| - program += 4;
|
| - break;
|
| -
|
| - case DW_OP_const8u:
|
| - stack_.push_back(reader->ReadEightBytes(program));
|
| - program += 8;
|
| - break;
|
| -
|
| - case DW_OP_const8s:
|
| - stack_.push_back(static_cast<int64>(reader->ReadEightBytes(program)));
|
| - program += 8;
|
| - break;
|
| -
|
| - case DW_OP_constu: {
|
| - size_t len;
|
| - stack_.push_back(reader->ReadUnsignedLEB128(program, &len));
|
| - program += len;
|
| - break;
|
| - }
|
| -
|
| - case DW_OP_consts: {
|
| - size_t len;
|
| - stack_.push_back(reader->ReadSignedLEB128(program, &len));
|
| - program += len;
|
| - break;
|
| - }
|
| -
|
| - // Register based addressing
|
| -
|
| - case DW_OP_fbreg: {
|
| - size_t len;
|
| - stack_.push_back(reader->ReadSignedLEB128(program, &len) + vm->ReadFrameBase());
|
| - program += len;
|
| - break;
|
| - }
|
| -
|
| - case DW_OP_breg0:
|
| - case DW_OP_breg1:
|
| - case DW_OP_breg2:
|
| - case DW_OP_breg3:
|
| - case DW_OP_breg4:
|
| - case DW_OP_breg5:
|
| - case DW_OP_breg6:
|
| - case DW_OP_breg7:
|
| - case DW_OP_breg8:
|
| - case DW_OP_breg9:
|
| - case DW_OP_breg10:
|
| - case DW_OP_breg11:
|
| - case DW_OP_breg12:
|
| - case DW_OP_breg13:
|
| - case DW_OP_breg14:
|
| - case DW_OP_breg15:
|
| - case DW_OP_breg16:
|
| - case DW_OP_breg17:
|
| - case DW_OP_breg18:
|
| - case DW_OP_breg19:
|
| - case DW_OP_breg20:
|
| - case DW_OP_breg21:
|
| - case DW_OP_breg22:
|
| - case DW_OP_breg23:
|
| - case DW_OP_breg24:
|
| - case DW_OP_breg25:
|
| - case DW_OP_breg26:
|
| - case DW_OP_breg27:
|
| - case DW_OP_breg28:
|
| - case DW_OP_breg29:
|
| - case DW_OP_breg30:
|
| - case DW_OP_breg31: {
|
| - size_t len;
|
| - stack_.push_back(reader->ReadSignedLEB128(program, &len) +
|
| - vm->ReadRegister(opcode - DW_OP_breg0));
|
| - program += len;
|
| - break;
|
| - }
|
| -
|
| - case DW_OP_bregX: {
|
| - size_t len;
|
| - uint64 reg = reader->ReadUnsignedLEB128(program, &len);
|
| - program += len;
|
| - stack_.push_back(reader->ReadSignedLEB128(program, &len) + vm->ReadRegister(reg));
|
| - program += len;
|
| - break;
|
| - }
|
| -
|
| - // Stack operations
|
| -
|
| - case DW_OP_dup:
|
| - NEEDS(1)
|
| - stack_.push_back(*StackTop());
|
| - break;
|
| -
|
| - case DW_OP_drop:
|
| - NEEDS(1)
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_pick: {
|
| - int ofs = stack_.size() - 1 - reader->ReadOneByte(program);
|
| - program++;
|
| - if (ofs < 0) Error("DW_OP_pick: bad offset");
|
| - stack_.push_back(stack_[ofs]);
|
| - break;
|
| - }
|
| -
|
| - case DW_OP_over:
|
| - NEEDS(2)
|
| - stack_.push_back(*StackSecond());
|
| - break;
|
| -
|
| - case DW_OP_swap: {
|
| - NEEDS(2)
|
| - address_t tmp = *StackTop();
|
| - *StackTop() = *StackSecond();
|
| - *StackSecond() = tmp;
|
| - break;
|
| - }
|
| -
|
| - case DW_OP_rot: {
|
| - NEEDS(3)
|
| - address_t tmp = *StackTop();
|
| - *StackTop() = *StackThird();
|
| - *StackThird() = *StackSecond();
|
| - *StackSecond() = tmp;
|
| - break;
|
| - }
|
| -
|
| - case DW_OP_deref:
|
| - NEEDS(1)
|
| - *StackTop() = vm->ReadMemory(*StackTop(), reader->AddressSize());
|
| - break;
|
| -
|
| - case DW_OP_deref_size:
|
| - NEEDS(1)
|
| - *StackTop() = vm->ReadMemory(*StackTop(), *program++);
|
| - break;
|
| -
|
| - // DW_OP_xderef and DW_OP_xderef_size not supported.
|
| -
|
| - // Arithmetic and logical operations
|
| -
|
| - case DW_OP_abs:
|
| - NEEDS(1)
|
| - *StackTop() = abs(*SignedStackTop());
|
| - break;
|
| -
|
| - case DW_OP_and:
|
| - NEEDS(2)
|
| - *StackSecond() &= *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_div:
|
| - NEEDS(2)
|
| - *SignedStackSecond() /= *SignedStackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_minus:
|
| - NEEDS(2)
|
| - *StackSecond() -= *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_mod:
|
| - NEEDS(2)
|
| - *StackSecond() %= *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_mul:
|
| - NEEDS(2)
|
| - *StackSecond() *= *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_neg:
|
| - NEEDS(1)
|
| - *SignedStackTop() = -*SignedStackTop();
|
| - break;
|
| -
|
| - case DW_OP_not:
|
| - NEEDS(1)
|
| - *StackTop() = ~*StackTop();
|
| - break;
|
| -
|
| - case DW_OP_or:
|
| - NEEDS(2)
|
| - *StackSecond() |= *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_plus:
|
| - NEEDS(2)
|
| - *StackSecond() += *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_plus_uconst: {
|
| - NEEDS(1)
|
| - size_t len;
|
| - *StackTop() += reader->ReadUnsignedLEB128(program, &len);
|
| - program += len;
|
| - break;
|
| - }
|
| -
|
| - case DW_OP_shl:
|
| - NEEDS(2)
|
| - *StackSecond() <<= *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_shr:
|
| - NEEDS(2)
|
| - *StackSecond() >>= *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_shra:
|
| - NEEDS(2)
|
| - *SignedStackSecond() >>= *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_xor:
|
| - NEEDS(2)
|
| - *StackSecond() ^= *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - // Control flow operators
|
| -
|
| - case DW_OP_le:
|
| - NEEDS(2)
|
| - *StackSecond() = *SignedStackSecond() <= *SignedStackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_ge:
|
| - NEEDS(2)
|
| - *StackSecond() = *SignedStackSecond() >= *SignedStackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_eq:
|
| - NEEDS(2)
|
| - *StackSecond() = *SignedStackSecond() == *SignedStackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_lt:
|
| - NEEDS(2)
|
| - *StackSecond() = *SignedStackSecond() < *SignedStackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_gt:
|
| - NEEDS(2)
|
| - *StackSecond() = *SignedStackSecond() > *SignedStackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_ne:
|
| - NEEDS(2)
|
| - *StackSecond() = *SignedStackSecond() != *SignedStackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_skip:
|
| - program += 2 + static_cast<int16>(reader->ReadTwoBytes(program));
|
| - break;
|
| -
|
| - case DW_OP_bra: {
|
| - NEEDS(1)
|
| - if (*StackTop()) {
|
| - program += static_cast<int16>(reader->ReadTwoBytes(program));
|
| - }
|
| - program += 2;
|
| - stack_.pop_back();
|
| - break;
|
| - }
|
| -
|
| - // Special operations
|
| -
|
| - case DW_OP_piece:
|
| - // The result at the top of the stack has a 'piece size' given
|
| - // by the argument. We do not currently do anything with this number.
|
| - size_t len;
|
| - reader->ReadUnsignedLEB128(program, &len);
|
| - program += len;
|
| - break;
|
| -
|
| - case DW_OP_nop:
|
| - break;
|
| -
|
| - default:
|
| - Error("Unknown opcode");
|
| - }
|
| - }
|
| -
|
| - if (program != program_end) Error("Invalid program length");
|
| - return *StackTop();
|
| -}
|
| -
|
| -#undef address_t
|
| -#undef signed_address_t
|
| -#undef StackTop
|
| -#undef StackSecond
|
| -#undef StackThird
|
| -#undef SignedStackTop
|
| -#undef SignedStackSecond
|
| -#undef SignedStackThird
|
| -
|
| -#define address_t uint64
|
| -#define signed_address_t int64
|
| -#define StackTop() (&stack_.back())
|
| -#define StackSecond() (&stack_[stack_.size()-2])
|
| -#define StackThird() (&stack_[stack_.size()-3])
|
| -#define SignedStackTop() ((signed_address_t*) StackTop())
|
| -#define SignedStackSecond() ((signed_address_t*) StackSecond())
|
| -#define SignedStackThird() ((signed_address_t*) StackThird())
|
| -
|
| -uint64_t DwarfRun64(IDwarfVM *vm, ByteReader *reader, const char *program, int length) {
|
| - std::vector<uint32> stack_;
|
| - const char *program_end = program + length;
|
| -
|
| - stack_.push_back(0);
|
| - while (program < program_end) {
|
| - uint8 opcode = reader->ReadOneByte(program);
|
| - program++;
|
| - switch (opcode) {
|
| -
|
| - // Register name operators
|
| - case DW_OP_reg0:
|
| - case DW_OP_reg1:
|
| - case DW_OP_reg2:
|
| - case DW_OP_reg3:
|
| - case DW_OP_reg4:
|
| - case DW_OP_reg5:
|
| - case DW_OP_reg6:
|
| - case DW_OP_reg7:
|
| - case DW_OP_reg8:
|
| - case DW_OP_reg9:
|
| - case DW_OP_reg10:
|
| - case DW_OP_reg11:
|
| - case DW_OP_reg12:
|
| - case DW_OP_reg13:
|
| - case DW_OP_reg14:
|
| - case DW_OP_reg15:
|
| - case DW_OP_reg16:
|
| - case DW_OP_reg17:
|
| - case DW_OP_reg18:
|
| - case DW_OP_reg19:
|
| - case DW_OP_reg20:
|
| - case DW_OP_reg21:
|
| - case DW_OP_reg22:
|
| - case DW_OP_reg23:
|
| - case DW_OP_reg24:
|
| - case DW_OP_reg25:
|
| - case DW_OP_reg26:
|
| - case DW_OP_reg27:
|
| - case DW_OP_reg28:
|
| - case DW_OP_reg29:
|
| - case DW_OP_reg30:
|
| - case DW_OP_reg31:
|
| - stack_.push_back(opcode - DW_OP_reg0);
|
| - break;
|
| -
|
| - case DW_OP_regX: {
|
| - size_t len;
|
| - stack_.push_back(reader->ReadUnsignedLEB128(program, &len));
|
| - program += len;
|
| - break;
|
| - }
|
| -
|
| - // Literal encodings
|
| -
|
| - case DW_OP_lit0:
|
| - case DW_OP_lit1:
|
| - case DW_OP_lit2:
|
| - case DW_OP_lit3:
|
| - case DW_OP_lit4:
|
| - case DW_OP_lit5:
|
| - case DW_OP_lit6:
|
| - case DW_OP_lit7:
|
| - case DW_OP_lit8:
|
| - case DW_OP_lit9:
|
| - case DW_OP_lit10:
|
| - case DW_OP_lit11:
|
| - case DW_OP_lit12:
|
| - case DW_OP_lit13:
|
| - case DW_OP_lit14:
|
| - case DW_OP_lit15:
|
| - case DW_OP_lit16:
|
| - case DW_OP_lit17:
|
| - case DW_OP_lit18:
|
| - case DW_OP_lit19:
|
| - case DW_OP_lit20:
|
| - case DW_OP_lit21:
|
| - case DW_OP_lit22:
|
| - case DW_OP_lit23:
|
| - case DW_OP_lit24:
|
| - case DW_OP_lit25:
|
| - case DW_OP_lit26:
|
| - case DW_OP_lit27:
|
| - case DW_OP_lit28:
|
| - case DW_OP_lit29:
|
| - case DW_OP_lit30:
|
| - case DW_OP_lit31:
|
| - stack_.push_back(opcode - DW_OP_lit0);
|
| - break;
|
| -
|
| - case DW_OP_addr:
|
| - stack_.push_back(reader->ReadAddress(program));
|
| - program += reader->AddressSize();
|
| - break;
|
| -
|
| - case DW_OP_const1u:
|
| - stack_.push_back(reader->ReadOneByte(program));
|
| - program++;
|
| - break;
|
| -
|
| - case DW_OP_const1s:
|
| - stack_.push_back(static_cast<int8>(reader->ReadOneByte(program)));
|
| - program++;
|
| - break;
|
| -
|
| - case DW_OP_const2u:
|
| - stack_.push_back(reader->ReadTwoBytes(program));
|
| - program += 2;
|
| - break;
|
| -
|
| - case DW_OP_const2s:
|
| - stack_.push_back(static_cast<int16>(reader->ReadTwoBytes(program)));
|
| - program += 2;
|
| - break;
|
| -
|
| - case DW_OP_const4u:
|
| - stack_.push_back(reader->ReadFourBytes(program));
|
| - program += 4;
|
| - break;
|
| -
|
| - case DW_OP_const4s:
|
| - stack_.push_back(static_cast<int32>(reader->ReadFourBytes(program)));
|
| - program += 4;
|
| - break;
|
| -
|
| - case DW_OP_const8u:
|
| - stack_.push_back(reader->ReadEightBytes(program));
|
| - program += 8;
|
| - break;
|
| -
|
| - case DW_OP_const8s:
|
| - stack_.push_back(static_cast<int64>(reader->ReadEightBytes(program)));
|
| - program += 8;
|
| - break;
|
| -
|
| - case DW_OP_constu: {
|
| - size_t len;
|
| - stack_.push_back(reader->ReadUnsignedLEB128(program, &len));
|
| - program += len;
|
| - break;
|
| - }
|
| -
|
| - case DW_OP_consts: {
|
| - size_t len;
|
| - stack_.push_back(reader->ReadSignedLEB128(program, &len));
|
| - program += len;
|
| - break;
|
| - }
|
| -
|
| - // Register based addressing
|
| -
|
| - case DW_OP_fbreg: {
|
| - size_t len;
|
| - stack_.push_back(reader->ReadSignedLEB128(program, &len) + vm->ReadFrameBase());
|
| - program += len;
|
| - break;
|
| - }
|
| -
|
| - case DW_OP_breg0:
|
| - case DW_OP_breg1:
|
| - case DW_OP_breg2:
|
| - case DW_OP_breg3:
|
| - case DW_OP_breg4:
|
| - case DW_OP_breg5:
|
| - case DW_OP_breg6:
|
| - case DW_OP_breg7:
|
| - case DW_OP_breg8:
|
| - case DW_OP_breg9:
|
| - case DW_OP_breg10:
|
| - case DW_OP_breg11:
|
| - case DW_OP_breg12:
|
| - case DW_OP_breg13:
|
| - case DW_OP_breg14:
|
| - case DW_OP_breg15:
|
| - case DW_OP_breg16:
|
| - case DW_OP_breg17:
|
| - case DW_OP_breg18:
|
| - case DW_OP_breg19:
|
| - case DW_OP_breg20:
|
| - case DW_OP_breg21:
|
| - case DW_OP_breg22:
|
| - case DW_OP_breg23:
|
| - case DW_OP_breg24:
|
| - case DW_OP_breg25:
|
| - case DW_OP_breg26:
|
| - case DW_OP_breg27:
|
| - case DW_OP_breg28:
|
| - case DW_OP_breg29:
|
| - case DW_OP_breg30:
|
| - case DW_OP_breg31: {
|
| - size_t len;
|
| - stack_.push_back(reader->ReadSignedLEB128(program, &len) +
|
| - vm->ReadRegister(opcode - DW_OP_breg0));
|
| - program += len;
|
| - break;
|
| - }
|
| -
|
| - case DW_OP_bregX: {
|
| - size_t len;
|
| - uint64 reg = reader->ReadUnsignedLEB128(program, &len);
|
| - program += len;
|
| - stack_.push_back(reader->ReadSignedLEB128(program, &len) + vm->ReadRegister(reg));
|
| - program += len;
|
| - break;
|
| - }
|
| -
|
| - // Stack operations
|
| -
|
| - case DW_OP_dup:
|
| - NEEDS(1)
|
| - stack_.push_back(*StackTop());
|
| - break;
|
| -
|
| - case DW_OP_drop:
|
| - NEEDS(1)
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_pick: {
|
| - int ofs = stack_.size() - 1 - reader->ReadOneByte(program);
|
| - program++;
|
| - if (ofs < 0) Error("DW_OP_pick: bad offset");
|
| - stack_.push_back(stack_[ofs]);
|
| - break;
|
| - }
|
| -
|
| - case DW_OP_over:
|
| - NEEDS(2)
|
| - stack_.push_back(*StackSecond());
|
| - break;
|
| -
|
| - case DW_OP_swap: {
|
| - NEEDS(2)
|
| - address_t tmp = *StackTop();
|
| - *StackTop() = *StackSecond();
|
| - *StackSecond() = tmp;
|
| - break;
|
| - }
|
| -
|
| - case DW_OP_rot: {
|
| - NEEDS(3)
|
| - address_t tmp = *StackTop();
|
| - *StackTop() = *StackThird();
|
| - *StackThird() = *StackSecond();
|
| - *StackSecond() = tmp;
|
| - break;
|
| - }
|
| -
|
| - case DW_OP_deref:
|
| - NEEDS(1)
|
| - *StackTop() = vm->ReadMemory(*StackTop(), reader->AddressSize());
|
| - break;
|
| -
|
| - case DW_OP_deref_size:
|
| - NEEDS(1)
|
| - *StackTop() = vm->ReadMemory(*StackTop(), *program++);
|
| - break;
|
| -
|
| - // DW_OP_xderef and DW_OP_xderef_size not supported.
|
| -
|
| - // Arithmetic and logical operations
|
| -
|
| - case DW_OP_abs:
|
| - NEEDS(1)
|
| - *StackTop() = abs(*SignedStackTop());
|
| - break;
|
| -
|
| - case DW_OP_and:
|
| - NEEDS(2)
|
| - *StackSecond() &= *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_div:
|
| - NEEDS(2)
|
| - *SignedStackSecond() /= *SignedStackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_minus:
|
| - NEEDS(2)
|
| - *StackSecond() -= *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_mod:
|
| - NEEDS(2)
|
| - *StackSecond() %= *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_mul:
|
| - NEEDS(2)
|
| - *StackSecond() *= *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_neg:
|
| - NEEDS(1)
|
| - *SignedStackTop() = -*SignedStackTop();
|
| - break;
|
| -
|
| - case DW_OP_not:
|
| - NEEDS(1)
|
| - *StackTop() = ~*StackTop();
|
| - break;
|
| -
|
| - case DW_OP_or:
|
| - NEEDS(2)
|
| - *StackSecond() |= *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_plus:
|
| - NEEDS(2)
|
| - *StackSecond() += *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_plus_uconst: {
|
| - NEEDS(1)
|
| - size_t len;
|
| - *StackTop() += reader->ReadUnsignedLEB128(program, &len);
|
| - program += len;
|
| - break;
|
| - }
|
| -
|
| - case DW_OP_shl:
|
| - NEEDS(2)
|
| - *StackSecond() <<= *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_shr:
|
| - NEEDS(2)
|
| - *StackSecond() >>= *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_shra:
|
| - NEEDS(2)
|
| - *SignedStackSecond() >>= *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_xor:
|
| - NEEDS(2)
|
| - *StackSecond() ^= *StackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - // Control flow operators
|
| -
|
| - case DW_OP_le:
|
| - NEEDS(2)
|
| - *StackSecond() = *SignedStackSecond() <= *SignedStackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_ge:
|
| - NEEDS(2)
|
| - *StackSecond() = *SignedStackSecond() >= *SignedStackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_eq:
|
| - NEEDS(2)
|
| - *StackSecond() = *SignedStackSecond() == *SignedStackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_lt:
|
| - NEEDS(2)
|
| - *StackSecond() = *SignedStackSecond() < *SignedStackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_gt:
|
| - NEEDS(2)
|
| - *StackSecond() = *SignedStackSecond() > *SignedStackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_ne:
|
| - NEEDS(2)
|
| - *StackSecond() = *SignedStackSecond() != *SignedStackTop();
|
| - stack_.pop_back();
|
| - break;
|
| -
|
| - case DW_OP_skip:
|
| - program += 2 + static_cast<int16>(reader->ReadTwoBytes(program));
|
| - break;
|
| -
|
| - case DW_OP_bra: {
|
| - NEEDS(1)
|
| - if (*StackTop()) {
|
| - program += static_cast<int16>(reader->ReadTwoBytes(program));
|
| - }
|
| - program += 2;
|
| - stack_.pop_back();
|
| - break;
|
| - }
|
| -
|
| - // Special operations
|
| -
|
| - case DW_OP_piece:
|
| - // The result at the top of the stack has a 'piece size' given
|
| - // by the argument. We do not currently do anything with this number.
|
| - size_t len;
|
| - reader->ReadUnsignedLEB128(program, &len);
|
| - program += len;
|
| - break;
|
| -
|
| - case DW_OP_nop:
|
| - break;
|
| -
|
| - default:
|
| - Error("Unknown opcode");
|
| - }
|
| - }
|
| -
|
| - if (program != program_end) Error("Invalid program length");
|
| - return *StackTop();
|
| -}
|
| -
|
| -
|
| -#undef NEEDS
|
| -
|
| -}
|
|
|