[llvm] 673e542 - MC: Fix fragment-in-BSS check
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jul 20 11:11:25 PDT 2025
Author: Fangrui Song
Date: 2025-07-20T11:11:21-07:00
New Revision: 673e5422ea4089805afa2a2c548c85be7c228a42
URL: https://github.com/llvm/llvm-project/commit/673e5422ea4089805afa2a2c548c85be7c228a42
DIFF: https://github.com/llvm/llvm-project/commit/673e5422ea4089805afa2a2c548c85be7c228a42.diff
LOG: MC: Fix fragment-in-BSS check
* Handle non-zero fill values for `.fill` and `.org` directives.
* Restore the fragment type check
(5ee34ff1e5cc952116f0da943ddaeb1a71db2940 removed a reachable
`llvm_unreachable`) to detect unintended API usage.
Remove virtual functions `getVirtualSectionKind` (added in
https://reviews.llvm.org/D78138) as they are unnecessary in diagnostics.
The a.out object file format has the BSS concept, which has been
inherited by COFF, XCOFF, Mach-O, and ELF object file formats.
Pull Request: https://github.com/llvm/llvm-project/pull/149721
Added:
Modified:
llvm/include/llvm/MC/MCSection.h
llvm/include/llvm/MC/MCSectionCOFF.h
llvm/include/llvm/MC/MCSectionELF.h
llvm/lib/MC/MCAssembler.cpp
llvm/lib/MC/MCParser/AsmParser.cpp
llvm/lib/MC/MCSection.cpp
llvm/lib/MC/MCSectionCOFF.cpp
llvm/lib/MC/MCSectionELF.cpp
llvm/test/MC/COFF/bss-text.s
llvm/test/MC/ELF/nobits-non-zero-value.s
Removed:
################################################################################
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<MCFillFragment>(F).getValue() != 0;
+ break;
+ case MCFragment::FT_Org:
+ HasNonZero = cast<MCOrgFragment>(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<const MCFragment *, SmallVector<const MCSymbol *, 0>> *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: <unknown>:0: error: IMAGE_SCN_CNT_UNINITIALIZED_DATA section '.bss' cannot have non-zero bytes
+# CHECK: <unknown>:0: error: BSS section '.bss' cannot have non-zero bytes
addb %bl,(%rax)
.section uninitialized,"b"
-# CHECK: <unknown>:0: error: IMAGE_SCN_CNT_UNINITIALIZED_DATA section 'uninitialized' cannot have non-zero bytes
+# CHECK: <unknown>: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: <unknown>:0: error: SHT_NOBITS section '.tbss' cannot have non-zero bytes
-# CHECK: <unknown>:0: error: SHT_NOBITS section '.bss' cannot have non-zero bytes
-# CHECK: <unknown>:0: error: SHT_NOBITS section '.bss1' cannot have fixups
+# CHECK: <unknown>:0: error: BSS section '.tbss' cannot have non-zero bytes
+# CHECK: <unknown>:0: error: BSS section '.bss' cannot have non-zero bytes
+# CHECK: <unknown>:0: error: BSS section 'data_fixup' cannot have fixups
+# CHECK: <unknown>:0: error: BSS section 'fill' cannot have non-zero bytes
+# CHECK: <unknown>:0: error: BSS section 'org' cannot have non-zero bytes
More information about the llvm-commits
mailing list