blob: dfe94f999fbea2fe661719314fd7591c103a2965 [file] [log] [blame]
Jim Laskeye5032892005-12-21 19:48:16 +00001//===-- llvm/CodeGen/DwarfWriter.cpp - Dwarf Framework ----------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by James M. Laskey and is distributed under the
6// University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains support for writing dwarf debug info into asm files.
11//
12//===----------------------------------------------------------------------===//
Jim Laskey3ea0e0e2006-01-27 18:32:41 +000013
Jim Laskeyb2efb852006-01-04 22:28:25 +000014#include "llvm/CodeGen/DwarfWriter.h"
Jim Laskeye5032892005-12-21 19:48:16 +000015
Jim Laskey063e7652006-01-17 17:31:53 +000016#include "llvm/ADT/StringExtras.h"
Jim Laskey52060a02006-01-24 00:49:18 +000017#include "llvm/Module.h"
18#include "llvm/Type.h"
Jim Laskeya7cea6f2006-01-04 13:52:30 +000019#include "llvm/CodeGen/AsmPrinter.h"
Jim Laskeyb2efb852006-01-04 22:28:25 +000020#include "llvm/CodeGen/MachineDebugInfo.h"
Jim Laskeyb3e789a2006-01-26 20:21:46 +000021#include "llvm/Support/Dwarf.h"
Jim Laskeya7cea6f2006-01-04 13:52:30 +000022#include "llvm/Support/CommandLine.h"
Jim Laskey52060a02006-01-24 00:49:18 +000023#include "llvm/Support/Mangler.h"
24#include "llvm/Target/TargetMachine.h"
Jim Laskeya7cea6f2006-01-04 13:52:30 +000025
Jim Laskeyb2efb852006-01-04 22:28:25 +000026#include <iostream>
Jim Laskeya7cea6f2006-01-04 13:52:30 +000027
Jim Laskeyb2efb852006-01-04 22:28:25 +000028using namespace llvm;
Jim Laskey9a777a32006-02-27 22:37:23 +000029using namespace llvm::dwarf;
Jim Laskeya7cea6f2006-01-04 13:52:30 +000030
31static cl::opt<bool>
32DwarfVerbose("dwarf-verbose", cl::Hidden,
Jim Laskey063e7652006-01-17 17:31:53 +000033 cl::desc("Add comments to Dwarf directives."));
34
Jim Laskey0d086af2006-02-27 12:43:29 +000035namespace llvm {
36
Jim Laskey063e7652006-01-17 17:31:53 +000037//===----------------------------------------------------------------------===//
Jim Laskey0d086af2006-02-27 12:43:29 +000038// Forward declarations.
39//
40class CompileUnit;
41class DIE;
Jim Laskey063e7652006-01-17 17:31:53 +000042
Jim Laskey0d086af2006-02-27 12:43:29 +000043//===----------------------------------------------------------------------===//
Jim Laskeybd761842006-02-27 17:27:12 +000044class CompileUnit {
45private:
46 CompileUnitDesc *Desc; // Compile unit debug descriptor.
47 unsigned ID; // File ID for source.
48 DIE *Die; // Compile unit die.
49 std::map<std::string, DIE *> Globals; // A map of globally visible named
50 // entities for this unit.
51
52public:
53 CompileUnit(CompileUnitDesc *CUD, unsigned I, DIE *D)
54 : Desc(CUD)
55 , ID(I)
56 , Die(D)
57 , Globals()
58 {}
59
60 ~CompileUnit();
61
62 // Accessors.
63 CompileUnitDesc *getDesc() const { return Desc; }
64 unsigned getID() const { return ID; }
65 DIE* getDie() const { return Die; }
66 std::map<std::string, DIE *> &getGlobals() { return Globals; }
67
68 /// hasContent - Return true if this compile unit has something to write out.
69 ///
70 bool hasContent() const;
71
72 /// AddGlobal - Add a new global entity to the compile unit.
73 ///
74 void AddGlobal(const std::string &Name, DIE *Die);
75
76};
77
78//===----------------------------------------------------------------------===//
Jim Laskey0d086af2006-02-27 12:43:29 +000079// DIEAbbrevData - Dwarf abbreviation data, describes the one attribute of a
80// Dwarf abbreviation.
81class DIEAbbrevData {
82private:
83 unsigned Attribute; // Dwarf attribute code.
84 unsigned Form; // Dwarf form code.
85
86public:
87 DIEAbbrevData(unsigned A, unsigned F)
88 : Attribute(A)
89 , Form(F)
90 {}
91
Jim Laskeybd761842006-02-27 17:27:12 +000092 // Accessors.
Jim Laskey0d086af2006-02-27 12:43:29 +000093 unsigned getAttribute() const { return Attribute; }
94 unsigned getForm() const { return Form; }
95
96 /// operator== - Used by DIEAbbrev to locate entry.
97 ///
98 bool operator==(const DIEAbbrevData &DAD) const {
99 return Attribute == DAD.Attribute && Form == DAD.Form;
Jim Laskey063e7652006-01-17 17:31:53 +0000100 }
Jim Laskey063e7652006-01-17 17:31:53 +0000101
Jim Laskey0d086af2006-02-27 12:43:29 +0000102 /// operator!= - Used by DIEAbbrev to locate entry.
103 ///
104 bool operator!=(const DIEAbbrevData &DAD) const {
105 return Attribute != DAD.Attribute || Form != DAD.Form;
Jim Laskey063e7652006-01-17 17:31:53 +0000106 }
Jim Laskey0d086af2006-02-27 12:43:29 +0000107
108 /// operator< - Used by DIEAbbrev to locate entry.
109 ///
110 bool operator<(const DIEAbbrevData &DAD) const {
111 return Attribute < DAD.Attribute ||
112 (Attribute == DAD.Attribute && Form < DAD.Form);
113 }
114};
Jim Laskey063e7652006-01-17 17:31:53 +0000115
Jim Laskey0d086af2006-02-27 12:43:29 +0000116//===----------------------------------------------------------------------===//
117// DIEAbbrev - Dwarf abbreviation, describes the organization of a debug
118// information object.
119class DIEAbbrev {
120private:
121 unsigned Tag; // Dwarf tag code.
122 unsigned ChildrenFlag; // Dwarf children flag.
123 std::vector<DIEAbbrevData> Data; // Raw data bytes for abbreviation.
Jim Laskey063e7652006-01-17 17:31:53 +0000124
Jim Laskey0d086af2006-02-27 12:43:29 +0000125public:
Jim Laskey063e7652006-01-17 17:31:53 +0000126
Jim Laskey0d086af2006-02-27 12:43:29 +0000127 DIEAbbrev(unsigned T, unsigned C)
128 : Tag(T)
129 , ChildrenFlag(C)
130 , Data()
131 {}
132 ~DIEAbbrev() {}
133
Jim Laskeybd761842006-02-27 17:27:12 +0000134 // Accessors.
Jim Laskey0d086af2006-02-27 12:43:29 +0000135 unsigned getTag() const { return Tag; }
136 unsigned getChildrenFlag() const { return ChildrenFlag; }
137 const std::vector<DIEAbbrevData> &getData() const { return Data; }
138 void setChildrenFlag(unsigned CF) { ChildrenFlag = CF; }
Jim Laskey063e7652006-01-17 17:31:53 +0000139
Jim Laskey0d086af2006-02-27 12:43:29 +0000140 /// operator== - Used by UniqueVector to locate entry.
141 ///
142 bool operator==(const DIEAbbrev &DA) const;
Jim Laskey063e7652006-01-17 17:31:53 +0000143
Jim Laskey0d086af2006-02-27 12:43:29 +0000144 /// operator< - Used by UniqueVector to locate entry.
145 ///
146 bool operator<(const DIEAbbrev &DA) const;
Jim Laskey063e7652006-01-17 17:31:53 +0000147
Jim Laskey0d086af2006-02-27 12:43:29 +0000148 /// AddAttribute - Adds another set of attribute information to the
149 /// abbreviation.
150 void AddAttribute(unsigned Attribute, unsigned Form) {
151 Data.push_back(DIEAbbrevData(Attribute, Form));
Jim Laskey063e7652006-01-17 17:31:53 +0000152 }
Jim Laskey0d086af2006-02-27 12:43:29 +0000153
154 /// Emit - Print the abbreviation using the specified Dwarf writer.
155 ///
156 void Emit(const DwarfWriter &DW) const;
157
158#ifndef NDEBUG
159 void print(std::ostream &O);
160 void dump();
161#endif
162};
Jim Laskey063e7652006-01-17 17:31:53 +0000163
Jim Laskey0d086af2006-02-27 12:43:29 +0000164//===----------------------------------------------------------------------===//
165// DIEValue - A debug information entry value.
166//
167class DIEValue {
168public:
169 enum {
170 isInteger,
171 isString,
172 isLabel,
173 isAsIsLabel,
174 isDelta,
175 isEntry
176 };
177
178 unsigned Type; // Type of the value
179
180 DIEValue(unsigned T) : Type(T) {}
181 virtual ~DIEValue() {}
182
183 // Implement isa/cast/dyncast.
184 static bool classof(const DIEValue *) { return true; }
185
186 /// EmitValue - Emit value via the Dwarf writer.
187 ///
188 virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const = 0;
189
190 /// SizeOf - Return the size of a value in bytes.
191 ///
192 virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const = 0;
193};
Jim Laskey063e7652006-01-17 17:31:53 +0000194
Jim Laskey0d086af2006-02-27 12:43:29 +0000195//===----------------------------------------------------------------------===//
196// DWInteger - An integer value DIE.
197//
198class DIEInteger : public DIEValue {
199private:
200 uint64_t Integer;
201
202public:
203 DIEInteger(uint64_t I) : DIEValue(isInteger), Integer(I) {}
Jim Laskey063e7652006-01-17 17:31:53 +0000204
Jim Laskey0d086af2006-02-27 12:43:29 +0000205 // Implement isa/cast/dyncast.
206 static bool classof(const DIEInteger *) { return true; }
207 static bool classof(const DIEValue *I) { return I->Type == isInteger; }
208
209 /// EmitValue - Emit integer of appropriate size.
210 ///
211 virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const;
212
213 /// SizeOf - Determine size of integer value in bytes.
214 ///
215 virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const;
216};
Jim Laskey063e7652006-01-17 17:31:53 +0000217
Jim Laskey0d086af2006-02-27 12:43:29 +0000218//===----------------------------------------------------------------------===//
219// DIEString - A string value DIE.
220//
221struct DIEString : public DIEValue {
222 const std::string String;
223
224 DIEString(const std::string &S) : DIEValue(isString), String(S) {}
Jim Laskey063e7652006-01-17 17:31:53 +0000225
Jim Laskey0d086af2006-02-27 12:43:29 +0000226 // Implement isa/cast/dyncast.
227 static bool classof(const DIEString *) { return true; }
228 static bool classof(const DIEValue *S) { return S->Type == isString; }
229
230 /// EmitValue - Emit string value.
231 ///
232 virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const;
233
234 /// SizeOf - Determine size of string value in bytes.
235 ///
236 virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const;
237};
Jim Laskey063e7652006-01-17 17:31:53 +0000238
Jim Laskey0d086af2006-02-27 12:43:29 +0000239//===----------------------------------------------------------------------===//
240// DIEDwarfLabel - A Dwarf internal label expression DIE.
241//
242struct DIEDwarfLabel : public DIEValue {
243 const DWLabel Label;
244
245 DIEDwarfLabel(const DWLabel &L) : DIEValue(isLabel), Label(L) {}
Jim Laskey063e7652006-01-17 17:31:53 +0000246
Jim Laskey0d086af2006-02-27 12:43:29 +0000247 // Implement isa/cast/dyncast.
248 static bool classof(const DIEDwarfLabel *) { return true; }
249 static bool classof(const DIEValue *L) { return L->Type == isLabel; }
250
251 /// EmitValue - Emit label value.
252 ///
253 virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const;
254
255 /// SizeOf - Determine size of label value in bytes.
256 ///
257 virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const;
258};
Jim Laskey063e7652006-01-17 17:31:53 +0000259
Jim Laskey063e7652006-01-17 17:31:53 +0000260
Jim Laskey0d086af2006-02-27 12:43:29 +0000261//===----------------------------------------------------------------------===//
262// DIEObjectLabel - A label to an object in code or data.
263//
264struct DIEObjectLabel : public DIEValue {
265 const std::string Label;
266
267 DIEObjectLabel(const std::string &L) : DIEValue(isAsIsLabel), Label(L) {}
Jim Laskey063e7652006-01-17 17:31:53 +0000268
Jim Laskey0d086af2006-02-27 12:43:29 +0000269 // Implement isa/cast/dyncast.
270 static bool classof(const DIEObjectLabel *) { return true; }
271 static bool classof(const DIEValue *L) { return L->Type == isAsIsLabel; }
272
273 /// EmitValue - Emit label value.
274 ///
275 virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const;
276
277 /// SizeOf - Determine size of label value in bytes.
278 ///
279 virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const;
280};
Jim Laskey063e7652006-01-17 17:31:53 +0000281
Jim Laskey0d086af2006-02-27 12:43:29 +0000282//===----------------------------------------------------------------------===//
283// DIEDelta - A simple label difference DIE.
284//
285struct DIEDelta : public DIEValue {
286 const DWLabel LabelHi;
287 const DWLabel LabelLo;
288
289 DIEDelta(const DWLabel &Hi, const DWLabel &Lo)
290 : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {}
Jim Laskey063e7652006-01-17 17:31:53 +0000291
Jim Laskey0d086af2006-02-27 12:43:29 +0000292 // Implement isa/cast/dyncast.
293 static bool classof(const DIEDelta *) { return true; }
294 static bool classof(const DIEValue *D) { return D->Type == isDelta; }
295
296 /// EmitValue - Emit delta value.
297 ///
298 virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const;
299
300 /// SizeOf - Determine size of delta value in bytes.
301 ///
302 virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const;
303};
Jim Laskey063e7652006-01-17 17:31:53 +0000304
Jim Laskey0d086af2006-02-27 12:43:29 +0000305//===----------------------------------------------------------------------===//
306// DIEntry - A pointer to a debug information entry.
307//
308struct DIEntry : public DIEValue {
309 DIE *Entry;
310
311 DIEntry(DIE *E) : DIEValue(isEntry), Entry(E) {}
312
313 // Implement isa/cast/dyncast.
314 static bool classof(const DIEntry *) { return true; }
315 static bool classof(const DIEValue *E) { return E->Type == isEntry; }
316
317 /// EmitValue - Emit delta value.
318 ///
319 virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const;
320
321 /// SizeOf - Determine size of delta value in bytes.
322 ///
323 virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const;
324};
325
326//===----------------------------------------------------------------------===//
327// DIE - A structured debug information entry. Has an abbreviation which
328// describes it's organization.
329class DIE {
330private:
331 DIEAbbrev *Abbrev; // Temporary buffer for abbreviation.
332 unsigned AbbrevID; // Decribing abbreviation ID.
333 unsigned Offset; // Offset in debug info section.
334 unsigned Size; // Size of instance + children.
335 std::vector<DIE *> Children; // Children DIEs.
336 std::vector<DIEValue *> Values; // Attributes values.
337
338public:
339 DIE(unsigned Tag);
340 ~DIE();
341
Jim Laskeybd761842006-02-27 17:27:12 +0000342 // Accessors.
Jim Laskey0d086af2006-02-27 12:43:29 +0000343 unsigned getAbbrevID() const { return AbbrevID; }
344 unsigned getOffset() const { return Offset; }
345 unsigned getSize() const { return Size; }
346 const std::vector<DIE *> &getChildren() const { return Children; }
347 const std::vector<DIEValue *> &getValues() const { return Values; }
348 void setOffset(unsigned O) { Offset = O; }
349 void setSize(unsigned S) { Size = S; }
350
351 /// SiblingOffset - Return the offset of the debug information entry's
352 /// sibling.
353 unsigned SiblingOffset() const { return Offset + Size; }
354
355 /// AddUInt - Add an unsigned integer attribute data and value.
356 ///
357 void AddUInt(unsigned Attribute, unsigned Form, uint64_t Integer);
358
359 /// AddSInt - Add an signed integer attribute data and value.
360 ///
361 void AddSInt(unsigned Attribute, unsigned Form, int64_t Integer);
362
363 /// AddString - Add a std::string attribute data and value.
364 ///
365 void AddString(unsigned Attribute, unsigned Form,
366 const std::string &String);
367
368 /// AddLabel - Add a Dwarf label attribute data and value.
369 ///
370 void AddLabel(unsigned Attribute, unsigned Form, const DWLabel &Label);
371
372 /// AddObjectLabel - Add a non-Dwarf label attribute data and value.
373 ///
374 void AddObjectLabel(unsigned Attribute, unsigned Form,
375 const std::string &Label);
376
377 /// AddDelta - Add a label delta attribute data and value.
378 ///
379 void AddDelta(unsigned Attribute, unsigned Form,
380 const DWLabel &Hi, const DWLabel &Lo);
381
382 /// AddDIEntry - Add a DIE attribute data and value.
383 ///
384 void AddDIEntry(unsigned Attribute, unsigned Form, DIE *Entry);
385
386 /// Complete - Indicate that all attributes have been added and
387 /// ready to get an abbreviation ID.
388 ///
389 void Complete(DwarfWriter &DW);
390
391 /// AddChild - Add a child to the DIE.
392 void AddChild(DIE *Child);
393};
394
395} // End of namespace llvm
Jim Laskey063e7652006-01-17 17:31:53 +0000396
397//===----------------------------------------------------------------------===//
398
Jim Laskeybd761842006-02-27 17:27:12 +0000399CompileUnit::~CompileUnit() {
400 delete Die;
401}
402
403/// hasContent - Return true if this compile unit has something to write out.
404///
405bool CompileUnit::hasContent() const {
406 return !Die->getChildren().empty();
407}
408
409/// AddGlobal - Add a new global entity to the compile unit.
410///
411void CompileUnit::AddGlobal(const std::string &Name, DIE *Die) {
412 Globals[Name] = Die;
413}
414
415//===----------------------------------------------------------------------===//
416
Jim Laskeyd18e2892006-01-20 20:34:06 +0000417/// operator== - Used by UniqueVector to locate entry.
418///
419bool DIEAbbrev::operator==(const DIEAbbrev &DA) const {
420 if (Tag != DA.Tag) return false;
421 if (ChildrenFlag != DA.ChildrenFlag) return false;
422 if (Data.size() != DA.Data.size()) return false;
423
Jim Laskey52060a02006-01-24 00:49:18 +0000424 for (unsigned i = 0, N = Data.size(); i < N; ++i) {
Jim Laskey63ae85f2006-01-21 01:13:18 +0000425 if (Data[i] != DA.Data[i]) return false;
Jim Laskeyd18e2892006-01-20 20:34:06 +0000426 }
427
428 return true;
429}
430
431/// operator< - Used by UniqueVector to locate entry.
432///
433bool DIEAbbrev::operator<(const DIEAbbrev &DA) const {
434 if (Tag != DA.Tag) return Tag < DA.Tag;
435 if (ChildrenFlag != DA.ChildrenFlag) return ChildrenFlag < DA.ChildrenFlag;
436 if (Data.size() != DA.Data.size()) return Data.size() < DA.Data.size();
437
Jim Laskey52060a02006-01-24 00:49:18 +0000438 for (unsigned i = 0, N = Data.size(); i < N; ++i) {
Jim Laskey63ae85f2006-01-21 01:13:18 +0000439 if (Data[i] != DA.Data[i]) return Data[i] < DA.Data[i];
Jim Laskeyd18e2892006-01-20 20:34:06 +0000440 }
441
442 return false;
443}
444
445/// Emit - Print the abbreviation using the specified Dwarf writer.
446///
447void DIEAbbrev::Emit(const DwarfWriter &DW) const {
448 // Emit its Dwarf tag type.
449 DW.EmitULEB128Bytes(Tag);
450 DW.EOL(TagString(Tag));
451
452 // Emit whether it has children DIEs.
453 DW.EmitULEB128Bytes(ChildrenFlag);
454 DW.EOL(ChildrenString(ChildrenFlag));
455
456 // For each attribute description.
Jim Laskey52060a02006-01-24 00:49:18 +0000457 for (unsigned i = 0, N = Data.size(); i < N; ++i) {
Jim Laskeyd18e2892006-01-20 20:34:06 +0000458 const DIEAbbrevData &AttrData = Data[i];
459
460 // Emit attribute type.
461 DW.EmitULEB128Bytes(AttrData.getAttribute());
462 DW.EOL(AttributeString(AttrData.getAttribute()));
463
464 // Emit form type.
465 DW.EmitULEB128Bytes(AttrData.getForm());
466 DW.EOL(FormEncodingString(AttrData.getForm()));
467 }
468
469 // Mark end of abbreviation.
470 DW.EmitULEB128Bytes(0); DW.EOL("EOM(1)");
471 DW.EmitULEB128Bytes(0); DW.EOL("EOM(2)");
472}
473
474#ifndef NDEBUG
475 void DIEAbbrev::print(std::ostream &O) {
476 O << "Abbreviation @"
Jeff Cohen05ebc8d2006-01-25 17:18:50 +0000477 << std::hex << (intptr_t)this << std::dec
Jim Laskeyd18e2892006-01-20 20:34:06 +0000478 << " "
479 << TagString(Tag)
480 << " "
481 << ChildrenString(ChildrenFlag)
482 << "\n";
483
Jim Laskey52060a02006-01-24 00:49:18 +0000484 for (unsigned i = 0, N = Data.size(); i < N; ++i) {
Jim Laskeyd18e2892006-01-20 20:34:06 +0000485 O << " "
486 << AttributeString(Data[i].getAttribute())
487 << " "
488 << FormEncodingString(Data[i].getForm())
489 << "\n";
490 }
491 }
492 void DIEAbbrev::dump() { print(std::cerr); }
493#endif
494
495//===----------------------------------------------------------------------===//
496
Jim Laskey063e7652006-01-17 17:31:53 +0000497/// EmitValue - Emit integer of appropriate size.
498///
499void DIEInteger::EmitValue(const DwarfWriter &DW, unsigned Form) const {
500 switch (Form) {
Jim Laskey40020172006-01-20 21:02:36 +0000501 case DW_FORM_flag: // Fall thru
Jim Laskeyda427fa2006-01-27 20:31:25 +0000502 case DW_FORM_data1: DW.EmitInt8(Integer); break;
503 case DW_FORM_data2: DW.EmitInt16(Integer); break;
504 case DW_FORM_data4: DW.EmitInt32(Integer); break;
505 case DW_FORM_data8: DW.EmitInt64(Integer); break;
Jim Laskey40020172006-01-20 21:02:36 +0000506 case DW_FORM_udata: DW.EmitULEB128Bytes(Integer); break;
507 case DW_FORM_sdata: DW.EmitSLEB128Bytes(Integer); break;
Jim Laskey063e7652006-01-17 17:31:53 +0000508 default: assert(0 && "DIE Value form not supported yet"); break;
509 }
510}
511
512/// SizeOf - Determine size of integer value in bytes.
513///
514unsigned DIEInteger::SizeOf(const DwarfWriter &DW, unsigned Form) const {
515 switch (Form) {
Jim Laskeyd18e2892006-01-20 20:34:06 +0000516 case DW_FORM_flag: // Fall thru
Jim Laskey063e7652006-01-17 17:31:53 +0000517 case DW_FORM_data1: return sizeof(int8_t);
518 case DW_FORM_data2: return sizeof(int16_t);
519 case DW_FORM_data4: return sizeof(int32_t);
Jim Laskeyd8f77ba2006-01-27 15:20:54 +0000520 case DW_FORM_data8: return sizeof(int64_t);
Jim Laskey40020172006-01-20 21:02:36 +0000521 case DW_FORM_udata: return DW.SizeULEB128(Integer);
522 case DW_FORM_sdata: return DW.SizeSLEB128(Integer);
Jim Laskey063e7652006-01-17 17:31:53 +0000523 default: assert(0 && "DIE Value form not supported yet"); break;
524 }
525 return 0;
526}
527
528//===----------------------------------------------------------------------===//
529
530/// EmitValue - Emit string value.
531///
532void DIEString::EmitValue(const DwarfWriter &DW, unsigned Form) const {
Jim Laskeyd18e2892006-01-20 20:34:06 +0000533 DW.EmitString(String);
Jim Laskey063e7652006-01-17 17:31:53 +0000534}
535
536/// SizeOf - Determine size of string value in bytes.
537///
538unsigned DIEString::SizeOf(const DwarfWriter &DW, unsigned Form) const {
Jim Laskey40020172006-01-20 21:02:36 +0000539 return String.size() + sizeof(char); // sizeof('\0');
Jim Laskey063e7652006-01-17 17:31:53 +0000540}
541
542//===----------------------------------------------------------------------===//
543
544/// EmitValue - Emit label value.
545///
Jim Laskey52060a02006-01-24 00:49:18 +0000546void DIEDwarfLabel::EmitValue(const DwarfWriter &DW, unsigned Form) const {
Jim Laskeyd18e2892006-01-20 20:34:06 +0000547 DW.EmitReference(Label);
Jim Laskey063e7652006-01-17 17:31:53 +0000548}
549
550/// SizeOf - Determine size of label value in bytes.
551///
Jim Laskey52060a02006-01-24 00:49:18 +0000552unsigned DIEDwarfLabel::SizeOf(const DwarfWriter &DW, unsigned Form) const {
Jim Laskey063e7652006-01-17 17:31:53 +0000553 return DW.getAddressSize();
554}
555
556//===----------------------------------------------------------------------===//
557
Jim Laskeyd18e2892006-01-20 20:34:06 +0000558/// EmitValue - Emit label value.
559///
Jim Laskey52060a02006-01-24 00:49:18 +0000560void DIEObjectLabel::EmitValue(const DwarfWriter &DW, unsigned Form) const {
Jim Laskeyda427fa2006-01-27 20:31:25 +0000561 DW.EmitInt8(sizeof(int8_t) + DW.getAddressSize());
Jim Laskey52060a02006-01-24 00:49:18 +0000562 DW.EOL("DW_FORM_block1 length");
563
Jim Laskeyda427fa2006-01-27 20:31:25 +0000564 DW.EmitInt8(DW_OP_addr);
Jim Laskey52060a02006-01-24 00:49:18 +0000565 DW.EOL("DW_OP_addr");
566
Jim Laskeyd18e2892006-01-20 20:34:06 +0000567 DW.EmitReference(Label);
568}
569
570/// SizeOf - Determine size of label value in bytes.
571///
Jim Laskey52060a02006-01-24 00:49:18 +0000572unsigned DIEObjectLabel::SizeOf(const DwarfWriter &DW, unsigned Form) const {
573 return sizeof(int8_t) + sizeof(int8_t) + DW.getAddressSize();
Jim Laskeyd18e2892006-01-20 20:34:06 +0000574}
575
576//===----------------------------------------------------------------------===//
577
Jim Laskey063e7652006-01-17 17:31:53 +0000578/// EmitValue - Emit delta value.
579///
580void DIEDelta::EmitValue(const DwarfWriter &DW, unsigned Form) const {
Jim Laskeyd18e2892006-01-20 20:34:06 +0000581 DW.EmitDifference(LabelHi, LabelLo);
Jim Laskey063e7652006-01-17 17:31:53 +0000582}
583
584/// SizeOf - Determine size of delta value in bytes.
585///
586unsigned DIEDelta::SizeOf(const DwarfWriter &DW, unsigned Form) const {
587 return DW.getAddressSize();
588}
589
590//===----------------------------------------------------------------------===//
Jim Laskeyd18e2892006-01-20 20:34:06 +0000591/// EmitValue - Emit extry offset.
592///
593void DIEntry::EmitValue(const DwarfWriter &DW, unsigned Form) const {
Jim Laskeyda427fa2006-01-27 20:31:25 +0000594 DW.EmitInt32(Entry->getOffset());
Jim Laskeyd18e2892006-01-20 20:34:06 +0000595}
596
597/// SizeOf - Determine size of label value in bytes.
598///
599unsigned DIEntry::SizeOf(const DwarfWriter &DW, unsigned Form) const {
600 return sizeof(int32_t);
601}
602
603//===----------------------------------------------------------------------===//
604
Jim Laskey0420f2a2006-02-22 19:02:11 +0000605DIE::DIE(unsigned Tag)
606: Abbrev(new DIEAbbrev(Tag, DW_CHILDREN_no))
Jim Laskeyd18e2892006-01-20 20:34:06 +0000607, AbbrevID(0)
608, Offset(0)
609, Size(0)
Jim Laskeyd18e2892006-01-20 20:34:06 +0000610, Children()
611, Values()
612{}
613
614DIE::~DIE() {
615 if (Abbrev) delete Abbrev;
616
Jim Laskey52060a02006-01-24 00:49:18 +0000617 for (unsigned i = 0, N = Children.size(); i < N; ++i) {
Jim Laskeyd18e2892006-01-20 20:34:06 +0000618 delete Children[i];
619 }
620
Jim Laskey52060a02006-01-24 00:49:18 +0000621 for (unsigned j = 0, M = Values.size(); j < M; ++j) {
Jim Laskeyd18e2892006-01-20 20:34:06 +0000622 delete Values[j];
623 }
Jim Laskeyd18e2892006-01-20 20:34:06 +0000624}
625
Jim Laskeyd8f77ba2006-01-27 15:20:54 +0000626/// AddUInt - Add an unsigned integer attribute data and value.
Jim Laskeyd18e2892006-01-20 20:34:06 +0000627///
Jim Laskeyd8f77ba2006-01-27 15:20:54 +0000628void DIE::AddUInt(unsigned Attribute, unsigned Form, uint64_t Integer) {
Jim Laskey40020172006-01-20 21:02:36 +0000629 if (Form == 0) {
Jim Laskey40020172006-01-20 21:02:36 +0000630 if ((unsigned char)Integer == Integer) Form = DW_FORM_data1;
631 else if ((unsigned short)Integer == Integer) Form = DW_FORM_data2;
Jim Laskeyd8f77ba2006-01-27 15:20:54 +0000632 else if ((unsigned int)Integer == Integer) Form = DW_FORM_data4;
633 else Form = DW_FORM_data8;
634 }
635 Abbrev->AddAttribute(Attribute, Form);
636 Values.push_back(new DIEInteger(Integer));
637}
638
639/// AddSInt - Add an signed integer attribute data and value.
640///
641void DIE::AddSInt(unsigned Attribute, unsigned Form, int64_t Integer) {
642 if (Form == 0) {
643 if ((char)Integer == Integer) Form = DW_FORM_data1;
644 else if ((short)Integer == Integer) Form = DW_FORM_data2;
645 else if ((int)Integer == Integer) Form = DW_FORM_data4;
646 else Form = DW_FORM_data8;
Jim Laskey40020172006-01-20 21:02:36 +0000647 }
Jim Laskeyd18e2892006-01-20 20:34:06 +0000648 Abbrev->AddAttribute(Attribute, Form);
649 Values.push_back(new DIEInteger(Integer));
650}
651
652/// AddString - Add a std::string attribute data and value.
653///
654void DIE::AddString(unsigned Attribute, unsigned Form,
655 const std::string &String) {
656 Abbrev->AddAttribute(Attribute, Form);
657 Values.push_back(new DIEString(String));
658}
659
660/// AddLabel - Add a Dwarf label attribute data and value.
661///
662void DIE::AddLabel(unsigned Attribute, unsigned Form,
663 const DWLabel &Label) {
664 Abbrev->AddAttribute(Attribute, Form);
Jim Laskey52060a02006-01-24 00:49:18 +0000665 Values.push_back(new DIEDwarfLabel(Label));
Jim Laskeyd18e2892006-01-20 20:34:06 +0000666}
667
Jim Laskey52060a02006-01-24 00:49:18 +0000668/// AddObjectLabel - Add an non-Dwarf label attribute data and value.
Jim Laskeyd18e2892006-01-20 20:34:06 +0000669///
Jim Laskey52060a02006-01-24 00:49:18 +0000670void DIE::AddObjectLabel(unsigned Attribute, unsigned Form,
671 const std::string &Label) {
Jim Laskeyd18e2892006-01-20 20:34:06 +0000672 Abbrev->AddAttribute(Attribute, Form);
Jim Laskey52060a02006-01-24 00:49:18 +0000673 Values.push_back(new DIEObjectLabel(Label));
Jim Laskeyd18e2892006-01-20 20:34:06 +0000674}
675
676/// AddDelta - Add a label delta attribute data and value.
677///
678void DIE::AddDelta(unsigned Attribute, unsigned Form,
679 const DWLabel &Hi, const DWLabel &Lo) {
680 Abbrev->AddAttribute(Attribute, Form);
681 Values.push_back(new DIEDelta(Hi, Lo));
682}
683
684/// AddDIEntry - Add a DIE attribute data and value.
685///
686void DIE::AddDIEntry(unsigned Attribute,
687 unsigned Form, DIE *Entry) {
688 Abbrev->AddAttribute(Attribute, Form);
689 Values.push_back(new DIEntry(Entry));
690}
691
692/// Complete - Indicate that all attributes have been added and ready to get an
693/// abbreviation ID.
694void DIE::Complete(DwarfWriter &DW) {
695 AbbrevID = DW.NewAbbreviation(Abbrev);
696 delete Abbrev;
697 Abbrev = NULL;
698}
699
700/// AddChild - Add a child to the DIE.
701///
702void DIE::AddChild(DIE *Child) {
Jim Laskey0420f2a2006-02-22 19:02:11 +0000703 assert(Abbrev && "Adding children without an abbreviation");
704 Abbrev->setChildrenFlag(DW_CHILDREN_yes);
Jim Laskeyd18e2892006-01-20 20:34:06 +0000705 Children.push_back(Child);
706}
707
708//===----------------------------------------------------------------------===//
709
Jim Laskey0420f2a2006-02-22 19:02:11 +0000710/// DWContext
Jim Laskeyd18e2892006-01-20 20:34:06 +0000711
712//===----------------------------------------------------------------------===//
Jim Laskey063e7652006-01-17 17:31:53 +0000713
714/// PrintHex - Print a value as a hexidecimal value.
715///
716void DwarfWriter::PrintHex(int Value) const {
717 O << "0x" << std::hex << Value << std::dec;
718}
719
720/// EOL - Print a newline character to asm stream. If a comment is present
721/// then it will be printed first. Comments should not contain '\n'.
722void DwarfWriter::EOL(const std::string &Comment) const {
723 if (DwarfVerbose) {
724 O << "\t"
725 << Asm->CommentString
726 << " "
727 << Comment;
728 }
729 O << "\n";
730}
Jim Laskeya7cea6f2006-01-04 13:52:30 +0000731
732/// EmitULEB128Bytes - Emit an assembler byte data directive to compose an
Jim Laskey063e7652006-01-17 17:31:53 +0000733/// unsigned leb128 value.
734void DwarfWriter::EmitULEB128Bytes(unsigned Value) const {
Jim Laskeya7cea6f2006-01-04 13:52:30 +0000735 if (hasLEB128) {
736 O << "\t.uleb128\t"
737 << Value;
738 } else {
Jim Laskeyb2efb852006-01-04 22:28:25 +0000739 O << Asm->Data8bitsDirective;
Jim Laskey063e7652006-01-17 17:31:53 +0000740 PrintULEB128(Value);
Jim Laskeya7cea6f2006-01-04 13:52:30 +0000741 }
Jim Laskeya7cea6f2006-01-04 13:52:30 +0000742}
743
744/// EmitSLEB128Bytes - Emit an assembler byte data directive to compose a
Jim Laskey063e7652006-01-17 17:31:53 +0000745/// signed leb128 value.
746void DwarfWriter::EmitSLEB128Bytes(int Value) const {
Jim Laskeya7cea6f2006-01-04 13:52:30 +0000747 if (hasLEB128) {
748 O << "\t.sleb128\t"
749 << Value;
750 } else {
Jim Laskeyb2efb852006-01-04 22:28:25 +0000751 O << Asm->Data8bitsDirective;
Jim Laskey063e7652006-01-17 17:31:53 +0000752 PrintSLEB128(Value);
Jim Laskeya7cea6f2006-01-04 13:52:30 +0000753 }
Jim Laskeya7cea6f2006-01-04 13:52:30 +0000754}
755
Jim Laskey063e7652006-01-17 17:31:53 +0000756/// PrintULEB128 - Print a series of hexidecimal values (separated by commas)
Jim Laskeyb2efb852006-01-04 22:28:25 +0000757/// representing an unsigned leb128 value.
Jim Laskey063e7652006-01-17 17:31:53 +0000758void DwarfWriter::PrintULEB128(unsigned Value) const {
Jim Laskeyb2efb852006-01-04 22:28:25 +0000759 do {
760 unsigned Byte = Value & 0x7f;
761 Value >>= 7;
762 if (Value) Byte |= 0x80;
Jim Laskey063e7652006-01-17 17:31:53 +0000763 PrintHex(Byte);
Jim Laskeyb2efb852006-01-04 22:28:25 +0000764 if (Value) O << ", ";
765 } while (Value);
766}
767
Jim Laskey063e7652006-01-17 17:31:53 +0000768/// SizeULEB128 - Compute the number of bytes required for an unsigned leb128
769/// value.
770unsigned DwarfWriter::SizeULEB128(unsigned Value) {
771 unsigned Size = 0;
772 do {
773 Value >>= 7;
774 Size += sizeof(int8_t);
775 } while (Value);
776 return Size;
777}
778
779/// PrintSLEB128 - Print a series of hexidecimal values (separated by commas)
Jim Laskeyb2efb852006-01-04 22:28:25 +0000780/// representing a signed leb128 value.
Jim Laskey063e7652006-01-17 17:31:53 +0000781void DwarfWriter::PrintSLEB128(int Value) const {
Jim Laskeyb2efb852006-01-04 22:28:25 +0000782 int Sign = Value >> (8 * sizeof(Value) - 1);
783 bool IsMore;
Jim Laskeya7cea6f2006-01-04 13:52:30 +0000784
Jim Laskeyb2efb852006-01-04 22:28:25 +0000785 do {
786 unsigned Byte = Value & 0x7f;
787 Value >>= 7;
788 IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
789 if (IsMore) Byte |= 0x80;
Jim Laskey063e7652006-01-17 17:31:53 +0000790 PrintHex(Byte);
Jim Laskeyb2efb852006-01-04 22:28:25 +0000791 if (IsMore) O << ", ";
792 } while (IsMore);
793}
794
Jim Laskey063e7652006-01-17 17:31:53 +0000795/// SizeSLEB128 - Compute the number of bytes required for a signed leb128
796/// value.
797unsigned DwarfWriter::SizeSLEB128(int Value) {
798 unsigned Size = 0;
799 int Sign = Value >> (8 * sizeof(Value) - 1);
800 bool IsMore;
801
802 do {
803 unsigned Byte = Value & 0x7f;
804 Value >>= 7;
805 IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
806 Size += sizeof(int8_t);
807 } while (IsMore);
808 return Size;
809}
810
Jim Laskeyda427fa2006-01-27 20:31:25 +0000811/// EmitInt8 - Emit a byte directive and value.
Jim Laskeyb2efb852006-01-04 22:28:25 +0000812///
Jim Laskeyda427fa2006-01-27 20:31:25 +0000813void DwarfWriter::EmitInt8(int Value) const {
Jim Laskey063e7652006-01-17 17:31:53 +0000814 O << Asm->Data8bitsDirective;
Jim Laskey0420f2a2006-02-22 19:02:11 +0000815 PrintHex(Value & 0xFF);
Jim Laskey063e7652006-01-17 17:31:53 +0000816}
817
Jim Laskeyda427fa2006-01-27 20:31:25 +0000818/// EmitInt16 - Emit a short directive and value.
Jim Laskey063e7652006-01-17 17:31:53 +0000819///
Jim Laskeyda427fa2006-01-27 20:31:25 +0000820void DwarfWriter::EmitInt16(int Value) const {
Jim Laskey063e7652006-01-17 17:31:53 +0000821 O << Asm->Data16bitsDirective;
Jim Laskey0420f2a2006-02-22 19:02:11 +0000822 PrintHex(Value & 0xFFFF);
Jim Laskey063e7652006-01-17 17:31:53 +0000823}
824
Jim Laskeyda427fa2006-01-27 20:31:25 +0000825/// EmitInt32 - Emit a long directive and value.
Jim Laskey063e7652006-01-17 17:31:53 +0000826///
Jim Laskeyda427fa2006-01-27 20:31:25 +0000827void DwarfWriter::EmitInt32(int Value) const {
Jim Laskey063e7652006-01-17 17:31:53 +0000828 O << Asm->Data32bitsDirective;
829 PrintHex(Value);
830}
831
Jim Laskeyda427fa2006-01-27 20:31:25 +0000832/// EmitInt64 - Emit a long long directive and value.
Jim Laskeyd8f77ba2006-01-27 15:20:54 +0000833///
Jim Laskeyda427fa2006-01-27 20:31:25 +0000834void DwarfWriter::EmitInt64(uint64_t Value) const {
Jim Laskeyd8f77ba2006-01-27 15:20:54 +0000835 if (Asm->Data64bitsDirective) {
836 O << Asm->Data64bitsDirective << "0x" << std::hex << Value << std::dec;
837 } else {
838 const TargetData &TD = Asm->TM.getTargetData();
839
840 if (TD.isBigEndian()) {
Jim Laskeyda427fa2006-01-27 20:31:25 +0000841 EmitInt32(unsigned(Value >> 32)); O << "\n";
842 EmitInt32(unsigned(Value));
Jim Laskeyd8f77ba2006-01-27 15:20:54 +0000843 } else {
Jim Laskeyda427fa2006-01-27 20:31:25 +0000844 EmitInt32(unsigned(Value)); O << "\n";
845 EmitInt32(unsigned(Value >> 32));
Jim Laskeyd8f77ba2006-01-27 15:20:54 +0000846 }
847 }
848}
849
Jim Laskey063e7652006-01-17 17:31:53 +0000850/// EmitString - Emit a string with quotes and a null terminator.
851/// Special characters are emitted properly. (Eg. '\t')
852void DwarfWriter::EmitString(const std::string &String) const {
853 O << Asm->AsciiDirective
854 << "\"";
Jim Laskey52060a02006-01-24 00:49:18 +0000855 for (unsigned i = 0, N = String.size(); i < N; ++i) {
Jim Laskey063e7652006-01-17 17:31:53 +0000856 unsigned char C = String[i];
857
858 if (!isascii(C) || iscntrl(C)) {
859 switch(C) {
860 case '\b': O << "\\b"; break;
861 case '\f': O << "\\f"; break;
862 case '\n': O << "\\n"; break;
863 case '\r': O << "\\r"; break;
864 case '\t': O << "\\t"; break;
865 default:
866 O << '\\';
867 O << char('0' + (C >> 6));
868 O << char('0' + (C >> 3));
869 O << char('0' + (C >> 0));
870 break;
871 }
872 } else if (C == '\"') {
873 O << "\\\"";
874 } else if (C == '\'') {
875 O << "\\\'";
876 } else {
877 O << C;
878 }
879 }
880 O << "\\0\"";
881}
882
883/// PrintLabelName - Print label name in form used by Dwarf writer.
884///
885void DwarfWriter::PrintLabelName(const char *Tag, unsigned Number) const {
Jim Laskeyb2efb852006-01-04 22:28:25 +0000886 O << Asm->PrivateGlobalPrefix
887 << "debug_"
Jim Laskey0420f2a2006-02-22 19:02:11 +0000888 << Tag;
889 if (Number) O << Number;
Jim Laskeyb2efb852006-01-04 22:28:25 +0000890}
891
Jim Laskey063e7652006-01-17 17:31:53 +0000892/// EmitLabel - Emit location label for internal use by Dwarf.
Jim Laskeyb2efb852006-01-04 22:28:25 +0000893///
Jim Laskey063e7652006-01-17 17:31:53 +0000894void DwarfWriter::EmitLabel(const char *Tag, unsigned Number) const {
895 PrintLabelName(Tag, Number);
Jim Laskeyb2efb852006-01-04 22:28:25 +0000896 O << ":\n";
897}
898
Jim Laskeye719a7c2006-01-18 16:54:26 +0000899/// EmitReference - Emit a reference to a label.
Jim Laskey063e7652006-01-17 17:31:53 +0000900///
Jim Laskeye719a7c2006-01-18 16:54:26 +0000901void DwarfWriter::EmitReference(const char *Tag, unsigned Number) const {
Jim Laskey063e7652006-01-17 17:31:53 +0000902 if (AddressSize == 4)
903 O << Asm->Data32bitsDirective;
904 else
905 O << Asm->Data64bitsDirective;
906
907 PrintLabelName(Tag, Number);
908}
Jim Laskey73683212006-01-21 00:59:54 +0000909void DwarfWriter::EmitReference(const std::string &Name) const {
Jim Laskeyd18e2892006-01-20 20:34:06 +0000910 if (AddressSize == 4)
911 O << Asm->Data32bitsDirective;
912 else
913 O << Asm->Data64bitsDirective;
914
915 O << Name;
916}
Jim Laskey063e7652006-01-17 17:31:53 +0000917
918/// EmitDifference - Emit an label difference as sizeof(pointer) value. Some
919/// assemblers do not accept absolute expressions with data directives, so there
920/// is an option (needsSet) to use an intermediary 'set' expression.
Jim Laskeyd18e2892006-01-20 20:34:06 +0000921void DwarfWriter::EmitDifference(const char *TagHi, unsigned NumberHi,
922 const char *TagLo, unsigned NumberLo) const {
Jim Laskey063e7652006-01-17 17:31:53 +0000923 if (needsSet) {
924 static unsigned SetCounter = 0;
Jim Laskeyd18e2892006-01-20 20:34:06 +0000925
Jim Laskey063e7652006-01-17 17:31:53 +0000926 O << "\t.set\t";
927 PrintLabelName("set", SetCounter);
928 O << ",";
Jim Laskeyd18e2892006-01-20 20:34:06 +0000929 PrintLabelName(TagHi, NumberHi);
Jim Laskey063e7652006-01-17 17:31:53 +0000930 O << "-";
Jim Laskeyd18e2892006-01-20 20:34:06 +0000931 PrintLabelName(TagLo, NumberLo);
Jim Laskey063e7652006-01-17 17:31:53 +0000932 O << "\n";
933
934 if (AddressSize == sizeof(int32_t))
935 O << Asm->Data32bitsDirective;
936 else
937 O << Asm->Data64bitsDirective;
938
939 PrintLabelName("set", SetCounter);
940
Jim Laskey52060a02006-01-24 00:49:18 +0000941 ++SetCounter;
Jim Laskey063e7652006-01-17 17:31:53 +0000942 } else {
943 if (AddressSize == sizeof(int32_t))
944 O << Asm->Data32bitsDirective;
945 else
946 O << Asm->Data64bitsDirective;
947
Jim Laskeyd18e2892006-01-20 20:34:06 +0000948 PrintLabelName(TagHi, NumberHi);
Jim Laskey063e7652006-01-17 17:31:53 +0000949 O << "-";
Jim Laskeyd18e2892006-01-20 20:34:06 +0000950 PrintLabelName(TagLo, NumberLo);
Jim Laskey063e7652006-01-17 17:31:53 +0000951 }
952}
953
Jim Laskeyd18e2892006-01-20 20:34:06 +0000954/// NewAbbreviation - Add the abbreviation to the Abbreviation vector.
Jim Laskey063e7652006-01-17 17:31:53 +0000955///
Jim Laskeyd18e2892006-01-20 20:34:06 +0000956unsigned DwarfWriter::NewAbbreviation(DIEAbbrev *Abbrev) {
957 return Abbreviations.insert(*Abbrev);
958}
959
960/// NewString - Add a string to the constant pool and returns a label.
961///
962DWLabel DwarfWriter::NewString(const std::string &String) {
963 unsigned StringID = StringPool.insert(String);
964 return DWLabel("string", StringID);
965}
966
Jim Laskey0420f2a2006-02-22 19:02:11 +0000967/// NewBasicType - Creates a new basic type if necessary, then adds to the
968/// owner.
969/// FIXME - Should never be needed.
Jim Laskey92ae7402006-03-01 18:20:30 +0000970DIE *DwarfWriter::NewBasicType(DIE *Context, Type *Ty) {
Jim Laskey0420f2a2006-02-22 19:02:11 +0000971 DIE *&Slot = TypeToDieMap[Ty];
972 if (Slot) return Slot;
973
974 const char *Name;
975 unsigned Size;
976 unsigned Encoding = 0;
977
978 switch (Ty->getTypeID()) {
979 case Type::UByteTyID:
980 Name = "unsigned char";
981 Size = 1;
982 Encoding = DW_ATE_unsigned_char;
983 break;
984 case Type::SByteTyID:
985 Name = "char";
986 Size = 1;
987 Encoding = DW_ATE_signed_char;
988 break;
989 case Type::UShortTyID:
990 Name = "unsigned short";
991 Size = 2;
992 Encoding = DW_ATE_unsigned;
993 break;
994 case Type::ShortTyID:
995 Name = "short";
996 Size = 2;
997 Encoding = DW_ATE_signed;
998 break;
999 case Type::UIntTyID:
1000 Name = "unsigned int";
1001 Size = 4;
1002 Encoding = DW_ATE_unsigned;
1003 break;
1004 case Type::IntTyID:
1005 Name = "int";
1006 Size = 4;
1007 Encoding = DW_ATE_signed;
1008 break;
1009 case Type::ULongTyID:
1010 Name = "unsigned long long";
1011 Size = 7;
1012 Encoding = DW_ATE_unsigned;
1013 break;
1014 case Type::LongTyID:
1015 Name = "long long";
1016 Size = 7;
1017 Encoding = DW_ATE_signed;
1018 break;
1019 case Type::FloatTyID:
1020 Name = "float";
1021 Size = 4;
1022 Encoding = DW_ATE_float;
1023 break;
1024 case Type::DoubleTyID:
1025 Name = "double";
1026 Size = 8;
1027 Encoding = DW_ATE_float;
1028 break;
1029 default:
1030 // FIXME - handle more complex types.
1031 Name = "unknown";
1032 Size = 1;
1033 Encoding = DW_ATE_address;
1034 break;
1035 }
1036
1037 // construct the type DIE.
1038 Slot = new DIE(DW_TAG_base_type);
1039 Slot->AddString(DW_AT_name, DW_FORM_string, Name);
1040 Slot->AddUInt (DW_AT_byte_size, 0, Size);
1041 Slot->AddUInt (DW_AT_encoding, DW_FORM_data1, Encoding);
1042
Jim Laskey92ae7402006-03-01 18:20:30 +00001043 // Add to context.
1044 Context->AddChild(Slot);
Jim Laskey0420f2a2006-02-22 19:02:11 +00001045
1046 return Slot;
1047}
1048
Jim Laskeyf4afdd92006-02-23 16:58:18 +00001049/// NewType - Create a new type DIE.
1050///
Jim Laskey92ae7402006-03-01 18:20:30 +00001051DIE *DwarfWriter::NewType(DIE *Context, TypeDesc *TyDesc) {
Jim Laskey69906002006-02-24 16:46:40 +00001052 // FIXME - hack to get around NULL types short term.
Jim Laskey92ae7402006-03-01 18:20:30 +00001053 if (!TyDesc) return NewBasicType(Context, Type::IntTy);
1054
1055 // FIXME - Should handle other contexts that compile units.
Jim Laskey69906002006-02-24 16:46:40 +00001056
Jim Laskeyf4afdd92006-02-23 16:58:18 +00001057 // Check for pre-existence.
1058 DIE *&Slot = DescToDieMap[TyDesc];
1059 if (Slot) return Slot;
1060
1061 // Get core information.
1062 const std::string &Name = TyDesc->getName();
Jim Laskey288fe0f2006-03-01 18:13:05 +00001063 uint64_t Size = TyDesc->getSize() >> 3;
Jim Laskeyf4afdd92006-02-23 16:58:18 +00001064
Jim Laskey434b40b2006-02-23 22:37:30 +00001065 DIE *Ty = NULL;
Jim Laskeyf4afdd92006-02-23 16:58:18 +00001066
Jim Laskey434b40b2006-02-23 22:37:30 +00001067 if (BasicTypeDesc *BasicTy = dyn_cast<BasicTypeDesc>(TyDesc)) {
Jim Laskey69906002006-02-24 16:46:40 +00001068 // Fundamental types like int, float, bool
Jim Laskey434b40b2006-02-23 22:37:30 +00001069 Slot = Ty = new DIE(DW_TAG_base_type);
1070 unsigned Encoding = BasicTy->getEncoding();
1071 Ty->AddUInt (DW_AT_encoding, DW_FORM_data1, Encoding);
Jim Laskey69906002006-02-24 16:46:40 +00001072 } else if (DerivedTypeDesc *DerivedTy = dyn_cast<DerivedTypeDesc>(TyDesc)) {
Jim Laskey69906002006-02-24 16:46:40 +00001073 // Create specific DIE.
Jim Laskey9c4447a2006-03-01 20:39:36 +00001074 Slot = Ty = new DIE(DerivedTy->getTag());
Jim Laskey69906002006-02-24 16:46:40 +00001075
1076 // Map to main type, void will not have a type.
1077 if (TypeDesc *FromTy = DerivedTy->getFromType()) {
Jim Laskey92ae7402006-03-01 18:20:30 +00001078 Ty->AddDIEntry(DW_AT_type, DW_FORM_ref4, NewType(Context, FromTy));
Jim Laskey69906002006-02-24 16:46:40 +00001079 }
Jim Laskeyf8913f12006-03-01 17:53:02 +00001080 } else if (CompositeTypeDesc *CompTy = dyn_cast<CompositeTypeDesc>(TyDesc)) {
Jim Laskeyf8913f12006-03-01 17:53:02 +00001081 // Create specific DIE.
Jim Laskey9c4447a2006-03-01 20:39:36 +00001082 Slot = Ty = new DIE(CompTy->getTag());
Jim Laskeyf8913f12006-03-01 17:53:02 +00001083 std::vector<DebugInfoDesc *> &Elements = CompTy->getElements();
1084
1085 switch (CompTy->getTag()) {
Jim Laskey9c4447a2006-03-01 20:39:36 +00001086 case DW_TAG_array_type: {
Jim Laskeyf8913f12006-03-01 17:53:02 +00001087 // Add element type.
1088 if (TypeDesc *FromTy = CompTy->getFromType()) {
Jim Laskey92ae7402006-03-01 18:20:30 +00001089 Ty->AddDIEntry(DW_AT_type, DW_FORM_ref4, NewType(Context, FromTy));
Jim Laskeyf8913f12006-03-01 17:53:02 +00001090 }
1091 // Don't emit size attribute.
1092 Size = 0;
1093
1094 // Construct an anonymous type for index type.
1095 DIE *IndexTy = new DIE(DW_TAG_base_type);
1096 IndexTy->AddUInt(DW_AT_byte_size, 0, 4);
1097 IndexTy->AddUInt(DW_AT_encoding, DW_FORM_data1, DW_ATE_signed);
1098 // Add to context.
Jim Laskey92ae7402006-03-01 18:20:30 +00001099 Context->AddChild(IndexTy);
Jim Laskeyf8913f12006-03-01 17:53:02 +00001100
1101 // Add subranges to array type.
1102 for(unsigned i = 0, N = Elements.size(); i < N; ++i) {
1103 SubrangeDesc *SRD = cast<SubrangeDesc>(Elements[i]);
1104 int64_t Lo = SRD->getLo();
1105 int64_t Hi = SRD->getHi();
1106 DIE *Subrange = new DIE(DW_TAG_subrange_type);
1107
1108 // If a range is available.
1109 if (Lo != Hi) {
1110 Subrange->AddDIEntry(DW_AT_type, DW_FORM_ref4, IndexTy);
1111 // Only add low if non-zero.
Jim Laskey6a3eb012006-03-01 23:52:37 +00001112 if (Lo) Subrange->AddSInt(DW_AT_lower_bound, 0, Lo);
1113 Subrange->AddSInt(DW_AT_upper_bound, 0, Hi);
Jim Laskeyf8913f12006-03-01 17:53:02 +00001114 }
1115 Ty->AddChild(Subrange);
1116 }
1117
1118 break;
1119 }
Jim Laskey9c4447a2006-03-01 20:39:36 +00001120 case DW_TAG_structure_type: {
Jim Laskeyf8913f12006-03-01 17:53:02 +00001121 break;
1122 }
Jim Laskey9c4447a2006-03-01 20:39:36 +00001123 case DW_TAG_union_type: {
Jim Laskeyf8913f12006-03-01 17:53:02 +00001124 break;
1125 }
Jim Laskey9c4447a2006-03-01 20:39:36 +00001126 case DW_TAG_enumeration_type: {
Jim Laskey6a3eb012006-03-01 23:52:37 +00001127 // Add enumerators to enumeration type.
1128 for(unsigned i = 0, N = Elements.size(); i < N; ++i) {
1129 EnumeratorDesc *ED = cast<EnumeratorDesc>(Elements[i]);
1130 const std::string &Name = ED->getName();
1131 int64_t Value = ED->getValue();
1132 DIE *Enumerator = new DIE(DW_TAG_enumerator);
1133 Enumerator->AddString(DW_AT_name, DW_FORM_string, Name);
1134 Enumerator->AddSInt(DW_AT_const_value, DW_FORM_sdata, Value);
1135 Ty->AddChild(Enumerator);
1136 }
1137
Jim Laskeyf8913f12006-03-01 17:53:02 +00001138 break;
1139 }
1140 default: break;
1141 }
Jim Laskeyf4afdd92006-02-23 16:58:18 +00001142 }
Jim Laskey434b40b2006-02-23 22:37:30 +00001143
1144 assert(Ty && "Type not supported yet");
Jim Laskeyf4afdd92006-02-23 16:58:18 +00001145
Jim Laskey69906002006-02-24 16:46:40 +00001146 // Add size if non-zero (derived types don't have a size.)
Jim Laskey434b40b2006-02-23 22:37:30 +00001147 if (Size) Ty->AddUInt(DW_AT_byte_size, 0, Size);
Jim Laskey69906002006-02-24 16:46:40 +00001148 // Add name if not anonymous or intermediate type.
Jim Laskey434b40b2006-02-23 22:37:30 +00001149 if (!Name.empty()) Ty->AddString(DW_AT_name, DW_FORM_string, Name);
Jim Laskey69906002006-02-24 16:46:40 +00001150 // Add source line info if present.
1151 if (CompileUnitDesc *File = TyDesc->getFile()) {
Jim Laskeybd761842006-02-27 17:27:12 +00001152 CompileUnit *FileUnit = FindCompileUnit(File);
1153 unsigned FileID = FileUnit->getID();
Jim Laskey69906002006-02-24 16:46:40 +00001154 int Line = TyDesc->getLine();
1155 Ty->AddUInt(DW_AT_decl_file, 0, FileID);
1156 Ty->AddUInt(DW_AT_decl_line, 0, Line);
1157 }
Jim Laskey434b40b2006-02-23 22:37:30 +00001158
Jim Laskeyf4afdd92006-02-23 16:58:18 +00001159 // Add to context owner.
Jim Laskey92ae7402006-03-01 18:20:30 +00001160 Context->AddChild(Ty);
Jim Laskeyf4afdd92006-02-23 16:58:18 +00001161
1162 return Slot;
1163}
1164
Jim Laskeybd761842006-02-27 17:27:12 +00001165/// NewCompileUnit - Create new compile unit and it's die.
Jim Laskey063e7652006-01-17 17:31:53 +00001166///
Jim Laskeybd761842006-02-27 17:27:12 +00001167CompileUnit *DwarfWriter::NewCompileUnit(CompileUnitDesc *UnitDesc,
1168 unsigned ID) {
1169 // Construct debug information entry.
1170 DIE *Die = new DIE(DW_TAG_compile_unit);
1171 Die->AddLabel (DW_AT_stmt_list, DW_FORM_data4, DWLabel("line", 0));
1172 Die->AddLabel (DW_AT_high_pc, DW_FORM_addr, DWLabel("text_end", 0));
1173 Die->AddLabel (DW_AT_low_pc, DW_FORM_addr, DWLabel("text_begin", 0));
1174 Die->AddString(DW_AT_producer, DW_FORM_string, UnitDesc->getProducer());
1175 Die->AddUInt (DW_AT_language, DW_FORM_data1, UnitDesc->getLanguage());
1176 Die->AddString(DW_AT_name, DW_FORM_string, UnitDesc->getFileName());
1177 Die->AddString(DW_AT_comp_dir, DW_FORM_string, UnitDesc->getDirectory());
1178
1179 // Add die to descriptor map.
1180 DescToDieMap[UnitDesc] = Die;
1181
1182 // Construct compile unit.
1183 CompileUnit *Unit = new CompileUnit(UnitDesc, ID, Die);
1184
1185 // Add Unit to compile unit map.
1186 DescToUnitMap[UnitDesc] = Unit;
1187
1188 return Unit;
1189}
Jim Laskey0420f2a2006-02-22 19:02:11 +00001190
Jim Laskeybd761842006-02-27 17:27:12 +00001191/// FindCompileUnit - Get the compile unit for the given descriptor.
1192///
1193CompileUnit *DwarfWriter::FindCompileUnit(CompileUnitDesc *UnitDesc) {
1194 CompileUnit *Unit = DescToUnitMap[UnitDesc];
1195 assert(Unit && "Missing compile unit.");
Jim Laskeyd18e2892006-01-20 20:34:06 +00001196 return Unit;
Jim Laskey063e7652006-01-17 17:31:53 +00001197}
1198
Jim Laskey0420f2a2006-02-22 19:02:11 +00001199/// NewGlobalVariable - Add a new global variable DIE.
1200///
1201DIE *DwarfWriter::NewGlobalVariable(GlobalVariableDesc *GVD) {
1202 // Check for pre-existence.
1203 DIE *&Slot = DescToDieMap[GVD];
1204 if (Slot) return Slot;
1205
1206 // Get the compile unit context.
Jim Laskeybd761842006-02-27 17:27:12 +00001207 CompileUnitDesc *UnitDesc = static_cast<CompileUnitDesc *>(GVD->getContext());
1208 CompileUnit *Unit = FindCompileUnit(UnitDesc);
Jim Laskey0420f2a2006-02-22 19:02:11 +00001209 // Get the global variable itself.
1210 GlobalVariable *GV = GVD->getGlobalVariable();
1211 // Generate the mangled name.
1212 std::string MangledName = Asm->Mang->getValueName(GV);
1213
1214 // Gather the details (simplify add attribute code.)
1215 const std::string &Name = GVD->getName();
Jim Laskeybd761842006-02-27 17:27:12 +00001216 unsigned FileID = Unit->getID();
Jim Laskey0420f2a2006-02-22 19:02:11 +00001217 unsigned Line = GVD->getLine();
1218
Jim Laskeyf4afdd92006-02-23 16:58:18 +00001219 // Get the global's type.
Jim Laskey92ae7402006-03-01 18:20:30 +00001220 DIE *Type = NewType(Unit->getDie(), GVD->getTypeDesc());
Jim Laskeyf4afdd92006-02-23 16:58:18 +00001221
1222 // Create the globale variable DIE.
Jim Laskey0420f2a2006-02-22 19:02:11 +00001223 DIE *VariableDie = new DIE(DW_TAG_variable);
1224 VariableDie->AddString (DW_AT_name, DW_FORM_string, Name);
1225 VariableDie->AddUInt (DW_AT_decl_file, 0, FileID);
1226 VariableDie->AddUInt (DW_AT_decl_line, 0, Line);
1227 VariableDie->AddDIEntry (DW_AT_type, DW_FORM_ref4, Type);
1228 VariableDie->AddUInt (DW_AT_external, DW_FORM_flag, 1);
1229 // FIXME - needs to be a proper expression.
1230 VariableDie->AddObjectLabel(DW_AT_location, DW_FORM_block1, MangledName);
1231
1232 // Add to map.
1233 Slot = VariableDie;
1234
1235 // Add to context owner.
Jim Laskeybd761842006-02-27 17:27:12 +00001236 Unit->getDie()->AddChild(VariableDie);
Jim Laskey0420f2a2006-02-22 19:02:11 +00001237
1238 // Expose as global.
Jim Laskeybd761842006-02-27 17:27:12 +00001239 // FIXME - need to check external flag.
1240 Unit->AddGlobal(Name, VariableDie);
Jim Laskey0420f2a2006-02-22 19:02:11 +00001241
1242 return VariableDie;
1243}
1244
1245/// NewSubprogram - Add a new subprogram DIE.
1246///
1247DIE *DwarfWriter::NewSubprogram(SubprogramDesc *SPD) {
1248 // Check for pre-existence.
1249 DIE *&Slot = DescToDieMap[SPD];
1250 if (Slot) return Slot;
1251
1252 // Get the compile unit context.
Jim Laskeybd761842006-02-27 17:27:12 +00001253 CompileUnitDesc *UnitDesc = static_cast<CompileUnitDesc *>(SPD->getContext());
1254 CompileUnit *Unit = FindCompileUnit(UnitDesc);
Jim Laskey0420f2a2006-02-22 19:02:11 +00001255
1256 // Gather the details (simplify add attribute code.)
1257 const std::string &Name = SPD->getName();
Jim Laskeybd761842006-02-27 17:27:12 +00001258 unsigned FileID = Unit->getID();
Jim Laskey0420f2a2006-02-22 19:02:11 +00001259 // FIXME - faking the line for the time being.
1260 unsigned Line = 1;
1261
1262 // FIXME - faking the type for the time being.
Jim Laskey92ae7402006-03-01 18:20:30 +00001263 DIE *Type = NewBasicType(Unit->getDie(), Type::IntTy);
Jim Laskey0420f2a2006-02-22 19:02:11 +00001264
Jim Laskey8a8e9752006-02-27 20:37:42 +00001265 DIE *SubprogramDie = new DIE(DW_TAG_subprogram);
Jim Laskey0420f2a2006-02-22 19:02:11 +00001266 SubprogramDie->AddString (DW_AT_name, DW_FORM_string, Name);
1267 SubprogramDie->AddUInt (DW_AT_decl_file, 0, FileID);
1268 SubprogramDie->AddUInt (DW_AT_decl_line, 0, Line);
1269 SubprogramDie->AddDIEntry (DW_AT_type, DW_FORM_ref4, Type);
1270 SubprogramDie->AddUInt (DW_AT_external, DW_FORM_flag, 1);
1271
1272 // Add to map.
1273 Slot = SubprogramDie;
1274
1275 // Add to context owner.
Jim Laskeybd761842006-02-27 17:27:12 +00001276 Unit->getDie()->AddChild(SubprogramDie);
Jim Laskey0420f2a2006-02-22 19:02:11 +00001277
1278 // Expose as global.
Jim Laskeybd761842006-02-27 17:27:12 +00001279 Unit->AddGlobal(Name, SubprogramDie);
Jim Laskey0420f2a2006-02-22 19:02:11 +00001280
1281 return SubprogramDie;
1282}
1283
Jim Laskey063e7652006-01-17 17:31:53 +00001284/// EmitInitial - Emit initial Dwarf declarations. This is necessary for cc
1285/// tools to recognize the object file contains Dwarf information.
Jim Laskeyb2efb852006-01-04 22:28:25 +00001286///
1287void DwarfWriter::EmitInitial() const {
Jim Laskey063e7652006-01-17 17:31:53 +00001288 // Dwarf sections base addresses.
Jim Laskey0420f2a2006-02-22 19:02:11 +00001289 Asm->SwitchSection(DwarfFrameSection, 0);
1290 EmitLabel("section_frame", 0);
Jim Laskeya7cea6f2006-01-04 13:52:30 +00001291 Asm->SwitchSection(DwarfInfoSection, 0);
Jim Laskey0420f2a2006-02-22 19:02:11 +00001292 EmitLabel("section_info", 0);
Jim Laskeya7cea6f2006-01-04 13:52:30 +00001293 EmitLabel("info", 0);
Jim Laskey0420f2a2006-02-22 19:02:11 +00001294 Asm->SwitchSection(DwarfAbbrevSection, 0);
1295 EmitLabel("section_abbrev", 0);
1296 EmitLabel("abbrev", 0);
1297 Asm->SwitchSection(DwarfARangesSection, 0);
1298 EmitLabel("section_aranges", 0);
1299 Asm->SwitchSection(DwarfMacInfoSection, 0);
1300 EmitLabel("section_macinfo", 0);
Jim Laskeya7cea6f2006-01-04 13:52:30 +00001301 Asm->SwitchSection(DwarfLineSection, 0);
Jim Laskey0420f2a2006-02-22 19:02:11 +00001302 EmitLabel("section_line", 0);
Jim Laskeya7cea6f2006-01-04 13:52:30 +00001303 EmitLabel("line", 0);
Jim Laskey0420f2a2006-02-22 19:02:11 +00001304 Asm->SwitchSection(DwarfLocSection, 0);
1305 EmitLabel("section_loc", 0);
1306 Asm->SwitchSection(DwarfPubNamesSection, 0);
1307 EmitLabel("section_pubnames", 0);
1308 Asm->SwitchSection(DwarfStrSection, 0);
1309 EmitLabel("section_str", 0);
1310 Asm->SwitchSection(DwarfRangesSection, 0);
1311 EmitLabel("section_ranges", 0);
1312
Jim Laskey063e7652006-01-17 17:31:53 +00001313 Asm->SwitchSection(TextSection, 0);
1314 EmitLabel("text_begin", 0);
1315 Asm->SwitchSection(DataSection, 0);
1316 EmitLabel("data_begin", 0);
Jim Laskeya7cea6f2006-01-04 13:52:30 +00001317}
1318
Jim Laskey063e7652006-01-17 17:31:53 +00001319/// EmitDIE - Recusively Emits a debug information entry.
1320///
1321void DwarfWriter::EmitDIE(DIE *Die) const {
1322 // Get the abbreviation for this DIE.
1323 unsigned AbbrevID = Die->getAbbrevID();
1324 const DIEAbbrev &Abbrev = Abbreviations[AbbrevID];
Jim Laskey0d086af2006-02-27 12:43:29 +00001325
1326 O << "\n";
Jim Laskey063e7652006-01-17 17:31:53 +00001327
1328 // Emit the code (index) for the abbreviation.
1329 EmitULEB128Bytes(AbbrevID);
1330 EOL(std::string("Abbrev [" +
1331 utostr(AbbrevID) +
Jim Laskey0d086af2006-02-27 12:43:29 +00001332 "] 0x" + utohexstr(Die->getOffset()) +
1333 ":0x" + utohexstr(Die->getSize()) + " " +
1334 TagString(Abbrev.getTag())));
Jim Laskey063e7652006-01-17 17:31:53 +00001335
1336 const std::vector<DIEValue *> &Values = Die->getValues();
Jim Laskeyd18e2892006-01-20 20:34:06 +00001337 const std::vector<DIEAbbrevData> &AbbrevData = Abbrev.getData();
Jim Laskey063e7652006-01-17 17:31:53 +00001338
1339 // Emit the DIE attribute values.
Jim Laskey52060a02006-01-24 00:49:18 +00001340 for (unsigned i = 0, N = Values.size(); i < N; ++i) {
Jim Laskeyd18e2892006-01-20 20:34:06 +00001341 unsigned Attr = AbbrevData[i].getAttribute();
1342 unsigned Form = AbbrevData[i].getForm();
Jim Laskey063e7652006-01-17 17:31:53 +00001343 assert(Form && "Too many attributes for DIE (check abbreviation)");
1344
1345 switch (Attr) {
1346 case DW_AT_sibling: {
Jim Laskeyda427fa2006-01-27 20:31:25 +00001347 EmitInt32(Die->SiblingOffset());
Jim Laskey063e7652006-01-17 17:31:53 +00001348 break;
1349 }
1350 default: {
1351 // Emit an attribute using the defined form.
1352 Values[i]->EmitValue(*this, Form);
1353 break;
1354 }
1355 }
1356
1357 EOL(AttributeString(Attr));
1358 }
1359
1360 // Emit the DIE children if any.
1361 if (Abbrev.getChildrenFlag() == DW_CHILDREN_yes) {
1362 const std::vector<DIE *> &Children = Die->getChildren();
1363
Jim Laskey52060a02006-01-24 00:49:18 +00001364 for (unsigned j = 0, M = Children.size(); j < M; ++j) {
Jim Laskey063e7652006-01-17 17:31:53 +00001365 // FIXME - handle sibling offsets.
1366 // FIXME - handle all DIE types.
1367 EmitDIE(Children[j]);
1368 }
1369
Jim Laskeyda427fa2006-01-27 20:31:25 +00001370 EmitInt8(0); EOL("End Of Children Mark");
Jim Laskey063e7652006-01-17 17:31:53 +00001371 }
1372}
1373
1374/// SizeAndOffsetDie - Compute the size and offset of a DIE.
1375///
Jim Laskey0420f2a2006-02-22 19:02:11 +00001376unsigned DwarfWriter::SizeAndOffsetDie(DIE *Die, unsigned Offset) {
1377 // Record the abbreviation.
1378 Die->Complete(*this);
1379
Jim Laskey063e7652006-01-17 17:31:53 +00001380 // Get the abbreviation for this DIE.
1381 unsigned AbbrevID = Die->getAbbrevID();
1382 const DIEAbbrev &Abbrev = Abbreviations[AbbrevID];
1383
1384 // Set DIE offset
1385 Die->setOffset(Offset);
1386
1387 // Start the size with the size of abbreviation code.
1388 Offset += SizeULEB128(AbbrevID);
1389
1390 const std::vector<DIEValue *> &Values = Die->getValues();
Jim Laskeyd18e2892006-01-20 20:34:06 +00001391 const std::vector<DIEAbbrevData> &AbbrevData = Abbrev.getData();
Jim Laskey063e7652006-01-17 17:31:53 +00001392
1393 // Emit the DIE attribute values.
Jim Laskey52060a02006-01-24 00:49:18 +00001394 for (unsigned i = 0, N = Values.size(); i < N; ++i) {
Jim Laskey063e7652006-01-17 17:31:53 +00001395 // Size attribute value.
Jim Laskeyd18e2892006-01-20 20:34:06 +00001396 Offset += Values[i]->SizeOf(*this, AbbrevData[i].getForm());
Jim Laskey063e7652006-01-17 17:31:53 +00001397 }
1398
1399 // Emit the DIE children if any.
1400 if (Abbrev.getChildrenFlag() == DW_CHILDREN_yes) {
1401 const std::vector<DIE *> &Children = Die->getChildren();
1402
Jim Laskey52060a02006-01-24 00:49:18 +00001403 for (unsigned j = 0, M = Children.size(); j < M; ++j) {
Jim Laskey063e7652006-01-17 17:31:53 +00001404 // FIXME - handle sibling offsets.
1405 // FIXME - handle all DIE types.
1406 Offset = SizeAndOffsetDie(Children[j], Offset);
1407 }
1408
1409 // End of children marker.
1410 Offset += sizeof(int8_t);
1411 }
1412
1413 Die->setSize(Offset - Die->getOffset());
1414 return Offset;
1415}
1416
1417/// SizeAndOffsets - Compute the size and offset of all the DIEs.
1418///
1419void DwarfWriter::SizeAndOffsets() {
Jim Laskey063e7652006-01-17 17:31:53 +00001420
1421 // Process each compile unit.
Jim Laskey52060a02006-01-24 00:49:18 +00001422 for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i) {
Jim Laskeybd761842006-02-27 17:27:12 +00001423 CompileUnit *Unit = CompileUnits[i];
1424 if (Unit->hasContent()) {
1425 // Compute size of compile unit header
1426 unsigned Offset = sizeof(int32_t) + // Length of Compilation Unit Info
1427 sizeof(int16_t) + // DWARF version number
1428 sizeof(int32_t) + // Offset Into Abbrev. Section
1429 sizeof(int8_t); // Pointer Size (in bytes)
1430
1431 SizeAndOffsetDie(Unit->getDie(), Offset);
1432 }
Jim Laskey063e7652006-01-17 17:31:53 +00001433 }
1434}
1435
1436/// EmitDebugInfo - Emit the debug info section.
1437///
1438void DwarfWriter::EmitDebugInfo() const {
1439 // Start debug info section.
1440 Asm->SwitchSection(DwarfInfoSection, 0);
1441
Jim Laskeybd761842006-02-27 17:27:12 +00001442 // Process each compile unit.
1443 for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i) {
1444 CompileUnit *Unit = CompileUnits[i];
1445
1446 if (Unit->hasContent()) {
1447 DIE *Die = Unit->getDie();
Jim Laskey0d086af2006-02-27 12:43:29 +00001448 // Emit the compile units header.
Jim Laskeybd761842006-02-27 17:27:12 +00001449 EmitLabel("info_begin", Unit->getID());
Jim Laskey0d086af2006-02-27 12:43:29 +00001450 // Emit size of content not including length itself
Jim Laskeybd761842006-02-27 17:27:12 +00001451 unsigned ContentSize = Die->getSize() +
Jim Laskey0d086af2006-02-27 12:43:29 +00001452 sizeof(int16_t) + // DWARF version number
1453 sizeof(int32_t) + // Offset Into Abbrev. Section
1454 sizeof(int8_t); // Pointer Size (in bytes)
1455
1456 EmitInt32(ContentSize); EOL("Length of Compilation Unit Info");
1457 EmitInt16(DWARF_VERSION); EOL("DWARF version number");
1458 EmitReference("abbrev_begin", 0); EOL("Offset Into Abbrev. Section");
1459 EmitInt8(AddressSize); EOL("Address Size (in bytes)");
1460
Jim Laskeybd761842006-02-27 17:27:12 +00001461 EmitDIE(Die);
1462 EmitLabel("info_end", Unit->getID());
Jim Laskey063e7652006-01-17 17:31:53 +00001463 }
Jim Laskey0d086af2006-02-27 12:43:29 +00001464
1465 O << "\n";
Jim Laskey063e7652006-01-17 17:31:53 +00001466 }
1467}
1468
1469/// EmitAbbreviations - Emit the abbreviation section.
1470///
1471void DwarfWriter::EmitAbbreviations() const {
Jim Laskeyd18e2892006-01-20 20:34:06 +00001472 // Check to see if it is worth the effort.
1473 if (!Abbreviations.empty()) {
1474 // Start the debug abbrev section.
1475 Asm->SwitchSection(DwarfAbbrevSection, 0);
Jim Laskey063e7652006-01-17 17:31:53 +00001476
Jim Laskeyd18e2892006-01-20 20:34:06 +00001477 EmitLabel("abbrev_begin", 0);
Jim Laskey063e7652006-01-17 17:31:53 +00001478
Jim Laskeyd18e2892006-01-20 20:34:06 +00001479 // For each abbrevation.
1480 for (unsigned AbbrevID = 1, NAID = Abbreviations.size();
Jim Laskey52060a02006-01-24 00:49:18 +00001481 AbbrevID <= NAID; ++AbbrevID) {
Jim Laskeyd18e2892006-01-20 20:34:06 +00001482 // Get abbreviation data
1483 const DIEAbbrev &Abbrev = Abbreviations[AbbrevID];
Jim Laskey063e7652006-01-17 17:31:53 +00001484
Jim Laskeyd18e2892006-01-20 20:34:06 +00001485 // Emit the abbrevations code (base 1 index.)
1486 EmitULEB128Bytes(AbbrevID); EOL("Abbreviation Code");
Jim Laskey063e7652006-01-17 17:31:53 +00001487
Jim Laskeyd18e2892006-01-20 20:34:06 +00001488 // Emit the abbreviations data.
1489 Abbrev.Emit(*this);
Jim Laskey0d086af2006-02-27 12:43:29 +00001490
1491 O << "\n";
Jim Laskey063e7652006-01-17 17:31:53 +00001492 }
Jim Laskeyd18e2892006-01-20 20:34:06 +00001493
1494 EmitLabel("abbrev_end", 0);
Jim Laskey0d086af2006-02-27 12:43:29 +00001495
1496 O << "\n";
Jim Laskey063e7652006-01-17 17:31:53 +00001497 }
1498}
1499
1500/// EmitDebugLines - Emit source line information.
1501///
1502void DwarfWriter::EmitDebugLines() const {
1503 // Minimum line delta, thus ranging from -10..(255-10).
1504 const int MinLineDelta = -(DW_LNS_fixed_advance_pc + 1);
1505 // Maximum line delta, thus ranging from -10..(255-10).
1506 const int MaxLineDelta = 255 + MinLineDelta;
1507
1508 // Start the dwarf line section.
1509 Asm->SwitchSection(DwarfLineSection, 0);
1510
1511 // Construct the section header.
1512
1513 EmitDifference("line_end", 0, "line_begin", 0);
1514 EOL("Length of Source Line Info");
1515 EmitLabel("line_begin", 0);
1516
Jim Laskeyda427fa2006-01-27 20:31:25 +00001517 EmitInt16(DWARF_VERSION); EOL("DWARF version number");
Jim Laskey063e7652006-01-17 17:31:53 +00001518
1519 EmitDifference("line_prolog_end", 0, "line_prolog_begin", 0);
1520 EOL("Prolog Length");
1521 EmitLabel("line_prolog_begin", 0);
1522
Jim Laskeyda427fa2006-01-27 20:31:25 +00001523 EmitInt8(1); EOL("Minimum Instruction Length");
Jim Laskey063e7652006-01-17 17:31:53 +00001524
Jim Laskeyda427fa2006-01-27 20:31:25 +00001525 EmitInt8(1); EOL("Default is_stmt_start flag");
Jim Laskey063e7652006-01-17 17:31:53 +00001526
Jim Laskeyda427fa2006-01-27 20:31:25 +00001527 EmitInt8(MinLineDelta); EOL("Line Base Value (Special Opcodes)");
Jim Laskey063e7652006-01-17 17:31:53 +00001528
Jim Laskeyda427fa2006-01-27 20:31:25 +00001529 EmitInt8(MaxLineDelta); EOL("Line Range Value (Special Opcodes)");
Jim Laskey063e7652006-01-17 17:31:53 +00001530
Jim Laskeyda427fa2006-01-27 20:31:25 +00001531 EmitInt8(-MinLineDelta); EOL("Special Opcode Base");
Jim Laskey063e7652006-01-17 17:31:53 +00001532
1533 // Line number standard opcode encodings argument count
Jim Laskeyda427fa2006-01-27 20:31:25 +00001534 EmitInt8(0); EOL("DW_LNS_copy arg count");
1535 EmitInt8(1); EOL("DW_LNS_advance_pc arg count");
1536 EmitInt8(1); EOL("DW_LNS_advance_line arg count");
1537 EmitInt8(1); EOL("DW_LNS_set_file arg count");
1538 EmitInt8(1); EOL("DW_LNS_set_column arg count");
1539 EmitInt8(0); EOL("DW_LNS_negate_stmt arg count");
1540 EmitInt8(0); EOL("DW_LNS_set_basic_block arg count");
1541 EmitInt8(0); EOL("DW_LNS_const_add_pc arg count");
1542 EmitInt8(1); EOL("DW_LNS_fixed_advance_pc arg count");
Jim Laskey063e7652006-01-17 17:31:53 +00001543
1544 const UniqueVector<std::string> &Directories = DebugInfo->getDirectories();
1545 const UniqueVector<SourceFileInfo> &SourceFiles = DebugInfo->getSourceFiles();
1546
1547 // Emit directories.
1548 for (unsigned DirectoryID = 1, NDID = Directories.size();
Jim Laskey52060a02006-01-24 00:49:18 +00001549 DirectoryID <= NDID; ++DirectoryID) {
Jim Laskey063e7652006-01-17 17:31:53 +00001550 EmitString(Directories[DirectoryID]); EOL("Directory");
1551 }
Jim Laskeyda427fa2006-01-27 20:31:25 +00001552 EmitInt8(0); EOL("End of directories");
Jim Laskey063e7652006-01-17 17:31:53 +00001553
1554 // Emit files.
1555 for (unsigned SourceID = 1, NSID = SourceFiles.size();
Jim Laskey52060a02006-01-24 00:49:18 +00001556 SourceID <= NSID; ++SourceID) {
Jim Laskey063e7652006-01-17 17:31:53 +00001557 const SourceFileInfo &SourceFile = SourceFiles[SourceID];
1558 EmitString(SourceFile.getName()); EOL("Source");
1559 EmitULEB128Bytes(SourceFile.getDirectoryID()); EOL("Directory #");
1560 EmitULEB128Bytes(0); EOL("Mod date");
1561 EmitULEB128Bytes(0); EOL("File size");
1562 }
Jim Laskeyda427fa2006-01-27 20:31:25 +00001563 EmitInt8(0); EOL("End of files");
Jim Laskey063e7652006-01-17 17:31:53 +00001564
1565 EmitLabel("line_prolog_end", 0);
1566
1567 // Emit line information
1568 const std::vector<SourceLineInfo *> &LineInfos = DebugInfo->getSourceLines();
1569
1570 // Dwarf assumes we start with first line of first source file.
1571 unsigned Source = 1;
1572 unsigned Line = 1;
1573
1574 // Construct rows of the address, source, line, column matrix.
Jim Laskey52060a02006-01-24 00:49:18 +00001575 for (unsigned i = 0, N = LineInfos.size(); i < N; ++i) {
Jim Laskey063e7652006-01-17 17:31:53 +00001576 SourceLineInfo *LineInfo = LineInfos[i];
Jim Laskey0420f2a2006-02-22 19:02:11 +00001577
1578 if (DwarfVerbose) {
1579 unsigned SourceID = LineInfo->getSourceID();
1580 const SourceFileInfo &SourceFile = SourceFiles[SourceID];
1581 unsigned DirectoryID = SourceFile.getDirectoryID();
1582 O << "\t"
1583 << Asm->CommentString << " "
1584 << Directories[DirectoryID]
1585 << SourceFile.getName() << ":"
1586 << LineInfo->getLine() << "\n";
1587 }
Jim Laskey063e7652006-01-17 17:31:53 +00001588
1589 // Define the line address.
Jim Laskeyda427fa2006-01-27 20:31:25 +00001590 EmitInt8(0); EOL("Extended Op");
1591 EmitInt8(4 + 1); EOL("Op size");
1592 EmitInt8(DW_LNE_set_address); EOL("DW_LNE_set_address");
Jim Laskeye719a7c2006-01-18 16:54:26 +00001593 EmitReference("loc", i + 1); EOL("Location label");
Jim Laskey063e7652006-01-17 17:31:53 +00001594
1595 // If change of source, then switch to the new source.
1596 if (Source != LineInfo->getSourceID()) {
1597 Source = LineInfo->getSourceID();
Jim Laskeyda427fa2006-01-27 20:31:25 +00001598 EmitInt8(DW_LNS_set_file); EOL("DW_LNS_set_file");
Jim Laskeybd761842006-02-27 17:27:12 +00001599 EmitULEB128Bytes(Source); EOL("New Source");
Jim Laskey063e7652006-01-17 17:31:53 +00001600 }
1601
1602 // If change of line.
1603 if (Line != LineInfo->getLine()) {
1604 // Determine offset.
1605 int Offset = LineInfo->getLine() - Line;
1606 int Delta = Offset - MinLineDelta;
1607
1608 // Update line.
1609 Line = LineInfo->getLine();
1610
1611 // If delta is small enough and in range...
1612 if (Delta >= 0 && Delta < (MaxLineDelta - 1)) {
1613 // ... then use fast opcode.
Jim Laskeyda427fa2006-01-27 20:31:25 +00001614 EmitInt8(Delta - MinLineDelta); EOL("Line Delta");
Jim Laskey063e7652006-01-17 17:31:53 +00001615 } else {
1616 // ... otherwise use long hand.
Jim Laskeyda427fa2006-01-27 20:31:25 +00001617 EmitInt8(DW_LNS_advance_line); EOL("DW_LNS_advance_line");
Jim Laskey063e7652006-01-17 17:31:53 +00001618 EmitSLEB128Bytes(Offset); EOL("Line Offset");
Jim Laskeyda427fa2006-01-27 20:31:25 +00001619 EmitInt8(DW_LNS_copy); EOL("DW_LNS_copy");
Jim Laskey063e7652006-01-17 17:31:53 +00001620 }
1621 } else {
1622 // Copy the previous row (different address or source)
Jim Laskeyda427fa2006-01-27 20:31:25 +00001623 EmitInt8(DW_LNS_copy); EOL("DW_LNS_copy");
Jim Laskey063e7652006-01-17 17:31:53 +00001624 }
1625 }
1626
Jim Laskey0420f2a2006-02-22 19:02:11 +00001627 // Define last address.
1628 EmitInt8(0); EOL("Extended Op");
1629 EmitInt8(4 + 1); EOL("Op size");
1630 EmitInt8(DW_LNE_set_address); EOL("DW_LNE_set_address");
1631 EmitReference("text_end", 0); EOL("Location label");
1632
Jim Laskey063e7652006-01-17 17:31:53 +00001633 // Mark end of matrix.
Jim Laskeyda427fa2006-01-27 20:31:25 +00001634 EmitInt8(0); EOL("DW_LNE_end_sequence");
Jim Laskey063e7652006-01-17 17:31:53 +00001635 EmitULEB128Bytes(1); O << "\n";
Jim Laskeyda427fa2006-01-27 20:31:25 +00001636 EmitInt8(1); O << "\n";
Jim Laskey063e7652006-01-17 17:31:53 +00001637
1638 EmitLabel("line_end", 0);
Jim Laskey0d086af2006-02-27 12:43:29 +00001639
1640 O << "\n";
Jim Laskey063e7652006-01-17 17:31:53 +00001641}
Jim Laskey19ef4ef2006-01-17 20:41:40 +00001642
1643/// EmitDebugFrame - Emit visible names into a debug frame section.
1644///
1645void DwarfWriter::EmitDebugFrame() {
Jim Laskeye719a7c2006-01-18 16:54:26 +00001646 // FIXME - Should be per frame
Jim Laskey19ef4ef2006-01-17 20:41:40 +00001647}
1648
1649/// EmitDebugPubNames - Emit visible names into a debug pubnames section.
1650///
1651void DwarfWriter::EmitDebugPubNames() {
Jim Laskeybd761842006-02-27 17:27:12 +00001652 // Start the dwarf pubnames section.
1653 Asm->SwitchSection(DwarfPubNamesSection, 0);
Jim Laskeyd18e2892006-01-20 20:34:06 +00001654
Jim Laskeybd761842006-02-27 17:27:12 +00001655 // Process each compile unit.
1656 for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i) {
1657 CompileUnit *Unit = CompileUnits[i];
Jim Laskeyd18e2892006-01-20 20:34:06 +00001658
Jim Laskeybd761842006-02-27 17:27:12 +00001659 if (Unit->hasContent()) {
1660 EmitDifference("pubnames_end", Unit->getID(),
1661 "pubnames_begin", Unit->getID());
1662 EOL("Length of Public Names Info");
1663
1664 EmitLabel("pubnames_begin", Unit->getID());
1665
1666 EmitInt16(DWARF_VERSION); EOL("DWARF Version");
1667
1668 EmitReference("info_begin", Unit->getID());
1669 EOL("Offset of Compilation Unit Info");
Jim Laskeyd18e2892006-01-20 20:34:06 +00001670
Jim Laskeybd761842006-02-27 17:27:12 +00001671 EmitDifference("info_end", Unit->getID(), "info_begin", Unit->getID());
1672 EOL("Compilation Unit Length");
1673
1674 std::map<std::string, DIE *> &Globals = Unit->getGlobals();
1675
1676 for (std::map<std::string, DIE *>::iterator GI = Globals.begin(),
1677 GE = Globals.end();
1678 GI != GE; ++GI) {
1679 const std::string &Name = GI->first;
1680 DIE * Entity = GI->second;
1681
1682 EmitInt32(Entity->getOffset()); EOL("DIE offset");
1683 EmitString(Name); EOL("External Name");
1684 }
Jim Laskeyd18e2892006-01-20 20:34:06 +00001685
Jim Laskeybd761842006-02-27 17:27:12 +00001686 EmitInt32(0); EOL("End Mark");
1687 EmitLabel("pubnames_end", Unit->getID());
1688
1689 O << "\n";
Jim Laskeyd18e2892006-01-20 20:34:06 +00001690 }
Jim Laskeyd18e2892006-01-20 20:34:06 +00001691 }
Jim Laskey19ef4ef2006-01-17 20:41:40 +00001692}
1693
1694/// EmitDebugStr - Emit visible names into a debug str section.
1695///
1696void DwarfWriter::EmitDebugStr() {
Jim Laskeyd18e2892006-01-20 20:34:06 +00001697 // Check to see if it is worth the effort.
1698 if (!StringPool.empty()) {
1699 // Start the dwarf str section.
1700 Asm->SwitchSection(DwarfStrSection, 0);
1701
1702 // For each of strings in teh string pool.
1703 for (unsigned StringID = 1, N = StringPool.size();
Jim Laskey52060a02006-01-24 00:49:18 +00001704 StringID <= N; ++StringID) {
Jim Laskeyd18e2892006-01-20 20:34:06 +00001705 // Emit a label for reference from debug information entries.
1706 EmitLabel("string", StringID);
1707 // Emit the string itself.
1708 const std::string &String = StringPool[StringID];
1709 EmitString(String); O << "\n";
1710 }
Jim Laskey0d086af2006-02-27 12:43:29 +00001711
1712 O << "\n";
Jim Laskeyd18e2892006-01-20 20:34:06 +00001713 }
Jim Laskey19ef4ef2006-01-17 20:41:40 +00001714}
1715
1716/// EmitDebugLoc - Emit visible names into a debug loc section.
1717///
1718void DwarfWriter::EmitDebugLoc() {
Jim Laskeye719a7c2006-01-18 16:54:26 +00001719 // Start the dwarf loc section.
1720 Asm->SwitchSection(DwarfLocSection, 0);
Jim Laskey0d086af2006-02-27 12:43:29 +00001721
1722 O << "\n";
Jim Laskey19ef4ef2006-01-17 20:41:40 +00001723}
1724
1725/// EmitDebugARanges - Emit visible names into a debug aranges section.
1726///
1727void DwarfWriter::EmitDebugARanges() {
Jim Laskeye719a7c2006-01-18 16:54:26 +00001728 // Start the dwarf aranges section.
1729 Asm->SwitchSection(DwarfARangesSection, 0);
1730
1731 // FIXME - Mock up
Jim Laskeybd761842006-02-27 17:27:12 +00001732#if 0
1733 // Process each compile unit.
1734 for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i) {
1735 CompileUnit *Unit = CompileUnits[i];
1736
1737 if (Unit->hasContent()) {
1738 // Don't include size of length
1739 EmitInt32(0x1c); EOL("Length of Address Ranges Info");
1740
1741 EmitInt16(DWARF_VERSION); EOL("Dwarf Version");
1742
1743 EmitReference("info_begin", Unit->getID());
1744 EOL("Offset of Compilation Unit Info");
Jim Laskeye719a7c2006-01-18 16:54:26 +00001745
Jim Laskeybd761842006-02-27 17:27:12 +00001746 EmitInt8(AddressSize); EOL("Size of Address");
Jim Laskeye719a7c2006-01-18 16:54:26 +00001747
Jim Laskeybd761842006-02-27 17:27:12 +00001748 EmitInt8(0); EOL("Size of Segment Descriptor");
Jim Laskeye719a7c2006-01-18 16:54:26 +00001749
Jim Laskeybd761842006-02-27 17:27:12 +00001750 EmitInt16(0); EOL("Pad (1)");
1751 EmitInt16(0); EOL("Pad (2)");
Jim Laskeye719a7c2006-01-18 16:54:26 +00001752
Jim Laskeybd761842006-02-27 17:27:12 +00001753 // Range 1
1754 EmitReference("text_begin", 0); EOL("Address");
1755 EmitDifference("text_end", 0, "text_begin", 0); EOL("Length");
Jim Laskeye719a7c2006-01-18 16:54:26 +00001756
Jim Laskeybd761842006-02-27 17:27:12 +00001757 EmitInt32(0); EOL("EOM (1)");
1758 EmitInt32(0); EOL("EOM (2)");
1759
1760 O << "\n";
1761 }
1762 }
1763#endif
Jim Laskey19ef4ef2006-01-17 20:41:40 +00001764}
1765
1766/// EmitDebugRanges - Emit visible names into a debug ranges section.
1767///
1768void DwarfWriter::EmitDebugRanges() {
Jim Laskeye719a7c2006-01-18 16:54:26 +00001769 // Start the dwarf ranges section.
1770 Asm->SwitchSection(DwarfRangesSection, 0);
Jim Laskey0d086af2006-02-27 12:43:29 +00001771
1772 O << "\n";
Jim Laskey19ef4ef2006-01-17 20:41:40 +00001773}
1774
1775/// EmitDebugMacInfo - Emit visible names into a debug macinfo section.
1776///
1777void DwarfWriter::EmitDebugMacInfo() {
Jim Laskeye719a7c2006-01-18 16:54:26 +00001778 // Start the dwarf macinfo section.
1779 Asm->SwitchSection(DwarfMacInfoSection, 0);
Jim Laskey0d086af2006-02-27 12:43:29 +00001780
1781 O << "\n";
Jim Laskey19ef4ef2006-01-17 20:41:40 +00001782}
Jim Laskey063e7652006-01-17 17:31:53 +00001783
Jim Laskey52060a02006-01-24 00:49:18 +00001784/// ConstructCompileUnitDIEs - Create a compile unit DIE for each source and
1785/// header file.
1786void DwarfWriter::ConstructCompileUnitDIEs() {
Jim Laskey86cbdba2006-02-06 15:33:21 +00001787 const UniqueVector<CompileUnitDesc *> CUW = DebugInfo->getCompileUnits();
Jim Laskey6e87c0e2006-01-26 21:22:49 +00001788
1789 for (unsigned i = 1, N = CUW.size(); i <= N; ++i) {
Jim Laskeybd761842006-02-27 17:27:12 +00001790 CompileUnit *Unit = NewCompileUnit(CUW[i], i);
Jim Laskey52060a02006-01-24 00:49:18 +00001791 CompileUnits.push_back(Unit);
1792 }
1793}
1794
1795/// ConstructGlobalDIEs - Create DIEs for each of the externally visible global
1796/// variables.
1797void DwarfWriter::ConstructGlobalDIEs(Module &M) {
Jim Laskey86cbdba2006-02-06 15:33:21 +00001798 std::vector<GlobalVariableDesc *> GlobalVariables =
Jim Laskey0420f2a2006-02-22 19:02:11 +00001799 DebugInfo->getAnchoredDescriptors<GlobalVariableDesc>(M);
Jim Laskeyb3e789a2006-01-26 20:21:46 +00001800
1801 for (unsigned i = 0, N = GlobalVariables.size(); i < N; ++i) {
Jim Laskey86cbdba2006-02-06 15:33:21 +00001802 GlobalVariableDesc *GVD = GlobalVariables[i];
Jim Laskey0420f2a2006-02-22 19:02:11 +00001803 NewGlobalVariable(GVD);
Jim Laskey52060a02006-01-24 00:49:18 +00001804 }
1805}
1806
Jim Laskey0420f2a2006-02-22 19:02:11 +00001807/// ConstructSubprogramDIEs - Create DIEs for each of the externally visible
1808/// subprograms.
1809void DwarfWriter::ConstructSubprogramDIEs(Module &M) {
1810 std::vector<SubprogramDesc *> Subprograms =
1811 DebugInfo->getAnchoredDescriptors<SubprogramDesc>(M);
1812
1813 for (unsigned i = 0, N = Subprograms.size(); i < N; ++i) {
1814 SubprogramDesc *SPD = Subprograms[i];
1815 NewSubprogram(SPD);
1816 }
1817}
Jim Laskey52060a02006-01-24 00:49:18 +00001818
Jim Laskey063e7652006-01-17 17:31:53 +00001819/// ShouldEmitDwarf - Determine if Dwarf declarations should be made.
Jim Laskeyb2efb852006-01-04 22:28:25 +00001820///
1821bool DwarfWriter::ShouldEmitDwarf() {
1822 // Check if debug info is present.
1823 if (!DebugInfo || !DebugInfo->hasInfo()) return false;
1824
1825 // Make sure initial declarations are made.
1826 if (!didInitial) {
1827 EmitInitial();
1828 didInitial = true;
1829 }
1830
1831 // Okay to emit.
1832 return true;
1833}
1834
Jim Laskey063e7652006-01-17 17:31:53 +00001835//===----------------------------------------------------------------------===//
Jim Laskeyd18e2892006-01-20 20:34:06 +00001836// Main entry points.
Jim Laskey063e7652006-01-17 17:31:53 +00001837//
Jim Laskey52060a02006-01-24 00:49:18 +00001838
1839DwarfWriter::DwarfWriter(std::ostream &OS, AsmPrinter *A)
1840: O(OS)
1841, Asm(A)
1842, DebugInfo(NULL)
1843, didInitial(false)
1844, CompileUnits()
1845, Abbreviations()
Jim Laskey52060a02006-01-24 00:49:18 +00001846, StringPool()
Jim Laskeybd761842006-02-27 17:27:12 +00001847, DescToUnitMap()
Jim Laskey0420f2a2006-02-22 19:02:11 +00001848, DescToDieMap()
1849, TypeToDieMap()
Jim Laskey52060a02006-01-24 00:49:18 +00001850, AddressSize(sizeof(int32_t))
1851, hasLEB128(false)
1852, hasDotLoc(false)
1853, hasDotFile(false)
1854, needsSet(false)
1855, DwarfAbbrevSection(".debug_abbrev")
1856, DwarfInfoSection(".debug_info")
1857, DwarfLineSection(".debug_line")
1858, DwarfFrameSection(".debug_frame")
1859, DwarfPubNamesSection(".debug_pubnames")
1860, DwarfPubTypesSection(".debug_pubtypes")
1861, DwarfStrSection(".debug_str")
1862, DwarfLocSection(".debug_loc")
1863, DwarfARangesSection(".debug_aranges")
1864, DwarfRangesSection(".debug_ranges")
1865, DwarfMacInfoSection(".debug_macinfo")
1866, TextSection(".text")
1867, DataSection(".data")
1868{}
1869DwarfWriter::~DwarfWriter() {
1870 for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i) {
1871 delete CompileUnits[i];
Jim Laskey063e7652006-01-17 17:31:53 +00001872 }
Jim Laskey52060a02006-01-24 00:49:18 +00001873}
Jim Laskey063e7652006-01-17 17:31:53 +00001874
1875/// BeginModule - Emit all Dwarf sections that should come prior to the content.
Jim Laskeyb2efb852006-01-04 22:28:25 +00001876///
Jim Laskey52060a02006-01-24 00:49:18 +00001877void DwarfWriter::BeginModule(Module &M) {
Jim Laskeyb2efb852006-01-04 22:28:25 +00001878 if (!ShouldEmitDwarf()) return;
Jim Laskey063e7652006-01-17 17:31:53 +00001879 EOL("Dwarf Begin Module");
Jim Laskeyb2efb852006-01-04 22:28:25 +00001880}
1881
Jim Laskey063e7652006-01-17 17:31:53 +00001882/// EndModule - Emit all Dwarf sections that should come after the content.
Jim Laskeya7cea6f2006-01-04 13:52:30 +00001883///
Jim Laskey52060a02006-01-24 00:49:18 +00001884void DwarfWriter::EndModule(Module &M) {
Jim Laskeyb2efb852006-01-04 22:28:25 +00001885 if (!ShouldEmitDwarf()) return;
Jim Laskey063e7652006-01-17 17:31:53 +00001886 EOL("Dwarf End Module");
1887
1888 // Standard sections final addresses.
Jim Laskeye719a7c2006-01-18 16:54:26 +00001889 Asm->SwitchSection(TextSection, 0);
Jim Laskey063e7652006-01-17 17:31:53 +00001890 EmitLabel("text_end", 0);
Jim Laskeye719a7c2006-01-18 16:54:26 +00001891 Asm->SwitchSection(DataSection, 0);
Jim Laskey063e7652006-01-17 17:31:53 +00001892 EmitLabel("data_end", 0);
Jim Laskeyd18e2892006-01-20 20:34:06 +00001893
Jim Laskey52060a02006-01-24 00:49:18 +00001894 // Create all the compile unit DIEs.
1895 ConstructCompileUnitDIEs();
1896
1897 // Create DIEs for each of the externally visible global variables.
1898 ConstructGlobalDIEs(M);
Jim Laskey063e7652006-01-17 17:31:53 +00001899
Jim Laskey0420f2a2006-02-22 19:02:11 +00001900 // Create DIEs for each of the externally visible subprograms.
1901 ConstructSubprogramDIEs(M);
1902
Jim Laskey063e7652006-01-17 17:31:53 +00001903 // Compute DIE offsets and sizes.
1904 SizeAndOffsets();
1905
1906 // Emit all the DIEs into a debug info section
1907 EmitDebugInfo();
1908
1909 // Corresponding abbreviations into a abbrev section.
1910 EmitAbbreviations();
1911
1912 // Emit source line correspondence into a debug line section.
1913 EmitDebugLines();
Jim Laskey19ef4ef2006-01-17 20:41:40 +00001914
1915 // Emit info into a debug frame section.
Jim Laskey0d086af2006-02-27 12:43:29 +00001916 // EmitDebugFrame();
Jim Laskey19ef4ef2006-01-17 20:41:40 +00001917
1918 // Emit info into a debug pubnames section.
1919 EmitDebugPubNames();
1920
Jim Laskey19ef4ef2006-01-17 20:41:40 +00001921 // Emit info into a debug str section.
1922 EmitDebugStr();
1923
1924 // Emit info into a debug loc section.
1925 EmitDebugLoc();
1926
1927 // Emit info into a debug aranges section.
1928 EmitDebugARanges();
1929
1930 // Emit info into a debug ranges section.
1931 EmitDebugRanges();
1932
1933 // Emit info into a debug macinfo section.
1934 EmitDebugMacInfo();
Jim Laskeya7cea6f2006-01-04 13:52:30 +00001935}
1936
Jim Laskeye719a7c2006-01-18 16:54:26 +00001937/// BeginFunction - Gather pre-function debug information.
Jim Laskeya7cea6f2006-01-04 13:52:30 +00001938///
Jim Laskey52060a02006-01-24 00:49:18 +00001939void DwarfWriter::BeginFunction(MachineFunction &MF) {
Jim Laskeyb2efb852006-01-04 22:28:25 +00001940 if (!ShouldEmitDwarf()) return;
Jim Laskey063e7652006-01-17 17:31:53 +00001941 EOL("Dwarf Begin Function");
Jim Laskeya7cea6f2006-01-04 13:52:30 +00001942}
1943
Jim Laskeye719a7c2006-01-18 16:54:26 +00001944/// EndFunction - Gather and emit post-function debug information.
Jim Laskeya7cea6f2006-01-04 13:52:30 +00001945///
Jim Laskey52060a02006-01-24 00:49:18 +00001946void DwarfWriter::EndFunction(MachineFunction &MF) {
Jim Laskeyb2efb852006-01-04 22:28:25 +00001947 if (!ShouldEmitDwarf()) return;
Jim Laskey063e7652006-01-17 17:31:53 +00001948 EOL("Dwarf End Function");
Jim Laskeya7cea6f2006-01-04 13:52:30 +00001949}