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( 53d88c1a5aSDimitry Andric const GlobalValue *GV, 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.") + 58d88c1a5aSDimitry Andric TM.getSymbol(GV)->getName()); 5991bc56edSDimitry Andric if ((Encoding & 0x70) == dwarf::DW_EH_PE_absptr) 60d88c1a5aSDimitry Andric return TM.getSymbol(GV); 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( 87d88c1a5aSDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, 88d88c1a5aSDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 89139f7f9bSDimitry Andric 90139f7f9bSDimitry Andric if (Encoding & dwarf::DW_EH_PE_indirect) { 91139f7f9bSDimitry Andric MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>(); 92139f7f9bSDimitry Andric 93d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", 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()) { 99d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 100139f7f9bSDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 101139f7f9bSDimitry Andric } 102139f7f9bSDimitry Andric 103139f7f9bSDimitry Andric return TargetLoweringObjectFile:: 10497bc6c73SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), 105139f7f9bSDimitry Andric Encoding & ~dwarf::DW_EH_PE_indirect, Streamer); 106139f7f9bSDimitry Andric } 107139f7f9bSDimitry Andric 108d88c1a5aSDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM, 109d88c1a5aSDimitry Andric 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 1203ca95b02SDimitry Andric 1213ca95b02SDimitry Andric if (Name == getInstrProfCoverageSectionName(false)) 1223ca95b02SDimitry Andric return SectionKind::getMetadata(); 1233ca95b02SDimitry Andric 124f22ef01cSRoman Divacky if (Name.empty() || Name[0] != '.') return K; 125f22ef01cSRoman Divacky 126f22ef01cSRoman Divacky // Some lame default implementation based on some magic section names. 127f22ef01cSRoman Divacky if (Name == ".bss" || 128f22ef01cSRoman Divacky Name.startswith(".bss.") || 129f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.b.") || 130f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.b.") || 131f22ef01cSRoman Divacky Name == ".sbss" || 132f22ef01cSRoman Divacky Name.startswith(".sbss.") || 133f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.sb.") || 134f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.sb.")) 135f22ef01cSRoman Divacky return SectionKind::getBSS(); 136f22ef01cSRoman Divacky 137f22ef01cSRoman Divacky if (Name == ".tdata" || 138f22ef01cSRoman Divacky Name.startswith(".tdata.") || 139f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.td.") || 140f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.td.")) 141f22ef01cSRoman Divacky return SectionKind::getThreadData(); 142f22ef01cSRoman Divacky 143f22ef01cSRoman Divacky if (Name == ".tbss" || 144f22ef01cSRoman Divacky Name.startswith(".tbss.") || 145f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.tb.") || 146f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.tb.")) 147f22ef01cSRoman Divacky return SectionKind::getThreadBSS(); 148f22ef01cSRoman Divacky 149f22ef01cSRoman Divacky return K; 150f22ef01cSRoman Divacky } 151f22ef01cSRoman Divacky 152f22ef01cSRoman Divacky 153f22ef01cSRoman Divacky static unsigned getELFSectionType(StringRef Name, SectionKind K) { 154d88c1a5aSDimitry Andric // Use SHT_NOTE for section whose name starts with ".note" to allow 155d88c1a5aSDimitry Andric // emitting ELF notes from C variable declaration. 156d88c1a5aSDimitry Andric // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77609 157d88c1a5aSDimitry Andric if (Name.startswith(".note")) 158d88c1a5aSDimitry Andric return ELF::SHT_NOTE; 159f22ef01cSRoman Divacky 160f22ef01cSRoman Divacky if (Name == ".init_array") 1612754fe60SDimitry Andric return ELF::SHT_INIT_ARRAY; 162f22ef01cSRoman Divacky 163f22ef01cSRoman Divacky if (Name == ".fini_array") 1642754fe60SDimitry Andric return ELF::SHT_FINI_ARRAY; 165f22ef01cSRoman Divacky 166f22ef01cSRoman Divacky if (Name == ".preinit_array") 1672754fe60SDimitry Andric return ELF::SHT_PREINIT_ARRAY; 168f22ef01cSRoman Divacky 169f22ef01cSRoman Divacky if (K.isBSS() || K.isThreadBSS()) 1702754fe60SDimitry Andric return ELF::SHT_NOBITS; 171f22ef01cSRoman Divacky 1722754fe60SDimitry Andric return ELF::SHT_PROGBITS; 173f22ef01cSRoman Divacky } 174f22ef01cSRoman Divacky 175ff0cc061SDimitry Andric static unsigned getELFSectionFlags(SectionKind K) { 176f22ef01cSRoman Divacky unsigned Flags = 0; 177f22ef01cSRoman Divacky 178f22ef01cSRoman Divacky if (!K.isMetadata()) 1792754fe60SDimitry Andric Flags |= ELF::SHF_ALLOC; 180f22ef01cSRoman Divacky 181f22ef01cSRoman Divacky if (K.isText()) 1822754fe60SDimitry Andric Flags |= ELF::SHF_EXECINSTR; 183f22ef01cSRoman Divacky 184d88c1a5aSDimitry Andric if (K.isExecuteOnly()) 185d88c1a5aSDimitry Andric Flags |= ELF::SHF_ARM_PURECODE; 186d88c1a5aSDimitry Andric 187f22ef01cSRoman Divacky if (K.isWriteable()) 1882754fe60SDimitry Andric Flags |= ELF::SHF_WRITE; 189f22ef01cSRoman Divacky 190f22ef01cSRoman Divacky if (K.isThreadLocal()) 1912754fe60SDimitry Andric Flags |= ELF::SHF_TLS; 192f22ef01cSRoman Divacky 193ff0cc061SDimitry Andric if (K.isMergeableCString() || K.isMergeableConst()) 1942754fe60SDimitry Andric Flags |= ELF::SHF_MERGE; 195f22ef01cSRoman Divacky 196f22ef01cSRoman Divacky if (K.isMergeableCString()) 1972754fe60SDimitry Andric Flags |= ELF::SHF_STRINGS; 198f22ef01cSRoman Divacky 199f22ef01cSRoman Divacky return Flags; 200f22ef01cSRoman Divacky } 201f22ef01cSRoman Divacky 20291bc56edSDimitry Andric static const Comdat *getELFComdat(const GlobalValue *GV) { 20391bc56edSDimitry Andric const Comdat *C = GV->getComdat(); 20491bc56edSDimitry Andric if (!C) 20591bc56edSDimitry Andric return nullptr; 206f22ef01cSRoman Divacky 20791bc56edSDimitry Andric if (C->getSelectionKind() != Comdat::Any) 20891bc56edSDimitry Andric report_fatal_error("ELF COMDATs only support SelectionKind::Any, '" + 20991bc56edSDimitry Andric C->getName() + "' cannot be lowered."); 21091bc56edSDimitry Andric 21191bc56edSDimitry Andric return C; 21291bc56edSDimitry Andric } 21391bc56edSDimitry Andric 214ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( 215d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 216d88c1a5aSDimitry Andric StringRef SectionName = GO->getSection(); 217f22ef01cSRoman Divacky 218f22ef01cSRoman Divacky // Infer section flags from the section name if we can. 219f22ef01cSRoman Divacky Kind = getELFKindForNamedSection(SectionName, Kind); 220f22ef01cSRoman Divacky 22191bc56edSDimitry Andric StringRef Group = ""; 22291bc56edSDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 223d88c1a5aSDimitry Andric if (const Comdat *C = getELFComdat(GO)) { 22491bc56edSDimitry Andric Group = C->getName(); 22591bc56edSDimitry Andric Flags |= ELF::SHF_GROUP; 22691bc56edSDimitry Andric } 227f22ef01cSRoman Divacky return getContext().getELFSection(SectionName, 22891bc56edSDimitry Andric getELFSectionType(SectionName, Kind), Flags, 229ff0cc061SDimitry Andric /*EntrySize=*/0, Group); 230f22ef01cSRoman Divacky } 231f22ef01cSRoman Divacky 232ff0cc061SDimitry Andric /// Return the section prefix name used by options FunctionsSections and 233ff0cc061SDimitry Andric /// DataSections. 23491bc56edSDimitry Andric static StringRef getSectionPrefixForGlobal(SectionKind Kind) { 235ff0cc061SDimitry Andric if (Kind.isText()) 236ff0cc061SDimitry Andric return ".text"; 237ff0cc061SDimitry Andric if (Kind.isReadOnly()) 238ff0cc061SDimitry Andric return ".rodata"; 239ff0cc061SDimitry Andric if (Kind.isBSS()) 240ff0cc061SDimitry Andric return ".bss"; 241ff0cc061SDimitry Andric if (Kind.isThreadData()) 242ff0cc061SDimitry Andric return ".tdata"; 243ff0cc061SDimitry Andric if (Kind.isThreadBSS()) 244ff0cc061SDimitry Andric return ".tbss"; 2457d523365SDimitry Andric if (Kind.isData()) 246ff0cc061SDimitry Andric return ".data"; 247f22ef01cSRoman Divacky assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); 248ff0cc061SDimitry Andric return ".data.rel.ro"; 249f22ef01cSRoman Divacky } 250f22ef01cSRoman Divacky 251ff0cc061SDimitry Andric static MCSectionELF * 252d88c1a5aSDimitry Andric selectELFSectionForGlobal(MCContext &Ctx, const GlobalObject *GO, 253ff0cc061SDimitry Andric SectionKind Kind, Mangler &Mang, 254ff0cc061SDimitry Andric const TargetMachine &TM, bool EmitUniqueSection, 255ff0cc061SDimitry Andric unsigned Flags, unsigned *NextUniqueID) { 256ff0cc061SDimitry Andric unsigned EntrySize = 0; 257ff0cc061SDimitry Andric if (Kind.isMergeableCString()) { 258ff0cc061SDimitry Andric if (Kind.isMergeable2ByteCString()) { 259ff0cc061SDimitry Andric EntrySize = 2; 260ff0cc061SDimitry Andric } else if (Kind.isMergeable4ByteCString()) { 261ff0cc061SDimitry Andric EntrySize = 4; 262ff0cc061SDimitry Andric } else { 263ff0cc061SDimitry Andric EntrySize = 1; 264ff0cc061SDimitry Andric assert(Kind.isMergeable1ByteCString() && "unknown string width"); 265ff0cc061SDimitry Andric } 266ff0cc061SDimitry Andric } else if (Kind.isMergeableConst()) { 267ff0cc061SDimitry Andric if (Kind.isMergeableConst4()) { 268ff0cc061SDimitry Andric EntrySize = 4; 269ff0cc061SDimitry Andric } else if (Kind.isMergeableConst8()) { 270ff0cc061SDimitry Andric EntrySize = 8; 2713ca95b02SDimitry Andric } else if (Kind.isMergeableConst16()) { 272ff0cc061SDimitry Andric EntrySize = 16; 2733ca95b02SDimitry Andric } else { 2743ca95b02SDimitry Andric assert(Kind.isMergeableConst32() && "unknown data width"); 2753ca95b02SDimitry Andric EntrySize = 32; 276ff0cc061SDimitry Andric } 277ff0cc061SDimitry Andric } 27891bc56edSDimitry Andric 2792754fe60SDimitry Andric StringRef Group = ""; 280d88c1a5aSDimitry Andric if (const Comdat *C = getELFComdat(GO)) { 2812754fe60SDimitry Andric Flags |= ELF::SHF_GROUP; 282ff0cc061SDimitry Andric Group = C->getName(); 2832754fe60SDimitry Andric } 2842754fe60SDimitry Andric 285ff0cc061SDimitry Andric bool UniqueSectionNames = TM.getUniqueSectionNames(); 286ff0cc061SDimitry Andric SmallString<128> Name; 287ff0cc061SDimitry Andric if (Kind.isMergeableCString()) { 288f22ef01cSRoman Divacky // We also need alignment here. 289f22ef01cSRoman Divacky // FIXME: this is getting the alignment of the character, not the 290f22ef01cSRoman Divacky // alignment of the global! 291d88c1a5aSDimitry Andric unsigned Align = GO->getParent()->getDataLayout().getPreferredAlignment( 292d88c1a5aSDimitry Andric cast<GlobalVariable>(GO)); 293f22ef01cSRoman Divacky 294ff0cc061SDimitry Andric std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + "."; 295ff0cc061SDimitry Andric Name = SizeSpec + utostr(Align); 296ff0cc061SDimitry Andric } else if (Kind.isMergeableConst()) { 297ff0cc061SDimitry Andric Name = ".rodata.cst"; 298ff0cc061SDimitry Andric Name += utostr(EntrySize); 299ff0cc061SDimitry Andric } else { 300ff0cc061SDimitry Andric Name = getSectionPrefixForGlobal(Kind); 301ff0cc061SDimitry Andric } 302d88c1a5aSDimitry Andric 303d88c1a5aSDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) { 304d88c1a5aSDimitry Andric const auto &OptionalPrefix = F->getSectionPrefix(); 305d88c1a5aSDimitry Andric if (OptionalPrefix) 306d88c1a5aSDimitry Andric Name += *OptionalPrefix; 307d88c1a5aSDimitry Andric } 308ff0cc061SDimitry Andric 309ff0cc061SDimitry Andric if (EmitUniqueSection && UniqueSectionNames) { 310ff0cc061SDimitry Andric Name.push_back('.'); 311d88c1a5aSDimitry Andric TM.getNameWithPrefix(Name, GO, Mang, true); 312ff0cc061SDimitry Andric } 3133ca95b02SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 314ff0cc061SDimitry Andric if (EmitUniqueSection && !UniqueSectionNames) { 315ff0cc061SDimitry Andric UniqueID = *NextUniqueID; 316ff0cc061SDimitry Andric (*NextUniqueID)++; 317ff0cc061SDimitry Andric } 318d88c1a5aSDimitry Andric // Use 0 as the unique ID for execute-only text 319d88c1a5aSDimitry Andric if (Kind.isExecuteOnly()) 320d88c1a5aSDimitry Andric UniqueID = 0; 321ff0cc061SDimitry Andric return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags, 322ff0cc061SDimitry Andric EntrySize, Group, UniqueID); 323ff0cc061SDimitry Andric } 324ff0cc061SDimitry Andric 325ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( 326d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 327ff0cc061SDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 328ff0cc061SDimitry Andric 329ff0cc061SDimitry Andric // If we have -ffunction-section or -fdata-section then we should emit the 330ff0cc061SDimitry Andric // global value to a uniqued section specifically for it. 331ff0cc061SDimitry Andric bool EmitUniqueSection = false; 332ff0cc061SDimitry Andric if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) { 333ff0cc061SDimitry Andric if (Kind.isText()) 334ff0cc061SDimitry Andric EmitUniqueSection = TM.getFunctionSections(); 335f22ef01cSRoman Divacky else 336ff0cc061SDimitry Andric EmitUniqueSection = TM.getDataSections(); 337ff0cc061SDimitry Andric } 338d88c1a5aSDimitry Andric EmitUniqueSection |= GO->hasComdat(); 339f22ef01cSRoman Divacky 340d88c1a5aSDimitry Andric return selectELFSectionForGlobal(getContext(), GO, Kind, getMangler(), TM, 341ff0cc061SDimitry Andric EmitUniqueSection, Flags, &NextUniqueID); 342f22ef01cSRoman Divacky } 343f22ef01cSRoman Divacky 344ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( 345d88c1a5aSDimitry Andric const Function &F, const TargetMachine &TM) const { 346ff0cc061SDimitry Andric // If the function can be removed, produce a unique section so that 347ff0cc061SDimitry Andric // the table doesn't prevent the removal. 348ff0cc061SDimitry Andric const Comdat *C = F.getComdat(); 349ff0cc061SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C; 350ff0cc061SDimitry Andric if (!EmitUniqueSection) 351ff0cc061SDimitry Andric return ReadOnlySection; 352ff0cc061SDimitry Andric 353ff0cc061SDimitry Andric return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(), 354d88c1a5aSDimitry Andric getMangler(), TM, EmitUniqueSection, ELF::SHF_ALLOC, 355ff0cc061SDimitry Andric &NextUniqueID); 356f22ef01cSRoman Divacky } 357f22ef01cSRoman Divacky 358ff0cc061SDimitry Andric bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection( 359ff0cc061SDimitry Andric bool UsesLabelDifference, const Function &F) const { 360ff0cc061SDimitry Andric // We can always create relative relocations, so use another section 361ff0cc061SDimitry Andric // that can be marked non-executable. 362ff0cc061SDimitry Andric return false; 363f22ef01cSRoman Divacky } 364f22ef01cSRoman Divacky 365ff0cc061SDimitry Andric /// Given a mergeable constant with the specified size and relocation 366ff0cc061SDimitry Andric /// information, return a section that it should be placed in. 3677d523365SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForConstant( 3683ca95b02SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 3693ca95b02SDimitry Andric unsigned &Align) const { 370f22ef01cSRoman Divacky if (Kind.isMergeableConst4() && MergeableConst4Section) 371f22ef01cSRoman Divacky return MergeableConst4Section; 372f22ef01cSRoman Divacky if (Kind.isMergeableConst8() && MergeableConst8Section) 373f22ef01cSRoman Divacky return MergeableConst8Section; 374f22ef01cSRoman Divacky if (Kind.isMergeableConst16() && MergeableConst16Section) 375f22ef01cSRoman Divacky return MergeableConst16Section; 3763ca95b02SDimitry Andric if (Kind.isMergeableConst32() && MergeableConst32Section) 3773ca95b02SDimitry Andric return MergeableConst32Section; 378f22ef01cSRoman Divacky if (Kind.isReadOnly()) 379f22ef01cSRoman Divacky return ReadOnlySection; 380f22ef01cSRoman Divacky 381f22ef01cSRoman Divacky assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); 382f22ef01cSRoman Divacky return DataRelROSection; 383f22ef01cSRoman Divacky } 384f22ef01cSRoman Divacky 385ff0cc061SDimitry Andric static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray, 386ff0cc061SDimitry Andric bool IsCtor, unsigned Priority, 38739d628a0SDimitry Andric const MCSymbol *KeySym) { 38839d628a0SDimitry Andric std::string Name; 38939d628a0SDimitry Andric unsigned Type; 39039d628a0SDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE; 39139d628a0SDimitry Andric StringRef COMDAT = KeySym ? KeySym->getName() : ""; 39239d628a0SDimitry Andric 39339d628a0SDimitry Andric if (KeySym) 39439d628a0SDimitry Andric Flags |= ELF::SHF_GROUP; 395dff0c46cSDimitry Andric 3967ae0e2c9SDimitry Andric if (UseInitArray) { 39739d628a0SDimitry Andric if (IsCtor) { 39839d628a0SDimitry Andric Type = ELF::SHT_INIT_ARRAY; 39939d628a0SDimitry Andric Name = ".init_array"; 4007ae0e2c9SDimitry Andric } else { 40139d628a0SDimitry Andric Type = ELF::SHT_FINI_ARRAY; 40239d628a0SDimitry Andric Name = ".fini_array"; 403dff0c46cSDimitry Andric } 40439d628a0SDimitry Andric if (Priority != 65535) { 40539d628a0SDimitry Andric Name += '.'; 40639d628a0SDimitry Andric Name += utostr(Priority); 40739d628a0SDimitry Andric } 40839d628a0SDimitry Andric } else { 40939d628a0SDimitry Andric // The default scheme is .ctor / .dtor, so we have to invert the priority 41039d628a0SDimitry Andric // numbering. 41139d628a0SDimitry Andric if (IsCtor) 41239d628a0SDimitry Andric Name = ".ctors"; 41339d628a0SDimitry Andric else 41439d628a0SDimitry Andric Name = ".dtors"; 41539d628a0SDimitry Andric if (Priority != 65535) { 41639d628a0SDimitry Andric Name += '.'; 41739d628a0SDimitry Andric Name += utostr(65535 - Priority); 41839d628a0SDimitry Andric } 41939d628a0SDimitry Andric Type = ELF::SHT_PROGBITS; 42039d628a0SDimitry Andric } 42139d628a0SDimitry Andric 422ff0cc061SDimitry Andric return Ctx.getELFSection(Name, Type, Flags, 0, COMDAT); 42339d628a0SDimitry Andric } 42439d628a0SDimitry Andric 425ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticCtorSection( 42639d628a0SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 42739d628a0SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, true, Priority, 42839d628a0SDimitry Andric KeySym); 4297ae0e2c9SDimitry Andric } 430dff0c46cSDimitry Andric 431ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticDtorSection( 43291bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 43339d628a0SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, false, Priority, 43439d628a0SDimitry Andric KeySym); 4357ae0e2c9SDimitry Andric } 4367ae0e2c9SDimitry Andric 4373ca95b02SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference( 438d88c1a5aSDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 4393ca95b02SDimitry Andric const TargetMachine &TM) const { 4403ca95b02SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr 4413ca95b02SDimitry Andric // functions. 4423ca95b02SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) 4433ca95b02SDimitry Andric return nullptr; 4443ca95b02SDimitry Andric 4453ca95b02SDimitry Andric // Basic sanity checks. 4463ca95b02SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 4473ca95b02SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || 4483ca95b02SDimitry Andric RHS->isThreadLocal()) 4493ca95b02SDimitry Andric return nullptr; 4503ca95b02SDimitry Andric 4513ca95b02SDimitry Andric return MCBinaryExpr::createSub( 452d88c1a5aSDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS), PLTRelativeVariantKind, 4533ca95b02SDimitry Andric getContext()), 454d88c1a5aSDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); 4553ca95b02SDimitry Andric } 4563ca95b02SDimitry Andric 4577ae0e2c9SDimitry Andric void 4587ae0e2c9SDimitry Andric TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) { 4597ae0e2c9SDimitry Andric UseInitArray = UseInitArray_; 460d88c1a5aSDimitry Andric MCContext &Ctx = getContext(); 461d88c1a5aSDimitry Andric if (!UseInitArray) { 462d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getELFSection(".ctors", ELF::SHT_PROGBITS, 463d88c1a5aSDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE); 4647ae0e2c9SDimitry Andric 465d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getELFSection(".dtors", ELF::SHT_PROGBITS, 466d88c1a5aSDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE); 467d88c1a5aSDimitry Andric return; 468d88c1a5aSDimitry Andric } 469d88c1a5aSDimitry Andric 470d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getELFSection(".init_array", ELF::SHT_INIT_ARRAY, 471d88c1a5aSDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC); 472d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getELFSection(".fini_array", ELF::SHT_FINI_ARRAY, 473d88c1a5aSDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC); 4747ae0e2c9SDimitry Andric } 475dff0c46cSDimitry Andric 476f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 477f22ef01cSRoman Divacky // MachO 478f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 479f22ef01cSRoman Divacky 480ff0cc061SDimitry Andric TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO() 481ff0cc061SDimitry Andric : TargetLoweringObjectFile() { 482ff0cc061SDimitry Andric SupportIndirectSymViaGOTPCRel = true; 483ff0cc061SDimitry Andric } 484ff0cc061SDimitry Andric 485d88c1a5aSDimitry Andric void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx, 486d88c1a5aSDimitry Andric const TargetMachine &TM) { 487d88c1a5aSDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM); 488d88c1a5aSDimitry Andric if (TM.getRelocationModel() == Reloc::Static) { 489d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getMachOSection("__TEXT", "__constructor", 0, 490d88c1a5aSDimitry Andric SectionKind::getData()); 491d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getMachOSection("__TEXT", "__destructor", 0, 492d88c1a5aSDimitry Andric SectionKind::getData()); 493d88c1a5aSDimitry Andric } else { 494d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getMachOSection("__DATA", "__mod_init_func", 495d88c1a5aSDimitry Andric MachO::S_MOD_INIT_FUNC_POINTERS, 496d88c1a5aSDimitry Andric SectionKind::getData()); 497d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getMachOSection("__DATA", "__mod_term_func", 498d88c1a5aSDimitry Andric MachO::S_MOD_TERM_FUNC_POINTERS, 499d88c1a5aSDimitry Andric SectionKind::getData()); 500d88c1a5aSDimitry Andric } 501d88c1a5aSDimitry Andric } 502d88c1a5aSDimitry Andric 503139f7f9bSDimitry Andric /// emitModuleFlags - Perform code emission for module flags. 504d88c1a5aSDimitry Andric void TargetLoweringObjectFileMachO::emitModuleFlags( 505d88c1a5aSDimitry Andric MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, 506d88c1a5aSDimitry Andric const TargetMachine &TM) const { 507dff0c46cSDimitry Andric unsigned VersionVal = 0; 5087ae0e2c9SDimitry Andric unsigned ImageInfoFlags = 0; 50991bc56edSDimitry Andric MDNode *LinkerOptions = nullptr; 510dff0c46cSDimitry Andric StringRef SectionVal; 511dff0c46cSDimitry Andric 5123ca95b02SDimitry Andric for (const auto &MFE : ModuleFlags) { 513dff0c46cSDimitry Andric // Ignore flags with 'Require' behavior. 514dff0c46cSDimitry Andric if (MFE.Behavior == Module::Require) 515dff0c46cSDimitry Andric continue; 516dff0c46cSDimitry Andric 517dff0c46cSDimitry Andric StringRef Key = MFE.Key->getString(); 51839d628a0SDimitry Andric Metadata *Val = MFE.Val; 519dff0c46cSDimitry Andric 520139f7f9bSDimitry Andric if (Key == "Objective-C Image Info Version") { 52139d628a0SDimitry Andric VersionVal = mdconst::extract<ConstantInt>(Val)->getZExtValue(); 522139f7f9bSDimitry Andric } else if (Key == "Objective-C Garbage Collection" || 5237ae0e2c9SDimitry Andric Key == "Objective-C GC Only" || 52439d628a0SDimitry Andric Key == "Objective-C Is Simulated" || 5253ca95b02SDimitry Andric Key == "Objective-C Class Properties" || 52639d628a0SDimitry Andric Key == "Objective-C Image Swift Version") { 52739d628a0SDimitry Andric ImageInfoFlags |= mdconst::extract<ConstantInt>(Val)->getZExtValue(); 528139f7f9bSDimitry Andric } else if (Key == "Objective-C Image Info Section") { 529dff0c46cSDimitry Andric SectionVal = cast<MDString>(Val)->getString(); 530139f7f9bSDimitry Andric } else if (Key == "Linker Options") { 531139f7f9bSDimitry Andric LinkerOptions = cast<MDNode>(Val); 532139f7f9bSDimitry Andric } 533139f7f9bSDimitry Andric } 534139f7f9bSDimitry Andric 535139f7f9bSDimitry Andric // Emit the linker options if present. 536139f7f9bSDimitry Andric if (LinkerOptions) { 5373ca95b02SDimitry Andric for (const auto &Option : LinkerOptions->operands()) { 538139f7f9bSDimitry Andric SmallVector<std::string, 4> StrOptions; 5393ca95b02SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) 5403ca95b02SDimitry Andric StrOptions.push_back(cast<MDString>(Piece)->getString()); 541139f7f9bSDimitry Andric Streamer.EmitLinkerOptions(StrOptions); 542139f7f9bSDimitry Andric } 543dff0c46cSDimitry Andric } 544dff0c46cSDimitry Andric 545dff0c46cSDimitry Andric // The section is mandatory. If we don't have it, then we don't have GC info. 546dff0c46cSDimitry Andric if (SectionVal.empty()) return; 547dff0c46cSDimitry Andric 548dff0c46cSDimitry Andric StringRef Segment, Section; 549dff0c46cSDimitry Andric unsigned TAA = 0, StubSize = 0; 550dff0c46cSDimitry Andric bool TAAParsed; 551dff0c46cSDimitry Andric std::string ErrorCode = 552dff0c46cSDimitry Andric MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section, 553dff0c46cSDimitry Andric TAA, TAAParsed, StubSize); 554dff0c46cSDimitry Andric if (!ErrorCode.empty()) 555dff0c46cSDimitry Andric // If invalid, report the error with report_fatal_error. 556dff0c46cSDimitry Andric report_fatal_error("Invalid section specifier '" + Section + "': " + 557dff0c46cSDimitry Andric ErrorCode + "."); 558dff0c46cSDimitry Andric 559dff0c46cSDimitry Andric // Get the section. 560ff0cc061SDimitry Andric MCSectionMachO *S = getContext().getMachOSection( 5617d523365SDimitry Andric Segment, Section, TAA, StubSize, SectionKind::getData()); 562dff0c46cSDimitry Andric Streamer.SwitchSection(S); 563dff0c46cSDimitry Andric Streamer.EmitLabel(getContext(). 564ff0cc061SDimitry Andric getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); 565dff0c46cSDimitry Andric Streamer.EmitIntValue(VersionVal, 4); 5667ae0e2c9SDimitry Andric Streamer.EmitIntValue(ImageInfoFlags, 4); 567dff0c46cSDimitry Andric Streamer.AddBlankLine(); 568dff0c46cSDimitry Andric } 569dff0c46cSDimitry Andric 57091bc56edSDimitry Andric static void checkMachOComdat(const GlobalValue *GV) { 57191bc56edSDimitry Andric const Comdat *C = GV->getComdat(); 57291bc56edSDimitry Andric if (!C) 57391bc56edSDimitry Andric return; 57491bc56edSDimitry Andric 57591bc56edSDimitry Andric report_fatal_error("MachO doesn't support COMDATs, '" + C->getName() + 57691bc56edSDimitry Andric "' cannot be lowered."); 57791bc56edSDimitry Andric } 57891bc56edSDimitry Andric 579ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( 580d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 581f22ef01cSRoman Divacky // Parse the section specifier and create it if valid. 582f22ef01cSRoman Divacky StringRef Segment, Section; 5833b0f4066SDimitry Andric unsigned TAA = 0, StubSize = 0; 5843b0f4066SDimitry Andric bool TAAParsed; 58591bc56edSDimitry Andric 586d88c1a5aSDimitry Andric checkMachOComdat(GO); 58791bc56edSDimitry Andric 588f22ef01cSRoman Divacky std::string ErrorCode = 589d88c1a5aSDimitry Andric MCSectionMachO::ParseSectionSpecifier(GO->getSection(), Segment, Section, 5903b0f4066SDimitry Andric TAA, TAAParsed, StubSize); 591f22ef01cSRoman Divacky if (!ErrorCode.empty()) { 592f22ef01cSRoman Divacky // If invalid, report the error with report_fatal_error. 593d88c1a5aSDimitry Andric report_fatal_error("Global variable '" + GO->getName() + 594dff0c46cSDimitry Andric "' has an invalid section specifier '" + 595d88c1a5aSDimitry Andric GO->getSection() + "': " + ErrorCode + "."); 596f22ef01cSRoman Divacky } 597f22ef01cSRoman Divacky 598f22ef01cSRoman Divacky // Get the section. 599ff0cc061SDimitry Andric MCSectionMachO *S = 600f22ef01cSRoman Divacky getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind); 601f22ef01cSRoman Divacky 602dd6029ffSDimitry Andric // If TAA wasn't set by ParseSectionSpecifier() above, 603dd6029ffSDimitry Andric // use the value returned by getMachOSection() as a default. 6043b0f4066SDimitry Andric if (!TAAParsed) 605dd6029ffSDimitry Andric TAA = S->getTypeAndAttributes(); 606dd6029ffSDimitry Andric 607f22ef01cSRoman Divacky // Okay, now that we got the section, verify that the TAA & StubSize agree. 608f22ef01cSRoman Divacky // If the user declared multiple globals with different section flags, we need 609f22ef01cSRoman Divacky // to reject it here. 610f22ef01cSRoman Divacky if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) { 611f22ef01cSRoman Divacky // If invalid, report the error with report_fatal_error. 612d88c1a5aSDimitry Andric report_fatal_error("Global variable '" + GO->getName() + 613f22ef01cSRoman Divacky "' section type or attributes does not match previous" 614f22ef01cSRoman Divacky " section specifier"); 615f22ef01cSRoman Divacky } 616f22ef01cSRoman Divacky 617f22ef01cSRoman Divacky return S; 618f22ef01cSRoman Divacky } 619f22ef01cSRoman Divacky 620ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal( 621d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 622d88c1a5aSDimitry Andric checkMachOComdat(GO); 623f785676fSDimitry Andric 624f785676fSDimitry Andric // Handle thread local data. 625f785676fSDimitry Andric if (Kind.isThreadBSS()) return TLSBSSSection; 626f785676fSDimitry Andric if (Kind.isThreadData()) return TLSDataSection; 627f785676fSDimitry Andric 628f22ef01cSRoman Divacky if (Kind.isText()) 629d88c1a5aSDimitry Andric return GO->isWeakForLinker() ? TextCoalSection : TextSection; 630f22ef01cSRoman Divacky 631f22ef01cSRoman Divacky // If this is weak/linkonce, put this in a coalescable section, either in text 632f22ef01cSRoman Divacky // or data depending on if it is writable. 633d88c1a5aSDimitry Andric if (GO->isWeakForLinker()) { 634f22ef01cSRoman Divacky if (Kind.isReadOnly()) 635f22ef01cSRoman Divacky return ConstTextCoalSection; 636f22ef01cSRoman Divacky return DataCoalSection; 637f22ef01cSRoman Divacky } 638f22ef01cSRoman Divacky 639f22ef01cSRoman Divacky // FIXME: Alignment check should be handled by section classifier. 640f22ef01cSRoman Divacky if (Kind.isMergeable1ByteCString() && 641d88c1a5aSDimitry Andric GO->getParent()->getDataLayout().getPreferredAlignment( 642d88c1a5aSDimitry Andric cast<GlobalVariable>(GO)) < 32) 643f22ef01cSRoman Divacky return CStringSection; 644f22ef01cSRoman Divacky 645f22ef01cSRoman Divacky // Do not put 16-bit arrays in the UString section if they have an 646f22ef01cSRoman Divacky // externally visible label, this runs into issues with certain linker 647f22ef01cSRoman Divacky // versions. 648d88c1a5aSDimitry Andric if (Kind.isMergeable2ByteCString() && !GO->hasExternalLinkage() && 649d88c1a5aSDimitry Andric GO->getParent()->getDataLayout().getPreferredAlignment( 650d88c1a5aSDimitry Andric cast<GlobalVariable>(GO)) < 32) 651f22ef01cSRoman Divacky return UStringSection; 652f22ef01cSRoman Divacky 65339d628a0SDimitry Andric // With MachO only variables whose corresponding symbol starts with 'l' or 65439d628a0SDimitry Andric // 'L' can be merged, so we only try merging GVs with private linkage. 655d88c1a5aSDimitry Andric if (GO->hasPrivateLinkage() && Kind.isMergeableConst()) { 656f22ef01cSRoman Divacky if (Kind.isMergeableConst4()) 657f22ef01cSRoman Divacky return FourByteConstantSection; 658f22ef01cSRoman Divacky if (Kind.isMergeableConst8()) 659f22ef01cSRoman Divacky return EightByteConstantSection; 66091bc56edSDimitry Andric if (Kind.isMergeableConst16()) 661f22ef01cSRoman Divacky return SixteenByteConstantSection; 662f22ef01cSRoman Divacky } 663f22ef01cSRoman Divacky 664f22ef01cSRoman Divacky // Otherwise, if it is readonly, but not something we can specially optimize, 665f22ef01cSRoman Divacky // just drop it in .const. 666f22ef01cSRoman Divacky if (Kind.isReadOnly()) 667f22ef01cSRoman Divacky return ReadOnlySection; 668f22ef01cSRoman Divacky 669f22ef01cSRoman Divacky // If this is marked const, put it into a const section. But if the dynamic 670f22ef01cSRoman Divacky // linker needs to write to it, put it in the data segment. 671f22ef01cSRoman Divacky if (Kind.isReadOnlyWithRel()) 672f22ef01cSRoman Divacky return ConstDataSection; 673f22ef01cSRoman Divacky 674f22ef01cSRoman Divacky // Put zero initialized globals with strong external linkage in the 675f22ef01cSRoman Divacky // DATA, __common section with the .zerofill directive. 676f22ef01cSRoman Divacky if (Kind.isBSSExtern()) 677f22ef01cSRoman Divacky return DataCommonSection; 678f22ef01cSRoman Divacky 679f22ef01cSRoman Divacky // Put zero initialized globals with local linkage in __DATA,__bss directive 680f22ef01cSRoman Divacky // with the .zerofill directive (aka .lcomm). 681f22ef01cSRoman Divacky if (Kind.isBSSLocal()) 682f22ef01cSRoman Divacky return DataBSSSection; 683f22ef01cSRoman Divacky 684f22ef01cSRoman Divacky // Otherwise, just drop the variable in the normal data section. 685f22ef01cSRoman Divacky return DataSection; 686f22ef01cSRoman Divacky } 687f22ef01cSRoman Divacky 6887d523365SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getSectionForConstant( 6893ca95b02SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 6903ca95b02SDimitry Andric unsigned &Align) const { 691f22ef01cSRoman Divacky // If this constant requires a relocation, we have to put it in the data 692f22ef01cSRoman Divacky // segment, not in the text segment. 6937d523365SDimitry Andric if (Kind.isData() || Kind.isReadOnlyWithRel()) 694f22ef01cSRoman Divacky return ConstDataSection; 695f22ef01cSRoman Divacky 696f22ef01cSRoman Divacky if (Kind.isMergeableConst4()) 697f22ef01cSRoman Divacky return FourByteConstantSection; 698f22ef01cSRoman Divacky if (Kind.isMergeableConst8()) 699f22ef01cSRoman Divacky return EightByteConstantSection; 70091bc56edSDimitry Andric if (Kind.isMergeableConst16()) 701f22ef01cSRoman Divacky return SixteenByteConstantSection; 702f22ef01cSRoman Divacky return ReadOnlySection; // .const 703f22ef01cSRoman Divacky } 704f22ef01cSRoman Divacky 70591bc56edSDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference( 706d88c1a5aSDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, 707d88c1a5aSDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 708f22ef01cSRoman Divacky // The mach-o version of this method defaults to returning a stub reference. 709f22ef01cSRoman Divacky 710f22ef01cSRoman Divacky if (Encoding & DW_EH_PE_indirect) { 711f22ef01cSRoman Divacky MachineModuleInfoMachO &MachOMMI = 712f22ef01cSRoman Divacky MMI->getObjFileInfo<MachineModuleInfoMachO>(); 713f22ef01cSRoman Divacky 714d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); 715f22ef01cSRoman Divacky 716f22ef01cSRoman Divacky // Add information about the stub reference to MachOMMI so that the stub 717f22ef01cSRoman Divacky // gets emitted by the asmprinter. 7183ca95b02SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 71991bc56edSDimitry Andric if (!StubSym.getPointer()) { 720d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 721f22ef01cSRoman Divacky StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 722f22ef01cSRoman Divacky } 723f22ef01cSRoman Divacky 724f22ef01cSRoman Divacky return TargetLoweringObjectFile:: 72597bc6c73SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), 726139f7f9bSDimitry Andric Encoding & ~dwarf::DW_EH_PE_indirect, Streamer); 727f22ef01cSRoman Divacky } 728f22ef01cSRoman Divacky 729d88c1a5aSDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM, 730d88c1a5aSDimitry Andric MMI, Streamer); 731f22ef01cSRoman Divacky } 732f22ef01cSRoman Divacky 73391bc56edSDimitry Andric MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol( 734d88c1a5aSDimitry Andric const GlobalValue *GV, const TargetMachine &TM, 7353b0f4066SDimitry Andric MachineModuleInfo *MMI) const { 7363b0f4066SDimitry Andric // The mach-o version of this method defaults to returning a stub reference. 7373b0f4066SDimitry Andric MachineModuleInfoMachO &MachOMMI = 7383b0f4066SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 7393b0f4066SDimitry Andric 740d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); 7413b0f4066SDimitry Andric 7423b0f4066SDimitry Andric // Add information about the stub reference to MachOMMI so that the stub 7433b0f4066SDimitry Andric // gets emitted by the asmprinter. 744dff0c46cSDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 74591bc56edSDimitry Andric if (!StubSym.getPointer()) { 746d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 7473b0f4066SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 7483b0f4066SDimitry Andric } 7493b0f4066SDimitry Andric 7503b0f4066SDimitry Andric return SSym; 7513b0f4066SDimitry Andric } 7523b0f4066SDimitry Andric 753ff0cc061SDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel( 754ff0cc061SDimitry Andric const MCSymbol *Sym, const MCValue &MV, int64_t Offset, 755ff0cc061SDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 7567d523365SDimitry Andric // Although MachO 32-bit targets do not explicitly have a GOTPCREL relocation 757ff0cc061SDimitry Andric // as 64-bit do, we replace the GOT equivalent by accessing the final symbol 758ff0cc061SDimitry Andric // through a non_lazy_ptr stub instead. One advantage is that it allows the 759ff0cc061SDimitry Andric // computation of deltas to final external symbols. Example: 760ff0cc061SDimitry Andric // 761ff0cc061SDimitry Andric // _extgotequiv: 762ff0cc061SDimitry Andric // .long _extfoo 763ff0cc061SDimitry Andric // 764ff0cc061SDimitry Andric // _delta: 765ff0cc061SDimitry Andric // .long _extgotequiv-_delta 766ff0cc061SDimitry Andric // 767ff0cc061SDimitry Andric // is transformed to: 768ff0cc061SDimitry Andric // 769ff0cc061SDimitry Andric // _delta: 770ff0cc061SDimitry Andric // .long L_extfoo$non_lazy_ptr-(_delta+0) 771ff0cc061SDimitry Andric // 772ff0cc061SDimitry Andric // .section __IMPORT,__pointers,non_lazy_symbol_pointers 773ff0cc061SDimitry Andric // L_extfoo$non_lazy_ptr: 774ff0cc061SDimitry Andric // .indirect_symbol _extfoo 775ff0cc061SDimitry Andric // .long 0 776ff0cc061SDimitry Andric // 777ff0cc061SDimitry Andric MachineModuleInfoMachO &MachOMMI = 778ff0cc061SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 779ff0cc061SDimitry Andric MCContext &Ctx = getContext(); 780ff0cc061SDimitry Andric 781ff0cc061SDimitry Andric // The offset must consider the original displacement from the base symbol 782ff0cc061SDimitry Andric // since 32-bit targets don't have a GOTPCREL to fold the PC displacement. 783ff0cc061SDimitry Andric Offset = -MV.getConstant(); 784ff0cc061SDimitry Andric const MCSymbol *BaseSym = &MV.getSymB()->getSymbol(); 785ff0cc061SDimitry Andric 786ff0cc061SDimitry Andric // Access the final symbol via sym$non_lazy_ptr and generate the appropriated 787ff0cc061SDimitry Andric // non_lazy_ptr stubs. 788ff0cc061SDimitry Andric SmallString<128> Name; 789ff0cc061SDimitry Andric StringRef Suffix = "$non_lazy_ptr"; 7907d523365SDimitry Andric Name += MMI->getModule()->getDataLayout().getPrivateGlobalPrefix(); 791ff0cc061SDimitry Andric Name += Sym->getName(); 792ff0cc061SDimitry Andric Name += Suffix; 793ff0cc061SDimitry Andric MCSymbol *Stub = Ctx.getOrCreateSymbol(Name); 794ff0cc061SDimitry Andric 795ff0cc061SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub); 796ff0cc061SDimitry Andric if (!StubSym.getPointer()) 797ff0cc061SDimitry Andric StubSym = MachineModuleInfoImpl:: 798ff0cc061SDimitry Andric StubValueTy(const_cast<MCSymbol *>(Sym), true /* access indirectly */); 799ff0cc061SDimitry Andric 800ff0cc061SDimitry Andric const MCExpr *BSymExpr = 80197bc6c73SDimitry Andric MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx); 802ff0cc061SDimitry Andric const MCExpr *LHS = 80397bc6c73SDimitry Andric MCSymbolRefExpr::create(Stub, MCSymbolRefExpr::VK_None, Ctx); 804ff0cc061SDimitry Andric 805ff0cc061SDimitry Andric if (!Offset) 80697bc6c73SDimitry Andric return MCBinaryExpr::createSub(LHS, BSymExpr, Ctx); 807ff0cc061SDimitry Andric 808ff0cc061SDimitry Andric const MCExpr *RHS = 80997bc6c73SDimitry Andric MCBinaryExpr::createAdd(BSymExpr, MCConstantExpr::create(Offset, Ctx), Ctx); 81097bc6c73SDimitry Andric return MCBinaryExpr::createSub(LHS, RHS, Ctx); 811ff0cc061SDimitry Andric } 812ff0cc061SDimitry Andric 8137d523365SDimitry Andric static bool canUsePrivateLabel(const MCAsmInfo &AsmInfo, 8147d523365SDimitry Andric const MCSection &Section) { 8157d523365SDimitry Andric if (!AsmInfo.isSectionAtomizableBySymbols(Section)) 8167d523365SDimitry Andric return true; 8177d523365SDimitry Andric 8187d523365SDimitry Andric // If it is not dead stripped, it is safe to use private labels. 8197d523365SDimitry Andric const MCSectionMachO &SMO = cast<MCSectionMachO>(Section); 8207d523365SDimitry Andric if (SMO.hasAttribute(MachO::S_ATTR_NO_DEAD_STRIP)) 8217d523365SDimitry Andric return true; 8227d523365SDimitry Andric 8237d523365SDimitry Andric return false; 8247d523365SDimitry Andric } 8257d523365SDimitry Andric 8267d523365SDimitry Andric void TargetLoweringObjectFileMachO::getNameWithPrefix( 827d88c1a5aSDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, 8287d523365SDimitry Andric const TargetMachine &TM) const { 829d88c1a5aSDimitry Andric bool CannotUsePrivateLabel = true; 830d88c1a5aSDimitry Andric if (auto *GO = GV->getBaseObject()) { 831d88c1a5aSDimitry Andric SectionKind GOKind = TargetLoweringObjectFile::getKindForGlobal(GO, TM); 832d88c1a5aSDimitry Andric const MCSection *TheSection = SectionForGlobal(GO, GOKind, TM); 833d88c1a5aSDimitry Andric CannotUsePrivateLabel = 8347d523365SDimitry Andric !canUsePrivateLabel(*TM.getMCAsmInfo(), *TheSection); 835d88c1a5aSDimitry Andric } 836d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 8377d523365SDimitry Andric } 8387d523365SDimitry Andric 839f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 840f22ef01cSRoman Divacky // COFF 841f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 842f22ef01cSRoman Divacky 843f22ef01cSRoman Divacky static unsigned 8443ca95b02SDimitry Andric getCOFFSectionFlags(SectionKind K, const TargetMachine &TM) { 845f22ef01cSRoman Divacky unsigned Flags = 0; 8463ca95b02SDimitry Andric bool isThumb = TM.getTargetTriple().getArch() == Triple::thumb; 847f22ef01cSRoman Divacky 848ffd1746dSEd Schouten if (K.isMetadata()) 849f22ef01cSRoman Divacky Flags |= 850ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_DISCARDABLE; 851f22ef01cSRoman Divacky else if (K.isText()) 852f22ef01cSRoman Divacky Flags |= 853ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_EXECUTE | 8542754fe60SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 8553ca95b02SDimitry Andric COFF::IMAGE_SCN_CNT_CODE | 8563ca95b02SDimitry Andric (isThumb ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0); 857f22ef01cSRoman Divacky else if (K.isBSS()) 858f22ef01cSRoman Divacky Flags |= 859ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | 860ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ | 861ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_WRITE; 862dff0c46cSDimitry Andric else if (K.isThreadLocal()) 863dff0c46cSDimitry Andric Flags |= 864dff0c46cSDimitry Andric COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 865dff0c46cSDimitry Andric COFF::IMAGE_SCN_MEM_READ | 866dff0c46cSDimitry Andric COFF::IMAGE_SCN_MEM_WRITE; 86739d628a0SDimitry Andric else if (K.isReadOnly() || K.isReadOnlyWithRel()) 868f22ef01cSRoman Divacky Flags |= 869ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 870ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ; 871f22ef01cSRoman Divacky else if (K.isWriteable()) 872f22ef01cSRoman Divacky Flags |= 873ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 874ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ | 875ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_WRITE; 876f22ef01cSRoman Divacky 877f22ef01cSRoman Divacky return Flags; 878f22ef01cSRoman Divacky } 879f22ef01cSRoman Divacky 88091bc56edSDimitry Andric static const GlobalValue *getComdatGVForCOFF(const GlobalValue *GV) { 88191bc56edSDimitry Andric const Comdat *C = GV->getComdat(); 88291bc56edSDimitry Andric assert(C && "expected GV to have a Comdat!"); 88391bc56edSDimitry Andric 88491bc56edSDimitry Andric StringRef ComdatGVName = C->getName(); 88591bc56edSDimitry Andric const GlobalValue *ComdatGV = GV->getParent()->getNamedValue(ComdatGVName); 88691bc56edSDimitry Andric if (!ComdatGV) 88791bc56edSDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 88891bc56edSDimitry Andric "' does not exist."); 88991bc56edSDimitry Andric 89091bc56edSDimitry Andric if (ComdatGV->getComdat() != C) 89191bc56edSDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 89239d628a0SDimitry Andric "' is not a key for its COMDAT."); 89391bc56edSDimitry Andric 89491bc56edSDimitry Andric return ComdatGV; 89591bc56edSDimitry Andric } 89691bc56edSDimitry Andric 89791bc56edSDimitry Andric static int getSelectionForCOFF(const GlobalValue *GV) { 89891bc56edSDimitry Andric if (const Comdat *C = GV->getComdat()) { 89991bc56edSDimitry Andric const GlobalValue *ComdatKey = getComdatGVForCOFF(GV); 90091bc56edSDimitry Andric if (const auto *GA = dyn_cast<GlobalAlias>(ComdatKey)) 90191bc56edSDimitry Andric ComdatKey = GA->getBaseObject(); 90291bc56edSDimitry Andric if (ComdatKey == GV) { 90391bc56edSDimitry Andric switch (C->getSelectionKind()) { 90491bc56edSDimitry Andric case Comdat::Any: 90591bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ANY; 90691bc56edSDimitry Andric case Comdat::ExactMatch: 90791bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH; 90891bc56edSDimitry Andric case Comdat::Largest: 90991bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_LARGEST; 91091bc56edSDimitry Andric case Comdat::NoDuplicates: 91191bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 91291bc56edSDimitry Andric case Comdat::SameSize: 91391bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_SAME_SIZE; 91491bc56edSDimitry Andric } 91591bc56edSDimitry Andric } else { 91691bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE; 91791bc56edSDimitry Andric } 91891bc56edSDimitry Andric } 91991bc56edSDimitry Andric return 0; 92091bc56edSDimitry Andric } 92191bc56edSDimitry Andric 922ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal( 923d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 924139f7f9bSDimitry Andric int Selection = 0; 9253ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 926d88c1a5aSDimitry Andric StringRef Name = GO->getSection(); 92791bc56edSDimitry Andric StringRef COMDATSymName = ""; 928d88c1a5aSDimitry Andric if (GO->hasComdat()) { 929d88c1a5aSDimitry Andric Selection = getSelectionForCOFF(GO); 93091bc56edSDimitry Andric const GlobalValue *ComdatGV; 93191bc56edSDimitry Andric if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) 932d88c1a5aSDimitry Andric ComdatGV = getComdatGVForCOFF(GO); 93391bc56edSDimitry Andric else 934d88c1a5aSDimitry Andric ComdatGV = GO; 93591bc56edSDimitry Andric 93691bc56edSDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 937d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV); 93891bc56edSDimitry Andric COMDATSymName = Sym->getName(); 939139f7f9bSDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 94091bc56edSDimitry Andric } else { 94191bc56edSDimitry Andric Selection = 0; 94291bc56edSDimitry Andric } 943139f7f9bSDimitry Andric } 9443ca95b02SDimitry Andric 9453ca95b02SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, 946f785676fSDimitry Andric Selection); 947f22ef01cSRoman Divacky } 948f22ef01cSRoman Divacky 94991bc56edSDimitry Andric static const char *getCOFFSectionNameForUniqueGlobal(SectionKind Kind) { 950f22ef01cSRoman Divacky if (Kind.isText()) 95191bc56edSDimitry Andric return ".text"; 952f22ef01cSRoman Divacky if (Kind.isBSS()) 95391bc56edSDimitry Andric return ".bss"; 95491bc56edSDimitry Andric if (Kind.isThreadLocal()) 95591bc56edSDimitry Andric return ".tls$"; 95639d628a0SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 95791bc56edSDimitry Andric return ".rdata"; 95839d628a0SDimitry Andric return ".data"; 959f22ef01cSRoman Divacky } 960f22ef01cSRoman Divacky 961ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal( 962d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 96391bc56edSDimitry Andric // If we have -ffunction-sections then we should emit the global value to a 96491bc56edSDimitry Andric // uniqued section specifically for it. 96591bc56edSDimitry Andric bool EmitUniquedSection; 96691bc56edSDimitry Andric if (Kind.isText()) 96791bc56edSDimitry Andric EmitUniquedSection = TM.getFunctionSections(); 96891bc56edSDimitry Andric else 96991bc56edSDimitry Andric EmitUniquedSection = TM.getDataSections(); 970f22ef01cSRoman Divacky 971d88c1a5aSDimitry Andric if ((EmitUniquedSection && !Kind.isCommon()) || GO->hasComdat()) { 97291bc56edSDimitry Andric const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); 9733ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 974f22ef01cSRoman Divacky 975ffd1746dSEd Schouten Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 976d88c1a5aSDimitry Andric int Selection = getSelectionForCOFF(GO); 97791bc56edSDimitry Andric if (!Selection) 97891bc56edSDimitry Andric Selection = COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 97991bc56edSDimitry Andric const GlobalValue *ComdatGV; 980d88c1a5aSDimitry Andric if (GO->hasComdat()) 981d88c1a5aSDimitry Andric ComdatGV = getComdatGVForCOFF(GO); 98291bc56edSDimitry Andric else 983d88c1a5aSDimitry Andric ComdatGV = GO; 984f22ef01cSRoman Divacky 9853ca95b02SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 9863ca95b02SDimitry Andric if (EmitUniquedSection) 9873ca95b02SDimitry Andric UniqueID = NextUniqueID++; 9883ca95b02SDimitry Andric 98991bc56edSDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 990d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV); 99191bc56edSDimitry Andric StringRef COMDATSymName = Sym->getName(); 99291bc56edSDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, 9933ca95b02SDimitry Andric COMDATSymName, Selection, UniqueID); 994ff0cc061SDimitry Andric } else { 995ff0cc061SDimitry Andric SmallString<256> TmpData; 996d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(TmpData, GO, /*CannotUsePrivateLabel=*/true); 997ff0cc061SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, TmpData, 9983ca95b02SDimitry Andric Selection, UniqueID); 99991bc56edSDimitry Andric } 1000f22ef01cSRoman Divacky } 1001f22ef01cSRoman Divacky 1002f22ef01cSRoman Divacky if (Kind.isText()) 1003f785676fSDimitry Andric return TextSection; 1004f22ef01cSRoman Divacky 1005dff0c46cSDimitry Andric if (Kind.isThreadLocal()) 1006f785676fSDimitry Andric return TLSDataSection; 1007dff0c46cSDimitry Andric 100839d628a0SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 1009f785676fSDimitry Andric return ReadOnlySection; 1010f785676fSDimitry Andric 101191bc56edSDimitry Andric // Note: we claim that common symbols are put in BSSSection, but they are 101291bc56edSDimitry Andric // really emitted with the magic .comm directive, which creates a symbol table 101391bc56edSDimitry Andric // entry but not a section. 101491bc56edSDimitry Andric if (Kind.isBSS() || Kind.isCommon()) 1015f785676fSDimitry Andric return BSSSection; 1016f785676fSDimitry Andric 1017f785676fSDimitry Andric return DataSection; 1018f22ef01cSRoman Divacky } 1019f22ef01cSRoman Divacky 1020ff0cc061SDimitry Andric void TargetLoweringObjectFileCOFF::getNameWithPrefix( 1021d88c1a5aSDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, 10227d523365SDimitry Andric const TargetMachine &TM) const { 10237d523365SDimitry Andric bool CannotUsePrivateLabel = false; 1024ff0cc061SDimitry Andric if (GV->hasPrivateLinkage() && 1025ff0cc061SDimitry Andric ((isa<Function>(GV) && TM.getFunctionSections()) || 1026ff0cc061SDimitry Andric (isa<GlobalVariable>(GV) && TM.getDataSections()))) 1027ff0cc061SDimitry Andric CannotUsePrivateLabel = true; 1028ff0cc061SDimitry Andric 1029d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 1030ff0cc061SDimitry Andric } 1031ff0cc061SDimitry Andric 1032ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable( 1033d88c1a5aSDimitry Andric const Function &F, const TargetMachine &TM) const { 1034ff0cc061SDimitry Andric // If the function can be removed, produce a unique section so that 1035ff0cc061SDimitry Andric // the table doesn't prevent the removal. 1036ff0cc061SDimitry Andric const Comdat *C = F.getComdat(); 1037ff0cc061SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C; 1038ff0cc061SDimitry Andric if (!EmitUniqueSection) 1039ff0cc061SDimitry Andric return ReadOnlySection; 1040ff0cc061SDimitry Andric 1041ff0cc061SDimitry Andric // FIXME: we should produce a symbol for F instead. 1042ff0cc061SDimitry Andric if (F.hasPrivateLinkage()) 1043ff0cc061SDimitry Andric return ReadOnlySection; 1044ff0cc061SDimitry Andric 1045d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(&F); 1046ff0cc061SDimitry Andric StringRef COMDATSymName = Sym->getName(); 1047ff0cc061SDimitry Andric 1048ff0cc061SDimitry Andric SectionKind Kind = SectionKind::getReadOnly(); 1049ff0cc061SDimitry Andric const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); 10503ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 1051ff0cc061SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 10523ca95b02SDimitry Andric unsigned UniqueID = NextUniqueID++; 1053ff0cc061SDimitry Andric 1054ff0cc061SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, 10553ca95b02SDimitry Andric COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); 1056ff0cc061SDimitry Andric } 1057ff0cc061SDimitry Andric 1058d88c1a5aSDimitry Andric void TargetLoweringObjectFileCOFF::emitModuleFlags( 1059d88c1a5aSDimitry Andric MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, 1060d88c1a5aSDimitry Andric const TargetMachine &TM) const { 106191bc56edSDimitry Andric MDNode *LinkerOptions = nullptr; 1062284c1978SDimitry Andric 10633ca95b02SDimitry Andric for (const auto &MFE : ModuleFlags) { 1064284c1978SDimitry Andric StringRef Key = MFE.Key->getString(); 10653ca95b02SDimitry Andric if (Key == "Linker Options") 10663ca95b02SDimitry Andric LinkerOptions = cast<MDNode>(MFE.Val); 1067284c1978SDimitry Andric } 1068284c1978SDimitry Andric 10693ca95b02SDimitry Andric if (LinkerOptions) { 1070284c1978SDimitry Andric // Emit the linker options to the linker .drectve section. According to the 10713ca95b02SDimitry Andric // spec, this section is a space-separated string containing flags for 10723ca95b02SDimitry Andric // linker. 1073ff0cc061SDimitry Andric MCSection *Sec = getDrectveSection(); 1074284c1978SDimitry Andric Streamer.SwitchSection(Sec); 10753ca95b02SDimitry Andric for (const auto &Option : LinkerOptions->operands()) { 10763ca95b02SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) { 1077284c1978SDimitry Andric // Lead with a space for consistency with our dllexport implementation. 1078ff0cc061SDimitry Andric std::string Directive(" "); 10793ca95b02SDimitry Andric Directive.append(cast<MDString>(Piece)->getString()); 1080ff0cc061SDimitry Andric Streamer.EmitBytes(Directive); 1081284c1978SDimitry Andric } 1082284c1978SDimitry Andric } 1083284c1978SDimitry Andric } 10843ca95b02SDimitry Andric } 108591bc56edSDimitry Andric 1086d88c1a5aSDimitry Andric void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx, 1087d88c1a5aSDimitry Andric const TargetMachine &TM) { 1088d88c1a5aSDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM); 1089d88c1a5aSDimitry Andric const Triple &T = TM.getTargetTriple(); 1090d88c1a5aSDimitry Andric if (T.isKnownWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) { 1091d88c1a5aSDimitry Andric StaticCtorSection = 1092d88c1a5aSDimitry Andric Ctx.getCOFFSection(".CRT$XCU", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1093d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ, 1094d88c1a5aSDimitry Andric SectionKind::getReadOnly()); 1095d88c1a5aSDimitry Andric StaticDtorSection = 1096d88c1a5aSDimitry Andric Ctx.getCOFFSection(".CRT$XTX", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1097d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ, 1098d88c1a5aSDimitry Andric SectionKind::getReadOnly()); 1099d88c1a5aSDimitry Andric } else { 1100d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getCOFFSection( 1101d88c1a5aSDimitry Andric ".ctors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1102d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, 1103d88c1a5aSDimitry Andric SectionKind::getData()); 1104d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getCOFFSection( 1105d88c1a5aSDimitry Andric ".dtors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1106d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, 1107d88c1a5aSDimitry Andric SectionKind::getData()); 1108d88c1a5aSDimitry Andric } 1109d88c1a5aSDimitry Andric } 1110d88c1a5aSDimitry Andric 1111ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection( 111291bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 111339d628a0SDimitry Andric return getContext().getAssociativeCOFFSection( 11143ca95b02SDimitry Andric cast<MCSectionCOFF>(StaticCtorSection), KeySym, 0); 111591bc56edSDimitry Andric } 111691bc56edSDimitry Andric 1117ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection( 111891bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 111939d628a0SDimitry Andric return getContext().getAssociativeCOFFSection( 11203ca95b02SDimitry Andric cast<MCSectionCOFF>(StaticDtorSection), KeySym, 0); 112191bc56edSDimitry Andric } 11223dac3a9bSDimitry Andric 11233dac3a9bSDimitry Andric void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal( 1124d88c1a5aSDimitry Andric raw_ostream &OS, const GlobalValue *GV) const { 11253dac3a9bSDimitry Andric if (!GV->hasDLLExportStorageClass() || GV->isDeclaration()) 11263dac3a9bSDimitry Andric return; 11273dac3a9bSDimitry Andric 11283dac3a9bSDimitry Andric const Triple &TT = getTargetTriple(); 11293dac3a9bSDimitry Andric 11303dac3a9bSDimitry Andric if (TT.isKnownWindowsMSVCEnvironment()) 11313dac3a9bSDimitry Andric OS << " /EXPORT:"; 11323dac3a9bSDimitry Andric else 11333dac3a9bSDimitry Andric OS << " -export:"; 11343dac3a9bSDimitry Andric 11353dac3a9bSDimitry Andric if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) { 11363dac3a9bSDimitry Andric std::string Flag; 11373dac3a9bSDimitry Andric raw_string_ostream FlagOS(Flag); 1138d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(FlagOS, GV, false); 11393dac3a9bSDimitry Andric FlagOS.flush(); 11407d523365SDimitry Andric if (Flag[0] == GV->getParent()->getDataLayout().getGlobalPrefix()) 11413dac3a9bSDimitry Andric OS << Flag.substr(1); 11423dac3a9bSDimitry Andric else 11433dac3a9bSDimitry Andric OS << Flag; 11443dac3a9bSDimitry Andric } else { 1145d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(OS, GV, false); 11463dac3a9bSDimitry Andric } 11473dac3a9bSDimitry Andric 11483dac3a9bSDimitry Andric if (!GV->getValueType()->isFunctionTy()) { 11493dac3a9bSDimitry Andric if (TT.isKnownWindowsMSVCEnvironment()) 11503dac3a9bSDimitry Andric OS << ",DATA"; 11513dac3a9bSDimitry Andric else 11523dac3a9bSDimitry Andric OS << ",data"; 11533dac3a9bSDimitry Andric } 11543dac3a9bSDimitry Andric } 1155