1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-21 18:22:53 +01:00

[XCOFF][DebugInfo] support DWARF for XCOFF for assembly output.

Reviewed By: jasonliu

Differential Revision: https://reviews.llvm.org/D95518
This commit is contained in:
Chen Zheng 2021-03-04 20:47:41 -05:00
parent 5d0845c0e0
commit 38673999a0
22 changed files with 1496 additions and 80 deletions

View File

@ -388,6 +388,14 @@ protected:
/// 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;
@ -673,6 +681,14 @@ public:
return SupportsExtendedDwarfLocDirective;
}
bool usesDwarfFileAndLocDirectives() const {
return UsesDwarfFileAndLocDirectives;
}
bool needsDwarfSectionSizeInHeader() const {
return DwarfSectionSizeRequired;
}
void addInitialFrameState(const MCCFIInstruction &Inst);
const std::vector<MCCFIInstruction> &getInitialFrameState() const {

View File

@ -279,16 +279,35 @@ namespace llvm {
};
struct XCOFFSectionKey {
// Section name.
std::string SectionName;
XCOFF::StorageMappingClass MappingClass;
// Section property.
// For csect section, it is storage mapping class.
// For debug section, it is section type flags.
union {
XCOFF::StorageMappingClass MappingClass;
XCOFF::DwarfSectionSubtypeFlags DwarfSubtypeFlags;
};
bool IsCsect;
XCOFFSectionKey(StringRef SectionName,
XCOFF::StorageMappingClass MappingClass)
: SectionName(SectionName), MappingClass(MappingClass) {}
: SectionName(SectionName), MappingClass(MappingClass),
IsCsect(true) {}
XCOFFSectionKey(StringRef SectionName,
XCOFF::DwarfSectionSubtypeFlags DwarfSubtypeFlags)
: SectionName(SectionName), DwarfSubtypeFlags(DwarfSubtypeFlags),
IsCsect(false) {}
bool operator<(const XCOFFSectionKey &Other) const {
return std::tie(SectionName, MappingClass) <
std::tie(Other.SectionName, Other.MappingClass);
if (IsCsect && Other.IsCsect)
return std::tie(SectionName, MappingClass) <
std::tie(Other.SectionName, Other.MappingClass);
if (IsCsect != Other.IsCsect)
return IsCsect;
return std::tie(SectionName, DwarfSubtypeFlags) <
std::tie(Other.SectionName, Other.DwarfSubtypeFlags);
}
};
@ -599,11 +618,11 @@ namespace llvm {
const MCSymbolWasm *Group, unsigned UniqueID,
const char *BeginSymName);
MCSectionXCOFF *
getXCOFFSection(StringRef Section, SectionKind K,
Optional<XCOFF::CsectProperties> CsectProp = None,
bool MultiSymbolsAllowed = false,
const char *BeginSymName = nullptr);
MCSectionXCOFF *getXCOFFSection(
StringRef Section, SectionKind K,
Optional<XCOFF::CsectProperties> CsectProp = None,
bool MultiSymbolsAllowed = false, const char *BeginSymName = nullptr,
Optional<XCOFF::DwarfSectionSubtypeFlags> DwarfSubtypeFlags = None);
// Create and save a copy of STI and return a reference to the copy.
MCSubtargetInfo &getSubtargetCopy(const MCSubtargetInfo &STI);

View File

@ -173,7 +173,7 @@ public:
// 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 @@ class MCDwarfLineTable {
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<MCDwarfLineStr> &LineStr) const;
Expected<unsigned> tryGetFile(StringRef &Directory, StringRef &FileName,

View File

@ -146,7 +146,9 @@ public:
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 emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel) override;
void emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
const MCSymbol *Label);
void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line,

View File

@ -35,6 +35,7 @@ class MCSectionXCOFF final : public MCSection {
Optional<XCOFF::CsectProperties> CsectProp;
MCSymbolXCOFF *const QualName;
StringRef SymbolTableName;
Optional<XCOFF::DwarfSectionSubtypeFlags> DwarfSubtypeFlags;
bool MultiSymbolsAllowed;
static constexpr unsigned DefaultAlignVal = 4;
@ -44,12 +45,13 @@ class MCSectionXCOFF final : public MCSection {
bool MultiSymbolsAllowed)
: MCSection(SV_XCOFF, Name, K, Begin),
CsectProp(XCOFF::CsectProperties(SMC, ST)), QualName(QualName),
SymbolTableName(SymbolTableName),
SymbolTableName(SymbolTableName), DwarfSubtypeFlags(None),
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);
// A csect is 4 byte aligned by default, except for undefined symbol csects.
@ -58,10 +60,11 @@ class MCSectionXCOFF final : public MCSection {
}
MCSectionXCOFF(StringRef Name, SectionKind K, MCSymbolXCOFF *QualName,
XCOFF::DwarfSectionSubtypeFlags DwarfSubtypeFlags,
MCSymbol *Begin, StringRef SymbolTableName,
bool MultiSymbolsAllowed)
: MCSection(SV_XCOFF, Name, K, Begin), QualName(QualName),
SymbolTableName(SymbolTableName),
SymbolTableName(SymbolTableName), DwarfSubtypeFlags(DwarfSubtypeFlags),
MultiSymbolsAllowed(MultiSymbolsAllowed) {
assert(QualName != nullptr && "QualName is needed.");
@ -103,6 +106,10 @@ public:
StringRef getSymbolTableName() const { return SymbolTableName; }
bool isMultiSymbolsAllowed() const { return MultiSymbolsAllowed; }
bool isCsect() const { return CsectProp.hasValue(); }
bool isDwarfSect() const { return DwarfSubtypeFlags.hasValue(); }
Optional<XCOFF::DwarfSectionSubtypeFlags> getDwarfSubtypeFlags() const {
return DwarfSubtypeFlags;
}
};
} // end namespace llvm

View File

@ -1092,6 +1092,23 @@ public:
/// Return the end symbol generated inside, the caller needs to emit it.
virtual MCSymbol *emitDwarfUnitLength(const Twine &Prefix,
const Twine &Comment);
/// Emit the debug line start label.
virtual void emitDwarfLineStartLabel(MCSymbol *StartSym);
/// Emit the debug line end entry.
virtual void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel) {}
/// 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) {}
/// Do finalization for the streamer at the end of a section.
virtual void doFinalizationAtSectionEnd(MCSection *Section) {}
};
/// Create a dummy machine code streamer, which does nothing. This is useful for

View File

@ -392,11 +392,21 @@ DwarfDebug::DwarfDebug(AsmPrinter *A)
DwarfVersion =
TT.isNVPTX() ? 2 : (DwarfVersion ? DwarfVersion : dwarf::DWARF_VERSION);
bool Dwarf64 =
(Asm->TM.Options.MCOptions.Dwarf64 || MMI->getModule()->isDwarf64()) &&
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 || MMI->getModule()->isDwarf64()) &&
TT.isOSBinFormatELF()) ||
TT.isOSBinFormatXCOFF();
if (!Dwarf64 && TT.isArch64Bit() && TT.isOSBinFormatXCOFF())
report_fatal_error("XCOFF requires DWARF64 for 64-bit mode!");
UseRangesSection = !NoDwarfRangesSection && !TT.isNVPTX();

View File

