[MC] Error on a .zerofill directive in a non-virtual section
authorFrancis Visoiu Mistrih <francisvm@yahoo.com>
Mon, 2 Jul 2018 17:29:43 +0000 (17:29 +0000)
committerFrancis Visoiu Mistrih <francisvm@yahoo.com>
Mon, 2 Jul 2018 17:29:43 +0000 (17:29 +0000)
On darwin, all virtual sections have zerofill type, and having a
.zerofill directive in a non-virtual section is not allowed. Instead of
asserting, show a nicer error.

In order to use the equivalent of .zerofill in a non-virtual section,
the usage of .zero of .space is required.

This patch replaces the assert with an error.

Differential Revision: https://reviews.llvm.org/D48517

llvm-svn: 336127

16 files changed:
llvm/include/llvm/MC/MCELFStreamer.h
llvm/include/llvm/MC/MCStreamer.h
llvm/include/llvm/MC/MCWasmStreamer.h
llvm/include/llvm/MC/MCWinCOFFStreamer.h
llvm/lib/MC/MCAsmStreamer.cpp
llvm/lib/MC/MCELFStreamer.cpp
llvm/lib/MC/MCMachOStreamer.cpp
llvm/lib/MC/MCNullStreamer.cpp
llvm/lib/MC/MCParser/DarwinAsmParser.cpp
llvm/lib/MC/MCWasmStreamer.cpp
llvm/lib/MC/MCWinCOFFStreamer.cpp
llvm/lib/Object/RecordStreamer.cpp
llvm/lib/Object/RecordStreamer.h
llvm/test/MC/MachO/zero-space.s [new file with mode: 0644]
llvm/test/MC/MachO/zerofill-text.s [new file with mode: 0644]
llvm/tools/llvm-mca/llvm-mca.cpp

index b1b083f..3797079 100644 (file)
@@ -59,7 +59,8 @@ public:
                              unsigned ByteAlignment) override;
 
   void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
-                    uint64_t Size = 0, unsigned ByteAlignment = 0) override;
+                    uint64_t Size = 0, unsigned ByteAlignment = 0,
+                    SMLoc L = SMLoc()) override;
   void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
                       unsigned ByteAlignment = 0) override;
   void EmitValueImpl(const MCExpr *Value, unsigned Size,
index 43712de..d33c319 100644 (file)
@@ -566,7 +566,8 @@ public:
   /// \param ByteAlignment - The alignment of the zerofill symbol if
   /// non-zero. This must be a power of 2 on some targets.
   virtual void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
-                            uint64_t Size = 0, unsigned ByteAlignment = 0) = 0;
+                            uint64_t Size = 0, unsigned ByteAlignment = 0,
+                            SMLoc Loc = SMLoc()) = 0;
 
   /// Emit a thread local bss (.tbss) symbol.
   ///
index e2da11c..01e6a43 100644 (file)
@@ -60,7 +60,8 @@ public:
                              unsigned ByteAlignment) override;
 
   void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
-                    uint64_t Size = 0, unsigned ByteAlignment = 0) override;
+                    uint64_t Size = 0, unsigned ByteAlignment = 0,
+                    SMLoc Loc = SMLoc()) override;
   void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
                       unsigned ByteAlignment = 0) override;
   void EmitValueImpl(const MCExpr *Value, unsigned Size,
index 58f70b4..ee91fff 100644 (file)
@@ -59,7 +59,7 @@ public:
   void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
                              unsigned ByteAlignment) override;
   void EmitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
-                    unsigned ByteAlignment) override;
+                    unsigned ByteAlignment, SMLoc Loc = SMLoc()) override;
   void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
                       unsigned ByteAlignment) override;
   void EmitIdent(StringRef IdentString) override;
index 681e7e4..5398cfe 100644 (file)
@@ -178,7 +178,8 @@ public:
                              unsigned ByteAlignment) override;
 
   void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
-                    uint64_t Size = 0, unsigned ByteAlignment = 0) override;
+                    uint64_t Size = 0, unsigned ByteAlignment = 0,
+                    SMLoc Loc = SMLoc()) override;
 
   void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
                       unsigned ByteAlignment = 0) override;
@@ -749,14 +750,18 @@ void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
 }
 
 void MCAsmStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
-                                 uint64_t Size, unsigned ByteAlignment) {
+                                 uint64_t Size, unsigned ByteAlignment,
+                                 SMLoc Loc) {
   if (Symbol)
     AssignFragment(Symbol, &Section->getDummyFragment());
 
   // Note: a .zerofill directive does not switch sections.
   OS << ".zerofill ";
 
+  assert(Section->getVariant() == MCSection::SV_MachO &&
+         ".zerofill is a Mach-O specific directive");
   // This is a mach-o specific directive.
+
   const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
   OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
 
@@ -779,7 +784,11 @@ void MCAsmStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
 
   assert(Symbol && "Symbol shouldn't be NULL!");
   // Instead of using the Section we'll just use the shortcut.
+
+  assert(Section->getVariant() == MCSection::SV_MachO &&
+         ".zerofill is a Mach-O specific directive");
   // This is a mach-o specific directive and section.
+
   OS << ".tbss ";
   Symbol->print(OS, MAI);
   OS << ", " << Size;
index 11b0fc6..95b48e6 100644 (file)
@@ -683,7 +683,8 @@ void MCELFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
 }
 
 void MCELFStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
-                                 uint64_t Size, unsigned ByteAlignment) {
+                                 uint64_t Size, unsigned ByteAlignment,
+                                 SMLoc Loc) {
   llvm_unreachable("ELF doesn't support this directive");
 }
 
index 69995fa..43e6960 100644 (file)
@@ -102,7 +102,8 @@ public:
   void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
                              unsigned ByteAlignment) override;
   void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
-                    uint64_t Size = 0, unsigned ByteAlignment = 0) override;
+                    uint64_t Size = 0, unsigned ByteAlignment = 0,
+                    SMLoc Loc = SMLoc()) override;
   void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
                       unsigned ByteAlignment = 0) override;
 
@@ -413,9 +414,18 @@ void MCMachOStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
 }
 
 void MCMachOStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
-                                   uint64_t Size, unsigned ByteAlignment) {
-  // On darwin all virtual sections have zerofill type.
-  assert(Section->isVirtualSection() && "Section does not have zerofill type!");
+                                   uint64_t Size, unsigned ByteAlignment,
+                                   SMLoc Loc) {
+  // On darwin all virtual sections have zerofill type. Disallow the usage of
+  // .zerofill in non-virtual functions. If something similar is needed, use
+  // .space or .zero.
+  if (!Section->isVirtualSection()) {
+    getContext().reportError(
+        Loc, "The usage of .zerofill is restricted to sections of "
+             "ZEROFILL type. Use .zero or .space instead.");
+    return; // Early returning here shouldn't harm. EmitZeros should work on any
+            // section.
+  }
 
   PushSection();
   SwitchSection(Section);
index ccf658e..a96dec1 100644 (file)
@@ -30,7 +30,8 @@ namespace {
     void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
                           unsigned ByteAlignment) override {}
     void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
-                      uint64_t Size = 0, unsigned ByteAlignment = 0) override {}
+                      uint64_t Size = 0, unsigned ByteAlignment = 0,
+                      SMLoc Loc = SMLoc()) override {}
     void EmitGPRel32Value(const MCExpr *Value) override {}
     void BeginCOFFSymbolDef(const MCSymbol *Symbol) override {}
     void EmitCOFFSymbolStorageClass(int StorageClass) override {}
index 82741f8..e6fc1fa 100644 (file)
@@ -888,6 +888,7 @@ bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) {
   Lex();
 
   StringRef Section;
+  SMLoc SectionLoc = getLexer().getLoc();
   if (getParser().parseIdentifier(Section))
     return TokError("expected section name after comma in '.zerofill' "
                     "directive");
@@ -896,9 +897,10 @@ bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) {
   // the section but with no symbol.
   if (getLexer().is(AsmToken::EndOfStatement)) {
     // Create the zerofill section but no symbol
-    getStreamer().EmitZerofill(getContext().getMachOSection(
-                                 Segment, Section, MachO::S_ZEROFILL,
-                                 0, SectionKind::getBSS()));
+    getStreamer().EmitZerofill(
+        getContext().getMachOSection(Segment, Section, MachO::S_ZEROFILL, 0,
+                                     SectionKind::getBSS()),
+        /*Symbol=*/nullptr, /*Size=*/0, /*ByteAlignment=*/0, SectionLoc);
     return false;
   }
 
@@ -957,7 +959,7 @@ bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) {
   getStreamer().EmitZerofill(getContext().getMachOSection(
                                Segment, Section, MachO::S_ZEROFILL,
                                0, SectionKind::getBSS()),
-                             Sym, Size, 1 << Pow2Alignment);
+                             Sym, Size, 1 << Pow2Alignment, SectionLoc);
 
   return false;
 }
index c950ac7..0e59322 100644 (file)
@@ -215,7 +215,8 @@ void MCWasmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
 }
 
 void MCWasmStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
-                                  uint64_t Size, unsigned ByteAlignment) {
+                                  uint64_t Size, unsigned ByteAlignment,
+                                  SMLoc Loc) {
   llvm_unreachable("Wasm doesn't support this directive");
 }
 
index 32dc46c..1a1b504 100644 (file)
@@ -279,7 +279,8 @@ void MCWinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
 }
 
 void MCWinCOFFStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
-                                     uint64_t Size, unsigned ByteAlignment) {
+                                     uint64_t Size, unsigned ByteAlignment,
+                                     SMLoc Loc) {
   llvm_unreachable("not implemented");
 }
 
index f49c823..1f57867 100644 (file)
@@ -107,7 +107,8 @@ bool RecordStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
 }
 
 void RecordStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
-                                  uint64_t Size, unsigned ByteAlignment) {
+                                  uint64_t Size, unsigned ByteAlignment,
+                                  SMLoc Loc) {
   markDefined(*Symbol);
 }
 
index 13eac02..3d5ae59 100644 (file)
@@ -53,7 +53,7 @@ public:
   void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
   bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
   void EmitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
-                    unsigned ByteAlignment) override;
+                    unsigned ByteAlignment, SMLoc Loc = SMLoc()) override;
   void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
                         unsigned ByteAlignment) override;
   /// Record .symver aliases for later processing.
diff --git a/llvm/test/MC/MachO/zero-space.s b/llvm/test/MC/MachO/zero-space.s
new file mode 100644 (file)
index 0000000..b823c42
--- /dev/null
@@ -0,0 +1,89 @@
+// RUN: llvm-mc -triple x86_64-apple-darwin9 %s -filetype=obj -o - | llvm-readobj -file-headers -s -sd -r -t --macho-segment --macho-dysymtab --macho-indirect-symbols | FileCheck %s
+
+        .const
+        .p2align 6
+        Lzero:
+          .space 64
+          .zero 64
+
+// CHECK: File: <stdin>
+// CHECK-NEXT: Format: Mach-O 64-bit x86-64
+// CHECK-NEXT: Arch: x86_64
+// CHECK-NEXT: AddressSize: 64bit
+// CHECK-NEXT: MachHeader {
+// CHECK-NEXT:   Magic: Magic64 (0xFEEDFACF)
+// CHECK-NEXT:   CpuType: X86-64 (0x1000007)
+// CHECK-NEXT:   CpuSubType: CPU_SUBTYPE_X86_64_ALL (0x3)
+// CHECK-NEXT:   FileType: Relocatable (0x1)
+// CHECK-NEXT:   NumOfLoadCommands: 2
+// CHECK-NEXT:   SizeOfLoadCommands: 248
+// CHECK-NEXT:   Flags [ (0x0)
+// CHECK-NEXT:   ]
+// CHECK-NEXT:   Reserved: 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: Sections [
+// CHECK-NEXT:   Section {
+// CHECK-NEXT:     Index: 0
+// CHECK-NEXT:     Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
+// CHECK-NEXT:     Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
+// CHECK-NEXT:     Address: 0x0
+// CHECK-NEXT:     Size: 0x0
+// CHECK-NEXT:     Offset: 280
+// CHECK-NEXT:     Alignment: 0
+// CHECK-NEXT:     RelocationOffset: 0x0
+// CHECK-NEXT:     RelocationCount: 0
+// CHECK-NEXT:     Type: 0x0
+// CHECK-NEXT:     Attributes [ (0x800000)
+// CHECK-NEXT:       PureInstructions (0x800000)
+// CHECK-NEXT:     ]
+// CHECK-NEXT:     Reserved1: 0x0
+// CHECK-NEXT:     Reserved2: 0x0
+// CHECK-NEXT:     Reserved3: 0x0
+// CHECK-NEXT:     SectionData (
+// CHECK-NEXT:     )
+// CHECK-NEXT:   }
+// CHECK-NEXT:   Section {
+// CHECK-NEXT:     Index: 1
+// CHECK-NEXT:     Name: __const (5F 5F 63 6F 6E 73 74 00 00 00 00 00 00 00 00 00)
+// CHECK-NEXT:     Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
+// CHECK-NEXT:     Address: 0x0
+// CHECK-NEXT:     Size: 0x80
+// CHECK-NEXT:     Offset: 280
+// CHECK-NEXT:     Alignment: 6
+// CHECK-NEXT:     RelocationOffset: 0x0
+// CHECK-NEXT:     RelocationCount: 0
+// CHECK-NEXT:     Type: 0x0
+// CHECK-NEXT:     Attributes [ (0x0)
+// CHECK-NEXT:     ]
+// CHECK-NEXT:     Reserved1: 0x0
+// CHECK-NEXT:     Reserved2: 0x0
+// CHECK-NEXT:     Reserved3: 0x0
+// CHECK-NEXT:     SectionData (
+// CHECK-NEXT:       0000: 00000000 00000000 00000000 00000000  |................|
+// CHECK-NEXT:       0010: 00000000 00000000 00000000 00000000  |................|
+// CHECK-NEXT:       0020: 00000000 00000000 00000000 00000000  |................|
+// CHECK-NEXT:       0030: 00000000 00000000 00000000 00000000  |................|
+// CHECK-NEXT:       0040: 00000000 00000000 00000000 00000000  |................|
+// CHECK-NEXT:       0050: 00000000 00000000 00000000 00000000  |................|
+// CHECK-NEXT:       0060: 00000000 00000000 00000000 00000000  |................|
+// CHECK-NEXT:       0070: 00000000 00000000 00000000 00000000  |................|
+// CHECK-NEXT:     )
+// CHECK-NEXT:   }
+// CHECK-NEXT: ]
+// CHECK-NEXT: Relocations [
+// CHECK-NEXT: ]
+// CHECK-NEXT: Symbols [
+// CHECK-NEXT: ]
+// CHECK-NEXT: Segment {
+// CHECK-NEXT:   Cmd: LC_SEGMENT_64
+// CHECK-NEXT:   Name:
+// CHECK-NEXT:   Size: 232
+// CHECK-NEXT:   vmaddr: 0x0
+// CHECK-NEXT:   vmsize: 0x80
+// CHECK-NEXT:   fileoff: 280
+// CHECK-NEXT:   filesize: 128
+// CHECK-NEXT:   maxprot: rwx
+// CHECK-NEXT:   initprot: rwx
+// CHECK-NEXT:   nsects: 2
+// CHECK-NEXT:   flags: 0x0
+// CHECK-NEXT: }
diff --git a/llvm/test/MC/MachO/zerofill-text.s b/llvm/test/MC/MachO/zerofill-text.s
new file mode 100644 (file)
index 0000000..e69558c
--- /dev/null
@@ -0,0 +1,7 @@
+// RUN: not llvm-mc -triple x86_64-apple-darwin9 %s -filetype=obj -o /dev/null 2>&1 | FileCheck %s
+
+        .text
+        .zerofill __TEXT, __const, zfill, 2, 1
+
+// CHECK: 4:27: error: The usage of .zerofill is restricted to sections of ZEROFILL type. Use .zero or .space instead.
+// CHECK-NEXT: .zerofill __TEXT, __const, zfill, 2, 1
index a492eb8..4cdd6ba 100644 (file)
@@ -287,7 +287,8 @@ public:
   void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
                         unsigned ByteAlignment) override {}
   void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
-                    uint64_t Size = 0, unsigned ByteAlignment = 0) override {}
+                    uint64_t Size = 0, unsigned ByteAlignment = 0,
+                    SMLoc Loc = SMLoc()) override {}
   void EmitGPRel32Value(const MCExpr *Value) override {}
   void BeginCOFFSymbolDef(const MCSymbol *Symbol) override {}
   void EmitCOFFSymbolStorageClass(int StorageClass) override {}