diff options
Diffstat (limited to 'lib/CodeGen/DwarfWriter.cpp')
-rw-r--r-- | lib/CodeGen/DwarfWriter.cpp | 3930 |
1 files changed, 0 insertions, 3930 deletions
diff --git a/lib/CodeGen/DwarfWriter.cpp b/lib/CodeGen/DwarfWriter.cpp deleted file mode 100644 index 5d6acc30ba..0000000000 --- a/lib/CodeGen/DwarfWriter.cpp +++ /dev/null @@ -1,3930 +0,0 @@ -//===-- llvm/CodeGen/DwarfWriter.cpp - Dwarf Framework ----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains support for writing dwarf info into asm files. -// -//===----------------------------------------------------------------------===// - -#include "llvm/CodeGen/DwarfWriter.h" - -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/UniqueVector.h" -#include "llvm/Module.h" -#include "llvm/Type.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineLocation.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Dwarf.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/DataTypes.h" -#include "llvm/Support/Mangler.h" -#include "llvm/System/Path.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetFrameInfo.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" -#include <ostream> -#include <string> -using namespace llvm; -using namespace llvm::dwarf; - -namespace llvm { - -//===----------------------------------------------------------------------===// - -/// Configuration values for initial hash set sizes (log2). -/// -static const unsigned InitDiesSetSize = 9; // 512 -static const unsigned InitAbbreviationsSetSize = 9; // 512 -static const unsigned InitValuesSetSize = 9; // 512 - -//===----------------------------------------------------------------------===// -/// Forward declarations. -/// -class DIE; -class DIEValue; - -//===----------------------------------------------------------------------===// -/// DWLabel - Labels are used to track locations in the assembler file. -/// Labels appear in the form @verbatim <prefix><Tag><Number> @endverbatim, -/// where the tag is a category of label (Ex. location) and number is a value -/// unique in that category. -class DWLabel { -public: - /// Tag - Label category tag. Should always be a staticly declared C string. - /// - const char *Tag; - - /// Number - Value to make label unique. - /// - unsigned Number; - - DWLabel(const char *T, unsigned N) : Tag(T), Number(N) {} - - void Profile(FoldingSetNodeID &ID) const { - ID.AddString(std::string(Tag)); - ID.AddInteger(Number); - } - -#ifndef NDEBUG - void print(std::ostream *O) const { - if (O) print(*O); - } - void print(std::ostream &O) const { - O << "." << Tag; - if (Number) O << Number; - } -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIEAbbrevData - Dwarf abbreviation data, describes the one attribute of a -/// Dwarf abbreviation. -class DIEAbbrevData { -private: - /// Attribute - Dwarf attribute code. - /// - unsigned Attribute; - - /// Form - Dwarf form code. - /// - unsigned Form; - -public: - DIEAbbrevData(unsigned A, unsigned F) - : Attribute(A) - , Form(F) - {} - - // Accessors. - unsigned getAttribute() const { return Attribute; } - unsigned getForm() const { return Form; } - - /// Profile - Used to gather unique data for the abbreviation folding set. - /// - void Profile(FoldingSetNodeID &ID)const { - ID.AddInteger(Attribute); - ID.AddInteger(Form); - } -}; - -//===----------------------------------------------------------------------===// -/// DIEAbbrev - Dwarf abbreviation, describes the organization of a debug -/// information object. -class DIEAbbrev : public FoldingSetNode { -private: - /// Tag - Dwarf tag code. - /// - unsigned Tag; - - /// Unique number for node. - /// - unsigned Number; - - /// ChildrenFlag - Dwarf children flag. - /// - unsigned ChildrenFlag; - - /// Data - Raw data bytes for abbreviation. - /// - SmallVector<DIEAbbrevData, 8> Data; - -public: - - DIEAbbrev(unsigned T, unsigned C) - : Tag(T) - , ChildrenFlag(C) - , Data() - {} - ~DIEAbbrev() {} - - // Accessors. - unsigned getTag() const { return Tag; } - unsigned getNumber() const { return Number; } - unsigned getChildrenFlag() const { return ChildrenFlag; } - const SmallVector<DIEAbbrevData, 8> &getData() const { return Data; } - void setTag(unsigned T) { Tag = T; } - void setChildrenFlag(unsigned CF) { ChildrenFlag = CF; } - void setNumber(unsigned N) { Number = N; } - - /// AddAttribute - Adds another set of attribute information to the - /// abbreviation. - void AddAttribute(unsigned Attribute, unsigned Form) { - Data.push_back(DIEAbbrevData(Attribute, Form)); - } - - /// AddFirstAttribute - Adds a set of attribute information to the front - /// of the abbreviation. - void AddFirstAttribute(unsigned Attribute, unsigned Form) { - Data.insert(Data.begin(), DIEAbbrevData(Attribute, Form)); - } - - /// Profile - Used to gather unique data for the abbreviation folding set. - /// - void Profile(FoldingSetNodeID &ID) { - ID.AddInteger(Tag); - ID.AddInteger(ChildrenFlag); - - // For each attribute description. - for (unsigned i = 0, N = Data.size(); i < N; ++i) - Data[i].Profile(ID); - } - - /// Emit - Print the abbreviation using the specified Dwarf writer. - /// - void Emit(const DwarfDebug &DD) const; - -#ifndef NDEBUG - void print(std::ostream *O) { - if (O) print(*O); - } - void print(std::ostream &O); - void dump(); -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIE - A structured debug information entry. Has an abbreviation which -/// describes it's organization. -class DIE : public FoldingSetNode { -protected: - /// Abbrev - Buffer for constructing abbreviation. - /// - DIEAbbrev Abbrev; - - /// Offset - Offset in debug info section. - /// - unsigned Offset; - - /// Size - Size of instance + children. - /// - unsigned Size; - - /// Children DIEs. - /// - std::vector<DIE *> Children; - - /// Attributes values. - /// - SmallVector<DIEValue*, 32> Values; - -public: - explicit DIE(unsigned Tag) - : Abbrev(Tag, DW_CHILDREN_no) - , Offset(0) - , Size(0) - , Children() - , Values() - {} - virtual ~DIE(); - - // Accessors. - DIEAbbrev &getAbbrev() { return Abbrev; } - unsigned getAbbrevNumber() const { - return Abbrev.getNumber(); - } - unsigned getTag() const { return Abbrev.getTag(); } - unsigned getOffset() const { return Offset; } - unsigned getSize() const { return Size; } - const std::vector<DIE *> &getChildren() const { return Children; } - SmallVector<DIEValue*, 32> &getValues() { return Values; } - void setTag(unsigned Tag) { Abbrev.setTag(Tag); } - void setOffset(unsigned O) { Offset = O; } - void setSize(unsigned S) { Size = S; } - - /// AddValue - Add a value and attributes to a DIE. - /// - void AddValue(unsigned Attribute, unsigned Form, DIEValue *Value) { - Abbrev.AddAttribute(Attribute, Form); - Values.push_back(Value); - } - - /// SiblingOffset - Return the offset of the debug information entry's - /// sibling. - unsigned SiblingOffset() const { return Offset + Size; } - - /// AddSiblingOffset - Add a sibling offset field to the front of the DIE. - /// - void AddSiblingOffset(); - - /// AddChild - Add a child to the DIE. - /// - void AddChild(DIE *Child) { - Abbrev.setChildrenFlag(DW_CHILDREN_yes); - Children.push_back(Child); - } - - /// Detach - Detaches objects connected to it after copying. - /// - void Detach() { - Children.clear(); - } - - /// Profile - Used to gather unique data for the value folding set. - /// - void Profile(FoldingSetNodeID &ID) ; - -#ifndef NDEBUG - void print(std::ostream *O, unsigned IncIndent = 0) { - if (O) print(*O, IncIndent); - } - void print(std::ostream &O, unsigned IncIndent = 0); - void dump(); -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIEValue - A debug information entry value. -/// -class DIEValue : public FoldingSetNode { -public: - enum { - isInteger, - isString, - isLabel, - isAsIsLabel, - isSectionOffset, - isDelta, - isEntry, - isBlock - }; - - /// Type - Type of data stored in the value. - /// - unsigned Type; - - explicit DIEValue(unsigned T) - : Type(T) - {} - virtual ~DIEValue() {} - - // Accessors - unsigned getType() const { return Type; } - - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *) { return true; } - - /// EmitValue - Emit value via the Dwarf writer. - /// - virtual void EmitValue(DwarfDebug &DD, unsigned Form) = 0; - - /// SizeOf - Return the size of a value in bytes. - /// - virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const = 0; - - /// Profile - Used to gather unique data for the value folding set. - /// - virtual void Profile(FoldingSetNodeID &ID) = 0; - -#ifndef NDEBUG - void print(std::ostream *O) { - if (O) print(*O); - } - virtual void print(std::ostream &O) = 0; - void dump(); -#endif -}; - -//===----------------------------------------------------------------------===// -/// DWInteger - An integer value DIE. -/// -class DIEInteger : public DIEValue { -private: - uint64_t Integer; - -public: - explicit DIEInteger(uint64_t I) : DIEValue(isInteger), Integer(I) {} - - // Implement isa/cast/dyncast. - static bool classof(const DIEInteger *) { return true; } - static bool classof(const DIEValue *I) { return I->Type == isInteger; } - - /// BestForm - Choose the best form for integer. - /// - static unsigned BestForm(bool IsSigned, uint64_t Integer) { - if (IsSigned) { - if ((char)Integer == (signed)Integer) return DW_FORM_data1; - if ((short)Integer == (signed)Integer) return DW_FORM_data2; - if ((int)Integer == (signed)Integer) return DW_FORM_data4; - } else { - if ((unsigned char)Integer == Integer) return DW_FORM_data1; - if ((unsigned short)Integer == Integer) return DW_FORM_data2; - if ((unsigned int)Integer == Integer) return DW_FORM_data4; - } - return DW_FORM_data8; - } - - /// EmitValue - Emit integer of appropriate size. - /// - virtual void EmitValue(DwarfDebug &DD, unsigned Form); - - /// SizeOf - Determine size of integer value in bytes. - /// - virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const; - - /// Profile - Used to gather unique data for the value folding set. - /// - static void Profile(FoldingSetNodeID &ID, unsigned Integer) { - ID.AddInteger(isInteger); - ID.AddInteger(Integer); - } - virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, Integer); } - -#ifndef NDEBUG - virtual void print(std::ostream &O) { - O << "Int: " << (int64_t)Integer - << " 0x" << std::hex << Integer << std::dec; - } -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIEString - A string value DIE. -/// -class DIEString : public DIEValue { -public: - const std::string String; - - explicit DIEString(const std::string &S) : DIEValue(isString), String(S) {} - - // Implement isa/cast/dyncast. - static bool classof(const DIEString *) { return true; } - static bool classof(const DIEValue *S) { return S->Type == isString; } - - /// EmitValue - Emit string value. - /// - virtual void EmitValue(DwarfDebug &DD, unsigned Form); - - /// SizeOf - Determine size of string value in bytes. - /// - virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const { - return String.size() + sizeof(char); // sizeof('\0'); - } - - /// Profile - Used to gather unique data for the value folding set. - /// - static void Profile(FoldingSetNodeID &ID, const std::string &String) { - ID.AddInteger(isString); - ID.AddString(String); - } - virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, String); } - -#ifndef NDEBUG - virtual void print(std::ostream &O) { - O << "Str: \"" << String << "\""; - } -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIEDwarfLabel - A Dwarf internal label expression DIE. -// -class DIEDwarfLabel : public DIEValue { -public: - - const DWLabel Label; - - explicit DIEDwarfLabel(const DWLabel &L) : DIEValue(isLabel), Label(L) {} - - // Implement isa/cast/dyncast. - static bool classof(const DIEDwarfLabel *) { return true; } - static bool classof(const DIEValue *L) { return L->Type == isLabel; } - - /// EmitValue - Emit label value. - /// - virtual void EmitValue(DwarfDebug &DD, unsigned Form); - - /// SizeOf - Determine size of label value in bytes. - /// - virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const; - - /// Profile - Used to gather unique data for the value folding set. - /// - static void Profile(FoldingSetNodeID &ID, const DWLabel &Label) { - ID.AddInteger(isLabel); - Label.Profile(ID); - } - virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, Label); } - -#ifndef NDEBUG - virtual void print(std::ostream &O) { - O << "Lbl: "; - Label.print(O); - } -#endif -}; - - -//===----------------------------------------------------------------------===// -/// DIEObjectLabel - A label to an object in code or data. -// -class DIEObjectLabel : public DIEValue { -public: - const std::string Label; - - explicit DIEObjectLabel(const std::string &L) - : DIEValue(isAsIsLabel), Label(L) {} - - // Implement isa/cast/dyncast. - static bool classof(const DIEObjectLabel *) { return true; } - static bool classof(const DIEValue *L) { return L->Type == isAsIsLabel; } - - /// EmitValue - Emit label value. - /// - virtual void EmitValue(DwarfDebug &DD, unsigned Form); - - /// SizeOf - Determine size of label value in bytes. - /// - virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const; - - /// Profile - Used to gather unique data for the value folding set. - /// - static void Profile(FoldingSetNodeID &ID, const std::string &Label) { - ID.AddInteger(isAsIsLabel); - ID.AddString(Label); - } - virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, Label); } - -#ifndef NDEBUG - virtual void print(std::ostream &O) { - O << "Obj: " << Label; - } -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIESectionOffset - A section offset DIE. -// -class DIESectionOffset : public DIEValue { -public: - const DWLabel Label; - const DWLabel Section; - bool IsEH : 1; - bool UseSet : 1; - - DIESectionOffset(const DWLabel &Lab, const DWLabel &Sec, - bool isEH = false, bool useSet = true) - : DIEValue(isSectionOffset), Label(Lab), Section(Sec), - IsEH(isEH), UseSet(useSet) {} - - // Implement isa/cast/dyncast. - static bool classof(const DIESectionOffset *) { return true; } - static bool classof(const DIEValue *D) { return D->Type == isSectionOffset; } - - /// EmitValue - Emit section offset. - /// - virtual void EmitValue(DwarfDebug &DD, unsigned Form); - - /// SizeOf - Determine size of section offset value in bytes. - /// - virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const; - - /// Profile - Used to gather unique data for the value folding set. - /// - static void Profile(FoldingSetNodeID &ID, const DWLabel &Label, - const DWLabel &Section) { - ID.AddInteger(isSectionOffset); - Label.Profile(ID); - Section.Profile(ID); - // IsEH and UseSet are specific to the Label/Section that we will emit - // the offset for; so Label/Section are enough for uniqueness. - } - virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, Label, Section); } - -#ifndef NDEBUG - virtual void print(std::ostream &O) { - O << "Off: "; - Label.print(O); - O << "-"; - Section.print(O); - O << "-" << IsEH << "-" << UseSet; - } -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIEDelta - A simple label difference DIE. -/// -class DIEDelta : public DIEValue { -public: - const DWLabel LabelHi; - const DWLabel LabelLo; - - DIEDelta(const DWLabel &Hi, const DWLabel &Lo) - : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {} - - // Implement isa/cast/dyncast. - static bool classof(const DIEDelta *) { return true; } - static bool classof(const DIEValue *D) { return D->Type == isDelta; } - - /// EmitValue - Emit delta value. - /// - virtual void EmitValue(DwarfDebug &DD, unsigned Form); - - /// SizeOf - Determine size of delta value in bytes. - /// - virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const; - - /// Profile - Used to gather unique data for the value folding set. - /// - static void Profile(FoldingSetNodeID &ID, const DWLabel &LabelHi, - const DWLabel &LabelLo) { - ID.AddInteger(isDelta); - LabelHi.Profile(ID); - LabelLo.Profile(ID); - } - virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, LabelHi, LabelLo); } - -#ifndef NDEBUG - virtual void print(std::ostream &O) { - O << "Del: "; - LabelHi.print(O); - O << "-"; - LabelLo.print(O); - } -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIEntry - A pointer to another debug information entry. An instance of this -/// class can also be used as a proxy for a debug information entry not yet -/// defined (ie. types.) -class DIEntry : public DIEValue { -public: - DIE *Entry; - - explicit 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 debug information entry offset. - /// - virtual void EmitValue(DwarfDebug &DD, unsigned Form); - - /// SizeOf - Determine size of debug information entry in bytes. - /// - virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const { - return sizeof(int32_t); - } - - /// Profile - Used to gather unique data for the value folding set. - /// - static void Profile(FoldingSetNodeID &ID, DIE *Entry) { - ID.AddInteger(isEntry); - ID.AddPointer(Entry); - } - virtual void Profile(FoldingSetNodeID &ID) { - ID.AddInteger(isEntry); - - if (Entry) { - ID.AddPointer(Entry); - } else { - ID.AddPointer(this); - } - } - -#ifndef NDEBUG - virtual void print(std::ostream &O) { - O << "Die: 0x" << std::hex << (intptr_t)Entry << std::dec; - } -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIEBlock - A block of values. Primarily used for location expressions. -// -class DIEBlock : public DIEValue, public DIE { -public: - unsigned Size; // Size in bytes excluding size header. - - DIEBlock() - : DIEValue(isBlock) - , DIE(0) - , Size(0) - {} - ~DIEBlock() { - } - - // Implement isa/cast/dyncast. - static bool classof(const DIEBlock *) { return true; } - static bool classof(const DIEValue *E) { return E->Type == isBlock; } - - /// ComputeSize - calculate the size of the block. - /// - unsigned ComputeSize(DwarfDebug &DD); - - /// BestForm - Choose the best form for data. - /// - unsigned BestForm() const { - if ((unsigned char)Size == Size) return DW_FORM_block1; - if ((unsigned short)Size == Size) return DW_FORM_block2; - if ((unsigned int)Size == Size) return DW_FORM_block4; - return DW_FORM_block; - } - - /// EmitValue - Emit block data. - /// - virtual void EmitValue(DwarfDebug &DD, unsigned Form); - - /// SizeOf - Determine size of block data in bytes. - /// - virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const; - - - /// Profile - Used to gather unique data for the value folding set. - /// - virtual void Profile(FoldingSetNodeID &ID) { - ID.AddInteger(isBlock); - DIE::Profile(ID); - } - -#ifndef NDEBUG - virtual void print(std::ostream &O) { - O << "Blk: "; - DIE::print(O, 5); - } -#endif -}; - -//===----------------------------------------------------------------------===// -/// CompileUnit - This dwarf writer support class manages information associate -/// with a source file. -class CompileUnit { -private: - /// Desc - Compile unit debug descriptor. - /// - CompileUnitDesc *Desc; - - /// ID - File identifier for source. - /// - unsigned ID; - - /// Die - Compile unit debug information entry. - /// - DIE *Die; - - /// DescToDieMap - Tracks the mapping of unit level debug informaton - /// descriptors to debug information entries. - std::map<DebugInfoDesc *, DIE *> DescToDieMap; - - /// DescToDIEntryMap - Tracks the mapping of unit level debug informaton - /// descriptors to debug information entries using a DIEntry proxy. - std::map<DebugInfoDesc *, DIEntry *> DescToDIEntryMap; - - /// Globals - A map of globally visible named entities for this unit. - /// - std::map<std::string, DIE *> Globals; - - /// DiesSet - Used to uniquely define dies within the compile unit. - /// - FoldingSet<DIE> DiesSet; - - /// Dies - List of all dies in the compile unit. - /// - std::vector<DIE *> Dies; - -public: - CompileUnit(CompileUnitDesc *CUD, unsigned I, DIE *D) - : Desc(CUD) - , ID(I) - , Die(D) - , DescToDieMap() - , DescToDIEntryMap() - , Globals() - , DiesSet(InitDiesSetSize) - , Dies() - {} - - ~CompileUnit() { - delete Die; - - for (unsigned i = 0, N = Dies.size(); i < N; ++i) - delete Dies[i]; - } - - // Accessors. - CompileUnitDesc *getDesc() const { return Desc; } - unsigned getID() const { return ID; } - DIE* getDie() const { return Die; } - std::map<std::string, DIE *> &getGlobals() { return Globals; } - - /// hasContent - Return true if this compile unit has something to write out. - /// - bool hasContent() const { - return !Die->getChildren().empty(); - } - - /// AddGlobal - Add a new global entity to the compile unit. - /// - void AddGlobal(const std::string &Name, DIE *Die) { - Globals[Name] = Die; - } - - /// getDieMapSlotFor - Returns the debug information entry map slot for the - /// specified debug descriptor. - DIE *&getDieMapSlotFor(DebugInfoDesc *DID) { - return DescToDieMap[DID]; - } - - /// getDIEntrySlotFor - Returns the debug information entry proxy slot for the - /// specified debug descriptor. - DIEntry *&getDIEntrySlotFor(DebugInfoDesc *DID) { - return DescToDIEntryMap[DID]; - } - - /// AddDie - Adds or interns the DIE to the compile unit. - /// - DIE *AddDie(DIE &Buffer) { - FoldingSetNodeID ID; - Buffer.Profile(ID); - void *Where; - DIE *Die = DiesSet.FindNodeOrInsertPos(ID, Where); - - if (!Die) { - Die = new DIE(Buffer); - DiesSet.InsertNode(Die, Where); - this->Die->AddChild(Die); - Buffer.Detach(); - } - - return Die; - } -}; - -//===----------------------------------------------------------------------===// -/// Dwarf - Emits general Dwarf directives. -/// -class Dwarf { - -protected: - - //===--------------------------------------------------------------------===// - // Core attributes used by the Dwarf writer. - // - - // - /// O - Stream to .s file. - /// - std::ostream &O; - - /// Asm - Target of Dwarf emission. - /// - AsmPrinter *Asm; - - /// TAI - Target asm information. - const TargetAsmInfo *TAI; - - /// TD - Target data. - const TargetData *TD; - - /// RI - Register Information. - const TargetRegisterInfo *RI; - - /// M - Current module. - /// - Module *M; - - /// MF - Current machine function. - /// - MachineFunction *MF; - - /// MMI - Collected machine module information. - /// - MachineModuleInfo *MMI; - - /// SubprogramCount - The running count of functions being compiled. - /// - unsigned SubprogramCount; - - /// Flavor - A unique string indicating what dwarf producer this is, used to - /// unique labels. - const char * const Flavor; - - unsigned SetCounter; - Dwarf(std::ostream &OS, AsmPrinter *A, const TargetAsmInfo *T, - const char *flavor) - : O(OS) - , Asm(A) - , TAI(T) - , TD(Asm->TM.getTargetData()) - , RI(Asm->TM.getRegisterInfo()) - , M(NULL) - , MF(NULL) - , MMI(NULL) - , SubprogramCount(0) - , Flavor(flavor) - , SetCounter(1) - { - } - -public: - - //===--------------------------------------------------------------------===// - // Accessors. - // - AsmPrinter *getAsm() const { return Asm; } - MachineModuleInfo *getMMI() const { return MMI; } - const TargetAsmInfo *getTargetAsmInfo() const { return TAI; } - const TargetData *getTargetData() const { return TD; } - - void PrintRelDirective(bool Force32Bit = false, bool isInSection = false) - const { - if (isInSection && TAI->getDwarfSectionOffsetDirective()) - O << TAI->getDwarfSectionOffsetDirective(); - else if (Force32Bit || TD->getPointerSize() == sizeof(int32_t)) - O << TAI->getData32bitsDirective(); - else - O << TAI->getData64bitsDirective(); - } - - /// PrintLabelName - Print label name in form used by Dwarf writer. - /// - void PrintLabelName(DWLabel Label) const { - PrintLabelName(Label.Tag, Label.Number); - } - void PrintLabelName(const char *Tag, unsigned Number) const { - O << TAI->getPrivateGlobalPrefix() << Tag; - if (Number) O << Number; - } - - void PrintLabelName(const char *Tag, unsigned Number, - const char *Suffix) const { - O << TAI->getPrivateGlobalPrefix() << Tag; - if (Number) O << Number; - O << Suffix; - } - - /// EmitLabel - Emit location label for internal use by Dwarf. - /// - void EmitLabel(DWLabel Label) const { - EmitLabel(Label.Tag, Label.Number); - } - void EmitLabel(const char *Tag, unsigned Number) const { - PrintLabelName(Tag, Number); - O << ":\n"; - } - - /// EmitReference - Emit a reference to a label. - /// - void EmitReference(DWLabel Label, bool IsPCRelative = false, - bool Force32Bit = false) const { - EmitReference(Label.Tag, Label.Number, IsPCRelative, Force32Bit); - } - void EmitReference(const char *Tag, unsigned Number, - bool IsPCRelative = false, bool Force32Bit = false) const { - PrintRelDirective(Force32Bit); - PrintLabelName(Tag, Number); - - if (IsPCRelative) O << "-" << TAI->getPCSymbol(); - } - void EmitReference(const std::string &Name, bool IsPCRelative = false, - bool Force32Bit = false) const { - PrintRelDirective(Force32Bit); - - O << Name; - - if (IsPCRelative) O << "-" << TAI->getPCSymbol(); - } - - /// EmitDifference - Emit the difference between two labels. Some - /// assemblers do not behave with absolute expressions with data directives, - /// so there is an option (needsSet) to use an intermediary set expression. - void EmitDifference(DWLabel LabelHi, DWLabel LabelLo, - bool IsSmall = false) { - EmitDifference(LabelHi.Tag, LabelHi.Number, - LabelLo.Tag, LabelLo.Number, - IsSmall); - } - void EmitDifference(const char *TagHi, unsigned NumberHi, - const char *TagLo, unsigned NumberLo, - bool IsSmall = false) { - if (TAI->needsSet()) { - O << "\t.set\t"; - PrintLabelName("set", SetCounter, Flavor); - O << ","; - PrintLabelName(TagHi, NumberHi); - O << "-"; - PrintLabelName(TagLo, NumberLo); - O << "\n"; - - PrintRelDirective(IsSmall); - PrintLabelName("set", SetCounter, Flavor); - ++SetCounter; - } else { - PrintRelDirective(IsSmall); - - PrintLabelName(TagHi, NumberHi); - O << "-"; - PrintLabelName(TagLo, NumberLo); - } - } - - void EmitSectionOffset(const char* Label, const char* Section, - unsigned LabelNumber, unsigned SectionNumber, - bool IsSmall = false, bool isEH = false, - bool useSet = true) { - bool printAbsolute = false; - if (isEH) - printAbsolute = TAI->isAbsoluteEHSectionOffsets(); - else - printAbsolute = TAI->isAbsoluteDebugSectionOffsets(); - - if (TAI->needsSet() && useSet) { - O << "\t.set\t"; - PrintLabelName("set", SetCounter, Flavor); - O << ","; - PrintLabelName(Label, LabelNumber); - - if (!printAbsolute) { - O << "-"; - PrintLabelName(Section, SectionNumber); - } - O << "\n"; - - PrintRelDirective(IsSmall); - - PrintLabelName("set", SetCounter, Flavor); - ++SetCounter; - } else { - PrintRelDirective(IsSmall, true); - - PrintLabelName(Label, LabelNumber); - - if (!printAbsolute) { - O << "-"; - PrintLabelName(Section, SectionNumber); - } - } - } - - /// EmitFrameMoves - Emit frame instructions to describe the layout of the - /// frame. - void EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID, - const std::vector<MachineMove> &Moves, bool isEH) { - int stackGrowth = - Asm->TM.getFrameInfo()->getStackGrowthDirection() == - TargetFrameInfo::StackGrowsUp ? - TD->getPointerSize() : -TD->getPointerSize(); - bool IsLocal = BaseLabel && strcmp(BaseLabel, "label") == 0; - - for (unsigned i = 0, N = Moves.size(); i < N; ++i) { - const MachineMove &Move = Moves[i]; - unsigned LabelID = Move.getLabelID(); - - if (LabelID) { - LabelID = MMI->MappedLabel(LabelID); - - // Throw out move if the label is invalid. - if (!LabelID) continue; - } - - const MachineLocation &Dst = Move.getDestination(); - const MachineLocation &Src = Move.getSource(); - - // Advance row if new location. - if (BaseLabel && LabelID && (BaseLabelID != LabelID || !IsLocal)) { - Asm->EmitInt8(DW_CFA_advance_loc4); - Asm->EOL("DW_CFA_advance_loc4"); - EmitDifference("label", LabelID, BaseLabel, BaseLabelID, true); - Asm->EOL(); - - BaseLabelID = LabelID; - BaseLabel = "label"; - IsLocal = true; - } - - // If advancing cfa. - if (Dst.isRegister() && Dst.getRegister() == MachineLocation::VirtualFP) { - if (!Src.isRegister()) { - if (Src.getRegister() == MachineLocation::VirtualFP) { - Asm->EmitInt8(DW_CFA_def_cfa_offset); - Asm->EOL("DW_CFA_def_cfa_offset"); - } else { - Asm->EmitInt8(DW_CFA_def_cfa); - Asm->EOL("DW_CFA_def_cfa"); - Asm->EmitULEB128Bytes(RI->getDwarfRegNum(Src.getRegister(), isEH)); - Asm->EOL("Register"); - } - - int Offset = -Src.getOffset(); - - Asm->EmitULEB128Bytes(Offset); - Asm->EOL("Offset"); - } else { - assert(0 && "Machine move no supported yet."); - } - } else if (Src.isRegister() && - Src.getRegister() == MachineLocation::VirtualFP) { - if (Dst.isRegister()) { - Asm->EmitInt8(DW_CFA_def_cfa_register); - Asm->EOL("DW_CFA_def_cfa_register"); - Asm->EmitULEB128Bytes(RI->getDwarfRegNum(Dst.getRegister(), isEH)); - Asm->EOL("Register"); - } else { - assert(0 && "Machine move no supported yet."); - } - } else { - unsigned Reg = RI->getDwarfRegNum(Src.getRegister(), isEH); - int Offset = Dst.getOffset() / stackGrowth; - - if (Offset < 0) { - Asm->EmitInt8(DW_CFA_offset_extended_sf); - Asm->EOL("DW_CFA_offset_extended_sf"); - Asm->EmitULEB128Bytes(Reg); - Asm->EOL("Reg"); - Asm->EmitSLEB128Bytes(Offset); - Asm->EOL("Offset"); - } else if (Reg < 64) { - Asm->EmitInt8(DW_CFA_offset + Reg); - if (VerboseAsm) - Asm->EOL("DW_CFA_offset + Reg (" + utostr(Reg) + ")"); - else - Asm->EOL(); - Asm->EmitULEB128Bytes(Offset); - Asm->EOL("Offset"); - } else { - Asm->EmitInt8(DW_CFA_offset_extended); - Asm->EOL("DW_CFA_offset_extended"); - Asm->EmitULEB128Bytes(Reg); - Asm->EOL("Reg"); - Asm->EmitULEB128Bytes(Offset); - Asm->EOL("Offset"); - } - } - } - } - -}; - -//===----------------------------------------------------------------------===// -/// DwarfDebug - Emits Dwarf debug directives. -/// -class DwarfDebug : public Dwarf { - -private: - //===--------------------------------------------------------------------===// - // Attributes used to construct specific Dwarf sections. - // - - /// CompileUnits - All the compile units involved in this build. The index - /// of each entry in this vector corresponds to the sources in MMI. - std::vector<CompileUnit *> CompileUnits; - - /// AbbreviationsSet - Used to uniquely define abbreviations. - /// - FoldingSet<DIEAbbrev> AbbreviationsSet; - - /// Abbreviations - A list of all the unique abbreviations in use. - /// - std::vector<DIEAbbrev *> Abbreviations; - - /// ValuesSet - Used to uniquely define values. - /// - FoldingSet<DIEValue> ValuesSet; - |