-
Couldn't load subscription status.
- Fork 15k
[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 all 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,38 @@ 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)) | ||
| SequenceIter SeqPos; | ||
|
|
||
| if (StmtSequenceOffset) { | ||
| // If we have a statement sequence offset, find the specific sequence. | ||
| // Linear search for sequence with matching StmtSeqOffset | ||
| SeqPos = std::find_if(Sequences.begin(), LastSeq, | ||
| [&](const DWARFDebugLine::Sequence &S) { | ||
| return S.StmtSeqOffset == *StmtSequenceOffset; | ||
| }); | ||
|
|
||
| // If sequence not found, return false | ||
| if (SeqPos == LastSeq) | ||
| return false; | ||
|
|
||
| // Set LastSeq to the next sequence since we only want the one matching | ||
| // sequence (sequences are guaranteed to have unique StmtSeqOffset) | ||
| LastSeq = SeqPos + 1; | ||
| } else { | ||
| // No specific sequence requested, find first sequence containing address | ||
| SeqPos = std::upper_bound(Sequences.begin(), LastSeq, Sequence, | ||
| DWARFDebugLine::Sequence::orderByHighPC); | ||
| if (SeqPos == LastSeq) | ||
| return false; | ||
| } | ||
|
|
||
| // If the start sequence doesn't contain the address, nothing to do | ||
| if (!SeqPos->containsPC(Address)) | ||
| 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) { | ||
|
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.