Skip to content

Commit ea0a12d

Browse files
MaskRaycachemeifyoucan
authored andcommitted
MC: Optimize emitInstruction and simplify fragment-in-BSS check
Move the FT_Relaxable-in-BSS check from frequently-called MCObjectStreamer::emitInstruction to MCAssembler::writeSectionData, along with existing checks for other fragment types. For the uncommon diagnostics, losing the location information is acceptable.
1 parent 9f37c9e commit ea0a12d

File tree

7 files changed

+35
-60
lines changed

7 files changed

+35
-60
lines changed

llvm/include/llvm/MC/MCObjectStreamer.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ class MCObjectStreamer : public MCStreamer {
5454
void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &);
5555
void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
5656
void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
57-
void emitInstructionImpl(const MCInst &Inst, const MCSubtargetInfo &STI);
5857

5958
protected:
6059
MCObjectStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,

llvm/lib/MC/MCAssembler.cpp

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -583,42 +583,23 @@ void MCAssembler::writeSectionData(raw_ostream &OS,
583583
const MCSection *Sec) const {
584584
assert(getBackendPtr() && "Expected assembler backend");
585585

586-
// Ignore virtual sections.
587586
if (Sec->isVirtualSection()) {
588587
assert(getSectionFileSize(*Sec) == 0 && "Invalid size for section!");
589588

590-
// Check that contents are only things legal inside a virtual section.
589+
// Ensure no fixups or non-zero bytes are written to BSS sections, catching
590+
// errors in both input assembly code and MCStreamer API usage. Location is
591+
// not tracked for efficiency.
592+
auto Fn = [](char c) { return c != 0; };
591593
for (const MCFragment &F : *Sec) {
592-
switch (F.getKind()) {
593-
default: llvm_unreachable("Invalid fragment in virtual section!");
594-
case MCFragment::FT_Data: {
595-
// Check that we aren't trying to write a non-zero contents (or fixups)
596-
// into a virtual section. This is to support clients which use standard
597-
// directives to fill the contents of virtual sections.
598-
if (F.getFixups().size() || F.getVarFixups().size())
599-
reportError(SMLoc(), Sec->getVirtualSectionKind() + " section '" +
600-
Sec->getName() + "' cannot have fixups");
601-
for (char C : F.getContents())
602-
if (C) {
603-
reportError(SMLoc(), Sec->getVirtualSectionKind() + " section '" +
604-
Sec->getName() +
605-
"' cannot have non-zero initializers");
606-
break;
607-
}
594+
if (any_of(F.getContents(), Fn) || any_of(F.getVarContents(), Fn)) {
595+
reportError(SMLoc(), Sec->getVirtualSectionKind() + " section '" +
596+
Sec->getName() +
597+
"' cannot have non-zero bytes");
608598
break;
609599
}
610-
case MCFragment::FT_Align:
611-
// Check that we aren't trying to write a non-zero value into a virtual
612-
// section.
613-
assert((cast<MCAlignFragment>(F).getFillLen() == 0 ||
614-
cast<MCAlignFragment>(F).getFill() == 0) &&
615-
"Invalid align in virtual section!");
616-
break;
617-
case MCFragment::FT_Fill:
618-
assert((cast<MCFillFragment>(F).getValue() == 0) &&
619-
"Invalid fill in virtual section!");
620-
break;
621-
case MCFragment::FT_Org:
600+
if (F.getFixups().size() || F.getVarFixups().size()) {
601+
reportError(SMLoc(), Sec->getVirtualSectionKind() + " section '" +
602+
Sec->getName() + "' cannot have fixups");
622603
break;
623604
}
624605
}

llvm/lib/MC/MCObjectStreamer.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -279,18 +279,6 @@ bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
279279

280280
void MCObjectStreamer::emitInstruction(const MCInst &Inst,
281281
const MCSubtargetInfo &STI) {
282-
const MCSection &Sec = *getCurrentSectionOnly();
283-
if (Sec.isVirtualSection()) {
284-
getContext().reportError(Inst.getLoc(), Twine(Sec.getVirtualSectionKind()) +
285-
" section '" + Sec.getName() +
286-
"' cannot have instructions");
287-
return;
288-
}
289-
emitInstructionImpl(Inst, STI);
290-
}
291-
292-
void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst,
293-
const MCSubtargetInfo &STI) {
294282
MCStreamer::emitInstruction(Inst, STI);
295283

296284
MCSection *Sec = getCurrentSectionOnly();

llvm/lib/MC/WinCOFFObjectWriter.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ class llvm::WinCOFFWriter {
179179
void SetSymbolName(COFFSymbol &S);
180180
void SetSectionName(COFFSection &S);
181181

182-
bool IsPhysicalSection(COFFSection *S);
182+
bool isUninitializedData(const COFFSection &S);
183183

184184
// Entity writing methods.
185185
void WriteFileHeader(const COFF::header &Header);
@@ -453,8 +453,8 @@ void WinCOFFWriter::SetSymbolName(COFFSymbol &S) {
453453
std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size());
454454
}
455455

456-
bool WinCOFFWriter::IsPhysicalSection(COFFSection *S) {
457-
return (S->Header.Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) ==
456+
bool WinCOFFWriter::isUninitializedData(const COFFSection &S) {
457+
return (S.Header.Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) !=
458458
0;
459459
}
460460

@@ -606,6 +606,9 @@ void WinCOFFWriter::writeSection(const COFFSection &Sec) {
606606
assert(AuxSyms.size() == 1 && AuxSyms[0].AuxType == ATSectionDefinition);
607607
AuxSymbol &SecDef = AuxSyms[0];
608608
SecDef.Aux.SectionDefinition.CheckSum = CRC;
609+
} else if (isUninitializedData(Sec)) {
610+
// Error if fixups or non-zero bytes are present.
611+
writeSectionContents(*Sec.MCSection);
609612
}
610613

611614
// Write relocations for this section.
@@ -745,7 +748,7 @@ void WinCOFFWriter::assignFileOffsets() {
745748

746749
Sec->Header.SizeOfRawData = Asm->getSectionAddressSize(Section);
747750

748-
if (IsPhysicalSection(Sec)) {
751+
if (!isUninitializedData(*Sec)) {
749752
Sec->Header.PointerToRawData = Offset;
750753
Offset += Sec->Header.SizeOfRawData;
751754
}

llvm/test/MC/COFF/bss-text.s

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
# RUN: not llvm-mc -filetype=obj -triple=x86_64-pc-win32 %s -o /dev/null 2>&1 | FileCheck %s
1+
# RUN: not llvm-mc -filetype=obj -triple=x86_64-pc-win32 %s -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error:
22

33
## -filetype=asm does not check the error.
44
# RUN: llvm-mc -triple=x86_64-pc-win32 %s
55

6+
.bss
7+
# CHECK: <unknown>:0: error: IMAGE_SCN_CNT_UNINITIALIZED_DATA section '.bss' cannot have non-zero bytes
8+
addb %bl,(%rax)
9+
610
.section uninitialized,"b"
7-
# MCRelaxableFragment
8-
# CHECK: {{.*}}.s:[[#@LINE+1]]:3: error: IMAGE_SCN_CNT_UNINITIALIZED_DATA section 'uninitialized' cannot have instructions
11+
# CHECK: <unknown>:0: error: IMAGE_SCN_CNT_UNINITIALIZED_DATA section 'uninitialized' cannot have non-zero bytes
912
jmp foo
1013

11-
.bss
12-
# CHECK: {{.*}}.s:[[#@LINE+1]]:3: error: IMAGE_SCN_CNT_UNINITIALIZED_DATA section '.bss' cannot have instructions
14+
.section bss0,"b"
1315
addb %al,(%rax)

llvm/test/MC/COFF/section.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
.section s ; .long 1
3030
.section s_, "" ; .long 1
3131
.section s_a,"a"; .long 1
32-
.section s_b,"b"; .long 1
32+
.section s_b,"b"; .long 0
3333
.section s_d,"d"; .long 1
3434
.section s_D,"D"; .long 1
3535
.section s_n,"n"; .long 1
Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
1-
# RUN: not llvm-mc -filetype=obj -triple=x86_64 %s -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error:
1+
# RUN: not llvm-mc -filetype=obj -triple=x86_64 %s -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error: --implicit-check-not=warning:
22

33
## -filetype=asm does not check the error.
44
# RUN: llvm-mc -triple=x86_64 %s
55

66
.section .tbss,"aw",@nobits
7-
# MCRelaxableFragment
8-
# CHECK: {{.*}}.s:[[#@LINE+1]]:3: error: SHT_NOBITS section '.tbss' cannot have instructions
97
jmp foo
108

119
.bss
12-
# CHECK: {{.*}}.s:[[#@LINE+1]]:3: error: SHT_NOBITS section '.bss' cannot have instructions
1310
addb %al,(%rax)
1411

1512
# CHECK: {{.*}}.s:[[#@LINE+1]]:11: warning: ignoring non-zero fill value in SHT_NOBITS section '.bss'
1613
.align 4, 42
1714

18-
# CHECK-NOT: {{.*}}.s:[[#@LINE+1]]:11: warning: ignoring non-zero fill value in SHT_NOBITS section '.bss'
1915
.align 4, 0
2016

21-
# CHECK: <unknown>:0: error: SHT_NOBITS section '.bss' cannot have non-zero initializers
2217
.long 1
2318

19+
.section .bss0,"aw",%nobits
20+
addb %al,(%rax)
21+
2422
.section .bss1,"aw",%nobits
25-
# CHECK: <unknown>:0: error: SHT_NOBITS section '.bss1' cannot have fixups
2623
.quad foo
24+
25+
## Location is not tracked for efficiency.
26+
# CHECK: <unknown>:0: error: SHT_NOBITS section '.tbss' cannot have non-zero bytes
27+
# CHECK: <unknown>:0: error: SHT_NOBITS section '.bss' cannot have non-zero bytes
28+
# CHECK: <unknown>:0: error: SHT_NOBITS section '.bss1' cannot have fixups

0 commit comments

Comments
 (0)