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" 55f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.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 64db17bf38SDimitry Andric static void GetObjCImageInfo(ArrayRef<Module::ModuleFlagEntry> ModuleFlags, 65db17bf38SDimitry Andric unsigned &Version, unsigned &Flags, 66db17bf38SDimitry Andric StringRef &Section) { 67db17bf38SDimitry Andric for (const auto &MFE: ModuleFlags) { 68db17bf38SDimitry Andric // Ignore flags with 'Require' behaviour. 69db17bf38SDimitry Andric if (MFE.Behavior == Module::Require) 70db17bf38SDimitry Andric continue; 71db17bf38SDimitry Andric 72db17bf38SDimitry Andric StringRef Key = MFE.Key->getString(); 73db17bf38SDimitry Andric if (Key == "Objective-C Image Info Version") { 74db17bf38SDimitry Andric Version = mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue(); 75db17bf38SDimitry Andric } else if (Key == "Objective-C Garbage Collection" || 76db17bf38SDimitry Andric Key == "Objective-C GC Only" || 77db17bf38SDimitry Andric Key == "Objective-C Is Simulated" || 78db17bf38SDimitry Andric Key == "Objective-C Class Properties" || 79db17bf38SDimitry Andric Key == "Objective-C Image Swift Version") { 80db17bf38SDimitry Andric Flags |= mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue(); 81db17bf38SDimitry Andric } else if (Key == "Objective-C Image Info Section") { 82db17bf38SDimitry Andric Section = cast<MDString>(MFE.Val)->getString(); 83db17bf38SDimitry Andric } 84db17bf38SDimitry Andric } 85db17bf38SDimitry Andric } 86db17bf38SDimitry Andric 87f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 88f22ef01cSRoman Divacky // ELF 89f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 90f22ef01cSRoman Divacky 91db17bf38SDimitry Andric void TargetLoweringObjectFileELF::emitModuleFlags( 92db17bf38SDimitry Andric MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, 93db17bf38SDimitry Andric const TargetMachine &TM) const { 94db17bf38SDimitry Andric unsigned Version = 0; 95db17bf38SDimitry Andric unsigned Flags = 0; 96db17bf38SDimitry Andric StringRef Section; 97db17bf38SDimitry Andric 98db17bf38SDimitry Andric GetObjCImageInfo(ModuleFlags, Version, Flags, Section); 99db17bf38SDimitry Andric if (Section.empty()) 100db17bf38SDimitry Andric return; 101db17bf38SDimitry Andric 102db17bf38SDimitry Andric auto &C = getContext(); 103db17bf38SDimitry Andric auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC); 104db17bf38SDimitry Andric Streamer.SwitchSection(S); 105db17bf38SDimitry Andric Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); 106db17bf38SDimitry Andric Streamer.EmitIntValue(Version, 4); 107db17bf38SDimitry Andric Streamer.EmitIntValue(Flags, 4); 108db17bf38SDimitry Andric Streamer.AddBlankLine(); 109db17bf38SDimitry Andric } 110db17bf38SDimitry Andric 11191bc56edSDimitry Andric MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol( 112d88c1a5aSDimitry Andric const GlobalValue *GV, const TargetMachine &TM, 1133b0f4066SDimitry Andric MachineModuleInfo *MMI) const { 1143b0f4066SDimitry Andric unsigned Encoding = getPersonalityEncoding(); 1157a7e6055SDimitry Andric if ((Encoding & 0x80) == DW_EH_PE_indirect) 116ff0cc061SDimitry Andric return getContext().getOrCreateSymbol(StringRef("DW.ref.") + 117d88c1a5aSDimitry Andric TM.getSymbol(GV)->getName()); 1187a7e6055SDimitry Andric if ((Encoding & 0x70) == DW_EH_PE_absptr) 119d88c1a5aSDimitry Andric return TM.getSymbol(GV); 12091bc56edSDimitry Andric report_fatal_error("We do not support this DWARF encoding yet!"); 1213b0f4066SDimitry Andric } 1223b0f4066SDimitry Andric 1237d523365SDimitry Andric void TargetLoweringObjectFileELF::emitPersonalityValue( 1247d523365SDimitry Andric MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym) const { 12517a519f9SDimitry Andric SmallString<64> NameData("DW.ref."); 12617a519f9SDimitry Andric NameData += Sym->getName(); 12797bc6c73SDimitry Andric MCSymbolELF *Label = 12897bc6c73SDimitry Andric cast<MCSymbolELF>(getContext().getOrCreateSymbol(NameData)); 1293b0f4066SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_Hidden); 1303b0f4066SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_Weak); 1313b0f4066SDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP; 1323ca95b02SDimitry Andric MCSection *Sec = getContext().getELFNamedSection(".data", Label->getName(), 1333ca95b02SDimitry Andric ELF::SHT_PROGBITS, Flags, 0); 1347d523365SDimitry Andric unsigned Size = DL.getPointerSize(); 1353b0f4066SDimitry Andric Streamer.SwitchSection(Sec); 1367d523365SDimitry Andric Streamer.EmitValueToAlignment(DL.getPointerABIAlignment()); 1373b0f4066SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject); 13897bc6c73SDimitry Andric const MCExpr *E = MCConstantExpr::create(Size, getContext()); 13997bc6c73SDimitry Andric Streamer.emitELFSize(Label, E); 1403b0f4066SDimitry Andric Streamer.EmitLabel(Label); 1413b0f4066SDimitry Andric 1423b0f4066SDimitry Andric Streamer.EmitSymbolValue(Sym, Size); 1433b0f4066SDimitry Andric } 1443b0f4066SDimitry Andric 14591bc56edSDimitry Andric const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference( 146d88c1a5aSDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, 147d88c1a5aSDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 1487a7e6055SDimitry Andric if (Encoding & DW_EH_PE_indirect) { 149139f7f9bSDimitry Andric MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>(); 150139f7f9bSDimitry Andric 151d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", TM); 152139f7f9bSDimitry Andric 153139f7f9bSDimitry Andric // Add information about the stub reference to ELFMMI so that the stub 154139f7f9bSDimitry Andric // gets emitted by the asmprinter. 155139f7f9bSDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym); 15691bc56edSDimitry Andric if (!StubSym.getPointer()) { 157d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 158139f7f9bSDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 159139f7f9bSDimitry Andric } 160139f7f9bSDimitry Andric 161139f7f9bSDimitry Andric return TargetLoweringObjectFile:: 16297bc6c73SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), 1637a7e6055SDimitry Andric Encoding & ~DW_EH_PE_indirect, Streamer); 164139f7f9bSDimitry Andric } 165139f7f9bSDimitry Andric 166d88c1a5aSDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM, 167d88c1a5aSDimitry Andric MMI, Streamer); 168139f7f9bSDimitry Andric } 169139f7f9bSDimitry Andric 170f22ef01cSRoman Divacky static SectionKind 171f22ef01cSRoman Divacky getELFKindForNamedSection(StringRef Name, SectionKind K) { 172bd5abe19SDimitry Andric // N.B.: The defaults used in here are no the same ones used in MC. 173bd5abe19SDimitry Andric // We follow gcc, MC follows gas. For example, given ".section .eh_frame", 174bd5abe19SDimitry Andric // both gas and MC will produce a section with no flags. Given 1757ae0e2c9SDimitry Andric // section(".eh_frame") gcc will produce: 1767ae0e2c9SDimitry Andric // 177bd5abe19SDimitry Andric // .section .eh_frame,"a",@progbits 1783ca95b02SDimitry Andric 1797a7e6055SDimitry Andric if (Name == getInstrProfSectionName(IPSK_covmap, Triple::ELF, 1807a7e6055SDimitry Andric /*AddSegmentInfo=*/false)) 1813ca95b02SDimitry Andric return SectionKind::getMetadata(); 1823ca95b02SDimitry Andric 183f22ef01cSRoman Divacky if (Name.empty() || Name[0] != '.') return K; 184f22ef01cSRoman Divacky 185f22ef01cSRoman Divacky // Some lame default implementation based on some magic section names. 186f22ef01cSRoman Divacky if (Name == ".bss" || 187f22ef01cSRoman Divacky Name.startswith(".bss.") || 188f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.b.") || 189f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.b.") || 190f22ef01cSRoman Divacky Name == ".sbss" || 191f22ef01cSRoman Divacky Name.startswith(".sbss.") || 192f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.sb.") || 193f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.sb.")) 194f22ef01cSRoman Divacky return SectionKind::getBSS(); 195f22ef01cSRoman Divacky 196f22ef01cSRoman Divacky if (Name == ".tdata" || 197f22ef01cSRoman Divacky Name.startswith(".tdata.") || 198f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.td.") || 199f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.td.")) 200f22ef01cSRoman Divacky return SectionKind::getThreadData(); 201f22ef01cSRoman Divacky 202f22ef01cSRoman Divacky if (Name == ".tbss" || 203f22ef01cSRoman Divacky Name.startswith(".tbss.") || 204f22ef01cSRoman Divacky Name.startswith(".gnu.linkonce.tb.") || 205f22ef01cSRoman Divacky Name.startswith(".llvm.linkonce.tb.")) 206f22ef01cSRoman Divacky return SectionKind::getThreadBSS(); 207f22ef01cSRoman Divacky 208f22ef01cSRoman Divacky return K; 209f22ef01cSRoman Divacky } 210f22ef01cSRoman Divacky 211f22ef01cSRoman Divacky static unsigned getELFSectionType(StringRef Name, SectionKind K) { 212d88c1a5aSDimitry Andric // Use SHT_NOTE for section whose name starts with ".note" to allow 213d88c1a5aSDimitry Andric // emitting ELF notes from C variable declaration. 214d88c1a5aSDimitry Andric // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77609 215d88c1a5aSDimitry Andric if (Name.startswith(".note")) 216d88c1a5aSDimitry Andric return ELF::SHT_NOTE; 217f22ef01cSRoman Divacky 218f22ef01cSRoman Divacky if (Name == ".init_array") 2192754fe60SDimitry Andric return ELF::SHT_INIT_ARRAY; 220f22ef01cSRoman Divacky 221f22ef01cSRoman Divacky if (Name == ".fini_array") 2222754fe60SDimitry Andric return ELF::SHT_FINI_ARRAY; 223f22ef01cSRoman Divacky 224f22ef01cSRoman Divacky if (Name == ".preinit_array") 2252754fe60SDimitry Andric return ELF::SHT_PREINIT_ARRAY; 226f22ef01cSRoman Divacky 227f22ef01cSRoman Divacky if (K.isBSS() || K.isThreadBSS()) 2282754fe60SDimitry Andric return ELF::SHT_NOBITS; 229f22ef01cSRoman Divacky 2302754fe60SDimitry Andric return ELF::SHT_PROGBITS; 231f22ef01cSRoman Divacky } 232f22ef01cSRoman Divacky 233ff0cc061SDimitry Andric static unsigned getELFSectionFlags(SectionKind K) { 234f22ef01cSRoman Divacky unsigned Flags = 0; 235f22ef01cSRoman Divacky 236f22ef01cSRoman Divacky if (!K.isMetadata()) 2372754fe60SDimitry Andric Flags |= ELF::SHF_ALLOC; 238f22ef01cSRoman Divacky 239f22ef01cSRoman Divacky if (K.isText()) 2402754fe60SDimitry Andric Flags |= ELF::SHF_EXECINSTR; 241f22ef01cSRoman Divacky 242d88c1a5aSDimitry Andric if (K.isExecuteOnly()) 243d88c1a5aSDimitry Andric Flags |= ELF::SHF_ARM_PURECODE; 244d88c1a5aSDimitry Andric 245f22ef01cSRoman Divacky if (K.isWriteable()) 2462754fe60SDimitry Andric Flags |= ELF::SHF_WRITE; 247f22ef01cSRoman Divacky 248f22ef01cSRoman Divacky if (K.isThreadLocal()) 2492754fe60SDimitry Andric Flags |= ELF::SHF_TLS; 250f22ef01cSRoman Divacky 251ff0cc061SDimitry Andric if (K.isMergeableCString() || K.isMergeableConst()) 2522754fe60SDimitry Andric Flags |= ELF::SHF_MERGE; 253f22ef01cSRoman Divacky 254f22ef01cSRoman Divacky if (K.isMergeableCString()) 2552754fe60SDimitry Andric Flags |= ELF::SHF_STRINGS; 256f22ef01cSRoman Divacky 257f22ef01cSRoman Divacky return Flags; 258f22ef01cSRoman Divacky } 259f22ef01cSRoman Divacky 26091bc56edSDimitry Andric static const Comdat *getELFComdat(const GlobalValue *GV) { 26191bc56edSDimitry Andric const Comdat *C = GV->getComdat(); 26291bc56edSDimitry Andric if (!C) 26391bc56edSDimitry Andric return nullptr; 264f22ef01cSRoman Divacky 26591bc56edSDimitry Andric if (C->getSelectionKind() != Comdat::Any) 26691bc56edSDimitry Andric report_fatal_error("ELF COMDATs only support SelectionKind::Any, '" + 26791bc56edSDimitry Andric C->getName() + "' cannot be lowered."); 26891bc56edSDimitry Andric 26991bc56edSDimitry Andric return C; 27091bc56edSDimitry Andric } 27191bc56edSDimitry Andric 2727a7e6055SDimitry Andric static const MCSymbolELF *getAssociatedSymbol(const GlobalObject *GO, 2737a7e6055SDimitry Andric const TargetMachine &TM) { 2747a7e6055SDimitry Andric MDNode *MD = GO->getMetadata(LLVMContext::MD_associated); 2757a7e6055SDimitry Andric if (!MD) 2767a7e6055SDimitry Andric return nullptr; 2777a7e6055SDimitry Andric 2785517e702SDimitry Andric const MDOperand &Op = MD->getOperand(0); 2795517e702SDimitry Andric if (!Op.get()) 2805517e702SDimitry Andric return nullptr; 2815517e702SDimitry Andric 2825517e702SDimitry Andric auto *VM = dyn_cast<ValueAsMetadata>(Op); 2837a7e6055SDimitry Andric if (!VM) 2847a7e6055SDimitry Andric report_fatal_error("MD_associated operand is not ValueAsMetadata"); 2857a7e6055SDimitry Andric 2867a7e6055SDimitry Andric GlobalObject *OtherGO = dyn_cast<GlobalObject>(VM->getValue()); 2877a7e6055SDimitry Andric return OtherGO ? dyn_cast<MCSymbolELF>(TM.getSymbol(OtherGO)) : nullptr; 2887a7e6055SDimitry Andric } 2897a7e6055SDimitry Andric 290ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( 291d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 292d88c1a5aSDimitry Andric StringRef SectionName = GO->getSection(); 293f22ef01cSRoman Divacky 294db17bf38SDimitry Andric // Check if '#pragma clang section' name is applicable. 295db17bf38SDimitry Andric // Note that pragma directive overrides -ffunction-section, -fdata-section 296db17bf38SDimitry Andric // and so section name is exactly as user specified and not uniqued. 297db17bf38SDimitry Andric const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO); 298db17bf38SDimitry Andric if (GV && GV->hasImplicitSection()) { 299db17bf38SDimitry Andric auto Attrs = GV->getAttributes(); 300db17bf38SDimitry Andric if (Attrs.hasAttribute("bss-section") && Kind.isBSS()) { 301db17bf38SDimitry Andric SectionName = Attrs.getAttribute("bss-section").getValueAsString(); 302db17bf38SDimitry Andric } else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) { 303db17bf38SDimitry Andric SectionName = Attrs.getAttribute("rodata-section").getValueAsString(); 304db17bf38SDimitry Andric } else if (Attrs.hasAttribute("data-section") && Kind.isData()) { 305db17bf38SDimitry Andric SectionName = Attrs.getAttribute("data-section").getValueAsString(); 306db17bf38SDimitry Andric } 307db17bf38SDimitry Andric } 308db17bf38SDimitry Andric const Function *F = dyn_cast<Function>(GO); 309db17bf38SDimitry Andric if (F && F->hasFnAttribute("implicit-section-name")) { 310db17bf38SDimitry Andric SectionName = F->getFnAttribute("implicit-section-name").getValueAsString(); 311db17bf38SDimitry Andric } 312db17bf38SDimitry Andric 313f22ef01cSRoman Divacky // Infer section flags from the section name if we can. 314f22ef01cSRoman Divacky Kind = getELFKindForNamedSection(SectionName, Kind); 315f22ef01cSRoman Divacky 31691bc56edSDimitry Andric StringRef Group = ""; 31791bc56edSDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 318d88c1a5aSDimitry Andric if (const Comdat *C = getELFComdat(GO)) { 31991bc56edSDimitry Andric Group = C->getName(); 32091bc56edSDimitry Andric Flags |= ELF::SHF_GROUP; 32191bc56edSDimitry Andric } 3227a7e6055SDimitry Andric 3237a7e6055SDimitry Andric // A section can have at most one associated section. Put each global with 3247a7e6055SDimitry Andric // MD_associated in a unique section. 3257a7e6055SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 3267a7e6055SDimitry Andric const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM); 3277a7e6055SDimitry Andric if (AssociatedSymbol) { 3287a7e6055SDimitry Andric UniqueID = NextUniqueID++; 3297a7e6055SDimitry Andric Flags |= ELF::SHF_LINK_ORDER; 3307a7e6055SDimitry Andric } 3317a7e6055SDimitry Andric 3327a7e6055SDimitry Andric MCSectionELF *Section = getContext().getELFSection( 3337a7e6055SDimitry Andric SectionName, getELFSectionType(SectionName, Kind), Flags, 3347a7e6055SDimitry Andric /*EntrySize=*/0, Group, UniqueID, AssociatedSymbol); 3357a7e6055SDimitry Andric // Make sure that we did not get some other section with incompatible sh_link. 3367a7e6055SDimitry Andric // This should not be possible due to UniqueID code above. 3377a7e6055SDimitry Andric assert(Section->getAssociatedSymbol() == AssociatedSymbol); 3387a7e6055SDimitry Andric return Section; 339f22ef01cSRoman Divacky } 340f22ef01cSRoman Divacky 341ff0cc061SDimitry Andric /// Return the section prefix name used by options FunctionsSections and 342ff0cc061SDimitry Andric /// DataSections. 34391bc56edSDimitry Andric static StringRef getSectionPrefixForGlobal(SectionKind Kind) { 344ff0cc061SDimitry Andric if (Kind.isText()) 345ff0cc061SDimitry Andric return ".text"; 346ff0cc061SDimitry Andric if (Kind.isReadOnly()) 347ff0cc061SDimitry Andric return ".rodata"; 348ff0cc061SDimitry Andric if (Kind.isBSS()) 349ff0cc061SDimitry Andric return ".bss"; 350ff0cc061SDimitry Andric if (Kind.isThreadData()) 351ff0cc061SDimitry Andric return ".tdata"; 352ff0cc061SDimitry Andric if (Kind.isThreadBSS()) 353ff0cc061SDimitry Andric return ".tbss"; 3547d523365SDimitry Andric if (Kind.isData()) 355ff0cc061SDimitry Andric return ".data"; 356f22ef01cSRoman Divacky assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); 357ff0cc061SDimitry Andric return ".data.rel.ro"; 358f22ef01cSRoman Divacky } 359f22ef01cSRoman Divacky 3607a7e6055SDimitry Andric static MCSectionELF *selectELFSectionForGlobal( 3617a7e6055SDimitry Andric MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang, 3627a7e6055SDimitry Andric const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags, 3637a7e6055SDimitry Andric unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) { 364ff0cc061SDimitry Andric unsigned EntrySize = 0; 365ff0cc061SDimitry Andric if (Kind.isMergeableCString()) { 366ff0cc061SDimitry Andric if (Kind.isMergeable2ByteCString()) { 367ff0cc061SDimitry Andric EntrySize = 2; 368ff0cc061SDimitry Andric } else if (Kind.isMergeable4ByteCString()) { 369ff0cc061SDimitry Andric EntrySize = 4; 370ff0cc061SDimitry Andric } else { 371ff0cc061SDimitry Andric EntrySize = 1; 372ff0cc061SDimitry Andric assert(Kind.isMergeable1ByteCString() && "unknown string width"); 373ff0cc061SDimitry Andric } 374ff0cc061SDimitry Andric } else if (Kind.isMergeableConst()) { 375ff0cc061SDimitry Andric if (Kind.isMergeableConst4()) { 376ff0cc061SDimitry Andric EntrySize = 4; 377ff0cc061SDimitry Andric } else if (Kind.isMergeableConst8()) { 378ff0cc061SDimitry Andric EntrySize = 8; 3793ca95b02SDimitry Andric } else if (Kind.isMergeableConst16()) { 380ff0cc061SDimitry Andric EntrySize = 16; 3813ca95b02SDimitry Andric } else { 3823ca95b02SDimitry Andric assert(Kind.isMergeableConst32() && "unknown data width"); 3833ca95b02SDimitry Andric EntrySize = 32; 384ff0cc061SDimitry Andric } 385ff0cc061SDimitry Andric } 38691bc56edSDimitry Andric 3872754fe60SDimitry Andric StringRef Group = ""; 388d88c1a5aSDimitry Andric if (const Comdat *C = getELFComdat(GO)) { 3892754fe60SDimitry Andric Flags |= ELF::SHF_GROUP; 390ff0cc061SDimitry Andric Group = C->getName(); 3912754fe60SDimitry Andric } 3922754fe60SDimitry Andric 393ff0cc061SDimitry Andric bool UniqueSectionNames = TM.getUniqueSectionNames(); 394ff0cc061SDimitry Andric SmallString<128> Name; 395ff0cc061SDimitry Andric if (Kind.isMergeableCString()) { 396f22ef01cSRoman Divacky // We also need alignment here. 397f22ef01cSRoman Divacky // FIXME: this is getting the alignment of the character, not the 398f22ef01cSRoman Divacky // alignment of the global! 399d88c1a5aSDimitry Andric unsigned Align = GO->getParent()->getDataLayout().getPreferredAlignment( 400d88c1a5aSDimitry Andric cast<GlobalVariable>(GO)); 401f22ef01cSRoman Divacky 402ff0cc061SDimitry Andric std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + "."; 403ff0cc061SDimitry Andric Name = SizeSpec + utostr(Align); 404ff0cc061SDimitry Andric } else if (Kind.isMergeableConst()) { 405ff0cc061SDimitry Andric Name = ".rodata.cst"; 406ff0cc061SDimitry Andric Name += utostr(EntrySize); 407ff0cc061SDimitry Andric } else { 408ff0cc061SDimitry Andric Name = getSectionPrefixForGlobal(Kind); 409ff0cc061SDimitry Andric } 410d88c1a5aSDimitry Andric 411d88c1a5aSDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) { 412d88c1a5aSDimitry Andric const auto &OptionalPrefix = F->getSectionPrefix(); 413d88c1a5aSDimitry Andric if (OptionalPrefix) 414d88c1a5aSDimitry Andric Name += *OptionalPrefix; 415d88c1a5aSDimitry Andric } 416ff0cc061SDimitry Andric 417ff0cc061SDimitry Andric if (EmitUniqueSection && UniqueSectionNames) { 418ff0cc061SDimitry Andric Name.push_back('.'); 419d88c1a5aSDimitry Andric TM.getNameWithPrefix(Name, GO, Mang, true); 420ff0cc061SDimitry Andric } 4213ca95b02SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 422ff0cc061SDimitry Andric if (EmitUniqueSection && !UniqueSectionNames) { 423ff0cc061SDimitry Andric UniqueID = *NextUniqueID; 424ff0cc061SDimitry Andric (*NextUniqueID)++; 425ff0cc061SDimitry Andric } 426d88c1a5aSDimitry Andric // Use 0 as the unique ID for execute-only text 427d88c1a5aSDimitry Andric if (Kind.isExecuteOnly()) 428d88c1a5aSDimitry Andric UniqueID = 0; 429ff0cc061SDimitry Andric return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags, 4307a7e6055SDimitry Andric EntrySize, Group, UniqueID, AssociatedSymbol); 431ff0cc061SDimitry Andric } 432ff0cc061SDimitry Andric 433ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( 434d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 435ff0cc061SDimitry Andric unsigned Flags = getELFSectionFlags(Kind); 436ff0cc061SDimitry Andric 437ff0cc061SDimitry Andric // If we have -ffunction-section or -fdata-section then we should emit the 438ff0cc061SDimitry Andric // global value to a uniqued section specifically for it. 439ff0cc061SDimitry Andric bool EmitUniqueSection = false; 440ff0cc061SDimitry Andric if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) { 441ff0cc061SDimitry Andric if (Kind.isText()) 442ff0cc061SDimitry Andric EmitUniqueSection = TM.getFunctionSections(); 443f22ef01cSRoman Divacky else 444ff0cc061SDimitry Andric EmitUniqueSection = TM.getDataSections(); 445ff0cc061SDimitry Andric } 446d88c1a5aSDimitry Andric EmitUniqueSection |= GO->hasComdat(); 447f22ef01cSRoman Divacky 4487a7e6055SDimitry Andric const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM); 4497a7e6055SDimitry Andric if (AssociatedSymbol) { 4507a7e6055SDimitry Andric EmitUniqueSection = true; 4517a7e6055SDimitry Andric Flags |= ELF::SHF_LINK_ORDER; 4527a7e6055SDimitry Andric } 4537a7e6055SDimitry Andric 4547a7e6055SDimitry Andric MCSectionELF *Section = selectELFSectionForGlobal( 4557a7e6055SDimitry Andric getContext(), GO, Kind, getMangler(), TM, EmitUniqueSection, Flags, 4567a7e6055SDimitry Andric &NextUniqueID, AssociatedSymbol); 4577a7e6055SDimitry Andric assert(Section->getAssociatedSymbol() == AssociatedSymbol); 4587a7e6055SDimitry Andric return Section; 459f22ef01cSRoman Divacky } 460f22ef01cSRoman Divacky 461ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( 462d88c1a5aSDimitry Andric const Function &F, const TargetMachine &TM) const { 463ff0cc061SDimitry Andric // If the function can be removed, produce a unique section so that 464ff0cc061SDimitry Andric // the table doesn't prevent the removal. 465ff0cc061SDimitry Andric const Comdat *C = F.getComdat(); 466ff0cc061SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C; 467ff0cc061SDimitry Andric if (!EmitUniqueSection) 468ff0cc061SDimitry Andric return ReadOnlySection; 469ff0cc061SDimitry Andric 470ff0cc061SDimitry Andric return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(), 4717a7e6055SDimitry Andric getMangler(), TM, EmitUniqueSection, 4727a7e6055SDimitry Andric ELF::SHF_ALLOC, &NextUniqueID, 4737a7e6055SDimitry Andric /* AssociatedSymbol */ nullptr); 474f22ef01cSRoman Divacky } 475f22ef01cSRoman Divacky 476ff0cc061SDimitry Andric bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection( 477ff0cc061SDimitry Andric bool UsesLabelDifference, const Function &F) const { 478ff0cc061SDimitry Andric // We can always create relative relocations, so use another section 479ff0cc061SDimitry Andric // that can be marked non-executable. 480ff0cc061SDimitry Andric return false; 481f22ef01cSRoman Divacky } 482f22ef01cSRoman Divacky 483ff0cc061SDimitry Andric /// Given a mergeable constant with the specified size and relocation 484ff0cc061SDimitry Andric /// information, return a section that it should be placed in. 4857d523365SDimitry Andric MCSection *TargetLoweringObjectFileELF::getSectionForConstant( 4863ca95b02SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 4873ca95b02SDimitry Andric unsigned &Align) const { 488f22ef01cSRoman Divacky if (Kind.isMergeableConst4() && MergeableConst4Section) 489f22ef01cSRoman Divacky return MergeableConst4Section; 490f22ef01cSRoman Divacky if (Kind.isMergeableConst8() && MergeableConst8Section) 491f22ef01cSRoman Divacky return MergeableConst8Section; 492f22ef01cSRoman Divacky if (Kind.isMergeableConst16() && MergeableConst16Section) 493f22ef01cSRoman Divacky return MergeableConst16Section; 4943ca95b02SDimitry Andric if (Kind.isMergeableConst32() && MergeableConst32Section) 4953ca95b02SDimitry Andric return MergeableConst32Section; 496f22ef01cSRoman Divacky if (Kind.isReadOnly()) 497f22ef01cSRoman Divacky return ReadOnlySection; 498f22ef01cSRoman Divacky 499f22ef01cSRoman Divacky assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); 500f22ef01cSRoman Divacky return DataRelROSection; 501f22ef01cSRoman Divacky } 502f22ef01cSRoman Divacky 503ff0cc061SDimitry Andric static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray, 504ff0cc061SDimitry Andric bool IsCtor, unsigned Priority, 50539d628a0SDimitry Andric const MCSymbol *KeySym) { 50639d628a0SDimitry Andric std::string Name; 50739d628a0SDimitry Andric unsigned Type; 50839d628a0SDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE; 50939d628a0SDimitry Andric StringRef COMDAT = KeySym ? KeySym->getName() : ""; 51039d628a0SDimitry Andric 51139d628a0SDimitry Andric if (KeySym) 51239d628a0SDimitry Andric Flags |= ELF::SHF_GROUP; 513dff0c46cSDimitry Andric 5147ae0e2c9SDimitry Andric if (UseInitArray) { 51539d628a0SDimitry Andric if (IsCtor) { 51639d628a0SDimitry Andric Type = ELF::SHT_INIT_ARRAY; 51739d628a0SDimitry Andric Name = ".init_array"; 5187ae0e2c9SDimitry Andric } else { 51939d628a0SDimitry Andric Type = ELF::SHT_FINI_ARRAY; 52039d628a0SDimitry Andric Name = ".fini_array"; 521dff0c46cSDimitry Andric } 52239d628a0SDimitry Andric if (Priority != 65535) { 52339d628a0SDimitry Andric Name += '.'; 52439d628a0SDimitry Andric Name += utostr(Priority); 52539d628a0SDimitry Andric } 52639d628a0SDimitry Andric } else { 52739d628a0SDimitry Andric // The default scheme is .ctor / .dtor, so we have to invert the priority 52839d628a0SDimitry Andric // numbering. 52939d628a0SDimitry Andric if (IsCtor) 53039d628a0SDimitry Andric Name = ".ctors"; 53139d628a0SDimitry Andric else 53239d628a0SDimitry Andric Name = ".dtors"; 53339d628a0SDimitry Andric if (Priority != 65535) { 53439d628a0SDimitry Andric Name += '.'; 53539d628a0SDimitry Andric Name += utostr(65535 - Priority); 53639d628a0SDimitry Andric } 53739d628a0SDimitry Andric Type = ELF::SHT_PROGBITS; 53839d628a0SDimitry Andric } 53939d628a0SDimitry Andric 540ff0cc061SDimitry Andric return Ctx.getELFSection(Name, Type, Flags, 0, COMDAT); 54139d628a0SDimitry Andric } 54239d628a0SDimitry Andric 543ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticCtorSection( 54439d628a0SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 54539d628a0SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, true, Priority, 54639d628a0SDimitry Andric KeySym); 5477ae0e2c9SDimitry Andric } 548dff0c46cSDimitry Andric 549ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticDtorSection( 55091bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 55139d628a0SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, false, Priority, 55239d628a0SDimitry Andric KeySym); 5537ae0e2c9SDimitry Andric } 5547ae0e2c9SDimitry Andric 5553ca95b02SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference( 556d88c1a5aSDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 5573ca95b02SDimitry Andric const TargetMachine &TM) const { 5583ca95b02SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr 5593ca95b02SDimitry Andric // functions. 5603ca95b02SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) 5613ca95b02SDimitry Andric return nullptr; 5623ca95b02SDimitry Andric 5633ca95b02SDimitry Andric // Basic sanity checks. 5643ca95b02SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 5653ca95b02SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || 5663ca95b02SDimitry Andric RHS->isThreadLocal()) 5673ca95b02SDimitry Andric return nullptr; 5683ca95b02SDimitry Andric 5693ca95b02SDimitry Andric return MCBinaryExpr::createSub( 570d88c1a5aSDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS), PLTRelativeVariantKind, 5713ca95b02SDimitry Andric getContext()), 572d88c1a5aSDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); 5733ca95b02SDimitry Andric } 5743ca95b02SDimitry Andric 5757ae0e2c9SDimitry Andric void 5767ae0e2c9SDimitry Andric TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) { 5777ae0e2c9SDimitry Andric UseInitArray = UseInitArray_; 578d88c1a5aSDimitry Andric MCContext &Ctx = getContext(); 579d88c1a5aSDimitry Andric if (!UseInitArray) { 580d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getELFSection(".ctors", ELF::SHT_PROGBITS, 581d88c1a5aSDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE); 5827ae0e2c9SDimitry Andric 583d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getELFSection(".dtors", ELF::SHT_PROGBITS, 584d88c1a5aSDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE); 585d88c1a5aSDimitry Andric return; 586d88c1a5aSDimitry Andric } 587d88c1a5aSDimitry Andric 588d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getELFSection(".init_array", ELF::SHT_INIT_ARRAY, 589d88c1a5aSDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC); 590d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getELFSection(".fini_array", ELF::SHT_FINI_ARRAY, 591d88c1a5aSDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC); 5927ae0e2c9SDimitry Andric } 593dff0c46cSDimitry Andric 594f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 595f22ef01cSRoman Divacky // MachO 596f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 597f22ef01cSRoman Divacky 598ff0cc061SDimitry Andric TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO() 599ff0cc061SDimitry Andric : TargetLoweringObjectFile() { 600ff0cc061SDimitry Andric SupportIndirectSymViaGOTPCRel = true; 601ff0cc061SDimitry Andric } 602ff0cc061SDimitry Andric 603d88c1a5aSDimitry Andric void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx, 604d88c1a5aSDimitry Andric const TargetMachine &TM) { 605d88c1a5aSDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM); 606d88c1a5aSDimitry Andric if (TM.getRelocationModel() == Reloc::Static) { 607d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getMachOSection("__TEXT", "__constructor", 0, 608d88c1a5aSDimitry Andric SectionKind::getData()); 609d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getMachOSection("__TEXT", "__destructor", 0, 610d88c1a5aSDimitry Andric SectionKind::getData()); 611d88c1a5aSDimitry Andric } else { 612d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getMachOSection("__DATA", "__mod_init_func", 613d88c1a5aSDimitry Andric MachO::S_MOD_INIT_FUNC_POINTERS, 614d88c1a5aSDimitry Andric SectionKind::getData()); 615d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getMachOSection("__DATA", "__mod_term_func", 616d88c1a5aSDimitry Andric MachO::S_MOD_TERM_FUNC_POINTERS, 617d88c1a5aSDimitry Andric SectionKind::getData()); 618d88c1a5aSDimitry Andric } 619d88c1a5aSDimitry Andric } 620d88c1a5aSDimitry Andric 621139f7f9bSDimitry Andric /// emitModuleFlags - Perform code emission for module flags. 622d88c1a5aSDimitry Andric void TargetLoweringObjectFileMachO::emitModuleFlags( 623d88c1a5aSDimitry Andric MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, 624d88c1a5aSDimitry Andric const TargetMachine &TM) const { 62591bc56edSDimitry Andric MDNode *LinkerOptions = nullptr; 626dff0c46cSDimitry Andric 6273ca95b02SDimitry Andric for (const auto &MFE : ModuleFlags) { 628dff0c46cSDimitry Andric StringRef Key = MFE.Key->getString(); 629db17bf38SDimitry Andric if (Key == "Linker Options") 630db17bf38SDimitry Andric LinkerOptions = cast<MDNode>(MFE.Val); 631139f7f9bSDimitry Andric } 632139f7f9bSDimitry Andric 633139f7f9bSDimitry Andric // Emit the linker options if present. 634139f7f9bSDimitry Andric if (LinkerOptions) { 6353ca95b02SDimitry Andric for (const auto &Option : LinkerOptions->operands()) { 636139f7f9bSDimitry Andric SmallVector<std::string, 4> StrOptions; 6373ca95b02SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) 6383ca95b02SDimitry Andric StrOptions.push_back(cast<MDString>(Piece)->getString()); 639139f7f9bSDimitry Andric Streamer.EmitLinkerOptions(StrOptions); 640139f7f9bSDimitry Andric } 641dff0c46cSDimitry Andric } 642dff0c46cSDimitry Andric 643db17bf38SDimitry Andric unsigned VersionVal = 0; 644db17bf38SDimitry Andric unsigned ImageInfoFlags = 0; 645db17bf38SDimitry Andric StringRef SectionVal; 646db17bf38SDimitry Andric GetObjCImageInfo(ModuleFlags, VersionVal, ImageInfoFlags, SectionVal); 647db17bf38SDimitry Andric 648dff0c46cSDimitry Andric // The section is mandatory. If we don't have it, then we don't have GC info. 649db17bf38SDimitry Andric if (SectionVal.empty()) 650db17bf38SDimitry Andric return; 651dff0c46cSDimitry Andric 652dff0c46cSDimitry Andric StringRef Segment, Section; 653dff0c46cSDimitry Andric unsigned TAA = 0, StubSize = 0; 654dff0c46cSDimitry Andric bool TAAParsed; 655dff0c46cSDimitry Andric std::string ErrorCode = 656dff0c46cSDimitry Andric MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section, 657dff0c46cSDimitry Andric TAA, TAAParsed, StubSize); 658dff0c46cSDimitry Andric if (!ErrorCode.empty()) 659dff0c46cSDimitry Andric // If invalid, report the error with report_fatal_error. 660dff0c46cSDimitry Andric report_fatal_error("Invalid section specifier '" + Section + "': " + 661dff0c46cSDimitry Andric ErrorCode + "."); 662dff0c46cSDimitry Andric 663dff0c46cSDimitry Andric // Get the section. 664ff0cc061SDimitry Andric MCSectionMachO *S = getContext().getMachOSection( 6657d523365SDimitry Andric Segment, Section, TAA, StubSize, SectionKind::getData()); 666dff0c46cSDimitry Andric Streamer.SwitchSection(S); 667dff0c46cSDimitry Andric Streamer.EmitLabel(getContext(). 668ff0cc061SDimitry Andric getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); 669dff0c46cSDimitry Andric Streamer.EmitIntValue(VersionVal, 4); 6707ae0e2c9SDimitry Andric Streamer.EmitIntValue(ImageInfoFlags, 4); 671dff0c46cSDimitry Andric Streamer.AddBlankLine(); 672dff0c46cSDimitry Andric } 673dff0c46cSDimitry Andric 67491bc56edSDimitry Andric static void checkMachOComdat(const GlobalValue *GV) { 67591bc56edSDimitry Andric const Comdat *C = GV->getComdat(); 67691bc56edSDimitry Andric if (!C) 67791bc56edSDimitry Andric return; 67891bc56edSDimitry Andric 67991bc56edSDimitry Andric report_fatal_error("MachO doesn't support COMDATs, '" + C->getName() + 68091bc56edSDimitry Andric "' cannot be lowered."); 68191bc56edSDimitry Andric } 68291bc56edSDimitry Andric 683ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( 684d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 685f22ef01cSRoman Divacky // Parse the section specifier and create it if valid. 686f22ef01cSRoman Divacky StringRef Segment, Section; 6873b0f4066SDimitry Andric unsigned TAA = 0, StubSize = 0; 6883b0f4066SDimitry Andric bool TAAParsed; 68991bc56edSDimitry Andric 690d88c1a5aSDimitry Andric checkMachOComdat(GO); 69191bc56edSDimitry Andric 692f22ef01cSRoman Divacky std::string ErrorCode = 693d88c1a5aSDimitry Andric MCSectionMachO::ParseSectionSpecifier(GO->getSection(), Segment, Section, 6943b0f4066SDimitry Andric TAA, TAAParsed, StubSize); 695f22ef01cSRoman Divacky if (!ErrorCode.empty()) { 696f22ef01cSRoman Divacky // If invalid, report the error with report_fatal_error. 697d88c1a5aSDimitry Andric report_fatal_error("Global variable '" + GO->getName() + 698dff0c46cSDimitry Andric "' has an invalid section specifier '" + 699d88c1a5aSDimitry Andric GO->getSection() + "': " + ErrorCode + "."); 700f22ef01cSRoman Divacky } 701f22ef01cSRoman Divacky 702f22ef01cSRoman Divacky // Get the section. 703ff0cc061SDimitry Andric MCSectionMachO *S = 704f22ef01cSRoman Divacky getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind); 705f22ef01cSRoman Divacky 706dd6029ffSDimitry Andric // If TAA wasn't set by ParseSectionSpecifier() above, 707dd6029ffSDimitry Andric // use the value returned by getMachOSection() as a default. 7083b0f4066SDimitry Andric if (!TAAParsed) 709dd6029ffSDimitry Andric TAA = S->getTypeAndAttributes(); 710dd6029ffSDimitry Andric 711f22ef01cSRoman Divacky // Okay, now that we got the section, verify that the TAA & StubSize agree. 712f22ef01cSRoman Divacky // If the user declared multiple globals with different section flags, we need 713f22ef01cSRoman Divacky // to reject it here. 714f22ef01cSRoman Divacky if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) { 715f22ef01cSRoman Divacky // If invalid, report the error with report_fatal_error. 716d88c1a5aSDimitry Andric report_fatal_error("Global variable '" + GO->getName() + 717f22ef01cSRoman Divacky "' section type or attributes does not match previous" 718f22ef01cSRoman Divacky " section specifier"); 719f22ef01cSRoman Divacky } 720f22ef01cSRoman Divacky 721f22ef01cSRoman Divacky return S; 722f22ef01cSRoman Divacky } 723f22ef01cSRoman Divacky 724ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal( 725d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 726d88c1a5aSDimitry Andric checkMachOComdat(GO); 727f785676fSDimitry Andric 728f785676fSDimitry Andric // Handle thread local data. 729f785676fSDimitry Andric if (Kind.isThreadBSS()) return TLSBSSSection; 730f785676fSDimitry Andric if (Kind.isThreadData()) return TLSDataSection; 731f785676fSDimitry Andric 732f22ef01cSRoman Divacky if (Kind.isText()) 733d88c1a5aSDimitry Andric return GO->isWeakForLinker() ? TextCoalSection : TextSection; 734f22ef01cSRoman Divacky 735f22ef01cSRoman Divacky // If this is weak/linkonce, put this in a coalescable section, either in text 736f22ef01cSRoman Divacky // or data depending on if it is writable. 737d88c1a5aSDimitry Andric if (GO->isWeakForLinker()) { 738f22ef01cSRoman Divacky if (Kind.isReadOnly()) 739f22ef01cSRoman Divacky return ConstTextCoalSection; 740f22ef01cSRoman Divacky return DataCoalSection; 741f22ef01cSRoman Divacky } 742f22ef01cSRoman Divacky 743f22ef01cSRoman Divacky // FIXME: Alignment check should be handled by section classifier. 744f22ef01cSRoman Divacky if (Kind.isMergeable1ByteCString() && 745d88c1a5aSDimitry Andric GO->getParent()->getDataLayout().getPreferredAlignment( 746d88c1a5aSDimitry Andric cast<GlobalVariable>(GO)) < 32) 747f22ef01cSRoman Divacky return CStringSection; 748f22ef01cSRoman Divacky 749f22ef01cSRoman Divacky // Do not put 16-bit arrays in the UString section if they have an 750f22ef01cSRoman Divacky // externally visible label, this runs into issues with certain linker 751f22ef01cSRoman Divacky // versions. 752d88c1a5aSDimitry Andric if (Kind.isMergeable2ByteCString() && !GO->hasExternalLinkage() && 753d88c1a5aSDimitry Andric GO->getParent()->getDataLayout().getPreferredAlignment( 754d88c1a5aSDimitry Andric cast<GlobalVariable>(GO)) < 32) 755f22ef01cSRoman Divacky return UStringSection; 756f22ef01cSRoman Divacky 75739d628a0SDimitry Andric // With MachO only variables whose corresponding symbol starts with 'l' or 75839d628a0SDimitry Andric // 'L' can be merged, so we only try merging GVs with private linkage. 759d88c1a5aSDimitry Andric if (GO->hasPrivateLinkage() && Kind.isMergeableConst()) { 760f22ef01cSRoman Divacky if (Kind.isMergeableConst4()) 761f22ef01cSRoman Divacky return FourByteConstantSection; 762f22ef01cSRoman Divacky if (Kind.isMergeableConst8()) 763f22ef01cSRoman Divacky return EightByteConstantSection; 76491bc56edSDimitry Andric if (Kind.isMergeableConst16()) 765f22ef01cSRoman Divacky return SixteenByteConstantSection; 766f22ef01cSRoman Divacky } 767f22ef01cSRoman Divacky 768f22ef01cSRoman Divacky // Otherwise, if it is readonly, but not something we can specially optimize, 769f22ef01cSRoman Divacky // just drop it in .const. 770f22ef01cSRoman Divacky if (Kind.isReadOnly()) 771f22ef01cSRoman Divacky return ReadOnlySection; 772f22ef01cSRoman Divacky 773f22ef01cSRoman Divacky // If this is marked const, put it into a const section. But if the dynamic 774f22ef01cSRoman Divacky // linker needs to write to it, put it in the data segment. 775f22ef01cSRoman Divacky if (Kind.isReadOnlyWithRel()) 776f22ef01cSRoman Divacky return ConstDataSection; 777f22ef01cSRoman Divacky 778f22ef01cSRoman Divacky // Put zero initialized globals with strong external linkage in the 779f22ef01cSRoman Divacky // DATA, __common section with the .zerofill directive. 780f22ef01cSRoman Divacky if (Kind.isBSSExtern()) 781f22ef01cSRoman Divacky return DataCommonSection; 782f22ef01cSRoman Divacky 783f22ef01cSRoman Divacky // Put zero initialized globals with local linkage in __DATA,__bss directive 784f22ef01cSRoman Divacky // with the .zerofill directive (aka .lcomm). 785f22ef01cSRoman Divacky if (Kind.isBSSLocal()) 786f22ef01cSRoman Divacky return DataBSSSection; 787f22ef01cSRoman Divacky 788f22ef01cSRoman Divacky // Otherwise, just drop the variable in the normal data section. 789f22ef01cSRoman Divacky return DataSection; 790f22ef01cSRoman Divacky } 791f22ef01cSRoman Divacky 7927d523365SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getSectionForConstant( 7933ca95b02SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 7943ca95b02SDimitry Andric unsigned &Align) const { 795f22ef01cSRoman Divacky // If this constant requires a relocation, we have to put it in the data 796f22ef01cSRoman Divacky // segment, not in the text segment. 7977d523365SDimitry Andric if (Kind.isData() || Kind.isReadOnlyWithRel()) 798f22ef01cSRoman Divacky return ConstDataSection; 799f22ef01cSRoman Divacky 800f22ef01cSRoman Divacky if (Kind.isMergeableConst4()) 801f22ef01cSRoman Divacky return FourByteConstantSection; 802f22ef01cSRoman Divacky if (Kind.isMergeableConst8()) 803f22ef01cSRoman Divacky return EightByteConstantSection; 80491bc56edSDimitry Andric if (Kind.isMergeableConst16()) 805f22ef01cSRoman Divacky return SixteenByteConstantSection; 806f22ef01cSRoman Divacky return ReadOnlySection; // .const 807f22ef01cSRoman Divacky } 808f22ef01cSRoman Divacky 80991bc56edSDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference( 810d88c1a5aSDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, 811d88c1a5aSDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 812f22ef01cSRoman Divacky // The mach-o version of this method defaults to returning a stub reference. 813f22ef01cSRoman Divacky 814f22ef01cSRoman Divacky if (Encoding & DW_EH_PE_indirect) { 815f22ef01cSRoman Divacky MachineModuleInfoMachO &MachOMMI = 816f22ef01cSRoman Divacky MMI->getObjFileInfo<MachineModuleInfoMachO>(); 817f22ef01cSRoman Divacky 818d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); 819f22ef01cSRoman Divacky 820f22ef01cSRoman Divacky // Add information about the stub reference to MachOMMI so that the stub 821f22ef01cSRoman Divacky // gets emitted by the asmprinter. 8223ca95b02SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 82391bc56edSDimitry Andric if (!StubSym.getPointer()) { 824d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 825f22ef01cSRoman Divacky StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 826f22ef01cSRoman Divacky } 827f22ef01cSRoman Divacky 828f22ef01cSRoman Divacky return TargetLoweringObjectFile:: 82997bc6c73SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), 8307a7e6055SDimitry Andric Encoding & ~DW_EH_PE_indirect, Streamer); 831f22ef01cSRoman Divacky } 832f22ef01cSRoman Divacky 833d88c1a5aSDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM, 834d88c1a5aSDimitry Andric MMI, Streamer); 835f22ef01cSRoman Divacky } 836f22ef01cSRoman Divacky 83791bc56edSDimitry Andric MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol( 838d88c1a5aSDimitry Andric const GlobalValue *GV, const TargetMachine &TM, 8393b0f4066SDimitry Andric MachineModuleInfo *MMI) const { 8403b0f4066SDimitry Andric // The mach-o version of this method defaults to returning a stub reference. 8413b0f4066SDimitry Andric MachineModuleInfoMachO &MachOMMI = 8423b0f4066SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 8433b0f4066SDimitry Andric 844d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); 8453b0f4066SDimitry Andric 8463b0f4066SDimitry Andric // Add information about the stub reference to MachOMMI so that the stub 8473b0f4066SDimitry Andric // gets emitted by the asmprinter. 848dff0c46cSDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 84991bc56edSDimitry Andric if (!StubSym.getPointer()) { 850d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 8513b0f4066SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 8523b0f4066SDimitry Andric } 8533b0f4066SDimitry Andric 8543b0f4066SDimitry Andric return SSym; 8553b0f4066SDimitry Andric } 8563b0f4066SDimitry Andric 857ff0cc061SDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel( 858ff0cc061SDimitry Andric const MCSymbol *Sym, const MCValue &MV, int64_t Offset, 859ff0cc061SDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 8607d523365SDimitry Andric // Although MachO 32-bit targets do not explicitly have a GOTPCREL relocation 861ff0cc061SDimitry Andric // as 64-bit do, we replace the GOT equivalent by accessing the final symbol 862ff0cc061SDimitry Andric // through a non_lazy_ptr stub instead. One advantage is that it allows the 863ff0cc061SDimitry Andric // computation of deltas to final external symbols. Example: 864ff0cc061SDimitry Andric // 865ff0cc061SDimitry Andric // _extgotequiv: 866ff0cc061SDimitry Andric // .long _extfoo 867ff0cc061SDimitry Andric // 868ff0cc061SDimitry Andric // _delta: 869ff0cc061SDimitry Andric // .long _extgotequiv-_delta 870ff0cc061SDimitry Andric // 871ff0cc061SDimitry Andric // is transformed to: 872ff0cc061SDimitry Andric // 873ff0cc061SDimitry Andric // _delta: 874ff0cc061SDimitry Andric // .long L_extfoo$non_lazy_ptr-(_delta+0) 875ff0cc061SDimitry Andric // 876ff0cc061SDimitry Andric // .section __IMPORT,__pointers,non_lazy_symbol_pointers 877ff0cc061SDimitry Andric // L_extfoo$non_lazy_ptr: 878ff0cc061SDimitry Andric // .indirect_symbol _extfoo 879ff0cc061SDimitry Andric // .long 0 880ff0cc061SDimitry Andric // 881ff0cc061SDimitry Andric MachineModuleInfoMachO &MachOMMI = 882ff0cc061SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 883ff0cc061SDimitry Andric MCContext &Ctx = getContext(); 884ff0cc061SDimitry Andric 885ff0cc061SDimitry Andric // The offset must consider the original displacement from the base symbol 886ff0cc061SDimitry Andric // since 32-bit targets don't have a GOTPCREL to fold the PC displacement. 887ff0cc061SDimitry Andric Offset = -MV.getConstant(); 888ff0cc061SDimitry Andric const MCSymbol *BaseSym = &MV.getSymB()->getSymbol(); 889ff0cc061SDimitry Andric 890ff0cc061SDimitry Andric // Access the final symbol via sym$non_lazy_ptr and generate the appropriated 891ff0cc061SDimitry Andric // non_lazy_ptr stubs. 892ff0cc061SDimitry Andric SmallString<128> Name; 893ff0cc061SDimitry Andric StringRef Suffix = "$non_lazy_ptr"; 8947d523365SDimitry Andric Name += MMI->getModule()->getDataLayout().getPrivateGlobalPrefix(); 895ff0cc061SDimitry Andric Name += Sym->getName(); 896ff0cc061SDimitry Andric Name += Suffix; 897ff0cc061SDimitry Andric MCSymbol *Stub = Ctx.getOrCreateSymbol(Name); 898ff0cc061SDimitry Andric 899ff0cc061SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub); 900ff0cc061SDimitry Andric if (!StubSym.getPointer()) 901ff0cc061SDimitry Andric StubSym = MachineModuleInfoImpl:: 902ff0cc061SDimitry Andric StubValueTy(const_cast<MCSymbol *>(Sym), true /* access indirectly */); 903ff0cc061SDimitry Andric 904ff0cc061SDimitry Andric const MCExpr *BSymExpr = 90597bc6c73SDimitry Andric MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx); 906ff0cc061SDimitry Andric const MCExpr *LHS = 90797bc6c73SDimitry Andric MCSymbolRefExpr::create(Stub, MCSymbolRefExpr::VK_None, Ctx); 908ff0cc061SDimitry Andric 909ff0cc061SDimitry Andric if (!Offset) 91097bc6c73SDimitry Andric return MCBinaryExpr::createSub(LHS, BSymExpr, Ctx); 911ff0cc061SDimitry Andric 912ff0cc061SDimitry Andric const MCExpr *RHS = 91397bc6c73SDimitry Andric MCBinaryExpr::createAdd(BSymExpr, MCConstantExpr::create(Offset, Ctx), Ctx); 91497bc6c73SDimitry Andric return MCBinaryExpr::createSub(LHS, RHS, Ctx); 915ff0cc061SDimitry Andric } 916ff0cc061SDimitry Andric 9177d523365SDimitry Andric static bool canUsePrivateLabel(const MCAsmInfo &AsmInfo, 9187d523365SDimitry Andric const MCSection &Section) { 9197d523365SDimitry Andric if (!AsmInfo.isSectionAtomizableBySymbols(Section)) 9207d523365SDimitry Andric return true; 9217d523365SDimitry Andric 9227d523365SDimitry Andric // If it is not dead stripped, it is safe to use private labels. 9237d523365SDimitry Andric const MCSectionMachO &SMO = cast<MCSectionMachO>(Section); 9247d523365SDimitry Andric if (SMO.hasAttribute(MachO::S_ATTR_NO_DEAD_STRIP)) 9257d523365SDimitry Andric return true; 9267d523365SDimitry Andric 9277d523365SDimitry Andric return false; 9287d523365SDimitry Andric } 9297d523365SDimitry Andric 9307d523365SDimitry Andric void TargetLoweringObjectFileMachO::getNameWithPrefix( 931d88c1a5aSDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, 9327d523365SDimitry Andric const TargetMachine &TM) const { 933d88c1a5aSDimitry Andric bool CannotUsePrivateLabel = true; 934d88c1a5aSDimitry Andric if (auto *GO = GV->getBaseObject()) { 935d88c1a5aSDimitry Andric SectionKind GOKind = TargetLoweringObjectFile::getKindForGlobal(GO, TM); 936d88c1a5aSDimitry Andric const MCSection *TheSection = SectionForGlobal(GO, GOKind, TM); 937d88c1a5aSDimitry Andric CannotUsePrivateLabel = 9387d523365SDimitry Andric !canUsePrivateLabel(*TM.getMCAsmInfo(), *TheSection); 939d88c1a5aSDimitry Andric } 940d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 9417d523365SDimitry Andric } 9427d523365SDimitry Andric 943f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 944f22ef01cSRoman Divacky // COFF 945f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 946f22ef01cSRoman Divacky 947f22ef01cSRoman Divacky static unsigned 9483ca95b02SDimitry Andric getCOFFSectionFlags(SectionKind K, const TargetMachine &TM) { 949f22ef01cSRoman Divacky unsigned Flags = 0; 9503ca95b02SDimitry Andric bool isThumb = TM.getTargetTriple().getArch() == Triple::thumb; 951f22ef01cSRoman Divacky 952ffd1746dSEd Schouten if (K.isMetadata()) 953f22ef01cSRoman Divacky Flags |= 954ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_DISCARDABLE; 955f22ef01cSRoman Divacky else if (K.isText()) 956f22ef01cSRoman Divacky Flags |= 957ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_EXECUTE | 9582754fe60SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 9593ca95b02SDimitry Andric COFF::IMAGE_SCN_CNT_CODE | 9603ca95b02SDimitry Andric (isThumb ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0); 961f22ef01cSRoman Divacky else if (K.isBSS()) 962f22ef01cSRoman Divacky Flags |= 963ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | 964ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ | 965ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_WRITE; 966dff0c46cSDimitry Andric else if (K.isThreadLocal()) 967dff0c46cSDimitry Andric Flags |= 968dff0c46cSDimitry Andric COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 969dff0c46cSDimitry Andric COFF::IMAGE_SCN_MEM_READ | 970dff0c46cSDimitry Andric COFF::IMAGE_SCN_MEM_WRITE; 97139d628a0SDimitry Andric else if (K.isReadOnly() || K.isReadOnlyWithRel()) 972f22ef01cSRoman Divacky Flags |= 973ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 974ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ; 975f22ef01cSRoman Divacky else if (K.isWriteable()) 976f22ef01cSRoman Divacky Flags |= 977ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 978ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ | 979ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_WRITE; 980f22ef01cSRoman Divacky 981f22ef01cSRoman Divacky return Flags; 982f22ef01cSRoman Divacky } 983f22ef01cSRoman Divacky 98491bc56edSDimitry Andric static const GlobalValue *getComdatGVForCOFF(const GlobalValue *GV) { 98591bc56edSDimitry Andric const Comdat *C = GV->getComdat(); 98691bc56edSDimitry Andric assert(C && "expected GV to have a Comdat!"); 98791bc56edSDimitry Andric 98891bc56edSDimitry Andric StringRef ComdatGVName = C->getName(); 98991bc56edSDimitry Andric const GlobalValue *ComdatGV = GV->getParent()->getNamedValue(ComdatGVName); 99091bc56edSDimitry Andric if (!ComdatGV) 99191bc56edSDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 99291bc56edSDimitry Andric "' does not exist."); 99391bc56edSDimitry Andric 99491bc56edSDimitry Andric if (ComdatGV->getComdat() != C) 99591bc56edSDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 99639d628a0SDimitry Andric "' is not a key for its COMDAT."); 99791bc56edSDimitry Andric 99891bc56edSDimitry Andric return ComdatGV; 99991bc56edSDimitry Andric } 100091bc56edSDimitry Andric 100191bc56edSDimitry Andric static int getSelectionForCOFF(const GlobalValue *GV) { 100291bc56edSDimitry Andric if (const Comdat *C = GV->getComdat()) { 100391bc56edSDimitry Andric const GlobalValue *ComdatKey = getComdatGVForCOFF(GV); 100491bc56edSDimitry Andric if (const auto *GA = dyn_cast<GlobalAlias>(ComdatKey)) 100591bc56edSDimitry Andric ComdatKey = GA->getBaseObject(); 100691bc56edSDimitry Andric if (ComdatKey == GV) { 100791bc56edSDimitry Andric switch (C->getSelectionKind()) { 100891bc56edSDimitry Andric case Comdat::Any: 100991bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ANY; 101091bc56edSDimitry Andric case Comdat::ExactMatch: 101191bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH; 101291bc56edSDimitry Andric case Comdat::Largest: 101391bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_LARGEST; 101491bc56edSDimitry Andric case Comdat::NoDuplicates: 101591bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 101691bc56edSDimitry Andric case Comdat::SameSize: 101791bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_SAME_SIZE; 101891bc56edSDimitry Andric } 101991bc56edSDimitry Andric } else { 102091bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE; 102191bc56edSDimitry Andric } 102291bc56edSDimitry Andric } 102391bc56edSDimitry Andric return 0; 102491bc56edSDimitry Andric } 102591bc56edSDimitry Andric 1026ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal( 1027d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 1028139f7f9bSDimitry Andric int Selection = 0; 10293ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 1030d88c1a5aSDimitry Andric StringRef Name = GO->getSection(); 103191bc56edSDimitry Andric StringRef COMDATSymName = ""; 1032d88c1a5aSDimitry Andric if (GO->hasComdat()) { 1033d88c1a5aSDimitry Andric Selection = getSelectionForCOFF(GO); 103491bc56edSDimitry Andric const GlobalValue *ComdatGV; 103591bc56edSDimitry Andric if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) 1036d88c1a5aSDimitry Andric ComdatGV = getComdatGVForCOFF(GO); 103791bc56edSDimitry Andric else 1038d88c1a5aSDimitry Andric ComdatGV = GO; 103991bc56edSDimitry Andric 104091bc56edSDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 1041d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV); 104291bc56edSDimitry Andric COMDATSymName = Sym->getName(); 1043139f7f9bSDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 104491bc56edSDimitry Andric } else { 104591bc56edSDimitry Andric Selection = 0; 104691bc56edSDimitry Andric } 1047139f7f9bSDimitry Andric } 10483ca95b02SDimitry Andric 10493ca95b02SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, 1050f785676fSDimitry Andric Selection); 1051f22ef01cSRoman Divacky } 1052f22ef01cSRoman Divacky 105391bc56edSDimitry Andric static const char *getCOFFSectionNameForUniqueGlobal(SectionKind Kind) { 1054f22ef01cSRoman Divacky if (Kind.isText()) 105591bc56edSDimitry Andric return ".text"; 1056f22ef01cSRoman Divacky if (Kind.isBSS()) 105791bc56edSDimitry Andric return ".bss"; 105891bc56edSDimitry Andric if (Kind.isThreadLocal()) 105991bc56edSDimitry Andric return ".tls$"; 106039d628a0SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 106191bc56edSDimitry Andric return ".rdata"; 106239d628a0SDimitry Andric return ".data"; 1063f22ef01cSRoman Divacky } 1064f22ef01cSRoman Divacky 1065ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal( 1066d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 106791bc56edSDimitry Andric // If we have -ffunction-sections then we should emit the global value to a 106891bc56edSDimitry Andric // uniqued section specifically for it. 106991bc56edSDimitry Andric bool EmitUniquedSection; 107091bc56edSDimitry Andric if (Kind.isText()) 107191bc56edSDimitry Andric EmitUniquedSection = TM.getFunctionSections(); 107291bc56edSDimitry Andric else 107391bc56edSDimitry Andric EmitUniquedSection = TM.getDataSections(); 1074f22ef01cSRoman Divacky 1075d88c1a5aSDimitry Andric if ((EmitUniquedSection && !Kind.isCommon()) || GO->hasComdat()) { 107691bc56edSDimitry Andric const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); 10773ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 1078f22ef01cSRoman Divacky 1079ffd1746dSEd Schouten Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 1080d88c1a5aSDimitry Andric int Selection = getSelectionForCOFF(GO); 108191bc56edSDimitry Andric if (!Selection) 108291bc56edSDimitry Andric Selection = COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 108391bc56edSDimitry Andric const GlobalValue *ComdatGV; 1084d88c1a5aSDimitry Andric if (GO->hasComdat()) 1085d88c1a5aSDimitry Andric ComdatGV = getComdatGVForCOFF(GO); 108691bc56edSDimitry Andric else 1087d88c1a5aSDimitry Andric ComdatGV = GO; 1088f22ef01cSRoman Divacky 10893ca95b02SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 10903ca95b02SDimitry Andric if (EmitUniquedSection) 10913ca95b02SDimitry Andric UniqueID = NextUniqueID++; 10923ca95b02SDimitry Andric 109391bc56edSDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 1094d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV); 109591bc56edSDimitry Andric StringRef COMDATSymName = Sym->getName(); 109691bc56edSDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, 10973ca95b02SDimitry Andric COMDATSymName, Selection, UniqueID); 1098ff0cc061SDimitry Andric } else { 1099ff0cc061SDimitry Andric SmallString<256> TmpData; 1100d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(TmpData, GO, /*CannotUsePrivateLabel=*/true); 1101ff0cc061SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, TmpData, 11023ca95b02SDimitry Andric Selection, UniqueID); 110391bc56edSDimitry Andric } 1104f22ef01cSRoman Divacky } 1105f22ef01cSRoman Divacky 1106f22ef01cSRoman Divacky if (Kind.isText()) 1107f785676fSDimitry Andric return TextSection; 1108f22ef01cSRoman Divacky 1109dff0c46cSDimitry Andric if (Kind.isThreadLocal()) 1110f785676fSDimitry Andric return TLSDataSection; 1111dff0c46cSDimitry Andric 111239d628a0SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 1113f785676fSDimitry Andric return ReadOnlySection; 1114f785676fSDimitry Andric 111591bc56edSDimitry Andric // Note: we claim that common symbols are put in BSSSection, but they are 111691bc56edSDimitry Andric // really emitted with the magic .comm directive, which creates a symbol table 111791bc56edSDimitry Andric // entry but not a section. 111891bc56edSDimitry Andric if (Kind.isBSS() || Kind.isCommon()) 1119f785676fSDimitry Andric return BSSSection; 1120f785676fSDimitry Andric 1121f785676fSDimitry Andric return DataSection; 1122f22ef01cSRoman Divacky } 1123f22ef01cSRoman Divacky 1124ff0cc061SDimitry Andric void TargetLoweringObjectFileCOFF::getNameWithPrefix( 1125d88c1a5aSDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, 11267d523365SDimitry Andric const TargetMachine &TM) const { 11277d523365SDimitry Andric bool CannotUsePrivateLabel = false; 1128ff0cc061SDimitry Andric if (GV->hasPrivateLinkage() && 1129ff0cc061SDimitry Andric ((isa<Function>(GV) && TM.getFunctionSections()) || 1130ff0cc061SDimitry Andric (isa<GlobalVariable>(GV) && TM.getDataSections()))) 1131ff0cc061SDimitry Andric CannotUsePrivateLabel = true; 1132ff0cc061SDimitry Andric 1133d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 1134ff0cc061SDimitry Andric } 1135ff0cc061SDimitry Andric 1136ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable( 1137d88c1a5aSDimitry Andric const Function &F, const TargetMachine &TM) const { 1138ff0cc061SDimitry Andric // If the function can be removed, produce a unique section so that 1139ff0cc061SDimitry Andric // the table doesn't prevent the removal. 1140ff0cc061SDimitry Andric const Comdat *C = F.getComdat(); 1141ff0cc061SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C; 1142ff0cc061SDimitry Andric if (!EmitUniqueSection) 1143ff0cc061SDimitry Andric return ReadOnlySection; 1144ff0cc061SDimitry Andric 1145ff0cc061SDimitry Andric // FIXME: we should produce a symbol for F instead. 1146ff0cc061SDimitry Andric if (F.hasPrivateLinkage()) 1147ff0cc061SDimitry Andric return ReadOnlySection; 1148ff0cc061SDimitry Andric 1149d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(&F); 1150ff0cc061SDimitry Andric StringRef COMDATSymName = Sym->getName(); 1151ff0cc061SDimitry Andric 1152ff0cc061SDimitry Andric SectionKind Kind = SectionKind::getReadOnly(); 1153ff0cc061SDimitry Andric const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); 11543ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 1155ff0cc061SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 11563ca95b02SDimitry Andric unsigned UniqueID = NextUniqueID++; 1157ff0cc061SDimitry Andric 1158ff0cc061SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, 11593ca95b02SDimitry Andric COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); 1160ff0cc061SDimitry Andric } 1161ff0cc061SDimitry Andric 1162d88c1a5aSDimitry Andric void TargetLoweringObjectFileCOFF::emitModuleFlags( 1163d88c1a5aSDimitry Andric MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, 1164d88c1a5aSDimitry Andric const TargetMachine &TM) const { 116591bc56edSDimitry Andric MDNode *LinkerOptions = nullptr; 1166284c1978SDimitry Andric 11673ca95b02SDimitry Andric for (const auto &MFE : ModuleFlags) { 1168284c1978SDimitry Andric StringRef Key = MFE.Key->getString(); 11693ca95b02SDimitry Andric if (Key == "Linker Options") 11703ca95b02SDimitry Andric LinkerOptions = cast<MDNode>(MFE.Val); 1171284c1978SDimitry Andric } 1172284c1978SDimitry Andric 11733ca95b02SDimitry Andric if (LinkerOptions) { 1174284c1978SDimitry Andric // Emit the linker options to the linker .drectve section. According to the 11753ca95b02SDimitry Andric // spec, this section is a space-separated string containing flags for 11763ca95b02SDimitry Andric // linker. 1177ff0cc061SDimitry Andric MCSection *Sec = getDrectveSection(); 1178284c1978SDimitry Andric Streamer.SwitchSection(Sec); 11793ca95b02SDimitry Andric for (const auto &Option : LinkerOptions->operands()) { 11803ca95b02SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) { 1181284c1978SDimitry Andric // Lead with a space for consistency with our dllexport implementation. 1182ff0cc061SDimitry Andric std::string Directive(" "); 11833ca95b02SDimitry Andric Directive.append(cast<MDString>(Piece)->getString()); 1184ff0cc061SDimitry Andric Streamer.EmitBytes(Directive); 1185284c1978SDimitry Andric } 1186284c1978SDimitry Andric } 1187284c1978SDimitry Andric } 1188db17bf38SDimitry Andric 1189db17bf38SDimitry Andric unsigned Version = 0; 1190db17bf38SDimitry Andric unsigned Flags = 0; 1191db17bf38SDimitry Andric StringRef Section; 1192db17bf38SDimitry Andric 1193db17bf38SDimitry Andric GetObjCImageInfo(ModuleFlags, Version, Flags, Section); 1194db17bf38SDimitry Andric if (Section.empty()) 1195db17bf38SDimitry Andric return; 1196db17bf38SDimitry Andric 1197db17bf38SDimitry Andric auto &C = getContext(); 1198db17bf38SDimitry Andric auto *S = C.getCOFFSection( 1199db17bf38SDimitry Andric Section, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, 1200db17bf38SDimitry Andric SectionKind::getReadOnly()); 1201db17bf38SDimitry Andric Streamer.SwitchSection(S); 1202db17bf38SDimitry Andric Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); 1203db17bf38SDimitry Andric Streamer.EmitIntValue(Version, 4); 1204db17bf38SDimitry Andric Streamer.EmitIntValue(Flags, 4); 1205db17bf38SDimitry Andric Streamer.AddBlankLine(); 12063ca95b02SDimitry Andric } 120791bc56edSDimitry Andric 1208d88c1a5aSDimitry Andric void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx, 1209d88c1a5aSDimitry Andric const TargetMachine &TM) { 1210d88c1a5aSDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM); 1211d88c1a5aSDimitry Andric const Triple &T = TM.getTargetTriple(); 1212d88c1a5aSDimitry Andric if (T.isKnownWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) { 1213d88c1a5aSDimitry Andric StaticCtorSection = 1214d88c1a5aSDimitry Andric Ctx.getCOFFSection(".CRT$XCU", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1215d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ, 1216d88c1a5aSDimitry Andric SectionKind::getReadOnly()); 1217d88c1a5aSDimitry Andric StaticDtorSection = 1218d88c1a5aSDimitry Andric Ctx.getCOFFSection(".CRT$XTX", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1219d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ, 1220d88c1a5aSDimitry Andric SectionKind::getReadOnly()); 1221d88c1a5aSDimitry Andric } else { 1222d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getCOFFSection( 1223d88c1a5aSDimitry Andric ".ctors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1224d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, 1225d88c1a5aSDimitry Andric SectionKind::getData()); 1226d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getCOFFSection( 1227d88c1a5aSDimitry Andric ".dtors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1228d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, 1229d88c1a5aSDimitry Andric SectionKind::getData()); 1230d88c1a5aSDimitry Andric } 1231d88c1a5aSDimitry Andric } 1232d88c1a5aSDimitry Andric 1233ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection( 123491bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 123539d628a0SDimitry Andric return getContext().getAssociativeCOFFSection( 12363ca95b02SDimitry Andric cast<MCSectionCOFF>(StaticCtorSection), KeySym, 0); 123791bc56edSDimitry Andric } 123891bc56edSDimitry Andric 1239ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection( 124091bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 124139d628a0SDimitry Andric return getContext().getAssociativeCOFFSection( 12423ca95b02SDimitry Andric cast<MCSectionCOFF>(StaticDtorSection), KeySym, 0); 124391bc56edSDimitry Andric } 12443dac3a9bSDimitry Andric 12453dac3a9bSDimitry Andric void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal( 1246d88c1a5aSDimitry Andric raw_ostream &OS, const GlobalValue *GV) const { 12477a7e6055SDimitry Andric emitLinkerFlagsForGlobalCOFF(OS, GV, getTargetTriple(), getMangler()); 12483dac3a9bSDimitry Andric } 12493dac3a9bSDimitry Andric 12507a7e6055SDimitry Andric //===----------------------------------------------------------------------===// 12517a7e6055SDimitry Andric // Wasm 12527a7e6055SDimitry Andric //===----------------------------------------------------------------------===// 12537a7e6055SDimitry Andric 12547a7e6055SDimitry Andric static const Comdat *getWasmComdat(const GlobalValue *GV) { 12557a7e6055SDimitry Andric const Comdat *C = GV->getComdat(); 12567a7e6055SDimitry Andric if (!C) 12577a7e6055SDimitry Andric return nullptr; 12587a7e6055SDimitry Andric 12597a7e6055SDimitry Andric if (C->getSelectionKind() != Comdat::Any) 12607a7e6055SDimitry Andric report_fatal_error("Wasm COMDATs only support SelectionKind::Any, '" + 12617a7e6055SDimitry Andric C->getName() + "' cannot be lowered."); 12627a7e6055SDimitry Andric 12637a7e6055SDimitry Andric return C; 12643dac3a9bSDimitry Andric } 12657a7e6055SDimitry Andric 12667a7e6055SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal( 12677a7e6055SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 12687a7e6055SDimitry Andric llvm_unreachable("getExplicitSectionGlobal not yet implemented"); 12697a7e6055SDimitry Andric return nullptr; 12707a7e6055SDimitry Andric } 12717a7e6055SDimitry Andric 12727a7e6055SDimitry Andric static MCSectionWasm * 12737a7e6055SDimitry Andric selectWasmSectionForGlobal(MCContext &Ctx, const GlobalObject *GO, 12747a7e6055SDimitry Andric SectionKind Kind, Mangler &Mang, 12757a7e6055SDimitry Andric const TargetMachine &TM, bool EmitUniqueSection, 12767a7e6055SDimitry Andric unsigned Flags, unsigned *NextUniqueID) { 12777a7e6055SDimitry Andric StringRef Group = ""; 12787a7e6055SDimitry Andric if (getWasmComdat(GO)) 12797a7e6055SDimitry Andric llvm_unreachable("comdat not yet supported for wasm"); 12807a7e6055SDimitry Andric 12817a7e6055SDimitry Andric bool UniqueSectionNames = TM.getUniqueSectionNames(); 12827a7e6055SDimitry Andric SmallString<128> Name = getSectionPrefixForGlobal(Kind); 12837a7e6055SDimitry Andric 12847a7e6055SDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) { 12857a7e6055SDimitry Andric const auto &OptionalPrefix = F->getSectionPrefix(); 12867a7e6055SDimitry Andric if (OptionalPrefix) 12877a7e6055SDimitry Andric Name += *OptionalPrefix; 12887a7e6055SDimitry Andric } 12897a7e6055SDimitry Andric 12907a7e6055SDimitry Andric if (EmitUniqueSection && UniqueSectionNames) { 12917a7e6055SDimitry Andric Name.push_back('.'); 12927a7e6055SDimitry Andric TM.getNameWithPrefix(Name, GO, Mang, true); 12937a7e6055SDimitry Andric } 12947a7e6055SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 12957a7e6055SDimitry Andric if (EmitUniqueSection && !UniqueSectionNames) { 12967a7e6055SDimitry Andric UniqueID = *NextUniqueID; 12977a7e6055SDimitry Andric (*NextUniqueID)++; 12987a7e6055SDimitry Andric } 12997a7e6055SDimitry Andric return Ctx.getWasmSection(Name, /*Type=*/0, Flags, 13007a7e6055SDimitry Andric Group, UniqueID); 13017a7e6055SDimitry Andric } 13027a7e6055SDimitry Andric 13037a7e6055SDimitry Andric MCSection *TargetLoweringObjectFileWasm::SelectSectionForGlobal( 13047a7e6055SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 13057a7e6055SDimitry Andric 13067a7e6055SDimitry Andric if (Kind.isCommon()) 13077a7e6055SDimitry Andric report_fatal_error("mergable sections not supported yet on wasm"); 13087a7e6055SDimitry Andric 13097a7e6055SDimitry Andric // If we have -ffunction-section or -fdata-section then we should emit the 13107a7e6055SDimitry Andric // global value to a uniqued section specifically for it. 13117a7e6055SDimitry Andric bool EmitUniqueSection = false; 13127a7e6055SDimitry Andric if (Kind.isText()) 13137a7e6055SDimitry Andric EmitUniqueSection = TM.getFunctionSections(); 13147a7e6055SDimitry Andric else 13157a7e6055SDimitry Andric EmitUniqueSection = TM.getDataSections(); 13167a7e6055SDimitry Andric EmitUniqueSection |= GO->hasComdat(); 13177a7e6055SDimitry Andric 13187a7e6055SDimitry Andric return selectWasmSectionForGlobal(getContext(), GO, Kind, getMangler(), TM, 13197a7e6055SDimitry Andric EmitUniqueSection, /*Flags=*/0, 13207a7e6055SDimitry Andric &NextUniqueID); 13217a7e6055SDimitry Andric } 13227a7e6055SDimitry Andric 13237a7e6055SDimitry Andric bool TargetLoweringObjectFileWasm::shouldPutJumpTableInFunctionSection( 13247a7e6055SDimitry Andric bool UsesLabelDifference, const Function &F) const { 13257a7e6055SDimitry Andric // We can always create relative relocations, so use another section 13267a7e6055SDimitry Andric // that can be marked non-executable. 13277a7e6055SDimitry Andric return false; 13287a7e6055SDimitry Andric } 13297a7e6055SDimitry Andric 13307a7e6055SDimitry Andric const MCExpr *TargetLoweringObjectFileWasm::lowerRelativeReference( 13317a7e6055SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 13327a7e6055SDimitry Andric const TargetMachine &TM) const { 13337a7e6055SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr 13347a7e6055SDimitry Andric // functions. 13357a7e6055SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) 13367a7e6055SDimitry Andric return nullptr; 13377a7e6055SDimitry Andric 13387a7e6055SDimitry Andric // Basic sanity checks. 13397a7e6055SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 13407a7e6055SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || 13417a7e6055SDimitry Andric RHS->isThreadLocal()) 13427a7e6055SDimitry Andric return nullptr; 13437a7e6055SDimitry Andric 13447a7e6055SDimitry Andric return MCBinaryExpr::createSub( 13457a7e6055SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS), MCSymbolRefExpr::VK_None, 13467a7e6055SDimitry Andric getContext()), 13477a7e6055SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); 13487a7e6055SDimitry Andric } 13497a7e6055SDimitry Andric 13507a7e6055SDimitry Andric void 13517a7e6055SDimitry Andric TargetLoweringObjectFileWasm::InitializeWasm() { 13527a7e6055SDimitry Andric // TODO: Initialize StaticCtorSection and StaticDtorSection. 13533dac3a9bSDimitry Andric } 1354