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"
16139f7f9bSDimitry Andric #include "llvm/ADT/SmallString.h"
17139f7f9bSDimitry Andric #include "llvm/ADT/StringExtras.h"
18139f7f9bSDimitry Andric #include "llvm/ADT/Triple.h"
19f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineModuleInfoImpls.h"
20139f7f9bSDimitry Andric #include "llvm/IR/Constants.h"
21139f7f9bSDimitry Andric #include "llvm/IR/DataLayout.h"
22139f7f9bSDimitry Andric #include "llvm/IR/DerivedTypes.h"
23139f7f9bSDimitry Andric #include "llvm/IR/Function.h"
24139f7f9bSDimitry Andric #include "llvm/IR/GlobalVariable.h"
2591bc56edSDimitry Andric #include "llvm/IR/Mangler.h"
26139f7f9bSDimitry Andric #include "llvm/IR/Module.h"
27f22ef01cSRoman Divacky #include "llvm/MC/MCContext.h"
28f22ef01cSRoman Divacky #include "llvm/MC/MCExpr.h"
29f22ef01cSRoman Divacky #include "llvm/MC/MCSectionCOFF.h"
30139f7f9bSDimitry Andric #include "llvm/MC/MCSectionELF.h"
31139f7f9bSDimitry Andric #include "llvm/MC/MCSectionMachO.h"
323b0f4066SDimitry Andric #include "llvm/MC/MCStreamer.h"
33f22ef01cSRoman Divacky #include "llvm/MC/MCSymbol.h"
34ff0cc061SDimitry Andric #include "llvm/MC/MCValue.h"
35f22ef01cSRoman Divacky #include "llvm/Support/Dwarf.h"
362754fe60SDimitry Andric #include "llvm/Support/ELF.h"
37f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h"
38f22ef01cSRoman Divacky #include "llvm/Support/raw_ostream.h"
3991bc56edSDimitry Andric #include "llvm/Target/TargetLowering.h"
40139f7f9bSDimitry Andric #include "llvm/Target/TargetMachine.h"
4139d628a0SDimitry Andric #include "llvm/Target/TargetSubtargetInfo.h"
42f22ef01cSRoman Divacky using namespace llvm;
43f22ef01cSRoman Divacky using namespace dwarf;
44f22ef01cSRoman Divacky 
45f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
46f22ef01cSRoman Divacky //                                  ELF
47f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
48f22ef01cSRoman Divacky 
4991bc56edSDimitry Andric MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol(
5091bc56edSDimitry Andric     const GlobalValue *GV, Mangler &Mang, const TargetMachine &TM,
513b0f4066SDimitry Andric     MachineModuleInfo *MMI) const {
523b0f4066SDimitry Andric   unsigned Encoding = getPersonalityEncoding();
5391bc56edSDimitry Andric   if ((Encoding & 0x80) == dwarf::DW_EH_PE_indirect)
54ff0cc061SDimitry Andric     return getContext().getOrCreateSymbol(StringRef("DW.ref.") +
5591bc56edSDimitry Andric                                           TM.getSymbol(GV, Mang)->getName());
5691bc56edSDimitry Andric   if ((Encoding & 0x70) == dwarf::DW_EH_PE_absptr)
5791bc56edSDimitry Andric     return TM.getSymbol(GV, Mang);
5891bc56edSDimitry Andric   report_fatal_error("We do not support this DWARF encoding yet!");
593b0f4066SDimitry Andric }
603b0f4066SDimitry Andric 
613b0f4066SDimitry Andric void TargetLoweringObjectFileELF::emitPersonalityValue(MCStreamer &Streamer,
623b0f4066SDimitry Andric                                                        const TargetMachine &TM,
633b0f4066SDimitry Andric                                                        const MCSymbol *Sym) const {
6417a519f9SDimitry Andric   SmallString<64> NameData("DW.ref.");
6517a519f9SDimitry Andric   NameData += Sym->getName();
66ff0cc061SDimitry Andric   MCSymbol *Label = getContext().getOrCreateSymbol(NameData);
673b0f4066SDimitry Andric   Streamer.EmitSymbolAttribute(Label, MCSA_Hidden);
683b0f4066SDimitry Andric   Streamer.EmitSymbolAttribute(Label, MCSA_Weak);
6917a519f9SDimitry Andric   StringRef Prefix = ".data.";
7017a519f9SDimitry Andric   NameData.insert(NameData.begin(), Prefix.begin(), Prefix.end());
713b0f4066SDimitry Andric   unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP;
72ff0cc061SDimitry Andric   MCSection *Sec = getContext().getELFSection(NameData, ELF::SHT_PROGBITS,
73ff0cc061SDimitry Andric                                               Flags, 0, Label->getName());
74ff0cc061SDimitry Andric   unsigned Size = TM.getDataLayout()->getPointerSize();
753b0f4066SDimitry Andric   Streamer.SwitchSection(Sec);
76ff0cc061SDimitry Andric   Streamer.EmitValueToAlignment(TM.getDataLayout()->getPointerABIAlignment());
773b0f4066SDimitry Andric   Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject);
78dff0c46cSDimitry Andric   const MCExpr *E = MCConstantExpr::Create(Size, getContext());
793b0f4066SDimitry Andric   Streamer.EmitELFSize(Label, E);
803b0f4066SDimitry Andric   Streamer.EmitLabel(Label);
813b0f4066SDimitry Andric 
823b0f4066SDimitry Andric   Streamer.EmitSymbolValue(Sym, Size);
833b0f4066SDimitry Andric }
843b0f4066SDimitry Andric 
8591bc56edSDimitry Andric const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference(
8691bc56edSDimitry Andric     const GlobalValue *GV, unsigned Encoding, Mangler &Mang,
8791bc56edSDimitry Andric     const TargetMachine &TM, MachineModuleInfo *MMI,
88139f7f9bSDimitry Andric     MCStreamer &Streamer) const {
89139f7f9bSDimitry Andric 
90139f7f9bSDimitry Andric   if (Encoding & dwarf::DW_EH_PE_indirect) {
91139f7f9bSDimitry Andric     MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>();
92139f7f9bSDimitry Andric 
9391bc56edSDimitry Andric     MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", Mang, TM);
94139f7f9bSDimitry Andric 
95139f7f9bSDimitry Andric     // Add information about the stub reference to ELFMMI so that the stub
96139f7f9bSDimitry Andric     // gets emitted by the asmprinter.
97139f7f9bSDimitry Andric     MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym);
9891bc56edSDimitry Andric     if (!StubSym.getPointer()) {
9991bc56edSDimitry Andric       MCSymbol *Sym = TM.getSymbol(GV, Mang);
100139f7f9bSDimitry Andric       StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
101139f7f9bSDimitry Andric     }
102139f7f9bSDimitry Andric 
103139f7f9bSDimitry Andric     return TargetLoweringObjectFile::
104139f7f9bSDimitry Andric       getTTypeReference(MCSymbolRefExpr::Create(SSym, getContext()),
105139f7f9bSDimitry Andric                         Encoding & ~dwarf::DW_EH_PE_indirect, Streamer);
106139f7f9bSDimitry Andric   }
107139f7f9bSDimitry Andric 
108139f7f9bSDimitry Andric   return TargetLoweringObjectFile::
10991bc56edSDimitry Andric     getTTypeGlobalReference(GV, Encoding, Mang, TM, MMI, Streamer);
110139f7f9bSDimitry Andric }
111139f7f9bSDimitry Andric 
112f22ef01cSRoman Divacky static SectionKind
113f22ef01cSRoman Divacky getELFKindForNamedSection(StringRef Name, SectionKind K) {
114bd5abe19SDimitry Andric   // N.B.: The defaults used in here are no the same ones used in MC.
115bd5abe19SDimitry Andric   // We follow gcc, MC follows gas. For example, given ".section .eh_frame",
116bd5abe19SDimitry Andric   // both gas and MC will produce a section with no flags. Given
1177ae0e2c9SDimitry Andric   // section(".eh_frame") gcc will produce:
1187ae0e2c9SDimitry Andric   //
119bd5abe19SDimitry Andric   //   .section   .eh_frame,"a",@progbits
120f22ef01cSRoman Divacky   if (Name.empty() || Name[0] != '.') return K;
121f22ef01cSRoman Divacky 
122f22ef01cSRoman Divacky   // Some lame default implementation based on some magic section names.
123f22ef01cSRoman Divacky   if (Name == ".bss" ||
124f22ef01cSRoman Divacky       Name.startswith(".bss.") ||
125f22ef01cSRoman Divacky       Name.startswith(".gnu.linkonce.b.") ||
126f22ef01cSRoman Divacky       Name.startswith(".llvm.linkonce.b.") ||
127f22ef01cSRoman Divacky       Name == ".sbss" ||
128f22ef01cSRoman Divacky       Name.startswith(".sbss.") ||
129f22ef01cSRoman Divacky       Name.startswith(".gnu.linkonce.sb.") ||
130f22ef01cSRoman Divacky       Name.startswith(".llvm.linkonce.sb."))
131f22ef01cSRoman Divacky     return SectionKind::getBSS();
132f22ef01cSRoman Divacky 
133f22ef01cSRoman Divacky   if (Name == ".tdata" ||
134f22ef01cSRoman Divacky       Name.startswith(".tdata.") ||
135f22ef01cSRoman Divacky       Name.startswith(".gnu.linkonce.td.") ||
136f22ef01cSRoman Divacky       Name.startswith(".llvm.linkonce.td."))
137f22ef01cSRoman Divacky     return SectionKind::getThreadData();
138f22ef01cSRoman Divacky 
139f22ef01cSRoman Divacky   if (Name == ".tbss" ||
140f22ef01cSRoman Divacky       Name.startswith(".tbss.") ||
141f22ef01cSRoman Divacky       Name.startswith(".gnu.linkonce.tb.") ||
142f22ef01cSRoman Divacky       Name.startswith(".llvm.linkonce.tb."))
143f22ef01cSRoman Divacky     return SectionKind::getThreadBSS();
144f22ef01cSRoman Divacky 
145f22ef01cSRoman Divacky   return K;
146f22ef01cSRoman Divacky }
147f22ef01cSRoman Divacky 
148f22ef01cSRoman Divacky 
149f22ef01cSRoman Divacky static unsigned getELFSectionType(StringRef Name, SectionKind K) {
150f22ef01cSRoman Divacky 
151f22ef01cSRoman Divacky   if (Name == ".init_array")
1522754fe60SDimitry Andric     return ELF::SHT_INIT_ARRAY;
153f22ef01cSRoman Divacky 
154f22ef01cSRoman Divacky   if (Name == ".fini_array")
1552754fe60SDimitry Andric     return ELF::SHT_FINI_ARRAY;
156f22ef01cSRoman Divacky 
157f22ef01cSRoman Divacky   if (Name == ".preinit_array")
1582754fe60SDimitry Andric     return ELF::SHT_PREINIT_ARRAY;
159f22ef01cSRoman Divacky 
160f22ef01cSRoman Divacky   if (K.isBSS() || K.isThreadBSS())
1612754fe60SDimitry Andric     return ELF::SHT_NOBITS;
162f22ef01cSRoman Divacky 
1632754fe60SDimitry Andric   return ELF::SHT_PROGBITS;
164f22ef01cSRoman Divacky }
165f22ef01cSRoman Divacky 
166ff0cc061SDimitry Andric static unsigned getELFSectionFlags(SectionKind K) {
167f22ef01cSRoman Divacky   unsigned Flags = 0;
168f22ef01cSRoman Divacky 
169f22ef01cSRoman Divacky   if (!K.isMetadata())
1702754fe60SDimitry Andric     Flags |= ELF::SHF_ALLOC;
171f22ef01cSRoman Divacky 
172f22ef01cSRoman Divacky   if (K.isText())
1732754fe60SDimitry Andric     Flags |= ELF::SHF_EXECINSTR;
174f22ef01cSRoman Divacky 
175f22ef01cSRoman Divacky   if (K.isWriteable())
1762754fe60SDimitry Andric     Flags |= ELF::SHF_WRITE;
177f22ef01cSRoman Divacky 
178f22ef01cSRoman Divacky   if (K.isThreadLocal())
1792754fe60SDimitry Andric     Flags |= ELF::SHF_TLS;
180f22ef01cSRoman Divacky 
181ff0cc061SDimitry Andric   if (K.isMergeableCString() || K.isMergeableConst())
1822754fe60SDimitry Andric     Flags |= ELF::SHF_MERGE;
183f22ef01cSRoman Divacky 
184f22ef01cSRoman Divacky   if (K.isMergeableCString())
1852754fe60SDimitry Andric     Flags |= ELF::SHF_STRINGS;
186f22ef01cSRoman Divacky 
187f22ef01cSRoman Divacky   return Flags;
188f22ef01cSRoman Divacky }
189f22ef01cSRoman Divacky 
19091bc56edSDimitry Andric static const Comdat *getELFComdat(const GlobalValue *GV) {
19191bc56edSDimitry Andric   const Comdat *C = GV->getComdat();
19291bc56edSDimitry Andric   if (!C)
19391bc56edSDimitry Andric     return nullptr;
194f22ef01cSRoman Divacky 
19591bc56edSDimitry Andric   if (C->getSelectionKind() != Comdat::Any)
19691bc56edSDimitry Andric     report_fatal_error("ELF COMDATs only support SelectionKind::Any, '" +
19791bc56edSDimitry Andric                        C->getName() + "' cannot be lowered.");
19891bc56edSDimitry Andric 
19991bc56edSDimitry Andric   return C;
20091bc56edSDimitry Andric }
20191bc56edSDimitry Andric 
202ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
20391bc56edSDimitry Andric     const GlobalValue *GV, SectionKind Kind, Mangler &Mang,
20491bc56edSDimitry Andric     const TargetMachine &TM) const {
205f22ef01cSRoman Divacky   StringRef SectionName = GV->getSection();
206f22ef01cSRoman Divacky 
207f22ef01cSRoman Divacky   // Infer section flags from the section name if we can.
208f22ef01cSRoman Divacky   Kind = getELFKindForNamedSection(SectionName, Kind);
209f22ef01cSRoman Divacky 
21091bc56edSDimitry Andric   StringRef Group = "";
21191bc56edSDimitry Andric   unsigned Flags = getELFSectionFlags(Kind);
21291bc56edSDimitry Andric   if (const Comdat *C = getELFComdat(GV)) {
21391bc56edSDimitry Andric     Group = C->getName();
21491bc56edSDimitry Andric     Flags |= ELF::SHF_GROUP;
21591bc56edSDimitry Andric   }
216f22ef01cSRoman Divacky   return getContext().getELFSection(SectionName,
21791bc56edSDimitry Andric                                     getELFSectionType(SectionName, Kind), Flags,
218ff0cc061SDimitry Andric                                     /*EntrySize=*/0, Group);
219f22ef01cSRoman Divacky }
220f22ef01cSRoman Divacky 
221ff0cc061SDimitry Andric /// Return the section prefix name used by options FunctionsSections and
222ff0cc061SDimitry Andric /// DataSections.
22391bc56edSDimitry Andric static StringRef getSectionPrefixForGlobal(SectionKind Kind) {
224ff0cc061SDimitry Andric   if (Kind.isText())
225ff0cc061SDimitry Andric     return ".text";
226ff0cc061SDimitry Andric   if (Kind.isReadOnly())
227ff0cc061SDimitry Andric     return ".rodata";
228ff0cc061SDimitry Andric   if (Kind.isBSS())
229ff0cc061SDimitry Andric     return ".bss";
230ff0cc061SDimitry Andric   if (Kind.isThreadData())
231ff0cc061SDimitry Andric     return ".tdata";
232ff0cc061SDimitry Andric   if (Kind.isThreadBSS())
233ff0cc061SDimitry Andric     return ".tbss";
234ff0cc061SDimitry Andric   if (Kind.isDataNoRel())
235ff0cc061SDimitry Andric     return ".data";
236ff0cc061SDimitry Andric   if (Kind.isDataRelLocal())
237ff0cc061SDimitry Andric     return ".data.rel.local";
238ff0cc061SDimitry Andric   if (Kind.isDataRel())
239ff0cc061SDimitry Andric     return ".data.rel";
240ff0cc061SDimitry Andric   if (Kind.isReadOnlyWithRelLocal())
241ff0cc061SDimitry Andric     return ".data.rel.ro.local";
242f22ef01cSRoman Divacky   assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
243ff0cc061SDimitry Andric   return ".data.rel.ro";
244f22ef01cSRoman Divacky }
245f22ef01cSRoman Divacky 
246ff0cc061SDimitry Andric static MCSectionELF *
247ff0cc061SDimitry Andric selectELFSectionForGlobal(MCContext &Ctx, const GlobalValue *GV,
248ff0cc061SDimitry Andric                           SectionKind Kind, Mangler &Mang,
249ff0cc061SDimitry Andric                           const TargetMachine &TM, bool EmitUniqueSection,
250ff0cc061SDimitry Andric                           unsigned Flags, unsigned *NextUniqueID) {
251ff0cc061SDimitry Andric   unsigned EntrySize = 0;
252ff0cc061SDimitry Andric   if (Kind.isMergeableCString()) {
253ff0cc061SDimitry Andric     if (Kind.isMergeable2ByteCString()) {
254ff0cc061SDimitry Andric       EntrySize = 2;
255ff0cc061SDimitry Andric     } else if (Kind.isMergeable4ByteCString()) {
256ff0cc061SDimitry Andric       EntrySize = 4;
257ff0cc061SDimitry Andric     } else {
258ff0cc061SDimitry Andric       EntrySize = 1;
259ff0cc061SDimitry Andric       assert(Kind.isMergeable1ByteCString() && "unknown string width");
260ff0cc061SDimitry Andric     }
261ff0cc061SDimitry Andric   } else if (Kind.isMergeableConst()) {
262ff0cc061SDimitry Andric     if (Kind.isMergeableConst4()) {
263ff0cc061SDimitry Andric       EntrySize = 4;
264ff0cc061SDimitry Andric     } else if (Kind.isMergeableConst8()) {
265ff0cc061SDimitry Andric       EntrySize = 8;
266ff0cc061SDimitry Andric     } else {
267ff0cc061SDimitry Andric       assert(Kind.isMergeableConst16() && "unknown data width");
268ff0cc061SDimitry Andric       EntrySize = 16;
269ff0cc061SDimitry Andric     }
270ff0cc061SDimitry Andric   }
27191bc56edSDimitry Andric 
2722754fe60SDimitry Andric   StringRef Group = "";
273ff0cc061SDimitry Andric   if (const Comdat *C = getELFComdat(GV)) {
2742754fe60SDimitry Andric     Flags |= ELF::SHF_GROUP;
275ff0cc061SDimitry Andric     Group = C->getName();
2762754fe60SDimitry Andric   }
2772754fe60SDimitry Andric 
278ff0cc061SDimitry Andric   bool UniqueSectionNames = TM.getUniqueSectionNames();
279ff0cc061SDimitry Andric   SmallString<128> Name;
280ff0cc061SDimitry Andric   if (Kind.isMergeableCString()) {
281f22ef01cSRoman Divacky     // We also need alignment here.
282f22ef01cSRoman Divacky     // FIXME: this is getting the alignment of the character, not the
283f22ef01cSRoman Divacky     // alignment of the global!
284f22ef01cSRoman Divacky     unsigned Align =
285ff0cc061SDimitry Andric         TM.getDataLayout()->getPreferredAlignment(cast<GlobalVariable>(GV));
286f22ef01cSRoman Divacky 
287ff0cc061SDimitry Andric     std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + ".";
288ff0cc061SDimitry Andric     Name = SizeSpec + utostr(Align);
289ff0cc061SDimitry Andric   } else if (Kind.isMergeableConst()) {
290ff0cc061SDimitry Andric     Name = ".rodata.cst";
291ff0cc061SDimitry Andric     Name += utostr(EntrySize);
292ff0cc061SDimitry Andric   } else {
293ff0cc061SDimitry Andric     Name = getSectionPrefixForGlobal(Kind);
294ff0cc061SDimitry Andric   }
295ff0cc061SDimitry Andric 
296ff0cc061SDimitry Andric   if (EmitUniqueSection && UniqueSectionNames) {
297ff0cc061SDimitry Andric     Name.push_back('.');
298ff0cc061SDimitry Andric     TM.getNameWithPrefix(Name, GV, Mang, true);
299ff0cc061SDimitry Andric   }
300ff0cc061SDimitry Andric   unsigned UniqueID = ~0;
301ff0cc061SDimitry Andric   if (EmitUniqueSection && !UniqueSectionNames) {
302ff0cc061SDimitry Andric     UniqueID = *NextUniqueID;
303ff0cc061SDimitry Andric     (*NextUniqueID)++;
304ff0cc061SDimitry Andric   }
305ff0cc061SDimitry Andric   return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags,
306ff0cc061SDimitry Andric                            EntrySize, Group, UniqueID);
307ff0cc061SDimitry Andric }
308ff0cc061SDimitry Andric 
309ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal(
310ff0cc061SDimitry Andric     const GlobalValue *GV, SectionKind Kind, Mangler &Mang,
311ff0cc061SDimitry Andric     const TargetMachine &TM) const {
312ff0cc061SDimitry Andric   unsigned Flags = getELFSectionFlags(Kind);
313ff0cc061SDimitry Andric 
314ff0cc061SDimitry Andric   // If we have -ffunction-section or -fdata-section then we should emit the
315ff0cc061SDimitry Andric   // global value to a uniqued section specifically for it.
316ff0cc061SDimitry Andric   bool EmitUniqueSection = false;
317ff0cc061SDimitry Andric   if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) {
318ff0cc061SDimitry Andric     if (Kind.isText())
319ff0cc061SDimitry Andric       EmitUniqueSection = TM.getFunctionSections();
320f22ef01cSRoman Divacky     else
321ff0cc061SDimitry Andric       EmitUniqueSection = TM.getDataSections();
322ff0cc061SDimitry Andric   }
323ff0cc061SDimitry Andric   EmitUniqueSection |= GV->hasComdat();
324f22ef01cSRoman Divacky 
325ff0cc061SDimitry Andric   return selectELFSectionForGlobal(getContext(), GV, Kind, Mang, TM,
326ff0cc061SDimitry Andric                                    EmitUniqueSection, Flags, &NextUniqueID);
327f22ef01cSRoman Divacky }
328f22ef01cSRoman Divacky 
329ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(
330ff0cc061SDimitry Andric     const Function &F, Mangler &Mang, const TargetMachine &TM) const {
331ff0cc061SDimitry Andric   // If the function can be removed, produce a unique section so that
332ff0cc061SDimitry Andric   // the table doesn't prevent the removal.
333ff0cc061SDimitry Andric   const Comdat *C = F.getComdat();
334ff0cc061SDimitry Andric   bool EmitUniqueSection = TM.getFunctionSections() || C;
335ff0cc061SDimitry Andric   if (!EmitUniqueSection)
336ff0cc061SDimitry Andric     return ReadOnlySection;
337ff0cc061SDimitry Andric 
338ff0cc061SDimitry Andric   return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(),
339ff0cc061SDimitry Andric                                    Mang, TM, EmitUniqueSection, ELF::SHF_ALLOC,
340ff0cc061SDimitry Andric                                    &NextUniqueID);
341f22ef01cSRoman Divacky }
342f22ef01cSRoman Divacky 
343ff0cc061SDimitry Andric bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection(
344ff0cc061SDimitry Andric     bool UsesLabelDifference, const Function &F) const {
345ff0cc061SDimitry Andric   // We can always create relative relocations, so use another section
346ff0cc061SDimitry Andric   // that can be marked non-executable.
347ff0cc061SDimitry Andric   return false;
348f22ef01cSRoman Divacky }
349f22ef01cSRoman Divacky 
350ff0cc061SDimitry Andric /// Given a mergeable constant with the specified size and relocation
351ff0cc061SDimitry Andric /// information, return a section that it should be placed in.
352ff0cc061SDimitry Andric MCSection *
35391bc56edSDimitry Andric TargetLoweringObjectFileELF::getSectionForConstant(SectionKind Kind,
35491bc56edSDimitry Andric                                                    const Constant *C) const {
355f22ef01cSRoman Divacky   if (Kind.isMergeableConst4() && MergeableConst4Section)
356f22ef01cSRoman Divacky     return MergeableConst4Section;
357f22ef01cSRoman Divacky   if (Kind.isMergeableConst8() && MergeableConst8Section)
358f22ef01cSRoman Divacky     return MergeableConst8Section;
359f22ef01cSRoman Divacky   if (Kind.isMergeableConst16() && MergeableConst16Section)
360f22ef01cSRoman Divacky     return MergeableConst16Section;
361f22ef01cSRoman Divacky   if (Kind.isReadOnly())
362f22ef01cSRoman Divacky     return ReadOnlySection;
363f22ef01cSRoman Divacky 
364f22ef01cSRoman Divacky   if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
365f22ef01cSRoman Divacky   assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
366f22ef01cSRoman Divacky   return DataRelROSection;
367f22ef01cSRoman Divacky }
368f22ef01cSRoman Divacky 
369ff0cc061SDimitry Andric static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray,
370ff0cc061SDimitry Andric                                               bool IsCtor, unsigned Priority,
37139d628a0SDimitry Andric                                               const MCSymbol *KeySym) {
37239d628a0SDimitry Andric   std::string Name;
37339d628a0SDimitry Andric   unsigned Type;
37439d628a0SDimitry Andric   unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE;
37539d628a0SDimitry Andric   StringRef COMDAT = KeySym ? KeySym->getName() : "";
37639d628a0SDimitry Andric 
37739d628a0SDimitry Andric   if (KeySym)
37839d628a0SDimitry Andric     Flags |= ELF::SHF_GROUP;
379dff0c46cSDimitry Andric 
3807ae0e2c9SDimitry Andric   if (UseInitArray) {
38139d628a0SDimitry Andric     if (IsCtor) {
38239d628a0SDimitry Andric       Type = ELF::SHT_INIT_ARRAY;
38339d628a0SDimitry Andric       Name = ".init_array";
3847ae0e2c9SDimitry Andric     } else {
38539d628a0SDimitry Andric       Type = ELF::SHT_FINI_ARRAY;
38639d628a0SDimitry Andric       Name = ".fini_array";
387dff0c46cSDimitry Andric     }
38839d628a0SDimitry Andric     if (Priority != 65535) {
38939d628a0SDimitry Andric       Name += '.';
39039d628a0SDimitry Andric       Name += utostr(Priority);
39139d628a0SDimitry Andric     }
39239d628a0SDimitry Andric   } else {
39339d628a0SDimitry Andric     // The default scheme is .ctor / .dtor, so we have to invert the priority
39439d628a0SDimitry Andric     // numbering.
39539d628a0SDimitry Andric     if (IsCtor)
39639d628a0SDimitry Andric       Name = ".ctors";
39739d628a0SDimitry Andric     else
39839d628a0SDimitry Andric       Name = ".dtors";
39939d628a0SDimitry Andric     if (Priority != 65535) {
40039d628a0SDimitry Andric       Name += '.';
40139d628a0SDimitry Andric       Name += utostr(65535 - Priority);
40239d628a0SDimitry Andric     }
40339d628a0SDimitry Andric     Type = ELF::SHT_PROGBITS;
40439d628a0SDimitry Andric   }
40539d628a0SDimitry Andric 
406ff0cc061SDimitry Andric   return Ctx.getELFSection(Name, Type, Flags, 0, COMDAT);
40739d628a0SDimitry Andric }
40839d628a0SDimitry Andric 
409ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticCtorSection(
41039d628a0SDimitry Andric     unsigned Priority, const MCSymbol *KeySym) const {
41139d628a0SDimitry Andric   return getStaticStructorSection(getContext(), UseInitArray, true, Priority,
41239d628a0SDimitry Andric                                   KeySym);
4137ae0e2c9SDimitry Andric }
414dff0c46cSDimitry Andric 
415ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticDtorSection(
41691bc56edSDimitry Andric     unsigned Priority, const MCSymbol *KeySym) const {
41739d628a0SDimitry Andric   return getStaticStructorSection(getContext(), UseInitArray, false, Priority,
41839d628a0SDimitry Andric                                   KeySym);
4197ae0e2c9SDimitry Andric }
4207ae0e2c9SDimitry Andric 
4217ae0e2c9SDimitry Andric void
4227ae0e2c9SDimitry Andric TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) {
4237ae0e2c9SDimitry Andric   UseInitArray = UseInitArray_;
4247ae0e2c9SDimitry Andric   if (!UseInitArray)
4257ae0e2c9SDimitry Andric     return;
4267ae0e2c9SDimitry Andric 
427ff0cc061SDimitry Andric   StaticCtorSection = getContext().getELFSection(
428ff0cc061SDimitry Andric       ".init_array", ELF::SHT_INIT_ARRAY, ELF::SHF_WRITE | ELF::SHF_ALLOC);
429ff0cc061SDimitry Andric   StaticDtorSection = getContext().getELFSection(
430ff0cc061SDimitry Andric       ".fini_array", ELF::SHT_FINI_ARRAY, ELF::SHF_WRITE | ELF::SHF_ALLOC);
4317ae0e2c9SDimitry Andric }
432dff0c46cSDimitry Andric 
433f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
434f22ef01cSRoman Divacky //                                 MachO
435f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
436f22ef01cSRoman Divacky 
437ff0cc061SDimitry Andric TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO()
438ff0cc061SDimitry Andric   : TargetLoweringObjectFile() {
439ff0cc061SDimitry Andric   SupportIndirectSymViaGOTPCRel = true;
440ff0cc061SDimitry Andric }
441ff0cc061SDimitry Andric 
44291bc56edSDimitry Andric /// getDepLibFromLinkerOpt - Extract the dependent library name from a linker
44391bc56edSDimitry Andric /// option string. Returns StringRef() if the option does not specify a library.
44491bc56edSDimitry Andric StringRef TargetLoweringObjectFileMachO::
44591bc56edSDimitry Andric getDepLibFromLinkerOpt(StringRef LinkerOption) const {
44691bc56edSDimitry Andric   const char *LibCmd = "-l";
44791bc56edSDimitry Andric   if (LinkerOption.startswith(LibCmd))
44891bc56edSDimitry Andric     return LinkerOption.substr(strlen(LibCmd));
44991bc56edSDimitry Andric   return StringRef();
45091bc56edSDimitry Andric }
45191bc56edSDimitry Andric 
452139f7f9bSDimitry Andric /// emitModuleFlags - Perform code emission for module flags.
453dff0c46cSDimitry Andric void TargetLoweringObjectFileMachO::
454dff0c46cSDimitry Andric emitModuleFlags(MCStreamer &Streamer,
455dff0c46cSDimitry Andric                 ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
45691bc56edSDimitry Andric                 Mangler &Mang, const TargetMachine &TM) const {
457dff0c46cSDimitry Andric   unsigned VersionVal = 0;
4587ae0e2c9SDimitry Andric   unsigned ImageInfoFlags = 0;
45991bc56edSDimitry Andric   MDNode *LinkerOptions = nullptr;
460dff0c46cSDimitry Andric   StringRef SectionVal;
461dff0c46cSDimitry Andric 
462dff0c46cSDimitry Andric   for (ArrayRef<Module::ModuleFlagEntry>::iterator
463dff0c46cSDimitry Andric          i = ModuleFlags.begin(), e = ModuleFlags.end(); i != e; ++i) {
464dff0c46cSDimitry Andric     const Module::ModuleFlagEntry &MFE = *i;
465dff0c46cSDimitry Andric 
466dff0c46cSDimitry Andric     // Ignore flags with 'Require' behavior.
467dff0c46cSDimitry Andric     if (MFE.Behavior == Module::Require)
468dff0c46cSDimitry Andric       continue;
469dff0c46cSDimitry Andric 
470dff0c46cSDimitry Andric     StringRef Key = MFE.Key->getString();
47139d628a0SDimitry Andric     Metadata *Val = MFE.Val;
472dff0c46cSDimitry Andric 
473139f7f9bSDimitry Andric     if (Key == "Objective-C Image Info Version") {
47439d628a0SDimitry Andric       VersionVal = mdconst::extract<ConstantInt>(Val)->getZExtValue();
475139f7f9bSDimitry Andric     } else if (Key == "Objective-C Garbage Collection" ||
4767ae0e2c9SDimitry Andric                Key == "Objective-C GC Only" ||
47739d628a0SDimitry Andric                Key == "Objective-C Is Simulated" ||
47839d628a0SDimitry Andric                Key == "Objective-C Image Swift Version") {
47939d628a0SDimitry Andric       ImageInfoFlags |= mdconst::extract<ConstantInt>(Val)->getZExtValue();
480139f7f9bSDimitry Andric     } else if (Key == "Objective-C Image Info Section") {
481dff0c46cSDimitry Andric       SectionVal = cast<MDString>(Val)->getString();
482139f7f9bSDimitry Andric     } else if (Key == "Linker Options") {
483139f7f9bSDimitry Andric       LinkerOptions = cast<MDNode>(Val);
484139f7f9bSDimitry Andric     }
485139f7f9bSDimitry Andric   }
486139f7f9bSDimitry Andric 
487139f7f9bSDimitry Andric   // Emit the linker options if present.
488139f7f9bSDimitry Andric   if (LinkerOptions) {
489139f7f9bSDimitry Andric     for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) {
490139f7f9bSDimitry Andric       MDNode *MDOptions = cast<MDNode>(LinkerOptions->getOperand(i));
491139f7f9bSDimitry Andric       SmallVector<std::string, 4> StrOptions;
492139f7f9bSDimitry Andric 
493139f7f9bSDimitry Andric       // Convert to strings.
494139f7f9bSDimitry Andric       for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) {
495139f7f9bSDimitry Andric         MDString *MDOption = cast<MDString>(MDOptions->getOperand(ii));
496139f7f9bSDimitry Andric         StrOptions.push_back(MDOption->getString());
497139f7f9bSDimitry Andric       }
498139f7f9bSDimitry Andric 
499139f7f9bSDimitry Andric       Streamer.EmitLinkerOptions(StrOptions);
500139f7f9bSDimitry Andric     }
501dff0c46cSDimitry Andric   }
502dff0c46cSDimitry Andric 
503dff0c46cSDimitry Andric   // The section is mandatory. If we don't have it, then we don't have GC info.
504dff0c46cSDimitry Andric   if (SectionVal.empty()) return;
505dff0c46cSDimitry Andric 
506dff0c46cSDimitry Andric   StringRef Segment, Section;
507dff0c46cSDimitry Andric   unsigned TAA = 0, StubSize = 0;
508dff0c46cSDimitry Andric   bool TAAParsed;
509dff0c46cSDimitry Andric   std::string ErrorCode =
510dff0c46cSDimitry Andric     MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section,
511dff0c46cSDimitry Andric                                           TAA, TAAParsed, StubSize);
512dff0c46cSDimitry Andric   if (!ErrorCode.empty())
513dff0c46cSDimitry Andric     // If invalid, report the error with report_fatal_error.
514dff0c46cSDimitry Andric     report_fatal_error("Invalid section specifier '" + Section + "': " +
515dff0c46cSDimitry Andric                        ErrorCode + ".");
516dff0c46cSDimitry Andric 
517dff0c46cSDimitry Andric   // Get the section.
518ff0cc061SDimitry Andric   MCSectionMachO *S = getContext().getMachOSection(
519ff0cc061SDimitry Andric       Segment, Section, TAA, StubSize, SectionKind::getDataNoRel());
520dff0c46cSDimitry Andric   Streamer.SwitchSection(S);
521dff0c46cSDimitry Andric   Streamer.EmitLabel(getContext().
522ff0cc061SDimitry Andric                      getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO")));
523dff0c46cSDimitry Andric   Streamer.EmitIntValue(VersionVal, 4);
5247ae0e2c9SDimitry Andric   Streamer.EmitIntValue(ImageInfoFlags, 4);
525dff0c46cSDimitry Andric   Streamer.AddBlankLine();
526dff0c46cSDimitry Andric }
527dff0c46cSDimitry Andric 
52891bc56edSDimitry Andric static void checkMachOComdat(const GlobalValue *GV) {
52991bc56edSDimitry Andric   const Comdat *C = GV->getComdat();
53091bc56edSDimitry Andric   if (!C)
53191bc56edSDimitry Andric     return;
53291bc56edSDimitry Andric 
53391bc56edSDimitry Andric   report_fatal_error("MachO doesn't support COMDATs, '" + C->getName() +
53491bc56edSDimitry Andric                      "' cannot be lowered.");
53591bc56edSDimitry Andric }
53691bc56edSDimitry Andric 
537ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal(
53891bc56edSDimitry Andric     const GlobalValue *GV, SectionKind Kind, Mangler &Mang,
53991bc56edSDimitry Andric     const TargetMachine &TM) const {
540f22ef01cSRoman Divacky   // Parse the section specifier and create it if valid.
541f22ef01cSRoman Divacky   StringRef Segment, Section;
5423b0f4066SDimitry Andric   unsigned TAA = 0, StubSize = 0;
5433b0f4066SDimitry Andric   bool TAAParsed;
54491bc56edSDimitry Andric 
54591bc56edSDimitry Andric   checkMachOComdat(GV);
54691bc56edSDimitry Andric 
547f22ef01cSRoman Divacky   std::string ErrorCode =
548f22ef01cSRoman Divacky     MCSectionMachO::ParseSectionSpecifier(GV->getSection(), Segment, Section,
5493b0f4066SDimitry Andric                                           TAA, TAAParsed, StubSize);
550f22ef01cSRoman Divacky   if (!ErrorCode.empty()) {
551f22ef01cSRoman Divacky     // If invalid, report the error with report_fatal_error.
552dff0c46cSDimitry Andric     report_fatal_error("Global variable '" + GV->getName() +
553dff0c46cSDimitry Andric                        "' has an invalid section specifier '" +
554dff0c46cSDimitry Andric                        GV->getSection() + "': " + ErrorCode + ".");
555f22ef01cSRoman Divacky   }
556f22ef01cSRoman Divacky 
557f22ef01cSRoman Divacky   // Get the section.
558ff0cc061SDimitry Andric   MCSectionMachO *S =
559f22ef01cSRoman Divacky       getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind);
560f22ef01cSRoman Divacky 
561dd6029ffSDimitry Andric   // If TAA wasn't set by ParseSectionSpecifier() above,
562dd6029ffSDimitry Andric   // use the value returned by getMachOSection() as a default.
5633b0f4066SDimitry Andric   if (!TAAParsed)
564dd6029ffSDimitry Andric     TAA = S->getTypeAndAttributes();
565dd6029ffSDimitry Andric 
566f22ef01cSRoman Divacky   // Okay, now that we got the section, verify that the TAA & StubSize agree.
567f22ef01cSRoman Divacky   // If the user declared multiple globals with different section flags, we need
568f22ef01cSRoman Divacky   // to reject it here.
569f22ef01cSRoman Divacky   if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) {
570f22ef01cSRoman Divacky     // If invalid, report the error with report_fatal_error.
571dff0c46cSDimitry Andric     report_fatal_error("Global variable '" + GV->getName() +
572f22ef01cSRoman Divacky                        "' section type or attributes does not match previous"
573f22ef01cSRoman Divacky                        " section specifier");
574f22ef01cSRoman Divacky   }
575f22ef01cSRoman Divacky 
576f22ef01cSRoman Divacky   return S;
577f22ef01cSRoman Divacky }
578f22ef01cSRoman Divacky 
579ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal(
580ff0cc061SDimitry Andric     const GlobalValue *GV, SectionKind Kind, Mangler &Mang,
581ff0cc061SDimitry Andric     const TargetMachine &TM) const {
58291bc56edSDimitry Andric   checkMachOComdat(GV);
583f785676fSDimitry Andric 
584f785676fSDimitry Andric   // Handle thread local data.
585f785676fSDimitry Andric   if (Kind.isThreadBSS()) return TLSBSSSection;
586f785676fSDimitry Andric   if (Kind.isThreadData()) return TLSDataSection;
587f785676fSDimitry Andric 
588f22ef01cSRoman Divacky   if (Kind.isText())
589f22ef01cSRoman Divacky     return GV->isWeakForLinker() ? TextCoalSection : TextSection;
590f22ef01cSRoman Divacky 
591f22ef01cSRoman Divacky   // If this is weak/linkonce, put this in a coalescable section, either in text
592f22ef01cSRoman Divacky   // or data depending on if it is writable.
593f22ef01cSRoman Divacky   if (GV->isWeakForLinker()) {
594f22ef01cSRoman Divacky     if (Kind.isReadOnly())
595f22ef01cSRoman Divacky       return ConstTextCoalSection;
596f22ef01cSRoman Divacky     return DataCoalSection;
597f22ef01cSRoman Divacky   }
598f22ef01cSRoman Divacky 
599f22ef01cSRoman Divacky   // FIXME: Alignment check should be handled by section classifier.
600f22ef01cSRoman Divacky   if (Kind.isMergeable1ByteCString() &&
601ff0cc061SDimitry Andric       TM.getDataLayout()->getPreferredAlignment(cast<GlobalVariable>(GV)) < 32)
602f22ef01cSRoman Divacky     return CStringSection;
603f22ef01cSRoman Divacky 
604f22ef01cSRoman Divacky   // Do not put 16-bit arrays in the UString section if they have an
605f22ef01cSRoman Divacky   // externally visible label, this runs into issues with certain linker
606f22ef01cSRoman Divacky   // versions.
607f22ef01cSRoman Divacky   if (Kind.isMergeable2ByteCString() && !GV->hasExternalLinkage() &&
608ff0cc061SDimitry Andric       TM.getDataLayout()->getPreferredAlignment(cast<GlobalVariable>(GV)) < 32)
609f22ef01cSRoman Divacky     return UStringSection;
610f22ef01cSRoman Divacky 
61139d628a0SDimitry Andric   // With MachO only variables whose corresponding symbol starts with 'l' or
61239d628a0SDimitry Andric   // 'L' can be merged, so we only try merging GVs with private linkage.
61339d628a0SDimitry Andric   if (GV->hasPrivateLinkage() && Kind.isMergeableConst()) {
614f22ef01cSRoman Divacky     if (Kind.isMergeableConst4())
615f22ef01cSRoman Divacky       return FourByteConstantSection;
616f22ef01cSRoman Divacky     if (Kind.isMergeableConst8())
617f22ef01cSRoman Divacky       return EightByteConstantSection;
61891bc56edSDimitry Andric     if (Kind.isMergeableConst16())
619f22ef01cSRoman Divacky       return SixteenByteConstantSection;
620f22ef01cSRoman Divacky   }
621f22ef01cSRoman Divacky 
622f22ef01cSRoman Divacky   // Otherwise, if it is readonly, but not something we can specially optimize,
623f22ef01cSRoman Divacky   // just drop it in .const.
624f22ef01cSRoman Divacky   if (Kind.isReadOnly())
625f22ef01cSRoman Divacky     return ReadOnlySection;
626f22ef01cSRoman Divacky 
627f22ef01cSRoman Divacky   // If this is marked const, put it into a const section.  But if the dynamic
628f22ef01cSRoman Divacky   // linker needs to write to it, put it in the data segment.
629f22ef01cSRoman Divacky   if (Kind.isReadOnlyWithRel())
630f22ef01cSRoman Divacky     return ConstDataSection;
631f22ef01cSRoman Divacky 
632f22ef01cSRoman Divacky   // Put zero initialized globals with strong external linkage in the
633f22ef01cSRoman Divacky   // DATA, __common section with the .zerofill directive.
634f22ef01cSRoman Divacky   if (Kind.isBSSExtern())
635f22ef01cSRoman Divacky     return DataCommonSection;
636f22ef01cSRoman Divacky 
637f22ef01cSRoman Divacky   // Put zero initialized globals with local linkage in __DATA,__bss directive
638f22ef01cSRoman Divacky   // with the .zerofill directive (aka .lcomm).
639f22ef01cSRoman Divacky   if (Kind.isBSSLocal())
640f22ef01cSRoman Divacky     return DataBSSSection;
641f22ef01cSRoman Divacky 
642f22ef01cSRoman Divacky   // Otherwise, just drop the variable in the normal data section.
643f22ef01cSRoman Divacky   return DataSection;
644f22ef01cSRoman Divacky }
645f22ef01cSRoman Divacky 
646ff0cc061SDimitry Andric MCSection *
64791bc56edSDimitry Andric TargetLoweringObjectFileMachO::getSectionForConstant(SectionKind Kind,
64891bc56edSDimitry Andric                                                      const Constant *C) const {
649f22ef01cSRoman Divacky   // If this constant requires a relocation, we have to put it in the data
650f22ef01cSRoman Divacky   // segment, not in the text segment.
651f22ef01cSRoman Divacky   if (Kind.isDataRel() || Kind.isReadOnlyWithRel())
652f22ef01cSRoman Divacky     return ConstDataSection;
653f22ef01cSRoman Divacky 
654f22ef01cSRoman Divacky   if (Kind.isMergeableConst4())
655f22ef01cSRoman Divacky     return FourByteConstantSection;
656f22ef01cSRoman Divacky   if (Kind.isMergeableConst8())
657f22ef01cSRoman Divacky     return EightByteConstantSection;
65891bc56edSDimitry Andric   if (Kind.isMergeableConst16())
659f22ef01cSRoman Divacky     return SixteenByteConstantSection;
660f22ef01cSRoman Divacky   return ReadOnlySection;  // .const
661f22ef01cSRoman Divacky }
662f22ef01cSRoman Divacky 
66391bc56edSDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference(
66491bc56edSDimitry Andric     const GlobalValue *GV, unsigned Encoding, Mangler &Mang,
66591bc56edSDimitry Andric     const TargetMachine &TM, MachineModuleInfo *MMI,
666f22ef01cSRoman Divacky     MCStreamer &Streamer) const {
667f22ef01cSRoman Divacky   // The mach-o version of this method defaults to returning a stub reference.
668f22ef01cSRoman Divacky 
669f22ef01cSRoman Divacky   if (Encoding & DW_EH_PE_indirect) {
670f22ef01cSRoman Divacky     MachineModuleInfoMachO &MachOMMI =
671f22ef01cSRoman Divacky       MMI->getObjFileInfo<MachineModuleInfoMachO>();
672f22ef01cSRoman Divacky 
67391bc56edSDimitry Andric     MCSymbol *SSym =
67491bc56edSDimitry Andric         getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", Mang, TM);
675f22ef01cSRoman Divacky 
676f22ef01cSRoman Divacky     // Add information about the stub reference to MachOMMI so that the stub
677f22ef01cSRoman Divacky     // gets emitted by the asmprinter.
678f8254f43SDimitry Andric     MachineModuleInfoImpl::StubValueTy &StubSym =
679f8254f43SDimitry Andric       GV->hasHiddenVisibility() ? MachOMMI.getHiddenGVStubEntry(SSym) :
680f8254f43SDimitry Andric                                   MachOMMI.getGVStubEntry(SSym);
68191bc56edSDimitry Andric     if (!StubSym.getPointer()) {
68291bc56edSDimitry Andric       MCSymbol *Sym = TM.getSymbol(GV, Mang);
683f22ef01cSRoman Divacky       StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
684f22ef01cSRoman Divacky     }
685f22ef01cSRoman Divacky 
686f22ef01cSRoman Divacky     return TargetLoweringObjectFile::
687139f7f9bSDimitry Andric       getTTypeReference(MCSymbolRefExpr::Create(SSym, getContext()),
688139f7f9bSDimitry Andric                         Encoding & ~dwarf::DW_EH_PE_indirect, Streamer);
689f22ef01cSRoman Divacky   }
690f22ef01cSRoman Divacky 
69191bc56edSDimitry Andric   return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, Mang,
69291bc56edSDimitry Andric                                                            TM, MMI, Streamer);
693f22ef01cSRoman Divacky }
694f22ef01cSRoman Divacky 
69591bc56edSDimitry Andric MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol(
69691bc56edSDimitry Andric     const GlobalValue *GV, Mangler &Mang, const TargetMachine &TM,
6973b0f4066SDimitry Andric     MachineModuleInfo *MMI) const {
6983b0f4066SDimitry Andric   // The mach-o version of this method defaults to returning a stub reference.
6993b0f4066SDimitry Andric   MachineModuleInfoMachO &MachOMMI =
7003b0f4066SDimitry Andric     MMI->getObjFileInfo<MachineModuleInfoMachO>();
7013b0f4066SDimitry Andric 
70291bc56edSDimitry Andric   MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", Mang, TM);
7033b0f4066SDimitry Andric 
7043b0f4066SDimitry Andric   // Add information about the stub reference to MachOMMI so that the stub
7053b0f4066SDimitry Andric   // gets emitted by the asmprinter.
706dff0c46cSDimitry Andric   MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym);
70791bc56edSDimitry Andric   if (!StubSym.getPointer()) {
70891bc56edSDimitry Andric     MCSymbol *Sym = TM.getSymbol(GV, Mang);
7093b0f4066SDimitry Andric     StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
7103b0f4066SDimitry Andric   }
7113b0f4066SDimitry Andric 
7123b0f4066SDimitry Andric   return SSym;
7133b0f4066SDimitry Andric }
7143b0f4066SDimitry Andric 
715ff0cc061SDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel(
716ff0cc061SDimitry Andric     const MCSymbol *Sym, const MCValue &MV, int64_t Offset,
717ff0cc061SDimitry Andric     MachineModuleInfo *MMI, MCStreamer &Streamer) const {
718ff0cc061SDimitry Andric   // Although MachO 32-bit targets do not explictly have a GOTPCREL relocation
719ff0cc061SDimitry Andric   // as 64-bit do, we replace the GOT equivalent by accessing the final symbol
720ff0cc061SDimitry Andric   // through a non_lazy_ptr stub instead. One advantage is that it allows the
721ff0cc061SDimitry Andric   // computation of deltas to final external symbols. Example:
722ff0cc061SDimitry Andric   //
723ff0cc061SDimitry Andric   //    _extgotequiv:
724ff0cc061SDimitry Andric   //       .long   _extfoo
725ff0cc061SDimitry Andric   //
726ff0cc061SDimitry Andric   //    _delta:
727ff0cc061SDimitry Andric   //       .long   _extgotequiv-_delta
728ff0cc061SDimitry Andric   //
729ff0cc061SDimitry Andric   // is transformed to:
730ff0cc061SDimitry Andric   //
731ff0cc061SDimitry Andric   //    _delta:
732ff0cc061SDimitry Andric   //       .long   L_extfoo$non_lazy_ptr-(_delta+0)
733ff0cc061SDimitry Andric   //
734ff0cc061SDimitry Andric   //       .section        __IMPORT,__pointers,non_lazy_symbol_pointers
735ff0cc061SDimitry Andric   //    L_extfoo$non_lazy_ptr:
736ff0cc061SDimitry Andric   //       .indirect_symbol        _extfoo
737ff0cc061SDimitry Andric   //       .long   0
738ff0cc061SDimitry Andric   //
739ff0cc061SDimitry Andric   MachineModuleInfoMachO &MachOMMI =
740ff0cc061SDimitry Andric     MMI->getObjFileInfo<MachineModuleInfoMachO>();
741ff0cc061SDimitry Andric   MCContext &Ctx = getContext();
742ff0cc061SDimitry Andric 
743ff0cc061SDimitry Andric   // The offset must consider the original displacement from the base symbol
744ff0cc061SDimitry Andric   // since 32-bit targets don't have a GOTPCREL to fold the PC displacement.
745ff0cc061SDimitry Andric   Offset = -MV.getConstant();
746ff0cc061SDimitry Andric   const MCSymbol *BaseSym = &MV.getSymB()->getSymbol();
747ff0cc061SDimitry Andric 
748ff0cc061SDimitry Andric   // Access the final symbol via sym$non_lazy_ptr and generate the appropriated
749ff0cc061SDimitry Andric   // non_lazy_ptr stubs.
750ff0cc061SDimitry Andric   SmallString<128> Name;
751ff0cc061SDimitry Andric   StringRef Suffix = "$non_lazy_ptr";
752ff0cc061SDimitry Andric   Name += DL->getPrivateGlobalPrefix();
753ff0cc061SDimitry Andric   Name += Sym->getName();
754ff0cc061SDimitry Andric   Name += Suffix;
755ff0cc061SDimitry Andric   MCSymbol *Stub = Ctx.getOrCreateSymbol(Name);
756ff0cc061SDimitry Andric 
757ff0cc061SDimitry Andric   MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub);
758ff0cc061SDimitry Andric   if (!StubSym.getPointer())
759ff0cc061SDimitry Andric     StubSym = MachineModuleInfoImpl::
760ff0cc061SDimitry Andric       StubValueTy(const_cast<MCSymbol *>(Sym), true /* access indirectly */);
761ff0cc061SDimitry Andric 
762ff0cc061SDimitry Andric   const MCExpr *BSymExpr =
763ff0cc061SDimitry Andric     MCSymbolRefExpr::Create(BaseSym, MCSymbolRefExpr::VK_None, Ctx);
764ff0cc061SDimitry Andric   const MCExpr *LHS =
765ff0cc061SDimitry Andric     MCSymbolRefExpr::Create(Stub, MCSymbolRefExpr::VK_None, Ctx);
766ff0cc061SDimitry Andric 
767ff0cc061SDimitry Andric   if (!Offset)
768ff0cc061SDimitry Andric     return MCBinaryExpr::CreateSub(LHS, BSymExpr, Ctx);
769ff0cc061SDimitry Andric 
770ff0cc061SDimitry Andric   const MCExpr *RHS =
771ff0cc061SDimitry Andric     MCBinaryExpr::CreateAdd(BSymExpr, MCConstantExpr::Create(Offset, Ctx), Ctx);
772ff0cc061SDimitry Andric   return MCBinaryExpr::CreateSub(LHS, RHS, Ctx);
773ff0cc061SDimitry Andric }
774ff0cc061SDimitry Andric 
775f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
776f22ef01cSRoman Divacky //                                  COFF
777f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
778f22ef01cSRoman Divacky 
779f22ef01cSRoman Divacky static unsigned
780f22ef01cSRoman Divacky getCOFFSectionFlags(SectionKind K) {
781f22ef01cSRoman Divacky   unsigned Flags = 0;
782f22ef01cSRoman Divacky 
783ffd1746dSEd Schouten   if (K.isMetadata())
784f22ef01cSRoman Divacky     Flags |=
785ffd1746dSEd Schouten       COFF::IMAGE_SCN_MEM_DISCARDABLE;
786f22ef01cSRoman Divacky   else if (K.isText())
787f22ef01cSRoman Divacky     Flags |=
788ffd1746dSEd Schouten       COFF::IMAGE_SCN_MEM_EXECUTE |
7892754fe60SDimitry Andric       COFF::IMAGE_SCN_MEM_READ |
790ffd1746dSEd Schouten       COFF::IMAGE_SCN_CNT_CODE;
791f22ef01cSRoman Divacky   else if (K.isBSS())
792f22ef01cSRoman Divacky     Flags |=
793ffd1746dSEd Schouten       COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
794ffd1746dSEd Schouten       COFF::IMAGE_SCN_MEM_READ |
795ffd1746dSEd Schouten       COFF::IMAGE_SCN_MEM_WRITE;
796dff0c46cSDimitry Andric   else if (K.isThreadLocal())
797dff0c46cSDimitry Andric     Flags |=
798dff0c46cSDimitry Andric       COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
799dff0c46cSDimitry Andric       COFF::IMAGE_SCN_MEM_READ |
800dff0c46cSDimitry Andric       COFF::IMAGE_SCN_MEM_WRITE;
80139d628a0SDimitry Andric   else if (K.isReadOnly() || K.isReadOnlyWithRel())
802f22ef01cSRoman Divacky     Flags |=
803ffd1746dSEd Schouten       COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
804ffd1746dSEd Schouten       COFF::IMAGE_SCN_MEM_READ;
805f22ef01cSRoman Divacky   else if (K.isWriteable())
806f22ef01cSRoman Divacky     Flags |=
807ffd1746dSEd Schouten       COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
808ffd1746dSEd Schouten       COFF::IMAGE_SCN_MEM_READ |
809ffd1746dSEd Schouten       COFF::IMAGE_SCN_MEM_WRITE;
810f22ef01cSRoman Divacky 
811f22ef01cSRoman Divacky   return Flags;
812f22ef01cSRoman Divacky }
813f22ef01cSRoman Divacky 
81491bc56edSDimitry Andric static const GlobalValue *getComdatGVForCOFF(const GlobalValue *GV) {
81591bc56edSDimitry Andric   const Comdat *C = GV->getComdat();
81691bc56edSDimitry Andric   assert(C && "expected GV to have a Comdat!");
81791bc56edSDimitry Andric 
81891bc56edSDimitry Andric   StringRef ComdatGVName = C->getName();
81991bc56edSDimitry Andric   const GlobalValue *ComdatGV = GV->getParent()->getNamedValue(ComdatGVName);
82091bc56edSDimitry Andric   if (!ComdatGV)
82191bc56edSDimitry Andric     report_fatal_error("Associative COMDAT symbol '" + ComdatGVName +
82291bc56edSDimitry Andric                        "' does not exist.");
82391bc56edSDimitry Andric 
82491bc56edSDimitry Andric   if (ComdatGV->getComdat() != C)
82591bc56edSDimitry Andric     report_fatal_error("Associative COMDAT symbol '" + ComdatGVName +
82639d628a0SDimitry Andric                        "' is not a key for its COMDAT.");
82791bc56edSDimitry Andric 
82891bc56edSDimitry Andric   return ComdatGV;
82991bc56edSDimitry Andric }
83091bc56edSDimitry Andric 
83191bc56edSDimitry Andric static int getSelectionForCOFF(const GlobalValue *GV) {
83291bc56edSDimitry Andric   if (const Comdat *C = GV->getComdat()) {
83391bc56edSDimitry Andric     const GlobalValue *ComdatKey = getComdatGVForCOFF(GV);
83491bc56edSDimitry Andric     if (const auto *GA = dyn_cast<GlobalAlias>(ComdatKey))
83591bc56edSDimitry Andric       ComdatKey = GA->getBaseObject();
83691bc56edSDimitry Andric     if (ComdatKey == GV) {
83791bc56edSDimitry Andric       switch (C->getSelectionKind()) {
83891bc56edSDimitry Andric       case Comdat::Any:
83991bc56edSDimitry Andric         return COFF::IMAGE_COMDAT_SELECT_ANY;
84091bc56edSDimitry Andric       case Comdat::ExactMatch:
84191bc56edSDimitry Andric         return COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH;
84291bc56edSDimitry Andric       case Comdat::Largest:
84391bc56edSDimitry Andric         return COFF::IMAGE_COMDAT_SELECT_LARGEST;
84491bc56edSDimitry Andric       case Comdat::NoDuplicates:
84591bc56edSDimitry Andric         return COFF::IMAGE_COMDAT_SELECT_NODUPLICATES;
84691bc56edSDimitry Andric       case Comdat::SameSize:
84791bc56edSDimitry Andric         return COFF::IMAGE_COMDAT_SELECT_SAME_SIZE;
84891bc56edSDimitry Andric       }
84991bc56edSDimitry Andric     } else {
85091bc56edSDimitry Andric       return COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE;
85191bc56edSDimitry Andric     }
85291bc56edSDimitry Andric   } else if (GV->isWeakForLinker()) {
85391bc56edSDimitry Andric     return COFF::IMAGE_COMDAT_SELECT_ANY;
85491bc56edSDimitry Andric   }
85591bc56edSDimitry Andric   return 0;
85691bc56edSDimitry Andric }
85791bc56edSDimitry Andric 
858ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal(
85991bc56edSDimitry Andric     const GlobalValue *GV, SectionKind Kind, Mangler &Mang,
86091bc56edSDimitry Andric     const TargetMachine &TM) const {
861139f7f9bSDimitry Andric   int Selection = 0;
862139f7f9bSDimitry Andric   unsigned Characteristics = getCOFFSectionFlags(Kind);
86391bc56edSDimitry Andric   StringRef Name = GV->getSection();
86491bc56edSDimitry Andric   StringRef COMDATSymName = "";
865ff0cc061SDimitry Andric   if (GV->hasComdat()) {
86691bc56edSDimitry Andric     Selection = getSelectionForCOFF(GV);
86791bc56edSDimitry Andric     const GlobalValue *ComdatGV;
86891bc56edSDimitry Andric     if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
86991bc56edSDimitry Andric       ComdatGV = getComdatGVForCOFF(GV);
87091bc56edSDimitry Andric     else
87191bc56edSDimitry Andric       ComdatGV = GV;
87291bc56edSDimitry Andric 
87391bc56edSDimitry Andric     if (!ComdatGV->hasPrivateLinkage()) {
87491bc56edSDimitry Andric       MCSymbol *Sym = TM.getSymbol(ComdatGV, Mang);
87591bc56edSDimitry Andric       COMDATSymName = Sym->getName();
876139f7f9bSDimitry Andric       Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
87791bc56edSDimitry Andric     } else {
87891bc56edSDimitry Andric       Selection = 0;
87991bc56edSDimitry Andric     }
880139f7f9bSDimitry Andric   }
881139f7f9bSDimitry Andric   return getContext().getCOFFSection(Name,
882139f7f9bSDimitry Andric                                      Characteristics,
883f785676fSDimitry Andric                                      Kind,
88491bc56edSDimitry Andric                                      COMDATSymName,
885f785676fSDimitry Andric                                      Selection);
886f22ef01cSRoman Divacky }
887f22ef01cSRoman Divacky 
88891bc56edSDimitry Andric static const char *getCOFFSectionNameForUniqueGlobal(SectionKind Kind) {
889f22ef01cSRoman Divacky   if (Kind.isText())
89091bc56edSDimitry Andric     return ".text";
891f22ef01cSRoman Divacky   if (Kind.isBSS())
89291bc56edSDimitry Andric     return ".bss";
89391bc56edSDimitry Andric   if (Kind.isThreadLocal())
89491bc56edSDimitry Andric     return ".tls$";
89539d628a0SDimitry Andric   if (Kind.isReadOnly() || Kind.isReadOnlyWithRel())
89691bc56edSDimitry Andric     return ".rdata";
89739d628a0SDimitry Andric   return ".data";
898f22ef01cSRoman Divacky }
899f22ef01cSRoman Divacky 
900ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal(
901ff0cc061SDimitry Andric     const GlobalValue *GV, SectionKind Kind, Mangler &Mang,
902ff0cc061SDimitry Andric     const TargetMachine &TM) const {
90391bc56edSDimitry Andric   // If we have -ffunction-sections then we should emit the global value to a
90491bc56edSDimitry Andric   // uniqued section specifically for it.
90591bc56edSDimitry Andric   bool EmitUniquedSection;
90691bc56edSDimitry Andric   if (Kind.isText())
90791bc56edSDimitry Andric     EmitUniquedSection = TM.getFunctionSections();
90891bc56edSDimitry Andric   else
90991bc56edSDimitry Andric     EmitUniquedSection = TM.getDataSections();
910f22ef01cSRoman Divacky 
911ff0cc061SDimitry Andric   if ((EmitUniquedSection && !Kind.isCommon()) || GV->hasComdat()) {
91291bc56edSDimitry Andric     const char *Name = getCOFFSectionNameForUniqueGlobal(Kind);
913f22ef01cSRoman Divacky     unsigned Characteristics = getCOFFSectionFlags(Kind);
914f22ef01cSRoman Divacky 
915ffd1746dSEd Schouten     Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
91691bc56edSDimitry Andric     int Selection = getSelectionForCOFF(GV);
91791bc56edSDimitry Andric     if (!Selection)
91891bc56edSDimitry Andric       Selection = COFF::IMAGE_COMDAT_SELECT_NODUPLICATES;
91991bc56edSDimitry Andric     const GlobalValue *ComdatGV;
92091bc56edSDimitry Andric     if (GV->hasComdat())
92191bc56edSDimitry Andric       ComdatGV = getComdatGVForCOFF(GV);
92291bc56edSDimitry Andric     else
92391bc56edSDimitry Andric       ComdatGV = GV;
924f22ef01cSRoman Divacky 
92591bc56edSDimitry Andric     if (!ComdatGV->hasPrivateLinkage()) {
92691bc56edSDimitry Andric       MCSymbol *Sym = TM.getSymbol(ComdatGV, Mang);
92791bc56edSDimitry Andric       StringRef COMDATSymName = Sym->getName();
92891bc56edSDimitry Andric       return getContext().getCOFFSection(Name, Characteristics, Kind,
92991bc56edSDimitry Andric                                          COMDATSymName, Selection);
930ff0cc061SDimitry Andric     } else {
931ff0cc061SDimitry Andric       SmallString<256> TmpData;
932ff0cc061SDimitry Andric       getNameWithPrefix(TmpData, GV, /*CannotUsePrivateLabel=*/true, Mang, TM);
933ff0cc061SDimitry Andric       return getContext().getCOFFSection(Name, Characteristics, Kind, TmpData,
934ff0cc061SDimitry Andric                                          Selection);
93591bc56edSDimitry Andric     }
936f22ef01cSRoman Divacky   }
937f22ef01cSRoman Divacky 
938f22ef01cSRoman Divacky   if (Kind.isText())
939f785676fSDimitry Andric     return TextSection;
940f22ef01cSRoman Divacky 
941dff0c46cSDimitry Andric   if (Kind.isThreadLocal())
942f785676fSDimitry Andric     return TLSDataSection;
943dff0c46cSDimitry Andric 
94439d628a0SDimitry Andric   if (Kind.isReadOnly() || Kind.isReadOnlyWithRel())
945f785676fSDimitry Andric     return ReadOnlySection;
946f785676fSDimitry Andric 
94791bc56edSDimitry Andric   // Note: we claim that common symbols are put in BSSSection, but they are
94891bc56edSDimitry Andric   // really emitted with the magic .comm directive, which creates a symbol table
94991bc56edSDimitry Andric   // entry but not a section.
95091bc56edSDimitry Andric   if (Kind.isBSS() || Kind.isCommon())
951f785676fSDimitry Andric     return BSSSection;
952f785676fSDimitry Andric 
953f785676fSDimitry Andric   return DataSection;
954f22ef01cSRoman Divacky }
955f22ef01cSRoman Divacky 
956ff0cc061SDimitry Andric void TargetLoweringObjectFileCOFF::getNameWithPrefix(
957ff0cc061SDimitry Andric     SmallVectorImpl<char> &OutName, const GlobalValue *GV,
958ff0cc061SDimitry Andric     bool CannotUsePrivateLabel, Mangler &Mang, const TargetMachine &TM) const {
959ff0cc061SDimitry Andric   if (GV->hasPrivateLinkage() &&
960ff0cc061SDimitry Andric       ((isa<Function>(GV) && TM.getFunctionSections()) ||
961ff0cc061SDimitry Andric        (isa<GlobalVariable>(GV) && TM.getDataSections())))
962ff0cc061SDimitry Andric     CannotUsePrivateLabel = true;
963ff0cc061SDimitry Andric 
964ff0cc061SDimitry Andric   Mang.getNameWithPrefix(OutName, GV, CannotUsePrivateLabel);
965ff0cc061SDimitry Andric }
966ff0cc061SDimitry Andric 
967ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable(
968ff0cc061SDimitry Andric     const Function &F, Mangler &Mang, const TargetMachine &TM) const {
969ff0cc061SDimitry Andric   // If the function can be removed, produce a unique section so that
970ff0cc061SDimitry Andric   // the table doesn't prevent the removal.
971ff0cc061SDimitry Andric   const Comdat *C = F.getComdat();
972ff0cc061SDimitry Andric   bool EmitUniqueSection = TM.getFunctionSections() || C;
973ff0cc061SDimitry Andric   if (!EmitUniqueSection)
974ff0cc061SDimitry Andric     return ReadOnlySection;
975ff0cc061SDimitry Andric 
976ff0cc061SDimitry Andric   // FIXME: we should produce a symbol for F instead.
977ff0cc061SDimitry Andric   if (F.hasPrivateLinkage())
978ff0cc061SDimitry Andric     return ReadOnlySection;
979ff0cc061SDimitry Andric 
980ff0cc061SDimitry Andric   MCSymbol *Sym = TM.getSymbol(&F, Mang);
981ff0cc061SDimitry Andric   StringRef COMDATSymName = Sym->getName();
982ff0cc061SDimitry Andric 
983ff0cc061SDimitry Andric   SectionKind Kind = SectionKind::getReadOnly();
984ff0cc061SDimitry Andric   const char *Name = getCOFFSectionNameForUniqueGlobal(Kind);
985ff0cc061SDimitry Andric   unsigned Characteristics = getCOFFSectionFlags(Kind);
986ff0cc061SDimitry Andric   Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
987ff0cc061SDimitry Andric 
988ff0cc061SDimitry Andric   return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName,
989ff0cc061SDimitry Andric                                      COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE);
990ff0cc061SDimitry Andric }
991ff0cc061SDimitry Andric 
99291bc56edSDimitry Andric StringRef TargetLoweringObjectFileCOFF::
99391bc56edSDimitry Andric getDepLibFromLinkerOpt(StringRef LinkerOption) const {
99491bc56edSDimitry Andric   const char *LibCmd = "/DEFAULTLIB:";
99591bc56edSDimitry Andric   if (LinkerOption.startswith(LibCmd))
99691bc56edSDimitry Andric     return LinkerOption.substr(strlen(LibCmd));
99791bc56edSDimitry Andric   return StringRef();
99891bc56edSDimitry Andric }
99991bc56edSDimitry Andric 
1000284c1978SDimitry Andric void TargetLoweringObjectFileCOFF::
1001284c1978SDimitry Andric emitModuleFlags(MCStreamer &Streamer,
1002284c1978SDimitry Andric                 ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
100391bc56edSDimitry Andric                 Mangler &Mang, const TargetMachine &TM) const {
100491bc56edSDimitry Andric   MDNode *LinkerOptions = nullptr;
1005284c1978SDimitry Andric 
1006284c1978SDimitry Andric   // Look for the "Linker Options" flag, since it's the only one we support.
1007284c1978SDimitry Andric   for (ArrayRef<Module::ModuleFlagEntry>::iterator
1008284c1978SDimitry Andric        i = ModuleFlags.begin(), e = ModuleFlags.end(); i != e; ++i) {
1009284c1978SDimitry Andric     const Module::ModuleFlagEntry &MFE = *i;
1010284c1978SDimitry Andric     StringRef Key = MFE.Key->getString();
101139d628a0SDimitry Andric     Metadata *Val = MFE.Val;
1012284c1978SDimitry Andric     if (Key == "Linker Options") {
1013284c1978SDimitry Andric       LinkerOptions = cast<MDNode>(Val);
1014284c1978SDimitry Andric       break;
1015284c1978SDimitry Andric     }
1016284c1978SDimitry Andric   }
1017284c1978SDimitry Andric   if (!LinkerOptions)
1018284c1978SDimitry Andric     return;
1019284c1978SDimitry Andric 
1020284c1978SDimitry Andric   // Emit the linker options to the linker .drectve section.  According to the
1021284c1978SDimitry Andric   // spec, this section is a space-separated string containing flags for linker.
1022ff0cc061SDimitry Andric   MCSection *Sec = getDrectveSection();
1023284c1978SDimitry Andric   Streamer.SwitchSection(Sec);
1024284c1978SDimitry Andric   for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) {
1025284c1978SDimitry Andric     MDNode *MDOptions = cast<MDNode>(LinkerOptions->getOperand(i));
1026284c1978SDimitry Andric     for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) {
1027284c1978SDimitry Andric       MDString *MDOption = cast<MDString>(MDOptions->getOperand(ii));
1028284c1978SDimitry Andric       // Lead with a space for consistency with our dllexport implementation.
1029ff0cc061SDimitry Andric       std::string Directive(" ");
1030ff0cc061SDimitry Andric       Directive.append(MDOption->getString());
1031ff0cc061SDimitry Andric       Streamer.EmitBytes(Directive);
1032284c1978SDimitry Andric     }
1033284c1978SDimitry Andric   }
1034284c1978SDimitry Andric }
103591bc56edSDimitry Andric 
1036ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection(
103791bc56edSDimitry Andric     unsigned Priority, const MCSymbol *KeySym) const {
103839d628a0SDimitry Andric   return getContext().getAssociativeCOFFSection(
103939d628a0SDimitry Andric       cast<MCSectionCOFF>(StaticCtorSection), KeySym);
104091bc56edSDimitry Andric }
104191bc56edSDimitry Andric 
1042ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(
104391bc56edSDimitry Andric     unsigned Priority, const MCSymbol *KeySym) const {
104439d628a0SDimitry Andric   return getContext().getAssociativeCOFFSection(
104539d628a0SDimitry Andric       cast<MCSectionCOFF>(StaticDtorSection), KeySym);
104691bc56edSDimitry Andric }
1047