aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCStreamer.cpp
diff options
context:
space:
mode:
authoralx32 <103613512+alx32@users.noreply.github.com>2024-11-13 18:51:34 -0800
committerGitHub <noreply@github.com>2024-11-13 18:51:34 -0800
commitf407dff50cdcbcfee9dd92397d3792627c3ac708 (patch)
tree068503f8f0ddabfe705a3009204b5aad780f69f2 /llvm/lib/MC/MCStreamer.cpp
parente9aee4fd80874f80556456f64c303ffb957bd614 (diff)
downloadllvm-f407dff50cdcbcfee9dd92397d3792627c3ac708.zip
llvm-f407dff50cdcbcfee9dd92397d3792627c3ac708.tar.gz
llvm-f407dff50cdcbcfee9dd92397d3792627c3ac708.tar.bz2
[DebugInfo][DWARF] Emit Per-Function Line Table Offsets and End Sequences (#110192)
**Summary** This patch introduces a new compiler option `-mllvm -emit-func-debug-line-table-offsets` that enables the emission of per-function line table offsets and end sequences in DWARF debug information. This enhancement allows tools and debuggers to accurately attribute line number information to their corresponding functions, even in scenarios where functions are merged or share the same address space due to optimizations like Identical Code Folding (ICF) in the linker. **Background** RFC: [New DWARF Attribute for Symbolication of Merged Functions](https://discourse.llvm.org/t/rfc-new-dwarf-attribute-for-symbolication-of-merged-functions/79434) Previous similar PR: [#93137](https://github.com/llvm/llvm-project/pull/93137) – This PR was very similar to the current one but at the time, the assembler had no support for emitting labels within the line table. That support was added in PR [#99710](https://github.com/llvm/llvm-project/pull/99710) - and in this PR we use some of the support added in the assembler PR. In the current implementation, Clang generates line information in the `debug_line` section without directly associating line entries with their originating `DW_TAG_subprogram` DIEs. This can lead to issues when post-compilation optimizations merge functions, resulting in overlapping address ranges and ambiguous line information. For example, when functions are merged by ICF in LLD, multiple functions may end up sharing the same address range. Without explicit linkage between functions and their line entries, tools cannot accurately attribute line information to the correct function, adversely affecting debugging and call stack resolution. **Implementation Details** To address the above issue, the patch makes the following key changes: **`DW_AT_LLVM_stmt_sequence` Attribute**: Introduces a new LLVM-specific attribute `DW_AT_LLVM_stmt_sequence` to each `DW_TAG_subprogram` DIE. This attribute holds a label pointing to the offset in the line table where the function's line entries begin. **End-of-Sequence Markers**: Emits an explicit DW_LNE_end_sequence after each function's line entries in the line table. This marks the end of the line information for that function, ensuring that line entries are correctly delimited. **Assembler and Streamer Modifications**: Modifies the MCStreamer and related classes to support emitting the necessary labels and tracking the current function's line entries. A new flag GenerateFuncLineTableOffsets is added to control this behavior. **Compiler Option**: Introduces the `-mllvm -emit-func-debug-line-table-offsets` option to enable this functionality, allowing users to opt-in as needed.
Diffstat (limited to 'llvm/lib/MC/MCStreamer.cpp')
-rw-r--r--llvm/lib/MC/MCStreamer.cpp14
1 files changed, 14 insertions, 0 deletions
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index cfef318..df1b160 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -483,6 +483,20 @@ void MCStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
Frame.End = (MCSymbol *)1;
}
+MCSymbol *MCStreamer::emitLineTableLabel() {
+ // Create a label and insert it into the line table and return this label
+ const MCDwarfLoc &DwarfLoc = getContext().getCurrentDwarfLoc();
+
+ MCSymbol *LineStreamLabel = getContext().createTempSymbol();
+ MCDwarfLineEntry LabelLineEntry(nullptr, DwarfLoc, LineStreamLabel);
+ getContext()
+ .getMCDwarfLineTable(getContext().getDwarfCompileUnitID())
+ .getMCLineSections()
+ .addLineEntry(LabelLineEntry, getCurrentSectionOnly() /*Section*/);
+
+ return LineStreamLabel;
+}
+
MCSymbol *MCStreamer::emitCFILabel() {
// Return a dummy non-null value so that label fields appear filled in when
// generating textual assembly.