summaryrefslogtreecommitdiff
path: root/source/Symbol/DWARFCallFrameInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Symbol/DWARFCallFrameInfo.cpp')
-rw-r--r--source/Symbol/DWARFCallFrameInfo.cpp107
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 &section_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;