[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