X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FDwarfWriter.cpp;h=d1f195d55672aea08c5dd8b0aa5c6ee699a628d2;hb=ee888132754c709de8d2e2c5ef85531a15ed44f2;hp=cf6a922d23ce444ba09174ff79e78bea5297f516;hpb=ef4a661725716c60b49c40eed5225cac52f877e9;p=oota-llvm.git diff --git a/lib/CodeGen/DwarfWriter.cpp b/lib/CodeGen/DwarfWriter.cpp index cf6a922d23c..d1f195d5567 100644 --- a/lib/CodeGen/DwarfWriter.cpp +++ b/lib/CodeGen/DwarfWriter.cpp @@ -28,6 +28,7 @@ #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/MRegisterInfo.h" #include "llvm/Target/TargetData.h" @@ -798,9 +799,14 @@ protected: /// 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) + Dwarf(std::ostream &OS, AsmPrinter *A, const TargetAsmInfo *T, + const char *flavor) : O(OS) , Asm(A) , TAI(T) @@ -810,6 +816,7 @@ protected: , MF(NULL) , MMI(NULL) , SubprogramCount(0) + , Flavor(flavor) , SetCounter(1) { } @@ -822,12 +829,13 @@ public: 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 || TAI->getAddressSize() == sizeof(int32_t)) + else if (Force32Bit || TD->getPointerSize() == sizeof(int32_t)) O << TAI->getData32bitsDirective(); else O << TAI->getData64bitsDirective(); @@ -839,11 +847,17 @@ public: 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 { @@ -856,18 +870,20 @@ public: /// EmitReference - Emit a reference to a label. /// - void EmitReference(DWLabel Label, bool IsPCRelative = false) const { - EmitReference(Label.Tag, Label.Number, IsPCRelative); + 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) const { - PrintRelDirective(); + 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) const { - PrintRelDirective(); + void EmitReference(const std::string &Name, bool IsPCRelative = false, + bool Force32Bit = false) const { + PrintRelDirective(Force32Bit); O << Name; @@ -888,7 +904,7 @@ public: bool IsSmall = false) { if (TAI->needsSet()) { O << "\t.set\t"; - PrintLabelName("set", SetCounter); + PrintLabelName("set", SetCounter, Flavor); O << ","; PrintLabelName(TagHi, NumberHi); O << "-"; @@ -896,9 +912,7 @@ public: O << "\n"; PrintRelDirective(IsSmall); - - PrintLabelName("set", SetCounter); - + PrintLabelName("set", SetCounter, Flavor); ++SetCounter; } else { PrintRelDirective(IsSmall); @@ -915,7 +929,7 @@ public: bool printAbsolute = false; if (TAI->needsSet()) { O << "\t.set\t"; - PrintLabelName("set", SetCounter); + PrintLabelName("set", SetCounter, Flavor); O << ","; PrintLabelName(Label, LabelNumber); @@ -932,7 +946,7 @@ public: PrintRelDirective(IsSmall); - PrintLabelName("set", SetCounter); + PrintLabelName("set", SetCounter, Flavor); ++SetCounter; } else { PrintRelDirective(IsSmall, true); @@ -954,11 +968,11 @@ public: /// EmitFrameMoves - Emit frame instructions to describe the layout of the /// frame. void EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID, - const std::vector &Moves) { + const std::vector &Moves, bool isEH) { int stackGrowth = Asm->TM.getFrameInfo()->getStackGrowthDirection() == TargetFrameInfo::StackGrowsUp ? - TAI->getAddressSize() : -TAI->getAddressSize(); + TD->getPointerSize() : -TD->getPointerSize(); bool IsLocal = BaseLabel && strcmp(BaseLabel, "label") == 0; for (unsigned i = 0, N = Moves.size(); i < N; ++i) { @@ -996,7 +1010,7 @@ public: } else { Asm->EmitInt8(DW_CFA_def_cfa); Asm->EOL("DW_CFA_def_cfa"); - Asm->EmitULEB128Bytes(RI->getDwarfRegNum(Src.getRegister())); + Asm->EmitULEB128Bytes(RI->getDwarfRegNum(Src.getRegister(), isEH)); Asm->EOL("Register"); } @@ -1012,13 +1026,13 @@ public: if (Dst.isRegister()) { Asm->EmitInt8(DW_CFA_def_cfa_register); Asm->EOL("DW_CFA_def_cfa_register"); - Asm->EmitULEB128Bytes(RI->getDwarfRegNum(Dst.getRegister())); + 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()); + unsigned Reg = RI->getDwarfRegNum(Src.getRegister(), isEH); int Offset = Dst.getOffset() / stackGrowth; if (Offset < 0) { @@ -1301,7 +1315,9 @@ public: ValuesSet.InsertNode(Value, Where); Values.push_back(Value); } else { + // Already exists, reuse the previous one. delete Block; + Block = cast(Value); } Die->AddValue(Attribute, Block->BestForm(), Value); @@ -1324,7 +1340,7 @@ private: /// provided. void AddAddress(DIE *Die, unsigned Attribute, const MachineLocation &Location) { - unsigned Reg = RI->getDwarfRegNum(Location.getRegister()); + unsigned Reg = RI->getDwarfRegNum(Location.getRegister(), false); DIEBlock *Block = new DIEBlock(); if (Location.isRegister()) { @@ -1379,7 +1395,7 @@ private: /// DIE *ConstructPointerType(CompileUnit *Unit, const std::string &Name) { DIE Buffer(DW_TAG_pointer_type); - AddUInt(&Buffer, DW_AT_byte_size, 0, TAI->getAddressSize()); + AddUInt(&Buffer, DW_AT_byte_size, 0, TD->getPointerSize()); if (!Name.empty()) AddString(&Buffer, DW_AT_name, DW_FORM_string, Name); return Unit->AddDie(Buffer); } @@ -2120,7 +2136,7 @@ private: Asm->EmitInt16(DWARF_VERSION); Asm->EOL("DWARF version number"); EmitSectionOffset("abbrev_begin", "section_abbrev", 0, 0, true, false); Asm->EOL("Offset Into Abbrev. Section"); - Asm->EmitInt8(TAI->getAddressSize()); Asm->EOL("Address Size (in bytes)"); + Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)"); EmitDIE(Die); // FIXME - extra padding for gdb bug. @@ -2170,6 +2186,11 @@ private: /// EmitDebugLines - Emit source line information. /// void EmitDebugLines() { + // If there are no lines to emit (such as when we're using .loc directives + // to emit .debug_line information) don't emit a .debug_line header. + if (SectionSourceLines.empty()) + return; + // Minimum line delta, thus ranging from -10..(255-10). const int MinLineDelta = -(DW_LNS_fixed_advance_pc + 1); // Maximum line delta, thus ranging from -10..(255-10). @@ -2266,7 +2287,7 @@ private: // Define the line address. Asm->EmitInt8(0); Asm->EOL("Extended Op"); - Asm->EmitInt8(TAI->getAddressSize() + 1); Asm->EOL("Op size"); + Asm->EmitInt8(TD->getPointerSize() + 1); Asm->EOL("Op size"); Asm->EmitInt8(DW_LNE_set_address); Asm->EOL("DW_LNE_set_address"); EmitReference("label", LabelID); Asm->EOL("Location label"); @@ -2304,7 +2325,7 @@ private: // Define last address of section. Asm->EmitInt8(0); Asm->EOL("Extended Op"); - Asm->EmitInt8(TAI->getAddressSize() + 1); Asm->EOL("Op size"); + Asm->EmitInt8(TD->getPointerSize() + 1); Asm->EOL("Op size"); Asm->EmitInt8(DW_LNE_set_address); Asm->EOL("DW_LNE_set_address"); EmitReference("section_end", j + 1); Asm->EOL("Section end label"); @@ -2328,7 +2349,7 @@ private: int stackGrowth = Asm->TM.getFrameInfo()->getStackGrowthDirection() == TargetFrameInfo::StackGrowsUp ? - TAI->getAddressSize() : -TAI->getAddressSize(); + TD->getPointerSize() : -TD->getPointerSize(); // Start the dwarf frame section. Asm->SwitchToDataSection(TAI->getDwarfFrameSection()); @@ -2349,13 +2370,13 @@ private: Asm->EOL("CIE Code Alignment Factor"); Asm->EmitSLEB128Bytes(stackGrowth); Asm->EOL("CIE Data Alignment Factor"); - Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister())); + Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), false)); Asm->EOL("CIE RA Column"); std::vector Moves; RI->getInitialFrameState(Moves); - EmitFrameMoves(NULL, 0, Moves); + EmitFrameMoves(NULL, 0, Moves, false); Asm->EmitAlignment(2); EmitLabel("debug_frame_common_end", 0); @@ -2388,7 +2409,7 @@ private: "func_begin", DebugFrameInfo.Number); Asm->EOL("FDE address range"); - EmitFrameMoves("func_begin", DebugFrameInfo.Number, DebugFrameInfo.Moves); + EmitFrameMoves("func_begin", DebugFrameInfo.Number, DebugFrameInfo.Moves, false); Asm->EmitAlignment(2); EmitLabel("debug_frame_end", DebugFrameInfo.Number); @@ -2486,7 +2507,7 @@ private: EmitReference("info_begin", Unit->getID()); Asm->EOL("Offset of Compilation Unit Info"); - Asm->EmitInt8(TAI->getAddressSize()); Asm->EOL("Size of Address"); + Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Size of Address"); Asm->EmitInt8(0); Asm->EOL("Size of Segment Descriptor"); @@ -2499,9 +2520,9 @@ private: Asm->EmitInt32(0); Asm->EOL("EOM (1)"); Asm->EmitInt32(0); Asm->EOL("EOM (2)"); + #endif Asm->EOL(); - #endif } /// EmitDebugRanges - Emit visible names into a debug ranges section. @@ -2563,7 +2584,7 @@ public: // Main entry points. // DwarfDebug(std::ostream &OS, AsmPrinter *A, const TargetAsmInfo *T) - : Dwarf(OS, A, T) + : Dwarf(OS, A, T, "dbg") , CompileUnits() , AbbreviationsSet(InitAbbreviationsSetSize) , Abbreviations() @@ -2592,9 +2613,6 @@ public: MMI = mmi; shouldEmit = true; - // Emit initial sections - EmitInitial(); - // Create all the compile unit DIEs. ConstructCompileUnitDIEs(); @@ -2606,6 +2624,23 @@ public: // Prime section data. SectionMap.insert(TAI->getTextSection()); + + // Print out .file directives to specify files for .loc directives. These + // are printed out early so that they precede any .loc directives. + if (TAI->hasDotLocAndDotFile()) { + const UniqueVector &SourceFiles = MMI->getSourceFiles(); + const UniqueVector &Directories = MMI->getDirectories(); + for (unsigned i = 1, e = SourceFiles.size(); i <= e; ++i) { + sys::Path FullPath(Directories[SourceFiles[i].getDirectoryID()]); + bool AppendOk = FullPath.appendComponent(SourceFiles[i].getName()); + assert(AppendOk && "Could not append filename to directory!"); + Asm->EmitFile(i, FullPath.toString()); + Asm->EOL(); + } + } + + // Emit initial sections + EmitInitial(); } } @@ -2729,12 +2764,15 @@ private: bool hasCalls; bool hasLandingPads; std::vector Moves; + Function::LinkageTypes linkage; FunctionEHFrameInfo(const std::string &FN, unsigned Num, unsigned P, bool hC, bool hL, - const std::vector &M): + const std::vector &M, + Function::LinkageTypes l): FnName(FN), Number(Num), PersonalityIndex(P), - hasCalls(hC), hasLandingPads(hL), Moves(M) { } + hasCalls(hC), hasLandingPads(hL), Moves(M), + linkage(l) { } }; std::vector EHFrames; @@ -2750,7 +2788,7 @@ private: int stackGrowth = Asm->TM.getFrameInfo()->getStackGrowthDirection() == TargetFrameInfo::StackGrowsUp ? - TAI->getAddressSize() : -TAI->getAddressSize(); + TD->getPointerSize() : -TD->getPointerSize(); // Begin eh frame section. Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection()); @@ -2782,7 +2820,7 @@ private: Asm->EOL("CIE Code Alignment Factor"); Asm->EmitSLEB128Bytes(stackGrowth); Asm->EOL("CIE Data Alignment Factor"); - Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister())); + Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true)); Asm->EOL("CIE RA Column"); // If there is a personality, we need to indicate the functions location. @@ -2818,7 +2856,7 @@ private: // Indicate locations of general callee saved registers in frame. std::vector Moves; RI->getInitialFrameState(Moves); - EmitFrameMoves(NULL, 0, Moves); + EmitFrameMoves(NULL, 0, Moves, true); Asm->EmitAlignment(2); EmitLabel("eh_frame_common_end", Index); @@ -2832,15 +2870,25 @@ private: Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection()); // Externally visible entry into the functions eh frame info. - if (const char *GlobalDirective = TAI->getGlobalDirective()) - O << GlobalDirective << EHFrameInfo.FnName << ".eh\n"; - + // If the corresponding function is static, this should not be + // externally visible. + if (EHFrameInfo.linkage != Function::InternalLinkage) { + if (const char *GlobalEHDirective = TAI->getGlobalEHDirective()) + O << GlobalEHDirective << EHFrameInfo.FnName << "\n"; + } + // If there are no calls then you can't unwind. if (!EHFrameInfo.hasCalls) { - O << EHFrameInfo.FnName << ".eh = 0\n"; + O << EHFrameInfo.FnName << " = 0\n"; } else { - O << EHFrameInfo.FnName << ".eh:\n"; - + O << EHFrameInfo.FnName << ":\n"; + + // If corresponding function is weak definition, this should be too. + if ((EHFrameInfo.linkage == Function::WeakLinkage || + EHFrameInfo.linkage == Function::LinkOnceLinkage) && + TAI->getWeakDefDirective()) + O << TAI->getWeakDefDirective() << EHFrameInfo.FnName << "\n"; + // EH frame header. EmitDifference("eh_frame_end", EHFrameInfo.Number, "eh_frame_begin", EHFrameInfo.Number, true); @@ -2867,7 +2915,7 @@ private: if (EHFrameInfo.hasLandingPads) { EmitReference("exception", EHFrameInfo.Number, true); - } else if(TAI->getAddressSize() == 8) { + } else if (TD->getPointerSize() == 8) { Asm->EmitInt64((int)0); } else { Asm->EmitInt32((int)0); @@ -2880,14 +2928,14 @@ private: // Indicate locations of function specific callee saved registers in // frame. - EmitFrameMoves("eh_func_begin", EHFrameInfo.Number, EHFrameInfo.Moves); + EmitFrameMoves("eh_func_begin", EHFrameInfo.Number, EHFrameInfo.Moves, true); Asm->EmitAlignment(2); EmitLabel("eh_frame_end", EHFrameInfo.Number); } if (const char *UsedDirective = TAI->getUsedDirective()) - O << UsedDirective << EHFrameInfo.FnName << ".eh\n\n"; + O << UsedDirective << EHFrameInfo.FnName << "\n\n"; } /// EmitExceptionTable - Emit landing pads and actions. @@ -2942,6 +2990,7 @@ private: static inline unsigned getEmptyKey() { return -1U; } static inline unsigned getTombstoneKey() { return -2U; } static unsigned getHashValue(const unsigned &Key) { return Key; } + static bool isEqual(unsigned LHS, unsigned RHS) { return LHS == RHS; } static bool isPod() { return true; } }; @@ -3151,7 +3200,7 @@ private: for (unsigned i = 0, e = CallSites.size(); i < e; ++i) SizeSites += Asm->SizeULEB128(CallSites[i].Action); - unsigned SizeTypes = TypeInfos.size() * TAI->getAddressSize(); + unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize(); unsigned TypeOffset = sizeof(int8_t) + // Call site format Asm->SizeULEB128(SizeSites) + // Call-site table length @@ -3212,7 +3261,7 @@ private: Asm->EOL("Region length"); if (!S.PadLabel) { - if (TAI->getAddressSize() == sizeof(int32_t)) + if (TD->getPointerSize() == sizeof(int32_t)) Asm->EmitInt32(0); else Asm->EmitInt64(0); @@ -3265,7 +3314,7 @@ public: // Main entry points. // DwarfException(std::ostream &OS, AsmPrinter *A, const TargetAsmInfo *T) - : Dwarf(OS, A, T) + : Dwarf(OS, A, T, "eh") , shouldEmit(false) {} @@ -3320,12 +3369,14 @@ public: EmitExceptionTable(); // Save EH frame information - EHFrames.push_back(FunctionEHFrameInfo(getAsm()->CurrentFnName, - SubprogramCount, - MMI->getPersonalityIndex(), - MF->getFrameInfo()->hasCalls(), - !MMI->getLandingPads().empty(), - MMI->getFrameMoves())); + EHFrames. + push_back(FunctionEHFrameInfo(getAsm()->getCurrentFunctionEHName(MF), + SubprogramCount, + MMI->getPersonalityIndex(), + MF->getFrameInfo()->hasCalls(), + !MMI->getLandingPads().empty(), + MMI->getFrameMoves(), + MF->getFunction()->getLinkage())); } }; @@ -3445,13 +3496,15 @@ void DIEString::EmitValue(DwarfDebug &DD, unsigned Form) { /// EmitValue - Emit label value. /// void DIEDwarfLabel::EmitValue(DwarfDebug &DD, unsigned Form) { - DD.EmitReference(Label); + bool IsSmall = Form == DW_FORM_data4; + DD.EmitReference(Label, false, IsSmall); } /// SizeOf - Determine size of label value in bytes. /// unsigned DIEDwarfLabel::SizeOf(const DwarfDebug &DD, unsigned Form) const { - return DD.getTargetAsmInfo()->getAddressSize(); + if (Form == DW_FORM_data4) return 4; + return DD.getTargetData()->getPointerSize(); } //===----------------------------------------------------------------------===// @@ -3459,13 +3512,15 @@ unsigned DIEDwarfLabel::SizeOf(const DwarfDebug &DD, unsigned Form) const { /// EmitValue - Emit label value. /// void DIEObjectLabel::EmitValue(DwarfDebug &DD, unsigned Form) { - DD.EmitReference(Label); + bool IsSmall = Form == DW_FORM_data4; + DD.EmitReference(Label, false, IsSmall); } /// SizeOf - Determine size of label value in bytes. /// unsigned DIEObjectLabel::SizeOf(const DwarfDebug &DD, unsigned Form) const { - return DD.getTargetAsmInfo()->getAddressSize(); + if (Form == DW_FORM_data4) return 4; + return DD.getTargetData()->getPointerSize(); } //===----------------------------------------------------------------------===// @@ -3481,7 +3536,7 @@ void DIEDelta::EmitValue(DwarfDebug &DD, unsigned Form) { /// unsigned DIEDelta::SizeOf(const DwarfDebug &DD, unsigned Form) const { if (Form == DW_FORM_data4) return 4; - return DD.getTargetAsmInfo()->getAddressSize(); + return DD.getTargetData()->getPointerSize(); } //===----------------------------------------------------------------------===//