blob: b245e45f3c17032a661ad6ba4fc37f7b53a4d0b8 [file] [log] [blame]
Bill Wendling0310d762009-05-15 09:23:25 +00001//===-- llvm/CodeGen/DwarfDebug.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// This file contains support for writing dwarf debug info into asm files.
11//
12//===----------------------------------------------------------------------===//
Chris Lattner6cde3e62010-03-09 00:39:24 +000013
Devang Patele4b27562009-08-28 23:24:31 +000014#define DEBUG_TYPE "dwarfdebug"
Bill Wendling0310d762009-05-15 09:23:25 +000015#include "DwarfDebug.h"
Chris Lattner74e41f92010-04-05 05:24:55 +000016#include "DIE.h"
Bill Wendling57fbba42010-04-05 22:59:21 +000017#include "llvm/Constants.h"
Bill Wendling0310d762009-05-15 09:23:25 +000018#include "llvm/Module.h"
David Greeneb2c66fc2009-08-19 21:52:55 +000019#include "llvm/CodeGen/MachineFunction.h"
Bill Wendling0310d762009-05-15 09:23:25 +000020#include "llvm/CodeGen/MachineModuleInfo.h"
Chris Lattnerb7db7332010-03-09 01:58:53 +000021#include "llvm/MC/MCAsmInfo.h"
Chris Lattnera87dea42009-07-31 18:48:30 +000022#include "llvm/MC/MCSection.h"
Chris Lattner6c2f9e12009-08-19 05:49:37 +000023#include "llvm/MC/MCStreamer.h"
Chris Lattnerb7db7332010-03-09 01:58:53 +000024#include "llvm/MC/MCSymbol.h"
Chris Lattner45111d12010-01-16 21:57:06 +000025#include "llvm/Target/Mangler.h"
Bill Wendling0310d762009-05-15 09:23:25 +000026#include "llvm/Target/TargetData.h"
27#include "llvm/Target/TargetFrameInfo.h"
Chris Lattnerf0144122009-07-28 03:13:23 +000028#include "llvm/Target/TargetLoweringObjectFile.h"
Chris Lattner9d1c1ad2010-04-04 18:06:11 +000029#include "llvm/Target/TargetMachine.h"
Chris Lattnerf0144122009-07-28 03:13:23 +000030#include "llvm/Target/TargetRegisterInfo.h"
Devang Patel2a4a3b72010-04-19 19:14:02 +000031#include "llvm/Target/TargetOptions.h"
Chris Lattner74e41f92010-04-05 05:24:55 +000032#include "llvm/Analysis/DebugInfo.h"
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +000033#include "llvm/ADT/STLExtras.h"
Chris Lattner23132b12009-08-24 03:52:50 +000034#include "llvm/ADT/StringExtras.h"
Devang Patel9cdb4102010-04-21 16:32:19 +000035#include "llvm/Support/CommandLine.h"
Daniel Dunbar6e4bdfc2009-10-13 06:47:08 +000036#include "llvm/Support/Debug.h"
37#include "llvm/Support/ErrorHandling.h"
Devang Patel3139fcf2010-01-26 21:39:14 +000038#include "llvm/Support/ValueHandle.h"
Chris Lattner0ad9c912010-01-22 22:09:00 +000039#include "llvm/Support/FormattedStream.h"
Chris Lattnera87dea42009-07-31 18:48:30 +000040#include "llvm/Support/Timer.h"
41#include "llvm/System/Path.h"
Bill Wendling0310d762009-05-15 09:23:25 +000042using namespace llvm;
43
Devang Patel9cdb4102010-04-21 16:32:19 +000044static cl::opt<bool> PrintDbgScope("print-dbgscope", cl::Hidden,
45 cl::desc("Print DbgScope information for each machine instruction"));
46
Devang Patel708e4742010-04-21 19:08:53 +000047static cl::opt<bool> DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden,
48 cl::desc("Disable debug info printing"));
49
Bill Wendling5f017e82010-04-07 09:28:04 +000050namespace {
51 const char *DWARFGroupName = "DWARF Emission";
52 const char *DbgTimerName = "DWARF Debug Writer";
53} // end anonymous namespace
54
Bill Wendling0310d762009-05-15 09:23:25 +000055//===----------------------------------------------------------------------===//
56
57/// Configuration values for initial hash set sizes (log2).
58///
Bill Wendling0310d762009-05-15 09:23:25 +000059static const unsigned InitAbbreviationsSetSize = 9; // log2(512)
Bill Wendling0310d762009-05-15 09:23:25 +000060
61namespace llvm {
62
63//===----------------------------------------------------------------------===//
64/// CompileUnit - This dwarf writer support class manages information associate
65/// with a source file.
Nick Lewycky5f9843f2009-11-17 08:11:44 +000066class CompileUnit {
Bill Wendling0310d762009-05-15 09:23:25 +000067 /// ID - File identifier for source.
68 ///
69 unsigned ID;
70
71 /// Die - Compile unit debug information entry.
72 ///
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +000073 const OwningPtr<DIE> CUDie;
Bill Wendling0310d762009-05-15 09:23:25 +000074
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +000075 /// IndexTyDie - An anonymous type for index type. Owned by CUDie.
Devang Patel6f01d9c2009-11-21 00:31:03 +000076 DIE *IndexTyDie;
77
Bill Wendling0310d762009-05-15 09:23:25 +000078 /// GVToDieMap - Tracks the mapping of unit level debug informaton
79 /// variables to debug information entries.
Devang Patele4b27562009-08-28 23:24:31 +000080 /// FIXME : Rename GVToDieMap -> NodeToDieMap
Devang Patel622b0262010-01-19 06:19:05 +000081 DenseMap<MDNode *, DIE *> GVToDieMap;
Bill Wendling0310d762009-05-15 09:23:25 +000082
83 /// GVToDIEEntryMap - Tracks the mapping of unit level debug informaton
84 /// descriptors to debug information entries using a DIEEntry proxy.
Devang Patele4b27562009-08-28 23:24:31 +000085 /// FIXME : Rename
Devang Patel622b0262010-01-19 06:19:05 +000086 DenseMap<MDNode *, DIEEntry *> GVToDIEEntryMap;
Bill Wendling0310d762009-05-15 09:23:25 +000087
88 /// Globals - A map of globally visible named entities for this unit.
89 ///
90 StringMap<DIE*> Globals;
91
Devang Patel193f7202009-11-24 01:14:22 +000092 /// GlobalTypes - A map of globally visible types for this unit.
93 ///
94 StringMap<DIE*> GlobalTypes;
95
Bill Wendling0310d762009-05-15 09:23:25 +000096public:
97 CompileUnit(unsigned I, DIE *D)
Devang Patel2c4ceb12009-11-21 02:48:08 +000098 : ID(I), CUDie(D), IndexTyDie(0) {}
Bill Wendling0310d762009-05-15 09:23:25 +000099
100 // Accessors.
Devang Patel193f7202009-11-24 01:14:22 +0000101 unsigned getID() const { return ID; }
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +0000102 DIE* getCUDie() const { return CUDie.get(); }
Devang Patel193f7202009-11-24 01:14:22 +0000103 const StringMap<DIE*> &getGlobals() const { return Globals; }
104 const StringMap<DIE*> &getGlobalTypes() const { return GlobalTypes; }
Bill Wendling0310d762009-05-15 09:23:25 +0000105
106 /// hasContent - Return true if this compile unit has something to write out.
107 ///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000108 bool hasContent() const { return !CUDie->getChildren().empty(); }
Bill Wendling0310d762009-05-15 09:23:25 +0000109
Devang Patel2c4ceb12009-11-21 02:48:08 +0000110 /// addGlobal - Add a new global entity to the compile unit.
Bill Wendling0310d762009-05-15 09:23:25 +0000111 ///
Benjamin Kramerbbb88db2010-03-31 20:15:45 +0000112 void addGlobal(StringRef Name, DIE *Die) { Globals[Name] = Die; }
Bill Wendling0310d762009-05-15 09:23:25 +0000113
Devang Patel193f7202009-11-24 01:14:22 +0000114 /// addGlobalType - Add a new global type to the compile unit.
115 ///
Benjamin Kramerbbb88db2010-03-31 20:15:45 +0000116 void addGlobalType(StringRef Name, DIE *Die) {
Devang Patel193f7202009-11-24 01:14:22 +0000117 GlobalTypes[Name] = Die;
118 }
119
Devang Patel017d1212009-11-20 21:37:22 +0000120 /// getDIE - Returns the debug information entry map slot for the
Bill Wendling0310d762009-05-15 09:23:25 +0000121 /// specified debug variable.
Devang Patel017d1212009-11-20 21:37:22 +0000122 DIE *getDIE(MDNode *N) { return GVToDieMap.lookup(N); }
Jim Grosbach31ef40e2009-11-21 23:12:12 +0000123
Devang Patel017d1212009-11-20 21:37:22 +0000124 /// insertDIE - Insert DIE into the map.
125 void insertDIE(MDNode *N, DIE *D) {
126 GVToDieMap.insert(std::make_pair(N, D));
127 }
Bill Wendling0310d762009-05-15 09:23:25 +0000128
Devang Patel017d1212009-11-20 21:37:22 +0000129 /// getDIEEntry - Returns the debug information entry for the speciefied
130 /// debug variable.
Devang Patel6404e4e2009-12-15 19:16:48 +0000131 DIEEntry *getDIEEntry(MDNode *N) {
Devang Patel622b0262010-01-19 06:19:05 +0000132 DenseMap<MDNode *, DIEEntry *>::iterator I = GVToDIEEntryMap.find(N);
Devang Patel6404e4e2009-12-15 19:16:48 +0000133 if (I == GVToDIEEntryMap.end())
134 return NULL;
135 return I->second;
136 }
Devang Patel017d1212009-11-20 21:37:22 +0000137
138 /// insertDIEEntry - Insert debug information entry into the map.
139 void insertDIEEntry(MDNode *N, DIEEntry *E) {
140 GVToDIEEntryMap.insert(std::make_pair(N, E));
Bill Wendling0310d762009-05-15 09:23:25 +0000141 }
142
Devang Patel2c4ceb12009-11-21 02:48:08 +0000143 /// addDie - Adds or interns the DIE to the compile unit.
Bill Wendling0310d762009-05-15 09:23:25 +0000144 ///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000145 void addDie(DIE *Buffer) {
146 this->CUDie->addChild(Buffer);
Bill Wendling0310d762009-05-15 09:23:25 +0000147 }
Devang Patel6f01d9c2009-11-21 00:31:03 +0000148
149 // getIndexTyDie - Get an anonymous type for index type.
150 DIE *getIndexTyDie() {
151 return IndexTyDie;
152 }
153
Jim Grosbach7ab38df2009-11-22 19:20:36 +0000154 // setIndexTyDie - Set D as anonymous type for index which can be reused
155 // later.
Devang Patel6f01d9c2009-11-21 00:31:03 +0000156 void setIndexTyDie(DIE *D) {
157 IndexTyDie = D;
158 }
159
Bill Wendling0310d762009-05-15 09:23:25 +0000160};
161
162//===----------------------------------------------------------------------===//
163/// DbgVariable - This class is used to track local variable information.
164///
Devang Patelf76a3d62009-11-16 21:53:40 +0000165class DbgVariable {
Bill Wendling0310d762009-05-15 09:23:25 +0000166 DIVariable Var; // Variable Descriptor.
167 unsigned FrameIndex; // Variable frame index.
Devang Patel90a48ad2010-03-15 18:33:46 +0000168 const MachineInstr *DbgValueMInsn; // DBG_VALUE
Devang Patelaead63c2010-03-29 22:59:58 +0000169 // DbgValueLabel - DBG_VALUE is effective from this label.
170 MCSymbol *DbgValueLabel;
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000171 DbgVariable *const AbstractVar; // Abstract variable for this variable.
Devang Patel53bb5c92009-11-10 23:06:00 +0000172 DIE *TheDIE;
Bill Wendling0310d762009-05-15 09:23:25 +0000173public:
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000174 // AbsVar may be NULL.
175 DbgVariable(DIVariable V, unsigned I, DbgVariable *AbsVar)
Devang Patelaead63c2010-03-29 22:59:58 +0000176 : Var(V), FrameIndex(I), DbgValueMInsn(0),
177 DbgValueLabel(0), AbstractVar(AbsVar), TheDIE(0) {}
Devang Patel90a48ad2010-03-15 18:33:46 +0000178 DbgVariable(DIVariable V, const MachineInstr *MI, DbgVariable *AbsVar)
Devang Patelaead63c2010-03-29 22:59:58 +0000179 : Var(V), FrameIndex(0), DbgValueMInsn(MI), DbgValueLabel(0),
180 AbstractVar(AbsVar), TheDIE(0)
Devang Patel90a48ad2010-03-15 18:33:46 +0000181 {}
Bill Wendling0310d762009-05-15 09:23:25 +0000182
183 // Accessors.
Devang Patel53bb5c92009-11-10 23:06:00 +0000184 DIVariable getVariable() const { return Var; }
185 unsigned getFrameIndex() const { return FrameIndex; }
Devang Patel90a48ad2010-03-15 18:33:46 +0000186 const MachineInstr *getDbgValue() const { return DbgValueMInsn; }
Devang Patelaead63c2010-03-29 22:59:58 +0000187 MCSymbol *getDbgValueLabel() const { return DbgValueLabel; }
188 void setDbgValueLabel(MCSymbol *L) { DbgValueLabel = L; }
Devang Patel53bb5c92009-11-10 23:06:00 +0000189 DbgVariable *getAbstractVariable() const { return AbstractVar; }
190 void setDIE(DIE *D) { TheDIE = D; }
191 DIE *getDIE() const { return TheDIE; }
Bill Wendling0310d762009-05-15 09:23:25 +0000192};
193
194//===----------------------------------------------------------------------===//
Devang Patel9cdb4102010-04-21 16:32:19 +0000195/// DbgRange - This is used to track range of instructions with identical
196/// debug info scope.
197///
198typedef std::pair<const MachineInstr *, const MachineInstr *> DbgRange;
199
200//===----------------------------------------------------------------------===//
Bill Wendling0310d762009-05-15 09:23:25 +0000201/// DbgScope - This class is used to track scope information.
202///
Devang Patelf76a3d62009-11-16 21:53:40 +0000203class DbgScope {
Bill Wendling0310d762009-05-15 09:23:25 +0000204 DbgScope *Parent; // Parent to this scope.
Jim Grosbach31ef40e2009-11-21 23:12:12 +0000205 DIDescriptor Desc; // Debug info descriptor for scope.
Devang Patel3139fcf2010-01-26 21:39:14 +0000206 // Location at which this scope is inlined.
207 AssertingVH<MDNode> InlinedAtLocation;
Devang Patel53bb5c92009-11-10 23:06:00 +0000208 bool AbstractScope; // Abstract Scope
Devang Pateld38dd112009-10-01 18:25:23 +0000209 const MachineInstr *LastInsn; // Last instruction of this scope.
210 const MachineInstr *FirstInsn; // First instruction of this scope.
Devang Patel9cdb4102010-04-21 16:32:19 +0000211 unsigned DFSIn, DFSOut;
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000212 // Scopes defined in scope. Contents not owned.
213 SmallVector<DbgScope *, 4> Scopes;
214 // Variables declared in scope. Contents owned.
215 SmallVector<DbgVariable *, 8> Variables;
Devang Patel9cdb4102010-04-21 16:32:19 +0000216 SmallVector<DbgRange, 4> Ranges;
Owen Anderson04c05f72009-06-24 22:53:20 +0000217 // Private state for dump()
218 mutable unsigned IndentLevel;
Bill Wendling0310d762009-05-15 09:23:25 +0000219public:
Devang Patelc90aefe2009-10-14 21:08:09 +0000220 DbgScope(DbgScope *P, DIDescriptor D, MDNode *I = 0)
Devang Patel53bb5c92009-11-10 23:06:00 +0000221 : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(false),
Devang Patel9cdb4102010-04-21 16:32:19 +0000222 LastInsn(0), FirstInsn(0),
223 DFSIn(0), DFSOut(0), IndentLevel(0) {}
Bill Wendling0310d762009-05-15 09:23:25 +0000224 virtual ~DbgScope();
225
226 // Accessors.
227 DbgScope *getParent() const { return Parent; }
Devang Patel53bb5c92009-11-10 23:06:00 +0000228 void setParent(DbgScope *P) { Parent = P; }
Bill Wendling0310d762009-05-15 09:23:25 +0000229 DIDescriptor getDesc() const { return Desc; }
Chris Lattnerbc733f52010-03-13 02:17:42 +0000230 MDNode *getInlinedAt() const { return InlinedAtLocation; }
Devang Patel53bb5c92009-11-10 23:06:00 +0000231 MDNode *getScopeNode() const { return Desc.getNode(); }
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000232 const SmallVector<DbgScope *, 4> &getScopes() { return Scopes; }
233 const SmallVector<DbgVariable *, 8> &getVariables() { return Variables; }
Devang Patel9cdb4102010-04-21 16:32:19 +0000234 const SmallVector<DbgRange, 4> &getRanges() { return Ranges; }
235
236 /// openInsnRange - This scope covers instruction range starting from MI.
237 void openInsnRange(const MachineInstr *MI) {
238 if (!FirstInsn)
239 FirstInsn = MI;
240
241 if (Parent)
242 Parent->openInsnRange(MI);
243 }
244
245 /// extendInsnRange - Extend the current instruction range covered by
246 /// this scope.
247 void extendInsnRange(const MachineInstr *MI) {
248 assert (FirstInsn && "MI Range is not open!");
249 LastInsn = MI;
250 if (Parent)
251 Parent->extendInsnRange(MI);
252 }
253
254 /// closeInsnRange - Create a range based on FirstInsn and LastInsn collected
255 /// until now. This is used when a new scope is encountered while walking
256 /// machine instructions.
257 void closeInsnRange(DbgScope *NewScope = NULL) {
258 assert (LastInsn && "Last insn missing!");
259 Ranges.push_back(DbgRange(FirstInsn, LastInsn));
260 FirstInsn = NULL;
261 LastInsn = NULL;
262 // If Parent dominates NewScope then do not close Parent's instruction
263 // range.
264 if (Parent && (!NewScope || !Parent->dominates(NewScope)))
265 Parent->closeInsnRange(NewScope);
266 }
267
Devang Patel53bb5c92009-11-10 23:06:00 +0000268 void setAbstractScope() { AbstractScope = true; }
269 bool isAbstractScope() const { return AbstractScope; }
Devang Patel9cdb4102010-04-21 16:32:19 +0000270
271 // Depth First Search support to walk and mainpluate DbgScope hierarchy.
272 unsigned getDFSOut() const { return DFSOut; }
273 void setDFSOut(unsigned O) { DFSOut = O; }
274 unsigned getDFSIn() const { return DFSIn; }
275 void setDFSIn(unsigned I) { DFSIn = I; }
276 bool dominates(const DbgScope *S) {
277 if (S == this)
278 return true;
279 if (DFSIn < S->getDFSIn() && DFSOut > S->getDFSOut())
280 return true;
281 return false;
282 }
Devang Patel53bb5c92009-11-10 23:06:00 +0000283
Devang Patel2c4ceb12009-11-21 02:48:08 +0000284 /// addScope - Add a scope to the scope.
Bill Wendling0310d762009-05-15 09:23:25 +0000285 ///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000286 void addScope(DbgScope *S) { Scopes.push_back(S); }
Bill Wendling0310d762009-05-15 09:23:25 +0000287
Devang Patel2c4ceb12009-11-21 02:48:08 +0000288 /// addVariable - Add a variable to the scope.
Bill Wendling0310d762009-05-15 09:23:25 +0000289 ///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000290 void addVariable(DbgVariable *V) { Variables.push_back(V); }
Bill Wendling0310d762009-05-15 09:23:25 +0000291
Bill Wendling0310d762009-05-15 09:23:25 +0000292#ifndef NDEBUG
293 void dump() const;
294#endif
295};
Devang Patel9cdb4102010-04-21 16:32:19 +0000296
Chris Lattnerea761862010-04-05 04:09:20 +0000297} // end llvm namespace
Bill Wendling0310d762009-05-15 09:23:25 +0000298
299#ifndef NDEBUG
300void DbgScope::dump() const {
David Greenef83adbc2009-12-24 00:31:35 +0000301 raw_ostream &err = dbgs();
Chris Lattnerc281de12009-08-23 00:51:00 +0000302 err.indent(IndentLevel);
Devang Patel53bb5c92009-11-10 23:06:00 +0000303 MDNode *N = Desc.getNode();
304 N->dump();
Devang Patel53bb5c92009-11-10 23:06:00 +0000305 if (AbstractScope)
306 err << "Abstract Scope\n";
Bill Wendling0310d762009-05-15 09:23:25 +0000307
308 IndentLevel += 2;
Devang Patel53bb5c92009-11-10 23:06:00 +0000309 if (!Scopes.empty())
310 err << "Children ...\n";
Bill Wendling0310d762009-05-15 09:23:25 +0000311 for (unsigned i = 0, e = Scopes.size(); i != e; ++i)
312 if (Scopes[i] != this)
313 Scopes[i]->dump();
314
315 IndentLevel -= 2;
316}
317#endif
318
Bill Wendling0310d762009-05-15 09:23:25 +0000319DbgScope::~DbgScope() {
Bill Wendling0310d762009-05-15 09:23:25 +0000320 for (unsigned j = 0, M = Variables.size(); j < M; ++j)
321 delete Variables[j];
Bill Wendling0310d762009-05-15 09:23:25 +0000322}
323
Chris Lattner49cd6642010-04-05 05:11:15 +0000324DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
Chris Lattnerd38fee82010-04-05 00:13:49 +0000325 : Asm(A), MMI(Asm->MMI), ModuleCU(0),
Chris Lattner994cb122010-04-05 03:52:55 +0000326 AbbreviationsSet(InitAbbreviationsSetSize),
Devang Patelf2548ca2010-04-16 23:33:45 +0000327 CurrentFnDbgScope(0), PrevLabel(NULL) {
Chris Lattnerbc733f52010-03-13 02:17:42 +0000328 NextStringPoolNumber = 0;
Chris Lattner9c69e285532010-04-04 22:59:04 +0000329
Chris Lattner4ad1efe2010-04-04 23:10:38 +0000330 DwarfFrameSectionSym = DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0;
331 DwarfStrSectionSym = TextSectionSym = 0;
Devang Patel9cdb4102010-04-21 16:32:19 +0000332 DwarfDebugRangeSectionSym = 0;
Torok Edwin9c421072010-04-07 10:44:46 +0000333 if (TimePassesIsEnabled) {
334 NamedRegionTimer T(DbgTimerName, DWARFGroupName);
335 beginModule(M);
336 } else {
337 beginModule(M);
338 }
Bill Wendling0310d762009-05-15 09:23:25 +0000339}
340DwarfDebug::~DwarfDebug() {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000341 for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
342 DIEBlocks[j]->~DIEBlock();
Bill Wendling0310d762009-05-15 09:23:25 +0000343}
344
Chris Lattnerbc733f52010-03-13 02:17:42 +0000345MCSymbol *DwarfDebug::getStringPoolEntry(StringRef Str) {
346 std::pair<MCSymbol*, unsigned> &Entry = StringPool[Str];
347 if (Entry.first) return Entry.first;
348
349 Entry.second = NextStringPoolNumber++;
Chris Lattnerc0215722010-04-04 19:25:43 +0000350 return Entry.first = Asm->GetTempSymbol("string", Entry.second);
Chris Lattnerbc733f52010-03-13 02:17:42 +0000351}
352
353
Devang Patel2c4ceb12009-11-21 02:48:08 +0000354/// assignAbbrevNumber - Define a unique number for the abbreviation.
Bill Wendling0310d762009-05-15 09:23:25 +0000355///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000356void DwarfDebug::assignAbbrevNumber(DIEAbbrev &Abbrev) {
Bill Wendling0310d762009-05-15 09:23:25 +0000357 // Profile the node so that we can make it unique.
358 FoldingSetNodeID ID;
359 Abbrev.Profile(ID);
360
361 // Check the set for priors.
362 DIEAbbrev *InSet = AbbreviationsSet.GetOrInsertNode(&Abbrev);
363
364 // If it's newly added.
365 if (InSet == &Abbrev) {
366 // Add to abbreviation list.
367 Abbreviations.push_back(&Abbrev);
368
369 // Assign the vector position + 1 as its number.
370 Abbrev.setNumber(Abbreviations.size());
371 } else {
372 // Assign existing abbreviation number.
373 Abbrev.setNumber(InSet->getNumber());
374 }
375}
376
Devang Patel2c4ceb12009-11-21 02:48:08 +0000377/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug
Bill Wendling995f80a2009-05-20 23:24:48 +0000378/// information entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000379DIEEntry *DwarfDebug::createDIEEntry(DIE *Entry) {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000380 DIEEntry *Value = new (DIEValueAllocator) DIEEntry(Entry);
Bill Wendling0310d762009-05-15 09:23:25 +0000381 return Value;
382}
383
Devang Patel2c4ceb12009-11-21 02:48:08 +0000384/// addUInt - Add an unsigned integer attribute data and value.
Bill Wendling0310d762009-05-15 09:23:25 +0000385///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000386void DwarfDebug::addUInt(DIE *Die, unsigned Attribute,
Bill Wendling0310d762009-05-15 09:23:25 +0000387 unsigned Form, uint64_t Integer) {
388 if (!Form) Form = DIEInteger::BestForm(false, Integer);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000389 DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000390 Die->addValue(Attribute, Form, Value);
Bill Wendling0310d762009-05-15 09:23:25 +0000391}
392
Devang Patel2c4ceb12009-11-21 02:48:08 +0000393/// addSInt - Add an signed integer attribute data and value.
Bill Wendling0310d762009-05-15 09:23:25 +0000394///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000395void DwarfDebug::addSInt(DIE *Die, unsigned Attribute,
Bill Wendling0310d762009-05-15 09:23:25 +0000396 unsigned Form, int64_t Integer) {
397 if (!Form) Form = DIEInteger::BestForm(true, Integer);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000398 DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000399 Die->addValue(Attribute, Form, Value);
Bill Wendling0310d762009-05-15 09:23:25 +0000400}
401
Devang Patel69f57b12009-12-02 15:25:16 +0000402/// addString - Add a string attribute data and value. DIEString only
403/// keeps string reference.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000404void DwarfDebug::addString(DIE *Die, unsigned Attribute, unsigned Form,
Chris Lattner4cf202b2010-01-23 03:11:46 +0000405 StringRef String) {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000406 DIEValue *Value = new (DIEValueAllocator) DIEString(String);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000407 Die->addValue(Attribute, Form, Value);
Bill Wendling0310d762009-05-15 09:23:25 +0000408}
409
Devang Patel2c4ceb12009-11-21 02:48:08 +0000410/// addLabel - Add a Dwarf label attribute data and value.
Bill Wendling0310d762009-05-15 09:23:25 +0000411///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000412void DwarfDebug::addLabel(DIE *Die, unsigned Attribute, unsigned Form,
Chris Lattnerb98b1bf2010-03-08 22:23:36 +0000413 const MCSymbol *Label) {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000414 DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000415 Die->addValue(Attribute, Form, Value);
Bill Wendling0310d762009-05-15 09:23:25 +0000416}
417
Devang Patel2c4ceb12009-11-21 02:48:08 +0000418/// addDelta - Add a label delta attribute data and value.
Bill Wendling0310d762009-05-15 09:23:25 +0000419///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000420void DwarfDebug::addDelta(DIE *Die, unsigned Attribute, unsigned Form,
Chris Lattnerb98b1bf2010-03-08 22:23:36 +0000421 const MCSymbol *Hi, const MCSymbol *Lo) {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000422 DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000423 Die->addValue(Attribute, Form, Value);
Bill Wendling0310d762009-05-15 09:23:25 +0000424}
425
Chris Lattner74e41f92010-04-05 05:24:55 +0000426/// addDIEEntry - Add a DIE attribute data and value.
427///
428void DwarfDebug::addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form,
429 DIE *Entry) {
430 Die->addValue(Attribute, Form, createDIEEntry(Entry));
431}
432
433
Devang Patel2c4ceb12009-11-21 02:48:08 +0000434/// addBlock - Add block data.
Bill Wendling0310d762009-05-15 09:23:25 +0000435///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000436void DwarfDebug::addBlock(DIE *Die, unsigned Attribute, unsigned Form,
Bill Wendling0310d762009-05-15 09:23:25 +0000437 DIEBlock *Block) {
Chris Lattnera37d5382010-04-05 00:18:22 +0000438 Block->ComputeSize(Asm);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000439 DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000440 Die->addValue(Attribute, Block->BestForm(), Block);
Bill Wendling0310d762009-05-15 09:23:25 +0000441}
442
Devang Patel2c4ceb12009-11-21 02:48:08 +0000443/// addSourceLine - Add location information to specified debug information
Bill Wendling0310d762009-05-15 09:23:25 +0000444/// entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000445void DwarfDebug::addSourceLine(DIE *Die, const DIVariable *V) {
Bill Wendling0310d762009-05-15 09:23:25 +0000446 // If there is no compile unit specified, don't add a line #.
Devang Patel3c91b052010-03-08 20:52:55 +0000447 if (!V->getCompileUnit().Verify())
Bill Wendling0310d762009-05-15 09:23:25 +0000448 return;
449
450 unsigned Line = V->getLineNumber();
Devang Patel77bf2952010-03-08 22:02:50 +0000451 unsigned FileID = GetOrCreateSourceID(V->getContext().getDirectory(),
452 V->getContext().getFilename());
Bill Wendling0310d762009-05-15 09:23:25 +0000453 assert(FileID && "Invalid file id");
Devang Patel2c4ceb12009-11-21 02:48:08 +0000454 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
455 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Bill Wendling0310d762009-05-15 09:23:25 +0000456}
457
Devang Patel2c4ceb12009-11-21 02:48:08 +0000458/// addSourceLine - Add location information to specified debug information
Bill Wendling0310d762009-05-15 09:23:25 +0000459/// entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000460void DwarfDebug::addSourceLine(DIE *Die, const DIGlobal *G) {
Bill Wendling0310d762009-05-15 09:23:25 +0000461 // If there is no compile unit specified, don't add a line #.
Devang Patel3c91b052010-03-08 20:52:55 +0000462 if (!G->getCompileUnit().Verify())
Bill Wendling0310d762009-05-15 09:23:25 +0000463 return;
464
465 unsigned Line = G->getLineNumber();
Devang Patel77bf2952010-03-08 22:02:50 +0000466 unsigned FileID = GetOrCreateSourceID(G->getContext().getDirectory(),
467 G->getContext().getFilename());
Bill Wendling0310d762009-05-15 09:23:25 +0000468 assert(FileID && "Invalid file id");
Devang Patel2c4ceb12009-11-21 02:48:08 +0000469 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
470 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Bill Wendling0310d762009-05-15 09:23:25 +0000471}
Devang Patel82dfc0c2009-08-31 22:47:13 +0000472
Devang Patel2c4ceb12009-11-21 02:48:08 +0000473/// addSourceLine - Add location information to specified debug information
Devang Patel82dfc0c2009-08-31 22:47:13 +0000474/// entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000475void DwarfDebug::addSourceLine(DIE *Die, const DISubprogram *SP) {
Devang Patel82dfc0c2009-08-31 22:47:13 +0000476 // If there is no compile unit specified, don't add a line #.
Devang Patel3c91b052010-03-08 20:52:55 +0000477 if (!SP->getCompileUnit().Verify())
Devang Patel82dfc0c2009-08-31 22:47:13 +0000478 return;
Caroline Ticec6f9d622009-09-11 18:25:54 +0000479 // If the line number is 0, don't add it.
480 if (SP->getLineNumber() == 0)
481 return;
482
Devang Patel82dfc0c2009-08-31 22:47:13 +0000483 unsigned Line = SP->getLineNumber();
Devang Patel77bf2952010-03-08 22:02:50 +0000484 if (!SP->getContext().Verify())
485 return;
Devang Patel9bb59a22010-03-24 21:30:35 +0000486 unsigned FileID = GetOrCreateSourceID(SP->getDirectory(),
487 SP->getFilename());
Devang Patel82dfc0c2009-08-31 22:47:13 +0000488 assert(FileID && "Invalid file id");
Devang Patel2c4ceb12009-11-21 02:48:08 +0000489 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
490 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Devang Patel82dfc0c2009-08-31 22:47:13 +0000491}
492
Devang Patel2c4ceb12009-11-21 02:48:08 +0000493/// addSourceLine - Add location information to specified debug information
Devang Patel82dfc0c2009-08-31 22:47:13 +0000494/// entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000495void DwarfDebug::addSourceLine(DIE *Die, const DIType *Ty) {
Bill Wendling0310d762009-05-15 09:23:25 +0000496 // If there is no compile unit specified, don't add a line #.
497 DICompileUnit CU = Ty->getCompileUnit();
Devang Patel3c91b052010-03-08 20:52:55 +0000498 if (!CU.Verify())
Bill Wendling0310d762009-05-15 09:23:25 +0000499 return;
500
501 unsigned Line = Ty->getLineNumber();
Devang Patel77bf2952010-03-08 22:02:50 +0000502 if (!Ty->getContext().Verify())
503 return;
504 unsigned FileID = GetOrCreateSourceID(Ty->getContext().getDirectory(),
505 Ty->getContext().getFilename());
Bill Wendling0310d762009-05-15 09:23:25 +0000506 assert(FileID && "Invalid file id");
Devang Patel2c4ceb12009-11-21 02:48:08 +0000507 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
508 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Bill Wendling0310d762009-05-15 09:23:25 +0000509}
510
Devang Patel6404e4e2009-12-15 19:16:48 +0000511/// addSourceLine - Add location information to specified debug information
512/// entry.
513void DwarfDebug::addSourceLine(DIE *Die, const DINameSpace *NS) {
514 // If there is no compile unit specified, don't add a line #.
Devang Patel3c91b052010-03-08 20:52:55 +0000515 if (!NS->getCompileUnit().Verify())
Devang Patel6404e4e2009-12-15 19:16:48 +0000516 return;
517
518 unsigned Line = NS->getLineNumber();
519 StringRef FN = NS->getFilename();
520 StringRef Dir = NS->getDirectory();
521
522 unsigned FileID = GetOrCreateSourceID(Dir, FN);
523 assert(FileID && "Invalid file id");
524 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
525 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
526}
527
Caroline Ticedc8f6042009-08-31 21:19:37 +0000528/* Byref variables, in Blocks, are declared by the programmer as
529 "SomeType VarName;", but the compiler creates a
530 __Block_byref_x_VarName struct, and gives the variable VarName
531 either the struct, or a pointer to the struct, as its type. This
532 is necessary for various behind-the-scenes things the compiler
533 needs to do with by-reference variables in blocks.
534
535 However, as far as the original *programmer* is concerned, the
536 variable should still have type 'SomeType', as originally declared.
537
538 The following function dives into the __Block_byref_x_VarName
539 struct to find the original type of the variable. This will be
540 passed back to the code generating the type for the Debug
541 Information Entry for the variable 'VarName'. 'VarName' will then
542 have the original type 'SomeType' in its debug information.
543
544 The original type 'SomeType' will be the type of the field named
545 'VarName' inside the __Block_byref_x_VarName struct.
546
547 NOTE: In order for this to not completely fail on the debugger
548 side, the Debug Information Entry for the variable VarName needs to
549 have a DW_AT_location that tells the debugger how to unwind through
550 the pointers and __Block_byref_x_VarName struct to find the actual
Devang Patel2c4ceb12009-11-21 02:48:08 +0000551 value of the variable. The function addBlockByrefType does this. */
Caroline Ticedc8f6042009-08-31 21:19:37 +0000552
553/// Find the type the programmer originally declared the variable to be
554/// and return that type.
555///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000556DIType DwarfDebug::getBlockByrefType(DIType Ty, std::string Name) {
Caroline Ticedc8f6042009-08-31 21:19:37 +0000557
558 DIType subType = Ty;
559 unsigned tag = Ty.getTag();
560
561 if (tag == dwarf::DW_TAG_pointer_type) {
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000562 DIDerivedType DTy = DIDerivedType(Ty.getNode());
Caroline Ticedc8f6042009-08-31 21:19:37 +0000563 subType = DTy.getTypeDerivedFrom();
564 }
565
566 DICompositeType blockStruct = DICompositeType(subType.getNode());
Caroline Ticedc8f6042009-08-31 21:19:37 +0000567 DIArray Elements = blockStruct.getTypeArray();
568
Caroline Ticedc8f6042009-08-31 21:19:37 +0000569 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
570 DIDescriptor Element = Elements.getElement(i);
571 DIDerivedType DT = DIDerivedType(Element.getNode());
Devang Patel65dbc902009-11-25 17:36:49 +0000572 if (Name == DT.getName())
Caroline Ticedc8f6042009-08-31 21:19:37 +0000573 return (DT.getTypeDerivedFrom());
574 }
575
576 return Ty;
577}
578
Devang Patel2c4ceb12009-11-21 02:48:08 +0000579/// addComplexAddress - Start with the address based on the location provided,
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000580/// and generate the DWARF information necessary to find the actual variable
581/// given the extra address information encoded in the DIVariable, starting from
582/// the starting location. Add the DWARF information to the die.
583///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000584void DwarfDebug::addComplexAddress(DbgVariable *&DV, DIE *Die,
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000585 unsigned Attribute,
586 const MachineLocation &Location) {
587 const DIVariable &VD = DV->getVariable();
588 DIType Ty = VD.getType();
589
590 // Decode the original location, and use that as the start of the byref
591 // variable's location.
Chris Lattnerd38fee82010-04-05 00:13:49 +0000592 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000593 unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000594 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000595
596 if (Location.isReg()) {
597 if (Reg < 32) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000598 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000599 } else {
600 Reg = Reg - dwarf::DW_OP_reg0;
Devang Patel2c4ceb12009-11-21 02:48:08 +0000601 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
602 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000603 }
604 } else {
605 if (Reg < 32)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000606 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000607 else {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000608 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
609 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000610 }
611
Devang Patel2c4ceb12009-11-21 02:48:08 +0000612 addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000613 }
614
615 for (unsigned i = 0, N = VD.getNumAddrElements(); i < N; ++i) {
616 uint64_t Element = VD.getAddrElement(i);
617
618 if (Element == DIFactory::OpPlus) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000619 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
620 addUInt(Block, 0, dwarf::DW_FORM_udata, VD.getAddrElement(++i));
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000621 } else if (Element == DIFactory::OpDeref) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000622 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000623 } else llvm_unreachable("unknown DIFactory Opcode");
624 }
625
626 // Now attach the location information to the DIE.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000627 addBlock(Die, Attribute, 0, Block);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000628}
629
Caroline Ticedc8f6042009-08-31 21:19:37 +0000630/* Byref variables, in Blocks, are declared by the programmer as "SomeType
631 VarName;", but the compiler creates a __Block_byref_x_VarName struct, and
632 gives the variable VarName either the struct, or a pointer to the struct, as
633 its type. This is necessary for various behind-the-scenes things the
634 compiler needs to do with by-reference variables in Blocks.
635
636 However, as far as the original *programmer* is concerned, the variable
637 should still have type 'SomeType', as originally declared.
638
Devang Patel2c4ceb12009-11-21 02:48:08 +0000639 The function getBlockByrefType dives into the __Block_byref_x_VarName
Caroline Ticedc8f6042009-08-31 21:19:37 +0000640 struct to find the original type of the variable, which is then assigned to
641 the variable's Debug Information Entry as its real type. So far, so good.
642 However now the debugger will expect the variable VarName to have the type
643 SomeType. So we need the location attribute for the variable to be an
Daniel Dunbarf612ff62009-09-19 20:40:05 +0000644 expression that explains to the debugger how to navigate through the
Caroline Ticedc8f6042009-08-31 21:19:37 +0000645 pointers and struct to find the actual variable of type SomeType.
646
647 The following function does just that. We start by getting
648 the "normal" location for the variable. This will be the location
649 of either the struct __Block_byref_x_VarName or the pointer to the
650 struct __Block_byref_x_VarName.
651
652 The struct will look something like:
653
654 struct __Block_byref_x_VarName {
655 ... <various fields>
656 struct __Block_byref_x_VarName *forwarding;
657 ... <various other fields>
658 SomeType VarName;
659 ... <maybe more fields>
660 };
661
662 If we are given the struct directly (as our starting point) we
663 need to tell the debugger to:
664
665 1). Add the offset of the forwarding field.
666
Dan Gohmanf451cb82010-02-10 16:03:48 +0000667 2). Follow that pointer to get the real __Block_byref_x_VarName
Caroline Ticedc8f6042009-08-31 21:19:37 +0000668 struct to use (the real one may have been copied onto the heap).
669
670 3). Add the offset for the field VarName, to find the actual variable.
671
672 If we started with a pointer to the struct, then we need to
673 dereference that pointer first, before the other steps.
674 Translating this into DWARF ops, we will need to append the following
675 to the current location description for the variable:
676
677 DW_OP_deref -- optional, if we start with a pointer
678 DW_OP_plus_uconst <forward_fld_offset>
679 DW_OP_deref
680 DW_OP_plus_uconst <varName_fld_offset>
681
682 That is what this function does. */
683
Devang Patel2c4ceb12009-11-21 02:48:08 +0000684/// addBlockByrefAddress - Start with the address based on the location
Caroline Ticedc8f6042009-08-31 21:19:37 +0000685/// provided, and generate the DWARF information necessary to find the
686/// actual Block variable (navigating the Block struct) based on the
687/// starting location. Add the DWARF information to the die. For
688/// more information, read large comment just above here.
689///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000690void DwarfDebug::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
Daniel Dunbar00564992009-09-19 20:40:14 +0000691 unsigned Attribute,
692 const MachineLocation &Location) {
Caroline Ticedc8f6042009-08-31 21:19:37 +0000693 const DIVariable &VD = DV->getVariable();
694 DIType Ty = VD.getType();
695 DIType TmpTy = Ty;
696 unsigned Tag = Ty.getTag();
697 bool isPointer = false;
698
Devang Patel65dbc902009-11-25 17:36:49 +0000699 StringRef varName = VD.getName();
Caroline Ticedc8f6042009-08-31 21:19:37 +0000700
701 if (Tag == dwarf::DW_TAG_pointer_type) {
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000702 DIDerivedType DTy = DIDerivedType(Ty.getNode());
Caroline Ticedc8f6042009-08-31 21:19:37 +0000703 TmpTy = DTy.getTypeDerivedFrom();
704 isPointer = true;
705 }
706
707 DICompositeType blockStruct = DICompositeType(TmpTy.getNode());
708
Daniel Dunbar00564992009-09-19 20:40:14 +0000709 // Find the __forwarding field and the variable field in the __Block_byref
710 // struct.
Daniel Dunbar00564992009-09-19 20:40:14 +0000711 DIArray Fields = blockStruct.getTypeArray();
712 DIDescriptor varField = DIDescriptor();
713 DIDescriptor forwardingField = DIDescriptor();
Caroline Ticedc8f6042009-08-31 21:19:37 +0000714
Daniel Dunbar00564992009-09-19 20:40:14 +0000715 for (unsigned i = 0, N = Fields.getNumElements(); i < N; ++i) {
716 DIDescriptor Element = Fields.getElement(i);
717 DIDerivedType DT = DIDerivedType(Element.getNode());
Devang Patel65dbc902009-11-25 17:36:49 +0000718 StringRef fieldName = DT.getName();
719 if (fieldName == "__forwarding")
Daniel Dunbar00564992009-09-19 20:40:14 +0000720 forwardingField = Element;
Devang Patel65dbc902009-11-25 17:36:49 +0000721 else if (fieldName == varName)
Daniel Dunbar00564992009-09-19 20:40:14 +0000722 varField = Element;
723 }
Daniel Dunbarf612ff62009-09-19 20:40:05 +0000724
Daniel Dunbar00564992009-09-19 20:40:14 +0000725 // Get the offsets for the forwarding field and the variable field.
Chris Lattner1d65ba72010-03-31 06:06:37 +0000726 unsigned forwardingFieldOffset =
Daniel Dunbar00564992009-09-19 20:40:14 +0000727 DIDerivedType(forwardingField.getNode()).getOffsetInBits() >> 3;
Chris Lattner1d65ba72010-03-31 06:06:37 +0000728 unsigned varFieldOffset =
Daniel Dunbar00564992009-09-19 20:40:14 +0000729 DIDerivedType(varField.getNode()).getOffsetInBits() >> 3;
Caroline Ticedc8f6042009-08-31 21:19:37 +0000730
Mike Stump7e3720d2009-09-24 23:21:26 +0000731 // Decode the original location, and use that as the start of the byref
732 // variable's location.
Chris Lattnerd38fee82010-04-05 00:13:49 +0000733 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Daniel Dunbar00564992009-09-19 20:40:14 +0000734 unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000735 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Caroline Ticedc8f6042009-08-31 21:19:37 +0000736
Daniel Dunbar00564992009-09-19 20:40:14 +0000737 if (Location.isReg()) {
738 if (Reg < 32)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000739 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
Daniel Dunbar00564992009-09-19 20:40:14 +0000740 else {
741 Reg = Reg - dwarf::DW_OP_reg0;
Devang Patel2c4ceb12009-11-21 02:48:08 +0000742 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
743 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Daniel Dunbar00564992009-09-19 20:40:14 +0000744 }
745 } else {
746 if (Reg < 32)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000747 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
Daniel Dunbar00564992009-09-19 20:40:14 +0000748 else {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000749 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
750 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Daniel Dunbar00564992009-09-19 20:40:14 +0000751 }
Caroline Ticedc8f6042009-08-31 21:19:37 +0000752
Devang Patel2c4ceb12009-11-21 02:48:08 +0000753 addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
Daniel Dunbar00564992009-09-19 20:40:14 +0000754 }
Caroline Ticedc8f6042009-08-31 21:19:37 +0000755
Mike Stump7e3720d2009-09-24 23:21:26 +0000756 // If we started with a pointer to the __Block_byref... struct, then
Daniel Dunbar00564992009-09-19 20:40:14 +0000757 // the first thing we need to do is dereference the pointer (DW_OP_deref).
Daniel Dunbar00564992009-09-19 20:40:14 +0000758 if (isPointer)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000759 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
Caroline Ticedc8f6042009-08-31 21:19:37 +0000760
Daniel Dunbar00564992009-09-19 20:40:14 +0000761 // Next add the offset for the '__forwarding' field:
762 // DW_OP_plus_uconst ForwardingFieldOffset. Note there's no point in
763 // adding the offset if it's 0.
Daniel Dunbar00564992009-09-19 20:40:14 +0000764 if (forwardingFieldOffset > 0) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000765 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
766 addUInt(Block, 0, dwarf::DW_FORM_udata, forwardingFieldOffset);
Daniel Dunbar00564992009-09-19 20:40:14 +0000767 }
Caroline Ticedc8f6042009-08-31 21:19:37 +0000768
Daniel Dunbar00564992009-09-19 20:40:14 +0000769 // Now dereference the __forwarding field to get to the real __Block_byref
770 // struct: DW_OP_deref.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000771 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
Caroline Ticedc8f6042009-08-31 21:19:37 +0000772
Daniel Dunbar00564992009-09-19 20:40:14 +0000773 // Now that we've got the real __Block_byref... struct, add the offset
774 // for the variable's field to get to the location of the actual variable:
775 // DW_OP_plus_uconst varFieldOffset. Again, don't add if it's 0.
Daniel Dunbar00564992009-09-19 20:40:14 +0000776 if (varFieldOffset > 0) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000777 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
778 addUInt(Block, 0, dwarf::DW_FORM_udata, varFieldOffset);
Daniel Dunbar00564992009-09-19 20:40:14 +0000779 }
Caroline Ticedc8f6042009-08-31 21:19:37 +0000780
Daniel Dunbar00564992009-09-19 20:40:14 +0000781 // Now attach the location information to the DIE.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000782 addBlock(Die, Attribute, 0, Block);
Caroline Ticedc8f6042009-08-31 21:19:37 +0000783}
784
Devang Patel2c4ceb12009-11-21 02:48:08 +0000785/// addAddress - Add an address attribute to a die based on the location
Bill Wendling0310d762009-05-15 09:23:25 +0000786/// provided.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000787void DwarfDebug::addAddress(DIE *Die, unsigned Attribute,
Bill Wendling0310d762009-05-15 09:23:25 +0000788 const MachineLocation &Location) {
Chris Lattnerd38fee82010-04-05 00:13:49 +0000789 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Bill Wendling0310d762009-05-15 09:23:25 +0000790 unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000791 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Bill Wendling0310d762009-05-15 09:23:25 +0000792
793 if (Location.isReg()) {
794 if (Reg < 32) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000795 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
Bill Wendling0310d762009-05-15 09:23:25 +0000796 } else {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000797 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx);
798 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Bill Wendling0310d762009-05-15 09:23:25 +0000799 }
800 } else {
801 if (Reg < 32) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000802 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
Bill Wendling0310d762009-05-15 09:23:25 +0000803 } else {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000804 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
805 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Bill Wendling0310d762009-05-15 09:23:25 +0000806 }
807
Devang Patel2c4ceb12009-11-21 02:48:08 +0000808 addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
Bill Wendling0310d762009-05-15 09:23:25 +0000809 }
810
Devang Patel2c4ceb12009-11-21 02:48:08 +0000811 addBlock(Die, Attribute, 0, Block);
Bill Wendling0310d762009-05-15 09:23:25 +0000812}
813
Devang Patelc366f832009-12-10 19:14:49 +0000814/// addToContextOwner - Add Die into the list of its context owner's children.
815void DwarfDebug::addToContextOwner(DIE *Die, DIDescriptor Context) {
Devang Patel3c91b052010-03-08 20:52:55 +0000816 if (Context.isType()) {
Devang Patelc366f832009-12-10 19:14:49 +0000817 DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context.getNode()));
818 ContextDIE->addChild(Die);
Devang Patel6404e4e2009-12-15 19:16:48 +0000819 } else if (Context.isNameSpace()) {
820 DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context.getNode()));
821 ContextDIE->addChild(Die);
Devang Patelc366f832009-12-10 19:14:49 +0000822 } else if (DIE *ContextDIE = ModuleCU->getDIE(Context.getNode()))
823 ContextDIE->addChild(Die);
824 else
825 ModuleCU->addDie(Die);
826}
827
Devang Patel16ced732009-12-10 18:05:33 +0000828/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
829/// given DIType.
830DIE *DwarfDebug::getOrCreateTypeDIE(DIType Ty) {
831 DIE *TyDIE = ModuleCU->getDIE(Ty.getNode());
832 if (TyDIE)
833 return TyDIE;
834
835 // Create new type.
836 TyDIE = new DIE(dwarf::DW_TAG_base_type);
837 ModuleCU->insertDIE(Ty.getNode(), TyDIE);
838 if (Ty.isBasicType())
839 constructTypeDIE(*TyDIE, DIBasicType(Ty.getNode()));
840 else if (Ty.isCompositeType())
841 constructTypeDIE(*TyDIE, DICompositeType(Ty.getNode()));
842 else {
843 assert(Ty.isDerivedType() && "Unknown kind of DIType");
844 constructTypeDIE(*TyDIE, DIDerivedType(Ty.getNode()));
845 }
846
Devang Patelc366f832009-12-10 19:14:49 +0000847 addToContextOwner(TyDIE, Ty.getContext());
Devang Patel16ced732009-12-10 18:05:33 +0000848 return TyDIE;
849}
850
Devang Patel2c4ceb12009-11-21 02:48:08 +0000851/// addType - Add a new type attribute to the specified entity.
Devang Patel8a241142009-12-09 18:24:21 +0000852void DwarfDebug::addType(DIE *Entity, DIType Ty) {
Devang Patel3c91b052010-03-08 20:52:55 +0000853 if (!Ty.isValid())
Bill Wendling0310d762009-05-15 09:23:25 +0000854 return;
855
856 // Check for pre-existence.
Devang Patel8a241142009-12-09 18:24:21 +0000857 DIEEntry *Entry = ModuleCU->getDIEEntry(Ty.getNode());
Bill Wendling0310d762009-05-15 09:23:25 +0000858 // If it exists then use the existing value.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000859 if (Entry) {
860 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
Bill Wendling0310d762009-05-15 09:23:25 +0000861 return;
862 }
863
Bill Wendling0310d762009-05-15 09:23:25 +0000864 // Construct type.
Devang Patel16ced732009-12-10 18:05:33 +0000865 DIE *Buffer = getOrCreateTypeDIE(Ty);
Bill Wendling0310d762009-05-15 09:23:25 +0000866
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000867 // Set up proxy.
868 Entry = createDIEEntry(Buffer);
869 ModuleCU->insertDIEEntry(Ty.getNode(), Entry);
870
Devang Patel2c4ceb12009-11-21 02:48:08 +0000871 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
Bill Wendling0310d762009-05-15 09:23:25 +0000872}
873
Devang Patel2c4ceb12009-11-21 02:48:08 +0000874/// constructTypeDIE - Construct basic type die from DIBasicType.
Devang Patel8a241142009-12-09 18:24:21 +0000875void DwarfDebug::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
Bill Wendling0310d762009-05-15 09:23:25 +0000876 // Get core information.
Devang Patel65dbc902009-11-25 17:36:49 +0000877 StringRef Name = BTy.getName();
Bill Wendling0310d762009-05-15 09:23:25 +0000878 Buffer.setTag(dwarf::DW_TAG_base_type);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000879 addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
Bill Wendling0310d762009-05-15 09:23:25 +0000880 BTy.getEncoding());
881
882 // Add name if not anonymous or intermediate type.
Devang Patel65dbc902009-11-25 17:36:49 +0000883 if (!Name.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +0000884 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Bill Wendling0310d762009-05-15 09:23:25 +0000885 uint64_t Size = BTy.getSizeInBits() >> 3;
Devang Patel2c4ceb12009-11-21 02:48:08 +0000886 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
Bill Wendling0310d762009-05-15 09:23:25 +0000887}
888
Devang Patel2c4ceb12009-11-21 02:48:08 +0000889/// constructTypeDIE - Construct derived type die from DIDerivedType.
Devang Patel8a241142009-12-09 18:24:21 +0000890void DwarfDebug::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
Bill Wendling0310d762009-05-15 09:23:25 +0000891 // Get core information.
Devang Patel65dbc902009-11-25 17:36:49 +0000892 StringRef Name = DTy.getName();
Bill Wendling0310d762009-05-15 09:23:25 +0000893 uint64_t Size = DTy.getSizeInBits() >> 3;
894 unsigned Tag = DTy.getTag();
895
896 // FIXME - Workaround for templates.
897 if (Tag == dwarf::DW_TAG_inheritance) Tag = dwarf::DW_TAG_reference_type;
898
899 Buffer.setTag(Tag);
900
901 // Map to main type, void will not have a type.
902 DIType FromTy = DTy.getTypeDerivedFrom();
Devang Patel8a241142009-12-09 18:24:21 +0000903 addType(&Buffer, FromTy);
Bill Wendling0310d762009-05-15 09:23:25 +0000904
905 // Add name if not anonymous or intermediate type.
Devang Pateldeea5642009-11-30 23:56:56 +0000906 if (!Name.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +0000907 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Bill Wendling0310d762009-05-15 09:23:25 +0000908
909 // Add size if non-zero (derived types might be zero-sized.)
910 if (Size)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000911 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
Bill Wendling0310d762009-05-15 09:23:25 +0000912
913 // Add source line info if available and TyDesc is not a forward declaration.
Devang Patel05f6fa82009-11-23 18:43:37 +0000914 if (!DTy.isForwardDecl())
Devang Patel2c4ceb12009-11-21 02:48:08 +0000915 addSourceLine(&Buffer, &DTy);
Bill Wendling0310d762009-05-15 09:23:25 +0000916}
917
Devang Patel2c4ceb12009-11-21 02:48:08 +0000918/// constructTypeDIE - Construct type DIE from DICompositeType.
Devang Patel8a241142009-12-09 18:24:21 +0000919void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
Bill Wendling0310d762009-05-15 09:23:25 +0000920 // Get core information.
Devang Patel65dbc902009-11-25 17:36:49 +0000921 StringRef Name = CTy.getName();
Bill Wendling0310d762009-05-15 09:23:25 +0000922
923 uint64_t Size = CTy.getSizeInBits() >> 3;
924 unsigned Tag = CTy.getTag();
925 Buffer.setTag(Tag);
926
927 switch (Tag) {
928 case dwarf::DW_TAG_vector_type:
929 case dwarf::DW_TAG_array_type:
Devang Patel8a241142009-12-09 18:24:21 +0000930 constructArrayTypeDIE(Buffer, &CTy);
Bill Wendling0310d762009-05-15 09:23:25 +0000931 break;
932 case dwarf::DW_TAG_enumeration_type: {
933 DIArray Elements = CTy.getTypeArray();
934
935 // Add enumerators to enumeration type.
936 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
937 DIE *ElemDie = NULL;
Devang Patel3c91b052010-03-08 20:52:55 +0000938 DIDescriptor Enum(Elements.getElement(i).getNode());
939 if (Enum.isEnumerator()) {
940 ElemDie = constructEnumTypeDIE(DIEnumerator(Enum.getNode()));
Devang Patel2c4ceb12009-11-21 02:48:08 +0000941 Buffer.addChild(ElemDie);
Devang Patelc5254722009-10-09 17:51:49 +0000942 }
Bill Wendling0310d762009-05-15 09:23:25 +0000943 }
944 }
945 break;
946 case dwarf::DW_TAG_subroutine_type: {
947 // Add return type.
948 DIArray Elements = CTy.getTypeArray();
949 DIDescriptor RTy = Elements.getElement(0);
Devang Patel8a241142009-12-09 18:24:21 +0000950 addType(&Buffer, DIType(RTy.getNode()));
Bill Wendling0310d762009-05-15 09:23:25 +0000951
952 // Add prototype flag.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000953 addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +0000954
955 // Add arguments.
956 for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
957 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
958 DIDescriptor Ty = Elements.getElement(i);
Devang Patel8a241142009-12-09 18:24:21 +0000959 addType(Arg, DIType(Ty.getNode()));
Devang Patel2c4ceb12009-11-21 02:48:08 +0000960 Buffer.addChild(Arg);
Bill Wendling0310d762009-05-15 09:23:25 +0000961 }
962 }
963 break;
964 case dwarf::DW_TAG_structure_type:
965 case dwarf::DW_TAG_union_type:
966 case dwarf::DW_TAG_class_type: {
967 // Add elements to structure type.
968 DIArray Elements = CTy.getTypeArray();
969
970 // A forward struct declared type may not have elements available.
Devang Patel3c91b052010-03-08 20:52:55 +0000971 unsigned N = Elements.getNumElements();
972 if (N == 0)
Bill Wendling0310d762009-05-15 09:23:25 +0000973 break;
974
975 // Add elements to structure type.
Devang Patel3c91b052010-03-08 20:52:55 +0000976 for (unsigned i = 0; i < N; ++i) {
Bill Wendling0310d762009-05-15 09:23:25 +0000977 DIDescriptor Element = Elements.getElement(i);
978 DIE *ElemDie = NULL;
Devang Patel3c91b052010-03-08 20:52:55 +0000979 if (Element.isSubprogram())
Devang Patelffe966c2009-12-14 16:18:45 +0000980 ElemDie = createSubprogramDIE(DISubprogram(Element.getNode()));
Devang Patel3c91b052010-03-08 20:52:55 +0000981 else if (Element.isVariable()) {
Devang Patel1ee0cb92010-01-30 01:08:30 +0000982 DIVariable DV(Element.getNode());
983 ElemDie = new DIE(dwarf::DW_TAG_variable);
984 addString(ElemDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,
985 DV.getName());
986 addType(ElemDie, DV.getType());
987 addUInt(ElemDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
988 addUInt(ElemDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
989 addSourceLine(ElemDie, &DV);
Devang Patel3c91b052010-03-08 20:52:55 +0000990 } else if (Element.isDerivedType())
Devang Patel8a241142009-12-09 18:24:21 +0000991 ElemDie = createMemberDIE(DIDerivedType(Element.getNode()));
Devang Patel3c91b052010-03-08 20:52:55 +0000992 else
993 continue;
Devang Patel2c4ceb12009-11-21 02:48:08 +0000994 Buffer.addChild(ElemDie);
Bill Wendling0310d762009-05-15 09:23:25 +0000995 }
996
Devang Patela1ba2692009-08-27 23:51:51 +0000997 if (CTy.isAppleBlockExtension())
Devang Patel2c4ceb12009-11-21 02:48:08 +0000998 addUInt(&Buffer, dwarf::DW_AT_APPLE_block, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +0000999
1000 unsigned RLang = CTy.getRunTimeLang();
1001 if (RLang)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001002 addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class,
Bill Wendling0310d762009-05-15 09:23:25 +00001003 dwarf::DW_FORM_data1, RLang);
Devang Patelb5544992010-01-26 21:16:06 +00001004
1005 DICompositeType ContainingType = CTy.getContainingType();
Devang Patel3c91b052010-03-08 20:52:55 +00001006 if (DIDescriptor(ContainingType.getNode()).isCompositeType())
Devang Patelb5544992010-01-26 21:16:06 +00001007 addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
1008 getOrCreateTypeDIE(DIType(ContainingType.getNode())));
Bill Wendling0310d762009-05-15 09:23:25 +00001009 break;
1010 }
1011 default:
1012 break;
1013 }
1014
1015 // Add name if not anonymous or intermediate type.
Devang Patel65dbc902009-11-25 17:36:49 +00001016 if (!Name.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001017 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Bill Wendling0310d762009-05-15 09:23:25 +00001018
Devang Patel8cbb6122010-01-29 18:34:58 +00001019 if (Tag == dwarf::DW_TAG_enumeration_type || Tag == dwarf::DW_TAG_class_type ||
Bill Wendling0310d762009-05-15 09:23:25 +00001020 Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) {
1021 // Add size if non-zero (derived types might be zero-sized.)
1022 if (Size)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001023 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
Bill Wendling0310d762009-05-15 09:23:25 +00001024 else {
1025 // Add zero size if it is not a forward declaration.
1026 if (CTy.isForwardDecl())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001027 addUInt(&Buffer, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +00001028 else
Devang Patel2c4ceb12009-11-21 02:48:08 +00001029 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, 0);
Bill Wendling0310d762009-05-15 09:23:25 +00001030 }
1031
1032 // Add source line info if available.
1033 if (!CTy.isForwardDecl())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001034 addSourceLine(&Buffer, &CTy);
Bill Wendling0310d762009-05-15 09:23:25 +00001035 }
1036}
1037
Devang Patel2c4ceb12009-11-21 02:48:08 +00001038/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
1039void DwarfDebug::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){
Bill Wendling0310d762009-05-15 09:23:25 +00001040 int64_t L = SR.getLo();
1041 int64_t H = SR.getHi();
1042 DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type);
1043
Devang Patel2c4ceb12009-11-21 02:48:08 +00001044 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IndexTy);
Devang Patel6325a532009-08-14 20:59:16 +00001045 if (L)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001046 addSInt(DW_Subrange, dwarf::DW_AT_lower_bound, 0, L);
Devang Pateld55224c2009-12-04 23:10:24 +00001047 addSInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, H);
Bill Wendling0310d762009-05-15 09:23:25 +00001048
Devang Patel2c4ceb12009-11-21 02:48:08 +00001049 Buffer.addChild(DW_Subrange);
Bill Wendling0310d762009-05-15 09:23:25 +00001050}
1051
Devang Patel2c4ceb12009-11-21 02:48:08 +00001052/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
Devang Patel8a241142009-12-09 18:24:21 +00001053void DwarfDebug::constructArrayTypeDIE(DIE &Buffer,
Bill Wendling0310d762009-05-15 09:23:25 +00001054 DICompositeType *CTy) {
1055 Buffer.setTag(dwarf::DW_TAG_array_type);
1056 if (CTy->getTag() == dwarf::DW_TAG_vector_type)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001057 addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +00001058
1059 // Emit derived type.
Devang Patel8a241142009-12-09 18:24:21 +00001060 addType(&Buffer, CTy->getTypeDerivedFrom());
Bill Wendling0310d762009-05-15 09:23:25 +00001061 DIArray Elements = CTy->getTypeArray();
1062
Devang Patel6f01d9c2009-11-21 00:31:03 +00001063 // Get an anonymous type for index type.
Devang Patel8a241142009-12-09 18:24:21 +00001064 DIE *IdxTy = ModuleCU->getIndexTyDie();
Devang Patel6f01d9c2009-11-21 00:31:03 +00001065 if (!IdxTy) {
1066 // Construct an anonymous type for index type.
1067 IdxTy = new DIE(dwarf::DW_TAG_base_type);
Devang Patel2c4ceb12009-11-21 02:48:08 +00001068 addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t));
1069 addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
Devang Patel6f01d9c2009-11-21 00:31:03 +00001070 dwarf::DW_ATE_signed);
Devang Patel8a241142009-12-09 18:24:21 +00001071 ModuleCU->addDie(IdxTy);
1072 ModuleCU->setIndexTyDie(IdxTy);
Devang Patel6f01d9c2009-11-21 00:31:03 +00001073 }
Bill Wendling0310d762009-05-15 09:23:25 +00001074
1075 // Add subranges to array type.
1076 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
1077 DIDescriptor Element = Elements.getElement(i);
1078 if (Element.getTag() == dwarf::DW_TAG_subrange_type)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001079 constructSubrangeDIE(Buffer, DISubrange(Element.getNode()), IdxTy);
Bill Wendling0310d762009-05-15 09:23:25 +00001080 }
1081}
1082
Devang Patel2c4ceb12009-11-21 02:48:08 +00001083/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
Devang Patel3c91b052010-03-08 20:52:55 +00001084DIE *DwarfDebug::constructEnumTypeDIE(DIEnumerator ETy) {
Bill Wendling0310d762009-05-15 09:23:25 +00001085 DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator);
Devang Patel3c91b052010-03-08 20:52:55 +00001086 StringRef Name = ETy.getName();
Devang Patel2c4ceb12009-11-21 02:48:08 +00001087 addString(Enumerator, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Devang Patel3c91b052010-03-08 20:52:55 +00001088 int64_t Value = ETy.getEnumValue();
Devang Patel2c4ceb12009-11-21 02:48:08 +00001089 addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value);
Bill Wendling0310d762009-05-15 09:23:25 +00001090 return Enumerator;
1091}
1092
Devang Patel351ca332010-01-05 01:46:14 +00001093/// getRealLinkageName - If special LLVM prefix that is used to inform the asm
1094/// printer to not emit usual symbol prefix before the symbol name is used then
1095/// return linkage name after skipping this special LLVM prefix.
1096static StringRef getRealLinkageName(StringRef LinkageName) {
1097 char One = '\1';
1098 if (LinkageName.startswith(StringRef(&One, 1)))
1099 return LinkageName.substr(1);
1100 return LinkageName;
1101}
1102
Devang Patel2c4ceb12009-11-21 02:48:08 +00001103/// createGlobalVariableDIE - Create new DIE using GV.
Devang Patel8a241142009-12-09 18:24:21 +00001104DIE *DwarfDebug::createGlobalVariableDIE(const DIGlobalVariable &GV) {
Jim Grosbach7ab38df2009-11-22 19:20:36 +00001105 // If the global variable was optmized out then no need to create debug info
1106 // entry.
Devang Patel84c73e92009-11-06 17:58:12 +00001107 if (!GV.getGlobal()) return NULL;
Devang Patel65dbc902009-11-25 17:36:49 +00001108 if (GV.getDisplayName().empty()) return NULL;
Devang Patel465c3be2009-11-06 01:30:04 +00001109
Bill Wendling0310d762009-05-15 09:23:25 +00001110 DIE *GVDie = new DIE(dwarf::DW_TAG_variable);
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001111 addString(GVDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,
Devang Patel5ccdd102009-09-29 18:40:58 +00001112 GV.getDisplayName());
1113
Devang Patel65dbc902009-11-25 17:36:49 +00001114 StringRef LinkageName = GV.getLinkageName();
Devang Patel351ca332010-01-05 01:46:14 +00001115 if (!LinkageName.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001116 addString(GVDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string,
Devang Patel351ca332010-01-05 01:46:14 +00001117 getRealLinkageName(LinkageName));
1118
Devang Patel8a241142009-12-09 18:24:21 +00001119 addType(GVDie, GV.getType());
Bill Wendling0310d762009-05-15 09:23:25 +00001120 if (!GV.isLocalToUnit())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001121 addUInt(GVDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
1122 addSourceLine(GVDie, &GV);
Devang Patelb71a16d2009-10-05 23:22:08 +00001123
Bill Wendling0310d762009-05-15 09:23:25 +00001124 return GVDie;
1125}
1126
Devang Patel2c4ceb12009-11-21 02:48:08 +00001127/// createMemberDIE - Create new member DIE.
Devang Patel8a241142009-12-09 18:24:21 +00001128DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) {
Bill Wendling0310d762009-05-15 09:23:25 +00001129 DIE *MemberDie = new DIE(DT.getTag());
Devang Patel65dbc902009-11-25 17:36:49 +00001130 StringRef Name = DT.getName();
1131 if (!Name.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001132 addString(MemberDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Devang Patel65dbc902009-11-25 17:36:49 +00001133
Devang Patel8a241142009-12-09 18:24:21 +00001134 addType(MemberDie, DT.getTypeDerivedFrom());
Bill Wendling0310d762009-05-15 09:23:25 +00001135
Devang Patel2c4ceb12009-11-21 02:48:08 +00001136 addSourceLine(MemberDie, &DT);
Bill Wendling0310d762009-05-15 09:23:25 +00001137
Benjamin Kramer345ef342010-03-31 19:34:01 +00001138 DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
Devang Patel2c4ceb12009-11-21 02:48:08 +00001139 addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
Devang Patel33db5082009-11-04 22:06:12 +00001140
Bill Wendling0310d762009-05-15 09:23:25 +00001141 uint64_t Size = DT.getSizeInBits();
Devang Patel61ecbd12009-11-04 23:48:00 +00001142 uint64_t FieldSize = DT.getOriginalTypeSize();
Bill Wendling0310d762009-05-15 09:23:25 +00001143
1144 if (Size != FieldSize) {
1145 // Handle bitfield.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001146 addUInt(MemberDie, dwarf::DW_AT_byte_size, 0, DT.getOriginalTypeSize()>>3);
1147 addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits());
Bill Wendling0310d762009-05-15 09:23:25 +00001148
1149 uint64_t Offset = DT.getOffsetInBits();
Bill Wendling0310d762009-05-15 09:23:25 +00001150 uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
1151 uint64_t HiMark = (Offset + FieldSize) & AlignMask;
Benjamin Kramer3d594fd2010-01-07 17:50:57 +00001152 uint64_t FieldOffset = (HiMark - FieldSize);
Bill Wendling0310d762009-05-15 09:23:25 +00001153 Offset -= FieldOffset;
1154
1155 // Maybe we need to work from the other end.
Chris Lattnerd38fee82010-04-05 00:13:49 +00001156 if (Asm->getTargetData().isLittleEndian())
1157 Offset = FieldSize - (Offset + Size);
Devang Patel2c4ceb12009-11-21 02:48:08 +00001158 addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
Bill Wendling0310d762009-05-15 09:23:25 +00001159
Devang Patel33db5082009-11-04 22:06:12 +00001160 // Here WD_AT_data_member_location points to the anonymous
1161 // field that includes this bit field.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001162 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, FieldOffset >> 3);
Devang Patel33db5082009-11-04 22:06:12 +00001163
1164 } else
1165 // This is not a bitfield.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001166 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);
Devang Patel33db5082009-11-04 22:06:12 +00001167
Devang Patelc1dc8ff2010-02-03 20:08:48 +00001168 if (DT.getTag() == dwarf::DW_TAG_inheritance
1169 && DT.isVirtual()) {
1170
1171 // For C++, virtual base classes are not at fixed offset. Use following
1172 // expression to extract appropriate offset from vtable.
1173 // BaseAddr = ObAddr + *((*ObAddr) - Offset)
1174
Benjamin Kramer345ef342010-03-31 19:34:01 +00001175 DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock();
Devang Patelc1dc8ff2010-02-03 20:08:48 +00001176 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
1177 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1178 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1179 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits());
1180 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
1181 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1182 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1183
1184 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0,
1185 VBaseLocationDie);
1186 } else
1187 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
Bill Wendling0310d762009-05-15 09:23:25 +00001188
1189 if (DT.isProtected())
Devang Patel5d11eb02009-12-03 19:11:07 +00001190 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
Bill Wendling0310d762009-05-15 09:23:25 +00001191 dwarf::DW_ACCESS_protected);
1192 else if (DT.isPrivate())
Devang Patel5d11eb02009-12-03 19:11:07 +00001193 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
Bill Wendling0310d762009-05-15 09:23:25 +00001194 dwarf::DW_ACCESS_private);
Devang Patel5d11eb02009-12-03 19:11:07 +00001195 else if (DT.getTag() == dwarf::DW_TAG_inheritance)
1196 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1197 dwarf::DW_ACCESS_public);
1198 if (DT.isVirtual())
1199 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag,
1200 dwarf::DW_VIRTUALITY_virtual);
Bill Wendling0310d762009-05-15 09:23:25 +00001201 return MemberDie;
1202}
1203
Devang Patelffe966c2009-12-14 16:18:45 +00001204/// createSubprogramDIE - Create new DIE using SP.
1205DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) {
1206 DIE *SPDie = ModuleCU->getDIE(SP.getNode());
1207 if (SPDie)
1208 return SPDie;
1209
1210 SPDie = new DIE(dwarf::DW_TAG_subprogram);
Devang Patel1eac3e72010-03-02 17:58:15 +00001211 // Constructors and operators for anonymous aggregates do not have names.
Devang Patel6b506cb2010-03-02 01:26:20 +00001212 if (!SP.getName().empty())
1213 addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName());
Bill Wendling0310d762009-05-15 09:23:25 +00001214
Devang Patel65dbc902009-11-25 17:36:49 +00001215 StringRef LinkageName = SP.getLinkageName();
Devang Patel351ca332010-01-05 01:46:14 +00001216 if (!LinkageName.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001217 addString(SPDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string,
Devang Patel351ca332010-01-05 01:46:14 +00001218 getRealLinkageName(LinkageName));
1219
Devang Patel2c4ceb12009-11-21 02:48:08 +00001220 addSourceLine(SPDie, &SP);
Bill Wendling0310d762009-05-15 09:23:25 +00001221
Bill Wendling0310d762009-05-15 09:23:25 +00001222 // Add prototyped tag, if C or ObjC.
1223 unsigned Lang = SP.getCompileUnit().getLanguage();
1224 if (Lang == dwarf::DW_LANG_C99 || Lang == dwarf::DW_LANG_C89 ||
1225 Lang == dwarf::DW_LANG_ObjC)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001226 addUInt(SPDie, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +00001227
1228 // Add Return Type.
Devang Patel1d5cc1d2009-12-03 01:25:38 +00001229 DICompositeType SPTy = SP.getType();
1230 DIArray Args = SPTy.getTypeArray();
Bill Wendling0310d762009-05-15 09:23:25 +00001231 unsigned SPTag = SPTy.getTag();
Devang Patel5d11eb02009-12-03 19:11:07 +00001232
Devang Patel3c91b052010-03-08 20:52:55 +00001233 if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type)
Devang Patel8a241142009-12-09 18:24:21 +00001234 addType(SPDie, SPTy);
Devang Patel1d5cc1d2009-12-03 01:25:38 +00001235 else
Devang Patel8a241142009-12-09 18:24:21 +00001236 addType(SPDie, DIType(Args.getElement(0).getNode()));
Devang Patel1d5cc1d2009-12-03 01:25:38 +00001237
Devang Patel5d11eb02009-12-03 19:11:07 +00001238 unsigned VK = SP.getVirtuality();
1239 if (VK) {
1240 addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK);
Benjamin Kramer345ef342010-03-31 19:34:01 +00001241 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel5d11eb02009-12-03 19:11:07 +00001242 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1243 addUInt(Block, 0, dwarf::DW_FORM_data1, SP.getVirtualIndex());
1244 addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
Devang Patel622b0262010-01-19 06:19:05 +00001245 ContainingTypeMap.insert(std::make_pair(SPDie,
1246 SP.getContainingType().getNode()));
Devang Patel5d11eb02009-12-03 19:11:07 +00001247 }
1248
Devang Patelffe966c2009-12-14 16:18:45 +00001249 if (MakeDecl || !SP.isDefinition()) {
Devang Patel2c4ceb12009-11-21 02:48:08 +00001250 addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +00001251
1252 // Add arguments. Do not add arguments for subprogram definition. They will
Devang Patel1d5cc1d2009-12-03 01:25:38 +00001253 // be handled while processing variables.
1254 DICompositeType SPTy = SP.getType();
1255 DIArray Args = SPTy.getTypeArray();
1256 unsigned SPTag = SPTy.getTag();
1257
Bill Wendling0310d762009-05-15 09:23:25 +00001258 if (SPTag == dwarf::DW_TAG_subroutine_type)
1259 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
1260 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
Devang Patelb4645642010-02-06 01:02:37 +00001261 DIType ATy = DIType(DIType(Args.getElement(i).getNode()));
1262 addType(Arg, ATy);
1263 if (ATy.isArtificial())
1264 addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
Devang Patel2c4ceb12009-11-21 02:48:08 +00001265 SPDie->addChild(Arg);
Bill Wendling0310d762009-05-15 09:23:25 +00001266 }
1267 }
1268
Devang Patel4e0d19d2010-02-03 19:57:19 +00001269 if (SP.isArtificial())
1270 addUInt(SPDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
1271
Bill Wendling0310d762009-05-15 09:23:25 +00001272 // DW_TAG_inlined_subroutine may refer to this DIE.
Devang Patel8a241142009-12-09 18:24:21 +00001273 ModuleCU->insertDIE(SP.getNode(), SPDie);
Devang Patel2a4a3b72010-04-19 19:14:02 +00001274
Evan Chenge5667632010-04-21 03:18:23 +00001275 if (!DisableFramePointerElim(*Asm->MF))
Devang Patel2a4a3b72010-04-19 19:14:02 +00001276 addUInt(SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr, dwarf::DW_FORM_flag, 1);
1277
Bill Wendling0310d762009-05-15 09:23:25 +00001278 return SPDie;
1279}
1280
Devang Patel53bb5c92009-11-10 23:06:00 +00001281DbgScope *DwarfDebug::getOrCreateAbstractScope(MDNode *N) {
Chris Lattnered7a77b2010-03-31 05:36:29 +00001282 assert(N && "Invalid Scope encoding!");
Devang Patel53bb5c92009-11-10 23:06:00 +00001283
1284 DbgScope *AScope = AbstractScopes.lookup(N);
1285 if (AScope)
1286 return AScope;
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001287
Devang Patel53bb5c92009-11-10 23:06:00 +00001288 DbgScope *Parent = NULL;
1289
1290 DIDescriptor Scope(N);
1291 if (Scope.isLexicalBlock()) {
1292 DILexicalBlock DB(N);
1293 DIDescriptor ParentDesc = DB.getContext();
Devang Patel3c91b052010-03-08 20:52:55 +00001294 Parent = getOrCreateAbstractScope(ParentDesc.getNode());
Devang Patel53bb5c92009-11-10 23:06:00 +00001295 }
1296
1297 AScope = new DbgScope(Parent, DIDescriptor(N), NULL);
1298
1299 if (Parent)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001300 Parent->addScope(AScope);
Devang Patel53bb5c92009-11-10 23:06:00 +00001301 AScope->setAbstractScope();
1302 AbstractScopes[N] = AScope;
1303 if (DIDescriptor(N).isSubprogram())
1304 AbstractScopesList.push_back(AScope);
1305 return AScope;
1306}
Devang Patelaf9e8472009-10-01 20:31:14 +00001307
Devang Patel5f094002010-04-06 23:53:48 +00001308/// isSubprogramContext - Return true if Context is either a subprogram
1309/// or another context nested inside a subprogram.
Dan Gohmanb3579832010-04-15 17:08:50 +00001310static bool isSubprogramContext(MDNode *Context) {
Devang Patel5f094002010-04-06 23:53:48 +00001311 if (!Context)
1312 return false;
1313 DIDescriptor D(Context);
1314 if (D.isSubprogram())
1315 return true;
1316 if (D.isType())
1317 return isSubprogramContext(DIType(Context).getContext().getNode());
1318 return false;
1319}
1320
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001321/// updateSubprogramScopeDIE - Find DIE for the given subprogram and
Devang Patel2c4ceb12009-11-21 02:48:08 +00001322/// attach appropriate DW_AT_low_pc and DW_AT_high_pc attributes.
1323/// If there are global variables in this scope then create and insert
1324/// DIEs for these variables.
1325DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) {
Chris Lattnerd38fee82010-04-05 00:13:49 +00001326 DIE *SPDie = ModuleCU->getDIE(SPNode);
1327 assert(SPDie && "Unable to find subprogram DIE!");
1328 DISubprogram SP(SPNode);
Chris Lattner206d61e2010-03-13 07:26:18 +00001329
Chris Lattnerd38fee82010-04-05 00:13:49 +00001330 // There is not any need to generate specification DIE for a function
1331 // defined at compile unit level. If a function is defined inside another
1332 // function then gdb prefers the definition at top level and but does not
1333 // expect specification DIE in parent function. So avoid creating
1334 // specification DIE for a function defined inside a function.
1335 if (SP.isDefinition() && !SP.getContext().isCompileUnit() &&
Devang Patel5f094002010-04-06 23:53:48 +00001336 !SP.getContext().isFile() &&
1337 !isSubprogramContext(SP.getContext().getNode())) {
Chris Lattnerd38fee82010-04-05 00:13:49 +00001338 addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
1339
1340 // Add arguments.
1341 DICompositeType SPTy = SP.getType();
1342 DIArray Args = SPTy.getTypeArray();
1343 unsigned SPTag = SPTy.getTag();
1344 if (SPTag == dwarf::DW_TAG_subroutine_type)
1345 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
1346 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
1347 DIType ATy = DIType(DIType(Args.getElement(i).getNode()));
1348 addType(Arg, ATy);
1349 if (ATy.isArtificial())
1350 addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
1351 SPDie->addChild(Arg);
1352 }
1353 DIE *SPDeclDie = SPDie;
1354 SPDie = new DIE(dwarf::DW_TAG_subprogram);
1355 addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
1356 SPDeclDie);
1357 ModuleCU->addDie(SPDie);
1358 }
1359
1360 addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1361 Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber()));
1362 addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
1363 Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()));
1364 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
1365 MachineLocation Location(RI->getFrameRegister(*Asm->MF));
1366 addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
Devang Patelb4645642010-02-06 01:02:37 +00001367
Chris Lattnerd38fee82010-04-05 00:13:49 +00001368 if (!DISubprogram(SPNode).isLocalToUnit())
1369 addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
1370
1371 return SPDie;
Devang Patel53bb5c92009-11-10 23:06:00 +00001372}
1373
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001374/// constructLexicalScope - Construct new DW_TAG_lexical_block
Devang Patel2c4ceb12009-11-21 02:48:08 +00001375/// for this scope and attach DW_AT_low_pc/DW_AT_high_pc labels.
1376DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {
Devang Patel9cdb4102010-04-21 16:32:19 +00001377
1378 DIE *ScopeDIE = new DIE(dwarf::DW_TAG_lexical_block);
1379 if (Scope->isAbstractScope())
1380 return ScopeDIE;
1381
1382 const SmallVector<DbgRange, 4> &Ranges = Scope->getRanges();
1383 if (Ranges.empty())
1384 return 0;
1385
1386 SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin();
1387 if (Ranges.size() > 1) {
1388 // .debug_range section has not been laid out yet. Emit offset in
1389 // .debug_range as a uint, size 4, for now. emitDIE will handle
1390 // DW_AT_ranges appropriately.
1391 addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4,
1392 DebugRangeSymbols.size() * Asm->getTargetData().getPointerSize());
1393 for (SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin(),
1394 RE = Ranges.end(); RI != RE; ++RI) {
1395 DebugRangeSymbols.push_back(InsnBeforeLabelMap.lookup(RI->first));
1396 DebugRangeSymbols.push_back(InsnAfterLabelMap.lookup(RI->second));
1397 }
1398 DebugRangeSymbols.push_back(NULL);
1399 DebugRangeSymbols.push_back(NULL);
1400 return ScopeDIE;
1401 }
1402
1403 MCSymbol *Start = InsnBeforeLabelMap.lookup(RI->first);
1404 MCSymbol *End = InsnAfterLabelMap.lookup(RI->second);
1405
Devang Patelaead63c2010-03-29 22:59:58 +00001406 if (Start == 0 || End == 0) return 0;
Devang Patel53bb5c92009-11-10 23:06:00 +00001407
Chris Lattnerb7db7332010-03-09 01:58:53 +00001408 assert(Start->isDefined() && "Invalid starting label for an inlined scope!");
1409 assert(End->isDefined() && "Invalid end label for an inlined scope!");
Chris Lattnera34ec2292010-03-09 01:51:43 +00001410
Devang Patelbc655ea2010-04-22 18:28:58 +00001411 addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, Start);
1412 addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, End);
Devang Patel53bb5c92009-11-10 23:06:00 +00001413
1414 return ScopeDIE;
1415}
1416
Devang Patel2c4ceb12009-11-21 02:48:08 +00001417/// constructInlinedScopeDIE - This scope represents inlined body of
1418/// a function. Construct DIE to represent this concrete inlined copy
1419/// of the function.
1420DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
Devang Patel9cdb4102010-04-21 16:32:19 +00001421
1422 const SmallVector<DbgRange, 4> &Ranges = Scope->getRanges();
1423 assert (Ranges.empty() == false
1424 && "DbgScope does not have instruction markers!");
1425
1426 // FIXME : .debug_inlined section specification does not clearly state how
1427 // to emit inlined scope that is split into multiple instruction ranges.
1428 // For now, use first instruction range and emit low_pc/high_pc pair and
1429 // corresponding .debug_inlined section entry for this pair.
1430 SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin();
1431 MCSymbol *StartLabel = InsnBeforeLabelMap.lookup(RI->first);
1432 MCSymbol *EndLabel = InsnAfterLabelMap.lookup(RI->second);
1433
1434 if (StartLabel == 0 || EndLabel == 0) {
1435 assert (0 && "Unexpected Start and End labels for a inlined scope!");
1436 return 0;
1437 }
Chris Lattnerb7db7332010-03-09 01:58:53 +00001438 assert(StartLabel->isDefined() &&
Chris Lattnera34ec2292010-03-09 01:51:43 +00001439 "Invalid starting label for an inlined scope!");
Chris Lattnerb7db7332010-03-09 01:58:53 +00001440 assert(EndLabel->isDefined() &&
Chris Lattnera34ec2292010-03-09 01:51:43 +00001441 "Invalid end label for an inlined scope!");
Devang Patel9cdb4102010-04-21 16:32:19 +00001442
Devang Patel3c91b052010-03-08 20:52:55 +00001443 if (!Scope->getScopeNode())
Devang Patel0ef3fa62010-03-08 19:20:38 +00001444 return NULL;
Devang Patel3c91b052010-03-08 20:52:55 +00001445 DIScope DS(Scope->getScopeNode());
Devang Patel53bb5c92009-11-10 23:06:00 +00001446 DIE *ScopeDIE = new DIE(dwarf::DW_TAG_inlined_subroutine);
1447
1448 DISubprogram InlinedSP = getDISubprogram(DS.getNode());
Devang Patel017d1212009-11-20 21:37:22 +00001449 DIE *OriginDIE = ModuleCU->getDIE(InlinedSP.getNode());
Chris Lattnered7a77b2010-03-31 05:36:29 +00001450 assert(OriginDIE && "Unable to find Origin DIE!");
Devang Patel2c4ceb12009-11-21 02:48:08 +00001451 addDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin,
Devang Patel53bb5c92009-11-10 23:06:00 +00001452 dwarf::DW_FORM_ref4, OriginDIE);
1453
Chris Lattner6ed0f902010-03-09 00:31:02 +00001454 addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, StartLabel);
Chris Lattnerb7db7332010-03-09 01:58:53 +00001455 addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, EndLabel);
Devang Patel53bb5c92009-11-10 23:06:00 +00001456
1457 InlinedSubprogramDIEs.insert(OriginDIE);
1458
1459 // Track the start label for this inlined function.
Devang Patel622b0262010-01-19 06:19:05 +00001460 DenseMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator
Devang Patel53bb5c92009-11-10 23:06:00 +00001461 I = InlineInfo.find(InlinedSP.getNode());
1462
1463 if (I == InlineInfo.end()) {
Chris Lattner6ed0f902010-03-09 00:31:02 +00001464 InlineInfo[InlinedSP.getNode()].push_back(std::make_pair(StartLabel,
Jim Grosbach7ab38df2009-11-22 19:20:36 +00001465 ScopeDIE));
Devang Patel53bb5c92009-11-10 23:06:00 +00001466 InlinedSPNodes.push_back(InlinedSP.getNode());
1467 } else
Chris Lattner6ed0f902010-03-09 00:31:02 +00001468 I->second.push_back(std::make_pair(StartLabel, ScopeDIE));
Devang Patel53bb5c92009-11-10 23:06:00 +00001469
Devang Patel53bb5c92009-11-10 23:06:00 +00001470 DILocation DL(Scope->getInlinedAt());
Devang Patel2c4ceb12009-11-21 02:48:08 +00001471 addUInt(ScopeDIE, dwarf::DW_AT_call_file, 0, ModuleCU->getID());
1472 addUInt(ScopeDIE, dwarf::DW_AT_call_line, 0, DL.getLineNumber());
Devang Patel53bb5c92009-11-10 23:06:00 +00001473
1474 return ScopeDIE;
1475}
1476
Devang Patel2c4ceb12009-11-21 02:48:08 +00001477
1478/// constructVariableDIE - Construct a DIE for the given DbgVariable.
Devang Patel8a241142009-12-09 18:24:21 +00001479DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
Devang Patel53bb5c92009-11-10 23:06:00 +00001480 // Get the descriptor.
1481 const DIVariable &VD = DV->getVariable();
Devang Patel65dbc902009-11-25 17:36:49 +00001482 StringRef Name = VD.getName();
1483 if (Name.empty())
Devang Patel3fb6bd62009-11-13 02:25:26 +00001484 return NULL;
Devang Patel53bb5c92009-11-10 23:06:00 +00001485
1486 // Translate tag to proper Dwarf tag. The result variable is dropped for
1487 // now.
1488 unsigned Tag;
1489 switch (VD.getTag()) {
1490 case dwarf::DW_TAG_return_variable:
1491 return NULL;
1492 case dwarf::DW_TAG_arg_variable:
1493 Tag = dwarf::DW_TAG_formal_parameter;
1494 break;
1495 case dwarf::DW_TAG_auto_variable: // fall thru
1496 default:
1497 Tag = dwarf::DW_TAG_variable;
1498 break;
1499 }
1500
1501 // Define variable debug information entry.
1502 DIE *VariableDie = new DIE(Tag);
1503
1504
1505 DIE *AbsDIE = NULL;
1506 if (DbgVariable *AV = DV->getAbstractVariable())
1507 AbsDIE = AV->getDIE();
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001508
Devang Patel53bb5c92009-11-10 23:06:00 +00001509 if (AbsDIE) {
1510 DIScope DS(Scope->getScopeNode());
1511 DISubprogram InlinedSP = getDISubprogram(DS.getNode());
Devang Patel017d1212009-11-20 21:37:22 +00001512 DIE *OriginSPDIE = ModuleCU->getDIE(InlinedSP.getNode());
Daniel Dunbarc0326792009-11-11 03:09:50 +00001513 (void) OriginSPDIE;
Chris Lattnered7a77b2010-03-31 05:36:29 +00001514 assert(OriginSPDIE && "Unable to find Origin DIE for the SP!");
Devang Patel53bb5c92009-11-10 23:06:00 +00001515 DIE *AbsDIE = DV->getAbstractVariable()->getDIE();
Chris Lattnered7a77b2010-03-31 05:36:29 +00001516 assert(AbsDIE && "Unable to find Origin DIE for the Variable!");
Devang Patel2c4ceb12009-11-21 02:48:08 +00001517 addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin,
Devang Patel53bb5c92009-11-10 23:06:00 +00001518 dwarf::DW_FORM_ref4, AbsDIE);
1519 }
1520 else {
Devang Patel2c4ceb12009-11-21 02:48:08 +00001521 addString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
1522 addSourceLine(VariableDie, &VD);
Devang Patel53bb5c92009-11-10 23:06:00 +00001523
1524 // Add variable type.
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001525 // FIXME: isBlockByrefVariable should be reformulated in terms of complex
Devang Patel53bb5c92009-11-10 23:06:00 +00001526 // addresses instead.
1527 if (VD.isBlockByrefVariable())
Devang Patel8a241142009-12-09 18:24:21 +00001528 addType(VariableDie, getBlockByrefType(VD.getType(), Name));
Devang Patel53bb5c92009-11-10 23:06:00 +00001529 else
Devang Patel8a241142009-12-09 18:24:21 +00001530 addType(VariableDie, VD.getType());
Devang Patel53bb5c92009-11-10 23:06:00 +00001531 }
1532
1533 // Add variable address.
1534 if (!Scope->isAbstractScope()) {
Devang Patel90a48ad2010-03-15 18:33:46 +00001535 // Check if variable is described by DBG_VALUE instruction.
1536 if (const MachineInstr *DbgValueInsn = DV->getDbgValue()) {
1537 if (DbgValueInsn->getNumOperands() == 3) {
1538 // FIXME : Handle getNumOperands != 3
1539 if (DbgValueInsn->getOperand(0).getType()
1540 == MachineOperand::MO_Register
1541 && DbgValueInsn->getOperand(0).getReg()) {
1542 MachineLocation Location;
1543 Location.set(DbgValueInsn->getOperand(0).getReg());
1544 addAddress(VariableDie, dwarf::DW_AT_location, Location);
Devang Patelaead63c2010-03-29 22:59:58 +00001545 if (MCSymbol *VS = DV->getDbgValueLabel())
1546 addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
1547 VS);
Devang Patel90a48ad2010-03-15 18:33:46 +00001548 } else if (DbgValueInsn->getOperand(0).getType() ==
1549 MachineOperand::MO_Immediate) {
Benjamin Kramer345ef342010-03-31 19:34:01 +00001550 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel90a48ad2010-03-15 18:33:46 +00001551 unsigned Imm = DbgValueInsn->getOperand(0).getImm();
1552 addUInt(Block, 0, dwarf::DW_FORM_udata, Imm);
1553 addBlock(VariableDie, dwarf::DW_AT_const_value, 0, Block);
Devang Patelaead63c2010-03-29 22:59:58 +00001554 if (MCSymbol *VS = DV->getDbgValueLabel())
1555 addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
1556 VS);
Bill Wendling57fbba42010-04-05 22:59:21 +00001557 } else if (DbgValueInsn->getOperand(0).getType() ==
1558 MachineOperand::MO_FPImmediate) {
1559 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
1560 APFloat FPImm = DbgValueInsn->getOperand(0).getFPImm()->getValueAPF();
1561
1562 // Get the raw data form of the floating point.
1563 const APInt FltVal = FPImm.bitcastToAPInt();
1564 const char *FltPtr = (const char*)FltVal.getRawData();
1565
John McCall795ee9d2010-04-06 23:35:53 +00001566 int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte.
Bill Wendling57fbba42010-04-05 22:59:21 +00001567 bool LittleEndian = Asm->getTargetData().isLittleEndian();
1568 int Incr = (LittleEndian ? 1 : -1);
1569 int Start = (LittleEndian ? 0 : NumBytes - 1);
1570 int Stop = (LittleEndian ? NumBytes : -1);
1571
1572 // Output the constant to DWARF one byte at a time.
1573 for (; Start != Stop; Start += Incr)
1574 addUInt(Block, 0, dwarf::DW_FORM_data1,
1575 (unsigned char)0xFF & FltPtr[Start]);
1576
1577 addBlock(VariableDie, dwarf::DW_AT_const_value, 0, Block);
1578
1579 if (MCSymbol *VS = DV->getDbgValueLabel())
1580 addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
1581 VS);
Devang Patel90a48ad2010-03-15 18:33:46 +00001582 } else {
1583 //FIXME : Handle other operand types.
1584 delete VariableDie;
1585 return NULL;
1586 }
1587 }
1588 } else {
1589 MachineLocation Location;
1590 unsigned FrameReg;
Chris Lattnerd38fee82010-04-05 00:13:49 +00001591 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
1592 int Offset = RI->getFrameIndexReference(*Asm->MF, DV->getFrameIndex(),
Chris Lattner1d65ba72010-03-31 06:06:37 +00001593 FrameReg);
Devang Patel90a48ad2010-03-15 18:33:46 +00001594 Location.set(FrameReg, Offset);
1595
1596 if (VD.hasComplexAddress())
1597 addComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
1598 else if (VD.isBlockByrefVariable())
1599 addBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
1600 else
1601 addAddress(VariableDie, dwarf::DW_AT_location, Location);
1602 }
Devang Patel53bb5c92009-11-10 23:06:00 +00001603 }
Devang Patelb4645642010-02-06 01:02:37 +00001604
1605 if (Tag == dwarf::DW_TAG_formal_parameter && VD.getType().isArtificial())
1606 addUInt(VariableDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
Devang Patel53bb5c92009-11-10 23:06:00 +00001607 DV->setDIE(VariableDie);
1608 return VariableDie;
1609
1610}
Devang Patel2c4ceb12009-11-21 02:48:08 +00001611
Devang Patel193f7202009-11-24 01:14:22 +00001612void DwarfDebug::addPubTypes(DISubprogram SP) {
1613 DICompositeType SPTy = SP.getType();
1614 unsigned SPTag = SPTy.getTag();
1615 if (SPTag != dwarf::DW_TAG_subroutine_type)
1616 return;
1617
1618 DIArray Args = SPTy.getTypeArray();
Devang Patel193f7202009-11-24 01:14:22 +00001619 for (unsigned i = 0, e = Args.getNumElements(); i != e; ++i) {
1620 DIType ATy(Args.getElement(i).getNode());
Devang Patel3c91b052010-03-08 20:52:55 +00001621 if (!ATy.isValid())
Devang Patel193f7202009-11-24 01:14:22 +00001622 continue;
1623 DICompositeType CATy = getDICompositeType(ATy);
Devang Patel50d80e32010-04-13 20:35:04 +00001624 if (DIDescriptor(CATy.getNode()).Verify() && !CATy.getName().empty()
1625 && !CATy.isForwardDecl()) {
Devang Patel193f7202009-11-24 01:14:22 +00001626 if (DIEEntry *Entry = ModuleCU->getDIEEntry(CATy.getNode()))
1627 ModuleCU->addGlobalType(CATy.getName(), Entry->getEntry());
1628 }
1629 }
1630}
1631
Devang Patel2c4ceb12009-11-21 02:48:08 +00001632/// constructScopeDIE - Construct a DIE for this scope.
1633DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) {
Devang Patel3c91b052010-03-08 20:52:55 +00001634 if (!Scope || !Scope->getScopeNode())
1635 return NULL;
1636
1637 DIScope DS(Scope->getScopeNode());
1638 DIE *ScopeDIE = NULL;
1639 if (Scope->getInlinedAt())
1640 ScopeDIE = constructInlinedScopeDIE(Scope);
1641 else if (DS.isSubprogram()) {
1642 if (Scope->isAbstractScope())
1643 ScopeDIE = ModuleCU->getDIE(DS.getNode());
1644 else
1645 ScopeDIE = updateSubprogramScopeDIE(DS.getNode());
1646 }
Devang Patelaead63c2010-03-29 22:59:58 +00001647 else
Devang Patel3c91b052010-03-08 20:52:55 +00001648 ScopeDIE = constructLexicalScopeDIE(Scope);
Devang Patelaead63c2010-03-29 22:59:58 +00001649 if (!ScopeDIE) return NULL;
Devang Patel3c91b052010-03-08 20:52:55 +00001650
Devang Patel53bb5c92009-11-10 23:06:00 +00001651 // Add variables to scope.
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00001652 const SmallVector<DbgVariable *, 8> &Variables = Scope->getVariables();
Devang Patel53bb5c92009-11-10 23:06:00 +00001653 for (unsigned i = 0, N = Variables.size(); i < N; ++i) {
Devang Patel8a241142009-12-09 18:24:21 +00001654 DIE *VariableDIE = constructVariableDIE(Variables[i], Scope);
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001655 if (VariableDIE)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001656 ScopeDIE->addChild(VariableDIE);
Devang Patel53bb5c92009-11-10 23:06:00 +00001657 }
1658
1659 // Add nested scopes.
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00001660 const SmallVector<DbgScope *, 4> &Scopes = Scope->getScopes();
Devang Patel53bb5c92009-11-10 23:06:00 +00001661 for (unsigned j = 0, M = Scopes.size(); j < M; ++j) {
1662 // Define the Scope debug information entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001663 DIE *NestedDIE = constructScopeDIE(Scopes[j]);
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001664 if (NestedDIE)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001665 ScopeDIE->addChild(NestedDIE);
Devang Patel53bb5c92009-11-10 23:06:00 +00001666 }
Devang Patel193f7202009-11-24 01:14:22 +00001667
1668 if (DS.isSubprogram())
1669 addPubTypes(DISubprogram(DS.getNode()));
1670
1671 return ScopeDIE;
Devang Patel53bb5c92009-11-10 23:06:00 +00001672}
1673
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001674/// GetOrCreateSourceID - Look up the source id with the given directory and
1675/// source file names. If none currently exists, create a new id and insert it
1676/// in the SourceIds map. This can update DirectoryNames and SourceFileNames
1677/// maps as well.
Chris Lattner1d65ba72010-03-31 06:06:37 +00001678unsigned DwarfDebug::GetOrCreateSourceID(StringRef DirName, StringRef FileName){
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001679 unsigned DId;
1680 StringMap<unsigned>::iterator DI = DirectoryIdMap.find(DirName);
1681 if (DI != DirectoryIdMap.end()) {
1682 DId = DI->getValue();
1683 } else {
1684 DId = DirectoryNames.size() + 1;
1685 DirectoryIdMap[DirName] = DId;
1686 DirectoryNames.push_back(DirName);
1687 }
1688
1689 unsigned FId;
1690 StringMap<unsigned>::iterator FI = SourceFileIdMap.find(FileName);
1691 if (FI != SourceFileIdMap.end()) {
1692 FId = FI->getValue();
1693 } else {
1694 FId = SourceFileNames.size() + 1;
1695 SourceFileIdMap[FileName] = FId;
1696 SourceFileNames.push_back(FileName);
1697 }
1698
1699 DenseMap<std::pair<unsigned, unsigned>, unsigned>::iterator SI =
1700 SourceIdMap.find(std::make_pair(DId, FId));
1701 if (SI != SourceIdMap.end())
1702 return SI->second;
1703
1704 unsigned SrcId = SourceIds.size() + 1; // DW_AT_decl_file cannot be 0.
1705 SourceIdMap[std::make_pair(DId, FId)] = SrcId;
1706 SourceIds.push_back(std::make_pair(DId, FId));
1707
1708 return SrcId;
1709}
1710
Devang Patel6404e4e2009-12-15 19:16:48 +00001711/// getOrCreateNameSpace - Create a DIE for DINameSpace.
1712DIE *DwarfDebug::getOrCreateNameSpace(DINameSpace NS) {
1713 DIE *NDie = ModuleCU->getDIE(NS.getNode());
1714 if (NDie)
1715 return NDie;
1716 NDie = new DIE(dwarf::DW_TAG_namespace);
1717 ModuleCU->insertDIE(NS.getNode(), NDie);
1718 if (!NS.getName().empty())
1719 addString(NDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, NS.getName());
1720 addSourceLine(NDie, &NS);
1721 addToContextOwner(NDie, NS.getContext());
1722 return NDie;
1723}
1724
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +00001725void DwarfDebug::constructCompileUnit(MDNode *N) {
Devang Patele4b27562009-08-28 23:24:31 +00001726 DICompileUnit DIUnit(N);
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +00001727 // Use first compile unit marked as isMain as the compile unit for this
1728 // module.
1729 if (ModuleCU || !DIUnit.isMain())
1730 return;
Devang Patel65dbc902009-11-25 17:36:49 +00001731 StringRef FN = DIUnit.getFilename();
1732 StringRef Dir = DIUnit.getDirectory();
Devang Patel5ccdd102009-09-29 18:40:58 +00001733 unsigned ID = GetOrCreateSourceID(Dir, FN);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001734
1735 DIE *Die = new DIE(dwarf::DW_TAG_compile_unit);
Devang Patel2c4ceb12009-11-21 02:48:08 +00001736 addString(Die, dwarf::DW_AT_producer, dwarf::DW_FORM_string,
Devang Patel5ccdd102009-09-29 18:40:58 +00001737 DIUnit.getProducer());
Devang Patel2c4ceb12009-11-21 02:48:08 +00001738 addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data1,
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001739 DIUnit.getLanguage());
Devang Patel2c4ceb12009-11-21 02:48:08 +00001740 addString(Die, dwarf::DW_AT_name, dwarf::DW_FORM_string, FN);
Chris Lattner9c69e285532010-04-04 22:59:04 +00001741 addLabel(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, TextSectionSym);
Devang Patel4a602ca2010-03-22 23:11:36 +00001742 addLabel(Die, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
Chris Lattnerc0215722010-04-04 19:25:43 +00001743 Asm->GetTempSymbol("text_end"));
Devang Patel4a602ca2010-03-22 23:11:36 +00001744 // DW_AT_stmt_list is a offset of line number information for this
1745 // compile unit in debug_line section. It is always zero when only one
1746 // compile unit is emitted in one object file.
1747 addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001748
Devang Patel65dbc902009-11-25 17:36:49 +00001749 if (!Dir.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001750 addString(Die, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string, Dir);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001751 if (DIUnit.isOptimized())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001752 addUInt(Die, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001753
Devang Patel65dbc902009-11-25 17:36:49 +00001754 StringRef Flags = DIUnit.getFlags();
1755 if (!Flags.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001756 addString(Die, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string, Flags);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001757
1758 unsigned RVer = DIUnit.getRunTimeVersion();
1759 if (RVer)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001760 addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001761 dwarf::DW_FORM_data1, RVer);
1762
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +00001763 assert(!ModuleCU &&
1764 "ModuleCU assigned since the top of constructCompileUnit");
1765 ModuleCU = new CompileUnit(ID, Die);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001766}
1767
Devang Patel2c4ceb12009-11-21 02:48:08 +00001768void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
Devang Patele4b27562009-08-28 23:24:31 +00001769 DIGlobalVariable DI_GV(N);
Daniel Dunbarf612ff62009-09-19 20:40:05 +00001770
Devang Patel905cf5e2009-09-04 23:59:07 +00001771 // If debug information is malformed then ignore it.
1772 if (DI_GV.Verify() == false)
1773 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001774
1775 // Check for pre-existence.
Devang Patel017d1212009-11-20 21:37:22 +00001776 if (ModuleCU->getDIE(DI_GV.getNode()))
Devang Patel13e16b62009-06-26 01:49:18 +00001777 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001778
Devang Patel8a241142009-12-09 18:24:21 +00001779 DIE *VariableDie = createGlobalVariableDIE(DI_GV);
Devang Pateledb45632009-12-10 23:25:41 +00001780 if (!VariableDie)
1781 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001782
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001783 // Add to map.
Devang Patel017d1212009-11-20 21:37:22 +00001784 ModuleCU->insertDIE(N, VariableDie);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001785
1786 // Add to context owner.
Devang Patelc9b16cc2010-01-15 01:12:22 +00001787 DIDescriptor GVContext = DI_GV.getContext();
1788 // Do not create specification DIE if context is either compile unit
1789 // or a subprogram.
Chris Lattner1d65ba72010-03-31 06:06:37 +00001790 if (DI_GV.isDefinition() && !GVContext.isCompileUnit() &&
Devang Patel5f094002010-04-06 23:53:48 +00001791 !GVContext.isFile() &&
1792 !isSubprogramContext(GVContext.getNode())) {
Devang Patel6404e4e2009-12-15 19:16:48 +00001793 // Create specification DIE.
1794 DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
1795 addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
1796 dwarf::DW_FORM_ref4, VariableDie);
Benjamin Kramer345ef342010-03-31 19:34:01 +00001797 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel6404e4e2009-12-15 19:16:48 +00001798 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
Chris Lattner4faf59a2010-03-08 22:31:46 +00001799 addLabel(Block, 0, dwarf::DW_FORM_udata,
Chris Lattnerdeb0cba2010-03-12 21:09:07 +00001800 Asm->Mang->getSymbol(DI_GV.getGlobal()));
Devang Patel6404e4e2009-12-15 19:16:48 +00001801 addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
Devang Patel8581e012010-02-09 01:58:33 +00001802 addUInt(VariableDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
Devang Patel6404e4e2009-12-15 19:16:48 +00001803 ModuleCU->addDie(VariableSpecDIE);
1804 } else {
Benjamin Kramer345ef342010-03-31 19:34:01 +00001805 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel6404e4e2009-12-15 19:16:48 +00001806 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
Chris Lattner4faf59a2010-03-08 22:31:46 +00001807 addLabel(Block, 0, dwarf::DW_FORM_udata,
Chris Lattnerdeb0cba2010-03-12 21:09:07 +00001808 Asm->Mang->getSymbol(DI_GV.getGlobal()));
Devang Patel6404e4e2009-12-15 19:16:48 +00001809 addBlock(VariableDie, dwarf::DW_AT_location, 0, Block);
1810 }
Devang Patelc9b16cc2010-01-15 01:12:22 +00001811 addToContextOwner(VariableDie, GVContext);
Devang Patelc366f832009-12-10 19:14:49 +00001812
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001813 // Expose as global. FIXME - need to check external flag.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001814 ModuleCU->addGlobal(DI_GV.getName(), VariableDie);
Devang Patel193f7202009-11-24 01:14:22 +00001815
1816 DIType GTy = DI_GV.getType();
Devang Patel50d80e32010-04-13 20:35:04 +00001817 if (GTy.isCompositeType() && !GTy.getName().empty()
1818 && !GTy.isForwardDecl()) {
Devang Patel193f7202009-11-24 01:14:22 +00001819 DIEEntry *Entry = ModuleCU->getDIEEntry(GTy.getNode());
Chris Lattnered7a77b2010-03-31 05:36:29 +00001820 assert(Entry && "Missing global type!");
Devang Patel193f7202009-11-24 01:14:22 +00001821 ModuleCU->addGlobalType(GTy.getName(), Entry->getEntry());
1822 }
Devang Patel13e16b62009-06-26 01:49:18 +00001823 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001824}
1825
Devang Patel2c4ceb12009-11-21 02:48:08 +00001826void DwarfDebug::constructSubprogramDIE(MDNode *N) {
Devang Patele4b27562009-08-28 23:24:31 +00001827 DISubprogram SP(N);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001828
Stuart Hastings639336e2010-04-06 21:38:29 +00001829 // Check for pre-existence.
1830 if (ModuleCU->getDIE(N))
1831 return;
1832
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001833 if (!SP.isDefinition())
1834 // This is a method declaration which will be handled while constructing
1835 // class type.
Devang Patel13e16b62009-06-26 01:49:18 +00001836 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001837
Stuart Hastings639336e2010-04-06 21:38:29 +00001838 DIE *SubprogramDie = createSubprogramDIE(SP);
1839
1840 // Add to map.
1841 ModuleCU->insertDIE(N, SubprogramDie);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001842
1843 // Add to context owner.
Devang Patel6404e4e2009-12-15 19:16:48 +00001844 addToContextOwner(SubprogramDie, SP.getContext());
Devang Patel0000fad2009-12-08 23:21:45 +00001845
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001846 // Expose as global.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001847 ModuleCU->addGlobal(SP.getName(), SubprogramDie);
Devang Patel193f7202009-11-24 01:14:22 +00001848
Devang Patel13e16b62009-06-26 01:49:18 +00001849 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001850}
1851
Devang Patel2c4ceb12009-11-21 02:48:08 +00001852/// beginModule - Emit all Dwarf sections that should come prior to the
Daniel Dunbar00564992009-09-19 20:40:14 +00001853/// content. Create global DIEs and emit initial debug info sections.
1854/// This is inovked by the target AsmPrinter.
Chris Lattner75f50722010-04-04 07:48:20 +00001855void DwarfDebug::beginModule(Module *M) {
Devang Patel708e4742010-04-21 19:08:53 +00001856 if (DisableDebugInfoPrinting)
1857 return;
1858
Devang Patel78ab9e22009-07-30 18:56:46 +00001859 DebugInfoFinder DbgFinder;
1860 DbgFinder.processModule(*M);
Devang Patel13e16b62009-06-26 01:49:18 +00001861
Chris Lattnerd850ac72010-04-05 02:19:28 +00001862 bool HasDebugInfo = false;
1863
1864 // Scan all the compile-units to see if there are any marked as the main unit.
1865 // if not, we do not generate debug info.
1866 for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(),
1867 E = DbgFinder.compile_unit_end(); I != E; ++I) {
1868 if (DICompileUnit(*I).isMain()) {
1869 HasDebugInfo = true;
1870 break;
1871 }
1872 }
1873
1874 if (!HasDebugInfo) return;
1875
1876 // Tell MMI that we have debug info.
1877 MMI->setDebugInfoAvailability(true);
1878
Chris Lattnerbe15beb2010-04-04 23:17:54 +00001879 // Emit initial sections.
Chris Lattnerd850ac72010-04-05 02:19:28 +00001880 EmitSectionLabels();
Chris Lattnerbe15beb2010-04-04 23:17:54 +00001881
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001882 // Create all the compile unit DIEs.
Devang Patel78ab9e22009-07-30 18:56:46 +00001883 for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(),
1884 E = DbgFinder.compile_unit_end(); I != E; ++I)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001885 constructCompileUnit(*I);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001886
Devang Patel53bb5c92009-11-10 23:06:00 +00001887 // Create DIEs for each subprogram.
Devang Patel78ab9e22009-07-30 18:56:46 +00001888 for (DebugInfoFinder::iterator I = DbgFinder.subprogram_begin(),
1889 E = DbgFinder.subprogram_end(); I != E; ++I)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001890 constructSubprogramDIE(*I);
Devang Patel13e16b62009-06-26 01:49:18 +00001891
Devang Patelc366f832009-12-10 19:14:49 +00001892 // Create DIEs for each global variable.
1893 for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(),
1894 E = DbgFinder.global_variable_end(); I != E; ++I)
1895 constructGlobalVariableDIE(*I);
1896
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001897 // Prime section data.
Chris Lattnerf0144122009-07-28 03:13:23 +00001898 SectionMap.insert(Asm->getObjFileLowering().getTextSection());
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001899
1900 // Print out .file directives to specify files for .loc directives. These are
1901 // printed out early so that they precede any .loc directives.
Chris Lattnerd38fee82010-04-05 00:13:49 +00001902 if (Asm->MAI->hasDotLocAndDotFile()) {
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001903 for (unsigned i = 1, e = getNumSourceIds()+1; i != e; ++i) {
1904 // Remember source id starts at 1.
1905 std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(i);
Chris Lattner0ad9c912010-01-22 22:09:00 +00001906 // FIXME: don't use sys::path for this! This should not depend on the
1907 // host.
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001908 sys::Path FullPath(getSourceDirectoryName(Id.first));
1909 bool AppendOk =
1910 FullPath.appendComponent(getSourceFileName(Id.second));
1911 assert(AppendOk && "Could not append filename to directory!");
1912 AppendOk = false;
Chris Lattnera6594fc2010-01-25 18:58:59 +00001913 Asm->OutStreamer.EmitDwarfFileDirective(i, FullPath.str());
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001914 }
1915 }
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001916}
1917
Devang Patel2c4ceb12009-11-21 02:48:08 +00001918/// endModule - Emit all Dwarf sections that should come after the content.
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001919///
Devang Patel2c4ceb12009-11-21 02:48:08 +00001920void DwarfDebug::endModule() {
Bill Wendling5f017e82010-04-07 09:28:04 +00001921 if (!ModuleCU) return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001922
Devang Patel53bb5c92009-11-10 23:06:00 +00001923 // Attach DW_AT_inline attribute with inlined subprogram DIEs.
1924 for (SmallPtrSet<DIE *, 4>::iterator AI = InlinedSubprogramDIEs.begin(),
1925 AE = InlinedSubprogramDIEs.end(); AI != AE; ++AI) {
1926 DIE *ISP = *AI;
Devang Patel2c4ceb12009-11-21 02:48:08 +00001927 addUInt(ISP, dwarf::DW_AT_inline, 0, dwarf::DW_INL_inlined);
Devang Patel53bb5c92009-11-10 23:06:00 +00001928 }
1929
Devang Patel622b0262010-01-19 06:19:05 +00001930 for (DenseMap<DIE *, MDNode *>::iterator CI = ContainingTypeMap.begin(),
Devang Patel5d11eb02009-12-03 19:11:07 +00001931 CE = ContainingTypeMap.end(); CI != CE; ++CI) {
1932 DIE *SPDie = CI->first;
1933 MDNode *N = dyn_cast_or_null<MDNode>(CI->second);
1934 if (!N) continue;
1935 DIE *NDie = ModuleCU->getDIE(N);
1936 if (!NDie) continue;
1937 addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
Devang Patel5d11eb02009-12-03 19:11:07 +00001938 }
1939
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001940 // Standard sections final addresses.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00001941 Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getTextSection());
Chris Lattnerc0215722010-04-04 19:25:43 +00001942 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("text_end"));
Chris Lattner6c2f9e12009-08-19 05:49:37 +00001943 Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getDataSection());
Chris Lattnerc0215722010-04-04 19:25:43 +00001944 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("data_end"));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001945
1946 // End text sections.
1947 for (unsigned i = 1, N = SectionMap.size(); i <= N; ++i) {
Chris Lattner6c2f9e12009-08-19 05:49:37 +00001948 Asm->OutStreamer.SwitchSection(SectionMap[i]);
Chris Lattnerc0215722010-04-04 19:25:43 +00001949 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_end", i));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001950 }
1951
1952 // Emit common frame information.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001953 emitCommonDebugFrame();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001954
1955 // Emit function debug frame information
1956 for (std::vector<FunctionDebugFrameInfo>::iterator I = DebugFrames.begin(),
1957 E = DebugFrames.end(); I != E; ++I)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001958 emitFunctionDebugFrame(*I);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001959
1960 // Compute DIE offsets and sizes.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001961 computeSizeAndOffsets();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001962
1963 // Emit all the DIEs into a debug info section
Devang Patel2c4ceb12009-11-21 02:48:08 +00001964 emitDebugInfo();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001965
1966 // Corresponding abbreviations into a abbrev section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001967 emitAbbreviations();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001968
1969 // Emit source line correspondence into a debug line section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001970 emitDebugLines();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001971
1972 // Emit info into a debug pubnames section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001973 emitDebugPubNames();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001974
Devang Patel193f7202009-11-24 01:14:22 +00001975 // Emit info into a debug pubtypes section.
1976 emitDebugPubTypes();
1977
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001978 // Emit info into a debug loc section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001979 emitDebugLoc();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001980
1981 // Emit info into a debug aranges section.
1982 EmitDebugARanges();
1983
1984 // Emit info into a debug ranges section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001985 emitDebugRanges();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001986
1987 // Emit info into a debug macinfo section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001988 emitDebugMacInfo();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001989
1990 // Emit inline info.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001991 emitDebugInlineInfo();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001992
Chris Lattnerbc733f52010-03-13 02:17:42 +00001993 // Emit info into a debug str section.
1994 emitDebugStr();
1995
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +00001996 delete ModuleCU;
1997 ModuleCU = NULL; // Reset for the next Module, if any.
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001998}
1999
Devang Patel53bb5c92009-11-10 23:06:00 +00002000/// findAbstractVariable - Find abstract variable, if any, associated with Var.
Jim Grosbach7ab38df2009-11-22 19:20:36 +00002001DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
2002 unsigned FrameIdx,
Chris Lattnerde4845c2010-04-02 19:42:39 +00002003 DebugLoc ScopeLoc) {
Devang Patel53bb5c92009-11-10 23:06:00 +00002004
2005 DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var.getNode());
2006 if (AbsDbgVariable)
2007 return AbsDbgVariable;
2008
Chris Lattnerde4845c2010-04-02 19:42:39 +00002009 LLVMContext &Ctx = Var.getNode()->getContext();
2010 DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope(Ctx));
Devang Patel53bb5c92009-11-10 23:06:00 +00002011 if (!Scope)
2012 return NULL;
2013
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002014 AbsDbgVariable = new DbgVariable(Var, FrameIdx,
2015 NULL /* No more-abstract variable*/);
Devang Patel2c4ceb12009-11-21 02:48:08 +00002016 Scope->addVariable(AbsDbgVariable);
Devang Patel53bb5c92009-11-10 23:06:00 +00002017 AbstractVariables[Var.getNode()] = AbsDbgVariable;
2018 return AbsDbgVariable;
2019}
2020
Devang Patel90a48ad2010-03-15 18:33:46 +00002021/// findAbstractVariable - Find abstract variable, if any, associated with Var.
2022/// FIXME : Refactor findAbstractVariable.
2023DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
2024 const MachineInstr *MI,
Chris Lattnerde4845c2010-04-02 19:42:39 +00002025 DebugLoc ScopeLoc) {
Devang Patel90a48ad2010-03-15 18:33:46 +00002026
2027 DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var.getNode());
2028 if (AbsDbgVariable)
2029 return AbsDbgVariable;
2030
Chris Lattnerde4845c2010-04-02 19:42:39 +00002031 LLVMContext &Ctx = Var.getNode()->getContext();
2032 DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope(Ctx));
Devang Patel90a48ad2010-03-15 18:33:46 +00002033 if (!Scope)
2034 return NULL;
2035
Devang Patelaead63c2010-03-29 22:59:58 +00002036 AbsDbgVariable = new DbgVariable(Var, MI,
Devang Patel90a48ad2010-03-15 18:33:46 +00002037 NULL /* No more-abstract variable*/);
2038 Scope->addVariable(AbsDbgVariable);
2039 AbstractVariables[Var.getNode()] = AbsDbgVariable;
Devang Patelaead63c2010-03-29 22:59:58 +00002040 DbgValueStartMap[MI] = AbsDbgVariable;
Devang Patel90a48ad2010-03-15 18:33:46 +00002041 return AbsDbgVariable;
2042}
2043
Devang Patel2c4ceb12009-11-21 02:48:08 +00002044/// collectVariableInfo - Populate DbgScope entries with variables' info.
2045void DwarfDebug::collectVariableInfo() {
Chris Lattnerd38fee82010-04-05 00:13:49 +00002046 const LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
Chris Lattnerde4845c2010-04-02 19:42:39 +00002047
Devang Patele717faa2009-10-06 01:26:37 +00002048 MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo();
2049 for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(),
2050 VE = VMap.end(); VI != VE; ++VI) {
Devang Patelbc5201f2010-01-22 22:52:10 +00002051 MDNode *Var = VI->first;
Devang Patel53bb5c92009-11-10 23:06:00 +00002052 if (!Var) continue;
Chris Lattnerde4845c2010-04-02 19:42:39 +00002053 DIVariable DV(Var);
2054 const std::pair<unsigned, DebugLoc> &VP = VI->second;
Devang Patel53bb5c92009-11-10 23:06:00 +00002055
Chris Lattnerde4845c2010-04-02 19:42:39 +00002056 DbgScope *Scope = 0;
2057 if (MDNode *IA = VP.second.getInlinedAt(Ctx))
2058 Scope = ConcreteScopes.lookup(IA);
2059 if (Scope == 0)
2060 Scope = DbgScopeMap.lookup(VP.second.getScope(Ctx));
2061
Devang Patelfb0ee432009-11-10 23:20:04 +00002062 // If variable scope is not found then skip this variable.
Chris Lattnerde4845c2010-04-02 19:42:39 +00002063 if (Scope == 0)
Devang Patelfb0ee432009-11-10 23:20:04 +00002064 continue;
Devang Patel53bb5c92009-11-10 23:06:00 +00002065
Chris Lattnerde4845c2010-04-02 19:42:39 +00002066 DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VP.first, VP.second);
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002067 DbgVariable *RegVar = new DbgVariable(DV, VP.first, AbsDbgVariable);
Devang Patel2c4ceb12009-11-21 02:48:08 +00002068 Scope->addVariable(RegVar);
Devang Patele717faa2009-10-06 01:26:37 +00002069 }
Devang Patel90a48ad2010-03-15 18:33:46 +00002070
2071 // Collect variable information from DBG_VALUE machine instructions;
Chris Lattnerd38fee82010-04-05 00:13:49 +00002072 for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
Devang Patel90a48ad2010-03-15 18:33:46 +00002073 I != E; ++I) {
2074 for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
2075 II != IE; ++II) {
2076 const MachineInstr *MInsn = II;
Chris Lattner14d750d2010-03-31 05:39:57 +00002077 if (!MInsn->isDebugValue())
Devang Patel90a48ad2010-03-15 18:33:46 +00002078 continue;
Devang Patelaead63c2010-03-29 22:59:58 +00002079
Devang Patel90a48ad2010-03-15 18:33:46 +00002080 // FIXME : Lift this restriction.
2081 if (MInsn->getNumOperands() != 3)
2082 continue;
Dan Gohman82d5eaf2010-04-17 16:43:55 +00002083 DIVariable DV(
2084 const_cast<MDNode *>(MInsn->getOperand(MInsn->getNumOperands() - 1)
2085 .getMetadata()));
Devang Patel90a48ad2010-03-15 18:33:46 +00002086 if (DV.getTag() == dwarf::DW_TAG_arg_variable) {
2087 // FIXME Handle inlined subroutine arguments.
2088 DbgVariable *ArgVar = new DbgVariable(DV, MInsn, NULL);
2089 CurrentFnDbgScope->addVariable(ArgVar);
Devang Patelaead63c2010-03-29 22:59:58 +00002090 DbgValueStartMap[MInsn] = ArgVar;
Devang Patel90a48ad2010-03-15 18:33:46 +00002091 continue;
2092 }
2093
2094 DebugLoc DL = MInsn->getDebugLoc();
2095 if (DL.isUnknown()) continue;
Chris Lattnerde4845c2010-04-02 19:42:39 +00002096 DbgScope *Scope = 0;
2097 if (MDNode *IA = DL.getInlinedAt(Ctx))
2098 Scope = ConcreteScopes.lookup(IA);
2099 if (Scope == 0)
2100 Scope = DbgScopeMap.lookup(DL.getScope(Ctx));
2101
Devang Patel90a48ad2010-03-15 18:33:46 +00002102 // If variable scope is not found then skip this variable.
Chris Lattnerde4845c2010-04-02 19:42:39 +00002103 if (Scope == 0)
Devang Patel90a48ad2010-03-15 18:33:46 +00002104 continue;
2105
Chris Lattnerde4845c2010-04-02 19:42:39 +00002106 DbgVariable *AbsDbgVariable = findAbstractVariable(DV, MInsn, DL);
Devang Patel90a48ad2010-03-15 18:33:46 +00002107 DbgVariable *RegVar = new DbgVariable(DV, MInsn, AbsDbgVariable);
Devang Patelaead63c2010-03-29 22:59:58 +00002108 DbgValueStartMap[MInsn] = RegVar;
Devang Patel90a48ad2010-03-15 18:33:46 +00002109 Scope->addVariable(RegVar);
2110 }
2111 }
Devang Patele717faa2009-10-06 01:26:37 +00002112}
2113
Devang Patel553881b2010-03-29 17:20:31 +00002114/// beginScope - Process beginning of a scope.
2115void DwarfDebug::beginScope(const MachineInstr *MI) {
Devang Patel553881b2010-03-29 17:20:31 +00002116 // Check location.
2117 DebugLoc DL = MI->getDebugLoc();
2118 if (DL.isUnknown())
2119 return;
Devang Patel553881b2010-03-29 17:20:31 +00002120
Chris Lattnerd38fee82010-04-05 00:13:49 +00002121 MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext());
Chris Lattnerde4845c2010-04-02 19:42:39 +00002122
2123 // FIXME: Should only verify each scope once!
2124 if (!DIScope(Scope).Verify())
Devang Patel553881b2010-03-29 17:20:31 +00002125 return;
Devang Patel553881b2010-03-29 17:20:31 +00002126
Devang Patelaead63c2010-03-29 22:59:58 +00002127 // DBG_VALUE instruction establishes new value.
Chris Lattner14d750d2010-03-31 05:39:57 +00002128 if (MI->isDebugValue()) {
Devang Patelaead63c2010-03-29 22:59:58 +00002129 DenseMap<const MachineInstr *, DbgVariable *>::iterator DI
2130 = DbgValueStartMap.find(MI);
2131 if (DI != DbgValueStartMap.end()) {
Devang Patel9cdb4102010-04-21 16:32:19 +00002132 MCSymbol *Label = NULL;
2133 if (DL == PrevInstLoc)
2134 Label = PrevLabel;
2135 else {
2136 Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
2137 PrevInstLoc = DL;
2138 PrevLabel = Label;
2139 }
Devang Patelaead63c2010-03-29 22:59:58 +00002140 DI->second->setDbgValueLabel(Label);
2141 }
Devang Patel7ed63112010-03-30 18:07:00 +00002142 return;
Devang Patelaead63c2010-03-29 22:59:58 +00002143 }
2144
Devang Patel553881b2010-03-29 17:20:31 +00002145 // Emit a label to indicate location change. This is used for line
Devang Patel9cdb4102010-04-21 16:32:19 +00002146 // table even if this instruction does not start a new scope.
2147 MCSymbol *Label = NULL;
2148 if (DL == PrevInstLoc)
2149 Label = PrevLabel;
2150 else {
2151 Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
2152 PrevInstLoc = DL;
2153 PrevLabel = Label;
2154 }
Devang Patel553881b2010-03-29 17:20:31 +00002155
Devang Patel1c246352010-04-08 16:50:29 +00002156 // If this instruction begins a scope then note down corresponding label.
2157 if (InsnsBeginScopeSet.count(MI) != 0)
2158 InsnBeforeLabelMap[MI] = Label;
Devang Patel0d20ac82009-10-06 01:50:42 +00002159}
2160
Devang Patel2c4ceb12009-11-21 02:48:08 +00002161/// endScope - Process end of a scope.
2162void DwarfDebug::endScope(const MachineInstr *MI) {
Devang Patel1c246352010-04-08 16:50:29 +00002163 if (InsnsEndScopeSet.count(MI) != 0) {
2164 // Emit a label if this instruction ends a scope.
2165 MCSymbol *Label = MMI->getContext().CreateTempSymbol();
2166 Asm->OutStreamer.EmitLabel(Label);
2167 InsnAfterLabelMap[MI] = Label;
2168 }
Devang Patel53bb5c92009-11-10 23:06:00 +00002169}
2170
Devang Patel9cdb4102010-04-21 16:32:19 +00002171/// getOrCreateDbgScope - Create DbgScope for the scope.
2172DbgScope *DwarfDebug::getOrCreateDbgScope(MDNode *Scope, MDNode *InlinedAt) {
Devang Patel53bb5c92009-11-10 23:06:00 +00002173 if (!InlinedAt) {
2174 DbgScope *WScope = DbgScopeMap.lookup(Scope);
2175 if (WScope)
Devang Patel9cdb4102010-04-21 16:32:19 +00002176 return WScope;
Devang Patel53bb5c92009-11-10 23:06:00 +00002177 WScope = new DbgScope(NULL, DIDescriptor(Scope), NULL);
2178 DbgScopeMap.insert(std::make_pair(Scope, WScope));
Devang Patel9cdb4102010-04-21 16:32:19 +00002179 if (DIDescriptor(Scope).isLexicalBlock()) {
2180 DbgScope *Parent =
2181 getOrCreateDbgScope(DILexicalBlock(Scope).getContext().getNode(), NULL);
2182 WScope->setParent(Parent);
2183 Parent->addScope(WScope);
2184 }
2185
2186 if (!WScope->getParent()) {
2187 StringRef SPName = DISubprogram(Scope).getLinkageName();
2188 if (SPName == Asm->MF->getFunction()->getName())
2189 CurrentFnDbgScope = WScope;
2190 }
2191
2192 return WScope;
Devang Patel53bb5c92009-11-10 23:06:00 +00002193 }
2194
2195 DbgScope *WScope = DbgScopeMap.lookup(InlinedAt);
2196 if (WScope)
Devang Patel9cdb4102010-04-21 16:32:19 +00002197 return WScope;
Devang Patel53bb5c92009-11-10 23:06:00 +00002198
2199 WScope = new DbgScope(NULL, DIDescriptor(Scope), InlinedAt);
2200 DbgScopeMap.insert(std::make_pair(InlinedAt, WScope));
2201 DILocation DL(InlinedAt);
Devang Patel9cdb4102010-04-21 16:32:19 +00002202 DbgScope *Parent =
2203 getOrCreateDbgScope(DL.getScope().getNode(), DL.getOrigLocation().getNode());
2204 WScope->setParent(Parent);
2205 Parent->addScope(WScope);
2206
2207 ConcreteScopes[InlinedAt] = WScope;
2208 getOrCreateAbstractScope(Scope);
2209
2210 return WScope;
Devang Patel0d20ac82009-10-06 01:50:42 +00002211}
2212
Devang Patel9cdb4102010-04-21 16:32:19 +00002213/// hasValidLocation - Return true if debug location entry attached with
2214/// machine instruction encodes valid location info.
2215static bool hasValidLocation(LLVMContext &Ctx,
2216 const MachineInstr *MInsn,
2217 MDNode *&Scope, MDNode *&InlinedAt) {
2218 if (MInsn->isDebugValue())
2219 return false;
2220 DebugLoc DL = MInsn->getDebugLoc();
2221 if (DL.isUnknown()) return false;
2222
2223 MDNode *S = DL.getScope(Ctx);
2224
2225 // There is no need to create another DIE for compile unit. For all
2226 // other scopes, create one DbgScope now. This will be translated
2227 // into a scope DIE at the end.
2228 if (DIScope(S).isCompileUnit()) return false;
2229
2230 Scope = S;
2231 InlinedAt = DL.getInlinedAt(Ctx);
2232 return true;
2233}
2234
2235/// calculateDominanceGraph - Calculate dominance graph for DbgScope
2236/// hierarchy.
2237static void calculateDominanceGraph(DbgScope *Scope) {
2238 assert (Scope && "Unable to calculate scop edominance graph!");
2239 SmallVector<DbgScope *, 4> WorkStack;
2240 WorkStack.push_back(Scope);
2241 unsigned Counter = 0;
2242 while (!WorkStack.empty()) {
2243 DbgScope *WS = WorkStack.back();
2244 const SmallVector<DbgScope *, 4> &Children = WS->getScopes();
2245 bool visitedChildren = false;
2246 for (SmallVector<DbgScope *, 4>::const_iterator SI = Children.begin(),
2247 SE = Children.end(); SI != SE; ++SI) {
2248 DbgScope *ChildScope = *SI;
2249 if (!ChildScope->getDFSOut()) {
2250 WorkStack.push_back(ChildScope);
2251 visitedChildren = true;
2252 ChildScope->setDFSIn(++Counter);
2253 break;
2254 }
2255 }
2256 if (!visitedChildren) {
2257 WorkStack.pop_back();
2258 WS->setDFSOut(++Counter);
2259 }
2260 }
2261}
2262
2263/// printDbgScopeInfo - Print DbgScope info for each machine instruction.
2264static
2265void printDbgScopeInfo(LLVMContext &Ctx, const MachineFunction *MF,
2266 DenseMap<const MachineInstr *, DbgScope *> &MI2ScopeMap)
2267{
2268#ifndef NDEBUG
2269 unsigned PrevDFSIn = 0;
2270 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
2271 I != E; ++I) {
2272 for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
2273 II != IE; ++II) {
2274 const MachineInstr *MInsn = II;
2275 MDNode *Scope = NULL;
2276 MDNode *InlinedAt = NULL;
2277
2278 // Check if instruction has valid location information.
2279 if (hasValidLocation(Ctx, MInsn, Scope, InlinedAt)) {
2280 dbgs() << " [ ";
2281 if (InlinedAt)
2282 dbgs() << "*";
2283 DenseMap<const MachineInstr *, DbgScope *>::iterator DI =
2284 MI2ScopeMap.find(MInsn);
2285 if (DI != MI2ScopeMap.end()) {
2286 DbgScope *S = DI->second;
2287 dbgs() << S->getDFSIn();
2288 PrevDFSIn = S->getDFSIn();
2289 } else
2290 dbgs() << PrevDFSIn;
2291 } else
2292 dbgs() << " [ x" << PrevDFSIn;
2293 dbgs() << " ]";
2294 MInsn->dump();
2295 }
2296 dbgs() << "\n";
2297 }
2298#endif
2299}
Devang Patel2c4ceb12009-11-21 02:48:08 +00002300/// extractScopeInformation - Scan machine instructions in this function
Chris Lattner14d750d2010-03-31 05:39:57 +00002301/// and collect DbgScopes. Return true, if at least one scope was found.
Chris Lattnereec791a2010-01-26 23:18:02 +00002302bool DwarfDebug::extractScopeInformation() {
Devang Patelaf9e8472009-10-01 20:31:14 +00002303 // If scope information was extracted using .dbg intrinsics then there is not
2304 // any need to extract these information by scanning each instruction.
2305 if (!DbgScopeMap.empty())
2306 return false;
2307
Devang Patel53bb5c92009-11-10 23:06:00 +00002308 // Scan each instruction and create scopes. First build working set of scopes.
Devang Patel9cdb4102010-04-21 16:32:19 +00002309 LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
2310 SmallVector<DbgRange, 4> MIRanges;
2311 DenseMap<const MachineInstr *, DbgScope *> MI2ScopeMap;
2312 MDNode *PrevScope = NULL;
2313 MDNode *PrevInlinedAt = NULL;
2314 const MachineInstr *RangeBeginMI = NULL;
2315 const MachineInstr *PrevMI = NULL;
Chris Lattnerd38fee82010-04-05 00:13:49 +00002316 for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
Devang Patelaf9e8472009-10-01 20:31:14 +00002317 I != E; ++I) {
2318 for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
2319 II != IE; ++II) {
2320 const MachineInstr *MInsn = II;
Devang Patel9cdb4102010-04-21 16:32:19 +00002321 MDNode *Scope = NULL;
2322 MDNode *InlinedAt = NULL;
2323
2324 // Check if instruction has valid location information.
2325 if (!hasValidLocation(Ctx, MInsn, Scope, InlinedAt)) {
2326 PrevMI = MInsn;
2327 continue;
2328 }
Chris Lattnerde4845c2010-04-02 19:42:39 +00002329
Devang Patel9cdb4102010-04-21 16:32:19 +00002330 // If scope has not changed then skip this instruction.
2331 if (Scope == PrevScope && PrevInlinedAt == InlinedAt) {
2332 PrevMI = MInsn;
2333 continue;
2334 }
2335
2336 if (RangeBeginMI) {
2337 // If we have alread seen a beginning of a instruction range and
2338 // current instruction scope does not match scope of first instruction
2339 // in this range then create a new instruction range.
2340 DbgRange R(RangeBeginMI, PrevMI);
2341 MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevScope, PrevInlinedAt);
2342 MIRanges.push_back(R);
2343 }
2344
2345 // This is a beginning of a new instruction range.
2346 RangeBeginMI = MInsn;
Chris Lattnerde4845c2010-04-02 19:42:39 +00002347
Devang Patel9cdb4102010-04-21 16:32:19 +00002348 // Reset previous markers.
2349 PrevMI = MInsn;
2350 PrevScope = Scope;
2351 PrevInlinedAt = InlinedAt;
Devang Patel53bb5c92009-11-10 23:06:00 +00002352 }
2353 }
2354
Devang Patel9cdb4102010-04-21 16:32:19 +00002355 // Create last instruction range.
2356 if (RangeBeginMI && PrevMI && PrevScope) {
2357 DbgRange R(RangeBeginMI, PrevMI);
2358 MIRanges.push_back(R);
2359 MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevScope, PrevInlinedAt);
Devang Patelaf9e8472009-10-01 20:31:14 +00002360 }
Devang Patel9cdb4102010-04-21 16:32:19 +00002361
Devang Patel344130e2010-01-04 20:44:00 +00002362 if (!CurrentFnDbgScope)
2363 return false;
2364
Devang Patel9cdb4102010-04-21 16:32:19 +00002365 calculateDominanceGraph(CurrentFnDbgScope);
2366 if (PrintDbgScope)
2367 printDbgScopeInfo(Ctx, Asm->MF, MI2ScopeMap);
2368
2369 // Find ranges of instructions covered by each DbgScope;
2370 DbgScope *PrevDbgScope = NULL;
2371 for (SmallVector<DbgRange, 4>::const_iterator RI = MIRanges.begin(),
2372 RE = MIRanges.end(); RI != RE; ++RI) {
2373 const DbgRange &R = *RI;
2374 DbgScope *S = MI2ScopeMap.lookup(R.first);
2375 assert (S && "Lost DbgScope for a machine instruction!");
2376 if (PrevDbgScope && !PrevDbgScope->dominates(S))
2377 PrevDbgScope->closeInsnRange(S);
2378 S->openInsnRange(R.first);
2379 S->extendInsnRange(R.second);
2380 PrevDbgScope = S;
2381 }
2382
2383 if (PrevDbgScope)
2384 PrevDbgScope->closeInsnRange();
Devang Patelaf9e8472009-10-01 20:31:14 +00002385
Devang Patele37b0c62010-04-08 18:43:56 +00002386 identifyScopeMarkers();
Devang Patel6122a4d2010-04-08 15:37:09 +00002387
2388 return !DbgScopeMap.empty();
2389}
2390
Devang Patel9cdb4102010-04-21 16:32:19 +00002391/// identifyScopeMarkers() -
2392/// Each DbgScope has first instruction and last instruction to mark beginning
2393/// and end of a scope respectively. Create an inverse map that list scopes
2394/// starts (and ends) with an instruction. One instruction may start (or end)
2395/// multiple scopes. Ignore scopes that are not reachable.
Devang Patele37b0c62010-04-08 18:43:56 +00002396void DwarfDebug::identifyScopeMarkers() {
Devang Patel42aafd72010-01-20 02:05:23 +00002397 SmallVector<DbgScope *, 4> WorkList;
2398 WorkList.push_back(CurrentFnDbgScope);
2399 while (!WorkList.empty()) {
Chris Lattner14d750d2010-03-31 05:39:57 +00002400 DbgScope *S = WorkList.pop_back_val();
Devang Patel9cdb4102010-04-21 16:32:19 +00002401
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002402 const SmallVector<DbgScope *, 4> &Children = S->getScopes();
Devang Patel42aafd72010-01-20 02:05:23 +00002403 if (!Children.empty())
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002404 for (SmallVector<DbgScope *, 4>::const_iterator SI = Children.begin(),
Devang Patel42aafd72010-01-20 02:05:23 +00002405 SE = Children.end(); SI != SE; ++SI)
2406 WorkList.push_back(*SI);
2407
Devang Patel53bb5c92009-11-10 23:06:00 +00002408 if (S->isAbstractScope())
2409 continue;
Devang Patel9cdb4102010-04-21 16:32:19 +00002410
2411 const SmallVector<DbgRange, 4> &Ranges = S->getRanges();
2412 if (Ranges.empty())
2413 continue;
2414 for (SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin(),
2415 RE = Ranges.end(); RI != RE; ++RI) {
2416 assert(RI->first && "DbgRange does not have first instruction!");
2417 assert(RI->second && "DbgRange does not have second instruction!");
2418 InsnsBeginScopeSet.insert(RI->first);
2419 InsnsEndScopeSet.insert(RI->second);
2420 }
Devang Patelaf9e8472009-10-01 20:31:14 +00002421 }
Devang Patelaf9e8472009-10-01 20:31:14 +00002422}
2423
Dan Gohman084751c2010-04-20 00:37:27 +00002424/// FindFirstDebugLoc - Find the first debug location in the function. This
2425/// is intended to be an approximation for the source position of the
2426/// beginning of the function.
2427static DebugLoc FindFirstDebugLoc(const MachineFunction *MF) {
2428 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
2429 I != E; ++I)
2430 for (MachineBasicBlock::const_iterator MBBI = I->begin(), MBBE = I->end();
2431 MBBI != MBBE; ++MBBI) {
2432 DebugLoc DL = MBBI->getDebugLoc();
2433 if (!DL.isUnknown())
2434 return DL;
2435 }
2436 return DebugLoc();
2437}
2438
Devang Patel2c4ceb12009-11-21 02:48:08 +00002439/// beginFunction - Gather pre-function debug information. Assumes being
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002440/// emitted immediately after the function entry point.
Chris Lattnereec791a2010-01-26 23:18:02 +00002441void DwarfDebug::beginFunction(const MachineFunction *MF) {
Chris Lattner994cb122010-04-05 03:52:55 +00002442 if (!MMI->hasDebugInfo()) return;
Bill Wendling5f017e82010-04-07 09:28:04 +00002443 if (!extractScopeInformation()) return;
Chris Lattnera909d662010-03-29 20:38:20 +00002444
Devang Patel2c4ceb12009-11-21 02:48:08 +00002445 collectVariableInfo();
Devang Patel60b35bd2009-10-06 18:37:31 +00002446
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002447 // Assumes in correct section after the entry point.
Chris Lattnerc0215722010-04-04 19:25:43 +00002448 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("func_begin",
Chris Lattnerd38fee82010-04-05 00:13:49 +00002449 Asm->getFunctionNumber()));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002450
2451 // Emit label for the implicitly defined dbg.stoppoint at the start of the
2452 // function.
Dan Gohman084751c2010-04-20 00:37:27 +00002453 DebugLoc FDL = FindFirstDebugLoc(MF);
Chris Lattnerde4845c2010-04-02 19:42:39 +00002454 if (FDL.isUnknown()) return;
2455
2456 MDNode *Scope = FDL.getScope(MF->getFunction()->getContext());
2457
2458 DISubprogram SP = getDISubprogram(Scope);
2459 unsigned Line, Col;
2460 if (SP.Verify()) {
2461 Line = SP.getLineNumber();
2462 Col = 0;
2463 } else {
2464 Line = FDL.getLine();
2465 Col = FDL.getCol();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002466 }
Chris Lattnerde4845c2010-04-02 19:42:39 +00002467
2468 recordSourceLine(Line, Col, Scope);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002469}
2470
Devang Patel2c4ceb12009-11-21 02:48:08 +00002471/// endFunction - Gather and emit post-function debug information.
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002472///
Chris Lattnereec791a2010-01-26 23:18:02 +00002473void DwarfDebug::endFunction(const MachineFunction *MF) {
Bill Wendling5f017e82010-04-07 09:28:04 +00002474 if (!MMI->hasDebugInfo() || DbgScopeMap.empty()) return;
Devang Patel70d75ca2009-11-12 19:02:56 +00002475
Devang Patel344130e2010-01-04 20:44:00 +00002476 if (CurrentFnDbgScope) {
2477 // Define end label for subprogram.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002478 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("func_end",
2479 Asm->getFunctionNumber()));
Devang Patel344130e2010-01-04 20:44:00 +00002480
2481 // Get function line info.
2482 if (!Lines.empty()) {
2483 // Get section line info.
2484 unsigned ID = SectionMap.insert(Asm->getCurrentSection());
2485 if (SectionSourceLines.size() < ID) SectionSourceLines.resize(ID);
2486 std::vector<SrcLineInfo> &SectionLineInfos = SectionSourceLines[ID-1];
2487 // Append the function info to section info.
2488 SectionLineInfos.insert(SectionLineInfos.end(),
2489 Lines.begin(), Lines.end());
2490 }
2491
2492 // Construct abstract scopes.
2493 for (SmallVector<DbgScope *, 4>::iterator AI = AbstractScopesList.begin(),
2494 AE = AbstractScopesList.end(); AI != AE; ++AI)
2495 constructScopeDIE(*AI);
2496
2497 constructScopeDIE(CurrentFnDbgScope);
2498
Chris Lattnerd38fee82010-04-05 00:13:49 +00002499 DebugFrames.push_back(FunctionDebugFrameInfo(Asm->getFunctionNumber(),
Devang Patel344130e2010-01-04 20:44:00 +00002500 MMI->getFrameMoves()));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002501 }
2502
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002503 // Clear debug info
Devang Patelf54b8522010-01-19 01:26:02 +00002504 CurrentFnDbgScope = NULL;
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002505 DeleteContainerSeconds(DbgScopeMap);
Devang Patel51424712010-04-09 16:04:20 +00002506 InsnsBeginScopeSet.clear();
2507 InsnsEndScopeSet.clear();
Devang Patelaead63c2010-03-29 22:59:58 +00002508 DbgValueStartMap.clear();
Devang Patelf54b8522010-01-19 01:26:02 +00002509 ConcreteScopes.clear();
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002510 DeleteContainerSeconds(AbstractScopes);
Devang Patelf54b8522010-01-19 01:26:02 +00002511 AbstractScopesList.clear();
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002512 AbstractVariables.clear();
Devang Patel1d526c32010-04-14 01:18:28 +00002513 InsnBeforeLabelMap.clear();
2514 InsnAfterLabelMap.clear();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002515 Lines.clear();
Devang Patelf2548ca2010-04-16 23:33:45 +00002516 PrevLabel = NULL;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002517}
2518
Chris Lattnerc6087842010-03-09 04:54:43 +00002519/// recordSourceLine - Register a source line with debug info. Returns the
2520/// unique label that was emitted and which provides correspondence to
2521/// the source line list.
2522MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, MDNode *S) {
Devang Patel65dbc902009-11-25 17:36:49 +00002523 StringRef Dir;
2524 StringRef Fn;
Devang Patelf84548d2009-10-05 18:03:19 +00002525
2526 DIDescriptor Scope(S);
2527 if (Scope.isCompileUnit()) {
2528 DICompileUnit CU(S);
2529 Dir = CU.getDirectory();
2530 Fn = CU.getFilename();
2531 } else if (Scope.isSubprogram()) {
2532 DISubprogram SP(S);
2533 Dir = SP.getDirectory();
2534 Fn = SP.getFilename();
2535 } else if (Scope.isLexicalBlock()) {
2536 DILexicalBlock DB(S);
2537 Dir = DB.getDirectory();
2538 Fn = DB.getFilename();
2539 } else
Chris Lattner206d61e2010-03-13 07:26:18 +00002540 assert(0 && "Unexpected scope info");
Devang Patelf84548d2009-10-05 18:03:19 +00002541
2542 unsigned Src = GetOrCreateSourceID(Dir, Fn);
Chris Lattner63d78362010-03-14 08:36:50 +00002543 MCSymbol *Label = MMI->getContext().CreateTempSymbol();
Chris Lattner25b68c62010-03-14 08:15:55 +00002544 Lines.push_back(SrcLineInfo(Line, Col, Src, Label));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002545
Chris Lattnerc6087842010-03-09 04:54:43 +00002546 Asm->OutStreamer.EmitLabel(Label);
2547 return Label;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002548}
2549
Bill Wendling829e67b2009-05-20 23:22:40 +00002550//===----------------------------------------------------------------------===//
2551// Emit Methods
2552//===----------------------------------------------------------------------===//
2553
Devang Patel2c4ceb12009-11-21 02:48:08 +00002554/// computeSizeAndOffset - Compute the size and offset of a DIE.
Bill Wendling94d04b82009-05-20 23:21:38 +00002555///
Jim Grosbach7ab38df2009-11-22 19:20:36 +00002556unsigned
2557DwarfDebug::computeSizeAndOffset(DIE *Die, unsigned Offset, bool Last) {
Bill Wendling94d04b82009-05-20 23:21:38 +00002558 // Get the children.
2559 const std::vector<DIE *> &Children = Die->getChildren();
2560
2561 // If not last sibling and has children then add sibling offset attribute.
Jeffrey Yasskin638fe8d2010-03-22 18:47:14 +00002562 if (!Last && !Children.empty())
Benjamin Kramer345ef342010-03-31 19:34:01 +00002563 Die->addSiblingOffset(DIEValueAllocator);
Bill Wendling94d04b82009-05-20 23:21:38 +00002564
2565 // Record the abbreviation.
Devang Patel2c4ceb12009-11-21 02:48:08 +00002566 assignAbbrevNumber(Die->getAbbrev());
Bill Wendling94d04b82009-05-20 23:21:38 +00002567
2568 // Get the abbreviation for this DIE.
2569 unsigned AbbrevNumber = Die->getAbbrevNumber();
2570 const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1];
2571
2572 // Set DIE offset
2573 Die->setOffset(Offset);
2574
2575 // Start the size with the size of abbreviation code.
Chris Lattneraf76e592009-08-22 20:48:53 +00002576 Offset += MCAsmInfo::getULEB128Size(AbbrevNumber);
Bill Wendling94d04b82009-05-20 23:21:38 +00002577
2578 const SmallVector<DIEValue*, 32> &Values = Die->getValues();
2579 const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData();
2580
2581 // Size the DIE attribute values.
2582 for (unsigned i = 0, N = Values.size(); i < N; ++i)
2583 // Size attribute value.
Chris Lattnera37d5382010-04-05 00:18:22 +00002584 Offset += Values[i]->SizeOf(Asm, AbbrevData[i].getForm());
Bill Wendling94d04b82009-05-20 23:21:38 +00002585
2586 // Size the DIE children if any.
2587 if (!Children.empty()) {
2588 assert(Abbrev->getChildrenFlag() == dwarf::DW_CHILDREN_yes &&
2589 "Children flag not set");
2590
2591 for (unsigned j = 0, M = Children.size(); j < M; ++j)
Devang Patel2c4ceb12009-11-21 02:48:08 +00002592 Offset = computeSizeAndOffset(Children[j], Offset, (j + 1) == M);
Bill Wendling94d04b82009-05-20 23:21:38 +00002593
2594 // End of children marker.
2595 Offset += sizeof(int8_t);
2596 }
2597
2598 Die->setSize(Offset - Die->getOffset());
2599 return Offset;
2600}
2601
Devang Patel2c4ceb12009-11-21 02:48:08 +00002602/// computeSizeAndOffsets - Compute the size and offset of all the DIEs.
Bill Wendling94d04b82009-05-20 23:21:38 +00002603///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002604void DwarfDebug::computeSizeAndOffsets() {
Bill Wendling94d04b82009-05-20 23:21:38 +00002605 // Compute size of compile unit header.
2606 static unsigned Offset =
2607 sizeof(int32_t) + // Length of Compilation Unit Info
2608 sizeof(int16_t) + // DWARF version number
2609 sizeof(int32_t) + // Offset Into Abbrev. Section
2610 sizeof(int8_t); // Pointer Size (in bytes)
2611
Devang Patel2c4ceb12009-11-21 02:48:08 +00002612 computeSizeAndOffset(ModuleCU->getCUDie(), Offset, true);
Bill Wendling94d04b82009-05-20 23:21:38 +00002613}
2614
Chris Lattner11b8f302010-04-04 23:02:02 +00002615/// EmitSectionSym - Switch to the specified MCSection and emit an assembler
2616/// temporary label to it if SymbolStem is specified.
Chris Lattner9c69e285532010-04-04 22:59:04 +00002617static MCSymbol *EmitSectionSym(AsmPrinter *Asm, const MCSection *Section,
Chris Lattner11b8f302010-04-04 23:02:02 +00002618 const char *SymbolStem = 0) {
Chris Lattner9c69e285532010-04-04 22:59:04 +00002619 Asm->OutStreamer.SwitchSection(Section);
Chris Lattner11b8f302010-04-04 23:02:02 +00002620 if (!SymbolStem) return 0;
2621
Chris Lattner9c69e285532010-04-04 22:59:04 +00002622 MCSymbol *TmpSym = Asm->GetTempSymbol(SymbolStem);
2623 Asm->OutStreamer.EmitLabel(TmpSym);
2624 return TmpSym;
2625}
2626
2627/// EmitSectionLabels - Emit initial Dwarf sections with a label at
2628/// the start of each one.
Chris Lattnerfa070b02010-04-04 22:33:59 +00002629void DwarfDebug::EmitSectionLabels() {
Chris Lattner6c2f9e12009-08-19 05:49:37 +00002630 const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
Daniel Dunbarf612ff62009-09-19 20:40:05 +00002631
Bill Wendling94d04b82009-05-20 23:21:38 +00002632 // Dwarf sections base addresses.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002633 if (Asm->MAI->doesDwarfRequireFrameSection()) {
Chris Lattner9c69e285532010-04-04 22:59:04 +00002634 DwarfFrameSectionSym =
2635 EmitSectionSym(Asm, TLOF.getDwarfFrameSection(), "section_debug_frame");
2636 }
Bill Wendling94d04b82009-05-20 23:21:38 +00002637
Chris Lattner9c69e285532010-04-04 22:59:04 +00002638 DwarfInfoSectionSym =
2639 EmitSectionSym(Asm, TLOF.getDwarfInfoSection(), "section_info");
2640 DwarfAbbrevSectionSym =
2641 EmitSectionSym(Asm, TLOF.getDwarfAbbrevSection(), "section_abbrev");
Chris Lattner11b8f302010-04-04 23:02:02 +00002642 EmitSectionSym(Asm, TLOF.getDwarfARangesSection());
Chris Lattner9c69e285532010-04-04 22:59:04 +00002643
2644 if (const MCSection *MacroInfo = TLOF.getDwarfMacroInfoSection())
Chris Lattner11b8f302010-04-04 23:02:02 +00002645 EmitSectionSym(Asm, MacroInfo);
Bill Wendling94d04b82009-05-20 23:21:38 +00002646
Chris Lattner11b8f302010-04-04 23:02:02 +00002647 EmitSectionSym(Asm, TLOF.getDwarfLineSection());
2648 EmitSectionSym(Asm, TLOF.getDwarfLocSection());
2649 EmitSectionSym(Asm, TLOF.getDwarfPubNamesSection());
2650 EmitSectionSym(Asm, TLOF.getDwarfPubTypesSection());
Chris Lattner9c69e285532010-04-04 22:59:04 +00002651 DwarfStrSectionSym =
2652 EmitSectionSym(Asm, TLOF.getDwarfStrSection(), "section_str");
Devang Patelf2548ca2010-04-16 23:33:45 +00002653 DwarfDebugRangeSectionSym = EmitSectionSym(Asm, TLOF.getDwarfRangesSection(),
2654 "debug_range");
Bill Wendling94d04b82009-05-20 23:21:38 +00002655
Chris Lattner9c69e285532010-04-04 22:59:04 +00002656 TextSectionSym = EmitSectionSym(Asm, TLOF.getTextSection(), "text_begin");
Chris Lattner4ad1efe2010-04-04 23:10:38 +00002657 EmitSectionSym(Asm, TLOF.getDataSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00002658}
2659
Devang Patel2c4ceb12009-11-21 02:48:08 +00002660/// emitDIE - Recusively Emits a debug information entry.
Bill Wendling94d04b82009-05-20 23:21:38 +00002661///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002662void DwarfDebug::emitDIE(DIE *Die) {
Bill Wendling94d04b82009-05-20 23:21:38 +00002663 // Get the abbreviation for this DIE.
2664 unsigned AbbrevNumber = Die->getAbbrevNumber();
2665 const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1];
2666
Bill Wendling94d04b82009-05-20 23:21:38 +00002667 // Emit the code (index) for the abbreviation.
Chris Lattner3f53c832010-04-04 18:52:31 +00002668 if (Asm->isVerbose())
Chris Lattner894d75a2010-01-22 23:18:42 +00002669 Asm->OutStreamer.AddComment("Abbrev [" + Twine(AbbrevNumber) + "] 0x" +
2670 Twine::utohexstr(Die->getOffset()) + ":0x" +
2671 Twine::utohexstr(Die->getSize()) + " " +
2672 dwarf::TagString(Abbrev->getTag()));
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002673 Asm->EmitULEB128(AbbrevNumber);
Bill Wendling94d04b82009-05-20 23:21:38 +00002674
Jeffrey Yasskin638fe8d2010-03-22 18:47:14 +00002675 const SmallVector<DIEValue*, 32> &Values = Die->getValues();
Bill Wendling94d04b82009-05-20 23:21:38 +00002676 const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData();
2677
2678 // Emit the DIE attribute values.
2679 for (unsigned i = 0, N = Values.size(); i < N; ++i) {
2680 unsigned Attr = AbbrevData[i].getAttribute();
2681 unsigned Form = AbbrevData[i].getForm();
2682 assert(Form && "Too many attributes for DIE (check abbreviation)");
2683
Chris Lattner3f53c832010-04-04 18:52:31 +00002684 if (Asm->isVerbose())
Chris Lattnera8013622010-01-24 18:54:17 +00002685 Asm->OutStreamer.AddComment(dwarf::AttributeString(Attr));
2686
Bill Wendling94d04b82009-05-20 23:21:38 +00002687 switch (Attr) {
2688 case dwarf::DW_AT_sibling:
Devang Patel2c4ceb12009-11-21 02:48:08 +00002689 Asm->EmitInt32(Die->getSiblingOffset());
Bill Wendling94d04b82009-05-20 23:21:38 +00002690 break;
2691 case dwarf::DW_AT_abstract_origin: {
2692 DIEEntry *E = cast<DIEEntry>(Values[i]);
2693 DIE *Origin = E->getEntry();
Devang Patel53bb5c92009-11-10 23:06:00 +00002694 unsigned Addr = Origin->getOffset();
Bill Wendling94d04b82009-05-20 23:21:38 +00002695 Asm->EmitInt32(Addr);
2696 break;
2697 }
Devang Patelf2548ca2010-04-16 23:33:45 +00002698 case dwarf::DW_AT_ranges: {
2699 // DW_AT_range Value encodes offset in debug_range section.
2700 DIEInteger *V = cast<DIEInteger>(Values[i]);
2701 Asm->EmitLabelOffsetDifference(DwarfDebugRangeSectionSym,
2702 V->getValue(),
2703 DwarfDebugRangeSectionSym,
2704 4);
2705 break;
2706 }
Bill Wendling94d04b82009-05-20 23:21:38 +00002707 default:
2708 // Emit an attribute using the defined form.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002709 Values[i]->EmitValue(Asm, Form);
Bill Wendling94d04b82009-05-20 23:21:38 +00002710 break;
2711 }
Bill Wendling94d04b82009-05-20 23:21:38 +00002712 }
2713
2714 // Emit the DIE children if any.
2715 if (Abbrev->getChildrenFlag() == dwarf::DW_CHILDREN_yes) {
2716 const std::vector<DIE *> &Children = Die->getChildren();
2717
2718 for (unsigned j = 0, M = Children.size(); j < M; ++j)
Devang Patel2c4ceb12009-11-21 02:48:08 +00002719 emitDIE(Children[j]);
Bill Wendling94d04b82009-05-20 23:21:38 +00002720
Chris Lattner3f53c832010-04-04 18:52:31 +00002721 if (Asm->isVerbose())
Chris Lattner233f52b2010-03-09 23:52:58 +00002722 Asm->OutStreamer.AddComment("End Of Children Mark");
2723 Asm->EmitInt8(0);
Bill Wendling94d04b82009-05-20 23:21:38 +00002724 }
2725}
2726
Devang Patel8a241142009-12-09 18:24:21 +00002727/// emitDebugInfo - Emit the debug info section.
Bill Wendling94d04b82009-05-20 23:21:38 +00002728///
Devang Patel8a241142009-12-09 18:24:21 +00002729void DwarfDebug::emitDebugInfo() {
2730 // Start debug info section.
2731 Asm->OutStreamer.SwitchSection(
2732 Asm->getObjFileLowering().getDwarfInfoSection());
2733 DIE *Die = ModuleCU->getCUDie();
Bill Wendling94d04b82009-05-20 23:21:38 +00002734
2735 // Emit the compile units header.
Chris Lattnerc0215722010-04-04 19:25:43 +00002736 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("info_begin",
2737 ModuleCU->getID()));
Bill Wendling94d04b82009-05-20 23:21:38 +00002738
2739 // Emit size of content not including length itself
2740 unsigned ContentSize = Die->getSize() +
2741 sizeof(int16_t) + // DWARF version number
2742 sizeof(int32_t) + // Offset Into Abbrev. Section
2743 sizeof(int8_t) + // Pointer Size (in bytes)
2744 sizeof(int32_t); // FIXME - extra pad for gdb bug.
2745
Chris Lattner233f52b2010-03-09 23:52:58 +00002746 Asm->OutStreamer.AddComment("Length of Compilation Unit Info");
2747 Asm->EmitInt32(ContentSize);
2748 Asm->OutStreamer.AddComment("DWARF version number");
2749 Asm->EmitInt16(dwarf::DWARF_VERSION);
2750 Asm->OutStreamer.AddComment("Offset Into Abbrev. Section");
Chris Lattner6189ed12010-04-04 23:25:33 +00002751 Asm->EmitSectionOffset(Asm->GetTempSymbol("abbrev_begin"),
2752 DwarfAbbrevSectionSym);
Chris Lattner233f52b2010-03-09 23:52:58 +00002753 Asm->OutStreamer.AddComment("Address Size (in bytes)");
Chris Lattnerd38fee82010-04-05 00:13:49 +00002754 Asm->EmitInt8(Asm->getTargetData().getPointerSize());
Bill Wendling94d04b82009-05-20 23:21:38 +00002755
Devang Patel2c4ceb12009-11-21 02:48:08 +00002756 emitDIE(Die);
Bill Wendling94d04b82009-05-20 23:21:38 +00002757 // FIXME - extra padding for gdb bug.
Chris Lattner233f52b2010-03-09 23:52:58 +00002758 Asm->OutStreamer.AddComment("4 extra padding bytes for GDB");
2759 Asm->EmitInt8(0);
2760 Asm->EmitInt8(0);
2761 Asm->EmitInt8(0);
2762 Asm->EmitInt8(0);
Chris Lattnerc0215722010-04-04 19:25:43 +00002763 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("info_end", ModuleCU->getID()));
Bill Wendling94d04b82009-05-20 23:21:38 +00002764}
2765
Devang Patel2c4ceb12009-11-21 02:48:08 +00002766/// emitAbbreviations - Emit the abbreviation section.
Bill Wendling94d04b82009-05-20 23:21:38 +00002767///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002768void DwarfDebug::emitAbbreviations() const {
Bill Wendling94d04b82009-05-20 23:21:38 +00002769 // Check to see if it is worth the effort.
2770 if (!Abbreviations.empty()) {
2771 // Start the debug abbrev section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00002772 Asm->OutStreamer.SwitchSection(
2773 Asm->getObjFileLowering().getDwarfAbbrevSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00002774
Chris Lattnerc0215722010-04-04 19:25:43 +00002775 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("abbrev_begin"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002776
2777 // For each abbrevation.
2778 for (unsigned i = 0, N = Abbreviations.size(); i < N; ++i) {
2779 // Get abbreviation data
2780 const DIEAbbrev *Abbrev = Abbreviations[i];
2781
2782 // Emit the abbrevations code (base 1 index.)
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002783 Asm->EmitULEB128(Abbrev->getNumber(), "Abbreviation Code");
Bill Wendling94d04b82009-05-20 23:21:38 +00002784
2785 // Emit the abbreviations data.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002786 Abbrev->Emit(Asm);
Bill Wendling94d04b82009-05-20 23:21:38 +00002787 }
2788
2789 // Mark end of abbreviations.
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002790 Asm->EmitULEB128(0, "EOM(3)");
Bill Wendling94d04b82009-05-20 23:21:38 +00002791
Chris Lattnerc0215722010-04-04 19:25:43 +00002792 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("abbrev_end"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002793 }
2794}
2795
Devang Patel2c4ceb12009-11-21 02:48:08 +00002796/// emitEndOfLineMatrix - Emit the last address of the section and the end of
Bill Wendling94d04b82009-05-20 23:21:38 +00002797/// the line matrix.
2798///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002799void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) {
Bill Wendling94d04b82009-05-20 23:21:38 +00002800 // Define last address of section.
Chris Lattner233f52b2010-03-09 23:52:58 +00002801 Asm->OutStreamer.AddComment("Extended Op");
2802 Asm->EmitInt8(0);
2803
2804 Asm->OutStreamer.AddComment("Op size");
Chris Lattnerd38fee82010-04-05 00:13:49 +00002805 Asm->EmitInt8(Asm->getTargetData().getPointerSize() + 1);
Chris Lattner233f52b2010-03-09 23:52:58 +00002806 Asm->OutStreamer.AddComment("DW_LNE_set_address");
2807 Asm->EmitInt8(dwarf::DW_LNE_set_address);
2808
2809 Asm->OutStreamer.AddComment("Section end label");
Chris Lattnerd85fc6e2010-03-10 01:17:49 +00002810
Chris Lattnerc0215722010-04-04 19:25:43 +00002811 Asm->OutStreamer.EmitSymbolValue(Asm->GetTempSymbol("section_end",SectionEnd),
Chris Lattnerd38fee82010-04-05 00:13:49 +00002812 Asm->getTargetData().getPointerSize(),
2813 0/*AddrSpace*/);
Bill Wendling94d04b82009-05-20 23:21:38 +00002814
2815 // Mark end of matrix.
Chris Lattner233f52b2010-03-09 23:52:58 +00002816 Asm->OutStreamer.AddComment("DW_LNE_end_sequence");
2817 Asm->EmitInt8(0);
Chris Lattner0ad9c912010-01-22 22:09:00 +00002818 Asm->EmitInt8(1);
Chris Lattner894d75a2010-01-22 23:18:42 +00002819 Asm->EmitInt8(1);
Bill Wendling94d04b82009-05-20 23:21:38 +00002820}
2821
Devang Patel2c4ceb12009-11-21 02:48:08 +00002822/// emitDebugLines - Emit source line information.
Bill Wendling94d04b82009-05-20 23:21:38 +00002823///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002824void DwarfDebug::emitDebugLines() {
Bill Wendling94d04b82009-05-20 23:21:38 +00002825 // If the target is using .loc/.file, the assembler will be emitting the
2826 // .debug_line table automatically.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002827 if (Asm->MAI->hasDotLocAndDotFile())
Bill Wendling94d04b82009-05-20 23:21:38 +00002828 return;
2829
2830 // Minimum line delta, thus ranging from -10..(255-10).
2831 const int MinLineDelta = -(dwarf::DW_LNS_fixed_advance_pc + 1);
2832 // Maximum line delta, thus ranging from -10..(255-10).
2833 const int MaxLineDelta = 255 + MinLineDelta;
2834
2835 // Start the dwarf line section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00002836 Asm->OutStreamer.SwitchSection(
2837 Asm->getObjFileLowering().getDwarfLineSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00002838
2839 // Construct the section header.
Chris Lattner233f52b2010-03-09 23:52:58 +00002840 Asm->OutStreamer.AddComment("Length of Source Line Info");
Chris Lattnera6437182010-04-04 19:58:12 +00002841 Asm->EmitLabelDifference(Asm->GetTempSymbol("line_end"),
2842 Asm->GetTempSymbol("line_begin"), 4);
Chris Lattnerc0215722010-04-04 19:25:43 +00002843 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_begin"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002844
Chris Lattner233f52b2010-03-09 23:52:58 +00002845 Asm->OutStreamer.AddComment("DWARF version number");
2846 Asm->EmitInt16(dwarf::DWARF_VERSION);
Bill Wendling94d04b82009-05-20 23:21:38 +00002847
Chris Lattner233f52b2010-03-09 23:52:58 +00002848 Asm->OutStreamer.AddComment("Prolog Length");
Chris Lattnera6437182010-04-04 19:58:12 +00002849 Asm->EmitLabelDifference(Asm->GetTempSymbol("line_prolog_end"),
2850 Asm->GetTempSymbol("line_prolog_begin"), 4);
Chris Lattnerc0215722010-04-04 19:25:43 +00002851 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_prolog_begin"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002852
Chris Lattner233f52b2010-03-09 23:52:58 +00002853 Asm->OutStreamer.AddComment("Minimum Instruction Length");
2854 Asm->EmitInt8(1);
2855 Asm->OutStreamer.AddComment("Default is_stmt_start flag");
2856 Asm->EmitInt8(1);
2857 Asm->OutStreamer.AddComment("Line Base Value (Special Opcodes)");
2858 Asm->EmitInt8(MinLineDelta);
2859 Asm->OutStreamer.AddComment("Line Range Value (Special Opcodes)");
2860 Asm->EmitInt8(MaxLineDelta);
2861 Asm->OutStreamer.AddComment("Special Opcode Base");
2862 Asm->EmitInt8(-MinLineDelta);
Bill Wendling94d04b82009-05-20 23:21:38 +00002863
2864 // Line number standard opcode encodings argument count
Chris Lattner233f52b2010-03-09 23:52:58 +00002865 Asm->OutStreamer.AddComment("DW_LNS_copy arg count");
2866 Asm->EmitInt8(0);
2867 Asm->OutStreamer.AddComment("DW_LNS_advance_pc arg count");
2868 Asm->EmitInt8(1);
2869 Asm->OutStreamer.AddComment("DW_LNS_advance_line arg count");
2870 Asm->EmitInt8(1);
2871 Asm->OutStreamer.AddComment("DW_LNS_set_file arg count");
2872 Asm->EmitInt8(1);
2873 Asm->OutStreamer.AddComment("DW_LNS_set_column arg count");
2874 Asm->EmitInt8(1);
2875 Asm->OutStreamer.AddComment("DW_LNS_negate_stmt arg count");
2876 Asm->EmitInt8(0);
2877 Asm->OutStreamer.AddComment("DW_LNS_set_basic_block arg count");
2878 Asm->EmitInt8(0);
2879 Asm->OutStreamer.AddComment("DW_LNS_const_add_pc arg count");
2880 Asm->EmitInt8(0);
2881 Asm->OutStreamer.AddComment("DW_LNS_fixed_advance_pc arg count");
2882 Asm->EmitInt8(1);
Bill Wendling94d04b82009-05-20 23:21:38 +00002883
2884 // Emit directories.
2885 for (unsigned DI = 1, DE = getNumSourceDirectories()+1; DI != DE; ++DI) {
Chris Lattner4cf202b2010-01-23 03:11:46 +00002886 const std::string &Dir = getSourceDirectoryName(DI);
Chris Lattner3f53c832010-04-04 18:52:31 +00002887 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("Directory");
Chris Lattner4cf202b2010-01-23 03:11:46 +00002888 Asm->OutStreamer.EmitBytes(StringRef(Dir.c_str(), Dir.size()+1), 0);
Bill Wendling94d04b82009-05-20 23:21:38 +00002889 }
2890
Chris Lattner233f52b2010-03-09 23:52:58 +00002891 Asm->OutStreamer.AddComment("End of directories");
2892 Asm->EmitInt8(0);
Bill Wendling94d04b82009-05-20 23:21:38 +00002893
2894 // Emit files.
2895 for (unsigned SI = 1, SE = getNumSourceIds()+1; SI != SE; ++SI) {
2896 // Remember source id starts at 1.
2897 std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(SI);
Chris Lattner4cf202b2010-01-23 03:11:46 +00002898 const std::string &FN = getSourceFileName(Id.second);
Chris Lattner3f53c832010-04-04 18:52:31 +00002899 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("Source");
Chris Lattner4cf202b2010-01-23 03:11:46 +00002900 Asm->OutStreamer.EmitBytes(StringRef(FN.c_str(), FN.size()+1), 0);
2901
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002902 Asm->EmitULEB128(Id.first, "Directory #");
2903 Asm->EmitULEB128(0, "Mod date");
2904 Asm->EmitULEB128(0, "File size");
Bill Wendling94d04b82009-05-20 23:21:38 +00002905 }
2906
Chris Lattner233f52b2010-03-09 23:52:58 +00002907 Asm->OutStreamer.AddComment("End of files");
2908 Asm->EmitInt8(0);
Bill Wendling94d04b82009-05-20 23:21:38 +00002909
Chris Lattnerc0215722010-04-04 19:25:43 +00002910 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_prolog_end"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002911
2912 // A sequence for each text section.
2913 unsigned SecSrcLinesSize = SectionSourceLines.size();
2914
2915 for (unsigned j = 0; j < SecSrcLinesSize; ++j) {
2916 // Isolate current sections line info.
2917 const std::vector<SrcLineInfo> &LineInfos = SectionSourceLines[j];
2918
Bill Wendling94d04b82009-05-20 23:21:38 +00002919 // Dwarf assumes we start with first line of first source file.
2920 unsigned Source = 1;
2921 unsigned Line = 1;
2922
2923 // Construct rows of the address, source, line, column matrix.
2924 for (unsigned i = 0, N = LineInfos.size(); i < N; ++i) {
2925 const SrcLineInfo &LineInfo = LineInfos[i];
Chris Lattner25b68c62010-03-14 08:15:55 +00002926 MCSymbol *Label = LineInfo.getLabel();
Chris Lattnerb9130602010-03-14 02:20:58 +00002927 if (!Label->isDefined()) continue; // Not emitted, in dead code.
Bill Wendling94d04b82009-05-20 23:21:38 +00002928
Caroline Ticec6f9d622009-09-11 18:25:54 +00002929 if (LineInfo.getLine() == 0) continue;
2930
Chris Lattner0d9d70f2010-03-09 23:38:23 +00002931 if (Asm->isVerbose()) {
Chris Lattner188a87d2010-03-10 01:04:13 +00002932 std::pair<unsigned, unsigned> SrcID =
Bill Wendling94d04b82009-05-20 23:21:38 +00002933 getSourceDirectoryAndFileIds(LineInfo.getSourceID());
Chris Lattner188a87d2010-03-10 01:04:13 +00002934 Asm->OutStreamer.AddComment(Twine(getSourceDirectoryName(SrcID.first)) +
Chris Lattner49f618a2010-03-10 02:29:31 +00002935 "/" +
2936 Twine(getSourceFileName(SrcID.second)) +
Chris Lattner188a87d2010-03-10 01:04:13 +00002937 ":" + Twine(LineInfo.getLine()));
Bill Wendling94d04b82009-05-20 23:21:38 +00002938 }
2939
2940 // Define the line address.
Chris Lattner233f52b2010-03-09 23:52:58 +00002941 Asm->OutStreamer.AddComment("Extended Op");
2942 Asm->EmitInt8(0);
2943 Asm->OutStreamer.AddComment("Op size");
Chris Lattnerd38fee82010-04-05 00:13:49 +00002944 Asm->EmitInt8(Asm->getTargetData().getPointerSize() + 1);
Chris Lattner233f52b2010-03-09 23:52:58 +00002945
2946 Asm->OutStreamer.AddComment("DW_LNE_set_address");
2947 Asm->EmitInt8(dwarf::DW_LNE_set_address);
2948
2949 Asm->OutStreamer.AddComment("Location label");
Chris Lattnerd38fee82010-04-05 00:13:49 +00002950 Asm->OutStreamer.EmitSymbolValue(Label,
2951 Asm->getTargetData().getPointerSize(),
Chris Lattnerb9130602010-03-14 02:20:58 +00002952 0/*AddrSpace*/);
Chris Lattnerd85fc6e2010-03-10 01:17:49 +00002953
Bill Wendling94d04b82009-05-20 23:21:38 +00002954 // If change of source, then switch to the new source.
2955 if (Source != LineInfo.getSourceID()) {
2956 Source = LineInfo.getSourceID();
Chris Lattner233f52b2010-03-09 23:52:58 +00002957 Asm->OutStreamer.AddComment("DW_LNS_set_file");
2958 Asm->EmitInt8(dwarf::DW_LNS_set_file);
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002959 Asm->EmitULEB128(Source, "New Source");
Bill Wendling94d04b82009-05-20 23:21:38 +00002960 }
2961
2962 // If change of line.
2963 if (Line != LineInfo.getLine()) {
2964 // Determine offset.
2965 int Offset = LineInfo.getLine() - Line;
2966 int Delta = Offset - MinLineDelta;
2967
2968 // Update line.
2969 Line = LineInfo.getLine();
2970
2971 // If delta is small enough and in range...
2972 if (Delta >= 0 && Delta < (MaxLineDelta - 1)) {
2973 // ... then use fast opcode.
Chris Lattner233f52b2010-03-09 23:52:58 +00002974 Asm->OutStreamer.AddComment("Line Delta");
2975 Asm->EmitInt8(Delta - MinLineDelta);
Bill Wendling94d04b82009-05-20 23:21:38 +00002976 } else {
2977 // ... otherwise use long hand.
Chris Lattner233f52b2010-03-09 23:52:58 +00002978 Asm->OutStreamer.AddComment("DW_LNS_advance_line");
Bill Wendling94d04b82009-05-20 23:21:38 +00002979 Asm->EmitInt8(dwarf::DW_LNS_advance_line);
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002980 Asm->EmitSLEB128(Offset, "Line Offset");
Chris Lattner233f52b2010-03-09 23:52:58 +00002981 Asm->OutStreamer.AddComment("DW_LNS_copy");
2982 Asm->EmitInt8(dwarf::DW_LNS_copy);
Bill Wendling94d04b82009-05-20 23:21:38 +00002983 }
2984 } else {
2985 // Copy the previous row (different address or source)
Chris Lattner233f52b2010-03-09 23:52:58 +00002986 Asm->OutStreamer.AddComment("DW_LNS_copy");
2987 Asm->EmitInt8(dwarf::DW_LNS_copy);
Bill Wendling94d04b82009-05-20 23:21:38 +00002988 }
2989 }
2990
Devang Patel2c4ceb12009-11-21 02:48:08 +00002991 emitEndOfLineMatrix(j + 1);
Bill Wendling94d04b82009-05-20 23:21:38 +00002992 }
2993
2994 if (SecSrcLinesSize == 0)
2995 // Because we're emitting a debug_line section, we still need a line
2996 // table. The linker and friends expect it to exist. If there's nothing to
2997 // put into it, emit an empty table.
Devang Patel2c4ceb12009-11-21 02:48:08 +00002998 emitEndOfLineMatrix(1);
Bill Wendling94d04b82009-05-20 23:21:38 +00002999
Chris Lattnerc0215722010-04-04 19:25:43 +00003000 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_end"));
Bill Wendling94d04b82009-05-20 23:21:38 +00003001}
3002
Devang Patel2c4ceb12009-11-21 02:48:08 +00003003/// emitCommonDebugFrame - Emit common frame info into a debug frame section.
Bill Wendling94d04b82009-05-20 23:21:38 +00003004///
Devang Patel2c4ceb12009-11-21 02:48:08 +00003005void DwarfDebug::emitCommonDebugFrame() {
Chris Lattnerd38fee82010-04-05 00:13:49 +00003006 if (!Asm->MAI->doesDwarfRequireFrameSection())
Bill Wendling94d04b82009-05-20 23:21:38 +00003007 return;
3008
Chris Lattnerd38fee82010-04-05 00:13:49 +00003009 int stackGrowth = Asm->getTargetData().getPointerSize();
3010 if (Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
3011 TargetFrameInfo::StackGrowsDown)
3012 stackGrowth *= -1;
Bill Wendling94d04b82009-05-20 23:21:38 +00003013
3014 // Start the dwarf frame section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003015 Asm->OutStreamer.SwitchSection(
3016 Asm->getObjFileLowering().getDwarfFrameSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00003017
Chris Lattnerc0215722010-04-04 19:25:43 +00003018 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common"));
Chris Lattner233f52b2010-03-09 23:52:58 +00003019 Asm->OutStreamer.AddComment("Length of Common Information Entry");
Chris Lattnera6437182010-04-04 19:58:12 +00003020 Asm->EmitLabelDifference(Asm->GetTempSymbol("debug_frame_common_end"),
3021 Asm->GetTempSymbol("debug_frame_common_begin"), 4);
Bill Wendling94d04b82009-05-20 23:21:38 +00003022
Chris Lattnerc0215722010-04-04 19:25:43 +00003023 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common_begin"));
Chris Lattner233f52b2010-03-09 23:52:58 +00003024 Asm->OutStreamer.AddComment("CIE Identifier Tag");
Bill Wendling94d04b82009-05-20 23:21:38 +00003025 Asm->EmitInt32((int)dwarf::DW_CIE_ID);
Chris Lattner233f52b2010-03-09 23:52:58 +00003026 Asm->OutStreamer.AddComment("CIE Version");
Bill Wendling94d04b82009-05-20 23:21:38 +00003027 Asm->EmitInt8(dwarf::DW_CIE_VERSION);
Chris Lattner233f52b2010-03-09 23:52:58 +00003028 Asm->OutStreamer.AddComment("CIE Augmentation");
Chris Lattner4cf202b2010-01-23 03:11:46 +00003029 Asm->OutStreamer.EmitIntValue(0, 1, /*addrspace*/0); // nul terminator.
Chris Lattner7e1a8f82010-04-04 19:09:29 +00003030 Asm->EmitULEB128(1, "CIE Code Alignment Factor");
3031 Asm->EmitSLEB128(stackGrowth, "CIE Data Alignment Factor");
Chris Lattner233f52b2010-03-09 23:52:58 +00003032 Asm->OutStreamer.AddComment("CIE RA Column");
Chris Lattnerd38fee82010-04-05 00:13:49 +00003033 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Bill Wendling94d04b82009-05-20 23:21:38 +00003034 Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), false));
Bill Wendling94d04b82009-05-20 23:21:38 +00003035
3036 std::vector<MachineMove> Moves;
3037 RI->getInitialFrameState(Moves);
3038
Chris Lattner02b86b92010-04-04 23:41:46 +00003039 Asm->EmitFrameMoves(Moves, 0, false);
Bill Wendling94d04b82009-05-20 23:21:38 +00003040
3041 Asm->EmitAlignment(2, 0, 0, false);
Chris Lattnerc0215722010-04-04 19:25:43 +00003042 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common_end"));
Bill Wendling94d04b82009-05-20 23:21:38 +00003043}
3044
Devang Patel2c4ceb12009-11-21 02:48:08 +00003045/// emitFunctionDebugFrame - Emit per function frame info into a debug frame
Bill Wendling94d04b82009-05-20 23:21:38 +00003046/// section.
Chris Lattner206d61e2010-03-13 07:26:18 +00003047void DwarfDebug::
3048emitFunctionDebugFrame(const FunctionDebugFrameInfo &DebugFrameInfo) {
Chris Lattnerd38fee82010-04-05 00:13:49 +00003049 if (!Asm->MAI->doesDwarfRequireFrameSection())
Bill Wendling94d04b82009-05-20 23:21:38 +00003050 return;
3051
3052 // Start the dwarf frame section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003053 Asm->OutStreamer.SwitchSection(
3054 Asm->getObjFileLowering().getDwarfFrameSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00003055
Chris Lattner233f52b2010-03-09 23:52:58 +00003056 Asm->OutStreamer.AddComment("Length of Frame Information Entry");
Chris Lattner206d61e2010-03-13 07:26:18 +00003057 MCSymbol *DebugFrameBegin =
Chris Lattnerc0215722010-04-04 19:25:43 +00003058 Asm->GetTempSymbol("debug_frame_begin", DebugFrameInfo.Number);
Chris Lattner206d61e2010-03-13 07:26:18 +00003059 MCSymbol *DebugFrameEnd =
Chris Lattnerc0215722010-04-04 19:25:43 +00003060 Asm->GetTempSymbol("debug_frame_end", DebugFrameInfo.Number);
Chris Lattnera6437182010-04-04 19:58:12 +00003061 Asm->EmitLabelDifference(DebugFrameEnd, DebugFrameBegin, 4);
Bill Wendling94d04b82009-05-20 23:21:38 +00003062
Chris Lattner206d61e2010-03-13 07:26:18 +00003063 Asm->OutStreamer.EmitLabel(DebugFrameBegin);
Bill Wendling94d04b82009-05-20 23:21:38 +00003064
Chris Lattner233f52b2010-03-09 23:52:58 +00003065 Asm->OutStreamer.AddComment("FDE CIE offset");
Chris Lattner6189ed12010-04-04 23:25:33 +00003066 Asm->EmitSectionOffset(Asm->GetTempSymbol("debug_frame_common"),
3067 DwarfFrameSectionSym);
Bill Wendling94d04b82009-05-20 23:21:38 +00003068
Chris Lattner233f52b2010-03-09 23:52:58 +00003069 Asm->OutStreamer.AddComment("FDE initial location");
Chris Lattnerc0215722010-04-04 19:25:43 +00003070 MCSymbol *FuncBeginSym =
3071 Asm->GetTempSymbol("func_begin", DebugFrameInfo.Number);
Chris Lattnerfb658072010-03-13 07:40:56 +00003072 Asm->OutStreamer.EmitSymbolValue(FuncBeginSym,
Chris Lattnerd38fee82010-04-05 00:13:49 +00003073 Asm->getTargetData().getPointerSize(),
3074 0/*AddrSpace*/);
Chris Lattnerd85fc6e2010-03-10 01:17:49 +00003075
3076
Chris Lattner233f52b2010-03-09 23:52:58 +00003077 Asm->OutStreamer.AddComment("FDE address range");
Chris Lattnera6437182010-04-04 19:58:12 +00003078 Asm->EmitLabelDifference(Asm->GetTempSymbol("func_end",DebugFrameInfo.Number),
Chris Lattnerd38fee82010-04-05 00:13:49 +00003079 FuncBeginSym, Asm->getTargetData().getPointerSize());
Bill Wendling94d04b82009-05-20 23:21:38 +00003080
Chris Lattner02b86b92010-04-04 23:41:46 +00003081 Asm->EmitFrameMoves(DebugFrameInfo.Moves, FuncBeginSym, false);
Bill Wendling94d04b82009-05-20 23:21:38 +00003082
3083 Asm->EmitAlignment(2, 0, 0, false);
Chris Lattner206d61e2010-03-13 07:26:18 +00003084 Asm->OutStreamer.EmitLabel(DebugFrameEnd);
Bill Wendling94d04b82009-05-20 23:21:38 +00003085}
3086
Devang Patel8a241142009-12-09 18:24:21 +00003087/// emitDebugPubNames - Emit visible names into a debug pubnames section.
3088///
3089void DwarfDebug::emitDebugPubNames() {
3090 // Start the dwarf pubnames section.
3091 Asm->OutStreamer.SwitchSection(
3092 Asm->getObjFileLowering().getDwarfPubNamesSection());
3093
Chris Lattner233f52b2010-03-09 23:52:58 +00003094 Asm->OutStreamer.AddComment("Length of Public Names Info");
Chris Lattnera6437182010-04-04 19:58:12 +00003095 Asm->EmitLabelDifference(
3096 Asm->GetTempSymbol("pubnames_end", ModuleCU->getID()),
3097 Asm->GetTempSymbol("pubnames_begin", ModuleCU->getID()), 4);
Bill Wendling94d04b82009-05-20 23:21:38 +00003098
Chris Lattnerc0215722010-04-04 19:25:43 +00003099 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_begin",
3100 ModuleCU->getID()));
Bill Wendling94d04b82009-05-20 23:21:38 +00003101
Chris Lattner233f52b2010-03-09 23:52:58 +00003102 Asm->OutStreamer.AddComment("DWARF Version");
3103 Asm->EmitInt16(dwarf::DWARF_VERSION);
Bill Wendling94d04b82009-05-20 23:21:38 +00003104
Chris Lattner233f52b2010-03-09 23:52:58 +00003105 Asm->OutStreamer.AddComment("Offset of Compilation Unit Info");
Chris Lattner6189ed12010-04-04 23:25:33 +00003106 Asm->EmitSectionOffset(Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
3107 DwarfInfoSectionSym);
Bill Wendling94d04b82009-05-20 23:21:38 +00003108
Chris Lattner233f52b2010-03-09 23:52:58 +00003109 Asm->OutStreamer.AddComment("Compilation Unit Length");
Chris Lattnera6437182010-04-04 19:58:12 +00003110 Asm->EmitLabelDifference(Asm->GetTempSymbol("info_end", ModuleCU->getID()),
3111 Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
3112 4);
Bill Wendling94d04b82009-05-20 23:21:38 +00003113
Devang Patel8a241142009-12-09 18:24:21 +00003114 const StringMap<DIE*> &Globals = ModuleCU->getGlobals();
Bill Wendling94d04b82009-05-20 23:21:38 +00003115 for (StringMap<DIE*>::const_iterator
3116 GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) {
3117 const char *Name = GI->getKeyData();
Chris Lattner233f52b2010-03-09 23:52:58 +00003118 DIE *Entity = GI->second;
Bill Wendling94d04b82009-05-20 23:21:38 +00003119
Chris Lattner233f52b2010-03-09 23:52:58 +00003120 Asm->OutStreamer.AddComment("DIE offset");
3121 Asm->EmitInt32(Entity->getOffset());
Chris Lattner4cf202b2010-01-23 03:11:46 +00003122
Chris Lattner3f53c832010-04-04 18:52:31 +00003123 if (Asm->isVerbose())
Chris Lattner4cf202b2010-01-23 03:11:46 +00003124 Asm->OutStreamer.AddComment("External Name");
3125 Asm->OutStreamer.EmitBytes(StringRef(Name, strlen(Name)+1), 0);
Bill Wendling94d04b82009-05-20 23:21:38 +00003126 }
3127
Chris Lattner233f52b2010-03-09 23:52:58 +00003128 Asm->OutStreamer.AddComment("End Mark");
3129 Asm->EmitInt32(0);
Chris Lattnerc0215722010-04-04 19:25:43 +00003130 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_end",
3131 ModuleCU->getID()));
Bill Wendling94d04b82009-05-20 23:21:38 +00003132}
3133
Devang Patel193f7202009-11-24 01:14:22 +00003134void DwarfDebug::emitDebugPubTypes() {
Devang Patelf3a03762009-11-24 19:18:41 +00003135 // Start the dwarf pubnames section.
3136 Asm->OutStreamer.SwitchSection(
3137 Asm->getObjFileLowering().getDwarfPubTypesSection());
Chris Lattner233f52b2010-03-09 23:52:58 +00003138 Asm->OutStreamer.AddComment("Length of Public Types Info");
Chris Lattnera6437182010-04-04 19:58:12 +00003139 Asm->EmitLabelDifference(
3140 Asm->GetTempSymbol("pubtypes_end", ModuleCU->getID()),
3141 Asm->GetTempSymbol("pubtypes_begin", ModuleCU->getID()), 4);
Devang Patel193f7202009-11-24 01:14:22 +00003142
Chris Lattnerc0215722010-04-04 19:25:43 +00003143 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubtypes_begin",
3144 ModuleCU->getID()));
Devang Patel193f7202009-11-24 01:14:22 +00003145
Chris Lattner3f53c832010-04-04 18:52:31 +00003146 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DWARF Version");
Devang Patele3d6d222010-02-02 03:47:27 +00003147 Asm->EmitInt16(dwarf::DWARF_VERSION);
Devang Patel193f7202009-11-24 01:14:22 +00003148
Chris Lattner233f52b2010-03-09 23:52:58 +00003149 Asm->OutStreamer.AddComment("Offset of Compilation ModuleCU Info");
Chris Lattner6189ed12010-04-04 23:25:33 +00003150 Asm->EmitSectionOffset(Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
3151 DwarfInfoSectionSym);
Devang Patel193f7202009-11-24 01:14:22 +00003152
Chris Lattner233f52b2010-03-09 23:52:58 +00003153 Asm->OutStreamer.AddComment("Compilation ModuleCU Length");
Chris Lattnera6437182010-04-04 19:58:12 +00003154 Asm->EmitLabelDifference(Asm->GetTempSymbol("info_end", ModuleCU->getID()),
3155 Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
3156 4);
Devang Patel193f7202009-11-24 01:14:22 +00003157
3158 const StringMap<DIE*> &Globals = ModuleCU->getGlobalTypes();
3159 for (StringMap<DIE*>::const_iterator
3160 GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) {
3161 const char *Name = GI->getKeyData();
3162 DIE * Entity = GI->second;
3163
Chris Lattner3f53c832010-04-04 18:52:31 +00003164 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DIE offset");
Devang Patele3d6d222010-02-02 03:47:27 +00003165 Asm->EmitInt32(Entity->getOffset());
Chris Lattner4cf202b2010-01-23 03:11:46 +00003166
Chris Lattner3f53c832010-04-04 18:52:31 +00003167 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("External Name");
Devang Patel31acb892010-02-02 03:37:03 +00003168 Asm->OutStreamer.EmitBytes(StringRef(Name, GI->getKeyLength()+1), 0);
Devang Patel193f7202009-11-24 01:14:22 +00003169 }
3170
Chris Lattner233f52b2010-03-09 23:52:58 +00003171 Asm->OutStreamer.AddComment("End Mark");
3172 Asm->EmitInt32(0);
Chris Lattnerc0215722010-04-04 19:25:43 +00003173 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubtypes_end",
3174 ModuleCU->getID()));
Devang Patel193f7202009-11-24 01:14:22 +00003175}
3176
Devang Patel2c4ceb12009-11-21 02:48:08 +00003177/// emitDebugStr - Emit visible names into a debug str section.
Bill Wendling94d04b82009-05-20 23:21:38 +00003178///
Devang Patel2c4ceb12009-11-21 02:48:08 +00003179void DwarfDebug::emitDebugStr() {
Bill Wendling94d04b82009-05-20 23:21:38 +00003180 // Check to see if it is worth the effort.
Chris Lattner0d9d70f2010-03-09 23:38:23 +00003181 if (StringPool.empty()) return;
3182
3183 // Start the dwarf str section.
3184 Asm->OutStreamer.SwitchSection(
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003185 Asm->getObjFileLowering().getDwarfStrSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00003186
Chris Lattnerbc733f52010-03-13 02:17:42 +00003187 // Get all of the string pool entries and put them in an array by their ID so
3188 // we can sort them.
3189 SmallVector<std::pair<unsigned,
3190 StringMapEntry<std::pair<MCSymbol*, unsigned> >*>, 64> Entries;
3191
3192 for (StringMap<std::pair<MCSymbol*, unsigned> >::iterator
3193 I = StringPool.begin(), E = StringPool.end(); I != E; ++I)
3194 Entries.push_back(std::make_pair(I->second.second, &*I));
3195
3196 array_pod_sort(Entries.begin(), Entries.end());
3197
3198 for (unsigned i = 0, e = Entries.size(); i != e; ++i) {
Chris Lattner0d9d70f2010-03-09 23:38:23 +00003199 // Emit a label for reference from debug information entries.
Chris Lattnerbc733f52010-03-13 02:17:42 +00003200 Asm->OutStreamer.EmitLabel(Entries[i].second->getValue().first);
Chris Lattner0d9d70f2010-03-09 23:38:23 +00003201
3202 // Emit the string itself.
Chris Lattnerbc733f52010-03-13 02:17:42 +00003203 Asm->OutStreamer.EmitBytes(Entries[i].second->getKey(), 0/*addrspace*/);
Bill Wendling94d04b82009-05-20 23:21:38 +00003204 }
3205}
3206
Devang Patel2c4ceb12009-11-21 02:48:08 +00003207/// emitDebugLoc - Emit visible names into a debug loc section.
Bill Wendling94d04b82009-05-20 23:21:38 +00003208///
Devang Patel2c4ceb12009-11-21 02:48:08 +00003209void DwarfDebug::emitDebugLoc() {
Bill Wendling94d04b82009-05-20 23:21:38 +00003210 // Start the dwarf loc section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003211 Asm->OutStreamer.SwitchSection(
3212 Asm->getObjFileLowering().getDwarfLocSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00003213}
3214
3215/// EmitDebugARanges - Emit visible names into a debug aranges section.
3216///
3217void DwarfDebug::EmitDebugARanges() {
3218 // Start the dwarf aranges section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003219 Asm->OutStreamer.SwitchSection(
3220 Asm->getObjFileLowering().getDwarfARangesSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00003221}
3222
Devang Patel2c4ceb12009-11-21 02:48:08 +00003223/// emitDebugRanges - Emit visible names into a debug ranges section.
Bill Wendling94d04b82009-05-20 23:21:38 +00003224///
Devang Patel2c4ceb12009-11-21 02:48:08 +00003225void DwarfDebug::emitDebugRanges() {
Bill Wendling94d04b82009-05-20 23:21:38 +00003226 // Start the dwarf ranges section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003227 Asm->OutStreamer.SwitchSection(
Devang Patelf2548ca2010-04-16 23:33:45 +00003228 Asm->getObjFileLowering().getDwarfRangesSection());
3229 for (SmallVector<const MCSymbol *, 8>::const_iterator I = DebugRangeSymbols.begin(),
3230 E = DebugRangeSymbols.end(); I != E; ++I) {
3231 if (*I)
3232 Asm->EmitLabelDifference(*I, TextSectionSym,
3233 Asm->getTargetData().getPointerSize());
3234 else
3235 Asm->OutStreamer.EmitIntValue(0, Asm->getTargetData().getPointerSize(),
3236 /*addrspace*/0);
3237 }
Bill Wendling94d04b82009-05-20 23:21:38 +00003238}
3239
Devang Patel2c4ceb12009-11-21 02:48:08 +00003240/// emitDebugMacInfo - Emit visible names into a debug macinfo section.
Bill Wendling94d04b82009-05-20 23:21:38 +00003241///
Devang Patel2c4ceb12009-11-21 02:48:08 +00003242void DwarfDebug::emitDebugMacInfo() {
Daniel Dunbarf612ff62009-09-19 20:40:05 +00003243 if (const MCSection *LineInfo =
Chris Lattner18a4c162009-08-02 07:24:22 +00003244 Asm->getObjFileLowering().getDwarfMacroInfoSection()) {
Bill Wendling94d04b82009-05-20 23:21:38 +00003245 // Start the dwarf macinfo section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003246 Asm->OutStreamer.SwitchSection(LineInfo);
Bill Wendling94d04b82009-05-20 23:21:38 +00003247 }
3248}
3249
Devang Patel2c4ceb12009-11-21 02:48:08 +00003250/// emitDebugInlineInfo - Emit inline info using following format.
Bill Wendling94d04b82009-05-20 23:21:38 +00003251/// Section Header:
3252/// 1. length of section
3253/// 2. Dwarf version number
3254/// 3. address size.
3255///
3256/// Entries (one "entry" for each function that was inlined):
3257///
3258/// 1. offset into __debug_str section for MIPS linkage name, if exists;
3259/// otherwise offset into __debug_str for regular function name.
3260/// 2. offset into __debug_str section for regular function name.
3261/// 3. an unsigned LEB128 number indicating the number of distinct inlining
3262/// instances for the function.
3263///
3264/// The rest of the entry consists of a {die_offset, low_pc} pair for each
3265/// inlined instance; the die_offset points to the inlined_subroutine die in the
3266/// __debug_info section, and the low_pc is the starting address for the
3267/// inlining instance.
Devang Patel2c4ceb12009-11-21 02:48:08 +00003268void DwarfDebug::emitDebugInlineInfo() {
Chris Lattnerd38fee82010-04-05 00:13:49 +00003269 if (!Asm->MAI->doesDwarfUsesInlineInfoSection())
Bill Wendling94d04b82009-05-20 23:21:38 +00003270 return;
3271
Devang Patel1dbc7712009-06-29 20:45:18 +00003272 if (!ModuleCU)
Bill Wendling94d04b82009-05-20 23:21:38 +00003273 return;
3274
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003275 Asm->OutStreamer.SwitchSection(
3276 Asm->getObjFileLowering().getDwarfDebugInlineSection());
Chris Lattner0ad9c912010-01-22 22:09:00 +00003277
Chris Lattner233f52b2010-03-09 23:52:58 +00003278 Asm->OutStreamer.AddComment("Length of Debug Inlined Information Entry");
Chris Lattnera6437182010-04-04 19:58:12 +00003279 Asm->EmitLabelDifference(Asm->GetTempSymbol("debug_inlined_end", 1),
3280 Asm->GetTempSymbol("debug_inlined_begin", 1), 4);
Bill Wendling94d04b82009-05-20 23:21:38 +00003281
Chris Lattnerc0215722010-04-04 19:25:43 +00003282 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_begin", 1));
Bill Wendling94d04b82009-05-20 23:21:38 +00003283
Chris Lattner233f52b2010-03-09 23:52:58 +00003284 Asm->OutStreamer.AddComment("Dwarf Version");
3285 Asm->EmitInt16(dwarf::DWARF_VERSION);
3286 Asm->OutStreamer.AddComment("Address Size (in bytes)");
Chris Lattnerd38fee82010-04-05 00:13:49 +00003287 Asm->EmitInt8(Asm->getTargetData().getPointerSize());
Bill Wendling94d04b82009-05-20 23:21:38 +00003288
Devang Patel53bb5c92009-11-10 23:06:00 +00003289 for (SmallVector<MDNode *, 4>::iterator I = InlinedSPNodes.begin(),
3290 E = InlinedSPNodes.end(); I != E; ++I) {
Jim Grosbach31ef40e2009-11-21 23:12:12 +00003291
Devang Patel53bb5c92009-11-10 23:06:00 +00003292 MDNode *Node = *I;
Devang Patel622b0262010-01-19 06:19:05 +00003293 DenseMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator II
Jim Grosbach7ab38df2009-11-22 19:20:36 +00003294 = InlineInfo.find(Node);
Devang Patel53bb5c92009-11-10 23:06:00 +00003295 SmallVector<InlineInfoLabels, 4> &Labels = II->second;
Devang Patele4b27562009-08-28 23:24:31 +00003296 DISubprogram SP(Node);
Devang Patel65dbc902009-11-25 17:36:49 +00003297 StringRef LName = SP.getLinkageName();
3298 StringRef Name = SP.getName();
Bill Wendling94d04b82009-05-20 23:21:38 +00003299
Chris Lattner233f52b2010-03-09 23:52:58 +00003300 Asm->OutStreamer.AddComment("MIPS linkage name");
Chris Lattner4cf202b2010-01-23 03:11:46 +00003301 if (LName.empty()) {
3302 Asm->OutStreamer.EmitBytes(Name, 0);
3303 Asm->OutStreamer.EmitIntValue(0, 1, 0); // nul terminator.
3304 } else
Chris Lattner6189ed12010-04-04 23:25:33 +00003305 Asm->EmitSectionOffset(getStringPoolEntry(getRealLinkageName(LName)),
3306 DwarfStrSectionSym);
Devang Patel53bb5c92009-11-10 23:06:00 +00003307
Chris Lattner233f52b2010-03-09 23:52:58 +00003308 Asm->OutStreamer.AddComment("Function name");
Chris Lattner6189ed12010-04-04 23:25:33 +00003309 Asm->EmitSectionOffset(getStringPoolEntry(Name), DwarfStrSectionSym);
Chris Lattner7e1a8f82010-04-04 19:09:29 +00003310 Asm->EmitULEB128(Labels.size(), "Inline count");
Bill Wendling94d04b82009-05-20 23:21:38 +00003311
Devang Patel53bb5c92009-11-10 23:06:00 +00003312 for (SmallVector<InlineInfoLabels, 4>::iterator LI = Labels.begin(),
Bill Wendling94d04b82009-05-20 23:21:38 +00003313 LE = Labels.end(); LI != LE; ++LI) {
Chris Lattner3f53c832010-04-04 18:52:31 +00003314 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DIE offset");
Chris Lattner6ed0f902010-03-09 00:31:02 +00003315 Asm->EmitInt32(LI->second->getOffset());
Bill Wendling94d04b82009-05-20 23:21:38 +00003316
Chris Lattner3f53c832010-04-04 18:52:31 +00003317 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("low_pc");
Chris Lattnerd38fee82010-04-05 00:13:49 +00003318 Asm->OutStreamer.EmitSymbolValue(LI->first,
3319 Asm->getTargetData().getPointerSize(),0);
Bill Wendling94d04b82009-05-20 23:21:38 +00003320 }
3321 }
3322
Chris Lattnerc0215722010-04-04 19:25:43 +00003323 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_end", 1));
Bill Wendling94d04b82009-05-20 23:21:38 +00003324}