Loading libunwindstack/DwarfOp.cpp +40 −14 Original line number Diff line number Diff line Loading @@ -36,13 +36,45 @@ template <typename AddressType> constexpr typename DwarfOp<AddressType>::OpCallback DwarfOp<AddressType>::kCallbackTable[256]; template <typename AddressType> bool DwarfOp<AddressType>::Eval(uint64_t start, uint64_t end, uint8_t dwarf_version) { uint32_t iterations = 0; bool DwarfOp<AddressType>::Eval(uint64_t start, uint64_t end) { is_register_ = false; stack_.clear(); memory_->set_cur_offset(start); dex_pc_set_ = false; // Unroll the first Decode calls to be able to check for a special // sequence of ops and values that indicate this is the dex pc. // The pattern is: // OP_const4u (0x0c) 'D' 'E' 'X' '1' // OP_drop (0x13) if (memory_->cur_offset() < end) { if (!Decode()) { return false; } } else { return true; } bool check_for_drop; if (cur_op_ == 0x0c && operands_.back() == 0x31584544) { check_for_drop = true; } else { check_for_drop = false; } if (memory_->cur_offset() < end) { if (!Decode()) { return false; } } else { return true; } if (check_for_drop && cur_op_ == 0x13) { dex_pc_set_ = true; } uint32_t iterations = 2; while (memory_->cur_offset() < end) { if (!Decode(dwarf_version)) { if (!Decode()) { return false; } // To protect against a branch that creates an infinite loop, Loading @@ -56,7 +88,7 @@ bool DwarfOp<AddressType>::Eval(uint64_t start, uint64_t end, uint8_t dwarf_vers } template <typename AddressType> bool DwarfOp<AddressType>::Decode(uint8_t dwarf_version) { bool DwarfOp<AddressType>::Decode() { last_error_.code = DWARF_ERROR_NONE; if (!memory_->ReadBytes(&cur_op_, 1)) { last_error_.code = DWARF_ERROR_MEMORY_INVALID; Loading @@ -71,12 +103,6 @@ bool DwarfOp<AddressType>::Decode(uint8_t dwarf_version) { return false; } // Check for an unsupported opcode. if (dwarf_version < op->supported_version) { last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; return false; } // Make sure that the required number of stack elements is available. if (stack_.size() < op->num_required_stack_values) { last_error_.code = DWARF_ERROR_STACK_INDEX_NOT_VALID; Loading Loading @@ -434,22 +460,22 @@ bool DwarfOp<AddressType>::op_regx() { template <typename AddressType> bool DwarfOp<AddressType>::op_breg() { uint16_t reg = cur_op() - 0x70; if (reg >= regs_->total_regs()) { if (reg >= regs_info_->Total()) { last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; return false; } stack_.push_front((*regs_)[reg] + OperandAt(0)); stack_.push_front(regs_info_->Get(reg) + OperandAt(0)); return true; } template <typename AddressType> bool DwarfOp<AddressType>::op_bregx() { AddressType reg = OperandAt(0); if (reg >= regs_->total_regs()) { if (reg >= regs_info_->Total()) { last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; return false; } stack_.push_front((*regs_)[reg] + OperandAt(1)); stack_.push_front(regs_info_->Get(reg) + OperandAt(1)); return true; } Loading Loading
libunwindstack/DwarfOp.cpp +40 −14 Original line number Diff line number Diff line Loading @@ -36,13 +36,45 @@ template <typename AddressType> constexpr typename DwarfOp<AddressType>::OpCallback DwarfOp<AddressType>::kCallbackTable[256]; template <typename AddressType> bool DwarfOp<AddressType>::Eval(uint64_t start, uint64_t end, uint8_t dwarf_version) { uint32_t iterations = 0; bool DwarfOp<AddressType>::Eval(uint64_t start, uint64_t end) { is_register_ = false; stack_.clear(); memory_->set_cur_offset(start); dex_pc_set_ = false; // Unroll the first Decode calls to be able to check for a special // sequence of ops and values that indicate this is the dex pc. // The pattern is: // OP_const4u (0x0c) 'D' 'E' 'X' '1' // OP_drop (0x13) if (memory_->cur_offset() < end) { if (!Decode()) { return false; } } else { return true; } bool check_for_drop; if (cur_op_ == 0x0c && operands_.back() == 0x31584544) { check_for_drop = true; } else { check_for_drop = false; } if (memory_->cur_offset() < end) { if (!Decode()) { return false; } } else { return true; } if (check_for_drop && cur_op_ == 0x13) { dex_pc_set_ = true; } uint32_t iterations = 2; while (memory_->cur_offset() < end) { if (!Decode(dwarf_version)) { if (!Decode()) { return false; } // To protect against a branch that creates an infinite loop, Loading @@ -56,7 +88,7 @@ bool DwarfOp<AddressType>::Eval(uint64_t start, uint64_t end, uint8_t dwarf_vers } template <typename AddressType> bool DwarfOp<AddressType>::Decode(uint8_t dwarf_version) { bool DwarfOp<AddressType>::Decode() { last_error_.code = DWARF_ERROR_NONE; if (!memory_->ReadBytes(&cur_op_, 1)) { last_error_.code = DWARF_ERROR_MEMORY_INVALID; Loading @@ -71,12 +103,6 @@ bool DwarfOp<AddressType>::Decode(uint8_t dwarf_version) { return false; } // Check for an unsupported opcode. if (dwarf_version < op->supported_version) { last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; return false; } // Make sure that the required number of stack elements is available. if (stack_.size() < op->num_required_stack_values) { last_error_.code = DWARF_ERROR_STACK_INDEX_NOT_VALID; Loading Loading @@ -434,22 +460,22 @@ bool DwarfOp<AddressType>::op_regx() { template <typename AddressType> bool DwarfOp<AddressType>::op_breg() { uint16_t reg = cur_op() - 0x70; if (reg >= regs_->total_regs()) { if (reg >= regs_info_->Total()) { last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; return false; } stack_.push_front((*regs_)[reg] + OperandAt(0)); stack_.push_front(regs_info_->Get(reg) + OperandAt(0)); return true; } template <typename AddressType> bool DwarfOp<AddressType>::op_bregx() { AddressType reg = OperandAt(0); if (reg >= regs_->total_regs()) { if (reg >= regs_info_->Total()) { last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; return false; } stack_.push_front((*regs_)[reg] + OperandAt(1)); stack_.push_front(regs_info_->Get(reg) + OperandAt(1)); return true; } Loading