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" 277d523365SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 28f22ef01cSRoman Divacky #include "llvm/MC/MCContext.h" 29f22ef01cSRoman Divacky #include "llvm/MC/MCExpr.h" 30f22ef01cSRoman Divacky #include "llvm/MC/MCSectionCOFF.h" 31139f7f9bSDimitry Andric #include "llvm/MC/MCSectionELF.h" 32139f7f9bSDimitry Andric #include "llvm/MC/MCSectionMachO.h" 333b0f4066SDimitry Andric #include "llvm/MC/MCStreamer.h" 3497bc6c73SDimitry Andric #include "llvm/MC/MCSymbolELF.h" 35ff0cc061SDimitry Andric #include "llvm/MC/MCValue.h" 363ca95b02SDimitry Andric #include "llvm/ProfileData/InstrProf.h" 377d523365SDimitry Andric #include "llvm/Support/COFF.h" 38f22ef01cSRoman Divacky #include "llvm/Support/Dwarf.h" 392754fe60SDimitry Andric #include "llvm/Support/ELF.h" 40f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h" 41f22ef01cSRoman Divacky #include "llvm/Support/raw_ostream.h" 4291bc56edSDimitry Andric #include "llvm/Target/TargetLowering.h" 43139f7f9bSDimitry Andric #include "llvm/Target/TargetMachine.h" 4439d628a0SDimitry Andric #include "llvm/Target/TargetSubtargetInfo.h" 45f22ef01cSRoman Divacky using namespace llvm; 46f22ef01cSRoman Divacky using namespace dwarf; 47f22ef01cSRoman Divacky 48f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 49f22ef01cSRoman Divacky // ELF 50f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 51f22ef01cSRoman Divacky 5291bc56edSDimitry Andric MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol( 5391bc56edSDimitry Andric const GlobalValue *GV, Mangler &Mang, const TargetMachine &TM, 543b0f4066SDimitry Andric MachineModuleInfo *MMI) const { 553b0f4066SDimitry Andric unsigned Encoding = getPersonalityEncoding(); 5691bc56edSDimitry Andric if ((Encoding & 0x80) == dwarf::DW_EH_PE_indirect) 57ff0cc061SDimitry Andric return getContext().getOrCreateSymbol(StringRef("DW.ref.") + 5891bc56edSDimitry Andric TM.getSymbol(GV, Mang)->getName()); 5991bc56edSDimitry Andric if ((Encoding & 0x70) == dwarf::DW_EH_PE_absptr) 6091bc56edSDimitry Andric return TM.getSymbol(GV, Mang); 6191bc56edSDimitry Andric report_fatal_error("We do not support this DWARF encoding yet!"); 623b0f4066SDimitry Andric } 633b0f4066SDimitry Andric 647d523365SDimitry Andric void TargetLoweringObjectFileELF::emitPersonalityValue( 657d523365SDimitry Andric MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym) const { 6617a519f9SDimitry Andric SmallString<64> NameData("DW.ref."); 6717a519f9SDimitry Andric NameData += Sym->getName(); 6897bc6c73SDimitry Andric MCSymbolELF *Label = 6997bc6c73SDimitry Andric cast<MCSymbolELF>(getContext().getOrCreateSymbol(NameData)); 703b0f4066SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_Hidden); 713b0f4066SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_Weak); 723b0f4066SDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP; 733ca95b02SDimitry Andric MCSection *Sec = getContext().getELFNamedSection(".data", Label->getName(), 743ca95b02SDimitry Andric ELF::SHT_PROGBITS, Flags, 0); 757d523365SDimitry Andric unsigned Size = DL.getPointerSize(); 763b0f4066SDimitry Andric Streamer.SwitchSection(Sec); 777d523365SDimitry Andric Streamer.EmitValueToAlignment(DL.getPointerABIAlignment()); 783b0f4066SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject); 7997bc6c73SDimitry Andric const MCExpr *E = MCConstantExpr::create(Size, getContext()); 8097bc6c73SDimitry Andric Streamer.emitELFSize(Label, E); 813b0f4066SDimitry Andric Streamer.EmitLabel(Label); 823b0f4066SDimitry Andric 833b0f4066SDimitry Andric Streamer.EmitSymbolValue(Sym, Size); 843b0f4066SDimitry Andric } 853b0f4066SDimitry Andric 8691bc56edSDimitry Andric const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference( 8791bc56edSDimitry Andric const GlobalValue *GV, unsigned Encoding, Mangler &Mang, 8891bc56edSDimitry Andric const TargetMachine &TM, MachineModuleInfo *MMI, 89139f7f9bSDimitry Andric MCStreamer &Streamer) const { 90139f7f9bSDimitry Andric 91139f7f9bSDimitry Andric if (Encoding & dwarf::DW_EH_PE_indirect) { 92139f7f9bSDimitry Andric MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>(); 93139f7f9bSDimitry Andric 9491bc56edSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", Mang, TM); 95139f7f9bSDimitry Andric 96139f7f9bSDimitry Andric // Add information about the stub reference to ELFMMI so that the stub 97139f7f9bSDimitry Andric // gets emitted by the asmprinter. 98139f7f9bSDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym); 9991bc56edSDimitry Andric if (!StubSym.getPointer()) { 10091bc56edSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV, Mang); 101139f7f9bSDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 102139f7f9bSDimitry Andric } 103139f7f9bSDimitry Andric 104139f7f9bSDimitry Andric return TargetLoweringObjectFile:: 10597bc6c73SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), 106139f7f9bSDimitry Andric Encoding & ~dwarf::DW_EH_PE_indirect, Streamer); 107139f7f9bSDimitry Andric } 108139f7f9bSDimitry Andric 109139f7f9bSDimitry Andric return TargetLoweringObjectFile:: 11091bc56edSDimitry Andric getTTypeGlobalReference(GV, Encoding, Mang, TM, MMI, Streamer); 111139f7f9bSDimitry Andric } 112139f7f9bSDimitry Andric 113f22ef01cSRoman Divacky static SectionKind 114f22ef01cSRoman Divacky getELFKindForNamedSection(StringRef Name, SectionKind K) { 115bd5abe19SDimitry Andric // N.B.: The defaults used in here are no the same ones used in MC. 116bd5abe19SDimitry Andric // We follow gcc, MC follows gas. For example, given ".section .eh_frame", 117bd5abe19SDimitry Andric // both gas and MC will produce a section with no flags. Given 1187ae0e2c9SDimitry Andric // section(".eh_frame") gcc will produce: 1197ae0e2c9SDimitry Andric // 120bd5abe19SDimitry Andric // .section .eh_frame,"a",@progbits 1213ca95b02SDimitry Andric 1223ca95b02SDimitry Andric if (Name == getInstrProfCoverageSectionName(false)) 1233ca95b02SDimitry Andric return SectionKind::getMetadata(); 1243ca95b02SDimitry Andric 125f22ef01cSRoman Divacky if (Name.empty() || Name[0] != '.') return K; 126f22ef01cSRoman Divacky 127f22ef01cSRoman Divacky // Some lame default implementation based on some magic section names. 128f22ef01cSRoman Divacky if (Name == ".bss" || 129f22ef01cSRoman Divacky Name.startswith(".bss.") || 130f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.b.") || 131f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.b.") || 132f22ef01cSRoman Divacky Name == ".sbss" || 133f22ef01cSRoman Divacky Name.startswith(".sbss.") || 134f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.sb.") || 135f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.sb.")) 136f22ef01cSRoman Divacky return SectionKind::getBSS(); 137f22ef01cSRoman Divacky 138f22ef01cSRoman Divacky if (Name == ".tdata" || 139f22ef01cSRoman Divacky Name.startswith(".tdata.") || 140f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.td.") || 141f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.td.")) 142f22ef01cSRoman Divacky return SectionKind::getThreadData(); 143f22ef01cSRoman Divacky 144f22ef01cSRoman Divacky if (Name == ".tbss" || 145f22ef01cSRoman Divacky Name.startswith(".tbss.") || 146f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.tb.") || 147f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.tb.")) 148f22ef01cSRoman Divacky return SectionKind::getThreadBSS(); 149f22ef01cSRoman Divacky 150f22ef01cSRoman Divacky return K; 151f22ef01cSRoman Divacky } 152f22ef01cSRoman Divacky 153f22ef01cSRoman Divacky 154f22ef01cSRoman Divacky static unsigned getELFSectionType(StringRef Name, SectionKind K) { 155f22ef01cSRoman Divacky 156f22ef01cSRoman Divacky if (Name == ".init_array") 1572754fe60SDimitry Andric return ELF::SHT_INIT_ARRAY; 158f22ef01cSRoman Divacky 159f22ef01cSRoman Divacky if (Name == ".fini_array") 1602754fe60SDimitry Andric return ELF::SHT_FINI_ARRAY; 161f22ef01cSRoman Divacky 162f22ef01cSRoman Divacky if (Name == ".preinit_array") 1632754fe60SDimitry Andric return ELF::SHT_PREINIT_ARRAY; 164f22ef01cSRoman Divacky 165f22ef01cSRoman Divacky if (K.isBSS() || K.isThreadBSS()) 1662754fe60SDimitry Andric return ELF::SHT_NOBITS; 167f22ef01cSRoman Divacky 1682754fe60SDimitry Andric return ELF::SHT_PROGBITS; 169f22ef01cSRoman Divacky } 170f22ef01cSRoman Divacky 171ff0cc061SDimitry Andric static unsigned getELFSectionFlags(SectionKind K) { 172f22ef01cSRoman Divacky unsigned Flags = 0; 173f22ef01cSRoman Divacky 174f22ef01cSRoman Divacky if (!K.isMetadata()) 1752754fe60SDimitry Andric Flags |= ELF::SHF_ALLOC; 176f22ef01cSRoman Divacky 177f22ef01cSRoman Divacky if (K.isText()) 1782754fe60SDimitry Andric Flags |= ELF::SHF_EXECINSTR; 179f22ef01cSRoman Divacky 180f22ef01cSRoman Divacky if (K.isWriteable()) 1812754fe60SDimitry Andric Flags |= ELF::SHF_WRITE; 182f22ef01cSRoman Divacky 183f22ef01cSRoman Divacky if (K.isThreadLocal()) 1842754fe60SDimitry Andric Flags |= ELF::SHF_TLS; 185f22ef01cSRoman Divacky 186ff0cc061SDimitry Andric if (K.isMergeableCString() || K.isMergeableConst()) 1872754fe60SDimitry Andric Flags |= ELF::SHF_MERGE; 188f22ef01cSRoman Divacky 189f22ef01cSRoman Divacky if (K.isMergeableCString()) 1902754fe60SDimitry Andric Flags |= ELF::SHF_STRINGS; 191f22ef01cSRoman Divacky 192f22ef01cSRoman Divacky return Flags; 193f22ef01cSRoman Divacky } 194f22ef01cSRoman Divacky 19591bc56edSDimitry Andric static const Comdat *getELFComdat(const GlobalValue *GV) { 19691bc56edSDimitry Andric const Comdat *C = GV->getComdat(); 19791bc56edSDimitry Andric if (!C) 19891bc56edSDimitry Andric return nullptr; 199f22ef01cSRoman Divacky 20091bc56edSDimitry Andric if (C->getSelectionKind() != Comdat::Any) 20191bc56edSDimitry Andric report_fatal_error("ELF COMDATs only support SelectionKind::Any, '" + 20291bc56edSDimitry Andric C->getName() + "' cannot be lowered."); 20391bc56edSDimitry Andric 20491bc56edSDimitry Andric return C; 20591bc56edSDimitry Andric } 20691bc56edSDimitry Andric 207ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( 20891bc56edSDimitry Andric const GlobalValue *GV, SectionKind Kind, Mangler &Mang, 20991bc56edSDimitry Andric const TargetMachine &TM) const { 210f22ef01cSRoman Divacky StringRef SectionName = GV->getSection(); 211f22ef01cSRoman Divacky 212f22ef01cSRoman Divacky // Infer section flags from the section name if we can. 213f22ef01cSRoman Divacky Kind = getELFKindForNamedSection(SectionName, Kind); 214f22ef01cSRoman Divacky 21591bc56edSDimitry Andric StringRef Group = ""; 21691bc56edSDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 21791bc56edSDimitry Andric if (const Comdat *C = getELFComdat(GV)) { 21891bc56edSDimitry Andric Group = C->getName(); 21991bc56edSDimitry Andric Flags |= ELF::SHF_GROUP; 22091bc56edSDimitry Andric } 221f22ef01cSRoman Divacky return getContext().getELFSection(SectionName, 22291bc56edSDimitry Andric getELFSectionType(SectionName, Kind), Flags, 223ff0cc061SDimitry Andric /*EntrySize=*/0, Group); 224f22ef01cSRoman Divacky } 225f22ef01cSRoman Divacky 226ff0cc061SDimitry Andric /// Return the section prefix name used by options FunctionsSections and 227ff0cc061SDimitry Andric /// DataSections. 22891bc56edSDimitry Andric static StringRef getSectionPrefixForGlobal(SectionKind Kind) { 229ff0cc061SDimitry Andric if (Kind.isText()) 230ff0cc061SDimitry Andric return ".text"; 231ff0cc061SDimitry Andric if (Kind.isReadOnly()) 232ff0cc061SDimitry Andric return ".rodata"; 233ff0cc061SDimitry Andric if (Kind.isBSS()) 234ff0cc061SDimitry Andric return ".bss"; 235ff0cc061SDimitry Andric if (Kind.isThreadData()) 236ff0cc061SDimitry Andric return ".tdata"; 237ff0cc061SDimitry Andric if (Kind.isThreadBSS()) 238ff0cc061SDimitry Andric return ".tbss"; 2397d523365SDimitry Andric if (Kind.isData()) 240ff0cc061SDimitry Andric return ".data"; 241f22ef01cSRoman Divacky assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); 242ff0cc061SDimitry Andric return ".data.rel.ro"; 243f22ef01cSRoman Divacky } 244f22ef01cSRoman Divacky 245ff0cc061SDimitry Andric static MCSectionELF * 246ff0cc061SDimitry Andric selectELFSectionForGlobal(MCContext &Ctx, const GlobalValue *GV, 247ff0cc061SDimitry Andric SectionKind Kind, Mangler &Mang, 248ff0cc061SDimitry Andric const TargetMachine &TM, bool EmitUniqueSection, 249ff0cc061SDimitry Andric unsigned Flags, unsigned *NextUniqueID) { 250ff0cc061SDimitry Andric unsigned EntrySize = 0; 251ff0cc061SDimitry Andric if (Kind.isMergeableCString()) { 252ff0cc061SDimitry Andric if (Kind.isMergeable2ByteCString()) { 253ff0cc061SDimitry Andric EntrySize = 2; 254ff0cc061SDimitry Andric } else if (Kind.isMergeable4ByteCString()) { 255ff0cc061SDimitry Andric EntrySize = 4; 256ff0cc061SDimitry Andric } else { 257ff0cc061SDimitry Andric EntrySize = 1; 258ff0cc061SDimitry Andric assert(Kind.isMergeable1ByteCString() && "unknown string width"); 259ff0cc061SDimitry Andric } 260ff0cc061SDimitry Andric } else if (Kind.isMergeableConst()) { 261ff0cc061SDimitry Andric if (Kind.isMergeableConst4()) { 262ff0cc061SDimitry Andric EntrySize = 4; 263ff0cc061SDimitry Andric } else if (Kind.isMergeableConst8()) { 264ff0cc061SDimitry Andric EntrySize = 8; 2653ca95b02SDimitry Andric } else if (Kind.isMergeableConst16()) { 266ff0cc061SDimitry Andric EntrySize = 16; 2673ca95b02SDimitry Andric } else { 2683ca95b02SDimitry Andric assert(Kind.isMergeableConst32() && "unknown data width"); 2693ca95b02SDimitry Andric EntrySize = 32; 270ff0cc061SDimitry Andric } 271ff0cc061SDimitry Andric } 27291bc56edSDimitry Andric 2732754fe60SDimitry Andric StringRef Group = ""; 274ff0cc061SDimitry Andric if (const Comdat *C = getELFComdat(GV)) { 2752754fe60SDimitry Andric Flags |= ELF::SHF_GROUP; 276ff0cc061SDimitry Andric Group = C->getName(); 2772754fe60SDimitry Andric } 2782754fe60SDimitry Andric 279ff0cc061SDimitry Andric bool UniqueSectionNames = TM.getUniqueSectionNames(); 280ff0cc061SDimitry Andric SmallString<128> Name; 281ff0cc061SDimitry Andric if (Kind.isMergeableCString()) { 282f22ef01cSRoman Divacky // We also need alignment here. 283f22ef01cSRoman Divacky // FIXME: this is getting the alignment of the character, not the 284f22ef01cSRoman Divacky // alignment of the global! 2857d523365SDimitry Andric unsigned Align = GV->getParent()->getDataLayout().getPreferredAlignment( 2867d523365SDimitry Andric cast<GlobalVariable>(GV)); 287f22ef01cSRoman Divacky 288ff0cc061SDimitry Andric std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + "."; 289ff0cc061SDimitry Andric Name = SizeSpec + utostr(Align); 290ff0cc061SDimitry Andric } else if (Kind.isMergeableConst()) { 291ff0cc061SDimitry Andric Name = ".rodata.cst"; 292ff0cc061SDimitry Andric Name += utostr(EntrySize); 293ff0cc061SDimitry Andric } else { 294ff0cc061SDimitry Andric Name = getSectionPrefixForGlobal(Kind); 295ff0cc061SDimitry Andric } 2963ca95b02SDimitry Andric // FIXME: Extend the section prefix to include hotness catagories such as .hot 2973ca95b02SDimitry Andric // or .unlikely for functions. 298ff0cc061SDimitry Andric 299ff0cc061SDimitry Andric if (EmitUniqueSection && UniqueSectionNames) { 300ff0cc061SDimitry Andric Name.push_back('.'); 301ff0cc061SDimitry Andric TM.getNameWithPrefix(Name, GV, Mang, true); 302ff0cc061SDimitry Andric } 3033ca95b02SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 304ff0cc061SDimitry Andric if (EmitUniqueSection && !UniqueSectionNames) { 305ff0cc061SDimitry Andric UniqueID = *NextUniqueID; 306ff0cc061SDimitry Andric (*NextUniqueID)++; 307ff0cc061SDimitry Andric } 308ff0cc061SDimitry Andric return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags, 309ff0cc061SDimitry Andric EntrySize, Group, UniqueID); 310ff0cc061SDimitry Andric } 311ff0cc061SDimitry Andric 312ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( 313ff0cc061SDimitry Andric const GlobalValue *GV, SectionKind Kind, Mangler &Mang, 314ff0cc061SDimitry Andric const TargetMachine &TM) const { 315ff0cc061SDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 316ff0cc061SDimitry Andric 317ff0cc061SDimitry Andric // If we have -ffunction-section or -fdata-section then we should emit the 318ff0cc061SDimitry Andric // global value to a uniqued section specifically for it. 319ff0cc061SDimitry Andric bool EmitUniqueSection = false; 320ff0cc061SDimitry Andric if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) { 321ff0cc061SDimitry Andric if (Kind.isText()) 322ff0cc061SDimitry Andric EmitUniqueSection = TM.getFunctionSections(); 323f22ef01cSRoman Divacky else 324ff0cc061SDimitry Andric EmitUniqueSection = TM.getDataSections(); 325ff0cc061SDimitry Andric } 326ff0cc061SDimitry Andric EmitUniqueSection |= GV->hasComdat(); 327f22ef01cSRoman Divacky 328ff0cc061SDimitry Andric return selectELFSectionForGlobal(getContext(), GV, Kind, Mang, TM, 329ff0cc061SDimitry Andric EmitUniqueSection, Flags, &NextUniqueID); 330f22ef01cSRoman Divacky } 331f22ef01cSRoman Divacky 332ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( 333ff0cc061SDimitry Andric const Function &F, Mangler &Mang, const TargetMachine &TM) const { 334ff0cc061SDimitry Andric // If the function can be removed, produce a unique section so that 335ff0cc061SDimitry Andric // the table doesn't prevent the removal. 336ff0cc061SDimitry Andric const Comdat *C = F.getComdat(); 337ff0cc061SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C; 338ff0cc061SDimitry Andric if (!EmitUniqueSection) 339ff0cc061SDimitry Andric return ReadOnlySection; 340ff0cc061SDimitry Andric 341ff0cc061SDimitry Andric return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(), 342ff0cc061SDimitry Andric Mang, TM, EmitUniqueSection, ELF::SHF_ALLOC, 343ff0cc061SDimitry Andric &NextUniqueID); 344f22ef01cSRoman Divacky } 345f22ef01cSRoman Divacky 346ff0cc061SDimitry Andric bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection( 347ff0cc061SDimitry Andric bool UsesLabelDifference, const Function &F) const { 348ff0cc061SDimitry Andric // We can always create relative relocations, so use another section 349ff0cc061SDimitry Andric // that can be marked non-executable. 350ff0cc061SDimitry Andric return false; 351f22ef01cSRoman Divacky } 352f22ef01cSRoman Divacky 353ff0cc061SDimitry Andric /// Given a mergeable constant with the specified size and relocation 354ff0cc061SDimitry Andric /// information, return a section that it should be placed in. 3557d523365SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForConstant( 3563ca95b02SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 3573ca95b02SDimitry Andric unsigned &Align) const { 358f22ef01cSRoman Divacky if (Kind.isMergeableConst4() && MergeableConst4Section) 359f22ef01cSRoman Divacky return MergeableConst4Section; 360f22ef01cSRoman Divacky if (Kind.isMergeableConst8() && MergeableConst8Section) 361f22ef01cSRoman Divacky return MergeableConst8Section; 362f22ef01cSRoman Divacky if (Kind.isMergeableConst16() && MergeableConst16Section) 363f22ef01cSRoman Divacky return MergeableConst16Section; 3643ca95b02SDimitry Andric if (Kind.isMergeableConst32() && MergeableConst32Section) 3653ca95b02SDimitry Andric return MergeableConst32Section; 366f22ef01cSRoman Divacky if (Kind.isReadOnly()) 367f22ef01cSRoman Divacky return ReadOnlySection; 368f22ef01cSRoman Divacky 369f22ef01cSRoman Divacky assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); 370f22ef01cSRoman Divacky return DataRelROSection; 371f22ef01cSRoman Divacky } 372f22ef01cSRoman Divacky 373ff0cc061SDimitry Andric static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray, 374ff0cc061SDimitry Andric bool IsCtor, unsigned Priority, 37539d628a0SDimitry Andric const MCSymbol *KeySym) { 37639d628a0SDimitry Andric std::string Name; 37739d628a0SDimitry Andric unsigned Type; 37839d628a0SDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE; 37939d628a0SDimitry Andric StringRef COMDAT = KeySym ? KeySym->getName() : ""; 38039d628a0SDimitry Andric 38139d628a0SDimitry Andric if (KeySym) 38239d628a0SDimitry Andric Flags |= ELF::SHF_GROUP; 383dff0c46cSDimitry Andric 3847ae0e2c9SDimitry Andric if (UseInitArray) { 38539d628a0SDimitry Andric if (IsCtor) { 38639d628a0SDimitry Andric Type = ELF::SHT_INIT_ARRAY; 38739d628a0SDimitry Andric Name = ".init_array"; 3887ae0e2c9SDimitry Andric } else { 38939d628a0SDimitry Andric Type = ELF::SHT_FINI_ARRAY; 39039d628a0SDimitry Andric Name = ".fini_array"; 391dff0c46cSDimitry Andric } 39239d628a0SDimitry Andric if (Priority != 65535) { 39339d628a0SDimitry Andric Name += '.'; 39439d628a0SDimitry Andric Name += utostr(Priority); 39539d628a0SDimitry Andric } 39639d628a0SDimitry Andric } else { 39739d628a0SDimitry Andric // The default scheme is .ctor / .dtor, so we have to invert the priority 39839d628a0SDimitry Andric // numbering. 39939d628a0SDimitry Andric if (IsCtor) 40039d628a0SDimitry Andric Name = ".ctors"; 40139d628a0SDimitry Andric else 40239d628a0SDimitry Andric Name = ".dtors"; 40339d628a0SDimitry Andric if (Priority != 65535) { 40439d628a0SDimitry Andric Name += '.'; 40539d628a0SDimitry Andric Name += utostr(65535 - Priority); 40639d628a0SDimitry Andric } 40739d628a0SDimitry Andric Type = ELF::SHT_PROGBITS; 40839d628a0SDimitry Andric } 40939d628a0SDimitry Andric 410ff0cc061SDimitry Andric return Ctx.getELFSection(Name, Type, Flags, 0, COMDAT); 41139d628a0SDimitry Andric } 41239d628a0SDimitry Andric 413ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticCtorSection( 41439d628a0SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 41539d628a0SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, true, Priority, 41639d628a0SDimitry Andric KeySym); 4177ae0e2c9SDimitry Andric } 418dff0c46cSDimitry Andric 419ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticDtorSection( 42091bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 42139d628a0SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, false, Priority, 42239d628a0SDimitry Andric KeySym); 4237ae0e2c9SDimitry Andric } 4247ae0e2c9SDimitry Andric 4253ca95b02SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference( 4263ca95b02SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, Mangler &Mang, 4273ca95b02SDimitry Andric const TargetMachine &TM) const { 4283ca95b02SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr 4293ca95b02SDimitry Andric // functions. 4303ca95b02SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) 4313ca95b02SDimitry Andric return nullptr; 4323ca95b02SDimitry Andric 4333ca95b02SDimitry Andric // Basic sanity checks. 4343ca95b02SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 4353ca95b02SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || 4363ca95b02SDimitry Andric RHS->isThreadLocal()) 4373ca95b02SDimitry Andric return nullptr; 4383ca95b02SDimitry Andric 4393ca95b02SDimitry Andric return MCBinaryExpr::createSub( 4403ca95b02SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS, Mang), PLTRelativeVariantKind, 4413ca95b02SDimitry Andric getContext()), 4423ca95b02SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS, Mang), getContext()), 4433ca95b02SDimitry Andric getContext()); 4443ca95b02SDimitry Andric } 4453ca95b02SDimitry Andric 4467ae0e2c9SDimitry Andric void 4477ae0e2c9SDimitry Andric TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) { 4487ae0e2c9SDimitry Andric UseInitArray = UseInitArray_; 4497ae0e2c9SDimitry Andric if (!UseInitArray) 4507ae0e2c9SDimitry Andric return; 4517ae0e2c9SDimitry Andric 452ff0cc061SDimitry Andric StaticCtorSection = getContext().getELFSection( 453ff0cc061SDimitry Andric ".init_array", ELF::SHT_INIT_ARRAY, ELF::SHF_WRITE | ELF::SHF_ALLOC); 454ff0cc061SDimitry Andric StaticDtorSection = getContext().getELFSection( 455ff0cc061SDimitry Andric ".fini_array", ELF::SHT_FINI_ARRAY, ELF::SHF_WRITE | ELF::SHF_ALLOC); 4567ae0e2c9SDimitry Andric } 457dff0c46cSDimitry Andric 458f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 459f22ef01cSRoman Divacky // MachO 460f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 461f22ef01cSRoman Divacky 462ff0cc061SDimitry Andric TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO() 463ff0cc061SDimitry Andric : TargetLoweringObjectFile() { 464ff0cc061SDimitry Andric SupportIndirectSymViaGOTPCRel = true; 465ff0cc061SDimitry Andric } 466ff0cc061SDimitry Andric 467139f7f9bSDimitry Andric /// emitModuleFlags - Perform code emission for module flags. 468dff0c46cSDimitry Andric void TargetLoweringObjectFileMachO:: 469dff0c46cSDimitry Andric emitModuleFlags(MCStreamer &Streamer, 470dff0c46cSDimitry Andric ArrayRef<Module::ModuleFlagEntry> ModuleFlags, 47191bc56edSDimitry Andric Mangler &Mang, const TargetMachine &TM) const { 472dff0c46cSDimitry Andric unsigned VersionVal = 0; 4737ae0e2c9SDimitry Andric unsigned ImageInfoFlags = 0; 47491bc56edSDimitry Andric MDNode *LinkerOptions = nullptr; 475dff0c46cSDimitry Andric StringRef SectionVal; 476dff0c46cSDimitry Andric 4773ca95b02SDimitry Andric for (const auto &MFE : ModuleFlags) { 478dff0c46cSDimitry Andric // Ignore flags with 'Require' behavior. 479dff0c46cSDimitry Andric if (MFE.Behavior == Module::Require) 480dff0c46cSDimitry Andric continue; 481dff0c46cSDimitry Andric 482dff0c46cSDimitry Andric StringRef Key = MFE.Key->getString(); 48339d628a0SDimitry Andric Metadata *Val = MFE.Val; 484dff0c46cSDimitry Andric 485139f7f9bSDimitry Andric if (Key == "Objective-C Image Info Version") { 48639d628a0SDimitry Andric VersionVal = mdconst::extract<ConstantInt>(Val)->getZExtValue(); 487139f7f9bSDimitry Andric } else if (Key == "Objective-C Garbage Collection" || 4887ae0e2c9SDimitry Andric Key == "Objective-C GC Only" || 48939d628a0SDimitry Andric Key == "Objective-C Is Simulated" || 4903ca95b02SDimitry Andric Key == "Objective-C Class Properties" || 49139d628a0SDimitry Andric Key == "Objective-C Image Swift Version") { 49239d628a0SDimitry Andric ImageInfoFlags |= mdconst::extract<ConstantInt>(Val)->getZExtValue(); 493139f7f9bSDimitry Andric } else if (Key == "Objective-C Image Info Section") { 494dff0c46cSDimitry Andric SectionVal = cast<MDString>(Val)->getString(); 495139f7f9bSDimitry Andric } else if (Key == "Linker Options") { 496139f7f9bSDimitry Andric LinkerOptions = cast<MDNode>(Val); 497139f7f9bSDimitry Andric } 498139f7f9bSDimitry Andric } 499139f7f9bSDimitry Andric 500139f7f9bSDimitry Andric // Emit the linker options if present. 501139f7f9bSDimitry Andric if (LinkerOptions) { 5023ca95b02SDimitry Andric for (const auto &Option : LinkerOptions->operands()) { 503139f7f9bSDimitry Andric SmallVector<std::string, 4> StrOptions; 5043ca95b02SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) 5053ca95b02SDimitry Andric StrOptions.push_back(cast<MDString>(Piece)->getString()); 506139f7f9bSDimitry Andric Streamer.EmitLinkerOptions(StrOptions); 507139f7f9bSDimitry Andric } 508dff0c46cSDimitry Andric } 509dff0c46cSDimitry Andric 510dff0c46cSDimitry Andric // The section is mandatory. If we don't have it, then we don't have GC info. 511dff0c46cSDimitry Andric if (SectionVal.empty()) return; 512dff0c46cSDimitry Andric 513dff0c46cSDimitry Andric StringRef Segment, Section; 514dff0c46cSDimitry Andric unsigned TAA = 0, StubSize = 0; 515dff0c46cSDimitry Andric bool TAAParsed; 516dff0c46cSDimitry Andric std::string ErrorCode = 517dff0c46cSDimitry Andric MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section, 518dff0c46cSDimitry Andric TAA, TAAParsed, StubSize); 519dff0c46cSDimitry Andric if (!ErrorCode.empty()) 520dff0c46cSDimitry Andric // If invalid, report the error with report_fatal_error. 521dff0c46cSDimitry Andric report_fatal_error("Invalid section specifier '" + Section + "': " + 522dff0c46cSDimitry Andric ErrorCode + "."); 523dff0c46cSDimitry Andric 524dff0c46cSDimitry Andric // Get the section. 525ff0cc061SDimitry Andric MCSectionMachO *S = getContext().getMachOSection( 5267d523365SDimitry Andric Segment, Section, TAA, StubSize, SectionKind::getData()); 527dff0c46cSDimitry Andric Streamer.SwitchSection(S); 528dff0c46cSDimitry Andric Streamer.EmitLabel(getContext(). 529ff0cc061SDimitry Andric getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); 530dff0c46cSDimitry Andric Streamer.EmitIntValue(VersionVal, 4); 5317ae0e2c9SDimitry Andric Streamer.EmitIntValue(ImageInfoFlags, 4); 532dff0c46cSDimitry Andric Streamer.AddBlankLine(); 533dff0c46cSDimitry Andric } 534dff0c46cSDimitry Andric 53591bc56edSDimitry Andric static void checkMachOComdat(const GlobalValue *GV) { 53691bc56edSDimitry Andric const Comdat *C = GV->getComdat(); 53791bc56edSDimitry Andric if (!C) 53891bc56edSDimitry Andric return; 53991bc56edSDimitry Andric 54091bc56edSDimitry Andric report_fatal_error("MachO doesn't support COMDATs, '" + C->getName() + 54191bc56edSDimitry Andric "' cannot be lowered."); 54291bc56edSDimitry Andric } 54391bc56edSDimitry Andric 544ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( 54591bc56edSDimitry Andric const GlobalValue *GV, SectionKind Kind, Mangler &Mang, 54691bc56edSDimitry Andric const TargetMachine &TM) const { 547f22ef01cSRoman Divacky // Parse the section specifier and create it if valid. 548f22ef01cSRoman Divacky StringRef Segment, Section; 5493b0f4066SDimitry Andric unsigned TAA = 0, StubSize = 0; 5503b0f4066SDimitry Andric bool TAAParsed; 55191bc56edSDimitry Andric 55291bc56edSDimitry Andric checkMachOComdat(GV); 55391bc56edSDimitry Andric 554f22ef01cSRoman Divacky std::string ErrorCode = 555f22ef01cSRoman Divacky MCSectionMachO::ParseSectionSpecifier(GV->getSection(), Segment, Section, 5563b0f4066SDimitry Andric TAA, TAAParsed, StubSize); 557f22ef01cSRoman Divacky if (!ErrorCode.empty()) { 558f22ef01cSRoman Divacky // If invalid, report the error with report_fatal_error. 559dff0c46cSDimitry Andric report_fatal_error("Global variable '" + GV->getName() + 560dff0c46cSDimitry Andric "' has an invalid section specifier '" + 561dff0c46cSDimitry Andric GV->getSection() + "': " + ErrorCode + "."); 562f22ef01cSRoman Divacky } 563f22ef01cSRoman Divacky 564f22ef01cSRoman Divacky // Get the section. 565ff0cc061SDimitry Andric MCSectionMachO *S = 566f22ef01cSRoman Divacky getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind); 567f22ef01cSRoman Divacky 568dd6029ffSDimitry Andric // If TAA wasn't set by ParseSectionSpecifier() above, 569dd6029ffSDimitry Andric // use the value returned by getMachOSection() as a default. 5703b0f4066SDimitry Andric if (!TAAParsed) 571dd6029ffSDimitry Andric TAA = S->getTypeAndAttributes(); 572dd6029ffSDimitry Andric 573f22ef01cSRoman Divacky // Okay, now that we got the section, verify that the TAA & StubSize agree. 574f22ef01cSRoman Divacky // If the user declared multiple globals with different section flags, we need 575f22ef01cSRoman Divacky // to reject it here. 576f22ef01cSRoman Divacky if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) { 577f22ef01cSRoman Divacky // If invalid, report the error with report_fatal_error. 578dff0c46cSDimitry Andric report_fatal_error("Global variable '" + GV->getName() + 579f22ef01cSRoman Divacky "' section type or attributes does not match previous" 580f22ef01cSRoman Divacky " section specifier"); 581f22ef01cSRoman Divacky } 582f22ef01cSRoman Divacky 583f22ef01cSRoman Divacky return S; 584f22ef01cSRoman Divacky } 585f22ef01cSRoman Divacky 586ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal( 587ff0cc061SDimitry Andric const GlobalValue *GV, SectionKind Kind, Mangler &Mang, 588ff0cc061SDimitry Andric const TargetMachine &TM) const { 58991bc56edSDimitry Andric checkMachOComdat(GV); 590f785676fSDimitry Andric 591f785676fSDimitry Andric // Handle thread local data. 592f785676fSDimitry Andric if (Kind.isThreadBSS()) return TLSBSSSection; 593f785676fSDimitry Andric if (Kind.isThreadData()) return TLSDataSection; 594f785676fSDimitry Andric 595f22ef01cSRoman Divacky if (Kind.isText()) 596f22ef01cSRoman Divacky return GV->isWeakForLinker() ? TextCoalSection : TextSection; 597f22ef01cSRoman Divacky 598f22ef01cSRoman Divacky // If this is weak/linkonce, put this in a coalescable section, either in text 599f22ef01cSRoman Divacky // or data depending on if it is writable. 600f22ef01cSRoman Divacky if (GV->isWeakForLinker()) { 601f22ef01cSRoman Divacky if (Kind.isReadOnly()) 602f22ef01cSRoman Divacky return ConstTextCoalSection; 603f22ef01cSRoman Divacky return DataCoalSection; 604f22ef01cSRoman Divacky } 605f22ef01cSRoman Divacky 606f22ef01cSRoman Divacky // FIXME: Alignment check should be handled by section classifier. 607f22ef01cSRoman Divacky if (Kind.isMergeable1ByteCString() && 6087d523365SDimitry Andric GV->getParent()->getDataLayout().getPreferredAlignment( 6097d523365SDimitry Andric cast<GlobalVariable>(GV)) < 32) 610f22ef01cSRoman Divacky return CStringSection; 611f22ef01cSRoman Divacky 612f22ef01cSRoman Divacky // Do not put 16-bit arrays in the UString section if they have an 613f22ef01cSRoman Divacky // externally visible label, this runs into issues with certain linker 614f22ef01cSRoman Divacky // versions. 615f22ef01cSRoman Divacky if (Kind.isMergeable2ByteCString() && !GV->hasExternalLinkage() && 6167d523365SDimitry Andric GV->getParent()->getDataLayout().getPreferredAlignment( 6177d523365SDimitry Andric cast<GlobalVariable>(GV)) < 32) 618f22ef01cSRoman Divacky return UStringSection; 619f22ef01cSRoman Divacky 62039d628a0SDimitry Andric // With MachO only variables whose corresponding symbol starts with 'l' or 62139d628a0SDimitry Andric // 'L' can be merged, so we only try merging GVs with private linkage. 62239d628a0SDimitry Andric if (GV->hasPrivateLinkage() && Kind.isMergeableConst()) { 623f22ef01cSRoman Divacky if (Kind.isMergeableConst4()) 624f22ef01cSRoman Divacky return FourByteConstantSection; 625f22ef01cSRoman Divacky if (Kind.isMergeableConst8()) 626f22ef01cSRoman Divacky return EightByteConstantSection; 62791bc56edSDimitry Andric if (Kind.isMergeableConst16()) 628f22ef01cSRoman Divacky return SixteenByteConstantSection; 629f22ef01cSRoman Divacky } 630f22ef01cSRoman Divacky 631f22ef01cSRoman Divacky // Otherwise, if it is readonly, but not something we can specially optimize, 632f22ef01cSRoman Divacky // just drop it in .const. 633f22ef01cSRoman Divacky if (Kind.isReadOnly()) 634f22ef01cSRoman Divacky return ReadOnlySection; 635f22ef01cSRoman Divacky 636f22ef01cSRoman Divacky // If this is marked const, put it into a const section. But if the dynamic 637f22ef01cSRoman Divacky // linker needs to write to it, put it in the data segment. 638f22ef01cSRoman Divacky if (Kind.isReadOnlyWithRel()) 639f22ef01cSRoman Divacky return ConstDataSection; 640f22ef01cSRoman Divacky 641f22ef01cSRoman Divacky // Put zero initialized globals with strong external linkage in the 642f22ef01cSRoman Divacky // DATA, __common section with the .zerofill directive. 643f22ef01cSRoman Divacky if (Kind.isBSSExtern()) 644f22ef01cSRoman Divacky return DataCommonSection; 645f22ef01cSRoman Divacky 646f22ef01cSRoman Divacky // Put zero initialized globals with local linkage in __DATA,__bss directive 647f22ef01cSRoman Divacky // with the .zerofill directive (aka .lcomm). 648f22ef01cSRoman Divacky if (Kind.isBSSLocal()) 649f22ef01cSRoman Divacky return DataBSSSection; 650f22ef01cSRoman Divacky 651f22ef01cSRoman Divacky // Otherwise, just drop the variable in the normal data section. 652f22ef01cSRoman Divacky return DataSection; 653f22ef01cSRoman Divacky } 654f22ef01cSRoman Divacky 6557d523365SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getSectionForConstant( 6563ca95b02SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 6573ca95b02SDimitry Andric unsigned &Align) const { 658f22ef01cSRoman Divacky // If this constant requires a relocation, we have to put it in the data 659f22ef01cSRoman Divacky // segment, not in the text segment. 6607d523365SDimitry Andric if (Kind.isData() || Kind.isReadOnlyWithRel()) 661f22ef01cSRoman Divacky return ConstDataSection; 662f22ef01cSRoman Divacky 663f22ef01cSRoman Divacky if (Kind.isMergeableConst4()) 664f22ef01cSRoman Divacky return FourByteConstantSection; 665f22ef01cSRoman Divacky if (Kind.isMergeableConst8()) 666f22ef01cSRoman Divacky return EightByteConstantSection; 66791bc56edSDimitry Andric if (Kind.isMergeableConst16()) 668f22ef01cSRoman Divacky return SixteenByteConstantSection; 669f22ef01cSRoman Divacky return ReadOnlySection; // .const 670f22ef01cSRoman Divacky } 671f22ef01cSRoman Divacky 67291bc56edSDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference( 67391bc56edSDimitry Andric const GlobalValue *GV, unsigned Encoding, Mangler &Mang, 67491bc56edSDimitry Andric const TargetMachine &TM, MachineModuleInfo *MMI, 675f22ef01cSRoman Divacky MCStreamer &Streamer) const { 676f22ef01cSRoman Divacky // The mach-o version of this method defaults to returning a stub reference. 677f22ef01cSRoman Divacky 678f22ef01cSRoman Divacky if (Encoding & DW_EH_PE_indirect) { 679f22ef01cSRoman Divacky MachineModuleInfoMachO &MachOMMI = 680f22ef01cSRoman Divacky MMI->getObjFileInfo<MachineModuleInfoMachO>(); 681f22ef01cSRoman Divacky 68291bc56edSDimitry Andric MCSymbol *SSym = 68391bc56edSDimitry Andric getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", Mang, TM); 684f22ef01cSRoman Divacky 685f22ef01cSRoman Divacky // Add information about the stub reference to MachOMMI so that the stub 686f22ef01cSRoman Divacky // gets emitted by the asmprinter. 6873ca95b02SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 68891bc56edSDimitry Andric if (!StubSym.getPointer()) { 68991bc56edSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV, Mang); 690f22ef01cSRoman Divacky StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 691f22ef01cSRoman Divacky } 692f22ef01cSRoman Divacky 693f22ef01cSRoman Divacky return TargetLoweringObjectFile:: 69497bc6c73SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), 695139f7f9bSDimitry Andric Encoding & ~dwarf::DW_EH_PE_indirect, Streamer); 696f22ef01cSRoman Divacky } 697f22ef01cSRoman Divacky 69891bc56edSDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, Mang, 69991bc56edSDimitry Andric TM, MMI, Streamer); 700f22ef01cSRoman Divacky } 701f22ef01cSRoman Divacky 70291bc56edSDimitry Andric MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol( 70391bc56edSDimitry Andric const GlobalValue *GV, Mangler &Mang, const TargetMachine &TM, 7043b0f4066SDimitry Andric MachineModuleInfo *MMI) const { 7053b0f4066SDimitry Andric // The mach-o version of this method defaults to returning a stub reference. 7063b0f4066SDimitry Andric MachineModuleInfoMachO &MachOMMI = 7073b0f4066SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 7083b0f4066SDimitry Andric 70991bc56edSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", Mang, TM); 7103b0f4066SDimitry Andric 7113b0f4066SDimitry Andric // Add information about the stub reference to MachOMMI so that the stub 7123b0f4066SDimitry Andric // gets emitted by the asmprinter. 713dff0c46cSDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 71491bc56edSDimitry Andric if (!StubSym.getPointer()) { 71591bc56edSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV, Mang); 7163b0f4066SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 7173b0f4066SDimitry Andric } 7183b0f4066SDimitry Andric 7193b0f4066SDimitry Andric return SSym; 7203b0f4066SDimitry Andric } 7213b0f4066SDimitry Andric 722ff0cc061SDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel( 723ff0cc061SDimitry Andric const MCSymbol *Sym, const MCValue &MV, int64_t Offset, 724ff0cc061SDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 7257d523365SDimitry Andric // Although MachO 32-bit targets do not explicitly have a GOTPCREL relocation 726ff0cc061SDimitry Andric // as 64-bit do, we replace the GOT equivalent by accessing the final symbol 727ff0cc061SDimitry Andric // through a non_lazy_ptr stub instead. One advantage is that it allows the 728ff0cc061SDimitry Andric // computation of deltas to final external symbols. Example: 729ff0cc061SDimitry Andric // 730ff0cc061SDimitry Andric // _extgotequiv: 731ff0cc061SDimitry Andric // .long _extfoo 732ff0cc061SDimitry Andric // 733ff0cc061SDimitry Andric // _delta: 734ff0cc061SDimitry Andric // .long _extgotequiv-_delta 735ff0cc061SDimitry Andric // 736ff0cc061SDimitry Andric // is transformed to: 737ff0cc061SDimitry Andric // 738ff0cc061SDimitry Andric // _delta: 739ff0cc061SDimitry Andric // .long L_extfoo$non_lazy_ptr-(_delta+0) 740ff0cc061SDimitry Andric // 741ff0cc061SDimitry Andric // .section __IMPORT,__pointers,non_lazy_symbol_pointers 742ff0cc061SDimitry Andric // L_extfoo$non_lazy_ptr: 743ff0cc061SDimitry Andric // .indirect_symbol _extfoo 744ff0cc061SDimitry Andric // .long 0 745ff0cc061SDimitry Andric // 746ff0cc061SDimitry Andric MachineModuleInfoMachO &MachOMMI = 747ff0cc061SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 748ff0cc061SDimitry Andric MCContext &Ctx = getContext(); 749ff0cc061SDimitry Andric 750ff0cc061SDimitry Andric // The offset must consider the original displacement from the base symbol 751ff0cc061SDimitry Andric // since 32-bit targets don't have a GOTPCREL to fold the PC displacement. 752ff0cc061SDimitry Andric Offset = -MV.getConstant(); 753ff0cc061SDimitry Andric const MCSymbol *BaseSym = &MV.getSymB()->getSymbol(); 754ff0cc061SDimitry Andric 755ff0cc061SDimitry Andric // Access the final symbol via sym$non_lazy_ptr and generate the appropriated 756ff0cc061SDimitry Andric // non_lazy_ptr stubs. 757ff0cc061SDimitry Andric SmallString<128> Name; 758ff0cc061SDimitry Andric StringRef Suffix = "$non_lazy_ptr"; 7597d523365SDimitry Andric Name += MMI->getModule()->getDataLayout().getPrivateGlobalPrefix(); 760ff0cc061SDimitry Andric Name += Sym->getName(); 761ff0cc061SDimitry Andric Name += Suffix; 762ff0cc061SDimitry Andric MCSymbol *Stub = Ctx.getOrCreateSymbol(Name); 763ff0cc061SDimitry Andric 764ff0cc061SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub); 765ff0cc061SDimitry Andric if (!StubSym.getPointer()) 766ff0cc061SDimitry Andric StubSym = MachineModuleInfoImpl:: 767ff0cc061SDimitry Andric StubValueTy(const_cast<MCSymbol *>(Sym), true /* access indirectly */); 768ff0cc061SDimitry Andric 769ff0cc061SDimitry Andric const MCExpr *BSymExpr = 77097bc6c73SDimitry Andric MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx); 771ff0cc061SDimitry Andric const MCExpr *LHS = 77297bc6c73SDimitry Andric MCSymbolRefExpr::create(Stub, MCSymbolRefExpr::VK_None, Ctx); 773ff0cc061SDimitry Andric 774ff0cc061SDimitry Andric if (!Offset) 77597bc6c73SDimitry Andric return MCBinaryExpr::createSub(LHS, BSymExpr, Ctx); 776ff0cc061SDimitry Andric 777ff0cc061SDimitry Andric const MCExpr *RHS = 77897bc6c73SDimitry Andric MCBinaryExpr::createAdd(BSymExpr, MCConstantExpr::create(Offset, Ctx), Ctx); 77997bc6c73SDimitry Andric return MCBinaryExpr::createSub(LHS, RHS, Ctx); 780ff0cc061SDimitry Andric } 781ff0cc061SDimitry Andric 7827d523365SDimitry Andric static bool canUsePrivateLabel(const MCAsmInfo &AsmInfo, 7837d523365SDimitry Andric const MCSection &Section) { 7847d523365SDimitry Andric if (!AsmInfo.isSectionAtomizableBySymbols(Section)) 7857d523365SDimitry Andric return true; 7867d523365SDimitry Andric 7877d523365SDimitry Andric // If it is not dead stripped, it is safe to use private labels. 7887d523365SDimitry Andric const MCSectionMachO &SMO = cast<MCSectionMachO>(Section); 7897d523365SDimitry Andric if (SMO.hasAttribute(MachO::S_ATTR_NO_DEAD_STRIP)) 7907d523365SDimitry Andric return true; 7917d523365SDimitry Andric 7927d523365SDimitry Andric return false; 7937d523365SDimitry Andric } 7947d523365SDimitry Andric 7957d523365SDimitry Andric void TargetLoweringObjectFileMachO::getNameWithPrefix( 7967d523365SDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, Mangler &Mang, 7977d523365SDimitry Andric const TargetMachine &TM) const { 7987d523365SDimitry Andric SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM); 7997d523365SDimitry Andric const MCSection *TheSection = SectionForGlobal(GV, GVKind, Mang, TM); 8007d523365SDimitry Andric bool CannotUsePrivateLabel = 8017d523365SDimitry Andric !canUsePrivateLabel(*TM.getMCAsmInfo(), *TheSection); 8027d523365SDimitry Andric Mang.getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 8037d523365SDimitry Andric } 8047d523365SDimitry Andric 805f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 806f22ef01cSRoman Divacky // COFF 807f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 808f22ef01cSRoman Divacky 809f22ef01cSRoman Divacky static unsigned 8103ca95b02SDimitry Andric getCOFFSectionFlags(SectionKind K, const TargetMachine &TM) { 811f22ef01cSRoman Divacky unsigned Flags = 0; 8123ca95b02SDimitry Andric bool isThumb = TM.getTargetTriple().getArch() == Triple::thumb; 813f22ef01cSRoman Divacky 814ffd1746dSEd Schouten if (K.isMetadata()) 815f22ef01cSRoman Divacky Flags |= 816ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_DISCARDABLE; 817f22ef01cSRoman Divacky else if (K.isText()) 818f22ef01cSRoman Divacky Flags |= 819ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_EXECUTE | 8202754fe60SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 8213ca95b02SDimitry Andric COFF::IMAGE_SCN_CNT_CODE | 8223ca95b02SDimitry Andric (isThumb ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0); 823f22ef01cSRoman Divacky else if (K.isBSS()) 824f22ef01cSRoman Divacky Flags |= 825ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | 826ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ | 827ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_WRITE; 828dff0c46cSDimitry Andric else if (K.isThreadLocal()) 829dff0c46cSDimitry Andric Flags |= 830dff0c46cSDimitry Andric COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 831dff0c46cSDimitry Andric COFF::IMAGE_SCN_MEM_READ | 832dff0c46cSDimitry Andric COFF::IMAGE_SCN_MEM_WRITE; 83339d628a0SDimitry Andric else if (K.isReadOnly() || K.isReadOnlyWithRel()) 834f22ef01cSRoman Divacky Flags |= 835ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 836ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ; 837f22ef01cSRoman Divacky else if (K.isWriteable()) 838f22ef01cSRoman Divacky Flags |= 839ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 840ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ | 841ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_WRITE; 842f22ef01cSRoman Divacky 843f22ef01cSRoman Divacky return Flags; 844f22ef01cSRoman Divacky } 845f22ef01cSRoman Divacky 84691bc56edSDimitry Andric static const GlobalValue *getComdatGVForCOFF(const GlobalValue *GV) { 84791bc56edSDimitry Andric const Comdat *C = GV->getComdat(); 84891bc56edSDimitry Andric assert(C && "expected GV to have a Comdat!"); 84991bc56edSDimitry Andric 85091bc56edSDimitry Andric StringRef ComdatGVName = C->getName(); 85191bc56edSDimitry Andric const GlobalValue *ComdatGV = GV->getParent()->getNamedValue(ComdatGVName); 85291bc56edSDimitry Andric if (!ComdatGV) 85391bc56edSDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 85491bc56edSDimitry Andric "' does not exist."); 85591bc56edSDimitry Andric 85691bc56edSDimitry Andric if (ComdatGV->getComdat() != C) 85791bc56edSDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 85839d628a0SDimitry Andric "' is not a key for its COMDAT."); 85991bc56edSDimitry Andric 86091bc56edSDimitry Andric return ComdatGV; 86191bc56edSDimitry Andric } 86291bc56edSDimitry Andric 86391bc56edSDimitry Andric static int getSelectionForCOFF(const GlobalValue *GV) { 86491bc56edSDimitry Andric if (const Comdat *C = GV->getComdat()) { 86591bc56edSDimitry Andric const GlobalValue *ComdatKey = getComdatGVForCOFF(GV); 86691bc56edSDimitry Andric if (const auto *GA = dyn_cast<GlobalAlias>(ComdatKey)) 86791bc56edSDimitry Andric ComdatKey = GA->getBaseObject(); 86891bc56edSDimitry Andric if (ComdatKey == GV) { 86991bc56edSDimitry Andric switch (C->getSelectionKind()) { 87091bc56edSDimitry Andric case Comdat::Any: 87191bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ANY; 87291bc56edSDimitry Andric case Comdat::ExactMatch: 87391bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH; 87491bc56edSDimitry Andric case Comdat::Largest: 87591bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_LARGEST; 87691bc56edSDimitry Andric case Comdat::NoDuplicates: 87791bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 87891bc56edSDimitry Andric case Comdat::SameSize: 87991bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_SAME_SIZE; 88091bc56edSDimitry Andric } 88191bc56edSDimitry Andric } else { 88291bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE; 88391bc56edSDimitry Andric } 88491bc56edSDimitry Andric } 88591bc56edSDimitry Andric return 0; 88691bc56edSDimitry Andric } 88791bc56edSDimitry Andric 888ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal( 88991bc56edSDimitry Andric const GlobalValue *GV, SectionKind Kind, Mangler &Mang, 89091bc56edSDimitry Andric const TargetMachine &TM) const { 891139f7f9bSDimitry Andric int Selection = 0; 8923ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 89391bc56edSDimitry Andric StringRef Name = GV->getSection(); 89491bc56edSDimitry Andric StringRef COMDATSymName = ""; 895ff0cc061SDimitry Andric if (GV->hasComdat()) { 89691bc56edSDimitry Andric Selection = getSelectionForCOFF(GV); 89791bc56edSDimitry Andric const GlobalValue *ComdatGV; 89891bc56edSDimitry Andric if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) 89991bc56edSDimitry Andric ComdatGV = getComdatGVForCOFF(GV); 90091bc56edSDimitry Andric else 90191bc56edSDimitry Andric ComdatGV = GV; 90291bc56edSDimitry Andric 90391bc56edSDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 90491bc56edSDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV, Mang); 90591bc56edSDimitry Andric COMDATSymName = Sym->getName(); 906139f7f9bSDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 90791bc56edSDimitry Andric } else { 90891bc56edSDimitry Andric Selection = 0; 90991bc56edSDimitry Andric } 910139f7f9bSDimitry Andric } 9113ca95b02SDimitry Andric 9123ca95b02SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, 913f785676fSDimitry Andric Selection); 914f22ef01cSRoman Divacky } 915f22ef01cSRoman Divacky 91691bc56edSDimitry Andric static const char *getCOFFSectionNameForUniqueGlobal(SectionKind Kind) { 917f22ef01cSRoman Divacky if (Kind.isText()) 91891bc56edSDimitry Andric return ".text"; 919f22ef01cSRoman Divacky if (Kind.isBSS()) 92091bc56edSDimitry Andric return ".bss"; 92191bc56edSDimitry Andric if (Kind.isThreadLocal()) 92291bc56edSDimitry Andric return ".tls$"; 92339d628a0SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 92491bc56edSDimitry Andric return ".rdata"; 92539d628a0SDimitry Andric return ".data"; 926f22ef01cSRoman Divacky } 927f22ef01cSRoman Divacky 928ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal( 929ff0cc061SDimitry Andric const GlobalValue *GV, SectionKind Kind, Mangler &Mang, 930ff0cc061SDimitry Andric const TargetMachine &TM) const { 93191bc56edSDimitry Andric // If we have -ffunction-sections then we should emit the global value to a 93291bc56edSDimitry Andric // uniqued section specifically for it. 93391bc56edSDimitry Andric bool EmitUniquedSection; 93491bc56edSDimitry Andric if (Kind.isText()) 93591bc56edSDimitry Andric EmitUniquedSection = TM.getFunctionSections(); 93691bc56edSDimitry Andric else 93791bc56edSDimitry Andric EmitUniquedSection = TM.getDataSections(); 938f22ef01cSRoman Divacky 939ff0cc061SDimitry Andric if ((EmitUniquedSection && !Kind.isCommon()) || GV->hasComdat()) { 94091bc56edSDimitry Andric const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); 9413ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 942f22ef01cSRoman Divacky 943ffd1746dSEd Schouten Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 94491bc56edSDimitry Andric int Selection = getSelectionForCOFF(GV); 94591bc56edSDimitry Andric if (!Selection) 94691bc56edSDimitry Andric Selection = COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 94791bc56edSDimitry Andric const GlobalValue *ComdatGV; 94891bc56edSDimitry Andric if (GV->hasComdat()) 94991bc56edSDimitry Andric ComdatGV = getComdatGVForCOFF(GV); 95091bc56edSDimitry Andric else 95191bc56edSDimitry Andric ComdatGV = GV; 952f22ef01cSRoman Divacky 9533ca95b02SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 9543ca95b02SDimitry Andric if (EmitUniquedSection) 9553ca95b02SDimitry Andric UniqueID = NextUniqueID++; 9563ca95b02SDimitry Andric 95791bc56edSDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 95891bc56edSDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV, Mang); 95991bc56edSDimitry Andric StringRef COMDATSymName = Sym->getName(); 96091bc56edSDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, 9613ca95b02SDimitry Andric COMDATSymName, Selection, UniqueID); 962ff0cc061SDimitry Andric } else { 963ff0cc061SDimitry Andric SmallString<256> TmpData; 9647d523365SDimitry Andric Mang.getNameWithPrefix(TmpData, GV, /*CannotUsePrivateLabel=*/true); 965ff0cc061SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, TmpData, 9663ca95b02SDimitry Andric Selection, UniqueID); 96791bc56edSDimitry Andric } 968f22ef01cSRoman Divacky } 969f22ef01cSRoman Divacky 970f22ef01cSRoman Divacky if (Kind.isText()) 971f785676fSDimitry Andric return TextSection; 972f22ef01cSRoman Divacky 973dff0c46cSDimitry Andric if (Kind.isThreadLocal()) 974f785676fSDimitry Andric return TLSDataSection; 975dff0c46cSDimitry Andric 97639d628a0SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 977f785676fSDimitry Andric return ReadOnlySection; 978f785676fSDimitry Andric 97991bc56edSDimitry Andric // Note: we claim that common symbols are put in BSSSection, but they are 98091bc56edSDimitry Andric // really emitted with the magic .comm directive, which creates a symbol table 98191bc56edSDimitry Andric // entry but not a section. 98291bc56edSDimitry Andric if (Kind.isBSS() || Kind.isCommon()) 983f785676fSDimitry Andric return BSSSection; 984f785676fSDimitry Andric 985f785676fSDimitry Andric return DataSection; 986f22ef01cSRoman Divacky } 987f22ef01cSRoman Divacky 988ff0cc061SDimitry Andric void TargetLoweringObjectFileCOFF::getNameWithPrefix( 9897d523365SDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, Mangler &Mang, 9907d523365SDimitry Andric const TargetMachine &TM) const { 9917d523365SDimitry Andric bool CannotUsePrivateLabel = false; 992ff0cc061SDimitry Andric if (GV->hasPrivateLinkage() && 993ff0cc061SDimitry Andric ((isa<Function>(GV) && TM.getFunctionSections()) || 994ff0cc061SDimitry Andric (isa<GlobalVariable>(GV) && TM.getDataSections()))) 995ff0cc061SDimitry Andric CannotUsePrivateLabel = true; 996ff0cc061SDimitry Andric 997ff0cc061SDimitry Andric Mang.getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 998ff0cc061SDimitry Andric } 999ff0cc061SDimitry Andric 1000ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable( 1001ff0cc061SDimitry Andric const Function &F, Mangler &Mang, const TargetMachine &TM) const { 1002ff0cc061SDimitry Andric // If the function can be removed, produce a unique section so that 1003ff0cc061SDimitry Andric // the table doesn't prevent the removal. 1004ff0cc061SDimitry Andric const Comdat *C = F.getComdat(); 1005ff0cc061SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C; 1006ff0cc061SDimitry Andric if (!EmitUniqueSection) 1007ff0cc061SDimitry Andric return ReadOnlySection; 1008ff0cc061SDimitry Andric 1009ff0cc061SDimitry Andric // FIXME: we should produce a symbol for F instead. 1010ff0cc061SDimitry Andric if (F.hasPrivateLinkage()) 1011ff0cc061SDimitry Andric return ReadOnlySection; 1012ff0cc061SDimitry Andric 1013ff0cc061SDimitry Andric MCSymbol *Sym = TM.getSymbol(&F, Mang); 1014ff0cc061SDimitry Andric StringRef COMDATSymName = Sym->getName(); 1015ff0cc061SDimitry Andric 1016ff0cc061SDimitry Andric SectionKind Kind = SectionKind::getReadOnly(); 1017ff0cc061SDimitry Andric const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); 10183ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 1019ff0cc061SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 10203ca95b02SDimitry Andric unsigned UniqueID = NextUniqueID++; 1021ff0cc061SDimitry Andric 1022ff0cc061SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, 10233ca95b02SDimitry Andric COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); 1024ff0cc061SDimitry Andric } 1025ff0cc061SDimitry Andric 1026284c1978SDimitry Andric void TargetLoweringObjectFileCOFF:: 1027284c1978SDimitry Andric emitModuleFlags(MCStreamer &Streamer, 1028284c1978SDimitry Andric ArrayRef<Module::ModuleFlagEntry> ModuleFlags, 102991bc56edSDimitry Andric Mangler &Mang, const TargetMachine &TM) const { 103091bc56edSDimitry Andric MDNode *LinkerOptions = nullptr; 1031284c1978SDimitry Andric 10323ca95b02SDimitry Andric for (const auto &MFE : ModuleFlags) { 1033284c1978SDimitry Andric StringRef Key = MFE.Key->getString(); 10343ca95b02SDimitry Andric if (Key == "Linker Options") 10353ca95b02SDimitry Andric LinkerOptions = cast<MDNode>(MFE.Val); 1036284c1978SDimitry Andric } 1037284c1978SDimitry Andric 10383ca95b02SDimitry Andric if (LinkerOptions) { 1039284c1978SDimitry Andric // Emit the linker options to the linker .drectve section. According to the 10403ca95b02SDimitry Andric // spec, this section is a space-separated string containing flags for 10413ca95b02SDimitry Andric // linker. 1042ff0cc061SDimitry Andric MCSection *Sec = getDrectveSection(); 1043284c1978SDimitry Andric Streamer.SwitchSection(Sec); 10443ca95b02SDimitry Andric for (const auto &Option : LinkerOptions->operands()) { 10453ca95b02SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) { 1046284c1978SDimitry Andric // Lead with a space for consistency with our dllexport implementation. 1047ff0cc061SDimitry Andric std::string Directive(" "); 10483ca95b02SDimitry Andric Directive.append(cast<MDString>(Piece)->getString()); 1049ff0cc061SDimitry Andric Streamer.EmitBytes(Directive); 1050284c1978SDimitry Andric } 1051284c1978SDimitry Andric } 1052284c1978SDimitry Andric } 10533ca95b02SDimitry Andric } 105491bc56edSDimitry Andric 1055ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection( 105691bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 105739d628a0SDimitry Andric return getContext().getAssociativeCOFFSection( 10583ca95b02SDimitry Andric cast<MCSectionCOFF>(StaticCtorSection), KeySym, 0); 105991bc56edSDimitry Andric } 106091bc56edSDimitry Andric 1061ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection( 106291bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 106339d628a0SDimitry Andric return getContext().getAssociativeCOFFSection( 10643ca95b02SDimitry Andric cast<MCSectionCOFF>(StaticDtorSection), KeySym, 0); 106591bc56edSDimitry Andric } 10663dac3a9bSDimitry Andric 10673dac3a9bSDimitry Andric void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal( 10683dac3a9bSDimitry Andric raw_ostream &OS, const GlobalValue *GV, const Mangler &Mang) const { 10693dac3a9bSDimitry Andric if (!GV->hasDLLExportStorageClass() || GV->isDeclaration()) 10703dac3a9bSDimitry Andric return; 10713dac3a9bSDimitry Andric 10723dac3a9bSDimitry Andric const Triple &TT = getTargetTriple(); 10733dac3a9bSDimitry Andric 10743dac3a9bSDimitry Andric if (TT.isKnownWindowsMSVCEnvironment()) 10753dac3a9bSDimitry Andric OS << " /EXPORT:"; 10763dac3a9bSDimitry Andric else 10773dac3a9bSDimitry Andric OS << " -export:"; 10783dac3a9bSDimitry Andric 10793dac3a9bSDimitry Andric if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) { 10803dac3a9bSDimitry Andric std::string Flag; 10813dac3a9bSDimitry Andric raw_string_ostream FlagOS(Flag); 10823dac3a9bSDimitry Andric Mang.getNameWithPrefix(FlagOS, GV, false); 10833dac3a9bSDimitry Andric FlagOS.flush(); 10847d523365SDimitry Andric if (Flag[0] == GV->getParent()->getDataLayout().getGlobalPrefix()) 10853dac3a9bSDimitry Andric OS << Flag.substr(1); 10863dac3a9bSDimitry Andric else 10873dac3a9bSDimitry Andric OS << Flag; 10883dac3a9bSDimitry Andric } else { 10893dac3a9bSDimitry Andric Mang.getNameWithPrefix(OS, GV, false); 10903dac3a9bSDimitry Andric } 10913dac3a9bSDimitry Andric 10923dac3a9bSDimitry Andric if (!GV->getValueType()->isFunctionTy()) { 10933dac3a9bSDimitry Andric if (TT.isKnownWindowsMSVCEnvironment()) 10943dac3a9bSDimitry Andric OS << ",DATA"; 10953dac3a9bSDimitry Andric else 10963dac3a9bSDimitry Andric OS << ",data"; 10973dac3a9bSDimitry Andric } 10983dac3a9bSDimitry Andric } 1099