diff options
Diffstat (limited to 'source/Symbol/DWARFCallFrameInfo.cpp')
-rw-r--r-- | source/Symbol/DWARFCallFrameInfo.cpp | 107 |
1 files changed, 26 insertions, 81 deletions
diff --git a/source/Symbol/DWARFCallFrameInfo.cpp b/source/Symbol/DWARFCallFrameInfo.cpp index c8c3a10026a2..0ab9fa4b7bbd 100644 --- a/source/Symbol/DWARFCallFrameInfo.cpp +++ b/source/Symbol/DWARFCallFrameInfo.cpp @@ -1,9 +1,8 @@ //===-- DWARFCallFrameInfo.cpp ----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -24,12 +23,10 @@ using namespace lldb; using namespace lldb_private; -//---------------------------------------------------------------------- // GetDwarfEHPtr // // Used for calls when the value type is specified by a DWARF EH Frame pointer // encoding. -//---------------------------------------------------------------------- static uint64_t GetGNUEHPointer(const DataExtractor &DE, offset_t *offset_ptr, uint32_t eh_ptr_enc, addr_t pc_rel_addr, addr_t text_addr, @@ -41,9 +38,7 @@ GetGNUEHPointer(const DataExtractor &DE, offset_t *offset_ptr, uint64_t baseAddress = 0; uint64_t addressValue = 0; const uint32_t addr_size = DE.GetAddressByteSize(); -#ifdef LLDB_CONFIGURATION_DEBUG assert(addr_size == 4 || addr_size == 8); -#endif bool signExtendValue = false; // Decode the base part or adjust our offset @@ -151,8 +146,15 @@ DWARFCallFrameInfo::DWARFCallFrameInfo(ObjectFile &objfile, SectionSP §ion_sp, Type type) : m_objfile(objfile), m_section_sp(section_sp), m_type(type) {} -bool DWARFCallFrameInfo::GetUnwindPlan(Address addr, UnwindPlan &unwind_plan) { +bool DWARFCallFrameInfo::GetUnwindPlan(const Address &addr, + UnwindPlan &unwind_plan) { + return GetUnwindPlan(AddressRange(addr, 1), unwind_plan); +} + +bool DWARFCallFrameInfo::GetUnwindPlan(const AddressRange &range, + UnwindPlan &unwind_plan) { FDEEntryMap::Entry fde_entry; + Address addr = range.GetBaseAddress(); // Make sure that the Address we're searching for is the same object file as // this DWARFCallFrameInfo, we only store File offsets in m_fde_index. @@ -161,9 +163,9 @@ bool DWARFCallFrameInfo::GetUnwindPlan(Address addr, UnwindPlan &unwind_plan) { module_sp->GetObjectFile() != &m_objfile) return false; - if (!GetFDEEntryByFileAddress(addr.GetFileAddress(), fde_entry)) - return false; - return FDEToUnwindPlan(fde_entry.data, addr, unwind_plan); + if (llvm::Optional<FDEEntryMap::Entry> entry = GetFirstFDEEntryInRange(range)) + return FDEToUnwindPlan(entry->data, addr, unwind_plan); + return false; } bool DWARFCallFrameInfo::GetAddressRange(Address addr, AddressRange &range) { @@ -188,23 +190,21 @@ bool DWARFCallFrameInfo::GetAddressRange(Address addr, AddressRange &range) { return true; } -bool DWARFCallFrameInfo::GetFDEEntryByFileAddress( - addr_t file_addr, FDEEntryMap::Entry &fde_entry) { - if (m_section_sp.get() == nullptr || m_section_sp->IsEncrypted()) - return false; +llvm::Optional<DWARFCallFrameInfo::FDEEntryMap::Entry> +DWARFCallFrameInfo::GetFirstFDEEntryInRange(const AddressRange &range) { + if (!m_section_sp || m_section_sp->IsEncrypted()) + return llvm::None; GetFDEIndex(); - if (m_fde_index.IsEmpty()) - return false; - - FDEEntryMap::Entry *fde = m_fde_index.FindEntryThatContains(file_addr); + addr_t start_file_addr = range.GetBaseAddress().GetFileAddress(); + const FDEEntryMap::Entry *fde = + m_fde_index.FindEntryThatContainsOrFollows(start_file_addr); + if (fde && fde->DoesIntersect( + FDEEntryMap::Range(start_file_addr, range.GetByteSize()))) + return *fde; - if (fde == nullptr) - return false; - - fde_entry = *fde; - return true; + return llvm::None; } void DWARFCallFrameInfo::GetFunctionAddressAndSizeVector( @@ -231,7 +231,7 @@ DWARFCallFrameInfo::GetCIE(dw_offset_t cie_offset) { if (pos != m_cie_map.end()) { // Parse and cache the CIE - if (pos->second.get() == nullptr) + if (pos->second == nullptr) pos->second = ParseCIE(cie_offset); return pos->second.get(); @@ -999,61 +999,6 @@ bool DWARFCallFrameInfo::HandleCommonDwarfOpcode(uint8_t primary_opcode, uint32_t block_len = (uint32_t)m_cfi_data.GetULEB128(&offset); const uint8_t *block_data = (const uint8_t *)m_cfi_data.GetData(&offset, block_len); - //#if defined(__i386__) || defined(__x86_64__) - // // The EH frame info for EIP and RIP contains code that - // looks for traps to - // // be a specific type and increments the PC. - // // For i386: - // // DW_CFA_val_expression where: - // // eip = DW_OP_breg6(+28), DW_OP_deref, DW_OP_dup, - // DW_OP_plus_uconst(0x34), - // // DW_OP_deref, DW_OP_swap, DW_OP_plus_uconst(0), - // DW_OP_deref, - // // DW_OP_dup, DW_OP_lit3, DW_OP_ne, DW_OP_swap, - // DW_OP_lit4, DW_OP_ne, - // // DW_OP_and, DW_OP_plus - // // This basically does a: - // // eip = ucontenxt.mcontext32->gpr.eip; - // // if (ucontenxt.mcontext32->exc.trapno != 3 && - // ucontenxt.mcontext32->exc.trapno != 4) - // // eip++; - // // - // // For x86_64: - // // DW_CFA_val_expression where: - // // rip = DW_OP_breg3(+48), DW_OP_deref, DW_OP_dup, - // DW_OP_plus_uconst(0x90), DW_OP_deref, - // // DW_OP_swap, DW_OP_plus_uconst(0), - // DW_OP_deref_size(4), DW_OP_dup, DW_OP_lit3, - // // DW_OP_ne, DW_OP_swap, DW_OP_lit4, DW_OP_ne, - // DW_OP_and, DW_OP_plus - // // This basically does a: - // // rip = ucontenxt.mcontext64->gpr.rip; - // // if (ucontenxt.mcontext64->exc.trapno != 3 && - // ucontenxt.mcontext64->exc.trapno != 4) - // // rip++; - // // The trap comparisons and increments are not needed as - // it hoses up the unwound PC which - // // is expected to point at least past the instruction that - // causes the fault/trap. So we - // // take it out by trimming the expression right at the - // first "DW_OP_swap" opcodes - // if (block_data != NULL && thread->GetPCRegNum(Thread::GCC) - // == reg_num) - // { - // if (thread->Is64Bit()) - // { - // if (block_len > 9 && block_data[8] == DW_OP_swap - // && block_data[9] == DW_OP_plus_uconst) - // block_len = 8; - // } - // else - // { - // if (block_len > 8 && block_data[7] == DW_OP_swap - // && block_data[8] == DW_OP_plus_uconst) - // block_len = 7; - // } - // } - //#endif reg_location.SetIsDWARFExpression(block_data, block_len); row.SetRegisterInfo(reg_num, reg_location); return true; |