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 2355517e702SDimitry Andric const MDOperand &Op = MD->getOperand(0); 2365517e702SDimitry Andric if (!Op.get()) 2375517e702SDimitry Andric return nullptr; 2385517e702SDimitry Andric 2395517e702SDimitry Andric auto *VM = dyn_cast<ValueAsMetadata>(Op); 2407a7e6055SDimitry Andric if (!VM) 2417a7e6055SDimitry Andric report_fatal_error("MD_associated operand is not ValueAsMetadata"); 2427a7e6055SDimitry Andric 2437a7e6055SDimitry Andric GlobalObject *OtherGO = dyn_cast<GlobalObject>(VM->getValue()); 2447a7e6055SDimitry Andric return OtherGO ? dyn_cast<MCSymbolELF>(TM.getSymbol(OtherGO)) : nullptr; 2457a7e6055SDimitry Andric } 2467a7e6055SDimitry Andric 247ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( 248d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 249d88c1a5aSDimitry Andric StringRef SectionName = GO->getSection(); 250f22ef01cSRoman Divacky 251f22ef01cSRoman Divacky // Infer section flags from the section name if we can. 252f22ef01cSRoman Divacky Kind = getELFKindForNamedSection(SectionName, Kind); 253f22ef01cSRoman Divacky 25491bc56edSDimitry Andric StringRef Group = ""; 25591bc56edSDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 256d88c1a5aSDimitry Andric if (const Comdat *C = getELFComdat(GO)) { 25791bc56edSDimitry Andric Group = C->getName(); 25891bc56edSDimitry Andric Flags |= ELF::SHF_GROUP; 25991bc56edSDimitry Andric } 2607a7e6055SDimitry Andric 2617a7e6055SDimitry Andric // A section can have at most one associated section. Put each global with 2627a7e6055SDimitry Andric // MD_associated in a unique section. 2637a7e6055SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 2647a7e6055SDimitry Andric const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM); 2657a7e6055SDimitry Andric if (AssociatedSymbol) { 2667a7e6055SDimitry Andric UniqueID = NextUniqueID++; 2677a7e6055SDimitry Andric Flags |= ELF::SHF_LINK_ORDER; 2687a7e6055SDimitry Andric } 2697a7e6055SDimitry Andric 2707a7e6055SDimitry Andric MCSectionELF *Section = getContext().getELFSection( 2717a7e6055SDimitry Andric SectionName, getELFSectionType(SectionName, Kind), Flags, 2727a7e6055SDimitry Andric /*EntrySize=*/0, Group, UniqueID, AssociatedSymbol); 2737a7e6055SDimitry Andric // Make sure that we did not get some other section with incompatible sh_link. 2747a7e6055SDimitry Andric // This should not be possible due to UniqueID code above. 2757a7e6055SDimitry Andric assert(Section->getAssociatedSymbol() == AssociatedSymbol); 2767a7e6055SDimitry Andric return Section; 277f22ef01cSRoman Divacky } 278f22ef01cSRoman Divacky 279ff0cc061SDimitry Andric /// Return the section prefix name used by options FunctionsSections and 280ff0cc061SDimitry Andric /// DataSections. 28191bc56edSDimitry Andric static StringRef getSectionPrefixForGlobal(SectionKind Kind) { 282ff0cc061SDimitry Andric if (Kind.isText()) 283ff0cc061SDimitry Andric return ".text"; 284ff0cc061SDimitry Andric if (Kind.isReadOnly()) 285ff0cc061SDimitry Andric return ".rodata"; 286ff0cc061SDimitry Andric if (Kind.isBSS()) 287ff0cc061SDimitry Andric return ".bss"; 288ff0cc061SDimitry Andric if (Kind.isThreadData()) 289ff0cc061SDimitry Andric return ".tdata"; 290ff0cc061SDimitry Andric if (Kind.isThreadBSS()) 291ff0cc061SDimitry Andric return ".tbss"; 2927d523365SDimitry Andric if (Kind.isData()) 293ff0cc061SDimitry Andric return ".data"; 294f22ef01cSRoman Divacky assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); 295ff0cc061SDimitry Andric return ".data.rel.ro"; 296f22ef01cSRoman Divacky } 297f22ef01cSRoman Divacky 2987a7e6055SDimitry Andric static MCSectionELF *selectELFSectionForGlobal( 2997a7e6055SDimitry Andric MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang, 3007a7e6055SDimitry Andric const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags, 3017a7e6055SDimitry Andric unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) { 302ff0cc061SDimitry Andric unsigned EntrySize = 0; 303ff0cc061SDimitry Andric if (Kind.isMergeableCString()) { 304ff0cc061SDimitry Andric if (Kind.isMergeable2ByteCString()) { 305ff0cc061SDimitry Andric EntrySize = 2; 306ff0cc061SDimitry Andric } else if (Kind.isMergeable4ByteCString()) { 307ff0cc061SDimitry Andric EntrySize = 4; 308ff0cc061SDimitry Andric } else { 309ff0cc061SDimitry Andric EntrySize = 1; 310ff0cc061SDimitry Andric assert(Kind.isMergeable1ByteCString() && "unknown string width"); 311ff0cc061SDimitry Andric } 312ff0cc061SDimitry Andric } else if (Kind.isMergeableConst()) { 313ff0cc061SDimitry Andric if (Kind.isMergeableConst4()) { 314ff0cc061SDimitry Andric EntrySize = 4; 315ff0cc061SDimitry Andric } else if (Kind.isMergeableConst8()) { 316ff0cc061SDimitry Andric EntrySize = 8; 3173ca95b02SDimitry Andric } else if (Kind.isMergeableConst16()) { 318ff0cc061SDimitry Andric EntrySize = 16; 3193ca95b02SDimitry Andric } else { 3203ca95b02SDimitry Andric assert(Kind.isMergeableConst32() && "unknown data width"); 3213ca95b02SDimitry Andric EntrySize = 32; 322ff0cc061SDimitry Andric } 323ff0cc061SDimitry Andric } 32491bc56edSDimitry Andric 3252754fe60SDimitry Andric StringRef Group = ""; 326d88c1a5aSDimitry Andric if (const Comdat *C = getELFComdat(GO)) { 3272754fe60SDimitry Andric Flags |= ELF::SHF_GROUP; 328ff0cc061SDimitry Andric Group = C->getName(); 3292754fe60SDimitry Andric } 3302754fe60SDimitry Andric 331ff0cc061SDimitry Andric bool UniqueSectionNames = TM.getUniqueSectionNames(); 332ff0cc061SDimitry Andric SmallString<128> Name; 333ff0cc061SDimitry Andric if (Kind.isMergeableCString()) { 334f22ef01cSRoman Divacky // We also need alignment here. 335f22ef01cSRoman Divacky // FIXME: this is getting the alignment of the character, not the 336f22ef01cSRoman Divacky // alignment of the global! 337d88c1a5aSDimitry Andric unsigned Align = GO->getParent()->getDataLayout().getPreferredAlignment( 338d88c1a5aSDimitry Andric cast<GlobalVariable>(GO)); 339f22ef01cSRoman Divacky 340ff0cc061SDimitry Andric std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + "."; 341ff0cc061SDimitry Andric Name = SizeSpec + utostr(Align); 342ff0cc061SDimitry Andric } else if (Kind.isMergeableConst()) { 343ff0cc061SDimitry Andric Name = ".rodata.cst"; 344ff0cc061SDimitry Andric Name += utostr(EntrySize); 345ff0cc061SDimitry Andric } else { 346ff0cc061SDimitry Andric Name = getSectionPrefixForGlobal(Kind); 347ff0cc061SDimitry Andric } 348d88c1a5aSDimitry Andric 349d88c1a5aSDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) { 350d88c1a5aSDimitry Andric const auto &OptionalPrefix = F->getSectionPrefix(); 351d88c1a5aSDimitry Andric if (OptionalPrefix) 352d88c1a5aSDimitry Andric Name += *OptionalPrefix; 353d88c1a5aSDimitry Andric } 354ff0cc061SDimitry Andric 355ff0cc061SDimitry Andric if (EmitUniqueSection && UniqueSectionNames) { 356ff0cc061SDimitry Andric Name.push_back('.'); 357d88c1a5aSDimitry Andric TM.getNameWithPrefix(Name, GO, Mang, true); 358ff0cc061SDimitry Andric } 3593ca95b02SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 360ff0cc061SDimitry Andric if (EmitUniqueSection && !UniqueSectionNames) { 361ff0cc061SDimitry Andric UniqueID = *NextUniqueID; 362ff0cc061SDimitry Andric (*NextUniqueID)++; 363ff0cc061SDimitry Andric } 364d88c1a5aSDimitry Andric // Use 0 as the unique ID for execute-only text 365d88c1a5aSDimitry Andric if (Kind.isExecuteOnly()) 366d88c1a5aSDimitry Andric UniqueID = 0; 367ff0cc061SDimitry Andric return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags, 3687a7e6055SDimitry Andric EntrySize, Group, UniqueID, AssociatedSymbol); 369ff0cc061SDimitry Andric } 370ff0cc061SDimitry Andric 371ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( 372d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 373ff0cc061SDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 374ff0cc061SDimitry Andric 375ff0cc061SDimitry Andric // If we have -ffunction-section or -fdata-section then we should emit the 376ff0cc061SDimitry Andric // global value to a uniqued section specifically for it. 377ff0cc061SDimitry Andric bool EmitUniqueSection = false; 378ff0cc061SDimitry Andric if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) { 379ff0cc061SDimitry Andric if (Kind.isText()) 380ff0cc061SDimitry Andric EmitUniqueSection = TM.getFunctionSections(); 381f22ef01cSRoman Divacky else 382ff0cc061SDimitry Andric EmitUniqueSection = TM.getDataSections(); 383ff0cc061SDimitry Andric } 384d88c1a5aSDimitry Andric EmitUniqueSection |= GO->hasComdat(); 385f22ef01cSRoman Divacky 3867a7e6055SDimitry Andric const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM); 3877a7e6055SDimitry Andric if (AssociatedSymbol) { 3887a7e6055SDimitry Andric EmitUniqueSection = true; 3897a7e6055SDimitry Andric Flags |= ELF::SHF_LINK_ORDER; 3907a7e6055SDimitry Andric } 3917a7e6055SDimitry Andric 3927a7e6055SDimitry Andric MCSectionELF *Section = selectELFSectionForGlobal( 3937a7e6055SDimitry Andric getContext(), GO, Kind, getMangler(), TM, EmitUniqueSection, Flags, 3947a7e6055SDimitry Andric &NextUniqueID, AssociatedSymbol); 3957a7e6055SDimitry Andric assert(Section->getAssociatedSymbol() == AssociatedSymbol); 3967a7e6055SDimitry Andric return Section; 397f22ef01cSRoman Divacky } 398f22ef01cSRoman Divacky 399ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( 400d88c1a5aSDimitry Andric const Function &F, const TargetMachine &TM) const { 401ff0cc061SDimitry Andric // If the function can be removed, produce a unique section so that 402ff0cc061SDimitry Andric // the table doesn't prevent the removal. 403ff0cc061SDimitry Andric const Comdat *C = F.getComdat(); 404ff0cc061SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C; 405ff0cc061SDimitry Andric if (!EmitUniqueSection) 406ff0cc061SDimitry Andric return ReadOnlySection; 407ff0cc061SDimitry Andric 408ff0cc061SDimitry Andric return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(), 4097a7e6055SDimitry Andric getMangler(), TM, EmitUniqueSection, 4107a7e6055SDimitry Andric ELF::SHF_ALLOC, &NextUniqueID, 4117a7e6055SDimitry Andric /* AssociatedSymbol */ nullptr); 412f22ef01cSRoman Divacky } 413f22ef01cSRoman Divacky 414ff0cc061SDimitry Andric bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection( 415ff0cc061SDimitry Andric bool UsesLabelDifference, const Function &F) const { 416ff0cc061SDimitry Andric // We can always create relative relocations, so use another section 417ff0cc061SDimitry Andric // that can be marked non-executable. 418ff0cc061SDimitry Andric return false; 419f22ef01cSRoman Divacky } 420f22ef01cSRoman Divacky 421ff0cc061SDimitry Andric /// Given a mergeable constant with the specified size and relocation 422ff0cc061SDimitry Andric /// information, return a section that it should be placed in. 4237d523365SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForConstant( 4243ca95b02SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 4253ca95b02SDimitry Andric unsigned &Align) const { 426f22ef01cSRoman Divacky if (Kind.isMergeableConst4() && MergeableConst4Section) 427f22ef01cSRoman Divacky return MergeableConst4Section; 428f22ef01cSRoman Divacky if (Kind.isMergeableConst8() && MergeableConst8Section) 429f22ef01cSRoman Divacky return MergeableConst8Section; 430f22ef01cSRoman Divacky if (Kind.isMergeableConst16() && MergeableConst16Section) 431f22ef01cSRoman Divacky return MergeableConst16Section; 4323ca95b02SDimitry Andric if (Kind.isMergeableConst32() && MergeableConst32Section) 4333ca95b02SDimitry Andric return MergeableConst32Section; 434f22ef01cSRoman Divacky if (Kind.isReadOnly()) 435f22ef01cSRoman Divacky return ReadOnlySection; 436f22ef01cSRoman Divacky 437f22ef01cSRoman Divacky assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); 438f22ef01cSRoman Divacky return DataRelROSection; 439f22ef01cSRoman Divacky } 440f22ef01cSRoman Divacky 441ff0cc061SDimitry Andric static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray, 442ff0cc061SDimitry Andric bool IsCtor, unsigned Priority, 44339d628a0SDimitry Andric const MCSymbol *KeySym) { 44439d628a0SDimitry Andric std::string Name; 44539d628a0SDimitry Andric unsigned Type; 44639d628a0SDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE; 44739d628a0SDimitry Andric StringRef COMDAT = KeySym ? KeySym->getName() : ""; 44839d628a0SDimitry Andric 44939d628a0SDimitry Andric if (KeySym) 45039d628a0SDimitry Andric Flags |= ELF::SHF_GROUP; 451dff0c46cSDimitry Andric 4527ae0e2c9SDimitry Andric if (UseInitArray) { 45339d628a0SDimitry Andric if (IsCtor) { 45439d628a0SDimitry Andric Type = ELF::SHT_INIT_ARRAY; 45539d628a0SDimitry Andric Name = ".init_array"; 4567ae0e2c9SDimitry Andric } else { 45739d628a0SDimitry Andric Type = ELF::SHT_FINI_ARRAY; 45839d628a0SDimitry Andric Name = ".fini_array"; 459dff0c46cSDimitry Andric } 46039d628a0SDimitry Andric if (Priority != 65535) { 46139d628a0SDimitry Andric Name += '.'; 46239d628a0SDimitry Andric Name += utostr(Priority); 46339d628a0SDimitry Andric } 46439d628a0SDimitry Andric } else { 46539d628a0SDimitry Andric // The default scheme is .ctor / .dtor, so we have to invert the priority 46639d628a0SDimitry Andric // numbering. 46739d628a0SDimitry Andric if (IsCtor) 46839d628a0SDimitry Andric Name = ".ctors"; 46939d628a0SDimitry Andric else 47039d628a0SDimitry Andric Name = ".dtors"; 47139d628a0SDimitry Andric if (Priority != 65535) { 47239d628a0SDimitry Andric Name += '.'; 47339d628a0SDimitry Andric Name += utostr(65535 - Priority); 47439d628a0SDimitry Andric } 47539d628a0SDimitry Andric Type = ELF::SHT_PROGBITS; 47639d628a0SDimitry Andric } 47739d628a0SDimitry Andric 478ff0cc061SDimitry Andric return Ctx.getELFSection(Name, Type, Flags, 0, COMDAT); 47939d628a0SDimitry Andric } 48039d628a0SDimitry Andric 481ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticCtorSection( 48239d628a0SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 48339d628a0SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, true, Priority, 48439d628a0SDimitry Andric KeySym); 4857ae0e2c9SDimitry Andric } 486dff0c46cSDimitry Andric 487ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticDtorSection( 48891bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 48939d628a0SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, false, Priority, 49039d628a0SDimitry Andric KeySym); 4917ae0e2c9SDimitry Andric } 4927ae0e2c9SDimitry Andric 4933ca95b02SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference( 494d88c1a5aSDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 4953ca95b02SDimitry Andric const TargetMachine &TM) const { 4963ca95b02SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr 4973ca95b02SDimitry Andric // functions. 4983ca95b02SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) 4993ca95b02SDimitry Andric return nullptr; 5003ca95b02SDimitry Andric 5013ca95b02SDimitry Andric // Basic sanity checks. 5023ca95b02SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 5033ca95b02SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || 5043ca95b02SDimitry Andric RHS->isThreadLocal()) 5053ca95b02SDimitry Andric return nullptr; 5063ca95b02SDimitry Andric 5073ca95b02SDimitry Andric return MCBinaryExpr::createSub( 508d88c1a5aSDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS), PLTRelativeVariantKind, 5093ca95b02SDimitry Andric getContext()), 510d88c1a5aSDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); 5113ca95b02SDimitry Andric } 5123ca95b02SDimitry Andric 5137ae0e2c9SDimitry Andric void 5147ae0e2c9SDimitry Andric TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) { 5157ae0e2c9SDimitry Andric UseInitArray = UseInitArray_; 516d88c1a5aSDimitry Andric MCContext &Ctx = getContext(); 517d88c1a5aSDimitry Andric if (!UseInitArray) { 518d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getELFSection(".ctors", ELF::SHT_PROGBITS, 519d88c1a5aSDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE); 5207ae0e2c9SDimitry Andric 521d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getELFSection(".dtors", ELF::SHT_PROGBITS, 522d88c1a5aSDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE); 523d88c1a5aSDimitry Andric return; 524d88c1a5aSDimitry Andric } 525d88c1a5aSDimitry Andric 526d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getELFSection(".init_array", ELF::SHT_INIT_ARRAY, 527d88c1a5aSDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC); 528d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getELFSection(".fini_array", ELF::SHT_FINI_ARRAY, 529d88c1a5aSDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC); 5307ae0e2c9SDimitry Andric } 531dff0c46cSDimitry Andric 532f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 533f22ef01cSRoman Divacky // MachO 534f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 535f22ef01cSRoman Divacky 536ff0cc061SDimitry Andric TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO() 537ff0cc061SDimitry Andric : TargetLoweringObjectFile() { 538ff0cc061SDimitry Andric SupportIndirectSymViaGOTPCRel = true; 539ff0cc061SDimitry Andric } 540ff0cc061SDimitry Andric 541d88c1a5aSDimitry Andric void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx, 542d88c1a5aSDimitry Andric const TargetMachine &TM) { 543d88c1a5aSDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM); 544d88c1a5aSDimitry Andric if (TM.getRelocationModel() == Reloc::Static) { 545d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getMachOSection("__TEXT", "__constructor", 0, 546d88c1a5aSDimitry Andric SectionKind::getData()); 547d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getMachOSection("__TEXT", "__destructor", 0, 548d88c1a5aSDimitry Andric SectionKind::getData()); 549d88c1a5aSDimitry Andric } else { 550d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getMachOSection("__DATA", "__mod_init_func", 551d88c1a5aSDimitry Andric MachO::S_MOD_INIT_FUNC_POINTERS, 552d88c1a5aSDimitry Andric SectionKind::getData()); 553d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getMachOSection("__DATA", "__mod_term_func", 554d88c1a5aSDimitry Andric MachO::S_MOD_TERM_FUNC_POINTERS, 555d88c1a5aSDimitry Andric SectionKind::getData()); 556d88c1a5aSDimitry Andric } 557d88c1a5aSDimitry Andric } 558d88c1a5aSDimitry Andric 559139f7f9bSDimitry Andric /// emitModuleFlags - Perform code emission for module flags. 560d88c1a5aSDimitry Andric void TargetLoweringObjectFileMachO::emitModuleFlags( 561d88c1a5aSDimitry Andric MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, 562d88c1a5aSDimitry Andric const TargetMachine &TM) const { 563dff0c46cSDimitry Andric unsigned VersionVal = 0; 5647ae0e2c9SDimitry Andric unsigned ImageInfoFlags = 0; 56591bc56edSDimitry Andric MDNode *LinkerOptions = nullptr; 566dff0c46cSDimitry Andric StringRef SectionVal; 567dff0c46cSDimitry Andric 5683ca95b02SDimitry Andric for (const auto &MFE : ModuleFlags) { 569dff0c46cSDimitry Andric // Ignore flags with 'Require' behavior. 570dff0c46cSDimitry Andric if (MFE.Behavior == Module::Require) 571dff0c46cSDimitry Andric continue; 572dff0c46cSDimitry Andric 573dff0c46cSDimitry Andric StringRef Key = MFE.Key->getString(); 57439d628a0SDimitry Andric Metadata *Val = MFE.Val; 575dff0c46cSDimitry Andric 576139f7f9bSDimitry Andric if (Key == "Objective-C Image Info Version") { 57739d628a0SDimitry Andric VersionVal = mdconst::extract<ConstantInt>(Val)->getZExtValue(); 578139f7f9bSDimitry Andric } else if (Key == "Objective-C Garbage Collection" || 5797ae0e2c9SDimitry Andric Key == "Objective-C GC Only" || 58039d628a0SDimitry Andric Key == "Objective-C Is Simulated" || 5813ca95b02SDimitry Andric Key == "Objective-C Class Properties" || 58239d628a0SDimitry Andric Key == "Objective-C Image Swift Version") { 58339d628a0SDimitry Andric ImageInfoFlags |= mdconst::extract<ConstantInt>(Val)->getZExtValue(); 584139f7f9bSDimitry Andric } else if (Key == "Objective-C Image Info Section") { 585dff0c46cSDimitry Andric SectionVal = cast<MDString>(Val)->getString(); 586139f7f9bSDimitry Andric } else if (Key == "Linker Options") { 587139f7f9bSDimitry Andric LinkerOptions = cast<MDNode>(Val); 588139f7f9bSDimitry Andric } 589139f7f9bSDimitry Andric } 590139f7f9bSDimitry Andric 591139f7f9bSDimitry Andric // Emit the linker options if present. 592139f7f9bSDimitry Andric if (LinkerOptions) { 5933ca95b02SDimitry Andric for (const auto &Option : LinkerOptions->operands()) { 594139f7f9bSDimitry Andric SmallVector<std::string, 4> StrOptions; 5953ca95b02SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) 5963ca95b02SDimitry Andric StrOptions.push_back(cast<MDString>(Piece)->getString()); 597139f7f9bSDimitry Andric Streamer.EmitLinkerOptions(StrOptions); 598139f7f9bSDimitry Andric } 599dff0c46cSDimitry Andric } 600dff0c46cSDimitry Andric 601dff0c46cSDimitry Andric // The section is mandatory. If we don't have it, then we don't have GC info. 602dff0c46cSDimitry Andric if (SectionVal.empty()) return; 603dff0c46cSDimitry Andric 604dff0c46cSDimitry Andric StringRef Segment, Section; 605dff0c46cSDimitry Andric unsigned TAA = 0, StubSize = 0; 606dff0c46cSDimitry Andric bool TAAParsed; 607dff0c46cSDimitry Andric std::string ErrorCode = 608dff0c46cSDimitry Andric MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section, 609dff0c46cSDimitry Andric TAA, TAAParsed, StubSize); 610dff0c46cSDimitry Andric if (!ErrorCode.empty()) 611dff0c46cSDimitry Andric // If invalid, report the error with report_fatal_error. 612dff0c46cSDimitry Andric report_fatal_error("Invalid section specifier '" + Section + "': " + 613dff0c46cSDimitry Andric ErrorCode + "."); 614dff0c46cSDimitry Andric 615dff0c46cSDimitry Andric // Get the section. 616ff0cc061SDimitry Andric MCSectionMachO *S = getContext().getMachOSection( 6177d523365SDimitry Andric Segment, Section, TAA, StubSize, SectionKind::getData()); 618dff0c46cSDimitry Andric Streamer.SwitchSection(S); 619dff0c46cSDimitry Andric Streamer.EmitLabel(getContext(). 620ff0cc061SDimitry Andric getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); 621dff0c46cSDimitry Andric Streamer.EmitIntValue(VersionVal, 4); 6227ae0e2c9SDimitry Andric Streamer.EmitIntValue(ImageInfoFlags, 4); 623dff0c46cSDimitry Andric Streamer.AddBlankLine(); 624dff0c46cSDimitry Andric } 625dff0c46cSDimitry Andric 62691bc56edSDimitry Andric static void checkMachOComdat(const GlobalValue *GV) { 62791bc56edSDimitry Andric const Comdat *C = GV->getComdat(); 62891bc56edSDimitry Andric if (!C) 62991bc56edSDimitry Andric return; 63091bc56edSDimitry Andric 63191bc56edSDimitry Andric report_fatal_error("MachO doesn't support COMDATs, '" + C->getName() + 63291bc56edSDimitry Andric "' cannot be lowered."); 63391bc56edSDimitry Andric } 63491bc56edSDimitry Andric 635ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( 636d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 637f22ef01cSRoman Divacky // Parse the section specifier and create it if valid. 638f22ef01cSRoman Divacky StringRef Segment, Section; 6393b0f4066SDimitry Andric unsigned TAA = 0, StubSize = 0; 6403b0f4066SDimitry Andric bool TAAParsed; 64191bc56edSDimitry Andric 642d88c1a5aSDimitry Andric checkMachOComdat(GO); 64391bc56edSDimitry Andric 644f22ef01cSRoman Divacky std::string ErrorCode = 645d88c1a5aSDimitry Andric MCSectionMachO::ParseSectionSpecifier(GO->getSection(), Segment, Section, 6463b0f4066SDimitry Andric TAA, TAAParsed, StubSize); 647f22ef01cSRoman Divacky if (!ErrorCode.empty()) { 648f22ef01cSRoman Divacky // If invalid, report the error with report_fatal_error. 649d88c1a5aSDimitry Andric report_fatal_error("Global variable '" + GO->getName() + 650dff0c46cSDimitry Andric "' has an invalid section specifier '" + 651d88c1a5aSDimitry Andric GO->getSection() + "': " + ErrorCode + "."); 652f22ef01cSRoman Divacky } 653f22ef01cSRoman Divacky 654f22ef01cSRoman Divacky // Get the section. 655ff0cc061SDimitry Andric MCSectionMachO *S = 656f22ef01cSRoman Divacky getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind); 657f22ef01cSRoman Divacky 658dd6029ffSDimitry Andric // If TAA wasn't set by ParseSectionSpecifier() above, 659dd6029ffSDimitry Andric // use the value returned by getMachOSection() as a default. 6603b0f4066SDimitry Andric if (!TAAParsed) 661dd6029ffSDimitry Andric TAA = S->getTypeAndAttributes(); 662dd6029ffSDimitry Andric 663f22ef01cSRoman Divacky // Okay, now that we got the section, verify that the TAA & StubSize agree. 664f22ef01cSRoman Divacky // If the user declared multiple globals with different section flags, we need 665f22ef01cSRoman Divacky // to reject it here. 666f22ef01cSRoman Divacky if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) { 667f22ef01cSRoman Divacky // If invalid, report the error with report_fatal_error. 668d88c1a5aSDimitry Andric report_fatal_error("Global variable '" + GO->getName() + 669f22ef01cSRoman Divacky "' section type or attributes does not match previous" 670f22ef01cSRoman Divacky " section specifier"); 671f22ef01cSRoman Divacky } 672f22ef01cSRoman Divacky 673f22ef01cSRoman Divacky return S; 674f22ef01cSRoman Divacky } 675f22ef01cSRoman Divacky 676ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal( 677d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 678d88c1a5aSDimitry Andric checkMachOComdat(GO); 679f785676fSDimitry Andric 680f785676fSDimitry Andric // Handle thread local data. 681f785676fSDimitry Andric if (Kind.isThreadBSS()) return TLSBSSSection; 682f785676fSDimitry Andric if (Kind.isThreadData()) return TLSDataSection; 683f785676fSDimitry Andric 684f22ef01cSRoman Divacky if (Kind.isText()) 685d88c1a5aSDimitry Andric return GO->isWeakForLinker() ? TextCoalSection : TextSection; 686f22ef01cSRoman Divacky 687f22ef01cSRoman Divacky // If this is weak/linkonce, put this in a coalescable section, either in text 688f22ef01cSRoman Divacky // or data depending on if it is writable. 689d88c1a5aSDimitry Andric if (GO->isWeakForLinker()) { 690f22ef01cSRoman Divacky if (Kind.isReadOnly()) 691f22ef01cSRoman Divacky return ConstTextCoalSection; 692f22ef01cSRoman Divacky return DataCoalSection; 693f22ef01cSRoman Divacky } 694f22ef01cSRoman Divacky 695f22ef01cSRoman Divacky // FIXME: Alignment check should be handled by section classifier. 696f22ef01cSRoman Divacky if (Kind.isMergeable1ByteCString() && 697d88c1a5aSDimitry Andric GO->getParent()->getDataLayout().getPreferredAlignment( 698d88c1a5aSDimitry Andric cast<GlobalVariable>(GO)) < 32) 699f22ef01cSRoman Divacky return CStringSection; 700f22ef01cSRoman Divacky 701f22ef01cSRoman Divacky // Do not put 16-bit arrays in the UString section if they have an 702f22ef01cSRoman Divacky // externally visible label, this runs into issues with certain linker 703f22ef01cSRoman Divacky // versions. 704d88c1a5aSDimitry Andric if (Kind.isMergeable2ByteCString() && !GO->hasExternalLinkage() && 705d88c1a5aSDimitry Andric GO->getParent()->getDataLayout().getPreferredAlignment( 706d88c1a5aSDimitry Andric cast<GlobalVariable>(GO)) < 32) 707f22ef01cSRoman Divacky return UStringSection; 708f22ef01cSRoman Divacky 70939d628a0SDimitry Andric // With MachO only variables whose corresponding symbol starts with 'l' or 71039d628a0SDimitry Andric // 'L' can be merged, so we only try merging GVs with private linkage. 711d88c1a5aSDimitry Andric if (GO->hasPrivateLinkage() && Kind.isMergeableConst()) { 712f22ef01cSRoman Divacky if (Kind.isMergeableConst4()) 713f22ef01cSRoman Divacky return FourByteConstantSection; 714f22ef01cSRoman Divacky if (Kind.isMergeableConst8()) 715f22ef01cSRoman Divacky return EightByteConstantSection; 71691bc56edSDimitry Andric if (Kind.isMergeableConst16()) 717f22ef01cSRoman Divacky return SixteenByteConstantSection; 718f22ef01cSRoman Divacky } 719f22ef01cSRoman Divacky 720f22ef01cSRoman Divacky // Otherwise, if it is readonly, but not something we can specially optimize, 721f22ef01cSRoman Divacky // just drop it in .const. 722f22ef01cSRoman Divacky if (Kind.isReadOnly()) 723f22ef01cSRoman Divacky return ReadOnlySection; 724f22ef01cSRoman Divacky 725f22ef01cSRoman Divacky // If this is marked const, put it into a const section. But if the dynamic 726f22ef01cSRoman Divacky // linker needs to write to it, put it in the data segment. 727f22ef01cSRoman Divacky if (Kind.isReadOnlyWithRel()) 728f22ef01cSRoman Divacky return ConstDataSection; 729f22ef01cSRoman Divacky 730f22ef01cSRoman Divacky // Put zero initialized globals with strong external linkage in the 731f22ef01cSRoman Divacky // DATA, __common section with the .zerofill directive. 732f22ef01cSRoman Divacky if (Kind.isBSSExtern()) 733f22ef01cSRoman Divacky return DataCommonSection; 734f22ef01cSRoman Divacky 735f22ef01cSRoman Divacky // Put zero initialized globals with local linkage in __DATA,__bss directive 736f22ef01cSRoman Divacky // with the .zerofill directive (aka .lcomm). 737f22ef01cSRoman Divacky if (Kind.isBSSLocal()) 738f22ef01cSRoman Divacky return DataBSSSection; 739f22ef01cSRoman Divacky 740f22ef01cSRoman Divacky // Otherwise, just drop the variable in the normal data section. 741f22ef01cSRoman Divacky return DataSection; 742f22ef01cSRoman Divacky } 743f22ef01cSRoman Divacky 7447d523365SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getSectionForConstant( 7453ca95b02SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 7463ca95b02SDimitry Andric unsigned &Align) const { 747f22ef01cSRoman Divacky // If this constant requires a relocation, we have to put it in the data 748f22ef01cSRoman Divacky // segment, not in the text segment. 7497d523365SDimitry Andric if (Kind.isData() || Kind.isReadOnlyWithRel()) 750f22ef01cSRoman Divacky return ConstDataSection; 751f22ef01cSRoman Divacky 752f22ef01cSRoman Divacky if (Kind.isMergeableConst4()) 753f22ef01cSRoman Divacky return FourByteConstantSection; 754f22ef01cSRoman Divacky if (Kind.isMergeableConst8()) 755f22ef01cSRoman Divacky return EightByteConstantSection; 75691bc56edSDimitry Andric if (Kind.isMergeableConst16()) 757f22ef01cSRoman Divacky return SixteenByteConstantSection; 758f22ef01cSRoman Divacky return ReadOnlySection; // .const 759f22ef01cSRoman Divacky } 760f22ef01cSRoman Divacky 76191bc56edSDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference( 762d88c1a5aSDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, 763d88c1a5aSDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 764f22ef01cSRoman Divacky // The mach-o version of this method defaults to returning a stub reference. 765f22ef01cSRoman Divacky 766f22ef01cSRoman Divacky if (Encoding & DW_EH_PE_indirect) { 767f22ef01cSRoman Divacky MachineModuleInfoMachO &MachOMMI = 768f22ef01cSRoman Divacky MMI->getObjFileInfo<MachineModuleInfoMachO>(); 769f22ef01cSRoman Divacky 770d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); 771f22ef01cSRoman Divacky 772f22ef01cSRoman Divacky // Add information about the stub reference to MachOMMI so that the stub 773f22ef01cSRoman Divacky // gets emitted by the asmprinter. 7743ca95b02SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 77591bc56edSDimitry Andric if (!StubSym.getPointer()) { 776d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 777f22ef01cSRoman Divacky StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 778f22ef01cSRoman Divacky } 779f22ef01cSRoman Divacky 780f22ef01cSRoman Divacky return TargetLoweringObjectFile:: 78197bc6c73SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), 7827a7e6055SDimitry Andric Encoding & ~DW_EH_PE_indirect, Streamer); 783f22ef01cSRoman Divacky } 784f22ef01cSRoman Divacky 785d88c1a5aSDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM, 786d88c1a5aSDimitry Andric MMI, Streamer); 787f22ef01cSRoman Divacky } 788f22ef01cSRoman Divacky 78991bc56edSDimitry Andric MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol( 790d88c1a5aSDimitry Andric const GlobalValue *GV, const TargetMachine &TM, 7913b0f4066SDimitry Andric MachineModuleInfo *MMI) const { 7923b0f4066SDimitry Andric // The mach-o version of this method defaults to returning a stub reference. 7933b0f4066SDimitry Andric MachineModuleInfoMachO &MachOMMI = 7943b0f4066SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 7953b0f4066SDimitry Andric 796d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); 7973b0f4066SDimitry Andric 7983b0f4066SDimitry Andric // Add information about the stub reference to MachOMMI so that the stub 7993b0f4066SDimitry Andric // gets emitted by the asmprinter. 800dff0c46cSDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 80191bc56edSDimitry Andric if (!StubSym.getPointer()) { 802d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 8033b0f4066SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 8043b0f4066SDimitry Andric } 8053b0f4066SDimitry Andric 8063b0f4066SDimitry Andric return SSym; 8073b0f4066SDimitry Andric } 8083b0f4066SDimitry Andric 809ff0cc061SDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel( 810ff0cc061SDimitry Andric const MCSymbol *Sym, const MCValue &MV, int64_t Offset, 811ff0cc061SDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 8127d523365SDimitry Andric // Although MachO 32-bit targets do not explicitly have a GOTPCREL relocation 813ff0cc061SDimitry Andric // as 64-bit do, we replace the GOT equivalent by accessing the final symbol 814ff0cc061SDimitry Andric // through a non_lazy_ptr stub instead. One advantage is that it allows the 815ff0cc061SDimitry Andric // computation of deltas to final external symbols. Example: 816ff0cc061SDimitry Andric // 817ff0cc061SDimitry Andric // _extgotequiv: 818ff0cc061SDimitry Andric // .long _extfoo 819ff0cc061SDimitry Andric // 820ff0cc061SDimitry Andric // _delta: 821ff0cc061SDimitry Andric // .long _extgotequiv-_delta 822ff0cc061SDimitry Andric // 823ff0cc061SDimitry Andric // is transformed to: 824ff0cc061SDimitry Andric // 825ff0cc061SDimitry Andric // _delta: 826ff0cc061SDimitry Andric // .long L_extfoo$non_lazy_ptr-(_delta+0) 827ff0cc061SDimitry Andric // 828ff0cc061SDimitry Andric // .section __IMPORT,__pointers,non_lazy_symbol_pointers 829ff0cc061SDimitry Andric // L_extfoo$non_lazy_ptr: 830ff0cc061SDimitry Andric // .indirect_symbol _extfoo 831ff0cc061SDimitry Andric // .long 0 832ff0cc061SDimitry Andric // 833ff0cc061SDimitry Andric MachineModuleInfoMachO &MachOMMI = 834ff0cc061SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 835ff0cc061SDimitry Andric MCContext &Ctx = getContext(); 836ff0cc061SDimitry Andric 837ff0cc061SDimitry Andric // The offset must consider the original displacement from the base symbol 838ff0cc061SDimitry Andric // since 32-bit targets don't have a GOTPCREL to fold the PC displacement. 839ff0cc061SDimitry Andric Offset = -MV.getConstant(); 840ff0cc061SDimitry Andric const MCSymbol *BaseSym = &MV.getSymB()->getSymbol(); 841ff0cc061SDimitry Andric 842ff0cc061SDimitry Andric // Access the final symbol via sym$non_lazy_ptr and generate the appropriated 843ff0cc061SDimitry Andric // non_lazy_ptr stubs. 844ff0cc061SDimitry Andric SmallString<128> Name; 845ff0cc061SDimitry Andric StringRef Suffix = "$non_lazy_ptr"; 8467d523365SDimitry Andric Name += MMI->getModule()->getDataLayout().getPrivateGlobalPrefix(); 847ff0cc061SDimitry Andric Name += Sym->getName(); 848ff0cc061SDimitry Andric Name += Suffix; 849ff0cc061SDimitry Andric MCSymbol *Stub = Ctx.getOrCreateSymbol(Name); 850ff0cc061SDimitry Andric 851ff0cc061SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub); 852ff0cc061SDimitry Andric if (!StubSym.getPointer()) 853ff0cc061SDimitry Andric StubSym = MachineModuleInfoImpl:: 854ff0cc061SDimitry Andric StubValueTy(const_cast<MCSymbol *>(Sym), true /* access indirectly */); 855ff0cc061SDimitry Andric 856ff0cc061SDimitry Andric const MCExpr *BSymExpr = 85797bc6c73SDimitry Andric MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx); 858ff0cc061SDimitry Andric const MCExpr *LHS = 85997bc6c73SDimitry Andric MCSymbolRefExpr::create(Stub, MCSymbolRefExpr::VK_None, Ctx); 860ff0cc061SDimitry Andric 861ff0cc061SDimitry Andric if (!Offset) 86297bc6c73SDimitry Andric return MCBinaryExpr::createSub(LHS, BSymExpr, Ctx); 863ff0cc061SDimitry Andric 864ff0cc061SDimitry Andric const MCExpr *RHS = 86597bc6c73SDimitry Andric MCBinaryExpr::createAdd(BSymExpr, MCConstantExpr::create(Offset, Ctx), Ctx); 86697bc6c73SDimitry Andric return MCBinaryExpr::createSub(LHS, RHS, Ctx); 867ff0cc061SDimitry Andric } 868ff0cc061SDimitry Andric 8697d523365SDimitry Andric static bool canUsePrivateLabel(const MCAsmInfo &AsmInfo, 8707d523365SDimitry Andric const MCSection &Section) { 8717d523365SDimitry Andric if (!AsmInfo.isSectionAtomizableBySymbols(Section)) 8727d523365SDimitry Andric return true; 8737d523365SDimitry Andric 8747d523365SDimitry Andric // If it is not dead stripped, it is safe to use private labels. 8757d523365SDimitry Andric const MCSectionMachO &SMO = cast<MCSectionMachO>(Section); 8767d523365SDimitry Andric if (SMO.hasAttribute(MachO::S_ATTR_NO_DEAD_STRIP)) 8777d523365SDimitry Andric return true; 8787d523365SDimitry Andric 8797d523365SDimitry Andric return false; 8807d523365SDimitry Andric } 8817d523365SDimitry Andric 8827d523365SDimitry Andric void TargetLoweringObjectFileMachO::getNameWithPrefix( 883d88c1a5aSDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, 8847d523365SDimitry Andric const TargetMachine &TM) const { 885d88c1a5aSDimitry Andric bool CannotUsePrivateLabel = true; 886d88c1a5aSDimitry Andric if (auto *GO = GV->getBaseObject()) { 887d88c1a5aSDimitry Andric SectionKind GOKind = TargetLoweringObjectFile::getKindForGlobal(GO, TM); 888d88c1a5aSDimitry Andric const MCSection *TheSection = SectionForGlobal(GO, GOKind, TM); 889d88c1a5aSDimitry Andric CannotUsePrivateLabel = 8907d523365SDimitry Andric !canUsePrivateLabel(*TM.getMCAsmInfo(), *TheSection); 891d88c1a5aSDimitry Andric } 892d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 8937d523365SDimitry Andric } 8947d523365SDimitry Andric 895f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 896f22ef01cSRoman Divacky // COFF 897f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 898f22ef01cSRoman Divacky 899f22ef01cSRoman Divacky static unsigned 9003ca95b02SDimitry Andric getCOFFSectionFlags(SectionKind K, const TargetMachine &TM) { 901f22ef01cSRoman Divacky unsigned Flags = 0; 9023ca95b02SDimitry Andric bool isThumb = TM.getTargetTriple().getArch() == Triple::thumb; 903f22ef01cSRoman Divacky 904ffd1746dSEd Schouten if (K.isMetadata()) 905f22ef01cSRoman Divacky Flags |= 906ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_DISCARDABLE; 907f22ef01cSRoman Divacky else if (K.isText()) 908f22ef01cSRoman Divacky Flags |= 909ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_EXECUTE | 9102754fe60SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 9113ca95b02SDimitry Andric COFF::IMAGE_SCN_CNT_CODE | 9123ca95b02SDimitry Andric (isThumb ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0); 913f22ef01cSRoman Divacky else if (K.isBSS()) 914f22ef01cSRoman Divacky Flags |= 915ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | 916ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ | 917ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_WRITE; 918dff0c46cSDimitry Andric else if (K.isThreadLocal()) 919dff0c46cSDimitry Andric Flags |= 920dff0c46cSDimitry Andric COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 921dff0c46cSDimitry Andric COFF::IMAGE_SCN_MEM_READ | 922dff0c46cSDimitry Andric COFF::IMAGE_SCN_MEM_WRITE; 92339d628a0SDimitry Andric else if (K.isReadOnly() || K.isReadOnlyWithRel()) 924f22ef01cSRoman Divacky Flags |= 925ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 926ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ; 927f22ef01cSRoman Divacky else if (K.isWriteable()) 928f22ef01cSRoman Divacky Flags |= 929ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 930ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ | 931ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_WRITE; 932f22ef01cSRoman Divacky 933f22ef01cSRoman Divacky return Flags; 934f22ef01cSRoman Divacky } 935f22ef01cSRoman Divacky 93691bc56edSDimitry Andric static const GlobalValue *getComdatGVForCOFF(const GlobalValue *GV) { 93791bc56edSDimitry Andric const Comdat *C = GV->getComdat(); 93891bc56edSDimitry Andric assert(C && "expected GV to have a Comdat!"); 93991bc56edSDimitry Andric 94091bc56edSDimitry Andric StringRef ComdatGVName = C->getName(); 94191bc56edSDimitry Andric const GlobalValue *ComdatGV = GV->getParent()->getNamedValue(ComdatGVName); 94291bc56edSDimitry Andric if (!ComdatGV) 94391bc56edSDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 94491bc56edSDimitry Andric "' does not exist."); 94591bc56edSDimitry Andric 94691bc56edSDimitry Andric if (ComdatGV->getComdat() != C) 94791bc56edSDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 94839d628a0SDimitry Andric "' is not a key for its COMDAT."); 94991bc56edSDimitry Andric 95091bc56edSDimitry Andric return ComdatGV; 95191bc56edSDimitry Andric } 95291bc56edSDimitry Andric 95391bc56edSDimitry Andric static int getSelectionForCOFF(const GlobalValue *GV) { 95491bc56edSDimitry Andric if (const Comdat *C = GV->getComdat()) { 95591bc56edSDimitry Andric const GlobalValue *ComdatKey = getComdatGVForCOFF(GV); 95691bc56edSDimitry Andric if (const auto *GA = dyn_cast<GlobalAlias>(ComdatKey)) 95791bc56edSDimitry Andric ComdatKey = GA->getBaseObject(); 95891bc56edSDimitry Andric if (ComdatKey == GV) { 95991bc56edSDimitry Andric switch (C->getSelectionKind()) { 96091bc56edSDimitry Andric case Comdat::Any: 96191bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ANY; 96291bc56edSDimitry Andric case Comdat::ExactMatch: 96391bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH; 96491bc56edSDimitry Andric case Comdat::Largest: 96591bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_LARGEST; 96691bc56edSDimitry Andric case Comdat::NoDuplicates: 96791bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 96891bc56edSDimitry Andric case Comdat::SameSize: 96991bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_SAME_SIZE; 97091bc56edSDimitry Andric } 97191bc56edSDimitry Andric } else { 97291bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE; 97391bc56edSDimitry Andric } 97491bc56edSDimitry Andric } 97591bc56edSDimitry Andric return 0; 97691bc56edSDimitry Andric } 97791bc56edSDimitry Andric 978ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal( 979d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 980139f7f9bSDimitry Andric int Selection = 0; 9813ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 982d88c1a5aSDimitry Andric StringRef Name = GO->getSection(); 98391bc56edSDimitry Andric StringRef COMDATSymName = ""; 984d88c1a5aSDimitry Andric if (GO->hasComdat()) { 985d88c1a5aSDimitry Andric Selection = getSelectionForCOFF(GO); 98691bc56edSDimitry Andric const GlobalValue *ComdatGV; 98791bc56edSDimitry Andric if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) 988d88c1a5aSDimitry Andric ComdatGV = getComdatGVForCOFF(GO); 98991bc56edSDimitry Andric else 990d88c1a5aSDimitry Andric ComdatGV = GO; 99191bc56edSDimitry Andric 99291bc56edSDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 993d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV); 99491bc56edSDimitry Andric COMDATSymName = Sym->getName(); 995139f7f9bSDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 99691bc56edSDimitry Andric } else { 99791bc56edSDimitry Andric Selection = 0; 99891bc56edSDimitry Andric } 999139f7f9bSDimitry Andric } 10003ca95b02SDimitry Andric 10013ca95b02SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, 1002f785676fSDimitry Andric Selection); 1003f22ef01cSRoman Divacky } 1004f22ef01cSRoman Divacky 100591bc56edSDimitry Andric static const char *getCOFFSectionNameForUniqueGlobal(SectionKind Kind) { 1006f22ef01cSRoman Divacky if (Kind.isText()) 100791bc56edSDimitry Andric return ".text"; 1008f22ef01cSRoman Divacky if (Kind.isBSS()) 100991bc56edSDimitry Andric return ".bss"; 101091bc56edSDimitry Andric if (Kind.isThreadLocal()) 101191bc56edSDimitry Andric return ".tls$"; 101239d628a0SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 101391bc56edSDimitry Andric return ".rdata"; 101439d628a0SDimitry Andric return ".data"; 1015f22ef01cSRoman Divacky } 1016f22ef01cSRoman Divacky 1017ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal( 1018d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 101991bc56edSDimitry Andric // If we have -ffunction-sections then we should emit the global value to a 102091bc56edSDimitry Andric // uniqued section specifically for it. 102191bc56edSDimitry Andric bool EmitUniquedSection; 102291bc56edSDimitry Andric if (Kind.isText()) 102391bc56edSDimitry Andric EmitUniquedSection = TM.getFunctionSections(); 102491bc56edSDimitry Andric else 102591bc56edSDimitry Andric EmitUniquedSection = TM.getDataSections(); 1026f22ef01cSRoman Divacky 1027d88c1a5aSDimitry Andric if ((EmitUniquedSection && !Kind.isCommon()) || GO->hasComdat()) { 102891bc56edSDimitry Andric const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); 10293ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 1030f22ef01cSRoman Divacky 1031ffd1746dSEd Schouten Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 1032d88c1a5aSDimitry Andric int Selection = getSelectionForCOFF(GO); 103391bc56edSDimitry Andric if (!Selection) 103491bc56edSDimitry Andric Selection = COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 103591bc56edSDimitry Andric const GlobalValue *ComdatGV; 1036d88c1a5aSDimitry Andric if (GO->hasComdat()) 1037d88c1a5aSDimitry Andric ComdatGV = getComdatGVForCOFF(GO); 103891bc56edSDimitry Andric else 1039d88c1a5aSDimitry Andric ComdatGV = GO; 1040f22ef01cSRoman Divacky 10413ca95b02SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 10423ca95b02SDimitry Andric if (EmitUniquedSection) 10433ca95b02SDimitry Andric UniqueID = NextUniqueID++; 10443ca95b02SDimitry Andric 104591bc56edSDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 1046d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV); 104791bc56edSDimitry Andric StringRef COMDATSymName = Sym->getName(); 104891bc56edSDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, 10493ca95b02SDimitry Andric COMDATSymName, Selection, UniqueID); 1050ff0cc061SDimitry Andric } else { 1051ff0cc061SDimitry Andric SmallString<256> TmpData; 1052d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(TmpData, GO, /*CannotUsePrivateLabel=*/true); 1053ff0cc061SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, TmpData, 10543ca95b02SDimitry Andric Selection, UniqueID); 105591bc56edSDimitry Andric } 1056f22ef01cSRoman Divacky } 1057f22ef01cSRoman Divacky 1058f22ef01cSRoman Divacky if (Kind.isText()) 1059f785676fSDimitry Andric return TextSection; 1060f22ef01cSRoman Divacky 1061dff0c46cSDimitry Andric if (Kind.isThreadLocal()) 1062f785676fSDimitry Andric return TLSDataSection; 1063dff0c46cSDimitry Andric 106439d628a0SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 1065f785676fSDimitry Andric return ReadOnlySection; 1066f785676fSDimitry Andric 106791bc56edSDimitry Andric // Note: we claim that common symbols are put in BSSSection, but they are 106891bc56edSDimitry Andric // really emitted with the magic .comm directive, which creates a symbol table 106991bc56edSDimitry Andric // entry but not a section. 107091bc56edSDimitry Andric if (Kind.isBSS() || Kind.isCommon()) 1071f785676fSDimitry Andric return BSSSection; 1072f785676fSDimitry Andric 1073f785676fSDimitry Andric return DataSection; 1074f22ef01cSRoman Divacky } 1075f22ef01cSRoman Divacky 1076ff0cc061SDimitry Andric void TargetLoweringObjectFileCOFF::getNameWithPrefix( 1077d88c1a5aSDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, 10787d523365SDimitry Andric const TargetMachine &TM) const { 10797d523365SDimitry Andric bool CannotUsePrivateLabel = false; 1080ff0cc061SDimitry Andric if (GV->hasPrivateLinkage() && 1081ff0cc061SDimitry Andric ((isa<Function>(GV) && TM.getFunctionSections()) || 1082ff0cc061SDimitry Andric (isa<GlobalVariable>(GV) && TM.getDataSections()))) 1083ff0cc061SDimitry Andric CannotUsePrivateLabel = true; 1084ff0cc061SDimitry Andric 1085d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 1086ff0cc061SDimitry Andric } 1087ff0cc061SDimitry Andric 1088ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable( 1089d88c1a5aSDimitry Andric const Function &F, const TargetMachine &TM) const { 1090ff0cc061SDimitry Andric // If the function can be removed, produce a unique section so that 1091ff0cc061SDimitry Andric // the table doesn't prevent the removal. 1092ff0cc061SDimitry Andric const Comdat *C = F.getComdat(); 1093ff0cc061SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C; 1094ff0cc061SDimitry Andric if (!EmitUniqueSection) 1095ff0cc061SDimitry Andric return ReadOnlySection; 1096ff0cc061SDimitry Andric 1097ff0cc061SDimitry Andric // FIXME: we should produce a symbol for F instead. 1098ff0cc061SDimitry Andric if (F.hasPrivateLinkage()) 1099ff0cc061SDimitry Andric return ReadOnlySection; 1100ff0cc061SDimitry Andric 1101d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(&F); 1102ff0cc061SDimitry Andric StringRef COMDATSymName = Sym->getName(); 1103ff0cc061SDimitry Andric 1104ff0cc061SDimitry Andric SectionKind Kind = SectionKind::getReadOnly(); 1105ff0cc061SDimitry Andric const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); 11063ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 1107ff0cc061SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 11083ca95b02SDimitry Andric unsigned UniqueID = NextUniqueID++; 1109ff0cc061SDimitry Andric 1110ff0cc061SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, 11113ca95b02SDimitry Andric COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); 1112ff0cc061SDimitry Andric } 1113ff0cc061SDimitry Andric 1114d88c1a5aSDimitry Andric void TargetLoweringObjectFileCOFF::emitModuleFlags( 1115d88c1a5aSDimitry Andric MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, 1116d88c1a5aSDimitry Andric const TargetMachine &TM) const { 111791bc56edSDimitry Andric MDNode *LinkerOptions = nullptr; 1118284c1978SDimitry Andric 11193ca95b02SDimitry Andric for (const auto &MFE : ModuleFlags) { 1120284c1978SDimitry Andric StringRef Key = MFE.Key->getString(); 11213ca95b02SDimitry Andric if (Key == "Linker Options") 11223ca95b02SDimitry Andric LinkerOptions = cast<MDNode>(MFE.Val); 1123284c1978SDimitry Andric } 1124284c1978SDimitry Andric 11253ca95b02SDimitry Andric if (LinkerOptions) { 1126284c1978SDimitry Andric // Emit the linker options to the linker .drectve section. According to the 11273ca95b02SDimitry Andric // spec, this section is a space-separated string containing flags for 11283ca95b02SDimitry Andric // linker. 1129ff0cc061SDimitry Andric MCSection *Sec = getDrectveSection(); 1130284c1978SDimitry Andric Streamer.SwitchSection(Sec); 11313ca95b02SDimitry Andric for (const auto &Option : LinkerOptions->operands()) { 11323ca95b02SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) { 1133284c1978SDimitry Andric // Lead with a space for consistency with our dllexport implementation. 1134ff0cc061SDimitry Andric std::string Directive(" "); 11353ca95b02SDimitry Andric Directive.append(cast<MDString>(Piece)->getString()); 1136ff0cc061SDimitry Andric Streamer.EmitBytes(Directive); 1137284c1978SDimitry Andric } 1138284c1978SDimitry Andric } 1139284c1978SDimitry Andric } 11403ca95b02SDimitry Andric } 114191bc56edSDimitry Andric 1142d88c1a5aSDimitry Andric void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx, 1143d88c1a5aSDimitry Andric const TargetMachine &TM) { 1144d88c1a5aSDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM); 1145d88c1a5aSDimitry Andric const Triple &T = TM.getTargetTriple(); 1146d88c1a5aSDimitry Andric if (T.isKnownWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) { 1147d88c1a5aSDimitry Andric StaticCtorSection = 1148d88c1a5aSDimitry Andric Ctx.getCOFFSection(".CRT$XCU", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1149d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ, 1150d88c1a5aSDimitry Andric SectionKind::getReadOnly()); 1151d88c1a5aSDimitry Andric StaticDtorSection = 1152d88c1a5aSDimitry Andric Ctx.getCOFFSection(".CRT$XTX", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1153d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ, 1154d88c1a5aSDimitry Andric SectionKind::getReadOnly()); 1155d88c1a5aSDimitry Andric } else { 1156d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getCOFFSection( 1157d88c1a5aSDimitry Andric ".ctors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1158d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, 1159d88c1a5aSDimitry Andric SectionKind::getData()); 1160d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getCOFFSection( 1161d88c1a5aSDimitry Andric ".dtors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1162d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, 1163d88c1a5aSDimitry Andric SectionKind::getData()); 1164d88c1a5aSDimitry Andric } 1165d88c1a5aSDimitry Andric } 1166d88c1a5aSDimitry Andric 1167ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection( 116891bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 116939d628a0SDimitry Andric return getContext().getAssociativeCOFFSection( 11703ca95b02SDimitry Andric cast<MCSectionCOFF>(StaticCtorSection), KeySym, 0); 117191bc56edSDimitry Andric } 117291bc56edSDimitry Andric 1173ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection( 117491bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 117539d628a0SDimitry Andric return getContext().getAssociativeCOFFSection( 11763ca95b02SDimitry Andric cast<MCSectionCOFF>(StaticDtorSection), KeySym, 0); 117791bc56edSDimitry Andric } 11783dac3a9bSDimitry Andric 11793dac3a9bSDimitry Andric void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal( 1180d88c1a5aSDimitry Andric raw_ostream &OS, const GlobalValue *GV) const { 11817a7e6055SDimitry Andric emitLinkerFlagsForGlobalCOFF(OS, GV, getTargetTriple(), getMangler()); 11823dac3a9bSDimitry Andric } 11833dac3a9bSDimitry Andric 11847a7e6055SDimitry Andric //===----------------------------------------------------------------------===// 11857a7e6055SDimitry Andric // Wasm 11867a7e6055SDimitry Andric //===----------------------------------------------------------------------===// 11877a7e6055SDimitry Andric 11887a7e6055SDimitry Andric static const Comdat *getWasmComdat(const GlobalValue *GV) { 11897a7e6055SDimitry Andric const Comdat *C = GV->getComdat(); 11907a7e6055SDimitry Andric if (!C) 11917a7e6055SDimitry Andric return nullptr; 11927a7e6055SDimitry Andric 11937a7e6055SDimitry Andric if (C->getSelectionKind() != Comdat::Any) 11947a7e6055SDimitry Andric report_fatal_error("Wasm COMDATs only support SelectionKind::Any, '" + 11957a7e6055SDimitry Andric C->getName() + "' cannot be lowered."); 11967a7e6055SDimitry Andric 11977a7e6055SDimitry Andric return C; 11983dac3a9bSDimitry Andric } 11997a7e6055SDimitry Andric 12007a7e6055SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal( 12017a7e6055SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 12027a7e6055SDimitry Andric llvm_unreachable("getExplicitSectionGlobal not yet implemented"); 12037a7e6055SDimitry Andric return nullptr; 12047a7e6055SDimitry Andric } 12057a7e6055SDimitry Andric 12067a7e6055SDimitry Andric static MCSectionWasm * 12077a7e6055SDimitry Andric selectWasmSectionForGlobal(MCContext &Ctx, const GlobalObject *GO, 12087a7e6055SDimitry Andric SectionKind Kind, Mangler &Mang, 12097a7e6055SDimitry Andric const TargetMachine &TM, bool EmitUniqueSection, 12107a7e6055SDimitry Andric unsigned Flags, unsigned *NextUniqueID) { 12117a7e6055SDimitry Andric StringRef Group = ""; 12127a7e6055SDimitry Andric if (getWasmComdat(GO)) 12137a7e6055SDimitry Andric llvm_unreachable("comdat not yet supported for wasm"); 12147a7e6055SDimitry Andric 12157a7e6055SDimitry Andric bool UniqueSectionNames = TM.getUniqueSectionNames(); 12167a7e6055SDimitry Andric SmallString<128> Name = getSectionPrefixForGlobal(Kind); 12177a7e6055SDimitry Andric 12187a7e6055SDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) { 12197a7e6055SDimitry Andric const auto &OptionalPrefix = F->getSectionPrefix(); 12207a7e6055SDimitry Andric if (OptionalPrefix) 12217a7e6055SDimitry Andric Name += *OptionalPrefix; 12227a7e6055SDimitry Andric } 12237a7e6055SDimitry Andric 12247a7e6055SDimitry Andric if (EmitUniqueSection && UniqueSectionNames) { 12257a7e6055SDimitry Andric Name.push_back('.'); 12267a7e6055SDimitry Andric TM.getNameWithPrefix(Name, GO, Mang, true); 12277a7e6055SDimitry Andric } 12287a7e6055SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 12297a7e6055SDimitry Andric if (EmitUniqueSection && !UniqueSectionNames) { 12307a7e6055SDimitry Andric UniqueID = *NextUniqueID; 12317a7e6055SDimitry Andric (*NextUniqueID)++; 12327a7e6055SDimitry Andric } 12337a7e6055SDimitry Andric return Ctx.getWasmSection(Name, /*Type=*/0, Flags, 12347a7e6055SDimitry Andric Group, UniqueID); 12357a7e6055SDimitry Andric } 12367a7e6055SDimitry Andric 12377a7e6055SDimitry Andric MCSection *TargetLoweringObjectFileWasm::SelectSectionForGlobal( 12387a7e6055SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 12397a7e6055SDimitry Andric 12407a7e6055SDimitry Andric if (Kind.isCommon()) 12417a7e6055SDimitry Andric report_fatal_error("mergable sections not supported yet on wasm"); 12427a7e6055SDimitry Andric 12437a7e6055SDimitry Andric // If we have -ffunction-section or -fdata-section then we should emit the 12447a7e6055SDimitry Andric // global value to a uniqued section specifically for it. 12457a7e6055SDimitry Andric bool EmitUniqueSection = false; 12467a7e6055SDimitry Andric if (Kind.isText()) 12477a7e6055SDimitry Andric EmitUniqueSection = TM.getFunctionSections(); 12487a7e6055SDimitry Andric else 12497a7e6055SDimitry Andric EmitUniqueSection = TM.getDataSections(); 12507a7e6055SDimitry Andric EmitUniqueSection |= GO->hasComdat(); 12517a7e6055SDimitry Andric 12527a7e6055SDimitry Andric return selectWasmSectionForGlobal(getContext(), GO, Kind, getMangler(), TM, 12537a7e6055SDimitry Andric EmitUniqueSection, /*Flags=*/0, 12547a7e6055SDimitry Andric &NextUniqueID); 12557a7e6055SDimitry Andric } 12567a7e6055SDimitry Andric 12577a7e6055SDimitry Andric bool TargetLoweringObjectFileWasm::shouldPutJumpTableInFunctionSection( 12587a7e6055SDimitry Andric bool UsesLabelDifference, const Function &F) const { 12597a7e6055SDimitry Andric // We can always create relative relocations, so use another section 12607a7e6055SDimitry Andric // that can be marked non-executable. 12617a7e6055SDimitry Andric return false; 12627a7e6055SDimitry Andric } 12637a7e6055SDimitry Andric 12647a7e6055SDimitry Andric const MCExpr *TargetLoweringObjectFileWasm::lowerRelativeReference( 12657a7e6055SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 12667a7e6055SDimitry Andric const TargetMachine &TM) const { 12677a7e6055SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr 12687a7e6055SDimitry Andric // functions. 12697a7e6055SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) 12707a7e6055SDimitry Andric return nullptr; 12717a7e6055SDimitry Andric 12727a7e6055SDimitry Andric // Basic sanity checks. 12737a7e6055SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 12747a7e6055SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || 12757a7e6055SDimitry Andric RHS->isThreadLocal()) 12767a7e6055SDimitry Andric return nullptr; 12777a7e6055SDimitry Andric 12787a7e6055SDimitry Andric return MCBinaryExpr::createSub( 12797a7e6055SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS), MCSymbolRefExpr::VK_None, 12807a7e6055SDimitry Andric getContext()), 12817a7e6055SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); 12827a7e6055SDimitry Andric } 12837a7e6055SDimitry Andric 12847a7e6055SDimitry Andric void 12857a7e6055SDimitry Andric TargetLoweringObjectFileWasm::InitializeWasm() { 12867a7e6055SDimitry Andric // TODO: Initialize StaticCtorSection and StaticDtorSection. 12873dac3a9bSDimitry Andric } 1288