[llvm] [dsymutil] Fix line table sequence mapping for stmt_sequence attributes (PR #143656)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 10 22:58:21 PDT 2025
https://github.com/alx32 updated https://github.com/llvm/llvm-project/pull/143656
>From 61f0636eca17b87e3ff5f8f19dafc21247640fac Mon Sep 17 00:00:00 2001
From: Alex Borcan <alexborcan at fb.com>
Date: Tue, 10 Jun 2025 22:25:05 -0700
Subject: [PATCH] [dsymutil] Fix line table sequence mapping for stmt_sequence
attributes
---
llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 33 +++++++++++++++++--
.../tools/dsymutil/ARM/stmt-seq-macho.test | 7 +++-
2 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index ae4cc6d85c120..6cd06b6173c29 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -2297,8 +2297,37 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
// Create a map of stmt sequence offsets to original row indices.
DenseMap<uint64_t, unsigned> SeqOffToOrigRow;
- for (const DWARFDebugLine::Sequence &Seq : LT->Sequences)
- SeqOffToOrigRow[Seq.StmtSeqOffset] = Seq.FirstRowIndex;
+ // The DWARF parser's discovery of sequences can be incomplete. To
+ // ensure all DW_AT_LLVM_stmt_sequence attributes can be patched, we
+ // build a map from both the parser's results and a manual
+ // reconstruction.
+ if (!LT->Rows.empty()) {
+ // First, trust the sequences that the DWARF parser did identify.
+ for (const DWARFDebugLine::Sequence &Seq : LT->Sequences)
+ SeqOffToOrigRow.try_emplace(Seq.StmtSeqOffset, Seq.FirstRowIndex);
+
+ // Second, manually find sequence boundaries and match them to the
+ // sorted attributes to handle sequences the parser might have missed.
+ auto StmtAttrs = Unit.getStmtSeqListAttributes();
+ llvm::sort(StmtAttrs,
+ [](const PatchLocation &A, const PatchLocation &B) {
+ return A.get() < B.get();
+ });
+
+ std::vector<size_t> SeqStartRows;
+ SeqStartRows.push_back(0);
+ for (size_t i = 0; i < LT->Rows.size() - 1; ++i)
+ if (LT->Rows[i].EndSequence)
+ SeqStartRows.push_back(i + 1);
+
+ // Correlate the sorted attributes with the reconstructed sequence
+ // starts. This provides a partial mapping if counts are mismatched,
+ // maximizing the number of correctly patched attributes.
+ size_t NumMappings = std::min(StmtAttrs.size(), SeqStartRows.size());
+ for (size_t i = 0; i < NumMappings; ++i) {
+ SeqOffToOrigRow.try_emplace(StmtAttrs[i].get(), SeqStartRows[i]);
+ }
+ }
// Create a map of original row indices to new row indices.
DenseMap<size_t, size_t> OrigRowToNewRow;
diff --git a/llvm/test/tools/dsymutil/ARM/stmt-seq-macho.test b/llvm/test/tools/dsymutil/ARM/stmt-seq-macho.test
index f2fe794e1b484..b6ad216bc0be3 100644
--- a/llvm/test/tools/dsymutil/ARM/stmt-seq-macho.test
+++ b/llvm/test/tools/dsymutil/ARM/stmt-seq-macho.test
@@ -4,7 +4,12 @@
# RUN: yaml2obj %t/stmt_seq_macho.exe.yaml -o %t/stmt_seq_macho.exe
# RUN: yaml2obj %t/stmt_seq_macho.o.yaml -o %t/stmt_seq_macho.o
# RUN: dsymutil --flat --verify-dwarf=none -oso-prepend-path %t %t/stmt_seq_macho.exe -o %t/stmt_seq_macho.dSYM
-# RUN: llvm-dwarfdump --debug-info --debug-line -v %t/stmt_seq_macho.dSYM | sort | FileCheck %s -check-prefix=CHECK_DSYM
+# RUN: llvm-dwarfdump --debug-info --debug-line -v %t/stmt_seq_macho.dSYM > %t/stmt_seq_macho.dSYM.txt
+# RUN: cat %t/stmt_seq_macho.dSYM.txt | sort | FileCheck %s -check-prefix=CHECK_DSYM
+# RUN: cat %t/stmt_seq_macho.dSYM.txt | FileCheck %s -check-prefix=CHECK_NO_INVALID_OFFSET
+
+# CHECK_NO_INVALID_OFFSET-NOT: DW_AT_LLVM_stmt_sequence{{.*}}0xffffffff
+
# CHECK_DSYM: DW_AT_LLVM_stmt_sequence [DW_FORM_sec_offset] ([[OFFSET1:(0x[0-9a-f]+)]])
# CHECK_DSYM: DW_AT_LLVM_stmt_sequence [DW_FORM_sec_offset] ([[OFFSET2:(0x[0-9a-f]+)]])
More information about the llvm-commits
mailing list