-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[DebugInfo][DWARF] Utilize DW_AT_LLVM_stmt_sequence attr in line table lookups #123391
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
658a02c
ad1d1d0
cc8df97
88a816f
7aa8cae
16e8e20
569bbe4
539ab4c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -531,6 +531,7 @@ void DWARFDebugLine::Sequence::reset() { | |
| FirstRowIndex = 0; | ||
| LastRowIndex = 0; | ||
| Empty = true; | ||
| StmtSeqOffset = UINT64_MAX; | ||
| } | ||
|
|
||
| DWARFDebugLine::LineTable::LineTable() { clear(); } | ||
|
|
@@ -561,13 +562,12 @@ void DWARFDebugLine::LineTable::clear() { | |
| DWARFDebugLine::ParsingState::ParsingState( | ||
| struct LineTable *LT, uint64_t TableOffset, | ||
| function_ref<void(Error)> ErrorHandler) | ||
| : LineTable(LT), LineTableOffset(TableOffset), ErrorHandler(ErrorHandler) { | ||
| resetRowAndSequence(); | ||
| } | ||
| : LineTable(LT), LineTableOffset(TableOffset), ErrorHandler(ErrorHandler) {} | ||
|
|
||
| void DWARFDebugLine::ParsingState::resetRowAndSequence() { | ||
| void DWARFDebugLine::ParsingState::resetRowAndSequence(uint64_t Offset) { | ||
| Row.reset(LineTable->Prologue.DefaultIsStmt); | ||
| Sequence.reset(); | ||
| Sequence.StmtSeqOffset = Offset; | ||
| } | ||
|
|
||
| void DWARFDebugLine::ParsingState::appendRowToMatrix() { | ||
|
|
@@ -848,6 +848,10 @@ Error DWARFDebugLine::LineTable::parse( | |
| *OS << '\n'; | ||
| Row::dumpTableHeader(*OS, /*Indent=*/Verbose ? 12 : 0); | ||
| } | ||
| // *OffsetPtr points to the end of the prologue - i.e. the start of the first | ||
| // sequence. So initialize the first sequence offset accordingly. | ||
| State.resetRowAndSequence(*OffsetPtr); | ||
|
|
||
| bool TombstonedAddress = false; | ||
| auto EmitRow = [&] { | ||
| if (!TombstonedAddress) { | ||
|
|
@@ -912,7 +916,9 @@ Error DWARFDebugLine::LineTable::parse( | |
| // into this code path - if it were invalid, the default case would be | ||
| // followed. | ||
| EmitRow(); | ||
| State.resetRowAndSequence(); | ||
| // Cursor now points to right after the end_sequence opcode - so points | ||
| // to the start of the next sequence - if one exists. | ||
| State.resetRowAndSequence(Cursor.tell()); | ||
| break; | ||
|
|
||
| case DW_LNE_set_address: | ||
|
|
@@ -1364,23 +1370,25 @@ DWARFDebugLine::LineTable::lookupAddressImpl(object::SectionedAddress Address, | |
|
|
||
| bool DWARFDebugLine::LineTable::lookupAddressRange( | ||
| object::SectionedAddress Address, uint64_t Size, | ||
| std::vector<uint32_t> &Result) const { | ||
| std::vector<uint32_t> &Result, | ||
| std::optional<uint64_t> StmtSequenceOffset) const { | ||
|
|
||
| // Search for relocatable addresses | ||
| if (lookupAddressRangeImpl(Address, Size, Result)) | ||
| if (lookupAddressRangeImpl(Address, Size, Result, StmtSequenceOffset)) | ||
| return true; | ||
|
|
||
| if (Address.SectionIndex == object::SectionedAddress::UndefSection) | ||
| return false; | ||
|
|
||
| // Search for absolute addresses | ||
| Address.SectionIndex = object::SectionedAddress::UndefSection; | ||
| return lookupAddressRangeImpl(Address, Size, Result); | ||
| return lookupAddressRangeImpl(Address, Size, Result, StmtSequenceOffset); | ||
| } | ||
|
|
||
| bool DWARFDebugLine::LineTable::lookupAddressRangeImpl( | ||
| object::SectionedAddress Address, uint64_t Size, | ||
| std::vector<uint32_t> &Result) const { | ||
| std::vector<uint32_t> &Result, | ||
| std::optional<uint64_t> StmtSequenceOffset) const { | ||
| if (Sequences.empty()) | ||
| return false; | ||
| uint64_t EndAddr = Address.Address + Size; | ||
|
|
@@ -1389,16 +1397,36 @@ bool DWARFDebugLine::LineTable::lookupAddressRangeImpl( | |
| Sequence.SectionIndex = Address.SectionIndex; | ||
| Sequence.HighPC = Address.Address; | ||
| SequenceIter LastSeq = Sequences.end(); | ||
| SequenceIter SeqPos = llvm::upper_bound( | ||
| Sequences, Sequence, DWARFDebugLine::Sequence::orderByHighPC); | ||
| if (SeqPos == LastSeq || !SeqPos->containsPC(Address)) | ||
| return false; | ||
| SequenceIter SeqPos; | ||
|
|
||
| if (StmtSequenceOffset) { | ||
| // If we have a statement sequence offset, find the specific sequence | ||
| // Binary search for sequence with matching StmtSeqOffset | ||
| Sequence.StmtSeqOffset = *StmtSequenceOffset; | ||
| SeqPos = std::lower_bound(Sequences.begin(), LastSeq, Sequence, | ||
|
||
| [](const DWARFDebugLine::Sequence &LHS, | ||
| const DWARFDebugLine::Sequence &RHS) { | ||
| return LHS.StmtSeqOffset < RHS.StmtSeqOffset; | ||
| }); | ||
|
|
||
| // If sequence not found or doesn't contain the address, return false | ||
| if (SeqPos == LastSeq || SeqPos->StmtSeqOffset != *StmtSequenceOffset || | ||
| !SeqPos->containsPC(Address)) | ||
| return false; | ||
|
|
||
| // Set LastSeq to just past this sequence since we only want this one | ||
| LastSeq = std::next(SeqPos); | ||
|
||
| } else { | ||
| // No specific sequence requested, find first sequence containing address | ||
| SeqPos = std::upper_bound(Sequences.begin(), LastSeq, Sequence, | ||
| DWARFDebugLine::Sequence::orderByHighPC); | ||
| if (SeqPos == LastSeq || !SeqPos->containsPC(Address)) | ||
alx32 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return false; | ||
| } | ||
|
|
||
| SequenceIter StartPos = SeqPos; | ||
|
|
||
| // Add the rows from the first sequence to the vector, starting with the | ||
| // index we just calculated | ||
|
|
||
| // Process sequences that overlap with the desired range | ||
| while (SeqPos != LastSeq && SeqPos->LowPC < EndAddr) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Aside: this seems questionable... The LowPC of one sequence isn't necessarily related to the LowPC of another sequence (the linker could reorder them), so I'm not sure what this is meant to do but I'm a bit surprised/not sure it does whatever it is meant to do. |
||
| const DWARFDebugLine::Sequence &CurSeq = *SeqPos; | ||
| // For the first sequence, we need to find which row in the sequence is the | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.