//===-- DarwinTargetAsmInfo.cpp - Darwin asm properties ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file defines target asm properties related what form asm statements // should take in general on Darwin-based targets // //===----------------------------------------------------------------------===// #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" #include "llvm/GlobalVariable.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Mangler.h" #include "llvm/Target/DarwinTargetAsmInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetData.h" using namespace llvm; DarwinTargetAsmInfo::DarwinTargetAsmInfo(const TargetMachine &TM) : TargetAsmInfo(TM) { TextSection = getOrCreateSection("\t.text", true, SectionKind::Text); DataSection = getOrCreateSection("\t.data", true, SectionKind::DataRel); CStringSection_ = getOrCreateSection("\t.cstring", true, SectionKind::MergeableCString); FourByteConstantSection = getOrCreateSection("\t.literal4\n", true, SectionKind::MergeableConst4); EightByteConstantSection = getOrCreateSection("\t.literal8\n", true, SectionKind::MergeableConst8); SixteenByteConstantSection = getOrCreateSection("\t.literal16\n", true, SectionKind::MergeableConst16); ReadOnlySection = getOrCreateSection("\t.const", true, SectionKind::ReadOnly); TextCoalSection = getOrCreateSection("\t__TEXT,__textcoal_nt,coalesced,pure_instructions", false, SectionKind::Text); ConstTextCoalSection = getOrCreateSection("\t__TEXT,__const_coal,coalesced", false, SectionKind::Text); ConstDataCoalSection = getOrCreateSection("\t__DATA,__const_coal,coalesced", false, SectionKind::Text); ConstDataSection = getOrCreateSection("\t.const_data", true, SectionKind::ReadOnlyWithRel); DataCoalSection = getOrCreateSection("\t__DATA,__datacoal_nt,coalesced", false, SectionKind::DataRel); // Common settings for all Darwin targets. // Syntax: GlobalPrefix = "_"; PrivateGlobalPrefix = "L"; LinkerPrivateGlobalPrefix = "l"; // Marker for some ObjC metadata NeedsSet = true; NeedsIndirectEncoding = true; AllowQuotesInName = true; HasSingleParameterDotFile = false; // In non-PIC modes, emit a special label before jump tables so that the // linker can perform more accurate dead code stripping. We do not check the // relocation model here since it can be overridden later. JumpTableSpecialLabelPrefix = "l"; // Directives: WeakDefDirective = "\t.weak_definition "; WeakRefDirective = "\t.weak_reference "; HiddenDirective = "\t.private_extern "; // Sections: CStringSection = "\t.cstring"; JumpTableDataSection = "\t.const"; BSSSection = 0; if (TM.getRelocationModel() == Reloc::Static) { StaticCtorsSection = ".constructor"; StaticDtorsSection = ".destructor"; } else { StaticCtorsSection = ".mod_init_func"; StaticDtorsSection = ".mod_term_func"; } // _foo.eh symbols are currently always exported so that the linker knows // about them. This may not strictly be necessary on 10.6 and later, but it // doesn't hurt anything. Is_EHSymbolPrivate = false; DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug"; DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug"; DwarfLineSection = ".section __DWARF,__debug_line,regular,debug"; DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug"; DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug"; DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug"; DwarfStrSection = ".section __DWARF,__debug_str,regular,debug"; DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug"; DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug"; DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug"; DwarfMacroInfoSection = ".section __DWARF,__debug_macinfo,regular,debug"; } /// emitUsedDirectiveFor - On Darwin, internally linked data beginning with /// the PrivateGlobalPrefix or the LinkerPrivateGlobalPrefix does not have the /// directive emitted (this occurs in ObjC metadata). bool DarwinTargetAsmInfo::emitUsedDirectiveFor(const GlobalValue* GV, Mangler *Mang) const { 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 Section* DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind) const { assert(!Kind.isThreadLocal() && "Darwin doesn't support TLS"); if (Kind.isText()) return Kind.isWeak() ? 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 (Kind.isWeak()) { if (Kind.isReadOnly()) return ConstTextCoalSection; return DataCoalSection; } // FIXME: Alignment check should be handled by section classifier. if (Kind.isMergeableCString()) return MergeableStringSection(cast(GV)); if (Kind.isMergeableConst()) { if (Kind.isMergeableConst4()) return FourByteConstantSection; if (Kind.isMergeableConst8()) return EightByteConstantSection; if (Kind.isMergeableConst16()) return SixteenByteConstantSection; return ReadOnlySection; // .const } // FIXME: ROData -> const in -static mode that is relocatable but they happen // by the static linker. Why not mergeable? if (Kind.isReadOnly()) return getReadOnlySection(); // 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 Section* DarwinTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const { const TargetData *TD = TM.getTargetData(); Constant *C = cast(GV)->getInitializer(); const Type *Ty = cast(C->getType())->getElementType(); unsigned Size = TD->getTypeAllocSize(Ty); if (Size) { unsigned Align = TD->getPreferredAlignment(GV); if (Align <= 32) return getCStringSection_(); } return getReadOnlySection(); } const Section * DarwinTargetAsmInfo::getSectionForMergeableConstant(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()) return SixteenByteConstantSection; return ReadOnlySection; // .const }