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 6424d58133SDimitry Andric static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags, 65db17bf38SDimitry Andric StringRef &Section) { 6624d58133SDimitry Andric SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags; 6724d58133SDimitry Andric M.getModuleFlagsMetadata(ModuleFlags); 6824d58133SDimitry Andric 69db17bf38SDimitry Andric for (const auto &MFE: ModuleFlags) { 70db17bf38SDimitry Andric // Ignore flags with 'Require' behaviour. 71db17bf38SDimitry Andric if (MFE.Behavior == Module::Require) 72db17bf38SDimitry Andric continue; 73db17bf38SDimitry Andric 74db17bf38SDimitry Andric StringRef Key = MFE.Key->getString(); 75db17bf38SDimitry Andric if (Key == "Objective-C Image Info Version") { 76db17bf38SDimitry Andric Version = mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue(); 77db17bf38SDimitry Andric } else if (Key == "Objective-C Garbage Collection" || 78db17bf38SDimitry Andric Key == "Objective-C GC Only" || 79db17bf38SDimitry Andric Key == "Objective-C Is Simulated" || 80db17bf38SDimitry Andric Key == "Objective-C Class Properties" || 81db17bf38SDimitry Andric Key == "Objective-C Image Swift Version") { 82db17bf38SDimitry Andric Flags |= mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue(); 83db17bf38SDimitry Andric } else if (Key == "Objective-C Image Info Section") { 84db17bf38SDimitry Andric Section = cast<MDString>(MFE.Val)->getString(); 85db17bf38SDimitry Andric } 86db17bf38SDimitry Andric } 87db17bf38SDimitry Andric } 88db17bf38SDimitry Andric 89f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 90f22ef01cSRoman Divacky // ELF 91f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 92f22ef01cSRoman Divacky 9324d58133SDimitry Andric void TargetLoweringObjectFileELF::emitModuleMetadata( 9424d58133SDimitry Andric MCStreamer &Streamer, Module &M, const TargetMachine &TM) const { 95db17bf38SDimitry Andric unsigned Version = 0; 96db17bf38SDimitry Andric unsigned Flags = 0; 97db17bf38SDimitry Andric StringRef Section; 98db17bf38SDimitry Andric 9924d58133SDimitry Andric GetObjCImageInfo(M, Version, Flags, Section); 100db17bf38SDimitry Andric if (Section.empty()) 101db17bf38SDimitry Andric return; 102db17bf38SDimitry Andric 103db17bf38SDimitry Andric auto &C = getContext(); 104db17bf38SDimitry Andric auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC); 105db17bf38SDimitry Andric Streamer.SwitchSection(S); 106db17bf38SDimitry Andric Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); 107db17bf38SDimitry Andric Streamer.EmitIntValue(Version, 4); 108db17bf38SDimitry Andric Streamer.EmitIntValue(Flags, 4); 109db17bf38SDimitry Andric Streamer.AddBlankLine(); 110db17bf38SDimitry Andric } 111db17bf38SDimitry Andric 11291bc56edSDimitry Andric MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol( 113d88c1a5aSDimitry Andric const GlobalValue *GV, const TargetMachine &TM, 1143b0f4066SDimitry Andric MachineModuleInfo *MMI) const { 1153b0f4066SDimitry Andric unsigned Encoding = getPersonalityEncoding(); 1167a7e6055SDimitry Andric if ((Encoding & 0x80) == DW_EH_PE_indirect) 117ff0cc061SDimitry Andric return getContext().getOrCreateSymbol(StringRef("DW.ref.") + 118d88c1a5aSDimitry Andric TM.getSymbol(GV)->getName()); 1197a7e6055SDimitry Andric if ((Encoding & 0x70) == DW_EH_PE_absptr) 120d88c1a5aSDimitry Andric return TM.getSymbol(GV); 12191bc56edSDimitry Andric report_fatal_error("We do not support this DWARF encoding yet!"); 1223b0f4066SDimitry Andric } 1233b0f4066SDimitry Andric 1247d523365SDimitry Andric void TargetLoweringObjectFileELF::emitPersonalityValue( 1257d523365SDimitry Andric MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym) const { 12617a519f9SDimitry Andric SmallString<64> NameData("DW.ref."); 12717a519f9SDimitry Andric NameData += Sym->getName(); 12897bc6c73SDimitry Andric MCSymbolELF *Label = 12997bc6c73SDimitry Andric cast<MCSymbolELF>(getContext().getOrCreateSymbol(NameData)); 1303b0f4066SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_Hidden); 1313b0f4066SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_Weak); 1323b0f4066SDimitry Andric unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP; 1333ca95b02SDimitry Andric MCSection *Sec = getContext().getELFNamedSection(".data", Label->getName(), 1343ca95b02SDimitry Andric ELF::SHT_PROGBITS, Flags, 0); 1357d523365SDimitry Andric unsigned Size = DL.getPointerSize(); 1363b0f4066SDimitry Andric Streamer.SwitchSection(Sec); 1377d523365SDimitry Andric Streamer.EmitValueToAlignment(DL.getPointerABIAlignment()); 1383b0f4066SDimitry Andric Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject); 13997bc6c73SDimitry Andric const MCExpr *E = MCConstantExpr::create(Size, getContext()); 14097bc6c73SDimitry Andric Streamer.emitELFSize(Label, E); 1413b0f4066SDimitry Andric Streamer.EmitLabel(Label); 1423b0f4066SDimitry Andric 1433b0f4066SDimitry Andric Streamer.EmitSymbolValue(Sym, Size); 1443b0f4066SDimitry Andric } 1453b0f4066SDimitry Andric 14691bc56edSDimitry Andric const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference( 147d88c1a5aSDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, 148d88c1a5aSDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 1497a7e6055SDimitry Andric if (Encoding & DW_EH_PE_indirect) { 150139f7f9bSDimitry Andric MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>(); 151139f7f9bSDimitry Andric 152d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", TM); 153139f7f9bSDimitry Andric 154139f7f9bSDimitry Andric // Add information about the stub reference to ELFMMI so that the stub 155139f7f9bSDimitry Andric // gets emitted by the asmprinter. 156139f7f9bSDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym); 15791bc56edSDimitry Andric if (!StubSym.getPointer()) { 158d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 159139f7f9bSDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 160139f7f9bSDimitry Andric } 161139f7f9bSDimitry Andric 162139f7f9bSDimitry Andric return TargetLoweringObjectFile:: 16397bc6c73SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), 1647a7e6055SDimitry Andric Encoding & ~DW_EH_PE_indirect, Streamer); 165139f7f9bSDimitry Andric } 166139f7f9bSDimitry Andric 167d88c1a5aSDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM, 168d88c1a5aSDimitry Andric MMI, Streamer); 169139f7f9bSDimitry Andric } 170139f7f9bSDimitry Andric 171f22ef01cSRoman Divacky static SectionKind 172f22ef01cSRoman Divacky 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"; 53439d628a0SDimitry Andric if (Priority != 65535) { 53539d628a0SDimitry Andric Name += '.'; 53639d628a0SDimitry Andric Name += utostr(65535 - Priority); 53739d628a0SDimitry Andric } 53839d628a0SDimitry Andric Type = ELF::SHT_PROGBITS; 53939d628a0SDimitry Andric } 54039d628a0SDimitry Andric 541ff0cc061SDimitry Andric return Ctx.getELFSection(Name, Type, Flags, 0, COMDAT); 54239d628a0SDimitry Andric } 54339d628a0SDimitry Andric 544ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticCtorSection( 54539d628a0SDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 54639d628a0SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, true, Priority, 54739d628a0SDimitry Andric KeySym); 5487ae0e2c9SDimitry Andric } 549dff0c46cSDimitry Andric 550ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileELF::getStaticDtorSection( 55191bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 55239d628a0SDimitry Andric return getStaticStructorSection(getContext(), UseInitArray, false, Priority, 55339d628a0SDimitry Andric KeySym); 5547ae0e2c9SDimitry Andric } 5557ae0e2c9SDimitry Andric 5563ca95b02SDimitry Andric const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference( 557d88c1a5aSDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 5583ca95b02SDimitry Andric const TargetMachine &TM) const { 5593ca95b02SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr 5603ca95b02SDimitry Andric // functions. 5613ca95b02SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) 5623ca95b02SDimitry Andric return nullptr; 5633ca95b02SDimitry Andric 5643ca95b02SDimitry Andric // Basic sanity checks. 5653ca95b02SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 5663ca95b02SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || 5673ca95b02SDimitry Andric RHS->isThreadLocal()) 5683ca95b02SDimitry Andric return nullptr; 5693ca95b02SDimitry Andric 5703ca95b02SDimitry Andric return MCBinaryExpr::createSub( 571d88c1a5aSDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS), PLTRelativeVariantKind, 5723ca95b02SDimitry Andric getContext()), 573d88c1a5aSDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); 5743ca95b02SDimitry Andric } 5753ca95b02SDimitry Andric 5767ae0e2c9SDimitry Andric void 5777ae0e2c9SDimitry Andric TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) { 5787ae0e2c9SDimitry Andric UseInitArray = UseInitArray_; 579d88c1a5aSDimitry Andric MCContext &Ctx = getContext(); 580d88c1a5aSDimitry Andric if (!UseInitArray) { 581d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getELFSection(".ctors", ELF::SHT_PROGBITS, 582d88c1a5aSDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE); 5837ae0e2c9SDimitry Andric 584d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getELFSection(".dtors", ELF::SHT_PROGBITS, 585d88c1a5aSDimitry Andric ELF::SHF_ALLOC | ELF::SHF_WRITE); 586d88c1a5aSDimitry Andric return; 587d88c1a5aSDimitry Andric } 588d88c1a5aSDimitry Andric 589d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getELFSection(".init_array", ELF::SHT_INIT_ARRAY, 590d88c1a5aSDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC); 591d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getELFSection(".fini_array", ELF::SHT_FINI_ARRAY, 592d88c1a5aSDimitry Andric ELF::SHF_WRITE | ELF::SHF_ALLOC); 5937ae0e2c9SDimitry Andric } 594dff0c46cSDimitry Andric 595f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 596f22ef01cSRoman Divacky // MachO 597f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 598f22ef01cSRoman Divacky 599ff0cc061SDimitry Andric TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO() 600ff0cc061SDimitry Andric : TargetLoweringObjectFile() { 601ff0cc061SDimitry Andric SupportIndirectSymViaGOTPCRel = true; 602ff0cc061SDimitry Andric } 603ff0cc061SDimitry Andric 604d88c1a5aSDimitry Andric void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx, 605d88c1a5aSDimitry Andric const TargetMachine &TM) { 606d88c1a5aSDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM); 607d88c1a5aSDimitry Andric if (TM.getRelocationModel() == Reloc::Static) { 608d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getMachOSection("__TEXT", "__constructor", 0, 609d88c1a5aSDimitry Andric SectionKind::getData()); 610d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getMachOSection("__TEXT", "__destructor", 0, 611d88c1a5aSDimitry Andric SectionKind::getData()); 612d88c1a5aSDimitry Andric } else { 613d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getMachOSection("__DATA", "__mod_init_func", 614d88c1a5aSDimitry Andric MachO::S_MOD_INIT_FUNC_POINTERS, 615d88c1a5aSDimitry Andric SectionKind::getData()); 616d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getMachOSection("__DATA", "__mod_term_func", 617d88c1a5aSDimitry Andric MachO::S_MOD_TERM_FUNC_POINTERS, 618d88c1a5aSDimitry Andric SectionKind::getData()); 619d88c1a5aSDimitry Andric } 620d88c1a5aSDimitry Andric } 621d88c1a5aSDimitry Andric 62224d58133SDimitry Andric void TargetLoweringObjectFileMachO::emitModuleMetadata( 62324d58133SDimitry Andric MCStreamer &Streamer, Module &M, const TargetMachine &TM) const { 624139f7f9bSDimitry Andric // Emit the linker options if present. 62524d58133SDimitry Andric if (auto *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { 6263ca95b02SDimitry Andric for (const auto &Option : LinkerOptions->operands()) { 627139f7f9bSDimitry Andric SmallVector<std::string, 4> StrOptions; 6283ca95b02SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) 6293ca95b02SDimitry Andric StrOptions.push_back(cast<MDString>(Piece)->getString()); 630139f7f9bSDimitry Andric Streamer.EmitLinkerOptions(StrOptions); 631139f7f9bSDimitry Andric } 632dff0c46cSDimitry Andric } 633dff0c46cSDimitry Andric 634db17bf38SDimitry Andric unsigned VersionVal = 0; 635db17bf38SDimitry Andric unsigned ImageInfoFlags = 0; 636db17bf38SDimitry Andric StringRef SectionVal; 63724d58133SDimitry Andric 63824d58133SDimitry Andric GetObjCImageInfo(M, VersionVal, ImageInfoFlags, SectionVal); 639db17bf38SDimitry Andric 640dff0c46cSDimitry Andric // The section is mandatory. If we don't have it, then we don't have GC info. 641db17bf38SDimitry Andric if (SectionVal.empty()) 642db17bf38SDimitry Andric return; 643dff0c46cSDimitry Andric 644dff0c46cSDimitry Andric StringRef Segment, Section; 645dff0c46cSDimitry Andric unsigned TAA = 0, StubSize = 0; 646dff0c46cSDimitry Andric bool TAAParsed; 647dff0c46cSDimitry Andric std::string ErrorCode = 648dff0c46cSDimitry Andric MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section, 649dff0c46cSDimitry Andric TAA, TAAParsed, StubSize); 650dff0c46cSDimitry Andric if (!ErrorCode.empty()) 651dff0c46cSDimitry Andric // If invalid, report the error with report_fatal_error. 652dff0c46cSDimitry Andric report_fatal_error("Invalid section specifier '" + Section + "': " + 653dff0c46cSDimitry Andric ErrorCode + "."); 654dff0c46cSDimitry Andric 655dff0c46cSDimitry Andric // Get the section. 656ff0cc061SDimitry Andric MCSectionMachO *S = getContext().getMachOSection( 6577d523365SDimitry Andric Segment, Section, TAA, StubSize, SectionKind::getData()); 658dff0c46cSDimitry Andric Streamer.SwitchSection(S); 659dff0c46cSDimitry Andric Streamer.EmitLabel(getContext(). 660ff0cc061SDimitry Andric getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); 661dff0c46cSDimitry Andric Streamer.EmitIntValue(VersionVal, 4); 6627ae0e2c9SDimitry Andric Streamer.EmitIntValue(ImageInfoFlags, 4); 663dff0c46cSDimitry Andric Streamer.AddBlankLine(); 664dff0c46cSDimitry Andric } 665dff0c46cSDimitry Andric 66691bc56edSDimitry Andric static void checkMachOComdat(const GlobalValue *GV) { 66791bc56edSDimitry Andric const Comdat *C = GV->getComdat(); 66891bc56edSDimitry Andric if (!C) 66991bc56edSDimitry Andric return; 67091bc56edSDimitry Andric 67191bc56edSDimitry Andric report_fatal_error("MachO doesn't support COMDATs, '" + C->getName() + 67291bc56edSDimitry Andric "' cannot be lowered."); 67391bc56edSDimitry Andric } 67491bc56edSDimitry Andric 675ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( 676d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 677f22ef01cSRoman Divacky // Parse the section specifier and create it if valid. 678f22ef01cSRoman Divacky StringRef Segment, Section; 6793b0f4066SDimitry Andric unsigned TAA = 0, StubSize = 0; 6803b0f4066SDimitry Andric bool TAAParsed; 68191bc56edSDimitry Andric 682d88c1a5aSDimitry Andric checkMachOComdat(GO); 68391bc56edSDimitry Andric 684f22ef01cSRoman Divacky std::string ErrorCode = 685d88c1a5aSDimitry Andric MCSectionMachO::ParseSectionSpecifier(GO->getSection(), Segment, Section, 6863b0f4066SDimitry Andric TAA, TAAParsed, StubSize); 687f22ef01cSRoman Divacky if (!ErrorCode.empty()) { 688f22ef01cSRoman Divacky // If invalid, report the error with report_fatal_error. 689d88c1a5aSDimitry Andric report_fatal_error("Global variable '" + GO->getName() + 690dff0c46cSDimitry Andric "' has an invalid section specifier '" + 691d88c1a5aSDimitry Andric GO->getSection() + "': " + ErrorCode + "."); 692f22ef01cSRoman Divacky } 693f22ef01cSRoman Divacky 694f22ef01cSRoman Divacky // Get the section. 695ff0cc061SDimitry Andric MCSectionMachO *S = 696f22ef01cSRoman Divacky getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind); 697f22ef01cSRoman Divacky 698dd6029ffSDimitry Andric // If TAA wasn't set by ParseSectionSpecifier() above, 699dd6029ffSDimitry Andric // use the value returned by getMachOSection() as a default. 7003b0f4066SDimitry Andric if (!TAAParsed) 701dd6029ffSDimitry Andric TAA = S->getTypeAndAttributes(); 702dd6029ffSDimitry Andric 703f22ef01cSRoman Divacky // Okay, now that we got the section, verify that the TAA & StubSize agree. 704f22ef01cSRoman Divacky // If the user declared multiple globals with different section flags, we need 705f22ef01cSRoman Divacky // to reject it here. 706f22ef01cSRoman Divacky if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) { 707f22ef01cSRoman Divacky // If invalid, report the error with report_fatal_error. 708d88c1a5aSDimitry Andric report_fatal_error("Global variable '" + GO->getName() + 709f22ef01cSRoman Divacky "' section type or attributes does not match previous" 710f22ef01cSRoman Divacky " section specifier"); 711f22ef01cSRoman Divacky } 712f22ef01cSRoman Divacky 713f22ef01cSRoman Divacky return S; 714f22ef01cSRoman Divacky } 715f22ef01cSRoman Divacky 716ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal( 717d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 718d88c1a5aSDimitry Andric checkMachOComdat(GO); 719f785676fSDimitry Andric 720f785676fSDimitry Andric // Handle thread local data. 721f785676fSDimitry Andric if (Kind.isThreadBSS()) return TLSBSSSection; 722f785676fSDimitry Andric if (Kind.isThreadData()) return TLSDataSection; 723f785676fSDimitry Andric 724f22ef01cSRoman Divacky if (Kind.isText()) 725d88c1a5aSDimitry Andric return GO->isWeakForLinker() ? TextCoalSection : TextSection; 726f22ef01cSRoman Divacky 727f22ef01cSRoman Divacky // If this is weak/linkonce, put this in a coalescable section, either in text 728f22ef01cSRoman Divacky // or data depending on if it is writable. 729d88c1a5aSDimitry Andric if (GO->isWeakForLinker()) { 730f22ef01cSRoman Divacky if (Kind.isReadOnly()) 731f22ef01cSRoman Divacky return ConstTextCoalSection; 732f22ef01cSRoman Divacky return DataCoalSection; 733f22ef01cSRoman Divacky } 734f22ef01cSRoman Divacky 735f22ef01cSRoman Divacky // FIXME: Alignment check should be handled by section classifier. 736f22ef01cSRoman Divacky if (Kind.isMergeable1ByteCString() && 737d88c1a5aSDimitry Andric GO->getParent()->getDataLayout().getPreferredAlignment( 738d88c1a5aSDimitry Andric cast<GlobalVariable>(GO)) < 32) 739f22ef01cSRoman Divacky return CStringSection; 740f22ef01cSRoman Divacky 741f22ef01cSRoman Divacky // Do not put 16-bit arrays in the UString section if they have an 742f22ef01cSRoman Divacky // externally visible label, this runs into issues with certain linker 743f22ef01cSRoman Divacky // versions. 744d88c1a5aSDimitry Andric if (Kind.isMergeable2ByteCString() && !GO->hasExternalLinkage() && 745d88c1a5aSDimitry Andric GO->getParent()->getDataLayout().getPreferredAlignment( 746d88c1a5aSDimitry Andric cast<GlobalVariable>(GO)) < 32) 747f22ef01cSRoman Divacky return UStringSection; 748f22ef01cSRoman Divacky 74939d628a0SDimitry Andric // With MachO only variables whose corresponding symbol starts with 'l' or 75039d628a0SDimitry Andric // 'L' can be merged, so we only try merging GVs with private linkage. 751d88c1a5aSDimitry Andric if (GO->hasPrivateLinkage() && Kind.isMergeableConst()) { 752f22ef01cSRoman Divacky if (Kind.isMergeableConst4()) 753f22ef01cSRoman Divacky return FourByteConstantSection; 754f22ef01cSRoman Divacky if (Kind.isMergeableConst8()) 755f22ef01cSRoman Divacky return EightByteConstantSection; 75691bc56edSDimitry Andric if (Kind.isMergeableConst16()) 757f22ef01cSRoman Divacky return SixteenByteConstantSection; 758f22ef01cSRoman Divacky } 759f22ef01cSRoman Divacky 760f22ef01cSRoman Divacky // Otherwise, if it is readonly, but not something we can specially optimize, 761f22ef01cSRoman Divacky // just drop it in .const. 762f22ef01cSRoman Divacky if (Kind.isReadOnly()) 763f22ef01cSRoman Divacky return ReadOnlySection; 764f22ef01cSRoman Divacky 765f22ef01cSRoman Divacky // If this is marked const, put it into a const section. But if the dynamic 766f22ef01cSRoman Divacky // linker needs to write to it, put it in the data segment. 767f22ef01cSRoman Divacky if (Kind.isReadOnlyWithRel()) 768f22ef01cSRoman Divacky return ConstDataSection; 769f22ef01cSRoman Divacky 770f22ef01cSRoman Divacky // Put zero initialized globals with strong external linkage in the 771f22ef01cSRoman Divacky // DATA, __common section with the .zerofill directive. 772f22ef01cSRoman Divacky if (Kind.isBSSExtern()) 773f22ef01cSRoman Divacky return DataCommonSection; 774f22ef01cSRoman Divacky 775f22ef01cSRoman Divacky // Put zero initialized globals with local linkage in __DATA,__bss directive 776f22ef01cSRoman Divacky // with the .zerofill directive (aka .lcomm). 777f22ef01cSRoman Divacky if (Kind.isBSSLocal()) 778f22ef01cSRoman Divacky return DataBSSSection; 779f22ef01cSRoman Divacky 780f22ef01cSRoman Divacky // Otherwise, just drop the variable in the normal data section. 781f22ef01cSRoman Divacky return DataSection; 782f22ef01cSRoman Divacky } 783f22ef01cSRoman Divacky 7847d523365SDimitry Andric MCSection *TargetLoweringObjectFileMachO::getSectionForConstant( 7853ca95b02SDimitry Andric const DataLayout &DL, SectionKind Kind, const Constant *C, 7863ca95b02SDimitry Andric unsigned &Align) const { 787f22ef01cSRoman Divacky // If this constant requires a relocation, we have to put it in the data 788f22ef01cSRoman Divacky // segment, not in the text segment. 7897d523365SDimitry Andric if (Kind.isData() || Kind.isReadOnlyWithRel()) 790f22ef01cSRoman Divacky return ConstDataSection; 791f22ef01cSRoman Divacky 792f22ef01cSRoman Divacky if (Kind.isMergeableConst4()) 793f22ef01cSRoman Divacky return FourByteConstantSection; 794f22ef01cSRoman Divacky if (Kind.isMergeableConst8()) 795f22ef01cSRoman Divacky return EightByteConstantSection; 79691bc56edSDimitry Andric if (Kind.isMergeableConst16()) 797f22ef01cSRoman Divacky return SixteenByteConstantSection; 798f22ef01cSRoman Divacky return ReadOnlySection; // .const 799f22ef01cSRoman Divacky } 800f22ef01cSRoman Divacky 80191bc56edSDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference( 802d88c1a5aSDimitry Andric const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, 803d88c1a5aSDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 804f22ef01cSRoman Divacky // The mach-o version of this method defaults to returning a stub reference. 805f22ef01cSRoman Divacky 806f22ef01cSRoman Divacky if (Encoding & DW_EH_PE_indirect) { 807f22ef01cSRoman Divacky MachineModuleInfoMachO &MachOMMI = 808f22ef01cSRoman Divacky MMI->getObjFileInfo<MachineModuleInfoMachO>(); 809f22ef01cSRoman Divacky 810d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); 811f22ef01cSRoman Divacky 812f22ef01cSRoman Divacky // Add information about the stub reference to MachOMMI so that the stub 813f22ef01cSRoman Divacky // gets emitted by the asmprinter. 8143ca95b02SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 81591bc56edSDimitry Andric if (!StubSym.getPointer()) { 816d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 817f22ef01cSRoman Divacky StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 818f22ef01cSRoman Divacky } 819f22ef01cSRoman Divacky 820f22ef01cSRoman Divacky return TargetLoweringObjectFile:: 82197bc6c73SDimitry Andric getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), 8227a7e6055SDimitry Andric Encoding & ~DW_EH_PE_indirect, Streamer); 823f22ef01cSRoman Divacky } 824f22ef01cSRoman Divacky 825d88c1a5aSDimitry Andric return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, TM, 826d88c1a5aSDimitry Andric MMI, Streamer); 827f22ef01cSRoman Divacky } 828f22ef01cSRoman Divacky 82991bc56edSDimitry Andric MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol( 830d88c1a5aSDimitry Andric const GlobalValue *GV, const TargetMachine &TM, 8313b0f4066SDimitry Andric MachineModuleInfo *MMI) const { 8323b0f4066SDimitry Andric // The mach-o version of this method defaults to returning a stub reference. 8333b0f4066SDimitry Andric MachineModuleInfoMachO &MachOMMI = 8343b0f4066SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 8353b0f4066SDimitry Andric 836d88c1a5aSDimitry Andric MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", TM); 8373b0f4066SDimitry Andric 8383b0f4066SDimitry Andric // Add information about the stub reference to MachOMMI so that the stub 8393b0f4066SDimitry Andric // gets emitted by the asmprinter. 840dff0c46cSDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym); 84191bc56edSDimitry Andric if (!StubSym.getPointer()) { 842d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(GV); 8433b0f4066SDimitry Andric StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); 8443b0f4066SDimitry Andric } 8453b0f4066SDimitry Andric 8463b0f4066SDimitry Andric return SSym; 8473b0f4066SDimitry Andric } 8483b0f4066SDimitry Andric 849ff0cc061SDimitry Andric const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel( 850ff0cc061SDimitry Andric const MCSymbol *Sym, const MCValue &MV, int64_t Offset, 851ff0cc061SDimitry Andric MachineModuleInfo *MMI, MCStreamer &Streamer) const { 8527d523365SDimitry Andric // Although MachO 32-bit targets do not explicitly have a GOTPCREL relocation 853ff0cc061SDimitry Andric // as 64-bit do, we replace the GOT equivalent by accessing the final symbol 854ff0cc061SDimitry Andric // through a non_lazy_ptr stub instead. One advantage is that it allows the 855ff0cc061SDimitry Andric // computation of deltas to final external symbols. Example: 856ff0cc061SDimitry Andric // 857ff0cc061SDimitry Andric // _extgotequiv: 858ff0cc061SDimitry Andric // .long _extfoo 859ff0cc061SDimitry Andric // 860ff0cc061SDimitry Andric // _delta: 861ff0cc061SDimitry Andric // .long _extgotequiv-_delta 862ff0cc061SDimitry Andric // 863ff0cc061SDimitry Andric // is transformed to: 864ff0cc061SDimitry Andric // 865ff0cc061SDimitry Andric // _delta: 866ff0cc061SDimitry Andric // .long L_extfoo$non_lazy_ptr-(_delta+0) 867ff0cc061SDimitry Andric // 868ff0cc061SDimitry Andric // .section __IMPORT,__pointers,non_lazy_symbol_pointers 869ff0cc061SDimitry Andric // L_extfoo$non_lazy_ptr: 870ff0cc061SDimitry Andric // .indirect_symbol _extfoo 871ff0cc061SDimitry Andric // .long 0 872ff0cc061SDimitry Andric // 873ff0cc061SDimitry Andric MachineModuleInfoMachO &MachOMMI = 874ff0cc061SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoMachO>(); 875ff0cc061SDimitry Andric MCContext &Ctx = getContext(); 876ff0cc061SDimitry Andric 877ff0cc061SDimitry Andric // The offset must consider the original displacement from the base symbol 878ff0cc061SDimitry Andric // since 32-bit targets don't have a GOTPCREL to fold the PC displacement. 879ff0cc061SDimitry Andric Offset = -MV.getConstant(); 880ff0cc061SDimitry Andric const MCSymbol *BaseSym = &MV.getSymB()->getSymbol(); 881ff0cc061SDimitry Andric 882ff0cc061SDimitry Andric // Access the final symbol via sym$non_lazy_ptr and generate the appropriated 883ff0cc061SDimitry Andric // non_lazy_ptr stubs. 884ff0cc061SDimitry Andric SmallString<128> Name; 885ff0cc061SDimitry Andric StringRef Suffix = "$non_lazy_ptr"; 8867d523365SDimitry Andric Name += MMI->getModule()->getDataLayout().getPrivateGlobalPrefix(); 887ff0cc061SDimitry Andric Name += Sym->getName(); 888ff0cc061SDimitry Andric Name += Suffix; 889ff0cc061SDimitry Andric MCSymbol *Stub = Ctx.getOrCreateSymbol(Name); 890ff0cc061SDimitry Andric 891ff0cc061SDimitry Andric MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub); 892ff0cc061SDimitry Andric if (!StubSym.getPointer()) 893ff0cc061SDimitry Andric StubSym = MachineModuleInfoImpl:: 894ff0cc061SDimitry Andric StubValueTy(const_cast<MCSymbol *>(Sym), true /* access indirectly */); 895ff0cc061SDimitry Andric 896ff0cc061SDimitry Andric const MCExpr *BSymExpr = 89797bc6c73SDimitry Andric MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx); 898ff0cc061SDimitry Andric const MCExpr *LHS = 89997bc6c73SDimitry Andric MCSymbolRefExpr::create(Stub, MCSymbolRefExpr::VK_None, Ctx); 900ff0cc061SDimitry Andric 901ff0cc061SDimitry Andric if (!Offset) 90297bc6c73SDimitry Andric return MCBinaryExpr::createSub(LHS, BSymExpr, Ctx); 903ff0cc061SDimitry Andric 904ff0cc061SDimitry Andric const MCExpr *RHS = 90597bc6c73SDimitry Andric MCBinaryExpr::createAdd(BSymExpr, MCConstantExpr::create(Offset, Ctx), Ctx); 90697bc6c73SDimitry Andric return MCBinaryExpr::createSub(LHS, RHS, Ctx); 907ff0cc061SDimitry Andric } 908ff0cc061SDimitry Andric 9097d523365SDimitry Andric static bool canUsePrivateLabel(const MCAsmInfo &AsmInfo, 9107d523365SDimitry Andric const MCSection &Section) { 9117d523365SDimitry Andric if (!AsmInfo.isSectionAtomizableBySymbols(Section)) 9127d523365SDimitry Andric return true; 9137d523365SDimitry Andric 9147d523365SDimitry Andric // If it is not dead stripped, it is safe to use private labels. 9157d523365SDimitry Andric const MCSectionMachO &SMO = cast<MCSectionMachO>(Section); 9167d523365SDimitry Andric if (SMO.hasAttribute(MachO::S_ATTR_NO_DEAD_STRIP)) 9177d523365SDimitry Andric return true; 9187d523365SDimitry Andric 9197d523365SDimitry Andric return false; 9207d523365SDimitry Andric } 9217d523365SDimitry Andric 9227d523365SDimitry Andric void TargetLoweringObjectFileMachO::getNameWithPrefix( 923d88c1a5aSDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, 9247d523365SDimitry Andric const TargetMachine &TM) const { 925d88c1a5aSDimitry Andric bool CannotUsePrivateLabel = true; 926d88c1a5aSDimitry Andric if (auto *GO = GV->getBaseObject()) { 927d88c1a5aSDimitry Andric SectionKind GOKind = TargetLoweringObjectFile::getKindForGlobal(GO, TM); 928d88c1a5aSDimitry Andric const MCSection *TheSection = SectionForGlobal(GO, GOKind, TM); 929d88c1a5aSDimitry Andric CannotUsePrivateLabel = 9307d523365SDimitry Andric !canUsePrivateLabel(*TM.getMCAsmInfo(), *TheSection); 931d88c1a5aSDimitry Andric } 932d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 9337d523365SDimitry Andric } 9347d523365SDimitry Andric 935f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 936f22ef01cSRoman Divacky // COFF 937f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 938f22ef01cSRoman Divacky 939f22ef01cSRoman Divacky static unsigned 9403ca95b02SDimitry Andric getCOFFSectionFlags(SectionKind K, const TargetMachine &TM) { 941f22ef01cSRoman Divacky unsigned Flags = 0; 9423ca95b02SDimitry Andric bool isThumb = TM.getTargetTriple().getArch() == Triple::thumb; 943f22ef01cSRoman Divacky 944ffd1746dSEd Schouten if (K.isMetadata()) 945f22ef01cSRoman Divacky Flags |= 946ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_DISCARDABLE; 947f22ef01cSRoman Divacky else if (K.isText()) 948f22ef01cSRoman Divacky Flags |= 949ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_EXECUTE | 9502754fe60SDimitry Andric COFF::IMAGE_SCN_MEM_READ | 9513ca95b02SDimitry Andric COFF::IMAGE_SCN_CNT_CODE | 9523ca95b02SDimitry Andric (isThumb ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0); 953f22ef01cSRoman Divacky else if (K.isBSS()) 954f22ef01cSRoman Divacky Flags |= 955ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | 956ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ | 957ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_WRITE; 958dff0c46cSDimitry Andric else if (K.isThreadLocal()) 959dff0c46cSDimitry Andric Flags |= 960dff0c46cSDimitry Andric COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 961dff0c46cSDimitry Andric COFF::IMAGE_SCN_MEM_READ | 962dff0c46cSDimitry Andric COFF::IMAGE_SCN_MEM_WRITE; 96339d628a0SDimitry Andric else if (K.isReadOnly() || K.isReadOnlyWithRel()) 964f22ef01cSRoman Divacky Flags |= 965ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 966ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ; 967f22ef01cSRoman Divacky else if (K.isWriteable()) 968f22ef01cSRoman Divacky Flags |= 969ffd1746dSEd Schouten COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 970ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_READ | 971ffd1746dSEd Schouten COFF::IMAGE_SCN_MEM_WRITE; 972f22ef01cSRoman Divacky 973f22ef01cSRoman Divacky return Flags; 974f22ef01cSRoman Divacky } 975f22ef01cSRoman Divacky 97691bc56edSDimitry Andric static const GlobalValue *getComdatGVForCOFF(const GlobalValue *GV) { 97791bc56edSDimitry Andric const Comdat *C = GV->getComdat(); 97891bc56edSDimitry Andric assert(C && "expected GV to have a Comdat!"); 97991bc56edSDimitry Andric 98091bc56edSDimitry Andric StringRef ComdatGVName = C->getName(); 98191bc56edSDimitry Andric const GlobalValue *ComdatGV = GV->getParent()->getNamedValue(ComdatGVName); 98291bc56edSDimitry Andric if (!ComdatGV) 98391bc56edSDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 98491bc56edSDimitry Andric "' does not exist."); 98591bc56edSDimitry Andric 98691bc56edSDimitry Andric if (ComdatGV->getComdat() != C) 98791bc56edSDimitry Andric report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + 98839d628a0SDimitry Andric "' is not a key for its COMDAT."); 98991bc56edSDimitry Andric 99091bc56edSDimitry Andric return ComdatGV; 99191bc56edSDimitry Andric } 99291bc56edSDimitry Andric 99391bc56edSDimitry Andric static int getSelectionForCOFF(const GlobalValue *GV) { 99491bc56edSDimitry Andric if (const Comdat *C = GV->getComdat()) { 99591bc56edSDimitry Andric const GlobalValue *ComdatKey = getComdatGVForCOFF(GV); 99691bc56edSDimitry Andric if (const auto *GA = dyn_cast<GlobalAlias>(ComdatKey)) 99791bc56edSDimitry Andric ComdatKey = GA->getBaseObject(); 99891bc56edSDimitry Andric if (ComdatKey == GV) { 99991bc56edSDimitry Andric switch (C->getSelectionKind()) { 100091bc56edSDimitry Andric case Comdat::Any: 100191bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ANY; 100291bc56edSDimitry Andric case Comdat::ExactMatch: 100391bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH; 100491bc56edSDimitry Andric case Comdat::Largest: 100591bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_LARGEST; 100691bc56edSDimitry Andric case Comdat::NoDuplicates: 100791bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 100891bc56edSDimitry Andric case Comdat::SameSize: 100991bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_SAME_SIZE; 101091bc56edSDimitry Andric } 101191bc56edSDimitry Andric } else { 101291bc56edSDimitry Andric return COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE; 101391bc56edSDimitry Andric } 101491bc56edSDimitry Andric } 101591bc56edSDimitry Andric return 0; 101691bc56edSDimitry Andric } 101791bc56edSDimitry Andric 1018ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal( 1019d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 1020139f7f9bSDimitry Andric int Selection = 0; 10213ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 1022d88c1a5aSDimitry Andric StringRef Name = GO->getSection(); 102391bc56edSDimitry Andric StringRef COMDATSymName = ""; 1024d88c1a5aSDimitry Andric if (GO->hasComdat()) { 1025d88c1a5aSDimitry Andric Selection = getSelectionForCOFF(GO); 102691bc56edSDimitry Andric const GlobalValue *ComdatGV; 102791bc56edSDimitry Andric if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) 1028d88c1a5aSDimitry Andric ComdatGV = getComdatGVForCOFF(GO); 102991bc56edSDimitry Andric else 1030d88c1a5aSDimitry Andric ComdatGV = GO; 103191bc56edSDimitry Andric 103291bc56edSDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 1033d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV); 103491bc56edSDimitry Andric COMDATSymName = Sym->getName(); 1035139f7f9bSDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 103691bc56edSDimitry Andric } else { 103791bc56edSDimitry Andric Selection = 0; 103891bc56edSDimitry Andric } 1039139f7f9bSDimitry Andric } 10403ca95b02SDimitry Andric 10413ca95b02SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, 1042f785676fSDimitry Andric Selection); 1043f22ef01cSRoman Divacky } 1044f22ef01cSRoman Divacky 104591bc56edSDimitry Andric static const char *getCOFFSectionNameForUniqueGlobal(SectionKind Kind) { 1046f22ef01cSRoman Divacky if (Kind.isText()) 104791bc56edSDimitry Andric return ".text"; 1048f22ef01cSRoman Divacky if (Kind.isBSS()) 104991bc56edSDimitry Andric return ".bss"; 105091bc56edSDimitry Andric if (Kind.isThreadLocal()) 105191bc56edSDimitry Andric return ".tls$"; 105239d628a0SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 105391bc56edSDimitry Andric return ".rdata"; 105439d628a0SDimitry Andric return ".data"; 1055f22ef01cSRoman Divacky } 1056f22ef01cSRoman Divacky 1057ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal( 1058d88c1a5aSDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 105991bc56edSDimitry Andric // If we have -ffunction-sections then we should emit the global value to a 106091bc56edSDimitry Andric // uniqued section specifically for it. 106191bc56edSDimitry Andric bool EmitUniquedSection; 106291bc56edSDimitry Andric if (Kind.isText()) 106391bc56edSDimitry Andric EmitUniquedSection = TM.getFunctionSections(); 106491bc56edSDimitry Andric else 106591bc56edSDimitry Andric EmitUniquedSection = TM.getDataSections(); 1066f22ef01cSRoman Divacky 1067d88c1a5aSDimitry Andric if ((EmitUniquedSection && !Kind.isCommon()) || GO->hasComdat()) { 106891bc56edSDimitry Andric const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); 10693ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 1070f22ef01cSRoman Divacky 1071ffd1746dSEd Schouten Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 1072d88c1a5aSDimitry Andric int Selection = getSelectionForCOFF(GO); 107391bc56edSDimitry Andric if (!Selection) 107491bc56edSDimitry Andric Selection = COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; 107591bc56edSDimitry Andric const GlobalValue *ComdatGV; 1076d88c1a5aSDimitry Andric if (GO->hasComdat()) 1077d88c1a5aSDimitry Andric ComdatGV = getComdatGVForCOFF(GO); 107891bc56edSDimitry Andric else 1079d88c1a5aSDimitry Andric ComdatGV = GO; 1080f22ef01cSRoman Divacky 10813ca95b02SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 10823ca95b02SDimitry Andric if (EmitUniquedSection) 10833ca95b02SDimitry Andric UniqueID = NextUniqueID++; 10843ca95b02SDimitry Andric 108591bc56edSDimitry Andric if (!ComdatGV->hasPrivateLinkage()) { 1086d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(ComdatGV); 108791bc56edSDimitry Andric StringRef COMDATSymName = Sym->getName(); 108891bc56edSDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, 10893ca95b02SDimitry Andric COMDATSymName, Selection, UniqueID); 1090ff0cc061SDimitry Andric } else { 1091ff0cc061SDimitry Andric SmallString<256> TmpData; 1092d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(TmpData, GO, /*CannotUsePrivateLabel=*/true); 1093ff0cc061SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, TmpData, 10943ca95b02SDimitry Andric Selection, UniqueID); 109591bc56edSDimitry Andric } 1096f22ef01cSRoman Divacky } 1097f22ef01cSRoman Divacky 1098f22ef01cSRoman Divacky if (Kind.isText()) 1099f785676fSDimitry Andric return TextSection; 1100f22ef01cSRoman Divacky 1101dff0c46cSDimitry Andric if (Kind.isThreadLocal()) 1102f785676fSDimitry Andric return TLSDataSection; 1103dff0c46cSDimitry Andric 110439d628a0SDimitry Andric if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) 1105f785676fSDimitry Andric return ReadOnlySection; 1106f785676fSDimitry Andric 110791bc56edSDimitry Andric // Note: we claim that common symbols are put in BSSSection, but they are 110891bc56edSDimitry Andric // really emitted with the magic .comm directive, which creates a symbol table 110991bc56edSDimitry Andric // entry but not a section. 111091bc56edSDimitry Andric if (Kind.isBSS() || Kind.isCommon()) 1111f785676fSDimitry Andric return BSSSection; 1112f785676fSDimitry Andric 1113f785676fSDimitry Andric return DataSection; 1114f22ef01cSRoman Divacky } 1115f22ef01cSRoman Divacky 1116ff0cc061SDimitry Andric void TargetLoweringObjectFileCOFF::getNameWithPrefix( 1117d88c1a5aSDimitry Andric SmallVectorImpl<char> &OutName, const GlobalValue *GV, 11187d523365SDimitry Andric const TargetMachine &TM) const { 11197d523365SDimitry Andric bool CannotUsePrivateLabel = false; 1120ff0cc061SDimitry Andric if (GV->hasPrivateLinkage() && 1121ff0cc061SDimitry Andric ((isa<Function>(GV) && TM.getFunctionSections()) || 1122ff0cc061SDimitry Andric (isa<GlobalVariable>(GV) && TM.getDataSections()))) 1123ff0cc061SDimitry Andric CannotUsePrivateLabel = true; 1124ff0cc061SDimitry Andric 1125d88c1a5aSDimitry Andric getMangler().getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); 1126ff0cc061SDimitry Andric } 1127ff0cc061SDimitry Andric 1128ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable( 1129d88c1a5aSDimitry Andric const Function &F, const TargetMachine &TM) const { 1130ff0cc061SDimitry Andric // If the function can be removed, produce a unique section so that 1131ff0cc061SDimitry Andric // the table doesn't prevent the removal. 1132ff0cc061SDimitry Andric const Comdat *C = F.getComdat(); 1133ff0cc061SDimitry Andric bool EmitUniqueSection = TM.getFunctionSections() || C; 1134ff0cc061SDimitry Andric if (!EmitUniqueSection) 1135ff0cc061SDimitry Andric return ReadOnlySection; 1136ff0cc061SDimitry Andric 1137ff0cc061SDimitry Andric // FIXME: we should produce a symbol for F instead. 1138ff0cc061SDimitry Andric if (F.hasPrivateLinkage()) 1139ff0cc061SDimitry Andric return ReadOnlySection; 1140ff0cc061SDimitry Andric 1141d88c1a5aSDimitry Andric MCSymbol *Sym = TM.getSymbol(&F); 1142ff0cc061SDimitry Andric StringRef COMDATSymName = Sym->getName(); 1143ff0cc061SDimitry Andric 1144ff0cc061SDimitry Andric SectionKind Kind = SectionKind::getReadOnly(); 1145ff0cc061SDimitry Andric const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); 11463ca95b02SDimitry Andric unsigned Characteristics = getCOFFSectionFlags(Kind, TM); 1147ff0cc061SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 11483ca95b02SDimitry Andric unsigned UniqueID = NextUniqueID++; 1149ff0cc061SDimitry Andric 1150ff0cc061SDimitry Andric return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, 11513ca95b02SDimitry Andric COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); 1152ff0cc061SDimitry Andric } 1153ff0cc061SDimitry Andric 115424d58133SDimitry Andric void TargetLoweringObjectFileCOFF::emitModuleMetadata( 115524d58133SDimitry Andric MCStreamer &Streamer, Module &M, const TargetMachine &TM) const { 115624d58133SDimitry Andric if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { 1157284c1978SDimitry Andric // Emit the linker options to the linker .drectve section. According to the 11583ca95b02SDimitry Andric // spec, this section is a space-separated string containing flags for 11593ca95b02SDimitry Andric // linker. 1160ff0cc061SDimitry Andric MCSection *Sec = getDrectveSection(); 1161284c1978SDimitry Andric Streamer.SwitchSection(Sec); 11623ca95b02SDimitry Andric for (const auto &Option : LinkerOptions->operands()) { 11633ca95b02SDimitry Andric for (const auto &Piece : cast<MDNode>(Option)->operands()) { 1164284c1978SDimitry Andric // Lead with a space for consistency with our dllexport implementation. 1165ff0cc061SDimitry Andric std::string Directive(" "); 11663ca95b02SDimitry Andric Directive.append(cast<MDString>(Piece)->getString()); 1167ff0cc061SDimitry Andric Streamer.EmitBytes(Directive); 1168284c1978SDimitry Andric } 1169284c1978SDimitry Andric } 1170284c1978SDimitry Andric } 1171db17bf38SDimitry Andric 1172db17bf38SDimitry Andric unsigned Version = 0; 1173db17bf38SDimitry Andric unsigned Flags = 0; 1174db17bf38SDimitry Andric StringRef Section; 1175db17bf38SDimitry Andric 117624d58133SDimitry Andric GetObjCImageInfo(M, Version, Flags, Section); 1177db17bf38SDimitry Andric if (Section.empty()) 1178db17bf38SDimitry Andric return; 1179db17bf38SDimitry Andric 1180db17bf38SDimitry Andric auto &C = getContext(); 1181db17bf38SDimitry Andric auto *S = C.getCOFFSection( 1182db17bf38SDimitry Andric Section, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, 1183db17bf38SDimitry Andric SectionKind::getReadOnly()); 1184db17bf38SDimitry Andric Streamer.SwitchSection(S); 1185db17bf38SDimitry Andric Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); 1186db17bf38SDimitry Andric Streamer.EmitIntValue(Version, 4); 1187db17bf38SDimitry Andric Streamer.EmitIntValue(Flags, 4); 1188db17bf38SDimitry Andric Streamer.AddBlankLine(); 11893ca95b02SDimitry Andric } 119091bc56edSDimitry Andric 1191d88c1a5aSDimitry Andric void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx, 1192d88c1a5aSDimitry Andric const TargetMachine &TM) { 1193d88c1a5aSDimitry Andric TargetLoweringObjectFile::Initialize(Ctx, TM); 1194d88c1a5aSDimitry Andric const Triple &T = TM.getTargetTriple(); 1195d88c1a5aSDimitry Andric if (T.isKnownWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) { 1196d88c1a5aSDimitry Andric StaticCtorSection = 1197d88c1a5aSDimitry Andric Ctx.getCOFFSection(".CRT$XCU", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1198d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ, 1199d88c1a5aSDimitry Andric SectionKind::getReadOnly()); 1200d88c1a5aSDimitry Andric StaticDtorSection = 1201d88c1a5aSDimitry Andric Ctx.getCOFFSection(".CRT$XTX", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1202d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ, 1203d88c1a5aSDimitry Andric SectionKind::getReadOnly()); 1204d88c1a5aSDimitry Andric } else { 1205d88c1a5aSDimitry Andric StaticCtorSection = Ctx.getCOFFSection( 1206d88c1a5aSDimitry Andric ".ctors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1207d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, 1208d88c1a5aSDimitry Andric SectionKind::getData()); 1209d88c1a5aSDimitry Andric StaticDtorSection = Ctx.getCOFFSection( 1210d88c1a5aSDimitry Andric ".dtors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 1211d88c1a5aSDimitry Andric COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, 1212d88c1a5aSDimitry Andric SectionKind::getData()); 1213d88c1a5aSDimitry Andric } 1214d88c1a5aSDimitry Andric } 1215d88c1a5aSDimitry Andric 1216ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection( 121791bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 121839d628a0SDimitry Andric return getContext().getAssociativeCOFFSection( 12193ca95b02SDimitry Andric cast<MCSectionCOFF>(StaticCtorSection), KeySym, 0); 122091bc56edSDimitry Andric } 122191bc56edSDimitry Andric 1222ff0cc061SDimitry Andric MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection( 122391bc56edSDimitry Andric unsigned Priority, const MCSymbol *KeySym) const { 122439d628a0SDimitry Andric return getContext().getAssociativeCOFFSection( 12253ca95b02SDimitry Andric cast<MCSectionCOFF>(StaticDtorSection), KeySym, 0); 122691bc56edSDimitry Andric } 12273dac3a9bSDimitry Andric 12283dac3a9bSDimitry Andric void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal( 1229d88c1a5aSDimitry Andric raw_ostream &OS, const GlobalValue *GV) const { 12307a7e6055SDimitry Andric emitLinkerFlagsForGlobalCOFF(OS, GV, getTargetTriple(), getMangler()); 12313dac3a9bSDimitry Andric } 12323dac3a9bSDimitry Andric 12337a7e6055SDimitry Andric //===----------------------------------------------------------------------===// 12347a7e6055SDimitry Andric // Wasm 12357a7e6055SDimitry Andric //===----------------------------------------------------------------------===// 12367a7e6055SDimitry Andric 12377a7e6055SDimitry Andric static const Comdat *getWasmComdat(const GlobalValue *GV) { 12387a7e6055SDimitry Andric const Comdat *C = GV->getComdat(); 12397a7e6055SDimitry Andric if (!C) 12407a7e6055SDimitry Andric return nullptr; 12417a7e6055SDimitry Andric 12427a7e6055SDimitry Andric if (C->getSelectionKind() != Comdat::Any) 12437a7e6055SDimitry Andric report_fatal_error("Wasm COMDATs only support SelectionKind::Any, '" + 12447a7e6055SDimitry Andric C->getName() + "' cannot be lowered."); 12457a7e6055SDimitry Andric 12467a7e6055SDimitry Andric return C; 12473dac3a9bSDimitry Andric } 12487a7e6055SDimitry Andric 12497a7e6055SDimitry Andric MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal( 12507a7e6055SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 12517a7e6055SDimitry Andric llvm_unreachable("getExplicitSectionGlobal not yet implemented"); 12527a7e6055SDimitry Andric return nullptr; 12537a7e6055SDimitry Andric } 12547a7e6055SDimitry Andric 12557a7e6055SDimitry Andric static MCSectionWasm * 12567a7e6055SDimitry Andric selectWasmSectionForGlobal(MCContext &Ctx, const GlobalObject *GO, 12577a7e6055SDimitry Andric SectionKind Kind, Mangler &Mang, 12587a7e6055SDimitry Andric const TargetMachine &TM, bool EmitUniqueSection, 12597a7e6055SDimitry Andric unsigned Flags, unsigned *NextUniqueID) { 12607a7e6055SDimitry Andric StringRef Group = ""; 12617a7e6055SDimitry Andric if (getWasmComdat(GO)) 12627a7e6055SDimitry Andric llvm_unreachable("comdat not yet supported for wasm"); 12637a7e6055SDimitry Andric 12647a7e6055SDimitry Andric bool UniqueSectionNames = TM.getUniqueSectionNames(); 12657a7e6055SDimitry Andric SmallString<128> Name = getSectionPrefixForGlobal(Kind); 12667a7e6055SDimitry Andric 12677a7e6055SDimitry Andric if (const auto *F = dyn_cast<Function>(GO)) { 12687a7e6055SDimitry Andric const auto &OptionalPrefix = F->getSectionPrefix(); 12697a7e6055SDimitry Andric if (OptionalPrefix) 12707a7e6055SDimitry Andric Name += *OptionalPrefix; 12717a7e6055SDimitry Andric } 12727a7e6055SDimitry Andric 12737a7e6055SDimitry Andric if (EmitUniqueSection && UniqueSectionNames) { 12747a7e6055SDimitry Andric Name.push_back('.'); 12757a7e6055SDimitry Andric TM.getNameWithPrefix(Name, GO, Mang, true); 12767a7e6055SDimitry Andric } 12777a7e6055SDimitry Andric unsigned UniqueID = MCContext::GenericSectionID; 12787a7e6055SDimitry Andric if (EmitUniqueSection && !UniqueSectionNames) { 12797a7e6055SDimitry Andric UniqueID = *NextUniqueID; 12807a7e6055SDimitry Andric (*NextUniqueID)++; 12817a7e6055SDimitry Andric } 12827a7e6055SDimitry Andric return Ctx.getWasmSection(Name, /*Type=*/0, Flags, 12837a7e6055SDimitry Andric Group, UniqueID); 12847a7e6055SDimitry Andric } 12857a7e6055SDimitry Andric 12867a7e6055SDimitry Andric MCSection *TargetLoweringObjectFileWasm::SelectSectionForGlobal( 12877a7e6055SDimitry Andric const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 12887a7e6055SDimitry Andric 12897a7e6055SDimitry Andric if (Kind.isCommon()) 12907a7e6055SDimitry Andric report_fatal_error("mergable sections not supported yet on wasm"); 12917a7e6055SDimitry Andric 12927a7e6055SDimitry Andric // If we have -ffunction-section or -fdata-section then we should emit the 12937a7e6055SDimitry Andric // global value to a uniqued section specifically for it. 12947a7e6055SDimitry Andric bool EmitUniqueSection = false; 12957a7e6055SDimitry Andric if (Kind.isText()) 12967a7e6055SDimitry Andric EmitUniqueSection = TM.getFunctionSections(); 12977a7e6055SDimitry Andric else 12987a7e6055SDimitry Andric EmitUniqueSection = TM.getDataSections(); 12997a7e6055SDimitry Andric EmitUniqueSection |= GO->hasComdat(); 13007a7e6055SDimitry Andric 13017a7e6055SDimitry Andric return selectWasmSectionForGlobal(getContext(), GO, Kind, getMangler(), TM, 13027a7e6055SDimitry Andric EmitUniqueSection, /*Flags=*/0, 13037a7e6055SDimitry Andric &NextUniqueID); 13047a7e6055SDimitry Andric } 13057a7e6055SDimitry Andric 13067a7e6055SDimitry Andric bool TargetLoweringObjectFileWasm::shouldPutJumpTableInFunctionSection( 13077a7e6055SDimitry Andric bool UsesLabelDifference, const Function &F) const { 13087a7e6055SDimitry Andric // We can always create relative relocations, so use another section 13097a7e6055SDimitry Andric // that can be marked non-executable. 13107a7e6055SDimitry Andric return false; 13117a7e6055SDimitry Andric } 13127a7e6055SDimitry Andric 13137a7e6055SDimitry Andric const MCExpr *TargetLoweringObjectFileWasm::lowerRelativeReference( 13147a7e6055SDimitry Andric const GlobalValue *LHS, const GlobalValue *RHS, 13157a7e6055SDimitry Andric const TargetMachine &TM) const { 13167a7e6055SDimitry Andric // We may only use a PLT-relative relocation to refer to unnamed_addr 13177a7e6055SDimitry Andric // functions. 13187a7e6055SDimitry Andric if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) 13197a7e6055SDimitry Andric return nullptr; 13207a7e6055SDimitry Andric 13217a7e6055SDimitry Andric // Basic sanity checks. 13227a7e6055SDimitry Andric if (LHS->getType()->getPointerAddressSpace() != 0 || 13237a7e6055SDimitry Andric RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || 13247a7e6055SDimitry Andric RHS->isThreadLocal()) 13257a7e6055SDimitry Andric return nullptr; 13267a7e6055SDimitry Andric 13277a7e6055SDimitry Andric return MCBinaryExpr::createSub( 13287a7e6055SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(LHS), MCSymbolRefExpr::VK_None, 13297a7e6055SDimitry Andric getContext()), 13307a7e6055SDimitry Andric MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); 13317a7e6055SDimitry Andric } 13327a7e6055SDimitry Andric 13337a7e6055SDimitry Andric void 13347a7e6055SDimitry Andric TargetLoweringObjectFileWasm::InitializeWasm() { 13357a7e6055SDimitry Andric // TODO: Initialize StaticCtorSection and StaticDtorSection. 13363dac3a9bSDimitry Andric } 1337