diff options
Diffstat (limited to 'lldb/source/Symbol/ArmUnwindInfo.cpp')
-rw-r--r-- | lldb/source/Symbol/ArmUnwindInfo.cpp | 696 |
1 files changed, 311 insertions, 385 deletions
diff --git a/lldb/source/Symbol/ArmUnwindInfo.cpp b/lldb/source/Symbol/ArmUnwindInfo.cpp index 95207cbe320..19951498c1d 100644 --- a/lldb/source/Symbol/ArmUnwindInfo.cpp +++ b/lldb/source/Symbol/ArmUnwindInfo.cpp @@ -9,13 +9,13 @@ #include <vector> +#include "Utility/ARM_DWARF_Registers.h" #include "lldb/Core/Module.h" #include "lldb/Core/Section.h" #include "lldb/Host/Endian.h" #include "lldb/Symbol/ArmUnwindInfo.h" #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/UnwindPlan.h" -#include "Utility/ARM_DWARF_Registers.h" /* * Unwind information reader and parser for the ARM exception handling ABI @@ -31,415 +31,341 @@ using namespace lldb; using namespace lldb_private; // Converts a prel31 avlue to lldb::addr_t with sign extension -static addr_t -Prel31ToAddr(uint32_t prel31) -{ - addr_t res = prel31; - if (prel31 & (1<<30)) - res |= 0xffffffff80000000ULL; - return res; +static addr_t Prel31ToAddr(uint32_t prel31) { + addr_t res = prel31; + if (prel31 & (1 << 30)) + res |= 0xffffffff80000000ULL; + return res; } -ArmUnwindInfo::ArmExidxEntry::ArmExidxEntry(uint32_t f, lldb::addr_t a, uint32_t d) : - file_address(f), address(a), data(d) -{ -} +ArmUnwindInfo::ArmExidxEntry::ArmExidxEntry(uint32_t f, lldb::addr_t a, + uint32_t d) + : file_address(f), address(a), data(d) {} -bool -ArmUnwindInfo::ArmExidxEntry::operator<(const ArmExidxEntry& other) const -{ - return address < other.address; +bool ArmUnwindInfo::ArmExidxEntry::operator<(const ArmExidxEntry &other) const { + return address < other.address; } -ArmUnwindInfo::ArmUnwindInfo(const ObjectFile& objfile, - SectionSP& arm_exidx, - SectionSP& arm_extab) : - m_byte_order(objfile.GetByteOrder()), - m_arm_exidx_sp(arm_exidx), - m_arm_extab_sp(arm_extab) -{ - objfile.ReadSectionData(arm_exidx.get(), m_arm_exidx_data); - objfile.ReadSectionData(arm_extab.get(), m_arm_extab_data); - - addr_t exidx_base_addr = m_arm_exidx_sp->GetFileAddress(); - - offset_t offset = 0; - while (m_arm_exidx_data.ValidOffset(offset)) - { - lldb::addr_t file_addr = exidx_base_addr + offset; - lldb::addr_t addr = exidx_base_addr + - (addr_t)offset + - Prel31ToAddr(m_arm_exidx_data.GetU32(&offset)); - uint32_t data = m_arm_exidx_data.GetU32(&offset); - m_exidx_entries.emplace_back(file_addr, addr, data); - } - - // Sort the entries in the exidx section. The entries should be sorted inside the section but - // some old compiler isn't sorted them. - std::sort(m_exidx_entries.begin(), m_exidx_entries.end()); +ArmUnwindInfo::ArmUnwindInfo(const ObjectFile &objfile, SectionSP &arm_exidx, + SectionSP &arm_extab) + : m_byte_order(objfile.GetByteOrder()), m_arm_exidx_sp(arm_exidx), + m_arm_extab_sp(arm_extab) { + objfile.ReadSectionData(arm_exidx.get(), m_arm_exidx_data); + objfile.ReadSectionData(arm_extab.get(), m_arm_extab_data); + + addr_t exidx_base_addr = m_arm_exidx_sp->GetFileAddress(); + + offset_t offset = 0; + while (m_arm_exidx_data.ValidOffset(offset)) { + lldb::addr_t file_addr = exidx_base_addr + offset; + lldb::addr_t addr = exidx_base_addr + (addr_t)offset + + Prel31ToAddr(m_arm_exidx_data.GetU32(&offset)); + uint32_t data = m_arm_exidx_data.GetU32(&offset); + m_exidx_entries.emplace_back(file_addr, addr, data); + } + + // Sort the entries in the exidx section. The entries should be sorted inside + // the section but + // some old compiler isn't sorted them. + std::sort(m_exidx_entries.begin(), m_exidx_entries.end()); } -ArmUnwindInfo::~ArmUnwindInfo() -{ -} +ArmUnwindInfo::~ArmUnwindInfo() {} // Read a byte from the unwind instruction stream with the given offset. -// Custom function is required because have to red in order of significance within their containing +// Custom function is required because have to red in order of significance +// within their containing // word (most significant byte first) and in increasing word address order. -uint8_t -ArmUnwindInfo::GetByteAtOffset(const uint32_t* data, uint16_t offset) const -{ - uint32_t value = data[offset / 4]; - if (m_byte_order != endian::InlHostByteOrder()) - value = llvm::ByteSwap_32(value); - return (value >> ((3 - (offset % 4)) * 8)) & 0xff; +uint8_t ArmUnwindInfo::GetByteAtOffset(const uint32_t *data, + uint16_t offset) const { + uint32_t value = data[offset / 4]; + if (m_byte_order != endian::InlHostByteOrder()) + value = llvm::ByteSwap_32(value); + return (value >> ((3 - (offset % 4)) * 8)) & 0xff; } -uint64_t -ArmUnwindInfo::GetULEB128(const uint32_t* data, uint16_t& offset, uint16_t max_offset) const -{ - uint64_t result = 0; - uint8_t shift = 0; - while (offset < max_offset) - { - uint8_t byte = GetByteAtOffset(data, offset++); - result |= (uint64_t)(byte & 0x7f) << shift; - if ((byte & 0x80) == 0) - break; - shift += 7; - } - return result; +uint64_t ArmUnwindInfo::GetULEB128(const uint32_t *data, uint16_t &offset, + uint16_t max_offset) const { + uint64_t result = 0; + uint8_t shift = 0; + while (offset < max_offset) { + uint8_t byte = GetByteAtOffset(data, offset++); + result |= (uint64_t)(byte & 0x7f) << shift; + if ((byte & 0x80) == 0) + break; + shift += 7; + } + return result; } -bool -ArmUnwindInfo::GetUnwindPlan(Target &target, const Address& addr, UnwindPlan& unwind_plan) -{ - const uint32_t* data = (const uint32_t*)GetExceptionHandlingTableEntry(addr); - if (data == nullptr) - return false; // No unwind information for the function - - if (data[0] == 0x1) - return false; // EXIDX_CANTUNWIND - - uint16_t byte_count = 0; - uint16_t byte_offset = 0; - if (data[0] & 0x80000000) - { - switch ((data[0] >> 24) & 0x0f) - { - case 0: - byte_count = 4; - byte_offset = 1; - break; - case 1: - case 2: - byte_count = 4 * ((data[0] >> 16) & 0xff) + 4; - byte_offset = 2; - break; - default: - // Unhandled personality routine index - return false; - } - } - else - { - byte_count = 4 * ((data[1] >> 24) & 0xff) + 8; - byte_offset = 5; +bool ArmUnwindInfo::GetUnwindPlan(Target &target, const Address &addr, + UnwindPlan &unwind_plan) { + const uint32_t *data = (const uint32_t *)GetExceptionHandlingTableEntry(addr); + if (data == nullptr) + return false; // No unwind information for the function + + if (data[0] == 0x1) + return false; // EXIDX_CANTUNWIND + + uint16_t byte_count = 0; + uint16_t byte_offset = 0; + if (data[0] & 0x80000000) { + switch ((data[0] >> 24) & 0x0f) { + case 0: + byte_count = 4; + byte_offset = 1; + break; + case 1: + case 2: + byte_count = 4 * ((data[0] >> 16) & 0xff) + 4; + byte_offset = 2; + break; + default: + // Unhandled personality routine index + return false; } - - uint8_t vsp_reg = dwarf_sp; - int32_t vsp = 0; - std::vector<std::pair<uint32_t, int32_t>> register_offsets; // register -> (offset from vsp_reg) - - while (byte_offset < byte_count) - { - uint8_t byte1 = GetByteAtOffset(data, byte_offset++); - if ((byte1&0xc0) == 0x00) - { - // 00xxxxxx - // vsp = vsp + (xxxxxx << 2) + 4. Covers range 0x04-0x100 inclusive - vsp += ((byte1 & 0x3f) << 2) + 4; - } - else if ((byte1&0xc0) == 0x40) - { - // 01xxxxxx - // vsp = vsp – (xxxxxx << 2) - 4. Covers range 0x04-0x100 inclusive - vsp -= ((byte1 & 0x3f) << 2) + 4; - } - else if ((byte1&0xf0) == 0x80) - { - if (byte_offset >= byte_count) - return false; - - uint8_t byte2 = GetByteAtOffset(data, byte_offset++); - if (byte1 == 0x80 && byte2 == 0) - { - // 10000000 00000000 - // Refuse to unwind (for example, out of a cleanup) (see remark a) - return false; - } - else - { - // 1000iiii iiiiiiii (i not all 0) - // Pop up to 12 integer registers under masks {r15-r12}, {r11-r4} (see remark b) - uint16_t regs = ((byte1&0x0f) << 8) | byte2; - for (uint8_t i = 0; i < 12; ++i) - { - if (regs & (1<<i)) - { - register_offsets.emplace_back(dwarf_r4 + i, vsp); - vsp += 4; - } - } - } - } - else if ((byte1&0xff) == 0x9d) - { - // 10011101 - // Reserved as prefix for ARM register to register moves - return false; - } - else if ((byte1&0xff) == 0x9f) - { - // 10011111 - // Reserved as prefix for Intel Wireless MMX register to register moves - return false; - } - else if ((byte1&0xf0) == 0x90) - { - // 1001nnnn (nnnn != 13,15) - // Set vsp = r[nnnn] - vsp_reg = dwarf_r0 + (byte1&0x0f); - } - else if ((byte1&0xf8) == 0xa0) - { - // 10100nnn - // Pop r4-r[4+nnn] - uint8_t n = byte1&0x7; - for (uint8_t i = 0; i <= n; ++i) - { - register_offsets.emplace_back(dwarf_r4 + i, vsp); - vsp += 4; - } - } - else if ((byte1&0xf8) == 0xa8) - { - // 10101nnn - // Pop r4-r[4+nnn], r14 - uint8_t n = byte1&0x7; - for (uint8_t i = 0; i <= n; ++i) - { - register_offsets.emplace_back(dwarf_r4 + i, vsp); - vsp += 4; - } - - register_offsets.emplace_back(dwarf_lr, vsp); - vsp += 4; - } - else if ((byte1&0xff) == 0xb0) - { - // 10110000 - // Finish (see remark c) - break; - } - else if ((byte1&0xff) == 0xb1) - { - if (byte_offset >= byte_count) - return false; - - uint8_t byte2 = GetByteAtOffset(data, byte_offset++); - if ((byte2&0xff) == 0x00) - { - // 10110001 00000000 - // Spare (see remark f) - return false; - } - else if ((byte2&0xf0) == 0x00) - { - // 10110001 0000iiii (i not all 0) - // Pop integer registers under mask {r3, r2, r1, r0} - for (uint8_t i = 0; i < 4; ++i) - { - if (byte2 & (1<<i)) - { - register_offsets.emplace_back(dwarf_r0 + i, vsp); - vsp += 4; - } - } - } - else - { - // 10110001 xxxxyyyy - // Spare (xxxx != 0000) - return false; - } - } - else if ((byte1&0xff) == 0xb2) - { - // 10110010 uleb128 - // vsp = vsp + 0x204+ (uleb128 << 2) - uint64_t uleb128 = GetULEB128(data, byte_offset, byte_count); - vsp += 0x204 + (uleb128 << 2); - } - else if ((byte1&0xff) == 0xb3) - { - // 10110011 sssscccc - // Pop VFP double-precision registers D[ssss]-D[ssss+cccc] saved (as if) by FSTMFDX (see remark d) - if (byte_offset >= byte_count) - return false; - - uint8_t byte2 = GetByteAtOffset(data, byte_offset++); - uint8_t s = (byte2&0xf0) >> 4; - uint8_t c = (byte2&0x0f) >> 0; - for (uint8_t i = 0; i <= c; ++i) - { - register_offsets.emplace_back(dwarf_d0 + s + i, vsp); - vsp += 8; - } + } else { + byte_count = 4 * ((data[1] >> 24) & 0xff) + 8; + byte_offset = 5; + } + + uint8_t vsp_reg = dwarf_sp; + int32_t vsp = 0; + std::vector<std::pair<uint32_t, int32_t>> + register_offsets; // register -> (offset from vsp_reg) + + while (byte_offset < byte_count) { + uint8_t byte1 = GetByteAtOffset(data, byte_offset++); + if ((byte1 & 0xc0) == 0x00) { + // 00xxxxxx + // vsp = vsp + (xxxxxx << 2) + 4. Covers range 0x04-0x100 inclusive + vsp += ((byte1 & 0x3f) << 2) + 4; + } else if ((byte1 & 0xc0) == 0x40) { + // 01xxxxxx + // vsp = vsp – (xxxxxx << 2) - 4. Covers range 0x04-0x100 inclusive + vsp -= ((byte1 & 0x3f) << 2) + 4; + } else if ((byte1 & 0xf0) == 0x80) { + if (byte_offset >= byte_count) + return false; + + uint8_t byte2 = GetByteAtOffset(data, byte_offset++); + if (byte1 == 0x80 && byte2 == 0) { + // 10000000 00000000 + // Refuse to unwind (for example, out of a cleanup) (see remark a) + return false; + } else { + // 1000iiii iiiiiiii (i not all 0) + // Pop up to 12 integer registers under masks {r15-r12}, {r11-r4} (see + // remark b) + uint16_t regs = ((byte1 & 0x0f) << 8) | byte2; + for (uint8_t i = 0; i < 12; ++i) { + if (regs & (1 << i)) { + register_offsets.emplace_back(dwarf_r4 + i, vsp); vsp += 4; + } } - else if ((byte1&0xfc) == 0xb4) - { - // 101101nn - // Spare (was Pop FPA) - return false; - } - else if ((byte1&0xf8) == 0xb8) - { - // 10111nnn - // Pop VFP double-precision registers D[8]-D[8+nnn] saved (as if) by FSTMFDX (see remark d) - uint8_t n = byte1&0x07; - for (uint8_t i = 0; i <= n; ++i) - { - register_offsets.emplace_back(dwarf_d8 + i, vsp); - vsp += 8; - } + } + } else if ((byte1 & 0xff) == 0x9d) { + // 10011101 + // Reserved as prefix for ARM register to register moves + return false; + } else if ((byte1 & 0xff) == 0x9f) { + // 10011111 + // Reserved as prefix for Intel Wireless MMX register to register moves + return false; + } else if ((byte1 & 0xf0) == 0x90) { + // 1001nnnn (nnnn != 13,15) + // Set vsp = r[nnnn] + vsp_reg = dwarf_r0 + (byte1 & 0x0f); + } else if ((byte1 & 0xf8) == 0xa0) { + // 10100nnn + // Pop r4-r[4+nnn] + uint8_t n = byte1 & 0x7; + for (uint8_t i = 0; i <= n; ++i) { + register_offsets.emplace_back(dwarf_r4 + i, vsp); + vsp += 4; + } + } else if ((byte1 & 0xf8) == 0xa8) { + // 10101nnn + // Pop r4-r[4+nnn], r14 + uint8_t n = byte1 & 0x7; + for (uint8_t i = 0; i <= n; ++i) { + register_offsets.emplace_back(dwarf_r4 + i, vsp); + vsp += 4; + } + + register_offsets.emplace_back(dwarf_lr, vsp); + vsp += 4; + } else if ((byte1 & 0xff) == 0xb0) { + // 10110000 + // Finish (see remark c) + break; + } else if ((byte1 & 0xff) == 0xb1) { + if (byte_offset >= byte_count) + return false; + + uint8_t byte2 = GetByteAtOffset(data, byte_offset++); + if ((byte2 & 0xff) == 0x00) { + // 10110001 00000000 + // Spare (see remark f) + return false; + } else if ((byte2 & 0xf0) == 0x00) { + // 10110001 0000iiii (i not all 0) + // Pop integer registers under mask {r3, r2, r1, r0} + for (uint8_t i = 0; i < 4; ++i) { + if (byte2 & (1 << i)) { + register_offsets.emplace_back(dwarf_r0 + i, vsp); vsp += 4; + } } - else if ((byte1&0xf8) == 0xc0) - { - // 11000nnn (nnn != 6,7) - // Intel Wireless MMX pop wR[10]-wR[10+nnn] - - // 11000110 sssscccc - // Intel Wireless MMX pop wR[ssss]-wR[ssss+cccc] (see remark e) - - // 11000111 00000000 - // Spare - - // 11000111 0000iiii - // Intel Wireless MMX pop wCGR registers under mask {wCGR3,2,1,0} - - // 11000111 xxxxyyyy - // Spare (xxxx != 0000) - - return false; - } - else if ((byte1&0xff) == 0xc8) - { - // 11001000 sssscccc - // Pop VFP double precision registers D[16+ssss]-D[16+ssss+cccc] saved (as if) by FSTMFDD (see remarks d,e) - if (byte_offset >= byte_count) - return false; - - uint8_t byte2 = GetByteAtOffset(data, byte_offset++); - uint8_t s = (byte2&0xf0) >> 4; - uint8_t c = (byte2&0x0f) >> 0; - for (uint8_t i = 0; i <= c; ++i) - { - register_offsets.emplace_back(dwarf_d16 + s + i, vsp); - vsp += 8; - } - } - else if ((byte1&0xff) == 0xc9) - { - // 11001001 sssscccc - // Pop VFP double precision registers D[ssss]-D[ssss+cccc] saved (as if) by FSTMFDD (see remark d) - if (byte_offset >= byte_count) - return false; - - uint8_t byte2 = GetByteAtOffset(data, byte_offset++); - uint8_t s = (byte2&0xf0) >> 4; - uint8_t c = (byte2&0x0f) >> 0; - for (uint8_t i = 0; i <= c; ++i) - { - register_offsets.emplace_back(dwarf_d0 + s + i, vsp); - vsp += 8; - } - } - else if ((byte1&0xf8) == 0xc8) - { - // 11001yyy - // Spare (yyy != 000, 001) - return false; - } - else if ((byte1&0xf8) == 0xc0) - { - // 11010nnn - // Pop VFP double-precision registers D[8]-D[8+nnn] saved (as if) by FSTMFDD (see remark d) - uint8_t n = byte1&0x07; - for (uint8_t i = 0; i <= n; ++i) - { - register_offsets.emplace_back(dwarf_d8 + i, vsp); - vsp += 8; - } - } - else if ((byte1&0xc0) == 0xc0) - { - // 11xxxyyy Spare (xxx != 000, 001, 010) - return false; - } - else - { - return false; - } - } - - UnwindPlan::RowSP row = std::make_shared<UnwindPlan::Row>(); - row->SetOffset(0); - row->GetCFAValue().SetIsRegisterPlusOffset(vsp_reg, vsp); - - bool have_location_for_pc = false; - for (const auto& offset : register_offsets) - { - have_location_for_pc |= offset.first == dwarf_pc; - row->SetRegisterLocationToAtCFAPlusOffset(offset.first, offset.second - vsp, true); - } - - if (!have_location_for_pc) - { - UnwindPlan::Row::RegisterLocation lr_location; - if (row->GetRegisterInfo(dwarf_lr, lr_location)) - row->SetRegisterInfo(dwarf_pc, lr_location); - else - row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, false); + } else { + // 10110001 xxxxyyyy + // Spare (xxxx != 0000) + return false; + } + } else if ((byte1 & 0xff) == 0xb2) { + // 10110010 uleb128 + // vsp = vsp + 0x204+ (uleb128 << 2) + uint64_t uleb128 = GetULEB128(data, byte_offset, byte_count); + vsp += 0x204 + (uleb128 << 2); + } else if ((byte1 & 0xff) == 0xb3) { + // 10110011 sssscccc + // Pop VFP double-precision registers D[ssss]-D[ssss+cccc] saved (as if) + // by FSTMFDX (see remark d) + if (byte_offset >= byte_count) + return false; + + uint8_t byte2 = GetByteAtOffset(data, byte_offset++); + uint8_t s = (byte2 & 0xf0) >> 4; + uint8_t c = (byte2 & 0x0f) >> 0; + for (uint8_t i = 0; i <= c; ++i) { + register_offsets.emplace_back(dwarf_d0 + s + i, vsp); + vsp += 8; + } + vsp += 4; + } else if ((byte1 & 0xfc) == 0xb4) { + // 101101nn + // Spare (was Pop FPA) + return false; + } else if ((byte1 & 0xf8) == 0xb8) { + // 10111nnn + // Pop VFP double-precision registers D[8]-D[8+nnn] saved (as if) by + // FSTMFDX (see remark d) + uint8_t n = byte1 & 0x07; + for (uint8_t i = 0; i <= n; ++i) { + register_offsets.emplace_back(dwarf_d8 + i, vsp); + vsp += 8; + } + vsp += 4; + } else if ((byte1 & 0xf8) == 0xc0) { + // 11000nnn (nnn != 6,7) + // Intel Wireless MMX pop wR[10]-wR[10+nnn] + + // 11000110 sssscccc + // Intel Wireless MMX pop wR[ssss]-wR[ssss+cccc] (see remark e) + + // 11000111 00000000 + // Spare + + // 11000111 0000iiii + // Intel Wireless MMX pop wCGR registers under mask {wCGR3,2,1,0} + + // 11000111 xxxxyyyy + // Spare (xxxx != 0000) + + return false; + } else if ((byte1 & 0xff) == 0xc8) { + // 11001000 sssscccc + // Pop VFP double precision registers D[16+ssss]-D[16+ssss+cccc] saved (as + // if) by FSTMFDD (see remarks d,e) + if (byte_offset >= byte_count) + return false; + + uint8_t byte2 = GetByteAtOffset(data, byte_offset++); + uint8_t s = (byte2 & 0xf0) >> 4; + uint8_t c = (byte2 & 0x0f) >> 0; + for (uint8_t i = 0; i <= c; ++i) { + register_offsets.emplace_back(dwarf_d16 + s + i, vsp); + vsp += 8; + } + } else if ((byte1 & 0xff) == 0xc9) { + // 11001001 sssscccc + // Pop VFP double precision registers D[ssss]-D[ssss+cccc] saved (as if) + // by FSTMFDD (see remark d) + if (byte_offset >= byte_count) + return false; + + uint8_t byte2 = GetByteAtOffset(data, byte_offset++); + uint8_t s = (byte2 & 0xf0) >> 4; + uint8_t c = (byte2 & 0x0f) >> 0; + for (uint8_t i = 0; i <= c; ++i) { + register_offsets.emplace_back(dwarf_d0 + s + i, vsp); + vsp += 8; + } + } else if ((byte1 & 0xf8) == 0xc8) { + // 11001yyy + // Spare (yyy != 000, 001) + return false; + } else if ((byte1 & 0xf8) == 0xc0) { + // 11010nnn + // Pop VFP double-precision registers D[8]-D[8+nnn] saved (as if) by + // FSTMFDD (see remark d) + uint8_t n = byte1 & 0x07; + for (uint8_t i = 0; i <= n; ++i) { + register_offsets.emplace_back(dwarf_d8 + i, vsp); + vsp += 8; + } + } else if ((byte1 & 0xc0) == 0xc0) { + // 11xxxyyy Spare (xxx != 000, 001, 010) + return false; + } else { + return false; } + } + + UnwindPlan::RowSP row = std::make_shared<UnwindPlan::Row>(); + row->SetOffset(0); + row->GetCFAValue().SetIsRegisterPlusOffset(vsp_reg, vsp); + + bool have_location_for_pc = false; + for (const auto &offset : register_offsets) { + have_location_for_pc |= offset.first == dwarf_pc; + row->SetRegisterLocationToAtCFAPlusOffset(offset.first, offset.second - vsp, + true); + } + + if (!have_location_for_pc) { + UnwindPlan::Row::RegisterLocation lr_location; + if (row->GetRegisterInfo(dwarf_lr, lr_location)) + row->SetRegisterInfo(dwarf_pc, lr_location); + else + row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, false); + } - unwind_plan.AppendRow(row); - unwind_plan.SetSourceName ("ARM.exidx unwind info"); - unwind_plan.SetSourcedFromCompiler (eLazyBoolYes); - unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo); - unwind_plan.SetRegisterKind (eRegisterKindDWARF); + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("ARM.exidx unwind info"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolYes); + unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); - return true; + return true; } -const uint8_t* -ArmUnwindInfo::GetExceptionHandlingTableEntry(const Address& addr) -{ - auto it = std::upper_bound(m_exidx_entries.begin(), - m_exidx_entries.end(), - ArmExidxEntry{0, addr.GetFileAddress(), 0}); - if (it == m_exidx_entries.begin()) - return nullptr; - --it; +const uint8_t * +ArmUnwindInfo::GetExceptionHandlingTableEntry(const Address &addr) { + auto it = std::upper_bound(m_exidx_entries.begin(), m_exidx_entries.end(), + ArmExidxEntry{0, addr.GetFileAddress(), 0}); + if (it == m_exidx_entries.begin()) + return nullptr; + --it; - if (it->data == 0x1) - return nullptr; // EXIDX_CANTUNWIND + if (it->data == 0x1) + return nullptr; // EXIDX_CANTUNWIND - if (it->data & 0x80000000) - return (const uint8_t*)&it->data; + if (it->data & 0x80000000) + return (const uint8_t *)&it->data; - addr_t data_file_addr = it->file_address + 4 + Prel31ToAddr(it->data); - return m_arm_extab_data.GetDataStart() + (data_file_addr - m_arm_extab_sp->GetFileAddress()); + addr_t data_file_addr = it->file_address + 4 + Prel31ToAddr(it->data); + return m_arm_extab_data.GetDataStart() + + (data_file_addr - m_arm_extab_sp->GetFileAddress()); } |