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 15db17bf38SDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 16139f7f9bSDimitry Andric #include "llvm/ADT/SmallString.h" 177a7e6055SDimitry Andric #include "llvm/ADT/SmallVector.h" 18139f7f9bSDimitry Andric #include "llvm/ADT/StringExtras.h" 197a7e6055SDimitry Andric #include "llvm/ADT/StringRef.h" 20139f7f9bSDimitry Andric #include "llvm/ADT/Triple.h" 21db17bf38SDimitry Andric #include "llvm/BinaryFormat/COFF.h" 22db17bf38SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h" 23db17bf38SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 24db17bf38SDimitry Andric #include "llvm/BinaryFormat/MachO.h" 257a7e6055SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 26f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineModuleInfoImpls.h" 277a7e6055SDimitry Andric #include "llvm/IR/Comdat.h" 28139f7f9bSDimitry Andric #include "llvm/IR/Constants.h" 29139f7f9bSDimitry Andric #include "llvm/IR/DataLayout.h" 30139f7f9bSDimitry Andric #include "llvm/IR/DerivedTypes.h" 31139f7f9bSDimitry Andric #include "llvm/IR/Function.h" 327a7e6055SDimitry Andric #include "llvm/IR/GlobalAlias.h" 337a7e6055SDimitry Andric #include "llvm/IR/GlobalObject.h" 347a7e6055SDimitry Andric #include "llvm/IR/GlobalValue.h" 35139f7f9bSDimitry Andric #include "llvm/IR/GlobalVariable.h" 3691bc56edSDimitry Andric #include "llvm/IR/Mangler.h" 377a7e6055SDimitry Andric #include "llvm/IR/Metadata.h" 38139f7f9bSDimitry Andric #include "llvm/IR/Module.h" 397a7e6055SDimitry Andric #include "llvm/IR/Type.h" 407d523365SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 41f22ef01cSRoman Divacky #include "llvm/MC/MCContext.h" 42f22ef01cSRoman Divacky #include "llvm/MC/MCExpr.h" 43f22ef01cSRoman Divacky #include "llvm/MC/MCSectionCOFF.h" 44139f7f9bSDimitry Andric #include "llvm/MC/MCSectionELF.h" 45139f7f9bSDimitry Andric #include "llvm/MC/MCSectionMachO.h" 467a7e6055SDimitry Andric #include "llvm/MC/MCSectionWasm.h" 473b0f4066SDimitry Andric #include "llvm/MC/MCStreamer.h" 487a7e6055SDimitry Andric #include "llvm/MC/MCSymbol.h" 4997bc6c73SDimitry Andric #include "llvm/MC/MCSymbolELF.h" 50ff0cc061SDimitry Andric #include "llvm/MC/MCValue.h" 517a7e6055SDimitry Andric #include "llvm/MC/SectionKind.h" 523ca95b02SDimitry Andric #include "llvm/ProfileData/InstrProf.h" 537a7e6055SDimitry Andric #include "llvm/Support/Casting.h" 547a7e6055SDimitry Andric #include "llvm/Support/CodeGen.h" 552cab237bSDimitry Andric #include "llvm/Support/Format.h" 56f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h" 57f22ef01cSRoman Divacky #include "llvm/Support/raw_ostream.h" 58139f7f9bSDimitry Andric #include "llvm/Target/TargetMachine.h" 597a7e6055SDimitry Andric #include <cassert> 607a7e6055SDimitry Andric #include <string> 617a7e6055SDimitry Andric 62f22ef01cSRoman Divacky using namespace llvm; 63f22ef01cSRoman Divacky using namespace dwarf; 64f22ef01cSRoman Divacky 6524d58133SDimitry Andric static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags, 66db17bf38SDimitry Andric StringRef &Section) { 6724d58133SDimitry Andric SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags; 6824d58133SDimitry Andric M.getModuleFlagsMetadata(ModuleFlags); 6924d58133SDimitry Andric 70db17bf38SDimitry Andric for (const auto &MFE: ModuleFlags) { 71db17bf38SDimitry Andric // Ignore flags with 'Require' behaviour. 72db17bf38SDimitry Andric if (MFE.Behavior == Module::Require) 73db17bf38SDimitry Andric continue; 74db17bf38SDimitry Andric 75db17bf38SDimitry Andric StringRef Key = MFE.Key->getString(); 76db17bf38SDimitry Andric if (Key == "Objective-C Image Info Version") { 77db17bf38SDimitry Andric Version = mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue(); 78db17bf38SDimitry Andric } else if (Key == "Objective-C Garbage Collection" || 79db17bf38SDimitry Andric Key == "Objective-C GC Only" || 80db17bf38SDimitry Andric Key == "Objective-C Is Simulated" || 81db17bf38SDimitry Andric Key == "Objective-C Class Properties" || 82db17bf38SDimitry Andric Key == "Objective-C Image Swift Version") { 83db17bf38SDimitry Andric Flags |= mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue(); 84db17bf38SDimitry Andric } else if (Key == "Objective-C Image Info Section") { 85db17bf38SDimitry Andric Section = cast<MDString>(MFE.Val)->getString(); 86db17bf38SDimitry Andric } 87db17bf38SDimitry Andric } 88db17bf38SDimitry Andric } 89db17bf38SDimitry Andric 90f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 91f22ef01cSRoman Divacky // ELF 92f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 93f22ef01cSRoman Divacky 9424d58133SDimitry Andric void TargetLoweringObjectFileELF::emitModuleMetadata( 9524d58133SDimitry Andric MCStreamer &Streamer, Module &M, const TargetMachine &TM) const { 96db17bf38SDimitry Andric unsigned Version = 0; 97db17bf38SDimitry Andric unsigned Flags = 0; 98db17bf38SDimitry Andric StringRef Section; 99db17bf38SDimitry Andric 10024d58133SDimitry Andric GetObjCImageInfo(M, Version, Flags, Section); 101db17bf38SDimitry Andric if (Section.empty()) 102db17bf38SDimitry Andric return; 103db17bf38SDimitry Andric 104db17bf38SDimitry Andric auto &C = getContext(); 105db17bf38SDimitry Andric auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC); 106db17bf38SDimitry Andric Streamer.SwitchSection(S); 107db17bf38SDimitry Andric Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); 108db17bf38SDimitry Andric Streamer.EmitIntValue(Version, 4); 109db17bf38SDimitry Andric Streamer.EmitIntValue(Flags, 4); 110db17bf38SDimitry Andric Streamer.AddBlankLine(); 111db17bf38SDimitry Andric } 112db17bf38SDimitry Andric 11391bc56edSDimitry Andric MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol( 114d88c1a5aSDimitry Andric const GlobalValue *GV, const TargetMachine &TM, 1153b0f4066SDimitry Andric MachineModuleInfo *MMI) const { 1163b0f4066SDimitry Andric unsigned Encoding = getPersonalityEncoding(); 1177a7e6055SDimitry Andric if ((Encoding & 0x80) == DW_EH_PE_indirect) 118ff0cc061SDimitry Andric return getContext().getOrCreateSymbol(StringRef("DW.ref.") + 119d88c1a5aSDimitry Andric TM.getSymbol(GV)->getName()); 1207a7e6055SDimitry Andric if ((Encoding & 0x70) == DW_EH_PE_absptr) 121d88c1a5aSDimitry Andric return TM.getSymbol(GV); 12291bc56edSDimitry Andric report_fatal_error("We do not support this DWARF encoding yet!"); 1233b0f4066SDimitry Andric } 1243b0f4066SDimitry Andric 1257d523365SDimitry Andric void TargetLoweringObjectFileELF::emitPersonalityValue( 1267d523365SDimitry Andric MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym) const { 12717a519f9SDimitry Andric SmallString<64> NameData("DW.ref."); 12817a519f9SDimitry Andric NameData += Sym->getName(); 12997bc6c73SDimitry Andric MCSymbolELF *Label = 13097bc6c73SDimitry Andric cast<MCSymbolELF>(getContext().getOrCreateSymbol(NameData)); 1313b0f4066SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_Hidden); 1323b0f4066SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_Weak); 1333b0f4066SDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP; 1343ca95b02SDimitry Andric MCSection *Sec = getContext().getELFNamedSection(".data", Label->getName(), 1353ca95b02SDimitry Andric ELF::SHT_PROGBITS, Flags, 0); 1367d523365SDimitry Andric unsigned Size = DL.getPointerSize(); 1373b0f4066SDimitry Andric Streamer.SwitchSection(Sec); 1382cab237bSDimitry Andric Streamer.EmitValueToAlignment(DL.getPointerABIAlignment(0)); 1393b0f4066SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject); 14097bc6c73SDimitry Andric const MCExpr *E = MCConstantExpr::create(Size, getContext()); 14197bc6c73SDimitry Andric Streamer.emitELFSize(Label, E); 1423b0f4066SDimitry Andric Streamer.EmitLabel(Label); 1433b0f4066SDimitry Andric 1443b0f4066SDimitry Andric Streamer.EmitSymbolValue(Sym, Size); 1453b0f4066SDimitry Andric } 1463b0f4066SDimitry Andric 14791bc56edSDimitry Andric const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference( 148d88c1a5aSDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, 149d88c1a5aSDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 1507a7e6055SDimitry Andric if (Encoding & DW_EH_PE_indirect) { 151139f7f9bSDimitry Andric MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>(); 152139f7f9bSDimitry Andric 153d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", TM); 154139f7f9bSDimitry Andric 155139f7f9bSDimitry Andric // Add information about the stub reference to ELFMMI so that the stub 156139f7f9bSDimitry Andric // gets emitted by the asmprinter. 157139f7f9bSDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym); 15891bc56edSDimitry Andric if (!StubSym.getPointer()) { 159d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 160139f7f9bSDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 161139f7f9bSDimitry Andric } 162139f7f9bSDimitry Andric 163139f7f9bSDimitry Andric return TargetLoweringObjectFile:: 16497bc6c73SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), 1657a7e6055SDimitry Andric Encoding & ~DW_EH_PE_indirect, Streamer); 166139f7f9bSDimitry Andric } 167139f7f9bSDimitry Andric 168d88c1a5aSDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM, 169d88c1a5aSDimitry Andric MMI, Streamer); 170139f7f9bSDimitry Andric } 171139f7f9bSDimitry Andric 1722cab237bSDimitry Andric static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) { 173bd5abe19SDimitry Andric // N.B.: The defaults used in here are no the same ones used in MC. 174bd5abe19SDimitry Andric // We follow gcc, MC follows gas. For example, given ".section .eh_frame", 175bd5abe19SDimitry Andric // both gas and MC will produce a section with no flags. Given 1767ae0e2c9SDimitry Andric // section(".eh_frame") gcc will produce: 1777ae0e2c9SDimitry Andric // 178bd5abe19SDimitry Andric // .section .eh_frame,"a",@progbits 1793ca95b02SDimitry Andric 1807a7e6055SDimitry Andric if (Name == getInstrProfSectionName(IPSK_covmap, Triple::ELF, 1817a7e6055SDimitry Andric /*AddSegmentInfo=*/false)) 1823ca95b02SDimitry Andric return SectionKind::getMetadata(); 1833ca95b02SDimitry Andric 184f22ef01cSRoman Divacky if (Name.empty() || Name[0] != '.') return K; 185f22ef01cSRoman Divacky 186f22ef01cSRoman Divacky // Some lame default implementation based on some magic section names. 187f22ef01cSRoman Divacky if (Name == ".bss" || 188f22ef01cSRoman Divacky Name.startswith(".bss.") || 189f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.b.") || 190f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.b.") || 191f22ef01cSRoman Divacky Name == ".sbss" || 192f22ef01cSRoman Divacky Name.startswith(".sbss.") || 193f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.sb.") || 194f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.sb.")) 195f22ef01cSRoman Divacky return SectionKind::getBSS(); 196f22ef01cSRoman Divacky 197f22ef01cSRoman Divacky if (Name == ".tdata" || 198f22ef01cSRoman Divacky Name.startswith(".tdata.") || 199f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.td.") || 200f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.td.")) 201f22ef01cSRoman Divacky return SectionKind::getThreadData(); 202f22ef01cSRoman Divacky 203f22ef01cSRoman Divacky if (Name == ".tbss" || 204f22ef01cSRoman Divacky Name.startswith(".tbss.") || 205f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.tb.") || 206f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.tb.")) 207f22ef01cSRoman Divacky return SectionKind::getThreadBSS(); 208f22ef01cSRoman Divacky 209f22ef01cSRoman Divacky return K; 210f22ef01cSRoman Divacky } 211f22ef01cSRoman Divacky 212f22ef01cSRoman Divacky static unsigned getELFSectionType(StringRef Name, SectionKind K) { 213d88c1a5aSDimitry Andric // Use SHT_NOTE for section whose name starts with ".note" to allow 214d88c1a5aSDimitry Andric // emitting ELF notes from C variable declaration. 215d88c1a5aSDimitry Andric // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77609 216d88c1a5aSDimitry Andric if (Name.startswith(".note")) 217d88c1a5aSDimitry Andric return ELF::SHT_NOTE; 218f22ef01cSRoman Divacky 219f22ef01cSRoman Divacky if (Name == ".init_array") 2202754fe60SDimitry Andric return ELF::SHT_INIT_ARRAY; 221f22ef01cSRoman Divacky 222f22ef01cSRoman Divacky if (Name == ".fini_array") 2232754fe60SDimitry Andric return ELF::SHT_FINI_ARRAY; 224f22ef01cSRoman Divacky 225f22ef01cSRoman Divacky if (Name == ".preinit_array") 2262754fe60SDimitry Andric return ELF::SHT_PREINIT_ARRAY; 227f22ef01cSRoman Divacky 228f22ef01cSRoman Divacky if (K.isBSS() || K.isThreadBSS()) 2292754fe60SDimitry Andric return ELF::SHT_NOBITS; 230f22ef01cSRoman Divacky 2312754fe60SDimitry Andric return ELF::SHT_PROGBITS; 232f22ef01cSRoman Divacky } 233f22ef01cSRoman Divacky 234ff0cc061SDimitry Andric static unsigned getELFSectionFlags(SectionKind K) { 235f22ef01cSRoman Divacky unsigned Flags = 0; 236f22ef01cSRoman Divacky 237f22ef01cSRoman Divacky if (!K.isMetadata()) 2382754fe60SDimitry Andric Flags |= ELF::SHF_ALLOC; 239f22ef01cSRoman Divacky 240f22ef01cSRoman Divacky if (K.isText()) 2412754fe60SDimitry Andric Flags |= ELF::SHF_EXECINSTR; 242f22ef01cSRoman Divacky 243d88c1a5aSDimitry Andric if (K.isExecuteOnly()) 244d88c1a5aSDimitry Andric Flags |= ELF::SHF_ARM_PURECODE; 245d88c1a5aSDimitry Andric 246f22ef01cSRoman Divacky if (K.isWriteable()) 2472754fe60SDimitry Andric Flags |= ELF::SHF_WRITE; 248f22ef01cSRoman Divacky 249f22ef01cSRoman Divacky if (K.isThreadLocal()) 2502754fe60SDimitry Andric Flags |= ELF::SHF_TLS; 251f22ef01cSRoman Divacky 252ff0cc061SDimitry Andric if (K.isMergeableCString() || K.isMergeableConst()) 2532754fe60SDimitry Andric Flags |= ELF::SHF_MERGE; 254f22ef01cSRoman Divacky 255f22ef01cSRoman Divacky if (K.isMergeableCString()) 2562754fe60SDimitry Andric Flags |= ELF::SHF_STRINGS; 257f22ef01cSRoman Divacky 258f22ef01cSRoman Divacky return Flags; 259f22ef01cSRoman Divacky } 260f22ef01cSRoman Divacky 26191bc56edSDimitry Andric static const Comdat *getELFComdat(const GlobalValue *GV) { 26291bc56edSDimitry Andric const Comdat *C = GV->getComdat(); 26391bc56edSDimitry Andric if (!C) 26491bc56edSDimitry Andric return nullptr; 265f22ef01cSRoman Divacky 26691bc56edSDimitry Andric if (C->getSelectionKind() != Comdat::Any) 26791bc56edSDimitry Andric report_fatal_error("ELF COMDATs only support SelectionKind::Any, '" + 26891bc56edSDimitry Andric C->getName() + "' cannot be lowered."); 26991bc56edSDimitry Andric 27091bc56edSDimitry Andric return C; 27191bc56edSDimitry Andric } 27291bc56edSDimitry Andric 2737a7e6055SDimitry Andric static const MCSymbolELF *getAssociatedSymbol(const GlobalObject *GO, 2747a7e6055SDimitry Andric const TargetMachine &TM) { 2757a7e6055SDimitry Andric MDNode *MD = GO->getMetadata(LLVMContext::MD_associated); 2767a7e6055SDimitry Andric if (!MD) 2777a7e6055SDimitry Andric return nullptr; 2787a7e6055SDimitry Andric 2795517e702SDimitry Andric const MDOperand &Op = MD->getOperand(0); 2805517e702SDimitry Andric if (!Op.get()) 2815517e702SDimitry Andric return nullptr; 2825517e702SDimitry Andric 2835517e702SDimitry Andric auto *VM = dyn_cast<ValueAsMetadata>(Op); 2847a7e6055SDimitry Andric if (!VM) 2857a7e6055SDimitry Andric report_fatal_error("MD_associated operand is not ValueAsMetadata"); 2867a7e6055SDimitry Andric 2877a7e6055SDimitry Andric GlobalObject *OtherGO = dyn_cast<GlobalObject>(VM->getValue()); 2887a7e6055SDimitry Andric return OtherGO ? dyn_cast<MCSymbolELF>(TM.getSymbol(OtherGO)) : nullptr; 2897a7e6055SDimitry Andric } 2907a7e6055SDimitry Andric 291ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( 292d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 293d88c1a5aSDimitry Andric StringRef SectionName = GO->getSection(); 294f22ef01cSRoman Divacky 295db17bf38SDimitry Andric // Check if '#pragma clang section' name is applicable. 296db17bf38SDimitry Andric // Note that pragma directive overrides -ffunction-section, -fdata-section 297db17bf38SDimitry Andric // and so section name is exactly as user specified and not uniqued. 298db17bf38SDimitry Andric const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO); 299db17bf38SDimitry Andric if (GV && GV->hasImplicitSection()) { 300db17bf38SDimitry Andric auto Attrs = GV->getAttributes(); 301db17bf38SDimitry Andric if (Attrs.hasAttribute("bss-section") && Kind.isBSS()) { 302db17bf38SDimitry Andric SectionName = Attrs.getAttribute("bss-section").getValueAsString(); 303db17bf38SDimitry Andric } else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) { 304db17bf38SDimitry Andric SectionName = Attrs.getAttribute("rodata-section").getValueAsString(); 305db17bf38SDimitry Andric } else if (Attrs.hasAttribute("data-section") && Kind.isData()) { 306db17bf38SDimitry Andric SectionName = Attrs.getAttribute("data-section").getValueAsString(); 307db17bf38SDimitry Andric } 308db17bf38SDimitry Andric } 309db17bf38SDimitry Andric const Function *F = dyn_cast<Function>(GO); 310db17bf38SDimitry Andric if (F && F->hasFnAttribute("implicit-section-name")) { 311db17bf38SDimitry Andric SectionName = F->getFnAttribute("implicit-section-name").getValueAsString(); 312db17bf38SDimitry Andric } 313db17bf38SDimitry Andric 314f22ef01cSRoman Divacky // Infer section flags from the section name if we can. 315f22ef01cSRoman Divacky Kind = getELFKindForNamedSection(SectionName, Kind); 316f22ef01cSRoman Divacky 31791bc56edSDimitry Andric StringRef Group = ""; 31891bc56edSDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 319d88c1a5aSDimitry Andric if (const Comdat *C = getELFComdat(GO)) { 32091bc56edSDimitry Andric Group = C->getName(); 32191bc56edSDimitry Andric Flags |= ELF::SHF_GROUP; 32291bc56edSDimitry Andric } 3237a7e6055SDimitry Andric 3247a7e6055SDimitry Andric // A section can have at most one associated section. Put each global with 3257a7e6055SDimitry Andric // MD_associated in a unique section. 3267a7e6055SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 3277a7e6055SDimitry Andric const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM); 3287a7e6055SDimitry Andric if (AssociatedSymbol) { 3297a7e6055SDimitry Andric UniqueID = NextUniqueID++; 3307a7e6055SDimitry Andric Flags |= ELF::SHF_LINK_ORDER; 3317a7e6055SDimitry Andric } 3327a7e6055SDimitry Andric 3337a7e6055SDimitry Andric MCSectionELF *Section = getContext().getELFSection( 3347a7e6055SDimitry Andric SectionName, getELFSectionType(SectionName, Kind), Flags, 3357a7e6055SDimitry Andric /*EntrySize=*/0, Group, UniqueID, AssociatedSymbol); 3367a7e6055SDimitry Andric // Make sure that we did not get some other section with incompatible sh_link. 3377a7e6055SDimitry Andric // This should not be possible due to UniqueID code above. 3387a7e6055SDimitry Andric assert(Section->getAssociatedSymbol() == AssociatedSymbol); 3397a7e6055SDimitry Andric return Section; 340f22ef01cSRoman Divacky } 341f22ef01cSRoman Divacky 342ff0cc061SDimitry Andric /// Return the section prefix name used by options FunctionsSections and 343ff0cc061SDimitry Andric /// DataSections. 34491bc56edSDimitry Andric static StringRef getSectionPrefixForGlobal(SectionKind Kind) { 345ff0cc061SDimitry Andric if (Kind.isText()) 346ff0cc061SDimitry Andric return ".text"; 347ff0cc061SDimitry Andric if (Kind.isReadOnly()) 348ff0cc061SDimitry Andric return ".rodata"; 349ff0cc061SDimitry Andric if (Kind.isBSS()) 350ff0cc061SDimitry Andric return ".bss"; 351ff0cc061SDimitry Andric if (Kind.isThreadData()) 352ff0cc061SDimitry Andric return ".tdata"; 353ff0cc061SDimitry Andric if (Kind.isThreadBSS()) 354ff0cc061SDimitry Andric return ".tbss"; 3557d523365SDimitry Andric if (Kind.isData()) 356ff0cc061SDimitry Andric return ".data"; 357f22ef01cSRoman Divacky assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); 358ff0cc061SDimitry Andric return ".data.rel.ro"; 359f22ef01cSRoman Divacky } 360f22ef01cSRoman Divacky 3617a7e6055SDimitry Andric static MCSectionELF *selectELFSectionForGlobal( 3627a7e6055SDimitry Andric MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang, 3637a7e6055SDimitry Andric const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags, 3647a7e6055SDimitry Andric unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) { 365ff0cc061SDimitry Andric unsigned EntrySize = 0; 366ff0cc061SDimitry Andric if (Kind.isMergeableCString()) { 367ff0cc061SDimitry Andric if (Kind.isMergeable2ByteCString()) { 368ff0cc061SDimitry Andric EntrySize = 2; 369ff0cc061SDimitry Andric } else if (Kind.isMergeable4ByteCString()) { 370ff0cc061SDimitry Andric EntrySize = 4; 371ff0cc061SDimitry Andric } else { 372ff0cc061SDimitry Andric EntrySize = 1; 373ff0cc061SDimitry Andric assert(Kind.isMergeable1ByteCString() && "unknown string width"); 374ff0cc061SDimitry Andric } 375ff0cc061SDimitry Andric } else if (Kind.isMergeableConst()) { 376ff0cc061SDimitry Andric if (Kind.isMergeableConst4()) { 377ff0cc061SDimitry Andric EntrySize = 4; 378ff0cc061SDimitry Andric } else if (Kind.isMergeableConst8()) { 379ff0cc061SDimitry Andric EntrySize = 8; 3803ca95b02SDimitry Andric } else if (Kind.isMergeableConst16()) { 381ff0cc061SDimitry Andric EntrySize = 16; 3823ca95b02SDimitry Andric } else { 3833ca95b02SDimitry Andric assert(Kind.isMergeableConst32() && "unknown data width"); 3843ca95b02SDimitry Andric EntrySize = 32; 385ff0cc061SDimitry Andric } 386ff0cc061SDimitry Andric } 38791bc56edSDimitry Andric 3882754fe60SDimitry Andric StringRef Group = ""; 389d88c1a5aSDimitry Andric if (const Comdat *C = getELFComdat(GO)) { 3902754fe60SDimitry Andric Flags |= ELF::SHF_GROUP; 391ff0cc061SDimitry Andric Group = C->getName(); 3922754fe60SDimitry Andric } 3932754fe60SDimitry Andric 394ff0cc061SDimitry Andric bool UniqueSectionNames = TM.getUniqueSectionNames(); 395ff0cc061SDimitry Andric SmallString<128> Name; 396ff0cc061SDimitry Andric if (Kind.isMergeableCString()) { 397f22ef01cSRoman Divacky // We also need alignment here. 398f22ef01cSRoman Divacky // FIXME: this is getting the alignment of the character, not the 399f22ef01cSRoman Divacky // alignment of the global! 400d88c1a5aSDimitry Andric unsigned Align = GO->getParent()->getDataLayout().getPreferredAlignment( 401d88c1a5aSDimitry Andric cast<GlobalVariable>(GO)); 402f22ef01cSRoman Divacky 403ff0cc061SDimitry Andric std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + "."; 404ff0cc061SDimitry Andric Name = SizeSpec + utostr(Align); 405ff0cc061SDimitry Andric } else if (Kind.isMergeableConst()) { 406ff0cc061SDimitry Andric Name = ".rodata.cst"; 407ff0cc061SDimitry Andric Name += utostr(EntrySize); 408ff0cc061SDimitry Andric } else { 409ff0cc061SDimitry Andric Name = getSectionPrefixForGlobal(Kind); 410ff0cc061SDimitry Andric } 411d88c1a5aSDimitry Andric 412d88c1a5aSDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) { 413d88c1a5aSDimitry Andric const auto &OptionalPrefix = F->getSectionPrefix(); 414d88c1a5aSDimitry Andric if (OptionalPrefix) 415d88c1a5aSDimitry Andric Name += *OptionalPrefix; 416d88c1a5aSDimitry Andric } 417ff0cc061SDimitry Andric 418ff0cc061SDimitry Andric if (EmitUniqueSection && UniqueSectionNames) { 419ff0cc061SDimitry Andric Name.push_back('.'); 420d88c1a5aSDimitry Andric TM.getNameWithPrefix(Name, GO, Mang, true); 421ff0cc061SDimitry Andric } 4223ca95b02SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 423ff0cc061SDimitry Andric if (EmitUniqueSection && !UniqueSectionNames) { 424ff0cc061SDimitry Andric UniqueID = *NextUniqueID; 425ff0cc061SDimitry Andric (*NextUniqueID)++; 426ff0cc061SDimitry Andric } 427d88c1a5aSDimitry Andric // Use 0 as the unique ID for execute-only text 428d88c1a5aSDimitry Andric if (Kind.isExecuteOnly()) 429d88c1a5aSDimitry Andric UniqueID = 0; 430ff0cc061SDimitry Andric return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags, 4317a7e6055SDimitry Andric EntrySize, Group, UniqueID, AssociatedSymbol); 432ff0cc061SDimitry Andric } 433ff0cc061SDimitry Andric 434ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( 435d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 436ff0cc061SDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 437ff0cc061SDimitry Andric 438ff0cc061SDimitry Andric // If we have -ffunction-section or -fdata-section then we should emit the 439ff0cc061SDimitry Andric // global value to a uniqued section specifically for it. 440ff0cc061SDimitry Andric bool EmitUniqueSection = false; 441ff0cc061SDimitry Andric if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) { 442ff0cc061SDimitry Andric if (Kind.isText()) 443ff0cc061SDimitry Andric EmitUniqueSection = TM.getFunctionSections(); 444f22ef01cSRoman Divacky else 445ff0cc061SDimitry Andric EmitUniqueSection = TM.getDataSections(); 446ff0cc061SDimitry Andric } 447d88c1a5aSDimitry Andric EmitUniqueSection |= GO->hasComdat(); 448f22ef01cSRoman Divacky 4497a7e6055SDimitry Andric const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM); 4507a7e6055SDimitry Andric if (AssociatedSymbol) { 4517a7e6055SDimitry Andric EmitUniqueSection = true; 4527a7e6055SDimitry Andric Flags |= ELF::SHF_LINK_ORDER; 4537a7e6055SDimitry Andric } 4547a7e6055SDimitry Andric 4557a7e6055SDimitry Andric MCSectionELF *Section = selectELFSectionForGlobal( 4567a7e6055SDimitry Andric getContext(), GO, Kind, getMangler(), TM, EmitUniqueSection, Flags, 4577a7e6055SDimitry Andric &NextUniqueID, AssociatedSymbol); 4587a7e6055SDimitry Andric assert(Section->getAssociatedSymbol() == AssociatedSymbol); 4597a7e6055SDimitry Andric return Section; 460f22ef01cSRoman Divacky } 461f22ef01cSRoman Divacky 462ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( 463d88c1a5aSDimitry Andric const Function &F, const TargetMachine &TM) const { 464ff0cc061SDimitry Andric // If the function can be removed, produce a unique section so that 465ff0cc061SDimitry Andric // the table doesn't prevent the removal. 466ff0cc061SDimitry Andric const Comdat *C = F.getComdat(); 467ff0cc061SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C; 468ff0cc061SDimitry Andric if (!EmitUniqueSection) 469ff0cc061SDimitry Andric return ReadOnlySection; 470ff0cc061SDimitry Andric 471ff0cc061SDimitry Andric return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(), 4727a7e6055SDimitry Andric getMangler(), TM, EmitUniqueSection, 4737a7e6055SDimitry Andric ELF::SHF_ALLOC, &NextUniqueID, 4747a7e6055SDimitry Andric /* AssociatedSymbol */ nullptr); 475f22ef01cSRoman Divacky } 476f22ef01cSRoman Divacky 477ff0cc061SDimitry Andric bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection( 478ff0cc061SDimitry Andric bool UsesLabelDifference, const Function &F) const { 479ff0cc061SDimitry Andric // We can always create relative relocations, so use another section 480ff0cc061SDimitry Andric // that can be marked non-executable. 481ff0cc061SDimitry Andric return false; 482f22ef01cSRoman Divacky } 483f22ef01cSRoman Divacky 484ff0cc061SDimitry Andric /// Given a mergeable constant with the specified size and relocation 485ff0cc061SDimitry Andric /// information, return a section that it should be placed in. 4867d523365SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForConstant( 4873ca95b02SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 4883ca95b02SDimitry Andric unsigned &Align) const { 489f22ef01cSRoman Divacky if (Kind.isMergeableConst4() && MergeableConst4Section) 490f22ef01cSRoman Divacky return MergeableConst4Section; 491f22ef01cSRoman Divacky if (Kind.isMergeableConst8() && MergeableConst8Section) 492f22ef01cSRoman Divacky return MergeableConst8Section; 493f22ef01cSRoman Divacky if (Kind.isMergeableConst16() && MergeableConst16Section) 494f22ef01cSRoman Divacky return MergeableConst16Section; 4953ca95b02SDimitry Andric if (Kind.isMergeableConst32() && MergeableConst32Section) 4963ca95b02SDimitry Andric return MergeableConst32Section; 497f22ef01cSRoman Divacky if (Kind.isReadOnly()) 498f22ef01cSRoman Divacky return ReadOnlySection; 499f22ef01cSRoman Divacky 500f22ef01cSRoman Divacky assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); 501f22ef01cSRoman Divacky return DataRelROSection; 502f22ef01cSRoman Divacky } 503f22ef01cSRoman Divacky 504ff0cc061SDimitry Andric static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray, 505ff0cc061SDimitry Andric bool IsCtor, unsigned Priority, 50639d628a0SDimitry Andric const MCSymbol *KeySym) { 50739d628a0SDimitry Andric std::string Name; 50839d628a0SDimitry Andric unsigned Type; 50939d628a0SDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE; 51039d628a0SDimitry Andric StringRef COMDAT = KeySym ? KeySym->getName() : ""; 51139d628a0SDimitry Andric 51239d628a0SDimitry Andric if (KeySym) 51339d628a0SDimitry Andric Flags |= ELF::SHF_GROUP; 514dff0c46cSDimitry Andric 5157ae0e2c9SDimitry Andric if (UseInitArray) { 51639d628a0SDimitry Andric if (IsCtor) { 51739d628a0SDimitry Andric Type = ELF::SHT_INIT_ARRAY; 51839d628a0SDimitry Andric Name = ".init_array"; 5197ae0e2c9SDimitry Andric } else { 52039d628a0SDimitry Andric Type = ELF::SHT_FINI_ARRAY; 52139d628a0SDimitry Andric Name = ".fini_array"; 522dff0c46cSDimitry Andric } 52339d628a0SDimitry Andric if (Priority != 65535) { 52439d628a0SDimitry Andric Name += '.'; 52539d628a0SDimitry Andric Name += utostr(Priority); 52639d628a0SDimitry Andric } 52739d628a0SDimitry Andric } else { 52839d628a0SDimitry Andric // The default scheme is .ctor / .dtor, so we have to invert the priority 52939d628a0SDimitry Andric // numbering. 53039d628a0SDimitry Andric if (IsCtor) 53139d628a0SDimitry Andric Name = ".ctors"; 53239d628a0SDimitry Andric else 53339d628a0SDimitry Andric Name = ".dtors"; 5342cab237bSDimitry Andric if (Priority != 65535) 5352cab237bSDimitry Andric raw_string_ostream(Name) << format(".%05u", 65535 - Priority); 53639d628a0SDimitry Andric Type = ELF::SHT_PROGBITS; 53739d628a0SDimitry Andric } 53839d628a0SDimitry Andric 539ff0cc061SDimitry Andric return Ctx.getELFSection(Name, Type, Flags, 0, COMDAT); 54039d628a0SDimitry Andric } 54139d628a0SDimitry Andric 542ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticCtorSection( 54339d628a0SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 54439d628a0SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, true, Priority, 54539d628a0SDimitry Andric KeySym); 5467ae0e2c9SDimitry Andric } 547dff0c46cSDimitry Andric 548ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticDtorSection( 54991bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 55039d628a0SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, false, Priority, 55139d628a0SDimitry Andric KeySym); 5527ae0e2c9SDimitry Andric } 5537ae0e2c9SDimitry Andric 5543ca95b02SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference( 555d88c1a5aSDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 5563ca95b02SDimitry Andric const TargetMachine &TM) const { 5573ca95b02SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr 5583ca95b02SDimitry Andric // functions. 5593ca95b02SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) 5603ca95b02SDimitry Andric return nullptr; 5613ca95b02SDimitry Andric 5623ca95b02SDimitry Andric // Basic sanity checks. 5633ca95b02SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 5643ca95b02SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || 5653ca95b02SDimitry Andric RHS->isThreadLocal()) 5663ca95b02SDimitry Andric return nullptr; 5673ca95b02SDimitry Andric 5683ca95b02SDimitry Andric return MCBinaryExpr::createSub( 569d88c1a5aSDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS), PLTRelativeVariantKind, 5703ca95b02SDimitry Andric getContext()), 571d88c1a5aSDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); 5723ca95b02SDimitry Andric } 5733ca95b02SDimitry Andric 5747ae0e2c9SDimitry Andric void 5757ae0e2c9SDimitry Andric TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) { 5767ae0e2c9SDimitry Andric UseInitArray = UseInitArray_; 577d88c1a5aSDimitry Andric MCContext &Ctx = getContext(); 578d88c1a5aSDimitry Andric if (!UseInitArray) { 579d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getELFSection(".ctors", ELF::SHT_PROGBITS, 580d88c1a5aSDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE); 5817ae0e2c9SDimitry Andric 582d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getELFSection(".dtors", ELF::SHT_PROGBITS, 583d88c1a5aSDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE); 584d88c1a5aSDimitry Andric return; 585d88c1a5aSDimitry Andric } 586d88c1a5aSDimitry Andric 587d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getELFSection(".init_array", ELF::SHT_INIT_ARRAY, 588d88c1a5aSDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC); 589d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getELFSection(".fini_array", ELF::SHT_FINI_ARRAY, 590d88c1a5aSDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC); 5917ae0e2c9SDimitry Andric } 592dff0c46cSDimitry Andric 593f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 594f22ef01cSRoman Divacky // MachO 595f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 596f22ef01cSRoman Divacky 597ff0cc061SDimitry Andric TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO() 598ff0cc061SDimitry Andric : TargetLoweringObjectFile() { 599ff0cc061SDimitry Andric SupportIndirectSymViaGOTPCRel = true; 600ff0cc061SDimitry Andric } 601ff0cc061SDimitry Andric 602d88c1a5aSDimitry Andric void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx, 603d88c1a5aSDimitry Andric const TargetMachine &TM) { 604d88c1a5aSDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM); 605d88c1a5aSDimitry Andric if (TM.getRelocationModel() == Reloc::Static) { 606d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getMachOSection("__TEXT", "__constructor", 0, 607d88c1a5aSDimitry Andric SectionKind::getData()); 608d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getMachOSection("__TEXT", "__destructor", 0, 609d88c1a5aSDimitry Andric SectionKind::getData()); 610d88c1a5aSDimitry Andric } else { 611d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getMachOSection("__DATA", "__mod_init_func", 612d88c1a5aSDimitry Andric MachO::S_MOD_INIT_FUNC_POINTERS, 613d88c1a5aSDimitry Andric SectionKind::getData()); 614d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getMachOSection("__DATA", "__mod_term_func", 615d88c1a5aSDimitry Andric MachO::S_MOD_TERM_FUNC_POINTERS, 616d88c1a5aSDimitry Andric SectionKind::getData()); 617d88c1a5aSDimitry Andric } 618d88c1a5aSDimitry Andric } 619d88c1a5aSDimitry Andric 62024d58133SDimitry Andric void TargetLoweringObjectFileMachO::emitModuleMetadata( 62124d58133SDimitry Andric MCStreamer &Streamer, Module &M, const TargetMachine &TM) const { 622139f7f9bSDimitry Andric // Emit the linker options if present. 62324d58133SDimitry Andric if (auto *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { 6243ca95b02SDimitry Andric for (const auto &Option : LinkerOptions->operands()) { 625139f7f9bSDimitry Andric SmallVector<std::string, 4> StrOptions; 6263ca95b02SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) 6273ca95b02SDimitry Andric StrOptions.push_back(cast<MDString>(Piece)->getString()); 628139f7f9bSDimitry Andric Streamer.EmitLinkerOptions(StrOptions); 629139f7f9bSDimitry Andric } 630dff0c46cSDimitry Andric } 631dff0c46cSDimitry Andric 632db17bf38SDimitry Andric unsigned VersionVal = 0; 633db17bf38SDimitry Andric unsigned ImageInfoFlags = 0; 634db17bf38SDimitry Andric StringRef SectionVal; 63524d58133SDimitry Andric 63624d58133SDimitry Andric GetObjCImageInfo(M, VersionVal, ImageInfoFlags, SectionVal); 637db17bf38SDimitry Andric 638dff0c46cSDimitry Andric // The section is mandatory. If we don't have it, then we don't have GC info. 639db17bf38SDimitry Andric if (SectionVal.empty()) 640db17bf38SDimitry Andric return; 641dff0c46cSDimitry Andric 642dff0c46cSDimitry Andric StringRef Segment, Section; 643dff0c46cSDimitry Andric unsigned TAA = 0, StubSize = 0; 644dff0c46cSDimitry Andric bool TAAParsed; 645dff0c46cSDimitry Andric std::string ErrorCode = 646dff0c46cSDimitry Andric MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section, 647dff0c46cSDimitry Andric TAA, TAAParsed, StubSize); 648dff0c46cSDimitry Andric if (!ErrorCode.empty()) 649dff0c46cSDimitry Andric // If invalid, report the error with report_fatal_error. 650dff0c46cSDimitry Andric report_fatal_error("Invalid section specifier '" + Section + "': " + 651dff0c46cSDimitry Andric ErrorCode + "."); 652dff0c46cSDimitry Andric 653dff0c46cSDimitry Andric // Get the section. 654ff0cc061SDimitry Andric MCSectionMachO *S = getContext().getMachOSection( 6557d523365SDimitry Andric Segment, Section, TAA, StubSize, SectionKind::getData()); 656dff0c46cSDimitry Andric Streamer.SwitchSection(S); 657dff0c46cSDimitry Andric Streamer.EmitLabel(getContext(). 658ff0cc061SDimitry Andric getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); 659dff0c46cSDimitry Andric Streamer.EmitIntValue(VersionVal, 4); 6607ae0e2c9SDimitry Andric Streamer.EmitIntValue(ImageInfoFlags, 4); 661dff0c46cSDimitry Andric Streamer.AddBlankLine(); 662dff0c46cSDimitry Andric } 663dff0c46cSDimitry Andric 66491bc56edSDimitry Andric static void checkMachOComdat(const GlobalValue *GV) { 66591bc56edSDimitry Andric const Comdat *C = GV->getComdat(); 66691bc56edSDimitry Andric if (!C) 66791bc56edSDimitry Andric return; 66891bc56edSDimitry Andric 66991bc56edSDimitry Andric report_fatal_error("MachO doesn't support COMDATs, '" + C->getName() + 67091bc56edSDimitry Andric "' cannot be lowered."); 67191bc56edSDimitry Andric } 67291bc56edSDimitry Andric 673ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( 674d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 675f22ef01cSRoman Divacky // Parse the section specifier and create it if valid. 676f22ef01cSRoman Divacky StringRef Segment, Section; 6773b0f4066SDimitry Andric unsigned TAA = 0, StubSize = 0; 6783b0f4066SDimitry Andric bool TAAParsed; 67991bc56edSDimitry Andric 680d88c1a5aSDimitry Andric checkMachOComdat(GO); 68191bc56edSDimitry Andric 682f22ef01cSRoman Divacky std::string ErrorCode = 683d88c1a5aSDimitry Andric MCSectionMachO::ParseSectionSpecifier(GO->getSection(), Segment, Section, 6843b0f4066SDimitry Andric TAA, TAAParsed, StubSize); 685f22ef01cSRoman Divacky if (!ErrorCode.empty()) { 686f22ef01cSRoman Divacky // If invalid, report the error with report_fatal_error. 687d88c1a5aSDimitry Andric report_fatal_error("Global variable '" + GO->getName() + 688dff0c46cSDimitry Andric "' has an invalid section specifier '" + 689d88c1a5aSDimitry Andric GO->getSection() + "': " + ErrorCode + "."); 690f22ef01cSRoman Divacky } 691f22ef01cSRoman Divacky 692f22ef01cSRoman Divacky // Get the section. 693ff0cc061SDimitry Andric MCSectionMachO *S = 694f22ef01cSRoman Divacky getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind); 695f22ef01cSRoman Divacky 696dd6029ffSDimitry Andric // If TAA wasn't set by ParseSectionSpecifier() above, 697dd6029ffSDimitry Andric // use the value returned by getMachOSection() as a default. 6983b0f4066SDimitry Andric if (!TAAParsed) 699dd6029ffSDimitry Andric TAA = S->getTypeAndAttributes(); 700dd6029ffSDimitry Andric 701f22ef01cSRoman Divacky // Okay, now that we got the section, verify that the TAA & StubSize agree. 702f22ef01cSRoman Divacky // If the user declared multiple globals with different section flags, we need 703f22ef01cSRoman Divacky // to reject it here. 704f22ef01cSRoman Divacky if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) { 705f22ef01cSRoman Divacky // If invalid, report the error with report_fatal_error. 706d88c1a5aSDimitry Andric report_fatal_error("Global variable '" + GO->getName() + 707f22ef01cSRoman Divacky "' section type or attributes does not match previous" 708f22ef01cSRoman Divacky " section specifier"); 709f22ef01cSRoman Divacky } 710f22ef01cSRoman Divacky 711f22ef01cSRoman Divacky return S; 712f22ef01cSRoman Divacky } 713f22ef01cSRoman Divacky 714ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal( 715d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 716d88c1a5aSDimitry Andric checkMachOComdat(GO); 717f785676fSDimitry Andric 718f785676fSDimitry Andric // Handle thread local data. 719f785676fSDimitry Andric if (Kind.isThreadBSS()) return TLSBSSSection; 720f785676fSDimitry Andric if (Kind.isThreadData()) return TLSDataSection; 721f785676fSDimitry Andric 722f22ef01cSRoman Divacky if (Kind.isText()) 723d88c1a5aSDimitry Andric return GO->isWeakForLinker() ? TextCoalSection : TextSection; 724f22ef01cSRoman Divacky 725f22ef01cSRoman Divacky // If this is weak/linkonce, put this in a coalescable section, either in text 726f22ef01cSRoman Divacky // or data depending on if it is writable. 727d88c1a5aSDimitry Andric if (GO->isWeakForLinker()) { 728f22ef01cSRoman Divacky if (Kind.isReadOnly()) 729f22ef01cSRoman Divacky return ConstTextCoalSection; 730f22ef01cSRoman Divacky return DataCoalSection; 731f22ef01cSRoman Divacky } 732f22ef01cSRoman Divacky 733f22ef01cSRoman Divacky // FIXME: Alignment check should be handled by section classifier. 734f22ef01cSRoman Divacky if (Kind.isMergeable1ByteCString() && 735d88c1a5aSDimitry Andric GO->getParent()->getDataLayout().getPreferredAlignment( 736d88c1a5aSDimitry Andric cast<GlobalVariable>(GO)) < 32) 737f22ef01cSRoman Divacky return CStringSection; 738f22ef01cSRoman Divacky 739f22ef01cSRoman Divacky // Do not put 16-bit arrays in the UString section if they have an 740f22ef01cSRoman Divacky // externally visible label, this runs into issues with certain linker 741f22ef01cSRoman Divacky // versions. 742d88c1a5aSDimitry Andric if (Kind.isMergeable2ByteCString() && !GO->hasExternalLinkage() && 743d88c1a5aSDimitry Andric GO->getParent()->getDataLayout().getPreferredAlignment( 744d88c1a5aSDimitry Andric cast<GlobalVariable>(GO)) < 32) 745f22ef01cSRoman Divacky return UStringSection; 746f22ef01cSRoman Divacky 74739d628a0SDimitry Andric // With MachO only variables whose corresponding symbol starts with 'l' or 74839d628a0SDimitry Andric // 'L' can be merged, so we only try merging GVs with private linkage. 749d88c1a5aSDimitry Andric if (GO->hasPrivateLinkage() && Kind.isMergeableConst()) { 750f22ef01cSRoman Divacky if (Kind.isMergeableConst4()) 751f22ef01cSRoman Divacky return FourByteConstantSection; 752f22ef01cSRoman Divacky if (Kind.isMergeableConst8()) 753f22ef01cSRoman Divacky return EightByteConstantSection; 75491bc56edSDimitry Andric if (Kind.isMergeableConst16()) 755f22ef01cSRoman Divacky return SixteenByteConstantSection; 756f22ef01cSRoman Divacky } 757f22ef01cSRoman Divacky 758f22ef01cSRoman Divacky // Otherwise, if it is readonly, but not something we can specially optimize, 759f22ef01cSRoman Divacky // just drop it in .const. 760f22ef01cSRoman Divacky if (Kind.isReadOnly()) 761f22ef01cSRoman Divacky return ReadOnlySection; 762f22ef01cSRoman Divacky 763f22ef01cSRoman Divacky // If this is marked const, put it into a const section. But if the dynamic 764f22ef01cSRoman Divacky // linker needs to write to it, put it in the data segment. 765f22ef01cSRoman Divacky if (Kind.isReadOnlyWithRel()) 766f22ef01cSRoman Divacky return ConstDataSection; 767f22ef01cSRoman Divacky 768f22ef01cSRoman Divacky // Put zero initialized globals with strong external linkage in the 769f22ef01cSRoman Divacky // DATA, __common section with the .zerofill directive. 770f22ef01cSRoman Divacky if (Kind.isBSSExtern()) 771f22ef01cSRoman Divacky return DataCommonSection; 772f22ef01cSRoman Divacky 773f22ef01cSRoman Divacky // Put zero initialized globals with local linkage in __DATA,__bss directive 774f22ef01cSRoman Divacky // with the .zerofill directive (aka .lcomm). 775f22ef01cSRoman Divacky if (Kind.isBSSLocal()) 776f22ef01cSRoman Divacky return DataBSSSection; 777f22ef01cSRoman Divacky 778f22ef01cSRoman Divacky // Otherwise, just drop the variable in the normal data section. 779f22ef01cSRoman Divacky return DataSection; 780f22ef01cSRoman Divacky } 781f22ef01cSRoman Divacky 7827d523365SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getSectionForConstant( 7833ca95b02SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 7843ca95b02SDimitry Andric unsigned &Align) const { 785f22ef01cSRoman Divacky // If this constant requires a relocation, we have to put it in the data 786f22ef01cSRoman Divacky // segment, not in the text segment. 7877d523365SDimitry Andric if (Kind.isData() || Kind.isReadOnlyWithRel()) 788f22ef01cSRoman Divacky return ConstDataSection; 789f22ef01cSRoman Divacky 790f22ef01cSRoman Divacky if (Kind.isMergeableConst4()) 791f22ef01cSRoman Divacky return FourByteConstantSection; 792f22ef01cSRoman Divacky if (Kind.isMergeableConst8()) 793f22ef01cSRoman Divacky return EightByteConstantSection; 79491bc56edSDimitry Andric if (Kind.isMergeableConst16()) 795f22ef01cSRoman Divacky return SixteenByteConstantSection; 796f22ef01cSRoman Divacky return ReadOnlySection; // .const 797f22ef01cSRoman Divacky } 798f22ef01cSRoman Divacky 79991bc56edSDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference( 800d88c1a5aSDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, 801d88c1a5aSDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 802f22ef01cSRoman Divacky // The mach-o version of this method defaults to returning a stub reference. 803f22ef01cSRoman Divacky 804f22ef01cSRoman Divacky if (Encoding & DW_EH_PE_indirect) { 805f22ef01cSRoman Divacky MachineModuleInfoMachO &MachOMMI = 806f22ef01cSRoman Divacky MMI->getObjFileInfo<MachineModuleInfoMachO>(); 807f22ef01cSRoman Divacky 808d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); 809f22ef01cSRoman Divacky 810f22ef01cSRoman Divacky // Add information about the stub reference to MachOMMI so that the stub 811f22ef01cSRoman Divacky // gets emitted by the asmprinter. 8123ca95b02SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 81391bc56edSDimitry Andric if (!StubSym.getPointer()) { 814d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 815f22ef01cSRoman Divacky StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 816f22ef01cSRoman Divacky } 817f22ef01cSRoman Divacky 818f22ef01cSRoman Divacky return TargetLoweringObjectFile:: 81997bc6c73SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), 8207a7e6055SDimitry Andric Encoding & ~DW_EH_PE_indirect, Streamer); 821f22ef01cSRoman Divacky } 822f22ef01cSRoman Divacky 823d88c1a5aSDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM, 824d88c1a5aSDimitry Andric MMI, Streamer); 825f22ef01cSRoman Divacky } 826f22ef01cSRoman Divacky 82791bc56edSDimitry Andric MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol( 828d88c1a5aSDimitry Andric const GlobalValue *GV, const TargetMachine &TM, 8293b0f4066SDimitry Andric MachineModuleInfo *MMI) const { 8303b0f4066SDimitry Andric // The mach-o version of this method defaults to returning a stub reference. 8313b0f4066SDimitry Andric MachineModuleInfoMachO &MachOMMI = 8323b0f4066SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 8333b0f4066SDimitry Andric 834d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); 8353b0f4066SDimitry Andric 8363b0f4066SDimitry Andric // Add information about the stub reference to MachOMMI so that the stub 8373b0f4066SDimitry Andric // gets emitted by the asmprinter. 838dff0c46cSDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 83991bc56edSDimitry Andric if (!StubSym.getPointer()) { 840d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 8413b0f4066SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 8423b0f4066SDimitry Andric } 8433b0f4066SDimitry Andric 8443b0f4066SDimitry Andric return SSym; 8453b0f4066SDimitry Andric } 8463b0f4066SDimitry Andric 847ff0cc061SDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel( 848ff0cc061SDimitry Andric const MCSymbol *Sym, const MCValue &MV, int64_t Offset, 849ff0cc061SDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 8507d523365SDimitry Andric // Although MachO 32-bit targets do not explicitly have a GOTPCREL relocation 851ff0cc061SDimitry Andric // as 64-bit do, we replace the GOT equivalent by accessing the final symbol 852ff0cc061SDimitry Andric // through a non_lazy_ptr stub instead. One advantage is that it allows the 853ff0cc061SDimitry Andric // computation of deltas to final external symbols. Example: 854ff0cc061SDimitry Andric // 855ff0cc061SDimitry Andric // _extgotequiv: 856ff0cc061SDimitry Andric // .long _extfoo 857ff0cc061SDimitry Andric // 858ff0cc061SDimitry Andric // _delta: 859ff0cc061SDimitry Andric // .long _extgotequiv-_delta 860ff0cc061SDimitry Andric // 861ff0cc061SDimitry Andric // is transformed to: 862ff0cc061SDimitry Andric // 863ff0cc061SDimitry Andric // _delta: 864ff0cc061SDimitry Andric // .long L_extfoo$non_lazy_ptr-(_delta+0) 865ff0cc061SDimitry Andric // 866ff0cc061SDimitry Andric // .section __IMPORT,__pointers,non_lazy_symbol_pointers 867ff0cc061SDimitry Andric // L_extfoo$non_lazy_ptr: 868ff0cc061SDimitry Andric // .indirect_symbol _extfoo 869ff0cc061SDimitry Andric // .long 0 870ff0cc061SDimitry Andric // 871ff0cc061SDimitry Andric MachineModuleInfoMachO &MachOMMI = 872ff0cc061SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 873ff0cc061SDimitry Andric MCContext &Ctx = getContext(); 874ff0cc061SDimitry Andric 875ff0cc061SDimitry Andric // The offset must consider the original displacement from the base symbol 876ff0cc061SDimitry Andric // since 32-bit targets don't have a GOTPCREL to fold the PC displacement. 877ff0cc061SDimitry Andric Offset = -MV.getConstant(); 878ff0cc061SDimitry Andric const MCSymbol *BaseSym = &MV.getSymB()->getSymbol(); 879ff0cc061SDimitry Andric 880ff0cc061SDimitry Andric // Access the final symbol via sym$non_lazy_ptr and generate the appropriated 881ff0cc061SDimitry Andric // non_lazy_ptr stubs. 882ff0cc061SDimitry Andric SmallString<128> Name; 883ff0cc061SDimitry Andric StringRef Suffix = "$non_lazy_ptr"; 8847d523365SDimitry Andric Name += MMI->getModule()->getDataLayout().getPrivateGlobalPrefix(); 885ff0cc061SDimitry Andric Name += Sym->getName(); 886ff0cc061SDimitry Andric Name += Suffix; 887ff0cc061SDimitry Andric MCSymbol *Stub = Ctx.getOrCreateSymbol(Name); 888ff0cc061SDimitry Andric 889ff0cc061SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub); 890ff0cc061SDimitry Andric if (!StubSym.getPointer()) 891ff0cc061SDimitry Andric StubSym = MachineModuleInfoImpl:: 892ff0cc061SDimitry Andric StubValueTy(const_cast<MCSymbol *>(Sym), true /* access indirectly */); 893ff0cc061SDimitry Andric 894ff0cc061SDimitry Andric const MCExpr *BSymExpr = 89597bc6c73SDimitry Andric MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx); 896ff0cc061SDimitry Andric const MCExpr *LHS = 89797bc6c73SDimitry Andric MCSymbolRefExpr::create(Stub, MCSymbolRefExpr::VK_None, Ctx); 898ff0cc061SDimitry Andric 899ff0cc061SDimitry Andric if (!Offset) 90097bc6c73SDimitry Andric return MCBinaryExpr::createSub(LHS, BSymExpr, Ctx); 901ff0cc061SDimitry Andric 902ff0cc061SDimitry Andric const MCExpr *RHS = 90397bc6c73SDimitry Andric MCBinaryExpr::createAdd(BSymExpr, MCConstantExpr::create(Offset, Ctx), Ctx); 90497bc6c73SDimitry Andric return MCBinaryExpr::createSub(LHS, RHS, Ctx); 905ff0cc061SDimitry Andric } 906ff0cc061SDimitry Andric 9077d523365SDimitry Andric static bool canUsePrivateLabel(const MCAsmInfo &AsmInfo, 9087d523365SDimitry Andric const MCSection &Section) { 9097d523365SDimitry Andric if (!AsmInfo.isSectionAtomizableBySymbols(Section)) 9107d523365SDimitry Andric return true; 9117d523365SDimitry Andric 9127d523365SDimitry Andric // If it is not dead stripped, it is safe to use private labels. 9137d523365SDimitry Andric const MCSectionMachO &SMO = cast<MCSectionMachO>(Section); 9147d523365SDimitry Andric if (SMO.hasAttribute(MachO::S_ATTR_NO_DEAD_STRIP)) 9157d523365SDimitry Andric return true; 9167d523365SDimitry Andric 9177d523365SDimitry Andric return false; 9187d523365SDimitry Andric } 9197d523365SDimitry Andric 9207d523365SDimitry Andric void TargetLoweringObjectFileMachO::getNameWithPrefix( 921d88c1a5aSDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, 9227d523365SDimitry Andric const TargetMachine &TM) const { 923d88c1a5aSDimitry Andric bool CannotUsePrivateLabel = true; 924d88c1a5aSDimitry Andric if (auto *GO = GV->getBaseObject()) { 925d88c1a5aSDimitry Andric SectionKind GOKind = TargetLoweringObjectFile::getKindForGlobal(GO, TM); 926d88c1a5aSDimitry Andric const MCSection *TheSection = SectionForGlobal(GO, GOKind, TM); 927d88c1a5aSDimitry Andric CannotUsePrivateLabel = 9287d523365SDimitry Andric !canUsePrivateLabel(*TM.getMCAsmInfo(), *TheSection); 929d88c1a5aSDimitry Andric } 930d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 9317d523365SDimitry Andric } 9327d523365SDimitry Andric 933f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 934f22ef01cSRoman Divacky // COFF 935f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 936f22ef01cSRoman Divacky 937f22ef01cSRoman Divacky static unsigned 9383ca95b02SDimitry Andric getCOFFSectionFlags(SectionKind K, const TargetMachine &TM) { 939f22ef01cSRoman Divacky unsigned Flags = 0; 9403ca95b02SDimitry Andric bool isThumb = TM.getTargetTriple().getArch() == Triple::thumb; 941f22ef01cSRoman Divacky 942ffd1746dSEd Schouten if (K.isMetadata()) 943f22ef01cSRoman Divacky Flags |= 944ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_DISCARDABLE; 945f22ef01cSRoman Divacky else if (K.isText()) 946f22ef01cSRoman Divacky Flags |= 947ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_EXECUTE | 9482754fe60SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 9493ca95b02SDimitry Andric COFF::IMAGE_SCN_CNT_CODE | 9503ca95b02SDimitry Andric (isThumb ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0); 951f22ef01cSRoman Divacky else if (K.isBSS()) 952f22ef01cSRoman Divacky Flags |= 953ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | 954ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ | 955ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_WRITE; 956dff0c46cSDimitry Andric else if (K.isThreadLocal()) 957dff0c46cSDimitry Andric Flags |= 958dff0c46cSDimitry Andric COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 959dff0c46cSDimitry Andric COFF::IMAGE_SCN_MEM_READ | 960dff0c46cSDimitry Andric COFF::IMAGE_SCN_MEM_WRITE; 96139d628a0SDimitry Andric else if (K.isReadOnly() || K.isReadOnlyWithRel()) 962f22ef01cSRoman Divacky Flags |= 963ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 964ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ; 965f22ef01cSRoman Divacky else if (K.isWriteable()) 966f22ef01cSRoman Divacky Flags |= 967ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 968ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ | 969ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_WRITE; 970f22ef01cSRoman Divacky 971f22ef01cSRoman Divacky return Flags; 972f22ef01cSRoman Divacky } 973f22ef01cSRoman Divacky 97491bc56edSDimitry Andric static const GlobalValue *getComdatGVForCOFF(const GlobalValue *GV) { 97591bc56edSDimitry Andric const Comdat *C = GV->getComdat(); 97691bc56edSDimitry Andric assert(C && "expected GV to have a Comdat!"); 97791bc56edSDimitry Andric 97891bc56edSDimitry Andric StringRef ComdatGVName = C->getName(); 97991bc56edSDimitry Andric const GlobalValue *ComdatGV = GV->getParent()->getNamedValue(ComdatGVName); 98091bc56edSDimitry Andric if (!ComdatGV) 98191bc56edSDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 98291bc56edSDimitry Andric "' does not exist."); 98391bc56edSDimitry Andric 98491bc56edSDimitry Andric if (ComdatGV->getComdat() != C) 98591bc56edSDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 98639d628a0SDimitry Andric "' is not a key for its COMDAT."); 98791bc56edSDimitry Andric 98891bc56edSDimitry Andric return ComdatGV; 98991bc56edSDimitry Andric } 99091bc56edSDimitry Andric 99191bc56edSDimitry Andric static int getSelectionForCOFF(const GlobalValue *GV) { 99291bc56edSDimitry Andric if (const Comdat *C = GV->getComdat()) { 99391bc56edSDimitry Andric const GlobalValue *ComdatKey = getComdatGVForCOFF(GV); 99491bc56edSDimitry Andric if (const auto *GA = dyn_cast<GlobalAlias>(ComdatKey)) 99591bc56edSDimitry Andric ComdatKey = GA->getBaseObject(); 99691bc56edSDimitry Andric if (ComdatKey == GV) { 99791bc56edSDimitry Andric switch (C->getSelectionKind()) { 99891bc56edSDimitry Andric case Comdat::Any: 99991bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ANY; 100091bc56edSDimitry Andric case Comdat::ExactMatch: 100191bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH; 100291bc56edSDimitry Andric case Comdat::Largest: 100391bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_LARGEST; 100491bc56edSDimitry Andric case Comdat::NoDuplicates: 100591bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 100691bc56edSDimitry Andric case Comdat::SameSize: 100791bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_SAME_SIZE; 100891bc56edSDimitry Andric } 100991bc56edSDimitry Andric } else { 101091bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE; 101191bc56edSDimitry Andric } 101291bc56edSDimitry Andric } 101391bc56edSDimitry Andric return 0; 101491bc56edSDimitry Andric } 101591bc56edSDimitry Andric 1016ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal( 1017d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 1018139f7f9bSDimitry Andric int Selection = 0; 10193ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 1020d88c1a5aSDimitry Andric StringRef Name = GO->getSection(); 102191bc56edSDimitry Andric StringRef COMDATSymName = ""; 1022d88c1a5aSDimitry Andric if (GO->hasComdat()) { 1023d88c1a5aSDimitry Andric Selection = getSelectionForCOFF(GO); 102491bc56edSDimitry Andric const GlobalValue *ComdatGV; 102591bc56edSDimitry Andric if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) 1026d88c1a5aSDimitry Andric ComdatGV = getComdatGVForCOFF(GO); 102791bc56edSDimitry Andric else 1028d88c1a5aSDimitry Andric ComdatGV = GO; 102991bc56edSDimitry Andric 103091bc56edSDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 1031d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV); 103291bc56edSDimitry Andric COMDATSymName = Sym->getName(); 1033139f7f9bSDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 103491bc56edSDimitry Andric } else { 103591bc56edSDimitry Andric Selection = 0; 103691bc56edSDimitry Andric } 1037139f7f9bSDimitry Andric } 10383ca95b02SDimitry Andric 10393ca95b02SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, 1040f785676fSDimitry Andric Selection); 1041f22ef01cSRoman Divacky } 1042f22ef01cSRoman Divacky 104391bc56edSDimitry Andric static const char *getCOFFSectionNameForUniqueGlobal(SectionKind Kind) { 1044f22ef01cSRoman Divacky if (Kind.isText()) 104591bc56edSDimitry Andric return ".text"; 1046f22ef01cSRoman Divacky if (Kind.isBSS()) 104791bc56edSDimitry Andric return ".bss"; 104891bc56edSDimitry Andric if (Kind.isThreadLocal()) 104991bc56edSDimitry Andric return ".tls$"; 105039d628a0SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 105191bc56edSDimitry Andric return ".rdata"; 105239d628a0SDimitry Andric return ".data"; 1053f22ef01cSRoman Divacky } 1054f22ef01cSRoman Divacky 1055ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal( 1056d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 105791bc56edSDimitry Andric // If we have -ffunction-sections then we should emit the global value to a 105891bc56edSDimitry Andric // uniqued section specifically for it. 105991bc56edSDimitry Andric bool EmitUniquedSection; 106091bc56edSDimitry Andric if (Kind.isText()) 106191bc56edSDimitry Andric EmitUniquedSection = TM.getFunctionSections(); 106291bc56edSDimitry Andric else 106391bc56edSDimitry Andric EmitUniquedSection = TM.getDataSections(); 1064f22ef01cSRoman Divacky 1065d88c1a5aSDimitry Andric if ((EmitUniquedSection && !Kind.isCommon()) || GO->hasComdat()) { 106691bc56edSDimitry Andric const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); 10673ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 1068f22ef01cSRoman Divacky 1069ffd1746dSEd Schouten Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 1070d88c1a5aSDimitry Andric int Selection = getSelectionForCOFF(GO); 107191bc56edSDimitry Andric if (!Selection) 107291bc56edSDimitry Andric Selection = COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 107391bc56edSDimitry Andric const GlobalValue *ComdatGV; 1074d88c1a5aSDimitry Andric if (GO->hasComdat()) 1075d88c1a5aSDimitry Andric ComdatGV = getComdatGVForCOFF(GO); 107691bc56edSDimitry Andric else 1077d88c1a5aSDimitry Andric ComdatGV = GO; 1078f22ef01cSRoman Divacky 10793ca95b02SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 10803ca95b02SDimitry Andric if (EmitUniquedSection) 10813ca95b02SDimitry Andric UniqueID = NextUniqueID++; 10823ca95b02SDimitry Andric 108391bc56edSDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 1084d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV); 108591bc56edSDimitry Andric StringRef COMDATSymName = Sym->getName(); 108691bc56edSDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, 10873ca95b02SDimitry Andric COMDATSymName, Selection, UniqueID); 1088ff0cc061SDimitry Andric } else { 1089ff0cc061SDimitry Andric SmallString<256> TmpData; 1090d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(TmpData, GO, /*CannotUsePrivateLabel=*/true); 1091ff0cc061SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, TmpData, 10923ca95b02SDimitry Andric Selection, UniqueID); 109391bc56edSDimitry Andric } 1094f22ef01cSRoman Divacky } 1095f22ef01cSRoman Divacky 1096f22ef01cSRoman Divacky if (Kind.isText()) 1097f785676fSDimitry Andric return TextSection; 1098f22ef01cSRoman Divacky 1099dff0c46cSDimitry Andric if (Kind.isThreadLocal()) 1100f785676fSDimitry Andric return TLSDataSection; 1101dff0c46cSDimitry Andric 110239d628a0SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 1103f785676fSDimitry Andric return ReadOnlySection; 1104f785676fSDimitry Andric 110591bc56edSDimitry Andric // Note: we claim that common symbols are put in BSSSection, but they are 110691bc56edSDimitry Andric // really emitted with the magic .comm directive, which creates a symbol table 110791bc56edSDimitry Andric // entry but not a section. 110891bc56edSDimitry Andric if (Kind.isBSS() || Kind.isCommon()) 1109f785676fSDimitry Andric return BSSSection; 1110f785676fSDimitry Andric 1111f785676fSDimitry Andric return DataSection; 1112f22ef01cSRoman Divacky } 1113f22ef01cSRoman Divacky 1114ff0cc061SDimitry Andric void TargetLoweringObjectFileCOFF::getNameWithPrefix( 1115d88c1a5aSDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, 11167d523365SDimitry Andric const TargetMachine &TM) const { 11177d523365SDimitry Andric bool CannotUsePrivateLabel = false; 1118ff0cc061SDimitry Andric if (GV->hasPrivateLinkage() && 1119ff0cc061SDimitry Andric ((isa<Function>(GV) && TM.getFunctionSections()) || 1120ff0cc061SDimitry Andric (isa<GlobalVariable>(GV) && TM.getDataSections()))) 1121ff0cc061SDimitry Andric CannotUsePrivateLabel = true; 1122ff0cc061SDimitry Andric 1123d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 1124ff0cc061SDimitry Andric } 1125ff0cc061SDimitry Andric 1126ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable( 1127d88c1a5aSDimitry Andric const Function &F, const TargetMachine &TM) const { 1128ff0cc061SDimitry Andric // If the function can be removed, produce a unique section so that 1129ff0cc061SDimitry Andric // the table doesn't prevent the removal. 1130ff0cc061SDimitry Andric const Comdat *C = F.getComdat(); 1131ff0cc061SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C; 1132ff0cc061SDimitry Andric if (!EmitUniqueSection) 1133ff0cc061SDimitry Andric return ReadOnlySection; 1134ff0cc061SDimitry Andric 1135ff0cc061SDimitry Andric // FIXME: we should produce a symbol for F instead. 1136ff0cc061SDimitry Andric if (F.hasPrivateLinkage()) 1137ff0cc061SDimitry Andric return ReadOnlySection; 1138ff0cc061SDimitry Andric 1139d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(&F); 1140ff0cc061SDimitry Andric StringRef COMDATSymName = Sym->getName(); 1141ff0cc061SDimitry Andric 1142ff0cc061SDimitry Andric SectionKind Kind = SectionKind::getReadOnly(); 1143ff0cc061SDimitry Andric const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); 11443ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 1145ff0cc061SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 11463ca95b02SDimitry Andric unsigned UniqueID = NextUniqueID++; 1147ff0cc061SDimitry Andric 1148ff0cc061SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, 11493ca95b02SDimitry Andric COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); 1150ff0cc061SDimitry Andric } 1151ff0cc061SDimitry Andric 115224d58133SDimitry Andric void TargetLoweringObjectFileCOFF::emitModuleMetadata( 115324d58133SDimitry Andric MCStreamer &Streamer, Module &M, const TargetMachine &TM) const { 115424d58133SDimitry Andric if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { 1155284c1978SDimitry Andric // Emit the linker options to the linker .drectve section. According to the 11563ca95b02SDimitry Andric // spec, this section is a space-separated string containing flags for 11573ca95b02SDimitry Andric // linker. 1158ff0cc061SDimitry Andric MCSection *Sec = getDrectveSection(); 1159284c1978SDimitry Andric Streamer.SwitchSection(Sec); 11603ca95b02SDimitry Andric for (const auto &Option : LinkerOptions->operands()) { 11613ca95b02SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) { 1162284c1978SDimitry Andric // Lead with a space for consistency with our dllexport implementation. 1163ff0cc061SDimitry Andric std::string Directive(" "); 11643ca95b02SDimitry Andric Directive.append(cast<MDString>(Piece)->getString()); 1165ff0cc061SDimitry Andric Streamer.EmitBytes(Directive); 1166284c1978SDimitry Andric } 1167284c1978SDimitry Andric } 1168284c1978SDimitry Andric } 1169db17bf38SDimitry Andric 1170db17bf38SDimitry Andric unsigned Version = 0; 1171db17bf38SDimitry Andric unsigned Flags = 0; 1172db17bf38SDimitry Andric StringRef Section; 1173db17bf38SDimitry Andric 117424d58133SDimitry Andric GetObjCImageInfo(M, Version, Flags, Section); 1175db17bf38SDimitry Andric if (Section.empty()) 1176db17bf38SDimitry Andric return; 1177db17bf38SDimitry Andric 1178db17bf38SDimitry Andric auto &C = getContext(); 1179db17bf38SDimitry Andric auto *S = C.getCOFFSection( 1180db17bf38SDimitry Andric Section, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, 1181db17bf38SDimitry Andric SectionKind::getReadOnly()); 1182db17bf38SDimitry Andric Streamer.SwitchSection(S); 1183db17bf38SDimitry Andric Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); 1184db17bf38SDimitry Andric Streamer.EmitIntValue(Version, 4); 1185db17bf38SDimitry Andric Streamer.EmitIntValue(Flags, 4); 1186db17bf38SDimitry Andric Streamer.AddBlankLine(); 11873ca95b02SDimitry Andric } 118891bc56edSDimitry Andric 1189d88c1a5aSDimitry Andric void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx, 1190d88c1a5aSDimitry Andric const TargetMachine &TM) { 1191d88c1a5aSDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM); 1192d88c1a5aSDimitry Andric const Triple &T = TM.getTargetTriple(); 1193d88c1a5aSDimitry Andric if (T.isKnownWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) { 1194d88c1a5aSDimitry Andric StaticCtorSection = 1195d88c1a5aSDimitry Andric Ctx.getCOFFSection(".CRT$XCU", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1196d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ, 1197d88c1a5aSDimitry Andric SectionKind::getReadOnly()); 1198d88c1a5aSDimitry Andric StaticDtorSection = 1199d88c1a5aSDimitry Andric Ctx.getCOFFSection(".CRT$XTX", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1200d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ, 1201d88c1a5aSDimitry Andric SectionKind::getReadOnly()); 1202d88c1a5aSDimitry Andric } else { 1203d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getCOFFSection( 1204d88c1a5aSDimitry Andric ".ctors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1205d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, 1206d88c1a5aSDimitry Andric SectionKind::getData()); 1207d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getCOFFSection( 1208d88c1a5aSDimitry Andric ".dtors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1209d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, 1210d88c1a5aSDimitry Andric SectionKind::getData()); 1211d88c1a5aSDimitry Andric } 1212d88c1a5aSDimitry Andric } 1213d88c1a5aSDimitry Andric 12142cab237bSDimitry Andric static MCSectionCOFF *getCOFFStaticStructorSection(MCContext &Ctx, 12152cab237bSDimitry Andric const Triple &T, bool IsCtor, 12162cab237bSDimitry Andric unsigned Priority, 12172cab237bSDimitry Andric const MCSymbol *KeySym, 12182cab237bSDimitry Andric MCSectionCOFF *Default) { 12192cab237bSDimitry Andric if (T.isKnownWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) 12202cab237bSDimitry Andric return Ctx.getAssociativeCOFFSection(Default, KeySym, 0); 12212cab237bSDimitry Andric 12222cab237bSDimitry Andric std::string Name = IsCtor ? ".ctors" : ".dtors"; 12232cab237bSDimitry Andric if (Priority != 65535) 12242cab237bSDimitry Andric raw_string_ostream(Name) << format(".%05u", 65535 - Priority); 12252cab237bSDimitry Andric 12262cab237bSDimitry Andric return Ctx.getAssociativeCOFFSection( 12272cab237bSDimitry Andric Ctx.getCOFFSection(Name, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 12282cab237bSDimitry Andric COFF::IMAGE_SCN_MEM_READ | 12292cab237bSDimitry Andric COFF::IMAGE_SCN_MEM_WRITE, 12302cab237bSDimitry Andric SectionKind::getData()), 12312cab237bSDimitry Andric KeySym, 0); 12322cab237bSDimitry Andric } 12332cab237bSDimitry Andric 1234ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection( 123591bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 12362cab237bSDimitry Andric return getCOFFStaticStructorSection(getContext(), getTargetTriple(), true, 12372cab237bSDimitry Andric Priority, KeySym, 12382cab237bSDimitry Andric cast<MCSectionCOFF>(StaticCtorSection)); 123991bc56edSDimitry Andric } 124091bc56edSDimitry Andric 1241ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection( 124291bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 12432cab237bSDimitry Andric return getCOFFStaticStructorSection(getContext(), getTargetTriple(), false, 12442cab237bSDimitry Andric Priority, KeySym, 12452cab237bSDimitry Andric cast<MCSectionCOFF>(StaticDtorSection)); 124691bc56edSDimitry Andric } 12473dac3a9bSDimitry Andric 12483dac3a9bSDimitry Andric void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal( 1249d88c1a5aSDimitry Andric raw_ostream &OS, const GlobalValue *GV) const { 12507a7e6055SDimitry Andric emitLinkerFlagsForGlobalCOFF(OS, GV, getTargetTriple(), getMangler()); 12513dac3a9bSDimitry Andric } 12523dac3a9bSDimitry Andric 12537a7e6055SDimitry Andric //===----------------------------------------------------------------------===// 12547a7e6055SDimitry Andric // Wasm 12557a7e6055SDimitry Andric //===----------------------------------------------------------------------===// 12567a7e6055SDimitry Andric 12572cab237bSDimitry Andric static void checkWasmComdat(const GlobalValue *GV) { 12587a7e6055SDimitry Andric const Comdat *C = GV->getComdat(); 12597a7e6055SDimitry Andric if (!C) 12602cab237bSDimitry Andric return; 12617a7e6055SDimitry Andric 12622cab237bSDimitry Andric // TODO(sbc): At some point we may need COMDAT support but currently 12632cab237bSDimitry Andric // they are not supported. 12642cab237bSDimitry Andric report_fatal_error("WebAssembly doesn't support COMDATs, '" + C->getName() + 12652cab237bSDimitry Andric "' cannot be lowered."); 12662cab237bSDimitry Andric } 12677a7e6055SDimitry Andric 12682cab237bSDimitry Andric static SectionKind getWasmKindForNamedSection(StringRef Name, SectionKind K) { 12692cab237bSDimitry Andric // If we're told we have function data, then use that. 12702cab237bSDimitry Andric if (K.isText()) 12712cab237bSDimitry Andric return SectionKind::getText(); 12722cab237bSDimitry Andric 12732cab237bSDimitry Andric // Otherwise, ignore whatever section type the generic impl detected and use 12742cab237bSDimitry Andric // a plain data section. 12752cab237bSDimitry Andric return SectionKind::getData(); 12763dac3a9bSDimitry Andric } 12777a7e6055SDimitry Andric 12787a7e6055SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal( 12797a7e6055SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 12802cab237bSDimitry Andric StringRef Name = GO->getSection(); 12812cab237bSDimitry Andric checkWasmComdat(GO); 12822cab237bSDimitry Andric Kind = getWasmKindForNamedSection(Name, Kind); 12832cab237bSDimitry Andric return getContext().getWasmSection(Name, Kind); 12847a7e6055SDimitry Andric } 12857a7e6055SDimitry Andric 12862cab237bSDimitry Andric static MCSectionWasm *selectWasmSectionForGlobal( 12872cab237bSDimitry Andric MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang, 12882cab237bSDimitry Andric const TargetMachine &TM, bool EmitUniqueSection, unsigned *NextUniqueID) { 12897a7e6055SDimitry Andric StringRef Group = ""; 12902cab237bSDimitry Andric checkWasmComdat(GO); 12917a7e6055SDimitry Andric 12927a7e6055SDimitry Andric bool UniqueSectionNames = TM.getUniqueSectionNames(); 12937a7e6055SDimitry Andric SmallString<128> Name = getSectionPrefixForGlobal(Kind); 12947a7e6055SDimitry Andric 12957a7e6055SDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) { 12967a7e6055SDimitry Andric const auto &OptionalPrefix = F->getSectionPrefix(); 12977a7e6055SDimitry Andric if (OptionalPrefix) 12987a7e6055SDimitry Andric Name += *OptionalPrefix; 12997a7e6055SDimitry Andric } 13007a7e6055SDimitry Andric 13017a7e6055SDimitry Andric if (EmitUniqueSection && UniqueSectionNames) { 13027a7e6055SDimitry Andric Name.push_back('.'); 13037a7e6055SDimitry Andric TM.getNameWithPrefix(Name, GO, Mang, true); 13047a7e6055SDimitry Andric } 13057a7e6055SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 13067a7e6055SDimitry Andric if (EmitUniqueSection && !UniqueSectionNames) { 13077a7e6055SDimitry Andric UniqueID = *NextUniqueID; 13087a7e6055SDimitry Andric (*NextUniqueID)++; 13097a7e6055SDimitry Andric } 13102cab237bSDimitry Andric return Ctx.getWasmSection(Name, Kind, Group, UniqueID); 13117a7e6055SDimitry Andric } 13127a7e6055SDimitry Andric 13137a7e6055SDimitry Andric MCSection *TargetLoweringObjectFileWasm::SelectSectionForGlobal( 13147a7e6055SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 13157a7e6055SDimitry Andric 13167a7e6055SDimitry Andric if (Kind.isCommon()) 13177a7e6055SDimitry Andric report_fatal_error("mergable sections not supported yet on wasm"); 13187a7e6055SDimitry Andric 13197a7e6055SDimitry Andric // If we have -ffunction-section or -fdata-section then we should emit the 13207a7e6055SDimitry Andric // global value to a uniqued section specifically for it. 13217a7e6055SDimitry Andric bool EmitUniqueSection = false; 13227a7e6055SDimitry Andric if (Kind.isText()) 13237a7e6055SDimitry Andric EmitUniqueSection = TM.getFunctionSections(); 13247a7e6055SDimitry Andric else 13257a7e6055SDimitry Andric EmitUniqueSection = TM.getDataSections(); 13267a7e6055SDimitry Andric EmitUniqueSection |= GO->hasComdat(); 13277a7e6055SDimitry Andric 13287a7e6055SDimitry Andric return selectWasmSectionForGlobal(getContext(), GO, Kind, getMangler(), TM, 13292cab237bSDimitry Andric EmitUniqueSection, &NextUniqueID); 13307a7e6055SDimitry Andric } 13317a7e6055SDimitry Andric 13327a7e6055SDimitry Andric bool TargetLoweringObjectFileWasm::shouldPutJumpTableInFunctionSection( 13337a7e6055SDimitry Andric bool UsesLabelDifference, const Function &F) const { 13347a7e6055SDimitry Andric // We can always create relative relocations, so use another section 13357a7e6055SDimitry Andric // that can be marked non-executable. 13367a7e6055SDimitry Andric return false; 13377a7e6055SDimitry Andric } 13387a7e6055SDimitry Andric 13397a7e6055SDimitry Andric const MCExpr *TargetLoweringObjectFileWasm::lowerRelativeReference( 13407a7e6055SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 13417a7e6055SDimitry Andric const TargetMachine &TM) const { 13427a7e6055SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr 13437a7e6055SDimitry Andric // functions. 13447a7e6055SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) 13457a7e6055SDimitry Andric return nullptr; 13467a7e6055SDimitry Andric 13477a7e6055SDimitry Andric // Basic sanity checks. 13487a7e6055SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 13497a7e6055SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || 13507a7e6055SDimitry Andric RHS->isThreadLocal()) 13517a7e6055SDimitry Andric return nullptr; 13527a7e6055SDimitry Andric 13537a7e6055SDimitry Andric return MCBinaryExpr::createSub( 13547a7e6055SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS), MCSymbolRefExpr::VK_None, 13557a7e6055SDimitry Andric getContext()), 13567a7e6055SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); 13577a7e6055SDimitry Andric } 13587a7e6055SDimitry Andric 13592cab237bSDimitry Andric void TargetLoweringObjectFileWasm::InitializeWasm() { 13602cab237bSDimitry Andric StaticCtorSection = 13612cab237bSDimitry Andric getContext().getWasmSection(".init_array", SectionKind::getData()); 13622cab237bSDimitry Andric } 13632cab237bSDimitry Andric 13642cab237bSDimitry Andric MCSection *TargetLoweringObjectFileWasm::getStaticCtorSection( 13652cab237bSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 13662cab237bSDimitry Andric return Priority == UINT16_MAX ? 13672cab237bSDimitry Andric StaticCtorSection : 13682cab237bSDimitry Andric getContext().getWasmSection(".init_array." + utostr(Priority), 13692cab237bSDimitry Andric SectionKind::getData()); 13702cab237bSDimitry Andric } 13712cab237bSDimitry Andric 13722cab237bSDimitry Andric MCSection *TargetLoweringObjectFileWasm::getStaticDtorSection( 13732cab237bSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 13742cab237bSDimitry Andric llvm_unreachable("@llvm.global_dtors should have been lowered already"); 13752cab237bSDimitry Andric return nullptr; 13763dac3a9bSDimitry Andric } 1377