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 @@ -186,6 +186,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 @@ -78,6 +78,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 @@ -80,6 +80,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 @@ -687,10 +687,12 @@ for (unsigned i = 0, e = DF.getContents().size(); i != e; ++i) if (DF.getContents()[i]) { if (auto *ELFSec = dyn_cast(Sec)) - report_fatal_error("non-zero initializer found in section '" + - ELFSec->getSectionName() + "'"); + getContext().reportError( + SMLoc(), "non-zero initializer found in section '" + + ELFSec->getSectionName() + "'"); else - report_fatal_error("non-zero initializer found in virtual section"); + getContext().reportError( + SMLoc(), "non-zero initializer found in virtual section"); } 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 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 @@ -85,6 +85,10 @@ return IP; } +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 cannot have instructions + jmp foo + +.bss +# CHECK: {{.*}}.s:[[#@LINE+1]]:3: error: IMAGE_SCN_CNT_UNINITIALIZED_DATA section 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 cannot have instructions + jmp foo + +.bss +# CHECK: {{.*}}.s:[[#@LINE+1]]:3: error: SHT_NOBITS section cannot have instructions + addb %al,(%rax) + +# CHECK: :0: error: non-zero initializer found in section '.bss' + .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