aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Symbol/UnwindTable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/source/Symbol/UnwindTable.cpp')
-rw-r--r--contrib/llvm-project/lldb/source/Symbol/UnwindTable.cpp140
1 files changed, 54 insertions, 86 deletions
diff --git a/contrib/llvm-project/lldb/source/Symbol/UnwindTable.cpp b/contrib/llvm-project/lldb/source/Symbol/UnwindTable.cpp
index 11bedf3d6052..3aca495696c8 100644
--- a/contrib/llvm-project/lldb/source/Symbol/UnwindTable.cpp
+++ b/contrib/llvm-project/lldb/source/Symbol/UnwindTable.cpp
@@ -30,70 +30,27 @@ using namespace lldb;
using namespace lldb_private;
UnwindTable::UnwindTable(Module &module)
- : m_module(module), m_unwinds(), m_initialized(false), m_mutex(),
- m_object_file_unwind_up(), m_eh_frame_up(), m_compact_unwind_up(),
- m_arm_unwind_up() {}
+ : m_module(module), m_unwinds(), m_scanned_all_unwind_sources(false),
+ m_mutex(), m_object_file_unwind_up(), m_eh_frame_up(),
+ m_compact_unwind_up(), m_arm_unwind_up() {}
// We can't do some of this initialization when the ObjectFile is running its
// ctor; delay doing it until needed for something.
-
void UnwindTable::Initialize() {
- if (m_initialized)
+ if (m_scanned_all_unwind_sources)
return;
std::lock_guard<std::mutex> guard(m_mutex);
- if (m_initialized) // check again once we've acquired the lock
- return;
- m_initialized = true;
- ObjectFile *object_file = m_module.GetObjectFile();
- if (!object_file)
- return;
-
- m_object_file_unwind_up = object_file->CreateCallFrameInfo();
-
- SectionList *sl = m_module.GetSectionList();
- if (!sl)
+ if (m_scanned_all_unwind_sources) // check again once we've acquired the lock
return;
- SectionSP sect = sl->FindSectionByType(eSectionTypeEHFrame, true);
- if (sect.get()) {
- m_eh_frame_up = std::make_unique<DWARFCallFrameInfo>(
- *object_file, sect, DWARFCallFrameInfo::EH);
- }
-
- sect = sl->FindSectionByType(eSectionTypeDWARFDebugFrame, true);
- if (sect) {
- m_debug_frame_up = std::make_unique<DWARFCallFrameInfo>(
- *object_file, sect, DWARFCallFrameInfo::DWARF);
- }
-
- sect = sl->FindSectionByType(eSectionTypeCompactUnwind, true);
- if (sect) {
- m_compact_unwind_up =
- std::make_unique<CompactUnwindInfo>(*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 =
- std::make_unique<ArmUnwindInfo>(*object_file, sect, sect_extab);
- }
- }
-}
-
-void UnwindTable::Update() {
- if (!m_initialized)
- return Initialize();
-
- std::lock_guard<std::mutex> guard(m_mutex);
-
ObjectFile *object_file = m_module.GetObjectFile();
if (!object_file)
return;
+ m_scanned_all_unwind_sources = true;
+
if (!m_object_file_unwind_up)
m_object_file_unwind_up = object_file->CreateCallFrameInfo();
@@ -102,22 +59,19 @@ void UnwindTable::Update() {
return;
SectionSP sect = sl->FindSectionByType(eSectionTypeEHFrame, true);
- if (!m_eh_frame_up && sect) {
+ if (!m_eh_frame_up && sect)
m_eh_frame_up = std::make_unique<DWARFCallFrameInfo>(
*object_file, sect, DWARFCallFrameInfo::EH);
- }
sect = sl->FindSectionByType(eSectionTypeDWARFDebugFrame, true);
- if (!m_debug_frame_up && sect) {
+ if (!m_debug_frame_up && sect)
m_debug_frame_up = std::make_unique<DWARFCallFrameInfo>(
*object_file, sect, DWARFCallFrameInfo::DWARF);
- }
sect = sl->FindSectionByType(eSectionTypeCompactUnwind, true);
- if (!m_compact_unwind_up && sect) {
+ if (!m_compact_unwind_up && sect)
m_compact_unwind_up =
std::make_unique<CompactUnwindInfo>(*object_file, sect);
- }
sect = sl->FindSectionByType(eSectionTypeARMexidx, true);
if (!m_arm_unwind_up && sect) {
@@ -129,65 +83,78 @@ void UnwindTable::Update() {
}
}
+void UnwindTable::ModuleWasUpdated() {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ m_scanned_all_unwind_sources = false;
+ m_unwinds.clear();
+}
+
UnwindTable::~UnwindTable() = default;
-std::optional<AddressRange>
-UnwindTable::GetAddressRange(const Address &addr, const SymbolContext &sc) {
+AddressRanges UnwindTable::GetAddressRanges(const Address &addr,
+ const SymbolContext &sc) {
AddressRange range;
// First check the unwind info from the object file plugin
if (m_object_file_unwind_up &&
m_object_file_unwind_up->GetAddressRange(addr, range))
- return range;
+ return {range};
// Check the symbol context
- if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
- false, range) &&
- range.GetBaseAddress().IsValid())
- return range;
+ AddressRanges result;
+ for (size_t idx = 0;
+ sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, idx,
+ false, range) &&
+ range.GetBaseAddress().IsValid();
+ ++idx)
+ result.push_back(range);
+ if (!result.empty())
+ return result;
// 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;
+ return {range};
// Try debug_frame as well
if (m_debug_frame_up && m_debug_frame_up->GetAddressRange(addr, range))
- return range;
+ return {range};
- return std::nullopt;
+ return {};
+}
+
+static Address GetFunctionOrSymbolAddress(const Address &addr,
+ const SymbolContext &sc) {
+ if (Address result = sc.GetFunctionOrSymbolAddress(); result.IsValid())
+ return result;
+ return addr;
}
FuncUnwindersSP
UnwindTable::GetFuncUnwindersContainingAddress(const Address &addr,
- SymbolContext &sc) {
+ const SymbolContext &sc) {
Initialize();
std::lock_guard<std::mutex> guard(m_mutex);
// There is an UnwindTable per object file, so we can safely use file handles
addr_t file_addr = addr.GetFileAddress();
- iterator end = m_unwinds.end();
- iterator insert_pos = end;
- if (!m_unwinds.empty()) {
- insert_pos = m_unwinds.lower_bound(file_addr);
- iterator pos = insert_pos;
- if ((pos == m_unwinds.end()) ||
- (pos != m_unwinds.begin() &&
- pos->second->GetFunctionStartAddress() != addr))
- --pos;
-
+ iterator insert_pos = m_unwinds.upper_bound(file_addr);
+ if (insert_pos != m_unwinds.begin()) {
+ auto pos = std::prev(insert_pos);
if (pos->second->ContainsAddress(addr))
return pos->second;
}
- auto range_or = GetAddressRange(addr, sc);
- if (!range_or)
+ Address start_addr = GetFunctionOrSymbolAddress(addr, sc);
+ AddressRanges ranges = GetAddressRanges(addr, sc);
+ if (ranges.empty())
return nullptr;
- FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, *range_or));
- m_unwinds.insert(insert_pos,
- std::make_pair(range_or->GetBaseAddress().GetFileAddress(),
- func_unwinder_sp));
+ auto func_unwinder_sp =
+ std::make_shared<FuncUnwinders>(*this, start_addr, ranges);
+ for (const AddressRange &range : ranges)
+ m_unwinds.emplace_hint(insert_pos, range.GetBaseAddress().GetFileAddress(),
+ func_unwinder_sp);
return func_unwinder_sp;
}
@@ -199,11 +166,12 @@ FuncUnwindersSP UnwindTable::GetUncachedFuncUnwindersContainingAddress(
const Address &addr, const SymbolContext &sc) {
Initialize();
- auto range_or = GetAddressRange(addr, sc);
- if (!range_or)
+ Address start_addr = GetFunctionOrSymbolAddress(addr, sc);
+ AddressRanges ranges = GetAddressRanges(addr, sc);
+ if (ranges.empty())
return nullptr;
- return std::make_shared<FuncUnwinders>(*this, *range_or);
+ return std::make_shared<FuncUnwinders>(*this, start_addr, std::move(ranges));
}
void UnwindTable::Dump(Stream &s) {