-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[DWARFLinker] Adjust DW_AT_LLVM_stmt_sequence for rewritten line tables #128953
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
Conversation
563ab54
to
3840c2e
Compare
@llvm/pr-subscribers-debuginfo Author: None (alx32) ChangesSummary: Background Implementation details:
Patch is 21.13 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/128953.diff 9 Files Affected:
diff --git a/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h
index b1d3f03394f5e..3608e7821bbc4 100644
--- a/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h
+++ b/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h
@@ -122,10 +122,13 @@ class DwarfEmitter {
const AddressRanges &LinkedRanges) = 0;
/// Emit specified \p LineTable into .debug_line table.
- virtual void emitLineTableForUnit(const DWARFDebugLine::LineTable &LineTable,
- const CompileUnit &Unit,
- OffsetsStringPool &DebugStrPool,
- OffsetsStringPool &DebugLineStrPool) = 0;
+ /// The optional parameter RowOffsets, if provided, will be populated with the
+ /// offsets of each line table row in the output .debug_line section.
+ virtual void
+ emitLineTableForUnit(const DWARFDebugLine::LineTable &LineTable,
+ const CompileUnit &Unit, OffsetsStringPool &DebugStrPool,
+ OffsetsStringPool &DebugLineStrPool,
+ std::vector<uint64_t> *RowOffsets = nullptr) = 0;
/// Emit the .debug_pubnames contribution for \p Unit.
virtual void emitPubNamesForUnit(const CompileUnit &Unit) = 0;
diff --git a/llvm/include/llvm/DWARFLinker/Classic/DWARFLinkerCompileUnit.h b/llvm/include/llvm/DWARFLinker/Classic/DWARFLinkerCompileUnit.h
index cdb6f4a4443ab..9fae62a62e442 100644
--- a/llvm/include/llvm/DWARFLinker/Classic/DWARFLinkerCompileUnit.h
+++ b/llvm/include/llvm/DWARFLinker/Classic/DWARFLinkerCompileUnit.h
@@ -57,6 +57,7 @@ struct PatchLocation {
using RngListAttributesTy = SmallVector<PatchLocation>;
using LocListAttributesTy = SmallVector<PatchLocation>;
+using StmtSeqListAttributesTy = SmallVector<PatchLocation>;
/// Stores all information relating to a compile unit, be it in its original
/// instance in the object file to its brand new cloned and generated DIE tree.
@@ -175,6 +176,12 @@ class CompileUnit {
return LocationAttributes;
}
+ // Provide access to the list of DW_AT_LLVM_stmt_sequence attributes that may
+ // need to be patched
+ const StmtSeqListAttributesTy &getStmtSeqListAttributes() const {
+ return StmtSeqListAttributes;
+ }
+
/// Mark every DIE in this unit as kept. This function also
/// marks variables as InDebugMap so that they appear in the
/// reconstructed accelerator tables.
@@ -210,6 +217,10 @@ class CompileUnit {
/// debug_loc section.
void noteLocationAttribute(PatchLocation Attr);
+ // Record that the given DW_AT_LLVM_stmt_sequence attribute may need to be
+ // patched later
+ void noteStmtSeqListAttribute(PatchLocation Attr);
+
/// Add a name accelerator entry for \a Die with \a Name.
void addNamespaceAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name);
@@ -309,6 +320,12 @@ class CompileUnit {
/// location expression.
LocListAttributesTy LocationAttributes;
+ // List of DW_AT_LLVM_stmt_sequence attributes that may need to be patched
+ // after the dwarf linker rewrites the line table. During line table rewrite
+ // the line table format might change, so we have to patch any offsets that
+ // reference its contents.
+ StmtSeqListAttributesTy StmtSeqListAttributes;
+
/// Accelerator entries for the unit, both for the pub*
/// sections and the apple* ones.
/// @{
diff --git a/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h b/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h
index e7a1a3cd838c2..40740a3f2210b 100644
--- a/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h
+++ b/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h
@@ -149,10 +149,13 @@ class DwarfStreamer : public DwarfEmitter {
}
/// Emit .debug_line table entry for specified \p LineTable
- void emitLineTableForUnit(const DWARFDebugLine::LineTable &LineTable,
- const CompileUnit &Unit,
- OffsetsStringPool &DebugStrPool,
- OffsetsStringPool &DebugLineStrPool) override;
+ /// The optional parameter RowOffsets, if provided, will be populated with the
+ /// offsets of each line table row in the output .debug_line section.
+ void
+ emitLineTableForUnit(const DWARFDebugLine::LineTable &LineTable,
+ const CompileUnit &Unit, OffsetsStringPool &DebugStrPool,
+ OffsetsStringPool &DebugLineStrPool,
+ std::vector<uint64_t> *RowOffsets = nullptr) override;
uint64_t getLineSectionSize() const override { return LineSectionSize; }
@@ -266,7 +269,8 @@ class DwarfStreamer : public DwarfEmitter {
const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool,
OffsetsStringPool &DebugLineStrPool);
void emitLineTableRows(const DWARFDebugLine::LineTable &LineTable,
- MCSymbol *LineEndSym, unsigned AddressByteSize);
+ MCSymbol *LineEndSym, unsigned AddressByteSize,
+ std::vector<uint64_t> *RowOffsets = nullptr);
void emitIntOffset(uint64_t Offset, dwarf::DwarfFormat Format,
uint64_t &SectionSize);
void emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index d2b3561ee1c80..db0684e56e0c0 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -1447,6 +1447,18 @@ unsigned DWARFLinker::DIECloner::cloneScalarAttribute(
->sizeOf(Unit.getOrigUnit().getFormParams());
}
+ if (AttrSpec.Attr == dwarf::DW_AT_LLVM_stmt_sequence) {
+ // If needed, we'll patch this sec_offset later with the correct offset.
+ auto Patch = Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
+ dwarf::DW_FORM_sec_offset,
+ DIEInteger(*Val.getAsSectionOffset()));
+
+ // Record this patch location so that it can be fixed up later.
+ Unit.noteStmtSeqListAttribute(Patch);
+
+ return Unit.getOrigUnit().getFormParams().getDwarfOffsetByteSize();
+ }
+
if (LLVM_UNLIKELY(Linker.Options.Update)) {
if (auto OptionalValue = Val.getAsUnsignedConstant())
Value = *OptionalValue;
@@ -2081,29 +2093,43 @@ void DWARFLinker::DIECloner::emitDebugAddrSection(
Emitter->emitDwarfDebugAddrsFooter(Unit, EndLabel);
}
+/// A helper struct to help keep track of the association between the input and
+/// output rows during line table rewriting. This is used to patch
+/// DW_AT_LLVM_stmt_sequence attributes, which reference a particular line table
+/// row.
+struct TrackedRow {
+ DWARFDebugLine::Row Row;
+ size_t OriginalRowIndex;
+ bool isStartSeqInOutput;
+};
+
/// Insert the new line info sequence \p Seq into the current
/// set of already linked line info \p Rows.
-static void insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,
- std::vector<DWARFDebugLine::Row> &Rows) {
+static void insertLineSequence(std::vector<TrackedRow> &Seq,
+ std::vector<TrackedRow> &Rows) {
if (Seq.empty())
return;
- if (!Rows.empty() && Rows.back().Address < Seq.front().Address) {
+ // Mark the first row in Seq to indicate it is the start of a sequence
+ // in the output line table.
+ Seq.front().isStartSeqInOutput = true;
+
+ if (!Rows.empty() && Rows.back().Row.Address < Seq.front().Row.Address) {
llvm::append_range(Rows, Seq);
Seq.clear();
return;
}
- object::SectionedAddress Front = Seq.front().Address;
+ object::SectionedAddress Front = Seq.front().Row.Address;
auto InsertPoint = partition_point(
- Rows, [=](const DWARFDebugLine::Row &O) { return O.Address < Front; });
+ Rows, [=](const TrackedRow &O) { return O.Row.Address < Front; });
// FIXME: this only removes the unneeded end_sequence if the
// sequences have been inserted in order. Using a global sort like
- // described in generateLineTableForUnit() and delaying the end_sequene
+ // described in generateLineTableForUnit() and delaying the end_sequence
// elimination to emitLineTableForUnit() we can get rid of all of them.
- if (InsertPoint != Rows.end() && InsertPoint->Address == Front &&
- InsertPoint->EndSequence) {
+ if (InsertPoint != Rows.end() && InsertPoint->Row.Address == Front &&
+ InsertPoint->Row.EndSequence) {
*InsertPoint = Seq.front();
Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end());
} else {
@@ -2171,14 +2197,24 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
LineTable.Rows.clear();
LineTable.Sequences = LT->Sequences;
+
+ Emitter->emitLineTableForUnit(LineTable, Unit, DebugStrPool,
+ DebugLineStrPool);
} else {
- // This vector is the output line table.
- std::vector<DWARFDebugLine::Row> NewRows;
- NewRows.reserve(LT->Rows.size());
+ // Create TrackedRow objects for all input rows.
+ std::vector<TrackedRow> AllTrackedRows;
+ AllTrackedRows.reserve(LT->Rows.size());
+ for (size_t i = 0; i < LT->Rows.size(); i++)
+ AllTrackedRows.emplace_back(TrackedRow{LT->Rows[i], i, false});
+
+ // This vector is the output line table (still in TrackedRow form).
+ std::vector<TrackedRow> NewRows;
+ NewRows.reserve(AllTrackedRows.size());
// Current sequence of rows being extracted, before being inserted
// in NewRows.
- std::vector<DWARFDebugLine::Row> Seq;
+ std::vector<TrackedRow> Seq;
+ Seq.reserve(AllTrackedRows.size());
const auto &FunctionRanges = Unit.getFunctionRanges();
std::optional<AddressRangeValuePair> CurrRange;
@@ -2194,27 +2230,30 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
// Iterate over the object file line info and extract the sequences
// that correspond to linked functions.
- for (DWARFDebugLine::Row Row : LT->Rows) {
+ for (size_t i = 0; i < AllTrackedRows.size(); i++) {
+ TrackedRow TR = AllTrackedRows[i];
+
// Check whether we stepped out of the range. The range is
- // half-open, but consider accept the end address of the range if
+ // half-open, but consider accepting the end address of the range if
// it is marked as end_sequence in the input (because in that
// case, the relocation offset is accurate and that entry won't
// serve as the start of another function).
- if (!CurrRange || !CurrRange->Range.contains(Row.Address.Address)) {
- // We just stepped out of a known range. Insert a end_sequence
+ if (!CurrRange || !CurrRange->Range.contains(TR.Row.Address.Address)) {
+ // We just stepped out of a known range. Insert an end_sequence
// corresponding to the end of the range.
uint64_t StopAddress =
CurrRange ? CurrRange->Range.end() + CurrRange->Value : -1ULL;
- CurrRange = FunctionRanges.getRangeThatContains(Row.Address.Address);
+ CurrRange =
+ FunctionRanges.getRangeThatContains(TR.Row.Address.Address);
if (StopAddress != -1ULL && !Seq.empty()) {
// Insert end sequence row with the computed end address, but
// the same line as the previous one.
auto NextLine = Seq.back();
- NextLine.Address.Address = StopAddress;
- NextLine.EndSequence = 1;
- NextLine.PrologueEnd = 0;
- NextLine.BasicBlock = 0;
- NextLine.EpilogueBegin = 0;
+ NextLine.Row.Address.Address = StopAddress;
+ NextLine.Row.EndSequence = 1;
+ NextLine.Row.PrologueEnd = 0;
+ NextLine.Row.BasicBlock = 0;
+ NextLine.Row.EpilogueBegin = 0;
Seq.push_back(NextLine);
insertLineSequence(Seq, NewRows);
}
@@ -2224,22 +2263,78 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
}
// Ignore empty sequences.
- if (Row.EndSequence && Seq.empty())
+ if (TR.Row.EndSequence && Seq.empty())
continue;
// Relocate row address and add it to the current sequence.
- Row.Address.Address += CurrRange->Value;
- Seq.emplace_back(Row);
+ TR.Row.Address.Address += CurrRange->Value;
+ Seq.push_back(TR);
- if (Row.EndSequence)
+ if (TR.Row.EndSequence)
insertLineSequence(Seq, NewRows);
}
- LineTable.Rows = std::move(NewRows);
+ // Materialize the tracked rows into final DWARFDebugLine::Row objects.
+ LineTable.Rows.clear();
+ LineTable.Rows.reserve(NewRows.size());
+ for (auto &TR : NewRows)
+ LineTable.Rows.push_back(TR.Row);
+
+ // Use OutputRowOffsets to store the offsets of each line table row in the
+ // output .debug_line section.
+ std::vector<uint64_t> OutputRowOffsets;
+
+ // The unit might not have any DW_AT_LLVM_stmt_sequence attributes, so use
+ // hasStmtSeq to skip the patching logic.
+ bool hasStmtSeq = Unit.getStmtSeqListAttributes().size() > 0;
+ Emitter->emitLineTableForUnit(LineTable, Unit, DebugStrPool,
+ DebugLineStrPool,
+ hasStmtSeq ? &OutputRowOffsets : nullptr);
+
+ if (hasStmtSeq) {
+ assert(OutputRowOffsets.size() == NewRows.size() &&
+ "OutputRowOffsets size mismatch");
+
+ // 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;
+
+ // Create a map of original row indices to new row indices.
+ DenseMap<size_t, size_t> OrigRowToNewRow;
+ for (size_t i = 0; i < NewRows.size(); ++i)
+ OrigRowToNewRow[NewRows[i].OriginalRowIndex] = i;
+
+ // Patch DW_AT_LLVM_stmt_sequence attributes in the compile unit DIE
+ // with the correct offset into the .debug_line section.
+ for (const auto &StmtSeq : Unit.getStmtSeqListAttributes()) {
+ uint64_t OrigStmtSeq = StmtSeq.get();
+ // 1. Get the original row index from the stmt list offset.
+ auto OrigRowIter = SeqOffToOrigRow.find(OrigStmtSeq);
+ assert(OrigRowIter != SeqOffToOrigRow.end() &&
+ "Stmt list offset not found in sequence offsets map");
+ size_t OrigRowIndex = OrigRowIter->second;
+
+ // 2. Get the new row index from the original row index.
+ auto NewRowIter = OrigRowToNewRow.find(OrigRowIndex);
+ if (NewRowIter == OrigRowToNewRow.end()) {
+ // If the original row index is not found in the map, update the
+ // stmt_sequence attribute to the 'invalid offset' magic value.
+ StmtSeq.set(UINT64_MAX);
+ continue;
+ }
+
+ // 3. Get the offset of the new row in the output .debug_line section.
+ assert(NewRowIter->second < OutputRowOffsets.size() &&
+ "New row index out of bounds");
+ uint64_t NewStmtSeqOffset = OutputRowOffsets[NewRowIter->second];
+
+ // 4. Patch the stmt_list attribute with the new offset.
+ StmtSeq.set(NewStmtSeqOffset);
+ }
+ }
}
- Emitter->emitLineTableForUnit(LineTable, Unit, DebugStrPool,
- DebugLineStrPool);
} else
Linker.reportWarning("Cann't load line table.", ObjFile);
}
diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinkerCompileUnit.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinkerCompileUnit.cpp
index 1eb3a70a55135..66bf158e60f1d 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinkerCompileUnit.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinkerCompileUnit.cpp
@@ -185,6 +185,10 @@ void CompileUnit::noteLocationAttribute(PatchLocation Attr) {
LocationAttributes.emplace_back(Attr);
}
+void CompileUnit::noteStmtSeqListAttribute(PatchLocation Attr) {
+ StmtSeqListAttributes.emplace_back(Attr);
+}
+
void CompileUnit::addNamespaceAccelerator(const DIE *Die,
DwarfStringPoolEntryRef Name) {
Namespaces.emplace_back(Name, Die);
diff --git a/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp b/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp
index 947db9cbcd92d..3bfbdd36ad150 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp
@@ -809,7 +809,8 @@ void DwarfStreamer::emitDwarfDebugLocListsTableFragment(
void DwarfStreamer::emitLineTableForUnit(
const DWARFDebugLine::LineTable &LineTable, const CompileUnit &Unit,
- OffsetsStringPool &DebugStrPool, OffsetsStringPool &DebugLineStrPool) {
+ OffsetsStringPool &DebugStrPool, OffsetsStringPool &DebugLineStrPool,
+ std::vector<uint64_t> *RowOffsets) {
// Switch to the section where the table will be emitted into.
MS->switchSection(MC->getObjectFileInfo()->getDwarfLineSection());
@@ -830,7 +831,7 @@ void DwarfStreamer::emitLineTableForUnit(
// Emit rows.
emitLineTableRows(LineTable, LineEndSym,
- Unit.getOrigUnit().getAddressByteSize());
+ Unit.getOrigUnit().getAddressByteSize(), RowOffsets);
}
void DwarfStreamer::emitLineTablePrologue(const DWARFDebugLine::Prologue &P,
@@ -1036,7 +1037,7 @@ void DwarfStreamer::emitLineTableProloguePayload(
void DwarfStreamer::emitLineTableRows(
const DWARFDebugLine::LineTable &LineTable, MCSymbol *LineEndSym,
- unsigned AddressByteSize) {
+ unsigned AddressByteSize, std::vector<uint64_t> *RowOffsets) {
MCDwarfLineTableParams Params;
Params.DWARF2LineOpcodeBase = LineTable.Prologue.OpcodeBase;
@@ -1068,6 +1069,11 @@ void DwarfStreamer::emitLineTableRows(
unsigned RowsSinceLastSequence = 0;
for (const DWARFDebugLine::Row &Row : LineTable.Rows) {
+ // If we're tracking row offsets, record the current section size as the
+ // offset of this row.
+ if (RowOffsets)
+ RowOffsets->push_back(LineSectionSize);
+
int64_t AddressDelta;
if (Address == -1ULL) {
MS->emitIntValue(dwarf::DW_LNS_extended_op, 1);
diff --git a/llvm/test/tools/dsymutil/ARM/stmt-seq-macho.test b/llvm/test/tools/dsymutil/ARM/stmt-seq-macho.test
new file mode 100644
index 0000000000000..b5093ba767894
--- /dev/null
+++ b/llvm/test/tools/dsymutil/ARM/stmt-seq-macho.test
@@ -0,0 +1,74 @@
+RUN: dsymutil --flat -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/stmt_seq/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
+
+# 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]+)]])
+# CHECK_DSYM: DW_AT_LLVM_stmt_sequence [DW_FORM_sec_offset] ([[OFFSET3:(0x[0-9a-f]+)]])
+# CHECK_DSYM: DW_AT_LLVM_stmt_sequence [DW_FORM_sec_offset] ([[OFFSET4:(0x[0-9a-f]+)]])
+
+# CHECK_DSYM: [[OFFSET1]]: 00 DW_LNE_set_address
+# CHECK_DSYM: [[OFFSET2]]: 00 DW_LNE_set_address
+# CHECK_DSYM: [[OFFSET3]]: 00 DW_LNE_set_address
+# CHECK_DSYM: [[OFFSET4]]: 00 DW_LNE_set_address
+
+
+######## Generate stmt_seq_macho.exe & stmt_seq_macho.o via script: ##########
+# ------------------------------------------------------------------------------
+#!/bin/bash
+TOOLCHAIN=/path/to/llvm/bin
+
+# ------------------------------------------------------------------------------
+# Create the stmt_seq_macho.cpp source file
+# ------------------------------------------------------------------------------
+cat > stmt_seq_macho.cpp << 'EOF'
+#define ATTRIB extern "C" __attribute__((noinline))
+
+ATTRIB int function3_copy1(int a) {
+ int b = a + 3;
+ return b + 1;
+}
+
+ATTRIB int function2_copy1(int a) {
+ return a - 22;
+}
+
+ATTRIB int function3_copy2(int a) {
+ int b = a + 3;
+ return b + 1;
+}
+
+ATTRIB int function2_copy2(int a) {
+ int result = a - 22;
+ return result;
+}
+
+int main() {
+ int sum = 0;
+ sum += function2_copy2(3);
+ sum += function3...
[truncated]
|
3840c2e
to
c3b0163
Compare
This patch introduces support for the `DW_AT_LLVM_stmt_sequence` attribute in the GSYM DWARF transformer. With this change, the DWARF GSYM creation process can now accurately associate debug information with the correct functions, even when multiple functions have been merged together. The `macho-gsym-merged-callsites-dsym.yaml` test data is regenerated to include the fixes in the DWARF linker (#128953) and the test is updated to check that debug data is correctly associated for merged functions.
This patch introduces support for the `DW_AT_LLVM_stmt_sequence` attribute in the GSYM DWARF transformer. With this change, the DWARF GSYM creation process can now accurately associate debug information with the correct functions, even when multiple functions have been merged together. The `macho-gsym-merged-callsites-dsym.yaml` test data is regenerated to include the fixes in the DWARF linker (llvm/llvm-project#128953) and the test is updated to check that debug data is correctly associated for merged functions.
@JDevlieghere - I see you are the code owner for this area. Do you have time to take a look at this ? Happy to explain context or if anything is unclear. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When reading the patch I kept thinking "can we pre-compute any of these mappings" but I convinced myself that this is the most efficient approach as we're limiting most lookups to offsets belonging to DIEs that are actually kept. LGTM modulo nits.
deffcc0
to
b8491fa
Compare
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/81/builds/5197 Here is the relevant piece of the build log for the reference
|
…es (llvm#128953) **Summary:** This update adds handling for `DW_AT_LLVM_stmt_sequence` attributes in the DWARF linker. These attributes point to rows in the line table, which gets rewritten during linking. Since the row positions change, the offsets in these attributes need to be updated to match the new layout in the output `.debug_line` section. The changes add new data structures and tweak existing functions to track and fix these attributes. **Background** In llvm#110192 we added support to clang to generate the `DW_AT_LLVM_stmt_sequence` attribute for `DW_TAG_subprogram`'s. Corresponding RFC: [New DWARF Attribute for Symbolication of Merged Functions](https://discourse.llvm.org/t/rfc-new-dwarf-attribute-for-symbolication-of-merged-functions/79434). This attribute holds a label pointing to the offset in the line table where the function's line entries begin. **Implementation details:** Here’s what’s changed in the code: - **New Tracking in `CompileUnit`:** A `StmtSeqListAttributes` vector is added to the `CompileUnit` class. It stores the locations where `DW_AT_LLVM_stmt_sequence` attributes need to be patched, recorded when cloning DIEs (debug info entries). - **Updated `emitLineTableForUnit` Function:** This function now has an optional `RowOffsets` parameter. It collects the byte offsets of each row in the output line table. We only need to use this functionality if `DW_AT_LLVM_stmt_sequence` attributes are present in the unit. - **Row Tracking with `TrackedRow`:** A `TrackedRow` struct keeps track of each input row’s original index and whether it starts a sequence in the output table. This links old rows to their new positions in the rewritten line table. Several implementations were considered and prototyped here, but so far this has proven the simplest and cleanest approach. - **Patching Step:** After the line table is written, the linker uses the data in `TrackedRow`'s objects and `RowOffsets` array to update the `DW_AT_LLVM_stmt_sequence` attributes with the correct offsets.
This patch introduces support for the `DW_AT_LLVM_stmt_sequence` attribute in the GSYM DWARF transformer. With this change, the DWARF GSYM creation process can now accurately associate debug information with the correct functions, even when multiple functions have been merged together. The `macho-gsym-merged-callsites-dsym.yaml` test data is regenerated to include the fixes in the DWARF linker (llvm#128953) and the test is updated to check that debug data is correctly associated for merged functions.
Summary:
This update adds handling for
DW_AT_LLVM_stmt_sequence
attributes in the DWARF linker. These attributes point to rows in the line table, which gets rewritten during linking. Since the row positions change, the offsets in these attributes need to be updated to match the new layout in the output.debug_line
section. The changes add new data structures and tweak existing functions to track and fix these attributes.Background
In #110192 we added support to clang to generate the
DW_AT_LLVM_stmt_sequence
attribute forDW_TAG_subprogram
's. Corresponding RFC: New DWARF Attribute for Symbolication of Merged Functions. This attribute holds a label pointing to the offset in the line table where the function's line entries begin.Implementation details:
Here’s what’s changed in the code:
CompileUnit
: AStmtSeqListAttributes
vector is added to theCompileUnit
class. It stores the locations whereDW_AT_LLVM_stmt_sequence
attributes need to be patched, recorded when cloning DIEs (debug info entries).emitLineTableForUnit
Function: This function now has an optionalRowOffsets
parameter. It collects the byte offsets of each row in the output line table. We only need to use this functionality ifDW_AT_LLVM_stmt_sequence
attributes are present in the unit.TrackedRow
: ATrackedRow
struct keeps track of each input row’s original index and whether it starts a sequence in the output table. This links old rows to their new positions in the rewritten line table. Several implementations were considered and prototyped here, but so far this has proven the simplest and cleanest approach.TrackedRow
's objects andRowOffsets
array to update theDW_AT_LLVM_stmt_sequence
attributes with the correct offsets.