Skip to content

Commit

Permalink
[MC] Error on a .zerofill directive in a non-virtual section
Browse files Browse the repository at this point in the history
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
  • Loading branch information
francisvm committed Jul 2, 2018
1 parent d4f77a5 commit 4d5b107
Show file tree
Hide file tree
Showing 16 changed files with 147 additions and 21 deletions.
3 changes: 2 additions & 1 deletion llvm/include/llvm/MC/MCELFStreamer.h
Expand Up @@ -59,7 +59,8 @@ class MCELFStreamer : public MCObjectStreamer {
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,
Expand Down
3 changes: 2 additions & 1 deletion llvm/include/llvm/MC/MCStreamer.h
Expand Up @@ -566,7 +566,8 @@ class MCStreamer {
/// \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.
///
Expand Down
3 changes: 2 additions & 1 deletion llvm/include/llvm/MC/MCWasmStreamer.h
Expand Up @@ -60,7 +60,8 @@ class MCWasmStreamer : public MCObjectStreamer {
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,
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/MC/MCWinCOFFStreamer.h
Expand Up @@ -59,7 +59,7 @@ class MCWinCOFFStreamer : public MCObjectStreamer {
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;
Expand Down
13 changes: 11 additions & 2 deletions llvm/lib/MC/MCAsmStreamer.cpp
Expand Up @@ -178,7 +178,8 @@ class MCAsmStreamer final : public MCStreamer {
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;
Expand Down Expand Up @@ -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();

Expand All @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/MC/MCELFStreamer.cpp
Expand Up @@ -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");
}

Expand Down
18 changes: 14 additions & 4 deletions llvm/lib/MC/MCMachOStreamer.cpp
Expand Up @@ -102,7 +102,8 @@ class MCMachOStreamer : public MCObjectStreamer {
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;

Expand Down Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/MC/MCNullStreamer.cpp
Expand Up @@ -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 {}
Expand Down
10 changes: 6 additions & 4 deletions llvm/lib/MC/MCParser/DarwinAsmParser.cpp
Expand Up @@ -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");
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
}
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/MC/MCWasmStreamer.cpp
Expand Up @@ -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");
}

Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/MC/MCWinCOFFStreamer.cpp
Expand Up @@ -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");
}

Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Object/RecordStreamer.cpp
Expand Up @@ -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);
}

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Object/RecordStreamer.h
Expand Up @@ -53,7 +53,7 @@ class RecordStreamer : public MCStreamer {
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.
Expand Down
89 changes: 89 additions & 0 deletions llvm/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: <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: }
7 changes: 7 additions & 0 deletions llvm/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: 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
3 changes: 2 additions & 1 deletion llvm/tools/llvm-mca/llvm-mca.cpp
Expand Up @@ -287,7 +287,8 @@ class MCStreamerWrapper final : public MCStreamer {
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 {}
Expand Down

0 comments on commit 4d5b107

Please sign in to comment.