diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp
new file mode 100644
index 0000000..b1d9c9a
--- /dev/null
+++ b/lib/Target/TargetLoweringObjectFile.cpp
@@ -0,0 +1,647 @@
+//===-- llvm/Target/TargetLoweringObjectFile.cpp - Object File Info -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements classes used to handle lowerings specific to common
+// object file formats.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/ADT/StringExtras.h"
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+//                              Generic Code
+//===----------------------------------------------------------------------===//
+
+TargetLoweringObjectFile::TargetLoweringObjectFile() {
+  TextSection = 0;
+  DataSection = 0;
+  BSSSection_ = 0;
+  ReadOnlySection = 0;
+  TLSDataSection = 0;
+  TLSBSSSection = 0;
+  CStringSection_ = 0;
+}
+
+TargetLoweringObjectFile::~TargetLoweringObjectFile() {
+}
+
+static bool isSuitableForBSS(const GlobalVariable *GV) {
+  Constant *C = GV->getInitializer();
+  
+  // Must have zero initializer.
+  if (!C->isNullValue())
+    return false;
+  
+  // Leave constant zeros in readonly constant sections, so they can be shared.
+  if (GV->isConstant())
+    return false;
+  
+  // If the global has an explicit section specified, don't put it in BSS.
+  if (!GV->getSection().empty())
+    return false;
+  
+  // If -nozero-initialized-in-bss is specified, don't ever use BSS.
+  if (NoZerosInBSS)
+    return false;
+  
+  // Otherwise, put it in BSS!
+  return true;
+}
+
+static bool isConstantString(const Constant *C) {
+  // First check: is we have constant array of i8 terminated with zero
+  const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
+  // Check, if initializer is a null-terminated string
+  if (CVA && CVA->isCString())
+    return true;
+
+  // Another possibility: [1 x i8] zeroinitializer
+  if (isa<ConstantAggregateZero>(C))
+    if (const ArrayType *Ty = dyn_cast<ArrayType>(C->getType()))
+      return (Ty->getElementType() == Type::Int8Ty &&
+              Ty->getNumElements() == 1);
+
+  return false;
+}
+
+static SectionKind::Kind SectionKindForGlobal(const GlobalValue *GV,
+                                              const TargetMachine &TM) {
+  Reloc::Model ReloModel = TM.getRelocationModel();
+  
+  // Early exit - functions should be always in text sections.
+  const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
+  if (GVar == 0)
+    return SectionKind::Text;
+
+  
+  // Handle thread-local data first.
+  if (GVar->isThreadLocal()) {
+    if (isSuitableForBSS(GVar))
+      return SectionKind::ThreadBSS;
+    return SectionKind::ThreadData;
+  }
+
+  // Variable can be easily put to BSS section.
+  if (isSuitableForBSS(GVar))
+    return SectionKind::BSS;
+
+  Constant *C = GVar->getInitializer();
+  
+  // If the global is marked constant, we can put it into a mergable section,
+  // a mergable string section, or general .data if it contains relocations.
+  if (GVar->isConstant()) {
+    // If the initializer for the global contains something that requires a
+    // relocation, then we may have to drop this into a wriable data section
+    // even though it is marked const.
+    switch (C->getRelocationInfo()) {
+    default: llvm_unreachable("unknown relocation info kind");
+    case Constant::NoRelocation:
+      // If initializer is a null-terminated string, put it in a "cstring"
+      // section if the target has it.
+      if (isConstantString(C))
+        return SectionKind::MergeableCString;
+      
+      // Otherwise, just drop it into a mergable constant section.  If we have
+      // a section for this size, use it, otherwise use the arbitrary sized
+      // mergable section.
+      switch (TM.getTargetData()->getTypeAllocSize(C->getType())) {
+      case 4:  return SectionKind::MergeableConst4;
+      case 8:  return SectionKind::MergeableConst8;
+      case 16: return SectionKind::MergeableConst16;
+      default: return SectionKind::MergeableConst;
+      }
+      
+    case Constant::LocalRelocation:
+      // In static relocation model, the linker will resolve all addresses, so
+      // the relocation entries will actually be constants by the time the app
+      // starts up.  However, we can't put this into a mergable section, because
+      // the linker doesn't take relocations into consideration when it tries to
+      // merge entries in the section.
+      if (ReloModel == Reloc::Static)
+        return SectionKind::ReadOnly;
+              
+      // Otherwise, the dynamic linker needs to fix it up, put it in the
+      // writable data.rel.local section.
+      return SectionKind::ReadOnlyWithRelLocal;
+              
+    case Constant::GlobalRelocations:
+      // In static relocation model, the linker will resolve all addresses, so
+      // the relocation entries will actually be constants by the time the app
+      // starts up.  However, we can't put this into a mergable section, because
+      // the linker doesn't take relocations into consideration when it tries to
+      // merge entries in the section.
+      if (ReloModel == Reloc::Static)
+        return SectionKind::ReadOnly;
+      
+      // Otherwise, the dynamic linker needs to fix it up, put it in the
+      // writable data.rel section.
+      return SectionKind::ReadOnlyWithRel;
+    }
+  }
+
+  // Okay, this isn't a constant.  If the initializer for the global is going
+  // to require a runtime relocation by the dynamic linker, put it into a more
+  // specific section to improve startup time of the app.  This coalesces these
+  // globals together onto fewer pages, improving the locality of the dynamic
+  // linker.
+  if (ReloModel == Reloc::Static)
+    return SectionKind::DataNoRel;
+
+  switch (C->getRelocationInfo()) {
+  default: llvm_unreachable("unknown relocation info kind");
+  case Constant::NoRelocation:
+    return SectionKind::DataNoRel;
+  case Constant::LocalRelocation:
+    return SectionKind::DataRelLocal;
+  case Constant::GlobalRelocations:
+    return SectionKind::DataRel;
+  }
+}
+
+/// SectionForGlobal - This method computes the appropriate section to emit
+/// the specified global variable or function definition.  This should not
+/// be passed external (or available externally) globals.
+const Section *TargetLoweringObjectFile::
+SectionForGlobal(const GlobalValue *GV, const TargetMachine &TM) const {
+  assert(!GV->isDeclaration() && !GV->hasAvailableExternallyLinkage() &&
+         "Can only be used for global definitions");
+  
+  SectionKind::Kind GVKind = SectionKindForGlobal(GV, TM);
+  
+  SectionKind Kind = SectionKind::get(GVKind, GV->isWeakForLinker(),
+                                      GV->hasSection());
+
+
+  // Select section name.
+  if (GV->hasSection()) {
+    // If the target has special section hacks for specifically named globals,
+    // return them now.
+    if (const Section *TS = getSpecialCasedSectionGlobals(GV, Kind))
+      return TS;
+    
+    // If the target has magic semantics for certain section names, make sure to
+    // pick up the flags.  This allows the user to write things with attribute
+    // section and still get the appropriate section flags printed.
+    GVKind = getKindForNamedSection(GV->getSection().c_str(), GVKind);
+    
+    return getOrCreateSection(GV->getSection().c_str(), false, GVKind);
+  }
+
+  
+  // Use default section depending on the 'type' of global
+  return SelectSectionForGlobal(GV, Kind, TM);
+}
+
+// Lame default implementation. Calculate the section name for global.
+const Section*
+TargetLoweringObjectFile::SelectSectionForGlobal(const GlobalValue *GV,
+                                                 SectionKind Kind,
+                                                 const TargetMachine &TM) const{
+  assert(!Kind.isThreadLocal() && "Doesn't support TLS");
+  
+  if (Kind.isText())
+    return getTextSection();
+  
+  if (Kind.isBSS() && BSSSection_ != 0)
+    return BSSSection_;
+  
+  if (Kind.isReadOnly() && ReadOnlySection != 0)
+    return ReadOnlySection;
+
+  return getDataSection();
+}
+
+/// getSectionForMergableConstant - Given a mergable constant with the
+/// specified size and relocation information, return a section that it
+/// should be placed in.
+const Section *
+TargetLoweringObjectFile::
+getSectionForMergeableConstant(SectionKind Kind) const {
+  if (Kind.isReadOnly() && ReadOnlySection != 0)
+    return ReadOnlySection;
+  
+  return DataSection;
+}
+
+
+const Section *TargetLoweringObjectFile::
+getOrCreateSection(const char *Name, bool isDirective,
+                   SectionKind::Kind Kind) const {
+  Section &S = Sections[Name];
+
+  // This is newly-created section, set it up properly.
+  if (S.Name.empty()) {
+    S.Kind = SectionKind::get(Kind, false /*weak*/, !isDirective);
+    S.Name = Name;
+  }
+
+  return &S;
+}
+
+
+
+//===----------------------------------------------------------------------===//
+//                                  ELF
+//===----------------------------------------------------------------------===//
+
+TargetLoweringObjectFileELF::TargetLoweringObjectFileELF(bool atIsCommentChar,
+                                                         bool HasCrazyBSS)
+  : AtIsCommentChar(atIsCommentChar) {
+    
+  if (!HasCrazyBSS)
+    BSSSection_ = getOrCreateSection("\t.bss", true, SectionKind::BSS);
+  else
+    // PPC/Linux doesn't support the .bss directive, it needs .section .bss.
+    // FIXME: Does .section .bss work everywhere??
+    BSSSection_ = getOrCreateSection("\t.bss", false, SectionKind::BSS);
+
+    
+  TextSection = getOrCreateSection("\t.text", true, SectionKind::Text);
+  DataSection = getOrCreateSection("\t.data", true, SectionKind::DataRel);
+  ReadOnlySection =
+    getOrCreateSection("\t.rodata", false, SectionKind::ReadOnly);
+  TLSDataSection =
+    getOrCreateSection("\t.tdata", false, SectionKind::ThreadData);
+  CStringSection_ = getOrCreateSection("\t.rodata.str", true,
+                                       SectionKind::MergeableCString);
+
+  TLSBSSSection = getOrCreateSection("\t.tbss", false, SectionKind::ThreadBSS);
+
+  DataRelSection = getOrCreateSection("\t.data.rel", false,
+                                      SectionKind::DataRel);
+  DataRelLocalSection = getOrCreateSection("\t.data.rel.local", false,
+                                           SectionKind::DataRelLocal);
+  DataRelROSection = getOrCreateSection("\t.data.rel.ro", false,
+                                        SectionKind::ReadOnlyWithRel);
+  DataRelROLocalSection =
+    getOrCreateSection("\t.data.rel.ro.local", false,
+                       SectionKind::ReadOnlyWithRelLocal);
+    
+  MergeableConst4Section = getOrCreateSection(".rodata.cst4", false,
+                                              SectionKind::MergeableConst4);
+  MergeableConst8Section = getOrCreateSection(".rodata.cst8", false,
+                                              SectionKind::MergeableConst8);
+  MergeableConst16Section = getOrCreateSection(".rodata.cst16", false,
+                                               SectionKind::MergeableConst16);
+}
+
+
+SectionKind::Kind TargetLoweringObjectFileELF::
+getKindForNamedSection(const char *Name, SectionKind::Kind K) const {
+  if (Name[0] != '.') return K;
+  
+  // Some lame default implementation based on some magic section names.
+  if (strncmp(Name, ".gnu.linkonce.b.", 16) == 0 ||
+      strncmp(Name, ".llvm.linkonce.b.", 17) == 0 ||
+      strncmp(Name, ".gnu.linkonce.sb.", 17) == 0 ||
+      strncmp(Name, ".llvm.linkonce.sb.", 18) == 0)
+    return SectionKind::BSS;
+  
+  if (strcmp(Name, ".tdata") == 0 ||
+      strncmp(Name, ".tdata.", 7) == 0 ||
+      strncmp(Name, ".gnu.linkonce.td.", 17) == 0 ||
+      strncmp(Name, ".llvm.linkonce.td.", 18) == 0)
+    return SectionKind::ThreadData;
+  
+  if (strcmp(Name, ".tbss") == 0 ||
+      strncmp(Name, ".tbss.", 6) == 0 ||
+      strncmp(Name, ".gnu.linkonce.tb.", 17) == 0 ||
+      strncmp(Name, ".llvm.linkonce.tb.", 18) == 0)
+    return SectionKind::ThreadBSS;
+  
+  return K;
+}
+
+void TargetLoweringObjectFileELF::
+getSectionFlagsAsString(SectionKind Kind, SmallVectorImpl<char> &Str) const {
+  Str.push_back(',');
+  Str.push_back('"');
+  
+  if (!Kind.isMetadata())
+    Str.push_back('a');
+  if (Kind.isText())
+    Str.push_back('x');
+  if (Kind.isWriteable())
+    Str.push_back('w');
+  if (Kind.isMergeableConst() || Kind.isMergeableCString())
+    Str.push_back('M');
+  if (Kind.isMergeableCString())
+    Str.push_back('S');
+  if (Kind.isThreadLocal())
+    Str.push_back('T');
+  
+  Str.push_back('"');
+  Str.push_back(',');
+  
+  // If comment string is '@', e.g. as on ARM - use '%' instead
+  if (AtIsCommentChar)
+    Str.push_back('%');
+  else
+    Str.push_back('@');
+  
+  const char *KindStr;
+  if (Kind.isBSS())
+    KindStr = "nobits";
+  else
+    KindStr = "progbits";
+  
+  Str.append(KindStr, KindStr+strlen(KindStr));
+  
+  if (Kind.isMergeableCString()) {
+    // TODO: Eventually handle multiple byte character strings.  For now, all
+    // mergable C strings are single byte.
+    Str.push_back(',');
+    Str.push_back('1');
+  } else if (Kind.isMergeableConst4()) {
+    Str.push_back(',');
+    Str.push_back('4');
+  } else if (Kind.isMergeableConst8()) {
+    Str.push_back(',');
+    Str.push_back('8');
+  } else if (Kind.isMergeableConst16()) {
+    Str.push_back(',');
+    Str.push_back('1');
+    Str.push_back('6');
+  }
+}
+
+
+static const char *getSectionPrefixForUniqueGlobal(SectionKind Kind) {
+  if (Kind.isText())                 return ".gnu.linkonce.t.";
+  if (Kind.isReadOnly())             return ".gnu.linkonce.r.";
+  
+  if (Kind.isThreadData())           return ".gnu.linkonce.td.";
+  if (Kind.isThreadBSS())            return ".gnu.linkonce.tb.";
+  
+  if (Kind.isBSS())                  return ".gnu.linkonce.b.";
+  if (Kind.isDataNoRel())            return ".gnu.linkonce.d.";
+  if (Kind.isDataRelLocal())         return ".gnu.linkonce.d.rel.local.";
+  if (Kind.isDataRel())              return ".gnu.linkonce.d.rel.";
+  if (Kind.isReadOnlyWithRelLocal()) return ".gnu.linkonce.d.rel.ro.local.";
+  
+  assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
+  return ".gnu.linkonce.d.rel.ro.";
+}
+
+const Section *TargetLoweringObjectFileELF::
+SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+                       const TargetMachine &TM) const {
+  
+  // If this global is linkonce/weak and the target handles this by emitting it
+  // into a 'uniqued' section name, create and return the section now.
+  if (Kind.isWeak()) {
+    const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
+    // FIXME: Use mangler interface (PR4584).
+    std::string Name = Prefix+GV->getNameStr();
+    return getOrCreateSection(Name.c_str(), false, Kind.getKind());
+  }
+  
+  if (Kind.isText()) return TextSection;
+  if (Kind.isMergeableCString()) {
+    Constant *C = cast<GlobalVariable>(GV)->getInitializer();
+    
+    // FIXME: This is completely wrong.  Why is it comparing the size of the
+    // character type to 1?
+    /// cast<ArrayType>(C->getType())->getNumElements();
+    uint64_t Size = 1;
+    if (Size <= 16) {
+      assert(CStringSection_ && "Should have string section prefix");
+      
+      // We also need alignment here.
+      // FIXME: this is getting the alignment of the character, not the
+      // alignment of the global!
+      unsigned Align = 
+        TM.getTargetData()->getPreferredAlignment(cast<GlobalVariable>(GV));
+      
+      std::string Name = CStringSection_->getName() + utostr(Size) + '.' +
+      utostr(Align);
+      return getOrCreateSection(Name.c_str(), false,
+                                SectionKind::MergeableCString);
+    }
+    
+    return ReadOnlySection;
+  }
+  
+  if (Kind.isMergeableConst()) {
+    if (Kind.isMergeableConst4())
+      return MergeableConst4Section;
+    if (Kind.isMergeableConst8())
+      return MergeableConst8Section;
+    if (Kind.isMergeableConst16())
+      return MergeableConst16Section;
+    return ReadOnlySection;  // .const
+  }
+  
+  if (Kind.isReadOnly())             return ReadOnlySection;
+  
+  if (Kind.isThreadData())           return TLSDataSection;
+  if (Kind.isThreadBSS())            return TLSBSSSection;
+  
+  if (Kind.isBSS())                  return BSSSection_;
+  
+  if (Kind.isDataNoRel())            return DataSection;
+  if (Kind.isDataRelLocal())         return DataRelLocalSection;
+  if (Kind.isDataRel())              return DataRelSection;
+  if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
+  
+  assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
+  return DataRelROSection;
+}
+
+/// getSectionForMergeableConstant - Given a mergeable constant with the
+/// specified size and relocation information, return a section that it
+/// should be placed in.
+const Section *TargetLoweringObjectFileELF::
+getSectionForMergeableConstant(SectionKind Kind) const {
+  if (Kind.isMergeableConst4())
+    return MergeableConst4Section;
+  if (Kind.isMergeableConst8())
+    return MergeableConst8Section;
+  if (Kind.isMergeableConst16())
+    return MergeableConst16Section;
+  if (Kind.isReadOnly())
+    return ReadOnlySection;
+  
+  if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
+  assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
+  return DataRelROSection;
+}
+
+//===----------------------------------------------------------------------===//
+//                                 MachO
+//===----------------------------------------------------------------------===//
+
+TargetLoweringObjectFileMachO::
+TargetLoweringObjectFileMachO() {
+  TextSection = getOrCreateSection("\t.text", true, SectionKind::Text);
+  DataSection = getOrCreateSection("\t.data", true, SectionKind::DataRel);
+  
+  CStringSection_ = getOrCreateSection("\t.cstring", true,
+                                       SectionKind::MergeableCString);
+  FourByteConstantSection = getOrCreateSection("\t.literal4\n", true,
+                                               SectionKind::MergeableConst4);
+  EightByteConstantSection = getOrCreateSection("\t.literal8\n", true,
+                                                SectionKind::MergeableConst8);
+  SixteenByteConstantSection = 
+  getOrCreateSection("\t.literal16\n", true, SectionKind::MergeableConst16);
+  
+  ReadOnlySection = getOrCreateSection("\t.const", true, SectionKind::ReadOnly);
+  
+  TextCoalSection =
+  getOrCreateSection("\t__TEXT,__textcoal_nt,coalesced,pure_instructions",
+                     false, SectionKind::Text);
+  ConstTextCoalSection = getOrCreateSection("\t__TEXT,__const_coal,coalesced",
+                                            false, SectionKind::Text);
+  ConstDataCoalSection = getOrCreateSection("\t__DATA,__const_coal,coalesced",
+                                            false, SectionKind::Text);
+  ConstDataSection = getOrCreateSection("\t.const_data", true,
+                                        SectionKind::ReadOnlyWithRel);
+  DataCoalSection = getOrCreateSection("\t__DATA,__datacoal_nt,coalesced",
+                                       false, SectionKind::DataRel);
+}
+
+const Section *
+TargetLoweringObjectFileMachO::SelectSectionForGlobal(const GlobalValue *GV,
+                                                      SectionKind Kind,
+                                                const TargetMachine &TM) const {
+  assert(!Kind.isThreadLocal() && "Darwin doesn't support TLS");
+  
+  if (Kind.isText())
+    return Kind.isWeak() ? TextCoalSection : TextSection;
+  
+  // If this is weak/linkonce, put this in a coalescable section, either in text
+  // or data depending on if it is writable.
+  if (Kind.isWeak()) {
+    if (Kind.isReadOnly())
+      return ConstTextCoalSection;
+    return DataCoalSection;
+  }
+  
+  // FIXME: Alignment check should be handled by section classifier.
+  if (Kind.isMergeableCString()) {
+    Constant *C = cast<GlobalVariable>(GV)->getInitializer();
+    const Type *Ty = cast<ArrayType>(C->getType())->getElementType();
+    const TargetData &TD = *TM.getTargetData();
+    unsigned Size = TD.getTypeAllocSize(Ty);
+    if (Size) {
+      unsigned Align = TD.getPreferredAlignment(cast<GlobalVariable>(GV));
+      if (Align <= 32)
+        return CStringSection_;
+    }
+    
+    return ReadOnlySection;
+  }
+  
+  if (Kind.isMergeableConst()) {
+    if (Kind.isMergeableConst4())
+      return FourByteConstantSection;
+    if (Kind.isMergeableConst8())
+      return EightByteConstantSection;
+    if (Kind.isMergeableConst16())
+      return SixteenByteConstantSection;
+    return ReadOnlySection;  // .const
+  }
+  
+  // FIXME: ROData -> const in -static mode that is relocatable but they happen
+  // by the static linker.  Why not mergeable?
+  if (Kind.isReadOnly())
+    return ReadOnlySection;
+
+  // If this is marked const, put it into a const section.  But if the dynamic
+  // linker needs to write to it, put it in the data segment.
+  if (Kind.isReadOnlyWithRel())
+    return ConstDataSection;
+  
+  // Otherwise, just drop the variable in the normal data section.
+  return DataSection;
+}
+
+const Section *
+TargetLoweringObjectFileMachO::
+getSectionForMergeableConstant(SectionKind Kind) const {
+  // If this constant requires a relocation, we have to put it in the data
+  // segment, not in the text segment.
+  if (Kind.isDataRel())
+    return ConstDataSection;
+  
+  if (Kind.isMergeableConst4())
+    return FourByteConstantSection;
+  if (Kind.isMergeableConst8())
+    return EightByteConstantSection;
+  if (Kind.isMergeableConst16())
+    return SixteenByteConstantSection;
+  return ReadOnlySection;  // .const
+}
+
+//===----------------------------------------------------------------------===//
+//                                  COFF
+//===----------------------------------------------------------------------===//
+
+TargetLoweringObjectFileCOFF::TargetLoweringObjectFileCOFF() {
+  TextSection = getOrCreateSection("_text", true, SectionKind::Text);
+  DataSection = getOrCreateSection("_data", true, SectionKind::DataRel);
+}
+
+void TargetLoweringObjectFileCOFF::
+getSectionFlagsAsString(SectionKind Kind, SmallVectorImpl<char> &Str) const {
+  // FIXME: Inefficient.
+  std::string Res = ",\"";
+  if (Kind.isText())
+    Res += 'x';
+  if (Kind.isWriteable())
+    Res += 'w';
+  Res += "\"";
+  
+  Str.append(Res.begin(), Res.end());
+}
+
+static const char *getCOFFSectionPrefixForUniqueGlobal(SectionKind Kind) {
+  if (Kind.isText())
+    return ".text$linkonce";
+  if (Kind.isWriteable())
+    return ".data$linkonce";
+  return ".rdata$linkonce";
+}
+
+
+const Section *TargetLoweringObjectFileCOFF::
+SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+                       const TargetMachine &TM) const {
+  assert(!Kind.isThreadLocal() && "Doesn't support TLS");
+  
+  // If this global is linkonce/weak and the target handles this by emitting it
+  // into a 'uniqued' section name, create and return the section now.
+  if (Kind.isWeak()) {
+    const char *Prefix = getCOFFSectionPrefixForUniqueGlobal(Kind);
+    // FIXME: Use mangler interface (PR4584).
+    std::string Name = Prefix+GV->getNameStr();
+    return getOrCreateSection(Name.c_str(), false, Kind.getKind());
+  }
+  
+  if (Kind.isText())
+    return getTextSection();
+  
+  if (Kind.isBSS())
+    if (const Section *S = BSSSection_)
+      return S;
+  
+  if (Kind.isReadOnly() && ReadOnlySection != 0)
+    return ReadOnlySection;
+  
+  return getDataSection();
+}
+
