diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h --- a/llvm/include/llvm/MC/MCAsmInfo.h +++ b/llvm/include/llvm/MC/MCAsmInfo.h @@ -388,6 +388,14 @@ /// absolute difference. bool DwarfFDESymbolsUseAbsDiff = false; + /// True if the target supports generating the DWARF line table through using + /// the .loc/.file directives. Defaults to true. + bool UsesDwarfFileAndLocDirectives = true; + + /// True if the target needs the DWARF section length in the header (if any) + /// of the DWARF section in the assembly file. Defaults to true. + bool DwarfSectionSizeRequired = true; + /// True if dwarf register numbers are printed instead of symbolic register /// names in .cfi_* directives. Defaults to false. bool DwarfRegNumForCFI = false; @@ -667,6 +675,14 @@ return SupportsExtendedDwarfLocDirective; } + bool usesDwarfFileAndLocDirectives() const { + return UsesDwarfFileAndLocDirectives; + } + + bool needsDwarfSectionSizeInHeader() const { + return DwarfSectionSizeRequired; + } + void addInitialFrameState(const MCCFIInstruction &Inst); const std::vector &getInitialFrameState() const { diff --git a/llvm/include/llvm/MC/MCAsmStreamer.h b/llvm/include/llvm/MC/MCAsmStreamer.h --- a/llvm/include/llvm/MC/MCAsmStreamer.h +++ b/llvm/include/llvm/MC/MCAsmStreamer.h @@ -367,6 +367,18 @@ void emitRawTextImpl(StringRef String) override; void finishImpl() override; + + void emitDwarfUnitLength(uint64_t Length, const Twine &Comment) override; + + void emitDwarfUnitLength(MCSymbol *Hi, MCSymbol *Lo, + const Twine &Comment) override; + + void emitDwarfLineStartLabel(MCSymbol *StartSym, + MCSymbol *SymWithoutUnitLength) override; + + void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, + const MCSymbol *Label, + unsigned PointerSize) override; }; } // end anonymous namespace. diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h --- a/llvm/include/llvm/MC/MCContext.h +++ b/llvm/include/llvm/MC/MCContext.h @@ -574,7 +574,8 @@ const XCOFF::CsectProperty &CsectProp = XCOFF::CsectProperty(0xFF, 0xFF), bool MultiSymbolsAllowed = false, - const char *BeginSymName = nullptr); + const char *BeginSymName = nullptr, + unsigned SecFlags = 0); // Create and save a copy of STI and return a reference to the copy. MCSubtargetInfo &getSubtargetCopy(const MCSubtargetInfo &STI); diff --git a/llvm/include/llvm/MC/MCDwarf.h b/llvm/include/llvm/MC/MCDwarf.h --- a/llvm/include/llvm/MC/MCDwarf.h +++ b/llvm/include/llvm/MC/MCDwarf.h @@ -173,7 +173,7 @@ // This is called when an instruction is assembled into the specified // section and if there is information from the last .loc directive that // has yet to have a line entry made for it is made. - static void Make(MCObjectStreamer *MCOS, MCSection *Section); + static void make(MCStreamer *MCOS, MCSection *Section); }; /// Instances of this class represent the line information for a compile @@ -311,10 +311,10 @@ public: // This emits the Dwarf file and the line tables for all Compile Units. - static void Emit(MCObjectStreamer *MCOS, MCDwarfLineTableParams Params); + static void emit(MCStreamer *MCOS, MCDwarfLineTableParams Params); // This emits the Dwarf file and the line tables for a given Compile Unit. - void EmitCU(MCObjectStreamer *MCOS, MCDwarfLineTableParams Params, + void emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params, Optional &LineStr) const; Expected tryGetFile(StringRef &Directory, StringRef &FileName, diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h --- a/llvm/include/llvm/MC/MCObjectStreamer.h +++ b/llvm/include/llvm/MC/MCObjectStreamer.h @@ -151,7 +151,8 @@ unsigned Discriminator, StringRef FileName) override; void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, - const MCSymbol *Label, unsigned PointerSize); + const MCSymbol *Label, + unsigned PointerSize) override; void emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, const MCSymbol *Label); void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line, diff --git a/llvm/include/llvm/MC/MCSectionXCOFF.h b/llvm/include/llvm/MC/MCSectionXCOFF.h --- a/llvm/include/llvm/MC/MCSectionXCOFF.h +++ b/llvm/include/llvm/MC/MCSectionXCOFF.h @@ -36,21 +36,29 @@ XCOFF::SymbolType Type; MCSymbolXCOFF *const QualName; StringRef SymbolTableName; + unsigned SecFlags; bool MultiSymbolsAllowed; static constexpr unsigned DefaultAlignVal = 4; MCSectionXCOFF(StringRef Name, XCOFF::StorageMappingClass SMC, XCOFF::SymbolType ST, SectionKind K, MCSymbolXCOFF *QualName, - MCSymbol *Begin, StringRef SymbolTableName, + unsigned SecFlags, MCSymbol *Begin, StringRef SymbolTableName, bool MultiSymbolsAllowed) : MCSection(SV_XCOFF, Name, K, Begin), MappingClass(SMC), Type(ST), QualName(QualName), SymbolTableName(SymbolTableName), - MultiSymbolsAllowed(MultiSymbolsAllowed) { - assert((ST == XCOFF::XTY_SD || ST == XCOFF::XTY_CM || ST == XCOFF::XTY_ER) && - "Invalid or unhandled type for csect."); + SecFlags(SecFlags), MultiSymbolsAllowed(MultiSymbolsAllowed) { + bool DebugSec = SecFlags & (unsigned)XCOFF::STYP_DWARF; + if (!DebugSec) + assert( + (ST == XCOFF::XTY_SD || ST == XCOFF::XTY_CM || ST == XCOFF::XTY_ER) && + "Invalid or unhandled type for csect."); assert(QualName != nullptr && "QualName is needed."); + + // FIXME: use a more meanful name as *this maybe a debug section. QualName->setRepresentedCsect(this); - QualName->setStorageClass(XCOFF::C_HIDEXT); + // Debug sections have no storage class. + if (!DebugSec) + QualName->setStorageClass(XCOFF::C_HIDEXT); // A csect is 4 byte aligned by default, except for undefined symbol csects. if (Type != XCOFF::XTY_ER) setAlignment(Align(DefaultAlignVal)); @@ -79,6 +87,7 @@ bool isVirtualSection() const override; StringRef getSymbolTableName() const { return SymbolTableName; } bool isMultiSymbolsAllowed() const { return MultiSymbolsAllowed; } + unsigned getSecFlags() const { return SecFlags; } }; } // end namespace llvm diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -1104,6 +1104,19 @@ /// according to the settings. virtual void emitDwarfUnitLength(MCSymbol *Hi, MCSymbol *Lo, const Twine &Comment); + + /// Emit the debug line start label. + /// Return the 'new' start label for the reference inside debug line section. + virtual void emitDwarfLineStartLabel(MCSymbol *StartSym, + MCSymbol *SymWithoutUnitLength); + + /// If targets does not support representing debug line section by .loc/.file + /// directives in assembly output, we need to populate debug line section with + /// raw debug line contents. + virtual void emitDwarfAdvanceLineAddr(int64_t LineDelta, + const MCSymbol *LastLabel, + const MCSymbol *Label, + unsigned PointerSize) {} }; /// Create a dummy machine code streamer, which does nothing. This is useful for diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -380,10 +380,19 @@ DwarfVersion = TT.isNVPTX() ? 2 : (DwarfVersion ? DwarfVersion : dwarf::DWARF_VERSION); - bool Dwarf64 = Asm->TM.Options.MCOptions.Dwarf64 && - DwarfVersion >= 3 && // DWARF64 was introduced in DWARFv3. - TT.isArch64Bit() && // DWARF64 requires 64-bit relocations. - TT.isOSBinFormatELF(); // Support only ELF for now. + bool Dwarf64 = DwarfVersion >= 3 && // DWARF64 was introduced in DWARFv3. + TT.isArch64Bit(); // DWARF64 requires 64-bit relocations. + + // Support DWARF64 + // 1: For ELF when requested. + // 2: For XCOFF64: the AIX assembler will fill in debug section lengths + // according to the DWARF64 format for 64-bit assembly, so we must use + // DWARF64 in the compiler too for 64-bit mode. + Dwarf64 &= (Asm->TM.Options.MCOptions.Dwarf64 && TT.isOSBinFormatELF()) || + TT.isOSBinFormatXCOFF(); + + if (!Dwarf64 && TT.isArch64Bit() && TT.isOSBinFormatXCOFF()) + report_fatal_error("XCOFF requires DWARF64 for 64-bit mode!"); UseRangesSection = !NoDwarfRangesSection && !TT.isNVPTX(); diff --git a/llvm/lib/MC/MCAsmInfoXCOFF.cpp b/llvm/lib/MC/MCAsmInfoXCOFF.cpp --- a/llvm/lib/MC/MCAsmInfoXCOFF.cpp +++ b/llvm/lib/MC/MCAsmInfoXCOFF.cpp @@ -23,6 +23,8 @@ PrivateLabelPrefix = "L.."; SupportsQuotedNames = false; UseDotAlignForAlignment = true; + UsesDwarfFileAndLocDirectives = false; + DwarfSectionSizeRequired = false; if (UseLEB128Directives == cl::BOU_UNSET) HasLEB128Directives = false; ZeroDirective = "\t.space\t"; diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -1067,7 +1067,9 @@ if (!FileNoOrErr) return FileNoOrErr.takeError(); FileNo = FileNoOrErr.get(); - if (NumFiles == Table.getMCDwarfFiles().size()) + // For a new file, print a .file directive if the target supports it, otherwise + // return early. + if (NumFiles == Table.getMCDwarfFiles().size() || !MAI->usesDwarfFileAndLocDirectives()) return FileNo; SmallString<128> Str; @@ -1096,6 +1098,10 @@ getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum, Source); + // Target doesn't support .loc/.file directives, return early. + if (!MAI->usesDwarfFileAndLocDirectives()) + return; + SmallString<128> Str; raw_svector_ostream OS1(Str); printDwarfFileDirective(0, Directory, Filename, Checksum, Source, @@ -1111,6 +1117,14 @@ unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator, StringRef FileName) { + // If target doesn't support .loc/.file directive, we need to record the lines + // same way like we do in object mode. + if (!MAI->usesDwarfFileAndLocDirectives()) { + this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa, + Discriminator, FileName); + return; + } + OS << "\t.loc\t" << FileNo << " " << Line << " " << Column; if (MAI->supportsExtendedDwarfLocDirective()) { if (Flags & DWARF2_FLAG_BASIC_BLOCK) @@ -1754,6 +1768,11 @@ assert(getCurrentSectionOnly() && "Cannot emit contents before setting section!"); + if (!MAI->usesDwarfFileAndLocDirectives()) + // Now that a machine instruction has been assembled into this section, make + // a line entry for any .loc directive that has been seen. + MCDwarfLineEntry::make(this, getCurrentSectionOnly()); + // Show the encoding in a comment if we have a code emitter. AddEncodingComment(Inst, STI); @@ -1845,6 +1864,13 @@ if (getContext().getGenDwarfForAssembly()) MCGenDwarfInfo::Emit(this); + // Now it is time to emit debug line sections if target doesn't support .loc + // and .line directives. + if (!MAI->usesDwarfFileAndLocDirectives()) { + MCDwarfLineTable::emit(this, getAssembler().getDWARFLinetableParams()); + return; + } + // Emit the label for the line table, if requested - since the rest of the // line table will be defined by .loc/.file directives, and not emitted // directly, the label is the only work required here. @@ -1858,6 +1884,107 @@ } } +void MCAsmStreamer::emitDwarfUnitLength(uint64_t Length, const Twine &Comment) { + // If the assembler on some target fills in the DWARF unit length, we + // don't want to emit the length in the compiler. For example, the AIX + // assembler requires the assembly file with the unit length omitted from + // the debug section headers. In such cases, any label we placed occurs + // after the implied length field. We need to adjust the reference here + // to account for the offset introduced by the inserted length field. + if (!MAI->needsDwarfSectionSizeInHeader()) + return; + MCStreamer::emitDwarfUnitLength(Length, Comment); +} + +void MCAsmStreamer::emitDwarfUnitLength(MCSymbol *Hi, MCSymbol *Lo, + const Twine &Comment) { + // If the assembler on some target fills in the DWARF unit length, we + // don't want to emit the length in the compiler. For example, the AIX + // assembler requires the assembly file with the unit length omitted from + // the debug section headers. In such cases, any label we placed occurs + // after the implied length field. We need to adjust the reference here + // to account for the offset introduced by the inserted length field. + if (!MAI->needsDwarfSectionSizeInHeader()) { + if (Lo->isUndefined()) + emitLabel(Lo); + return; + } + MCStreamer::emitDwarfUnitLength(Hi, Lo, Comment); +} + +void MCAsmStreamer::emitDwarfLineStartLabel(MCSymbol *StartSym, + MCSymbol *SymWithoutUnitLength) { + // If the assembler on some target fills in the DWARF unit length, we + // don't want to emit the length in the compiler. For example, the AIX + // assembler requires the assembly file with the unit length omitted from + // the debug section headers. In such cases, any label we placed occurs + // after the implied length field. We need to adjust the reference here + // to account for the offset introduced by the inserted length field. + MCContext &Ctx = getContext(); + if (!MAI->needsDwarfSectionSizeInHeader()) { + // Emit the symbol which does not contain the unit length field. + emitLabel(SymWithoutUnitLength); + + // Adjust the outer reference to account for the offset introduced by the + // inserted length field. + unsigned LengthFieldSize = + dwarf::getUnitLengthFieldByteSize(Ctx.getDwarfFormat()); + const MCExpr *EntrySize = MCConstantExpr::create(LengthFieldSize, Ctx); + const MCExpr *OuterSym = MCBinaryExpr::createSub( + MCSymbolRefExpr::create(SymWithoutUnitLength, Ctx), EntrySize, Ctx); + + emitAssignment(StartSym, OuterSym); + return; + } + MCStreamer::emitDwarfLineStartLabel(StartSym, SymWithoutUnitLength); +} + +// Generate DWARF line sections for assembly mode without .loc/.file +void MCAsmStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta, + const MCSymbol *LastLabel, + const MCSymbol *Label, + unsigned PointerSize) { + assert(!MAI->usesDwarfFileAndLocDirectives() && + ".loc/.file don't need raw data in debug line section!"); + if (!LastLabel) { + // Set to CU beginning. + emitIntValue(dwarf::DW_LNS_extended_op, 1); + emitULEB128IntValue(PointerSize + 1); + emitIntValue(dwarf::DW_LNE_set_address, 1); + emitSymbolValue(Label, PointerSize); + + // Emit the sequence for the LineDelta (from 1) and a zero address delta. + MCDwarfLineAddr::Emit(this, MCDwarfLineTableParams(), LineDelta, 0); + return; + } + + // INT64_MAX is a signal of the end of the section. Emit DW_LNE_end_sequence + // for the end of the section. + if (LineDelta == INT64_MAX) { + // Set new address to end label. + emitIntValue(dwarf::DW_LNS_extended_op, 1); + emitULEB128IntValue(PointerSize + 1); + emitIntValue(dwarf::DW_LNE_set_address, 1); + emitSymbolValue(Label, PointerSize); + + emitIntValue(0, 1); + emitULEB128IntValue(1); + emitIntValue(dwarf::DW_LNE_end_sequence, 1); + return; + } + + // Set new address to new label. + emitIntValue(dwarf::DW_LNS_extended_op, 1); + emitULEB128IntValue(PointerSize + 1); + emitIntValue(dwarf::DW_LNE_set_address, 1); + emitSymbolValue(Label, PointerSize); + + // Advance line. + emitIntValue(dwarf::DW_LNS_advance_line, 1); + emitSLEB128IntValue(LineDelta); + emitIntValue(dwarf::DW_LNS_copy, 1); +} + MCStreamer *llvm::createAsmStreamer(MCContext &Context, std::unique_ptr OS, bool isVerboseAsm, bool useDwarfDirectory, diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/lib/MC/MCContext.cpp @@ -668,7 +668,7 @@ MCSectionXCOFF *MCContext::getXCOFFSection( StringRef Section, SectionKind Kind, const XCOFF::CsectProperty &CsectProp, - bool MultiSymbolsAllowed, const char *BeginSymName) { + bool MultiSymbolsAllowed, const char *BeginSymName, unsigned SecFlags) { // Do the lookup. If we have a hit, return it. auto IterBool = XCOFFUniquingMap.insert(std::make_pair( XCOFFSectionKey{Section.str(), (XCOFF::StorageMappingClass)CsectProp.SMC}, @@ -684,10 +684,16 @@ // Otherwise, return a new section. StringRef CachedName = Entry.first.SectionName; - MCSymbolXCOFF *QualName = cast(getOrCreateSymbol( - CachedName + "[" + - XCOFF::getMappingClassString((XCOFF::StorageMappingClass)CsectProp.SMC) + - "]")); + MCSymbolXCOFF *QualName = nullptr; + // Debug section don't have storage class attribute. + if ((SecFlags & (unsigned)XCOFF::STYP_DWARF) != 0) + QualName = cast(getOrCreateSymbol(CachedName)); + else + QualName = cast( + getOrCreateSymbol(CachedName + "[" + + XCOFF::getMappingClassString( + (XCOFF::StorageMappingClass)CsectProp.SMC) + + "]")); MCSymbol *Begin = nullptr; if (BeginSymName) @@ -697,8 +703,8 @@ // CachedName contains invalid character(s) such as '$' for an XCOFF symbol. MCSectionXCOFF *Result = new (XCOFFAllocator.Allocate()) MCSectionXCOFF( QualName->getUnqualifiedName(), (XCOFF::StorageMappingClass)CsectProp.SMC, - (XCOFF::SymbolType)CsectProp.ST, Kind, QualName, Begin, CachedName, - MultiSymbolsAllowed); + (XCOFF::SymbolType)CsectProp.ST, Kind, QualName, SecFlags, Begin, + CachedName, MultiSymbolsAllowed); Entry.second = Result; auto *F = new MCDataFragment(); diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -105,7 +105,7 @@ // and if there is information from the last .loc directive that has yet to have // a line entry made for it is made. // -void MCDwarfLineEntry::Make(MCObjectStreamer *MCOS, MCSection *Section) { +void MCDwarfLineEntry::make(MCStreamer *MCOS, MCSection *Section) { if (!MCOS->getContext().getDwarfLocSeen()) return; @@ -163,7 +163,7 @@ // in the LineSection. // static inline void emitDwarfLineTable( - MCObjectStreamer *MCOS, MCSection *Section, + MCStreamer *MCOS, MCSection *Section, const MCLineSection::MCDwarfLineEntryCollection &LineEntries) { unsigned FileNum = 1; unsigned LastLine = 1; @@ -245,8 +245,7 @@ // // This emits the Dwarf file and the line tables. // -void MCDwarfLineTable::Emit(MCObjectStreamer *MCOS, - MCDwarfLineTableParams Params) { +void MCDwarfLineTable::emit(MCStreamer *MCOS, MCDwarfLineTableParams Params) { MCContext &context = MCOS->getContext(); auto &LineTables = context.getMCDwarfLineTables(); @@ -266,7 +265,7 @@ // Handle the rest of the Compile Units. for (const auto &CUIDTablePair : LineTables) { - CUIDTablePair.second.EmitCU(MCOS, Params, LineStr); + CUIDTablePair.second.emitCU(MCOS, Params, LineStr); } if (LineStr) @@ -471,14 +470,16 @@ MCSymbol *LineStartSym = Label; if (!LineStartSym) LineStartSym = context.createTempSymbol(); + + MCSymbol *SymWithoutUnitLength = context.createTempSymbol("debug_line_"); + // Set the value of the symbol, as we are at the start of the line table. - MCOS->emitLabel(LineStartSym); + MCOS->emitDwarfLineStartLabel(LineStartSym, SymWithoutUnitLength); // Create a symbol for the end of the section (to be set when we get there). MCSymbol *LineEndSym = context.createTempSymbol(); unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(context.getDwarfFormat()); - MCSymbol *SymWithoutUnitLength = context.createTempSymbol("debug_line_"); MCOS->emitDwarfUnitLength(LineEndSym, SymWithoutUnitLength, "unit length"); // Next 2 bytes is the Version. @@ -536,8 +537,7 @@ return std::make_pair(LineStartSym, LineEndSym); } -void MCDwarfLineTable::EmitCU(MCObjectStreamer *MCOS, - MCDwarfLineTableParams Params, +void MCDwarfLineTable::emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params, Optional &LineStr) const { MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second; diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -871,17 +871,17 @@ TextSection = Ctx->getXCOFFSection( ".text", SectionKind::getText(), XCOFF::CsectProperty(XCOFF::StorageMappingClass::XMC_PR, XCOFF::XTY_SD), - /* MultiSymbolsAllowed*/ true); + /* MultiSymbolsAllowed */ true); DataSection = Ctx->getXCOFFSection( ".data", SectionKind::getData(), XCOFF::CsectProperty(XCOFF::StorageMappingClass::XMC_RW, XCOFF::XTY_SD), - /* MultiSymbolsAllowed*/ true); + /* MultiSymbolsAllowed */ true); ReadOnlySection = Ctx->getXCOFFSection( ".rodata", SectionKind::getReadOnly(), XCOFF::CsectProperty(XCOFF::StorageMappingClass::XMC_RO, XCOFF::XTY_SD), - /* MultiSymbolsAllowed*/ true); + /* MultiSymbolsAllowed */ true); TOCBaseSection = Ctx->getXCOFFSection( "TOC", SectionKind::getData(), @@ -901,18 +901,60 @@ // DWARF sections for XCOFF are not csects. They are special STYP_DWARF // sections, and the individual DWARF sections are distinguished by their // section subtype. - // TODO: Populate the DWARF sections appropriately. - DwarfAbbrevSection = nullptr; // SSUBTYP_DWABREV - DwarfInfoSection = nullptr; // SSUBTYP_DWINFO - DwarfLineSection = nullptr; // SSUBTYP_DWLINE - DwarfFrameSection = nullptr; // SSUBTYP_DWFRAME - DwarfPubNamesSection = nullptr; // SSUBTYP_DWPBNMS - DwarfPubTypesSection = nullptr; // SSUBTYP_DWPBTYP - DwarfStrSection = nullptr; // SSUBTYP_DWSTR - DwarfLocSection = nullptr; // SSUBTYP_DWLOC - DwarfARangesSection = nullptr; // SSUBTYP_DWARNGE - DwarfRangesSection = nullptr; // SSUBTYP_DWRNGES - DwarfMacinfoSection = nullptr; // SSUBTYP_DWMAC + DwarfAbbrevSection = Ctx->getXCOFFSection( + ".dwabrev", SectionKind::getMetadata(), XCOFF::CsectProperty(0xFF, 0xFF), + /* MultiSymbolsAllowed */ true, ".dwabrev", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWABREV); + + DwarfInfoSection = Ctx->getXCOFFSection( + ".dwinfo", SectionKind::getMetadata(), XCOFF::CsectProperty(0xFF, 0xFF), + /* MultiSymbolsAllowed */ true, ".dwinfo", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWINFO); + + DwarfLineSection = Ctx->getXCOFFSection( + ".dwline", SectionKind::getMetadata(), XCOFF::CsectProperty(0xFF, 0xFF), + /* MultiSymbolsAllowed */ true, ".dwline", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWLINE); + + DwarfFrameSection = Ctx->getXCOFFSection( + ".dwframe", SectionKind::getMetadata(), XCOFF::CsectProperty(0xFF, 0xFF), + /* MultiSymbolsAllowed */ true, ".dwframe", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWFRAME); + + DwarfPubNamesSection = Ctx->getXCOFFSection( + ".dwpbnms", SectionKind::getMetadata(), XCOFF::CsectProperty(0xFF, 0xFF), + /* MultiSymbolsAllowed */ true, ".dwpbnms", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWPBNMS); + + DwarfPubTypesSection = Ctx->getXCOFFSection( + ".dwpbtyp", SectionKind::getMetadata(), XCOFF::CsectProperty(0xFF, 0xFF), + /* MultiSymbolsAllowed */ true, ".dwpbtyp", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWPBTYP); + + DwarfStrSection = Ctx->getXCOFFSection( + ".dwstr", SectionKind::getMetadata(), XCOFF::CsectProperty(0xFF, 0xFF), + /* MultiSymbolsAllowed */ true, ".dwstr", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWSTR); + + DwarfLocSection = Ctx->getXCOFFSection( + ".dwloc", SectionKind::getMetadata(), XCOFF::CsectProperty(0xFF, 0xFF), + /* MultiSymbolsAllowed */ true, ".dwloc", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWLOC); + + DwarfARangesSection = Ctx->getXCOFFSection( + ".dwarnge", SectionKind::getMetadata(), XCOFF::CsectProperty(0xFF, 0xFF), + /* MultiSymbolsAllowed */ true, ".dwarnge", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWARNGE); + + DwarfRangesSection = Ctx->getXCOFFSection( + ".dwrnges", SectionKind::getMetadata(), XCOFF::CsectProperty(0xFF, 0xFF), + /* MultiSymbolsAllowed */ true, ".dwrnges", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWRNGES); + + DwarfMacinfoSection = Ctx->getXCOFFSection( + ".dwmac", SectionKind::getMetadata(), XCOFF::CsectProperty(0xFF, 0xFF), + /* MultiSymbolsAllowed */ true, ".dwmac", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWMAC); } void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC, diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -228,7 +228,7 @@ MCDataFragment *DF = getOrCreateDataFragment(); flushPendingLabels(DF, DF->getContents().size()); - MCDwarfLineEntry::Make(this, getCurrentSectionOnly()); + MCDwarfLineEntry::make(this, getCurrentSectionOnly()); // Avoid fixups when possible. int64_t AbsValue; @@ -385,7 +385,7 @@ // Now that a machine instruction has been assembled into this section, make // a line entry for any .loc directive that has been seen. - MCDwarfLineEntry::Make(this, getCurrentSectionOnly()); + MCDwarfLineEntry::make(this, getCurrentSectionOnly()); // If this instruction doesn't need relaxation, just emit it as data. MCAssembler &Assembler = getAssembler(); @@ -455,7 +455,7 @@ StringRef FileName) { // In case we see two .loc directives in a row, make sure the // first one gets a line entry. - MCDwarfLineEntry::Make(this, getCurrentSectionOnly()); + MCDwarfLineEntry::make(this, getCurrentSectionOnly()); this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa, Discriminator, FileName); @@ -573,7 +573,7 @@ } void MCObjectStreamer::emitBytes(StringRef Data) { - MCDwarfLineEntry::Make(this, getCurrentSectionOnly()); + MCDwarfLineEntry::make(this, getCurrentSectionOnly()); MCDataFragment *DF = getOrCreateDataFragment(); flushPendingLabels(DF, DF->getContents().size()); DF->getContents().append(Data.begin(), Data.end()); @@ -850,7 +850,7 @@ MCGenDwarfInfo::Emit(this); // Dump out the dwarf file & directory tables and line tables. - MCDwarfLineTable::Emit(this, getAssembler().getDWARFLinetableParams()); + MCDwarfLineTable::emit(this, getAssembler().getDWARFLinetableParams()); // Emit pseudo probes for the current module. MCPseudoProbeTable::emit(this); diff --git a/llvm/lib/MC/MCSectionXCOFF.cpp b/llvm/lib/MC/MCSectionXCOFF.cpp --- a/llvm/lib/MC/MCSectionXCOFF.cpp +++ b/llvm/lib/MC/MCSectionXCOFF.cpp @@ -9,6 +9,8 @@ #include "llvm/MC/MCSectionXCOFF.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCExpr.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -70,6 +72,16 @@ return; } + // XCOFF debug sections. + if (getKind().isMetadata() && (getSecFlags() & (unsigned)XCOFF::STYP_DWARF)) { + OS << "\n\t.dwsect " + << format("0x%" PRIx32, + (getSecFlags() & ~((unsigned)(XCOFF::STYP_DWARF)))) + << '\n'; + OS << MAI.getPrivateLabelPrefix() << getName() << ':' << '\n'; + return; + } + report_fatal_error("Printing for this SectionKind is unimplemented."); } diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -1017,6 +1017,12 @@ emitLabel(Lo); } +void MCStreamer::emitDwarfLineStartLabel(MCSymbol *StartSym, + MCSymbol *SymWithoutUnitLength) { + // Set the value of the symbol, as we are at the start of the line table. + emitLabel(StartSym); +} + void MCStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) { visitUsedExpr(*Value); Symbol->setVariableValue(Value); diff --git a/llvm/lib/MC/MCSymbolXCOFF.cpp b/llvm/lib/MC/MCSymbolXCOFF.cpp --- a/llvm/lib/MC/MCSymbolXCOFF.cpp +++ b/llvm/lib/MC/MCSymbolXCOFF.cpp @@ -13,9 +13,6 @@ MCSectionXCOFF *MCSymbolXCOFF::getRepresentedCsect() const { assert(RepresentedCsect && "Trying to get csect representation of this symbol but none was set."); - assert(!getName().equals(getUnqualifiedName()) && - "Symbol does not represent a csect; MCSectionXCOFF that represents " - "the symbol should not be (but is) set."); assert(getSymbolTableName().equals(RepresentedCsect->getSymbolTableName()) && "SymbolTableNames need to be the same for this symbol and its csect " "representation."); @@ -27,9 +24,6 @@ assert((!RepresentedCsect || RepresentedCsect == C) && "Trying to set a csect that doesn't match the one that this symbol is " "already mapped to."); - assert(!getName().equals(getUnqualifiedName()) && - "Symbol does not represent a csect; can only set a MCSectionXCOFF " - "representation for a csect."); assert(getSymbolTableName().equals(C->getSymbolTableName()) && "SymbolTableNames need to be the same for this symbol and its csect " "representation."); diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp @@ -63,4 +63,10 @@ // A size of 8 is only supported by the assembler under 64-bit. Data64bitsDirective = Is64Bit ? "\t.vbyte\t8, " : nullptr; + + // Debug Information + SupportsDebugInformation = true; + + // Set up DWARF directives + MinInstAlignment = 4; } diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -46,6 +46,7 @@ #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Module.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCAsmStreamer.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCExpr.h" @@ -2272,6 +2273,15 @@ } bool PPCAIXAsmPrinter::doFinalization(Module &M) { + // Add text end before we do any finalization. This is used to tell the debug + // line section where the text end is. + if (isa(OutStreamer) && + !OutContext.getAsmInfo()->usesDwarfFileAndLocDirectives()) { + MCSymbol *Sym = + OutStreamer->getCurrentSectionOnly()->getEndSymbol(OutContext); + if (!Sym->isInSection()) + OutStreamer->emitLabel(Sym); + } for (MCSymbol *Sym : ExtSymSDNodeSymbols) OutStreamer->emitSymbolAttribute(Sym, MCSA_Extern); return PPCAsmPrinter::doFinalization(M); diff --git a/llvm/test/CodeGen/PowerPC/aix-alias.ll b/llvm/test/CodeGen/PowerPC/aix-alias.ll --- a/llvm/test/CodeGen/PowerPC/aix-alias.ll +++ b/llvm/test/CodeGen/PowerPC/aix-alias.ll @@ -73,6 +73,7 @@ ; ASM-NEXT: nop ; ASM: bl .fun_hidden ; ASM: # -- End function +; ASM: L..sec_end0: ; ASM-NEXT: .csect .data[RW] ; ASM-NEXT: .globl var ; ASM: var: diff --git a/llvm/test/DebugInfo/XCOFF/empty.ll b/llvm/test/DebugInfo/XCOFF/empty.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/XCOFF/empty.ll @@ -0,0 +1,438 @@ + +; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | \ +; RUN: FileCheck %s --check-prefix=ASM32 +; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | \ +; RUN: FileCheck %s --check-prefix=ASM64 + +source_filename = "1.c" +target datalayout = "E-m:a-p:32:32-i64:64-n32" + +; Function Attrs: noinline nounwind optnone +define i32 @main() #0 !dbg !8 { +entry: + %retval = alloca i32, align 4 + store i32 0, i32* %retval, align 4 + ret i32 0, !dbg !12 +} + +attributes #0 = { noinline nounwind optnone "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pwr4" "target-features"="-altivec,-bpermd,-crypto,-direct-move,-extdiv,-float128,-htm,-power8-vector,-power9-vector,-spe,-vsx" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5, !6} +!llvm.ident = !{!7} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 12.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "1.c", directory: "debug") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 2} +!6 = !{i32 7, !"PIC Level", i32 2} +!7 = !{!"clang version 12.0.0"} +!8 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 1, type: !9, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) +!9 = !DISubroutineType(types: !10) +!10 = !{!11} +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !DILocation(line: 3, column: 3, scope: !8) + +; ASM32: .csect .text[PR],2 +; ASM32-NEXT: .file "1.c" +; ASM32-NEXT: .globl main[DS] # -- Begin function main +; ASM32-NEXT: .globl .main +; ASM32-NEXT: .align 4 +; ASM32-NEXT: .csect main[DS],2 +; ASM32-NEXT: .vbyte 4, .main # @main +; ASM32-NEXT: .vbyte 4, TOC[TC0] +; ASM32-NEXT: .vbyte 4, 0 +; ASM32-NEXT: .csect .text[PR],2 +; ASM32-NEXT: .main: +; ASM32-NEXT: L..func_begin0: +; ASM32-NEXT: # %bb.0: # %entry +; ASM32-NEXT: L..tmp0: +; ASM32-NEXT: li 3, 0 +; ASM32-NEXT: stw 3, -8(1) +; ASM32-NEXT: L..tmp1: +; ASM32-NEXT: L..tmp2: +; ASM32-NEXT: li 3, 0 +; ASM32-NEXT: blr +; ASM32-NEXT: L..tmp3: +; ASM32-NEXT: L..main0: +; ASM32-NEXT: .vbyte 4, 0x00000000 # Traceback table begin +; ASM32-NEXT: .byte 0x00 # Version = 0 +; ASM32-NEXT: .byte 0x09 # Language = CPlusPlus +; ASM32-NEXT: .byte 0x20 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue +; ASM32-NEXT: # +HasTraceBackTableOffset, -IsInternalProcedure +; ASM32-NEXT: # -HasControlledStorage, -IsTOCless +; ASM32-NEXT: # -IsFloatingPointPresent +; ASM32-NEXT: # -IsFloatingPointOperationLogOrAbortEnabled +; ASM32-NEXT: .byte 0x40 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed +; ASM32-NEXT: # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved +; ASM32-NEXT: .byte 0x80 # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0 +; ASM32-NEXT: .byte 0x00 # -HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0 +; ASM32-NEXT: .byte 0x00 # NumberOfFixedParms = 0 +; ASM32-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack +; ASM32-NEXT: .vbyte 4, L..main0-.main # Function size +; ASM32-NEXT: .vbyte 2, 0x0004 # Function name len = 4 +; ASM32-NEXT: .byte 'm,'a,'i,'n # Function Name +; ASM32-NEXT: L..func_end0: +; ASM32-NEXT: # -- End function +; ASM32-NEXT: L..sec_end0: +; ASM32: .dwsect 0x60000 +; ASM32-NEXT: L...dwabrev: +; ASM32-NEXT: .byte 1 # Abbreviation Code +; ASM32-NEXT: .byte 17 # DW_TAG_compile_unit +; ASM32-NEXT: .byte 1 # DW_CHILDREN_yes +; ASM32-NEXT: .byte 37 # DW_AT_producer +; ASM32-NEXT: .byte 14 # DW_FORM_strp +; ASM32-NEXT: .byte 19 # DW_AT_language +; ASM32-NEXT: .byte 5 # DW_FORM_data2 +; ASM32-NEXT: .byte 3 # DW_AT_name +; ASM32-NEXT: .byte 14 # DW_FORM_strp +; ASM32-NEXT: .byte 16 # DW_AT_stmt_list +; ASM32-NEXT: .byte 23 # DW_FORM_sec_offset +; ASM32-NEXT: .byte 27 # DW_AT_comp_dir +; ASM32-NEXT: .byte 14 # DW_FORM_strp +; ASM32-NEXT: .byte 17 # DW_AT_low_pc +; ASM32-NEXT: .byte 1 # DW_FORM_addr +; ASM32-NEXT: .byte 18 # DW_AT_high_pc +; ASM32-NEXT: .byte 6 # DW_FORM_data4 +; ASM32-NEXT: .byte 0 # EOM(1) +; ASM32-NEXT: .byte 0 # EOM(2) +; ASM32-NEXT: .byte 2 # Abbreviation Code +; ASM32-NEXT: .byte 46 # DW_TAG_subprogram +; ASM32-NEXT: .byte 0 # DW_CHILDREN_no +; ASM32-NEXT: .byte 17 # DW_AT_low_pc +; ASM32-NEXT: .byte 1 # DW_FORM_addr +; ASM32-NEXT: .byte 18 # DW_AT_high_pc +; ASM32-NEXT: .byte 6 # DW_FORM_data4 +; ASM32-NEXT: .byte 64 # DW_AT_frame_base +; ASM32-NEXT: .byte 24 # DW_FORM_exprloc +; ASM32-NEXT: .byte 3 # DW_AT_name +; ASM32-NEXT: .byte 14 # DW_FORM_strp +; ASM32-NEXT: .byte 58 # DW_AT_decl_file +; ASM32-NEXT: .byte 11 # DW_FORM_data1 +; ASM32-NEXT: .byte 59 # DW_AT_decl_line +; ASM32-NEXT: .byte 11 # DW_FORM_data1 +; ASM32-NEXT: .byte 39 # DW_AT_prototyped +; ASM32-NEXT: .byte 25 # DW_FORM_flag_present +; ASM32-NEXT: .byte 73 # DW_AT_type +; ASM32-NEXT: .byte 19 # DW_FORM_ref4 +; ASM32-NEXT: .byte 63 # DW_AT_external +; ASM32-NEXT: .byte 25 # DW_FORM_flag_present +; ASM32-NEXT: .byte 0 # EOM(1) +; ASM32-NEXT: .byte 0 # EOM(2) +; ASM32-NEXT: .byte 3 # Abbreviation Code +; ASM32-NEXT: .byte 36 # DW_TAG_base_type +; ASM32-NEXT: .byte 0 # DW_CHILDREN_no +; ASM32-NEXT: .byte 3 # DW_AT_name +; ASM32-NEXT: .byte 14 # DW_FORM_strp +; ASM32-NEXT: .byte 62 # DW_AT_encoding +; ASM32-NEXT: .byte 11 # DW_FORM_data1 +; ASM32-NEXT: .byte 11 # DW_AT_byte_size +; ASM32-NEXT: .byte 11 # DW_FORM_data1 +; ASM32-NEXT: .byte 0 # EOM(1) +; ASM32-NEXT: .byte 0 # EOM(2) +; ASM32-NEXT: .byte 0 # EOM(3) +; ASM32: .dwsect 0x10000 +; ASM32-NEXT: L...dwinfo: +; ASM32-NEXT: L..cu_begin0: +; ASM32-NEXT: L..debug_info_start0: +; ASM32-NEXT: .vbyte 2, 4 # DWARF version number +; ASM32-NEXT: .vbyte 4, L...dwabrev # Offset Into Abbrev. Section +; ASM32-NEXT: .byte 4 # Address Size (in bytes) +; ASM32-NEXT: .byte 1 # Abbrev [1] 0xb:0x38 DW_TAG_compile_unit +; ASM32-NEXT: .vbyte 4, L..info_string0 # DW_AT_producer +; ASM32-NEXT: .vbyte 2, 12 # DW_AT_language +; ASM32-NEXT: .vbyte 4, L..info_string1 # DW_AT_name +; ASM32-NEXT: .vbyte 4, L..line_table_start0 # DW_AT_stmt_list +; ASM32-NEXT: .vbyte 4, L..info_string2 # DW_AT_comp_dir +; ASM32-NEXT: .vbyte 4, L..func_begin0 # DW_AT_low_pc +; ASM32-NEXT: .vbyte 4, L..func_end0-L..func_begin0 # DW_AT_high_pc +; ASM32-NEXT: .byte 2 # Abbrev [2] 0x26:0x15 DW_TAG_subprogram +; ASM32-NEXT: .vbyte 4, L..func_begin0 # DW_AT_low_pc +; ASM32-NEXT: .vbyte 4, L..func_end0-L..func_begin0 # DW_AT_high_pc +; ASM32-NEXT: .byte 1 # DW_AT_frame_base +; ASM32-NEXT: .byte 81 +; ASM32-NEXT: .vbyte 4, L..info_string3 # DW_AT_name +; ASM32-NEXT: .byte 1 # DW_AT_decl_file +; ASM32-NEXT: .byte 1 # DW_AT_decl_line +; ASM32-NEXT: # DW_AT_prototyped +; ASM32-NEXT: .vbyte 4, 59 # DW_AT_type +; ASM32-NEXT: # DW_AT_external +; ASM32-NEXT: .byte 3 # Abbrev [3] 0x3b:0x7 DW_TAG_base_type +; ASM32-NEXT: .vbyte 4, L..info_string4 # DW_AT_name +; ASM32-NEXT: .byte 5 # DW_AT_encoding +; ASM32-NEXT: .byte 4 # DW_AT_byte_size +; ASM32-NEXT: .byte 0 # End Of Children Mark +; ASM32-NEXT: L..debug_info_end0: +; ASM32: .dwsect 0x70000 +; ASM32-NEXT: L...dwstr: +; ASM32-NEXT: L..info_string0: +; ASM32-NEXT: .byte 'c,'l,'a,'n,'g,' ,'v,'e,'r,'s,'i,'o,'n,' ,'1,'2,'.,'0,'.,'0,0000 # string offset=0 +; ASM32-NEXT: L..info_string1: +; ASM32-NEXT: .byte '1,'.,'c,0000 # string offset=21 +; ASM32-NEXT: L..info_string2: +; ASM32-NEXT: .byte 'd,'e,'b,'u,'g,0000 # string offset=25 +; ASM32-NEXT: L..info_string3: +; ASM32-NEXT: .byte 'm,'a,'i,'n,0000 # string offset=31 +; ASM32-NEXT: L..info_string4: +; ASM32-NEXT: .byte 'i,'n,'t,0000 # string offset=36 +; ASM32-NEXT: .toc +; ASM32: .dwsect 0x20000 +; ASM32-NEXT: L...dwline: +; ASM32-NEXT: L..debug_line_0: +; ASM32-NEXT: .set L..line_table_start0, L..debug_line_0-4 +; ASM32-NEXT: .vbyte 2, 4 +; ASM32-NEXT: .vbyte 4, (L..tmp5-L..debug_line_0)-6 +; ASM32-NEXT: .byte 4 +; ASM32-NEXT: .byte 1 +; ASM32-NEXT: .byte 1 +; ASM32-NEXT: .byte -5 +; ASM32-NEXT: .byte 14 +; ASM32-NEXT: .byte 13 +; ASM32-NEXT: .byte 0 +; ASM32-NEXT: .byte 1 +; ASM32-NEXT: .byte 1 +; ASM32-NEXT: .byte 1 +; ASM32-NEXT: .byte 1 +; ASM32-NEXT: .byte 0 +; ASM32-NEXT: .byte 0 +; ASM32-NEXT: .byte 0 +; ASM32-NEXT: .byte 1 +; ASM32-NEXT: .byte 0 +; ASM32-NEXT: .byte 0 +; ASM32-NEXT: .byte 1 +; ASM32-NEXT: .byte 'd,'e,'b,'u,'g +; ASM32-NEXT: .byte 0 +; ASM32-NEXT: .byte 0 +; ASM32-NEXT: .byte '1,'.,'c +; ASM32-NEXT: .byte 0 +; ASM32-NEXT: .byte 1 +; ASM32-NEXT: .byte 0 +; ASM32-NEXT: .byte 0 +; ASM32-NEXT: .byte 0 +; ASM32-NEXT: L..tmp5: +; ASM32-NEXT: .byte 0 +; ASM32-NEXT: .byte 5 +; ASM32-NEXT: .byte 2 +; ASM32-NEXT: .vbyte 4, L..tmp0 +; ASM32-NEXT: .byte 19 +; ASM32-NEXT: .byte 5 +; ASM32-NEXT: .byte 3 +; ASM32-NEXT: .byte 10 +; ASM32-NEXT: .byte 0 +; ASM32-NEXT: .byte 5 +; ASM32-NEXT: .byte 2 +; ASM32-NEXT: .vbyte 4, L..tmp2 +; ASM32-NEXT: .byte 3 +; ASM32-NEXT: .byte 1 +; ASM32-NEXT: .byte 1 +; ASM32-NEXT: .byte 0 +; ASM32-NEXT: .byte 5 +; ASM32-NEXT: .byte 2 +; ASM32-NEXT: .vbyte 4, L..sec_end0 +; ASM32-NEXT: .byte 0 +; ASM32-NEXT: .byte 1 +; ASM32-NEXT: .byte 1 +; ASM32-NEXT: L..tmp4: + +; ASM64: .csect .text[PR],2 +; ASM64-NEXT: .file "1.c" +; ASM64-NEXT: .globl main[DS] # -- Begin function main +; ASM64-NEXT: .globl .main +; ASM64-NEXT: .align 4 +; ASM64-NEXT: .csect main[DS],3 +; ASM64-NEXT: .vbyte 8, .main # @main +; ASM64-NEXT: .vbyte 8, TOC[TC0] +; ASM64-NEXT: .vbyte 8, 0 +; ASM64-NEXT: .csect .text[PR],2 +; ASM64-NEXT: .main: +; ASM64-NEXT: L..func_begin0: +; ASM64-NEXT: # %bb.0: # %entry +; ASM64-NEXT: L..tmp0: +; ASM64-NEXT: li 3, 0 +; ASM64-NEXT: stw 3, -12(1) +; ASM64-NEXT: L..tmp1: +; ASM64-NEXT: L..tmp2: +; ASM64-NEXT: li 3, 0 +; ASM64-NEXT: blr +; ASM64-NEXT: L..tmp3: +; ASM64-NEXT: L..main0: +; ASM64-NEXT: .vbyte 4, 0x00000000 # Traceback table begin +; ASM64-NEXT: .byte 0x00 # Version = 0 +; ASM64-NEXT: .byte 0x09 # Language = CPlusPlus +; ASM64-NEXT: .byte 0x20 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue +; ASM64-NEXT: # +HasTraceBackTableOffset, -IsInternalProcedure +; ASM64-NEXT: # -HasControlledStorage, -IsTOCless +; ASM64-NEXT: # -IsFloatingPointPresent +; ASM64-NEXT: # -IsFloatingPointOperationLogOrAbortEnabled +; ASM64-NEXT: .byte 0x40 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed +; ASM64-NEXT: # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved +; ASM64-NEXT: .byte 0x80 # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0 +; ASM64-NEXT: .byte 0x00 # -HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0 +; ASM64-NEXT: .byte 0x00 # NumberOfFixedParms = 0 +; ASM64-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack +; ASM64-NEXT: .vbyte 4, L..main0-.main # Function size +; ASM64-NEXT: .vbyte 2, 0x0004 # Function name len = 4 +; ASM64-NEXT: .byte 'm,'a,'i,'n # Function Name +; ASM64-NEXT: L..func_end0: +; ASM64-NEXT: # -- End function +; ASM64-NEXT: L..sec_end0: +; ASM64: .dwsect 0x60000 +; ASM64-NEXT: L...dwabrev: +; ASM64-NEXT: .byte 1 # Abbreviation Code +; ASM64-NEXT: .byte 17 # DW_TAG_compile_unit +; ASM64-NEXT: .byte 1 # DW_CHILDREN_yes +; ASM64-NEXT: .byte 37 # DW_AT_producer +; ASM64-NEXT: .byte 14 # DW_FORM_strp +; ASM64-NEXT: .byte 19 # DW_AT_language +; ASM64-NEXT: .byte 5 # DW_FORM_data2 +; ASM64-NEXT: .byte 3 # DW_AT_name +; ASM64-NEXT: .byte 14 # DW_FORM_strp +; ASM64-NEXT: .byte 16 # DW_AT_stmt_list +; ASM64-NEXT: .byte 23 # DW_FORM_sec_offset +; ASM64-NEXT: .byte 27 # DW_AT_comp_dir +; ASM64-NEXT: .byte 14 # DW_FORM_strp +; ASM64-NEXT: .byte 17 # DW_AT_low_pc +; ASM64-NEXT: .byte 1 # DW_FORM_addr +; ASM64-NEXT: .byte 18 # DW_AT_high_pc +; ASM64-NEXT: .byte 6 # DW_FORM_data4 +; ASM64-NEXT: .byte 0 # EOM(1) +; ASM64-NEXT: .byte 0 # EOM(2) +; ASM64-NEXT: .byte 2 # Abbreviation Code +; ASM64-NEXT: .byte 46 # DW_TAG_subprogram +; ASM64-NEXT: .byte 0 # DW_CHILDREN_no +; ASM64-NEXT: .byte 17 # DW_AT_low_pc +; ASM64-NEXT: .byte 1 # DW_FORM_addr +; ASM64-NEXT: .byte 18 # DW_AT_high_pc +; ASM64-NEXT: .byte 6 # DW_FORM_data4 +; ASM64-NEXT: .byte 64 # DW_AT_frame_base +; ASM64-NEXT: .byte 24 # DW_FORM_exprloc +; ASM64-NEXT: .byte 3 # DW_AT_name +; ASM64-NEXT: .byte 14 # DW_FORM_strp +; ASM64-NEXT: .byte 58 # DW_AT_decl_file +; ASM64-NEXT: .byte 11 # DW_FORM_data1 +; ASM64-NEXT: .byte 59 # DW_AT_decl_line +; ASM64-NEXT: .byte 11 # DW_FORM_data1 +; ASM64-NEXT: .byte 39 # DW_AT_prototyped +; ASM64-NEXT: .byte 25 # DW_FORM_flag_present +; ASM64-NEXT: .byte 73 # DW_AT_type +; ASM64-NEXT: .byte 19 # DW_FORM_ref4 +; ASM64-NEXT: .byte 63 # DW_AT_external +; ASM64-NEXT: .byte 25 # DW_FORM_flag_present +; ASM64-NEXT: .byte 0 # EOM(1) +; ASM64-NEXT: .byte 0 # EOM(2) +; ASM64-NEXT: .byte 3 # Abbreviation Code +; ASM64-NEXT: .byte 36 # DW_TAG_base_type +; ASM64-NEXT: .byte 0 # DW_CHILDREN_no +; ASM64-NEXT: .byte 3 # DW_AT_name +; ASM64-NEXT: .byte 14 # DW_FORM_strp +; ASM64-NEXT: .byte 62 # DW_AT_encoding +; ASM64-NEXT: .byte 11 # DW_FORM_data1 +; ASM64-NEXT: .byte 11 # DW_AT_byte_size +; ASM64-NEXT: .byte 11 # DW_FORM_data1 +; ASM64-NEXT: .byte 0 # EOM(1) +; ASM64-NEXT: .byte 0 # EOM(2) +; ASM64-NEXT: .byte 0 # EOM(3) +; ASM64: .dwsect 0x10000 +; ASM64-NEXT: L...dwinfo: +; ASM64-NEXT: L..cu_begin0: +; ASM64-NEXT: L..debug_info_start0: +; ASM64-NEXT: .vbyte 2, 4 # DWARF version number +; ASM64-NEXT: .vbyte 8, L...dwabrev # Offset Into Abbrev. Section +; ASM64-NEXT: .byte 8 # Address Size (in bytes) +; ASM64-NEXT: .byte 1 # Abbrev [1] 0x17:0x58 DW_TAG_compile_unit +; ASM64-NEXT: .vbyte 8, L..info_string0 # DW_AT_producer +; ASM64-NEXT: .vbyte 2, 12 # DW_AT_language +; ASM64-NEXT: .vbyte 8, L..info_string1 # DW_AT_name +; ASM64-NEXT: .vbyte 8, L..line_table_start0 # DW_AT_stmt_list +; ASM64-NEXT: .vbyte 8, L..info_string2 # DW_AT_comp_dir +; ASM64-NEXT: .vbyte 8, L..func_begin0 # DW_AT_low_pc +; ASM64-NEXT: .vbyte 4, L..func_end0-L..func_begin0 # DW_AT_high_pc +; ASM64-NEXT: .byte 2 # Abbrev [2] 0x46:0x1d DW_TAG_subprogram +; ASM64-NEXT: .vbyte 8, L..func_begin0 # DW_AT_low_pc +; ASM64-NEXT: .vbyte 4, L..func_end0-L..func_begin0 # DW_AT_high_pc +; ASM64-NEXT: .byte 1 # DW_AT_frame_base +; ASM64-NEXT: .byte 81 +; ASM64-NEXT: .vbyte 8, L..info_string3 # DW_AT_name +; ASM64-NEXT: .byte 1 # DW_AT_decl_file +; ASM64-NEXT: .byte 1 # DW_AT_decl_line +; ASM64-NEXT: # DW_AT_prototyped +; ASM64-NEXT: .vbyte 4, 99 # DW_AT_type +; ASM64-NEXT: # DW_AT_external +; ASM64-NEXT: .byte 3 # Abbrev [3] 0x63:0xb DW_TAG_base_type +; ASM64-NEXT: .vbyte 8, L..info_string4 # DW_AT_name +; ASM64-NEXT: .byte 5 # DW_AT_encoding +; ASM64-NEXT: .byte 4 # DW_AT_byte_size +; ASM64-NEXT: .byte 0 # End Of Children Mark +; ASM64-NEXT: L..debug_info_end0: +; ASM64: .dwsect 0x70000 +; ASM64-NEXT: L...dwstr: +; ASM64-NEXT: L..info_string0: +; ASM64-NEXT: .byte 'c,'l,'a,'n,'g,' ,'v,'e,'r,'s,'i,'o,'n,' ,'1,'2,'.,'0,'.,'0,0000 # string offset=0 +; ASM64-NEXT: L..info_string1: +; ASM64-NEXT: .byte '1,'.,'c,0000 # string offset=21 +; ASM64-NEXT: L..info_string2: +; ASM64-NEXT: .byte 'd,'e,'b,'u,'g,0000 # string offset=25 +; ASM64-NEXT: L..info_string3: +; ASM64-NEXT: .byte 'm,'a,'i,'n,0000 # string offset=31 +; ASM64-NEXT: L..info_string4: +; ASM64-NEXT: .byte 'i,'n,'t,0000 # string offset=36 +; ASM64-NEXT: .toc +; ASM64: .dwsect 0x20000 +; ASM64-NEXT: L...dwline: +; ASM64-NEXT: L..debug_line_0: +; ASM64-NEXT: .set L..line_table_start0, L..debug_line_0-12 +; ASM64-NEXT: .vbyte 2, 4 +; ASM64-NEXT: .vbyte 8, (L..tmp5-L..debug_line_0)-10 +; ASM64-NEXT: .byte 4 +; ASM64-NEXT: .byte 1 +; ASM64-NEXT: .byte 1 +; ASM64-NEXT: .byte -5 +; ASM64-NEXT: .byte 14 +; ASM64-NEXT: .byte 13 +; ASM64-NEXT: .byte 0 +; ASM64-NEXT: .byte 1 +; ASM64-NEXT: .byte 1 +; ASM64-NEXT: .byte 1 +; ASM64-NEXT: .byte 1 +; ASM64-NEXT: .byte 0 +; ASM64-NEXT: .byte 0 +; ASM64-NEXT: .byte 0 +; ASM64-NEXT: .byte 1 +; ASM64-NEXT: .byte 0 +; ASM64-NEXT: .byte 0 +; ASM64-NEXT: .byte 1 +; ASM64-NEXT: .byte 'd,'e,'b,'u,'g +; ASM64-NEXT: .byte 0 +; ASM64-NEXT: .byte 0 +; ASM64-NEXT: .byte '1,'.,'c +; ASM64-NEXT: .byte 0 +; ASM64-NEXT: .byte 1 +; ASM64-NEXT: .byte 0 +; ASM64-NEXT: .byte 0 +; ASM64-NEXT: .byte 0 +; ASM64-NEXT: L..tmp5: +; ASM64-NEXT: .byte 0 +; ASM64-NEXT: .byte 9 +; ASM64-NEXT: .byte 2 +; ASM64-NEXT: .vbyte 8, L..tmp0 +; ASM64-NEXT: .byte 19 +; ASM64-NEXT: .byte 5 +; ASM64-NEXT: .byte 3 +; ASM64-NEXT: .byte 10 +; ASM64-NEXT: .byte 0 +; ASM64-NEXT: .byte 9 +; ASM64-NEXT: .byte 2 +; ASM64-NEXT: .vbyte 8, L..tmp2 +; ASM64-NEXT: .byte 3 +; ASM64-NEXT: .byte 1 +; ASM64-NEXT: .byte 1 +; ASM64-NEXT: .byte 0 +; ASM64-NEXT: .byte 9 +; ASM64-NEXT: .byte 2 +; ASM64-NEXT: .vbyte 8, L..sec_end0 +; ASM64-NEXT: .byte 0 +; ASM64-NEXT: .byte 1 +; ASM64-NEXT: .byte 1 +; ASM64-NEXT: L..tmp4: diff --git a/llvm/test/DebugInfo/XCOFF/lit.local.cfg b/llvm/test/DebugInfo/XCOFF/lit.local.cfg new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/XCOFF/lit.local.cfg @@ -0,0 +1,2 @@ +if not 'PowerPC' in config.root.targets: + config.unsupported = True