@ -23,6 +23,8 @@ MCAsmInfoXCOFF::MCAsmInfoXCOFF() {
PrivateLabelPrefix = "L..";
SupportsQuotedNames = false;
UseDotAlignForAlignment = true;
UsesDwarfFileAndLocDirectives = false;
DwarfSectionSizeRequired = false;
if (UseLEB128Directives == cl::BOU_UNSET)
HasLEB128Directives = false;
ZeroDirective = "\t.space\t";

View File

@ -372,6 +372,21 @@ public:
void emitRawTextImpl(StringRef String) override;
void finishImpl() override;
void emitDwarfUnitLength(uint64_t Length, const Twine &Comment) override;
MCSymbol *emitDwarfUnitLength(const Twine &Prefix,
const Twine &Comment) override;
void emitDwarfLineStartLabel(MCSymbol *StartSym) override;
void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel) override;
void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
const MCSymbol *Label,
unsigned PointerSize) override;
void doFinalizationAtSectionEnd(MCSection *Section) override;
};
} // end anonymous namespace.
@ -1419,7 +1434,11 @@ Expected<unsigned> MCAsmStreamer::tryEmitDwarfFileDirective(
if (!FileNoOrErr)
return FileNoOrErr.takeError();
FileNo = FileNoOrErr.get();
if (NumFiles == Table.getMCDwarfFiles().size())
// Return early if this file is already emitted before or if target doesn't
// support .file directive.
if (NumFiles == Table.getMCDwarfFiles().size() ||
!MAI->usesDwarfFileAndLocDirectives())
return FileNo;
SmallString<128> Str;
@ -1448,6 +1467,10 @@ void MCAsmStreamer::emitDwarfFile0Directive(StringRef Directory,
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,
@ -1463,6 +1486,17 @@ void MCAsmStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
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()) {
// In case we see two .loc directives in a row, make sure the
// first one gets a line entry.
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)
@ -2106,6 +2140,11 @@ void MCAsmStreamer::emitInstruction(const MCInst &Inst,
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);
@ -2197,6 +2236,13 @@ void MCAsmStreamer::finishImpl() {
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.
@ -2210,6 +2256,135 @@ void MCAsmStreamer::finishImpl() {
}
}
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);
}
MCSymbol *MCAsmStreamer::emitDwarfUnitLength(const Twine &Prefix,
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 getContext().createTempSymbol(Prefix + "_end");
return MCStreamer::emitDwarfUnitLength(Prefix, Comment);
}
void MCAsmStreamer::emitDwarfLineStartLabel(MCSymbol *StartSym) {
// 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()) {
MCSymbol *DebugLineSymTmp = Ctx.createTempSymbol("debug_line_");
// Emit the symbol which does not contain the unit length field.
emitLabel(DebugLineSymTmp);
// 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(DebugLineSymTmp, Ctx), EntrySize, Ctx);
emitAssignment(StartSym, OuterSym);
return;
}
MCStreamer::emitDwarfLineStartLabel(StartSym);
}
void MCAsmStreamer::emitDwarfLineEndEntry(MCSection *Section,
MCSymbol *LastLabel) {
// If the targets write the raw debug line data for assembly output (We can
// not switch to Section and add the end symbol there for assembly output)
// we currently use the .text end label as any section end. This will not
// impact the debugability as we will jump to the caller of the last function
// in the section before we come into the .text end address.
assert(!MAI->usesDwarfFileAndLocDirectives() &&
".loc should not be generated together with raw data!");
MCContext &Ctx = getContext();
// FIXME: use section end symbol as end of the Section. We need to consider
// the explicit sections and -ffunction-sections when we try to generate or
// find section end symbol for the Section.
MCSection *TextSection = Ctx.getObjectFileInfo()->getTextSection();
assert(TextSection->hasEnded() && ".text section is not end!");
MCSymbol *SectionEnd = TextSection->getEndSymbol(Ctx);
const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();
emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
AsmInfo->getCodePointerSize());
}
// 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!");
// Set to new address.
AddComment("Set address to " + Label->getName());
emitIntValue(dwarf::DW_LNS_extended_op, 1);
emitULEB128IntValue(PointerSize + 1);
emitIntValue(dwarf::DW_LNE_set_address, 1);
emitSymbolValue(Label, PointerSize);
if (!LastLabel) {
// Emit the sequence for the LineDelta (from 1) and a zero address delta.
AddComment("Start sequence");
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) {
AddComment("End sequence");
emitIntValue(dwarf::DW_LNS_extended_op, 1);
emitULEB128IntValue(1);
emitIntValue(dwarf::DW_LNE_end_sequence, 1);
return;
}
// Advance line.
AddComment("Advance line " + Twine(LineDelta));
emitIntValue(dwarf::DW_LNS_advance_line, 1);
emitSLEB128IntValue(LineDelta);
emitIntValue(dwarf::DW_LNS_copy, 1);
}
void MCAsmStreamer::doFinalizationAtSectionEnd(MCSection *Section) {
// Emit section end. This is used to tell the debug line section where the end
// is for a text section if we don't use .loc to represent the debug line.
if (MAI->usesDwarfFileAndLocDirectives())
return;
SwitchSectionNoChange(Section);
MCSymbol *Sym = getCurrentSectionOnly()->getEndSymbol(getContext());
if (!Sym->isInSection())
emitLabel(Sym);
}
MCStreamer *llvm::createAsmStreamer(MCContext &Context,
std::unique_ptr<formatted_raw_ostream> OS,
bool isVerboseAsm, bool useDwarfDirectory,

View File

@ -686,15 +686,20 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind,
return Result;
}
MCSectionXCOFF *
MCContext::getXCOFFSection(StringRef Section, SectionKind Kind,
Optional<XCOFF::CsectProperties> CsectProp,
bool MultiSymbolsAllowed, const char *BeginSymName) {
MCSectionXCOFF *MCContext::getXCOFFSection(
StringRef Section, SectionKind Kind,
Optional<XCOFF::CsectProperties> CsectProp, bool MultiSymbolsAllowed,
const char *BeginSymName,
Optional<XCOFF::DwarfSectionSubtypeFlags> DwarfSectionSubtypeFlags) {
bool IsDwarfSec = DwarfSectionSubtypeFlags.hasValue();
assert((IsDwarfSec != CsectProp.hasValue()) && "Invalid XCOFF section!");
// Do the lookup. If we have a hit, return it.
// FIXME: handle the case for non-csect sections. Non-csect section has None
// CsectProp.
auto IterBool = XCOFFUniquingMap.insert(std::make_pair(
XCOFFSectionKey{Section.str(), CsectProp->MappingClass}, nullptr));
IsDwarfSec
? XCOFFSectionKey(Section.str(), DwarfSectionSubtypeFlags.getValue())
: XCOFFSectionKey(Section.str(), CsectProp->MappingClass),
nullptr));
auto &Entry = *IterBool.first;
if (!IterBool.second) {
MCSectionXCOFF *ExistedEntry = Entry.second;
@ -706,9 +711,14 @@ MCContext::getXCOFFSection(StringRef Section, SectionKind Kind,
// Otherwise, return a new section.
StringRef CachedName = Entry.first.SectionName;
MCSymbolXCOFF *QualName = cast<MCSymbolXCOFF>(getOrCreateSymbol(
CachedName + "[" + XCOFF::getMappingClassString(CsectProp->MappingClass) +
"]"));
MCSymbolXCOFF *QualName = nullptr;
// Debug section don't have storage class attribute.
if (IsDwarfSec)
QualName = cast<MCSymbolXCOFF>(getOrCreateSymbol(CachedName));
else
QualName = cast<MCSymbolXCOFF>(getOrCreateSymbol(
CachedName + "[" +
XCOFF::getMappingClassString(CsectProp->MappingClass) + "]"));
MCSymbol *Begin = nullptr;
if (BeginSymName)
@ -716,9 +726,18 @@ MCContext::getXCOFFSection(StringRef Section, SectionKind Kind,
// QualName->getUnqualifiedName() and CachedName are the same except when
// CachedName contains invalid character(s) such as '$' for an XCOFF symbol.
MCSectionXCOFF *Result = new (XCOFFAllocator.Allocate()) MCSectionXCOFF(
QualName->getUnqualifiedName(), CsectProp->MappingClass, CsectProp->Type,
Kind, QualName, Begin, CachedName, MultiSymbolsAllowed);
MCSectionXCOFF *Result = nullptr;
if (IsDwarfSec)
Result = new (XCOFFAllocator.Allocate())
MCSectionXCOFF(QualName->getUnqualifiedName(), Kind, QualName,
DwarfSectionSubtypeFlags.getValue(), Begin, CachedName,
MultiSymbolsAllowed);
else
Result = new (XCOFFAllocator.Allocate())
MCSectionXCOFF(QualName->getUnqualifiedName(), CsectProp->MappingClass,
CsectProp->Type, Kind, QualName, Begin, CachedName,
MultiSymbolsAllowed);
Entry.second = Result;
auto *F = new MCDataFragment();

View File

@ -105,7 +105,7 @@ static inline uint64_t ScaleAddrDelta(MCContext &Context, uint64_t AddrDelta) {
// 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 @@ makeStartPlusIntExpr(MCContext &Ctx, const MCSymbol &Start, int IntVal) {
// 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;
@ -226,27 +226,14 @@ static inline void emitDwarfLineTable(
LastLabel = Label;
}
// Emit a DW_LNE_end_sequence for the end of the section.
// Use the section end label to compute the address delta and use INT64_MAX
// as the line delta which is the signal that this is actually a
// DW_LNE_end_sequence.
MCSymbol *SectionEnd = MCOS->endSection(Section);
// Switch back the dwarf line section, in case endSection had to switch the
// section.
MCContext &Ctx = MCOS->getContext();
MCOS->SwitchSection(Ctx.getObjectFileInfo()->getDwarfLineSection());
const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();
MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
AsmInfo->getCodePointerSize());
// Generate DWARF line end entry.
MCOS->emitDwarfLineEndEntry(Section, LastLabel);
}
//
// 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 +253,7 @@ void MCDwarfLineTable::Emit(MCObjectStreamer *MCOS,
// 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,8 +458,9 @@ MCDwarfLineTableHeader::Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
MCSymbol *LineStartSym = Label;
if (!LineStartSym)
LineStartSym = context.createTempSymbol();
// Set the value of the symbol, as we are at the start of the line table.
MCOS->emitLabel(LineStartSym);
MCOS->emitDwarfLineStartLabel(LineStartSym);
unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(context.getDwarfFormat());
@ -529,8 +517,7 @@ MCDwarfLineTableHeader::Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
return std::make_pair(LineStartSym, LineEndSym);
}
void MCDwarfLineTable::EmitCU(MCObjectStreamer *MCOS,
MCDwarfLineTableParams Params,
void MCDwarfLineTable::emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params,
Optional<MCDwarfLineStr> &LineStr) const {
MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second;

View File

@ -914,18 +914,49 @@ void MCObjectFileInfo::initXCOFFMCObjectFileInfo(const Triple &T) {
// 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(), /* CsectProperties */ None,
/* MultiSymbolsAllowed */ true, ".dwabrev", XCOFF::SSUBTYP_DWABREV);
DwarfInfoSection = Ctx->getXCOFFSection(
".dwinfo", SectionKind::getMetadata(), /* CsectProperties */ None,
/* MultiSymbolsAllowed */ true, ".dwinfo", XCOFF::SSUBTYP_DWINFO);
DwarfLineSection = Ctx->getXCOFFSection(
".dwline", SectionKind::getMetadata(), /* CsectProperties */ None,
/* MultiSymbolsAllowed */ true, ".dwline", XCOFF::SSUBTYP_DWLINE);
DwarfFrameSection = Ctx->getXCOFFSection(
".dwframe", SectionKind::getMetadata(), /* CsectProperties */ None,
/* MultiSymbolsAllowed */ true, ".dwframe", XCOFF::SSUBTYP_DWFRAME);
DwarfPubNamesSection = Ctx->getXCOFFSection(
".dwpbnms", SectionKind::getMetadata(), /* CsectProperties */ None,
/* MultiSymbolsAllowed */ true, ".dwpbnms", XCOFF::SSUBTYP_DWPBNMS);
DwarfPubTypesSection = Ctx->getXCOFFSection(
".dwpbtyp", SectionKind::getMetadata(), /* CsectProperties */ None,
/* MultiSymbolsAllowed */ true, ".dwpbtyp", XCOFF::SSUBTYP_DWPBTYP);
DwarfStrSection = Ctx->getXCOFFSection(
".dwstr", SectionKind::getMetadata(), /* CsectProperties */ None,
/* MultiSymbolsAllowed */ true, ".dwstr", XCOFF::SSUBTYP_DWSTR);
DwarfLocSection = Ctx->getXCOFFSection(
".dwloc", SectionKind::getMetadata(), /* CsectProperties */ None,
/* MultiSymbolsAllowed */ true, ".dwloc", XCOFF::SSUBTYP_DWLOC);
DwarfARangesSection = Ctx->getXCOFFSection(
".dwarnge", SectionKind::getMetadata(), /* CsectProperties */ None,
/* MultiSymbolsAllowed */ true, ".dwarnge", XCOFF::SSUBTYP_DWARNGE);
DwarfRangesSection = Ctx->getXCOFFSection(
".dwrnges", SectionKind::getMetadata(), /* CsectProperties */ None,
/* MultiSymbolsAllowed */ true, ".dwrnges", XCOFF::SSUBTYP_DWRNGES);
DwarfMacinfoSection = Ctx->getXCOFFSection(
".dwmac", SectionKind::getMetadata(), /* CsectProperties */ None,
/* MultiSymbolsAllowed */ true, ".dwmac", XCOFF::SSUBTYP_DWMAC);
}
void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC,

View File

@ -9,12 +9,14 @@
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCCodeView.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSymbol.h"
@ -228,7 +230,7 @@ void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
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 +387,7 @@ void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst,
// 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 +457,7 @@ void MCObjectStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
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);
@ -505,6 +507,24 @@ void MCObjectStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
}
void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section,
MCSymbol *LastLabel) {
// Emit a DW_LNE_end_sequence for the end of the section.
// Use the section end label to compute the address delta and use INT64_MAX
// as the line delta which is the signal that this is actually a
// DW_LNE_end_sequence.
MCSymbol *SectionEnd = endSection(Section);
// Switch back the dwarf line section, in case endSection had to switch the
// section.
MCContext &Ctx = getContext();
SwitchSection(Ctx.getObjectFileInfo()->getDwarfLineSection());
const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();
emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
AsmInfo->getCodePointerSize());
}
void MCObjectStreamer::emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
const MCSymbol *Label) {
const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
@ -573,7 +593,7 @@ void MCObjectStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo) {
}
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 +870,7 @@ void MCObjectStreamer::finishImpl() {
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);

