diff options
author | Nirav Dave <niravd@google.com> | 2016-06-14 15:09:30 +0000 |
---|---|---|
committer | Nirav Dave <niravd@google.com> | 2016-06-14 15:09:30 +0000 |
commit | f8d00d5cac27171abd644c227fc4302a2bdc11c6 (patch) | |
tree | 54626cfe42083f8d7b38512149c8159bac1cafbe | |
parent | 17091364d13f2436eb63ec4df484d28fcb55d976 (diff) | |
download | bcm5719-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.cpp | 68 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/global-sections.ll | 18 |
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 |