Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c3aabea0 authored by David Srbecky's avatar David Srbecky Committed by android-build-merger
Browse files

Merge "Implement new DEX PC lookup scheme."

am: f1e55f7a

Change-Id: I9e7161dbef33febe2b8eb4398ceee163815b7a8f
parents 7987a191 f1e55f7a
Loading
Loading
Loading
Loading
+40 −14
Original line number Diff line number Diff line
@@ -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,
@@ -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;
@@ -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;
@@ -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