diff options
Diffstat (limited to 'source/Symbol/UnwindTable.cpp')
-rw-r--r-- | source/Symbol/UnwindTable.cpp | 110 |
1 files changed, 61 insertions, 49 deletions
diff --git a/source/Symbol/UnwindTable.cpp b/source/Symbol/UnwindTable.cpp index 336f0c3e04a7..405d57754ea5 100644 --- a/source/Symbol/UnwindTable.cpp +++ b/source/Symbol/UnwindTable.cpp @@ -44,38 +44,64 @@ void UnwindTable::Initialize() { if (m_initialized) // check again once we've acquired the lock return; + m_initialized = true; SectionList *sl = m_object_file.GetSectionList(); - if (sl) { - SectionSP sect = sl->FindSectionByType(eSectionTypeEHFrame, true); - if (sect.get()) { - m_eh_frame_up.reset(new DWARFCallFrameInfo(m_object_file, sect, - eRegisterKindEHFrame, true)); - } - sect = sl->FindSectionByType(eSectionTypeCompactUnwind, true); - if (sect.get()) { - m_compact_unwind_up.reset(new CompactUnwindInfo(m_object_file, sect)); - } - sect = sl->FindSectionByType(eSectionTypeARMexidx, true); - if (sect.get()) { - SectionSP sect_extab = sl->FindSectionByType(eSectionTypeARMextab, true); - if (sect_extab.get()) { - m_arm_unwind_up.reset( - new ArmUnwindInfo(m_object_file, sect, sect_extab)); - } - } + if (!sl) + return; + + SectionSP sect = sl->FindSectionByType(eSectionTypeEHFrame, true); + if (sect.get()) { + m_eh_frame_up.reset( + new DWARFCallFrameInfo(m_object_file, sect, DWARFCallFrameInfo::EH)); } - m_initialized = true; + sect = sl->FindSectionByType(eSectionTypeDWARFDebugFrame, true); + if (sect) { + m_debug_frame_up.reset( + new DWARFCallFrameInfo(m_object_file, sect, DWARFCallFrameInfo::DWARF)); + } + + sect = sl->FindSectionByType(eSectionTypeCompactUnwind, true); + if (sect) { + m_compact_unwind_up.reset(new CompactUnwindInfo(m_object_file, sect)); + } + + sect = sl->FindSectionByType(eSectionTypeARMexidx, true); + if (sect) { + SectionSP sect_extab = sl->FindSectionByType(eSectionTypeARMextab, true); + if (sect_extab.get()) { + m_arm_unwind_up.reset(new ArmUnwindInfo(m_object_file, sect, sect_extab)); + } + } } UnwindTable::~UnwindTable() {} +llvm::Optional<AddressRange> UnwindTable::GetAddressRange(const Address &addr, + SymbolContext &sc) { + AddressRange range; + + // First check the symbol context + if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0, + false, range) && + range.GetBaseAddress().IsValid()) + return range; + + // Does the eh_frame unwind info has a function bounds for this addr? + if (m_eh_frame_up && m_eh_frame_up->GetAddressRange(addr, range)) + return range; + + // Try debug_frame as well + if (m_debug_frame_up && m_debug_frame_up->GetAddressRange(addr, range)) + return range; + + return llvm::None; +} + FuncUnwindersSP UnwindTable::GetFuncUnwindersContainingAddress(const Address &addr, SymbolContext &sc) { - FuncUnwindersSP no_unwind_found; - Initialize(); std::lock_guard<std::mutex> guard(m_mutex); @@ -96,23 +122,14 @@ UnwindTable::GetFuncUnwindersContainingAddress(const Address &addr, return pos->second; } - AddressRange range; - if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0, - false, range) || - !range.GetBaseAddress().IsValid()) { - // Does the eh_frame unwind info has a function bounds for this addr? - if (m_eh_frame_up == nullptr || - !m_eh_frame_up->GetAddressRange(addr, range)) { - return no_unwind_found; - } - } + auto range_or = GetAddressRange(addr, sc); + if (!range_or) + return nullptr; - FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, range)); + FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, *range_or)); m_unwinds.insert(insert_pos, - std::make_pair(range.GetBaseAddress().GetFileAddress(), + std::make_pair(range_or->GetBaseAddress().GetFileAddress(), func_unwinder_sp)); - // StreamFile s(stdout, false); - // Dump (s); return func_unwinder_sp; } @@ -121,26 +138,16 @@ UnwindTable::GetFuncUnwindersContainingAddress(const Address &addr, // UnwindTable. This is intended for use by target modules show-unwind where we // want to create // new UnwindPlans, not re-use existing ones. - FuncUnwindersSP UnwindTable::GetUncachedFuncUnwindersContainingAddress(const Address &addr, SymbolContext &sc) { - FuncUnwindersSP no_unwind_found; Initialize(); - AddressRange range; - if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0, - false, range) || - !range.GetBaseAddress().IsValid()) { - // Does the eh_frame unwind info has a function bounds for this addr? - if (m_eh_frame_up == nullptr || - !m_eh_frame_up->GetAddressRange(addr, range)) { - return no_unwind_found; - } - } + auto range_or = GetAddressRange(addr, sc); + if (!range_or) + return nullptr; - FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, range)); - return func_unwinder_sp; + return std::make_shared<FuncUnwinders>(*this, *range_or); } void UnwindTable::Dump(Stream &s) { @@ -161,6 +168,11 @@ DWARFCallFrameInfo *UnwindTable::GetEHFrameInfo() { return m_eh_frame_up.get(); } +DWARFCallFrameInfo *UnwindTable::GetDebugFrameInfo() { + Initialize(); + return m_debug_frame_up.get(); +} + CompactUnwindInfo *UnwindTable::GetCompactUnwindInfo() { Initialize(); return m_compact_unwind_up.get(); |