17a7e6055SDimitry Andric //===- 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 15139f7f9bSDimitry Andric #include "llvm/ADT/SmallString.h" 167a7e6055SDimitry Andric #include "llvm/ADT/SmallVector.h" 17139f7f9bSDimitry Andric #include "llvm/ADT/StringExtras.h" 187a7e6055SDimitry Andric #include "llvm/ADT/StringRef.h" 19139f7f9bSDimitry Andric #include "llvm/ADT/Triple.h" 207a7e6055SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 21f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineModuleInfoImpls.h" 227a7e6055SDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 237a7e6055SDimitry Andric #include "llvm/IR/Comdat.h" 24139f7f9bSDimitry Andric #include "llvm/IR/Constants.h" 25139f7f9bSDimitry Andric #include "llvm/IR/DataLayout.h" 26139f7f9bSDimitry Andric #include "llvm/IR/DerivedTypes.h" 27139f7f9bSDimitry Andric #include "llvm/IR/Function.h" 287a7e6055SDimitry Andric #include "llvm/IR/GlobalAlias.h" 297a7e6055SDimitry Andric #include "llvm/IR/GlobalObject.h" 307a7e6055SDimitry Andric #include "llvm/IR/GlobalValue.h" 31139f7f9bSDimitry Andric #include "llvm/IR/GlobalVariable.h" 3291bc56edSDimitry Andric #include "llvm/IR/Mangler.h" 337a7e6055SDimitry Andric #include "llvm/IR/Metadata.h" 34139f7f9bSDimitry Andric #include "llvm/IR/Module.h" 357a7e6055SDimitry Andric #include "llvm/IR/Type.h" 367d523365SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 37f22ef01cSRoman Divacky #include "llvm/MC/MCContext.h" 38f22ef01cSRoman Divacky #include "llvm/MC/MCExpr.h" 39f22ef01cSRoman Divacky #include "llvm/MC/MCSectionCOFF.h" 40139f7f9bSDimitry Andric #include "llvm/MC/MCSectionELF.h" 41139f7f9bSDimitry Andric #include "llvm/MC/MCSectionMachO.h" 427a7e6055SDimitry Andric #include "llvm/MC/MCSectionWasm.h" 433b0f4066SDimitry Andric #include "llvm/MC/MCStreamer.h" 447a7e6055SDimitry Andric #include "llvm/MC/MCSymbol.h" 4597bc6c73SDimitry Andric #include "llvm/MC/MCSymbolELF.h" 46ff0cc061SDimitry Andric #include "llvm/MC/MCValue.h" 477a7e6055SDimitry Andric #include "llvm/MC/SectionKind.h" 483ca95b02SDimitry Andric #include "llvm/ProfileData/InstrProf.h" 497a7e6055SDimitry Andric #include "llvm/Support/Casting.h" 507a7e6055SDimitry Andric #include "llvm/Support/CodeGen.h" 517d523365SDimitry Andric #include "llvm/Support/COFF.h" 52f22ef01cSRoman Divacky #include "llvm/Support/Dwarf.h" 532754fe60SDimitry Andric #include "llvm/Support/ELF.h" 54f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h" 557a7e6055SDimitry Andric #include "llvm/Support/MachO.h" 56f22ef01cSRoman Divacky #include "llvm/Support/raw_ostream.h" 57139f7f9bSDimitry Andric #include "llvm/Target/TargetMachine.h" 587a7e6055SDimitry Andric #include <cassert> 597a7e6055SDimitry Andric #include <string> 607a7e6055SDimitry Andric 61f22ef01cSRoman Divacky using namespace llvm; 62f22ef01cSRoman Divacky using namespace dwarf; 63f22ef01cSRoman Divacky 64f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 65f22ef01cSRoman Divacky // ELF 66f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 67f22ef01cSRoman Divacky 6891bc56edSDimitry Andric MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol( 69d88c1a5aSDimitry Andric const GlobalValue *GV, const TargetMachine &TM, 703b0f4066SDimitry Andric MachineModuleInfo *MMI) const { 713b0f4066SDimitry Andric unsigned Encoding = getPersonalityEncoding(); 727a7e6055SDimitry Andric if ((Encoding & 0x80) == DW_EH_PE_indirect) 73ff0cc061SDimitry Andric return getContext().getOrCreateSymbol(StringRef("DW.ref.") + 74d88c1a5aSDimitry Andric TM.getSymbol(GV)->getName()); 757a7e6055SDimitry Andric if ((Encoding & 0x70) == DW_EH_PE_absptr) 76d88c1a5aSDimitry Andric return TM.getSymbol(GV); 7791bc56edSDimitry Andric report_fatal_error("We do not support this DWARF encoding yet!"); 783b0f4066SDimitry Andric } 793b0f4066SDimitry Andric 807d523365SDimitry Andric void TargetLoweringObjectFileELF::emitPersonalityValue( 817d523365SDimitry Andric MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym) const { 8217a519f9SDimitry Andric SmallString<64> NameData("DW.ref."); 8317a519f9SDimitry Andric NameData += Sym->getName(); 8497bc6c73SDimitry Andric MCSymbolELF *Label = 8597bc6c73SDimitry Andric cast<MCSymbolELF>(getContext().getOrCreateSymbol(NameData)); 863b0f4066SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_Hidden); 873b0f4066SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_Weak); 883b0f4066SDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP; 893ca95b02SDimitry Andric MCSection *Sec = getContext().getELFNamedSection(".data", Label->getName(), 903ca95b02SDimitry Andric ELF::SHT_PROGBITS, Flags, 0); 917d523365SDimitry Andric unsigned Size = DL.getPointerSize(); 923b0f4066SDimitry Andric Streamer.SwitchSection(Sec); 937d523365SDimitry Andric Streamer.EmitValueToAlignment(DL.getPointerABIAlignment()); 943b0f4066SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject); 9597bc6c73SDimitry Andric const MCExpr *E = MCConstantExpr::create(Size, getContext()); 9697bc6c73SDimitry Andric Streamer.emitELFSize(Label, E); 973b0f4066SDimitry Andric Streamer.EmitLabel(Label); 983b0f4066SDimitry Andric 993b0f4066SDimitry Andric Streamer.EmitSymbolValue(Sym, Size); 1003b0f4066SDimitry Andric } 1013b0f4066SDimitry Andric 10291bc56edSDimitry Andric const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference( 103d88c1a5aSDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, 104d88c1a5aSDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 1057a7e6055SDimitry Andric if (Encoding & DW_EH_PE_indirect) { 106139f7f9bSDimitry Andric MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>(); 107139f7f9bSDimitry Andric 108d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", TM); 109139f7f9bSDimitry Andric 110139f7f9bSDimitry Andric // Add information about the stub reference to ELFMMI so that the stub 111139f7f9bSDimitry Andric // gets emitted by the asmprinter. 112139f7f9bSDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym); 11391bc56edSDimitry Andric if (!StubSym.getPointer()) { 114d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 115139f7f9bSDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 116139f7f9bSDimitry Andric } 117139f7f9bSDimitry Andric 118139f7f9bSDimitry Andric return TargetLoweringObjectFile:: 11997bc6c73SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), 1207a7e6055SDimitry Andric Encoding & ~DW_EH_PE_indirect, Streamer); 121139f7f9bSDimitry Andric } 122139f7f9bSDimitry Andric 123d88c1a5aSDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM, 124d88c1a5aSDimitry Andric MMI, Streamer); 125139f7f9bSDimitry Andric } 126139f7f9bSDimitry Andric 127f22ef01cSRoman Divacky static SectionKind 128f22ef01cSRoman Divacky getELFKindForNamedSection(StringRef Name, SectionKind K) { 129bd5abe19SDimitry Andric // N.B.: The defaults used in here are no the same ones used in MC. 130bd5abe19SDimitry Andric // We follow gcc, MC follows gas. For example, given ".section .eh_frame", 131bd5abe19SDimitry Andric // both gas and MC will produce a section with no flags. Given 1327ae0e2c9SDimitry Andric // section(".eh_frame") gcc will produce: 1337ae0e2c9SDimitry Andric // 134bd5abe19SDimitry Andric // .section .eh_frame,"a",@progbits 1353ca95b02SDimitry Andric 1367a7e6055SDimitry Andric if (Name == getInstrProfSectionName(IPSK_covmap, Triple::ELF, 1377a7e6055SDimitry Andric /*AddSegmentInfo=*/false)) 1383ca95b02SDimitry Andric return SectionKind::getMetadata(); 1393ca95b02SDimitry Andric 140f22ef01cSRoman Divacky if (Name.empty() || Name[0] != '.') return K; 141f22ef01cSRoman Divacky 142f22ef01cSRoman Divacky // Some lame default implementation based on some magic section names. 143f22ef01cSRoman Divacky if (Name == ".bss" || 144f22ef01cSRoman Divacky Name.startswith(".bss.") || 145f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.b.") || 146f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.b.") || 147f22ef01cSRoman Divacky Name == ".sbss" || 148f22ef01cSRoman Divacky Name.startswith(".sbss.") || 149f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.sb.") || 150f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.sb.")) 151f22ef01cSRoman Divacky return SectionKind::getBSS(); 152f22ef01cSRoman Divacky 153f22ef01cSRoman Divacky if (Name == ".tdata" || 154f22ef01cSRoman Divacky Name.startswith(".tdata.") || 155f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.td.") || 156f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.td.")) 157f22ef01cSRoman Divacky return SectionKind::getThreadData(); 158f22ef01cSRoman Divacky 159f22ef01cSRoman Divacky if (Name == ".tbss" || 160f22ef01cSRoman Divacky Name.startswith(".tbss.") || 161f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.tb.") || 162f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.tb.")) 163f22ef01cSRoman Divacky return SectionKind::getThreadBSS(); 164f22ef01cSRoman Divacky 165f22ef01cSRoman Divacky return K; 166f22ef01cSRoman Divacky } 167f22ef01cSRoman Divacky 168f22ef01cSRoman Divacky static unsigned getELFSectionType(StringRef Name, SectionKind K) { 169d88c1a5aSDimitry Andric // Use SHT_NOTE for section whose name starts with ".note" to allow 170d88c1a5aSDimitry Andric // emitting ELF notes from C variable declaration. 171d88c1a5aSDimitry Andric // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77609 172d88c1a5aSDimitry Andric if (Name.startswith(".note")) 173d88c1a5aSDimitry Andric return ELF::SHT_NOTE; 174f22ef01cSRoman Divacky 175f22ef01cSRoman Divacky if (Name == ".init_array") 1762754fe60SDimitry Andric return ELF::SHT_INIT_ARRAY; 177f22ef01cSRoman Divacky 178f22ef01cSRoman Divacky if (Name == ".fini_array") 1792754fe60SDimitry Andric return ELF::SHT_FINI_ARRAY; 180f22ef01cSRoman Divacky 181f22ef01cSRoman Divacky if (Name == ".preinit_array") 1822754fe60SDimitry Andric return ELF::SHT_PREINIT_ARRAY; 183f22ef01cSRoman Divacky 184f22ef01cSRoman Divacky if (K.isBSS() || K.isThreadBSS()) 1852754fe60SDimitry Andric return ELF::SHT_NOBITS; 186f22ef01cSRoman Divacky 1872754fe60SDimitry Andric return ELF::SHT_PROGBITS; 188f22ef01cSRoman Divacky } 189f22ef01cSRoman Divacky 190ff0cc061SDimitry Andric static unsigned getELFSectionFlags(SectionKind K) { 191f22ef01cSRoman Divacky unsigned Flags = 0; 192f22ef01cSRoman Divacky 193f22ef01cSRoman Divacky if (!K.isMetadata()) 1942754fe60SDimitry Andric Flags |= ELF::SHF_ALLOC; 195f22ef01cSRoman Divacky 196f22ef01cSRoman Divacky if (K.isText()) 1972754fe60SDimitry Andric Flags |= ELF::SHF_EXECINSTR; 198f22ef01cSRoman Divacky 199d88c1a5aSDimitry Andric if (K.isExecuteOnly()) 200d88c1a5aSDimitry Andric Flags |= ELF::SHF_ARM_PURECODE; 201d88c1a5aSDimitry Andric 202f22ef01cSRoman Divacky if (K.isWriteable()) 2032754fe60SDimitry Andric Flags |= ELF::SHF_WRITE; 204f22ef01cSRoman Divacky 205f22ef01cSRoman Divacky if (K.isThreadLocal()) 2062754fe60SDimitry Andric Flags |= ELF::SHF_TLS; 207f22ef01cSRoman Divacky 208ff0cc061SDimitry Andric if (K.isMergeableCString() || K.isMergeableConst()) 2092754fe60SDimitry Andric Flags |= ELF::SHF_MERGE; 210f22ef01cSRoman Divacky 211f22ef01cSRoman Divacky if (K.isMergeableCString()) 2122754fe60SDimitry Andric Flags |= ELF::SHF_STRINGS; 213f22ef01cSRoman Divacky 214f22ef01cSRoman Divacky return Flags; 215f22ef01cSRoman Divacky } 216f22ef01cSRoman Divacky 21791bc56edSDimitry Andric static const Comdat *getELFComdat(const GlobalValue *GV) { 21891bc56edSDimitry Andric const Comdat *C = GV->getComdat(); 21991bc56edSDimitry Andric if (!C) 22091bc56edSDimitry Andric return nullptr; 221f22ef01cSRoman Divacky 22291bc56edSDimitry Andric if (C->getSelectionKind() != Comdat::Any) 22391bc56edSDimitry Andric report_fatal_error("ELF COMDATs only support SelectionKind::Any, '" + 22491bc56edSDimitry Andric C->getName() + "' cannot be lowered."); 22591bc56edSDimitry Andric 22691bc56edSDimitry Andric return C; 22791bc56edSDimitry Andric } 22891bc56edSDimitry Andric 2297a7e6055SDimitry Andric static const MCSymbolELF *getAssociatedSymbol(const GlobalObject *GO, 2307a7e6055SDimitry Andric const TargetMachine &TM) { 2317a7e6055SDimitry Andric MDNode *MD = GO->getMetadata(LLVMContext::MD_associated); 2327a7e6055SDimitry Andric if (!MD) 2337a7e6055SDimitry Andric return nullptr; 2347a7e6055SDimitry Andric 2357a7e6055SDimitry Andric auto *VM = dyn_cast<ValueAsMetadata>(MD->getOperand(0)); 2367a7e6055SDimitry Andric if (!VM) 2377a7e6055SDimitry Andric report_fatal_error("MD_associated operand is not ValueAsMetadata"); 2387a7e6055SDimitry Andric 2397a7e6055SDimitry Andric GlobalObject *OtherGO = dyn_cast<GlobalObject>(VM->getValue()); 2407a7e6055SDimitry Andric return OtherGO ? dyn_cast<MCSymbolELF>(TM.getSymbol(OtherGO)) : nullptr; 2417a7e6055SDimitry Andric } 2427a7e6055SDimitry Andric 243ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( 244d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 245d88c1a5aSDimitry Andric StringRef SectionName = GO->getSection(); 246f22ef01cSRoman Divacky 247f22ef01cSRoman Divacky // Infer section flags from the section name if we can. 248f22ef01cSRoman Divacky Kind = getELFKindForNamedSection(SectionName, Kind); 249f22ef01cSRoman Divacky 25091bc56edSDimitry Andric StringRef Group = ""; 25191bc56edSDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 252d88c1a5aSDimitry Andric if (const Comdat *C = getELFComdat(GO)) { 25391bc56edSDimitry Andric Group = C->getName(); 25491bc56edSDimitry Andric Flags |= ELF::SHF_GROUP; 25591bc56edSDimitry Andric } 2567a7e6055SDimitry Andric 2577a7e6055SDimitry Andric // A section can have at most one associated section. Put each global with 2587a7e6055SDimitry Andric // MD_associated in a unique section. 2597a7e6055SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 2607a7e6055SDimitry Andric const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM); 2617a7e6055SDimitry Andric if (AssociatedSymbol) { 2627a7e6055SDimitry Andric UniqueID = NextUniqueID++; 2637a7e6055SDimitry Andric Flags |= ELF::SHF_LINK_ORDER; 2647a7e6055SDimitry Andric } 2657a7e6055SDimitry Andric 2667a7e6055SDimitry Andric MCSectionELF *Section = getContext().getELFSection( 2677a7e6055SDimitry Andric SectionName, getELFSectionType(SectionName, Kind), Flags, 2687a7e6055SDimitry Andric /*EntrySize=*/0, Group, UniqueID, AssociatedSymbol); 2697a7e6055SDimitry Andric // Make sure that we did not get some other section with incompatible sh_link. 2707a7e6055SDimitry Andric // This should not be possible due to UniqueID code above. 2717a7e6055SDimitry Andric assert(Section->getAssociatedSymbol() == AssociatedSymbol); 2727a7e6055SDimitry Andric return Section; 273f22ef01cSRoman Divacky } 274f22ef01cSRoman Divacky 275ff0cc061SDimitry Andric /// Return the section prefix name used by options FunctionsSections and 276ff0cc061SDimitry Andric /// DataSections. 27791bc56edSDimitry Andric static StringRef getSectionPrefixForGlobal(SectionKind Kind) { 278ff0cc061SDimitry Andric if (Kind.isText()) 279ff0cc061SDimitry Andric return ".text"; 280ff0cc061SDimitry Andric if (Kind.isReadOnly()) 281ff0cc061SDimitry Andric return ".rodata"; 282ff0cc061SDimitry Andric if (Kind.isBSS()) 283ff0cc061SDimitry Andric return ".bss"; 284ff0cc061SDimitry Andric if (Kind.isThreadData()) 285ff0cc061SDimitry Andric return ".tdata"; 286ff0cc061SDimitry Andric if (Kind.isThreadBSS()) 287ff0cc061SDimitry Andric return ".tbss"; 2887d523365SDimitry Andric if (Kind.isData()) 289ff0cc061SDimitry Andric return ".data"; 290f22ef01cSRoman Divacky assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); 291ff0cc061SDimitry Andric return ".data.rel.ro"; 292f22ef01cSRoman Divacky } 293f22ef01cSRoman Divacky 2947a7e6055SDimitry Andric static MCSectionELF *selectELFSectionForGlobal( 2957a7e6055SDimitry Andric MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang, 2967a7e6055SDimitry Andric const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags, 2977a7e6055SDimitry Andric unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) { 298ff0cc061SDimitry Andric unsigned EntrySize = 0; 299ff0cc061SDimitry Andric if (Kind.isMergeableCString()) { 300ff0cc061SDimitry Andric if (Kind.isMergeable2ByteCString()) { 301ff0cc061SDimitry Andric EntrySize = 2; 302ff0cc061SDimitry Andric } else if (Kind.isMergeable4ByteCString()) { 303ff0cc061SDimitry Andric EntrySize = 4; 304ff0cc061SDimitry Andric } else { 305ff0cc061SDimitry Andric EntrySize = 1; 306ff0cc061SDimitry Andric assert(Kind.isMergeable1ByteCString() && "unknown string width"); 307ff0cc061SDimitry Andric } 308ff0cc061SDimitry Andric } else if (Kind.isMergeableConst()) { 309ff0cc061SDimitry Andric if (Kind.isMergeableConst4()) { 310ff0cc061SDimitry Andric EntrySize = 4; 311ff0cc061SDimitry Andric } else if (Kind.isMergeableConst8()) { 312ff0cc061SDimitry Andric EntrySize = 8; 3133ca95b02SDimitry Andric } else if (Kind.isMergeableConst16()) { 314ff0cc061SDimitry Andric EntrySize = 16; 3153ca95b02SDimitry Andric } else { 3163ca95b02SDimitry Andric assert(Kind.isMergeableConst32() && "unknown data width"); 3173ca95b02SDimitry Andric EntrySize = 32; 318ff0cc061SDimitry Andric } 319ff0cc061SDimitry Andric } 32091bc56edSDimitry Andric 3212754fe60SDimitry Andric StringRef Group = ""; 322d88c1a5aSDimitry Andric if (const Comdat *C = getELFComdat(GO)) { 3232754fe60SDimitry Andric Flags |= ELF::SHF_GROUP; 324ff0cc061SDimitry Andric Group = C->getName(); 3252754fe60SDimitry Andric } 3262754fe60SDimitry Andric 327ff0cc061SDimitry Andric bool UniqueSectionNames = TM.getUniqueSectionNames(); 328ff0cc061SDimitry Andric SmallString<128> Name; 329ff0cc061SDimitry Andric if (Kind.isMergeableCString()) { 330f22ef01cSRoman Divacky // We also need alignment here. 331f22ef01cSRoman Divacky // FIXME: this is getting the alignment of the character, not the 332f22ef01cSRoman Divacky // alignment of the global! 333d88c1a5aSDimitry Andric unsigned Align = GO->getParent()->getDataLayout().getPreferredAlignment( 334d88c1a5aSDimitry Andric cast<GlobalVariable>(GO)); 335f22ef01cSRoman Divacky 336ff0cc061SDimitry Andric std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + "."; 337ff0cc061SDimitry Andric Name = SizeSpec + utostr(Align); 338ff0cc061SDimitry Andric } else if (Kind.isMergeableConst()) { 339ff0cc061SDimitry Andric Name = ".rodata.cst"; 340ff0cc061SDimitry Andric Name += utostr(EntrySize); 341ff0cc061SDimitry Andric } else { 342ff0cc061SDimitry Andric Name = getSectionPrefixForGlobal(Kind); 343ff0cc061SDimitry Andric } 344d88c1a5aSDimitry Andric 345d88c1a5aSDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) { 346d88c1a5aSDimitry Andric const auto &OptionalPrefix = F->getSectionPrefix(); 347d88c1a5aSDimitry Andric if (OptionalPrefix) 348d88c1a5aSDimitry Andric Name += *OptionalPrefix; 349d88c1a5aSDimitry Andric } 350ff0cc061SDimitry Andric 351ff0cc061SDimitry Andric if (EmitUniqueSection && UniqueSectionNames) { 352ff0cc061SDimitry Andric Name.push_back('.'); 353d88c1a5aSDimitry Andric TM.getNameWithPrefix(Name, GO, Mang, true); 354ff0cc061SDimitry Andric } 3553ca95b02SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 356ff0cc061SDimitry Andric if (EmitUniqueSection && !UniqueSectionNames) { 357ff0cc061SDimitry Andric UniqueID = *NextUniqueID; 358ff0cc061SDimitry Andric (*NextUniqueID)++; 359ff0cc061SDimitry Andric } 360d88c1a5aSDimitry Andric // Use 0 as the unique ID for execute-only text 361d88c1a5aSDimitry Andric if (Kind.isExecuteOnly()) 362d88c1a5aSDimitry Andric UniqueID = 0; 363ff0cc061SDimitry Andric return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags, 3647a7e6055SDimitry Andric EntrySize, Group, UniqueID, AssociatedSymbol); 365ff0cc061SDimitry Andric } 366ff0cc061SDimitry Andric 367ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( 368d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 369ff0cc061SDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 370ff0cc061SDimitry Andric 371ff0cc061SDimitry Andric // If we have -ffunction-section or -fdata-section then we should emit the 372ff0cc061SDimitry Andric // global value to a uniqued section specifically for it. 373ff0cc061SDimitry Andric bool EmitUniqueSection = false; 374ff0cc061SDimitry Andric if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) { 375ff0cc061SDimitry Andric if (Kind.isText()) 376ff0cc061SDimitry Andric EmitUniqueSection = TM.getFunctionSections(); 377f22ef01cSRoman Divacky else 378ff0cc061SDimitry Andric EmitUniqueSection = TM.getDataSections(); 379ff0cc061SDimitry Andric } 380d88c1a5aSDimitry Andric EmitUniqueSection |= GO->hasComdat(); 381f22ef01cSRoman Divacky 3827a7e6055SDimitry Andric const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM); 3837a7e6055SDimitry Andric if (AssociatedSymbol) { 3847a7e6055SDimitry Andric EmitUniqueSection = true; 3857a7e6055SDimitry Andric Flags |= ELF::SHF_LINK_ORDER; 3867a7e6055SDimitry Andric } 3877a7e6055SDimitry Andric 3887a7e6055SDimitry Andric MCSectionELF *Section = selectELFSectionForGlobal( 3897a7e6055SDimitry Andric getContext(), GO, Kind, getMangler(), TM, EmitUniqueSection, Flags, 3907a7e6055SDimitry Andric &NextUniqueID, AssociatedSymbol); 3917a7e6055SDimitry Andric assert(Section->getAssociatedSymbol() == AssociatedSymbol); 3927a7e6055SDimitry Andric return Section; 393f22ef01cSRoman Divacky } 394f22ef01cSRoman Divacky 395ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( 396d88c1a5aSDimitry Andric const Function &F, const TargetMachine &TM) const { 397ff0cc061SDimitry Andric // If the function can be removed, produce a unique section so that 398ff0cc061SDimitry Andric // the table doesn't prevent the removal. 399ff0cc061SDimitry Andric const Comdat *C = F.getComdat(); 400ff0cc061SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C; 401ff0cc061SDimitry Andric if (!EmitUniqueSection) 402ff0cc061SDimitry Andric return ReadOnlySection; 403ff0cc061SDimitry Andric 404ff0cc061SDimitry Andric return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(), 4057a7e6055SDimitry Andric getMangler(), TM, EmitUniqueSection, 4067a7e6055SDimitry Andric ELF::SHF_ALLOC, &NextUniqueID, 4077a7e6055SDimitry Andric /* AssociatedSymbol */ nullptr); 408f22ef01cSRoman Divacky } 409f22ef01cSRoman Divacky 410ff0cc061SDimitry Andric bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection( 411ff0cc061SDimitry Andric bool UsesLabelDifference, const Function &F) const { 412ff0cc061SDimitry Andric // We can always create relative relocations, so use another section 413ff0cc061SDimitry Andric // that can be marked non-executable. 414ff0cc061SDimitry Andric return false; 415f22ef01cSRoman Divacky } 416f22ef01cSRoman Divacky 417ff0cc061SDimitry Andric /// Given a mergeable constant with the specified size and relocation 418ff0cc061SDimitry Andric /// information, return a section that it should be placed in. 4197d523365SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForConstant( 4203ca95b02SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 4213ca95b02SDimitry Andric unsigned &Align) const { 422f22ef01cSRoman Divacky if (Kind.isMergeableConst4() && MergeableConst4Section) 423f22ef01cSRoman Divacky return MergeableConst4Section; 424f22ef01cSRoman Divacky if (Kind.isMergeableConst8() && MergeableConst8Section) 425f22ef01cSRoman Divacky return MergeableConst8Section; 426f22ef01cSRoman Divacky if (Kind.isMergeableConst16() && MergeableConst16Section) 427f22ef01cSRoman Divacky return MergeableConst16Section; 4283ca95b02SDimitry Andric if (Kind.isMergeableConst32() && MergeableConst32Section) 4293ca95b02SDimitry Andric return MergeableConst32Section; 430f22ef01cSRoman Divacky if (Kind.isReadOnly()) 431f22ef01cSRoman Divacky return ReadOnlySection; 432f22ef01cSRoman Divacky 433f22ef01cSRoman Divacky assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); 434f22ef01cSRoman Divacky return DataRelROSection; 435f22ef01cSRoman Divacky } 436f22ef01cSRoman Divacky 437ff0cc061SDimitry Andric static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray, 438ff0cc061SDimitry Andric bool IsCtor, unsigned Priority, 43939d628a0SDimitry Andric const MCSymbol *KeySym) { 44039d628a0SDimitry Andric std::string Name; 44139d628a0SDimitry Andric unsigned Type; 44239d628a0SDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE; 44339d628a0SDimitry Andric StringRef COMDAT = KeySym ? KeySym->getName() : ""; 44439d628a0SDimitry Andric 44539d628a0SDimitry Andric if (KeySym) 44639d628a0SDimitry Andric Flags |= ELF::SHF_GROUP; 447dff0c46cSDimitry Andric 4487ae0e2c9SDimitry Andric if (UseInitArray) { 44939d628a0SDimitry Andric if (IsCtor) { 45039d628a0SDimitry Andric Type = ELF::SHT_INIT_ARRAY; 45139d628a0SDimitry Andric Name = ".init_array"; 4527ae0e2c9SDimitry Andric } else { 45339d628a0SDimitry Andric Type = ELF::SHT_FINI_ARRAY; 45439d628a0SDimitry Andric Name = ".fini_array"; 455dff0c46cSDimitry Andric } 45639d628a0SDimitry Andric if (Priority != 65535) { 45739d628a0SDimitry Andric Name += '.'; 45839d628a0SDimitry Andric Name += utostr(Priority); 45939d628a0SDimitry Andric } 46039d628a0SDimitry Andric } else { 46139d628a0SDimitry Andric // The default scheme is .ctor / .dtor, so we have to invert the priority 46239d628a0SDimitry Andric // numbering. 46339d628a0SDimitry Andric if (IsCtor) 46439d628a0SDimitry Andric Name = ".ctors"; 46539d628a0SDimitry Andric else 46639d628a0SDimitry Andric Name = ".dtors"; 46739d628a0SDimitry Andric if (Priority != 65535) { 46839d628a0SDimitry Andric Name += '.'; 46939d628a0SDimitry Andric Name += utostr(65535 - Priority); 47039d628a0SDimitry Andric } 47139d628a0SDimitry Andric Type = ELF::SHT_PROGBITS; 47239d628a0SDimitry Andric } 47339d628a0SDimitry Andric 474ff0cc061SDimitry Andric return Ctx.getELFSection(Name, Type, Flags, 0, COMDAT); 47539d628a0SDimitry Andric } 47639d628a0SDimitry Andric 477ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticCtorSection( 47839d628a0SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 47939d628a0SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, true, Priority, 48039d628a0SDimitry Andric KeySym); 4817ae0e2c9SDimitry Andric } 482dff0c46cSDimitry Andric 483ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticDtorSection( 48491bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 48539d628a0SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, false, Priority, 48639d628a0SDimitry Andric KeySym); 4877ae0e2c9SDimitry Andric } 4887ae0e2c9SDimitry Andric 4893ca95b02SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference( 490d88c1a5aSDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 4913ca95b02SDimitry Andric const TargetMachine &TM) const { 4923ca95b02SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr 4933ca95b02SDimitry Andric // functions. 4943ca95b02SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) 4953ca95b02SDimitry Andric return nullptr; 4963ca95b02SDimitry Andric 4973ca95b02SDimitry Andric // Basic sanity checks. 4983ca95b02SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 4993ca95b02SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || 5003ca95b02SDimitry Andric RHS->isThreadLocal()) 5013ca95b02SDimitry Andric return nullptr; 5023ca95b02SDimitry Andric 5033ca95b02SDimitry Andric return MCBinaryExpr::createSub( 504d88c1a5aSDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS), PLTRelativeVariantKind, 5053ca95b02SDimitry Andric getContext()), 506d88c1a5aSDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); 5073ca95b02SDimitry Andric } 5083ca95b02SDimitry Andric 5097ae0e2c9SDimitry Andric void 5107ae0e2c9SDimitry Andric TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) { 5117ae0e2c9SDimitry Andric UseInitArray = UseInitArray_; 512d88c1a5aSDimitry Andric MCContext &Ctx = getContext(); 513d88c1a5aSDimitry Andric if (!UseInitArray) { 514d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getELFSection(".ctors", ELF::SHT_PROGBITS, 515d88c1a5aSDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE); 5167ae0e2c9SDimitry Andric 517d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getELFSection(".dtors", ELF::SHT_PROGBITS, 518d88c1a5aSDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE); 519d88c1a5aSDimitry Andric return; 520d88c1a5aSDimitry Andric } 521d88c1a5aSDimitry Andric 522d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getELFSection(".init_array", ELF::SHT_INIT_ARRAY, 523d88c1a5aSDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC); 524d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getELFSection(".fini_array", ELF::SHT_FINI_ARRAY, 525d88c1a5aSDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC); 5267ae0e2c9SDimitry Andric } 527dff0c46cSDimitry Andric 528f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 529f22ef01cSRoman Divacky // MachO 530f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 531f22ef01cSRoman Divacky 532ff0cc061SDimitry Andric TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO() 533ff0cc061SDimitry Andric : TargetLoweringObjectFile() { 534ff0cc061SDimitry Andric SupportIndirectSymViaGOTPCRel = true; 535ff0cc061SDimitry Andric } 536ff0cc061SDimitry Andric 537d88c1a5aSDimitry Andric void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx, 538d88c1a5aSDimitry Andric const TargetMachine &TM) { 539d88c1a5aSDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM); 540d88c1a5aSDimitry Andric if (TM.getRelocationModel() == Reloc::Static) { 541d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getMachOSection("__TEXT", "__constructor", 0, 542d88c1a5aSDimitry Andric SectionKind::getData()); 543d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getMachOSection("__TEXT", "__destructor", 0, 544d88c1a5aSDimitry Andric SectionKind::getData()); 545d88c1a5aSDimitry Andric } else { 546d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getMachOSection("__DATA", "__mod_init_func", 547d88c1a5aSDimitry Andric MachO::S_MOD_INIT_FUNC_POINTERS, 548d88c1a5aSDimitry Andric SectionKind::getData()); 549d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getMachOSection("__DATA", "__mod_term_func", 550d88c1a5aSDimitry Andric MachO::S_MOD_TERM_FUNC_POINTERS, 551d88c1a5aSDimitry Andric SectionKind::getData()); 552d88c1a5aSDimitry Andric } 553d88c1a5aSDimitry Andric } 554d88c1a5aSDimitry Andric 555139f7f9bSDimitry Andric /// emitModuleFlags - Perform code emission for module flags. 556d88c1a5aSDimitry Andric void TargetLoweringObjectFileMachO::emitModuleFlags( 557d88c1a5aSDimitry Andric MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, 558d88c1a5aSDimitry Andric const TargetMachine &TM) const { 559dff0c46cSDimitry Andric unsigned VersionVal = 0; 5607ae0e2c9SDimitry Andric unsigned ImageInfoFlags = 0; 56191bc56edSDimitry Andric MDNode *LinkerOptions = nullptr; 562dff0c46cSDimitry Andric StringRef SectionVal; 563dff0c46cSDimitry Andric 5643ca95b02SDimitry Andric for (const auto &MFE : ModuleFlags) { 565dff0c46cSDimitry Andric // Ignore flags with 'Require' behavior. 566dff0c46cSDimitry Andric if (MFE.Behavior == Module::Require) 567dff0c46cSDimitry Andric continue; 568dff0c46cSDimitry Andric 569dff0c46cSDimitry Andric StringRef Key = MFE.Key->getString(); 57039d628a0SDimitry Andric Metadata *Val = MFE.Val; 571dff0c46cSDimitry Andric 572139f7f9bSDimitry Andric if (Key == "Objective-C Image Info Version") { 57339d628a0SDimitry Andric VersionVal = mdconst::extract<ConstantInt>(Val)->getZExtValue(); 574139f7f9bSDimitry Andric } else if (Key == "Objective-C Garbage Collection" || 5757ae0e2c9SDimitry Andric Key == "Objective-C GC Only" || 57639d628a0SDimitry Andric Key == "Objective-C Is Simulated" || 5773ca95b02SDimitry Andric Key == "Objective-C Class Properties" || 57839d628a0SDimitry Andric Key == "Objective-C Image Swift Version") { 57939d628a0SDimitry Andric ImageInfoFlags |= mdconst::extract<ConstantInt>(Val)->getZExtValue(); 580139f7f9bSDimitry Andric } else if (Key == "Objective-C Image Info Section") { 581dff0c46cSDimitry Andric SectionVal = cast<MDString>(Val)->getString(); 582139f7f9bSDimitry Andric } else if (Key == "Linker Options") { 583139f7f9bSDimitry Andric LinkerOptions = cast<MDNode>(Val); 584139f7f9bSDimitry Andric } 585139f7f9bSDimitry Andric } 586139f7f9bSDimitry Andric 587139f7f9bSDimitry Andric // Emit the linker options if present. 588139f7f9bSDimitry Andric if (LinkerOptions) { 5893ca95b02SDimitry Andric for (const auto &Option : LinkerOptions->operands()) { 590139f7f9bSDimitry Andric SmallVector<std::string, 4> StrOptions; 5913ca95b02SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) 5923ca95b02SDimitry Andric StrOptions.push_back(cast<MDString>(Piece)->getString()); 593139f7f9bSDimitry Andric Streamer.EmitLinkerOptions(StrOptions); 594139f7f9bSDimitry Andric } 595dff0c46cSDimitry Andric } 596dff0c46cSDimitry Andric 597dff0c46cSDimitry Andric // The section is mandatory. If we don't have it, then we don't have GC info. 598dff0c46cSDimitry Andric if (SectionVal.empty()) return; 599dff0c46cSDimitry Andric 600dff0c46cSDimitry Andric StringRef Segment, Section; 601dff0c46cSDimitry Andric unsigned TAA = 0, StubSize = 0; 602dff0c46cSDimitry Andric bool TAAParsed; 603dff0c46cSDimitry Andric std::string ErrorCode = 604dff0c46cSDimitry Andric MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section, 605dff0c46cSDimitry Andric TAA, TAAParsed, StubSize); 606dff0c46cSDimitry Andric if (!ErrorCode.empty()) 607dff0c46cSDimitry Andric // If invalid, report the error with report_fatal_error. 608dff0c46cSDimitry Andric report_fatal_error("Invalid section specifier '" + Section + "': " + 609dff0c46cSDimitry Andric ErrorCode + "."); 610dff0c46cSDimitry Andric 611dff0c46cSDimitry Andric // Get the section. 612ff0cc061SDimitry Andric MCSectionMachO *S = getContext().getMachOSection( 6137d523365SDimitry Andric Segment, Section, TAA, StubSize, SectionKind::getData()); 614dff0c46cSDimitry Andric Streamer.SwitchSection(S); 615dff0c46cSDimitry Andric Streamer.EmitLabel(getContext(). 616ff0cc061SDimitry Andric getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); 617dff0c46cSDimitry Andric Streamer.EmitIntValue(VersionVal, 4); 6187ae0e2c9SDimitry Andric Streamer.EmitIntValue(ImageInfoFlags, 4); 619dff0c46cSDimitry Andric Streamer.AddBlankLine(); 620dff0c46cSDimitry Andric } 621dff0c46cSDimitry Andric 62291bc56edSDimitry Andric static void checkMachOComdat(const GlobalValue *GV) { 62391bc56edSDimitry Andric const Comdat *C = GV->getComdat(); 62491bc56edSDimitry Andric if (!C) 62591bc56edSDimitry Andric return; 62691bc56edSDimitry Andric 62791bc56edSDimitry Andric report_fatal_error("MachO doesn't support COMDATs, '" + C->getName() + 62891bc56edSDimitry Andric "' cannot be lowered."); 62991bc56edSDimitry Andric } 63091bc56edSDimitry Andric 631ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( 632d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 633f22ef01cSRoman Divacky // Parse the section specifier and create it if valid. 634f22ef01cSRoman Divacky StringRef Segment, Section; 6353b0f4066SDimitry Andric unsigned TAA = 0, StubSize = 0; 6363b0f4066SDimitry Andric bool TAAParsed; 63791bc56edSDimitry Andric 638d88c1a5aSDimitry Andric checkMachOComdat(GO); 63991bc56edSDimitry Andric 640f22ef01cSRoman Divacky std::string ErrorCode = 641d88c1a5aSDimitry Andric MCSectionMachO::ParseSectionSpecifier(GO->getSection(), Segment, Section, 6423b0f4066SDimitry Andric TAA, TAAParsed, StubSize); 643f22ef01cSRoman Divacky if (!ErrorCode.empty()) { 644f22ef01cSRoman Divacky // If invalid, report the error with report_fatal_error. 645d88c1a5aSDimitry Andric report_fatal_error("Global variable '" + GO->getName() + 646dff0c46cSDimitry Andric "' has an invalid section specifier '" + 647d88c1a5aSDimitry Andric GO->getSection() + "': " + ErrorCode + "."); 648f22ef01cSRoman Divacky } 649f22ef01cSRoman Divacky 650f22ef01cSRoman Divacky // Get the section. 651ff0cc061SDimitry Andric MCSectionMachO *S = 652f22ef01cSRoman Divacky getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind); 653f22ef01cSRoman Divacky 654dd6029ffSDimitry Andric // If TAA wasn't set by ParseSectionSpecifier() above, 655dd6029ffSDimitry Andric // use the value returned by getMachOSection() as a default. 6563b0f4066SDimitry Andric if (!TAAParsed) 657dd6029ffSDimitry Andric TAA = S->getTypeAndAttributes(); 658dd6029ffSDimitry Andric 659f22ef01cSRoman Divacky // Okay, now that we got the section, verify that the TAA & StubSize agree. 660f22ef01cSRoman Divacky // If the user declared multiple globals with different section flags, we need 661f22ef01cSRoman Divacky // to reject it here. 662f22ef01cSRoman Divacky if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) { 663f22ef01cSRoman Divacky // If invalid, report the error with report_fatal_error. 664d88c1a5aSDimitry Andric report_fatal_error("Global variable '" + GO->getName() + 665f22ef01cSRoman Divacky "' section type or attributes does not match previous" 666f22ef01cSRoman Divacky " section specifier"); 667f22ef01cSRoman Divacky } 668f22ef01cSRoman Divacky 669f22ef01cSRoman Divacky return S; 670f22ef01cSRoman Divacky } 671f22ef01cSRoman Divacky 672ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal( 673d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 674d88c1a5aSDimitry Andric checkMachOComdat(GO); 675f785676fSDimitry Andric 676f785676fSDimitry Andric // Handle thread local data. 677f785676fSDimitry Andric if (Kind.isThreadBSS()) return TLSBSSSection; 678f785676fSDimitry Andric if (Kind.isThreadData()) return TLSDataSection; 679f785676fSDimitry Andric 680f22ef01cSRoman Divacky if (Kind.isText()) 681d88c1a5aSDimitry Andric return GO->isWeakForLinker() ? TextCoalSection : TextSection; 682f22ef01cSRoman Divacky 683f22ef01cSRoman Divacky // If this is weak/linkonce, put this in a coalescable section, either in text 684f22ef01cSRoman Divacky // or data depending on if it is writable. 685d88c1a5aSDimitry Andric if (GO->isWeakForLinker()) { 686f22ef01cSRoman Divacky if (Kind.isReadOnly()) 687f22ef01cSRoman Divacky return ConstTextCoalSection; 688f22ef01cSRoman Divacky return DataCoalSection; 689f22ef01cSRoman Divacky } 690f22ef01cSRoman Divacky 691f22ef01cSRoman Divacky // FIXME: Alignment check should be handled by section classifier. 692f22ef01cSRoman Divacky if (Kind.isMergeable1ByteCString() && 693d88c1a5aSDimitry Andric GO->getParent()->getDataLayout().getPreferredAlignment( 694d88c1a5aSDimitry Andric cast<GlobalVariable>(GO)) < 32) 695f22ef01cSRoman Divacky return CStringSection; 696f22ef01cSRoman Divacky 697f22ef01cSRoman Divacky // Do not put 16-bit arrays in the UString section if they have an 698f22ef01cSRoman Divacky // externally visible label, this runs into issues with certain linker 699f22ef01cSRoman Divacky // versions. 700d88c1a5aSDimitry Andric if (Kind.isMergeable2ByteCString() && !GO->hasExternalLinkage() && 701d88c1a5aSDimitry Andric GO->getParent()->getDataLayout().getPreferredAlignment( 702d88c1a5aSDimitry Andric cast<GlobalVariable>(GO)) < 32) 703f22ef01cSRoman Divacky return UStringSection; 704f22ef01cSRoman Divacky 70539d628a0SDimitry Andric // With MachO only variables whose corresponding symbol starts with 'l' or 70639d628a0SDimitry Andric // 'L' can be merged, so we only try merging GVs with private linkage. 707d88c1a5aSDimitry Andric if (GO->hasPrivateLinkage() && Kind.isMergeableConst()) { 708f22ef01cSRoman Divacky if (Kind.isMergeableConst4()) 709f22ef01cSRoman Divacky return FourByteConstantSection; 710f22ef01cSRoman Divacky if (Kind.isMergeableConst8()) 711f22ef01cSRoman Divacky return EightByteConstantSection; 71291bc56edSDimitry Andric if (Kind.isMergeableConst16()) 713f22ef01cSRoman Divacky return SixteenByteConstantSection; 714f22ef01cSRoman Divacky } 715f22ef01cSRoman Divacky 716f22ef01cSRoman Divacky // Otherwise, if it is readonly, but not something we can specially optimize, 717f22ef01cSRoman Divacky // just drop it in .const. 718f22ef01cSRoman Divacky if (Kind.isReadOnly()) 719f22ef01cSRoman Divacky return ReadOnlySection; 720f22ef01cSRoman Divacky 721f22ef01cSRoman Divacky // If this is marked const, put it into a const section. But if the dynamic 722f22ef01cSRoman Divacky // linker needs to write to it, put it in the data segment. 723f22ef01cSRoman Divacky if (Kind.isReadOnlyWithRel()) 724f22ef01cSRoman Divacky return ConstDataSection; 725f22ef01cSRoman Divacky 726f22ef01cSRoman Divacky // Put zero initialized globals with strong external linkage in the 727f22ef01cSRoman Divacky // DATA, __common section with the .zerofill directive. 728f22ef01cSRoman Divacky if (Kind.isBSSExtern()) 729f22ef01cSRoman Divacky return DataCommonSection; 730f22ef01cSRoman Divacky 731f22ef01cSRoman Divacky // Put zero initialized globals with local linkage in __DATA,__bss directive 732f22ef01cSRoman Divacky // with the .zerofill directive (aka .lcomm). 733f22ef01cSRoman Divacky if (Kind.isBSSLocal()) 734f22ef01cSRoman Divacky return DataBSSSection; 735f22ef01cSRoman Divacky 736f22ef01cSRoman Divacky // Otherwise, just drop the variable in the normal data section. 737f22ef01cSRoman Divacky return DataSection; 738f22ef01cSRoman Divacky } 739f22ef01cSRoman Divacky 7407d523365SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getSectionForConstant( 7413ca95b02SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 7423ca95b02SDimitry Andric unsigned &Align) const { 743f22ef01cSRoman Divacky // If this constant requires a relocation, we have to put it in the data 744f22ef01cSRoman Divacky // segment, not in the text segment. 7457d523365SDimitry Andric if (Kind.isData() || Kind.isReadOnlyWithRel()) 746f22ef01cSRoman Divacky return ConstDataSection; 747f22ef01cSRoman Divacky 748f22ef01cSRoman Divacky if (Kind.isMergeableConst4()) 749f22ef01cSRoman Divacky return FourByteConstantSection; 750f22ef01cSRoman Divacky if (Kind.isMergeableConst8()) 751f22ef01cSRoman Divacky return EightByteConstantSection; 75291bc56edSDimitry Andric if (Kind.isMergeableConst16()) 753f22ef01cSRoman Divacky return SixteenByteConstantSection; 754f22ef01cSRoman Divacky return ReadOnlySection; // .const 755f22ef01cSRoman Divacky } 756f22ef01cSRoman Divacky 75791bc56edSDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference( 758d88c1a5aSDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, 759d88c1a5aSDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 760f22ef01cSRoman Divacky // The mach-o version of this method defaults to returning a stub reference. 761f22ef01cSRoman Divacky 762f22ef01cSRoman Divacky if (Encoding & DW_EH_PE_indirect) { 763f22ef01cSRoman Divacky MachineModuleInfoMachO &MachOMMI = 764f22ef01cSRoman Divacky MMI->getObjFileInfo<MachineModuleInfoMachO>(); 765f22ef01cSRoman Divacky 766d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); 767f22ef01cSRoman Divacky 768f22ef01cSRoman Divacky // Add information about the stub reference to MachOMMI so that the stub 769f22ef01cSRoman Divacky // gets emitted by the asmprinter. 7703ca95b02SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 77191bc56edSDimitry Andric if (!StubSym.getPointer()) { 772d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 773f22ef01cSRoman Divacky StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 774f22ef01cSRoman Divacky } 775f22ef01cSRoman Divacky 776f22ef01cSRoman Divacky return TargetLoweringObjectFile:: 77797bc6c73SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), 7787a7e6055SDimitry Andric Encoding & ~DW_EH_PE_indirect, Streamer); 779f22ef01cSRoman Divacky } 780f22ef01cSRoman Divacky 781d88c1a5aSDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM, 782d88c1a5aSDimitry Andric MMI, Streamer); 783f22ef01cSRoman Divacky } 784f22ef01cSRoman Divacky 78591bc56edSDimitry Andric MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol( 786d88c1a5aSDimitry Andric const GlobalValue *GV, const TargetMachine &TM, 7873b0f4066SDimitry Andric MachineModuleInfo *MMI) const { 7883b0f4066SDimitry Andric // The mach-o version of this method defaults to returning a stub reference. 7893b0f4066SDimitry Andric MachineModuleInfoMachO &MachOMMI = 7903b0f4066SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 7913b0f4066SDimitry Andric 792d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); 7933b0f4066SDimitry Andric 7943b0f4066SDimitry Andric // Add information about the stub reference to MachOMMI so that the stub 7953b0f4066SDimitry Andric // gets emitted by the asmprinter. 796dff0c46cSDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 79791bc56edSDimitry Andric if (!StubSym.getPointer()) { 798d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 7993b0f4066SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 8003b0f4066SDimitry Andric } 8013b0f4066SDimitry Andric 8023b0f4066SDimitry Andric return SSym; 8033b0f4066SDimitry Andric } 8043b0f4066SDimitry Andric 805ff0cc061SDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel( 806ff0cc061SDimitry Andric const MCSymbol *Sym, const MCValue &MV, int64_t Offset, 807ff0cc061SDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 8087d523365SDimitry Andric // Although MachO 32-bit targets do not explicitly have a GOTPCREL relocation 809ff0cc061SDimitry Andric // as 64-bit do, we replace the GOT equivalent by accessing the final symbol 810ff0cc061SDimitry Andric // through a non_lazy_ptr stub instead. One advantage is that it allows the 811ff0cc061SDimitry Andric // computation of deltas to final external symbols. Example: 812ff0cc061SDimitry Andric // 813ff0cc061SDimitry Andric // _extgotequiv: 814ff0cc061SDimitry Andric // .long _extfoo 815ff0cc061SDimitry Andric // 816ff0cc061SDimitry Andric // _delta: 817ff0cc061SDimitry Andric // .long _extgotequiv-_delta 818ff0cc061SDimitry Andric // 819ff0cc061SDimitry Andric // is transformed to: 820ff0cc061SDimitry Andric // 821ff0cc061SDimitry Andric // _delta: 822ff0cc061SDimitry Andric // .long L_extfoo$non_lazy_ptr-(_delta+0) 823ff0cc061SDimitry Andric // 824ff0cc061SDimitry Andric // .section __IMPORT,__pointers,non_lazy_symbol_pointers 825ff0cc061SDimitry Andric // L_extfoo$non_lazy_ptr: 826ff0cc061SDimitry Andric // .indirect_symbol _extfoo 827ff0cc061SDimitry Andric // .long 0 828ff0cc061SDimitry Andric // 829ff0cc061SDimitry Andric MachineModuleInfoMachO &MachOMMI = 830ff0cc061SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 831ff0cc061SDimitry Andric MCContext &Ctx = getContext(); 832ff0cc061SDimitry Andric 833ff0cc061SDimitry Andric // The offset must consider the original displacement from the base symbol 834ff0cc061SDimitry Andric // since 32-bit targets don't have a GOTPCREL to fold the PC displacement. 835ff0cc061SDimitry Andric Offset = -MV.getConstant(); 836ff0cc061SDimitry Andric const MCSymbol *BaseSym = &MV.getSymB()->getSymbol(); 837ff0cc061SDimitry Andric 838ff0cc061SDimitry Andric // Access the final symbol via sym$non_lazy_ptr and generate the appropriated 839ff0cc061SDimitry Andric // non_lazy_ptr stubs. 840ff0cc061SDimitry Andric SmallString<128> Name; 841ff0cc061SDimitry Andric StringRef Suffix = "$non_lazy_ptr"; 8427d523365SDimitry Andric Name += MMI->getModule()->getDataLayout().getPrivateGlobalPrefix(); 843ff0cc061SDimitry Andric Name += Sym->getName(); 844ff0cc061SDimitry Andric Name += Suffix; 845ff0cc061SDimitry Andric MCSymbol *Stub = Ctx.getOrCreateSymbol(Name); 846ff0cc061SDimitry Andric 847ff0cc061SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub); 848ff0cc061SDimitry Andric if (!StubSym.getPointer()) 849ff0cc061SDimitry Andric StubSym = MachineModuleInfoImpl:: 850ff0cc061SDimitry Andric StubValueTy(const_cast<MCSymbol *>(Sym), true /* access indirectly */); 851ff0cc061SDimitry Andric 852ff0cc061SDimitry Andric const MCExpr *BSymExpr = 85397bc6c73SDimitry Andric MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx); 854ff0cc061SDimitry Andric const MCExpr *LHS = 85597bc6c73SDimitry Andric MCSymbolRefExpr::create(Stub, MCSymbolRefExpr::VK_None, Ctx); 856ff0cc061SDimitry Andric 857ff0cc061SDimitry Andric if (!Offset) 85897bc6c73SDimitry Andric return MCBinaryExpr::createSub(LHS, BSymExpr, Ctx); 859ff0cc061SDimitry Andric 860ff0cc061SDimitry Andric const MCExpr *RHS = 86197bc6c73SDimitry Andric MCBinaryExpr::createAdd(BSymExpr, MCConstantExpr::create(Offset, Ctx), Ctx); 86297bc6c73SDimitry Andric return MCBinaryExpr::createSub(LHS, RHS, Ctx); 863ff0cc061SDimitry Andric } 864ff0cc061SDimitry Andric 8657d523365SDimitry Andric static bool canUsePrivateLabel(const MCAsmInfo &AsmInfo, 8667d523365SDimitry Andric const MCSection &Section) { 8677d523365SDimitry Andric if (!AsmInfo.isSectionAtomizableBySymbols(Section)) 8687d523365SDimitry Andric return true; 8697d523365SDimitry Andric 8707d523365SDimitry Andric // If it is not dead stripped, it is safe to use private labels. 8717d523365SDimitry Andric const MCSectionMachO &SMO = cast<MCSectionMachO>(Section); 8727d523365SDimitry Andric if (SMO.hasAttribute(MachO::S_ATTR_NO_DEAD_STRIP)) 8737d523365SDimitry Andric return true; 8747d523365SDimitry Andric 8757d523365SDimitry Andric return false; 8767d523365SDimitry Andric } 8777d523365SDimitry Andric 8787d523365SDimitry Andric void TargetLoweringObjectFileMachO::getNameWithPrefix( 879d88c1a5aSDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, 8807d523365SDimitry Andric const TargetMachine &TM) const { 881d88c1a5aSDimitry Andric bool CannotUsePrivateLabel = true; 882d88c1a5aSDimitry Andric if (auto *GO = GV->getBaseObject()) { 883d88c1a5aSDimitry Andric SectionKind GOKind = TargetLoweringObjectFile::getKindForGlobal(GO, TM); 884d88c1a5aSDimitry Andric const MCSection *TheSection = SectionForGlobal(GO, GOKind, TM); 885d88c1a5aSDimitry Andric CannotUsePrivateLabel = 8867d523365SDimitry Andric !canUsePrivateLabel(*TM.getMCAsmInfo(), *TheSection); 887d88c1a5aSDimitry Andric } 888d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 8897d523365SDimitry Andric } 8907d523365SDimitry Andric 891f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 892f22ef01cSRoman Divacky // COFF 893f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 894f22ef01cSRoman Divacky 895f22ef01cSRoman Divacky static unsigned 8963ca95b02SDimitry Andric getCOFFSectionFlags(SectionKind K, const TargetMachine &TM) { 897f22ef01cSRoman Divacky unsigned Flags = 0; 8983ca95b02SDimitry Andric bool isThumb = TM.getTargetTriple().getArch() == Triple::thumb; 899f22ef01cSRoman Divacky 900ffd1746dSEd Schouten if (K.isMetadata()) 901f22ef01cSRoman Divacky Flags |= 902ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_DISCARDABLE; 903f22ef01cSRoman Divacky else if (K.isText()) 904f22ef01cSRoman Divacky Flags |= 905ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_EXECUTE | 9062754fe60SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 9073ca95b02SDimitry Andric COFF::IMAGE_SCN_CNT_CODE | 9083ca95b02SDimitry Andric (isThumb ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0); 909f22ef01cSRoman Divacky else if (K.isBSS()) 910f22ef01cSRoman Divacky Flags |= 911ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | 912ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ | 913ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_WRITE; 914dff0c46cSDimitry Andric else if (K.isThreadLocal()) 915dff0c46cSDimitry Andric Flags |= 916dff0c46cSDimitry Andric COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 917dff0c46cSDimitry Andric COFF::IMAGE_SCN_MEM_READ | 918dff0c46cSDimitry Andric COFF::IMAGE_SCN_MEM_WRITE; 91939d628a0SDimitry Andric else if (K.isReadOnly() || K.isReadOnlyWithRel()) 920f22ef01cSRoman Divacky Flags |= 921ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 922ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ; 923f22ef01cSRoman Divacky else if (K.isWriteable()) 924f22ef01cSRoman Divacky Flags |= 925ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 926ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ | 927ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_WRITE; 928f22ef01cSRoman Divacky 929f22ef01cSRoman Divacky return Flags; 930f22ef01cSRoman Divacky } 931f22ef01cSRoman Divacky 93291bc56edSDimitry Andric static const GlobalValue *getComdatGVForCOFF(const GlobalValue *GV) { 93391bc56edSDimitry Andric const Comdat *C = GV->getComdat(); 93491bc56edSDimitry Andric assert(C && "expected GV to have a Comdat!"); 93591bc56edSDimitry Andric 93691bc56edSDimitry Andric StringRef ComdatGVName = C->getName(); 93791bc56edSDimitry Andric const GlobalValue *ComdatGV = GV->getParent()->getNamedValue(ComdatGVName); 93891bc56edSDimitry Andric if (!ComdatGV) 93991bc56edSDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 94091bc56edSDimitry Andric "' does not exist."); 94191bc56edSDimitry Andric 94291bc56edSDimitry Andric if (ComdatGV->getComdat() != C) 94391bc56edSDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 94439d628a0SDimitry Andric "' is not a key for its COMDAT."); 94591bc56edSDimitry Andric 94691bc56edSDimitry Andric return ComdatGV; 94791bc56edSDimitry Andric } 94891bc56edSDimitry Andric 94991bc56edSDimitry Andric static int getSelectionForCOFF(const GlobalValue *GV) { 95091bc56edSDimitry Andric if (const Comdat *C = GV->getComdat()) { 95191bc56edSDimitry Andric const GlobalValue *ComdatKey = getComdatGVForCOFF(GV); 95291bc56edSDimitry Andric if (const auto *GA = dyn_cast<GlobalAlias>(ComdatKey)) 95391bc56edSDimitry Andric ComdatKey = GA->getBaseObject(); 95491bc56edSDimitry Andric if (ComdatKey == GV) { 95591bc56edSDimitry Andric switch (C->getSelectionKind()) { 95691bc56edSDimitry Andric case Comdat::Any: 95791bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ANY; 95891bc56edSDimitry Andric case Comdat::ExactMatch: 95991bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH; 96091bc56edSDimitry Andric case Comdat::Largest: 96191bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_LARGEST; 96291bc56edSDimitry Andric case Comdat::NoDuplicates: 96391bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 96491bc56edSDimitry Andric case Comdat::SameSize: 96591bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_SAME_SIZE; 96691bc56edSDimitry Andric } 96791bc56edSDimitry Andric } else { 96891bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE; 96991bc56edSDimitry Andric } 97091bc56edSDimitry Andric } 97191bc56edSDimitry Andric return 0; 97291bc56edSDimitry Andric } 97391bc56edSDimitry Andric 974ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal( 975d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 976139f7f9bSDimitry Andric int Selection = 0; 9773ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 978d88c1a5aSDimitry Andric StringRef Name = GO->getSection(); 97991bc56edSDimitry Andric StringRef COMDATSymName = ""; 980d88c1a5aSDimitry Andric if (GO->hasComdat()) { 981d88c1a5aSDimitry Andric Selection = getSelectionForCOFF(GO); 98291bc56edSDimitry Andric const GlobalValue *ComdatGV; 98391bc56edSDimitry Andric if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) 984d88c1a5aSDimitry Andric ComdatGV = getComdatGVForCOFF(GO); 98591bc56edSDimitry Andric else 986d88c1a5aSDimitry Andric ComdatGV = GO; 98791bc56edSDimitry Andric 98891bc56edSDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 989d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV); 99091bc56edSDimitry Andric COMDATSymName = Sym->getName(); 991139f7f9bSDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 99291bc56edSDimitry Andric } else { 99391bc56edSDimitry Andric Selection = 0; 99491bc56edSDimitry Andric } 995139f7f9bSDimitry Andric } 9963ca95b02SDimitry Andric 9973ca95b02SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, 998f785676fSDimitry Andric Selection); 999f22ef01cSRoman Divacky } 1000f22ef01cSRoman Divacky 100191bc56edSDimitry Andric static const char *getCOFFSectionNameForUniqueGlobal(SectionKind Kind) { 1002f22ef01cSRoman Divacky if (Kind.isText()) 100391bc56edSDimitry Andric return ".text"; 1004f22ef01cSRoman Divacky if (Kind.isBSS()) 100591bc56edSDimitry Andric return ".bss"; 100691bc56edSDimitry Andric if (Kind.isThreadLocal()) 100791bc56edSDimitry Andric return ".tls$"; 100839d628a0SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 100991bc56edSDimitry Andric return ".rdata"; 101039d628a0SDimitry Andric return ".data"; 1011f22ef01cSRoman Divacky } 1012f22ef01cSRoman Divacky 1013ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal( 1014d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 101591bc56edSDimitry Andric // If we have -ffunction-sections then we should emit the global value to a 101691bc56edSDimitry Andric // uniqued section specifically for it. 101791bc56edSDimitry Andric bool EmitUniquedSection; 101891bc56edSDimitry Andric if (Kind.isText()) 101991bc56edSDimitry Andric EmitUniquedSection = TM.getFunctionSections(); 102091bc56edSDimitry Andric else 102191bc56edSDimitry Andric EmitUniquedSection = TM.getDataSections(); 1022f22ef01cSRoman Divacky 1023d88c1a5aSDimitry Andric if ((EmitUniquedSection && !Kind.isCommon()) || GO->hasComdat()) { 102491bc56edSDimitry Andric const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); 10253ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 1026f22ef01cSRoman Divacky 1027ffd1746dSEd Schouten Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 1028d88c1a5aSDimitry Andric int Selection = getSelectionForCOFF(GO); 102991bc56edSDimitry Andric if (!Selection) 103091bc56edSDimitry Andric Selection = COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 103191bc56edSDimitry Andric const GlobalValue *ComdatGV; 1032d88c1a5aSDimitry Andric if (GO->hasComdat()) 1033d88c1a5aSDimitry Andric ComdatGV = getComdatGVForCOFF(GO); 103491bc56edSDimitry Andric else 1035d88c1a5aSDimitry Andric ComdatGV = GO; 1036f22ef01cSRoman Divacky 10373ca95b02SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 10383ca95b02SDimitry Andric if (EmitUniquedSection) 10393ca95b02SDimitry Andric UniqueID = NextUniqueID++; 10403ca95b02SDimitry Andric 104191bc56edSDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 1042d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV); 104391bc56edSDimitry Andric StringRef COMDATSymName = Sym->getName(); 104491bc56edSDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, 10453ca95b02SDimitry Andric COMDATSymName, Selection, UniqueID); 1046ff0cc061SDimitry Andric } else { 1047ff0cc061SDimitry Andric SmallString<256> TmpData; 1048d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(TmpData, GO, /*CannotUsePrivateLabel=*/true); 1049ff0cc061SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, TmpData, 10503ca95b02SDimitry Andric Selection, UniqueID); 105191bc56edSDimitry Andric } 1052f22ef01cSRoman Divacky } 1053f22ef01cSRoman Divacky 1054f22ef01cSRoman Divacky if (Kind.isText()) 1055f785676fSDimitry Andric return TextSection; 1056f22ef01cSRoman Divacky 1057dff0c46cSDimitry Andric if (Kind.isThreadLocal()) 1058f785676fSDimitry Andric return TLSDataSection; 1059dff0c46cSDimitry Andric 106039d628a0SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 1061f785676fSDimitry Andric return ReadOnlySection; 1062f785676fSDimitry Andric 106391bc56edSDimitry Andric // Note: we claim that common symbols are put in BSSSection, but they are 106491bc56edSDimitry Andric // really emitted with the magic .comm directive, which creates a symbol table 106591bc56edSDimitry Andric // entry but not a section. 106691bc56edSDimitry Andric if (Kind.isBSS() || Kind.isCommon()) 1067f785676fSDimitry Andric return BSSSection; 1068f785676fSDimitry Andric 1069f785676fSDimitry Andric return DataSection; 1070f22ef01cSRoman Divacky } 1071f22ef01cSRoman Divacky 1072ff0cc061SDimitry Andric void TargetLoweringObjectFileCOFF::getNameWithPrefix( 1073d88c1a5aSDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, 10747d523365SDimitry Andric const TargetMachine &TM) const { 10757d523365SDimitry Andric bool CannotUsePrivateLabel = false; 1076ff0cc061SDimitry Andric if (GV->hasPrivateLinkage() && 1077ff0cc061SDimitry Andric ((isa<Function>(GV) && TM.getFunctionSections()) || 1078ff0cc061SDimitry Andric (isa<GlobalVariable>(GV) && TM.getDataSections()))) 1079ff0cc061SDimitry Andric CannotUsePrivateLabel = true; 1080ff0cc061SDimitry Andric 1081d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 1082ff0cc061SDimitry Andric } 1083ff0cc061SDimitry Andric 1084ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable( 1085d88c1a5aSDimitry Andric const Function &F, const TargetMachine &TM) const { 1086ff0cc061SDimitry Andric // If the function can be removed, produce a unique section so that 1087ff0cc061SDimitry Andric // the table doesn't prevent the removal. 1088ff0cc061SDimitry Andric const Comdat *C = F.getComdat(); 1089ff0cc061SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C; 1090ff0cc061SDimitry Andric if (!EmitUniqueSection) 1091ff0cc061SDimitry Andric return ReadOnlySection; 1092ff0cc061SDimitry Andric 1093ff0cc061SDimitry Andric // FIXME: we should produce a symbol for F instead. 1094ff0cc061SDimitry Andric if (F.hasPrivateLinkage()) 1095ff0cc061SDimitry Andric return ReadOnlySection; 1096ff0cc061SDimitry Andric 1097d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(&F); 1098ff0cc061SDimitry Andric StringRef COMDATSymName = Sym->getName(); 1099ff0cc061SDimitry Andric 1100ff0cc061SDimitry Andric SectionKind Kind = SectionKind::getReadOnly(); 1101ff0cc061SDimitry Andric const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); 11023ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 1103ff0cc061SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 11043ca95b02SDimitry Andric unsigned UniqueID = NextUniqueID++; 1105ff0cc061SDimitry Andric 1106ff0cc061SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, 11073ca95b02SDimitry Andric COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); 1108ff0cc061SDimitry Andric } 1109ff0cc061SDimitry Andric 1110d88c1a5aSDimitry Andric void TargetLoweringObjectFileCOFF::emitModuleFlags( 1111d88c1a5aSDimitry Andric MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, 1112d88c1a5aSDimitry Andric const TargetMachine &TM) const { 111391bc56edSDimitry Andric MDNode *LinkerOptions = nullptr; 1114284c1978SDimitry Andric 11153ca95b02SDimitry Andric for (const auto &MFE : ModuleFlags) { 1116284c1978SDimitry Andric StringRef Key = MFE.Key->getString(); 11173ca95b02SDimitry Andric if (Key == "Linker Options") 11183ca95b02SDimitry Andric LinkerOptions = cast<MDNode>(MFE.Val); 1119284c1978SDimitry Andric } 1120284c1978SDimitry Andric 11213ca95b02SDimitry Andric if (LinkerOptions) { 1122284c1978SDimitry Andric // Emit the linker options to the linker .drectve section. According to the 11233ca95b02SDimitry Andric // spec, this section is a space-separated string containing flags for 11243ca95b02SDimitry Andric // linker. 1125ff0cc061SDimitry Andric MCSection *Sec = getDrectveSection(); 1126284c1978SDimitry Andric Streamer.SwitchSection(Sec); 11273ca95b02SDimitry Andric for (const auto &Option : LinkerOptions->operands()) { 11283ca95b02SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) { 1129284c1978SDimitry Andric // Lead with a space for consistency with our dllexport implementation. 1130ff0cc061SDimitry Andric std::string Directive(" "); 11313ca95b02SDimitry Andric Directive.append(cast<MDString>(Piece)->getString()); 1132ff0cc061SDimitry Andric Streamer.EmitBytes(Directive); 1133284c1978SDimitry Andric } 1134284c1978SDimitry Andric } 1135284c1978SDimitry Andric } 11363ca95b02SDimitry Andric } 113791bc56edSDimitry Andric 1138d88c1a5aSDimitry Andric void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx, 1139d88c1a5aSDimitry Andric const TargetMachine &TM) { 1140d88c1a5aSDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM); 1141d88c1a5aSDimitry Andric const Triple &T = TM.getTargetTriple(); 1142d88c1a5aSDimitry Andric if (T.isKnownWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) { 1143d88c1a5aSDimitry Andric StaticCtorSection = 1144d88c1a5aSDimitry Andric Ctx.getCOFFSection(".CRT$XCU", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1145d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ, 1146d88c1a5aSDimitry Andric SectionKind::getReadOnly()); 1147d88c1a5aSDimitry Andric StaticDtorSection = 1148d88c1a5aSDimitry Andric Ctx.getCOFFSection(".CRT$XTX", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1149d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ, 1150d88c1a5aSDimitry Andric SectionKind::getReadOnly()); 1151d88c1a5aSDimitry Andric } else { 1152d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getCOFFSection( 1153d88c1a5aSDimitry Andric ".ctors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1154d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, 1155d88c1a5aSDimitry Andric SectionKind::getData()); 1156d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getCOFFSection( 1157d88c1a5aSDimitry Andric ".dtors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1158d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, 1159d88c1a5aSDimitry Andric SectionKind::getData()); 1160d88c1a5aSDimitry Andric } 1161d88c1a5aSDimitry Andric } 1162d88c1a5aSDimitry Andric 1163ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection( 116491bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 116539d628a0SDimitry Andric return getContext().getAssociativeCOFFSection( 11663ca95b02SDimitry Andric cast<MCSectionCOFF>(StaticCtorSection), KeySym, 0); 116791bc56edSDimitry Andric } 116891bc56edSDimitry Andric 1169ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection( 117091bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 117139d628a0SDimitry Andric return getContext().getAssociativeCOFFSection( 11723ca95b02SDimitry Andric cast<MCSectionCOFF>(StaticDtorSection), KeySym, 0); 117391bc56edSDimitry Andric } 11743dac3a9bSDimitry Andric 11753dac3a9bSDimitry Andric void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal( 1176d88c1a5aSDimitry Andric raw_ostream &OS, const GlobalValue *GV) const { 11777a7e6055SDimitry Andric emitLinkerFlagsForGlobalCOFF(OS, GV, getTargetTriple(), getMangler()); 11783dac3a9bSDimitry Andric } 11793dac3a9bSDimitry Andric 11807a7e6055SDimitry Andric //===----------------------------------------------------------------------===// 11817a7e6055SDimitry Andric // Wasm 11827a7e6055SDimitry Andric //===----------------------------------------------------------------------===// 11837a7e6055SDimitry Andric 11847a7e6055SDimitry Andric static const Comdat *getWasmComdat(const GlobalValue *GV) { 11857a7e6055SDimitry Andric const Comdat *C = GV->getComdat(); 11867a7e6055SDimitry Andric if (!C) 11877a7e6055SDimitry Andric return nullptr; 11887a7e6055SDimitry Andric 11897a7e6055SDimitry Andric if (C->getSelectionKind() != Comdat::Any) 11907a7e6055SDimitry Andric report_fatal_error("Wasm COMDATs only support SelectionKind::Any, '" + 11917a7e6055SDimitry Andric C->getName() + "' cannot be lowered."); 11927a7e6055SDimitry Andric 11937a7e6055SDimitry Andric return C; 11943dac3a9bSDimitry Andric } 11957a7e6055SDimitry Andric 11967a7e6055SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal( 11977a7e6055SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 11987a7e6055SDimitry Andric llvm_unreachable("getExplicitSectionGlobal not yet implemented"); 11997a7e6055SDimitry Andric return nullptr; 12007a7e6055SDimitry Andric } 12017a7e6055SDimitry Andric 12027a7e6055SDimitry Andric static MCSectionWasm * 12037a7e6055SDimitry Andric selectWasmSectionForGlobal(MCContext &Ctx, const GlobalObject *GO, 12047a7e6055SDimitry Andric SectionKind Kind, Mangler &Mang, 12057a7e6055SDimitry Andric const TargetMachine &TM, bool EmitUniqueSection, 12067a7e6055SDimitry Andric unsigned Flags, unsigned *NextUniqueID) { 12077a7e6055SDimitry Andric StringRef Group = ""; 12087a7e6055SDimitry Andric if (getWasmComdat(GO)) 12097a7e6055SDimitry Andric llvm_unreachable("comdat not yet supported for wasm"); 12107a7e6055SDimitry Andric 12117a7e6055SDimitry Andric bool UniqueSectionNames = TM.getUniqueSectionNames(); 12127a7e6055SDimitry Andric SmallString<128> Name = getSectionPrefixForGlobal(Kind); 12137a7e6055SDimitry Andric 12147a7e6055SDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) { 12157a7e6055SDimitry Andric const auto &OptionalPrefix = F->getSectionPrefix(); 12167a7e6055SDimitry Andric if (OptionalPrefix) 12177a7e6055SDimitry Andric Name += *OptionalPrefix; 12187a7e6055SDimitry Andric } 12197a7e6055SDimitry Andric 12207a7e6055SDimitry Andric if (EmitUniqueSection && UniqueSectionNames) { 12217a7e6055SDimitry Andric Name.push_back('.'); 12227a7e6055SDimitry Andric TM.getNameWithPrefix(Name, GO, Mang, true); 12237a7e6055SDimitry Andric } 12247a7e6055SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 12257a7e6055SDimitry Andric if (EmitUniqueSection && !UniqueSectionNames) { 12267a7e6055SDimitry Andric UniqueID = *NextUniqueID; 12277a7e6055SDimitry Andric (*NextUniqueID)++; 12287a7e6055SDimitry Andric } 12297a7e6055SDimitry Andric return Ctx.getWasmSection(Name, /*Type=*/0, Flags, 12307a7e6055SDimitry Andric Group, UniqueID); 12317a7e6055SDimitry Andric } 12327a7e6055SDimitry Andric 12337a7e6055SDimitry Andric MCSection *TargetLoweringObjectFileWasm::SelectSectionForGlobal( 12347a7e6055SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 12357a7e6055SDimitry Andric 12367a7e6055SDimitry Andric if (Kind.isCommon()) 12377a7e6055SDimitry Andric report_fatal_error("mergable sections not supported yet on wasm"); 12387a7e6055SDimitry Andric 12397a7e6055SDimitry Andric // If we have -ffunction-section or -fdata-section then we should emit the 12407a7e6055SDimitry Andric // global value to a uniqued section specifically for it. 12417a7e6055SDimitry Andric bool EmitUniqueSection = false; 12427a7e6055SDimitry Andric if (Kind.isText()) 12437a7e6055SDimitry Andric EmitUniqueSection = TM.getFunctionSections(); 12447a7e6055SDimitry Andric else 12457a7e6055SDimitry Andric EmitUniqueSection = TM.getDataSections(); 12467a7e6055SDimitry Andric EmitUniqueSection |= GO->hasComdat(); 12477a7e6055SDimitry Andric 12487a7e6055SDimitry Andric return selectWasmSectionForGlobal(getContext(), GO, Kind, getMangler(), TM, 12497a7e6055SDimitry Andric EmitUniqueSection, /*Flags=*/0, 12507a7e6055SDimitry Andric &NextUniqueID); 12517a7e6055SDimitry Andric } 12527a7e6055SDimitry Andric 12537a7e6055SDimitry Andric bool TargetLoweringObjectFileWasm::shouldPutJumpTableInFunctionSection( 12547a7e6055SDimitry Andric bool UsesLabelDifference, const Function &F) const { 12557a7e6055SDimitry Andric // We can always create relative relocations, so use another section 12567a7e6055SDimitry Andric // that can be marked non-executable. 12577a7e6055SDimitry Andric return false; 12587a7e6055SDimitry Andric } 12597a7e6055SDimitry Andric 12607a7e6055SDimitry Andric const MCExpr *TargetLoweringObjectFileWasm::lowerRelativeReference( 12617a7e6055SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 12627a7e6055SDimitry Andric const TargetMachine &TM) const { 12637a7e6055SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr 12647a7e6055SDimitry Andric // functions. 12657a7e6055SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) 12667a7e6055SDimitry Andric return nullptr; 12677a7e6055SDimitry Andric 12687a7e6055SDimitry Andric // Basic sanity checks. 12697a7e6055SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 12707a7e6055SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || 12717a7e6055SDimitry Andric RHS->isThreadLocal()) 12727a7e6055SDimitry Andric return nullptr; 12737a7e6055SDimitry Andric 12747a7e6055SDimitry Andric return MCBinaryExpr::createSub( 12757a7e6055SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS), MCSymbolRefExpr::VK_None, 12767a7e6055SDimitry Andric getContext()), 12777a7e6055SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); 12787a7e6055SDimitry Andric } 12797a7e6055SDimitry Andric 12807a7e6055SDimitry Andric void 12817a7e6055SDimitry Andric TargetLoweringObjectFileWasm::InitializeWasm() { 12827a7e6055SDimitry Andric // TODO: Initialize StaticCtorSection and StaticDtorSection. 12833dac3a9bSDimitry Andric } 1284