Reworked how Dwarf debug info entries and abbreviations are handled. Added

pubnames and debuy str sections.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25487 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Laskey 2006-01-20 20:34:06 +00:00
parent bea99471c7
commit d18e28964b
2 changed files with 658 additions and 249 deletions

View File

@ -437,6 +437,15 @@ namespace llvm {
DW_CFA_hi_user = 0x3f DW_CFA_hi_user = 0x3f
}; };
//===--------------------------------------------------------------------===//
// Forward declarations.
//
class AsmPrinter;
class DIE;
class DwarfWriter;
class DWContext;
class MachineDebugInfo;
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// DWLabel - Labels are used to track locations in the assembler file. // DWLabel - Labels are used to track locations in the assembler file.
// Labels appear in the form <prefix>debug_<Tag><Number>, where the tag is a // Labels appear in the form <prefix>debug_<Tag><Number>, where the tag is a
@ -445,57 +454,89 @@ namespace llvm {
struct DWLabel { struct DWLabel {
const char *Tag; // Label category tag. Should always be const char *Tag; // Label category tag. Should always be
// a staticly declared C string. // a staticly declared C string.
unsigned Number; // Unique number unsigned Number; // Unique number.
DWLabel() : Tag(NULL), Number(0) {}
DWLabel(const char *T, unsigned N) : Tag(T), Number(N) {} DWLabel(const char *T, unsigned N) : Tag(T), Number(N) {}
}; };
//===--------------------------------------------------------------------===//
// DIEAbbrevData - Dwarf abbreviation data, describes the one attribute of a
// Dwarf abbreviation.
class DIEAbbrevData {
private:
unsigned Attribute; // Dwarf attribute code.
unsigned Form; // Dwarf form code.
public:
DIEAbbrevData(unsigned A, unsigned F)
: Attribute(A)
, Form(F)
{}
// Accessors
unsigned getAttribute() const { return Attribute; }
unsigned getForm() const { return Form; }
};
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// DIEAbbrev - Dwarf abbreviation, describes the organization of a debug // DIEAbbrev - Dwarf abbreviation, describes the organization of a debug
// information object. // information object.
//
class DIEAbbrev { class DIEAbbrev {
private: private:
const unsigned char *Data; // Static array of bytes containing the unsigned Tag; // Dwarf tag code.
// image of the raw abbreviation data. unsigned ChildrenFlag; // Dwarf children flag.
std::vector<DIEAbbrevData> Data; // Raw data bytes for abbreviation.
public: public:
DIEAbbrev(const unsigned char *D) DIEAbbrev(unsigned T, unsigned C)
: Data(D) : Tag(T)
, ChildrenFlag(C)
, Data()
{} {}
~DIEAbbrev() {}
// Accessors
unsigned getTag() const { return Tag; }
unsigned getChildrenFlag() const { return ChildrenFlag; }
const std::vector<DIEAbbrevData> &getData() const { return Data; }
/// operator== - Used by UniqueVector to locate entry. /// operator== - Used by UniqueVector to locate entry.
/// ///
bool operator==(const DIEAbbrev &DA) const { bool operator==(const DIEAbbrev &DA) const;
return Data == DA.Data;
}
/// operator< - Used by UniqueVector to locate entry. /// operator< - Used by UniqueVector to locate entry.
/// ///
bool operator<(const DIEAbbrev &DA) const { bool operator<(const DIEAbbrev &DA) const;
return Data < DA.Data;
}
// Accessors /// AddAttribute - Adds another set of attribute information to the
unsigned getTag() const { return Data[0]; } /// abbreviation.
unsigned getChildrenFlag() const { return Data[1]; } void AddAttribute(unsigned Attribute, unsigned Form) {
unsigned getAttribute(unsigned i) const { return Data[2 + 2 * i + 0]; } Data.push_back(DIEAbbrevData(Attribute, Form));
unsigned getForm(unsigned i) const { return Data[2 + 2 * i + 1]; } }
/// Emit - Print the abbreviation using the specified Dwarf writer.
///
void Emit(const DwarfWriter &DW) const;
#ifndef NDEBUG
void print(std::ostream &O);
void dump();
#endif
}; };
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// DIEValue - A debug information entry value. // DIEValue - A debug information entry value.
// //
class DwarfWriter;
class DIEValue { class DIEValue {
public: public:
enum { enum {
isInteger, isInteger,
isString, isString,
isLabel, isLabel,
isDelta isAsIsLabel,
isDelta,
isEntry
}; };
unsigned Type; // Type of the value unsigned Type; // Type of the value
@ -520,14 +561,14 @@ namespace llvm {
// //
class DIEInteger : public DIEValue { class DIEInteger : public DIEValue {
private: private:
int Value; int Integer;
public: public:
DIEInteger(int V) : DIEValue(isInteger), Value(V) {} DIEInteger(int I) : DIEValue(isInteger), Integer(I) {}
// Implement isa/cast/dyncast. // Implement isa/cast/dyncast.
static bool classof(const DIEInteger *) { return true; } static bool classof(const DIEInteger *) { return true; }
static bool classof(const DIEValue *V) { return V->Type == isInteger; } static bool classof(const DIEValue *I) { return I->Type == isInteger; }
/// EmitValue - Emit integer of appropriate size. /// EmitValue - Emit integer of appropriate size.
/// ///
@ -542,13 +583,13 @@ namespace llvm {
// DIEString - A string value DIE. // DIEString - A string value DIE.
// //
struct DIEString : public DIEValue { struct DIEString : public DIEValue {
const std::string Value; const std::string String;
DIEString(const std::string &V) : DIEValue(isString), Value(V) {} DIEString(const std::string &S) : DIEValue(isString), String(S) {}
// Implement isa/cast/dyncast. // Implement isa/cast/dyncast.
static bool classof(const DIEString *) { return true; } static bool classof(const DIEString *) { return true; }
static bool classof(const DIEValue *V) { return V->Type == isString; } static bool classof(const DIEValue *S) { return S->Type == isString; }
/// EmitValue - Emit string value. /// EmitValue - Emit string value.
/// ///
@ -563,13 +604,35 @@ namespace llvm {
// DIELabel - A simple label expression DIE. // DIELabel - A simple label expression DIE.
// //
struct DIELabel : public DIEValue { struct DIELabel : public DIEValue {
const DWLabel Value; const DWLabel Label;
DIELabel(const DWLabel &V) : DIEValue(isLabel), Value(V) {} DIELabel(const DWLabel &L) : DIEValue(isLabel), Label(L) {}
// Implement isa/cast/dyncast. // Implement isa/cast/dyncast.
static bool classof(const DWLabel *) { return true; } static bool classof(const DIELabel *) { return true; }
static bool classof(const DIEValue *V) { return V->Type == isLabel; } static bool classof(const DIEValue *L) { return L->Type == isLabel; }
/// EmitValue - Emit label value.
///
virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const;
/// SizeOf - Determine size of label value in bytes.
///
virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const;
};
//===--------------------------------------------------------------------===//
// DIEAsIsLabel - An exact name of a label.
//
struct DIEAsIsLabel : public DIEValue {
const std::string Label;
DIEAsIsLabel(const std::string &L) : DIEValue(isAsIsLabel), Label(L) {}
// Implement isa/cast/dyncast.
static bool classof(const DIEAsIsLabel *) { return true; }
static bool classof(const DIEValue *L) { return L->Type == isAsIsLabel; }
/// EmitValue - Emit label value. /// EmitValue - Emit label value.
/// ///
@ -584,15 +647,36 @@ namespace llvm {
// DIEDelta - A simple label difference DIE. // DIEDelta - A simple label difference DIE.
// //
struct DIEDelta : public DIEValue { struct DIEDelta : public DIEValue {
const DWLabel Value1; const DWLabel LabelHi;
const DWLabel Value2; const DWLabel LabelLo;
DIEDelta(const DWLabel &V1, const DWLabel &V2) DIEDelta(const DWLabel &Hi, const DWLabel &Lo)
: DIEValue(isDelta), Value1(V1), Value2(V2) {} : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {}
// Implement isa/cast/dyncast. // Implement isa/cast/dyncast.
static bool classof(const DIEDelta *) { return true; } static bool classof(const DIEDelta *) { return true; }
static bool classof(const DIEValue *V) { return V->Type == isDelta; } static bool classof(const DIEValue *D) { return D->Type == isDelta; }
/// EmitValue - Emit delta value.
///
virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const;
/// SizeOf - Determine size of delta value in bytes.
///
virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const;
};
//===--------------------------------------------------------------------===//
// DIEntry - A pointer to a debug information entry.
//
struct DIEntry : public DIEValue {
DIE *Entry;
DIEntry(DIE *E) : DIEValue(isEntry), Entry(E) {}
// Implement isa/cast/dyncast.
static bool classof(const DIEntry *) { return true; }
static bool classof(const DIEValue *E) { return E->Type == isEntry; }
/// EmitValue - Emit delta value. /// EmitValue - Emit delta value.
/// ///
@ -608,70 +692,106 @@ namespace llvm {
// describes it's organization. // describes it's organization.
class DIE { class DIE {
private: private:
DIEAbbrev *Abbrev; // Temporary buffer for abbreviation.
unsigned AbbrevID; // Decribing abbreviation ID. unsigned AbbrevID; // Decribing abbreviation ID.
unsigned Offset; // Offset in debug info section unsigned Offset; // Offset in debug info section.
unsigned Size; // Size of instance + children unsigned Size; // Size of instance + children.
std::vector<DIE *> Children; // Children DIEs DWContext *Context; // Context for types and values.
std::vector<DIEValue *> Values; // Attributes values std::vector<DIE *> Children; // Children DIEs.
std::vector<DIEValue *> Values; // Attributes values.
public: public:
DIE(unsigned AbbrevID) DIE(unsigned Tag, unsigned ChildrenFlag);
: AbbrevID(AbbrevID) ~DIE();
, Offset(0)
, Size(0)
, Children()
, Values()
{}
~DIE() {
for (unsigned i = 0, N = Children.size(); i < N; i++) {
delete Children[i];
}
for (unsigned j = 0, M = Children.size(); j < M; j++) {
delete Children[j];
}
}
// Accessors // Accessors
unsigned getAbbrevID() const { return AbbrevID; } unsigned getAbbrevID() const { return AbbrevID; }
unsigned getOffset() const { return Offset; } unsigned getOffset() const { return Offset; }
unsigned getSize() const { return Size; } unsigned getSize() const { return Size; }
DWContext *getContext() const { return Context; }
const std::vector<DIE *> &getChildren() const { return Children; } const std::vector<DIE *> &getChildren() const { return Children; }
const std::vector<DIEValue *> &getValues() const { return Values; } const std::vector<DIEValue *> &getValues() const { return Values; }
void setOffset(unsigned O) { Offset = O; } void setOffset(unsigned O) { Offset = O; }
void setSize(unsigned S) { Size = S; } void setSize(unsigned S) { Size = S; }
void setContext(DWContext *C) { Context = C; }
/// AddValue - Add an attribute value of appropriate type.
///
void AddValue(int Value) {
Values.push_back(new DIEInteger(Value));
}
void AddValue(const std::string &Value) {
Values.push_back(new DIEString(Value));
}
void AddValue(const DWLabel &Value) {
Values.push_back(new DIELabel(Value));
}
void AddValue(const DWLabel &Value1, const DWLabel &Value2) {
Values.push_back(new DIEDelta(Value1, Value2));
}
/// SiblingOffset - Return the offset of the debug information entry's /// SiblingOffset - Return the offset of the debug information entry's
/// sibling. /// sibling.
unsigned SiblingOffset() const { return Offset + Size; } unsigned SiblingOffset() const { return Offset + Size; }
/// AddInt - Add a simple integer attribute data and value.
///
void AddInt(unsigned Attribute, unsigned Form, int Integer);
/// AddString - Add a std::string attribute data and value.
///
void AddString(unsigned Attribute, unsigned Form,
const std::string &String);
/// AddLabel - Add a Dwarf label attribute data and value.
///
void AddLabel(unsigned Attribute, unsigned Form, const DWLabel &Label);
/// AddAsIsLabel - Add a non-Dwarf label attribute data and value.
///
void AddAsIsLabel(unsigned Attribute, unsigned Form,
const std::string &Label);
/// AddDelta - Add a label delta attribute data and value.
///
void AddDelta(unsigned Attribute, unsigned Form,
const DWLabel &Hi, const DWLabel &Lo);
/// AddDIEntry - Add a DIE attribute data and value.
///
void AddDIEntry(unsigned Attribute, unsigned Form, DIE *Entry);
/// Complete - Indicate that all attributes have been added and
/// ready to get an abbreviation ID.
///
void Complete(DwarfWriter &DW);
/// AddChild - Add a child to the DIE.
void AddChild(DIE *Child);
};
//===--------------------------------------------------------------------===//
/// DWContext - Name context for types and values.
///
class DWContext {
private:
DwarfWriter &DW; // DwarfWriter for global information.
DIE *Owner; // Owning debug information entry.
std::map<std::string, DIE*> Types; // Named types in context.
std::map<std::string, DIE*> Variables;// Named variables in context.
public:
DWContext(DwarfWriter &D, DIE *O)
: DW(D)
, Owner(O)
, Types()
, Variables()
{
Owner->setContext(this);
}
~DWContext() {}
/// NewBasicType - Creates a new basic type, if necessary, then adds in the
/// context and owner.
DIE *NewBasicType(const std::string &Name, unsigned Size,
unsigned Encoding);
/// NewVariable - Creates a basic variable, if necessary, then adds in the
/// context and owner.
DIE *NewVariable(const std::string &Name,
unsigned SourceFileID, unsigned Line,
DIE *Type, bool IsExternal);
}; };
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Forward declarations. // DwarfWriter - Emits Dwarf debug and exception handling directives.
//
class AsmPrinter;
class MachineDebugInfo;
//===--------------------------------------------------------------------===//
// DwarfWriter - emits Dwarf debug and exception handling directives.
// //
class DwarfWriter { class DwarfWriter {
protected: protected:
//===------------------------------------------------------------------===// //===------------------------------------------------------------------===//
@ -707,6 +827,18 @@ namespace llvm {
/// ///
UniqueVector<DIEAbbrev> Abbreviations; UniqueVector<DIEAbbrev> Abbreviations;
/// GlobalTypes - A map of globally visible named types.
///
std::map<std::string, DIE *> GlobalTypes;
/// GlobalEntities - A map of globally visible named entities.
///
std::map<std::string, DIE *> GlobalEntities;
/// StringPool - A UniqueVector of strings used by indirect references.
///
UniqueVector<std::string> StringPool;
//===------------------------------------------------------------------===// //===------------------------------------------------------------------===//
// Properties to be set by the derived class ctor, used to configure the // Properties to be set by the derived class ctor, used to configure the
// Dwarf writer. // Dwarf writer.
@ -861,21 +993,34 @@ public:
EmitReference(Label.Tag, Label.Number); EmitReference(Label.Tag, Label.Number);
} }
void EmitReference(const char *Tag, unsigned Number) const; void EmitReference(const char *Tag, unsigned Number) const;
void EmitReference(const std::string Name) const;
/// EmitDifference - Emit the difference between two labels. Some /// EmitDifference - Emit the difference between two labels. Some
/// assemblers do not behave with absolute expressions with data directives, /// assemblers do not behave with absolute expressions with data directives,
/// so there is an option (needsSet) to use an intermediary set expression. /// so there is an option (needsSet) to use an intermediary set expression.
void EmitDifference(DWLabel Label1, DWLabel Label2) const { void EmitDifference(DWLabel LabelHi, DWLabel LabelLo) const {
EmitDifference(Label1.Tag, Label1.Number, Label2.Tag, Label2.Number); EmitDifference(LabelHi.Tag, LabelHi.Number, LabelLo.Tag, LabelLo.Number);
} }
void EmitDifference(const char *Tag1, unsigned Number1, void EmitDifference(const char *TagHi, unsigned NumberHi,
const char *Tag2, unsigned Number2) const; const char *TagLo, unsigned NumberLo) const;
private: /// NewAbbreviation - Add the abbreviation to the Abbreviation vector.
/// NewDIE - Construct a new structured debug information entry.
/// ///
DIE *NewDIE(const unsigned char *AbbrevData); unsigned NewAbbreviation(DIEAbbrev *Abbrev);
/// NewString - Add a string to the constant pool and returns a label.
///
DWLabel NewString(const std::string &String);
/// NewGlobalType - Make the type visible globally using the given name.
///
void NewGlobalType(const std::string &Name, DIE *Type);
/// NewGlobalEntity - Make the entity visible globally using the given name.
///
void NewGlobalEntity(const std::string &Name, DIE *Entity);
private:
/// NewCompileUnit - Create new compile unit information. /// NewCompileUnit - Create new compile unit information.
/// ///
DIE *NewCompileUnit(const std::string &Directory, DIE *NewCompileUnit(const std::string &Directory,
@ -956,7 +1101,7 @@ private:
void SetDebugInfo(MachineDebugInfo *di) { DebugInfo = di; } void SetDebugInfo(MachineDebugInfo *di) { DebugInfo = di; }
//===------------------------------------------------------------------===// //===------------------------------------------------------------------===//
// Main enties. // Main entry points.
// //
/// BeginModule - Emit all Dwarf sections that should come prior to the /// BeginModule - Emit all Dwarf sections that should come prior to the

View File

@ -26,84 +26,6 @@ static cl::opt<bool>
DwarfVerbose("dwarf-verbose", cl::Hidden, DwarfVerbose("dwarf-verbose", cl::Hidden,
cl::desc("Add comments to Dwarf directives.")); cl::desc("Add comments to Dwarf directives."));
//===----------------------------------------------------------------------===//
// Dwarf abbreviations used by this emitter.
//
static const unsigned char AbbrevTAG_compile_unit[] = {
DW_TAG_compile_unit, DW_CHILDREN_yes,
DW_AT_stmt_list, DW_FORM_data4,
DW_AT_high_pc, DW_FORM_addr,
DW_AT_low_pc, DW_FORM_addr,
DW_AT_producer, DW_FORM_string,
DW_AT_language, DW_FORM_data1,
DW_AT_name, DW_FORM_string,
DW_AT_comp_dir, DW_FORM_string,
0, 0
};
static const unsigned char AbbrevTAG_subprogram[] = {
DW_TAG_subprogram, DW_CHILDREN_yes,
DW_AT_sibling, DW_FORM_ref4,
DW_AT_external, DW_FORM_flag,
DW_AT_name, DW_FORM_string,
DW_AT_decl_file, DW_FORM_data1,
DW_AT_decl_line, DW_FORM_data1,
DW_AT_prototyped, DW_FORM_flag,
DW_AT_type, DW_FORM_ref4,
DW_AT_low_pc, DW_FORM_addr,
DW_AT_high_pc, DW_FORM_addr,
DW_AT_frame_base, DW_FORM_block1,
0, 0
};
static const unsigned char AbbrevTAG_formal_parameter[] = {
DW_TAG_formal_parameter, DW_CHILDREN_no,
DW_AT_name, DW_FORM_string,
DW_AT_decl_file, DW_FORM_data1,
DW_AT_decl_line, DW_FORM_data1,
DW_AT_type, DW_FORM_ref4,
DW_AT_location, DW_FORM_block1,
0, 0
};
static const unsigned char AbbrevTAG_base_type[] = {
DW_TAG_base_type, DW_CHILDREN_no,
DW_AT_name, DW_FORM_string,
DW_AT_byte_size, DW_FORM_data1,
DW_AT_encoding, DW_FORM_data1,
0, 0
};
static const unsigned char AbbrevTAG_pointer_type[] = {
DW_TAG_pointer_type, DW_CHILDREN_no,
DW_AT_byte_size, DW_FORM_data1,
DW_AT_type, DW_FORM_ref4,
0, 0
};
static const unsigned char AbbrevTAG_array_type[] = {
DW_TAG_array_type, DW_CHILDREN_yes,
DW_AT_sibling, DW_FORM_ref4,
DW_AT_type, DW_FORM_ref4,
0, 0
};
static const unsigned char AbbrevTAG_subrange_type[] = {
DW_TAG_subrange_type, DW_CHILDREN_no,
0, 0
};
static const unsigned char AbbrevTAG_variable[] = {
DW_TAG_variable, DW_CHILDREN_no,
DW_AT_name, DW_FORM_string,
DW_AT_type, DW_FORM_ref4,
DW_AT_external, DW_FORM_flag,
DW_AT_artificial, DW_FORM_flag,
DW_AT_declaration, DW_FORM_flag,
0, 0
};
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// TagString - Return the string for the specified tag. /// TagString - Return the string for the specified tag.
@ -659,13 +581,102 @@ static const char *CallFrameString(unsigned Encoding) {
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// operator== - Used by UniqueVector to locate entry.
///
bool DIEAbbrev::operator==(const DIEAbbrev &DA) const {
if (Tag != DA.Tag) return false;
if (ChildrenFlag != DA.ChildrenFlag) return false;
if (Data.size() != DA.Data.size()) return false;
for (unsigned i = 0, N = Data.size(); i < N; i++) {
const DIEAbbrevData &AttrData = Data[i];
const DIEAbbrevData &DAAttrData = Data[i];
if (AttrData.getAttribute() != DAAttrData.getAttribute()) return false;
if (AttrData.getForm() != DAAttrData.getForm()) return false;
}
return true;
}
/// operator< - Used by UniqueVector to locate entry.
///
bool DIEAbbrev::operator<(const DIEAbbrev &DA) const {
if (Tag != DA.Tag) return Tag < DA.Tag;
if (ChildrenFlag != DA.ChildrenFlag) return ChildrenFlag < DA.ChildrenFlag;
if (Data.size() != DA.Data.size()) return Data.size() < DA.Data.size();
for (unsigned i = 0, N = Data.size(); i < N; i++) {
const DIEAbbrevData &AttrData = Data[i];
const DIEAbbrevData &DAAttrData = DA.Data[i];
if (AttrData.getAttribute() != DAAttrData.getAttribute())
return AttrData.getAttribute() < DAAttrData.getAttribute();
if (AttrData.getForm() != DAAttrData.getForm())
return AttrData.getForm() < DAAttrData.getForm();
}
return false;
}
/// Emit - Print the abbreviation using the specified Dwarf writer.
///
void DIEAbbrev::Emit(const DwarfWriter &DW) const {
// Emit its Dwarf tag type.
DW.EmitULEB128Bytes(Tag);
DW.EOL(TagString(Tag));
// Emit whether it has children DIEs.
DW.EmitULEB128Bytes(ChildrenFlag);
DW.EOL(ChildrenString(ChildrenFlag));
// For each attribute description.
for (unsigned i = 0, N = Data.size(); i < N; i++) {
const DIEAbbrevData &AttrData = Data[i];
// Emit attribute type.
DW.EmitULEB128Bytes(AttrData.getAttribute());
DW.EOL(AttributeString(AttrData.getAttribute()));
// Emit form type.
DW.EmitULEB128Bytes(AttrData.getForm());
DW.EOL(FormEncodingString(AttrData.getForm()));
}
// Mark end of abbreviation.
DW.EmitULEB128Bytes(0); DW.EOL("EOM(1)");
DW.EmitULEB128Bytes(0); DW.EOL("EOM(2)");
}
#ifndef NDEBUG
void DIEAbbrev::print(std::ostream &O) {
O << "Abbreviation @"
<< std::hex << (unsigned)this << std::dec
<< " "
<< TagString(Tag)
<< " "
<< ChildrenString(ChildrenFlag)
<< "\n";
for (unsigned i = 0, N = Data.size(); i < N; i++) {
O << " "
<< AttributeString(Data[i].getAttribute())
<< " "
<< FormEncodingString(Data[i].getForm())
<< "\n";
}
}
void DIEAbbrev::dump() { print(std::cerr); }
#endif
//===----------------------------------------------------------------------===//
/// EmitValue - Emit integer of appropriate size. /// EmitValue - Emit integer of appropriate size.
/// ///
void DIEInteger::EmitValue(const DwarfWriter &DW, unsigned Form) const { void DIEInteger::EmitValue(const DwarfWriter &DW, unsigned Form) const {
switch (Form) { switch (Form) {
case DW_FORM_data1: DW.EmitByte(Value); break; case DW_FORM_data1: // Fall thru
case DW_FORM_data2: DW.EmitShort(Value); break; case DW_FORM_flag: DW.EmitByte(Integer); break;
case DW_FORM_data4: DW.EmitLong(Value); break; case DW_FORM_data2: DW.EmitShort(Integer); break;
case DW_FORM_data4: DW.EmitLong(Integer); break;
default: assert(0 && "DIE Value form not supported yet"); break; default: assert(0 && "DIE Value form not supported yet"); break;
} }
} }
@ -674,6 +685,7 @@ void DIEInteger::EmitValue(const DwarfWriter &DW, unsigned Form) const {
/// ///
unsigned DIEInteger::SizeOf(const DwarfWriter &DW, unsigned Form) const { unsigned DIEInteger::SizeOf(const DwarfWriter &DW, unsigned Form) const {
switch (Form) { switch (Form) {
case DW_FORM_flag: // Fall thru
case DW_FORM_data1: return sizeof(int8_t); case DW_FORM_data1: return sizeof(int8_t);
case DW_FORM_data2: return sizeof(int16_t); case DW_FORM_data2: return sizeof(int16_t);
case DW_FORM_data4: return sizeof(int32_t); case DW_FORM_data4: return sizeof(int32_t);
@ -687,13 +699,13 @@ unsigned DIEInteger::SizeOf(const DwarfWriter &DW, unsigned Form) const {
/// EmitValue - Emit string value. /// EmitValue - Emit string value.
/// ///
void DIEString::EmitValue(const DwarfWriter &DW, unsigned Form) const { void DIEString::EmitValue(const DwarfWriter &DW, unsigned Form) const {
DW.EmitString(Value); DW.EmitString(String);
} }
/// SizeOf - Determine size of string value in bytes. /// SizeOf - Determine size of string value in bytes.
/// ///
unsigned DIEString::SizeOf(const DwarfWriter &DW, unsigned Form) const { unsigned DIEString::SizeOf(const DwarfWriter &DW, unsigned Form) const {
return Value.size() + sizeof(int8_t); return String.size() + sizeof('\0');
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -701,7 +713,7 @@ unsigned DIEString::SizeOf(const DwarfWriter &DW, unsigned Form) const {
/// EmitValue - Emit label value. /// EmitValue - Emit label value.
/// ///
void DIELabel::EmitValue(const DwarfWriter &DW, unsigned Form) const { void DIELabel::EmitValue(const DwarfWriter &DW, unsigned Form) const {
DW.EmitReference(Value); DW.EmitReference(Label);
} }
/// SizeOf - Determine size of label value in bytes. /// SizeOf - Determine size of label value in bytes.
@ -712,10 +724,24 @@ unsigned DIELabel::SizeOf(const DwarfWriter &DW, unsigned Form) const {
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// EmitValue - Emit label value.
///
void DIEAsIsLabel::EmitValue(const DwarfWriter &DW, unsigned Form) const {
DW.EmitReference(Label);
}
/// SizeOf - Determine size of label value in bytes.
///
unsigned DIEAsIsLabel::SizeOf(const DwarfWriter &DW, unsigned Form) const {
return DW.getAddressSize();
}
//===----------------------------------------------------------------------===//
/// EmitValue - Emit delta value. /// EmitValue - Emit delta value.
/// ///
void DIEDelta::EmitValue(const DwarfWriter &DW, unsigned Form) const { void DIEDelta::EmitValue(const DwarfWriter &DW, unsigned Form) const {
DW.EmitDifference(Value1, Value2); DW.EmitDifference(LabelHi, LabelLo);
} }
/// SizeOf - Determine size of delta value in bytes. /// SizeOf - Determine size of delta value in bytes.
@ -724,6 +750,171 @@ unsigned DIEDelta::SizeOf(const DwarfWriter &DW, unsigned Form) const {
return DW.getAddressSize(); return DW.getAddressSize();
} }
//===----------------------------------------------------------------------===//
/// EmitValue - Emit extry offset.
///
void DIEntry::EmitValue(const DwarfWriter &DW, unsigned Form) const {
DW.EmitLong(Entry->getOffset());
}
/// SizeOf - Determine size of label value in bytes.
///
unsigned DIEntry::SizeOf(const DwarfWriter &DW, unsigned Form) const {
return sizeof(int32_t);
}
//===----------------------------------------------------------------------===//
DIE::DIE(unsigned Tag, unsigned ChildrenFlag)
: Abbrev(new DIEAbbrev(Tag, ChildrenFlag))
, AbbrevID(0)
, Offset(0)
, Size(0)
, Context(NULL)
, Children()
, Values()
{}
DIE::~DIE() {
if (Abbrev) delete Abbrev;
for (unsigned i = 0, N = Children.size(); i < N; i++) {
delete Children[i];
}
for (unsigned j = 0, M = Values.size(); j < M; j++) {
delete Values[j];
}
if (Context) delete Context;
}
/// AddInt - Add a simple integer attribute data and value.
///
void DIE::AddInt(unsigned Attribute, unsigned Form,
int Integer) {
Abbrev->AddAttribute(Attribute, Form);
Values.push_back(new DIEInteger(Integer));
}
/// AddString - Add a std::string attribute data and value.
///
void DIE::AddString(unsigned Attribute, unsigned Form,
const std::string &String) {
Abbrev->AddAttribute(Attribute, Form);
Values.push_back(new DIEString(String));
}
/// AddLabel - Add a Dwarf label attribute data and value.
///
void DIE::AddLabel(unsigned Attribute, unsigned Form,
const DWLabel &Label) {
Abbrev->AddAttribute(Attribute, Form);
Values.push_back(new DIELabel(Label));
}
/// AddAsIsLabel - Add an non-Dwarf label attribute data and value.
///
void DIE::AddAsIsLabel(unsigned Attribute, unsigned Form,
const std::string &Label) {
Abbrev->AddAttribute(Attribute, Form);
Values.push_back(new DIEAsIsLabel(Label));
}
/// AddDelta - Add a label delta attribute data and value.
///
void DIE::AddDelta(unsigned Attribute, unsigned Form,
const DWLabel &Hi, const DWLabel &Lo) {
Abbrev->AddAttribute(Attribute, Form);
Values.push_back(new DIEDelta(Hi, Lo));
}
/// AddDIEntry - Add a DIE attribute data and value.
///
void DIE::AddDIEntry(unsigned Attribute,
unsigned Form, DIE *Entry) {
Abbrev->AddAttribute(Attribute, Form);
Values.push_back(new DIEntry(Entry));
}
/// Complete - Indicate that all attributes have been added and ready to get an
/// abbreviation ID.
void DIE::Complete(DwarfWriter &DW) {
AbbrevID = DW.NewAbbreviation(Abbrev);
delete Abbrev;
Abbrev = NULL;
}
/// AddChild - Add a child to the DIE.
///
void DIE::AddChild(DIE *Child) {
Children.push_back(Child);
}
//===----------------------------------------------------------------------===//
/// NewBasicType - Creates a new basic type if necessary, then adds in the
/// context and owner.
DIE *DWContext::NewBasicType(const std::string &Name, unsigned Size,
unsigned Encoding) {
// FIXME - Just a prototype.
DIE *Type = Types[Name];
// If first occurance of type.
if (!Type) {
// construct the type DIE.
Type = new DIE(DW_TAG_base_type, DW_CHILDREN_no);
Type->AddString(DW_AT_name, DW_FORM_string, Name);
Type->AddInt (DW_AT_byte_size, DW_FORM_data1, Size);
Type->AddInt (DW_AT_encoding, DW_FORM_data1, Encoding);
Type->Complete(DW);
// Add to context owner.
Owner->AddChild(Type);
// Add to map.
Types[Name] = Type;
}
return Type;
}
/// NewVariable - Creates a basic variable, if necessary, then adds in the
/// context and owner.
DIE *DWContext::NewVariable(const std::string &Name,
unsigned SourceFileID, unsigned Line,
DIE *Type, bool IsExternal) {
// FIXME - Just a prototype.
DIE *Variable = Variables[Name];
// If first occurance of variable.
if (!Variable) {
assert(IsExternal && "Internal variables not handled yet");
Variable = new DIE(DW_TAG_variable, DW_CHILDREN_no);
Variable->AddString (DW_AT_name, DW_FORM_string, Name);
Variable->AddInt (DW_AT_decl_file, DW_FORM_data1, SourceFileID);
Variable->AddInt (DW_AT_decl_line, DW_FORM_data1, Line);
Variable->AddDIEntry (DW_AT_type, DW_FORM_ref4, Type);
Variable->AddInt (DW_AT_external, DW_FORM_flag, (int)IsExternal);
Variable->AddAsIsLabel(DW_AT_location, DW_FORM_block1,
std::string("_")+Name+".b");
Variable->Complete(DW);
// Add to context owner.
Owner->AddChild(Variable);
// Add to map.
Variables[Name] = Variable;
// If external add to visible names.
if (IsExternal) {
DW.NewGlobalEntity(Name, Variable);
}
}
return Variable;
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// PrintHex - Print a value as a hexidecimal value. /// PrintHex - Print a value as a hexidecimal value.
@ -903,20 +1094,29 @@ void DwarfWriter::EmitReference(const char *Tag, unsigned Number) const {
PrintLabelName(Tag, Number); PrintLabelName(Tag, Number);
} }
void DwarfWriter::EmitReference(const std::string Name) const {
if (AddressSize == 4)
O << Asm->Data32bitsDirective;
else
O << Asm->Data64bitsDirective;
O << Name;
}
/// EmitDifference - Emit an label difference as sizeof(pointer) value. Some /// EmitDifference - Emit an label difference as sizeof(pointer) value. Some
/// assemblers do not accept absolute expressions with data directives, so there /// assemblers do not accept absolute expressions with data directives, so there
/// is an option (needsSet) to use an intermediary 'set' expression. /// is an option (needsSet) to use an intermediary 'set' expression.
void DwarfWriter::EmitDifference(const char *Tag1, unsigned Number1, void DwarfWriter::EmitDifference(const char *TagHi, unsigned NumberHi,
const char *Tag2, unsigned Number2) const { const char *TagLo, unsigned NumberLo) const {
if (needsSet) { if (needsSet) {
static unsigned SetCounter = 0; static unsigned SetCounter = 0;
O << "\t.set\t"; O << "\t.set\t";
PrintLabelName("set", SetCounter); PrintLabelName("set", SetCounter);
O << ","; O << ",";
PrintLabelName(Tag1, Number1); PrintLabelName(TagHi, NumberHi);
O << "-"; O << "-";
PrintLabelName(Tag2, Number2); PrintLabelName(TagLo, NumberLo);
O << "\n"; O << "\n";
if (AddressSize == sizeof(int32_t)) if (AddressSize == sizeof(int32_t))
@ -933,40 +1133,58 @@ void DwarfWriter::EmitDifference(const char *Tag1, unsigned Number1,
else else
O << Asm->Data64bitsDirective; O << Asm->Data64bitsDirective;
PrintLabelName(Tag1, Number1); PrintLabelName(TagHi, NumberHi);
O << "-"; O << "-";
PrintLabelName(Tag2, Number2); PrintLabelName(TagLo, NumberLo);
} }
} }
/// NewDIE - Construct a new structured debug information entry. /// NewAbbreviation - Add the abbreviation to the Abbreviation vector.
/// ///
DIE *DwarfWriter::NewDIE(const unsigned char *AbbrevData) { unsigned DwarfWriter::NewAbbreviation(DIEAbbrev *Abbrev) {
// Get the abbreviation ID. return Abbreviations.insert(*Abbrev);
unsigned AbbrevID = Abbreviations.insert(DIEAbbrev(AbbrevData)); }
// Allocate new new structured DIE.
DIE *Die = new DIE(AbbrevID); /// NewString - Add a string to the constant pool and returns a label.
// Return structured DIE. ///
return Die; DWLabel DwarfWriter::NewString(const std::string &String) {
unsigned StringID = StringPool.insert(String);
return DWLabel("string", StringID);
}
/// NewGlobalType - Make the type visible globally using the given name.
///
void DwarfWriter::NewGlobalType(const std::string &Name, DIE *Type) {
// FIXME - check for duplication.
GlobalTypes[Name] = Type;
}
/// NewGlobalEntity - Make the entity visible globally using the given name.
///
void DwarfWriter::NewGlobalEntity(const std::string &Name, DIE *Entity) {
// FIXME - check for duplication.
GlobalEntities[Name] = Entity;
} }
/// NewCompileUnit - Create new compile unit information. /// NewCompileUnit - Create new compile unit information.
/// ///
DIE *DwarfWriter::NewCompileUnit(const std::string &Directory, DIE *DwarfWriter::NewCompileUnit(const std::string &Directory,
const std::string &SourceName) { const std::string &SourceName) {
DIE *Die = NewDIE(AbbrevTAG_compile_unit); DIE *Unit = new DIE(DW_TAG_compile_unit, DW_CHILDREN_yes);
// FIXME - use the correct line set. // FIXME - use the correct line set.
Die->AddValue(DWLabel("line", 0)); Unit->AddLabel (DW_AT_stmt_list, DW_FORM_data4, DWLabel("line", 0));
Die->AddValue(DWLabel("text_end", 0)); Unit->AddLabel (DW_AT_high_pc, DW_FORM_addr, DWLabel("text_end", 0));
Die->AddValue(DWLabel("text_begin", 0)); Unit->AddLabel (DW_AT_low_pc, DW_FORM_addr, DWLabel("text_begin", 0));
// FIXME - The producer needs to be in this form, but should come from // FIXME - The producer needs to be in this form, but should come from
// an appropriate source. // an appropriate source.
Die->AddValue("llvm 3.4.x (LLVM Research Group)"); Unit->AddString(DW_AT_producer, DW_FORM_string,
Die->AddValue(DW_LANG_C89); "llvm 3.4.x (LLVM Research Group)");
Die->AddValue(SourceName); Unit->AddInt (DW_AT_language, DW_FORM_data1, DW_LANG_C89);
Die->AddValue(Directory); Unit->AddString(DW_AT_name, DW_FORM_string, SourceName);
Unit->AddString(DW_AT_comp_dir, DW_FORM_string, Directory);
Unit->Complete(*this);
return Die; return Unit;
} }
/// EmitInitial - Emit initial Dwarf declarations. This is necessary for cc /// EmitInitial - Emit initial Dwarf declarations. This is necessary for cc
@ -1003,11 +1221,12 @@ void DwarfWriter::EmitDIE(DIE *Die) const {
" "); " ");
const std::vector<DIEValue *> &Values = Die->getValues(); const std::vector<DIEValue *> &Values = Die->getValues();
const std::vector<DIEAbbrevData> &AbbrevData = Abbrev.getData();
// Emit the DIE attribute values. // Emit the DIE attribute values.
for (unsigned i = 0, N = Values.size(); i < N; i++) { for (unsigned i = 0, N = Values.size(); i < N; i++) {
unsigned Attr = Abbrev.getAttribute(i); unsigned Attr = AbbrevData[i].getAttribute();
unsigned Form = Abbrev.getForm(i); unsigned Form = AbbrevData[i].getForm();
assert(Form && "Too many attributes for DIE (check abbreviation)"); assert(Form && "Too many attributes for DIE (check abbreviation)");
switch (Attr) { switch (Attr) {
@ -1053,11 +1272,12 @@ unsigned DwarfWriter::SizeAndOffsetDie(DIE *Die, unsigned Offset) const {
Offset += SizeULEB128(AbbrevID); Offset += SizeULEB128(AbbrevID);
const std::vector<DIEValue *> &Values = Die->getValues(); const std::vector<DIEValue *> &Values = Die->getValues();
const std::vector<DIEAbbrevData> &AbbrevData = Abbrev.getData();
// Emit the DIE attribute values. // Emit the DIE attribute values.
for (unsigned i = 0, N = Values.size(); i < N; i++) { for (unsigned i = 0, N = Values.size(); i < N; i++) {
// Size attribute value. // Size attribute value.
Offset += Values[i]->SizeOf(*this, Abbrev.getForm(i)); Offset += Values[i]->SizeOf(*this, AbbrevData[i].getForm());
} }
// Emit the DIE children if any. // Emit the DIE children if any.
@ -1085,7 +1305,7 @@ void DwarfWriter::SizeAndOffsets() {
unsigned Offset = sizeof(int32_t) + // Length of Compilation Unit Info unsigned Offset = sizeof(int32_t) + // Length of Compilation Unit Info
sizeof(int16_t) + // DWARF version number sizeof(int16_t) + // DWARF version number
sizeof(int32_t) + // Offset Into Abbrev. Section sizeof(int32_t) + // Offset Into Abbrev. Section
sizeof(int8_t); // Pointer Size (in bytes) sizeof(int8_t); // Pointer Size (in bytes)
// Process each compile unit. // Process each compile unit.
for (unsigned i = 0, N = CompileUnits.size(); i < N; i++) { for (unsigned i = 0, N = CompileUnits.size(); i < N; i++) {
@ -1104,6 +1324,8 @@ void DwarfWriter::EmitDebugInfo() const {
// If there are any compile units. // If there are any compile units.
if (N) { if (N) {
EmitLabel("info_begin", 0);
// Emit the compile units header. // Emit the compile units header.
// Emit size of content not including length itself // Emit size of content not including length itself
@ -1113,7 +1335,7 @@ void DwarfWriter::EmitDebugInfo() const {
EmitShort(DWARF_VERSION); EOL("DWARF version number"); EmitShort(DWARF_VERSION); EOL("DWARF version number");
EmitReference("abbrev", 0); EOL("Offset Into Abbrev. Section"); EmitReference("abbrev_begin", 0); EOL("Offset Into Abbrev. Section");
EmitByte(AddressSize); EOL("Address Size (in bytes)"); EmitByte(AddressSize); EOL("Address Size (in bytes)");
@ -1121,52 +1343,35 @@ void DwarfWriter::EmitDebugInfo() const {
for (unsigned i = 0; i < N; i++) { for (unsigned i = 0; i < N; i++) {
EmitDIE(CompileUnits[i]); EmitDIE(CompileUnits[i]);
} }
EmitLabel("info_end", 0);
} }
} }
/// EmitAbbreviations - Emit the abbreviation section. /// EmitAbbreviations - Emit the abbreviation section.
/// ///
void DwarfWriter::EmitAbbreviations() const { void DwarfWriter::EmitAbbreviations() const {
// Start the debug abbrev section. // Check to see if it is worth the effort.
Asm->SwitchSection(DwarfAbbrevSection, 0); if (!Abbreviations.empty()) {
// Start the debug abbrev section.
// For each abbrevation. Asm->SwitchSection(DwarfAbbrevSection, 0);
for (unsigned AbbrevID = 1, NAID = Abbreviations.size();
AbbrevID <= NAID; AbbrevID++) {
// Get abbreviation data
const DIEAbbrev &Abbrev = Abbreviations[AbbrevID];
// Emit the abbrevations code (base 1 index.) EmitLabel("abbrev_begin", 0);
EmitULEB128Bytes(AbbrevID); EOL("Abbreviation Code");
// Emit its Dwarf tag type. // For each abbrevation.
EmitULEB128Bytes(Abbrev.getTag()); for (unsigned AbbrevID = 1, NAID = Abbreviations.size();
EOL(TagString(Abbrev.getTag())); AbbrevID <= NAID; AbbrevID++) {
// Get abbreviation data
// Emit whether it has children DIEs. const DIEAbbrev &Abbrev = Abbreviations[AbbrevID];
EmitULEB128Bytes(Abbrev.getChildrenFlag());
EOL(ChildrenString(Abbrev.getChildrenFlag()));
// For each attribute description.
for (unsigned i = 0; ; i++) {
unsigned Attr = Abbrev.getAttribute(i);
unsigned Form = Abbrev.getForm(i);
// Attributes are null terminated. // Emit the abbrevations code (base 1 index.)
if (!Attr) break; EmitULEB128Bytes(AbbrevID); EOL("Abbreviation Code");
// Emit attribute type. // Emit the abbreviations data.
EmitULEB128Bytes(Attr); Abbrev.Emit(*this);
EOL(AttributeString(Attr));
// Emit form type.
EmitULEB128Bytes(Form);
EOL(FormEncodingString(Form));
} }
// Mark end of abbreviation. EmitLabel("abbrev_end", 0);
EmitULEB128Bytes(0); EOL("EOM(1)");
EmitULEB128Bytes(0); EOL("EOM(2)");
} }
} }
@ -1303,22 +1508,67 @@ void DwarfWriter::EmitDebugFrame() {
/// EmitDebugPubNames - Emit visible names into a debug pubnames section. /// EmitDebugPubNames - Emit visible names into a debug pubnames section.
/// ///
void DwarfWriter::EmitDebugPubNames() { void DwarfWriter::EmitDebugPubNames() {
// Start the dwarf pubnames section. // Check to see if it is worth the effort.
Asm->SwitchSection(DwarfPubNamesSection, 0); if (!GlobalEntities.empty()) {
// Start the dwarf pubnames section.
Asm->SwitchSection(DwarfPubNamesSection, 0);
EmitDifference("pubnames_end", 0, "pubnames_begin", 0);
EOL("Length of Public Names Info");
EmitLabel("pubnames_begin", 0);
EmitShort(DWARF_VERSION); EOL("DWARF Version");
EmitReference("info_begin", 0); EOL("Offset of Compilation Unit Info");
EmitDifference("info_end", 0, "info_begin", 0);
EOL("Compilation Unit Length");
for (std::map<std::string, DIE *>::iterator G = GlobalTypes.begin(),
GE = GlobalTypes.begin();
G != GE; G++) {
const std::string &Name = (*G).first;
DIE * Entity = (*G).second;
EmitLong(Entity->getOffset()); EOL("DIE offset");
EmitString(Name); EOL("External Name");
}
EmitLong(0); EOL("End Mark");
EmitLabel("pubnames_end", 0);
}
} }
/// EmitDebugPubTypes - Emit visible names into a debug pubtypes section. /// EmitDebugPubTypes - Emit visible names into a debug pubtypes section.
/// ///
void DwarfWriter::EmitDebugPubTypes() { void DwarfWriter::EmitDebugPubTypes() {
// Start the dwarf pubtypes section. // Check to see if it is worth the effort.
Asm->SwitchSection(DwarfPubTypesSection, 0); if (!GlobalTypes.empty()) {
// Start the dwarf pubtypes section.
Asm->SwitchSection(DwarfPubTypesSection, 0);
}
} }
/// EmitDebugStr - Emit visible names into a debug str section. /// EmitDebugStr - Emit visible names into a debug str section.
/// ///
void DwarfWriter::EmitDebugStr() { void DwarfWriter::EmitDebugStr() {
// Start the dwarf str section. // Check to see if it is worth the effort.
Asm->SwitchSection(DwarfStrSection, 0); if (!StringPool.empty()) {
// Start the dwarf str section.
Asm->SwitchSection(DwarfStrSection, 0);
// For each of strings in teh string pool.
for (unsigned StringID = 1, N = StringPool.size();
StringID <= N; StringID++) {
// Emit a label for reference from debug information entries.
EmitLabel("string", StringID);
// Emit the string itself.
const std::string &String = StringPool[StringID];
EmitString(String); O << "\n";
}
}
} }
/// EmitDebugLoc - Emit visible names into a debug loc section. /// EmitDebugLoc - Emit visible names into a debug loc section.
@ -1341,7 +1591,7 @@ void DwarfWriter::EmitDebugARanges() {
EmitShort(DWARF_VERSION); EOL("Dwarf Version"); EmitShort(DWARF_VERSION); EOL("Dwarf Version");
EmitReference("info", 0); EOL("Offset of Compilation Unit Info"); EmitReference("info_begin", 0); EOL("Offset of Compilation Unit Info");
EmitByte(AddressSize); EOL("Size of Address"); EmitByte(AddressSize); EOL("Size of Address");
@ -1389,7 +1639,7 @@ bool DwarfWriter::ShouldEmitDwarf() {
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Main enties. // Main entry points.
// //
DwarfWriter::DwarfWriter(std::ostream &o, AsmPrinter *ap) DwarfWriter::DwarfWriter(std::ostream &o, AsmPrinter *ap)
@ -1399,6 +1649,9 @@ bool DwarfWriter::ShouldEmitDwarf() {
, didInitial(false) , didInitial(false)
, CompileUnits() , CompileUnits()
, Abbreviations() , Abbreviations()
, GlobalTypes()
, GlobalEntities()
, StringPool()
, AddressSize(sizeof(int32_t)) , AddressSize(sizeof(int32_t))
, hasLEB128(false) , hasLEB128(false)
, hasDotLoc(false) , hasDotLoc(false)
@ -1419,6 +1672,9 @@ bool DwarfWriter::ShouldEmitDwarf() {
, DataSection(".data") , DataSection(".data")
{} {}
DwarfWriter::~DwarfWriter() { DwarfWriter::~DwarfWriter() {
for (unsigned i = 0, N = CompileUnits.size(); i < N; i++) {
delete CompileUnits[i];
}
} }
/// BeginModule - Emit all Dwarf sections that should come prior to the content. /// BeginModule - Emit all Dwarf sections that should come prior to the content.
@ -1439,7 +1695,7 @@ void DwarfWriter::EndModule() {
EmitLabel("text_end", 0); EmitLabel("text_end", 0);
Asm->SwitchSection(DataSection, 0); Asm->SwitchSection(DataSection, 0);
EmitLabel("data_end", 0); EmitLabel("data_end", 0);
// Get directory and source information. // Get directory and source information.
const UniqueVector<std::string> &Directories = DebugInfo->getDirectories(); const UniqueVector<std::string> &Directories = DebugInfo->getDirectories();
const UniqueVector<SourceFileInfo> &SourceFiles = DebugInfo->getSourceFiles(); const UniqueVector<SourceFileInfo> &SourceFiles = DebugInfo->getSourceFiles();
@ -1450,8 +1706,16 @@ void DwarfWriter::EndModule() {
const SourceFileInfo &SourceFile = SourceFiles[SourceID]; const SourceFileInfo &SourceFile = SourceFiles[SourceID];
const std::string &Directory = Directories[SourceFile.getDirectoryID()]; const std::string &Directory = Directories[SourceFile.getDirectoryID()];
const std::string &SourceName = SourceFile.getName(); const std::string &SourceName = SourceFile.getName();
DIE *CompileUnit = NewCompileUnit(Directory, SourceName); DIE *Unit = NewCompileUnit(Directory, SourceName);
CompileUnits.push_back(CompileUnit);
#if 0
// FIXME - just testing.
DWContext *Context = new DWContext(*this, Unit);
DIE *TypeInt = Context->NewBasicType("int", sizeof(int32_t), DW_ATE_signed);
Context->NewVariable("MyGlobal", SourceID, 1, TypeInt, true);
#endif
CompileUnits.push_back(Unit);
} }
// Compute DIE offsets and sizes. // Compute DIE offsets and sizes.