https://github.com/medismailben created https://github.com/llvm/llvm-project/pull/158811
None >From 8ccfc58fd99356e88a16337f1fee21f104c49aa5 Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani <ism...@bennani.ma> Date: Tue, 16 Sep 2025 01:10:16 -0700 Subject: [PATCH] [lldb] Make LineEntry class and make AddressRange member optional Signed-off-by: Med Ismail Bennani <ism...@bennani.ma> --- .../lldb/Breakpoint/BreakpointLocation.h | 3 +- lldb/include/lldb/Core/Address.h | 2 +- lldb/include/lldb/Symbol/LineEntry.h | 20 ++++++- lldb/include/lldb/lldb-forward.h | 2 +- lldb/source/API/SBLineEntry.cpp | 10 ++-- lldb/source/API/SBThread.cpp | 13 +++-- lldb/source/Breakpoint/BreakpointResolver.cpp | 22 ++++++-- .../Commands/CommandObjectDisassemble.cpp | 4 +- lldb/source/Commands/CommandObjectSource.cpp | 6 +- lldb/source/Commands/CommandObjectTarget.cpp | 4 +- lldb/source/Commands/CommandObjectThread.cpp | 4 +- lldb/source/Core/AddressResolverFileLine.cpp | 4 +- lldb/source/Core/FormatEntity.cpp | 15 ++--- lldb/source/DataFormatters/TypeSummary.cpp | 4 +- .../Plugins/SymbolFile/PDB/SymbolFilePDB.cpp | 2 +- lldb/source/Symbol/CompileUnit.cpp | 16 ++++-- lldb/source/Symbol/Function.cpp | 17 +++--- lldb/source/Symbol/LineEntry.cpp | 55 +++++++++++++------ lldb/source/Symbol/LineTable.cpp | 15 ++--- lldb/source/Symbol/Symbol.cpp | 7 ++- lldb/source/Symbol/SymbolContext.cpp | 28 +++++++--- .../Target/ThreadPlanShouldStopHere.cpp | 2 +- .../source/Target/ThreadPlanStepOverRange.cpp | 4 +- lldb/source/Target/ThreadPlanStepRange.cpp | 12 ++-- lldb/tools/lldb-test/lldb-test.cpp | 11 +++- lldb/unittests/Symbol/LineTableTest.cpp | 11 +++- 26 files changed, 189 insertions(+), 104 deletions(-) diff --git a/lldb/include/lldb/Breakpoint/BreakpointLocation.h b/lldb/include/lldb/Breakpoint/BreakpointLocation.h index ab2e5e170559d..6a8d9ccfc8bc7 100644 --- a/lldb/include/lldb/Breakpoint/BreakpointLocation.h +++ b/lldb/include/lldb/Breakpoint/BreakpointLocation.h @@ -279,7 +279,8 @@ class BreakpointLocation /// The line entry must have the same start address as the address for this /// location. bool SetPreferredLineEntry(const LineEntry &line_entry) { - if (m_address == line_entry.range.GetBaseAddress()) { + if (line_entry.HasValidRange() && + m_address == line_entry.GetRange().GetBaseAddress()) { m_preferred_line_entry = line_entry; return true; } diff --git a/lldb/include/lldb/Core/Address.h b/lldb/include/lldb/Core/Address.h index 85b2ab7bb3cfe..a16cb55680a68 100644 --- a/lldb/include/lldb/Core/Address.h +++ b/lldb/include/lldb/Core/Address.h @@ -30,7 +30,7 @@ class Stream; class Symbol; class SymbolContext; class Target; -struct LineEntry; +class LineEntry; /// \class Address Address.h "lldb/Core/Address.h" /// A section + offset based address class. diff --git a/lldb/include/lldb/Symbol/LineEntry.h b/lldb/include/lldb/Symbol/LineEntry.h index 8da59cf0bd24a..755729a2a1442 100644 --- a/lldb/include/lldb/Symbol/LineEntry.h +++ b/lldb/include/lldb/Symbol/LineEntry.h @@ -13,12 +13,14 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/SupportFile.h" #include "lldb/lldb-private.h" +#include <optional> namespace lldb_private { /// \class LineEntry LineEntry.h "lldb/Symbol/LineEntry.h" /// A line table entry class. -struct LineEntry { +class LineEntry { +public: /// Default constructor. /// /// Initialize all member variables to invalid values. @@ -133,9 +135,21 @@ struct LineEntry { /// Helper to access the file. const FileSpec &GetFile() const { return file_sp->GetSpecOnly(); } - /// The section offset address range for this line entry. - AddressRange range; + /// Get the address range for this line entry. + /// \return The address range if valid, otherwise an invalid AddressRange. + const AddressRange &GetRange() const; + /// Check if this line entry has a valid address range. + bool HasValidRange() const; + + /// Set the address range for this line entry. + void SetRange(const AddressRange &range); + +private: + /// The section offset address range for this line entry (optional). + std::optional<AddressRange> m_range; + +public: /// The source file, possibly mapped by the target.source-map setting. lldb::SupportFileSP file_sp; diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index af5656b3dcad1..1dedfd0d644f7 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -306,7 +306,7 @@ class WatchpointResource; class WatchpointResourceCollection; class WatchpointSetOptions; struct CompilerContext; -struct LineEntry; +class LineEntry; struct PropertyDefinition; struct ScriptSummaryFormat; struct StatisticsOptions; diff --git a/lldb/source/API/SBLineEntry.cpp b/lldb/source/API/SBLineEntry.cpp index 0f4936f32a074..78ff488e8927f 100644 --- a/lldb/source/API/SBLineEntry.cpp +++ b/lldb/source/API/SBLineEntry.cpp @@ -50,8 +50,8 @@ SBAddress SBLineEntry::GetStartAddress() const { LLDB_INSTRUMENT_VA(this); SBAddress sb_address; - if (m_opaque_up) - sb_address.SetAddress(m_opaque_up->range.GetBaseAddress()); + if (m_opaque_up && m_opaque_up->HasValidRange()) + sb_address.SetAddress(m_opaque_up->GetRange().GetBaseAddress()); return sb_address; } @@ -60,9 +60,9 @@ SBAddress SBLineEntry::GetEndAddress() const { LLDB_INSTRUMENT_VA(this); SBAddress sb_address; - if (m_opaque_up) { - sb_address.SetAddress(m_opaque_up->range.GetBaseAddress()); - sb_address.OffsetAddress(m_opaque_up->range.GetByteSize()); + if (m_opaque_up && m_opaque_up->HasValidRange()) { + sb_address.SetAddress(m_opaque_up->GetRange().GetBaseAddress()); + sb_address.OffsetAddress(m_opaque_up->GetRange().GetByteSize()); } return sb_address; } diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp index 4e4aa48bc9a2e..da240a84db48c 100644 --- a/lldb/source/API/SBThread.cpp +++ b/lldb/source/API/SBThread.cpp @@ -515,9 +515,14 @@ void SBThread::StepInto(const char *target_name, uint32_t end_line, if (frame_sp && frame_sp->HasDebugInformation()) { SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); AddressRange range; - if (end_line == LLDB_INVALID_LINE_NUMBER) - range = sc.line_entry.range; - else { + if (end_line == LLDB_INVALID_LINE_NUMBER) { + if (sc.line_entry.HasValidRange()) + range = sc.line_entry.GetRange(); + else { + error = Status::FromErrorString("No valid range for line entry"); + return; + } + } else { llvm::Error err = sc.GetAddressRangeFromHereToEndLine(end_line, range); if (err) { error = Status::FromErrorString(llvm::toString(std::move(err)).c_str()); @@ -787,7 +792,7 @@ SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame, eSymbolContextLineEntry, sc_list); for (const SymbolContext &sc : sc_list) { addr_t step_addr = - sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); + sc.line_entry.GetRange().GetBaseAddress().GetLoadAddress(target); if (step_addr != LLDB_INVALID_ADDRESS) { AddressRange unused_range; if (frame_sc.function->GetRangeContainingLoadAddress(step_addr, *target, diff --git a/lldb/source/Breakpoint/BreakpointResolver.cpp b/lldb/source/Breakpoint/BreakpointResolver.cpp index 4ac40501a5df5..a91805156a63c 100644 --- a/lldb/source/Breakpoint/BreakpointResolver.cpp +++ b/lldb/source/Breakpoint/BreakpointResolver.cpp @@ -273,11 +273,19 @@ void BreakpointResolver::SetSCMatchesByLine( } // Sort by file address. - llvm::sort(worklist_begin, worklist_end, - [](const SymbolContext &a, const SymbolContext &b) { - return a.line_entry.range.GetBaseAddress().GetFileAddress() < - b.line_entry.range.GetBaseAddress().GetFileAddress(); - }); + llvm::sort( + worklist_begin, worklist_end, + [](const SymbolContext &a, const SymbolContext &b) { + auto a_addr = + a.line_entry.HasValidRange() + ? a.line_entry.GetRange().GetBaseAddress().GetFileAddress() + : LLDB_INVALID_ADDRESS; + auto b_addr = + b.line_entry.HasValidRange() + ? b.line_entry.GetRange().GetBaseAddress().GetFileAddress() + : LLDB_INVALID_ADDRESS; + return a_addr < b_addr; + }); // Go through and see if there are line table entries that are // contiguous, and if so keep only the first of the contiguous range. @@ -307,7 +315,9 @@ void BreakpointResolver::AddLocation(SearchFilter &filter, bool skip_prologue, llvm::StringRef log_ident) { Log *log = GetLog(LLDBLog::Breakpoints); - Address line_start = sc.line_entry.range.GetBaseAddress(); + Address line_start = sc.line_entry.HasValidRange() + ? sc.line_entry.GetRange().GetBaseAddress() + : Address(); if (!line_start.IsValid()) { LLDB_LOGF(log, "error: Unable to set breakpoint %s at file address " diff --git a/lldb/source/Commands/CommandObjectDisassemble.cpp b/lldb/source/Commands/CommandObjectDisassemble.cpp index c0553d2c6c8b2..5c32e985c78b8 100644 --- a/lldb/source/Commands/CommandObjectDisassemble.cpp +++ b/lldb/source/Commands/CommandObjectDisassemble.cpp @@ -356,8 +356,8 @@ CommandObjectDisassemble::GetCurrentLineRanges() { LineEntry pc_line_entry( frame->GetSymbolContext(eSymbolContextLineEntry).line_entry); - if (pc_line_entry.IsValid()) - return std::vector<AddressRange>{pc_line_entry.range}; + if (pc_line_entry.IsValid() && pc_line_entry.HasValidRange()) + return std::vector<AddressRange>{pc_line_entry.GetRange()}; // No line entry, so just disassemble around the current pc m_options.show_mixed = false; diff --git a/lldb/source/Commands/CommandObjectSource.cpp b/lldb/source/Commands/CommandObjectSource.cpp index 0b4599b16ef0d..fe38aa82ae5c0 100644 --- a/lldb/source/Commands/CommandObjectSource.cpp +++ b/lldb/source/Commands/CommandObjectSource.cpp @@ -1032,9 +1032,11 @@ class CommandObjectSourceList : public CommandObjectParsed { bool show_inlined_frames = true; const bool show_function_arguments = true; const bool show_function_name = true; + Address addr = sc.line_entry.HasValidRange() + ? sc.line_entry.GetRange().GetBaseAddress() + : Address(); sc.DumpStopContext(&result.GetOutputStream(), - m_exe_ctx.GetBestExecutionContextScope(), - sc.line_entry.range.GetBaseAddress(), + m_exe_ctx.GetBestExecutionContextScope(), addr, show_fullpaths, show_module, show_inlined_frames, show_function_arguments, show_function_name); result.GetOutputStream().EOL(); diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index 0f96fa92a731d..43a6211a18a33 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -1628,8 +1628,8 @@ static void DumpSymbolContextList( strm.EOL(); Address addr; - if (sc.line_entry.IsValid()) - addr = sc.line_entry.range.GetBaseAddress(); + if (sc.line_entry.IsValid() && sc.line_entry.HasValidRange()) + addr = sc.line_entry.GetRange().GetBaseAddress(); else if (sc.block && sc.block->GetContainingInlinedBlock()) sc.block->GetContainingInlinedBlock()->GetStartAddress(addr); else diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp index bbec714642ec9..9c9573cba9529 100644 --- a/lldb/source/Commands/CommandObjectThread.cpp +++ b/lldb/source/Commands/CommandObjectThread.cpp @@ -519,7 +519,7 @@ class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed { block_range.GetByteSize() - pc_offset_in_block; range = AddressRange(pc_address, range_length); } else { - range = sc.line_entry.range; + range = sc.line_entry.GetRange(); } new_plan_sp = thread->QueueThreadPlanForStepInRange( @@ -999,7 +999,7 @@ class CommandObjectThreadUntil : public CommandObjectParsed { while (idx < end_func_idx) { if (line_idx_ranges.FindEntryIndexThatContains(idx) != UINT32_MAX) { addr_t address = - line_entry.range.GetBaseAddress().GetLoadAddress(target); + line_entry.GetRange().GetBaseAddress().GetLoadAddress(target); if (address != LLDB_INVALID_ADDRESS) address_list.push_back(address); } diff --git a/lldb/source/Core/AddressResolverFileLine.cpp b/lldb/source/Core/AddressResolverFileLine.cpp index 6ab3b8fcee154..be2f3aa4bebbe 100644 --- a/lldb/source/Core/AddressResolverFileLine.cpp +++ b/lldb/source/Core/AddressResolverFileLine.cpp @@ -46,8 +46,8 @@ AddressResolverFileLine::SearchCallback(SearchFilter &filter, cu->ResolveSymbolContext(m_src_location_spec, eSymbolContextEverything, sc_list); for (const SymbolContext &sc : sc_list) { - Address line_start = sc.line_entry.range.GetBaseAddress(); - addr_t byte_size = sc.line_entry.range.GetByteSize(); + Address line_start = sc.line_entry.GetRange().GetBaseAddress(); + addr_t byte_size = sc.line_entry.GetRange().GetByteSize(); if (line_start.IsValid()) { AddressRange new_range(line_start, byte_size); m_address_ranges.push_back(new_range); diff --git a/lldb/source/Core/FormatEntity.cpp b/lldb/source/Core/FormatEntity.cpp index 491f5c6320d97..2548dfd1620fd 100644 --- a/lldb/source/Core/FormatEntity.cpp +++ b/lldb/source/Core/FormatEntity.cpp @@ -1918,10 +1918,11 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, return false; case Entry::Type::FunctionLineOffset: - if (sc) - return (DumpAddressOffsetFromFunction( - s, sc, exe_ctx, sc->line_entry.range.GetBaseAddress(), false, false, - false)); + if (sc) { + Address line_addr = sc->line_entry.GetRange().GetBaseAddress(); + return (DumpAddressOffsetFromFunction(s, sc, exe_ctx, line_addr, false, + false, false)); + } return false; case Entry::Type::FunctionPCOffset: @@ -1986,11 +1987,11 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, case Entry::Type::LineEntryStartAddress: case Entry::Type::LineEntryEndAddress: - if (sc && sc->line_entry.range.GetBaseAddress().IsValid()) { - Address addr = sc->line_entry.range.GetBaseAddress(); + if (sc && sc->line_entry.HasValidRange()) { + Address addr = sc->line_entry.GetRange().GetBaseAddress(); if (entry.type == Entry::Type::LineEntryEndAddress) - addr.Slide(sc->line_entry.range.GetByteSize()); + addr.Slide(sc->line_entry.GetRange().GetByteSize()); if (DumpAddressAndContent(s, sc, exe_ctx, addr, false)) return true; } diff --git a/lldb/source/DataFormatters/TypeSummary.cpp b/lldb/source/DataFormatters/TypeSummary.cpp index 6aa290698cd12..489d6c43f5092 100644 --- a/lldb/source/DataFormatters/TypeSummary.cpp +++ b/lldb/source/DataFormatters/TypeSummary.cpp @@ -105,8 +105,8 @@ bool StringSummaryFormat::FormatObject(ValueObject *valobj, std::string &retval, retval = std::string(s.GetString()); return true; } else { - if (FormatEntity::Format(m_format, s, &sc, &exe_ctx, - &sc.line_entry.range.GetBaseAddress(), valobj, + Address temp_addr = sc.line_entry.GetRange().GetBaseAddress(); + if (FormatEntity::Format(m_format, s, &sc, &exe_ctx, &temp_addr, valobj, false, false)) { retval.assign(std::string(s.GetString())); return true; diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 0e2ca1784e7e9..58d0c7f309784 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -947,7 +947,7 @@ uint32_t SymbolFilePDB::ResolveSymbolContext( continue; auto file_vm_addr = - sc.line_entry.range.GetBaseAddress().GetFileAddress(); + sc.line_entry.GetRange().GetBaseAddress().GetFileAddress(); if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0) continue; diff --git a/lldb/source/Symbol/CompileUnit.cpp b/lldb/source/Symbol/CompileUnit.cpp index 166f111ef6220..64e4e29d99c6b 100644 --- a/lldb/source/Symbol/CompileUnit.cpp +++ b/lldb/source/Symbol/CompileUnit.cpp @@ -335,7 +335,7 @@ void CompileUnit::ResolveSymbolContext( // line entry will be the in function that contained the line that might // be a CallSite, and we can just iterate over that function to find any // inline records, and dig up their call sites. - Address start_addr = line_entry.range.GetBaseAddress(); + Address start_addr = line_entry.GetRange().GetBaseAddress(); Function *function = start_addr.CalculateSymbolContextFunction(); // Record the size of the list to see if we added to it: size_t old_sc_list_size = sc_list.GetSize(); @@ -390,8 +390,9 @@ void CompileUnit::ResolveSymbolContext( *src_location_spec.GetColumn() == call_site_line.column)) matches_spec = true; } - if (matches_spec && - sibling_block->GetRangeAtIndex(0, call_site_line.range)) { + AddressRange range; + if (matches_spec && sibling_block->GetRangeAtIndex(0, range)) { + call_site_line.SetRange(range); SymbolContext call_site_sc(sc.target_sp, sc.module_sp, sc.comp_unit, sc.function, sc.block, &call_site_line, sc.symbol); @@ -446,8 +447,9 @@ void CompileUnit::ResolveSymbolContext( if (resolve_scope == eSymbolContextLineEntry) { sc_list.Append(sc); } else { - line_entry.range.GetBaseAddress().CalculateSymbolContext(&resolved_sc, - resolve_scope); + if (line_entry.HasValidRange()) + line_entry.GetRange().GetBaseAddress().CalculateSymbolContext( + &resolved_sc, resolve_scope); // Sometimes debug info is bad and isn't able to resolve the line entry's // address back to the same compile unit and/or line entry. If the compile // unit changed, then revert back to just the compile unit and line entry. @@ -474,7 +476,9 @@ void CompileUnit::ResolveSymbolContext( "unable to resolve a line table file address {0:x16} back " "to a compile unit, please file a bug and attach the address " "and file.", - line_entry.range.GetBaseAddress().GetFileAddress()); + line_entry.HasValidRange() + ? line_entry.GetRange().GetBaseAddress().GetFileAddress() + : 0); } sc_list.Append(sc); } diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp index 6114eccd935ee..39e85a10665d0 100644 --- a/lldb/source/Symbol/Function.cpp +++ b/lldb/source/Symbol/Function.cpp @@ -593,7 +593,7 @@ uint32_t Function::GetPrologueByteSize() { if (first_line_entry.is_prologue_end) { prologue_end_file_addr = - first_line_entry.range.GetBaseAddress().GetFileAddress(); + first_line_entry.GetRange().GetBaseAddress().GetFileAddress(); prologue_end_line_idx = first_line_entry_idx; } else { // Check the first few instructions and look for one that has @@ -605,7 +605,7 @@ uint32_t Function::GetPrologueByteSize() { if (line_table->GetLineEntryAtIndex(idx, line_entry)) { if (line_entry.is_prologue_end) { prologue_end_file_addr = - line_entry.range.GetBaseAddress().GetFileAddress(); + line_entry.GetRange().GetBaseAddress().GetFileAddress(); prologue_end_line_idx = idx; break; } @@ -625,7 +625,7 @@ uint32_t Function::GetPrologueByteSize() { if (line_table->GetLineEntryAtIndex(idx, line_entry)) { if (line_entry.line != first_line_entry.line) { prologue_end_file_addr = - line_entry.range.GetBaseAddress().GetFileAddress(); + line_entry.GetRange().GetBaseAddress().GetFileAddress(); prologue_end_line_idx = idx; break; } @@ -634,8 +634,8 @@ uint32_t Function::GetPrologueByteSize() { if (prologue_end_file_addr == LLDB_INVALID_ADDRESS) { prologue_end_file_addr = - first_line_entry.range.GetBaseAddress().GetFileAddress() + - first_line_entry.range.GetByteSize(); + first_line_entry.GetRange().GetBaseAddress().GetFileAddress() + + first_line_entry.GetRange().GetByteSize(); prologue_end_line_idx = first_line_entry_idx; } } @@ -659,7 +659,7 @@ uint32_t Function::GetPrologueByteSize() { if (line_entry.line != 0) break; } - if (line_entry.range.GetBaseAddress().GetFileAddress() >= + if (line_entry.GetRange().GetBaseAddress().GetFileAddress() >= range_end_file_addr) break; @@ -670,8 +670,9 @@ uint32_t Function::GetPrologueByteSize() { LineEntry first_non_zero_entry; if (line_table->GetLineEntryAtIndex(first_non_zero_line, first_non_zero_entry)) { - line_zero_end_file_addr = - first_non_zero_entry.range.GetBaseAddress().GetFileAddress(); + line_zero_end_file_addr = first_non_zero_entry.GetRange() + .GetBaseAddress() + .GetFileAddress(); } } diff --git a/lldb/source/Symbol/LineEntry.cpp b/lldb/source/Symbol/LineEntry.cpp index c941a6927cb93..8ec1fefc81af5 100644 --- a/lldb/source/Symbol/LineEntry.cpp +++ b/lldb/source/Symbol/LineEntry.cpp @@ -14,13 +14,13 @@ using namespace lldb_private; LineEntry::LineEntry() - : range(), file_sp(std::make_shared<SupportFile>()), + : m_range(), file_sp(std::make_shared<SupportFile>()), original_file_sp(std::make_shared<SupportFile>()), is_start_of_statement(0), is_start_of_basic_block(0), is_prologue_end(0), is_epilogue_begin(0), is_terminal_entry(0) {} void LineEntry::Clear() { - range.Clear(); + m_range.reset(); file_sp = std::make_shared<SupportFile>(); original_file_sp = std::make_shared<SupportFile>(); line = LLDB_INVALID_LINE_NUMBER; @@ -32,10 +32,19 @@ void LineEntry::Clear() { is_terminal_entry = 0; } -bool LineEntry::IsValid() const { - return range.GetBaseAddress().IsValid() && line != LLDB_INVALID_LINE_NUMBER; +bool LineEntry::IsValid() const { return line != LLDB_INVALID_LINE_NUMBER; } + +const AddressRange &LineEntry::GetRange() const { + static AddressRange invalid_range; + return m_range ? *m_range : invalid_range; +} + +bool LineEntry::HasValidRange() const { + return m_range.has_value() && m_range->GetBaseAddress().IsValid(); } +void LineEntry::SetRange(const AddressRange &range) { m_range = range; } + bool LineEntry::DumpStopContext(Stream *s, bool show_fullpaths) const { const FileSpec &file = file_sp->GetSpecOnly(); if (file) { @@ -62,11 +71,12 @@ bool LineEntry::Dump(Stream *s, Target *target, bool show_file, Address::DumpStyle fallback_style, bool show_range) const { if (show_range) { // Show address range - if (!range.Dump(s, target, style, fallback_style)) + if (!HasValidRange() || !GetRange().Dump(s, target, style, fallback_style)) return false; } else { // Show address only - if (!range.GetBaseAddress().Dump(s, target, style, fallback_style)) + if (!HasValidRange() || + !GetRange().GetBaseAddress().Dump(s, target, style, fallback_style)) return false; } if (show_file) @@ -99,11 +109,16 @@ bool LineEntry::GetDescription(Stream *s, lldb::DescriptionLevel level, if (level == lldb::eDescriptionLevelBrief || level == lldb::eDescriptionLevelFull) { if (show_address_only) { - range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress, - Address::DumpStyleFileAddress); + if (HasValidRange()) { + GetRange().GetBaseAddress().Dump(s, target, + Address::DumpStyleLoadAddress, + Address::DumpStyleFileAddress); + } } else { - range.Dump(s, target, Address::DumpStyleLoadAddress, - Address::DumpStyleFileAddress); + if (HasValidRange()) { + GetRange().Dump(s, target, Address::DumpStyleLoadAddress, + Address::DumpStyleFileAddress); + } } *s << ": " << GetFile(); @@ -145,13 +160,13 @@ bool lldb_private::operator<(const LineEntry &a, const LineEntry &b) { } int LineEntry::Compare(const LineEntry &a, const LineEntry &b) { - int result = Address::CompareFileAddress(a.range.GetBaseAddress(), - b.range.GetBaseAddress()); + int result = Address::CompareFileAddress(a.GetRange().GetBaseAddress(), + b.GetRange().GetBaseAddress()); if (result != 0) return result; - const lldb::addr_t a_byte_size = a.range.GetByteSize(); - const lldb::addr_t b_byte_size = b.range.GetByteSize(); + const lldb::addr_t a_byte_size = a.GetRange().GetByteSize(); + const lldb::addr_t b_byte_size = b.GetRange().GetByteSize(); if (a_byte_size < b_byte_size) return -1; @@ -183,7 +198,10 @@ AddressRange LineEntry::GetSameLineContiguousAddressRange( bool include_inlined_functions) const { // Add each LineEntry's range to complete_line_range until we find a // different file / line number. - AddressRange complete_line_range = range; + if (!HasValidRange()) + return {}; + AddressRange complete_line_range = GetRange(); + auto symbol_context_scope = lldb::eSymbolContextLineEntry; Declaration start_call_site(original_file_sp->GetSpecOnly(), line); if (include_inlined_functions) @@ -196,7 +214,8 @@ AddressRange LineEntry::GetSameLineContiguousAddressRange( range_end.CalculateSymbolContext(&next_line_sc, symbol_context_scope); if (!next_line_sc.line_entry.IsValid() || - next_line_sc.line_entry.range.GetByteSize() == 0) + !next_line_sc.line_entry.HasValidRange() || + next_line_sc.line_entry.GetRange().GetByteSize() == 0) break; if (original_file_sp->Equal(*next_line_sc.line_entry.original_file_sp, @@ -209,7 +228,7 @@ AddressRange LineEntry::GetSameLineContiguousAddressRange( // our AddressRange by its size and continue to see if there are more // LineEntries that we can combine. However, if there was nothing to // extend we're done. - if (!complete_line_range.Extend(next_line_sc.line_entry.range)) + if (!complete_line_range.Extend(next_line_sc.line_entry.GetRange())) break; continue; } @@ -231,7 +250,7 @@ AddressRange LineEntry::GetSameLineContiguousAddressRange( break; // Extend our AddressRange by the size of the inlined block, but if there // was nothing to add then we're done. - if (!complete_line_range.Extend(next_line_sc.line_entry.range)) + if (!complete_line_range.Extend(next_line_sc.line_entry.GetRange())) break; continue; } diff --git a/lldb/source/Symbol/LineTable.cpp b/lldb/source/Symbol/LineTable.cpp index ca3accd6894a7..65dd8f2a39c3b 100644 --- a/lldb/source/Symbol/LineTable.cpp +++ b/lldb/source/Symbol/LineTable.cpp @@ -244,19 +244,20 @@ bool LineTable::ConvertEntryAtIndexToLineEntry(uint32_t idx, if (entry.is_terminal_entry) --file_addr; - if (!module_sp->ResolveFileAddress(file_addr, - line_entry.range.GetBaseAddress())) + AddressRange range; + if (!module_sp->ResolveFileAddress(file_addr, range.GetBaseAddress())) return false; // Now undo the decrement above. - if (entry.is_terminal_entry) - line_entry.range.GetBaseAddress().Slide(1); + if (entry.is_terminal_entry) { + range.GetBaseAddress().Slide(1); + } if (!entry.is_terminal_entry && idx + 1 < m_entries.size()) - line_entry.range.SetByteSize(m_entries[idx + 1].file_addr - - entry.file_addr); + range.SetByteSize(m_entries[idx + 1].file_addr - entry.file_addr); else - line_entry.range.SetByteSize(0); + range.SetByteSize(0); + line_entry.SetRange(range); line_entry.file_sp = m_comp_unit->GetSupportFiles().GetSupportFileAtIndex(entry.file_idx); diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp index 40497dbccc5c3..a27e168bd8edd 100644 --- a/lldb/source/Symbol/Symbol.cpp +++ b/lldb/source/Symbol/Symbol.cpp @@ -330,7 +330,7 @@ uint32_t Symbol::GetPrologueByteSize() { base_address, eSymbolContextLineEntry, sc); if (resolved_flags & eSymbolContextLineEntry) { // Default to the end of the first line entry. - m_type_data = sc.line_entry.range.GetByteSize(); + m_type_data = sc.line_entry.GetRange().GetByteSize(); // Set address for next line. Address addr(base_address); @@ -356,8 +356,9 @@ uint32_t Symbol::GetPrologueByteSize() { } // Slide addr up to the next line address. - addr.Slide(sc_temp.line_entry.range.GetByteSize()); - total_offset += sc_temp.line_entry.range.GetByteSize(); + addr_t slide_amount = sc_temp.line_entry.GetRange().GetByteSize(); + addr.Slide(slide_amount); + total_offset += slide_amount; // If we've gone too far, bail out. if (total_offset >= m_addr_range.GetByteSize()) break; diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp index 3bbd1eff824e6..f53295f7a96f1 100644 --- a/lldb/source/Symbol/SymbolContext.cpp +++ b/lldb/source/Symbol/SymbolContext.cpp @@ -341,8 +341,10 @@ bool SymbolContext::GetAddressRange(uint32_t scope, uint32_t range_idx, bool use_inline_block_range, AddressRange &range) const { if ((scope & eSymbolContextLineEntry) && line_entry.IsValid()) { - range = line_entry.range; - return true; + if (line_entry.HasValidRange()) { + range = line_entry.GetRange(); + return true; + } } if ((scope & eSymbolContextBlock) && (block != nullptr)) { @@ -437,7 +439,9 @@ bool SymbolContext::GetParentOfInlinedScope(const Address &curr_frame_pc, const InlineFunctionInfo *curr_inlined_block_inlined_info = curr_inlined_block->GetInlinedFunctionInfo(); next_frame_pc = range.GetBaseAddress(); - next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc; + AddressRange new_range; + new_range.GetBaseAddress() = next_frame_pc; + next_frame_sc.line_entry.SetRange(new_range); next_frame_sc.line_entry.file_sp = std::make_shared<SupportFile>( curr_inlined_block_inlined_info->GetCallSite().GetFile()); next_frame_sc.line_entry.original_file_sp = @@ -668,7 +672,11 @@ SymbolContext::GetAddressRangeFromHereToEndLine(uint32_t end_line, return llvm::createStringError("Symbol context has no line table."); } - range = line_entry.range; + if (!line_entry.HasValidRange()) { + return llvm::createStringError("Line entry has no valid address range."); + } + + range = line_entry.GetRange(); if (line_entry.line > end_line) { return llvm::createStringError( "end line option %d must be after the current line: %d", end_line, @@ -708,15 +716,19 @@ SymbolContext::GetAddressRangeFromHereToEndLine(uint32_t end_line, } Block *func_block = GetFunctionBlock(); - if (func_block && func_block->GetRangeIndexContainingAddress( - end_entry.range.GetBaseAddress()) == UINT32_MAX) { + if (func_block && end_entry.HasValidRange() && + func_block->GetRangeIndexContainingAddress( + end_entry.GetRange().GetBaseAddress()) == UINT32_MAX) { return llvm::createStringError( "end line number %d is not contained within the current function.", end_line); } - lldb::addr_t range_size = end_entry.range.GetBaseAddress().GetFileAddress() - - range.GetBaseAddress().GetFileAddress(); + lldb::addr_t range_size = + end_entry.HasValidRange() + ? (end_entry.GetRange().GetBaseAddress().GetFileAddress() - + range.GetBaseAddress().GetFileAddress()) + : 0; range.SetByteSize(range_size); return llvm::Error::success(); } diff --git a/lldb/source/Target/ThreadPlanShouldStopHere.cpp b/lldb/source/Target/ThreadPlanShouldStopHere.cpp index d2cca49987f0f..f345c2cc2747a 100644 --- a/lldb/source/Target/ThreadPlanShouldStopHere.cpp +++ b/lldb/source/Target/ThreadPlanShouldStopHere.cpp @@ -128,7 +128,7 @@ ThreadPlanSP ThreadPlanShouldStopHere::DefaultStepFromHereCallback( sc = frame->GetSymbolContext(eSymbolContextLineEntry | eSymbolContextSymbol); if (sc.line_entry.line == 0) { - AddressRange range = sc.line_entry.range; + AddressRange range = sc.line_entry.GetRange(); bool just_step_out = false; if (sc.symbol) { ProcessSP process_sp(current_plan->GetThread().GetProcess()); diff --git a/lldb/source/Target/ThreadPlanStepOverRange.cpp b/lldb/source/Target/ThreadPlanStepOverRange.cpp index 643ee827c865c..b49eeab6eb12a 100644 --- a/lldb/source/Target/ThreadPlanStepOverRange.cpp +++ b/lldb/source/Target/ThreadPlanStepOverRange.cpp @@ -265,7 +265,7 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) { SupportFile::eEqualFileSpecAndChecksumIfSet)) { SymbolContext prev_sc; Address prev_address = - prev_line_entry.range.GetBaseAddress(); + prev_line_entry.GetRange().GetBaseAddress(); prev_address.CalculateSymbolContext(&prev_sc); if (prev_sc.block) { Block *inlined_block = @@ -290,7 +290,7 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) { // Make sure we haven't wandered out of the function we // started from... Address next_line_address = - next_line_entry.range.GetBaseAddress(); + next_line_entry.GetRange().GetBaseAddress(); Function *next_line_function = next_line_address.CalculateSymbolContextFunction(); if (next_line_function != m_addr_context.function) diff --git a/lldb/source/Target/ThreadPlanStepRange.cpp b/lldb/source/Target/ThreadPlanStepRange.cpp index dca96cc74ba46..e93d31c1339bb 100644 --- a/lldb/source/Target/ThreadPlanStepRange.cpp +++ b/lldb/source/Target/ThreadPlanStepRange.cpp @@ -160,8 +160,10 @@ bool ThreadPlanStepRange::InRange() { "stepping through that range: %s", s.GetData()); } - } else if (new_context.line_entry.range.GetBaseAddress().GetLoadAddress( - &GetTarget()) != pc_load_addr) { + } else if (new_context.line_entry.HasValidRange() && + new_context.line_entry.GetRange() + .GetBaseAddress() + .GetLoadAddress(&GetTarget()) != pc_load_addr) { // Another thing that sometimes happens here is that we step out of // one line into the MIDDLE of another line. So far I mostly see // this due to bugs in the debug information. But we probably don't @@ -170,7 +172,9 @@ bool ThreadPlanStepRange::InRange() { // and continue. m_addr_context = new_context; m_address_ranges.clear(); - AddRange(m_addr_context.line_entry.range); + if (m_addr_context.line_entry.HasValidRange()) { + AddRange(m_addr_context.line_entry.GetRange()); + } ret_value = true; if (log) { StreamString s; @@ -430,7 +434,7 @@ bool ThreadPlanStepRange::SetNextBranchBreakpoint() { FileSpec call_site_file_spec = call_site.GetFile(); top_most_line_entry.original_file_sp = std::make_shared<SupportFile>(call_site_file_spec); - top_most_line_entry.range = range; + top_most_line_entry.SetRange(range); top_most_line_entry.file_sp.reset(); top_most_line_entry.ApplyFileMappings( GetThread().CalculateTarget()); diff --git a/lldb/tools/lldb-test/lldb-test.cpp b/lldb/tools/lldb-test/lldb-test.cpp index 3f198d963a93b..383409069bcc6 100644 --- a/lldb/tools/lldb-test/lldb-test.cpp +++ b/lldb/tools/lldb-test/lldb-test.cpp @@ -786,13 +786,18 @@ Error opts::symbols::verify(lldb_private::Module &Module) { return make_string_error("Can't get a line entry of a compile unit."); for (uint32_t i = 1; i < count; i++) { - lldb::addr_t curr_end = - le.range.GetBaseAddress().GetFileAddress() + le.range.GetByteSize(); + lldb::addr_t curr_end = LLDB_INVALID_ADDRESS; + if (le.HasValidRange()) { + const lldb_private::AddressRange &range = le.GetRange(); + curr_end = + range.GetBaseAddress().GetFileAddress() + range.GetByteSize(); + } if (!lt->GetLineEntryAtIndex(i, le)) return make_string_error("Can't get a line entry of a compile unit"); - if (curr_end > le.range.GetBaseAddress().GetFileAddress()) + if (le.HasValidRange() && + curr_end > le.GetRange().GetBaseAddress().GetFileAddress()) return make_string_error( "Line table of a compile unit is inconsistent."); } diff --git a/lldb/unittests/Symbol/LineTableTest.cpp b/lldb/unittests/Symbol/LineTableTest.cpp index eadab40a37fac..4b6ff4e8c39e7 100644 --- a/lldb/unittests/Symbol/LineTableTest.cpp +++ b/lldb/unittests/Symbol/LineTableTest.cpp @@ -284,9 +284,14 @@ TEST_F(LineTableTest, FindLineEntryByAddress) { LineEntry entry; if (!table->FindLineEntryByAddress(Address(fixture->text_sp, addr), entry)) return {LLDB_INVALID_ADDRESS, LLDB_INVALID_ADDRESS, false}; - return {entry.range.GetBaseAddress().GetFileAddress(), - entry.range.GetByteSize(), - static_cast<bool>(entry.is_terminal_entry)}; + if (entry.HasValidRange()) { + return {entry.GetRange().GetBaseAddress().GetFileAddress(), + entry.GetRange().GetByteSize(), + static_cast<bool>(entry.is_terminal_entry)}; + } else { + return {LLDB_INVALID_ADDRESS, 0, + static_cast<bool>(entry.is_terminal_entry)}; + } }; EXPECT_THAT(find(0), testing::FieldsAre(0, 10, false)); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits