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

Commit 19ab4580 authored by Christopher Ferris's avatar Christopher Ferris Committed by Gerrit Code Review
Browse files

Merge "Add error propagation into Unwinder/Elf objects."

parents 4d182ff2 2fcf4cf1
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ bool ArmExidx::ExtractEntryData(uint32_t entry_offset) {
  uint32_t data;
  if (!elf_memory_->Read32(entry_offset + 4, &data)) {
    status_ = ARM_STATUS_READ_FAILED;
    status_address_ = entry_offset + 4;
    return false;
  }
  if (data == 1) {
@@ -97,6 +98,7 @@ bool ArmExidx::ExtractEntryData(uint32_t entry_offset) {
  uint32_t addr = (entry_offset + 4) + signed_data;
  if (!elf_memory_->Read32(addr, &data)) {
    status_ = ARM_STATUS_READ_FAILED;
    status_address_ = addr;
    return false;
  }

@@ -128,6 +130,7 @@ bool ArmExidx::ExtractEntryData(uint32_t entry_offset) {
    addr += 4;
    if (!elf_memory_->Read32(addr, &data)) {
      status_ = ARM_STATUS_READ_FAILED;
      status_address_ = addr;
      return false;
    }
    num_table_words = (data >> 24) & 0xff;
@@ -145,6 +148,7 @@ bool ArmExidx::ExtractEntryData(uint32_t entry_offset) {
  for (size_t i = 0; i < num_table_words; i++) {
    if (!elf_memory_->Read32(addr, &data)) {
      status_ = ARM_STATUS_READ_FAILED;
      status_address_ = addr;
      return false;
    }
    data_.push_back((data >> 24) & 0xff);
@@ -216,6 +220,7 @@ inline bool ArmExidx::DecodePrefix_10_00(uint8_t byte) {
    if (registers & (1 << reg)) {
      if (!process_memory_->Read32(cfa_, &(*regs_)[reg])) {
        status_ = ARM_STATUS_READ_FAILED;
        status_address_ = cfa_;
        return false;
      }
      cfa_ += 4;
@@ -284,6 +289,7 @@ inline bool ArmExidx::DecodePrefix_10_10(uint8_t byte) {
  for (size_t i = 4; i <= 4 + (byte & 0x7); i++) {
    if (!process_memory_->Read32(cfa_, &(*regs_)[i])) {
      status_ = ARM_STATUS_READ_FAILED;
      status_address_ = cfa_;
      return false;
    }
    cfa_ += 4;
@@ -291,6 +297,7 @@ inline bool ArmExidx::DecodePrefix_10_10(uint8_t byte) {
  if (byte & 0x8) {
    if (!process_memory_->Read32(cfa_, &(*regs_)[ARM_REG_R14])) {
      status_ = ARM_STATUS_READ_FAILED;
      status_address_ = cfa_;
      return false;
    }
    cfa_ += 4;
@@ -357,6 +364,7 @@ inline bool ArmExidx::DecodePrefix_10_11_0001() {
    if (byte & (1 << reg)) {
      if (!process_memory_->Read32(cfa_, &(*regs_)[reg])) {
        status_ = ARM_STATUS_READ_FAILED;
        status_address_ = cfa_;
        return false;
      }
      cfa_ += 4;
+2 −0
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ class ArmExidx {
  std::deque<uint8_t>* data() { return &data_; }

  ArmStatus status() { return status_; }
  uint64_t status_address() { return status_address_; }

  RegsArm* regs() { return regs_; }

@@ -97,6 +98,7 @@ class ArmExidx {
  uint32_t cfa_ = 0;
  std::deque<uint8_t> data_;
  ArmStatus status_ = ARM_STATUS_NONE;
  uint64_t status_address_ = 0;

  Memory* elf_memory_;
  Memory* process_memory_;
+3 −3
Original line number Diff line number Diff line
@@ -14,8 +14,8 @@
 * limitations under the License.
 */

#ifndef _LIBUNWINDSTACK_ERROR_H
#define _LIBUNWINDSTACK_ERROR_H
#ifndef _LIBUNWINDSTACK_CHECK_H
#define _LIBUNWINDSTACK_CHECK_H

#include <stdlib.h>

@@ -31,4 +31,4 @@ namespace unwindstack {

}  // namespace unwindstack

#endif  // _LIBUNWINDSTACK_ERROR_H
#endif  // _LIBUNWINDSTACK_CHECK_H
+17 −12
Original line number Diff line number Diff line
@@ -23,12 +23,12 @@

#include <android-base/stringprintf.h>

#include <unwindstack/DwarfError.h>
#include <unwindstack/DwarfLocation.h>
#include <unwindstack/Log.h>

#include "DwarfCfa.h"
#include "DwarfEncoding.h"
#include "DwarfError.h"
#include "DwarfOp.h"

namespace unwindstack {
@@ -44,7 +44,8 @@ bool DwarfCfa<AddressType>::GetLocationInfo(uint64_t pc, uint64_t start_offset,
      (*loc_regs)[entry.first] = entry.second;
    }
  }
  last_error_ = DWARF_ERROR_NONE;
  last_error_.code = DWARF_ERROR_NONE;
  last_error_.address = 0;

  memory_->set_cur_offset(start_offset);
  uint64_t cfa_offset;
@@ -54,7 +55,8 @@ bool DwarfCfa<AddressType>::GetLocationInfo(uint64_t pc, uint64_t start_offset,
    // Read the cfa information.
    uint8_t cfa_value;
    if (!memory_->ReadBytes(&cfa_value, 1)) {
      last_error_ = DWARF_ERROR_MEMORY_INVALID;
      last_error_.code = DWARF_ERROR_MEMORY_INVALID;
      last_error_.address = memory_->cur_offset();
      return false;
    }
    uint8_t cfa_low = cfa_value & 0x3f;
@@ -66,7 +68,8 @@ bool DwarfCfa<AddressType>::GetLocationInfo(uint64_t pc, uint64_t start_offset,
      case 2: {
        uint64_t offset;
        if (!memory_->ReadULEB128(&offset)) {
          last_error_ = DWARF_ERROR_MEMORY_INVALID;
          last_error_.code = DWARF_ERROR_MEMORY_INVALID;
          last_error_.address = memory_->cur_offset();
          return false;
        }
        SignedType signed_offset =
@@ -78,7 +81,7 @@ bool DwarfCfa<AddressType>::GetLocationInfo(uint64_t pc, uint64_t start_offset,
      case 3: {
        if (cie_loc_regs_ == nullptr) {
          log(0, "restore while processing cie");
          last_error_ = DWARF_ERROR_ILLEGAL_STATE;
          last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
          return false;
        }

@@ -93,7 +96,7 @@ bool DwarfCfa<AddressType>::GetLocationInfo(uint64_t pc, uint64_t start_offset,
      case 0: {
        const auto handle_func = DwarfCfa<AddressType>::kCallbackTable[cfa_low];
        if (handle_func == nullptr) {
          last_error_ = DWARF_ERROR_ILLEGAL_VALUE;
          last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
          return false;
        }

@@ -102,7 +105,8 @@ bool DwarfCfa<AddressType>::GetLocationInfo(uint64_t pc, uint64_t start_offset,
          if (cfa->operands[i] == DW_EH_PE_block) {
            uint64_t block_length;
            if (!memory_->ReadULEB128(&block_length)) {
              last_error_ = DWARF_ERROR_MEMORY_INVALID;
              last_error_.code = DWARF_ERROR_MEMORY_INVALID;
              last_error_.address = memory_->cur_offset();
              return false;
            }
            operands_.push_back(block_length);
@@ -111,7 +115,8 @@ bool DwarfCfa<AddressType>::GetLocationInfo(uint64_t pc, uint64_t start_offset,
          }
          uint64_t value;
          if (!memory_->ReadEncodedValue<AddressType>(cfa->operands[i], &value)) {
            last_error_ = DWARF_ERROR_MEMORY_INVALID;
            last_error_.code = DWARF_ERROR_MEMORY_INVALID;
            last_error_.address = memory_->cur_offset();
            return false;
          }
          operands_.push_back(value);
@@ -334,7 +339,7 @@ bool DwarfCfa<AddressType>::cfa_restore(dwarf_loc_regs_t* loc_regs) {
  AddressType reg = operands_[0];
  if (cie_loc_regs_ == nullptr) {
    log(0, "restore while processing cie");
    last_error_ = DWARF_ERROR_ILLEGAL_STATE;
    last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
    return false;
  }
  auto reg_entry = cie_loc_regs_->find(reg);
@@ -396,7 +401,7 @@ bool DwarfCfa<AddressType>::cfa_def_cfa_register(dwarf_loc_regs_t* loc_regs) {
  auto cfa_location = loc_regs->find(CFA_REG);
  if (cfa_location == loc_regs->end() || cfa_location->second.type != DWARF_LOCATION_REGISTER) {
    log(0, "Attempt to set new register, but cfa is not already set to a register.");
    last_error_ = DWARF_ERROR_ILLEGAL_STATE;
    last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
    return false;
  }

@@ -410,7 +415,7 @@ bool DwarfCfa<AddressType>::cfa_def_cfa_offset(dwarf_loc_regs_t* loc_regs) {
  auto cfa_location = loc_regs->find(CFA_REG);
  if (cfa_location == loc_regs->end() || cfa_location->second.type != DWARF_LOCATION_REGISTER) {
    log(0, "Attempt to set offset, but cfa is not set to a register.");
    last_error_ = DWARF_ERROR_ILLEGAL_STATE;
    last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
    return false;
  }
  cfa_location->second.values[1] = operands_[0];
@@ -454,7 +459,7 @@ bool DwarfCfa<AddressType>::cfa_def_cfa_offset_sf(dwarf_loc_regs_t* loc_regs) {
  auto cfa_location = loc_regs->find(CFA_REG);
  if (cfa_location == loc_regs->end() || cfa_location->second.type != DWARF_LOCATION_REGISTER) {
    log(0, "Attempt to set offset, but cfa is not set to a register.");
    last_error_ = DWARF_ERROR_ILLEGAL_STATE;
    last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
    return false;
  }
  SignedType offset = static_cast<SignedType>(operands_[0]) * fde_->cie->data_alignment_factor;
+5 −4
Original line number Diff line number Diff line
@@ -24,12 +24,11 @@
#include <type_traits>
#include <vector>

#include <unwindstack/DwarfError.h>
#include <unwindstack/DwarfLocation.h>
#include <unwindstack/DwarfMemory.h>
#include <unwindstack/DwarfStructs.h>

#include "DwarfError.h"

namespace unwindstack {

// DWARF Standard home: http://dwarfstd.org/
@@ -75,7 +74,9 @@ class DwarfCfa {
  bool Log(uint32_t indent, uint64_t pc, uint64_t load_bias, uint64_t start_offset,
           uint64_t end_offset);

  DwarfError last_error() { return last_error_; }
  const DwarfErrorData& last_error() { return last_error_; }
  DwarfErrorCode LastErrorCode() { return last_error_.code; }
  uint64_t LastErrorAddress() { return last_error_.address; }

  AddressType cur_pc() { return cur_pc_; }

@@ -89,7 +90,7 @@ class DwarfCfa {
  bool LogInstruction(uint32_t indent, uint64_t cfa_offset, uint8_t op, uint64_t* cur_pc);

 private:
  DwarfError last_error_;
  DwarfErrorData last_error_;
  DwarfMemory* memory_;
  const DwarfFde* fde_;

Loading