Line data Source code
1 : //===- llvm/CodeGen/DwarfFile.cpp - Dwarf Debug Framework -----------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 :
10 : #include "DwarfFile.h"
11 : #include "DwarfCompileUnit.h"
12 : #include "DwarfDebug.h"
13 : #include "DwarfUnit.h"
14 : #include "llvm/ADT/SmallVector.h"
15 : #include "llvm/CodeGen/AsmPrinter.h"
16 : #include "llvm/CodeGen/DIE.h"
17 : #include "llvm/IR/DebugInfoMetadata.h"
18 : #include "llvm/MC/MCStreamer.h"
19 : #include <algorithm>
20 : #include <cstdint>
21 :
22 : using namespace llvm;
23 :
24 53964 : DwarfFile::DwarfFile(AsmPrinter *AP, StringRef Pref, BumpPtrAllocator &DA)
25 53964 : : Asm(AP), Abbrevs(AbbrevAllocator), StrPool(DA, *Asm, Pref) {}
26 :
27 1389 : void DwarfFile::addUnit(std::unique_ptr<DwarfCompileUnit> U) {
28 1389 : CUs.push_back(std::move(U));
29 1389 : }
30 :
31 : // Emit the various dwarf units to the unit section USection with
32 : // the abbreviations going into ASection.
33 1105 : void DwarfFile::emitUnits(bool UseOffsets) {
34 2492 : for (const auto &TheU : CUs)
35 2774 : emitUnit(TheU.get(), UseOffsets);
36 1105 : }
37 :
38 1420 : void DwarfFile::emitUnit(DwarfUnit *TheU, bool UseOffsets) {
39 1420 : if (TheU->getCUNode()->isDebugDirectivesOnly())
40 : return;
41 :
42 : DIE &Die = TheU->getUnitDie();
43 1418 : MCSection *USection = TheU->getSection();
44 2836 : Asm->OutStreamer->SwitchSection(USection);
45 :
46 1418 : TheU->emitHeader(UseOffsets);
47 :
48 1418 : Asm->emitDwarfDIE(Die);
49 : }
50 :
51 : // Compute the size and offset for each DIE.
52 1105 : void DwarfFile::computeSizeAndOffsets() {
53 : // Offset from the first CU in the debug info section is 0 initially.
54 : unsigned SecOffset = 0;
55 :
56 : // Iterate over each compile unit and set the size and offsets for each
57 : // DIE within each compile unit. All offsets are CU relative.
58 2492 : for (const auto &TheU : CUs) {
59 1387 : if (TheU->getCUNode()->isDebugDirectivesOnly())
60 : continue;
61 :
62 : TheU->setDebugSectionOffset(SecOffset);
63 1385 : SecOffset += computeSizeAndOffsetsForUnit(TheU.get());
64 : }
65 1105 : }
66 :
67 1417 : unsigned DwarfFile::computeSizeAndOffsetsForUnit(DwarfUnit *TheU) {
68 : // CU-relative offset is reset to 0 here.
69 : unsigned Offset = sizeof(int32_t) + // Length of Unit Info
70 1417 : TheU->getHeaderSize(); // Unit-specific headers
71 :
72 : // The return value here is CU-relative, after laying out
73 : // all of the CU DIE.
74 1418 : return computeSizeAndOffset(TheU->getUnitDie(), Offset);
75 : }
76 :
77 : // Compute the size and offset of a DIE. The offset is relative to start of the
78 : // CU. It returns the offset after laying out the DIE.
79 1418 : unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) {
80 1418 : return Die.computeOffsetsAndAbbrevs(Asm, Abbrevs, Offset);
81 : }
82 :
83 1105 : void DwarfFile::emitAbbrevs(MCSection *Section) { Abbrevs.Emit(Asm, Section); }
84 :
85 : // Emit strings into a string section.
86 1105 : void DwarfFile::emitStrings(MCSection *StrSection, MCSection *OffsetSection,
87 : bool UseRelativeOffsets) {
88 1105 : StrPool.emit(*Asm, StrSection, OffsetSection, UseRelativeOffsets);
89 1105 : }
90 :
91 77237 : bool DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
92 77237 : auto &ScopeVars = ScopeVariables[LS];
93 77237 : const DILocalVariable *DV = Var->getVariable();
94 77237 : if (unsigned ArgNum = DV->getArg()) {
95 : auto Cached = ScopeVars.Args.find(ArgNum);
96 72564 : if (Cached == ScopeVars.Args.end())
97 72564 : ScopeVars.Args[ArgNum] = Var;
98 : else {
99 0 : Cached->second->addMMIEntry(*Var);
100 : return false;
101 : }
102 : } else {
103 4673 : ScopeVars.Locals.push_back(Var);
104 : }
105 77237 : return true;
106 : }
107 :
108 8 : void DwarfFile::addScopeLabel(LexicalScope *LS, DbgLabel *Label) {
109 8 : SmallVectorImpl<DbgLabel *> &Labels = ScopeLabels[LS];
110 8 : Labels.push_back(Label);
111 8 : }
|