Skip to content

Commit 61f0636

Browse files
committed
[dsymutil] Fix line table sequence mapping for stmt_sequence attributes
1 parent 45218e0 commit 61f0636

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2297,8 +2297,37 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
22972297

22982298
// Create a map of stmt sequence offsets to original row indices.
22992299
DenseMap<uint64_t, unsigned> SeqOffToOrigRow;
2300-
for (const DWARFDebugLine::Sequence &Seq : LT->Sequences)
2301-
SeqOffToOrigRow[Seq.StmtSeqOffset] = Seq.FirstRowIndex;
2300+
// The DWARF parser's discovery of sequences can be incomplete. To
2301+
// ensure all DW_AT_LLVM_stmt_sequence attributes can be patched, we
2302+
// build a map from both the parser's results and a manual
2303+
// reconstruction.
2304+
if (!LT->Rows.empty()) {
2305+
// First, trust the sequences that the DWARF parser did identify.
2306+
for (const DWARFDebugLine::Sequence &Seq : LT->Sequences)
2307+
SeqOffToOrigRow.try_emplace(Seq.StmtSeqOffset, Seq.FirstRowIndex);
2308+
2309+
// Second, manually find sequence boundaries and match them to the
2310+
// sorted attributes to handle sequences the parser might have missed.
2311+
auto StmtAttrs = Unit.getStmtSeqListAttributes();
2312+
llvm::sort(StmtAttrs,
2313+
[](const PatchLocation &A, const PatchLocation &B) {
2314+
return A.get() < B.get();
2315+
});
2316+
2317+
std::vector<size_t> SeqStartRows;
2318+
SeqStartRows.push_back(0);
2319+
for (size_t i = 0; i < LT->Rows.size() - 1; ++i)
2320+
if (LT->Rows[i].EndSequence)
2321+
SeqStartRows.push_back(i + 1);
2322+
2323+
// Correlate the sorted attributes with the reconstructed sequence
2324+
// starts. This provides a partial mapping if counts are mismatched,
2325+
// maximizing the number of correctly patched attributes.
2326+
size_t NumMappings = std::min(StmtAttrs.size(), SeqStartRows.size());
2327+
for (size_t i = 0; i < NumMappings; ++i) {
2328+
SeqOffToOrigRow.try_emplace(StmtAttrs[i].get(), SeqStartRows[i]);
2329+
}
2330+
}
23022331

23032332
// Create a map of original row indices to new row indices.
23042333
DenseMap<size_t, size_t> OrigRowToNewRow;

llvm/test/tools/dsymutil/ARM/stmt-seq-macho.test

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
# RUN: yaml2obj %t/stmt_seq_macho.exe.yaml -o %t/stmt_seq_macho.exe
55
# RUN: yaml2obj %t/stmt_seq_macho.o.yaml -o %t/stmt_seq_macho.o
66
# RUN: dsymutil --flat --verify-dwarf=none -oso-prepend-path %t %t/stmt_seq_macho.exe -o %t/stmt_seq_macho.dSYM
7-
# RUN: llvm-dwarfdump --debug-info --debug-line -v %t/stmt_seq_macho.dSYM | sort | FileCheck %s -check-prefix=CHECK_DSYM
7+
# RUN: llvm-dwarfdump --debug-info --debug-line -v %t/stmt_seq_macho.dSYM > %t/stmt_seq_macho.dSYM.txt
8+
# RUN: cat %t/stmt_seq_macho.dSYM.txt | sort | FileCheck %s -check-prefix=CHECK_DSYM
9+
# RUN: cat %t/stmt_seq_macho.dSYM.txt | FileCheck %s -check-prefix=CHECK_NO_INVALID_OFFSET
10+
11+
# CHECK_NO_INVALID_OFFSET-NOT: DW_AT_LLVM_stmt_sequence{{.*}}0xffffffff
12+
813

914
# CHECK_DSYM: DW_AT_LLVM_stmt_sequence [DW_FORM_sec_offset] ([[OFFSET1:(0x[0-9a-f]+)]])
1015
# CHECK_DSYM: DW_AT_LLVM_stmt_sequence [DW_FORM_sec_offset] ([[OFFSET2:(0x[0-9a-f]+)]])

0 commit comments

Comments
 (0)