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