aboutsummaryrefslogtreecommitdiffstats
path: root/source/Symbol/UnwindTable.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-07-01 13:24:58 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-07-01 13:24:58 +0000
commit1b306c26ade71504511d2fa75b03dfaee77f9620 (patch)
tree2c4c77af2ba9632c24ebf216b9a39989d74f5725 /source/Symbol/UnwindTable.cpp
parentfdea456ad833fbab0d3a296a58250950f11a498c (diff)
downloadsrc-1b306c26ade71504511d2fa75b03dfaee77f9620.tar.gz
src-1b306c26ade71504511d2fa75b03dfaee77f9620.zip
Vendor import of lldb trunk r306956:vendor/lldb/lldb-trunk-r306956
Notes
Notes: svn path=/vendor/lldb/dist/; revision=320543 svn path=/vendor/lldb/lldb-trunk-r306956/; revision=320544; tag=vendor/lldb/lldb-trunk-r306956
Diffstat (limited to 'source/Symbol/UnwindTable.cpp')
-rw-r--r--source/Symbol/UnwindTable.cpp110
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();