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 dwarf section length in the header(if any) of + /// dwarf section in 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 requiredDwarfSectionSize() 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,9 @@ void emitRawTextImpl(StringRef String) override; void finishImpl() 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 @@ XCOFF::StorageMappingClass MappingClass, XCOFF::SymbolType CSectType, SectionKind K, 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/MCSectionXCOFF.h b/llvm/include/llvm/MC/MCSectionXCOFF.h --- a/llvm/include/llvm/MC/MCSectionXCOFF.h +++ b/llvm/include/llvm/MC/MCSectionXCOFF.h @@ -36,18 +36,20 @@ 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) { + 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."); QualName->setRepresentedCsect(this); QualName->setStorageClass(XCOFF::C_HIDEXT); @@ -79,6 +81,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 @@ -1092,6 +1092,14 @@ void Finish(SMLoc EndLoc = SMLoc()); virtual bool mayHaveInstructions(MCSection &Sec) const { return true; } + + /// 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/AsmPrinterDwarf.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -18,6 +18,7 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/IR/DataLayout.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCAsmStreamer.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSection.h" @@ -207,6 +208,12 @@ void AsmPrinter::emitDwarfUnitLength(uint64_t Length, const Twine &Comment) const { + // If the assembler on some targets fills the dwarf unit length, we don't need + // to emit the length in compiler. For exmaple AIX assembler requires the + // assembly file without unit length in debug sections header. + if (!OutStreamer->getContext().getAsmInfo()->requiredDwarfSectionSize() && + isa(OutStreamer)) + return; assert(isDwarf64() || Length <= dwarf::DW_LENGTH_lo_reserved); maybeEmitDwarf64Mark(); OutStreamer->AddComment(Comment); @@ -215,6 +222,12 @@ void AsmPrinter::emitDwarfUnitLength(const MCSymbol *Hi, const MCSymbol *Lo, const Twine &Comment) const { + // If the assembler on some targets fills the dwarf unit length, we don't need + // to emit the length in compiler. For exmaple AIX assembler requires the + // assembly file without unit length in debug sections header. + if (!OutStreamer->getContext().getAsmInfo()->requiredDwarfSectionSize() && + isa(OutStreamer)) + return; maybeEmitDwarf64Mark(); OutStreamer->AddComment(Comment); OutStreamer->emitAbsoluteSymbolDiff(Hi, Lo, getDwarfOffsetByteSize()); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -27,6 +27,7 @@ #include "llvm/IR/DataLayout.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/GlobalVariable.h" +#include "llvm/MC/MCAsmStreamer.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" @@ -356,14 +357,34 @@ // left in the skeleton CU and so not included. // The line table entries are not always emitted in assembly, so it // is not okay to use line_table_start here. - addSectionLabel(getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym, - TLOF.getDwarfLineSection()->getBeginSymbol()); + // If the assembler on some targets will fill the dwarf unit length, we + // don't need to emit the length in compiler. For exmaple AIX assembler + // requires an assembly file without unit length in debug sections header. + // We need to adjust the reference here to contain the assembler insertion + // length. + MCContext &Ctx = Asm->OutStreamer->getContext(); + if (!Ctx.getAsmInfo()->requiredDwarfSectionSize() && + isa(Asm->OutStreamer)) + addLabelPlusOffset( + getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym, + -dwarf::getUnitLengthFieldByteSize(Ctx.getDwarfFormat())); + else + addSectionLabel(getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym, + TLOF.getDwarfLineSection()->getBeginSymbol()); } void DwarfCompileUnit::applyStmtList(DIE &D) { - const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); - addSectionLabel(D, dwarf::DW_AT_stmt_list, LineTableStartSym, - TLOF.getDwarfLineSection()->getBeginSymbol()); + MCContext &Ctx = Asm->OutStreamer->getContext(); + if (!Ctx.getAsmInfo()->requiredDwarfSectionSize() && + isa(Asm->OutStreamer)) + addLabelPlusOffset( + getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym, + -dwarf::getUnitLengthFieldByteSize(Ctx.getDwarfFormat())); + else { + const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); + addSectionLabel(D, dwarf::DW_AT_stmt_list, LineTableStartSym, + TLOF.getDwarfLineSection()->getBeginSymbol()); + } } void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin, 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,16 @@ 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: ELF. + // 2: XCOFF. AIX assembler will fill debug sections length according to + // DWARF64 format for 64 bit assembly, so must use DWARF64 in compiler too + // for 64 bit mode. + Dwarf64 &= (Asm->TM.Options.MCOptions.Dwarf64 && TT.isOSBinFormatELF()) || + TT.isOSBinFormatXCOFF(); 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 @@ -1070,6 +1070,10 @@ if (NumFiles == Table.getMCDwarfFiles().size()) return FileNo; + // Target doesn't support .loc/.file directives, return early. + if (!MAI->usesDwarfFileAndLocDirectives()) + return FileNo; + SmallString<128> Str; raw_svector_ostream OS1(Str); printDwarfFileDirective(FileNo, Directory, Filename, Checksum, Source, @@ -1096,6 +1100,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 +1119,15 @@ 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()) { + MCDwarfLineEntry::Make(this, getCurrentSectionOnly()); + 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 +1771,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 +1867,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 +1887,52 @@ } } +// 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 @@ -669,7 +669,8 @@ MCSectionXCOFF * MCContext::getXCOFFSection(StringRef Section, XCOFF::StorageMappingClass SMC, XCOFF::SymbolType Type, SectionKind Kind, - 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(), SMC}, nullptr)); @@ -695,7 +696,7 @@ // CachedName contains invalid character(s) such as '$' for an XCOFF symbol. MCSectionXCOFF *Result = new (XCOFFAllocator.Allocate()) MCSectionXCOFF(QualName->getUnqualifiedName(), SMC, Type, Kind, QualName, - Begin, CachedName, MultiSymbolsAllowed); + 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 @@ -24,6 +24,7 @@ #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCObjectStreamer.h" #include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCAsmStreamer.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" @@ -105,7 +106,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 +164,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 +246,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(); @@ -481,24 +481,32 @@ dwarf::getUnitLengthFieldByteSize(context.getDwarfFormat()); unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(context.getDwarfFormat()); - if (context.getDwarfFormat() == dwarf::DWARF64) - // Emit DWARF64 mark. - MCOS->emitInt32(dwarf::DW_LENGTH_DWARF64); - - // The length field does not include itself and, in case of the 64-bit DWARF - // format, the DWARF64 mark. - emitAbsValue(*MCOS, - makeEndMinusStartExpr(context, *LineStartSym, *LineEndSym, - UnitLengthBytes), - OffsetSize); + // Keep track of the bytes between the very start and where the header length + // comes out. + unsigned PreHeaderLengthBytes = 0; + + // If the assembler on some targets will fill the dwarf unit length, we + // don't need to emit the length in compiler. For exmaple AIX assembler + // requires the assembly file without unit length in debug sections header. + if (!(!MCOS->getContext().getAsmInfo()->requiredDwarfSectionSize() && + isa(MCOS))) { + if (context.getDwarfFormat() == dwarf::DWARF64) + // Emit DWARF64 mark. + MCOS->emitInt32(dwarf::DW_LENGTH_DWARF64); + + // The length field does not include itself and, in case of the 64-bit DWARF + // format, the DWARF64 mark. + emitAbsValue(*MCOS, + makeEndMinusStartExpr(context, *LineStartSym, *LineEndSym, + UnitLengthBytes), + OffsetSize); + PreHeaderLengthBytes += UnitLengthBytes; + } // Next 2 bytes is the Version. unsigned LineTableVersion = context.getDwarfVersion(); MCOS->emitInt16(LineTableVersion); - - // Keep track of the bytes between the very start and where the header length - // comes out. - unsigned PreHeaderLengthBytes = UnitLengthBytes + 2; + PreHeaderLengthBytes += 2; // In v5, we get address info next. if (LineTableVersion >= 5) { @@ -547,8 +555,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 @@ -898,18 +898,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", XCOFF::StorageMappingClass::XMC_RO, XCOFF::XTY_SD, + SectionKind::getMetadata(), /* MultiSymbolsAllowed*/ true, ".dwabrev", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWABREV); + + DwarfInfoSection = Ctx->getXCOFFSection( + ".dwinfo", XCOFF::StorageMappingClass::XMC_RO, XCOFF::XTY_SD, + SectionKind::getMetadata(), /* MultiSymbolsAllowed*/ true, ".dwinfo", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWINFO); + + DwarfLineSection = Ctx->getXCOFFSection( + ".dwline", XCOFF::StorageMappingClass::XMC_RO, XCOFF::XTY_SD, + SectionKind::getMetadata(), /* MultiSymbolsAllowed*/ true, ".dwline", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWLINE); + + DwarfFrameSection = Ctx->getXCOFFSection( + ".dwframe", XCOFF::StorageMappingClass::XMC_RO, XCOFF::XTY_SD, + SectionKind::getMetadata(), /* MultiSymbolsAllowed*/ true, ".dwframe", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWFRAME); + + DwarfPubNamesSection = Ctx->getXCOFFSection( + ".dwpbnms", XCOFF::StorageMappingClass::XMC_RO, XCOFF::XTY_SD, + SectionKind::getMetadata(), /* MultiSymbolsAllowed*/ true, ".dwpbnms", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWPBNMS); + + DwarfPubTypesSection = Ctx->getXCOFFSection( + ".dwpbtyp", XCOFF::StorageMappingClass::XMC_RO, XCOFF::XTY_SD, + SectionKind::getMetadata(), /* MultiSymbolsAllowed*/ true, ".dwpbtyp", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWPBTYP); + + DwarfStrSection = Ctx->getXCOFFSection( + ".dwstr", XCOFF::StorageMappingClass::XMC_RO, XCOFF::XTY_SD, + SectionKind::getMetadata(), /* MultiSymbolsAllowed*/ true, ".dwstr", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWSTR); + + DwarfLocSection = Ctx->getXCOFFSection( + ".dwloc", XCOFF::StorageMappingClass::XMC_RO, XCOFF::XTY_SD, + SectionKind::getMetadata(), /* MultiSymbolsAllowed*/ true, ".dwloc", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWLOC); + + DwarfARangesSection = Ctx->getXCOFFSection( + ".dwarnge", XCOFF::StorageMappingClass::XMC_RO, XCOFF::XTY_SD, + SectionKind::getMetadata(), /* MultiSymbolsAllowed*/ true, ".dwarnge", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWARNGE); + + DwarfRangesSection = Ctx->getXCOFFSection( + ".dwrnges", XCOFF::StorageMappingClass::XMC_RO, XCOFF::XTY_SD, + SectionKind::getMetadata(), /* MultiSymbolsAllowed*/ true, ".dwrnges", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWRNGES); + + DwarfMacinfoSection = Ctx->getXCOFFSection( + ".dwmac", XCOFF::StorageMappingClass::XMC_RO, XCOFF::XTY_SD, + SectionKind::getMetadata(), /* MultiSymbolsAllowed*/ true, ".dwmac", + XCOFF::STYP_DWARF | XCOFF::SSUBTYP_DWMAC); } void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC, 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,7 +9,9 @@ #include "llvm/MC/MCSectionXCOFF.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCExpr.h" +#include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Debug.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/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,16 @@ } bool PPCAIXAsmPrinter::doFinalization(Module &M) { + // Add text end before we do any finalization. This is used to tell 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,436 @@ + +; 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-4 # 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..line_table_start0: +; ASM32-NEXT: .vbyte 2, 4 +; ASM32-NEXT: .vbyte 4, (L..tmp5-L..line_table_start0)-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-12 # 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..line_table_start0: +; ASM64-NEXT: .vbyte 2, 4 +; ASM64-NEXT: .vbyte 8, (L..tmp5-L..line_table_start0)-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