diff --git a/llvm/include/llvm/MC/MCSection.h b/llvm/include/llvm/MC/MCSection.h index 68fc8767d6bce..2013b02ce5f23 100644 --- a/llvm/include/llvm/MC/MCSection.h +++ b/llvm/include/llvm/MC/MCSection.h @@ -112,7 +112,7 @@ class LLVM_ABI MCSection { StringRef Name; SectionVariant Variant; - MCSection(SectionVariant V, StringRef Name, bool IsText, bool IsVirtual, + MCSection(SectionVariant V, StringRef Name, bool IsText, bool IsBss, MCSymbol *Begin); // Protected non-virtual dtor prevents destroy through a base class pointer. ~MCSection() {} @@ -175,11 +175,9 @@ class LLVM_ABI MCSection { /// instead of 0s. virtual bool useCodeAlign() const = 0; - /// Return true if this is a BSS section (e.g., ELF .bss or .tbss) that does - /// not store content and is typically initialized to zeroes by the runtime. + /// Check whether this section is "virtual", that is has no actual object + /// file contents. bool isBssSection() const { return IsBss; } - - virtual StringRef getVirtualSectionKind() const; }; // Represents a contiguous piece of code or data within a section. Its size is diff --git a/llvm/include/llvm/MC/MCSectionCOFF.h b/llvm/include/llvm/MC/MCSectionCOFF.h index 4472a128caa6b..f979413a3791e 100644 --- a/llvm/include/llvm/MC/MCSectionCOFF.h +++ b/llvm/include/llvm/MC/MCSectionCOFF.h @@ -82,7 +82,6 @@ class MCSectionCOFF final : public MCSection { raw_ostream &OS, uint32_t Subsection) const override; bool useCodeAlign() const override; - StringRef getVirtualSectionKind() const override; unsigned getOrAssignWinCFISectionID(unsigned *NextID) const { if (WinCFISectionID == ~0U) diff --git a/llvm/include/llvm/MC/MCSectionELF.h b/llvm/include/llvm/MC/MCSectionELF.h index f09d30591a3cf..a01f95f44c954 100644 --- a/llvm/include/llvm/MC/MCSectionELF.h +++ b/llvm/include/llvm/MC/MCSectionELF.h @@ -88,7 +88,6 @@ class MCSectionELF final : public MCSection { raw_ostream &OS, uint32_t Subsection) const override; bool useCodeAlign() const override; - StringRef getVirtualSectionKind() const override; bool isUnique() const { return UniqueID != NonUniqueID; } unsigned getUniqueID() const { return UniqueID; } diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index 317ba8128cff1..26726c0902f5a 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -567,15 +567,37 @@ void MCAssembler::writeSectionData(raw_ostream &OS, // not tracked for efficiency. auto Fn = [](char c) { return c != 0; }; for (const MCFragment &F : *Sec) { - if (any_of(F.getContents(), Fn) || any_of(F.getVarContents(), Fn)) { - reportError(SMLoc(), Sec->getVirtualSectionKind() + " section '" + - Sec->getName() + + bool HasNonZero = false; + switch (F.getKind()) { + default: + reportFatalInternalError("BSS section '" + Sec->getName() + + "' contains invalid fragment"); + break; + case MCFragment::FT_Data: + case MCFragment::FT_Relaxable: + HasNonZero = + any_of(F.getContents(), Fn) || any_of(F.getVarContents(), Fn); + break; + case MCFragment::FT_Align: + // Disallowed for API usage. AsmParser changes non-zero fill values to + // 0. + assert(F.getAlignFill() == 0 && "Invalid align in virtual section!"); + break; + case MCFragment::FT_Fill: + HasNonZero = cast(F).getValue() != 0; + break; + case MCFragment::FT_Org: + HasNonZero = cast(F).getValue() != 0; + break; + } + if (HasNonZero) { + reportError(SMLoc(), "BSS section '" + Sec->getName() + "' cannot have non-zero bytes"); break; } if (F.getFixups().size() || F.getVarFixups().size()) { - reportError(SMLoc(), Sec->getVirtualSectionKind() + " section '" + - Sec->getName() + "' cannot have fixups"); + reportError(SMLoc(), + "BSS section '" + Sec->getName() + "' cannot have fixups"); break; } } diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 4c55e97f0c1fc..d0b6ea4cfd562 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -3406,9 +3406,8 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, uint8_t ValueSize) { if (HasFillExpr && FillExpr != 0 && Section->isBssSection()) { ReturnVal |= - Warning(FillExprLoc, "ignoring non-zero fill value in " + - Section->getVirtualSectionKind() + - " section '" + Section->getName() + "'"); + Warning(FillExprLoc, "ignoring non-zero fill value in BSS section '" + + Section->getName() + "'"); FillExpr = 0; } diff --git a/llvm/lib/MC/MCSection.cpp b/llvm/lib/MC/MCSection.cpp index fd1d072cf4152..1b5a7b337c207 100644 --- a/llvm/lib/MC/MCSection.cpp +++ b/llvm/lib/MC/MCSection.cpp @@ -18,10 +18,10 @@ using namespace llvm; -MCSection::MCSection(SectionVariant V, StringRef Name, bool IsText, - bool IsVirtual, MCSymbol *Begin) +MCSection::MCSection(SectionVariant V, StringRef Name, bool IsText, bool IsBss, + MCSymbol *Begin) : Begin(Begin), HasInstructions(false), IsRegistered(false), IsText(IsText), - IsBss(IsVirtual), LinkerRelaxable(false), Name(Name), Variant(V) { + IsBss(IsBss), LinkerRelaxable(false), Name(Name), Variant(V) { // The initial subsection number is 0. Create a fragment list. CurFragList = &Subsections.emplace_back(0u, FragList{}).second; } @@ -34,8 +34,6 @@ MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) { bool MCSection::hasEnded() const { return End && End->isInSection(); } -StringRef MCSection::getVirtualSectionKind() const { return "virtual"; } - #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void MCSection::dump( DenseMap> *FragToSyms) diff --git a/llvm/lib/MC/MCSectionCOFF.cpp b/llvm/lib/MC/MCSectionCOFF.cpp index 94e29ce27d881..5bf14735eda9b 100644 --- a/llvm/lib/MC/MCSectionCOFF.cpp +++ b/llvm/lib/MC/MCSectionCOFF.cpp @@ -115,7 +115,3 @@ void MCSectionCOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, } bool MCSectionCOFF::useCodeAlign() const { return isText(); } - -StringRef MCSectionCOFF::getVirtualSectionKind() const { - return "IMAGE_SCN_CNT_UNINITIALIZED_DATA"; -} diff --git a/llvm/lib/MC/MCSectionELF.cpp b/llvm/lib/MC/MCSectionELF.cpp index 299fe40706e3a..ef33f9c314579 100644 --- a/llvm/lib/MC/MCSectionELF.cpp +++ b/llvm/lib/MC/MCSectionELF.cpp @@ -215,5 +215,3 @@ void MCSectionELF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, bool MCSectionELF::useCodeAlign() const { return getFlags() & ELF::SHF_EXECINSTR; } - -StringRef MCSectionELF::getVirtualSectionKind() const { return "SHT_NOBITS"; } diff --git a/llvm/test/MC/COFF/bss-text.s b/llvm/test/MC/COFF/bss-text.s index 439bd789dff2c..cedbb2f032236 100644 --- a/llvm/test/MC/COFF/bss-text.s +++ b/llvm/test/MC/COFF/bss-text.s @@ -4,11 +4,11 @@ # RUN: llvm-mc -triple=x86_64-pc-win32 %s .bss -# CHECK: :0: error: IMAGE_SCN_CNT_UNINITIALIZED_DATA section '.bss' cannot have non-zero bytes +# CHECK: :0: error: BSS section '.bss' cannot have non-zero bytes addb %bl,(%rax) .section uninitialized,"b" -# CHECK: :0: error: IMAGE_SCN_CNT_UNINITIALIZED_DATA section 'uninitialized' cannot have non-zero bytes +# CHECK: :0: error: BSS section 'uninitialized' cannot have non-zero bytes jmp foo .section bss0,"b" diff --git a/llvm/test/MC/ELF/nobits-non-zero-value.s b/llvm/test/MC/ELF/nobits-non-zero-value.s index e9516aa3e835a..ea95ec97ac8d2 100644 --- a/llvm/test/MC/ELF/nobits-non-zero-value.s +++ b/llvm/test/MC/ELF/nobits-non-zero-value.s @@ -9,20 +9,37 @@ .bss addb %al,(%rax) -# CHECK: {{.*}}.s:[[#@LINE+1]]:11: warning: ignoring non-zero fill value in SHT_NOBITS section '.bss' +# CHECK: {{.*}}.s:[[#@LINE+1]]:11: warning: ignoring non-zero fill value in BSS section '.bss' .align 4, 42 -.align 4, 0 - .long 1 .section .bss0,"aw",%nobits addb %al,(%rax) -.section .bss1,"aw",%nobits +.section data_fixup,"aw",%nobits .quad foo +.section fill,"aw",%nobits +.fill b-a,1,1 + +.section org,"aw",%nobits +.org 1,1 + +.section ok,"aw",%nobits +.org 1 +.fill 1 +.fill b-a,1,0 +.align 4, 0 +.long 0 + +.text +a: nop +b: + ## Location is not tracked for efficiency. -# CHECK: :0: error: SHT_NOBITS section '.tbss' cannot have non-zero bytes -# CHECK: :0: error: SHT_NOBITS section '.bss' cannot have non-zero bytes -# CHECK: :0: error: SHT_NOBITS section '.bss1' cannot have fixups +# CHECK: :0: error: BSS section '.tbss' cannot have non-zero bytes +# CHECK: :0: error: BSS section '.bss' cannot have non-zero bytes +# CHECK: :0: error: BSS section 'data_fixup' cannot have fixups +# CHECK: :0: error: BSS section 'fill' cannot have non-zero bytes +# CHECK: :0: error: BSS section 'org' cannot have non-zero bytes