1 | //===- llvm/CodeGen/DwarfDebug.cpp - Dwarf Debug Framework ----------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file contains support for writing dwarf debug info into asm files. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "DwarfDebug.h" |
14 | #include "ByteStreamer.h" |
15 | #include "DIEHash.h" |
16 | #include "DwarfCompileUnit.h" |
17 | #include "DwarfExpression.h" |
18 | #include "DwarfUnit.h" |
19 | #include "llvm/ADT/APInt.h" |
20 | #include "llvm/ADT/Statistic.h" |
21 | #include "llvm/ADT/StringExtras.h" |
22 | #include "llvm/ADT/Twine.h" |
23 | #include "llvm/CodeGen/AsmPrinter.h" |
24 | #include "llvm/CodeGen/DIE.h" |
25 | #include "llvm/CodeGen/LexicalScopes.h" |
26 | #include "llvm/CodeGen/MachineBasicBlock.h" |
27 | #include "llvm/CodeGen/MachineFunction.h" |
28 | #include "llvm/CodeGen/MachineModuleInfo.h" |
29 | #include "llvm/CodeGen/MachineOperand.h" |
30 | #include "llvm/CodeGen/TargetInstrInfo.h" |
31 | #include "llvm/CodeGen/TargetLowering.h" |
32 | #include "llvm/CodeGen/TargetRegisterInfo.h" |
33 | #include "llvm/CodeGen/TargetSubtargetInfo.h" |
34 | #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" |
35 | #include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h" |
36 | #include "llvm/IR/Constants.h" |
37 | #include "llvm/IR/DebugInfoMetadata.h" |
38 | #include "llvm/IR/Function.h" |
39 | #include "llvm/IR/GlobalVariable.h" |
40 | #include "llvm/IR/Module.h" |
41 | #include "llvm/MC/MCAsmInfo.h" |
42 | #include "llvm/MC/MCContext.h" |
43 | #include "llvm/MC/MCSection.h" |
44 | #include "llvm/MC/MCStreamer.h" |
45 | #include "llvm/MC/MCSymbol.h" |
46 | #include "llvm/MC/MCTargetOptions.h" |
47 | #include "llvm/MC/MachineLocation.h" |
48 | #include "llvm/Support/Casting.h" |
49 | #include "llvm/Support/CommandLine.h" |
50 | #include "llvm/Support/Debug.h" |
51 | #include "llvm/Support/ErrorHandling.h" |
52 | #include "llvm/Support/MD5.h" |
53 | #include "llvm/Support/raw_ostream.h" |
54 | #include "llvm/Target/TargetLoweringObjectFile.h" |
55 | #include "llvm/Target/TargetMachine.h" |
56 | #include "llvm/TargetParser/Triple.h" |
57 | #include <cstddef> |
58 | #include <iterator> |
59 | #include <optional> |
60 | #include <string> |
61 | |
62 | using namespace llvm; |
63 | |
64 | #define DEBUG_TYPE "dwarfdebug" |
65 | |
66 | STATISTIC(NumCSParams, "Number of dbg call site params created" ); |
67 | |
68 | static cl::opt<bool> UseDwarfRangesBaseAddressSpecifier( |
69 | "use-dwarf-ranges-base-address-specifier" , cl::Hidden, |
70 | cl::desc("Use base address specifiers in debug_ranges" ), cl::init(Val: false)); |
71 | |
72 | static cl::opt<bool> GenerateARangeSection("generate-arange-section" , |
73 | cl::Hidden, |
74 | cl::desc("Generate dwarf aranges" ), |
75 | cl::init(Val: false)); |
76 | |
77 | static cl::opt<bool> |
78 | GenerateDwarfTypeUnits("generate-type-units" , cl::Hidden, |
79 | cl::desc("Generate DWARF4 type units." ), |
80 | cl::init(Val: false)); |
81 | |
82 | static cl::opt<bool> SplitDwarfCrossCuReferences( |
83 | "split-dwarf-cross-cu-references" , cl::Hidden, |
84 | cl::desc("Enable cross-cu references in DWO files" ), cl::init(Val: false)); |
85 | |
86 | enum DefaultOnOff { Default, Enable, Disable }; |
87 | |
88 | static cl::opt<DefaultOnOff> UnknownLocations( |
89 | "use-unknown-locations" , cl::Hidden, |
90 | cl::desc("Make an absence of debug location information explicit." ), |
91 | cl::values(clEnumVal(Default, "At top of block or after label" ), |
92 | clEnumVal(Enable, "In all cases" ), clEnumVal(Disable, "Never" )), |
93 | cl::init(Val: Default)); |
94 | |
95 | static cl::opt<AccelTableKind> AccelTables( |
96 | "accel-tables" , cl::Hidden, cl::desc("Output dwarf accelerator tables." ), |
97 | cl::values(clEnumValN(AccelTableKind::Default, "Default" , |
98 | "Default for platform" ), |
99 | clEnumValN(AccelTableKind::None, "Disable" , "Disabled." ), |
100 | clEnumValN(AccelTableKind::Apple, "Apple" , "Apple" ), |
101 | clEnumValN(AccelTableKind::Dwarf, "Dwarf" , "DWARF" )), |
102 | cl::init(Val: AccelTableKind::Default)); |
103 | |
104 | static cl::opt<DefaultOnOff> |
105 | DwarfInlinedStrings("dwarf-inlined-strings" , cl::Hidden, |
106 | cl::desc("Use inlined strings rather than string section." ), |
107 | cl::values(clEnumVal(Default, "Default for platform" ), |
108 | clEnumVal(Enable, "Enabled" ), |
109 | clEnumVal(Disable, "Disabled" )), |
110 | cl::init(Val: Default)); |
111 | |
112 | static cl::opt<bool> |
113 | NoDwarfRangesSection("no-dwarf-ranges-section" , cl::Hidden, |
114 | cl::desc("Disable emission .debug_ranges section." ), |
115 | cl::init(Val: false)); |
116 | |
117 | static cl::opt<DefaultOnOff> DwarfSectionsAsReferences( |
118 | "dwarf-sections-as-references" , cl::Hidden, |
119 | cl::desc("Use sections+offset as references rather than labels." ), |
120 | cl::values(clEnumVal(Default, "Default for platform" ), |
121 | clEnumVal(Enable, "Enabled" ), clEnumVal(Disable, "Disabled" )), |
122 | cl::init(Val: Default)); |
123 | |
124 | static cl::opt<bool> |
125 | UseGNUDebugMacro("use-gnu-debug-macro" , cl::Hidden, |
126 | cl::desc("Emit the GNU .debug_macro format with DWARF <5" ), |
127 | cl::init(Val: false)); |
128 | |
129 | static cl::opt<DefaultOnOff> DwarfOpConvert( |
130 | "dwarf-op-convert" , cl::Hidden, |
131 | cl::desc("Enable use of the DWARFv5 DW_OP_convert operator" ), |
132 | cl::values(clEnumVal(Default, "Default for platform" ), |
133 | clEnumVal(Enable, "Enabled" ), clEnumVal(Disable, "Disabled" )), |
134 | cl::init(Val: Default)); |
135 | |
136 | enum LinkageNameOption { |
137 | DefaultLinkageNames, |
138 | AllLinkageNames, |
139 | AbstractLinkageNames |
140 | }; |
141 | |
142 | static cl::opt<LinkageNameOption> |
143 | DwarfLinkageNames("dwarf-linkage-names" , cl::Hidden, |
144 | cl::desc("Which DWARF linkage-name attributes to emit." ), |
145 | cl::values(clEnumValN(DefaultLinkageNames, "Default" , |
146 | "Default for platform" ), |
147 | clEnumValN(AllLinkageNames, "All" , "All" ), |
148 | clEnumValN(AbstractLinkageNames, "Abstract" , |
149 | "Abstract subprograms" )), |
150 | cl::init(Val: DefaultLinkageNames)); |
151 | |
152 | static cl::opt<DwarfDebug::MinimizeAddrInV5> MinimizeAddrInV5Option( |
153 | "minimize-addr-in-v5" , cl::Hidden, |
154 | cl::desc("Always use DW_AT_ranges in DWARFv5 whenever it could allow more " |
155 | "address pool entry sharing to reduce relocations/object size" ), |
156 | cl::values(clEnumValN(DwarfDebug::MinimizeAddrInV5::Default, "Default" , |
157 | "Default address minimization strategy" ), |
158 | clEnumValN(DwarfDebug::MinimizeAddrInV5::Ranges, "Ranges" , |
159 | "Use rnglists for contiguous ranges if that allows " |
160 | "using a pre-existing base address" ), |
161 | clEnumValN(DwarfDebug::MinimizeAddrInV5::Expressions, |
162 | "Expressions" , |
163 | "Use exprloc addrx+offset expressions for any " |
164 | "address with a prior base address" ), |
165 | clEnumValN(DwarfDebug::MinimizeAddrInV5::Form, "Form" , |
166 | "Use addrx+offset extension form for any address " |
167 | "with a prior base address" ), |
168 | clEnumValN(DwarfDebug::MinimizeAddrInV5::Disabled, "Disabled" , |
169 | "Stuff" )), |
170 | cl::init(Val: DwarfDebug::MinimizeAddrInV5::Default)); |
171 | |
172 | /// Set to false to ignore Key Instructions metadata. |
173 | static cl::opt<bool> KeyInstructionsAreStmts( |
174 | "dwarf-use-key-instructions" , cl::Hidden, cl::init(Val: true), |
175 | cl::desc("Set to false to ignore Key Instructions metadata" )); |
176 | |
177 | static constexpr unsigned ULEB128PadSize = 4; |
178 | |
179 | void DebugLocDwarfExpression::emitOp(uint8_t Op, const char *) { |
180 | getActiveStreamer().emitInt8( |
181 | Byte: Op, Comment: Comment ? Twine(Comment) + " " + dwarf::OperationEncodingString(Encoding: Op) |
182 | : dwarf::OperationEncodingString(Encoding: Op)); |
183 | } |
184 | |
185 | void DebugLocDwarfExpression::emitSigned(int64_t Value) { |
186 | getActiveStreamer().emitSLEB128(DWord: Value, Comment: Twine(Value)); |
187 | } |
188 | |
189 | void DebugLocDwarfExpression::emitUnsigned(uint64_t Value) { |
190 | getActiveStreamer().emitULEB128(DWord: Value, Comment: Twine(Value)); |
191 | } |
192 | |
193 | void DebugLocDwarfExpression::emitData1(uint8_t Value) { |
194 | getActiveStreamer().emitInt8(Byte: Value, Comment: Twine(Value)); |
195 | } |
196 | |
197 | void DebugLocDwarfExpression::emitBaseTypeRef(uint64_t Idx) { |
198 | assert(Idx < (1ULL << (ULEB128PadSize * 7)) && "Idx wont fit" ); |
199 | getActiveStreamer().emitULEB128(DWord: Idx, Comment: Twine(Idx), PadTo: ULEB128PadSize); |
200 | } |
201 | |
202 | bool DebugLocDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI, |
203 | llvm::Register MachineReg) { |
204 | // This information is not available while emitting .debug_loc entries. |
205 | return false; |
206 | } |
207 | |
208 | void DebugLocDwarfExpression::enableTemporaryBuffer() { |
209 | assert(!IsBuffering && "Already buffering?" ); |
210 | if (!TmpBuf) |
211 | TmpBuf = std::make_unique<TempBuffer>(args: OutBS.GenerateComments); |
212 | IsBuffering = true; |
213 | } |
214 | |
215 | void DebugLocDwarfExpression::disableTemporaryBuffer() { IsBuffering = false; } |
216 | |
217 | unsigned DebugLocDwarfExpression::getTemporaryBufferSize() { |
218 | return TmpBuf ? TmpBuf->Bytes.size() : 0; |
219 | } |
220 | |
221 | void DebugLocDwarfExpression::commitTemporaryBuffer() { |
222 | if (!TmpBuf) |
223 | return; |
224 | for (auto Byte : enumerate(First&: TmpBuf->Bytes)) { |
225 | const char * = (Byte.index() < TmpBuf->Comments.size()) |
226 | ? TmpBuf->Comments[Byte.index()].c_str() |
227 | : "" ; |
228 | OutBS.emitInt8(Byte: Byte.value(), Comment); |
229 | } |
230 | TmpBuf->Bytes.clear(); |
231 | TmpBuf->Comments.clear(); |
232 | } |
233 | |
234 | const DIType *DbgVariable::getType() const { |
235 | return getVariable()->getType(); |
236 | } |
237 | |
238 | /// Get .debug_loc entry for the instruction range starting at MI. |
239 | static DbgValueLoc getDebugLocValue(const MachineInstr *MI) { |
240 | const DIExpression *Expr = MI->getDebugExpression(); |
241 | auto SingleLocExprOpt = DIExpression::convertToNonVariadicExpression(Expr); |
242 | const bool IsVariadic = !SingleLocExprOpt; |
243 | // If we have a variadic debug value instruction that is equivalent to a |
244 | // non-variadic instruction, then convert it to non-variadic form here. |
245 | if (!IsVariadic && !MI->isNonListDebugValue()) { |
246 | assert(MI->getNumDebugOperands() == 1 && |
247 | "Mismatched DIExpression and debug operands for debug instruction." ); |
248 | Expr = *SingleLocExprOpt; |
249 | } |
250 | assert(MI->getNumOperands() >= 3); |
251 | SmallVector<DbgValueLocEntry, 4> DbgValueLocEntries; |
252 | for (const MachineOperand &Op : MI->debug_operands()) { |
253 | if (Op.isReg()) { |
254 | MachineLocation MLoc(Op.getReg(), |
255 | MI->isNonListDebugValue() && MI->isDebugOffsetImm()); |
256 | DbgValueLocEntries.push_back(Elt: DbgValueLocEntry(MLoc)); |
257 | } else if (Op.isTargetIndex()) { |
258 | DbgValueLocEntries.push_back( |
259 | Elt: DbgValueLocEntry(TargetIndexLocation(Op.getIndex(), Op.getOffset()))); |
260 | } else if (Op.isImm()) |
261 | DbgValueLocEntries.push_back(Elt: DbgValueLocEntry(Op.getImm())); |
262 | else if (Op.isFPImm()) |
263 | DbgValueLocEntries.push_back(Elt: DbgValueLocEntry(Op.getFPImm())); |
264 | else if (Op.isCImm()) |
265 | DbgValueLocEntries.push_back(Elt: DbgValueLocEntry(Op.getCImm())); |
266 | else |
267 | llvm_unreachable("Unexpected debug operand in DBG_VALUE* instruction!" ); |
268 | } |
269 | return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic); |
270 | } |
271 | |
272 | static uint64_t getFragmentOffsetInBits(const DIExpression &Expr) { |
273 | std::optional<DIExpression::FragmentInfo> Fragment = Expr.getFragmentInfo(); |
274 | return Fragment ? Fragment->OffsetInBits : 0; |
275 | } |
276 | |
277 | bool llvm::operator<(const FrameIndexExpr &LHS, const FrameIndexExpr &RHS) { |
278 | return getFragmentOffsetInBits(Expr: *LHS.Expr) < |
279 | getFragmentOffsetInBits(Expr: *RHS.Expr); |
280 | } |
281 | |
282 | bool llvm::operator<(const EntryValueInfo &LHS, const EntryValueInfo &RHS) { |
283 | return getFragmentOffsetInBits(Expr: LHS.Expr) < getFragmentOffsetInBits(Expr: RHS.Expr); |
284 | } |
285 | |
286 | Loc::Single::Single(DbgValueLoc ValueLoc) |
287 | : ValueLoc(std::make_unique<DbgValueLoc>(args&: ValueLoc)), |
288 | Expr(ValueLoc.getExpression()) { |
289 | if (!Expr->getNumElements()) |
290 | Expr = nullptr; |
291 | } |
292 | |
293 | Loc::Single::Single(const MachineInstr *DbgValue) |
294 | : Single(getDebugLocValue(MI: DbgValue)) {} |
295 | |
296 | const std::set<FrameIndexExpr> &Loc::MMI::getFrameIndexExprs() const { |
297 | return FrameIndexExprs; |
298 | } |
299 | |
300 | void Loc::MMI::addFrameIndexExpr(const DIExpression *Expr, int FI) { |
301 | FrameIndexExprs.insert(x: {.FI: FI, .Expr: Expr}); |
302 | assert((FrameIndexExprs.size() == 1 || |
303 | llvm::all_of(FrameIndexExprs, |
304 | [](const FrameIndexExpr &FIE) { |
305 | return FIE.Expr && FIE.Expr->isFragment(); |
306 | })) && |
307 | "conflicting locations for variable" ); |
308 | } |
309 | |
310 | static AccelTableKind computeAccelTableKind(unsigned DwarfVersion, |
311 | bool GenerateTypeUnits, |
312 | DebuggerKind Tuning, |
313 | const Triple &TT) { |
314 | // Honor an explicit request. |
315 | if (AccelTables != AccelTableKind::Default) |
316 | return AccelTables; |
317 | |
318 | // Generating DWARF5 acceleration table. |
319 | // Currently Split dwarf and non ELF format is not supported. |
320 | if (GenerateTypeUnits && (DwarfVersion < 5 || !TT.isOSBinFormatELF())) |
321 | return AccelTableKind::None; |
322 | |
323 | // Accelerator tables get emitted if targetting DWARF v5 or LLDB. DWARF v5 |
324 | // always implies debug_names. For lower standard versions we use apple |
325 | // accelerator tables on apple platforms and debug_names elsewhere. |
326 | if (DwarfVersion >= 5) |
327 | return AccelTableKind::Dwarf; |
328 | if (Tuning == DebuggerKind::LLDB) |
329 | return TT.isOSBinFormatMachO() ? AccelTableKind::Apple |
330 | : AccelTableKind::Dwarf; |
331 | return AccelTableKind::None; |
332 | } |
333 | |
334 | DwarfDebug::DwarfDebug(AsmPrinter *A) |
335 | : DebugHandlerBase(A), DebugLocs(A->OutStreamer->isVerboseAsm()), |
336 | InfoHolder(A, "info_string" , DIEValueAllocator), |
337 | SkeletonHolder(A, "skel_string" , DIEValueAllocator), |
338 | IsDarwin(A->TM.getTargetTriple().isOSDarwin()) { |
339 | const Triple &TT = Asm->TM.getTargetTriple(); |
340 | |
341 | // Make sure we know our "debugger tuning". The target option takes |
342 | // precedence; fall back to triple-based defaults. |
343 | if (Asm->TM.Options.DebuggerTuning != DebuggerKind::Default) |
344 | DebuggerTuning = Asm->TM.Options.DebuggerTuning; |
345 | else if (IsDarwin) |
346 | DebuggerTuning = DebuggerKind::LLDB; |
347 | else if (TT.isPS()) |
348 | DebuggerTuning = DebuggerKind::SCE; |
349 | else if (TT.isOSAIX()) |
350 | DebuggerTuning = DebuggerKind::DBX; |
351 | else |
352 | DebuggerTuning = DebuggerKind::GDB; |
353 | |
354 | if (DwarfInlinedStrings == Default) |
355 | UseInlineStrings = TT.isNVPTX() || tuneForDBX(); |
356 | else |
357 | UseInlineStrings = DwarfInlinedStrings == Enable; |
358 | |
359 | // Always emit .debug_aranges for SCE tuning. |
360 | UseARangesSection = GenerateARangeSection || tuneForSCE(); |
361 | |
362 | HasAppleExtensionAttributes = tuneForLLDB(); |
363 | |
364 | // Handle split DWARF. |
365 | HasSplitDwarf = !Asm->TM.Options.MCOptions.SplitDwarfFile.empty(); |
366 | |
367 | // SCE defaults to linkage names only for abstract subprograms. |
368 | if (DwarfLinkageNames == DefaultLinkageNames) |
369 | UseAllLinkageNames = !tuneForSCE(); |
370 | else |
371 | UseAllLinkageNames = DwarfLinkageNames == AllLinkageNames; |
372 | |
373 | unsigned DwarfVersionNumber = Asm->TM.Options.MCOptions.DwarfVersion; |
374 | unsigned DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber |
375 | : MMI->getModule()->getDwarfVersion(); |
376 | // Use dwarf 4 by default if nothing is requested. For NVPTX, use dwarf 2. |
377 | DwarfVersion = |
378 | TT.isNVPTX() ? 2 : (DwarfVersion ? DwarfVersion : dwarf::DWARF_VERSION); |
379 | |
380 | bool Dwarf64 = DwarfVersion >= 3 && // DWARF64 was introduced in DWARFv3. |
381 | TT.isArch64Bit(); // DWARF64 requires 64-bit relocations. |
382 | |
383 | // Support DWARF64 |
384 | // 1: For ELF when requested. |
385 | // 2: For XCOFF64: the AIX assembler will fill in debug section lengths |
386 | // according to the DWARF64 format for 64-bit assembly, so we must use |
387 | // DWARF64 in the compiler too for 64-bit mode. |
388 | Dwarf64 &= |
389 | ((Asm->TM.Options.MCOptions.Dwarf64 || MMI->getModule()->isDwarf64()) && |
390 | TT.isOSBinFormatELF()) || |
391 | TT.isOSBinFormatXCOFF(); |
392 | |
393 | if (!Dwarf64 && TT.isArch64Bit() && TT.isOSBinFormatXCOFF()) |
394 | report_fatal_error(reason: "XCOFF requires DWARF64 for 64-bit mode!" ); |
395 | |
396 | UseRangesSection = !NoDwarfRangesSection && !TT.isNVPTX(); |
397 | |
398 | // Use sections as references. Force for NVPTX. |
399 | if (DwarfSectionsAsReferences == Default) |
400 | UseSectionsAsReferences = TT.isNVPTX(); |
401 | else |
402 | UseSectionsAsReferences = DwarfSectionsAsReferences == Enable; |
403 | |
404 | // Don't generate type units for unsupported object file formats. |
405 | GenerateTypeUnits = (A->TM.getTargetTriple().isOSBinFormatELF() || |
406 | A->TM.getTargetTriple().isOSBinFormatWasm()) && |
407 | GenerateDwarfTypeUnits; |
408 | |
409 | TheAccelTableKind = computeAccelTableKind( |
410 | DwarfVersion, GenerateTypeUnits, Tuning: DebuggerTuning, TT: A->TM.getTargetTriple()); |
411 | |
412 | // Work around a GDB bug. GDB doesn't support the standard opcode; |
413 | // SCE doesn't support GNU's; LLDB prefers the standard opcode, which |
414 | // is defined as of DWARF 3. |
415 | // See GDB bug 11616 - DW_OP_form_tls_address is unimplemented |
416 | // https://sourceware.org/bugzilla/show_bug.cgi?id=11616 |
417 | UseGNUTLSOpcode = tuneForGDB() || DwarfVersion < 3; |
418 | |
419 | UseDWARF2Bitfields = DwarfVersion < 4; |
420 | |
421 | // The DWARF v5 string offsets table has - possibly shared - contributions |
422 | // from each compile and type unit each preceded by a header. The string |
423 | // offsets table used by the pre-DWARF v5 split-DWARF implementation uses |
424 | // a monolithic string offsets table without any header. |
425 | UseSegmentedStringOffsetsTable = DwarfVersion >= 5; |
426 | |
427 | // Emit call-site-param debug info for GDB and LLDB, if the target supports |
428 | // the debug entry values feature. It can also be enabled explicitly. |
429 | EmitDebugEntryValues = Asm->TM.Options.ShouldEmitDebugEntryValues(); |
430 | |
431 | // It is unclear if the GCC .debug_macro extension is well-specified |
432 | // for split DWARF. For now, do not allow LLVM to emit it. |
433 | UseDebugMacroSection = |
434 | DwarfVersion >= 5 || (UseGNUDebugMacro && !useSplitDwarf()); |
435 | if (DwarfOpConvert == Default) |
436 | EnableOpConvert = !((tuneForGDB() && useSplitDwarf()) || (tuneForLLDB() && !TT.isOSBinFormatMachO())); |
437 | else |
438 | EnableOpConvert = (DwarfOpConvert == Enable); |
439 | |
440 | // Split DWARF would benefit object size significantly by trading reductions |
441 | // in address pool usage for slightly increased range list encodings. |
442 | if (DwarfVersion >= 5) |
443 | MinimizeAddr = MinimizeAddrInV5Option; |
444 | |
445 | Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion); |
446 | Asm->OutStreamer->getContext().setDwarfFormat(Dwarf64 ? dwarf::DWARF64 |
447 | : dwarf::DWARF32); |
448 | } |
449 | |
450 | // Define out of line so we don't have to include DwarfUnit.h in DwarfDebug.h. |
451 | DwarfDebug::~DwarfDebug() = default; |
452 | |
453 | static bool isObjCClass(StringRef Name) { |
454 | return Name.starts_with(Prefix: "+" ) || Name.starts_with(Prefix: "-" ); |
455 | } |
456 | |
457 | static bool hasObjCCategory(StringRef Name) { |
458 | if (!isObjCClass(Name)) |
459 | return false; |
460 | |
461 | return Name.contains(Other: ") " ); |
462 | } |
463 | |
464 | static void getObjCClassCategory(StringRef In, StringRef &Class, |
465 | StringRef &Category) { |
466 | if (!hasObjCCategory(Name: In)) { |
467 | Class = In.slice(Start: In.find(C: '[') + 1, End: In.find(C: ' ')); |
468 | Category = "" ; |
469 | return; |
470 | } |
471 | |
472 | Class = In.slice(Start: In.find(C: '[') + 1, End: In.find(C: '(')); |
473 | Category = In.slice(Start: In.find(C: '[') + 1, End: In.find(C: ' ')); |
474 | } |
475 | |
476 | static StringRef getObjCMethodName(StringRef In) { |
477 | return In.slice(Start: In.find(C: ' ') + 1, End: In.find(C: ']')); |
478 | } |
479 | |
480 | // Add the various names to the Dwarf accelerator table names. |
481 | void DwarfDebug::addSubprogramNames( |
482 | const DwarfUnit &Unit, |
483 | const DICompileUnit::DebugNameTableKind NameTableKind, |
484 | const DISubprogram *SP, DIE &Die) { |
485 | if (getAccelTableKind() != AccelTableKind::Apple && |
486 | NameTableKind != DICompileUnit::DebugNameTableKind::Apple && |
487 | NameTableKind == DICompileUnit::DebugNameTableKind::None) |
488 | return; |
489 | |
490 | if (!SP->isDefinition()) |
491 | return; |
492 | |
493 | if (SP->getName() != "" ) |
494 | addAccelName(Unit, NameTableKind, Name: SP->getName(), Die); |
495 | |
496 | // We drop the mangling escape prefix when emitting the DW_AT_linkage_name. So |
497 | // ensure we don't include it when inserting into the accelerator tables. |
498 | llvm::StringRef LinkageName = |
499 | GlobalValue::dropLLVMManglingEscape(Name: SP->getLinkageName()); |
500 | |
501 | // If the linkage name is different than the name, go ahead and output that as |
502 | // well into the name table. Only do that if we are going to actually emit |
503 | // that name. |
504 | if (LinkageName != "" && SP->getName() != LinkageName && |
505 | (useAllLinkageNames() || InfoHolder.getAbstractScopeDIEs().lookup(Val: SP))) |
506 | addAccelName(Unit, NameTableKind, Name: LinkageName, Die); |
507 | |
508 | // If this is an Objective-C selector name add it to the ObjC accelerator |
509 | // too. |
510 | if (isObjCClass(Name: SP->getName())) { |
511 | StringRef Class, Category; |
512 | getObjCClassCategory(In: SP->getName(), Class, Category); |
513 | addAccelObjC(Unit, NameTableKind, Name: Class, Die); |
514 | if (Category != "" ) |
515 | addAccelObjC(Unit, NameTableKind, Name: Category, Die); |
516 | // Also add the base method name to the name table. |
517 | addAccelName(Unit, NameTableKind, Name: getObjCMethodName(In: SP->getName()), Die); |
518 | } |
519 | } |
520 | |
521 | /// Check whether we should create a DIE for the given Scope, return true |
522 | /// if we don't create a DIE (the corresponding DIE is null). |
523 | bool DwarfDebug::isLexicalScopeDIENull(LexicalScope *Scope) { |
524 | if (Scope->isAbstractScope()) |
525 | return false; |
526 | |
527 | // We don't create a DIE if there is no Range. |
528 | const SmallVectorImpl<InsnRange> &Ranges = Scope->getRanges(); |
529 | if (Ranges.empty()) |
530 | return true; |
531 | |
532 | if (Ranges.size() > 1) |
533 | return false; |
534 | |
535 | // We don't create a DIE if we have a single Range and the end label |
536 | // is null. |
537 | return !getLabelAfterInsn(MI: Ranges.front().second); |
538 | } |
539 | |
540 | template <typename Func> static void forBothCUs(DwarfCompileUnit &CU, Func F) { |
541 | F(CU); |
542 | if (auto *SkelCU = CU.getSkeleton()) |
543 | if (CU.getCUNode()->getSplitDebugInlining()) |
544 | F(*SkelCU); |
545 | } |
546 | |
547 | bool DwarfDebug::shareAcrossDWOCUs() const { |
548 | return SplitDwarfCrossCuReferences; |
549 | } |
550 | |
551 | void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU, |
552 | LexicalScope *Scope) { |
553 | assert(Scope && Scope->getScopeNode()); |
554 | assert(Scope->isAbstractScope()); |
555 | assert(!Scope->getInlinedAt()); |
556 | |
557 | auto *SP = cast<DISubprogram>(Val: Scope->getScopeNode()); |
558 | |
559 | // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram |
560 | // was inlined from another compile unit. |
561 | if (useSplitDwarf() && !shareAcrossDWOCUs() && !SP->getUnit()->getSplitDebugInlining()) |
562 | // Avoid building the original CU if it won't be used |
563 | SrcCU.constructAbstractSubprogramScopeDIE(Scope); |
564 | else { |
565 | auto &CU = getOrCreateDwarfCompileUnit(DIUnit: SP->getUnit()); |
566 | if (auto *SkelCU = CU.getSkeleton()) { |
567 | (shareAcrossDWOCUs() ? CU : SrcCU) |
568 | .constructAbstractSubprogramScopeDIE(Scope); |
569 | if (CU.getCUNode()->getSplitDebugInlining()) |
570 | SkelCU->constructAbstractSubprogramScopeDIE(Scope); |
571 | } else |
572 | CU.constructAbstractSubprogramScopeDIE(Scope); |
573 | } |
574 | } |
575 | |
576 | /// Represents a parameter whose call site value can be described by applying a |
577 | /// debug expression to a register in the forwarded register worklist. |
578 | struct FwdRegParamInfo { |
579 | /// The described parameter register. |
580 | uint64_t ParamReg; |
581 | |
582 | /// Debug expression that has been built up when walking through the |
583 | /// instruction chain that produces the parameter's value. |
584 | const DIExpression *Expr; |
585 | }; |
586 | |
587 | /// Register worklist for finding call site values. |
588 | using FwdRegWorklist = MapVector<uint64_t, SmallVector<FwdRegParamInfo, 2>>; |
589 | /// Container for the set of registers known to be clobbered on the path to a |
590 | /// call site. |
591 | using ClobberedRegSet = SmallSet<Register, 16>; |
592 | |
593 | /// Append the expression \p Addition to \p Original and return the result. |
594 | static const DIExpression *combineDIExpressions(const DIExpression *Original, |
595 | const DIExpression *Addition) { |
596 | std::vector<uint64_t> Elts = Addition->getElements().vec(); |
597 | // Avoid multiple DW_OP_stack_values. |
598 | if (Original->isImplicit() && Addition->isImplicit()) |
599 | llvm::erase(C&: Elts, V: dwarf::DW_OP_stack_value); |
600 | const DIExpression *CombinedExpr = |
601 | (Elts.size() > 0) ? DIExpression::append(Expr: Original, Ops: Elts) : Original; |
602 | return CombinedExpr; |
603 | } |
604 | |
605 | /// Emit call site parameter entries that are described by the given value and |
606 | /// debug expression. |
607 | template <typename ValT> |
608 | static void finishCallSiteParams(ValT Val, const DIExpression *Expr, |
609 | ArrayRef<FwdRegParamInfo> DescribedParams, |
610 | ParamSet &Params) { |
611 | for (auto Param : DescribedParams) { |
612 | bool ShouldCombineExpressions = Expr && Param.Expr->getNumElements() > 0; |
613 | |
614 | // TODO: Entry value operations can currently not be combined with any |
615 | // other expressions, so we can't emit call site entries in those cases. |
616 | if (ShouldCombineExpressions && Expr->isEntryValue()) |
617 | continue; |
618 | |
619 | // If a parameter's call site value is produced by a chain of |
620 | // instructions we may have already created an expression for the |
621 | // parameter when walking through the instructions. Append that to the |
622 | // base expression. |
623 | const DIExpression *CombinedExpr = |
624 | ShouldCombineExpressions ? combineDIExpressions(Original: Expr, Addition: Param.Expr) |
625 | : Expr; |
626 | assert((!CombinedExpr || CombinedExpr->isValid()) && |
627 | "Combined debug expression is invalid" ); |
628 | |
629 | DbgValueLoc DbgLocVal(CombinedExpr, DbgValueLocEntry(Val)); |
630 | DbgCallSiteParam CSParm(Param.ParamReg, DbgLocVal); |
631 | Params.push_back(Elt: CSParm); |
632 | ++NumCSParams; |
633 | } |
634 | } |
635 | |
636 | /// Add \p Reg to the worklist, if it's not already present, and mark that the |
637 | /// given parameter registers' values can (potentially) be described using |
638 | /// that register and an debug expression. |
639 | static void addToFwdRegWorklist(FwdRegWorklist &Worklist, unsigned Reg, |
640 | const DIExpression *Expr, |
641 | ArrayRef<FwdRegParamInfo> ParamsToAdd) { |
642 | auto &ParamsForFwdReg = Worklist[Reg]; |
643 | for (auto Param : ParamsToAdd) { |
644 | assert(none_of(ParamsForFwdReg, |
645 | [Param](const FwdRegParamInfo &D) { |
646 | return D.ParamReg == Param.ParamReg; |
647 | }) && |
648 | "Same parameter described twice by forwarding reg" ); |
649 | |
650 | // If a parameter's call site value is produced by a chain of |
651 | // instructions we may have already created an expression for the |
652 | // parameter when walking through the instructions. Append that to the |
653 | // new expression. |
654 | const DIExpression *CombinedExpr = combineDIExpressions(Original: Expr, Addition: Param.Expr); |
655 | ParamsForFwdReg.push_back(Elt: {.ParamReg: Param.ParamReg, .Expr: CombinedExpr}); |
656 | } |
657 | } |
658 | |
659 | /// Interpret values loaded into registers by \p CurMI. |
660 | static void interpretValues(const MachineInstr *CurMI, |
661 | FwdRegWorklist &ForwardedRegWorklist, |
662 | ParamSet &Params, |
663 | ClobberedRegSet &ClobberedRegUnits) { |
664 | |
665 | const MachineFunction *MF = CurMI->getMF(); |
666 | const DIExpression *EmptyExpr = |
667 | DIExpression::get(Context&: MF->getFunction().getContext(), Elements: {}); |
668 | const auto &TRI = *MF->getSubtarget().getRegisterInfo(); |
669 | const auto &TII = *MF->getSubtarget().getInstrInfo(); |
670 | const auto &TLI = *MF->getSubtarget().getTargetLowering(); |
671 | |
672 | // If an instruction defines more than one item in the worklist, we may run |
673 | // into situations where a worklist register's value is (potentially) |
674 | // described by the previous value of another register that is also defined |
675 | // by that instruction. |
676 | // |
677 | // This can for example occur in cases like this: |
678 | // |
679 | // $r1 = mov 123 |
680 | // $r0, $r1 = mvrr $r1, 456 |
681 | // call @foo, $r0, $r1 |
682 | // |
683 | // When describing $r1's value for the mvrr instruction, we need to make sure |
684 | // that we don't finalize an entry value for $r0, as that is dependent on the |
685 | // previous value of $r1 (123 rather than 456). |
686 | // |
687 | // In order to not have to distinguish between those cases when finalizing |
688 | // entry values, we simply postpone adding new parameter registers to the |
689 | // worklist, by first keeping them in this temporary container until the |
690 | // instruction has been handled. |
691 | FwdRegWorklist TmpWorklistItems; |
692 | |
693 | // If the MI is an instruction defining one or more parameters' forwarding |
694 | // registers, add those defines. |
695 | ClobberedRegSet NewClobberedRegUnits; |
696 | auto getForwardingRegsDefinedByMI = [&](const MachineInstr &MI, |
697 | SmallSetVector<unsigned, 4> &Defs) { |
698 | if (MI.isDebugInstr()) |
699 | return; |
700 | |
701 | for (const MachineOperand &MO : MI.all_defs()) { |
702 | if (MO.getReg().isPhysical()) { |
703 | for (auto &FwdReg : ForwardedRegWorklist) |
704 | if (TRI.regsOverlap(RegA: FwdReg.first, RegB: MO.getReg())) |
705 | Defs.insert(X: FwdReg.first); |
706 | NewClobberedRegUnits.insert_range(R: TRI.regunits(Reg: MO.getReg())); |
707 | } |
708 | } |
709 | }; |
710 | |
711 | // Set of worklist registers that are defined by this instruction. |
712 | SmallSetVector<unsigned, 4> FwdRegDefs; |
713 | |
714 | getForwardingRegsDefinedByMI(*CurMI, FwdRegDefs); |
715 | if (FwdRegDefs.empty()) { |
716 | // Any definitions by this instruction will clobber earlier reg movements. |
717 | ClobberedRegUnits.insert_range(R&: NewClobberedRegUnits); |
718 | return; |
719 | } |
720 | |
721 | // It's possible that we find a copy from a non-volatile register to the param |
722 | // register, which is clobbered in the meantime. Test for clobbered reg unit |
723 | // overlaps before completing. |
724 | auto IsRegClobberedInMeantime = [&](Register Reg) -> bool { |
725 | for (auto &RegUnit : ClobberedRegUnits) |
726 | if (TRI.hasRegUnit(Reg, RegUnit)) |
727 | return true; |
728 | return false; |
729 | }; |
730 | |
731 | for (auto ParamFwdReg : FwdRegDefs) { |
732 | if (auto ParamValue = TII.describeLoadedValue(MI: *CurMI, Reg: ParamFwdReg)) { |
733 | if (ParamValue->first.isImm()) { |
734 | int64_t Val = ParamValue->first.getImm(); |
735 | finishCallSiteParams(Val, Expr: ParamValue->second, |
736 | DescribedParams: ForwardedRegWorklist[ParamFwdReg], Params); |
737 | } else if (ParamValue->first.isReg()) { |
738 | Register RegLoc = ParamValue->first.getReg(); |
739 | Register SP = TLI.getStackPointerRegisterToSaveRestore(); |
740 | Register FP = TRI.getFrameRegister(MF: *MF); |
741 | bool IsSPorFP = (RegLoc == SP) || (RegLoc == FP); |
742 | if (!IsRegClobberedInMeantime(RegLoc) && |
743 | (TRI.isCalleeSavedPhysReg(PhysReg: RegLoc, MF: *MF) || IsSPorFP)) { |
744 | MachineLocation MLoc(RegLoc, /*Indirect=*/IsSPorFP); |
745 | finishCallSiteParams(Val: MLoc, Expr: ParamValue->second, |
746 | DescribedParams: ForwardedRegWorklist[ParamFwdReg], Params); |
747 | } else { |
748 | // ParamFwdReg was described by the non-callee saved register |
749 | // RegLoc. Mark that the call site values for the parameters are |
750 | // dependent on that register instead of ParamFwdReg. Since RegLoc |
751 | // may be a register that will be handled in this iteration, we |
752 | // postpone adding the items to the worklist, and instead keep them |
753 | // in a temporary container. |
754 | addToFwdRegWorklist(Worklist&: TmpWorklistItems, Reg: RegLoc, Expr: ParamValue->second, |
755 | ParamsToAdd: ForwardedRegWorklist[ParamFwdReg]); |
756 | } |
757 | } |
758 | } |
759 | } |
760 | |
761 | // Remove all registers that this instruction defines from the worklist. |
762 | for (auto ParamFwdReg : FwdRegDefs) |
763 | ForwardedRegWorklist.erase(Key: ParamFwdReg); |
764 | |
765 | // Any definitions by this instruction will clobber earlier reg movements. |
766 | ClobberedRegUnits.insert_range(R&: NewClobberedRegUnits); |
767 | |
768 | // Now that we are done handling this instruction, add items from the |
769 | // temporary worklist to the real one. |
770 | for (auto &New : TmpWorklistItems) |
771 | addToFwdRegWorklist(Worklist&: ForwardedRegWorklist, Reg: New.first, Expr: EmptyExpr, ParamsToAdd: New.second); |
772 | TmpWorklistItems.clear(); |
773 | } |
774 | |
775 | static bool interpretNextInstr(const MachineInstr *CurMI, |
776 | FwdRegWorklist &ForwardedRegWorklist, |
777 | ParamSet &Params, |
778 | ClobberedRegSet &ClobberedRegUnits) { |
779 | // Skip bundle headers. |
780 | if (CurMI->isBundle()) |
781 | return true; |
782 | |
783 | // If the next instruction is a call we can not interpret parameter's |
784 | // forwarding registers or we finished the interpretation of all |
785 | // parameters. |
786 | if (CurMI->isCall()) |
787 | return false; |
788 | |
789 | if (ForwardedRegWorklist.empty()) |
790 | return false; |
791 | |
792 | // Avoid NOP description. |
793 | if (CurMI->getNumOperands() == 0) |
794 | return true; |
795 | |
796 | interpretValues(CurMI, ForwardedRegWorklist, Params, ClobberedRegUnits); |
797 | |
798 | return true; |
799 | } |
800 | |
801 | /// Try to interpret values loaded into registers that forward parameters |
802 | /// for \p CallMI. Store parameters with interpreted value into \p Params. |
803 | static void collectCallSiteParameters(const MachineInstr *CallMI, |
804 | ParamSet &Params) { |
805 | const MachineFunction *MF = CallMI->getMF(); |
806 | const auto &CalleesMap = MF->getCallSitesInfo(); |
807 | auto CSInfo = CalleesMap.find(Val: CallMI); |
808 | |
809 | // There is no information for the call instruction. |
810 | if (CSInfo == CalleesMap.end()) |
811 | return; |
812 | |
813 | const MachineBasicBlock *MBB = CallMI->getParent(); |
814 | |
815 | // Skip the call instruction. |
816 | auto I = std::next(x: CallMI->getReverseIterator()); |
817 | |
818 | FwdRegWorklist ForwardedRegWorklist; |
819 | |
820 | const DIExpression *EmptyExpr = |
821 | DIExpression::get(Context&: MF->getFunction().getContext(), Elements: {}); |
822 | |
823 | // Add all the forwarding registers into the ForwardedRegWorklist. |
824 | for (const auto &ArgReg : CSInfo->second.ArgRegPairs) { |
825 | bool InsertedReg = |
826 | ForwardedRegWorklist.insert(KV: {ArgReg.Reg, {{.ParamReg: ArgReg.Reg, .Expr: EmptyExpr}}}) |
827 | .second; |
828 | assert(InsertedReg && "Single register used to forward two arguments?" ); |
829 | (void)InsertedReg; |
830 | } |
831 | |
832 | // Do not emit CSInfo for undef forwarding registers. |
833 | for (const auto &MO : CallMI->uses()) |
834 | if (MO.isReg() && MO.isUndef()) |
835 | ForwardedRegWorklist.erase(Key: MO.getReg()); |
836 | |
837 | // We erase, from the ForwardedRegWorklist, those forwarding registers for |
838 | // which we successfully describe a loaded value (by using |
839 | // the describeLoadedValue()). For those remaining arguments in the working |
840 | // list, for which we do not describe a loaded value by |
841 | // the describeLoadedValue(), we try to generate an entry value expression |
842 | // for their call site value description, if the call is within the entry MBB. |
843 | // TODO: Handle situations when call site parameter value can be described |
844 | // as the entry value within basic blocks other than the first one. |
845 | bool ShouldTryEmitEntryVals = MBB->getIterator() == MF->begin(); |
846 | |
847 | // Search for a loading value in forwarding registers inside call delay slot. |
848 | ClobberedRegSet ClobberedRegUnits; |
849 | if (CallMI->hasDelaySlot()) { |
850 | auto Suc = std::next(x: CallMI->getIterator()); |
851 | // Only one-instruction delay slot is supported. |
852 | auto BundleEnd = llvm::getBundleEnd(I: CallMI->getIterator()); |
853 | (void)BundleEnd; |
854 | assert(std::next(Suc) == BundleEnd && |
855 | "More than one instruction in call delay slot" ); |
856 | // Try to interpret value loaded by instruction. |
857 | if (!interpretNextInstr(CurMI: &*Suc, ForwardedRegWorklist, Params, ClobberedRegUnits)) |
858 | return; |
859 | } |
860 | |
861 | // Search for a loading value in forwarding registers. |
862 | for (; I != MBB->rend(); ++I) { |
863 | // Try to interpret values loaded by instruction. |
864 | if (!interpretNextInstr(CurMI: &*I, ForwardedRegWorklist, Params, ClobberedRegUnits)) |
865 | return; |
866 | } |
867 | |
868 | // Emit the call site parameter's value as an entry value. |
869 | if (ShouldTryEmitEntryVals) { |
870 | // Create an expression where the register's entry value is used. |
871 | DIExpression *EntryExpr = DIExpression::get( |
872 | Context&: MF->getFunction().getContext(), Elements: {dwarf::DW_OP_LLVM_entry_value, 1}); |
873 | for (auto &RegEntry : ForwardedRegWorklist) { |
874 | MachineLocation MLoc(RegEntry.first); |
875 | finishCallSiteParams(Val: MLoc, Expr: EntryExpr, DescribedParams: RegEntry.second, Params); |
876 | } |
877 | } |
878 | } |
879 | |
880 | void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP, |
881 | DwarfCompileUnit &CU, DIE &ScopeDIE, |
882 | const MachineFunction &MF) { |
883 | // Add a call site-related attribute (DWARF5, Sec. 3.3.1.3). Do this only if |
884 | // the subprogram is required to have one. |
885 | if (!SP.areAllCallsDescribed() || !SP.isDefinition()) |
886 | return; |
887 | |
888 | // Use DW_AT_call_all_calls to express that call site entries are present |
889 | // for both tail and non-tail calls. Don't use DW_AT_call_all_source_calls |
890 | // because one of its requirements is not met: call site entries for |
891 | // optimized-out calls are elided. |
892 | CU.addFlag(Die&: ScopeDIE, Attribute: CU.getDwarf5OrGNUAttr(Attr: dwarf::DW_AT_call_all_calls)); |
893 | |
894 | const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); |
895 | assert(TII && "TargetInstrInfo not found: cannot label tail calls" ); |
896 | |
897 | // Delay slot support check. |
898 | auto delaySlotSupported = [&](const MachineInstr &MI) { |
899 | if (!MI.isBundledWithSucc()) |
900 | return false; |
901 | auto Suc = std::next(x: MI.getIterator()); |
902 | auto CallInstrBundle = getBundleStart(I: MI.getIterator()); |
903 | (void)CallInstrBundle; |
904 | auto DelaySlotBundle = getBundleStart(I: Suc); |
905 | (void)DelaySlotBundle; |
906 | // Ensure that label after call is following delay slot instruction. |
907 | // Ex. CALL_INSTRUCTION { |
908 | // DELAY_SLOT_INSTRUCTION } |
909 | // LABEL_AFTER_CALL |
910 | assert(getLabelAfterInsn(&*CallInstrBundle) == |
911 | getLabelAfterInsn(&*DelaySlotBundle) && |
912 | "Call and its successor instruction don't have same label after." ); |
913 | return true; |
914 | }; |
915 | |
916 | // Emit call site entries for each call or tail call in the function. |
917 | for (const MachineBasicBlock &MBB : MF) { |
918 | for (const MachineInstr &MI : MBB.instrs()) { |
919 | // Bundles with call in them will pass the isCall() test below but do not |
920 | // have callee operand information so skip them here. Iterator will |
921 | // eventually reach the call MI. |
922 | if (MI.isBundle()) |
923 | continue; |
924 | |
925 | // Skip instructions which aren't calls. Both calls and tail-calling jump |
926 | // instructions (e.g TAILJMPd64) are classified correctly here. |
927 | if (!MI.isCandidateForAdditionalCallInfo()) |
928 | continue; |
929 | |
930 | // Skip instructions marked as frame setup, as they are not interesting to |
931 | // the user. |
932 | if (MI.getFlag(Flag: MachineInstr::FrameSetup)) |
933 | continue; |
934 | |
935 | // Check if delay slot support is enabled. |
936 | if (MI.hasDelaySlot() && !delaySlotSupported(*&MI)) |
937 | return; |
938 | |
939 | // If this is a direct call, find the callee's subprogram. |
940 | // In the case of an indirect call find the register that holds |
941 | // the callee. |
942 | const MachineOperand &CalleeOp = TII->getCalleeOperand(MI); |
943 | if (!CalleeOp.isGlobal() && |
944 | (!CalleeOp.isReg() || !CalleeOp.getReg().isPhysical())) |
945 | continue; |
946 | |
947 | unsigned CallReg = 0; |
948 | const DISubprogram *CalleeSP = nullptr; |
949 | const Function *CalleeDecl = nullptr; |
950 | if (CalleeOp.isReg()) { |
951 | CallReg = CalleeOp.getReg(); |
952 | if (!CallReg) |
953 | continue; |
954 | } else { |
955 | CalleeDecl = dyn_cast<Function>(Val: CalleeOp.getGlobal()); |
956 | if (!CalleeDecl || !CalleeDecl->getSubprogram()) |
957 | continue; |
958 | CalleeSP = CalleeDecl->getSubprogram(); |
959 | } |
960 | |
961 | // TODO: Omit call site entries for runtime calls (objc_msgSend, etc). |
962 | |
963 | bool IsTail = TII->isTailCall(Inst: MI); |
964 | |
965 | // If MI is in a bundle, the label was created after the bundle since |
966 | // EmitFunctionBody iterates over top-level MIs. Get that top-level MI |
967 | // to search for that label below. |
968 | const MachineInstr *TopLevelCallMI = |
969 | MI.isInsideBundle() ? &*getBundleStart(I: MI.getIterator()) : &MI; |
970 | |
971 | // For non-tail calls, the return PC is needed to disambiguate paths in |
972 | // the call graph which could lead to some target function. For tail |
973 | // calls, no return PC information is needed, unless tuning for GDB in |
974 | // DWARF4 mode in which case we fake a return PC for compatibility. |
975 | const MCSymbol *PCAddr = |
976 | (!IsTail || CU.useGNUAnalogForDwarf5Feature()) |
977 | ? const_cast<MCSymbol *>(getLabelAfterInsn(MI: TopLevelCallMI)) |
978 | : nullptr; |
979 | |
980 | // For tail calls, it's necessary to record the address of the branch |
981 | // instruction so that the debugger can show where the tail call occurred. |
982 | const MCSymbol *CallAddr = |
983 | IsTail ? getLabelBeforeInsn(MI: TopLevelCallMI) : nullptr; |
984 | |
985 | assert((IsTail || PCAddr) && "Non-tail call without return PC" ); |
986 | |
987 | LLVM_DEBUG(dbgs() << "CallSiteEntry: " << MF.getName() << " -> " |
988 | << (CalleeDecl ? CalleeDecl->getName() |
989 | : StringRef(MF.getSubtarget() |
990 | .getRegisterInfo() |
991 | ->getName(CallReg))) |
992 | << (IsTail ? " [IsTail]" : "" ) << "\n" ); |
993 | |
994 | DIE &CallSiteDIE = CU.constructCallSiteEntryDIE( |
995 | ScopeDIE, CalleeSP, IsTail, PCAddr, CallAddr, CallReg); |
996 | |
997 | // Optionally emit call-site-param debug info. |
998 | if (emitDebugEntryValues()) { |
999 | ParamSet Params; |
1000 | // Try to interpret values of call site parameters. |
1001 | collectCallSiteParameters(CallMI: &MI, Params); |
1002 | CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params); |
1003 | } |
1004 | } |
1005 | } |
1006 | } |
1007 | |
1008 | void DwarfDebug::addGnuPubAttributes(DwarfCompileUnit &U, DIE &D) const { |
1009 | if (!U.hasDwarfPubSections()) |
1010 | return; |
1011 | |
1012 | U.addFlag(Die&: D, Attribute: dwarf::DW_AT_GNU_pubnames); |
1013 | } |
1014 | |
1015 | void DwarfDebug::finishUnitAttributes(const DICompileUnit *DIUnit, |
1016 | DwarfCompileUnit &NewCU) { |
1017 | DIE &Die = NewCU.getUnitDie(); |
1018 | StringRef FN = DIUnit->getFilename(); |
1019 | |
1020 | StringRef Producer = DIUnit->getProducer(); |
1021 | StringRef Flags = DIUnit->getFlags(); |
1022 | if (!Flags.empty() && !useAppleExtensionAttributes()) { |
1023 | std::string ProducerWithFlags = Producer.str() + " " + Flags.str(); |
1024 | NewCU.addString(Die, Attribute: dwarf::DW_AT_producer, Str: ProducerWithFlags); |
1025 | } else |
1026 | NewCU.addString(Die, Attribute: dwarf::DW_AT_producer, Str: Producer); |
1027 | |
1028 | NewCU.addUInt(Die, Attribute: dwarf::DW_AT_language, Form: dwarf::DW_FORM_data2, |
1029 | Integer: DIUnit->getSourceLanguage()); |
1030 | NewCU.addString(Die, Attribute: dwarf::DW_AT_name, Str: FN); |
1031 | StringRef SysRoot = DIUnit->getSysRoot(); |
1032 | if (!SysRoot.empty()) |
1033 | NewCU.addString(Die, Attribute: dwarf::DW_AT_LLVM_sysroot, Str: SysRoot); |
1034 | StringRef SDK = DIUnit->getSDK(); |
1035 | if (!SDK.empty()) |
1036 | NewCU.addString(Die, Attribute: dwarf::DW_AT_APPLE_sdk, Str: SDK); |
1037 | |
1038 | if (!useSplitDwarf()) { |
1039 | // Add DW_str_offsets_base to the unit DIE, except for split units. |
1040 | if (useSegmentedStringOffsetsTable()) |
1041 | NewCU.addStringOffsetsStart(); |
1042 | |
1043 | NewCU.initStmtList(); |
1044 | |
1045 | // If we're using split dwarf the compilation dir is going to be in the |
1046 | // skeleton CU and so we don't need to duplicate it here. |
1047 | if (!CompilationDir.empty()) |
1048 | NewCU.addString(Die, Attribute: dwarf::DW_AT_comp_dir, Str: CompilationDir); |
1049 | addGnuPubAttributes(U&: NewCU, D&: Die); |
1050 | } |
1051 | |
1052 | if (useAppleExtensionAttributes()) { |
1053 | if (DIUnit->isOptimized()) |
1054 | NewCU.addFlag(Die, Attribute: dwarf::DW_AT_APPLE_optimized); |
1055 | |
1056 | StringRef Flags = DIUnit->getFlags(); |
1057 | if (!Flags.empty()) |
1058 | NewCU.addString(Die, Attribute: dwarf::DW_AT_APPLE_flags, Str: Flags); |
1059 | |
1060 | if (unsigned RVer = DIUnit->getRuntimeVersion()) |
1061 | NewCU.addUInt(Die, Attribute: dwarf::DW_AT_APPLE_major_runtime_vers, |
1062 | Form: dwarf::DW_FORM_data1, Integer: RVer); |
1063 | } |
1064 | |
1065 | if (DIUnit->getDWOId()) { |
1066 | // This CU is either a clang module DWO or a skeleton CU. |
1067 | NewCU.addUInt(Die, Attribute: dwarf::DW_AT_GNU_dwo_id, Form: dwarf::DW_FORM_data8, |
1068 | Integer: DIUnit->getDWOId()); |
1069 | if (!DIUnit->getSplitDebugFilename().empty()) { |
1070 | // This is a prefabricated skeleton CU. |
1071 | dwarf::Attribute attrDWOName = getDwarfVersion() >= 5 |
1072 | ? dwarf::DW_AT_dwo_name |
1073 | : dwarf::DW_AT_GNU_dwo_name; |
1074 | NewCU.addString(Die, Attribute: attrDWOName, Str: DIUnit->getSplitDebugFilename()); |
1075 | } |
1076 | } |
1077 | } |
1078 | // Create new DwarfCompileUnit for the given metadata node with tag |
1079 | // DW_TAG_compile_unit. |
1080 | DwarfCompileUnit & |
1081 | DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) { |
1082 | if (auto *CU = CUMap.lookup(Key: DIUnit)) |
1083 | return *CU; |
1084 | |
1085 | if (useSplitDwarf() && |
1086 | !shareAcrossDWOCUs() && |
1087 | (!DIUnit->getSplitDebugInlining() || |
1088 | DIUnit->getEmissionKind() == DICompileUnit::FullDebug) && |
1089 | !CUMap.empty()) { |
1090 | return *CUMap.begin()->second; |
1091 | } |
1092 | CompilationDir = DIUnit->getDirectory(); |
1093 | |
1094 | auto OwnedUnit = std::make_unique<DwarfCompileUnit>( |
1095 | args: InfoHolder.getUnits().size(), args&: DIUnit, args&: Asm, args: this, args: &InfoHolder); |
1096 | DwarfCompileUnit &NewCU = *OwnedUnit; |
1097 | InfoHolder.addUnit(U: std::move(OwnedUnit)); |
1098 | |
1099 | // LTO with assembly output shares a single line table amongst multiple CUs. |
1100 | // To avoid the compilation directory being ambiguous, let the line table |
1101 | // explicitly describe the directory of all files, never relying on the |
1102 | // compilation directory. |
1103 | if (!Asm->OutStreamer->hasRawTextSupport() || SingleCU) |
1104 | Asm->OutStreamer->emitDwarfFile0Directive( |
1105 | Directory: CompilationDir, Filename: DIUnit->getFilename(), Checksum: getMD5AsBytes(File: DIUnit->getFile()), |
1106 | Source: DIUnit->getSource(), CUID: NewCU.getUniqueID()); |
1107 | |
1108 | if (useSplitDwarf()) { |
1109 | NewCU.setSkeleton(constructSkeletonCU(CU: NewCU)); |
1110 | NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoDWOSection()); |
1111 | } else { |
1112 | finishUnitAttributes(DIUnit, NewCU); |
1113 | NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoSection()); |
1114 | } |
1115 | |
1116 | CUMap.insert(KV: {DIUnit, &NewCU}); |
1117 | CUDieMap.insert(KV: {&NewCU.getUnitDie(), &NewCU}); |
1118 | return NewCU; |
1119 | } |
1120 | |
1121 | /// Sort and unique GVEs by comparing their fragment offset. |
1122 | static SmallVectorImpl<DwarfCompileUnit::GlobalExpr> & |
1123 | sortGlobalExprs(SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &GVEs) { |
1124 | llvm::sort( |
1125 | C&: GVEs, Comp: [](DwarfCompileUnit::GlobalExpr A, DwarfCompileUnit::GlobalExpr B) { |
1126 | // Sort order: first null exprs, then exprs without fragment |
1127 | // info, then sort by fragment offset in bits. |
1128 | // FIXME: Come up with a more comprehensive comparator so |
1129 | // the sorting isn't non-deterministic, and so the following |
1130 | // std::unique call works correctly. |
1131 | if (!A.Expr || !B.Expr) |
1132 | return !!B.Expr; |
1133 | auto FragmentA = A.Expr->getFragmentInfo(); |
1134 | auto FragmentB = B.Expr->getFragmentInfo(); |
1135 | if (!FragmentA || !FragmentB) |
1136 | return !!FragmentB; |
1137 | return FragmentA->OffsetInBits < FragmentB->OffsetInBits; |
1138 | }); |
1139 | GVEs.erase(CS: llvm::unique(R&: GVEs, |
1140 | P: [](DwarfCompileUnit::GlobalExpr A, |
1141 | DwarfCompileUnit::GlobalExpr B) { |
1142 | return A.Expr == B.Expr; |
1143 | }), |
1144 | CE: GVEs.end()); |
1145 | return GVEs; |
1146 | } |
1147 | |
1148 | // Emit all Dwarf sections that should come prior to the content. Create |
1149 | // global DIEs and emit initial debug info sections. This is invoked by |
1150 | // the target AsmPrinter. |
1151 | void DwarfDebug::beginModule(Module *M) { |
1152 | DebugHandlerBase::beginModule(M); |
1153 | |
1154 | if (!Asm) |
1155 | return; |
1156 | |
1157 | unsigned NumDebugCUs = std::distance(first: M->debug_compile_units_begin(), |
1158 | last: M->debug_compile_units_end()); |
1159 | if (NumDebugCUs == 0) |
1160 | return; |
1161 | |
1162 | assert(NumDebugCUs > 0 && "Asm unexpectedly initialized" ); |
1163 | SingleCU = NumDebugCUs == 1; |
1164 | DenseMap<DIGlobalVariable *, SmallVector<DwarfCompileUnit::GlobalExpr, 1>> |
1165 | GVMap; |
1166 | for (const GlobalVariable &Global : M->globals()) { |
1167 | SmallVector<DIGlobalVariableExpression *, 1> GVs; |
1168 | Global.getDebugInfo(GVs); |
1169 | for (auto *GVE : GVs) |
1170 | GVMap[GVE->getVariable()].push_back(Elt: {.Var: &Global, .Expr: GVE->getExpression()}); |
1171 | } |
1172 | |
1173 | // Create the symbol that designates the start of the unit's contribution |
1174 | // to the string offsets table. In a split DWARF scenario, only the skeleton |
1175 | // unit has the DW_AT_str_offsets_base attribute (and hence needs the symbol). |
1176 | if (useSegmentedStringOffsetsTable()) |
1177 | (useSplitDwarf() ? SkeletonHolder : InfoHolder) |
1178 | .setStringOffsetsStartSym(Asm->createTempSymbol(Name: "str_offsets_base" )); |
1179 | |
1180 | |
1181 | // Create the symbols that designates the start of the DWARF v5 range list |
1182 | // and locations list tables. They are located past the table headers. |
1183 | if (getDwarfVersion() >= 5) { |
1184 | DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; |
1185 | Holder.setRnglistsTableBaseSym( |
1186 | Asm->createTempSymbol(Name: "rnglists_table_base" )); |
1187 | |
1188 | if (useSplitDwarf()) |
1189 | InfoHolder.setRnglistsTableBaseSym( |
1190 | Asm->createTempSymbol(Name: "rnglists_dwo_table_base" )); |
1191 | } |
1192 | |
1193 | // Create the symbol that points to the first entry following the debug |
1194 | // address table (.debug_addr) header. |
1195 | AddrPool.setLabel(Asm->createTempSymbol(Name: "addr_table_base" )); |
1196 | DebugLocs.setSym(Asm->createTempSymbol(Name: "loclists_table_base" )); |
1197 | |
1198 | for (DICompileUnit *CUNode : M->debug_compile_units()) { |
1199 | if (CUNode->getImportedEntities().empty() && |
1200 | CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() && |
1201 | CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty()) |
1202 | continue; |
1203 | |
1204 | DwarfCompileUnit &CU = getOrCreateDwarfCompileUnit(DIUnit: CUNode); |
1205 | |
1206 | // Global Variables. |
1207 | for (auto *GVE : CUNode->getGlobalVariables()) { |
1208 | // Don't bother adding DIGlobalVariableExpressions listed in the CU if we |
1209 | // already know about the variable and it isn't adding a constant |
1210 | // expression. |
1211 | auto &GVMapEntry = GVMap[GVE->getVariable()]; |
1212 | auto *Expr = GVE->getExpression(); |
1213 | if (!GVMapEntry.size() || (Expr && Expr->isConstant())) |
1214 | GVMapEntry.push_back(Elt: {.Var: nullptr, .Expr: Expr}); |
1215 | } |
1216 | |
1217 | DenseSet<DIGlobalVariable *> Processed; |
1218 | for (auto *GVE : CUNode->getGlobalVariables()) { |
1219 | DIGlobalVariable *GV = GVE->getVariable(); |
1220 | if (Processed.insert(V: GV).second) |
1221 | CU.getOrCreateGlobalVariableDIE(GV, GlobalExprs: sortGlobalExprs(GVEs&: GVMap[GV])); |
1222 | } |
1223 | |
1224 | for (auto *Ty : CUNode->getEnumTypes()) |
1225 | CU.getOrCreateTypeDIE(TyNode: cast<DIType>(Val: Ty)); |
1226 | |
1227 | for (auto *Ty : CUNode->getRetainedTypes()) { |
1228 | // The retained types array by design contains pointers to |
1229 | // MDNodes rather than DIRefs. Unique them here. |
1230 | if (DIType *RT = dyn_cast<DIType>(Val: Ty)) |
1231 | // There is no point in force-emitting a forward declaration. |
1232 | CU.getOrCreateTypeDIE(TyNode: RT); |
1233 | } |
1234 | } |
1235 | } |
1236 | |
1237 | void DwarfDebug::finishEntityDefinitions() { |
1238 | for (const auto &Entity : ConcreteEntities) { |
1239 | DIE *Die = Entity->getDIE(); |
1240 | assert(Die); |
1241 | // FIXME: Consider the time-space tradeoff of just storing the unit pointer |
1242 | // in the ConcreteEntities list, rather than looking it up again here. |
1243 | // DIE::getUnit isn't simple - it walks parent pointers, etc. |
1244 | DwarfCompileUnit *Unit = CUDieMap.lookup(Val: Die->getUnitDie()); |
1245 | assert(Unit); |
1246 | Unit->finishEntityDefinition(Entity: Entity.get()); |
1247 | } |
1248 | } |
1249 | |
1250 | void DwarfDebug::finishSubprogramDefinitions() { |
1251 | for (const DISubprogram *SP : ProcessedSPNodes) { |
1252 | assert(SP->getUnit()->getEmissionKind() != DICompileUnit::NoDebug); |
1253 | forBothCUs( |
1254 | CU&: getOrCreateDwarfCompileUnit(DIUnit: SP->getUnit()), |
1255 | F: [&](DwarfCompileUnit &CU) { CU.finishSubprogramDefinition(SP); }); |
1256 | } |
1257 | } |
1258 | |
1259 | void DwarfDebug::finalizeModuleInfo() { |
1260 | const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); |
1261 | |
1262 | finishSubprogramDefinitions(); |
1263 | |
1264 | finishEntityDefinitions(); |
1265 | |
1266 | bool HasEmittedSplitCU = false; |
1267 | |
1268 | // Handle anything that needs to be done on a per-unit basis after |
1269 | // all other generation. |
1270 | for (const auto &P : CUMap) { |
1271 | auto &TheCU = *P.second; |
1272 | if (TheCU.getCUNode()->isDebugDirectivesOnly()) |
1273 | continue; |
1274 | TheCU.attachLexicalScopesAbstractOrigins(); |
1275 | // Emit DW_AT_containing_type attribute to connect types with their |
1276 | // vtable holding type. |
1277 | TheCU.constructContainingTypeDIEs(); |
1278 | |
1279 | // Add CU specific attributes if we need to add any. |
1280 | // If we're splitting the dwarf out now that we've got the entire |
1281 | // CU then add the dwo id to it. |
1282 | auto *SkCU = TheCU.getSkeleton(); |
1283 | |
1284 | bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty(); |
1285 | |
1286 | if (HasSplitUnit) { |
1287 | (void)HasEmittedSplitCU; |
1288 | assert((shareAcrossDWOCUs() || !HasEmittedSplitCU) && |
1289 | "Multiple CUs emitted into a single dwo file" ); |
1290 | HasEmittedSplitCU = true; |
1291 | dwarf::Attribute attrDWOName = getDwarfVersion() >= 5 |
1292 | ? dwarf::DW_AT_dwo_name |
1293 | : dwarf::DW_AT_GNU_dwo_name; |
1294 | finishUnitAttributes(DIUnit: TheCU.getCUNode(), NewCU&: TheCU); |
1295 | StringRef DWOName = Asm->TM.Options.MCOptions.SplitDwarfFile; |
1296 | TheCU.addString(Die&: TheCU.getUnitDie(), Attribute: attrDWOName, Str: DWOName); |
1297 | SkCU->addString(Die&: SkCU->getUnitDie(), Attribute: attrDWOName, Str: DWOName); |
1298 | // Emit a unique identifier for this CU. Include the DWO file name in the |
1299 | // hash to avoid the case where two (almost) empty compile units have the |
1300 | // same contents. This can happen if link-time optimization removes nearly |
1301 | // all (unused) code from a CU. |
1302 | uint64_t ID = |
1303 | DIEHash(Asm, &TheCU).computeCUSignature(DWOName, Die: TheCU.getUnitDie()); |
1304 | if (getDwarfVersion() >= 5) { |
1305 | TheCU.setDWOId(ID); |
1306 | SkCU->setDWOId(ID); |
1307 | } else { |
1308 | TheCU.addUInt(Die&: TheCU.getUnitDie(), Attribute: dwarf::DW_AT_GNU_dwo_id, |
1309 | Form: dwarf::DW_FORM_data8, Integer: ID); |
1310 | SkCU->addUInt(Die&: SkCU->getUnitDie(), Attribute: dwarf::DW_AT_GNU_dwo_id, |
1311 | Form: dwarf::DW_FORM_data8, Integer: ID); |
1312 | } |
1313 | |
1314 | if (getDwarfVersion() < 5 && !SkeletonHolder.getRangeLists().empty()) { |
1315 | const MCSymbol *Sym = TLOF.getDwarfRangesSection()->getBeginSymbol(); |
1316 | SkCU->addSectionLabel(Die&: SkCU->getUnitDie(), Attribute: dwarf::DW_AT_GNU_ranges_base, |
1317 | Label: Sym, Sec: Sym); |
1318 | } |
1319 | } else if (SkCU) { |
1320 | finishUnitAttributes(DIUnit: SkCU->getCUNode(), NewCU&: *SkCU); |
1321 | } |
1322 | |
1323 | // If we have code split among multiple sections or non-contiguous |
1324 | // ranges of code then emit a DW_AT_ranges attribute on the unit that will |
1325 | // remain in the .o file, otherwise add a DW_AT_low_pc. |
1326 | // FIXME: We should use ranges allow reordering of code ala |
1327 | // .subsections_via_symbols in mach-o. This would mean turning on |
1328 | // ranges for all subprogram DIEs for mach-o. |
1329 | DwarfCompileUnit &U = SkCU ? *SkCU : TheCU; |
1330 | |
1331 | if (unsigned NumRanges = TheCU.getRanges().size()) { |
1332 | // PTX does not support subtracting labels from the code section in the |
1333 | // debug_loc section. To work around this, the NVPTX backend needs the |
1334 | // compile unit to have no low_pc in order to have a zero base_address |
1335 | // when handling debug_loc in cuda-gdb. |
1336 | if (!(Asm->TM.getTargetTriple().isNVPTX() && tuneForGDB())) { |
1337 | if (NumRanges > 1 && useRangesSection()) |
1338 | // A DW_AT_low_pc attribute may also be specified in combination with |
1339 | // DW_AT_ranges to specify the default base address for use in |
1340 | // location lists (see Section 2.6.2) and range lists (see Section |
1341 | // 2.17.3). |
1342 | U.addUInt(Die&: U.getUnitDie(), Attribute: dwarf::DW_AT_low_pc, Form: dwarf::DW_FORM_addr, |
1343 | Integer: 0); |
1344 | else |
1345 | U.setBaseAddress(TheCU.getRanges().front().Begin); |
1346 | U.attachRangesOrLowHighPC(D&: U.getUnitDie(), Ranges: TheCU.takeRanges()); |
1347 | } |
1348 | } |
1349 | |
1350 | // We don't keep track of which addresses are used in which CU so this |
1351 | // is a bit pessimistic under LTO. |
1352 | if ((HasSplitUnit || getDwarfVersion() >= 5) && !AddrPool.isEmpty()) |
1353 | U.addAddrTableBase(); |
1354 | |
1355 | if (getDwarfVersion() >= 5) { |
1356 | if (U.hasRangeLists()) |
1357 | U.addRnglistsBase(); |
1358 | |
1359 | if (!DebugLocs.getLists().empty() && !useSplitDwarf()) { |
1360 | U.addSectionLabel(Die&: U.getUnitDie(), Attribute: dwarf::DW_AT_loclists_base, |
1361 | Label: DebugLocs.getSym(), |
1362 | Sec: TLOF.getDwarfLoclistsSection()->getBeginSymbol()); |
1363 | } |
1364 | } |
1365 | |
1366 | auto *CUNode = cast<DICompileUnit>(Val: P.first); |
1367 | // If compile Unit has macros, emit "DW_AT_macro_info/DW_AT_macros" |
1368 | // attribute. |
1369 | if (CUNode->getMacros()) { |
1370 | if (UseDebugMacroSection) { |
1371 | if (useSplitDwarf()) |
1372 | TheCU.addSectionDelta( |
1373 | Die&: TheCU.getUnitDie(), Attribute: dwarf::DW_AT_macros, Hi: U.getMacroLabelBegin(), |
1374 | Lo: TLOF.getDwarfMacroDWOSection()->getBeginSymbol()); |
1375 | else { |
1376 | dwarf::Attribute MacrosAttr = getDwarfVersion() >= 5 |
1377 | ? dwarf::DW_AT_macros |
1378 | : dwarf::DW_AT_GNU_macros; |
1379 | U.addSectionLabel(Die&: U.getUnitDie(), Attribute: MacrosAttr, Label: U.getMacroLabelBegin(), |
1380 | Sec: TLOF.getDwarfMacroSection()->getBeginSymbol()); |
1381 | } |
1382 | } else { |
1383 | if (useSplitDwarf()) |
1384 | TheCU.addSectionDelta( |
1385 | Die&: TheCU.getUnitDie(), Attribute: dwarf::DW_AT_macro_info, |
1386 | Hi: U.getMacroLabelBegin(), |
1387 | Lo: TLOF.getDwarfMacinfoDWOSection()->getBeginSymbol()); |
1388 | else |
1389 | U.addSectionLabel(Die&: U.getUnitDie(), Attribute: dwarf::DW_AT_macro_info, |
1390 | Label: U.getMacroLabelBegin(), |
1391 | Sec: TLOF.getDwarfMacinfoSection()->getBeginSymbol()); |
1392 | } |
1393 | } |
1394 | } |
1395 | |
1396 | // Emit all frontend-produced Skeleton CUs, i.e., Clang modules. |
1397 | for (auto *CUNode : MMI->getModule()->debug_compile_units()) |
1398 | if (CUNode->getDWOId()) |
1399 | getOrCreateDwarfCompileUnit(DIUnit: CUNode); |
1400 | |
1401 | // Compute DIE offsets and sizes. |
1402 | InfoHolder.computeSizeAndOffsets(); |
1403 | if (useSplitDwarf()) |
1404 | SkeletonHolder.computeSizeAndOffsets(); |
1405 | |
1406 | // Now that offsets are computed, can replace DIEs in debug_names Entry with |
1407 | // an actual offset. |
1408 | AccelDebugNames.convertDieToOffset(); |
1409 | } |
1410 | |
1411 | // Emit all Dwarf sections that should come after the content. |
1412 | void DwarfDebug::endModule() { |
1413 | // Terminate the pending line table. |
1414 | if (PrevCU) |
1415 | terminateLineTable(CU: PrevCU); |
1416 | PrevCU = nullptr; |
1417 | assert(CurFn == nullptr); |
1418 | assert(CurMI == nullptr); |
1419 | |
1420 | for (const auto &P : CUMap) { |
1421 | const auto *CUNode = cast<DICompileUnit>(Val: P.first); |
1422 | DwarfCompileUnit *CU = &*P.second; |
1423 | |
1424 | // Emit imported entities. |
1425 | for (auto *IE : CUNode->getImportedEntities()) { |
1426 | assert(!isa_and_nonnull<DILocalScope>(IE->getScope()) && |
1427 | "Unexpected function-local entity in 'imports' CU field." ); |
1428 | CU->getOrCreateImportedEntityDIE(IE); |
1429 | } |
1430 | for (const auto *D : CU->getDeferredLocalDecls()) { |
1431 | if (auto *IE = dyn_cast<DIImportedEntity>(Val: D)) |
1432 | CU->getOrCreateImportedEntityDIE(IE); |
1433 | else |
1434 | llvm_unreachable("Unexpected local retained node!" ); |
1435 | } |
1436 | |
1437 | // Emit base types. |
1438 | CU->createBaseTypeDIEs(); |
1439 | } |
1440 | |
1441 | // If we aren't actually generating debug info (check beginModule - |
1442 | // conditionalized on the presence of the llvm.dbg.cu metadata node) |
1443 | if (!Asm || !Asm->hasDebugInfo()) |
1444 | return; |
1445 | |
1446 | // Finalize the debug info for the module. |
1447 | finalizeModuleInfo(); |
1448 | |
1449 | if (useSplitDwarf()) |
1450 | // Emit debug_loc.dwo/debug_loclists.dwo section. |
1451 | emitDebugLocDWO(); |
1452 | else |
1453 | // Emit debug_loc/debug_loclists section. |
1454 | emitDebugLoc(); |
1455 | |
1456 | // Corresponding abbreviations into a abbrev section. |
1457 | emitAbbreviations(); |
1458 | |
1459 | // Emit all the DIEs into a debug info section. |
1460 | emitDebugInfo(); |
1461 | |
1462 | // Emit info into a debug aranges section. |
1463 | if (UseARangesSection) |
1464 | emitDebugARanges(); |
1465 | |
1466 | // Emit info into a debug ranges section. |
1467 | emitDebugRanges(); |
1468 | |
1469 | if (useSplitDwarf()) |
1470 | // Emit info into a debug macinfo.dwo section. |
1471 | emitDebugMacinfoDWO(); |
1472 | else |
1473 | // Emit info into a debug macinfo/macro section. |
1474 | emitDebugMacinfo(); |
1475 | |
1476 | emitDebugStr(); |
1477 | |
1478 | if (useSplitDwarf()) { |
1479 | emitDebugStrDWO(); |
1480 | emitDebugInfoDWO(); |
1481 | emitDebugAbbrevDWO(); |
1482 | emitDebugLineDWO(); |
1483 | emitDebugRangesDWO(); |
1484 | } |
1485 | |
1486 | emitDebugAddr(); |
1487 | |
1488 | // Emit info into the dwarf accelerator table sections. |
1489 | switch (getAccelTableKind()) { |
1490 | case AccelTableKind::Apple: |
1491 | emitAccelNames(); |
1492 | emitAccelObjC(); |
1493 | emitAccelNamespaces(); |
1494 | emitAccelTypes(); |
1495 | break; |
1496 | case AccelTableKind::Dwarf: |
1497 | emitAccelDebugNames(); |
1498 | break; |
1499 | case AccelTableKind::None: |
1500 | break; |
1501 | case AccelTableKind::Default: |
1502 | llvm_unreachable("Default should have already been resolved." ); |
1503 | } |
1504 | |
1505 | // Emit the pubnames and pubtypes sections if requested. |
1506 | emitDebugPubSections(); |
1507 | |
1508 | // clean up. |
1509 | // FIXME: AbstractVariables.clear(); |
1510 | } |
1511 | |
1512 | void DwarfDebug::ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU, |
1513 | const DINode *Node, const MDNode *ScopeNode) { |
1514 | if (CU.getExistingAbstractEntity(Node)) |
1515 | return; |
1516 | |
1517 | if (LexicalScope *Scope = |
1518 | LScopes.findAbstractScope(N: cast_or_null<DILocalScope>(Val: ScopeNode))) |
1519 | CU.createAbstractEntity(Node, Scope); |
1520 | } |
1521 | |
1522 | static const DILocalScope *getRetainedNodeScope(const MDNode *N) { |
1523 | const DIScope *S; |
1524 | if (const auto *LV = dyn_cast<DILocalVariable>(Val: N)) |
1525 | S = LV->getScope(); |
1526 | else if (const auto *L = dyn_cast<DILabel>(Val: N)) |
1527 | S = L->getScope(); |
1528 | else if (const auto *IE = dyn_cast<DIImportedEntity>(Val: N)) |
1529 | S = IE->getScope(); |
1530 | else |
1531 | llvm_unreachable("Unexpected retained node!" ); |
1532 | |
1533 | // Ensure the scope is not a DILexicalBlockFile. |
1534 | return cast<DILocalScope>(Val: S)->getNonLexicalBlockFileScope(); |
1535 | } |
1536 | |
1537 | // Collect variable information from side table maintained by MF. |
1538 | void DwarfDebug::collectVariableInfoFromMFTable( |
1539 | DwarfCompileUnit &TheCU, DenseSet<InlinedEntity> &Processed) { |
1540 | SmallDenseMap<InlinedEntity, DbgVariable *> MFVars; |
1541 | LLVM_DEBUG(dbgs() << "DwarfDebug: collecting variables from MF side table\n" ); |
1542 | for (const auto &VI : Asm->MF->getVariableDbgInfo()) { |
1543 | if (!VI.Var) |
1544 | continue; |
1545 | assert(VI.Var->isValidLocationForIntrinsic(VI.Loc) && |
1546 | "Expected inlined-at fields to agree" ); |
1547 | |
1548 | InlinedEntity Var(VI.Var, VI.Loc->getInlinedAt()); |
1549 | Processed.insert(V: Var); |
1550 | LexicalScope *Scope = LScopes.findLexicalScope(DL: VI.Loc); |
1551 | |
1552 | // If variable scope is not found then skip this variable. |
1553 | if (!Scope) { |
1554 | LLVM_DEBUG(dbgs() << "Dropping debug info for " << VI.Var->getName() |
1555 | << ", no variable scope found\n" ); |
1556 | continue; |
1557 | } |
1558 | |
1559 | ensureAbstractEntityIsCreatedIfScoped(CU&: TheCU, Node: Var.first, ScopeNode: Scope->getScopeNode()); |
1560 | |
1561 | // If we have already seen information for this variable, add to what we |
1562 | // already know. |
1563 | if (DbgVariable *PreviousLoc = MFVars.lookup(Val: Var)) { |
1564 | auto *PreviousMMI = std::get_if<Loc::MMI>(ptr: PreviousLoc); |
1565 | auto *PreviousEntryValue = std::get_if<Loc::EntryValue>(ptr: PreviousLoc); |
1566 | // Previous and new locations are both stack slots (MMI). |
1567 | if (PreviousMMI && VI.inStackSlot()) |
1568 | PreviousMMI->addFrameIndexExpr(Expr: VI.Expr, FI: VI.getStackSlot()); |
1569 | // Previous and new locations are both entry values. |
1570 | else if (PreviousEntryValue && VI.inEntryValueRegister()) |
1571 | PreviousEntryValue->addExpr(Reg: VI.getEntryValueRegister(), Expr: *VI.Expr); |
1572 | else { |
1573 | // Locations differ, this should (rarely) happen in optimized async |
1574 | // coroutines. |
1575 | // Prefer whichever location has an EntryValue. |
1576 | if (PreviousLoc->holds<Loc::MMI>()) |
1577 | PreviousLoc->emplace<Loc::EntryValue>(args: VI.getEntryValueRegister(), |
1578 | args: *VI.Expr); |
1579 | LLVM_DEBUG(dbgs() << "Dropping debug info for " << VI.Var->getName() |
1580 | << ", conflicting fragment location types\n" ); |
1581 | } |
1582 | continue; |
1583 | } |
1584 | |
1585 | auto RegVar = std::make_unique<DbgVariable>( |
1586 | args: cast<DILocalVariable>(Val: Var.first), args&: Var.second); |
1587 | if (VI.inStackSlot()) |
1588 | RegVar->emplace<Loc::MMI>(args: VI.Expr, args: VI.getStackSlot()); |
1589 | else |
1590 | RegVar->emplace<Loc::EntryValue>(args: VI.getEntryValueRegister(), args: *VI.Expr); |
1591 | LLVM_DEBUG(dbgs() << "Created DbgVariable for " << VI.Var->getName() |
1592 | << "\n" ); |
1593 | InfoHolder.addScopeVariable(LS: Scope, Var: RegVar.get()); |
1594 | MFVars.insert(KV: {Var, RegVar.get()}); |
1595 | ConcreteEntities.push_back(Elt: std::move(RegVar)); |
1596 | } |
1597 | } |
1598 | |
1599 | /// Determine whether a *singular* DBG_VALUE is valid for the entirety of its |
1600 | /// enclosing lexical scope. The check ensures there are no other instructions |
1601 | /// in the same lexical scope preceding the DBG_VALUE and that its range is |
1602 | /// either open or otherwise rolls off the end of the scope. |
1603 | static bool validThroughout(LexicalScopes &LScopes, |
1604 | const MachineInstr *DbgValue, |
1605 | const MachineInstr *RangeEnd, |
1606 | const InstructionOrdering &Ordering) { |
1607 | assert(DbgValue->getDebugLoc() && "DBG_VALUE without a debug location" ); |
1608 | auto MBB = DbgValue->getParent(); |
1609 | auto DL = DbgValue->getDebugLoc(); |
1610 | auto *LScope = LScopes.findLexicalScope(DL); |
1611 | // Scope doesn't exist; this is a dead DBG_VALUE. |
1612 | if (!LScope) |
1613 | return false; |
1614 | auto &LSRange = LScope->getRanges(); |
1615 | if (LSRange.size() == 0) |
1616 | return false; |
1617 | |
1618 | const MachineInstr *LScopeBegin = LSRange.front().first; |
1619 | // If the scope starts before the DBG_VALUE then we may have a negative |
1620 | // result. Otherwise the location is live coming into the scope and we |
1621 | // can skip the following checks. |
1622 | if (!Ordering.isBefore(A: DbgValue, B: LScopeBegin)) { |
1623 | // Exit if the lexical scope begins outside of the current block. |
1624 | if (LScopeBegin->getParent() != MBB) |
1625 | return false; |
1626 | |
1627 | MachineBasicBlock::const_reverse_iterator Pred(DbgValue); |
1628 | for (++Pred; Pred != MBB->rend(); ++Pred) { |
1629 | if (Pred->getFlag(Flag: MachineInstr::FrameSetup)) |
1630 | break; |
1631 | auto PredDL = Pred->getDebugLoc(); |
1632 | if (!PredDL || Pred->isMetaInstruction()) |
1633 | continue; |
1634 | // Check whether the instruction preceding the DBG_VALUE is in the same |
1635 | // (sub)scope as the DBG_VALUE. |
1636 | if (DL->getScope() == PredDL->getScope()) |
1637 | return false; |
1638 | auto *PredScope = LScopes.findLexicalScope(DL: PredDL); |
1639 | if (!PredScope || LScope->dominates(S: PredScope)) |
1640 | return false; |
1641 | } |
1642 | } |
1643 | |
1644 | // If the range of the DBG_VALUE is open-ended, report success. |
1645 | if (!RangeEnd) |
1646 | return true; |
1647 | |
1648 | // Single, constant DBG_VALUEs in the prologue are promoted to be live |
1649 | // throughout the function. This is a hack, presumably for DWARF v2 and not |
1650 | // necessarily correct. It would be much better to use a dbg.declare instead |
1651 | // if we know the constant is live throughout the scope. |
1652 | if (MBB->pred_empty() && |
1653 | all_of(Range: DbgValue->debug_operands(), |
1654 | P: [](const MachineOperand &Op) { return Op.isImm(); })) |
1655 | return true; |
1656 | |
1657 | // Test if the location terminates before the end of the scope. |
1658 | const MachineInstr *LScopeEnd = LSRange.back().second; |
1659 | if (Ordering.isBefore(A: RangeEnd, B: LScopeEnd)) |
1660 | return false; |
1661 | |
1662 | // There's a single location which starts at the scope start, and ends at or |
1663 | // after the scope end. |
1664 | return true; |
1665 | } |
1666 | |
1667 | /// Build the location list for all DBG_VALUEs in the function that |
1668 | /// describe the same variable. The resulting DebugLocEntries will have |
1669 | /// strict monotonically increasing begin addresses and will never |
1670 | /// overlap. If the resulting list has only one entry that is valid |
1671 | /// throughout variable's scope return true. |
1672 | // |
1673 | // See the definition of DbgValueHistoryMap::Entry for an explanation of the |
1674 | // different kinds of history map entries. One thing to be aware of is that if |
1675 | // a debug value is ended by another entry (rather than being valid until the |
1676 | // end of the function), that entry's instruction may or may not be included in |
1677 | // the range, depending on if the entry is a clobbering entry (it has an |
1678 | // instruction that clobbers one or more preceding locations), or if it is an |
1679 | // (overlapping) debug value entry. This distinction can be seen in the example |
1680 | // below. The first debug value is ended by the clobbering entry 2, and the |
1681 | // second and third debug values are ended by the overlapping debug value entry |
1682 | // 4. |
1683 | // |
1684 | // Input: |
1685 | // |
1686 | // History map entries [type, end index, mi] |
1687 | // |
1688 | // 0 | [DbgValue, 2, DBG_VALUE $reg0, [...] (fragment 0, 32)] |
1689 | // 1 | | [DbgValue, 4, DBG_VALUE $reg1, [...] (fragment 32, 32)] |
1690 | // 2 | | [Clobber, $reg0 = [...], -, -] |
1691 | // 3 | | [DbgValue, 4, DBG_VALUE 123, [...] (fragment 64, 32)] |
1692 | // 4 [DbgValue, ~0, DBG_VALUE @g, [...] (fragment 0, 96)] |
1693 | // |
1694 | // Output [start, end) [Value...]: |
1695 | // |
1696 | // [0-1) [(reg0, fragment 0, 32)] |
1697 | // [1-3) [(reg0, fragment 0, 32), (reg1, fragment 32, 32)] |
1698 | // [3-4) [(reg1, fragment 32, 32), (123, fragment 64, 32)] |
1699 | // [4-) [(@g, fragment 0, 96)] |
1700 | bool DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc, |
1701 | const DbgValueHistoryMap::Entries &Entries) { |
1702 | using OpenRange = |
1703 | std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>; |
1704 | SmallVector<OpenRange, 4> OpenRanges; |
1705 | bool isSafeForSingleLocation = true; |
1706 | const MachineInstr *StartDebugMI = nullptr; |
1707 | const MachineInstr *EndMI = nullptr; |
1708 | |
1709 | for (auto EB = Entries.begin(), EI = EB, EE = Entries.end(); EI != EE; ++EI) { |
1710 | const MachineInstr *Instr = EI->getInstr(); |
1711 | |
1712 | // Remove all values that are no longer live. |
1713 | size_t Index = std::distance(first: EB, last: EI); |
1714 | erase_if(C&: OpenRanges, P: [&](OpenRange &R) { return R.first <= Index; }); |
1715 | |
1716 | // If we are dealing with a clobbering entry, this iteration will result in |
1717 | // a location list entry starting after the clobbering instruction. |
1718 | const MCSymbol *StartLabel = |
1719 | EI->isClobber() ? getLabelAfterInsn(MI: Instr) : getLabelBeforeInsn(MI: Instr); |
1720 | assert(StartLabel && |
1721 | "Forgot label before/after instruction starting a range!" ); |
1722 | |
1723 | const MCSymbol *EndLabel; |
1724 | if (std::next(x: EI) == Entries.end()) { |
1725 | const MachineBasicBlock &EndMBB = Asm->MF->back(); |
1726 | EndLabel = Asm->MBBSectionRanges[EndMBB.getSectionID()].EndLabel; |
1727 | if (EI->isClobber()) |
1728 | EndMI = EI->getInstr(); |
1729 | } |
1730 | else if (std::next(x: EI)->isClobber()) |
1731 | EndLabel = getLabelAfterInsn(MI: std::next(x: EI)->getInstr()); |
1732 | else |
1733 | EndLabel = getLabelBeforeInsn(MI: std::next(x: EI)->getInstr()); |
1734 | assert(EndLabel && "Forgot label after instruction ending a range!" ); |
1735 | |
1736 | if (EI->isDbgValue()) |
1737 | LLVM_DEBUG(dbgs() << "DotDebugLoc: " << *Instr << "\n" ); |
1738 | |
1739 | // If this history map entry has a debug value, add that to the list of |
1740 | // open ranges and check if its location is valid for a single value |
1741 | // location. |
1742 | if (EI->isDbgValue()) { |
1743 | // Do not add undef debug values, as they are redundant information in |
1744 | // the location list entries. An undef debug results in an empty location |
1745 | // description. If there are any non-undef fragments then padding pieces |
1746 | // with empty location descriptions will automatically be inserted, and if |
1747 | // all fragments are undef then the whole location list entry is |
1748 | // redundant. |
1749 | if (!Instr->isUndefDebugValue()) { |
1750 | auto Value = getDebugLocValue(MI: Instr); |
1751 | OpenRanges.emplace_back(Args: EI->getEndIndex(), Args&: Value); |
1752 | |
1753 | // TODO: Add support for single value fragment locations. |
1754 | if (Instr->getDebugExpression()->isFragment()) |
1755 | isSafeForSingleLocation = false; |
1756 | |
1757 | if (!StartDebugMI) |
1758 | StartDebugMI = Instr; |
1759 | } else { |
1760 | isSafeForSingleLocation = false; |
1761 | } |
1762 | } |
1763 | |
1764 | // Location list entries with empty location descriptions are redundant |
1765 | // information in DWARF, so do not emit those. |
1766 | if (OpenRanges.empty()) |
1767 | continue; |
1768 | |
1769 | // Omit entries with empty ranges as they do not have any effect in DWARF. |
1770 | if (StartLabel == EndLabel) { |
1771 | LLVM_DEBUG(dbgs() << "Omitting location list entry with empty range.\n" ); |
1772 | continue; |
1773 | } |
1774 | |
1775 | SmallVector<DbgValueLoc, 4> Values; |
1776 | for (auto &R : OpenRanges) |
1777 | Values.push_back(Elt: R.second); |
1778 | |
1779 | // With Basic block sections, it is posssible that the StartLabel and the |
1780 | // Instr are not in the same section. This happens when the StartLabel is |
1781 | // the function begin label and the dbg value appears in a basic block |
1782 | // that is not the entry. In this case, the range needs to be split to |
1783 | // span each individual section in the range from StartLabel to EndLabel. |
1784 | if (Asm->MF->hasBBSections() && StartLabel == Asm->getFunctionBegin() && |
1785 | !Instr->getParent()->sameSection(MBB: &Asm->MF->front())) { |
1786 | for (const auto &[MBBSectionId, MBBSectionRange] : |
1787 | Asm->MBBSectionRanges) { |
1788 | if (Instr->getParent()->getSectionID() == MBBSectionId) { |
1789 | DebugLoc.emplace_back(Args: MBBSectionRange.BeginLabel, Args&: EndLabel, Args&: Values); |
1790 | break; |
1791 | } |
1792 | DebugLoc.emplace_back(Args: MBBSectionRange.BeginLabel, |
1793 | Args: MBBSectionRange.EndLabel, Args&: Values); |
1794 | } |
1795 | } else { |
1796 | DebugLoc.emplace_back(Args&: StartLabel, Args&: EndLabel, Args&: Values); |
1797 | } |
1798 | |
1799 | // Attempt to coalesce the ranges of two otherwise identical |
1800 | // DebugLocEntries. |
1801 | auto CurEntry = DebugLoc.rbegin(); |
1802 | LLVM_DEBUG({ |
1803 | dbgs() << CurEntry->getValues().size() << " Values:\n" ; |
1804 | for (auto &Value : CurEntry->getValues()) |
1805 | Value.dump(); |
1806 | dbgs() << "-----\n" ; |
1807 | }); |
1808 | |
1809 | auto PrevEntry = std::next(x: CurEntry); |
1810 | if (PrevEntry != DebugLoc.rend() && PrevEntry->MergeRanges(Next: *CurEntry)) |
1811 | DebugLoc.pop_back(); |
1812 | } |
1813 | |
1814 | if (!isSafeForSingleLocation || |
1815 | !validThroughout(LScopes, DbgValue: StartDebugMI, RangeEnd: EndMI, Ordering: getInstOrdering())) |
1816 | return false; |
1817 | |
1818 | if (DebugLoc.size() == 1) |
1819 | return true; |
1820 | |
1821 | if (!Asm->MF->hasBBSections()) |
1822 | return false; |
1823 | |
1824 | // Check here to see if loclist can be merged into a single range. If not, |
1825 | // we must keep the split loclists per section. This does exactly what |
1826 | // MergeRanges does without sections. We don't actually merge the ranges |
1827 | // as the split ranges must be kept intact if this cannot be collapsed |
1828 | // into a single range. |
1829 | const MachineBasicBlock *RangeMBB = nullptr; |
1830 | if (DebugLoc[0].getBeginSym() == Asm->getFunctionBegin()) |
1831 | RangeMBB = &Asm->MF->front(); |
1832 | else |
1833 | RangeMBB = Entries.begin()->getInstr()->getParent(); |
1834 | auto RangeIt = Asm->MBBSectionRanges.find(Key: RangeMBB->getSectionID()); |
1835 | assert(RangeIt != Asm->MBBSectionRanges.end() && |
1836 | "Range MBB not found in MBBSectionRanges!" ); |
1837 | auto *CurEntry = DebugLoc.begin(); |
1838 | auto *NextEntry = std::next(x: CurEntry); |
1839 | auto = std::next(x: RangeIt); |
1840 | while (NextEntry != DebugLoc.end()) { |
1841 | if (NextRangeIt == Asm->MBBSectionRanges.end()) |
1842 | return false; |
1843 | // CurEntry should end the current section and NextEntry should start |
1844 | // the next section and the Values must match for these two ranges to be |
1845 | // merged. Do not match the section label end if it is the entry block |
1846 | // section. This is because the end label for the Debug Loc and the |
1847 | // Function end label could be different. |
1848 | if ((RangeIt->second.EndLabel != Asm->getFunctionEnd() && |
1849 | CurEntry->getEndSym() != RangeIt->second.EndLabel) || |
1850 | NextEntry->getBeginSym() != NextRangeIt->second.BeginLabel || |
1851 | CurEntry->getValues() != NextEntry->getValues()) |
1852 | return false; |
1853 | RangeIt = NextRangeIt; |
1854 | NextRangeIt = std::next(x: RangeIt); |
1855 | CurEntry = NextEntry; |
1856 | NextEntry = std::next(x: CurEntry); |
1857 | } |
1858 | return true; |
1859 | } |
1860 | |
1861 | DbgEntity *DwarfDebug::createConcreteEntity(DwarfCompileUnit &TheCU, |
1862 | LexicalScope &Scope, |
1863 | const DINode *Node, |
1864 | const DILocation *Location, |
1865 | const MCSymbol *Sym) { |
1866 | ensureAbstractEntityIsCreatedIfScoped(CU&: TheCU, Node, ScopeNode: Scope.getScopeNode()); |
1867 | if (isa<const DILocalVariable>(Val: Node)) { |
1868 | ConcreteEntities.push_back( |
1869 | Elt: std::make_unique<DbgVariable>(args: cast<const DILocalVariable>(Val: Node), |
1870 | args&: Location)); |
1871 | InfoHolder.addScopeVariable(LS: &Scope, |
1872 | Var: cast<DbgVariable>(Val: ConcreteEntities.back().get())); |
1873 | } else if (isa<const DILabel>(Val: Node)) { |
1874 | ConcreteEntities.push_back( |
1875 | Elt: std::make_unique<DbgLabel>(args: cast<const DILabel>(Val: Node), |
1876 | args&: Location, args&: Sym)); |
1877 | InfoHolder.addScopeLabel(LS: &Scope, |
1878 | Label: cast<DbgLabel>(Val: ConcreteEntities.back().get())); |
1879 | } |
1880 | return ConcreteEntities.back().get(); |
1881 | } |
1882 | |
1883 | // Find variables for each lexical scope. |
1884 | void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU, |
1885 | const DISubprogram *SP, |
1886 | DenseSet<InlinedEntity> &Processed) { |
1887 | // Grab the variable info that was squirreled away in the MMI side-table. |
1888 | collectVariableInfoFromMFTable(TheCU, Processed); |
1889 | |
1890 | for (const auto &I : DbgValues) { |
1891 | InlinedEntity IV = I.first; |
1892 | if (Processed.count(V: IV)) |
1893 | continue; |
1894 | |
1895 | // Instruction ranges, specifying where IV is accessible. |
1896 | const auto &HistoryMapEntries = I.second; |
1897 | |
1898 | // Try to find any non-empty variable location. Do not create a concrete |
1899 | // entity if there are no locations. |
1900 | if (!DbgValues.hasNonEmptyLocation(Entries: HistoryMapEntries)) |
1901 | continue; |
1902 | |
1903 | LexicalScope *Scope = nullptr; |
1904 | const DILocalVariable *LocalVar = cast<DILocalVariable>(Val: IV.first); |
1905 | if (const DILocation *IA = IV.second) |
1906 | Scope = LScopes.findInlinedScope(N: LocalVar->getScope(), IA); |
1907 | else |
1908 | Scope = LScopes.findLexicalScope(N: LocalVar->getScope()); |
1909 | // If variable scope is not found then skip this variable. |
1910 | if (!Scope) |
1911 | continue; |
1912 | |
1913 | Processed.insert(V: IV); |
1914 | DbgVariable *RegVar = cast<DbgVariable>(Val: createConcreteEntity(TheCU, |
1915 | Scope&: *Scope, Node: LocalVar, Location: IV.second)); |
1916 | |
1917 | const MachineInstr *MInsn = HistoryMapEntries.front().getInstr(); |
1918 | assert(MInsn->isDebugValue() && "History must begin with debug value" ); |
1919 | |
1920 | // Check if there is a single DBG_VALUE, valid throughout the var's scope. |
1921 | // If the history map contains a single debug value, there may be an |
1922 | // additional entry which clobbers the debug value. |
1923 | size_t HistSize = HistoryMapEntries.size(); |
1924 | bool SingleValueWithClobber = |
1925 | HistSize == 2 && HistoryMapEntries[1].isClobber(); |
1926 | if (HistSize == 1 || SingleValueWithClobber) { |
1927 | const auto *End = |
1928 | SingleValueWithClobber ? HistoryMapEntries[1].getInstr() : nullptr; |
1929 | if (validThroughout(LScopes, DbgValue: MInsn, RangeEnd: End, Ordering: getInstOrdering())) { |
1930 | RegVar->emplace<Loc::Single>(args&: MInsn); |
1931 | continue; |
1932 | } |
1933 | } |
1934 | |
1935 | // Handle multiple DBG_VALUE instructions describing one variable. |
1936 | DebugLocStream::ListBuilder List(DebugLocs, TheCU, *Asm, *RegVar); |
1937 | |
1938 | // Build the location list for this variable. |
1939 | SmallVector<DebugLocEntry, 8> Entries; |
1940 | bool isValidSingleLocation = buildLocationList(DebugLoc&: Entries, Entries: HistoryMapEntries); |
1941 | |
1942 | // Check whether buildLocationList managed to merge all locations to one |
1943 | // that is valid throughout the variable's scope. If so, produce single |
1944 | // value location. |
1945 | if (isValidSingleLocation) { |
1946 | RegVar->emplace<Loc::Single>(args: Entries[0].getValues()[0]); |
1947 | continue; |
1948 | } |
1949 | |
1950 | // If the variable has a DIBasicType, extract it. Basic types cannot have |
1951 | // unique identifiers, so don't bother resolving the type with the |
1952 | // identifier map. |
1953 | const DIBasicType *BT = dyn_cast<DIBasicType>( |
1954 | Val: static_cast<const Metadata *>(LocalVar->getType())); |
1955 | |
1956 | // Finalize the entry by lowering it into a DWARF bytestream. |
1957 | for (auto &Entry : Entries) |
1958 | Entry.finalize(AP: *Asm, List, BT, TheCU); |
1959 | } |
1960 | |
1961 | // For each InlinedEntity collected from DBG_LABEL instructions, convert to |
1962 | // DWARF-related DbgLabel. |
1963 | for (const auto &I : DbgLabels) { |
1964 | InlinedEntity IL = I.first; |
1965 | const MachineInstr *MI = I.second; |
1966 | if (MI == nullptr) |
1967 | continue; |
1968 | |
1969 | LexicalScope *Scope = nullptr; |
1970 | const DILabel *Label = cast<DILabel>(Val: IL.first); |
1971 | // The scope could have an extra lexical block file. |
1972 | const DILocalScope *LocalScope = |
1973 | Label->getScope()->getNonLexicalBlockFileScope(); |
1974 | // Get inlined DILocation if it is inlined label. |
1975 | if (const DILocation *IA = IL.second) |
1976 | Scope = LScopes.findInlinedScope(N: LocalScope, IA); |
1977 | else |
1978 | Scope = LScopes.findLexicalScope(N: LocalScope); |
1979 | // If label scope is not found then skip this label. |
1980 | if (!Scope) |
1981 | continue; |
1982 | |
1983 | Processed.insert(V: IL); |
1984 | /// At this point, the temporary label is created. |
1985 | /// Save the temporary label to DbgLabel entity to get the |
1986 | /// actually address when generating Dwarf DIE. |
1987 | MCSymbol *Sym = getLabelBeforeInsn(MI); |
1988 | createConcreteEntity(TheCU, Scope&: *Scope, Node: Label, Location: IL.second, Sym); |
1989 | } |
1990 | |
1991 | // Collect info for retained nodes. |
1992 | for (const DINode *DN : SP->getRetainedNodes()) { |
1993 | const auto *LS = getRetainedNodeScope(N: DN); |
1994 | if (isa<DILocalVariable>(Val: DN) || isa<DILabel>(Val: DN)) { |
1995 | if (!Processed.insert(V: InlinedEntity(DN, nullptr)).second) |
1996 | continue; |
1997 | LexicalScope *LexS = LScopes.findLexicalScope(N: LS); |
1998 | if (LexS) |
1999 | createConcreteEntity(TheCU, Scope&: *LexS, Node: DN, Location: nullptr); |
2000 | } else { |
2001 | LocalDeclsPerLS[LS].insert(X: DN); |
2002 | } |
2003 | } |
2004 | } |
2005 | |
2006 | // Process beginning of an instruction. |
2007 | void DwarfDebug::beginInstruction(const MachineInstr *MI) { |
2008 | const MachineFunction &MF = *MI->getMF(); |
2009 | const auto *SP = MF.getFunction().getSubprogram(); |
2010 | bool NoDebug = |
2011 | !SP || SP->getUnit()->getEmissionKind() == DICompileUnit::NoDebug; |
2012 | |
2013 | // Delay slot support check. |
2014 | auto delaySlotSupported = [](const MachineInstr &MI) { |
2015 | if (!MI.isBundledWithSucc()) |
2016 | return false; |
2017 | auto Suc = std::next(x: MI.getIterator()); |
2018 | (void)Suc; |
2019 | // Ensure that delay slot instruction is successor of the call instruction. |
2020 | // Ex. CALL_INSTRUCTION { |
2021 | // DELAY_SLOT_INSTRUCTION } |
2022 | assert(Suc->isBundledWithPred() && |
2023 | "Call bundle instructions are out of order" ); |
2024 | return true; |
2025 | }; |
2026 | |
2027 | // When describing calls, we need a label for the call instruction. |
2028 | if (!NoDebug && SP->areAllCallsDescribed() && |
2029 | MI->isCandidateForAdditionalCallInfo(Type: MachineInstr::AnyInBundle) && |
2030 | (!MI->hasDelaySlot() || delaySlotSupported(*MI))) { |
2031 | const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); |
2032 | bool IsTail = TII->isTailCall(Inst: *MI); |
2033 | // For tail calls, we need the address of the branch instruction for |
2034 | // DW_AT_call_pc. |
2035 | if (IsTail) |
2036 | requestLabelBeforeInsn(MI); |
2037 | // For non-tail calls, we need the return address for the call for |
2038 | // DW_AT_call_return_pc. Under GDB tuning, this information is needed for |
2039 | // tail calls as well. |
2040 | requestLabelAfterInsn(MI); |
2041 | } |
2042 | |
2043 | DebugHandlerBase::beginInstruction(MI); |
2044 | if (!CurMI) |
2045 | return; |
2046 | |
2047 | if (NoDebug) |
2048 | return; |
2049 | |
2050 | // Check if source location changes, but ignore DBG_VALUE and CFI locations. |
2051 | // If the instruction is part of the function frame setup code, do not emit |
2052 | // any line record, as there is no correspondence with any user code. |
2053 | if (MI->isMetaInstruction() || MI->getFlag(Flag: MachineInstr::FrameSetup)) |
2054 | return; |
2055 | const DebugLoc &DL = MI->getDebugLoc(); |
2056 | unsigned Flags = 0; |
2057 | |
2058 | if (MI->getFlag(Flag: MachineInstr::FrameDestroy) && DL) { |
2059 | const MachineBasicBlock *MBB = MI->getParent(); |
2060 | if (MBB && (MBB != EpilogBeginBlock)) { |
2061 | // First time FrameDestroy has been seen in this basic block |
2062 | EpilogBeginBlock = MBB; |
2063 | Flags |= DWARF2_FLAG_EPILOGUE_BEGIN; |
2064 | } |
2065 | } |
2066 | |
2067 | auto RecordSourceLine = [this](auto &DL, auto Flags) { |
2068 | SmallString<128> LocationString; |
2069 | if (Asm->OutStreamer->isVerboseAsm()) { |
2070 | raw_svector_ostream OS(LocationString); |
2071 | DL.print(OS); |
2072 | } |
2073 | recordSourceLine(Line: DL.getLine(), Col: DL.getCol(), Scope: DL.getScope(), Flags, |
2074 | Location: LocationString); |
2075 | }; |
2076 | |
2077 | // When we emit a line-0 record, we don't update PrevInstLoc; so look at |
2078 | // the last line number actually emitted, to see if it was line 0. |
2079 | unsigned LastAsmLine = |
2080 | Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine(); |
2081 | |
2082 | // There may be a mixture of scopes using and not using Key Instructions. |
2083 | // Not-Key-Instructions functions inlined into Key Instructions functions |
2084 | // should use not-key is_stmt handling. Key Instructions functions inlined |
2085 | // into Not-Key-Instructions functions should use Key Instructions is_stmt |
2086 | // handling. |
2087 | bool ScopeUsesKeyInstructions = |
2088 | KeyInstructionsAreStmts && DL && |
2089 | DL->getScope()->getSubprogram()->getKeyInstructionsEnabled(); |
2090 | |
2091 | bool IsKey = false; |
2092 | if (ScopeUsesKeyInstructions && DL && DL.getLine()) |
2093 | IsKey = KeyInstructions.contains(V: MI); |
2094 | |
2095 | if (!DL && MI == PrologEndLoc) { |
2096 | // In rare situations, we might want to place the end of the prologue |
2097 | // somewhere that doesn't have a source location already. It should be in |
2098 | // the entry block. |
2099 | assert(MI->getParent() == &*MI->getMF()->begin()); |
2100 | recordSourceLine(Line: SP->getScopeLine(), Col: 0, Scope: SP, |
2101 | DWARF2_FLAG_PROLOGUE_END | DWARF2_FLAG_IS_STMT); |
2102 | return; |
2103 | } |
2104 | |
2105 | bool PrevInstInSameSection = |
2106 | (!PrevInstBB || |
2107 | PrevInstBB->getSectionID() == MI->getParent()->getSectionID()); |
2108 | bool ForceIsStmt = ForceIsStmtInstrs.contains(V: MI); |
2109 | if (PrevInstInSameSection && !ForceIsStmt && DL.isSameSourceLocation(Other: PrevInstLoc)) { |
2110 | // If we have an ongoing unspecified location, nothing to do here. |
2111 | if (!DL) |
2112 | return; |
2113 | |
2114 | // Skip this if the instruction is Key, else we might accidentally miss an |
2115 | // is_stmt. |
2116 | if (!IsKey) { |
2117 | // We have an explicit location, same as the previous location. |
2118 | // But we might be coming back to it after a line 0 record. |
2119 | if ((LastAsmLine == 0 && DL.getLine() != 0) || Flags) { |
2120 | // Reinstate the source location but not marked as a statement. |
2121 | RecordSourceLine(DL, Flags); |
2122 | } |
2123 | return; |
2124 | } |
2125 | } |
2126 | |
2127 | if (!DL) { |
2128 | // FIXME: We could assert that `DL.getKind() != DebugLocKind::Temporary` |
2129 | // here, or otherwise record any temporary DebugLocs seen to ensure that |
2130 | // transient compiler-generated instructions aren't leaking their DLs to |
2131 | // other instructions. |
2132 | // We have an unspecified location, which might want to be line 0. |
2133 | // If we have already emitted a line-0 record, don't repeat it. |
2134 | if (LastAsmLine == 0) |
2135 | return; |
2136 | // If user said Don't Do That, don't do that. |
2137 | if (UnknownLocations == Disable) |
2138 | return; |
2139 | // See if we have a reason to emit a line-0 record now. |
2140 | // Reasons to emit a line-0 record include: |
2141 | // - User asked for it (UnknownLocations). |
2142 | // - Instruction has a label, so it's referenced from somewhere else, |
2143 | // possibly debug information; we want it to have a source location. |
2144 | // - Instruction is at the top of a block; we don't want to inherit the |
2145 | // location from the physically previous (maybe unrelated) block. |
2146 | if (UnknownLocations == Enable || PrevLabel || |
2147 | (PrevInstBB && PrevInstBB != MI->getParent())) { |
2148 | // Preserve the file and column numbers, if we can, to save space in |
2149 | // the encoded line table. |
2150 | // Do not update PrevInstLoc, it remembers the last non-0 line. |
2151 | const MDNode *Scope = nullptr; |
2152 | unsigned Column = 0; |
2153 | if (PrevInstLoc) { |
2154 | Scope = PrevInstLoc.getScope(); |
2155 | Column = PrevInstLoc.getCol(); |
2156 | } |
2157 | recordSourceLine(/*Line=*/0, Col: Column, Scope, /*Flags=*/0); |
2158 | } |
2159 | return; |
2160 | } |
2161 | |
2162 | // We have an explicit location, different from the previous location. |
2163 | // Don't repeat a line-0 record, but otherwise emit the new location. |
2164 | // (The new location might be an explicit line 0, which we do emit.) |
2165 | if (DL.getLine() == 0 && LastAsmLine == 0) |
2166 | return; |
2167 | if (MI == PrologEndLoc) { |
2168 | Flags |= DWARF2_FLAG_PROLOGUE_END | DWARF2_FLAG_IS_STMT; |
2169 | PrologEndLoc = nullptr; |
2170 | } |
2171 | |
2172 | if (ScopeUsesKeyInstructions) { |
2173 | if (IsKey) |
2174 | Flags |= DWARF2_FLAG_IS_STMT; |
2175 | } else { |
2176 | // If the line changed, we call that a new statement; unless we went to |
2177 | // line 0 and came back, in which case it is not a new statement. |
2178 | unsigned OldLine = PrevInstLoc ? PrevInstLoc.getLine() : LastAsmLine; |
2179 | if (DL.getLine() && (DL.getLine() != OldLine || ForceIsStmt)) |
2180 | Flags |= DWARF2_FLAG_IS_STMT; |
2181 | } |
2182 | |
2183 | RecordSourceLine(DL, Flags); |
2184 | |
2185 | // If we're not at line 0, remember this location. |
2186 | if (DL.getLine()) |
2187 | PrevInstLoc = DL; |
2188 | } |
2189 | |
2190 | static std::pair<const MachineInstr *, bool> |
2191 | findPrologueEndLoc(const MachineFunction *MF) { |
2192 | // First known non-DBG_VALUE and non-frame setup location marks |
2193 | // the beginning of the function body. |
2194 | const auto &TII = *MF->getSubtarget().getInstrInfo(); |
2195 | const MachineInstr *NonTrivialInst = nullptr; |
2196 | const Function &F = MF->getFunction(); |
2197 | |
2198 | // Some instructions may be inserted into prologue after this function. Must |
2199 | // keep prologue for these cases. |
2200 | bool IsEmptyPrologue = |
2201 | !(F.hasPrologueData() || F.getMetadata(KindID: LLVMContext::MD_func_sanitize)); |
2202 | |
2203 | // Helper lambda to examine each instruction and potentially return it |
2204 | // as the prologue_end point. |
2205 | auto ExamineInst = [&](const MachineInstr &MI) |
2206 | -> std::optional<std::pair<const MachineInstr *, bool>> { |
2207 | // Is this instruction trivial data shuffling or frame-setup? |
2208 | bool isCopy = (TII.isCopyInstr(MI) ? true : false); |
2209 | bool isTrivRemat = TII.isTriviallyReMaterializable(MI); |
2210 | bool isFrameSetup = MI.getFlag(Flag: MachineInstr::FrameSetup); |
2211 | |
2212 | if (!isFrameSetup && MI.getDebugLoc()) { |
2213 | // Scan forward to try to find a non-zero line number. The |
2214 | // prologue_end marks the first breakpoint in the function after the |
2215 | // frame setup, and a compiler-generated line 0 location is not a |
2216 | // meaningful breakpoint. If none is found, return the first |
2217 | // location after the frame setup. |
2218 | if (MI.getDebugLoc().getLine()) |
2219 | return std::make_pair(x: &MI, y&: IsEmptyPrologue); |
2220 | } |
2221 | |
2222 | // Keep track of the first "non-trivial" instruction seen, i.e. anything |
2223 | // that doesn't involve shuffling data around or is a frame-setup. |
2224 | if (!isCopy && !isTrivRemat && !isFrameSetup && !NonTrivialInst) |
2225 | NonTrivialInst = &MI; |
2226 | |
2227 | IsEmptyPrologue = false; |
2228 | return std::nullopt; |
2229 | }; |
2230 | |
2231 | // Examine all the instructions at the start of the function. This doesn't |
2232 | // necessarily mean just the entry block: unoptimised code can fall-through |
2233 | // into an initial loop, and it makes sense to put the initial breakpoint on |
2234 | // the first instruction of such a loop. However, if we pass branches, we're |
2235 | // better off synthesising an early prologue_end. |
2236 | auto CurBlock = MF->begin(); |
2237 | auto CurInst = CurBlock->begin(); |
2238 | |
2239 | // Find the initial instruction, we're guaranteed one by the caller, but not |
2240 | // which block it's in. |
2241 | while (CurBlock->empty()) |
2242 | CurInst = (++CurBlock)->begin(); |
2243 | assert(CurInst != CurBlock->end()); |
2244 | |
2245 | // Helper function for stepping through the initial sequence of |
2246 | // unconditionally executed instructions. |
2247 | auto getNextInst = [&CurBlock, &CurInst, MF]() -> bool { |
2248 | // We've reached the end of the block. Did we just look at a terminator? |
2249 | if (CurInst->isTerminator()) { |
2250 | // Some kind of "real" control flow is occurring. At the very least |
2251 | // we would have to start exploring the CFG, a good signal that the |
2252 | // prologue is over. |
2253 | return false; |
2254 | } |
2255 | |
2256 | // If we've already fallen through into a loop, don't fall through |
2257 | // further, use a backup-location. |
2258 | if (CurBlock->pred_size() > 1) |
2259 | return false; |
2260 | |
2261 | // Fall-through from entry to the next block. This is common at -O0 when |
2262 | // there's no initialisation in the function. Bail if we're also at the |
2263 | // end of the function, or the remaining blocks have no instructions. |
2264 | // Skip empty blocks, in rare cases the entry can be empty, and |
2265 | // other optimisations may add empty blocks that the control flow falls |
2266 | // through. |
2267 | do { |
2268 | ++CurBlock; |
2269 | if (CurBlock == MF->end()) |
2270 | return false; |
2271 | } while (CurBlock->empty()); |
2272 | CurInst = CurBlock->begin(); |
2273 | return true; |
2274 | }; |
2275 | |
2276 | while (true) { |
2277 | // Check whether this non-meta instruction a good position for prologue_end. |
2278 | if (!CurInst->isMetaInstruction()) { |
2279 | auto FoundInst = ExamineInst(*CurInst); |
2280 | if (FoundInst) |
2281 | return *FoundInst; |
2282 | } |
2283 | |
2284 | // Try to continue searching, but use a backup-location if substantive |
2285 | // computation is happening. |
2286 | auto NextInst = std::next(x: CurInst); |
2287 | if (NextInst != CurInst->getParent()->end()) { |
2288 | // Continue examining the current block. |
2289 | CurInst = NextInst; |
2290 | continue; |
2291 | } |
2292 | |
2293 | if (!getNextInst()) |
2294 | break; |
2295 | } |
2296 | |
2297 | // We couldn't find any source-location, suggesting all meaningful information |
2298 | // got optimised away. Set the prologue_end to be the first non-trivial |
2299 | // instruction, which will get the scope line number. This is better than |
2300 | // nothing. |
2301 | // Only do this in the entry block, as we'll be giving it the scope line for |
2302 | // the function. Return IsEmptyPrologue==true if we've picked the first |
2303 | // instruction. |
2304 | if (NonTrivialInst && NonTrivialInst->getParent() == &*MF->begin()) { |
2305 | IsEmptyPrologue = NonTrivialInst == &*MF->begin()->begin(); |
2306 | return std::make_pair(x&: NonTrivialInst, y&: IsEmptyPrologue); |
2307 | } |
2308 | |
2309 | // If the entry path is empty, just don't have a prologue_end at all. |
2310 | return std::make_pair(x: nullptr, y&: IsEmptyPrologue); |
2311 | } |
2312 | |
2313 | /// Register a source line with debug info. Returns the unique label that was |
2314 | /// emitted and which provides correspondence to the source line list. |
2315 | static void recordSourceLine(AsmPrinter &Asm, unsigned Line, unsigned Col, |
2316 | const MDNode *S, unsigned Flags, unsigned CUID, |
2317 | uint16_t DwarfVersion, |
2318 | ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs, |
2319 | StringRef = {}) { |
2320 | StringRef Fn; |
2321 | unsigned FileNo = 1; |
2322 | unsigned Discriminator = 0; |
2323 | if (auto *Scope = cast_or_null<DIScope>(Val: S)) { |
2324 | Fn = Scope->getFilename(); |
2325 | if (Line != 0 && DwarfVersion >= 4) |
2326 | if (auto *LBF = dyn_cast<DILexicalBlockFile>(Val: Scope)) |
2327 | Discriminator = LBF->getDiscriminator(); |
2328 | |
2329 | FileNo = static_cast<DwarfCompileUnit &>(*DCUs[CUID]) |
2330 | .getOrCreateSourceID(File: Scope->getFile()); |
2331 | } |
2332 | Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Column: Col, Flags, Isa: 0, |
2333 | Discriminator, FileName: Fn, Comment); |
2334 | } |
2335 | |
2336 | const MachineInstr * |
2337 | DwarfDebug::emitInitialLocDirective(const MachineFunction &MF, unsigned CUID) { |
2338 | // Don't deal with functions that have no instructions. |
2339 | if (llvm::all_of(Range: MF, P: [](const MachineBasicBlock &MBB) { return MBB.empty(); })) |
2340 | return nullptr; |
2341 | |
2342 | std::pair<const MachineInstr *, bool> PrologEnd = findPrologueEndLoc(MF: &MF); |
2343 | const MachineInstr *PrologEndLoc = PrologEnd.first; |
2344 | bool IsEmptyPrologue = PrologEnd.second; |
2345 | |
2346 | // If the prolog is empty, no need to generate scope line for the proc. |
2347 | if (IsEmptyPrologue) { |
2348 | // If there's nowhere to put a prologue_end flag, emit a scope line in case |
2349 | // there are simply no source locations anywhere in the function. |
2350 | if (PrologEndLoc) { |
2351 | // Avoid trying to assign prologue_end to a line-zero location. |
2352 | // Instructions with no DebugLoc at all are fine, they'll be given the |
2353 | // scope line nuumber. |
2354 | const DebugLoc &DL = PrologEndLoc->getDebugLoc(); |
2355 | if (!DL || DL->getLine() != 0) |
2356 | return PrologEndLoc; |
2357 | |
2358 | // Later, don't place the prologue_end flag on this line-zero location. |
2359 | PrologEndLoc = nullptr; |
2360 | } |
2361 | } |
2362 | |
2363 | // Ensure the compile unit is created if the function is called before |
2364 | // beginFunction(). |
2365 | DISubprogram *SP = MF.getFunction().getSubprogram(); |
2366 | (void)getOrCreateDwarfCompileUnit(DIUnit: SP->getUnit()); |
2367 | // We'd like to list the prologue as "not statements" but GDB behaves |
2368 | // poorly if we do that. Revisit this with caution/GDB (7.5+) testing. |
2369 | ::recordSourceLine(Asm&: *Asm, Line: SP->getScopeLine(), Col: 0, S: SP, DWARF2_FLAG_IS_STMT, |
2370 | CUID, DwarfVersion: getDwarfVersion(), DCUs: getUnits()); |
2371 | return PrologEndLoc; |
2372 | } |
2373 | |
2374 | void DwarfDebug::computeKeyInstructions(const MachineFunction *MF) { |
2375 | // New function - reset KeyInstructions. |
2376 | KeyInstructions.clear(); |
2377 | |
2378 | // The current candidate is_stmt instructions for each source atom. |
2379 | // Map {(InlinedAt, Group): (Rank, Instructions)}. |
2380 | // NOTE: Anecdotally, for a large C++ blob, 99% of the instruction |
2381 | // SmallVectors contain 2 or fewer elements; use 2 inline elements. |
2382 | DenseMap<std::pair<DILocation *, uint64_t>, |
2383 | std::pair<uint8_t, SmallVector<const MachineInstr *, 2>>> |
2384 | GroupCandidates; |
2385 | |
2386 | const auto &TII = *MF->getSubtarget().getInstrInfo(); |
2387 | |
2388 | // For each instruction: |
2389 | // * Skip insts without DebugLoc, AtomGroup or AtomRank, and line zeros. |
2390 | // * Check if insts in this group have been seen already in GroupCandidates. |
2391 | // * If this instr rank is equal, add this instruction to GroupCandidates. |
2392 | // Remove existing instructions from GroupCandidates if they have the |
2393 | // same parent. |
2394 | // * If this instr rank is higher (lower precedence), ignore it. |
2395 | // * If this instr rank is lower (higher precedence), erase existing |
2396 | // instructions from GroupCandidates and add this one. |
2397 | // |
2398 | // Then insert each GroupCandidates instruction into KeyInstructions. |
2399 | |
2400 | for (auto &MBB : *MF) { |
2401 | // Rather than apply is_stmt directly to Key Instructions, we "float" |
2402 | // is_stmt up to the 1st instruction with the same line number in a |
2403 | // contiguous block. That instruction is called the "buoy". The |
2404 | // buoy gets reset if we encouner an instruction with an atom |
2405 | // group. |
2406 | const MachineInstr *Buoy = nullptr; |
2407 | // The atom group number associated with Buoy which may be 0 if we haven't |
2408 | // encountered an atom group yet in this blob of instructions with the same |
2409 | // line number. |
2410 | uint64_t BuoyAtom = 0; |
2411 | |
2412 | for (auto &MI : MBB) { |
2413 | if (MI.isMetaInstruction()) |
2414 | continue; |
2415 | |
2416 | const DILocation *Loc = MI.getDebugLoc().get(); |
2417 | if (!Loc || !Loc->getLine()) |
2418 | continue; |
2419 | |
2420 | // Reset the Buoy to this instruction if it has a different line number. |
2421 | if (!Buoy || Buoy->getDebugLoc().getLine() != Loc->getLine()) { |
2422 | Buoy = &MI; |
2423 | BuoyAtom = 0; // Set later when we know which atom the buoy is used by. |
2424 | } |
2425 | |
2426 | // Call instructions are handled specially - we always mark them as key |
2427 | // regardless of atom info. |
2428 | bool IsCallLike = MI.isCall() || TII.isTailCall(Inst: MI); |
2429 | if (IsCallLike) { |
2430 | // Calls are always key. Put the buoy (may not be the call) into |
2431 | // KeyInstructions directly rather than the candidate map to avoid it |
2432 | // being erased (and we may not have a group number for the call). |
2433 | KeyInstructions.insert(V: Buoy); |
2434 | |
2435 | // Avoid floating any future is_stmts up to the call. |
2436 | Buoy = nullptr; |
2437 | BuoyAtom = 0; |
2438 | |
2439 | if (!Loc->getAtomGroup() || !Loc->getAtomRank()) |
2440 | continue; |
2441 | } |
2442 | |
2443 | auto *InlinedAt = Loc->getInlinedAt(); |
2444 | uint64_t Group = Loc->getAtomGroup(); |
2445 | uint8_t Rank = Loc->getAtomRank(); |
2446 | if (!Group || !Rank) |
2447 | continue; |
2448 | |
2449 | // Don't let is_stmts float past instructions from different source atoms. |
2450 | if (BuoyAtom && BuoyAtom != Group) { |
2451 | Buoy = &MI; |
2452 | BuoyAtom = Group; |
2453 | } |
2454 | |
2455 | auto &[CandidateRank, CandidateInsts] = |
2456 | GroupCandidates[{InlinedAt, Group}]; |
2457 | |
2458 | // If CandidateRank is zero then CandidateInsts should be empty: there |
2459 | // are no other candidates for this group yet. If CandidateRank is nonzero |
2460 | // then CandidateInsts shouldn't be empty: we've got existing candidate |
2461 | // instructions. |
2462 | assert((CandidateRank == 0 && CandidateInsts.empty()) || |
2463 | (CandidateRank != 0 && !CandidateInsts.empty())); |
2464 | |
2465 | assert(Rank && "expected nonzero rank" ); |
2466 | // If we've seen other instructions in this group with higher precedence |
2467 | // (lower nonzero rank), don't add this one as a candidate. |
2468 | if (CandidateRank && CandidateRank < Rank) |
2469 | continue; |
2470 | |
2471 | // If we've seen other instructions in this group of the same rank, |
2472 | // discard any from this block (keeping the others). Else if we've |
2473 | // seen other instructions in this group of lower precedence (higher |
2474 | // rank), discard them all. |
2475 | if (CandidateRank == Rank) |
2476 | llvm::remove_if(Range&: CandidateInsts, P: [&MI](const MachineInstr *Candidate) { |
2477 | return MI.getParent() == Candidate->getParent(); |
2478 | }); |
2479 | else if (CandidateRank > Rank) |
2480 | CandidateInsts.clear(); |
2481 | |
2482 | if (Buoy) { |
2483 | // Add this candidate. |
2484 | CandidateInsts.push_back(Elt: Buoy); |
2485 | CandidateRank = Rank; |
2486 | |
2487 | assert(!BuoyAtom || BuoyAtom == Loc->getAtomGroup()); |
2488 | BuoyAtom = Loc->getAtomGroup(); |
2489 | } else { |
2490 | // Don't add calls, because they've been dealt with already. This means |
2491 | // CandidateInsts might now be empty - handle that. |
2492 | assert(IsCallLike); |
2493 | if (CandidateInsts.empty()) |
2494 | CandidateRank = 0; |
2495 | } |
2496 | } |
2497 | } |
2498 | |
2499 | for (const auto &[_, Insts] : GroupCandidates.values()) |
2500 | for (auto *I : Insts) |
2501 | KeyInstructions.insert(V: I); |
2502 | } |
2503 | |
2504 | /// For the function \p MF, finds the set of instructions which may represent a |
2505 | /// change in line number from one or more of the preceding MBBs. Stores the |
2506 | /// resulting set of instructions, which should have is_stmt set, in |
2507 | /// ForceIsStmtInstrs. |
2508 | void DwarfDebug::findForceIsStmtInstrs(const MachineFunction *MF) { |
2509 | ForceIsStmtInstrs.clear(); |
2510 | |
2511 | // For this function, we try to find MBBs where the last source line in every |
2512 | // block predecessor matches the first line seen in the block itself; for |
2513 | // every such MBB, we set is_stmt=false on the first line in the block, and |
2514 | // for every other block we set is_stmt=true on the first line. |
2515 | // For example, if we have the block %bb.3, which has 2 predecesors %bb.1 and |
2516 | // %bb.2: |
2517 | // bb.1: |
2518 | // $r3 = MOV64ri 12, debug-location !DILocation(line: 4) |
2519 | // JMP %bb.3, debug-location !DILocation(line: 5) |
2520 | // bb.2: |
2521 | // $r3 = MOV64ri 24, debug-location !DILocation(line: 5) |
2522 | // JMP %bb.3 |
2523 | // bb.3: |
2524 | // $r2 = MOV64ri 1 |
2525 | // $r1 = ADD $r2, $r3, debug-location !DILocation(line: 5) |
2526 | // When we examine %bb.3, we first check to see if it contains any |
2527 | // instructions with debug locations, and select the first such instruction; |
2528 | // in this case, the ADD, with line=5. We then examine both of its |
2529 | // predecessors to see what the last debug-location in them is. For each |
2530 | // predecessor, if they do not contain any debug-locations, or if the last |
2531 | // debug-location before jumping to %bb.3 does not have line=5, then the ADD |
2532 | // in %bb.3 must use IsStmt. In this case, all predecessors have a |
2533 | // debug-location with line=5 as the last debug-location before jumping to |
2534 | // %bb.3, so we do not set is_stmt for the ADD instruction - we know that |
2535 | // whichever MBB we have arrived from, the line has not changed. |
2536 | |
2537 | const auto *TII = MF->getSubtarget().getInstrInfo(); |
2538 | |
2539 | // We only need to the predecessors of MBBs that could have is_stmt set by |
2540 | // this logic. |
2541 | SmallDenseSet<MachineBasicBlock *, 4> PredMBBsToExamine; |
2542 | SmallDenseMap<MachineBasicBlock *, MachineInstr *> PotentialIsStmtMBBInstrs; |
2543 | // We use const_cast even though we won't actually modify MF, because some |
2544 | // methods we need take a non-const MBB. |
2545 | for (auto &MBB : *const_cast<MachineFunction *>(MF)) { |
2546 | if (MBB.empty() || MBB.pred_empty()) |
2547 | continue; |
2548 | for (auto &MI : MBB) { |
2549 | if (MI.getDebugLoc() && MI.getDebugLoc()->getLine()) { |
2550 | PredMBBsToExamine.insert_range(R: MBB.predecessors()); |
2551 | PotentialIsStmtMBBInstrs.insert(KV: {&MBB, &MI}); |
2552 | break; |
2553 | } |
2554 | } |
2555 | } |
2556 | |
2557 | // For each predecessor MBB, we examine the last line seen before each branch |
2558 | // or logical fallthrough. We use analyzeBranch to handle cases where |
2559 | // different branches have different outgoing lines (i.e. if there are |
2560 | // multiple branches that each have their own source location); otherwise we |
2561 | // just use the last line in the block. |
2562 | for (auto *MBB : PredMBBsToExamine) { |
2563 | auto CheckMBBEdge = [&](MachineBasicBlock *Succ, unsigned OutgoingLine) { |
2564 | auto MBBInstrIt = PotentialIsStmtMBBInstrs.find(Val: Succ); |
2565 | if (MBBInstrIt == PotentialIsStmtMBBInstrs.end()) |
2566 | return; |
2567 | MachineInstr *MI = MBBInstrIt->second; |
2568 | if (MI->getDebugLoc()->getLine() == OutgoingLine) |
2569 | return; |
2570 | PotentialIsStmtMBBInstrs.erase(I: MBBInstrIt); |
2571 | ForceIsStmtInstrs.insert(V: MI); |
2572 | }; |
2573 | // If this block is empty, we conservatively assume that its fallthrough |
2574 | // successor needs is_stmt; we could check MBB's predecessors to see if it |
2575 | // has a consistent entry line, but this seems unlikely to be worthwhile. |
2576 | if (MBB->empty()) { |
2577 | for (auto *Succ : MBB->successors()) |
2578 | CheckMBBEdge(Succ, 0); |
2579 | continue; |
2580 | } |
2581 | // If MBB has no successors that are in the "potential" set, due to one or |
2582 | // more of them having confirmed is_stmt, we can skip this check early. |
2583 | if (none_of(Range: MBB->successors(), P: [&](auto *SuccMBB) { |
2584 | return PotentialIsStmtMBBInstrs.contains(Val: SuccMBB); |
2585 | })) |
2586 | continue; |
2587 | // If we can't determine what DLs this branch's successors use, just treat |
2588 | // all the successors as coming from the last DebugLoc. |
2589 | SmallVector<MachineBasicBlock *, 2> SuccessorBBs; |
2590 | auto MIIt = MBB->rbegin(); |
2591 | { |
2592 | MachineBasicBlock *TBB = nullptr, *FBB = nullptr; |
2593 | SmallVector<MachineOperand, 4> Cond; |
2594 | bool AnalyzeFailed = TII->analyzeBranch(MBB&: *MBB, TBB, FBB, Cond); |
2595 | // For a conditional branch followed by unconditional branch where the |
2596 | // unconditional branch has a DebugLoc, that loc is the outgoing loc to |
2597 | // the the false destination only; otherwise, both destinations share an |
2598 | // outgoing loc. |
2599 | if (!AnalyzeFailed && !Cond.empty() && FBB != nullptr && |
2600 | MBB->back().getDebugLoc() && MBB->back().getDebugLoc()->getLine()) { |
2601 | unsigned FBBLine = MBB->back().getDebugLoc()->getLine(); |
2602 | assert(MIIt->isBranch() && "Bad result from analyzeBranch?" ); |
2603 | CheckMBBEdge(FBB, FBBLine); |
2604 | ++MIIt; |
2605 | SuccessorBBs.push_back(Elt: TBB); |
2606 | } else { |
2607 | // For all other cases, all successors share the last outgoing DebugLoc. |
2608 | SuccessorBBs.assign(in_start: MBB->succ_begin(), in_end: MBB->succ_end()); |
2609 | } |
2610 | } |
2611 | |
2612 | // If we don't find an outgoing loc, this block will start with a line 0. |
2613 | // It is possible that we have a block that has no DebugLoc, but acts as a |
2614 | // simple passthrough between two blocks that end and start with the same |
2615 | // line, e.g.: |
2616 | // bb.1: |
2617 | // JMP %bb.2, debug-location !10 |
2618 | // bb.2: |
2619 | // JMP %bb.3 |
2620 | // bb.3: |
2621 | // $r1 = ADD $r2, $r3, debug-location !10 |
2622 | // If these blocks were merged into a single block, we would not attach |
2623 | // is_stmt to the ADD, but with this logic that only checks the immediate |
2624 | // predecessor, we will; we make this tradeoff because doing a full dataflow |
2625 | // analysis would be expensive, and these situations are probably not common |
2626 | // enough for this to be worthwhile. |
2627 | unsigned LastLine = 0; |
2628 | while (MIIt != MBB->rend()) { |
2629 | if (auto DL = MIIt->getDebugLoc(); DL && DL->getLine()) { |
2630 | LastLine = DL->getLine(); |
2631 | break; |
2632 | } |
2633 | ++MIIt; |
2634 | } |
2635 | for (auto *Succ : SuccessorBBs) |
2636 | CheckMBBEdge(Succ, LastLine); |
2637 | } |
2638 | } |
2639 | |
2640 | // Gather pre-function debug information. Assumes being called immediately |
2641 | // after the function entry point has been emitted. |
2642 | void DwarfDebug::beginFunctionImpl(const MachineFunction *MF) { |
2643 | CurFn = MF; |
2644 | |
2645 | auto *SP = MF->getFunction().getSubprogram(); |
2646 | assert(LScopes.empty() || SP == LScopes.getCurrentFunctionScope()->getScopeNode()); |
2647 | if (SP->getUnit()->getEmissionKind() == DICompileUnit::NoDebug) |
2648 | return; |
2649 | |
2650 | DwarfCompileUnit &CU = getOrCreateDwarfCompileUnit(DIUnit: SP->getUnit()); |
2651 | FunctionLineTableLabel = CU.emitFuncLineTableOffsets() |
2652 | ? Asm->OutStreamer->emitLineTableLabel() |
2653 | : nullptr; |
2654 | |
2655 | Asm->OutStreamer->getContext().setDwarfCompileUnitID( |
2656 | getDwarfCompileUnitIDForLineTable(CU)); |
2657 | |
2658 | // Record beginning of function. |
2659 | PrologEndLoc = emitInitialLocDirective( |
2660 | MF: *MF, CUID: Asm->OutStreamer->getContext().getDwarfCompileUnitID()); |
2661 | |
2662 | // Run both `findForceIsStmtInstrs` and `computeKeyInstructions` because |
2663 | // Not-Key-Instructions functions may be inlined into Key Instructions |
2664 | // functions and vice versa. |
2665 | if (KeyInstructionsAreStmts) |
2666 | computeKeyInstructions(MF); |
2667 | findForceIsStmtInstrs(MF); |
2668 | } |
2669 | |
2670 | unsigned |
2671 | DwarfDebug::getDwarfCompileUnitIDForLineTable(const DwarfCompileUnit &CU) { |
2672 | // Set DwarfDwarfCompileUnitID in MCContext to the Compile Unit this function |
2673 | // belongs to so that we add to the correct per-cu line table in the |
2674 | // non-asm case. |
2675 | if (Asm->OutStreamer->hasRawTextSupport()) |
2676 | // Use a single line table if we are generating assembly. |
2677 | return 0; |
2678 | else |
2679 | return CU.getUniqueID(); |
2680 | } |
2681 | |
2682 | void DwarfDebug::terminateLineTable(const DwarfCompileUnit *CU) { |
2683 | const auto &CURanges = CU->getRanges(); |
2684 | auto &LineTable = Asm->OutStreamer->getContext().getMCDwarfLineTable( |
2685 | CUID: getDwarfCompileUnitIDForLineTable(CU: *CU)); |
2686 | // Add the last range label for the given CU. |
2687 | LineTable.getMCLineSections().addEndEntry( |
2688 | EndLabel: const_cast<MCSymbol *>(CURanges.back().End)); |
2689 | } |
2690 | |
2691 | void DwarfDebug::skippedNonDebugFunction() { |
2692 | // If we don't have a subprogram for this function then there will be a hole |
2693 | // in the range information. Keep note of this by setting the previously used |
2694 | // section to nullptr. |
2695 | // Terminate the pending line table. |
2696 | if (PrevCU) |
2697 | terminateLineTable(CU: PrevCU); |
2698 | PrevCU = nullptr; |
2699 | CurFn = nullptr; |
2700 | } |
2701 | |
2702 | // Gather and emit post-function debug information. |
2703 | void DwarfDebug::endFunctionImpl(const MachineFunction *MF) { |
2704 | const DISubprogram *SP = MF->getFunction().getSubprogram(); |
2705 | |
2706 | assert(CurFn == MF && |
2707 | "endFunction should be called with the same function as beginFunction" ); |
2708 | |
2709 | // Set DwarfDwarfCompileUnitID in MCContext to default value. |
2710 | Asm->OutStreamer->getContext().setDwarfCompileUnitID(0); |
2711 | |
2712 | LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); |
2713 | assert(!FnScope || SP == FnScope->getScopeNode()); |
2714 | DwarfCompileUnit &TheCU = getOrCreateDwarfCompileUnit(DIUnit: SP->getUnit()); |
2715 | if (TheCU.getCUNode()->isDebugDirectivesOnly()) { |
2716 | PrevLabel = nullptr; |
2717 | CurFn = nullptr; |
2718 | return; |
2719 | } |
2720 | |
2721 | DenseSet<InlinedEntity> Processed; |
2722 | collectEntityInfo(TheCU, SP, Processed); |
2723 | |
2724 | // Add the range of this function to the list of ranges for the CU. |
2725 | // With basic block sections, add ranges for all basic block sections. |
2726 | for (const auto &R : Asm->MBBSectionRanges) |
2727 | TheCU.addRange(Range: {.Begin: R.second.BeginLabel, .End: R.second.EndLabel}); |
2728 | |
2729 | // Under -gmlt, skip building the subprogram if there are no inlined |
2730 | // subroutines inside it. But with -fdebug-info-for-profiling, the subprogram |
2731 | // is still needed as we need its source location. |
2732 | if (!TheCU.getCUNode()->getDebugInfoForProfiling() && |
2733 | TheCU.getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly && |
2734 | LScopes.getAbstractScopesList().empty() && !IsDarwin) { |
2735 | for (const auto &R : Asm->MBBSectionRanges) |
2736 | addArangeLabel(SCU: SymbolCU(&TheCU, R.second.BeginLabel)); |
2737 | |
2738 | assert(InfoHolder.getScopeVariables().empty()); |
2739 | PrevLabel = nullptr; |
2740 | CurFn = nullptr; |
2741 | return; |
2742 | } |
2743 | |
2744 | #ifndef NDEBUG |
2745 | size_t NumAbstractSubprograms = LScopes.getAbstractScopesList().size(); |
2746 | #endif |
2747 | for (LexicalScope *AScope : LScopes.getAbstractScopesList()) { |
2748 | const auto *SP = cast<DISubprogram>(Val: AScope->getScopeNode()); |
2749 | for (const DINode *DN : SP->getRetainedNodes()) { |
2750 | const auto *LS = getRetainedNodeScope(N: DN); |
2751 | // Ensure LexicalScope is created for the scope of this node. |
2752 | auto *LexS = LScopes.getOrCreateAbstractScope(Scope: LS); |
2753 | assert(LexS && "Expected the LexicalScope to be created." ); |
2754 | if (isa<DILocalVariable>(Val: DN) || isa<DILabel>(Val: DN)) { |
2755 | // Collect info for variables/labels that were optimized out. |
2756 | if (!Processed.insert(V: InlinedEntity(DN, nullptr)).second || |
2757 | TheCU.getExistingAbstractEntity(Node: DN)) |
2758 | continue; |
2759 | TheCU.createAbstractEntity(Node: DN, Scope: LexS); |
2760 | } else { |
2761 | // Remember the node if this is a local declarations. |
2762 | LocalDeclsPerLS[LS].insert(X: DN); |
2763 | } |
2764 | assert( |
2765 | LScopes.getAbstractScopesList().size() == NumAbstractSubprograms && |
2766 | "getOrCreateAbstractScope() inserted an abstract subprogram scope" ); |
2767 | } |
2768 | constructAbstractSubprogramScopeDIE(SrcCU&: TheCU, Scope: AScope); |
2769 | } |
2770 | |
2771 | ProcessedSPNodes.insert(X: SP); |
2772 | DIE &ScopeDIE = |
2773 | TheCU.constructSubprogramScopeDIE(Sub: SP, Scope: FnScope, LineTableSym: FunctionLineTableLabel); |
2774 | if (auto *SkelCU = TheCU.getSkeleton()) |
2775 | if (!LScopes.getAbstractScopesList().empty() && |
2776 | TheCU.getCUNode()->getSplitDebugInlining()) |
2777 | SkelCU->constructSubprogramScopeDIE(Sub: SP, Scope: FnScope, LineTableSym: FunctionLineTableLabel); |
2778 | |
2779 | FunctionLineTableLabel = nullptr; |
2780 | |
2781 | // Construct call site entries. |
2782 | constructCallSiteEntryDIEs(SP: *SP, CU&: TheCU, ScopeDIE, MF: *MF); |
2783 | |
2784 | // Clear debug info |
2785 | // Ownership of DbgVariables is a bit subtle - ScopeVariables owns all the |
2786 | // DbgVariables except those that are also in AbstractVariables (since they |
2787 | // can be used cross-function) |
2788 | InfoHolder.getScopeVariables().clear(); |
2789 | InfoHolder.getScopeLabels().clear(); |
2790 | LocalDeclsPerLS.clear(); |
2791 | PrevLabel = nullptr; |
2792 | CurFn = nullptr; |
2793 | } |
2794 | |
2795 | // Register a source line with debug info. Returns the unique label that was |
2796 | // emitted and which provides correspondence to the source line list. |
2797 | void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S, |
2798 | unsigned Flags, StringRef Location) { |
2799 | ::recordSourceLine(Asm&: *Asm, Line, Col, S, Flags, |
2800 | CUID: Asm->OutStreamer->getContext().getDwarfCompileUnitID(), |
2801 | DwarfVersion: getDwarfVersion(), DCUs: getUnits(), Comment: Location); |
2802 | } |
2803 | |
2804 | //===----------------------------------------------------------------------===// |
2805 | // Emit Methods |
2806 | //===----------------------------------------------------------------------===// |
2807 | |
2808 | // Emit the debug info section. |
2809 | void DwarfDebug::emitDebugInfo() { |
2810 | DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; |
2811 | Holder.emitUnits(/* UseOffsets */ false); |
2812 | } |
2813 | |
2814 | // Emit the abbreviation section. |
2815 | void DwarfDebug::emitAbbreviations() { |
2816 | DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; |
2817 | |
2818 | Holder.emitAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevSection()); |
2819 | } |
2820 | |
2821 | void DwarfDebug::() { |
2822 | DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; |
2823 | Holder.getStringPool().emitStringOffsetsTableHeader( |
2824 | Asm&: *Asm, OffsetSection: Asm->getObjFileLowering().getDwarfStrOffSection(), |
2825 | StartSym: Holder.getStringOffsetsStartSym()); |
2826 | } |
2827 | |
2828 | template <typename AccelTableT> |
2829 | void DwarfDebug::emitAccel(AccelTableT &Accel, MCSection *Section, |
2830 | StringRef TableName) { |
2831 | Asm->OutStreamer->switchSection(Section); |
2832 | |
2833 | // Emit the full data. |
2834 | emitAppleAccelTable(Asm, Accel, TableName, Section->getBeginSymbol()); |
2835 | } |
2836 | |
2837 | void DwarfDebug::emitAccelDebugNames() { |
2838 | // Don't emit anything if we have no compilation units to index. |
2839 | if (getUnits().empty()) |
2840 | return; |
2841 | |
2842 | emitDWARF5AccelTable(Asm, Contents&: AccelDebugNames, DD: *this, CUs: getUnits()); |
2843 | } |
2844 | |
2845 | // Emit visible names into a hashed accelerator table section. |
2846 | void DwarfDebug::emitAccelNames() { |
2847 | emitAccel(Accel&: AccelNames, Section: Asm->getObjFileLowering().getDwarfAccelNamesSection(), |
2848 | TableName: "Names" ); |
2849 | } |
2850 | |
2851 | // Emit objective C classes and categories into a hashed accelerator table |
2852 | // section. |
2853 | void DwarfDebug::emitAccelObjC() { |
2854 | emitAccel(Accel&: AccelObjC, Section: Asm->getObjFileLowering().getDwarfAccelObjCSection(), |
2855 | TableName: "ObjC" ); |
2856 | } |
2857 | |
2858 | // Emit namespace dies into a hashed accelerator table. |
2859 | void DwarfDebug::emitAccelNamespaces() { |
2860 | emitAccel(Accel&: AccelNamespace, |
2861 | Section: Asm->getObjFileLowering().getDwarfAccelNamespaceSection(), |
2862 | TableName: "namespac" ); |
2863 | } |
2864 | |
2865 | // Emit type dies into a hashed accelerator table. |
2866 | void DwarfDebug::emitAccelTypes() { |
2867 | emitAccel(Accel&: AccelTypes, Section: Asm->getObjFileLowering().getDwarfAccelTypesSection(), |
2868 | TableName: "types" ); |
2869 | } |
2870 | |
2871 | // Public name handling. |
2872 | // The format for the various pubnames: |
2873 | // |
2874 | // dwarf pubnames - offset/name pairs where the offset is the offset into the CU |
2875 | // for the DIE that is named. |
2876 | // |
2877 | // gnu pubnames - offset/index value/name tuples where the offset is the offset |
2878 | // into the CU and the index value is computed according to the type of value |
2879 | // for the DIE that is named. |
2880 | // |
2881 | // For type units the offset is the offset of the skeleton DIE. For split dwarf |
2882 | // it's the offset within the debug_info/debug_types dwo section, however, the |
2883 | // reference in the pubname header doesn't change. |
2884 | |
2885 | /// computeIndexValue - Compute the gdb index value for the DIE and CU. |
2886 | static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU, |
2887 | const DIE *Die) { |
2888 | // Entities that ended up only in a Type Unit reference the CU instead (since |
2889 | // the pub entry has offsets within the CU there's no real offset that can be |
2890 | // provided anyway). As it happens all such entities (namespaces and types, |
2891 | // types only in C++ at that) are rendered as TYPE+EXTERNAL. If this turns out |
2892 | // not to be true it would be necessary to persist this information from the |
2893 | // point at which the entry is added to the index data structure - since by |
2894 | // the time the index is built from that, the original type/namespace DIE in a |
2895 | // type unit has already been destroyed so it can't be queried for properties |
2896 | // like tag, etc. |
2897 | if (Die->getTag() == dwarf::DW_TAG_compile_unit) |
2898 | return dwarf::PubIndexEntryDescriptor(dwarf::GIEK_TYPE, |
2899 | dwarf::GIEL_EXTERNAL); |
2900 | dwarf::GDBIndexEntryLinkage Linkage = dwarf::GIEL_STATIC; |
2901 | |
2902 | // We could have a specification DIE that has our most of our knowledge, |
2903 | // look for that now. |
2904 | if (DIEValue SpecVal = Die->findAttribute(Attribute: dwarf::DW_AT_specification)) { |
2905 | DIE &SpecDIE = SpecVal.getDIEEntry().getEntry(); |
2906 | if (SpecDIE.findAttribute(Attribute: dwarf::DW_AT_external)) |
2907 | Linkage = dwarf::GIEL_EXTERNAL; |
2908 | } else if (Die->findAttribute(Attribute: dwarf::DW_AT_external)) |
2909 | Linkage = dwarf::GIEL_EXTERNAL; |
2910 | |
2911 | switch (Die->getTag()) { |
2912 | case dwarf::DW_TAG_class_type: |
2913 | case dwarf::DW_TAG_structure_type: |
2914 | case dwarf::DW_TAG_union_type: |
2915 | case dwarf::DW_TAG_enumeration_type: |
2916 | return dwarf::PubIndexEntryDescriptor( |
2917 | dwarf::GIEK_TYPE, |
2918 | dwarf::isCPlusPlus(S: (dwarf::SourceLanguage)CU->getLanguage()) |
2919 | ? dwarf::GIEL_EXTERNAL |
2920 | : dwarf::GIEL_STATIC); |
2921 | case dwarf::DW_TAG_typedef: |
2922 | case dwarf::DW_TAG_base_type: |
2923 | case dwarf::DW_TAG_subrange_type: |
2924 | case dwarf::DW_TAG_template_alias: |
2925 | return dwarf::PubIndexEntryDescriptor(dwarf::GIEK_TYPE, dwarf::GIEL_STATIC); |
2926 | case dwarf::DW_TAG_namespace: |
2927 | return dwarf::GIEK_TYPE; |
2928 | case dwarf::DW_TAG_subprogram: |
2929 | return dwarf::PubIndexEntryDescriptor(dwarf::GIEK_FUNCTION, Linkage); |
2930 | case dwarf::DW_TAG_variable: |
2931 | return dwarf::PubIndexEntryDescriptor(dwarf::GIEK_VARIABLE, Linkage); |
2932 | case dwarf::DW_TAG_enumerator: |
2933 | return dwarf::PubIndexEntryDescriptor(dwarf::GIEK_VARIABLE, |
2934 | dwarf::GIEL_STATIC); |
2935 | default: |
2936 | return dwarf::GIEK_NONE; |
2937 | } |
2938 | } |
2939 | |
2940 | /// emitDebugPubSections - Emit visible names and types into debug pubnames and |
2941 | /// pubtypes sections. |
2942 | void DwarfDebug::emitDebugPubSections() { |
2943 | for (const auto &NU : CUMap) { |
2944 | DwarfCompileUnit *TheU = NU.second; |
2945 | if (!TheU->hasDwarfPubSections()) |
2946 | continue; |
2947 | |
2948 | bool GnuStyle = TheU->getCUNode()->getNameTableKind() == |
2949 | DICompileUnit::DebugNameTableKind::GNU; |
2950 | |
2951 | Asm->OutStreamer->switchSection( |
2952 | Section: GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection() |
2953 | : Asm->getObjFileLowering().getDwarfPubNamesSection()); |
2954 | emitDebugPubSection(GnuStyle, Name: "Names" , TheU, Globals: TheU->getGlobalNames()); |
2955 | |
2956 | Asm->OutStreamer->switchSection( |
2957 | Section: GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection() |
2958 | : Asm->getObjFileLowering().getDwarfPubTypesSection()); |
2959 | emitDebugPubSection(GnuStyle, Name: "Types" , TheU, Globals: TheU->getGlobalTypes()); |
2960 | } |
2961 | } |
2962 | |
2963 | void DwarfDebug::emitSectionReference(const DwarfCompileUnit &CU) { |
2964 | if (useSectionsAsReferences()) |
2965 | Asm->emitDwarfOffset(Label: CU.getSection()->getBeginSymbol(), |
2966 | Offset: CU.getDebugSectionOffset()); |
2967 | else |
2968 | Asm->emitDwarfSymbolReference(Label: CU.getLabelBegin()); |
2969 | } |
2970 | |
2971 | void DwarfDebug::emitDebugPubSection(bool GnuStyle, StringRef Name, |
2972 | DwarfCompileUnit *TheU, |
2973 | const StringMap<const DIE *> &Globals) { |
2974 | if (auto *Skeleton = TheU->getSkeleton()) |
2975 | TheU = Skeleton; |
2976 | |
2977 | // Emit the header. |
2978 | MCSymbol *EndLabel = Asm->emitDwarfUnitLength( |
2979 | Prefix: "pub" + Name, Comment: "Length of Public " + Name + " Info" ); |
2980 | |
2981 | Asm->OutStreamer->AddComment(T: "DWARF Version" ); |
2982 | Asm->emitInt16(Value: dwarf::DW_PUBNAMES_VERSION); |
2983 | |
2984 | Asm->OutStreamer->AddComment(T: "Offset of Compilation Unit Info" ); |
2985 | emitSectionReference(CU: *TheU); |
2986 | |
2987 | Asm->OutStreamer->AddComment(T: "Compilation Unit Length" ); |
2988 | Asm->emitDwarfLengthOrOffset(Value: TheU->getLength()); |
2989 | |
2990 | // Emit the pubnames for this compilation unit. |
2991 | SmallVector<std::pair<StringRef, const DIE *>, 0> Vec; |
2992 | for (const auto &GI : Globals) |
2993 | Vec.emplace_back(Args: GI.first(), Args: GI.second); |
2994 | llvm::sort(C&: Vec, Comp: [](auto &A, auto &B) { |
2995 | return A.second->getOffset() < B.second->getOffset(); |
2996 | }); |
2997 | for (const auto &[Name, Entity] : Vec) { |
2998 | Asm->OutStreamer->AddComment(T: "DIE offset" ); |
2999 | Asm->emitDwarfLengthOrOffset(Value: Entity->getOffset()); |
3000 | |
3001 | if (GnuStyle) { |
3002 | dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(CU: TheU, Die: Entity); |
3003 | Asm->OutStreamer->AddComment( |
3004 | T: Twine("Attributes: " ) + dwarf::GDBIndexEntryKindString(Kind: Desc.Kind) + |
3005 | ", " + dwarf::GDBIndexEntryLinkageString(Linkage: Desc.Linkage)); |
3006 | Asm->emitInt8(Value: Desc.toBits()); |
3007 | } |
3008 | |
3009 | Asm->OutStreamer->AddComment(T: "External Name" ); |
3010 | Asm->OutStreamer->emitBytes(Data: StringRef(Name.data(), Name.size() + 1)); |
3011 | } |
3012 | |
3013 | Asm->OutStreamer->AddComment(T: "End Mark" ); |
3014 | Asm->emitDwarfLengthOrOffset(Value: 0); |
3015 | Asm->OutStreamer->emitLabel(Symbol: EndLabel); |
3016 | } |
3017 | |
3018 | /// Emit null-terminated strings into a debug str section. |
3019 | void DwarfDebug::emitDebugStr() { |
3020 | MCSection *StringOffsetsSection = nullptr; |
3021 | if (useSegmentedStringOffsetsTable()) { |
3022 | emitStringOffsetsTableHeader(); |
3023 | StringOffsetsSection = Asm->getObjFileLowering().getDwarfStrOffSection(); |
3024 | } |
3025 | DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; |
3026 | Holder.emitStrings(StrSection: Asm->getObjFileLowering().getDwarfStrSection(), |
3027 | OffsetSection: StringOffsetsSection, /* UseRelativeOffsets = */ true); |
3028 | } |
3029 | |
3030 | void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer, |
3031 | const DebugLocStream::Entry &Entry, |
3032 | const DwarfCompileUnit *CU) { |
3033 | auto && = DebugLocs.getComments(E: Entry); |
3034 | auto = Comments.begin(); |
3035 | auto End = Comments.end(); |
3036 | |
3037 | // The expressions are inserted into a byte stream rather early (see |
3038 | // DwarfExpression::addExpression) so for those ops (e.g. DW_OP_convert) that |
3039 | // need to reference a base_type DIE the offset of that DIE is not yet known. |
3040 | // To deal with this we instead insert a placeholder early and then extract |
3041 | // it here and replace it with the real reference. |
3042 | unsigned PtrSize = Asm->MAI->getCodePointerSize(); |
3043 | DWARFDataExtractor Data(StringRef(DebugLocs.getBytes(E: Entry).data(), |
3044 | DebugLocs.getBytes(E: Entry).size()), |
3045 | Asm->getDataLayout().isLittleEndian(), PtrSize); |
3046 | DWARFExpression Expr(Data, PtrSize, Asm->OutContext.getDwarfFormat()); |
3047 | |
3048 | using Encoding = DWARFExpression::Operation::Encoding; |
3049 | uint64_t Offset = 0; |
3050 | for (const auto &Op : Expr) { |
3051 | assert(Op.getCode() != dwarf::DW_OP_const_type && |
3052 | "3 operand ops not yet supported" ); |
3053 | assert(!Op.getSubCode() && "SubOps not yet supported" ); |
3054 | Streamer.emitInt8(Byte: Op.getCode(), Comment: Comment != End ? *(Comment++) : "" ); |
3055 | Offset++; |
3056 | for (unsigned I = 0; I < Op.getDescription().Op.size(); ++I) { |
3057 | if (Op.getDescription().Op[I] == Encoding::BaseTypeRef) { |
3058 | unsigned Length = |
3059 | Streamer.emitDIERef(D: *CU->ExprRefedBaseTypes[Op.getRawOperand(Idx: I)].Die); |
3060 | // Make sure comments stay aligned. |
3061 | for (unsigned J = 0; J < Length; ++J) |
3062 | if (Comment != End) |
3063 | Comment++; |
3064 | } else { |
3065 | for (uint64_t J = Offset; J < Op.getOperandEndOffset(Idx: I); ++J) |
3066 | Streamer.emitInt8(Byte: Data.getData()[J], Comment: Comment != End ? *(Comment++) : "" ); |
3067 | } |
3068 | Offset = Op.getOperandEndOffset(Idx: I); |
3069 | } |
3070 | assert(Offset == Op.getEndOffset()); |
3071 | } |
3072 | } |
3073 | |
3074 | void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, |
3075 | const DbgValueLoc &Value, |
3076 | DwarfExpression &DwarfExpr) { |
3077 | auto *DIExpr = Value.getExpression(); |
3078 | DIExpressionCursor ExprCursor(DIExpr); |
3079 | DwarfExpr.addFragmentOffset(Expr: DIExpr); |
3080 | |
3081 | // If the DIExpr is an Entry Value, we want to follow the same code path |
3082 | // regardless of whether the DBG_VALUE is variadic or not. |
3083 | if (DIExpr && DIExpr->isEntryValue()) { |
3084 | // Entry values can only be a single register with no additional DIExpr, |
3085 | // so just add it directly. |
3086 | assert(Value.getLocEntries().size() == 1); |
3087 | assert(Value.getLocEntries()[0].isLocation()); |
3088 | MachineLocation Location = Value.getLocEntries()[0].getLoc(); |
3089 | DwarfExpr.setLocation(Loc: Location, DIExpr); |
3090 | |
3091 | DwarfExpr.beginEntryValueExpression(ExprCursor); |
3092 | |
3093 | const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo(); |
3094 | if (!DwarfExpr.addMachineRegExpression(TRI, Expr&: ExprCursor, MachineReg: Location.getReg())) |
3095 | return; |
3096 | return DwarfExpr.addExpression(Expr: std::move(ExprCursor)); |
3097 | } |
3098 | |
3099 | // Regular entry. |
3100 | auto EmitValueLocEntry = [&DwarfExpr, &BT, |
3101 | &AP](const DbgValueLocEntry &Entry, |
3102 | DIExpressionCursor &Cursor) -> bool { |
3103 | if (Entry.isInt()) { |
3104 | if (BT && (BT->getEncoding() == dwarf::DW_ATE_signed || |
3105 | BT->getEncoding() == dwarf::DW_ATE_signed_char)) |
3106 | DwarfExpr.addSignedConstant(Value: Entry.getInt()); |
3107 | else |
3108 | DwarfExpr.addUnsignedConstant(Value: Entry.getInt()); |
3109 | } else if (Entry.isLocation()) { |
3110 | MachineLocation Location = Entry.getLoc(); |
3111 | if (Location.isIndirect()) |
3112 | DwarfExpr.setMemoryLocationKind(); |
3113 | |
3114 | const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo(); |
3115 | if (!DwarfExpr.addMachineRegExpression(TRI, Expr&: Cursor, MachineReg: Location.getReg())) |
3116 | return false; |
3117 | } else if (Entry.isTargetIndexLocation()) { |
3118 | TargetIndexLocation Loc = Entry.getTargetIndexLocation(); |
3119 | // TODO TargetIndexLocation is a target-independent. Currently only the |
3120 | // WebAssembly-specific encoding is supported. |
3121 | assert(AP.TM.getTargetTriple().isWasm()); |
3122 | DwarfExpr.addWasmLocation(Index: Loc.Index, Offset: static_cast<uint64_t>(Loc.Offset)); |
3123 | } else if (Entry.isConstantFP()) { |
3124 | if (AP.getDwarfVersion() >= 4 && !AP.getDwarfDebug()->tuneForSCE() && |
3125 | !Cursor) { |
3126 | DwarfExpr.addConstantFP(Value: Entry.getConstantFP()->getValueAPF(), AP); |
3127 | } else if (Entry.getConstantFP() |
3128 | ->getValueAPF() |
3129 | .bitcastToAPInt() |
3130 | .getBitWidth() <= 64 /*bits*/) { |
3131 | DwarfExpr.addUnsignedConstant( |
3132 | Value: Entry.getConstantFP()->getValueAPF().bitcastToAPInt()); |
3133 | } else { |
3134 | LLVM_DEBUG( |
3135 | dbgs() << "Skipped DwarfExpression creation for ConstantFP of size" |
3136 | << Entry.getConstantFP() |
3137 | ->getValueAPF() |
3138 | .bitcastToAPInt() |
3139 | .getBitWidth() |
3140 | << " bits\n" ); |
3141 | return false; |
3142 | } |
3143 | } |
3144 | return true; |
3145 | }; |
3146 | |
3147 | if (!Value.isVariadic()) { |
3148 | if (!EmitValueLocEntry(Value.getLocEntries()[0], ExprCursor)) |
3149 | return; |
3150 | DwarfExpr.addExpression(Expr: std::move(ExprCursor)); |
3151 | return; |
3152 | } |
3153 | |
3154 | // If any of the location entries are registers with the value 0, then the |
3155 | // location is undefined. |
3156 | if (any_of(Range: Value.getLocEntries(), P: [](const DbgValueLocEntry &Entry) { |
3157 | return Entry.isLocation() && !Entry.getLoc().getReg(); |
3158 | })) |
3159 | return; |
3160 | |
3161 | DwarfExpr.addExpression( |
3162 | Expr: std::move(ExprCursor), |
3163 | InsertArg: [EmitValueLocEntry, &Value](unsigned Idx, |
3164 | DIExpressionCursor &Cursor) -> bool { |
3165 | return EmitValueLocEntry(Value.getLocEntries()[Idx], Cursor); |
3166 | }); |
3167 | } |
3168 | |
3169 | void DebugLocEntry::finalize(const AsmPrinter &AP, |
3170 | DebugLocStream::ListBuilder &List, |
3171 | const DIBasicType *BT, |
3172 | DwarfCompileUnit &TheCU) { |
3173 | assert(!Values.empty() && |
3174 | "location list entries without values are redundant" ); |
3175 | assert(Begin != End && "unexpected location list entry with empty range" ); |
3176 | DebugLocStream::EntryBuilder Entry(List, Begin, End); |
3177 | BufferByteStreamer Streamer = Entry.getStreamer(); |
3178 | DebugLocDwarfExpression DwarfExpr(AP.getDwarfVersion(), Streamer, TheCU); |
3179 | const DbgValueLoc &Value = Values[0]; |
3180 | if (Value.isFragment()) { |
3181 | // Emit all fragments that belong to the same variable and range. |
3182 | assert(llvm::all_of(Values, [](DbgValueLoc P) { |
3183 | return P.isFragment(); |
3184 | }) && "all values are expected to be fragments" ); |
3185 | assert(llvm::is_sorted(Values) && "fragments are expected to be sorted" ); |
3186 | |
3187 | for (const auto &Fragment : Values) |
3188 | DwarfDebug::emitDebugLocValue(AP, BT, Value: Fragment, DwarfExpr); |
3189 | |
3190 | } else { |
3191 | assert(Values.size() == 1 && "only fragments may have >1 value" ); |
3192 | DwarfDebug::emitDebugLocValue(AP, BT, Value, DwarfExpr); |
3193 | } |
3194 | DwarfExpr.finalize(); |
3195 | if (DwarfExpr.TagOffset) |
3196 | List.setTagOffset(*DwarfExpr.TagOffset); |
3197 | } |
3198 | |
3199 | void DwarfDebug::emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry, |
3200 | const DwarfCompileUnit *CU) { |
3201 | // Emit the size. |
3202 | Asm->OutStreamer->AddComment(T: "Loc expr size" ); |
3203 | if (getDwarfVersion() >= 5) |
3204 | Asm->emitULEB128(Value: DebugLocs.getBytes(E: Entry).size()); |
3205 | else if (DebugLocs.getBytes(E: Entry).size() <= std::numeric_limits<uint16_t>::max()) |
3206 | Asm->emitInt16(Value: DebugLocs.getBytes(E: Entry).size()); |
3207 | else { |
3208 | // The entry is too big to fit into 16 bit, drop it as there is nothing we |
3209 | // can do. |
3210 | Asm->emitInt16(Value: 0); |
3211 | return; |
3212 | } |
3213 | // Emit the entry. |
3214 | APByteStreamer Streamer(*Asm); |
3215 | emitDebugLocEntry(Streamer, Entry, CU); |
3216 | } |
3217 | |
3218 | // Emit the header of a DWARF 5 range list table list table. Returns the symbol |
3219 | // that designates the end of the table for the caller to emit when the table is |
3220 | // complete. |
3221 | static MCSymbol *(AsmPrinter *Asm, |
3222 | const DwarfFile &Holder) { |
3223 | MCSymbol *TableEnd = mcdwarf::emitListsTableHeaderStart(S&: *Asm->OutStreamer); |
3224 | |
3225 | Asm->OutStreamer->AddComment(T: "Offset entry count" ); |
3226 | Asm->emitInt32(Value: Holder.getRangeLists().size()); |
3227 | Asm->OutStreamer->emitLabel(Symbol: Holder.getRnglistsTableBaseSym()); |
3228 | |
3229 | for (const RangeSpanList &List : Holder.getRangeLists()) |
3230 | Asm->emitLabelDifference(Hi: List.Label, Lo: Holder.getRnglistsTableBaseSym(), |
3231 | Size: Asm->getDwarfOffsetByteSize()); |
3232 | |
3233 | return TableEnd; |
3234 | } |
3235 | |
3236 | // Emit the header of a DWARF 5 locations list table. Returns the symbol that |
3237 | // designates the end of the table for the caller to emit when the table is |
3238 | // complete. |
3239 | static MCSymbol *(AsmPrinter *Asm, |
3240 | const DwarfDebug &DD) { |
3241 | MCSymbol *TableEnd = mcdwarf::emitListsTableHeaderStart(S&: *Asm->OutStreamer); |
3242 | |
3243 | const auto &DebugLocs = DD.getDebugLocs(); |
3244 | |
3245 | Asm->OutStreamer->AddComment(T: "Offset entry count" ); |
3246 | Asm->emitInt32(Value: DebugLocs.getLists().size()); |
3247 | Asm->OutStreamer->emitLabel(Symbol: DebugLocs.getSym()); |
3248 | |
3249 | for (const auto &List : DebugLocs.getLists()) |
3250 | Asm->emitLabelDifference(Hi: List.Label, Lo: DebugLocs.getSym(), |
3251 | Size: Asm->getDwarfOffsetByteSize()); |
3252 | |
3253 | return TableEnd; |
3254 | } |
3255 | |
3256 | template <typename Ranges, typename PayloadEmitter> |
3257 | static void emitRangeList( |
3258 | DwarfDebug &DD, AsmPrinter *Asm, MCSymbol *Sym, const Ranges &R, |
3259 | const DwarfCompileUnit &CU, unsigned BaseAddressx, unsigned OffsetPair, |
3260 | unsigned StartxLength, unsigned EndOfList, |
3261 | StringRef (*StringifyEnum)(unsigned), |
3262 | bool ShouldUseBaseAddress, |
3263 | PayloadEmitter EmitPayload) { |
3264 | |
3265 | auto Size = Asm->MAI->getCodePointerSize(); |
3266 | bool UseDwarf5 = DD.getDwarfVersion() >= 5; |
3267 | |
3268 | // Emit our symbol so we can find the beginning of the range. |
3269 | Asm->OutStreamer->emitLabel(Symbol: Sym); |
3270 | |
3271 | // Gather all the ranges that apply to the same section so they can share |
3272 | // a base address entry. |
3273 | SmallMapVector<const MCSection *, std::vector<decltype(&*R.begin())>, 16> |
3274 | SectionRanges; |
3275 | |
3276 | for (const auto &Range : R) |
3277 | SectionRanges[&Range.Begin->getSection()].push_back(&Range); |
3278 | |
3279 | const MCSymbol *CUBase = CU.getBaseAddress(); |
3280 | bool BaseIsSet = false; |
3281 | for (const auto &P : SectionRanges) { |
3282 | auto *Base = CUBase; |
3283 | if ((Asm->TM.getTargetTriple().isNVPTX() && DD.tuneForGDB())) { |
3284 | // PTX does not support subtracting labels from the code section in the |
3285 | // debug_loc section. To work around this, the NVPTX backend needs the |
3286 | // compile unit to have no low_pc in order to have a zero base_address |
3287 | // when handling debug_loc in cuda-gdb. Additionally, cuda-gdb doesn't |
3288 | // seem to handle setting a per-variable base to zero. To make cuda-gdb |
3289 | // happy, just emit labels with no base while having no compile unit |
3290 | // low_pc. |
3291 | BaseIsSet = false; |
3292 | Base = nullptr; |
3293 | } else if (!Base && ShouldUseBaseAddress) { |
3294 | const MCSymbol *Begin = P.second.front()->Begin; |
3295 | const MCSymbol *NewBase = DD.getSectionLabel(S: &Begin->getSection()); |
3296 | if (!UseDwarf5) { |
3297 | Base = NewBase; |
3298 | BaseIsSet = true; |
3299 | Asm->OutStreamer->emitIntValue(Value: -1, Size); |
3300 | Asm->OutStreamer->AddComment(T: " base address" ); |
3301 | Asm->OutStreamer->emitSymbolValue(Sym: Base, Size); |
3302 | } else if (NewBase != Begin || P.second.size() > 1) { |
3303 | // Only use a base address if |
3304 | // * the existing pool address doesn't match (NewBase != Begin) |
3305 | // * or, there's more than one entry to share the base address |
3306 | Base = NewBase; |
3307 | BaseIsSet = true; |
3308 | Asm->OutStreamer->AddComment(T: StringifyEnum(BaseAddressx)); |
3309 | Asm->emitInt8(Value: BaseAddressx); |
3310 | Asm->OutStreamer->AddComment(T: " base address index" ); |
3311 | Asm->emitULEB128(Value: DD.getAddressPool().getIndex(Sym: Base)); |
3312 | } |
3313 | } else if (BaseIsSet && !UseDwarf5) { |
3314 | BaseIsSet = false; |
3315 | assert(!Base); |
3316 | Asm->OutStreamer->emitIntValue(Value: -1, Size); |
3317 | Asm->OutStreamer->emitIntValue(Value: 0, Size); |
3318 | } |
3319 | |
3320 | for (const auto *RS : P.second) { |
3321 | const MCSymbol *Begin = RS->Begin; |
3322 | const MCSymbol *End = RS->End; |
3323 | assert(Begin && "Range without a begin symbol?" ); |
3324 | assert(End && "Range without an end symbol?" ); |
3325 | if (Base) { |
3326 | if (UseDwarf5) { |
3327 | // Emit offset_pair when we have a base. |
3328 | Asm->OutStreamer->AddComment(T: StringifyEnum(OffsetPair)); |
3329 | Asm->emitInt8(Value: OffsetPair); |
3330 | Asm->OutStreamer->AddComment(T: " starting offset" ); |
3331 | Asm->emitLabelDifferenceAsULEB128(Hi: Begin, Lo: Base); |
3332 | Asm->OutStreamer->AddComment(T: " ending offset" ); |
3333 | Asm->emitLabelDifferenceAsULEB128(Hi: End, Lo: Base); |
3334 | } else { |
3335 | Asm->emitLabelDifference(Hi: Begin, Lo: Base, Size); |
3336 | Asm->emitLabelDifference(Hi: End, Lo: Base, Size); |
3337 | } |
3338 | } else if (UseDwarf5) { |
3339 | Asm->OutStreamer->AddComment(T: StringifyEnum(StartxLength)); |
3340 | Asm->emitInt8(Value: StartxLength); |
3341 | Asm->OutStreamer->AddComment(T: " start index" ); |
3342 | Asm->emitULEB128(Value: DD.getAddressPool().getIndex(Sym: Begin)); |
3343 | Asm->OutStreamer->AddComment(T: " length" ); |
3344 | Asm->emitLabelDifferenceAsULEB128(Hi: End, Lo: Begin); |
3345 | } else { |
3346 | Asm->OutStreamer->emitSymbolValue(Sym: Begin, Size); |
3347 | Asm->OutStreamer->emitSymbolValue(Sym: End, Size); |
3348 | } |
3349 | EmitPayload(*RS); |
3350 | } |
3351 | } |
3352 | |
3353 | if (UseDwarf5) { |
3354 | Asm->OutStreamer->AddComment(T: StringifyEnum(EndOfList)); |
3355 | Asm->emitInt8(Value: EndOfList); |
3356 | } else { |
3357 | // Terminate the list with two 0 values. |
3358 | Asm->OutStreamer->emitIntValue(Value: 0, Size); |
3359 | Asm->OutStreamer->emitIntValue(Value: 0, Size); |
3360 | } |
3361 | } |
3362 | |
3363 | // Handles emission of both debug_loclist / debug_loclist.dwo |
3364 | static void emitLocList(DwarfDebug &DD, AsmPrinter *Asm, const DebugLocStream::List &List) { |
3365 | emitRangeList(DD, Asm, Sym: List.Label, R: DD.getDebugLocs().getEntries(L: List), |
3366 | CU: *List.CU, BaseAddressx: dwarf::DW_LLE_base_addressx, |
3367 | OffsetPair: dwarf::DW_LLE_offset_pair, StartxLength: dwarf::DW_LLE_startx_length, |
3368 | EndOfList: dwarf::DW_LLE_end_of_list, StringifyEnum: llvm::dwarf::LocListEncodingString, |
3369 | /* ShouldUseBaseAddress */ true, |
3370 | EmitPayload: [&](const DebugLocStream::Entry &E) { |
3371 | DD.emitDebugLocEntryLocation(Entry: E, CU: List.CU); |
3372 | }); |
3373 | } |
3374 | |
3375 | void DwarfDebug::emitDebugLocImpl(MCSection *Sec) { |
3376 | if (DebugLocs.getLists().empty()) |
3377 | return; |
3378 | |
3379 | Asm->OutStreamer->switchSection(Section: Sec); |
3380 | |
3381 | MCSymbol *TableEnd = nullptr; |
3382 | if (getDwarfVersion() >= 5) |
3383 | TableEnd = emitLoclistsTableHeader(Asm, DD: *this); |
3384 | |
3385 | for (const auto &List : DebugLocs.getLists()) |
3386 | emitLocList(DD&: *this, Asm, List); |
3387 | |
3388 | if (TableEnd) |
3389 | Asm->OutStreamer->emitLabel(Symbol: TableEnd); |
3390 | } |
3391 | |
3392 | // Emit locations into the .debug_loc/.debug_loclists section. |
3393 | void DwarfDebug::emitDebugLoc() { |
3394 | emitDebugLocImpl( |
3395 | Sec: getDwarfVersion() >= 5 |
3396 | ? Asm->getObjFileLowering().getDwarfLoclistsSection() |
3397 | : Asm->getObjFileLowering().getDwarfLocSection()); |
3398 | } |
3399 | |
3400 | // Emit locations into the .debug_loc.dwo/.debug_loclists.dwo section. |
3401 | void DwarfDebug::emitDebugLocDWO() { |
3402 | if (getDwarfVersion() >= 5) { |
3403 | emitDebugLocImpl( |
3404 | Sec: Asm->getObjFileLowering().getDwarfLoclistsDWOSection()); |
3405 | |
3406 | return; |
3407 | } |
3408 | |
3409 | for (const auto &List : DebugLocs.getLists()) { |
3410 | Asm->OutStreamer->switchSection( |
3411 | Section: Asm->getObjFileLowering().getDwarfLocDWOSection()); |
3412 | Asm->OutStreamer->emitLabel(Symbol: List.Label); |
3413 | |
3414 | for (const auto &Entry : DebugLocs.getEntries(L: List)) { |
3415 | // GDB only supports startx_length in pre-standard split-DWARF. |
3416 | // (in v5 standard loclists, it currently* /only/ supports base_address + |
3417 | // offset_pair, so the implementations can't really share much since they |
3418 | // need to use different representations) |
3419 | // * as of October 2018, at least |
3420 | // |
3421 | // In v5 (see emitLocList), this uses SectionLabels to reuse existing |
3422 | // addresses in the address pool to minimize object size/relocations. |
3423 | Asm->emitInt8(Value: dwarf::DW_LLE_startx_length); |
3424 | unsigned idx = AddrPool.getIndex(Sym: Entry.Begin); |
3425 | Asm->emitULEB128(Value: idx); |
3426 | // Also the pre-standard encoding is slightly different, emitting this as |
3427 | // an address-length entry here, but its a ULEB128 in DWARFv5 loclists. |
3428 | Asm->emitLabelDifference(Hi: Entry.End, Lo: Entry.Begin, Size: 4); |
3429 | emitDebugLocEntryLocation(Entry, CU: List.CU); |
3430 | } |
3431 | Asm->emitInt8(Value: dwarf::DW_LLE_end_of_list); |
3432 | } |
3433 | } |
3434 | |
3435 | struct ArangeSpan { |
3436 | const MCSymbol *Start, *End; |
3437 | }; |
3438 | |
3439 | // Emit a debug aranges section, containing a CU lookup for any |
3440 | // address we can tie back to a CU. |
3441 | void DwarfDebug::emitDebugARanges() { |
3442 | if (ArangeLabels.empty()) |
3443 | return; |
3444 | |
3445 | // Provides a unique id per text section. |
3446 | MapVector<MCSection *, SmallVector<SymbolCU, 8>> SectionMap; |
3447 | |
3448 | // Filter labels by section. |
3449 | for (const SymbolCU &SCU : ArangeLabels) { |
3450 | if (SCU.Sym->isInSection()) { |
3451 | // Make a note of this symbol and it's section. |
3452 | MCSection *Section = &SCU.Sym->getSection(); |
3453 | SectionMap[Section].push_back(Elt: SCU); |
3454 | } else { |
3455 | // Some symbols (e.g. common/bss on mach-o) can have no section but still |
3456 | // appear in the output. This sucks as we rely on sections to build |
3457 | // arange spans. We can do it without, but it's icky. |
3458 | SectionMap[nullptr].push_back(Elt: SCU); |
3459 | } |
3460 | } |
3461 | |
3462 | DenseMap<DwarfCompileUnit *, std::vector<ArangeSpan>> Spans; |
3463 | |
3464 | for (auto &I : SectionMap) { |
3465 | MCSection *Section = I.first; |
3466 | SmallVector<SymbolCU, 8> &List = I.second; |
3467 | assert(!List.empty()); |
3468 | |
3469 | // If we have no section (e.g. common), just write out |
3470 | // individual spans for each symbol. |
3471 | if (!Section) { |
3472 | for (const SymbolCU &Cur : List) { |
3473 | ArangeSpan Span; |
3474 | Span.Start = Cur.Sym; |
3475 | Span.End = nullptr; |
3476 | assert(Cur.CU); |
3477 | Spans[Cur.CU].push_back(x: Span); |
3478 | } |
3479 | continue; |
3480 | } |
3481 | |
3482 | // Insert a final terminator. |
3483 | List.push_back(Elt: SymbolCU(nullptr, Asm->OutStreamer->endSection(Section))); |
3484 | |
3485 | // Build spans between each label. |
3486 | const MCSymbol *StartSym = List[0].Sym; |
3487 | for (size_t n = 1, e = List.size(); n < e; n++) { |
3488 | const SymbolCU &Prev = List[n - 1]; |
3489 | const SymbolCU &Cur = List[n]; |
3490 | |
3491 | // Try and build the longest span we can within the same CU. |
3492 | if (Cur.CU != Prev.CU) { |
3493 | ArangeSpan Span; |
3494 | Span.Start = StartSym; |
3495 | Span.End = Cur.Sym; |
3496 | assert(Prev.CU); |
3497 | Spans[Prev.CU].push_back(x: Span); |
3498 | StartSym = Cur.Sym; |
3499 | } |
3500 | } |
3501 | } |
3502 | |
3503 | // Start the dwarf aranges section. |
3504 | Asm->OutStreamer->switchSection( |
3505 | Section: Asm->getObjFileLowering().getDwarfARangesSection()); |
3506 | |
3507 | unsigned PtrSize = Asm->MAI->getCodePointerSize(); |
3508 | |
3509 | // Build a list of CUs used. |
3510 | std::vector<DwarfCompileUnit *> CUs; |
3511 | for (const auto &it : Spans) { |
3512 | DwarfCompileUnit *CU = it.first; |
3513 | CUs.push_back(x: CU); |
3514 | } |
3515 | |
3516 | // Sort the CU list (again, to ensure consistent output order). |
3517 | llvm::sort(C&: CUs, Comp: [](const DwarfCompileUnit *A, const DwarfCompileUnit *B) { |
3518 | return A->getUniqueID() < B->getUniqueID(); |
3519 | }); |
3520 | |
3521 | // Emit an arange table for each CU we used. |
3522 | for (DwarfCompileUnit *CU : CUs) { |
3523 | std::vector<ArangeSpan> &List = Spans[CU]; |
3524 | |
3525 | // Describe the skeleton CU's offset and length, not the dwo file's. |
3526 | if (auto *Skel = CU->getSkeleton()) |
3527 | CU = Skel; |
3528 | |
3529 | // Emit size of content not including length itself. |
3530 | unsigned ContentSize = |
3531 | sizeof(int16_t) + // DWARF ARange version number |
3532 | Asm->getDwarfOffsetByteSize() + // Offset of CU in the .debug_info |
3533 | // section |
3534 | sizeof(int8_t) + // Pointer Size (in bytes) |
3535 | sizeof(int8_t); // Segment Size (in bytes) |
3536 | |
3537 | unsigned TupleSize = PtrSize * 2; |
3538 | |
3539 | // 7.20 in the Dwarf specs requires the table to be aligned to a tuple. |
3540 | unsigned Padding = offsetToAlignment( |
3541 | Value: Asm->getUnitLengthFieldByteSize() + ContentSize, Alignment: Align(TupleSize)); |
3542 | |
3543 | ContentSize += Padding; |
3544 | ContentSize += (List.size() + 1) * TupleSize; |
3545 | |
3546 | // For each compile unit, write the list of spans it covers. |
3547 | Asm->emitDwarfUnitLength(Length: ContentSize, Comment: "Length of ARange Set" ); |
3548 | Asm->OutStreamer->AddComment(T: "DWARF Arange version number" ); |
3549 | Asm->emitInt16(Value: dwarf::DW_ARANGES_VERSION); |
3550 | Asm->OutStreamer->AddComment(T: "Offset Into Debug Info Section" ); |
3551 | emitSectionReference(CU: *CU); |
3552 | Asm->OutStreamer->AddComment(T: "Address Size (in bytes)" ); |
3553 | Asm->emitInt8(Value: PtrSize); |
3554 | Asm->OutStreamer->AddComment(T: "Segment Size (in bytes)" ); |
3555 | Asm->emitInt8(Value: 0); |
3556 | |
3557 | Asm->OutStreamer->emitFill(NumBytes: Padding, FillValue: 0xff); |
3558 | |
3559 | for (const ArangeSpan &Span : List) { |
3560 | Asm->emitLabelReference(Label: Span.Start, Size: PtrSize); |
3561 | |
3562 | // Calculate the size as being from the span start to its end. |
3563 | // |
3564 | // If the size is zero, then round it up to one byte. The DWARF |
3565 | // specification requires that entries in this table have nonzero |
3566 | // lengths. |
3567 | auto SizeRef = SymSize.find(Val: Span.Start); |
3568 | if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) { |
3569 | Asm->emitLabelDifference(Hi: Span.End, Lo: Span.Start, Size: PtrSize); |
3570 | } else { |
3571 | // For symbols without an end marker (e.g. common), we |
3572 | // write a single arange entry containing just that one symbol. |
3573 | uint64_t Size; |
3574 | if (SizeRef == SymSize.end() || SizeRef->second == 0) |
3575 | Size = 1; |
3576 | else |
3577 | Size = SizeRef->second; |
3578 | |
3579 | Asm->OutStreamer->emitIntValue(Value: Size, Size: PtrSize); |
3580 | } |
3581 | } |
3582 | |
3583 | Asm->OutStreamer->AddComment(T: "ARange terminator" ); |
3584 | Asm->OutStreamer->emitIntValue(Value: 0, Size: PtrSize); |
3585 | Asm->OutStreamer->emitIntValue(Value: 0, Size: PtrSize); |
3586 | } |
3587 | } |
3588 | |
3589 | /// Emit a single range list. We handle both DWARF v5 and earlier. |
3590 | static void emitRangeList(DwarfDebug &DD, AsmPrinter *Asm, |
3591 | const RangeSpanList &List) { |
3592 | emitRangeList(DD, Asm, Sym: List.Label, R: List.Ranges, CU: *List.CU, |
3593 | BaseAddressx: dwarf::DW_RLE_base_addressx, OffsetPair: dwarf::DW_RLE_offset_pair, |
3594 | StartxLength: dwarf::DW_RLE_startx_length, EndOfList: dwarf::DW_RLE_end_of_list, |
3595 | StringifyEnum: llvm::dwarf::RangeListEncodingString, |
3596 | ShouldUseBaseAddress: List.CU->getCUNode()->getRangesBaseAddress() || |
3597 | DD.getDwarfVersion() >= 5, |
3598 | EmitPayload: [](auto) {}); |
3599 | } |
3600 | |
3601 | void DwarfDebug::emitDebugRangesImpl(const DwarfFile &Holder, MCSection *Section) { |
3602 | if (Holder.getRangeLists().empty()) |
3603 | return; |
3604 | |
3605 | assert(useRangesSection()); |
3606 | assert(!CUMap.empty()); |
3607 | assert(llvm::any_of(CUMap, [](const decltype(CUMap)::value_type &Pair) { |
3608 | return !Pair.second->getCUNode()->isDebugDirectivesOnly(); |
3609 | })); |
3610 | |
3611 | Asm->OutStreamer->switchSection(Section); |
3612 | |
3613 | MCSymbol *TableEnd = nullptr; |
3614 | if (getDwarfVersion() >= 5) |
3615 | TableEnd = emitRnglistsTableHeader(Asm, Holder); |
3616 | |
3617 | for (const RangeSpanList &List : Holder.getRangeLists()) |
3618 | emitRangeList(DD&: *this, Asm, List); |
3619 | |
3620 | if (TableEnd) |
3621 | Asm->OutStreamer->emitLabel(Symbol: TableEnd); |
3622 | } |
3623 | |
3624 | /// Emit address ranges into the .debug_ranges section or into the DWARF v5 |
3625 | /// .debug_rnglists section. |
3626 | void DwarfDebug::emitDebugRanges() { |
3627 | const auto &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; |
3628 | |
3629 | emitDebugRangesImpl(Holder, |
3630 | Section: getDwarfVersion() >= 5 |
3631 | ? Asm->getObjFileLowering().getDwarfRnglistsSection() |
3632 | : Asm->getObjFileLowering().getDwarfRangesSection()); |
3633 | } |
3634 | |
3635 | void DwarfDebug::emitDebugRangesDWO() { |
3636 | emitDebugRangesImpl(Holder: InfoHolder, |
3637 | Section: Asm->getObjFileLowering().getDwarfRnglistsDWOSection()); |
3638 | } |
3639 | |
3640 | /// Emit the header of a DWARF 5 macro section, or the GNU extension for |
3641 | /// DWARF 4. |
3642 | static void (AsmPrinter *Asm, const DwarfDebug &DD, |
3643 | const DwarfCompileUnit &CU, uint16_t DwarfVersion) { |
3644 | enum { |
3645 | #define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID, |
3646 | #include "llvm/BinaryFormat/Dwarf.def" |
3647 | }; |
3648 | Asm->OutStreamer->AddComment(T: "Macro information version" ); |
3649 | Asm->emitInt16(Value: DwarfVersion >= 5 ? DwarfVersion : 4); |
3650 | // We emit the line offset flag unconditionally here, since line offset should |
3651 | // be mostly present. |
3652 | if (Asm->isDwarf64()) { |
3653 | Asm->OutStreamer->AddComment(T: "Flags: 64 bit, debug_line_offset present" ); |
3654 | Asm->emitInt8(Value: MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET); |
3655 | } else { |
3656 | Asm->OutStreamer->AddComment(T: "Flags: 32 bit, debug_line_offset present" ); |
3657 | Asm->emitInt8(Value: MACRO_FLAG_DEBUG_LINE_OFFSET); |
3658 | } |
3659 | Asm->OutStreamer->AddComment(T: "debug_line_offset" ); |
3660 | if (DD.useSplitDwarf()) |
3661 | Asm->emitDwarfLengthOrOffset(Value: 0); |
3662 | else |
3663 | Asm->emitDwarfSymbolReference(Label: CU.getLineTableStartSym()); |
3664 | } |
3665 | |
3666 | void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U) { |
3667 | for (auto *MN : Nodes) { |
3668 | if (auto *M = dyn_cast<DIMacro>(Val: MN)) |
3669 | emitMacro(M&: *M); |
3670 | else if (auto *F = dyn_cast<DIMacroFile>(Val: MN)) |
3671 | emitMacroFile(F&: *F, U); |
3672 | else |
3673 | llvm_unreachable("Unexpected DI type!" ); |
3674 | } |
3675 | } |
3676 | |
3677 | void DwarfDebug::emitMacro(DIMacro &M) { |
3678 | StringRef Name = M.getName(); |
3679 | StringRef Value = M.getValue(); |
3680 | |
3681 | // There should be one space between the macro name and the macro value in |
3682 | // define entries. In undef entries, only the macro name is emitted. |
3683 | std::string Str = Value.empty() ? Name.str() : (Name + " " + Value).str(); |
3684 | |
3685 | if (UseDebugMacroSection) { |
3686 | if (getDwarfVersion() >= 5) { |
3687 | unsigned Type = M.getMacinfoType() == dwarf::DW_MACINFO_define |
3688 | ? dwarf::DW_MACRO_define_strx |
3689 | : dwarf::DW_MACRO_undef_strx; |
3690 | Asm->OutStreamer->AddComment(T: dwarf::MacroString(Encoding: Type)); |
3691 | Asm->emitULEB128(Value: Type); |
3692 | Asm->OutStreamer->AddComment(T: "Line Number" ); |
3693 | Asm->emitULEB128(Value: M.getLine()); |
3694 | Asm->OutStreamer->AddComment(T: "Macro String" ); |
3695 | Asm->emitULEB128( |
3696 | Value: InfoHolder.getStringPool().getIndexedEntry(Asm&: *Asm, Str).getIndex()); |
3697 | } else { |
3698 | unsigned Type = M.getMacinfoType() == dwarf::DW_MACINFO_define |
3699 | ? dwarf::DW_MACRO_GNU_define_indirect |
3700 | : dwarf::DW_MACRO_GNU_undef_indirect; |
3701 | Asm->OutStreamer->AddComment(T: dwarf::GnuMacroString(Encoding: Type)); |
3702 | Asm->emitULEB128(Value: Type); |
3703 | Asm->OutStreamer->AddComment(T: "Line Number" ); |
3704 | Asm->emitULEB128(Value: M.getLine()); |
3705 | Asm->OutStreamer->AddComment(T: "Macro String" ); |
3706 | Asm->emitDwarfSymbolReference( |
3707 | Label: InfoHolder.getStringPool().getEntry(Asm&: *Asm, Str).getSymbol()); |
3708 | } |
3709 | } else { |
3710 | Asm->OutStreamer->AddComment(T: dwarf::MacinfoString(Encoding: M.getMacinfoType())); |
3711 | Asm->emitULEB128(Value: M.getMacinfoType()); |
3712 | Asm->OutStreamer->AddComment(T: "Line Number" ); |
3713 | Asm->emitULEB128(Value: M.getLine()); |
3714 | Asm->OutStreamer->AddComment(T: "Macro String" ); |
3715 | Asm->OutStreamer->emitBytes(Data: Str); |
3716 | Asm->emitInt8(Value: '\0'); |
3717 | } |
3718 | } |
3719 | |
3720 | void DwarfDebug::emitMacroFileImpl( |
3721 | DIMacroFile &MF, DwarfCompileUnit &U, unsigned StartFile, unsigned EndFile, |
3722 | StringRef (*MacroFormToString)(unsigned Form)) { |
3723 | |
3724 | Asm->OutStreamer->AddComment(T: MacroFormToString(StartFile)); |
3725 | Asm->emitULEB128(Value: StartFile); |
3726 | Asm->OutStreamer->AddComment(T: "Line Number" ); |
3727 | Asm->emitULEB128(Value: MF.getLine()); |
3728 | Asm->OutStreamer->AddComment(T: "File Number" ); |
3729 | DIFile &F = *MF.getFile(); |
3730 | if (useSplitDwarf()) |
3731 | Asm->emitULEB128(Value: getDwoLineTable(U)->getFile( |
3732 | Directory: F.getDirectory(), FileName: F.getFilename(), Checksum: getMD5AsBytes(File: &F), |
3733 | DwarfVersion: Asm->OutContext.getDwarfVersion(), Source: F.getSource())); |
3734 | else |
3735 | Asm->emitULEB128(Value: U.getOrCreateSourceID(File: &F)); |
3736 | handleMacroNodes(Nodes: MF.getElements(), U); |
3737 | Asm->OutStreamer->AddComment(T: MacroFormToString(EndFile)); |
3738 | Asm->emitULEB128(Value: EndFile); |
3739 | } |
3740 | |
3741 | void DwarfDebug::emitMacroFile(DIMacroFile &F, DwarfCompileUnit &U) { |
3742 | // DWARFv5 macro and DWARFv4 macinfo share some common encodings, |
3743 | // so for readibility/uniformity, We are explicitly emitting those. |
3744 | assert(F.getMacinfoType() == dwarf::DW_MACINFO_start_file); |
3745 | if (UseDebugMacroSection) |
3746 | emitMacroFileImpl( |
3747 | MF&: F, U, StartFile: dwarf::DW_MACRO_start_file, EndFile: dwarf::DW_MACRO_end_file, |
3748 | MacroFormToString: (getDwarfVersion() >= 5) ? dwarf::MacroString : dwarf::GnuMacroString); |
3749 | else |
3750 | emitMacroFileImpl(MF&: F, U, StartFile: dwarf::DW_MACINFO_start_file, |
3751 | EndFile: dwarf::DW_MACINFO_end_file, MacroFormToString: dwarf::MacinfoString); |
3752 | } |
3753 | |
3754 | void DwarfDebug::emitDebugMacinfoImpl(MCSection *Section) { |
3755 | for (const auto &P : CUMap) { |
3756 | auto &TheCU = *P.second; |
3757 | auto *SkCU = TheCU.getSkeleton(); |
3758 | DwarfCompileUnit &U = SkCU ? *SkCU : TheCU; |
3759 | auto *CUNode = cast<DICompileUnit>(Val: P.first); |
3760 | DIMacroNodeArray Macros = CUNode->getMacros(); |
3761 | if (Macros.empty()) |
3762 | continue; |
3763 | Asm->OutStreamer->switchSection(Section); |
3764 | Asm->OutStreamer->emitLabel(Symbol: U.getMacroLabelBegin()); |
3765 | if (UseDebugMacroSection) |
3766 | emitMacroHeader(Asm, DD: *this, CU: U, DwarfVersion: getDwarfVersion()); |
3767 | handleMacroNodes(Nodes: Macros, U); |
3768 | Asm->OutStreamer->AddComment(T: "End Of Macro List Mark" ); |
3769 | Asm->emitInt8(Value: 0); |
3770 | } |
3771 | } |
3772 | |
3773 | /// Emit macros into a debug macinfo/macro section. |
3774 | void DwarfDebug::emitDebugMacinfo() { |
3775 | auto &ObjLower = Asm->getObjFileLowering(); |
3776 | emitDebugMacinfoImpl(Section: UseDebugMacroSection |
3777 | ? ObjLower.getDwarfMacroSection() |
3778 | : ObjLower.getDwarfMacinfoSection()); |
3779 | } |
3780 | |
3781 | void DwarfDebug::emitDebugMacinfoDWO() { |
3782 | auto &ObjLower = Asm->getObjFileLowering(); |
3783 | emitDebugMacinfoImpl(Section: UseDebugMacroSection |
3784 | ? ObjLower.getDwarfMacroDWOSection() |
3785 | : ObjLower.getDwarfMacinfoDWOSection()); |
3786 | } |
3787 | |
3788 | // DWARF5 Experimental Separate Dwarf emitters. |
3789 | |
3790 | void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE &Die, |
3791 | std::unique_ptr<DwarfCompileUnit> NewU) { |
3792 | |
3793 | if (!CompilationDir.empty()) |
3794 | NewU->addString(Die, Attribute: dwarf::DW_AT_comp_dir, Str: CompilationDir); |
3795 | addGnuPubAttributes(U&: *NewU, D&: Die); |
3796 | |
3797 | SkeletonHolder.addUnit(U: std::move(NewU)); |
3798 | } |
3799 | |
3800 | DwarfCompileUnit &DwarfDebug::constructSkeletonCU(const DwarfCompileUnit &CU) { |
3801 | |
3802 | auto OwnedUnit = std::make_unique<DwarfCompileUnit>( |
3803 | args: CU.getUniqueID(), args: CU.getCUNode(), args&: Asm, args: this, args: &SkeletonHolder, |
3804 | args: UnitKind::Skeleton); |
3805 | DwarfCompileUnit &NewCU = *OwnedUnit; |
3806 | NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoSection()); |
3807 | |
3808 | NewCU.initStmtList(); |
3809 | |
3810 | if (useSegmentedStringOffsetsTable()) |
3811 | NewCU.addStringOffsetsStart(); |
3812 | |
3813 | initSkeletonUnit(U: CU, Die&: NewCU.getUnitDie(), NewU: std::move(OwnedUnit)); |
3814 | |
3815 | return NewCU; |
3816 | } |
3817 | |
3818 | // Emit the .debug_info.dwo section for separated dwarf. This contains the |
3819 | // compile units that would normally be in debug_info. |
3820 | void DwarfDebug::emitDebugInfoDWO() { |
3821 | assert(useSplitDwarf() && "No split dwarf debug info?" ); |
3822 | // Don't emit relocations into the dwo file. |
3823 | InfoHolder.emitUnits(/* UseOffsets */ true); |
3824 | } |
3825 | |
3826 | // Emit the .debug_abbrev.dwo section for separated dwarf. This contains the |
3827 | // abbreviations for the .debug_info.dwo section. |
3828 | void DwarfDebug::emitDebugAbbrevDWO() { |
3829 | assert(useSplitDwarf() && "No split dwarf?" ); |
3830 | InfoHolder.emitAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevDWOSection()); |
3831 | } |
3832 | |
3833 | void DwarfDebug::emitDebugLineDWO() { |
3834 | assert(useSplitDwarf() && "No split dwarf?" ); |
3835 | SplitTypeUnitFileTable.Emit( |
3836 | MCOS&: *Asm->OutStreamer, Params: MCDwarfLineTableParams(), |
3837 | Section: Asm->getObjFileLowering().getDwarfLineDWOSection()); |
3838 | } |
3839 | |
3840 | void DwarfDebug::() { |
3841 | assert(useSplitDwarf() && "No split dwarf?" ); |
3842 | InfoHolder.getStringPool().emitStringOffsetsTableHeader( |
3843 | Asm&: *Asm, OffsetSection: Asm->getObjFileLowering().getDwarfStrOffDWOSection(), |
3844 | StartSym: InfoHolder.getStringOffsetsStartSym()); |
3845 | } |
3846 | |
3847 | // Emit the .debug_str.dwo section for separated dwarf. This contains the |
3848 | // string section and is identical in format to traditional .debug_str |
3849 | // sections. |
3850 | void DwarfDebug::emitDebugStrDWO() { |
3851 | if (useSegmentedStringOffsetsTable()) |
3852 | emitStringOffsetsTableHeaderDWO(); |
3853 | assert(useSplitDwarf() && "No split dwarf?" ); |
3854 | MCSection *OffSec = Asm->getObjFileLowering().getDwarfStrOffDWOSection(); |
3855 | InfoHolder.emitStrings(StrSection: Asm->getObjFileLowering().getDwarfStrDWOSection(), |
3856 | OffsetSection: OffSec, /* UseRelativeOffsets = */ false); |
3857 | } |
3858 | |
3859 | // Emit address pool. |
3860 | void DwarfDebug::emitDebugAddr() { |
3861 | AddrPool.emit(Asm&: *Asm, AddrSection: Asm->getObjFileLowering().getDwarfAddrSection()); |
3862 | } |
3863 | |
3864 | MCDwarfDwoLineTable *DwarfDebug::getDwoLineTable(const DwarfCompileUnit &CU) { |
3865 | if (!useSplitDwarf()) |
3866 | return nullptr; |
3867 | const DICompileUnit *DIUnit = CU.getCUNode(); |
3868 | SplitTypeUnitFileTable.maybeSetRootFile( |
3869 | Directory: DIUnit->getDirectory(), FileName: DIUnit->getFilename(), |
3870 | Checksum: getMD5AsBytes(File: DIUnit->getFile()), Source: DIUnit->getSource()); |
3871 | return &SplitTypeUnitFileTable; |
3872 | } |
3873 | |
3874 | uint64_t DwarfDebug::makeTypeSignature(StringRef Identifier) { |
3875 | MD5 Hash; |
3876 | Hash.update(Str: Identifier); |
3877 | // ... take the least significant 8 bytes and return those. Our MD5 |
3878 | // implementation always returns its results in little endian, so we actually |
3879 | // need the "high" word. |
3880 | MD5::MD5Result Result; |
3881 | Hash.final(Result); |
3882 | return Result.high(); |
3883 | } |
3884 | |
3885 | void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, |
3886 | StringRef Identifier, DIE &RefDie, |
3887 | const DICompositeType *CTy) { |
3888 | // Fast path if we're building some type units and one has already used the |
3889 | // address pool we know we're going to throw away all this work anyway, so |
3890 | // don't bother building dependent types. |
3891 | if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed()) |
3892 | return; |
3893 | |
3894 | auto Ins = TypeSignatures.try_emplace(Key: CTy); |
3895 | if (!Ins.second) { |
3896 | CU.addDIETypeSignature(Die&: RefDie, Signature: Ins.first->second); |
3897 | return; |
3898 | } |
3899 | |
3900 | setCurrentDWARF5AccelTable(DWARF5AccelTableKind::TU); |
3901 | bool TopLevelType = TypeUnitsUnderConstruction.empty(); |
3902 | AddrPool.resetUsedFlag(); |
3903 | |
3904 | auto OwnedUnit = std::make_unique<DwarfTypeUnit>( |
3905 | args&: CU, args&: Asm, args: this, args: &InfoHolder, args: NumTypeUnitsCreated++, args: getDwoLineTable(CU)); |
3906 | DwarfTypeUnit &NewTU = *OwnedUnit; |
3907 | DIE &UnitDie = NewTU.getUnitDie(); |
3908 | TypeUnitsUnderConstruction.emplace_back(Args: std::move(OwnedUnit), Args&: CTy); |
3909 | |
3910 | NewTU.addUInt(Die&: UnitDie, Attribute: dwarf::DW_AT_language, Form: dwarf::DW_FORM_data2, |
3911 | Integer: CU.getLanguage()); |
3912 | |
3913 | uint64_t Signature = makeTypeSignature(Identifier); |
3914 | NewTU.setTypeSignature(Signature); |
3915 | Ins.first->second = Signature; |
3916 | |
3917 | if (useSplitDwarf()) { |
3918 | // Although multiple type units can have the same signature, they are not |
3919 | // guranteed to be bit identical. When LLDB uses .debug_names it needs to |
3920 | // know from which CU a type unit came from. These two attrbutes help it to |
3921 | // figure that out. |
3922 | if (getDwarfVersion() >= 5) { |
3923 | if (!CompilationDir.empty()) |
3924 | NewTU.addString(Die&: UnitDie, Attribute: dwarf::DW_AT_comp_dir, Str: CompilationDir); |
3925 | NewTU.addString(Die&: UnitDie, Attribute: dwarf::DW_AT_dwo_name, |
3926 | Str: Asm->TM.Options.MCOptions.SplitDwarfFile); |
3927 | } |
3928 | MCSection *Section = |
3929 | getDwarfVersion() <= 4 |
3930 | ? Asm->getObjFileLowering().getDwarfTypesDWOSection() |
3931 | : Asm->getObjFileLowering().getDwarfInfoDWOSection(); |
3932 | NewTU.setSection(Section); |
3933 | } else { |
3934 | MCSection *Section = |
3935 | getDwarfVersion() <= 4 |
3936 | ? Asm->getObjFileLowering().getDwarfTypesSection(Hash: Signature) |
3937 | : Asm->getObjFileLowering().getDwarfInfoSection(Hash: Signature); |
3938 | NewTU.setSection(Section); |
3939 | // Non-split type units reuse the compile unit's line table. |
3940 | CU.applyStmtList(D&: UnitDie); |
3941 | } |
3942 | |
3943 | // Add DW_AT_str_offsets_base to the type unit DIE, but not for split type |
3944 | // units. |
3945 | if (useSegmentedStringOffsetsTable() && !useSplitDwarf()) |
3946 | NewTU.addStringOffsetsStart(); |
3947 | |
3948 | NewTU.setType(NewTU.createTypeDIE(Ty: CTy)); |
3949 | |
3950 | if (TopLevelType) { |
3951 | auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction); |
3952 | TypeUnitsUnderConstruction.clear(); |
3953 | |
3954 | // Types referencing entries in the address table cannot be placed in type |
3955 | // units. |
3956 | if (AddrPool.hasBeenUsed()) { |
3957 | AccelTypeUnitsDebugNames.clear(); |
3958 | // Remove all the types built while building this type. |
3959 | // This is pessimistic as some of these types might not be dependent on |
3960 | // the type that used an address. |
3961 | for (const auto &TU : TypeUnitsToAdd) |
3962 | TypeSignatures.erase(Val: TU.second); |
3963 | |
3964 | // Construct this type in the CU directly. |
3965 | // This is inefficient because all the dependent types will be rebuilt |
3966 | // from scratch, including building them in type units, discovering that |
3967 | // they depend on addresses, throwing them out and rebuilding them. |
3968 | setCurrentDWARF5AccelTable(DWARF5AccelTableKind::CU); |
3969 | CU.constructTypeDIE(Buffer&: RefDie, CTy: cast<DICompositeType>(Val: CTy)); |
3970 | CU.updateAcceleratorTables(Context: CTy->getScope(), Ty: CTy, TyDIE: RefDie); |
3971 | return; |
3972 | } |
3973 | |
3974 | // If the type wasn't dependent on fission addresses, finish adding the type |
3975 | // and all its dependent types. |
3976 | for (auto &TU : TypeUnitsToAdd) { |
3977 | InfoHolder.computeSizeAndOffsetsForUnit(TheU: TU.first.get()); |
3978 | InfoHolder.emitUnit(TheU: TU.first.get(), UseOffsets: useSplitDwarf()); |
3979 | if (getDwarfVersion() >= 5 && |
3980 | getAccelTableKind() == AccelTableKind::Dwarf) { |
3981 | if (useSplitDwarf()) |
3982 | AccelDebugNames.addTypeUnitSignature(U&: *TU.first); |
3983 | else |
3984 | AccelDebugNames.addTypeUnitSymbol(U&: *TU.first); |
3985 | } |
3986 | } |
3987 | AccelTypeUnitsDebugNames.convertDieToOffset(); |
3988 | AccelDebugNames.addTypeEntries(Table&: AccelTypeUnitsDebugNames); |
3989 | AccelTypeUnitsDebugNames.clear(); |
3990 | setCurrentDWARF5AccelTable(DWARF5AccelTableKind::CU); |
3991 | } |
3992 | CU.addDIETypeSignature(Die&: RefDie, Signature); |
3993 | } |
3994 | |
3995 | // Add the Name along with its companion DIE to the appropriate accelerator |
3996 | // table (for AccelTableKind::Dwarf it's always AccelDebugNames, for |
3997 | // AccelTableKind::Apple, we use the table we got as an argument). If |
3998 | // accelerator tables are disabled, this function does nothing. |
3999 | template <typename DataT> |
4000 | void DwarfDebug::addAccelNameImpl( |
4001 | const DwarfUnit &Unit, |
4002 | const DICompileUnit::DebugNameTableKind NameTableKind, |
4003 | AccelTable<DataT> &AppleAccel, StringRef Name, const DIE &Die) { |
4004 | if (getAccelTableKind() == AccelTableKind::None || |
4005 | Unit.getUnitDie().getTag() == dwarf::DW_TAG_skeleton_unit || Name.empty()) |
4006 | return; |
4007 | |
4008 | if (getAccelTableKind() != AccelTableKind::Apple && |
4009 | NameTableKind != DICompileUnit::DebugNameTableKind::Apple && |
4010 | NameTableKind != DICompileUnit::DebugNameTableKind::Default) |
4011 | return; |
4012 | |
4013 | DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; |
4014 | DwarfStringPoolEntryRef Ref = Holder.getStringPool().getEntry(Asm&: *Asm, Str: Name); |
4015 | |
4016 | switch (getAccelTableKind()) { |
4017 | case AccelTableKind::Apple: |
4018 | AppleAccel.addName(Ref, Die); |
4019 | break; |
4020 | case AccelTableKind::Dwarf: { |
4021 | DWARF5AccelTable &Current = getCurrentDWARF5AccelTable(); |
4022 | assert(((&Current == &AccelTypeUnitsDebugNames) || |
4023 | ((&Current == &AccelDebugNames) && |
4024 | (Unit.getUnitDie().getTag() != dwarf::DW_TAG_type_unit))) && |
4025 | "Kind is CU but TU is being processed." ); |
4026 | assert(((&Current == &AccelDebugNames) || |
4027 | ((&Current == &AccelTypeUnitsDebugNames) && |
4028 | (Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit))) && |
4029 | "Kind is TU but CU is being processed." ); |
4030 | // The type unit can be discarded, so need to add references to final |
4031 | // acceleration table once we know it's complete and we emit it. |
4032 | Current.addName(Name: Ref, Args: Die, Args: Unit.getUniqueID(), |
4033 | Args: Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit); |
4034 | break; |
4035 | } |
4036 | case AccelTableKind::Default: |
4037 | llvm_unreachable("Default should have already been resolved." ); |
4038 | case AccelTableKind::None: |
4039 | llvm_unreachable("None handled above" ); |
4040 | } |
4041 | } |
4042 | |
4043 | void DwarfDebug::addAccelName( |
4044 | const DwarfUnit &Unit, |
4045 | const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, |
4046 | const DIE &Die) { |
4047 | addAccelNameImpl(Unit, NameTableKind, AppleAccel&: AccelNames, Name, Die); |
4048 | } |
4049 | |
4050 | void DwarfDebug::addAccelObjC( |
4051 | const DwarfUnit &Unit, |
4052 | const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, |
4053 | const DIE &Die) { |
4054 | // ObjC names go only into the Apple accelerator tables. |
4055 | if (getAccelTableKind() == AccelTableKind::Apple) |
4056 | addAccelNameImpl(Unit, NameTableKind, AppleAccel&: AccelObjC, Name, Die); |
4057 | } |
4058 | |
4059 | void DwarfDebug::addAccelNamespace( |
4060 | const DwarfUnit &Unit, |
4061 | const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, |
4062 | const DIE &Die) { |
4063 | addAccelNameImpl(Unit, NameTableKind, AppleAccel&: AccelNamespace, Name, Die); |
4064 | } |
4065 | |
4066 | void DwarfDebug::addAccelType( |
4067 | const DwarfUnit &Unit, |
4068 | const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, |
4069 | const DIE &Die, char Flags) { |
4070 | addAccelNameImpl(Unit, NameTableKind, AppleAccel&: AccelTypes, Name, Die); |
4071 | } |
4072 | |
4073 | uint16_t DwarfDebug::getDwarfVersion() const { |
4074 | return Asm->OutStreamer->getContext().getDwarfVersion(); |
4075 | } |
4076 | |
4077 | dwarf::Form DwarfDebug::getDwarfSectionOffsetForm() const { |
4078 | if (Asm->getDwarfVersion() >= 4) |
4079 | return dwarf::Form::DW_FORM_sec_offset; |
4080 | assert((!Asm->isDwarf64() || (Asm->getDwarfVersion() == 3)) && |
4081 | "DWARF64 is not defined prior DWARFv3" ); |
4082 | return Asm->isDwarf64() ? dwarf::Form::DW_FORM_data8 |
4083 | : dwarf::Form::DW_FORM_data4; |
4084 | } |
4085 | |
4086 | const MCSymbol *DwarfDebug::getSectionLabel(const MCSection *S) { |
4087 | return SectionLabels.lookup(Val: S); |
4088 | } |
4089 | |
4090 | void DwarfDebug::insertSectionLabel(const MCSymbol *S) { |
4091 | if (SectionLabels.insert(KV: std::make_pair(x: &S->getSection(), y&: S)).second) |
4092 | if (useSplitDwarf() || getDwarfVersion() >= 5) |
4093 | AddrPool.getIndex(Sym: S); |
4094 | } |
4095 | |
4096 | std::optional<MD5::MD5Result> |
4097 | DwarfDebug::getMD5AsBytes(const DIFile *File) const { |
4098 | assert(File); |
4099 | if (getDwarfVersion() < 5) |
4100 | return std::nullopt; |
4101 | std::optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum(); |
4102 | if (!Checksum || Checksum->Kind != DIFile::CSK_MD5) |
4103 | return std::nullopt; |
4104 | |
4105 | // Convert the string checksum to an MD5Result for the streamer. |
4106 | // The verifier validates the checksum so we assume it's okay. |
4107 | // An MD5 checksum is 16 bytes. |
4108 | std::string ChecksumString = fromHex(Input: Checksum->Value); |
4109 | MD5::MD5Result CKMem; |
4110 | llvm::copy(Range&: ChecksumString, Out: CKMem.data()); |
4111 | return CKMem; |
4112 | } |
4113 | |
4114 | bool DwarfDebug::alwaysUseRanges(const DwarfCompileUnit &CU) const { |
4115 | if (MinimizeAddr == MinimizeAddrInV5::Ranges) |
4116 | return true; |
4117 | if (MinimizeAddr != MinimizeAddrInV5::Default) |
4118 | return false; |
4119 | if (useSplitDwarf()) |
4120 | return true; |
4121 | return false; |
4122 | } |
4123 | |
4124 | void DwarfDebug::beginCodeAlignment(const MachineBasicBlock &MBB) { |
4125 | if (MBB.getAlignment() == Align(1)) |
4126 | return; |
4127 | |
4128 | auto *SP = MBB.getParent()->getFunction().getSubprogram(); |
4129 | bool NoDebug = |
4130 | !SP || SP->getUnit()->getEmissionKind() == DICompileUnit::NoDebug; |
4131 | |
4132 | if (NoDebug) |
4133 | return; |
4134 | |
4135 | auto PrevLoc = Asm->OutStreamer->getContext().getCurrentDwarfLoc(); |
4136 | if (PrevLoc.getLine()) { |
4137 | Asm->OutStreamer->emitDwarfLocDirective( |
4138 | FileNo: PrevLoc.getFileNum(), Line: 0, Column: PrevLoc.getColumn(), Flags: 0, Isa: 0, Discriminator: 0, FileName: StringRef()); |
4139 | MCDwarfLineEntry::make(MCOS: Asm->OutStreamer.get(), |
4140 | Section: Asm->OutStreamer->getCurrentSectionOnly()); |
4141 | } |
4142 | } |
4143 | |