]>
Commit | Line | Data |
---|---|---|
85aaf69f SL |
1 | #include "DwarfCompileUnit.h" |
2 | #include "DwarfExpression.h" | |
3 | #include "llvm/CodeGen/MachineFunction.h" | |
4 | #include "llvm/IR/DataLayout.h" | |
5 | #include "llvm/IR/GlobalValue.h" | |
6 | #include "llvm/IR/GlobalVariable.h" | |
7 | #include "llvm/IR/Instruction.h" | |
8 | #include "llvm/MC/MCAsmInfo.h" | |
9 | #include "llvm/MC/MCStreamer.h" | |
10 | #include "llvm/Target/TargetFrameLowering.h" | |
11 | #include "llvm/Target/TargetLoweringObjectFile.h" | |
12 | #include "llvm/Target/TargetMachine.h" | |
13 | #include "llvm/Target/TargetRegisterInfo.h" | |
14 | #include "llvm/Target/TargetSubtargetInfo.h" | |
15 | ||
16 | namespace llvm { | |
17 | ||
18 | DwarfCompileUnit::DwarfCompileUnit(unsigned UID, DICompileUnit Node, | |
19 | AsmPrinter *A, DwarfDebug *DW, | |
20 | DwarfFile *DWU) | |
21 | : DwarfUnit(UID, dwarf::DW_TAG_compile_unit, Node, A, DW, DWU), | |
22 | Skeleton(nullptr), LabelBegin(nullptr), BaseAddress(nullptr) { | |
23 | insertDIE(Node, &getUnitDie()); | |
24 | } | |
25 | ||
26 | /// addLabelAddress - Add a dwarf label attribute data and value using | |
27 | /// DW_FORM_addr or DW_FORM_GNU_addr_index. | |
28 | /// | |
29 | void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute, | |
30 | const MCSymbol *Label) { | |
31 | ||
32 | // Don't use the address pool in non-fission or in the skeleton unit itself. | |
33 | // FIXME: Once GDB supports this, it's probably worthwhile using the address | |
34 | // pool from the skeleton - maybe even in non-fission (possibly fewer | |
35 | // relocations by sharing them in the pool, but we have other ideas about how | |
36 | // to reduce the number of relocations as well/instead). | |
37 | if (!DD->useSplitDwarf() || !Skeleton) | |
38 | return addLocalLabelAddress(Die, Attribute, Label); | |
39 | ||
40 | if (Label) | |
41 | DD->addArangeLabel(SymbolCU(this, Label)); | |
42 | ||
43 | unsigned idx = DD->getAddressPool().getIndex(Label); | |
44 | DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx); | |
45 | Die.addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, Value); | |
46 | } | |
47 | ||
48 | void DwarfCompileUnit::addLocalLabelAddress(DIE &Die, | |
49 | dwarf::Attribute Attribute, | |
50 | const MCSymbol *Label) { | |
51 | if (Label) | |
52 | DD->addArangeLabel(SymbolCU(this, Label)); | |
53 | ||
54 | Die.addValue(Attribute, dwarf::DW_FORM_addr, | |
55 | Label ? (DIEValue *)new (DIEValueAllocator) DIELabel(Label) | |
56 | : new (DIEValueAllocator) DIEInteger(0)); | |
57 | } | |
58 | ||
59 | unsigned DwarfCompileUnit::getOrCreateSourceID(StringRef FileName, | |
60 | StringRef DirName) { | |
61 | // If we print assembly, we can't separate .file entries according to | |
62 | // compile units. Thus all files will belong to the default compile unit. | |
63 | ||
64 | // FIXME: add a better feature test than hasRawTextSupport. Even better, | |
65 | // extend .file to support this. | |
66 | return Asm->OutStreamer.EmitDwarfFileDirective( | |
67 | 0, DirName, FileName, | |
68 | Asm->OutStreamer.hasRawTextSupport() ? 0 : getUniqueID()); | |
69 | } | |
70 | ||
71 | // Return const expression if value is a GEP to access merged global | |
72 | // constant. e.g. | |
73 | // i8* getelementptr ({ i8, i8, i8, i8 }* @_MergedGlobals, i32 0, i32 0) | |
74 | static const ConstantExpr *getMergedGlobalExpr(const Value *V) { | |
75 | const ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(V); | |
76 | if (!CE || CE->getNumOperands() != 3 || | |
77 | CE->getOpcode() != Instruction::GetElementPtr) | |
78 | return nullptr; | |
79 | ||
80 | // First operand points to a global struct. | |
81 | Value *Ptr = CE->getOperand(0); | |
82 | if (!isa<GlobalValue>(Ptr) || | |
83 | !isa<StructType>(cast<PointerType>(Ptr->getType())->getElementType())) | |
84 | return nullptr; | |
85 | ||
86 | // Second operand is zero. | |
87 | const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CE->getOperand(1)); | |
88 | if (!CI || !CI->isZero()) | |
89 | return nullptr; | |
90 | ||
91 | // Third operand is offset. | |
92 | if (!isa<ConstantInt>(CE->getOperand(2))) | |
93 | return nullptr; | |
94 | ||
95 | return CE; | |
96 | } | |
97 | ||
98 | /// getOrCreateGlobalVariableDIE - get or create global variable DIE. | |
99 | DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(DIGlobalVariable GV) { | |
100 | // Check for pre-existence. | |
101 | if (DIE *Die = getDIE(GV)) | |
102 | return Die; | |
103 | ||
104 | assert(GV.isGlobalVariable()); | |
105 | ||
106 | DIScope GVContext = GV.getContext(); | |
107 | DIType GTy = DD->resolve(GV.getType()); | |
108 | ||
109 | // Construct the context before querying for the existence of the DIE in | |
110 | // case such construction creates the DIE. | |
111 | DIE *ContextDIE = getOrCreateContextDIE(GVContext); | |
112 | ||
113 | // Add to map. | |
114 | DIE *VariableDIE = &createAndAddDIE(GV.getTag(), *ContextDIE, GV); | |
115 | DIScope DeclContext; | |
116 | ||
117 | if (DIDerivedType SDMDecl = GV.getStaticDataMemberDeclaration()) { | |
118 | DeclContext = resolve(SDMDecl.getContext()); | |
119 | assert(SDMDecl.isStaticMember() && "Expected static member decl"); | |
120 | assert(GV.isDefinition()); | |
121 | // We need the declaration DIE that is in the static member's class. | |
122 | DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl); | |
123 | addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE); | |
124 | } else { | |
125 | DeclContext = GV.getContext(); | |
126 | // Add name and type. | |
127 | addString(*VariableDIE, dwarf::DW_AT_name, GV.getDisplayName()); | |
128 | addType(*VariableDIE, GTy); | |
129 | ||
130 | // Add scoping info. | |
131 | if (!GV.isLocalToUnit()) | |
132 | addFlag(*VariableDIE, dwarf::DW_AT_external); | |
133 | ||
134 | // Add line number info. | |
135 | addSourceLine(*VariableDIE, GV); | |
136 | } | |
137 | ||
138 | if (!GV.isDefinition()) | |
139 | addFlag(*VariableDIE, dwarf::DW_AT_declaration); | |
140 | ||
141 | // Add location. | |
142 | bool addToAccelTable = false; | |
143 | bool isGlobalVariable = GV.getGlobal() != nullptr; | |
144 | if (isGlobalVariable) { | |
145 | addToAccelTable = true; | |
146 | DIELoc *Loc = new (DIEValueAllocator) DIELoc(); | |
147 | const MCSymbol *Sym = Asm->getSymbol(GV.getGlobal()); | |
148 | if (GV.getGlobal()->isThreadLocal()) { | |
149 | // FIXME: Make this work with -gsplit-dwarf. | |
150 | unsigned PointerSize = Asm->getDataLayout().getPointerSize(); | |
151 | assert((PointerSize == 4 || PointerSize == 8) && | |
152 | "Add support for other sizes if necessary"); | |
153 | // Based on GCC's support for TLS: | |
154 | if (!DD->useSplitDwarf()) { | |
155 | // 1) Start with a constNu of the appropriate pointer size | |
156 | addUInt(*Loc, dwarf::DW_FORM_data1, | |
157 | PointerSize == 4 ? dwarf::DW_OP_const4u : dwarf::DW_OP_const8u); | |
158 | // 2) containing the (relocated) offset of the TLS variable | |
159 | // within the module's TLS block. | |
160 | addExpr(*Loc, dwarf::DW_FORM_udata, | |
161 | Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym)); | |
162 | } else { | |
163 | addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index); | |
164 | addUInt(*Loc, dwarf::DW_FORM_udata, | |
165 | DD->getAddressPool().getIndex(Sym, /* TLS */ true)); | |
166 | } | |
167 | // 3) followed by a custom OP to make the debugger do a TLS lookup. | |
168 | addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_push_tls_address); | |
169 | } else { | |
170 | DD->addArangeLabel(SymbolCU(this, Sym)); | |
171 | addOpAddress(*Loc, Sym); | |
172 | } | |
173 | ||
174 | addBlock(*VariableDIE, dwarf::DW_AT_location, Loc); | |
175 | // Add the linkage name. | |
176 | StringRef LinkageName = GV.getLinkageName(); | |
177 | if (!LinkageName.empty()) | |
178 | // From DWARF4: DIEs to which DW_AT_linkage_name may apply include: | |
179 | // TAG_common_block, TAG_constant, TAG_entry_point, TAG_subprogram and | |
180 | // TAG_variable. | |
181 | addString(*VariableDIE, | |
182 | DD->getDwarfVersion() >= 4 ? dwarf::DW_AT_linkage_name | |
183 | : dwarf::DW_AT_MIPS_linkage_name, | |
184 | GlobalValue::getRealLinkageName(LinkageName)); | |
185 | } else if (const ConstantInt *CI = | |
186 | dyn_cast_or_null<ConstantInt>(GV.getConstant())) { | |
187 | addConstantValue(*VariableDIE, CI, GTy); | |
188 | } else if (const ConstantExpr *CE = getMergedGlobalExpr(GV.getConstant())) { | |
189 | addToAccelTable = true; | |
190 | // GV is a merged global. | |
191 | DIELoc *Loc = new (DIEValueAllocator) DIELoc(); | |
192 | Value *Ptr = CE->getOperand(0); | |
193 | MCSymbol *Sym = Asm->getSymbol(cast<GlobalValue>(Ptr)); | |
194 | DD->addArangeLabel(SymbolCU(this, Sym)); | |
195 | addOpAddress(*Loc, Sym); | |
196 | addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); | |
197 | SmallVector<Value *, 3> Idx(CE->op_begin() + 1, CE->op_end()); | |
198 | addUInt(*Loc, dwarf::DW_FORM_udata, | |
199 | Asm->getDataLayout().getIndexedOffset(Ptr->getType(), Idx)); | |
200 | addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); | |
201 | addBlock(*VariableDIE, dwarf::DW_AT_location, Loc); | |
202 | } | |
203 | ||
204 | if (addToAccelTable) { | |
205 | DD->addAccelName(GV.getName(), *VariableDIE); | |
206 | ||
207 | // If the linkage name is different than the name, go ahead and output | |
208 | // that as well into the name table. | |
209 | if (GV.getLinkageName() != "" && GV.getName() != GV.getLinkageName()) | |
210 | DD->addAccelName(GV.getLinkageName(), *VariableDIE); | |
211 | } | |
212 | ||
213 | addGlobalName(GV.getName(), *VariableDIE, DeclContext); | |
214 | return VariableDIE; | |
215 | } | |
216 | ||
217 | void DwarfCompileUnit::addRange(RangeSpan Range) { | |
218 | bool SameAsPrevCU = this == DD->getPrevCU(); | |
219 | DD->setPrevCU(this); | |
220 | // If we have no current ranges just add the range and return, otherwise, | |
221 | // check the current section and CU against the previous section and CU we | |
222 | // emitted into and the subprogram was contained within. If these are the | |
223 | // same then extend our current range, otherwise add this as a new range. | |
224 | if (CURanges.empty() || !SameAsPrevCU || | |
225 | (&CURanges.back().getEnd()->getSection() != | |
226 | &Range.getEnd()->getSection())) { | |
227 | CURanges.push_back(Range); | |
228 | return; | |
229 | } | |
230 | ||
231 | CURanges.back().setEnd(Range.getEnd()); | |
232 | } | |
233 | ||
234 | void DwarfCompileUnit::addSectionLabel(DIE &Die, dwarf::Attribute Attribute, | |
235 | const MCSymbol *Label, | |
236 | const MCSymbol *Sec) { | |
237 | if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) | |
238 | addLabel(Die, Attribute, | |
239 | DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset | |
240 | : dwarf::DW_FORM_data4, | |
241 | Label); | |
242 | else | |
243 | addSectionDelta(Die, Attribute, Label, Sec); | |
244 | } | |
245 | ||
246 | void DwarfCompileUnit::initStmtList(MCSymbol *DwarfLineSectionSym) { | |
247 | // Define start line table label for each Compile Unit. | |
248 | MCSymbol *LineTableStartSym = | |
249 | Asm->OutStreamer.getDwarfLineTableSymbol(getUniqueID()); | |
250 | ||
251 | stmtListIndex = UnitDie.getValues().size(); | |
252 | ||
253 | // DW_AT_stmt_list is a offset of line number information for this | |
254 | // compile unit in debug_line section. For split dwarf this is | |
255 | // left in the skeleton CU and so not included. | |
256 | // The line table entries are not always emitted in assembly, so it | |
257 | // is not okay to use line_table_start here. | |
258 | addSectionLabel(UnitDie, dwarf::DW_AT_stmt_list, LineTableStartSym, | |
259 | DwarfLineSectionSym); | |
260 | } | |
261 | ||
262 | void DwarfCompileUnit::applyStmtList(DIE &D) { | |
263 | D.addValue(dwarf::DW_AT_stmt_list, | |
264 | UnitDie.getAbbrev().getData()[stmtListIndex].getForm(), | |
265 | UnitDie.getValues()[stmtListIndex]); | |
266 | } | |
267 | ||
268 | void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin, | |
269 | const MCSymbol *End) { | |
270 | assert(Begin && "Begin label should not be null!"); | |
271 | assert(End && "End label should not be null!"); | |
272 | assert(Begin->isDefined() && "Invalid starting label"); | |
273 | assert(End->isDefined() && "Invalid end label"); | |
274 | ||
275 | addLabelAddress(D, dwarf::DW_AT_low_pc, Begin); | |
276 | if (DD->getDwarfVersion() < 4) | |
277 | addLabelAddress(D, dwarf::DW_AT_high_pc, End); | |
278 | else | |
279 | addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin); | |
280 | } | |
281 | ||
282 | // Find DIE for the given subprogram and attach appropriate DW_AT_low_pc | |
283 | // and DW_AT_high_pc attributes. If there are global variables in this | |
284 | // scope then create and insert DIEs for these variables. | |
285 | DIE &DwarfCompileUnit::updateSubprogramScopeDIE(DISubprogram SP) { | |
286 | DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes()); | |
287 | ||
288 | attachLowHighPC(*SPDie, DD->getFunctionBeginSym(), DD->getFunctionEndSym()); | |
289 | if (!DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim( | |
290 | *DD->getCurrentFunction())) | |
291 | addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr); | |
292 | ||
293 | // Only include DW_AT_frame_base in full debug info | |
294 | if (!includeMinimalInlineScopes()) { | |
295 | const TargetRegisterInfo *RI = | |
296 | Asm->TM.getSubtargetImpl()->getRegisterInfo(); | |
297 | MachineLocation Location(RI->getFrameRegister(*Asm->MF)); | |
298 | if (RI->isPhysicalRegister(Location.getReg())) | |
299 | addAddress(*SPDie, dwarf::DW_AT_frame_base, Location); | |
300 | } | |
301 | ||
302 | // Add name to the name table, we do this here because we're guaranteed | |
303 | // to have concrete versions of our DW_TAG_subprogram nodes. | |
304 | DD->addSubprogramNames(SP, *SPDie); | |
305 | ||
306 | return *SPDie; | |
307 | } | |
308 | ||
309 | // Construct a DIE for this scope. | |
310 | void DwarfCompileUnit::constructScopeDIE( | |
311 | LexicalScope *Scope, SmallVectorImpl<std::unique_ptr<DIE>> &FinalChildren) { | |
312 | if (!Scope || !Scope->getScopeNode()) | |
313 | return; | |
314 | ||
315 | DIScope DS(Scope->getScopeNode()); | |
316 | ||
317 | assert((Scope->getInlinedAt() || !DS.isSubprogram()) && | |
318 | "Only handle inlined subprograms here, use " | |
319 | "constructSubprogramScopeDIE for non-inlined " | |
320 | "subprograms"); | |
321 | ||
322 | SmallVector<std::unique_ptr<DIE>, 8> Children; | |
323 | ||
324 | // We try to create the scope DIE first, then the children DIEs. This will | |
325 | // avoid creating un-used children then removing them later when we find out | |
326 | // the scope DIE is null. | |
327 | std::unique_ptr<DIE> ScopeDIE; | |
328 | if (Scope->getParent() && DS.isSubprogram()) { | |
329 | ScopeDIE = constructInlinedScopeDIE(Scope); | |
330 | if (!ScopeDIE) | |
331 | return; | |
332 | // We create children when the scope DIE is not null. | |
333 | createScopeChildrenDIE(Scope, Children); | |
334 | } else { | |
335 | // Early exit when we know the scope DIE is going to be null. | |
336 | if (DD->isLexicalScopeDIENull(Scope)) | |
337 | return; | |
338 | ||
339 | unsigned ChildScopeCount; | |
340 | ||
341 | // We create children here when we know the scope DIE is not going to be | |
342 | // null and the children will be added to the scope DIE. | |
343 | createScopeChildrenDIE(Scope, Children, &ChildScopeCount); | |
344 | ||
345 | // Skip imported directives in gmlt-like data. | |
346 | if (!includeMinimalInlineScopes()) { | |
347 | // There is no need to emit empty lexical block DIE. | |
348 | for (const auto &E : DD->findImportedEntitiesForScope(DS)) | |
349 | Children.push_back( | |
350 | constructImportedEntityDIE(DIImportedEntity(E.second))); | |
351 | } | |
352 | ||
353 | // If there are only other scopes as children, put them directly in the | |
354 | // parent instead, as this scope would serve no purpose. | |
355 | if (Children.size() == ChildScopeCount) { | |
356 | FinalChildren.insert(FinalChildren.end(), | |
357 | std::make_move_iterator(Children.begin()), | |
358 | std::make_move_iterator(Children.end())); | |
359 | return; | |
360 | } | |
361 | ScopeDIE = constructLexicalScopeDIE(Scope); | |
362 | assert(ScopeDIE && "Scope DIE should not be null."); | |
363 | } | |
364 | ||
365 | // Add children | |
366 | for (auto &I : Children) | |
367 | ScopeDIE->addChild(std::move(I)); | |
368 | ||
369 | FinalChildren.push_back(std::move(ScopeDIE)); | |
370 | } | |
371 | ||
372 | void DwarfCompileUnit::addSectionDelta(DIE &Die, dwarf::Attribute Attribute, | |
373 | const MCSymbol *Hi, const MCSymbol *Lo) { | |
374 | DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo); | |
375 | Die.addValue(Attribute, DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset | |
376 | : dwarf::DW_FORM_data4, | |
377 | Value); | |
378 | } | |
379 | ||
380 | void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE, | |
381 | SmallVector<RangeSpan, 2> Range) { | |
382 | // Emit offset in .debug_range as a relocatable label. emitDIE will handle | |
383 | // emitting it appropriately. | |
384 | auto *RangeSectionSym = DD->getRangeSectionSym(); | |
385 | ||
386 | RangeSpanList List( | |
387 | Asm->GetTempSymbol("debug_ranges", DD->getNextRangeNumber()), | |
388 | std::move(Range)); | |
389 | ||
390 | // Under fission, ranges are specified by constant offsets relative to the | |
391 | // CU's DW_AT_GNU_ranges_base. | |
392 | if (isDwoUnit()) | |
393 | addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(), | |
394 | RangeSectionSym); | |
395 | else | |
396 | addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(), | |
397 | RangeSectionSym); | |
398 | ||
399 | // Add the range list to the set of ranges to be emitted. | |
400 | (Skeleton ? Skeleton : this)->CURangeLists.push_back(std::move(List)); | |
401 | } | |
402 | ||
403 | void DwarfCompileUnit::attachRangesOrLowHighPC( | |
404 | DIE &Die, SmallVector<RangeSpan, 2> Ranges) { | |
405 | if (Ranges.size() == 1) { | |
406 | const auto &single = Ranges.front(); | |
407 | attachLowHighPC(Die, single.getStart(), single.getEnd()); | |
408 | } else | |
409 | addScopeRangeList(Die, std::move(Ranges)); | |
410 | } | |
411 | ||
412 | void DwarfCompileUnit::attachRangesOrLowHighPC( | |
413 | DIE &Die, const SmallVectorImpl<InsnRange> &Ranges) { | |
414 | SmallVector<RangeSpan, 2> List; | |
415 | List.reserve(Ranges.size()); | |
416 | for (const InsnRange &R : Ranges) | |
417 | List.push_back(RangeSpan(DD->getLabelBeforeInsn(R.first), | |
418 | DD->getLabelAfterInsn(R.second))); | |
419 | attachRangesOrLowHighPC(Die, std::move(List)); | |
420 | } | |
421 | ||
422 | // This scope represents inlined body of a function. Construct DIE to | |
423 | // represent this concrete inlined copy of the function. | |
424 | std::unique_ptr<DIE> | |
425 | DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) { | |
426 | assert(Scope->getScopeNode()); | |
427 | DIScope DS(Scope->getScopeNode()); | |
428 | DISubprogram InlinedSP = getDISubprogram(DS); | |
429 | // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram | |
430 | // was inlined from another compile unit. | |
431 | DIE *OriginDIE = DU->getAbstractSPDies()[InlinedSP]; | |
432 | assert(OriginDIE && "Unable to find original DIE for an inlined subprogram."); | |
433 | ||
434 | auto ScopeDIE = make_unique<DIE>(dwarf::DW_TAG_inlined_subroutine); | |
435 | addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE); | |
436 | ||
437 | attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges()); | |
438 | ||
439 | // Add the call site information to the DIE. | |
440 | DILocation DL(Scope->getInlinedAt()); | |
441 | addUInt(*ScopeDIE, dwarf::DW_AT_call_file, None, | |
442 | getOrCreateSourceID(DL.getFilename(), DL.getDirectory())); | |
443 | addUInt(*ScopeDIE, dwarf::DW_AT_call_line, None, DL.getLineNumber()); | |
444 | ||
445 | // Add name to the name table, we do this here because we're guaranteed | |
446 | // to have concrete versions of our DW_TAG_inlined_subprogram nodes. | |
447 | DD->addSubprogramNames(InlinedSP, *ScopeDIE); | |
448 | ||
449 | return ScopeDIE; | |
450 | } | |
451 | ||
452 | // Construct new DW_TAG_lexical_block for this scope and attach | |
453 | // DW_AT_low_pc/DW_AT_high_pc labels. | |
454 | std::unique_ptr<DIE> | |
455 | DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) { | |
456 | if (DD->isLexicalScopeDIENull(Scope)) | |
457 | return nullptr; | |
458 | ||
459 | auto ScopeDIE = make_unique<DIE>(dwarf::DW_TAG_lexical_block); | |
460 | if (Scope->isAbstractScope()) | |
461 | return ScopeDIE; | |
462 | ||
463 | attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges()); | |
464 | ||
465 | return ScopeDIE; | |
466 | } | |
467 | ||
468 | /// constructVariableDIE - Construct a DIE for the given DbgVariable. | |
469 | std::unique_ptr<DIE> DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, | |
470 | bool Abstract) { | |
471 | auto D = constructVariableDIEImpl(DV, Abstract); | |
472 | DV.setDIE(*D); | |
473 | return D; | |
474 | } | |
475 | ||
476 | std::unique_ptr<DIE> | |
477 | DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV, | |
478 | bool Abstract) { | |
479 | // Define variable debug information entry. | |
480 | auto VariableDie = make_unique<DIE>(DV.getTag()); | |
481 | ||
482 | if (Abstract) { | |
483 | applyVariableAttributes(DV, *VariableDie); | |
484 | return VariableDie; | |
485 | } | |
486 | ||
487 | // Add variable address. | |
488 | ||
489 | unsigned Offset = DV.getDotDebugLocOffset(); | |
490 | if (Offset != ~0U) { | |
491 | addLocationList(*VariableDie, dwarf::DW_AT_location, Offset); | |
492 | return VariableDie; | |
493 | } | |
494 | ||
495 | // Check if variable is described by a DBG_VALUE instruction. | |
496 | if (const MachineInstr *DVInsn = DV.getMInsn()) { | |
497 | assert(DVInsn->getNumOperands() == 4); | |
498 | if (DVInsn->getOperand(0).isReg()) { | |
499 | const MachineOperand RegOp = DVInsn->getOperand(0); | |
500 | // If the second operand is an immediate, this is an indirect value. | |
501 | if (DVInsn->getOperand(1).isImm()) { | |
502 | MachineLocation Location(RegOp.getReg(), | |
503 | DVInsn->getOperand(1).getImm()); | |
504 | addVariableAddress(DV, *VariableDie, Location); | |
505 | } else if (RegOp.getReg()) | |
506 | addVariableAddress(DV, *VariableDie, MachineLocation(RegOp.getReg())); | |
507 | } else if (DVInsn->getOperand(0).isImm()) | |
508 | addConstantValue(*VariableDie, DVInsn->getOperand(0), DV.getType()); | |
509 | else if (DVInsn->getOperand(0).isFPImm()) | |
510 | addConstantFPValue(*VariableDie, DVInsn->getOperand(0)); | |
511 | else if (DVInsn->getOperand(0).isCImm()) | |
512 | addConstantValue(*VariableDie, DVInsn->getOperand(0).getCImm(), | |
513 | DV.getType()); | |
514 | ||
515 | return VariableDie; | |
516 | } | |
517 | ||
518 | // .. else use frame index. | |
519 | int FI = DV.getFrameIndex(); | |
520 | if (FI != ~0) { | |
521 | unsigned FrameReg = 0; | |
522 | const TargetFrameLowering *TFI = | |
523 | Asm->TM.getSubtargetImpl()->getFrameLowering(); | |
524 | int Offset = TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg); | |
525 | MachineLocation Location(FrameReg, Offset); | |
526 | addVariableAddress(DV, *VariableDie, Location); | |
527 | } | |
528 | ||
529 | return VariableDie; | |
530 | } | |
531 | ||
532 | std::unique_ptr<DIE> DwarfCompileUnit::constructVariableDIE( | |
533 | DbgVariable &DV, const LexicalScope &Scope, DIE *&ObjectPointer) { | |
534 | auto Var = constructVariableDIE(DV, Scope.isAbstractScope()); | |
535 | if (DV.isObjectPointer()) | |
536 | ObjectPointer = Var.get(); | |
537 | return Var; | |
538 | } | |
539 | ||
540 | DIE *DwarfCompileUnit::createScopeChildrenDIE( | |
541 | LexicalScope *Scope, SmallVectorImpl<std::unique_ptr<DIE>> &Children, | |
542 | unsigned *ChildScopeCount) { | |
543 | DIE *ObjectPointer = nullptr; | |
544 | ||
545 | for (DbgVariable *DV : DU->getScopeVariables().lookup(Scope)) | |
546 | Children.push_back(constructVariableDIE(*DV, *Scope, ObjectPointer)); | |
547 | ||
548 | unsigned ChildCountWithoutScopes = Children.size(); | |
549 | ||
550 | for (LexicalScope *LS : Scope->getChildren()) | |
551 | constructScopeDIE(LS, Children); | |
552 | ||
553 | if (ChildScopeCount) | |
554 | *ChildScopeCount = Children.size() - ChildCountWithoutScopes; | |
555 | ||
556 | return ObjectPointer; | |
557 | } | |
558 | ||
559 | void DwarfCompileUnit::constructSubprogramScopeDIE(LexicalScope *Scope) { | |
560 | assert(Scope && Scope->getScopeNode()); | |
561 | assert(!Scope->getInlinedAt()); | |
562 | assert(!Scope->isAbstractScope()); | |
563 | DISubprogram Sub(Scope->getScopeNode()); | |
564 | ||
565 | assert(Sub.isSubprogram()); | |
566 | ||
567 | DD->getProcessedSPNodes().insert(Sub); | |
568 | ||
569 | DIE &ScopeDIE = updateSubprogramScopeDIE(Sub); | |
570 | ||
571 | // If this is a variadic function, add an unspecified parameter. | |
572 | DITypeArray FnArgs = Sub.getType().getTypeArray(); | |
573 | ||
574 | // Collect lexical scope children first. | |
575 | // ObjectPointer might be a local (non-argument) local variable if it's a | |
576 | // block's synthetic this pointer. | |
577 | if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE)) | |
578 | addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer); | |
579 | ||
580 | // If we have a single element of null, it is a function that returns void. | |
581 | // If we have more than one elements and the last one is null, it is a | |
582 | // variadic function. | |
583 | if (FnArgs.getNumElements() > 1 && | |
584 | !FnArgs.getElement(FnArgs.getNumElements() - 1) && | |
585 | !includeMinimalInlineScopes()) | |
586 | ScopeDIE.addChild(make_unique<DIE>(dwarf::DW_TAG_unspecified_parameters)); | |
587 | } | |
588 | ||
589 | DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope, | |
590 | DIE &ScopeDIE) { | |
591 | // We create children when the scope DIE is not null. | |
592 | SmallVector<std::unique_ptr<DIE>, 8> Children; | |
593 | DIE *ObjectPointer = createScopeChildrenDIE(Scope, Children); | |
594 | ||
595 | // Add children | |
596 | for (auto &I : Children) | |
597 | ScopeDIE.addChild(std::move(I)); | |
598 | ||
599 | return ObjectPointer; | |
600 | } | |
601 | ||
602 | void | |
603 | DwarfCompileUnit::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) { | |
604 | DIE *&AbsDef = DU->getAbstractSPDies()[Scope->getScopeNode()]; | |
605 | if (AbsDef) | |
606 | return; | |
607 | ||
608 | DISubprogram SP(Scope->getScopeNode()); | |
609 | ||
610 | DIE *ContextDIE; | |
611 | ||
612 | if (includeMinimalInlineScopes()) | |
613 | ContextDIE = &getUnitDie(); | |
614 | // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with | |
615 | // the important distinction that the DIDescriptor is not associated with the | |
616 | // DIE (since the DIDescriptor will be associated with the concrete DIE, if | |
617 | // any). It could be refactored to some common utility function. | |
618 | else if (DISubprogram SPDecl = SP.getFunctionDeclaration()) { | |
619 | ContextDIE = &getUnitDie(); | |
620 | getOrCreateSubprogramDIE(SPDecl); | |
621 | } else | |
622 | ContextDIE = getOrCreateContextDIE(resolve(SP.getContext())); | |
623 | ||
624 | // Passing null as the associated DIDescriptor because the abstract definition | |
625 | // shouldn't be found by lookup. | |
626 | AbsDef = | |
627 | &createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, DIDescriptor()); | |
628 | applySubprogramAttributesToDefinition(SP, *AbsDef); | |
629 | ||
630 | if (!includeMinimalInlineScopes()) | |
631 | addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); | |
632 | if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, *AbsDef)) | |
633 | addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer); | |
634 | } | |
635 | ||
636 | std::unique_ptr<DIE> | |
637 | DwarfCompileUnit::constructImportedEntityDIE(const DIImportedEntity &Module) { | |
638 | assert(Module.Verify() && | |
639 | "Use one of the MDNode * overloads to handle invalid metadata"); | |
640 | std::unique_ptr<DIE> IMDie = make_unique<DIE>((dwarf::Tag)Module.getTag()); | |
641 | insertDIE(Module, IMDie.get()); | |
642 | DIE *EntityDie; | |
643 | DIDescriptor Entity = resolve(Module.getEntity()); | |
644 | if (Entity.isNameSpace()) | |
645 | EntityDie = getOrCreateNameSpace(DINameSpace(Entity)); | |
646 | else if (Entity.isSubprogram()) | |
647 | EntityDie = getOrCreateSubprogramDIE(DISubprogram(Entity)); | |
648 | else if (Entity.isType()) | |
649 | EntityDie = getOrCreateTypeDIE(DIType(Entity)); | |
650 | else if (Entity.isGlobalVariable()) | |
651 | EntityDie = getOrCreateGlobalVariableDIE(DIGlobalVariable(Entity)); | |
652 | else | |
653 | EntityDie = getDIE(Entity); | |
654 | assert(EntityDie); | |
655 | addSourceLine(*IMDie, Module.getLineNumber(), | |
656 | Module.getContext().getFilename(), | |
657 | Module.getContext().getDirectory()); | |
658 | addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie); | |
659 | StringRef Name = Module.getName(); | |
660 | if (!Name.empty()) | |
661 | addString(*IMDie, dwarf::DW_AT_name, Name); | |
662 | ||
663 | return IMDie; | |
664 | } | |
665 | ||
666 | void DwarfCompileUnit::finishSubprogramDefinition(DISubprogram SP) { | |
667 | DIE *D = getDIE(SP); | |
668 | if (DIE *AbsSPDIE = DU->getAbstractSPDies().lookup(SP)) { | |
669 | if (D) | |
670 | // If this subprogram has an abstract definition, reference that | |
671 | addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE); | |
672 | } else { | |
673 | if (!D && !includeMinimalInlineScopes()) | |
674 | // Lazily construct the subprogram if we didn't see either concrete or | |
675 | // inlined versions during codegen. (except in -gmlt ^ where we want | |
676 | // to omit these entirely) | |
677 | D = getOrCreateSubprogramDIE(SP); | |
678 | if (D) | |
679 | // And attach the attributes | |
680 | applySubprogramAttributesToDefinition(SP, *D); | |
681 | } | |
682 | } | |
683 | void DwarfCompileUnit::collectDeadVariables(DISubprogram SP) { | |
684 | assert(SP.isSubprogram() && "CU's subprogram list contains a non-subprogram"); | |
685 | assert(SP.isDefinition() && | |
686 | "CU's subprogram list contains a subprogram declaration"); | |
687 | DIArray Variables = SP.getVariables(); | |
688 | if (Variables.getNumElements() == 0) | |
689 | return; | |
690 | ||
691 | DIE *SPDIE = DU->getAbstractSPDies().lookup(SP); | |
692 | if (!SPDIE) | |
693 | SPDIE = getDIE(SP); | |
694 | assert(SPDIE); | |
695 | for (unsigned vi = 0, ve = Variables.getNumElements(); vi != ve; ++vi) { | |
696 | DIVariable DV(Variables.getElement(vi)); | |
697 | assert(DV.isVariable()); | |
698 | DbgVariable NewVar(DV, DIExpression(nullptr), DD); | |
699 | auto VariableDie = constructVariableDIE(NewVar); | |
700 | applyVariableAttributes(NewVar, *VariableDie); | |
701 | SPDIE->addChild(std::move(VariableDie)); | |
702 | } | |
703 | } | |
704 | ||
705 | void DwarfCompileUnit::emitHeader(const MCSymbol *ASectionSym) const { | |
706 | // Don't bother labeling the .dwo unit, as its offset isn't used. | |
707 | if (!Skeleton) | |
708 | Asm->OutStreamer.EmitLabel(LabelBegin); | |
709 | ||
710 | DwarfUnit::emitHeader(ASectionSym); | |
711 | } | |
712 | ||
713 | /// addGlobalName - Add a new global name to the compile unit. | |
714 | void DwarfCompileUnit::addGlobalName(StringRef Name, DIE &Die, | |
715 | DIScope Context) { | |
716 | if (includeMinimalInlineScopes()) | |
717 | return; | |
718 | std::string FullName = getParentContextString(Context) + Name.str(); | |
719 | GlobalNames[FullName] = &Die; | |
720 | } | |
721 | ||
722 | /// Add a new global type to the unit. | |
723 | void DwarfCompileUnit::addGlobalType(DIType Ty, const DIE &Die, | |
724 | DIScope Context) { | |
725 | if (includeMinimalInlineScopes()) | |
726 | return; | |
727 | std::string FullName = getParentContextString(Context) + Ty.getName().str(); | |
728 | GlobalTypes[FullName] = &Die; | |
729 | } | |
730 | ||
731 | /// addVariableAddress - Add DW_AT_location attribute for a | |
732 | /// DbgVariable based on provided MachineLocation. | |
733 | void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die, | |
734 | MachineLocation Location) { | |
735 | if (DV.variableHasComplexAddress()) | |
736 | addComplexAddress(DV, Die, dwarf::DW_AT_location, Location); | |
737 | else if (DV.isBlockByrefVariable()) | |
738 | addBlockByrefAddress(DV, Die, dwarf::DW_AT_location, Location); | |
739 | else | |
740 | addAddress(Die, dwarf::DW_AT_location, Location, | |
741 | DV.getVariable().isIndirect()); | |
742 | } | |
743 | ||
744 | /// Add an address attribute to a die based on the location provided. | |
745 | void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute, | |
746 | const MachineLocation &Location, | |
747 | bool Indirect) { | |
748 | DIELoc *Loc = new (DIEValueAllocator) DIELoc(); | |
749 | ||
750 | bool validReg; | |
751 | if (Location.isReg() && !Indirect) | |
752 | validReg = addRegisterOpPiece(*Loc, Location.getReg()); | |
753 | else | |
754 | validReg = addRegisterOffset(*Loc, Location.getReg(), Location.getOffset()); | |
755 | ||
756 | if (!validReg) | |
757 | return; | |
758 | ||
759 | if (!Location.isReg() && Indirect) | |
760 | addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); | |
761 | ||
762 | // Now attach the location information to the DIE. | |
763 | addBlock(Die, Attribute, Loc); | |
764 | } | |
765 | ||
766 | /// Start with the address based on the location provided, and generate the | |
767 | /// DWARF information necessary to find the actual variable given the extra | |
768 | /// address information encoded in the DbgVariable, starting from the starting | |
769 | /// location. Add the DWARF information to the die. | |
770 | void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die, | |
771 | dwarf::Attribute Attribute, | |
772 | const MachineLocation &Location) { | |
773 | DIELoc *Loc = new (DIEValueAllocator) DIELoc(); | |
774 | DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); | |
775 | DIExpression Expr = DV.getExpression(); | |
776 | if (Location.getOffset()) { | |
777 | if (DwarfExpr.AddMachineRegIndirect(Location.getReg(), | |
778 | Location.getOffset())) { | |
779 | DwarfExpr.AddExpression(Expr); | |
780 | assert(!DV.getVariable().isIndirect() | |
781 | && "double indirection not handled"); | |
782 | } | |
783 | } else { | |
784 | if (DwarfExpr.AddMachineRegExpression(Expr, Location.getReg())) | |
785 | if (DV.getVariable().isIndirect()) | |
786 | DwarfExpr.EmitOp(dwarf::DW_OP_deref); | |
787 | } | |
788 | ||
789 | // Now attach the location information to the DIE. | |
790 | addBlock(Die, Attribute, Loc); | |
791 | } | |
792 | ||
793 | /// Add a Dwarf loclistptr attribute data and value. | |
794 | void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute, | |
795 | unsigned Index) { | |
796 | DIEValue *Value = new (DIEValueAllocator) DIELocList(Index); | |
797 | dwarf::Form Form = DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset | |
798 | : dwarf::DW_FORM_data4; | |
799 | Die.addValue(Attribute, Form, Value); | |
800 | } | |
801 | ||
802 | void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var, | |
803 | DIE &VariableDie) { | |
804 | StringRef Name = Var.getName(); | |
805 | if (!Name.empty()) | |
806 | addString(VariableDie, dwarf::DW_AT_name, Name); | |
807 | addSourceLine(VariableDie, Var.getVariable()); | |
808 | addType(VariableDie, Var.getType()); | |
809 | if (Var.isArtificial()) | |
810 | addFlag(VariableDie, dwarf::DW_AT_artificial); | |
811 | } | |
812 | ||
813 | /// Add a Dwarf expression attribute data and value. | |
814 | void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form, | |
815 | const MCExpr *Expr) { | |
816 | DIEValue *Value = new (DIEValueAllocator) DIEExpr(Expr); | |
817 | Die.addValue((dwarf::Attribute)0, Form, Value); | |
818 | } | |
819 | ||
820 | void DwarfCompileUnit::applySubprogramAttributesToDefinition(DISubprogram SP, | |
821 | DIE &SPDie) { | |
822 | DISubprogram SPDecl = SP.getFunctionDeclaration(); | |
823 | DIScope Context = resolve(SPDecl ? SPDecl.getContext() : SP.getContext()); | |
824 | applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes()); | |
825 | addGlobalName(SP.getName(), SPDie, Context); | |
826 | } | |
827 | ||
828 | bool DwarfCompileUnit::isDwoUnit() const { | |
829 | return DD->useSplitDwarf() && Skeleton; | |
830 | } | |
831 | ||
832 | bool DwarfCompileUnit::includeMinimalInlineScopes() const { | |
833 | return getCUNode().getEmissionKind() == DIBuilder::LineTablesOnly || | |
834 | (DD->useSplitDwarf() && !Skeleton); | |
835 | } | |
836 | } // end llvm namespace |