diff --git a/llvm/include/llvm/MC/MCSection.h b/llvm/include/llvm/MC/MCSection.h --- a/llvm/include/llvm/MC/MCSection.h +++ b/llvm/include/llvm/MC/MCSection.h @@ -189,6 +189,8 @@ /// file contents. virtual bool isVirtualSection() const = 0; + virtual StringRef getVirtualSectionKind() const; + /// Add a pending label for the requested subsection. This label will be /// associated with a fragment in flushPendingLabels() void addPendingLabel(MCSymbol* label, unsigned Subsection = 0); diff --git a/llvm/include/llvm/MC/MCSectionCOFF.h b/llvm/include/llvm/MC/MCSectionCOFF.h --- a/llvm/include/llvm/MC/MCSectionCOFF.h +++ b/llvm/include/llvm/MC/MCSectionCOFF.h @@ -74,6 +74,7 @@ const MCExpr *Subsection) const override; bool UseCodeAlign() const override; bool isVirtualSection() 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 --- a/llvm/include/llvm/MC/MCSectionELF.h +++ b/llvm/include/llvm/MC/MCSectionELF.h @@ -78,6 +78,7 @@ const MCExpr *Subsection) const override; bool UseCodeAlign() const override; bool isVirtualSection() 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 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -683,11 +683,16 @@ // directives to fill the contents of virtual sections. const MCDataFragment &DF = cast(F); if (DF.fixup_begin() != DF.fixup_end()) - report_fatal_error("cannot have fixups in virtual section!"); + getContext().reportError(SMLoc(), Sec->getVirtualSectionKind() + + " section '" + Sec->getName() + + "' cannot have fixups"); for (unsigned i = 0, e = DF.getContents().size(); i != e; ++i) if (DF.getContents()[i]) { - report_fatal_error("non-zero initializer found in section '" + - Sec->getName() + "'"); + getContext().reportError(SMLoc(), + Sec->getVirtualSectionKind() + + " section '" + Sec->getName() + + "' cannot have non-zero initializers"); + break; } break; } diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -367,6 +367,13 @@ void MCObjectStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) { + const MCSection &Sec = *getCurrentSectionOnly(); + if (Sec.isVirtualSection()) { + getContext().reportError(Inst.getLoc(), Twine(Sec.getVirtualSectionKind()) + + " section '" + Sec.getName() + + "' cannot have instructions"); + return; + } getAssembler().getBackend().emitInstructionBegin(*this, Inst); emitInstructionImpl(Inst, STI); getAssembler().getBackend().emitInstructionEnd(*this, Inst); diff --git a/llvm/lib/MC/MCSection.cpp b/llvm/lib/MC/MCSection.cpp --- a/llvm/lib/MC/MCSection.cpp +++ b/llvm/lib/MC/MCSection.cpp @@ -87,7 +87,9 @@ return IP; } -void MCSection::addPendingLabel(MCSymbol* label, unsigned Subsection) { +StringRef MCSection::getVirtualSectionKind() const { return "virtual"; } + +void MCSection::addPendingLabel(MCSymbol *label, unsigned Subsection) { PendingLabels.push_back(PendingLabel(label, Subsection)); } diff --git a/llvm/lib/MC/MCSectionCOFF.cpp b/llvm/lib/MC/MCSectionCOFF.cpp --- a/llvm/lib/MC/MCSectionCOFF.cpp +++ b/llvm/lib/MC/MCSectionCOFF.cpp @@ -111,3 +111,7 @@ bool MCSectionCOFF::isVirtualSection() const { return getCharacteristics() & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; } + +StringRef MCSectionCOFF::getVirtualSectionKind() const { + return "IMAGE_SCN_CNT_UNINITIALIZED_DATA"; +} diff --git a/llvm/lib/MC/MCSectionELF.cpp b/llvm/lib/MC/MCSectionELF.cpp --- a/llvm/lib/MC/MCSectionELF.cpp +++ b/llvm/lib/MC/MCSectionELF.cpp @@ -196,3 +196,5 @@ bool MCSectionELF::isVirtualSection() const { return getType() == ELF::SHT_NOBITS; } + +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 new file mode 100644 --- /dev/null +++ b/llvm/test/MC/COFF/bss-text.s @@ -0,0 +1,13 @@ +# RUN: not llvm-mc -filetype=obj -triple=x86_64-pc-win32 %s -o /dev/null 2>&1 | FileCheck %s + +## -filetype=asm does not check the error. +# RUN: llvm-mc -triple=x86_64-pc-win32 %s + +.section uninitialized,"b" +# MCRelaxableFragment +# CHECK: {{.*}}.s:[[#@LINE+1]]:3: error: IMAGE_SCN_CNT_UNINITIALIZED_DATA section 'uninitialized' cannot have instructions + jmp foo + +.bss +# CHECK: {{.*}}.s:[[#@LINE+1]]:3: error: IMAGE_SCN_CNT_UNINITIALIZED_DATA section '.bss' cannot have instructions + addb %al,(%rax) diff --git a/llvm/test/MC/ELF/ARM/bss-non-zero-value.s b/llvm/test/MC/ELF/ARM/bss-non-zero-value.s deleted file mode 100644 --- a/llvm/test/MC/ELF/ARM/bss-non-zero-value.s +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: not --crash llvm-mc -filetype=obj -triple arm-linux-gnu %s -o %t 2>%t.out -// RUN: FileCheck --input-file=%t.out %s -// CHECK: non-zero initializer found in section '.bss' - .bss - .globl a - .align 2 -a: - .long 1 - .size a, 4 diff --git a/llvm/test/MC/ELF/nobits-non-zero-value.s b/llvm/test/MC/ELF/nobits-non-zero-value.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/ELF/nobits-non-zero-value.s @@ -0,0 +1,16 @@ +# RUN: not llvm-mc -filetype=obj -triple=x86_64 %s -o /dev/null 2>&1 | FileCheck %s + +## -filetype=asm does not check the error. +# RUN: llvm-mc -triple=x86_64 %s + +.section .tbss,"aw",@nobits +# MCRelaxableFragment +# CHECK: {{.*}}.s:[[#@LINE+1]]:3: error: SHT_NOBITS section '.tbss' cannot have instructions + jmp foo + +.bss +# CHECK: {{.*}}.s:[[#@LINE+1]]:3: error: SHT_NOBITS section '.bss' cannot have instructions + addb %al,(%rax) + +# CHECK: :0: error: SHT_NOBITS section '.bss' cannot have non-zero initializers + .long 1 diff --git a/llvm/test/MC/X86/reloc-bss.s b/llvm/test/MC/X86/reloc-bss.s deleted file mode 100644 --- a/llvm/test/MC/X86/reloc-bss.s +++ /dev/null @@ -1,9 +0,0 @@ -# RUN: not --crash llvm-mc -filetype=obj -triple=x86_64-linux-gnu %s 2>&1 | FileCheck %s -# CHECK: LLVM ERROR: cannot have fixups in virtual section! - -.section .init_array,"awT",@nobits - -.hidden patatino -.globl patatino -patatino: - movl __init_array_start, %eax