Cleanup handling of .zerofill on darwin:
authorChris Lattner <sabre@nondot.org>
Tue, 19 Jan 2010 02:09:44 +0000 (02:09 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 19 Jan 2010 02:09:44 +0000 (02:09 +0000)
1. TargetLoweringObjectFileMachO should decide if something
   goes in zerofill instead of having every target do it.
2. TargetLoweringObjectFileMachO should assign said symbols to
   the right MCSection, the asmprinters should just emit to the
   right section.
3. Since all zerofill stuff goes through mcstreamer anymore,
   MAI can have a bool "haszerofill" instead of having the textual
   directive to emit.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93838 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCAsmInfo.h
include/llvm/Target/TargetLoweringObjectFile.h
lib/MC/MCAsmInfo.cpp
lib/MC/MCAsmInfoDarwin.cpp
lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
lib/Target/TargetLoweringObjectFile.cpp
lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp

index 1d90feb09b9eafdd49444c2ac63af4d07613a915..6d01278711faac103bf27828bd9e618ff3d5d0b2 100644 (file)
@@ -29,15 +29,15 @@ namespace llvm {
     // Properties to be set by the target writer, used to configure asm printer.
     //
 
-    /// ZeroFillDirective - Directive for emitting a global to the ZeroFill
-    /// section on this target.  Null if this target doesn't support zerofill.
-    const char *ZeroFillDirective;           // Default is null.
-
     /// NonexecutableStackDirective - Directive for declaring to the
     /// linker and beyond that the emitted code does not require stack
     /// memory to be executable.
     const char *NonexecutableStackDirective; // Default is null.
 
+    /// HasMachoZeroFillDirective - True if this is a MachO target that supports
+    /// the macho-specific .zerofill directive for emitting BSS Symbols.
+    bool HasMachoZeroFillDirective;           // Default is false.
+    
     /// NeedsSet - True if target asm treats expressions in data directives
     /// as linktime-relocatable.  For assembly-time computation, we need to
     /// use a .set.  Thus:
@@ -313,10 +313,7 @@ namespace llvm {
 
     // Accessors.
     //
-    const char *getZeroFillDirective() const {
-      return ZeroFillDirective;
-    }
-    bool hasZeroFillDirective() const { return ZeroFillDirective != 0; }
+    bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; }
     
     const char *getNonexecutableStackDirective() const {
       return NonexecutableStackDirective;
index 3dd747175b412beb35714c15056fc0fd585c6a67..fec56fa442cbcb8bb83bdc1ec6a77128959e4822 100644 (file)
@@ -258,6 +258,7 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
   const MCSection *ConstDataCoalSection;
   const MCSection *ConstDataSection;
   const MCSection *DataCoalSection;
+  const MCSection *DataCommonSection;
   const MCSection *FourByteConstantSection;
   const MCSection *EightByteConstantSection;
   const MCSection *SixteenByteConstantSection;
@@ -312,6 +313,12 @@ public:
     return ConstTextCoalSection;
   }
   
+  /// getDataCommonSection - Return the "__DATA,__common" section we put
+  /// zerofill (aka bss) data into.
+  const MCSection *getDataCommonSection() const {
+    return DataCommonSection;
+  }
+  
   /// getLazySymbolPointerSection - Return the section corresponding to
   /// the .lazy_symbol_pointer directive.
   const MCSection *getLazySymbolPointerSection() const {
index 3e5c97d7aa7a40f716881305683f440534d29234..6e8cd0ce8d758c76d0ca7ae9e3fcacf01c258241 100644 (file)
@@ -19,7 +19,7 @@
 using namespace llvm;
 
 MCAsmInfo::MCAsmInfo() {
-  ZeroFillDirective = 0;
+  HasMachoZeroFillDirective = false;
   NonexecutableStackDirective = 0;
   NeedsSet = false;
   MaxInstLength = 4;
index d99120d4d7888f7ffab4f3503f2bf80c2fb4c3e1..8719bee89bfb7bd5dbdd5b0d2b9bf46d72c3733e 100644 (file)
@@ -35,7 +35,7 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
   HiddenDirective = "\t.private_extern ";
   LCOMMDirective = "\t.lcomm\t";
   ZeroDirective = "\t.space\t";  // ".space N" emits N zeros.
-  ZeroFillDirective = "\t.zerofill\t";  // Uses .zerofill
+  HasMachoZeroFillDirective = true;  // Uses .zerofill
   SetDirective = "\t.set";
   ProtectedDirective = "\t.globl\t";
   HasDotTypeDotSizeDirective = false;
index ef2d460fab77c5bb0894df09da3c4cfa3f777665..30f9fec867ecd9a485020021282ded3cccfedbfa 100644 (file)
@@ -1196,71 +1196,76 @@ void ARMAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
   if (Subtarget->isTargetELF())
     O << "\t.type " << *GVarSym << ",%object\n";
 
+  SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
   const MCSection *TheSection =
-    getObjFileLowering().SectionForGlobal(GVar, Mang, TM);
+    getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
   OutStreamer.SwitchSection(TheSection);
 
+  // Handle the zerofill directive on darwin, which is a special form of BSS
+  // emission.
+  if (GVKind.isBSS() && MAI->hasMachoZeroFillDirective()) {
+    TargetLoweringObjectFileMachO &TLOFMacho = 
+    static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering());
+    if (TheSection == TLOFMacho.getDataCommonSection()) {
+      // .globl _foo
+      OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
+      // .zerofill __DATA, __common, _foo, 400, 5
+      OutStreamer.EmitZerofill(TheSection, GVarSym, Size, 1 << Align);
+      return;
+    }
+  }
+  
   // FIXME: get this stuff from section kind flags.
   if (C->isNullValue() && !GVar->hasSection() && !GVar->isThreadLocal() &&
       // Don't put things that should go in the cstring section into "comm".
-      !TheSection->getKind().isMergeableCString()) {
-    if (GVar->hasExternalLinkage()) {
-      if (const char *Directive = MAI->getZeroFillDirective()) {
-        O << "\t.globl\t" << *GVarSym << "\n";
-        O << Directive << "__DATA, __common, " << *GVarSym
-          << ", " << Size << ", " << Align << "\n";
-        return;
-      }
-    }
+      !TheSection->getKind().isMergeableCString() &&
+      (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
+    if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
 
-    if (GVar->hasLocalLinkage() || GVar->isWeakForLinker()) {
-      if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
-
-      if (isDarwin) {
-        if (GVar->hasLocalLinkage()) {
-          O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size
-            << ',' << Align;
-        } else if (GVar->hasCommonLinkage()) {
-          O << MAI->getCOMMDirective() << *GVarSym << ',' << Size
-            << ',' << Align;
-        } else {
-          OutStreamer.SwitchSection(TheSection);
-          O << "\t.globl " << *GVarSym << '\n' << MAI->getWeakDefDirective();
-          O << *GVarSym << '\n';
-          EmitAlignment(Align, GVar);
-          O << *GVarSym << ":";
-          if (VerboseAsm) {
-            O.PadToColumn(MAI->getCommentColumn());
-            O << MAI->getCommentString() << ' ';
-            WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
-          }
-          O << '\n';
-          EmitGlobalConstant(C);
-          return;
-        }
-      } else if (MAI->getLCOMMDirective() != NULL) {
-        if (GVar->hasLocalLinkage()) {
-          O << MAI->getLCOMMDirective() << *GVarSym << "," << Size;
-        } else {
-          O << MAI->getCOMMDirective() << *GVarSym << "," << Size;
-          if (MAI->getCOMMDirectiveTakesAlignment())
-            O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
+    if (isDarwin) {
+      if (GVar->hasLocalLinkage()) {
+        O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size
+          << ',' << Align;
+      } else if (GVar->hasCommonLinkage()) {
+        O << MAI->getCOMMDirective() << *GVarSym << ',' << Size
+          << ',' << Align;
+      } else {
+        OutStreamer.SwitchSection(TheSection);
+        O << "\t.globl " << *GVarSym << '\n' << MAI->getWeakDefDirective();
+        O << *GVarSym << '\n';
+        EmitAlignment(Align, GVar);
+        O << *GVarSym << ":";
+        if (VerboseAsm) {
+          O.PadToColumn(MAI->getCommentColumn());
+          O << MAI->getCommentString() << ' ';
+          WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
         }
+        O << '\n';
+        EmitGlobalConstant(C);
+        return;
+      }
+    } else if (MAI->getLCOMMDirective() != NULL) {
+      if (GVar->hasLocalLinkage()) {
+        O << MAI->getLCOMMDirective() << *GVarSym << "," << Size;
       } else {
-        if (GVar->hasLocalLinkage())
-          O << "\t.local\t" << *GVarSym << '\n';
         O << MAI->getCOMMDirective() << *GVarSym << "," << Size;
         if (MAI->getCOMMDirectiveTakesAlignment())
-          O << "," << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
-      }
-      if (VerboseAsm) {
-        O.PadToColumn(MAI->getCommentColumn());
-        O << MAI->getCommentString() << ' ';
-        WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
+          O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
       }
-      O << "\n";
-      return;
+    } else {
+      if (GVar->hasLocalLinkage())
+        O << "\t.local\t" << *GVarSym << '\n';
+      O << MAI->getCOMMDirective() << *GVarSym << "," << Size;
+      if (MAI->getCOMMDirectiveTakesAlignment())
+        O << "," << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
+    }
+    if (VerboseAsm) {
+      O.PadToColumn(MAI->getCommentColumn());
+      O << MAI->getCommentString() << ' ';
+      WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
     }
+    O << "\n";
+    return;
   }
 
   switch (GVar->getLinkage()) {
index db37a1ab66025042a8d836ccf1bcdeb89f36cd13..fad1c27fac65493a6e5bce0dfc0441e182cb10f9 100644 (file)
@@ -721,25 +721,25 @@ void PPCLinuxAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
       !GVar->hasSection() &&
       (GVar->hasLocalLinkage() || GVar->hasExternalLinkage() ||
        GVar->isWeakForLinker())) {
-      if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
-
-      if (GVar->hasExternalLinkage()) {
-        O << "\t.global " << *GVarSym << '\n';
-        O << "\t.type " << *GVarSym << ", @object\n";
-        O << *GVarSym << ":\n";
-        O << "\t.zero " << Size << '\n';
-      } else if (GVar->hasLocalLinkage()) {
-        O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size;
-      } else {
-        O << ".comm " << *GVarSym << ',' << Size;
-      }
-      if (VerboseAsm) {
-        O << "\t\t" << MAI->getCommentString() << " '";
-        WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
-        O << "'";
-      }
-      O << '\n';
-      return;
+    if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
+
+    if (GVar->hasExternalLinkage()) {
+      O << "\t.global " << *GVarSym << '\n';
+      O << "\t.type " << *GVarSym << ", @object\n";
+      O << *GVarSym << ":\n";
+      O << "\t.zero " << Size << '\n';
+    } else if (GVar->hasLocalLinkage()) {
+      O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size;
+    } else {
+      O << ".comm " << *GVarSym << ',' << Size;
+    }
+    if (VerboseAsm) {
+      O << "\t\t" << MAI->getCommentString() << " '";
+      WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
+      O << "'";
+    }
+    O << '\n';
+    return;
   }
 
   switch (GVar->getLinkage()) {
@@ -944,10 +944,25 @@ void PPCDarwinAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
   unsigned Size = TD->getTypeAllocSize(Type);
   unsigned Align = TD->getPreferredAlignmentLog(GVar);
 
+  SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
   const MCSection *TheSection =
-    getObjFileLowering().SectionForGlobal(GVar, Mang, TM);
+    getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
   OutStreamer.SwitchSection(TheSection);
 
+  // Handle the zerofill directive on darwin, which is a special form of BSS
+  // emission.
+  if (GVKind.isBSS() && MAI->hasMachoZeroFillDirective()) {
+    TargetLoweringObjectFileMachO &TLOFMacho = 
+    static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering());
+    if (TheSection == TLOFMacho.getDataCommonSection()) {
+      // .globl _foo
+      OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
+      // .zerofill __DATA, __common, _foo, 400, 5
+      OutStreamer.EmitZerofill(TheSection, GVarSym, Size, 1 << Align);
+      return;
+    }
+  }
+  
   /// FIXME: Drive this off the section!
   if (C->isNullValue() && /* FIXME: Verify correct */
       !GVar->hasSection() &&
@@ -957,11 +972,7 @@ void PPCDarwinAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
       !TheSection->getKind().isMergeableCString()) {
     if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
 
-    if (GVar->hasExternalLinkage()) {
-      O << "\t.globl " << *GVarSym << '\n';
-      O << "\t.zerofill __DATA, __common, " << *GVarSym << ", "
-        << Size << ", " << Align;
-    } else if (GVar->hasLocalLinkage()) {
+    if (GVar->hasLocalLinkage()) {
       O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size << ',' << Align;
     } else if (!GVar->hasCommonLinkage()) {
       O << "\t.globl " << *GVarSym << '\n' << MAI->getWeakDefDirective();
index 93cb420d6285e06251ce990859ff4f0ad384bd13..26a181aea0db80cad6227b54f9969433017864f0 100644 (file)
@@ -750,6 +750,9 @@ void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx,
   ConstDataCoalSection
     = getMachOSection("__DATA","__const_coal", MCSectionMachO::S_COALESCED,
                       SectionKind::getText());
+  DataCommonSection
+    = getMachOSection("__DATA","__common", MCSectionMachO::S_ZEROFILL,
+                      SectionKind::getBSS());
   ConstDataSection  // .const_data
     = getMachOSection("__DATA", "__const", 0,
                       SectionKind::getReadOnlyWithRel());
@@ -915,6 +918,11 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
   if (Kind.isReadOnlyWithRel())
     return ConstDataSection;
 
+  // Put zero initialized globals with strong external linkage in the
+  // DATA, __common section with the .zerofill directive.
+  if (Kind.isBSS() && GV->hasExternalLinkage())
+    return DataCommonSection;
+  
   // Otherwise, just drop the variable in the normal data section.
   return DataSection;
 }
index a24a4f1746dafe300932209322585560ae4ea166..3c290e8efd3c9f9ef50f9a6fc7e384306f86928b 100644 (file)
@@ -664,88 +664,83 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
   
   const TargetData *TD = TM.getTargetData();
 
-  MCSymbol *GVSym = GetGlobalValueSymbol(GVar);
+  MCSymbol *GVarSym = GetGlobalValueSymbol(GVar);
   Constant *C = GVar->getInitializer();
   const Type *Type = C->getType();
   unsigned Size = TD->getTypeAllocSize(Type);
   unsigned Align = TD->getPreferredAlignmentLog(GVar);
 
-  printVisibility(GVSym, GVar->getVisibility());
+  printVisibility(GVarSym, GVar->getVisibility());
 
   if (Subtarget->isTargetELF())
-    O << "\t.type\t" << *GVSym << ",@object\n";
+    O << "\t.type\t" << *GVarSym << ",@object\n";
   
   SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
   const MCSection *TheSection =
     getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
   OutStreamer.SwitchSection(TheSection);
 
+  // Handle the zerofill directive on darwin, which is a special form of BSS
+  // emission.
+  if (GVKind.isBSS() && MAI->hasMachoZeroFillDirective()) {
+    TargetLoweringObjectFileMachO &TLOFMacho = 
+      static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering());
+    if (TheSection == TLOFMacho.getDataCommonSection()) {
+      // .globl _foo
+      OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
+      // .zerofill __DATA, __common, _foo, 400, 5
+      OutStreamer.EmitZerofill(TheSection, GVarSym, Size, 1 << Align);
+      return;
+    }
+  }
+  
   // FIXME: get this stuff from section kind flags.
   if (C->isNullValue() && !GVar->hasSection() &&
       // Don't put things that should go in the cstring section into "comm".
-      !TheSection->getKind().isMergeableCString()) {
-    if (GVar->hasExternalLinkage()) {
-      if (MAI->hasZeroFillDirective()) {
-        // .globl _foo
-        OutStreamer.EmitSymbolAttribute(GVSym, MCStreamer::Global);
-        // .zerofill __DATA, __common, _foo, 400, 5
-        TargetLoweringObjectFileMachO &TLOFMacho = 
-          static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering());
-        // FIXME: This stuff should already be handled by SectionForGlobal!
-        const MCSection *TheSection = 
-          TLOFMacho.getMachOSection("__DATA", "__common",
-                                    MCSectionMachO::S_ZEROFILL,
-                                    SectionKind::getBSS());
-          
-        OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << Align);
-        return;
-      }
-    }
-
-    if (!GVar->isThreadLocal() &&
-        (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
-      if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
-
-      if (MAI->getLCOMMDirective() != NULL) {
-        if (GVar->hasLocalLinkage()) {
-          O << MAI->getLCOMMDirective() << *GVSym << ',' << Size;
-          if (Subtarget->isTargetDarwin())
-            O << ',' << Align;
-        } else if (Subtarget->isTargetDarwin() && !GVar->hasCommonLinkage()) {
-          OutStreamer.EmitSymbolAttribute(GVSym, MCStreamer::Global);
-          O << MAI->getWeakDefDirective() << *GVSym << '\n';
-          EmitAlignment(Align, GVar);
-          O << *GVSym << ":";
-          if (VerboseAsm) {
-            O.PadToColumn(MAI->getCommentColumn());
-            O << MAI->getCommentString() << ' ';
-            WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
-          }
-          O << '\n';
-          EmitGlobalConstant(C);
-          return;
-        } else {
-          O << MAI->getCOMMDirective() << *GVSym << ',' << Size;
-          if (MAI->getCOMMDirectiveTakesAlignment())
-            O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
+      !TheSection->getKind().isMergeableCString() &&
+      !GVar->isThreadLocal() &&
+      (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
+    if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
+
+    if (const char *LComm = MAI->getLCOMMDirective()) {
+      if (GVar->hasLocalLinkage()) {
+        O << LComm << *GVarSym << ',' << Size;
+        if (Subtarget->isTargetDarwin())
+          O << ',' << Align;
+      } else if (Subtarget->isTargetDarwin() && !GVar->hasCommonLinkage()) {
+        OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
+        O << MAI->getWeakDefDirective() << *GVarSym << '\n';
+        EmitAlignment(Align, GVar);
+        O << *GVarSym << ":";
+        if (VerboseAsm) {
+          O.PadToColumn(MAI->getCommentColumn());
+          O << MAI->getCommentString() << ' ';
+          WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
         }
+        O << '\n';
+        EmitGlobalConstant(C);
+        return;
       } else {
-        if (!Subtarget->isTargetCygMing()) {
-          if (GVar->hasLocalLinkage())
-            O << "\t.local\t" << *GVSym << '\n';
-        }
-        O << MAI->getCOMMDirective() << *GVSym << ',' << Size;
+        O << MAI->getCOMMDirective() << *GVarSym << ',' << Size;
         if (MAI->getCOMMDirectiveTakesAlignment())
           O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
       }
-      if (VerboseAsm) {
-        O.PadToColumn(MAI->getCommentColumn());
-        O << MAI->getCommentString() << ' ';
-        WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
+    } else {
+      if (!Subtarget->isTargetCygMing()) {
+        if (GVar->hasLocalLinkage())
+          O << "\t.local\t" << *GVarSym << '\n';
       }
-      O << '\n';
-      return;
+      O << MAI->getCOMMDirective() << *GVarSym << ',' << Size;
+      if (MAI->getCOMMDirectiveTakesAlignment())
+        O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
+    }
+    if (VerboseAsm) {
+      O.PadToColumn(MAI->getCommentColumn());
+      O << MAI->getCommentString() << ' ';
+      WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
     }
+    O << '\n';
+    return;
   }
 
   switch (GVar->getLinkage()) {
@@ -756,13 +751,13 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
   case GlobalValue::WeakODRLinkage:
   case GlobalValue::LinkerPrivateLinkage:
     if (Subtarget->isTargetDarwin()) {
-      OutStreamer.EmitSymbolAttribute(GVSym, MCStreamer::Global);
-      O << MAI->getWeakDefDirective() << *GVSym << '\n';
+      OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
+      O << MAI->getWeakDefDirective() << *GVarSym << '\n';
     } else if (Subtarget->isTargetCygMing()) {
-      OutStreamer.EmitSymbolAttribute(GVSym, MCStreamer::Global);
+      OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
       O << "\t.linkonce same_size\n";
     } else
-      O << "\t.weak\t" << *GVSym << '\n';
+      O << "\t.weak\t" << *GVarSym << '\n';
     break;
   case GlobalValue::DLLExportLinkage:
   case GlobalValue::AppendingLinkage:
@@ -770,7 +765,7 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
     // their name or something.  For now, just emit them as external.
   case GlobalValue::ExternalLinkage:
     // If external or appending, declare as a global symbol
-    OutStreamer.EmitSymbolAttribute(GVSym, MCStreamer::Global);
+    OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
     break;
   case GlobalValue::PrivateLinkage:
   case GlobalValue::InternalLinkage:
@@ -780,7 +775,7 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
   }
 
   EmitAlignment(Align, GVar);
-  O << *GVSym << ":";
+  O << *GVarSym << ":";
   if (VerboseAsm){
     O.PadToColumn(MAI->getCommentColumn());
     O << MAI->getCommentString() << ' ';
@@ -791,7 +786,7 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
   EmitGlobalConstant(C);
 
   if (MAI->hasDotTypeDotSizeDirective())
-    O << "\t.size\t" << *GVSym << ", " << Size << '\n';
+    O << "\t.size\t" << *GVarSym << ", " << Size << '\n';
 }
 
 void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {