summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNirav Dave <niravd@google.com>2016-06-14 15:09:30 +0000
committerNirav Dave <niravd@google.com>2016-06-14 15:09:30 +0000
commitf8d00d5cac27171abd644c227fc4302a2bdc11c6 (patch)
tree54626cfe42083f8d7b38512149c8159bac1cafbe
parent17091364d13f2436eb63ec4df484d28fcb55d976 (diff)
downloadbcm5719-llvm-f8d00d5cac27171abd644c227fc4302a2bdc11c6.tar.gz
bcm5719-llvm-f8d00d5cac27171abd644c227fc4302a2bdc11c6.zip
Fix BSS global handling in AsmPrinter
Change EmitGlobalVariable to check final assembler section is in BSS before using .lcomm/.comm directive. This prevents globals from being put into .bss erroneously when -data-sections is used. This fixes PR26570. Reviewers: echristo, rafael Subscribers: llvm-commits, mehdi_amini Differential Revision: http://reviews.llvm.org/D21146 llvm-svn: 272674
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp68
-rw-r--r--llvm/test/CodeGen/X86/global-sections.ll18
2 files changed, 51 insertions, 35 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 32f629eef74..d39881d9ce3 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -406,29 +406,42 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
HI.Handler->setSymbolSize(GVSym, Size);
}
- // Handle common and BSS local symbols (.lcomm).
- if (GVKind.isCommon() || GVKind.isBSSLocal()) {
+ // Handle common symbols
+ if (GVKind.isCommon()) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
unsigned Align = 1 << AlignLog;
+ if (!getObjFileLowering().getCommDirectiveSupportsAlignment())
+ Align = 0;
- // Handle common symbols.
- if (GVKind.isCommon()) {
- if (!getObjFileLowering().getCommDirectiveSupportsAlignment())
- Align = 0;
+ // .comm _foo, 42, 4
+ OutStreamer->EmitCommonSymbol(GVSym, Size, Align);
+ return;
+ }
- // .comm _foo, 42, 4
- OutStreamer->EmitCommonSymbol(GVSym, Size, Align);
- return;
- }
+ // Determine to which section this global should be emitted.
+ MCSection *TheSection =
+ getObjFileLowering().SectionForGlobal(GV, GVKind, *Mang, TM);
- // Handle local BSS symbols.
- if (MAI->hasMachoZeroFillDirective()) {
- MCSection *TheSection =
- getObjFileLowering().SectionForGlobal(GV, GVKind, *Mang, TM);
- // .zerofill __DATA, __bss, _foo, 400, 5
- OutStreamer->EmitZerofill(TheSection, GVSym, Size, Align);
- return;
- }
+ // If we have a bss global going to a section that supports the
+ // zerofill directive, do so here.
+ if (GVKind.isBSS() && MAI->hasMachoZeroFillDirective() &&
+ TheSection->isVirtualSection()) {
+ if (Size == 0)
+ Size = 1; // zerofill of 0 bytes is undefined.
+ unsigned Align = 1 << AlignLog;
+ EmitLinkage(GV, GVSym);
+ // .zerofill __DATA, __bss, _foo, 400, 5
+ OutStreamer->EmitZerofill(TheSection, GVSym, Size, Align);
+ return;
+ }
+
+ // If this is a BSS local symbol and we are emitting in the BSS
+ // section use .lcomm/.comm directive.
+ if (GVKind.isBSSLocal() &&
+ getObjFileLowering().getBSSSection() == TheSection) {
+ if (Size == 0)
+ Size = 1; // .comm Foo, 0 is undefined, avoid it.
+ unsigned Align = 1 << AlignLog;
// Use .lcomm only if it supports user-specified alignment.
// Otherwise, while it would still be correct to use .lcomm in some
@@ -452,23 +465,6 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
return;
}
- MCSymbol *EmittedInitSym = GVSym;
-
- MCSection *TheSection =
- getObjFileLowering().SectionForGlobal(GV, GVKind, *Mang, TM);
-
- // Handle the zerofill directive on darwin, which is a special form of BSS
- // emission.
- if (GVKind.isBSSExtern() && MAI->hasMachoZeroFillDirective()) {
- if (Size == 0) Size = 1; // zerofill of 0 bytes is undefined.
-
- // .globl _foo
- OutStreamer->EmitSymbolAttribute(GVSym, MCSA_Global);
- // .zerofill __DATA, __common, _foo, 400, 5
- OutStreamer->EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog);
- return;
- }
-
// Handle thread local data for mach-o which requires us to output an
// additional structure of data and mangle the original symbol so that we
// can reference it later.
@@ -521,6 +517,8 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
return;
}
+ MCSymbol *EmittedInitSym = GVSym;
+
OutStreamer->SwitchSection(TheSection);
EmitLinkage(GV, EmittedInitSym);
diff --git a/llvm/test/CodeGen/X86/global-sections.ll b/llvm/test/CodeGen/X86/global-sections.ll
index ef1b1ac7524..ea6df468ceb 100644
--- a/llvm/test/CodeGen/X86/global-sections.ll
+++ b/llvm/test/CodeGen/X86/global-sections.ll
@@ -311,3 +311,21 @@ bb7:
; WIN32-SECTIONS: .section .rdata,"dr",one_only,_G16
; WIN32-SECTIONS: _G16:
+
+; PR26570
+
+@G17 = internal global i8 0
+; LINUX: .type G17,@object
+; LINUX: .local G17
+; LINUX: .comm G17,1,1
+
+; DARWIN: .zerofill __DATA,__bss,_G17,1,0
+
+; LINUX-SECTIONS: .type G17,@object
+; LINUX-SECTIONS: .section .bss.G17,"aw",@nobits
+; LINUX-SECTIONS: .byte 0
+; LINUX-SECTIONS: .size G17, 1
+
+; WIN32-SECTIONS: .section .bss,"bw",one_only,_G17
+; WIN32-SECTIONS: _G17:
+; WIN32-SECTIONS:.byte 0
OpenPOWER on IntegriCloud