1f22ef01cSRoman Divacky //===-- llvm/CodeGen/TargetLoweringObjectFileImpl.cpp - Object File Info --===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This file implements classes used to handle lowerings specific to common
11f22ef01cSRoman Divacky // object file formats.
12f22ef01cSRoman Divacky //
13f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
14f22ef01cSRoman Divacky 
15f22ef01cSRoman Divacky #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
16f22ef01cSRoman Divacky #include "llvm/Constants.h"
17f22ef01cSRoman Divacky #include "llvm/DerivedTypes.h"
18f22ef01cSRoman Divacky #include "llvm/Function.h"
19f22ef01cSRoman Divacky #include "llvm/GlobalVariable.h"
20dff0c46cSDimitry Andric #include "llvm/Module.h"
21f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineModuleInfoImpls.h"
22f22ef01cSRoman Divacky #include "llvm/MC/MCContext.h"
23f22ef01cSRoman Divacky #include "llvm/MC/MCExpr.h"
24f22ef01cSRoman Divacky #include "llvm/MC/MCSectionMachO.h"
25f22ef01cSRoman Divacky #include "llvm/MC/MCSectionELF.h"
26f22ef01cSRoman Divacky #include "llvm/MC/MCSectionCOFF.h"
273b0f4066SDimitry Andric #include "llvm/MC/MCStreamer.h"
28f22ef01cSRoman Divacky #include "llvm/MC/MCSymbol.h"
29f22ef01cSRoman Divacky #include "llvm/Target/Mangler.h"
30f22ef01cSRoman Divacky #include "llvm/Target/TargetData.h"
31f22ef01cSRoman Divacky #include "llvm/Target/TargetMachine.h"
32f22ef01cSRoman Divacky #include "llvm/Target/TargetOptions.h"
33f22ef01cSRoman Divacky #include "llvm/Support/Dwarf.h"
342754fe60SDimitry Andric #include "llvm/Support/ELF.h"
35f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h"
36f22ef01cSRoman Divacky #include "llvm/Support/raw_ostream.h"
37f22ef01cSRoman Divacky #include "llvm/ADT/SmallString.h"
38f22ef01cSRoman Divacky #include "llvm/ADT/StringExtras.h"
392754fe60SDimitry Andric #include "llvm/ADT/Triple.h"
40f22ef01cSRoman Divacky using namespace llvm;
41f22ef01cSRoman Divacky using namespace dwarf;
42f22ef01cSRoman Divacky 
43f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
44f22ef01cSRoman Divacky //                                  ELF
45f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
46f22ef01cSRoman Divacky 
473b0f4066SDimitry Andric MCSymbol *
483b0f4066SDimitry Andric TargetLoweringObjectFileELF::getCFIPersonalitySymbol(const GlobalValue *GV,
493b0f4066SDimitry Andric                                                      Mangler *Mang,
503b0f4066SDimitry Andric                                                 MachineModuleInfo *MMI) const {
513b0f4066SDimitry Andric   unsigned Encoding = getPersonalityEncoding();
523b0f4066SDimitry Andric   switch (Encoding & 0x70) {
533b0f4066SDimitry Andric   default:
543b0f4066SDimitry Andric     report_fatal_error("We do not support this DWARF encoding yet!");
553b0f4066SDimitry Andric   case dwarf::DW_EH_PE_absptr:
563b0f4066SDimitry Andric     return  Mang->getSymbol(GV);
573b0f4066SDimitry Andric   case dwarf::DW_EH_PE_pcrel: {
5817a519f9SDimitry Andric     return getContext().GetOrCreateSymbol(StringRef("DW.ref.") +
5917a519f9SDimitry Andric                                           Mang->getSymbol(GV)->getName());
603b0f4066SDimitry Andric   }
613b0f4066SDimitry Andric   }
623b0f4066SDimitry Andric }
633b0f4066SDimitry Andric 
643b0f4066SDimitry Andric void TargetLoweringObjectFileELF::emitPersonalityValue(MCStreamer &Streamer,
653b0f4066SDimitry Andric                                                        const TargetMachine &TM,
663b0f4066SDimitry Andric                                                        const MCSymbol *Sym) const {
6717a519f9SDimitry Andric   SmallString<64> NameData("DW.ref.");
6817a519f9SDimitry Andric   NameData += Sym->getName();
6917a519f9SDimitry Andric   MCSymbol *Label = getContext().GetOrCreateSymbol(NameData);
703b0f4066SDimitry Andric   Streamer.EmitSymbolAttribute(Label, MCSA_Hidden);
713b0f4066SDimitry Andric   Streamer.EmitSymbolAttribute(Label, MCSA_Weak);
7217a519f9SDimitry Andric   StringRef Prefix = ".data.";
7317a519f9SDimitry Andric   NameData.insert(NameData.begin(), Prefix.begin(), Prefix.end());
743b0f4066SDimitry Andric   unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP;
753b0f4066SDimitry Andric   const MCSection *Sec = getContext().getELFSection(NameData,
763b0f4066SDimitry Andric                                                     ELF::SHT_PROGBITS,
773b0f4066SDimitry Andric                                                     Flags,
783b0f4066SDimitry Andric                                                     SectionKind::getDataRel(),
793b0f4066SDimitry Andric                                                     0, Label->getName());
80dff0c46cSDimitry Andric   unsigned Size = TM.getTargetData()->getPointerSize();
813b0f4066SDimitry Andric   Streamer.SwitchSection(Sec);
82dff0c46cSDimitry Andric   Streamer.EmitValueToAlignment(TM.getTargetData()->getPointerABIAlignment());
833b0f4066SDimitry Andric   Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject);
84dff0c46cSDimitry Andric   const MCExpr *E = MCConstantExpr::Create(Size, getContext());
853b0f4066SDimitry Andric   Streamer.EmitELFSize(Label, E);
863b0f4066SDimitry Andric   Streamer.EmitLabel(Label);
873b0f4066SDimitry Andric 
883b0f4066SDimitry Andric   Streamer.EmitSymbolValue(Sym, Size);
893b0f4066SDimitry Andric }
903b0f4066SDimitry Andric 
91f22ef01cSRoman Divacky static SectionKind
92f22ef01cSRoman Divacky getELFKindForNamedSection(StringRef Name, SectionKind K) {
93bd5abe19SDimitry Andric   // N.B.: The defaults used in here are no the same ones used in MC.
94bd5abe19SDimitry Andric   // We follow gcc, MC follows gas. For example, given ".section .eh_frame",
95bd5abe19SDimitry Andric   // both gas and MC will produce a section with no flags. Given
96bd5abe19SDimitry Andric   // section(".eh_frame") gcc will produce
97bd5abe19SDimitry Andric   // .section	.eh_frame,"a",@progbits
98f22ef01cSRoman Divacky   if (Name.empty() || Name[0] != '.') return K;
99f22ef01cSRoman Divacky 
100f22ef01cSRoman Divacky   // Some lame default implementation based on some magic section names.
101f22ef01cSRoman Divacky   if (Name == ".bss" ||
102f22ef01cSRoman Divacky       Name.startswith(".bss.") ||
103f22ef01cSRoman Divacky       Name.startswith(".gnu.linkonce.b.") ||
104f22ef01cSRoman Divacky       Name.startswith(".llvm.linkonce.b.") ||
105f22ef01cSRoman Divacky       Name == ".sbss" ||
106f22ef01cSRoman Divacky       Name.startswith(".sbss.") ||
107f22ef01cSRoman Divacky       Name.startswith(".gnu.linkonce.sb.") ||
108f22ef01cSRoman Divacky       Name.startswith(".llvm.linkonce.sb."))
109f22ef01cSRoman Divacky     return SectionKind::getBSS();
110f22ef01cSRoman Divacky 
111f22ef01cSRoman Divacky   if (Name == ".tdata" ||
112f22ef01cSRoman Divacky       Name.startswith(".tdata.") ||
113f22ef01cSRoman Divacky       Name.startswith(".gnu.linkonce.td.") ||
114f22ef01cSRoman Divacky       Name.startswith(".llvm.linkonce.td."))
115f22ef01cSRoman Divacky     return SectionKind::getThreadData();
116f22ef01cSRoman Divacky 
117f22ef01cSRoman Divacky   if (Name == ".tbss" ||
118f22ef01cSRoman Divacky       Name.startswith(".tbss.") ||
119f22ef01cSRoman Divacky       Name.startswith(".gnu.linkonce.tb.") ||
120f22ef01cSRoman Divacky       Name.startswith(".llvm.linkonce.tb."))
121f22ef01cSRoman Divacky     return SectionKind::getThreadBSS();
122f22ef01cSRoman Divacky 
123f22ef01cSRoman Divacky   return K;
124f22ef01cSRoman Divacky }
125f22ef01cSRoman Divacky 
126f22ef01cSRoman Divacky 
127f22ef01cSRoman Divacky static unsigned getELFSectionType(StringRef Name, SectionKind K) {
128f22ef01cSRoman Divacky 
129f22ef01cSRoman Divacky   if (Name == ".init_array")
1302754fe60SDimitry Andric     return ELF::SHT_INIT_ARRAY;
131f22ef01cSRoman Divacky 
132f22ef01cSRoman Divacky   if (Name == ".fini_array")
1332754fe60SDimitry Andric     return ELF::SHT_FINI_ARRAY;
134f22ef01cSRoman Divacky 
135f22ef01cSRoman Divacky   if (Name == ".preinit_array")
1362754fe60SDimitry Andric     return ELF::SHT_PREINIT_ARRAY;
137f22ef01cSRoman Divacky 
138f22ef01cSRoman Divacky   if (K.isBSS() || K.isThreadBSS())
1392754fe60SDimitry Andric     return ELF::SHT_NOBITS;
140f22ef01cSRoman Divacky 
1412754fe60SDimitry Andric   return ELF::SHT_PROGBITS;
142f22ef01cSRoman Divacky }
143f22ef01cSRoman Divacky 
144f22ef01cSRoman Divacky 
145f22ef01cSRoman Divacky static unsigned
146f22ef01cSRoman Divacky getELFSectionFlags(SectionKind K) {
147f22ef01cSRoman Divacky   unsigned Flags = 0;
148f22ef01cSRoman Divacky 
149f22ef01cSRoman Divacky   if (!K.isMetadata())
1502754fe60SDimitry Andric     Flags |= ELF::SHF_ALLOC;
151f22ef01cSRoman Divacky 
152f22ef01cSRoman Divacky   if (K.isText())
1532754fe60SDimitry Andric     Flags |= ELF::SHF_EXECINSTR;
154f22ef01cSRoman Divacky 
155f22ef01cSRoman Divacky   if (K.isWriteable())
1562754fe60SDimitry Andric     Flags |= ELF::SHF_WRITE;
157f22ef01cSRoman Divacky 
158f22ef01cSRoman Divacky   if (K.isThreadLocal())
1592754fe60SDimitry Andric     Flags |= ELF::SHF_TLS;
160f22ef01cSRoman Divacky 
161f22ef01cSRoman Divacky   // K.isMergeableConst() is left out to honour PR4650
162f22ef01cSRoman Divacky   if (K.isMergeableCString() || K.isMergeableConst4() ||
163f22ef01cSRoman Divacky       K.isMergeableConst8() || K.isMergeableConst16())
1642754fe60SDimitry Andric     Flags |= ELF::SHF_MERGE;
165f22ef01cSRoman Divacky 
166f22ef01cSRoman Divacky   if (K.isMergeableCString())
1672754fe60SDimitry Andric     Flags |= ELF::SHF_STRINGS;
168f22ef01cSRoman Divacky 
169f22ef01cSRoman Divacky   return Flags;
170f22ef01cSRoman Divacky }
171f22ef01cSRoman Divacky 
172f22ef01cSRoman Divacky 
173f22ef01cSRoman Divacky const MCSection *TargetLoweringObjectFileELF::
174f22ef01cSRoman Divacky getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
175f22ef01cSRoman Divacky                          Mangler *Mang, const TargetMachine &TM) const {
176f22ef01cSRoman Divacky   StringRef SectionName = GV->getSection();
177f22ef01cSRoman Divacky 
178f22ef01cSRoman Divacky   // Infer section flags from the section name if we can.
179f22ef01cSRoman Divacky   Kind = getELFKindForNamedSection(SectionName, Kind);
180f22ef01cSRoman Divacky 
181f22ef01cSRoman Divacky   return getContext().getELFSection(SectionName,
182f22ef01cSRoman Divacky                                     getELFSectionType(SectionName, Kind),
1832754fe60SDimitry Andric                                     getELFSectionFlags(Kind), Kind);
184f22ef01cSRoman Divacky }
185f22ef01cSRoman Divacky 
186f22ef01cSRoman Divacky /// getSectionPrefixForGlobal - Return the section prefix name used by options
187f22ef01cSRoman Divacky /// FunctionsSections and DataSections.
188f22ef01cSRoman Divacky static const char *getSectionPrefixForGlobal(SectionKind Kind) {
189f22ef01cSRoman Divacky   if (Kind.isText())                 return ".text.";
190f22ef01cSRoman Divacky   if (Kind.isReadOnly())             return ".rodata.";
191dff0c46cSDimitry Andric   if (Kind.isBSS())                  return ".bss.";
192f22ef01cSRoman Divacky 
193f22ef01cSRoman Divacky   if (Kind.isThreadData())           return ".tdata.";
194f22ef01cSRoman Divacky   if (Kind.isThreadBSS())            return ".tbss.";
195f22ef01cSRoman Divacky 
196f22ef01cSRoman Divacky   if (Kind.isDataNoRel())            return ".data.";
197f22ef01cSRoman Divacky   if (Kind.isDataRelLocal())         return ".data.rel.local.";
198f22ef01cSRoman Divacky   if (Kind.isDataRel())              return ".data.rel.";
199f22ef01cSRoman Divacky   if (Kind.isReadOnlyWithRelLocal()) return ".data.rel.ro.local.";
200f22ef01cSRoman Divacky 
201f22ef01cSRoman Divacky   assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
202f22ef01cSRoman Divacky   return ".data.rel.ro.";
203f22ef01cSRoman Divacky }
204f22ef01cSRoman Divacky 
205f22ef01cSRoman Divacky 
206f22ef01cSRoman Divacky const MCSection *TargetLoweringObjectFileELF::
207f22ef01cSRoman Divacky SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
208f22ef01cSRoman Divacky                        Mangler *Mang, const TargetMachine &TM) const {
209f22ef01cSRoman Divacky   // If we have -ffunction-section or -fdata-section then we should emit the
210f22ef01cSRoman Divacky   // global value to a uniqued section specifically for it.
211f22ef01cSRoman Divacky   bool EmitUniquedSection;
212f22ef01cSRoman Divacky   if (Kind.isText())
213f22ef01cSRoman Divacky     EmitUniquedSection = TM.getFunctionSections();
214f22ef01cSRoman Divacky   else
215f22ef01cSRoman Divacky     EmitUniquedSection = TM.getDataSections();
216f22ef01cSRoman Divacky 
217f22ef01cSRoman Divacky   // If this global is linkonce/weak and the target handles this by emitting it
218f22ef01cSRoman Divacky   // into a 'uniqued' section name, create and return the section now.
219f22ef01cSRoman Divacky   if ((GV->isWeakForLinker() || EmitUniquedSection) &&
220dff0c46cSDimitry Andric       !Kind.isCommon()) {
221f22ef01cSRoman Divacky     const char *Prefix;
222f22ef01cSRoman Divacky     Prefix = getSectionPrefixForGlobal(Kind);
223f22ef01cSRoman Divacky 
224f22ef01cSRoman Divacky     SmallString<128> Name(Prefix, Prefix+strlen(Prefix));
225f22ef01cSRoman Divacky     MCSymbol *Sym = Mang->getSymbol(GV);
226f22ef01cSRoman Divacky     Name.append(Sym->getName().begin(), Sym->getName().end());
2272754fe60SDimitry Andric     StringRef Group = "";
2282754fe60SDimitry Andric     unsigned Flags = getELFSectionFlags(Kind);
2292754fe60SDimitry Andric     if (GV->isWeakForLinker()) {
2302754fe60SDimitry Andric       Group = Sym->getName();
2312754fe60SDimitry Andric       Flags |= ELF::SHF_GROUP;
2322754fe60SDimitry Andric     }
2332754fe60SDimitry Andric 
234f22ef01cSRoman Divacky     return getContext().getELFSection(Name.str(),
235f22ef01cSRoman Divacky                                       getELFSectionType(Name.str(), Kind),
2362754fe60SDimitry Andric                                       Flags, Kind, 0, Group);
237f22ef01cSRoman Divacky   }
238f22ef01cSRoman Divacky 
239f22ef01cSRoman Divacky   if (Kind.isText()) return TextSection;
240f22ef01cSRoman Divacky 
241f22ef01cSRoman Divacky   if (Kind.isMergeable1ByteCString() ||
242f22ef01cSRoman Divacky       Kind.isMergeable2ByteCString() ||
243f22ef01cSRoman Divacky       Kind.isMergeable4ByteCString()) {
244f22ef01cSRoman Divacky 
245f22ef01cSRoman Divacky     // We also need alignment here.
246f22ef01cSRoman Divacky     // FIXME: this is getting the alignment of the character, not the
247f22ef01cSRoman Divacky     // alignment of the global!
248f22ef01cSRoman Divacky     unsigned Align =
249f22ef01cSRoman Divacky       TM.getTargetData()->getPreferredAlignment(cast<GlobalVariable>(GV));
250f22ef01cSRoman Divacky 
251f22ef01cSRoman Divacky     const char *SizeSpec = ".rodata.str1.";
252f22ef01cSRoman Divacky     if (Kind.isMergeable2ByteCString())
253f22ef01cSRoman Divacky       SizeSpec = ".rodata.str2.";
254f22ef01cSRoman Divacky     else if (Kind.isMergeable4ByteCString())
255f22ef01cSRoman Divacky       SizeSpec = ".rodata.str4.";
256f22ef01cSRoman Divacky     else
257f22ef01cSRoman Divacky       assert(Kind.isMergeable1ByteCString() && "unknown string width");
258f22ef01cSRoman Divacky 
259f22ef01cSRoman Divacky 
260f22ef01cSRoman Divacky     std::string Name = SizeSpec + utostr(Align);
2612754fe60SDimitry Andric     return getContext().getELFSection(Name, ELF::SHT_PROGBITS,
2622754fe60SDimitry Andric                                       ELF::SHF_ALLOC |
2632754fe60SDimitry Andric                                       ELF::SHF_MERGE |
2642754fe60SDimitry Andric                                       ELF::SHF_STRINGS,
265f22ef01cSRoman Divacky                                       Kind);
266f22ef01cSRoman Divacky   }
267f22ef01cSRoman Divacky 
268f22ef01cSRoman Divacky   if (Kind.isMergeableConst()) {
269f22ef01cSRoman Divacky     if (Kind.isMergeableConst4() && MergeableConst4Section)
270f22ef01cSRoman Divacky       return MergeableConst4Section;
271f22ef01cSRoman Divacky     if (Kind.isMergeableConst8() && MergeableConst8Section)
272f22ef01cSRoman Divacky       return MergeableConst8Section;
273f22ef01cSRoman Divacky     if (Kind.isMergeableConst16() && MergeableConst16Section)
274f22ef01cSRoman Divacky       return MergeableConst16Section;
275f22ef01cSRoman Divacky     return ReadOnlySection;  // .const
276f22ef01cSRoman Divacky   }
277f22ef01cSRoman Divacky 
278f22ef01cSRoman Divacky   if (Kind.isReadOnly())             return ReadOnlySection;
279f22ef01cSRoman Divacky 
280f22ef01cSRoman Divacky   if (Kind.isThreadData())           return TLSDataSection;
281f22ef01cSRoman Divacky   if (Kind.isThreadBSS())            return TLSBSSSection;
282f22ef01cSRoman Divacky 
283f22ef01cSRoman Divacky   // Note: we claim that common symbols are put in BSSSection, but they are
284f22ef01cSRoman Divacky   // really emitted with the magic .comm directive, which creates a symbol table
285f22ef01cSRoman Divacky   // entry but not a section.
286f22ef01cSRoman Divacky   if (Kind.isBSS() || Kind.isCommon()) return BSSSection;
287f22ef01cSRoman Divacky 
288f22ef01cSRoman Divacky   if (Kind.isDataNoRel())            return DataSection;
289f22ef01cSRoman Divacky   if (Kind.isDataRelLocal())         return DataRelLocalSection;
290f22ef01cSRoman Divacky   if (Kind.isDataRel())              return DataRelSection;
291f22ef01cSRoman Divacky   if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
292f22ef01cSRoman Divacky 
293f22ef01cSRoman Divacky   assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
294f22ef01cSRoman Divacky   return DataRelROSection;
295f22ef01cSRoman Divacky }
296f22ef01cSRoman Divacky 
297f22ef01cSRoman Divacky /// getSectionForConstant - Given a mergeable constant with the
298f22ef01cSRoman Divacky /// specified size and relocation information, return a section that it
299f22ef01cSRoman Divacky /// should be placed in.
300f22ef01cSRoman Divacky const MCSection *TargetLoweringObjectFileELF::
301f22ef01cSRoman Divacky getSectionForConstant(SectionKind Kind) const {
302f22ef01cSRoman Divacky   if (Kind.isMergeableConst4() && MergeableConst4Section)
303f22ef01cSRoman Divacky     return MergeableConst4Section;
304f22ef01cSRoman Divacky   if (Kind.isMergeableConst8() && MergeableConst8Section)
305f22ef01cSRoman Divacky     return MergeableConst8Section;
306f22ef01cSRoman Divacky   if (Kind.isMergeableConst16() && MergeableConst16Section)
307f22ef01cSRoman Divacky     return MergeableConst16Section;
308f22ef01cSRoman Divacky   if (Kind.isReadOnly())
309f22ef01cSRoman Divacky     return ReadOnlySection;
310f22ef01cSRoman Divacky 
311f22ef01cSRoman Divacky   if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
312f22ef01cSRoman Divacky   assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
313f22ef01cSRoman Divacky   return DataRelROSection;
314f22ef01cSRoman Divacky }
315f22ef01cSRoman Divacky 
316f22ef01cSRoman Divacky const MCExpr *TargetLoweringObjectFileELF::
317f22ef01cSRoman Divacky getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
318f22ef01cSRoman Divacky                                MachineModuleInfo *MMI,
319f22ef01cSRoman Divacky                                unsigned Encoding, MCStreamer &Streamer) const {
320f22ef01cSRoman Divacky 
321f22ef01cSRoman Divacky   if (Encoding & dwarf::DW_EH_PE_indirect) {
322f22ef01cSRoman Divacky     MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>();
323f22ef01cSRoman Divacky 
324f22ef01cSRoman Divacky     SmallString<128> Name;
325f22ef01cSRoman Divacky     Mang->getNameWithPrefix(Name, GV, true);
326f22ef01cSRoman Divacky     Name += ".DW.stub";
327f22ef01cSRoman Divacky 
328f22ef01cSRoman Divacky     // Add information about the stub reference to ELFMMI so that the stub
329f22ef01cSRoman Divacky     // gets emitted by the asmprinter.
330f22ef01cSRoman Divacky     MCSymbol *SSym = getContext().GetOrCreateSymbol(Name.str());
331f22ef01cSRoman Divacky     MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym);
332f22ef01cSRoman Divacky     if (StubSym.getPointer() == 0) {
333f22ef01cSRoman Divacky       MCSymbol *Sym = Mang->getSymbol(GV);
334f22ef01cSRoman Divacky       StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
335f22ef01cSRoman Divacky     }
336f22ef01cSRoman Divacky 
337f22ef01cSRoman Divacky     return TargetLoweringObjectFile::
3383b0f4066SDimitry Andric       getExprForDwarfReference(SSym, Encoding & ~dwarf::DW_EH_PE_indirect, Streamer);
339f22ef01cSRoman Divacky   }
340f22ef01cSRoman Divacky 
341f22ef01cSRoman Divacky   return TargetLoweringObjectFile::
342f22ef01cSRoman Divacky     getExprForDwarfGlobalReference(GV, Mang, MMI, Encoding, Streamer);
343f22ef01cSRoman Divacky }
344f22ef01cSRoman Divacky 
345dff0c46cSDimitry Andric const MCSection *
346dff0c46cSDimitry Andric TargetLoweringObjectFileELF::getStaticCtorSection(unsigned Priority) const {
347dff0c46cSDimitry Andric   // The default scheme is .ctor / .dtor, so we have to invert the priority
348dff0c46cSDimitry Andric   // numbering.
349dff0c46cSDimitry Andric   if (Priority == 65535)
350dff0c46cSDimitry Andric     return StaticCtorSection;
351dff0c46cSDimitry Andric 
352dff0c46cSDimitry Andric   std::string Name = std::string(".ctors.") + utostr(65535 - Priority);
353dff0c46cSDimitry Andric   return getContext().getELFSection(Name, ELF::SHT_PROGBITS,
354dff0c46cSDimitry Andric                                     ELF::SHF_ALLOC |ELF::SHF_WRITE,
355dff0c46cSDimitry Andric                                     SectionKind::getDataRel());
356dff0c46cSDimitry Andric }
357dff0c46cSDimitry Andric 
358dff0c46cSDimitry Andric const MCSection *
359dff0c46cSDimitry Andric TargetLoweringObjectFileELF::getStaticDtorSection(unsigned Priority) const {
360dff0c46cSDimitry Andric   // The default scheme is .ctor / .dtor, so we have to invert the priority
361dff0c46cSDimitry Andric   // numbering.
362dff0c46cSDimitry Andric   if (Priority == 65535)
363dff0c46cSDimitry Andric     return StaticDtorSection;
364dff0c46cSDimitry Andric 
365dff0c46cSDimitry Andric   std::string Name = std::string(".dtors.") + utostr(65535 - Priority);
366dff0c46cSDimitry Andric   return getContext().getELFSection(Name, ELF::SHT_PROGBITS,
367dff0c46cSDimitry Andric                                     ELF::SHF_ALLOC |ELF::SHF_WRITE,
368dff0c46cSDimitry Andric                                     SectionKind::getDataRel());
369dff0c46cSDimitry Andric }
370dff0c46cSDimitry Andric 
371f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
372f22ef01cSRoman Divacky //                                 MachO
373f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
374f22ef01cSRoman Divacky 
375dff0c46cSDimitry Andric /// emitModuleFlags - Emit the module flags that specify the garbage collection
376dff0c46cSDimitry Andric /// information.
377dff0c46cSDimitry Andric void TargetLoweringObjectFileMachO::
378dff0c46cSDimitry Andric emitModuleFlags(MCStreamer &Streamer,
379dff0c46cSDimitry Andric                 ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
380dff0c46cSDimitry Andric                 Mangler *Mang, const TargetMachine &TM) const {
381dff0c46cSDimitry Andric   unsigned VersionVal = 0;
382dff0c46cSDimitry Andric   unsigned GCFlags = 0;
383dff0c46cSDimitry Andric   StringRef SectionVal;
384dff0c46cSDimitry Andric 
385dff0c46cSDimitry Andric   for (ArrayRef<Module::ModuleFlagEntry>::iterator
386dff0c46cSDimitry Andric          i = ModuleFlags.begin(), e = ModuleFlags.end(); i != e; ++i) {
387dff0c46cSDimitry Andric     const Module::ModuleFlagEntry &MFE = *i;
388dff0c46cSDimitry Andric 
389dff0c46cSDimitry Andric     // Ignore flags with 'Require' behavior.
390dff0c46cSDimitry Andric     if (MFE.Behavior == Module::Require)
391dff0c46cSDimitry Andric       continue;
392dff0c46cSDimitry Andric 
393dff0c46cSDimitry Andric     StringRef Key = MFE.Key->getString();
394dff0c46cSDimitry Andric     Value *Val = MFE.Val;
395dff0c46cSDimitry Andric 
396dff0c46cSDimitry Andric     if (Key == "Objective-C Image Info Version")
397dff0c46cSDimitry Andric       VersionVal = cast<ConstantInt>(Val)->getZExtValue();
398dff0c46cSDimitry Andric     else if (Key == "Objective-C Garbage Collection" ||
399dff0c46cSDimitry Andric              Key == "Objective-C GC Only")
400dff0c46cSDimitry Andric       GCFlags |= cast<ConstantInt>(Val)->getZExtValue();
401dff0c46cSDimitry Andric     else if (Key == "Objective-C Image Info Section")
402dff0c46cSDimitry Andric       SectionVal = cast<MDString>(Val)->getString();
403dff0c46cSDimitry Andric   }
404dff0c46cSDimitry Andric 
405dff0c46cSDimitry Andric   // The section is mandatory. If we don't have it, then we don't have GC info.
406dff0c46cSDimitry Andric   if (SectionVal.empty()) return;
407dff0c46cSDimitry Andric 
408dff0c46cSDimitry Andric   StringRef Segment, Section;
409dff0c46cSDimitry Andric   unsigned TAA = 0, StubSize = 0;
410dff0c46cSDimitry Andric   bool TAAParsed;
411dff0c46cSDimitry Andric   std::string ErrorCode =
412dff0c46cSDimitry Andric     MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section,
413dff0c46cSDimitry Andric                                           TAA, TAAParsed, StubSize);
414dff0c46cSDimitry Andric   if (!ErrorCode.empty())
415dff0c46cSDimitry Andric     // If invalid, report the error with report_fatal_error.
416dff0c46cSDimitry Andric     report_fatal_error("Invalid section specifier '" + Section + "': " +
417dff0c46cSDimitry Andric                        ErrorCode + ".");
418dff0c46cSDimitry Andric 
419dff0c46cSDimitry Andric   // Get the section.
420dff0c46cSDimitry Andric   const MCSectionMachO *S =
421dff0c46cSDimitry Andric     getContext().getMachOSection(Segment, Section, TAA, StubSize,
422dff0c46cSDimitry Andric                                  SectionKind::getDataNoRel());
423dff0c46cSDimitry Andric   Streamer.SwitchSection(S);
424dff0c46cSDimitry Andric   Streamer.EmitLabel(getContext().
425dff0c46cSDimitry Andric                      GetOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO")));
426dff0c46cSDimitry Andric   Streamer.EmitIntValue(VersionVal, 4);
427dff0c46cSDimitry Andric   Streamer.EmitIntValue(GCFlags, 4);
428dff0c46cSDimitry Andric   Streamer.AddBlankLine();
429dff0c46cSDimitry Andric }
430dff0c46cSDimitry Andric 
431f22ef01cSRoman Divacky const MCSection *TargetLoweringObjectFileMachO::
432f22ef01cSRoman Divacky getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
433f22ef01cSRoman Divacky                          Mangler *Mang, const TargetMachine &TM) const {
434f22ef01cSRoman Divacky   // Parse the section specifier and create it if valid.
435f22ef01cSRoman Divacky   StringRef Segment, Section;
4363b0f4066SDimitry Andric   unsigned TAA = 0, StubSize = 0;
4373b0f4066SDimitry Andric   bool TAAParsed;
438f22ef01cSRoman Divacky   std::string ErrorCode =
439f22ef01cSRoman Divacky     MCSectionMachO::ParseSectionSpecifier(GV->getSection(), Segment, Section,
4403b0f4066SDimitry Andric                                           TAA, TAAParsed, StubSize);
441f22ef01cSRoman Divacky   if (!ErrorCode.empty()) {
442f22ef01cSRoman Divacky     // If invalid, report the error with report_fatal_error.
443dff0c46cSDimitry Andric     report_fatal_error("Global variable '" + GV->getName() +
444dff0c46cSDimitry Andric                        "' has an invalid section specifier '" +
445dff0c46cSDimitry Andric                        GV->getSection() + "': " + ErrorCode + ".");
446f22ef01cSRoman Divacky   }
447f22ef01cSRoman Divacky 
448f22ef01cSRoman Divacky   // Get the section.
449f22ef01cSRoman Divacky   const MCSectionMachO *S =
450f22ef01cSRoman Divacky     getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind);
451f22ef01cSRoman Divacky 
452dd6029ffSDimitry Andric   // If TAA wasn't set by ParseSectionSpecifier() above,
453dd6029ffSDimitry Andric   // use the value returned by getMachOSection() as a default.
4543b0f4066SDimitry Andric   if (!TAAParsed)
455dd6029ffSDimitry Andric     TAA = S->getTypeAndAttributes();
456dd6029ffSDimitry Andric 
457f22ef01cSRoman Divacky   // Okay, now that we got the section, verify that the TAA & StubSize agree.
458f22ef01cSRoman Divacky   // If the user declared multiple globals with different section flags, we need
459f22ef01cSRoman Divacky   // to reject it here.
460f22ef01cSRoman Divacky   if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) {
461f22ef01cSRoman Divacky     // If invalid, report the error with report_fatal_error.
462dff0c46cSDimitry Andric     report_fatal_error("Global variable '" + GV->getName() +
463f22ef01cSRoman Divacky                        "' section type or attributes does not match previous"
464f22ef01cSRoman Divacky                        " section specifier");
465f22ef01cSRoman Divacky   }
466f22ef01cSRoman Divacky 
467f22ef01cSRoman Divacky   return S;
468f22ef01cSRoman Divacky }
469f22ef01cSRoman Divacky 
470f22ef01cSRoman Divacky const MCSection *TargetLoweringObjectFileMachO::
471f22ef01cSRoman Divacky SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
472f22ef01cSRoman Divacky                        Mangler *Mang, const TargetMachine &TM) const {
473f22ef01cSRoman Divacky 
474f22ef01cSRoman Divacky   // Handle thread local data.
475f22ef01cSRoman Divacky   if (Kind.isThreadBSS()) return TLSBSSSection;
476f22ef01cSRoman Divacky   if (Kind.isThreadData()) return TLSDataSection;
477f22ef01cSRoman Divacky 
478f22ef01cSRoman Divacky   if (Kind.isText())
479f22ef01cSRoman Divacky     return GV->isWeakForLinker() ? TextCoalSection : TextSection;
480f22ef01cSRoman Divacky 
481f22ef01cSRoman Divacky   // If this is weak/linkonce, put this in a coalescable section, either in text
482f22ef01cSRoman Divacky   // or data depending on if it is writable.
483f22ef01cSRoman Divacky   if (GV->isWeakForLinker()) {
484f22ef01cSRoman Divacky     if (Kind.isReadOnly())
485f22ef01cSRoman Divacky       return ConstTextCoalSection;
486f22ef01cSRoman Divacky     return DataCoalSection;
487f22ef01cSRoman Divacky   }
488f22ef01cSRoman Divacky 
489f22ef01cSRoman Divacky   // FIXME: Alignment check should be handled by section classifier.
490f22ef01cSRoman Divacky   if (Kind.isMergeable1ByteCString() &&
491f22ef01cSRoman Divacky       TM.getTargetData()->getPreferredAlignment(cast<GlobalVariable>(GV)) < 32)
492f22ef01cSRoman Divacky     return CStringSection;
493f22ef01cSRoman Divacky 
494f22ef01cSRoman Divacky   // Do not put 16-bit arrays in the UString section if they have an
495f22ef01cSRoman Divacky   // externally visible label, this runs into issues with certain linker
496f22ef01cSRoman Divacky   // versions.
497f22ef01cSRoman Divacky   if (Kind.isMergeable2ByteCString() && !GV->hasExternalLinkage() &&
498f22ef01cSRoman Divacky       TM.getTargetData()->getPreferredAlignment(cast<GlobalVariable>(GV)) < 32)
499f22ef01cSRoman Divacky     return UStringSection;
500f22ef01cSRoman Divacky 
501f22ef01cSRoman Divacky   if (Kind.isMergeableConst()) {
502f22ef01cSRoman Divacky     if (Kind.isMergeableConst4())
503f22ef01cSRoman Divacky       return FourByteConstantSection;
504f22ef01cSRoman Divacky     if (Kind.isMergeableConst8())
505f22ef01cSRoman Divacky       return EightByteConstantSection;
506f22ef01cSRoman Divacky     if (Kind.isMergeableConst16() && SixteenByteConstantSection)
507f22ef01cSRoman Divacky       return SixteenByteConstantSection;
508f22ef01cSRoman Divacky   }
509f22ef01cSRoman Divacky 
510f22ef01cSRoman Divacky   // Otherwise, if it is readonly, but not something we can specially optimize,
511f22ef01cSRoman Divacky   // just drop it in .const.
512f22ef01cSRoman Divacky   if (Kind.isReadOnly())
513f22ef01cSRoman Divacky     return ReadOnlySection;
514f22ef01cSRoman Divacky 
515f22ef01cSRoman Divacky   // If this is marked const, put it into a const section.  But if the dynamic
516f22ef01cSRoman Divacky   // linker needs to write to it, put it in the data segment.
517f22ef01cSRoman Divacky   if (Kind.isReadOnlyWithRel())
518f22ef01cSRoman Divacky     return ConstDataSection;
519f22ef01cSRoman Divacky 
520f22ef01cSRoman Divacky   // Put zero initialized globals with strong external linkage in the
521f22ef01cSRoman Divacky   // DATA, __common section with the .zerofill directive.
522f22ef01cSRoman Divacky   if (Kind.isBSSExtern())
523f22ef01cSRoman Divacky     return DataCommonSection;
524f22ef01cSRoman Divacky 
525f22ef01cSRoman Divacky   // Put zero initialized globals with local linkage in __DATA,__bss directive
526f22ef01cSRoman Divacky   // with the .zerofill directive (aka .lcomm).
527f22ef01cSRoman Divacky   if (Kind.isBSSLocal())
528f22ef01cSRoman Divacky     return DataBSSSection;
529f22ef01cSRoman Divacky 
530f22ef01cSRoman Divacky   // Otherwise, just drop the variable in the normal data section.
531f22ef01cSRoman Divacky   return DataSection;
532f22ef01cSRoman Divacky }
533f22ef01cSRoman Divacky 
534f22ef01cSRoman Divacky const MCSection *
535f22ef01cSRoman Divacky TargetLoweringObjectFileMachO::getSectionForConstant(SectionKind Kind) const {
536f22ef01cSRoman Divacky   // If this constant requires a relocation, we have to put it in the data
537f22ef01cSRoman Divacky   // segment, not in the text segment.
538f22ef01cSRoman Divacky   if (Kind.isDataRel() || Kind.isReadOnlyWithRel())
539f22ef01cSRoman Divacky     return ConstDataSection;
540f22ef01cSRoman Divacky 
541f22ef01cSRoman Divacky   if (Kind.isMergeableConst4())
542f22ef01cSRoman Divacky     return FourByteConstantSection;
543f22ef01cSRoman Divacky   if (Kind.isMergeableConst8())
544f22ef01cSRoman Divacky     return EightByteConstantSection;
545f22ef01cSRoman Divacky   if (Kind.isMergeableConst16() && SixteenByteConstantSection)
546f22ef01cSRoman Divacky     return SixteenByteConstantSection;
547f22ef01cSRoman Divacky   return ReadOnlySection;  // .const
548f22ef01cSRoman Divacky }
549f22ef01cSRoman Divacky 
550f22ef01cSRoman Divacky /// shouldEmitUsedDirectiveFor - This hook allows targets to selectively decide
551f22ef01cSRoman Divacky /// not to emit the UsedDirective for some symbols in llvm.used.
552f22ef01cSRoman Divacky // FIXME: REMOVE this (rdar://7071300)
553f22ef01cSRoman Divacky bool TargetLoweringObjectFileMachO::
554f22ef01cSRoman Divacky shouldEmitUsedDirectiveFor(const GlobalValue *GV, Mangler *Mang) const {
555f22ef01cSRoman Divacky   /// On Darwin, internally linked data beginning with "L" or "l" does not have
556f22ef01cSRoman Divacky   /// the directive emitted (this occurs in ObjC metadata).
557f22ef01cSRoman Divacky   if (!GV) return false;
558f22ef01cSRoman Divacky 
559f22ef01cSRoman Divacky   // Check whether the mangled name has the "Private" or "LinkerPrivate" prefix.
560f22ef01cSRoman Divacky   if (GV->hasLocalLinkage() && !isa<Function>(GV)) {
561f22ef01cSRoman Divacky     // FIXME: ObjC metadata is currently emitted as internal symbols that have
562f22ef01cSRoman Divacky     // \1L and \0l prefixes on them.  Fix them to be Private/LinkerPrivate and
563f22ef01cSRoman Divacky     // this horrible hack can go away.
564f22ef01cSRoman Divacky     MCSymbol *Sym = Mang->getSymbol(GV);
565f22ef01cSRoman Divacky     if (Sym->getName()[0] == 'L' || Sym->getName()[0] == 'l')
566f22ef01cSRoman Divacky       return false;
567f22ef01cSRoman Divacky   }
568f22ef01cSRoman Divacky 
569f22ef01cSRoman Divacky   return true;
570f22ef01cSRoman Divacky }
571f22ef01cSRoman Divacky 
572f22ef01cSRoman Divacky const MCExpr *TargetLoweringObjectFileMachO::
573f22ef01cSRoman Divacky getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
574f22ef01cSRoman Divacky                                MachineModuleInfo *MMI, unsigned Encoding,
575f22ef01cSRoman Divacky                                MCStreamer &Streamer) const {
576f22ef01cSRoman Divacky   // The mach-o version of this method defaults to returning a stub reference.
577f22ef01cSRoman Divacky 
578f22ef01cSRoman Divacky   if (Encoding & DW_EH_PE_indirect) {
579f22ef01cSRoman Divacky     MachineModuleInfoMachO &MachOMMI =
580f22ef01cSRoman Divacky       MMI->getObjFileInfo<MachineModuleInfoMachO>();
581f22ef01cSRoman Divacky 
582f22ef01cSRoman Divacky     SmallString<128> Name;
583f22ef01cSRoman Divacky     Mang->getNameWithPrefix(Name, GV, true);
584f22ef01cSRoman Divacky     Name += "$non_lazy_ptr";
585f22ef01cSRoman Divacky 
586f22ef01cSRoman Divacky     // Add information about the stub reference to MachOMMI so that the stub
587f22ef01cSRoman Divacky     // gets emitted by the asmprinter.
588f22ef01cSRoman Divacky     MCSymbol *SSym = getContext().GetOrCreateSymbol(Name.str());
589f8254f43SDimitry Andric     MachineModuleInfoImpl::StubValueTy &StubSym =
590f8254f43SDimitry Andric       GV->hasHiddenVisibility() ? MachOMMI.getHiddenGVStubEntry(SSym) :
591f8254f43SDimitry Andric                                   MachOMMI.getGVStubEntry(SSym);
592f22ef01cSRoman Divacky     if (StubSym.getPointer() == 0) {
593f22ef01cSRoman Divacky       MCSymbol *Sym = Mang->getSymbol(GV);
594f22ef01cSRoman Divacky       StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
595f22ef01cSRoman Divacky     }
596f22ef01cSRoman Divacky 
597f22ef01cSRoman Divacky     return TargetLoweringObjectFile::
5983b0f4066SDimitry Andric       getExprForDwarfReference(SSym, Encoding & ~dwarf::DW_EH_PE_indirect, Streamer);
599f22ef01cSRoman Divacky   }
600f22ef01cSRoman Divacky 
601f22ef01cSRoman Divacky   return TargetLoweringObjectFile::
602f22ef01cSRoman Divacky     getExprForDwarfGlobalReference(GV, Mang, MMI, Encoding, Streamer);
603f22ef01cSRoman Divacky }
604f22ef01cSRoman Divacky 
6053b0f4066SDimitry Andric MCSymbol *TargetLoweringObjectFileMachO::
6063b0f4066SDimitry Andric getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang,
6073b0f4066SDimitry Andric                         MachineModuleInfo *MMI) const {
6083b0f4066SDimitry Andric   // The mach-o version of this method defaults to returning a stub reference.
6093b0f4066SDimitry Andric   MachineModuleInfoMachO &MachOMMI =
6103b0f4066SDimitry Andric     MMI->getObjFileInfo<MachineModuleInfoMachO>();
6113b0f4066SDimitry Andric 
6123b0f4066SDimitry Andric   SmallString<128> Name;
6133b0f4066SDimitry Andric   Mang->getNameWithPrefix(Name, GV, true);
6143b0f4066SDimitry Andric   Name += "$non_lazy_ptr";
6153b0f4066SDimitry Andric 
6163b0f4066SDimitry Andric   // Add information about the stub reference to MachOMMI so that the stub
6173b0f4066SDimitry Andric   // gets emitted by the asmprinter.
6183b0f4066SDimitry Andric   MCSymbol *SSym = getContext().GetOrCreateSymbol(Name.str());
619dff0c46cSDimitry Andric   MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym);
6203b0f4066SDimitry Andric   if (StubSym.getPointer() == 0) {
6213b0f4066SDimitry Andric     MCSymbol *Sym = Mang->getSymbol(GV);
6223b0f4066SDimitry Andric     StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
6233b0f4066SDimitry Andric   }
6243b0f4066SDimitry Andric 
6253b0f4066SDimitry Andric   return SSym;
6263b0f4066SDimitry Andric }
6273b0f4066SDimitry Andric 
628f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
629f22ef01cSRoman Divacky //                                  COFF
630f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
631f22ef01cSRoman Divacky 
632f22ef01cSRoman Divacky static unsigned
633f22ef01cSRoman Divacky getCOFFSectionFlags(SectionKind K) {
634f22ef01cSRoman Divacky   unsigned Flags = 0;
635f22ef01cSRoman Divacky 
636ffd1746dSEd Schouten   if (K.isMetadata())
637f22ef01cSRoman Divacky     Flags |=
638ffd1746dSEd Schouten       COFF::IMAGE_SCN_MEM_DISCARDABLE;
639f22ef01cSRoman Divacky   else if (K.isText())
640f22ef01cSRoman Divacky     Flags |=
641ffd1746dSEd Schouten       COFF::IMAGE_SCN_MEM_EXECUTE |
6422754fe60SDimitry Andric       COFF::IMAGE_SCN_MEM_READ |
643ffd1746dSEd Schouten       COFF::IMAGE_SCN_CNT_CODE;
644f22ef01cSRoman Divacky   else if (K.isBSS ())
645f22ef01cSRoman Divacky     Flags |=
646ffd1746dSEd Schouten       COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
647ffd1746dSEd Schouten       COFF::IMAGE_SCN_MEM_READ |
648ffd1746dSEd Schouten       COFF::IMAGE_SCN_MEM_WRITE;
649dff0c46cSDimitry Andric   else if (K.isThreadLocal())
650dff0c46cSDimitry Andric     Flags |=
651dff0c46cSDimitry Andric       COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
652dff0c46cSDimitry Andric       COFF::IMAGE_SCN_MEM_READ |
653dff0c46cSDimitry Andric       COFF::IMAGE_SCN_MEM_WRITE;
654f22ef01cSRoman Divacky   else if (K.isReadOnly())
655f22ef01cSRoman Divacky     Flags |=
656ffd1746dSEd Schouten       COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
657ffd1746dSEd Schouten       COFF::IMAGE_SCN_MEM_READ;
658f22ef01cSRoman Divacky   else if (K.isWriteable())
659f22ef01cSRoman Divacky     Flags |=
660ffd1746dSEd Schouten       COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
661ffd1746dSEd Schouten       COFF::IMAGE_SCN_MEM_READ |
662ffd1746dSEd Schouten       COFF::IMAGE_SCN_MEM_WRITE;
663f22ef01cSRoman Divacky 
664f22ef01cSRoman Divacky   return Flags;
665f22ef01cSRoman Divacky }
666f22ef01cSRoman Divacky 
667f22ef01cSRoman Divacky const MCSection *TargetLoweringObjectFileCOFF::
668f22ef01cSRoman Divacky getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
669f22ef01cSRoman Divacky                          Mangler *Mang, const TargetMachine &TM) const {
670f22ef01cSRoman Divacky   return getContext().getCOFFSection(GV->getSection(),
671f22ef01cSRoman Divacky                                      getCOFFSectionFlags(Kind),
672f22ef01cSRoman Divacky                                      Kind);
673f22ef01cSRoman Divacky }
674f22ef01cSRoman Divacky 
675f22ef01cSRoman Divacky static const char *getCOFFSectionPrefixForUniqueGlobal(SectionKind Kind) {
676f22ef01cSRoman Divacky   if (Kind.isText())
6772754fe60SDimitry Andric     return ".text$";
678f22ef01cSRoman Divacky   if (Kind.isBSS ())
6792754fe60SDimitry Andric     return ".bss$";
680dff0c46cSDimitry Andric   if (Kind.isThreadLocal())
681dff0c46cSDimitry Andric     return ".tls$";
682f22ef01cSRoman Divacky   if (Kind.isWriteable())
6832754fe60SDimitry Andric     return ".data$";
6842754fe60SDimitry Andric   return ".rdata$";
685f22ef01cSRoman Divacky }
686f22ef01cSRoman Divacky 
687f22ef01cSRoman Divacky 
688f22ef01cSRoman Divacky const MCSection *TargetLoweringObjectFileCOFF::
689f22ef01cSRoman Divacky SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
690f22ef01cSRoman Divacky                        Mangler *Mang, const TargetMachine &TM) const {
691f22ef01cSRoman Divacky 
692f22ef01cSRoman Divacky   // If this global is linkonce/weak and the target handles this by emitting it
693f22ef01cSRoman Divacky   // into a 'uniqued' section name, create and return the section now.
694f22ef01cSRoman Divacky   if (GV->isWeakForLinker()) {
695f22ef01cSRoman Divacky     const char *Prefix = getCOFFSectionPrefixForUniqueGlobal(Kind);
696f22ef01cSRoman Divacky     SmallString<128> Name(Prefix, Prefix+strlen(Prefix));
697f22ef01cSRoman Divacky     MCSymbol *Sym = Mang->getSymbol(GV);
6982754fe60SDimitry Andric     Name.append(Sym->getName().begin() + 1, Sym->getName().end());
699f22ef01cSRoman Divacky 
700f22ef01cSRoman Divacky     unsigned Characteristics = getCOFFSectionFlags(Kind);
701f22ef01cSRoman Divacky 
702ffd1746dSEd Schouten     Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
703f22ef01cSRoman Divacky 
704f22ef01cSRoman Divacky     return getContext().getCOFFSection(Name.str(), Characteristics,
7052754fe60SDimitry Andric                           COFF::IMAGE_COMDAT_SELECT_ANY, Kind);
706f22ef01cSRoman Divacky   }
707f22ef01cSRoman Divacky 
708f22ef01cSRoman Divacky   if (Kind.isText())
709f22ef01cSRoman Divacky     return getTextSection();
710f22ef01cSRoman Divacky 
711dff0c46cSDimitry Andric   if (Kind.isThreadLocal())
712dff0c46cSDimitry Andric     return getTLSDataSection();
713dff0c46cSDimitry Andric 
714f22ef01cSRoman Divacky   return getDataSection();
715f22ef01cSRoman Divacky }
716f22ef01cSRoman Divacky 
717