Index: include/llvm/MC/MCELFStreamer.h =================================================================== --- include/llvm/MC/MCELFStreamer.h +++ include/llvm/MC/MCELFStreamer.h @@ -59,7 +59,8 @@ 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: include/llvm/MC/MCStreamer.h =================================================================== --- include/llvm/MC/MCStreamer.h +++ include/llvm/MC/MCStreamer.h @@ -566,7 +566,8 @@ /// \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: include/llvm/MC/MCWasmStreamer.h =================================================================== --- include/llvm/MC/MCWasmStreamer.h +++ include/llvm/MC/MCWasmStreamer.h @@ -60,7 +60,8 @@ 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: include/llvm/MC/MCWinCOFFStreamer.h =================================================================== --- include/llvm/MC/MCWinCOFFStreamer.h +++ include/llvm/MC/MCWinCOFFStreamer.h @@ -59,7 +59,7 @@ 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: lib/MC/MCAsmStreamer.cpp =================================================================== --- lib/MC/MCAsmStreamer.cpp +++ lib/MC/MCAsmStreamer.cpp @@ -178,7 +178,8 @@ 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::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 @@ 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: lib/MC/MCELFStreamer.cpp =================================================================== --- lib/MC/MCELFStreamer.cpp +++ lib/MC/MCELFStreamer.cpp @@ -683,7 +683,8 @@ } 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: lib/MC/MCMachOStreamer.cpp =================================================================== --- lib/MC/MCMachOStreamer.cpp +++ lib/MC/MCMachOStreamer.cpp @@ -102,7 +102,8 @@ 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::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: lib/MC/MCNullStreamer.cpp =================================================================== --- lib/MC/MCNullStreamer.cpp +++ lib/MC/MCNullStreamer.cpp @@ -30,7 +30,8 @@ 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: lib/MC/MCParser/DarwinAsmParser.cpp =================================================================== --- lib/MC/MCParser/DarwinAsmParser.cpp +++ lib/MC/MCParser/DarwinAsmParser.cpp @@ -888,6 +888,7 @@ 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 @@ // 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 @@ getStreamer().EmitZerofill(getContext().getMachOSection( Segment, Section, MachO::S_ZEROFILL, 0, SectionKind::getBSS()), - Sym, Size, 1 << Pow2Alignment); + Sym, Size, 1 << Pow2Alignment, SectionLoc); return false; } Index: lib/MC/MCWasmStreamer.cpp =================================================================== --- lib/MC/MCWasmStreamer.cpp +++ lib/MC/MCWasmStreamer.cpp @@ -215,7 +215,8 @@ } 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: lib/MC/MCWinCOFFStreamer.cpp =================================================================== --- lib/MC/MCWinCOFFStreamer.cpp +++ lib/MC/MCWinCOFFStreamer.cpp @@ -279,7 +279,8 @@ } void MCWinCOFFStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol, - uint64_t Size, unsigned ByteAlignment) { + uint64_t Size, unsigned ByteAlignment, + SMLoc Loc) { llvm_unreachable("not implemented"); } Index: lib/Object/RecordStreamer.h =================================================================== --- lib/Object/RecordStreamer.h +++ lib/Object/RecordStreamer.h @@ -53,7 +53,7 @@ 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. Index: lib/Object/RecordStreamer.cpp =================================================================== --- lib/Object/RecordStreamer.cpp +++ lib/Object/RecordStreamer.cpp @@ -107,7 +107,8 @@ } void RecordStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol, - uint64_t Size, unsigned ByteAlignment) { + uint64_t Size, unsigned ByteAlignment, + SMLoc Loc) { markDefined(*Symbol); } Index: test/MC/MachO/zero-space.s =================================================================== --- /dev/null +++ test/MC/MachO/zero-space.s @@ -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: +// 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: } Index: test/MC/MachO/zerofill-text.s =================================================================== --- /dev/null +++ test/MC/MachO/zerofill-text.s @@ -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: 6:33: 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: tools/llvm-mca/llvm-mca.cpp =================================================================== --- tools/llvm-mca/llvm-mca.cpp +++ tools/llvm-mca/llvm-mca.cpp @@ -282,7 +282,8 @@ 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 {}