View File

@ -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;
@ -68,7 +70,7 @@ void MCSectionXCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
// Common csect type (uninitialized storage) does not have to print csect
// directive for section switching.
if (getCSectType() == XCOFF::XTY_CM) {
if (isCsect() && getCSectType() == XCOFF::XTY_CM) {
assert((getMappingClass() == XCOFF::XMC_RW ||
getMappingClass() == XCOFF::XMC_BS ||
getMappingClass() == XCOFF::XMC_UL) &&
@ -95,6 +97,14 @@ void MCSectionXCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
return;
}
// XCOFF debug sections.
if (getKind().isMetadata() && isDwarfSect()) {
OS << "\n\t.dwsect "
<< format("0x%" PRIx32, getDwarfSubtypeFlags().getValue()) << '\n';
OS << MAI.getPrivateLabelPrefix() << getName() << ':' << '\n';
return;
}
report_fatal_error("Printing for this SectionKind is unimplemented.");
}

View File

@ -1019,6 +1019,11 @@ MCSymbol *MCStreamer::emitDwarfUnitLength(const Twine &Prefix,
return Hi;
}
void MCStreamer::emitDwarfLineStartLabel(MCSymbol *StartSym) {
// 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);

View File

@ -13,9 +13,6 @@ using namespace llvm;
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 @@ void MCSymbolXCOFF::setRepresentedCsect(MCSectionXCOFF *C) {
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.");

View File

@ -63,4 +63,10 @@ PPCXCOFFMCAsmInfo::PPCXCOFFMCAsmInfo(bool Is64Bit, const Triple &T) {
// 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;
}

View File

@ -2303,6 +2303,11 @@ void PPCAIXAsmPrinter::emitInstruction(const MachineInstr *MI) {
}
bool PPCAIXAsmPrinter::doFinalization(Module &M) {
// Do streamer related finalization for DWARF.
if (!MAI->usesDwarfFileAndLocDirectives() && MMI->hasDebugInfo())
OutStreamer->doFinalizationAtSectionEnd(
OutStreamer->getContext().getObjectFileInfo()->getTextSection());
for (MCSymbol *Sym : ExtSymSDNodeSymbols)
OutStreamer->emitSymbolAttribute(Sym, MCSA_Extern);
return PPCAsmPrinter::doFinalization(M);

View File

@ -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
}
!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 2
; 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 4, 0
; ASM32-NEXT: L..tmp1:
; ASM32-NEXT: L..tmp2:
; ASM32-NEXT: li 3, 0
; ASM32-NEXT: stw 4, -4(1)
; 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: .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..tmp4
; ASM32-NEXT: L..tmp4:
; 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 # Set address to L..tmp0
; ASM32-NEXT: .byte 5
; ASM32-NEXT: .byte 2
; ASM32-NEXT: .vbyte 4, L..tmp0
; ASM32-NEXT: .byte 19 # Start sequence
; ASM32-NEXT: .byte 5
; ASM32-NEXT: .byte 3
; ASM32-NEXT: .byte 10
; ASM32-NEXT: .byte 0 # Set address to L..tmp2
; ASM32-NEXT: .byte 5
; ASM32-NEXT: .byte 2
; ASM32-NEXT: .vbyte 4, L..tmp2
; ASM32-NEXT: .byte 3 # Advance line 1
; ASM32-NEXT: .byte 1
; ASM32-NEXT: .byte 1
; ASM32-NEXT: .byte 0 # Set address to L..sec_end0
; ASM32-NEXT: .byte 5
; ASM32-NEXT: .byte 2
; ASM32-NEXT: .vbyte 4, L..sec_end0
; ASM32-NEXT: .byte 0 # End sequence
; ASM32-NEXT: .byte 1
; ASM32-NEXT: .byte 1
; ASM32-NEXT: L..debug_line_end0:
; 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 2
; 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 4, 0
; ASM64-NEXT: L..tmp1:
; ASM64-NEXT: L..tmp2:
; ASM64-NEXT: li 3, 0
; ASM64-NEXT: stw 4, -4(1)
; 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: .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..tmp4
; ASM64-NEXT: L..tmp4:
; 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 # Set address to L..tmp0
; ASM64-NEXT: .byte 9
; ASM64-NEXT: .byte 2
; ASM64-NEXT: .vbyte 8, L..tmp0
; ASM64-NEXT: .byte 19 # Start sequence
; ASM64-NEXT: .byte 5
; ASM64-NEXT: .byte 3
; ASM64-NEXT: .byte 10
; ASM64-NEXT: .byte 0 # Set address to L..tmp2
; ASM64-NEXT: .byte 9
; ASM64-NEXT: .byte 2
; ASM64-NEXT: .vbyte 8, L..tmp2
; ASM64-NEXT: .byte 3 # Advance line 1
; ASM64-NEXT: .byte 1
; ASM64-NEXT: .byte 1
; ASM64-NEXT: .byte 0 # Set address to L..sec_end0
; ASM64-NEXT: .byte 9
; ASM64-NEXT: .byte 2
; ASM64-NEXT: .vbyte 8, L..sec_end0
; ASM64-NEXT: .byte 0 # End sequence
; ASM64-NEXT: .byte 1
; ASM64-NEXT: .byte 1
; ASM64-NEXT: L..debug_line_end0:

View File

@ -0,0 +1,338 @@
; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | \
; RUN: FileCheck %s
source_filename = "2.c"
target datalayout = "E-m:a-p:32:32-i64:64-n32"
; Function Attrs: noinline nounwind optnone
define i32 @bar() #0 !dbg !8 {
entry:
ret i32 1, !dbg !13
}
; Function Attrs: noinline nounwind optnone
define i32 @main() #0 section "explicit_main_sec" !dbg !14 {
entry:
%retval = alloca i32, align 4
store i32 0, i32* %retval, align 4
%call = call i32 @bar(), !dbg !15
ret i32 %call, !dbg !16
}
!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 13.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
!1 = !DIFile(filename: "2.c", directory: "debug")
!2 = !{}
!3 = !{i32 7, !"Dwarf Version", i32 3}
!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 13.0.0"}
!8 = distinct !DISubprogram(name: "bar", scope: !9, file: !9, line: 1, type: !10, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
!9 = !DIFile(filename: "2.c", directory: "debug")
!10 = !DISubroutineType(types: !11)
!11 = !{!12}
!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!13 = !DILocation(line: 1, column: 12, scope: !8)
!14 = distinct !DISubprogram(name: "main", scope: !9, file: !9, line: 2, type: !10, scopeLine: 2, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
!15 = !DILocation(line: 3, column: 10, scope: !14)
!16 = !DILocation(line: 3, column: 3, scope: !14)
; CHECK: .csect .text[PR],2
; CHECK-NEXT: .file "2.c"
; CHECK-NEXT: .globl bar[DS] # -- Begin function bar
; CHECK-NEXT: .globl .bar
; CHECK-NEXT: .align 2
; CHECK-NEXT: .csect bar[DS],2
; CHECK-NEXT: .vbyte 4, .bar # @bar
; CHECK-NEXT: .vbyte 4, TOC[TC0]
; CHECK-NEXT: .vbyte 4, 0
; CHECK-NEXT: .csect .text[PR],2
; CHECK-NEXT: .bar:
; CHECK-NEXT: L..func_begin0:
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: L..tmp0:
; CHECK-NEXT: L..tmp1:
; CHECK-NEXT: li 3, 1
; CHECK-NEXT: blr
; CHECK-NEXT: L..tmp2:
; CHECK-NEXT: L..bar0:
; CHECK-NEXT: .vbyte 4, 0x00000000 # Traceback table begin
; CHECK-NEXT: .byte 0x00 # Version = 0
; CHECK-NEXT: .byte 0x09 # Language = CPlusPlus
; CHECK-NEXT: .byte 0x20 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
; CHECK-NEXT: # +HasTraceBackTableOffset, -IsInternalProcedure
; CHECK-NEXT: # -HasControlledStorage, -IsTOCless
; CHECK-NEXT: # -IsFloatingPointPresent
; CHECK-NEXT: # -IsFloatingPointOperationLogOrAbortEnabled
; CHECK-NEXT: .byte 0x40 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
; CHECK-NEXT: # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved
; CHECK-NEXT: .byte 0x80 # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0
; CHECK-NEXT: .byte 0x00 # -HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0
; CHECK-NEXT: .byte 0x00 # NumberOfFixedParms = 0
; CHECK-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack
; CHECK-NEXT: .vbyte 4, L..bar0-.bar # Function size
; CHECK-NEXT: .vbyte 2, 0x0003 # Function name len = 3
; CHECK-NEXT: .byte 'b,'a,'r # Function Name
; CHECK-NEXT: L..func_end0:
; CHECK-NEXT: # -- End function
; CHECK-NEXT: .csect explicit_main_sec[PR],2
; CHECK-NEXT: .globl main[DS] # -- Begin function main
; CHECK-NEXT: .globl .main
; CHECK-NEXT: .align 2
; CHECK-NEXT: .csect main[DS],2
; CHECK-NEXT: .vbyte 4, .main # @main
; CHECK-NEXT: .vbyte 4, TOC[TC0]
; CHECK-NEXT: .vbyte 4, 0
; CHECK-NEXT: .csect explicit_main_sec[PR],2
; CHECK-NEXT: .main:
; CHECK-NEXT: L..func_begin1:
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: L..tmp3:
; CHECK-NEXT: mflr 0
; CHECK-NEXT: stw 0, 8(1)
; CHECK-NEXT: stwu 1, -64(1)
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: stw 3, 60(1)
; CHECK-NEXT: L..tmp4:
; CHECK-NEXT: L..tmp5:
; CHECK-NEXT: bl .bar
; CHECK-NEXT: nop
; CHECK-NEXT: L..tmp6:
; CHECK-NEXT: addi 1, 1, 64
; CHECK-NEXT: lwz 0, 8(1)
; CHECK-NEXT: mtlr 0
; CHECK-NEXT: blr
; CHECK-NEXT: L..tmp7:
; CHECK-NEXT: L..main0:
; CHECK-NEXT: .vbyte 4, 0x00000000 # Traceback table begin
; CHECK-NEXT: .byte 0x00 # Version = 0
; CHECK-NEXT: .byte 0x09 # Language = CPlusPlus
; CHECK-NEXT: .byte 0x22 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
; CHECK-NEXT: # +HasTraceBackTableOffset, -IsInternalProcedure
; CHECK-NEXT: # -HasControlledStorage, -IsTOCless
; CHECK-NEXT: # +IsFloatingPointPresent
; CHECK-NEXT: # -IsFloatingPointOperationLogOrAbortEnabled
; CHECK-NEXT: .byte 0x41 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
; CHECK-NEXT: # OnConditionDirective = 0, -IsCRSaved, +IsLRSaved
; CHECK-NEXT: .byte 0x80 # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0
; CHECK-NEXT: .byte 0x00 # -HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0
; CHECK-NEXT: .byte 0x00 # NumberOfFixedParms = 0
; CHECK-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack
; CHECK-NEXT: .vbyte 4, L..main0-.main # Function size
; CHECK-NEXT: .vbyte 2, 0x0004 # Function name len = 4
; CHECK-NEXT: .byte 'm,'a,'i,'n # Function Name
; CHECK-NEXT: L..func_end1:
; CHECK-NEXT: # -- End function
; CHECK-NEXT: L..sec_end0:
; CHECK: .dwsect 0x60000
; CHECK-NEXT: L...dwabrev:
; CHECK-NEXT: .byte 1 # Abbreviation Code
; CHECK-NEXT: .byte 17 # DW_TAG_compile_unit
; CHECK-NEXT: .byte 1 # DW_CHILDREN_yes
; CHECK-NEXT: .byte 37 # DW_AT_producer
; CHECK-NEXT: .byte 14 # DW_FORM_strp
; CHECK-NEXT: .byte 19 # DW_AT_language
; CHECK-NEXT: .byte 5 # DW_FORM_data2
; CHECK-NEXT: .byte 3 # DW_AT_name
; CHECK-NEXT: .byte 14 # DW_FORM_strp
; CHECK-NEXT: .byte 16 # DW_AT_stmt_list
; CHECK-NEXT: .byte 6 # DW_FORM_data4
; CHECK-NEXT: .byte 27 # DW_AT_comp_dir
; CHECK-NEXT: .byte 14 # DW_FORM_strp
; CHECK-NEXT: .byte 17 # DW_AT_low_pc
; CHECK-NEXT: .byte 1 # DW_FORM_addr
; CHECK-NEXT: .byte 85 # DW_AT_ranges
; CHECK-NEXT: .byte 6 # DW_FORM_data4
; CHECK-NEXT: .byte 0 # EOM(1)
; CHECK-NEXT: .byte 0 # EOM(2)
; CHECK-NEXT: .byte 2 # Abbreviation Code
; CHECK-NEXT: .byte 46 # DW_TAG_subprogram
; CHECK-NEXT: .byte 0 # DW_CHILDREN_no
; CHECK-NEXT: .byte 17 # DW_AT_low_pc
; CHECK-NEXT: .byte 1 # DW_FORM_addr
; CHECK-NEXT: .byte 18 # DW_AT_high_pc
; CHECK-NEXT: .byte 1 # DW_FORM_addr
; CHECK-NEXT: .byte 64 # DW_AT_frame_base
; CHECK-NEXT: .byte 10 # DW_FORM_block1
; CHECK-NEXT: .byte 3 # DW_AT_name
; CHECK-NEXT: .byte 14 # DW_FORM_strp
; CHECK-NEXT: .byte 58 # DW_AT_decl_file
; CHECK-NEXT: .byte 11 # DW_FORM_data1
; CHECK-NEXT: .byte 59 # DW_AT_decl_line
; CHECK-NEXT: .byte 11 # DW_FORM_data1
; CHECK-NEXT: .byte 73 # DW_AT_type
; CHECK-NEXT: .byte 19 # DW_FORM_ref4
; CHECK-NEXT: .byte 63 # DW_AT_external
; CHECK-NEXT: .byte 12 # DW_FORM_flag
; CHECK-NEXT: .byte 0 # EOM(1)
; CHECK-NEXT: .byte 0 # EOM(2)
; CHECK-NEXT: .byte 3 # Abbreviation Code
; CHECK-NEXT: .byte 36 # DW_TAG_base_type
; CHECK-NEXT: .byte 0 # DW_CHILDREN_no
; CHECK-NEXT: .byte 3 # DW_AT_name
; CHECK-NEXT: .byte 14 # DW_FORM_strp
; CHECK-NEXT: .byte 62 # DW_AT_encoding
; CHECK-NEXT: .byte 11 # DW_FORM_data1
; CHECK-NEXT: .byte 11 # DW_AT_byte_size
; CHECK-NEXT: .byte 11 # DW_FORM_data1
; CHECK-NEXT: .byte 0 # EOM(1)
; CHECK-NEXT: .byte 0 # EOM(2)
; CHECK-NEXT: .byte 0 # EOM(3)
; CHECK: .dwsect 0x10000
; CHECK-NEXT: L...dwinfo:
; CHECK-NEXT: L..cu_begin0:
; CHECK-NEXT: .vbyte 2, 3 # DWARF version number
; CHECK-NEXT: .vbyte 4, L...dwabrev # Offset Into Abbrev. Section
; CHECK-NEXT: .byte 4 # Address Size (in bytes)
; CHECK-NEXT: .byte 1 # Abbrev [1] 0xb:0x4f DW_TAG_compile_unit
; CHECK-NEXT: .vbyte 4, L..info_string0 # DW_AT_producer
; CHECK-NEXT: .vbyte 2, 12 # DW_AT_language
; CHECK-NEXT: .vbyte 4, L..info_string1 # DW_AT_name
; CHECK-NEXT: .vbyte 4, L..line_table_start0 # DW_AT_stmt_list
; CHECK-NEXT: .vbyte 4, L..info_string2 # DW_AT_comp_dir
; CHECK-NEXT: .vbyte 4, 0 # DW_AT_low_pc
; CHECK-NEXT: .vbyte 4, L..debug_ranges0 # DW_AT_ranges
; CHECK-NEXT: .byte 2 # Abbrev [2] 0x26:0x16 DW_TAG_subprogram
; CHECK-NEXT: .vbyte 4, L..func_begin0 # DW_AT_low_pc
; CHECK-NEXT: .vbyte 4, L..func_end0 # DW_AT_high_pc
; CHECK-NEXT: .byte 1 # DW_AT_frame_base
; CHECK-NEXT: .byte 81
; CHECK-NEXT: .vbyte 4, L..info_string3 # DW_AT_name
; CHECK-NEXT: .byte 1 # DW_AT_decl_file
; CHECK-NEXT: .byte 1 # DW_AT_decl_line
; CHECK-NEXT: .vbyte 4, 82 # DW_AT_type
; CHECK-NEXT: .byte 1 # DW_AT_external
; CHECK-NEXT: .byte 2 # Abbrev [2] 0x3c:0x16 DW_TAG_subprogram
; CHECK-NEXT: .vbyte 4, L..func_begin1 # DW_AT_low_pc
; CHECK-NEXT: .vbyte 4, L..func_end1 # DW_AT_high_pc
; CHECK-NEXT: .byte 1 # DW_AT_frame_base
; CHECK-NEXT: .byte 81
; CHECK-NEXT: .vbyte 4, L..info_string5 # DW_AT_name
; CHECK-NEXT: .byte 1 # DW_AT_decl_file
; CHECK-NEXT: .byte 2 # DW_AT_decl_line
; CHECK-NEXT: .vbyte 4, 82 # DW_AT_type
; CHECK-NEXT: .byte 1 # DW_AT_external
; CHECK-NEXT: .byte 3 # Abbrev [3] 0x52:0x7 DW_TAG_base_type
; CHECK-NEXT: .vbyte 4, L..info_string4 # DW_AT_name
; CHECK-NEXT: .byte 5 # DW_AT_encoding
; CHECK-NEXT: .byte 4 # DW_AT_byte_size
; CHECK-NEXT: .byte 0 # End Of Children Mark
; CHECK-NEXT: L..debug_info_end0:
; CHECK: .dwsect 0x80000
; CHECK-NEXT: L...dwrnges:
; CHECK-NEXT: L..debug_ranges0:
; CHECK-NEXT: .vbyte 4, L..func_begin0
; CHECK-NEXT: .vbyte 4, L..func_end0
; CHECK-NEXT: .vbyte 4, L..func_begin1
; CHECK-NEXT: .vbyte 4, L..func_end1
; CHECK-NEXT: .vbyte 4, 0
; CHECK-NEXT: .vbyte 4, 0
; CHECK: .dwsect 0x70000
; CHECK-NEXT: L...dwstr:
; CHECK-NEXT: L..info_string0:
; CHECK-NEXT: .byte 'c,'l,'a,'n,'g,' ,'v,'e,'r,'s,'i,'o,'n,' ,'1,'3,'.,'0,'.,'0,0000 # string offset=0
; CHECK-NEXT: L..info_string1:
; CHECK-NEXT: .byte '2,'.,'c,0000 # string offset=21
; CHECK-NEXT: L..info_string2:
; CHECK-NEXT: .byte 'd,'e,'b,'u,'g,0000 # string offset=25
; CHECK-NEXT: L..info_string3:
; CHECK-NEXT: .byte 'b,'a,'r,0000 # string offset=31
; CHECK-NEXT: L..info_string4:
; CHECK-NEXT: .byte 'i,'n,'t,0000 # string offset=35
; CHECK-NEXT: L..info_string5:
; CHECK-NEXT: .byte 'm,'a,'i,'n,0000 # string offset=39
; CHECK-NEXT: .toc
; CHECK: .dwsect 0x20000
; CHECK-NEXT: L...dwline:
; CHECK-NEXT: L..debug_line_0:
; CHECK-NEXT: .set L..line_table_start0, L..debug_line_0-4
; CHECK-NEXT: .vbyte 2, 3
; CHECK-NEXT: .vbyte 4, L..tmp9-L..tmp8
; CHECK-NEXT: L..tmp8:
; CHECK-NEXT: .byte 4
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte -5
; CHECK-NEXT: .byte 14
; CHECK-NEXT: .byte 13
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 'd,'e,'b,'u,'g
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte '2,'.,'c
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 0
; CHECK-NEXT: L..tmp9:
; CHECK-NEXT: .byte 0 # Set address to L..tmp0
; CHECK-NEXT: .byte 5
; CHECK-NEXT: .byte 2
; CHECK-NEXT: .vbyte 4, L..tmp0
; CHECK-NEXT: .byte 1 # Start sequence
; CHECK-NEXT: .byte 5
; CHECK-NEXT: .byte 12
; CHECK-NEXT: .byte 10
; CHECK-NEXT: .byte 0 # Set address to L..tmp1
; CHECK-NEXT: .byte 5
; CHECK-NEXT: .byte 2
; CHECK-NEXT: .vbyte 4, L..tmp1
; CHECK-NEXT: .byte 3 # Advance line 0
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0 # Set address to L..sec_end0
; CHECK-NEXT: .byte 5
; CHECK-NEXT: .byte 2
; CHECK-NEXT: .vbyte 4, L..sec_end0
; CHECK-NEXT: .byte 0 # End sequence
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0 # Set address to L..tmp3
; CHECK-NEXT: .byte 5
; CHECK-NEXT: .byte 2
; CHECK-NEXT: .vbyte 4, L..tmp3
; CHECK-NEXT: .byte 19 # Start sequence
; CHECK-NEXT: .byte 5
; CHECK-NEXT: .byte 10
; CHECK-NEXT: .byte 10
; CHECK-NEXT: .byte 0 # Set address to L..tmp5
; CHECK-NEXT: .byte 5
; CHECK-NEXT: .byte 2
; CHECK-NEXT: .vbyte 4, L..tmp5
; CHECK-NEXT: .byte 3 # Advance line 1
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 5
; CHECK-NEXT: .byte 3
; CHECK-NEXT: .byte 6
; CHECK-NEXT: .byte 0 # Set address to L..tmp6
; CHECK-NEXT: .byte 5
; CHECK-NEXT: .byte 2
; CHECK-NEXT: .vbyte 4, L..tmp6
; CHECK-NEXT: .byte 3 # Advance line 0
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0 # Set address to L..sec_end0
; CHECK-NEXT: .byte 5
; CHECK-NEXT: .byte 2
; CHECK-NEXT: .vbyte 4, L..sec_end0
; CHECK-NEXT: .byte 0 # End sequence
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 1
; CHECK-NEXT: L..debug_line_end0:

View File

@ -0,0 +1,315 @@
; RUN: llc -mtriple powerpc-ibm-aix-xcoff -function-sections \
; RUN: < %s | FileCheck %s
source_filename = "1.c"
target datalayout = "E-m:a-p:32:32-i64:64-n32"
; Function Attrs: noinline nounwind optnone
define i32 @foo() #0 !dbg !8 {
entry:
ret i32 0, !dbg !12
}
; Function Attrs: noinline nounwind optnone
define i32 @bar() #0 !dbg !13 {
entry:
ret i32 1, !dbg !14
}
!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 13.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 3}
!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 13.0.0"}
!8 = distinct !DISubprogram(name: "foo", 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)
!13 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 6, type: !9, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
!14 = !DILocation(line: 8, column: 3, scope: !13)
; CHECK: .csect .text[PR],2
; CHECK-NEXT: .file "1.c"
; CHECK-NEXT: .csect .foo[PR],2
; CHECK-NEXT: .globl foo[DS] # -- Begin function foo
; CHECK-NEXT: .globl .foo[PR]
; CHECK-NEXT: .align 2
; CHECK-NEXT: .csect foo[DS],2
; CHECK-NEXT: .vbyte 4, .foo[PR] # @foo
; CHECK-NEXT: .vbyte 4, TOC[TC0]
; CHECK-NEXT: .vbyte 4, 0
; CHECK-NEXT: .csect .foo[PR],2
; CHECK-NEXT: L..func_begin0:
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: L..tmp0:
; CHECK-NEXT: L..tmp1:
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: blr
; CHECK-NEXT: L..tmp2:
; CHECK-NEXT: L..foo0:
; CHECK-NEXT: .vbyte 4, 0x00000000 # Traceback table begin
; CHECK-NEXT: .byte 0x00 # Version = 0
; CHECK-NEXT: .byte 0x09 # Language = CPlusPlus
; CHECK-NEXT: .byte 0x20 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
; CHECK-NEXT: # +HasTraceBackTableOffset, -IsInternalProcedure
; CHECK-NEXT: # -HasControlledStorage, -IsTOCless
; CHECK-NEXT: # -IsFloatingPointPresent
; CHECK-NEXT: # -IsFloatingPointOperationLogOrAbortEnabled
; CHECK-NEXT: .byte 0x40 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
; CHECK-NEXT: # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved
; CHECK-NEXT: .byte 0x80 # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0
; CHECK-NEXT: .byte 0x00 # -HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0
; CHECK-NEXT: .byte 0x00 # NumberOfFixedParms = 0
; CHECK-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack
; CHECK-NEXT: .vbyte 4, L..foo0-.foo[PR] # Function size
; CHECK-NEXT: .vbyte 2, 0x0003 # Function name len = 3
; CHECK-NEXT: .byte 'f,'o,'o # Function Name
; CHECK-NEXT: L..func_end0:
; CHECK-NEXT: # -- End function
; CHECK-NEXT: .csect .bar[PR],2
; CHECK-NEXT: .globl bar[DS] # -- Begin function bar
; CHECK-NEXT: .globl .bar[PR]
; CHECK-NEXT: .align 2
; CHECK-NEXT: .csect bar[DS],2
; CHECK-NEXT: .vbyte 4, .bar[PR] # @bar
; CHECK-NEXT: .vbyte 4, TOC[TC0]
; CHECK-NEXT: .vbyte 4, 0
; CHECK-NEXT: .csect .bar[PR],2
; CHECK-NEXT: L..func_begin1:
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: L..tmp3:
; CHECK-NEXT: L..tmp4:
; CHECK-NEXT: li 3, 1
; CHECK-NEXT: blr
; CHECK-NEXT: L..tmp5:
; CHECK-NEXT: L..bar0:
; CHECK-NEXT: .vbyte 4, 0x00000000 # Traceback table begin
; CHECK-NEXT: .byte 0x00 # Version = 0
; CHECK-NEXT: .byte 0x09 # Language = CPlusPlus
; CHECK-NEXT: .byte 0x20 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
; CHECK-NEXT: # +HasTraceBackTableOffset, -IsInternalProcedure
; CHECK-NEXT: # -HasControlledStorage, -IsTOCless
; CHECK-NEXT: # -IsFloatingPointPresent
; CHECK-NEXT: # -IsFloatingPointOperationLogOrAbortEnabled
; CHECK-NEXT: .byte 0x40 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
; CHECK-NEXT: # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved
; CHECK-NEXT: .byte 0x80 # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0
; CHECK-NEXT: .byte 0x00 # -HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0
; CHECK-NEXT: .byte 0x00 # NumberOfFixedParms = 0
; CHECK-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack
; CHECK-NEXT: .vbyte 4, L..bar0-.bar[PR] # Function size
; CHECK-NEXT: .vbyte 2, 0x0003 # Function name len = 3
; CHECK-NEXT: .byte 'b,'a,'r # Function Name
; CHECK-NEXT: L..func_end1:
; CHECK-NEXT: # -- End function
; CHECK-NEXT: L..sec_end0:
; CHECK: .dwsect 0x60000
; CHECK-NEXT: L...dwabrev:
; CHECK-NEXT: .byte 1 # Abbreviation Code
; CHECK-NEXT: .byte 17 # DW_TAG_compile_unit
; CHECK-NEXT: .byte 1 # DW_CHILDREN_yes
; CHECK-NEXT: .byte 37 # DW_AT_producer
; CHECK-NEXT: .byte 14 # DW_FORM_strp
; CHECK-NEXT: .byte 19 # DW_AT_language
; CHECK-NEXT: .byte 5 # DW_FORM_data2
; CHECK-NEXT: .byte 3 # DW_AT_name
; CHECK-NEXT: .byte 14 # DW_FORM_strp
; CHECK-NEXT: .byte 16 # DW_AT_stmt_list
; CHECK-NEXT: .byte 6 # DW_FORM_data4
; CHECK-NEXT: .byte 27 # DW_AT_comp_dir
; CHECK-NEXT: .byte 14 # DW_FORM_strp
; CHECK-NEXT: .byte 17 # DW_AT_low_pc
; CHECK-NEXT: .byte 1 # DW_FORM_addr
; CHECK-NEXT: .byte 85 # DW_AT_ranges
; CHECK-NEXT: .byte 6 # DW_FORM_data4
; CHECK-NEXT: .byte 0 # EOM(1)
; CHECK-NEXT: .byte 0 # EOM(2)
; CHECK-NEXT: .byte 2 # Abbreviation Code
; CHECK-NEXT: .byte 46 # DW_TAG_subprogram
; CHECK-NEXT: .byte 0 # DW_CHILDREN_no
; CHECK-NEXT: .byte 17 # DW_AT_low_pc
; CHECK-NEXT: .byte 1 # DW_FORM_addr
; CHECK-NEXT: .byte 18 # DW_AT_high_pc
; CHECK-NEXT: .byte 1 # DW_FORM_addr
; CHECK-NEXT: .byte 64 # DW_AT_frame_base
; CHECK-NEXT: .byte 10 # DW_FORM_block1
; CHECK-NEXT: .byte 3 # DW_AT_name
; CHECK-NEXT: .byte 14 # DW_FORM_strp
; CHECK-NEXT: .byte 58 # DW_AT_decl_file
; CHECK-NEXT: .byte 11 # DW_FORM_data1
; CHECK-NEXT: .byte 59 # DW_AT_decl_line
; CHECK-NEXT: .byte 11 # DW_FORM_data1
; CHECK-NEXT: .byte 39 # DW_AT_prototyped
; CHECK-NEXT: .byte 12 # DW_FORM_flag
; CHECK-NEXT: .byte 73 # DW_AT_type
; CHECK-NEXT: .byte 19 # DW_FORM_ref4
; CHECK-NEXT: .byte 63 # DW_AT_external
; CHECK-NEXT: .byte 12 # DW_FORM_flag
; CHECK-NEXT: .byte 0 # EOM(1)
; CHECK-NEXT: .byte 0 # EOM(2)
; CHECK-NEXT: .byte 3 # Abbreviation Code
; CHECK-NEXT: .byte 36 # DW_TAG_base_type
; CHECK-NEXT: .byte 0 # DW_CHILDREN_no
; CHECK-NEXT: .byte 3 # DW_AT_name
; CHECK-NEXT: .byte 14 # DW_FORM_strp
; CHECK-NEXT: .byte 62 # DW_AT_encoding
; CHECK-NEXT: .byte 11 # DW_FORM_data1
; CHECK-NEXT: .byte 11 # DW_AT_byte_size
; CHECK-NEXT: .byte 11 # DW_FORM_data1
; CHECK-NEXT: .byte 0 # EOM(1)
; CHECK-NEXT: .byte 0 # EOM(2)
; CHECK-NEXT: .byte 0 # EOM(3)
; CHECK: .dwsect 0x10000
; CHECK-NEXT: L...dwinfo:
; CHECK-NEXT: L..cu_begin0:
; CHECK-NEXT: .vbyte 2, 3 # DWARF version number
; CHECK-NEXT: .vbyte 4, L...dwabrev # Offset Into Abbrev. Section
; CHECK-NEXT: .byte 4 # Address Size (in bytes)
; CHECK-NEXT: .byte 1 # Abbrev [1] 0xb:0x51 DW_TAG_compile_unit
; CHECK-NEXT: .vbyte 4, L..info_string0 # DW_AT_producer
; CHECK-NEXT: .vbyte 2, 12 # DW_AT_language
; CHECK-NEXT: .vbyte 4, L..info_string1 # DW_AT_name
; CHECK-NEXT: .vbyte 4, L..line_table_start0 # DW_AT_stmt_list
; CHECK-NEXT: .vbyte 4, L..info_string2 # DW_AT_comp_dir
; CHECK-NEXT: .vbyte 4, 0 # DW_AT_low_pc
; CHECK-NEXT: .vbyte 4, L..debug_ranges0 # DW_AT_ranges
; CHECK-NEXT: .byte 2 # Abbrev [2] 0x26:0x17 DW_TAG_subprogram
; CHECK-NEXT: .vbyte 4, L..func_begin0 # DW_AT_low_pc
; CHECK-NEXT: .vbyte 4, L..func_end0 # DW_AT_high_pc
; CHECK-NEXT: .byte 1 # DW_AT_frame_base
; CHECK-NEXT: .byte 81
; CHECK-NEXT: .vbyte 4, L..info_string3 # DW_AT_name
; CHECK-NEXT: .byte 1 # DW_AT_decl_file
; CHECK-NEXT: .byte 1 # DW_AT_decl_line
; CHECK-NEXT: .byte 1 # DW_AT_prototyped
; CHECK-NEXT: .vbyte 4, 84 # DW_AT_type
; CHECK-NEXT: .byte 1 # DW_AT_external
; CHECK-NEXT: .byte 2 # Abbrev [2] 0x3d:0x17 DW_TAG_subprogram
; CHECK-NEXT: .vbyte 4, L..func_begin1 # DW_AT_low_pc
; CHECK-NEXT: .vbyte 4, L..func_end1 # DW_AT_high_pc
; CHECK-NEXT: .byte 1 # DW_AT_frame_base
; CHECK-NEXT: .byte 81
; CHECK-NEXT: .vbyte 4, L..info_string5 # DW_AT_name
; CHECK-NEXT: .byte 1 # DW_AT_decl_file
; CHECK-NEXT: .byte 6 # DW_AT_decl_line
; CHECK-NEXT: .byte 1 # DW_AT_prototyped
; CHECK-NEXT: .vbyte 4, 84 # DW_AT_type
; CHECK-NEXT: .byte 1 # DW_AT_external
; CHECK-NEXT: .byte 3 # Abbrev [3] 0x54:0x7 DW_TAG_base_type
; CHECK-NEXT: .vbyte 4, L..info_string4 # DW_AT_name
; CHECK-NEXT: .byte 5 # DW_AT_encoding
; CHECK-NEXT: .byte 4 # DW_AT_byte_size
; CHECK-NEXT: .byte 0 # End Of Children Mark
; CHECK-NEXT: L..debug_info_end0:
; CHECK: .dwsect 0x80000
; CHECK-NEXT: L...dwrnges:
; CHECK-NEXT: L..debug_ranges0:
; CHECK-NEXT: .vbyte 4, L..func_begin0
; CHECK-NEXT: .vbyte 4, L..func_end0
; CHECK-NEXT: .vbyte 4, L..func_begin1
; CHECK-NEXT: .vbyte 4, L..func_end1
; CHECK-NEXT: .vbyte 4, 0
; CHECK-NEXT: .vbyte 4, 0
; CHECK: .dwsect 0x70000
; CHECK-NEXT: L...dwstr:
; CHECK-NEXT: L..info_string0:
; CHECK-NEXT: .byte 'c,'l,'a,'n,'g,' ,'v,'e,'r,'s,'i,'o,'n,' ,'1,'3,'.,'0,'.,'0,0000 # string offset=0
; CHECK-NEXT: L..info_string1:
; CHECK-NEXT: .byte '1,'.,'c,0000 # string offset=21
; CHECK-NEXT: L..info_string2:
; CHECK-NEXT: .byte 'd,'e,'b,'u,'g,0000 # string offset=25
; CHECK-NEXT: L..info_string3:
; CHECK-NEXT: .byte 'f,'o,'o,0000 # string offset=31
; CHECK-NEXT: L..info_string4:
; CHECK-NEXT: .byte 'i,'n,'t,0000 # string offset=35
; CHECK-NEXT: L..info_string5:
; CHECK-NEXT: .byte 'b,'a,'r,0000 # string offset=39
; CHECK-NEXT: .toc
; CHECK: .dwsect 0x20000
; CHECK-NEXT: L...dwline:
; CHECK-NEXT: L..debug_line_0:
; CHECK-NEXT: .set L..line_table_start0, L..debug_line_0-4
; CHECK-NEXT: .vbyte 2, 3
; CHECK-NEXT: .vbyte 4, L..tmp7-L..tmp6
; CHECK-NEXT: L..tmp6:
; CHECK-NEXT: .byte 4
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte -5
; CHECK-NEXT: .byte 14
; CHECK-NEXT: .byte 13
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 'd,'e,'b,'u,'g
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte '1,'.,'c
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 0
; CHECK-NEXT: L..tmp7:
; CHECK-NEXT: .byte 0 # Set address to L..tmp0
; CHECK-NEXT: .byte 5
; CHECK-NEXT: .byte 2
; CHECK-NEXT: .vbyte 4, L..tmp0
; CHECK-NEXT: .byte 19 # Start sequence
; CHECK-NEXT: .byte 5
; CHECK-NEXT: .byte 3
; CHECK-NEXT: .byte 10
; CHECK-NEXT: .byte 0 # Set address to L..tmp1
; CHECK-NEXT: .byte 5
; CHECK-NEXT: .byte 2
; CHECK-NEXT: .vbyte 4, L..tmp1
; CHECK-NEXT: .byte 3 # Advance line 1
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0 # Set address to L..sec_end0
; CHECK-NEXT: .byte 5
; CHECK-NEXT: .byte 2
; CHECK-NEXT: .vbyte 4, L..sec_end0
; CHECK-NEXT: .byte 0 # End sequence
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0 # Set address to L..tmp3
; CHECK-NEXT: .byte 5
; CHECK-NEXT: .byte 2
; CHECK-NEXT: .vbyte 4, L..tmp3
; CHECK-NEXT: .byte 24 # Start sequence
; CHECK-NEXT: .byte 5
; CHECK-NEXT: .byte 3
; CHECK-NEXT: .byte 10
; CHECK-NEXT: .byte 0 # Set address to L..tmp4
; CHECK-NEXT: .byte 5
; CHECK-NEXT: .byte 2
; CHECK-NEXT: .vbyte 4, L..tmp4
; CHECK-NEXT: .byte 3 # Advance line 1
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 0 # Set address to L..sec_end0
; CHECK-NEXT: .byte 5
; CHECK-NEXT: .byte 2
; CHECK-NEXT: .vbyte 4, L..sec_end0
; CHECK-NEXT: .byte 0 # End sequence
; CHECK-NEXT: .byte 1
; CHECK-NEXT: .byte 1
; CHECK-NEXT: L..debug_line_end0:

View File

@ -0,0 +1,2 @@
if not 'PowerPC' in config.root.targets:
config.unsupported = True