/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- llvm/CodeGen/DwarfFile.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 | | #include "DwarfFile.h" |
10 | | #include "DwarfCompileUnit.h" |
11 | | #include "DwarfDebug.h" |
12 | | #include "DwarfUnit.h" |
13 | | #include "llvm/ADT/SmallVector.h" |
14 | | #include "llvm/CodeGen/AsmPrinter.h" |
15 | | #include "llvm/CodeGen/DIE.h" |
16 | | #include "llvm/IR/DebugInfoMetadata.h" |
17 | | #include "llvm/MC/MCStreamer.h" |
18 | | #include <algorithm> |
19 | | #include <cstdint> |
20 | | |
21 | | using namespace llvm; |
22 | | |
23 | | DwarfFile::DwarfFile(AsmPrinter *AP, StringRef Pref, BumpPtrAllocator &DA) |
24 | 71.5k | : Asm(AP), Abbrevs(AbbrevAllocator), StrPool(DA, *Asm, Pref) {} |
25 | | |
26 | 2.72k | void DwarfFile::addUnit(std::unique_ptr<DwarfCompileUnit> U) { |
27 | 2.72k | CUs.push_back(std::move(U)); |
28 | 2.72k | } |
29 | | |
30 | | // Emit the various dwarf units to the unit section USection with |
31 | | // the abbreviations going into ASection. |
32 | 3.26k | void DwarfFile::emitUnits(bool UseOffsets) { |
33 | 3.26k | for (const auto &TheU : CUs) |
34 | 2.72k | emitUnit(TheU.get(), UseOffsets); |
35 | 3.26k | } |
36 | | |
37 | 2.76k | void DwarfFile::emitUnit(DwarfUnit *TheU, bool UseOffsets) { |
38 | 2.76k | if (TheU->getCUNode()->isDebugDirectivesOnly()) |
39 | 3 | return; |
40 | 2.76k | |
41 | 2.76k | MCSection *S = TheU->getSection(); |
42 | 2.76k | |
43 | 2.76k | if (!S) |
44 | 0 | return; |
45 | 2.76k | |
46 | 2.76k | // Skip CUs that ended up not being needed (split CUs that were abandoned |
47 | 2.76k | // because they added no information beyond the non-split CU) |
48 | 2.76k | if (llvm::empty(TheU->getUnitDie().values())) |
49 | 1 | return; |
50 | 2.75k | |
51 | 2.75k | Asm->OutStreamer->SwitchSection(S); |
52 | 2.75k | TheU->emitHeader(UseOffsets); |
53 | 2.75k | Asm->emitDwarfDIE(TheU->getUnitDie()); |
54 | 2.75k | |
55 | 2.75k | if (MCSymbol *EndLabel = TheU->getEndLabel()) |
56 | 2.74k | Asm->OutStreamer->EmitLabel(EndLabel); |
57 | 2.75k | } |
58 | | |
59 | | // Compute the size and offset for each DIE. |
60 | 3.26k | void DwarfFile::computeSizeAndOffsets() { |
61 | 3.26k | // Offset from the first CU in the debug info section is 0 initially. |
62 | 3.26k | unsigned SecOffset = 0; |
63 | 3.26k | |
64 | 3.26k | // Iterate over each compile unit and set the size and offsets for each |
65 | 3.26k | // DIE within each compile unit. All offsets are CU relative. |
66 | 3.26k | for (const auto &TheU : CUs) { |
67 | 2.72k | if (TheU->getCUNode()->isDebugDirectivesOnly()) |
68 | 3 | continue; |
69 | 2.72k | |
70 | 2.72k | // Skip CUs that ended up not being needed (split CUs that were abandoned |
71 | 2.72k | // because they added no information beyond the non-split CU) |
72 | 2.72k | if (llvm::empty(TheU->getUnitDie().values())) |
73 | 1 | return; |
74 | 2.72k | |
75 | 2.72k | TheU->setDebugSectionOffset(SecOffset); |
76 | 2.72k | SecOffset += computeSizeAndOffsetsForUnit(TheU.get()); |
77 | 2.72k | } |
78 | 3.26k | } |
79 | | |
80 | 2.75k | unsigned DwarfFile::computeSizeAndOffsetsForUnit(DwarfUnit *TheU) { |
81 | 2.75k | // CU-relative offset is reset to 0 here. |
82 | 2.75k | unsigned Offset = sizeof(int32_t) + // Length of Unit Info |
83 | 2.75k | TheU->getHeaderSize(); // Unit-specific headers |
84 | 2.75k | |
85 | 2.75k | // The return value here is CU-relative, after laying out |
86 | 2.75k | // all of the CU DIE. |
87 | 2.75k | return computeSizeAndOffset(TheU->getUnitDie(), Offset); |
88 | 2.75k | } |
89 | | |
90 | | // Compute the size and offset of a DIE. The offset is relative to start of the |
91 | | // CU. It returns the offset after laying out the DIE. |
92 | 2.75k | unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) { |
93 | 2.75k | return Die.computeOffsetsAndAbbrevs(Asm, Abbrevs, Offset); |
94 | 2.75k | } |
95 | | |
96 | 3.26k | void DwarfFile::emitAbbrevs(MCSection *Section) { Abbrevs.Emit(Asm, Section); } |
97 | | |
98 | | // Emit strings into a string section. |
99 | | void DwarfFile::emitStrings(MCSection *StrSection, MCSection *OffsetSection, |
100 | 3.26k | bool UseRelativeOffsets) { |
101 | 3.26k | StrPool.emit(*Asm, StrSection, OffsetSection, UseRelativeOffsets); |
102 | 3.26k | } |
103 | | |
104 | 1.31k | bool DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) { |
105 | 1.31k | auto &ScopeVars = ScopeVariables[LS]; |
106 | 1.31k | const DILocalVariable *DV = Var->getVariable(); |
107 | 1.31k | if (unsigned ArgNum = DV->getArg()) { |
108 | 789 | auto Cached = ScopeVars.Args.find(ArgNum); |
109 | 789 | if (Cached == ScopeVars.Args.end()) |
110 | 789 | ScopeVars.Args[ArgNum] = Var; |
111 | 0 | else { |
112 | 0 | Cached->second->addMMIEntry(*Var); |
113 | 0 | return false; |
114 | 0 | } |
115 | 523 | } else { |
116 | 523 | ScopeVars.Locals.push_back(Var); |
117 | 523 | } |
118 | 1.31k | return true; |
119 | 1.31k | } |
120 | | |
121 | 8 | void DwarfFile::addScopeLabel(LexicalScope *LS, DbgLabel *Label) { |
122 | 8 | SmallVectorImpl<DbgLabel *> &Labels = ScopeLabels[LS]; |
123 | 8 | Labels.push_back(Label); |
124 | 8 | } |
125 | | |
126 | | std::pair<uint32_t, RangeSpanList *> |
127 | 56.9k | DwarfFile::addRange(const DwarfCompileUnit &CU, SmallVector<RangeSpan, 2> R) { |
128 | 56.9k | CURangeLists.push_back( |
129 | 56.9k | RangeSpanList(Asm->createTempSymbol("debug_ranges"), CU, std::move(R))); |
130 | 56.9k | return std::make_pair(CURangeLists.size() - 1, &CURangeLists.back()); |
131 | 56.9k | } |