Loading libunwindstack/ArmExidx.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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; } Loading Loading @@ -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; Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading libunwindstack/ArmExidx.h +2 −0 Original line number Diff line number Diff line Loading @@ -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_; } Loading Loading @@ -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_; Loading libunwindstack/Check.h +3 −3 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -31,4 +31,4 @@ namespace unwindstack { } // namespace unwindstack #endif // _LIBUNWINDSTACK_ERROR_H #endif // _LIBUNWINDSTACK_CHECK_H libunwindstack/DwarfCfa.cpp +17 −12 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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; Loading @@ -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; Loading @@ -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 = Loading @@ -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; } Loading @@ -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; } Loading @@ -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); Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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; } Loading @@ -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]; Loading Loading @@ -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; Loading libunwindstack/DwarfCfa.h +5 −4 Original line number Diff line number Diff line Loading @@ -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/ Loading Loading @@ -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_; } Loading @@ -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 Loading
libunwindstack/ArmExidx.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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; } Loading Loading @@ -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; Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading
libunwindstack/ArmExidx.h +2 −0 Original line number Diff line number Diff line Loading @@ -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_; } Loading Loading @@ -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_; Loading
libunwindstack/Check.h +3 −3 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -31,4 +31,4 @@ namespace unwindstack { } // namespace unwindstack #endif // _LIBUNWINDSTACK_ERROR_H #endif // _LIBUNWINDSTACK_CHECK_H
libunwindstack/DwarfCfa.cpp +17 −12 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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; Loading @@ -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; Loading @@ -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 = Loading @@ -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; } Loading @@ -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; } Loading @@ -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); Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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; } Loading @@ -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]; Loading Loading @@ -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; Loading
libunwindstack/DwarfCfa.h +5 −4 Original line number Diff line number Diff line Loading @@ -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/ Loading Loading @@ -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_; } Loading @@ -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