/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- AsmPrinterDwarf.cpp - AsmPrinter Dwarf Support --------------------===// |
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 | | // This file implements the Dwarf emissions parts of AsmPrinter. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "ByteStreamer.h" |
15 | | #include "DwarfDebug.h" |
16 | | #include "DwarfExpression.h" |
17 | | #include "llvm/ADT/Twine.h" |
18 | | #include "llvm/BinaryFormat/Dwarf.h" |
19 | | #include "llvm/CodeGen/AsmPrinter.h" |
20 | | #include "llvm/CodeGen/DIE.h" |
21 | | #include "llvm/CodeGen/MachineFunction.h" |
22 | | #include "llvm/CodeGen/MachineModuleInfo.h" |
23 | | #include "llvm/IR/DataLayout.h" |
24 | | #include "llvm/MC/MCAsmInfo.h" |
25 | | #include "llvm/MC/MCRegisterInfo.h" |
26 | | #include "llvm/MC/MCSection.h" |
27 | | #include "llvm/MC/MCStreamer.h" |
28 | | #include "llvm/MC/MCSymbol.h" |
29 | | #include "llvm/MC/MachineLocation.h" |
30 | | #include "llvm/Support/ErrorHandling.h" |
31 | | #include "llvm/Target/TargetLoweringObjectFile.h" |
32 | | #include "llvm/Target/TargetMachine.h" |
33 | | #include "llvm/Target/TargetSubtargetInfo.h" |
34 | | using namespace llvm; |
35 | | |
36 | | #define DEBUG_TYPE "asm-printer" |
37 | | |
38 | | //===----------------------------------------------------------------------===// |
39 | | // Dwarf Emission Helper Routines |
40 | | //===----------------------------------------------------------------------===// |
41 | | |
42 | | /// EmitSLEB128 - emit the specified signed leb128 value. |
43 | 4.52k | void AsmPrinter::EmitSLEB128(int64_t Value, const char *Desc) const { |
44 | 4.52k | if (isVerbose() && 4.52k Desc507 ) |
45 | 0 | OutStreamer->AddComment(Desc); |
46 | 4.52k | |
47 | 4.52k | OutStreamer->EmitSLEB128IntValue(Value); |
48 | 4.52k | } |
49 | | |
50 | | /// EmitULEB128 - emit the specified unsigned leb128 value. |
51 | | void AsmPrinter::EmitPaddedULEB128(uint64_t Value, unsigned PadTo, |
52 | 5.89k | const char *Desc) const { |
53 | 5.89k | if (isVerbose() && 5.89k Desc475 ) |
54 | 475 | OutStreamer->AddComment(Desc); |
55 | 5.89k | |
56 | 5.89k | OutStreamer->EmitPaddedULEB128IntValue(Value, PadTo); |
57 | 5.89k | } |
58 | | |
59 | 226k | void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc) const { |
60 | 226k | if (isVerbose() && 226k Desc25.4k ) |
61 | 22.0k | OutStreamer->AddComment(Desc); |
62 | 226k | |
63 | 226k | OutStreamer->EmitULEB128IntValue(Value); |
64 | 226k | } |
65 | | |
66 | 729 | static const char *DecodeDWARFEncoding(unsigned Encoding) { |
67 | 729 | switch (Encoding) { |
68 | 94 | case dwarf::DW_EH_PE_absptr: |
69 | 94 | return "absptr"; |
70 | 254 | case dwarf::DW_EH_PE_omit: |
71 | 254 | return "omit"; |
72 | 0 | case dwarf::DW_EH_PE_pcrel: |
73 | 0 | return "pcrel"; |
74 | 289 | case dwarf::DW_EH_PE_udata4: |
75 | 289 | return "udata4"; |
76 | 0 | case dwarf::DW_EH_PE_udata8: |
77 | 0 | return "udata8"; |
78 | 0 | case dwarf::DW_EH_PE_sdata4: |
79 | 0 | return "sdata4"; |
80 | 0 | case dwarf::DW_EH_PE_sdata8: |
81 | 0 | return "sdata8"; |
82 | 0 | case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4: |
83 | 0 | return "pcrel udata4"; |
84 | 0 | case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4: |
85 | 0 | return "pcrel sdata4"; |
86 | 0 | case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8: |
87 | 0 | return "pcrel udata8"; |
88 | 0 | case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8: |
89 | 0 | return "pcrel sdata8"; |
90 | 0 | case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4 |
91 | 0 | : |
92 | 0 | return "indirect pcrel udata4"; |
93 | 84 | case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 |
94 | 84 | : |
95 | 84 | return "indirect pcrel sdata4"; |
96 | 6 | case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8 |
97 | 6 | : |
98 | 6 | return "indirect pcrel udata8"; |
99 | 2 | case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8 |
100 | 2 | : |
101 | 2 | return "indirect pcrel sdata8"; |
102 | 0 | } |
103 | 0 |
|
104 | 0 | return "<unknown encoding>"; |
105 | 0 | } |
106 | | |
107 | | /// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an |
108 | | /// encoding. If verbose assembly output is enabled, we output comments |
109 | | /// describing the encoding. Desc is an optional string saying what the |
110 | | /// encoding is specifying (e.g. "LSDA"). |
111 | 8.85k | void AsmPrinter::EmitEncodingByte(unsigned Val, const char *Desc) const { |
112 | 8.85k | if (isVerbose()8.85k ) { |
113 | 729 | if (Desc) |
114 | 729 | OutStreamer->AddComment(Twine(Desc) + " Encoding = " + |
115 | 729 | Twine(DecodeDWARFEncoding(Val))); |
116 | 729 | else |
117 | 0 | OutStreamer->AddComment(Twine("Encoding = ") + DecodeDWARFEncoding(Val)); |
118 | 729 | } |
119 | 8.85k | |
120 | 8.85k | OutStreamer->EmitIntValue(Val, 1); |
121 | 8.85k | } |
122 | | |
123 | | /// GetSizeOfEncodedValue - Return the size of the encoding in bytes. |
124 | 4.83k | unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const { |
125 | 4.83k | if (Encoding == dwarf::DW_EH_PE_omit) |
126 | 0 | return 0; |
127 | 4.83k | |
128 | 4.83k | switch (Encoding & 0x07) { |
129 | 0 | default: |
130 | 0 | llvm_unreachable("Invalid encoded value."); |
131 | 172 | case dwarf::DW_EH_PE_absptr: |
132 | 172 | return MF->getDataLayout().getPointerSize(); |
133 | 0 | case dwarf::DW_EH_PE_udata2: |
134 | 0 | return 2; |
135 | 4.65k | case dwarf::DW_EH_PE_udata4: |
136 | 4.65k | return 4; |
137 | 11 | case dwarf::DW_EH_PE_udata8: |
138 | 11 | return 8; |
139 | 0 | } |
140 | 0 | } |
141 | | |
142 | | void AsmPrinter::EmitTTypeReference(const GlobalValue *GV, |
143 | 1.89k | unsigned Encoding) const { |
144 | 1.89k | if (GV1.89k ) { |
145 | 316 | const TargetLoweringObjectFile &TLOF = getObjFileLowering(); |
146 | 316 | |
147 | 316 | const MCExpr *Exp = |
148 | 316 | TLOF.getTTypeGlobalReference(GV, Encoding, TM, MMI, *OutStreamer); |
149 | 316 | OutStreamer->EmitValue(Exp, GetSizeOfEncodedValue(Encoding)); |
150 | 316 | } else |
151 | 1.58k | OutStreamer->EmitIntValue(0, GetSizeOfEncodedValue(Encoding)); |
152 | 1.89k | } |
153 | | |
154 | | void AsmPrinter::emitDwarfSymbolReference(const MCSymbol *Label, |
155 | 2.15k | bool ForceOffset) const { |
156 | 2.15k | if (!ForceOffset2.15k ) { |
157 | 2.14k | // On COFF targets, we have to emit the special .secrel32 directive. |
158 | 2.14k | if (MAI->needsDwarfSectionOffsetDirective()2.14k ) { |
159 | 120 | OutStreamer->EmitCOFFSecRel32(Label, /*Offset=*/0); |
160 | 120 | return; |
161 | 120 | } |
162 | 2.02k | |
163 | 2.02k | // If the format uses relocations with dwarf, refer to the symbol directly. |
164 | 2.02k | if (2.02k MAI->doesDwarfUseRelocationsAcrossSections()2.02k ) { |
165 | 963 | OutStreamer->EmitSymbolValue(Label, 4); |
166 | 963 | return; |
167 | 963 | } |
168 | 1.06k | } |
169 | 1.06k | |
170 | 1.06k | // Otherwise, emit it as a label difference from the start of the section. |
171 | 1.06k | EmitLabelDifference(Label, Label->getSection().getBeginSymbol(), 4); |
172 | 1.06k | } |
173 | | |
174 | 17.1k | void AsmPrinter::emitDwarfStringOffset(DwarfStringPoolEntryRef S) const { |
175 | 17.1k | if (MAI->doesDwarfUseRelocationsAcrossSections()17.1k ) { |
176 | 39 | emitDwarfSymbolReference(S.getSymbol()); |
177 | 39 | return; |
178 | 39 | } |
179 | 17.1k | |
180 | 17.1k | // Just emit the offset directly; no need for symbol math. |
181 | 17.1k | EmitInt32(S.getOffset()); |
182 | 17.1k | } |
183 | | |
184 | | //===----------------------------------------------------------------------===// |
185 | | // Dwarf Lowering Routines |
186 | | //===----------------------------------------------------------------------===// |
187 | | |
188 | 330k | void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const { |
189 | 330k | switch (Inst.getOperation()) { |
190 | 0 | default: |
191 | 0 | llvm_unreachable("Unexpected instruction"); |
192 | 18.3k | case MCCFIInstruction::OpDefCfaOffset: |
193 | 18.3k | OutStreamer->EmitCFIDefCfaOffset(Inst.getOffset()); |
194 | 18.3k | break; |
195 | 1.20k | case MCCFIInstruction::OpAdjustCfaOffset: |
196 | 1.20k | OutStreamer->EmitCFIAdjustCfaOffset(Inst.getOffset()); |
197 | 1.20k | break; |
198 | 35.6k | case MCCFIInstruction::OpDefCfa: |
199 | 35.6k | OutStreamer->EmitCFIDefCfa(Inst.getRegister(), Inst.getOffset()); |
200 | 35.6k | break; |
201 | 7.55k | case MCCFIInstruction::OpDefCfaRegister: |
202 | 7.55k | OutStreamer->EmitCFIDefCfaRegister(Inst.getRegister()); |
203 | 7.55k | break; |
204 | 266k | case MCCFIInstruction::OpOffset: |
205 | 266k | OutStreamer->EmitCFIOffset(Inst.getRegister(), Inst.getOffset()); |
206 | 266k | break; |
207 | 380 | case MCCFIInstruction::OpRegister: |
208 | 380 | OutStreamer->EmitCFIRegister(Inst.getRegister(), Inst.getRegister2()); |
209 | 380 | break; |
210 | 380 | case MCCFIInstruction::OpWindowSave: |
211 | 380 | OutStreamer->EmitCFIWindowSave(); |
212 | 380 | break; |
213 | 4 | case MCCFIInstruction::OpSameValue: |
214 | 4 | OutStreamer->EmitCFISameValue(Inst.getRegister()); |
215 | 4 | break; |
216 | 18 | case MCCFIInstruction::OpGnuArgsSize: |
217 | 18 | OutStreamer->EmitCFIGnuArgsSize(Inst.getOffset()); |
218 | 18 | break; |
219 | 0 | case MCCFIInstruction::OpEscape: |
220 | 0 | OutStreamer->EmitCFIEscape(Inst.getValues()); |
221 | 0 | break; |
222 | 330k | } |
223 | 330k | } |
224 | | |
225 | 62.5k | void AsmPrinter::emitDwarfDIE(const DIE &Die) const { |
226 | 62.5k | // Emit the code (index) for the abbreviation. |
227 | 62.5k | if (isVerbose()) |
228 | 2.15k | OutStreamer->AddComment("Abbrev [" + Twine(Die.getAbbrevNumber()) + "] 0x" + |
229 | 2.15k | Twine::utohexstr(Die.getOffset()) + ":0x" + |
230 | 2.15k | Twine::utohexstr(Die.getSize()) + " " + |
231 | 2.15k | dwarf::TagString(Die.getTag())); |
232 | 62.5k | EmitULEB128(Die.getAbbrevNumber()); |
233 | 62.5k | |
234 | 62.5k | // Emit the DIE attribute values. |
235 | 239k | for (const auto &V : Die.values()) { |
236 | 239k | dwarf::Attribute Attr = V.getAttribute(); |
237 | 239k | assert(V.getForm() && "Too many attributes for DIE (check abbreviation)"); |
238 | 239k | |
239 | 239k | if (isVerbose()239k ) { |
240 | 9.87k | OutStreamer->AddComment(dwarf::AttributeString(Attr)); |
241 | 9.87k | if (Attr == dwarf::DW_AT_accessibility) |
242 | 22 | OutStreamer->AddComment( |
243 | 22 | dwarf::AccessibilityString(V.getDIEInteger().getValue())); |
244 | 9.87k | } |
245 | 239k | |
246 | 239k | // Emit an attribute using the defined form. |
247 | 239k | V.EmitValue(this); |
248 | 239k | } |
249 | 62.5k | |
250 | 62.5k | // Emit the DIE children if any. |
251 | 62.5k | if (Die.hasChildren()62.5k ) { |
252 | 22.7k | for (auto &Child : Die.children()) |
253 | 61.1k | emitDwarfDIE(Child); |
254 | 22.7k | |
255 | 22.7k | OutStreamer->AddComment("End Of Children Mark"); |
256 | 22.7k | EmitInt8(0); |
257 | 22.7k | } |
258 | 62.5k | } |
259 | | |
260 | 10.0k | void AsmPrinter::emitDwarfAbbrev(const DIEAbbrev &Abbrev) const { |
261 | 10.0k | // Emit the abbreviations code (base 1 index.) |
262 | 10.0k | EmitULEB128(Abbrev.getNumber(), "Abbreviation Code"); |
263 | 10.0k | |
264 | 10.0k | // Emit the abbreviations data. |
265 | 10.0k | Abbrev.Emit(this); |
266 | 10.0k | } |