//===-- llvm/Target/TargetLoweringObjectFile.cpp - Object File Info -------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements classes used to handle lowerings specific to common // object file formats. // //===----------------------------------------------------------------------===// #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" #include "llvm/GlobalVariable.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Support/Mangler.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" using namespace llvm; //===----------------------------------------------------------------------===// // Generic Code //===----------------------------------------------------------------------===// TargetLoweringObjectFile::TargetLoweringObjectFile() : Ctx(0) { TextSection = 0; DataSection = 0; BSSSection = 0; ReadOnlySection = 0; StaticCtorSection = 0; StaticDtorSection = 0; LSDASection = 0; EHFrameSection = 0; DwarfAbbrevSection = 0; DwarfInfoSection = 0; DwarfLineSection = 0; DwarfFrameSection = 0; DwarfPubNamesSection = 0; DwarfPubTypesSection = 0; DwarfDebugInlineSection = 0; DwarfStrSection = 0; DwarfLocSection = 0; DwarfARangesSection = 0; DwarfRangesSection = 0; DwarfMacroInfoSection = 0; } TargetLoweringObjectFile::~TargetLoweringObjectFile() { } static bool isSuitableForBSS(const GlobalVariable *GV) { Constant *C = GV->getInitializer(); // Must have zero initializer. if (!C->isNullValue()) return false; // Leave constant zeros in readonly constant sections, so they can be shared. if (GV->isConstant()) return false; // If the global has an explicit section specified, don't put it in BSS. if (!GV->getSection().empty()) return false; // If -nozero-initialized-in-bss is specified, don't ever use BSS. if (NoZerosInBSS) return false; // Otherwise, put it in BSS! return true; } /// IsNullTerminatedString - Return true if the specified constant (which is /// known to have a type that is an array of 1/2/4 byte elements) ends with a /// nul value and contains no other nuls in it. static bool IsNullTerminatedString(const Constant *C) { const ArrayType *ATy = cast(C->getType()); // First check: is we have constant array of i8 terminated with zero if (const ConstantArray *CVA = dyn_cast(C)) { if (ATy->getNumElements() == 0) return false; ConstantInt *Null = dyn_cast(CVA->getOperand(ATy->getNumElements()-1)); if (Null == 0 || Null->getZExtValue() != 0) return false; // Not null terminated. // Verify that the null doesn't occur anywhere else in the string. for (unsigned i = 0, e = ATy->getNumElements()-1; i != e; ++i) // Reject constantexpr elements etc. if (!isa(CVA->getOperand(i)) || CVA->getOperand(i) == Null) return false; return true; } // Another possibility: [1 x i8] zeroinitializer if (isa(C)) return ATy->getNumElements() == 1; return false; } /// getKindForGlobal - This is a top-level target-independent classifier for /// a global variable. Given an global variable and information from TM, it /// classifies the global in a variety of ways that make various target /// implementations simpler. The target implementation is free to ignore this /// extra info of course. SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV, const TargetMachine &TM){ assert(!GV->isDeclaration() && !GV->hasAvailableExternallyLinkage() && "Can only be used for global definitions"); Reloc::Model ReloModel = TM.getRelocationModel(); // Early exit - functions should be always in text sections. const GlobalVariable *GVar = dyn_cast(GV); if (GVar == 0) return SectionKind::getText(); // Handle thread-local data first. if (GVar->isThreadLocal()) { if (isSuitableForBSS(GVar)) return SectionKind::getThreadBSS(); return SectionKind::getThreadData(); } // Variable can be easily put to BSS section. if (isSuitableForBSS(GVar)) return SectionKind::getBSS(); Constant *C = GVar->getInitializer(); // If the global is marked constant, we can put it into a mergable section, // a mergable string section, or general .data if it contains relocations. if (GVar->isConstant()) { // If the initializer for the global contains something that requires a // relocation, then we may have to drop this into a wriable data section // even though it is marked const. switch (C->getRelocationInfo()) { default: llvm_unreachable("unknown relocation info kind"); case Constant::NoRelocation: // If initializer is a null-terminated string, put it in a "cstring" // section of the right width. if (const ArrayType *ATy = dyn_cast(C->getType())) { if (const IntegerType *ITy = dyn_cast(ATy->getElementType())) { if ((ITy->getBitWidth() == 8 || ITy->getBitWidth() == 16 || ITy->getBitWidth() == 32) && IsNullTerminatedString(C)) { if (ITy->getBitWidth() == 8) return SectionKind::getMergeable1ByteCString(); if (ITy->getBitWidth() == 16) return SectionKind::getMergeable2ByteCString(); assert(ITy->getBitWidth() == 32 && "Unknown width"); return SectionKind::getMergeable4ByteCString(); } } } // Otherwise, just drop it into a mergable constant section. If we have // a section for this size, use it, otherwise use the arbitrary sized // mergable section. switch (TM.getTargetData()->getTypeAllocSize(C->getType())) { case 4: return SectionKind::getMergeableConst4(); case 8: return SectionKind::getMergeableConst8(); case 16: return SectionKind::getMergeableConst16(); default: return SectionKind::getMergeableConst(); } case Constant::LocalRelocation: // In static relocation model, the linker will resolve all addresses, so // the relocation entries will actually be constants by the time the app // starts up. However, we can't put this into a mergable section, because // the linker doesn't take relocations into consideration when it tries to // merge entries in the section. if (ReloModel == Reloc::Static) return SectionKind::getReadOnly(); // Otherwise, the dynamic linker needs to fix it up, put it in the // writable data.rel.local section. return SectionKind::getReadOnlyWithRelLocal(); case Constant::GlobalRelocations: // In static relocation model, the linker will resolve all addresses, so // the relocation entries will actually be constants by the time the app // starts up. However, we can't put this into a mergable section, because // the linker doesn't take relocations into consideration when it tries to // merge entries in the section. if (ReloModel == Reloc::Static) return SectionKind::getReadOnly(); // Otherwise, the dynamic linker needs to fix it up, put it in the // writable data.rel section. return SectionKind::getReadOnlyWithRel(); } } // Okay, this isn't a constant. If the initializer for the global is going // to require a runtime relocation by the dynamic linker, put it into a more // specific section to improve startup time of the app. This coalesces these // globals together onto fewer pages, improving the locality of the dynamic // linker. if (ReloModel == Reloc::Static) return SectionKind::getDataNoRel(); switch (C->getRelocationInfo()) { default: llvm_unreachable("unknown relocation info kind"); case Constant::NoRelocation: return SectionKind::getDataNoRel(); case Constant::LocalRelocation: return SectionKind::getDataRelLocal(); case Constant::GlobalRelocations: return SectionKind::getDataRel(); } } /// SectionForGlobal - This method computes the appropriate section to emit /// the specified global variable or function definition. This should not /// be passed external (or available externally) globals. const MCSection *TargetLoweringObjectFile:: SectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const { // Select section name. if (GV->hasSection()) return getExplicitSectionGlobal(GV, Kind, Mang, TM); // Use default section depending on the 'type' of global return SelectSectionForGlobal(GV, Kind, Mang, TM); } // Lame default implementation. Calculate the section name for global. const MCSection * TargetLoweringObjectFile::SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const{ assert(!Kind.isThreadLocal() && "Doesn't support TLS"); if (Kind.isText()) return getTextSection(); if (Kind.isBSS() && BSSSection != 0) return BSSSection; if (Kind.isReadOnly() && ReadOnlySection != 0) return ReadOnlySection; return getDataSection(); } /// getSectionForConstant - Given a mergable constant with the /// specified size and relocation information, return a section that it /// should be placed in. const MCSection * TargetLoweringObjectFile::getSectionForConstant(SectionKind Kind) const { if (Kind.isReadOnly() && ReadOnlySection != 0) return ReadOnlySection; return DataSection; } /// getSymbolForDwarfGlobalReference - Return an MCExpr to use for a /// pc-relative reference to the specified global variable from exception /// handling information. In addition to the symbol, this returns /// by-reference: /// /// IsIndirect - True if the returned symbol is actually a stub that contains /// the address of the symbol, false if the symbol is the global itself. /// /// IsPCRel - True if the symbol reference is already pc-relative, false if /// the caller needs to subtract off the address of the reference from the /// symbol. /// const MCExpr *TargetLoweringObjectFile:: getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, MachineModuleInfo *MMI, bool &IsIndirect, bool &IsPCRel) const { // The generic implementation of this just returns a direct reference to the // symbol. IsIndirect = false; IsPCRel = false; SmallString<128> Name; Mang->getNameWithPrefix(Name, GV, false); return MCSymbolRefExpr::Create(Name.str(), getContext()); } //===----------------------------------------------------------------------===// // ELF //===----------------------------------------------------------------------===// typedef StringMap ELFUniqueMapTy; TargetLoweringObjectFileELF::~TargetLoweringObjectFileELF() { // If we have the section uniquing map, free it. delete (ELFUniqueMapTy*)UniquingMap; } const MCSection *TargetLoweringObjectFileELF:: getELFSection(StringRef Section, unsigned Type, unsigned Flags, SectionKind Kind, bool IsExplicit) const { if (UniquingMap == 0) UniquingMap = new ELFUniqueMapTy(); ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)UniquingMap; // Do the lookup, if we have a hit, return it. const MCSectionELF *&Entry = Map[Section]; if (Entry) return Entry; return Entry = MCSectionELF::Create(Section, Type, Flags, Kind, IsExplicit, getContext()); } void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx, const TargetMachine &TM) { if (UniquingMap != 0) ((ELFUniqueMapTy*)UniquingMap)->clear(); TargetLoweringObjectFile::Initialize(Ctx, TM); BSSSection = getELFSection(".bss", MCSectionELF::SHT_NOBITS, MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC, SectionKind::getBSS()); TextSection = getELFSection(".text", MCSectionELF::SHT_PROGBITS, MCSectionELF::SHF_EXECINSTR | MCSectionELF::SHF_ALLOC, SectionKind::getText()); DataSection = getELFSection(".data", MCSectionELF::SHT_PROGBITS, MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC, SectionKind::getDataRel()); ReadOnlySection = getELFSection(".rodata", MCSectionELF::SHT_PROGBITS, MCSectionELF::SHF_ALLOC, SectionKind::getReadOnly()); TLSDataSection = getELFSection(".tdata", MCSectionELF::SHT_PROGBITS, MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_TLS | MCSectionELF::SHF_WRITE, SectionKind::getThreadData()); TLSBSSSection = getELFSection(".tbss", MCSectionELF::SHT_NOBITS, MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_TLS | MCSectionELF::SHF_WRITE, SectionKind::getThreadBSS()); DataRelSection = getELFSection(".data.rel", MCSectionELF::SHT_PROGBITS, MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE, SectionKind::getDataRel()); DataRelLocalSection = getELFSection(".data.rel.local", MCSectionELF::SHT_PROGBITS, MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE, SectionKind::getDataRelLocal()); DataRelROSection = getELFSection(".data.rel.ro", MCSectionELF::SHT_PROGBITS, MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE, SectionKind::getReadOnlyWithRel()); DataRelROLocalSection = getELFSection(".data.rel.ro.local", MCSectionELF::SHT_PROGBITS, MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE, SectionKind::getReadOnlyWithRelLocal()); MergeableConst4Section = getELFSection(".rodata.cst4", MCSectionELF::SHT_PROGBITS, MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE, SectionKind::getMergeableConst4()); MergeableConst8Section = getELFSection(".rodata.cst8", MCSectionELF::SHT_PROGBITS, MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE, SectionKind::getMergeableConst8()); MergeableConst16Section = getELFSection(".rodata.cst16", MCSectionELF::SHT_PROGBITS, MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE, SectionKind::getMergeableConst16()); StaticCtorSection = getELFSection(".ctors", MCSectionELF::SHT_PROGBITS, MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE, SectionKind::getDataRel()); StaticDtorSection = getELFSection(".dtors", MCSectionELF::SHT_PROGBITS, MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE, SectionKind::getDataRel()); // Exception Handling Sections. // FIXME: We're emitting LSDA info into a readonly section on ELF, even though // it contains relocatable pointers. In PIC mode, this is probably a big // runtime hit for C++ apps. Either the contents of the LSDA need to be // adjusted or this should be a data section. LSDASection = getELFSection(".gcc_except_table", MCSectionELF::SHT_PROGBITS, MCSectionELF::SHF_ALLOC, SectionKind::getReadOnly()); EHFrameSection = getELFSection(".eh_frame", MCSectionELF::SHT_PROGBITS, MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE, SectionKind::getDataRel()); // Debug Info Sections. DwarfAbbrevSection = getELFSection(".debug_abbrev", MCSectionELF::SHT_PROGBITS, 0, SectionKind::getMetadata()); DwarfInfoSection = getELFSection(".debug_info", MCSectionELF::SHT_PROGBITS, 0, SectionKind::getMetadata()); DwarfLineSection = getELFSection(".debug_line", MCSectionELF::SHT_PROGBITS, 0, SectionKind::getMetadata()); DwarfFrameSection = getELFSection(".debug_frame", MCSectionELF::SHT_PROGBITS, 0, SectionKind::getMetadata()); DwarfPubNamesSection = getELFSection(".debug_pubnames", MCSectionELF::SHT_PROGBITS, 0, SectionKind::getMetadata()); DwarfPubTypesSection = getELFSection(".debug_pubtypes", MCSectionELF::SHT_PROGBITS, 0, SectionKind::getMetadata()); DwarfStrSection = getELFSection(".debug_str", MCSectionELF::SHT_PROGBITS, 0, SectionKind::getMetadata()); DwarfLocSection = getELFSection(".debug_loc", MCSectionELF::SHT_PROGBITS, 0, SectionKind::getMetadata()); DwarfARangesSection = getELFSection(".debug_aranges", MCSectionELF::SHT_PROGBITS, 0, SectionKind::getMetadata()); DwarfRangesSection = getELFSection(".debug_ranges", MCSectionELF::SHT_PROGBITS, 0, SectionKind::getMetadata()); DwarfMacroInfoSection = getELFSection(".debug_macinfo", MCSectionELF::SHT_PROGBITS, 0, SectionKind::getMetadata()); } static SectionKind getELFKindForNamedSection(const char *Name, SectionKind K) { if (Name[0] != '.') return K; // Some lame default implementation based on some magic section names. if (strcmp(Name, ".bss") == 0 || strncmp(Name, ".bss.", 5) == 0 || strncmp(Name, ".gnu.linkonce.b.", 16) == 0 || strncmp(Name, ".llvm.linkonce.b.", 17) == 0 || strcmp(Name, ".sbss") == 0 || strncmp(Name, ".sbss.", 6) == 0 || strncmp(Name, ".gnu.linkonce.sb.", 17) == 0 || strncmp(Name, ".llvm.linkonce.sb.", 18) == 0) return SectionKind::getBSS(); if (strcmp(Name, ".tdata") == 0 || strncmp(Name, ".tdata.", 7) == 0 || strncmp(Name, ".gnu.linkonce.td.", 17) == 0 || strncmp(Name, ".llvm.linkonce.td.", 18) == 0) return SectionKind::getThreadData(); if (strcmp(Name, ".tbss") == 0 || strncmp(Name, ".tbss.", 6) == 0 || strncmp(Name, ".gnu.linkonce.tb.", 17) == 0 || strncmp(Name, ".llvm.linkonce.tb.", 18) == 0) return SectionKind::getThreadBSS(); return K; } static unsigned getELFSectionType(const char *Name, SectionKind K) { if (strcmp(Name, ".init_array") == 0) return MCSectionELF::SHT_INIT_ARRAY; if (strcmp(Name, ".fini_array") == 0) return MCSectionELF::SHT_FINI_ARRAY; if (strcmp(Name, ".preinit_array") == 0) return MCSectionELF::SHT_PREINIT_ARRAY; if (K.isBSS() || K.isThreadBSS()) return MCSectionELF::SHT_NOBITS; return MCSectionELF::SHT_PROGBITS; } static unsigned getELFSectionFlags(SectionKind K) { unsigned Flags = 0; if (!K.isMetadata()) Flags |= MCSectionELF::SHF_ALLOC; if (K.isText()) Flags |= MCSectionELF::SHF_EXECINSTR; if (K.isWriteable()) Flags |= MCSectionELF::SHF_WRITE; if (K.isThreadLocal()) Flags |= MCSectionELF::SHF_TLS; // K.isMergeableConst() is left out to honour PR4650 if (K.isMergeableCString() || K.isMergeableConst4() || K.isMergeableConst8() || K.isMergeableConst16()) Flags |= MCSectionELF::SHF_MERGE; if (K.isMergeableCString()) Flags |= MCSectionELF::SHF_STRINGS; return Flags; } const MCSection *TargetLoweringObjectFileELF:: getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const { const char *SectionName = GV->getSection().c_str(); // Infer section flags from the section name if we can. Kind = getELFKindForNamedSection(SectionName, Kind); return getELFSection(SectionName, getELFSectionType(SectionName, Kind), getELFSectionFlags(Kind), Kind, true); } static const char *getSectionPrefixForUniqueGlobal(SectionKind Kind) { if (Kind.isText()) return ".gnu.linkonce.t."; if (Kind.isReadOnly()) return ".gnu.linkonce.r."; if (Kind.isThreadData()) return ".gnu.linkonce.td."; if (Kind.isThreadBSS()) return ".gnu.linkonce.tb."; if (Kind.isBSS()) return ".gnu.linkonce.b."; if (Kind.isDataNoRel()) return ".gnu.linkonce.d."; if (Kind.isDataRelLocal()) return ".gnu.linkonce.d.rel.local."; if (Kind.isDataRel()) return ".gnu.linkonce.d.rel."; if (Kind.isReadOnlyWithRelLocal()) return ".gnu.linkonce.d.rel.ro.local."; assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); return ".gnu.linkonce.d.rel.ro."; } const MCSection *TargetLoweringObjectFileELF:: SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const { // If this global is linkonce/weak and the target handles this by emitting it // into a 'uniqued' section name, create and return the section now. if (GV->isWeakForLinker()) { const char *Prefix = getSectionPrefixForUniqueGlobal(Kind); std::string Name = Mang->makeNameProper(GV->getNameStr()); return getELFSection((Prefix+Name).c_str(), getELFSectionType((Prefix+Name).c_str(), Kind), getELFSectionFlags(Kind), Kind); } if (Kind.isText()) return TextSection; if (Kind.isMergeable1ByteCString() || Kind.isMergeable2ByteCString() || Kind.isMergeable4ByteCString()) { // We also need alignment here. // FIXME: this is getting the alignment of the character, not the // alignment of the global! unsigned Align = TM.getTargetData()->getPreferredAlignment(cast(GV)); const char *SizeSpec = ".rodata.str1."; if (Kind.isMergeable2ByteCString()) SizeSpec = ".rodata.str2."; else if (Kind.isMergeable4ByteCString()) SizeSpec = ".rodata.str4."; else assert(Kind.isMergeable1ByteCString() && "unknown string width"); std::string Name = SizeSpec + utostr(Align); return getELFSection(Name.c_str(), MCSectionELF::SHT_PROGBITS, MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE | MCSectionELF::SHF_STRINGS, Kind); } if (Kind.isMergeableConst()) { if (Kind.isMergeableConst4() && MergeableConst4Section) return MergeableConst4Section; if (Kind.isMergeableConst8() && MergeableConst8Section) return MergeableConst8Section; if (Kind.isMergeableConst16() && MergeableConst16Section) return MergeableConst16Section; return ReadOnlySection; // .const } if (Kind.isReadOnly()) return ReadOnlySection; if (Kind.isThreadData()) return TLSDataSection; if (Kind.isThreadBSS()) return TLSBSSSection; if (Kind.isBSS()) return BSSSection; if (Kind.isDataNoRel()) return DataSection; if (Kind.isDataRelLocal()) return DataRelLocalSection; if (Kind.isDataRel()) return DataRelSection; if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection; assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); return DataRelROSection; } /// getSectionForConstant - Given a mergeable constant with the /// specified size and relocation information, return a section that it /// should be placed in. const MCSection *TargetLoweringObjectFileELF:: getSectionForConstant(SectionKind Kind) const { if (Kind.isMergeableConst4() && MergeableConst4Section) return MergeableConst4Section; if (Kind.isMergeableConst8() && MergeableConst8Section) return MergeableConst8Section; if (Kind.isMergeableConst16() && MergeableConst16Section) return MergeableConst16Section; if (Kind.isReadOnly()) return ReadOnlySection; if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection; assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); return DataRelROSection; } //===----------------------------------------------------------------------===// // MachO //===----------------------------------------------------------------------===// typedef StringMap MachOUniqueMapTy; TargetLoweringObjectFileMachO::~TargetLoweringObjectFileMachO() { // If we have the MachO uniquing map, free it. delete (MachOUniqueMapTy*)UniquingMap; } const MCSectionMachO *TargetLoweringObjectFileMachO:: getMachOSection(const StringRef &Segment, const StringRef &Section, unsigned TypeAndAttributes, unsigned Reserved2, SectionKind Kind) const { // We unique sections by their segment/section pair. The returned section // may not have the same flags as the requested section, if so this should be // diagnosed by the client as an error. // Create the map if it doesn't already exist. if (UniquingMap == 0) UniquingMap = new MachOUniqueMapTy(); MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)UniquingMap; // Form the name to look up. SmallString<64> Name; Name += Segment; Name.push_back(','); Name += Section; // Do the lookup, if we have a hit, return it. const MCSectionMachO *&Entry = Map[Name.str()]; if (Entry) return Entry; // Otherwise, return a new section. return Entry = MCSectionMachO::Create(Segment, Section, TypeAndAttributes, Reserved2, Kind, getContext()); } void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx, const TargetMachine &TM) { if (UniquingMap != 0) ((MachOUniqueMapTy*)UniquingMap)->clear(); TargetLoweringObjectFile::Initialize(Ctx, TM); TextSection // .text = getMachOSection("__TEXT", "__text", MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, SectionKind::getText()); DataSection // .data = getMachOSection("__DATA", "__data", 0, SectionKind::getDataRel()); CStringSection // .cstring = getMachOSection("__TEXT", "__cstring", MCSectionMachO::S_CSTRING_LITERALS, SectionKind::getMergeable1ByteCString()); UStringSection = getMachOSection("__TEXT","__ustring", 0, SectionKind::getMergeable2ByteCString()); FourByteConstantSection // .literal4 = getMachOSection("__TEXT", "__literal4", MCSectionMachO::S_4BYTE_LITERALS, SectionKind::getMergeableConst4()); EightByteConstantSection // .literal8 = getMachOSection("__TEXT", "__literal8", MCSectionMachO::S_8BYTE_LITERALS, SectionKind::getMergeableConst8()); // ld_classic doesn't support .literal16 in 32-bit mode, and ld64 falls back // to using it in -static mode. SixteenByteConstantSection = 0; if (TM.getRelocationModel() != Reloc::Static && TM.getTargetData()->getPointerSize() == 32) SixteenByteConstantSection = // .literal16 getMachOSection("__TEXT", "__literal16",MCSectionMachO::S_16BYTE_LITERALS, SectionKind::getMergeableConst16()); ReadOnlySection // .const = getMachOSection("__TEXT", "__const", 0, SectionKind::getReadOnly()); TextCoalSection = getMachOSection("__TEXT", "__textcoal_nt", MCSectionMachO::S_COALESCED | MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, SectionKind::getText()); ConstTextCoalSection = getMachOSection("__TEXT", "__const_coal", MCSectionMachO::S_COALESCED, SectionKind::getText()); ConstDataCoalSection = getMachOSection("__DATA","__const_coal", MCSectionMachO::S_COALESCED, SectionKind::getText()); ConstDataSection // .const_data = getMachOSection("__DATA", "__const", 0, SectionKind::getReadOnlyWithRel()); DataCoalSection = getMachOSection("__DATA","__datacoal_nt", MCSectionMachO::S_COALESCED, SectionKind::getDataRel()); LazySymbolPointerSection = getMachOSection("__DATA", "__la_symbol_ptr", MCSectionMachO::S_LAZY_SYMBOL_POINTERS, SectionKind::getMetadata()); NonLazySymbolPointerSection = getMachOSection("__DATA", "__nl_symbol_ptr", MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, SectionKind::getMetadata()); if (TM.getRelocationModel() == Reloc::Static) { StaticCtorSection = getMachOSection("__TEXT", "__constructor", 0,SectionKind::getDataRel()); StaticDtorSection = getMachOSection("__TEXT", "__destructor", 0, SectionKind::getDataRel()); } else { StaticCtorSection = getMachOSection("__DATA", "__mod_init_func", MCSectionMachO::S_MOD_INIT_FUNC_POINTERS, SectionKind::getDataRel()); StaticDtorSection = getMachOSection("__DATA", "__mod_term_func", MCSectionMachO::S_MOD_TERM_FUNC_POINTERS, SectionKind::getDataRel()); } // Exception Handling. LSDASection = getMachOSection("__TEXT", "__gcc_except_tab", 0, SectionKind::getReadOnly()); EHFrameSection = getMachOSection("__TEXT", "__eh_frame", MCSectionMachO::S_COALESCED | MCSectionMachO::S_ATTR_NO_TOC | MCSectionMachO::S_ATTR_STRIP_STATIC_SYMS | MCSectionMachO::S_ATTR_LIVE_SUPPORT, SectionKind::getReadOnly()); // Debug Information. DwarfAbbrevSection = getMachOSection("__DWARF", "__debug_abbrev", MCSectionMachO::S_ATTR_DEBUG, SectionKind::getMetadata()); DwarfInfoSection = getMachOSection("__DWARF", "__debug_info", MCSectionMachO::S_ATTR_DEBUG, SectionKind::getMetadata()); DwarfLineSection = getMachOSection("__DWARF", "__debug_line", MCSectionMachO::S_ATTR_DEBUG, SectionKind::getMetadata()); DwarfFrameSection = getMachOSection("__DWARF", "__debug_frame", MCSectionMachO::S_ATTR_DEBUG, SectionKind::getMetadata()); DwarfPubNamesSection = getMachOSection("__DWARF", "__debug_pubnames", MCSectionMachO::S_ATTR_DEBUG, SectionKind::getMetadata()); DwarfPubTypesSection = getMachOSection("__DWARF", "__debug_pubtypes", MCSectionMachO::S_ATTR_DEBUG, SectionKind::getMetadata()); DwarfStrSection = getMachOSection("__DWARF", "__debug_str", MCSectionMachO::S_ATTR_DEBUG, SectionKind::getMetadata()); DwarfLocSection = getMachOSection("__DWARF", "__debug_loc", MCSectionMachO::S_ATTR_DEBUG, SectionKind::getMetadata()); DwarfARangesSection = getMachOSection("__DWARF", "__debug_aranges", MCSectionMachO::S_ATTR_DEBUG, SectionKind::getMetadata()); DwarfRangesSection = getMachOSection("__DWARF", "__debug_ranges", MCSectionMachO::S_ATTR_DEBUG, SectionKind::getMetadata()); DwarfMacroInfoSection = getMachOSection("__DWARF", "__debug_macinfo", MCSectionMachO::S_ATTR_DEBUG, SectionKind::getMetadata()); DwarfDebugInlineSection = getMachOSection("__DWARF", "__debug_inlined", MCSectionMachO::S_ATTR_DEBUG, SectionKind::getMetadata()); } const MCSection *TargetLoweringObjectFileMachO:: getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const { // Parse the section specifier and create it if valid. StringRef Segment, Section; unsigned TAA, StubSize; std::string ErrorCode = MCSectionMachO::ParseSectionSpecifier(GV->getSection(), Segment, Section, TAA, StubSize); if (!ErrorCode.empty()) { // If invalid, report the error with llvm_report_error. llvm_report_error("Global variable '" + GV->getNameStr() + "' has an invalid section specifier '" + GV->getSection()+ "': " + ErrorCode + "."); // Fall back to dropping it into the data section. return DataSection; } // Get the section. const MCSectionMachO *S = getMachOSection(Segment, Section, TAA, StubSize, Kind); // Okay, now that we got the section, verify that the TAA & StubSize agree. // If the user declared multiple globals with different section flags, we need // to reject it here. if (S->getTypeAndAttributes() != TAA || S->getStubSize() != StubSize) { // If invalid, report the error with llvm_report_error. llvm_report_error("Global variable '" + GV->getNameStr() + "' section type or attributes does not match previous" " section specifier"); } return S; } const MCSection *TargetLoweringObjectFileMachO:: SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const { assert(!Kind.isThreadLocal() && "Darwin doesn't support TLS"); if (Kind.isText()) return GV->isWeakForLinker() ? TextCoalSection : TextSection; // If this is weak/linkonce, put this in a coalescable section, either in text // or data depending on if it is writable. if (GV->isWeakForLinker()) { if (Kind.isReadOnly()) return ConstTextCoalSection; return DataCoalSection; } // FIXME: Alignment check should be handled by section classifier. if (Kind.isMergeable1ByteCString() || Kind.isMergeable2ByteCString()) { if (TM.getTargetData()->getPreferredAlignment( cast(GV)) < 32) { if (Kind.isMergeable1ByteCString()) return CStringSection; assert(Kind.isMergeable2ByteCString()); return UStringSection; } } if (Kind.isMergeableConst()) { if (Kind.isMergeableConst4()) return FourByteConstantSection; if (Kind.isMergeableConst8()) return EightByteConstantSection; if (Kind.isMergeableConst16() && SixteenByteConstantSection) return SixteenByteConstantSection; } // Otherwise, if it is readonly, but not something we can specially optimize, // just drop it in .const. if (Kind.isReadOnly()) return ReadOnlySection; // If this is marked const, put it into a const section. But if the dynamic // linker needs to write to it, put it in the data segment. if (Kind.isReadOnlyWithRel()) return ConstDataSection; // Otherwise, just drop the variable in the normal data section. return DataSection; } const MCSection * TargetLoweringObjectFileMachO::getSectionForConstant(SectionKind Kind) const { // If this constant requires a relocation, we have to put it in the data // segment, not in the text segment. if (Kind.isDataRel()) return ConstDataSection; if (Kind.isMergeableConst4()) return FourByteConstantSection; if (Kind.isMergeableConst8()) return EightByteConstantSection; if (Kind.isMergeableConst16() && SixteenByteConstantSection) return SixteenByteConstantSection; return ReadOnlySection; // .const } /// shouldEmitUsedDirectiveFor - This hook allows targets to selectively decide /// not to emit the UsedDirective for some symbols in llvm.used. // FIXME: REMOVE this (rdar://7071300) bool TargetLoweringObjectFileMachO:: shouldEmitUsedDirectiveFor(const GlobalValue *GV, Mangler *Mang) const { /// On Darwin, internally linked data beginning with "L" or "l" does not have /// the directive emitted (this occurs in ObjC metadata). if (!GV) return false; // Check whether the mangled name has the "Private" or "LinkerPrivate" prefix. if (GV->hasLocalLinkage() && !isa(GV)) { // FIXME: ObjC metadata is currently emitted as internal symbols that have // \1L and \0l prefixes on them. Fix them to be Private/LinkerPrivate and // this horrible hack can go away. const std::string &Name = Mang->getMangledName(GV); if (Name[0] == 'L' || Name[0] == 'l') return false; } return true; } const MCExpr *TargetLoweringObjectFileMachO:: getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, MachineModuleInfo *MMI, bool &IsIndirect, bool &IsPCRel) const { // The mach-o version of this method defaults to returning a stub reference. IsIndirect = true; IsPCRel = false; SmallString<128> Name; Mang->getNameWithPrefix(Name, GV, true); Name += "$non_lazy_ptr"; return MCSymbolRefExpr::Create(Name.str(), getContext()); } //===----------------------------------------------------------------------===// // COFF //===----------------------------------------------------------------------===// typedef StringMap COFFUniqueMapTy; TargetLoweringObjectFileCOFF::~TargetLoweringObjectFileCOFF() { delete (COFFUniqueMapTy*)UniquingMap; } const MCSection *TargetLoweringObjectFileCOFF:: getCOFFSection(const char *Name, bool isDirective, SectionKind Kind) const { // Create the map if it doesn't already exist. if (UniquingMap == 0) UniquingMap = new MachOUniqueMapTy(); COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)UniquingMap; // Do the lookup, if we have a hit, return it. const MCSectionCOFF *&Entry = Map[Name]; if (Entry) return Entry; return Entry = MCSectionCOFF::Create(Name, isDirective, Kind, getContext()); } void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx, const TargetMachine &TM) { if (UniquingMap != 0) ((COFFUniqueMapTy*)UniquingMap)->clear(); TargetLoweringObjectFile::Initialize(Ctx, TM); TextSection = getCOFFSection("\t.text", true, SectionKind::getText()); DataSection = getCOFFSection("\t.data", true, SectionKind::getDataRel()); StaticCtorSection = getCOFFSection(".ctors", false, SectionKind::getDataRel()); StaticDtorSection = getCOFFSection(".dtors", false, SectionKind::getDataRel()); // FIXME: We're emitting LSDA info into a readonly section on COFF, even // though it contains relocatable pointers. In PIC mode, this is probably a // big runtime hit for C++ apps. Either the contents of the LSDA need to be // adjusted or this should be a data section. LSDASection = getCOFFSection(".gcc_except_table", false, SectionKind::getReadOnly()); EHFrameSection = getCOFFSection(".eh_frame", false, SectionKind::getDataRel()); // Debug info. // FIXME: Don't use 'directive' mode here. DwarfAbbrevSection = getCOFFSection("\t.section\t.debug_abbrev,\"dr\"", true, SectionKind::getMetadata()); DwarfInfoSection = getCOFFSection("\t.section\t.debug_info,\"dr\"", true, SectionKind::getMetadata()); DwarfLineSection = getCOFFSection("\t.section\t.debug_line,\"dr\"", true, SectionKind::getMetadata()); DwarfFrameSection = getCOFFSection("\t.section\t.debug_frame,\"dr\"", true, SectionKind::getMetadata()); DwarfPubNamesSection = getCOFFSection("\t.section\t.debug_pubnames,\"dr\"", true, SectionKind::getMetadata()); DwarfPubTypesSection = getCOFFSection("\t.section\t.debug_pubtypes,\"dr\"", true, SectionKind::getMetadata()); DwarfStrSection = getCOFFSection("\t.section\t.debug_str,\"dr\"", true, SectionKind::getMetadata()); DwarfLocSection = getCOFFSection("\t.section\t.debug_loc,\"dr\"", true, SectionKind::getMetadata()); DwarfARangesSection = getCOFFSection("\t.section\t.debug_aranges,\"dr\"", true, SectionKind::getMetadata()); DwarfRangesSection = getCOFFSection("\t.section\t.debug_ranges,\"dr\"", true, SectionKind::getMetadata()); DwarfMacroInfoSection = getCOFFSection("\t.section\t.debug_macinfo,\"dr\"", true, SectionKind::getMetadata()); } const MCSection *TargetLoweringObjectFileCOFF:: getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const { return getCOFFSection(GV->getSection().c_str(), false, Kind); } static const char *getCOFFSectionPrefixForUniqueGlobal(SectionKind Kind) { if (Kind.isText()) return ".text$linkonce"; if (Kind.isWriteable()) return ".data$linkonce"; return ".rdata$linkonce"; } const MCSection *TargetLoweringObjectFileCOFF:: SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const { assert(!Kind.isThreadLocal() && "Doesn't support TLS"); // If this global is linkonce/weak and the target handles this by emitting it // into a 'uniqued' section name, create and return the section now. if (GV->isWeakForLinker()) { const char *Prefix = getCOFFSectionPrefixForUniqueGlobal(Kind); std::string Name = Mang->makeNameProper(GV->getNameStr()); return getCOFFSection((Prefix+Name).c_str(), false, Kind); } if (Kind.isText()) return getTextSection(); return getDataSection(); }