X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FTargetLoweringObjectFileImpl.cpp;h=58ae9cc53bda3c1968ff43b72f69de0e7e29b46d;hb=5666fc71f0e2ed2c0400d8bca079a1dd3f33fe53;hp=0ef10bfa4407b1ad3d032c2c500922782b8fc332;hpb=3b75cfe17930b392b1d6ba8f6fd432833c159472;p=oota-llvm.git diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 0ef10bfa440..58ae9cc53bd 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -24,13 +24,16 @@ #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Mangler.h" #include "llvm/IR/Module.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCSymbolELF.h" +#include "llvm/MC/MCValue.h" +#include "llvm/Support/COFF.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/ELF.h" #include "llvm/Support/ErrorHandling.h" @@ -50,34 +53,32 @@ MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol( MachineModuleInfo *MMI) const { unsigned Encoding = getPersonalityEncoding(); if ((Encoding & 0x80) == dwarf::DW_EH_PE_indirect) - return getContext().GetOrCreateSymbol(StringRef("DW.ref.") + + return getContext().getOrCreateSymbol(StringRef("DW.ref.") + TM.getSymbol(GV, Mang)->getName()); if ((Encoding & 0x70) == dwarf::DW_EH_PE_absptr) return TM.getSymbol(GV, Mang); report_fatal_error("We do not support this DWARF encoding yet!"); } -void TargetLoweringObjectFileELF::emitPersonalityValue(MCStreamer &Streamer, - const TargetMachine &TM, - const MCSymbol *Sym) const { +void TargetLoweringObjectFileELF::emitPersonalityValue( + MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym) const { SmallString<64> NameData("DW.ref."); NameData += Sym->getName(); - MCSymbol *Label = getContext().GetOrCreateSymbol(NameData); + MCSymbolELF *Label = + cast(getContext().getOrCreateSymbol(NameData)); Streamer.EmitSymbolAttribute(Label, MCSA_Hidden); Streamer.EmitSymbolAttribute(Label, MCSA_Weak); StringRef Prefix = ".data."; NameData.insert(NameData.begin(), Prefix.begin(), Prefix.end()); unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP; - const MCSection *Sec = getContext().getELFSection(NameData, - ELF::SHT_PROGBITS, - Flags, - 0, Label->getName()); - unsigned Size = TM.getDataLayout()->getPointerSize(); + MCSection *Sec = getContext().getELFSection(NameData, ELF::SHT_PROGBITS, + Flags, 0, Label->getName()); + unsigned Size = DL.getPointerSize(); Streamer.SwitchSection(Sec); - Streamer.EmitValueToAlignment(TM.getDataLayout()->getPointerABIAlignment()); + Streamer.EmitValueToAlignment(DL.getPointerABIAlignment()); Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject); - const MCExpr *E = MCConstantExpr::Create(Size, getContext()); - Streamer.EmitELFSize(Label, E); + const MCExpr *E = MCConstantExpr::create(Size, getContext()); + Streamer.emitELFSize(Label, E); Streamer.EmitLabel(Label); Streamer.EmitSymbolValue(Sym, Size); @@ -102,7 +103,7 @@ const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference( } return TargetLoweringObjectFile:: - getTTypeReference(MCSymbolRefExpr::Create(SSym, getContext()), + getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), Encoding & ~dwarf::DW_EH_PE_indirect, Streamer); } @@ -164,9 +165,7 @@ static unsigned getELFSectionType(StringRef Name, SectionKind K) { return ELF::SHT_PROGBITS; } - -static unsigned -getELFSectionFlags(SectionKind K, bool InCOMDAT) { +static unsigned getELFSectionFlags(SectionKind K) { unsigned Flags = 0; if (!K.isMetadata()) @@ -181,10 +180,7 @@ getELFSectionFlags(SectionKind K, bool InCOMDAT) { if (K.isThreadLocal()) Flags |= ELF::SHF_TLS; - // FIXME: There is nothing in ELF preventing an SHF_MERGE from being - // in a comdat. We just avoid it for now because we don't print - // those .sections correctly. - if (!InCOMDAT && (K.isMergeableCString() || K.isMergeableConst())) + if (K.isMergeableCString() || K.isMergeableConst()) Flags |= ELF::SHF_MERGE; if (K.isMergeableCString()) @@ -205,7 +201,7 @@ static const Comdat *getELFComdat(const GlobalValue *GV) { return C; } -const MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( +MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( const GlobalValue *GV, SectionKind Kind, Mangler &Mang, const TargetMachine &TM) const { StringRef SectionName = GV->getSection(); @@ -214,7 +210,7 @@ const MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( Kind = getELFKindForNamedSection(SectionName, Kind); StringRef Group = ""; - unsigned Flags = getELFSectionFlags(Kind, GV->hasComdat()); + unsigned Flags = getELFSectionFlags(Kind); if (const Comdat *C = getELFComdat(GV)) { Group = C->getName(); Flags |= ELF::SHF_GROUP; @@ -237,107 +233,96 @@ static StringRef getSectionPrefixForGlobal(SectionKind Kind) { return ".tdata"; if (Kind.isThreadBSS()) return ".tbss"; - if (Kind.isDataNoRel()) + if (Kind.isData()) return ".data"; - if (Kind.isDataRelLocal()) - return ".data.rel.local"; - if (Kind.isDataRel()) - return ".data.rel"; - if (Kind.isReadOnlyWithRelLocal()) - return ".data.rel.ro.local"; assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); return ".data.rel.ro"; } -const MCSection *TargetLoweringObjectFileELF:: -SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler &Mang, const TargetMachine &TM) const { - unsigned Flags = getELFSectionFlags(Kind, GV->hasComdat()); - - // If we have -ffunction-section or -fdata-section then we should emit the - // global value to a uniqued section specifically for it. - bool EmitUniquedSection = false; - if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) { - if (Kind.isText()) - EmitUniquedSection = TM.getFunctionSections(); - else - EmitUniquedSection = TM.getDataSections(); - } - - if (EmitUniquedSection || GV->hasComdat()) { - StringRef Prefix = getSectionPrefixForGlobal(Kind); - - SmallString<128> Name(Prefix); - bool UniqueSectionNames = TM.getUniqueSectionNames(); - if (UniqueSectionNames) { - Name.push_back('.'); - TM.getNameWithPrefix(Name, GV, Mang, true); +static MCSectionELF * +selectELFSectionForGlobal(MCContext &Ctx, const GlobalValue *GV, + SectionKind Kind, Mangler &Mang, + const TargetMachine &TM, bool EmitUniqueSection, + unsigned Flags, unsigned *NextUniqueID) { + unsigned EntrySize = 0; + if (Kind.isMergeableCString()) { + if (Kind.isMergeable2ByteCString()) { + EntrySize = 2; + } else if (Kind.isMergeable4ByteCString()) { + EntrySize = 4; + } else { + EntrySize = 1; + assert(Kind.isMergeable1ByteCString() && "unknown string width"); } - StringRef Group = ""; - if (const Comdat *C = getELFComdat(GV)) { - Flags |= ELF::SHF_GROUP; - Group = C->getName(); + } else if (Kind.isMergeableConst()) { + if (Kind.isMergeableConst4()) { + EntrySize = 4; + } else if (Kind.isMergeableConst8()) { + EntrySize = 8; + } else { + assert(Kind.isMergeableConst16() && "unknown data width"); + EntrySize = 16; } - - return getContext().getELFSection(Name, getELFSectionType(Name, Kind), - Flags, 0, Group, !UniqueSectionNames); } - if (Kind.isText()) return TextSection; + StringRef Group = ""; + if (const Comdat *C = getELFComdat(GV)) { + Flags |= ELF::SHF_GROUP; + Group = C->getName(); + } + bool UniqueSectionNames = TM.getUniqueSectionNames(); + SmallString<128> Name; if (Kind.isMergeableCString()) { - // We also need alignment here. // FIXME: this is getting the alignment of the character, not the // alignment of the global! - unsigned Align = - TM.getDataLayout()->getPreferredAlignment(cast(GV)); - - unsigned EntrySize = 1; - if (Kind.isMergeable2ByteCString()) - EntrySize = 2; - else if (Kind.isMergeable4ByteCString()) - EntrySize = 4; - else - assert(Kind.isMergeable1ByteCString() && "unknown string width"); + unsigned Align = GV->getParent()->getDataLayout().getPreferredAlignment( + cast(GV)); std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + "."; - std::string Name = SizeSpec + utostr(Align); - return getContext().getELFSection( - Name, ELF::SHT_PROGBITS, - ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS, EntrySize, ""); + Name = SizeSpec + utostr(Align); + } else if (Kind.isMergeableConst()) { + Name = ".rodata.cst"; + Name += utostr(EntrySize); + } else { + Name = getSectionPrefixForGlobal(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 (EmitUniqueSection && UniqueSectionNames) { + Name.push_back('.'); + TM.getNameWithPrefix(Name, GV, Mang, true); } + unsigned UniqueID = ~0; + if (EmitUniqueSection && !UniqueSectionNames) { + UniqueID = *NextUniqueID; + (*NextUniqueID)++; + } + return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags, + EntrySize, Group, UniqueID); +} - if (Kind.isReadOnly()) return ReadOnlySection; - - if (Kind.isThreadData()) return TLSDataSection; - if (Kind.isThreadBSS()) return TLSBSSSection; - - // Note: we claim that common symbols are put in BSSSection, but they are - // really emitted with the magic .comm directive, which creates a symbol table - // entry but not a section. - if (Kind.isBSS() || Kind.isCommon()) return BSSSection; +MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( + const GlobalValue *GV, SectionKind Kind, Mangler &Mang, + const TargetMachine &TM) const { + unsigned Flags = getELFSectionFlags(Kind); - if (Kind.isDataNoRel()) return DataSection; - if (Kind.isDataRelLocal()) return DataRelLocalSection; - if (Kind.isDataRel()) return DataRelSection; - if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection; + // If we have -ffunction-section or -fdata-section then we should emit the + // global value to a uniqued section specifically for it. + bool EmitUniqueSection = false; + if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) { + if (Kind.isText()) + EmitUniqueSection = TM.getFunctionSections(); + else + EmitUniqueSection = TM.getDataSections(); + } + EmitUniqueSection |= GV->hasComdat(); - assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); - return DataRelROSection; + return selectELFSectionForGlobal(getContext(), GV, Kind, Mang, TM, + EmitUniqueSection, Flags, &NextUniqueID); } -const MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( +MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( const Function &F, Mangler &Mang, const TargetMachine &TM) const { // If the function can be removed, produce a unique section so that // the table doesn't prevent the removal. @@ -346,17 +331,9 @@ const MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( if (!EmitUniqueSection) return ReadOnlySection; - SmallString<128> Name(".rodata."); - TM.getNameWithPrefix(Name, &F, Mang, true); - - unsigned Flags = ELF::SHF_ALLOC; - StringRef Group = ""; - if (C) { - Flags |= ELF::SHF_GROUP; - Group = C->getName(); - } - - return getContext().getELFSection(Name, ELF::SHT_PROGBITS, Flags, 0, Group); + return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(), + Mang, TM, EmitUniqueSection, ELF::SHF_ALLOC, + &NextUniqueID); } bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection( @@ -366,12 +343,10 @@ bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection( return false; } -/// 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 Constant *C) const { +/// Given a mergeable constant with the specified size and relocation +/// information, return a section that it should be placed in. +MCSection *TargetLoweringObjectFileELF::getSectionForConstant( + const DataLayout &DL, SectionKind Kind, const Constant *C) const { if (Kind.isMergeableConst4() && MergeableConst4Section) return MergeableConst4Section; if (Kind.isMergeableConst8() && MergeableConst8Section) @@ -381,16 +356,13 @@ TargetLoweringObjectFileELF::getSectionForConstant(SectionKind Kind, if (Kind.isReadOnly()) return ReadOnlySection; - if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection; assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); return DataRelROSection; } -static const MCSectionELF *getStaticStructorSection(MCContext &Ctx, - bool UseInitArray, - bool IsCtor, - unsigned Priority, - const MCSymbol *KeySym) { +static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray, + bool IsCtor, unsigned Priority, + const MCSymbol *KeySym) { std::string Name; unsigned Type; unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE; @@ -428,13 +400,13 @@ static const MCSectionELF *getStaticStructorSection(MCContext &Ctx, return Ctx.getELFSection(Name, Type, Flags, 0, COMDAT); } -const MCSection *TargetLoweringObjectFileELF::getStaticCtorSection( +MCSection *TargetLoweringObjectFileELF::getStaticCtorSection( unsigned Priority, const MCSymbol *KeySym) const { return getStaticStructorSection(getContext(), UseInitArray, true, Priority, KeySym); } -const MCSection *TargetLoweringObjectFileELF::getStaticDtorSection( +MCSection *TargetLoweringObjectFileELF::getStaticDtorSection( unsigned Priority, const MCSymbol *KeySym) const { return getStaticStructorSection(getContext(), UseInitArray, false, Priority, KeySym); @@ -456,14 +428,9 @@ TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) { // MachO //===----------------------------------------------------------------------===// -/// getDepLibFromLinkerOpt - Extract the dependent library name from a linker -/// option string. Returns StringRef() if the option does not specify a library. -StringRef TargetLoweringObjectFileMachO:: -getDepLibFromLinkerOpt(StringRef LinkerOption) const { - const char *LibCmd = "-l"; - if (LinkerOption.startswith(LibCmd)) - return LinkerOption.substr(strlen(LibCmd)); - return StringRef(); +TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO() + : TargetLoweringObjectFile() { + SupportIndirectSymViaGOTPCRel = true; } /// emitModuleFlags - Perform code emission for module flags. @@ -532,12 +499,11 @@ emitModuleFlags(MCStreamer &Streamer, ErrorCode + "."); // Get the section. - const MCSectionMachO *S = - getContext().getMachOSection(Segment, Section, TAA, StubSize, - SectionKind::getDataNoRel()); + MCSectionMachO *S = getContext().getMachOSection( + Segment, Section, TAA, StubSize, SectionKind::getData()); Streamer.SwitchSection(S); Streamer.EmitLabel(getContext(). - GetOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); + getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); Streamer.EmitIntValue(VersionVal, 4); Streamer.EmitIntValue(ImageInfoFlags, 4); Streamer.AddBlankLine(); @@ -552,7 +518,7 @@ static void checkMachOComdat(const GlobalValue *GV) { "' cannot be lowered."); } -const MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( +MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( const GlobalValue *GV, SectionKind Kind, Mangler &Mang, const TargetMachine &TM) const { // Parse the section specifier and create it if valid. @@ -573,8 +539,8 @@ const MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( } // Get the section. - const MCSectionMachO *S = - getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind); + MCSectionMachO *S = + getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind); // If TAA wasn't set by ParseSectionSpecifier() above, // use the value returned by getMachOSection() as a default. @@ -594,9 +560,9 @@ const MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( return S; } -const MCSection *TargetLoweringObjectFileMachO:: -SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler &Mang, const TargetMachine &TM) const { +MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal( + const GlobalValue *GV, SectionKind Kind, Mangler &Mang, + const TargetMachine &TM) const { checkMachOComdat(GV); // Handle thread local data. @@ -616,14 +582,16 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, // FIXME: Alignment check should be handled by section classifier. if (Kind.isMergeable1ByteCString() && - TM.getDataLayout()->getPreferredAlignment(cast(GV)) < 32) + GV->getParent()->getDataLayout().getPreferredAlignment( + cast(GV)) < 32) return CStringSection; // Do not put 16-bit arrays in the UString section if they have an // externally visible label, this runs into issues with certain linker // versions. if (Kind.isMergeable2ByteCString() && !GV->hasExternalLinkage() && - TM.getDataLayout()->getPreferredAlignment(cast(GV)) < 32) + GV->getParent()->getDataLayout().getPreferredAlignment( + cast(GV)) < 32) return UStringSection; // With MachO only variables whose corresponding symbol starts with 'l' or @@ -661,12 +629,11 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, return DataSection; } -const MCSection * -TargetLoweringObjectFileMachO::getSectionForConstant(SectionKind Kind, - const Constant *C) const { +MCSection *TargetLoweringObjectFileMachO::getSectionForConstant( + const DataLayout &DL, SectionKind Kind, const Constant *C) const { // If this constant requires a relocation, we have to put it in the data // segment, not in the text segment. - if (Kind.isDataRel() || Kind.isReadOnlyWithRel()) + if (Kind.isData() || Kind.isReadOnlyWithRel()) return ConstDataSection; if (Kind.isMergeableConst4()) @@ -702,7 +669,7 @@ const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference( } return TargetLoweringObjectFile:: - getTTypeReference(MCSymbolRefExpr::Create(SSym, getContext()), + getTTypeReference(MCSymbolRefExpr::create(SSym, getContext()), Encoding & ~dwarf::DW_EH_PE_indirect, Streamer); } @@ -730,6 +697,89 @@ MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol( return SSym; } +const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel( + const MCSymbol *Sym, const MCValue &MV, int64_t Offset, + MachineModuleInfo *MMI, MCStreamer &Streamer) const { + // Although MachO 32-bit targets do not explicitly have a GOTPCREL relocation + // as 64-bit do, we replace the GOT equivalent by accessing the final symbol + // through a non_lazy_ptr stub instead. One advantage is that it allows the + // computation of deltas to final external symbols. Example: + // + // _extgotequiv: + // .long _extfoo + // + // _delta: + // .long _extgotequiv-_delta + // + // is transformed to: + // + // _delta: + // .long L_extfoo$non_lazy_ptr-(_delta+0) + // + // .section __IMPORT,__pointers,non_lazy_symbol_pointers + // L_extfoo$non_lazy_ptr: + // .indirect_symbol _extfoo + // .long 0 + // + MachineModuleInfoMachO &MachOMMI = + MMI->getObjFileInfo(); + MCContext &Ctx = getContext(); + + // The offset must consider the original displacement from the base symbol + // since 32-bit targets don't have a GOTPCREL to fold the PC displacement. + Offset = -MV.getConstant(); + const MCSymbol *BaseSym = &MV.getSymB()->getSymbol(); + + // Access the final symbol via sym$non_lazy_ptr and generate the appropriated + // non_lazy_ptr stubs. + SmallString<128> Name; + StringRef Suffix = "$non_lazy_ptr"; + Name += MMI->getModule()->getDataLayout().getPrivateGlobalPrefix(); + Name += Sym->getName(); + Name += Suffix; + MCSymbol *Stub = Ctx.getOrCreateSymbol(Name); + + MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub); + if (!StubSym.getPointer()) + StubSym = MachineModuleInfoImpl:: + StubValueTy(const_cast(Sym), true /* access indirectly */); + + const MCExpr *BSymExpr = + MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx); + const MCExpr *LHS = + MCSymbolRefExpr::create(Stub, MCSymbolRefExpr::VK_None, Ctx); + + if (!Offset) + return MCBinaryExpr::createSub(LHS, BSymExpr, Ctx); + + const MCExpr *RHS = + MCBinaryExpr::createAdd(BSymExpr, MCConstantExpr::create(Offset, Ctx), Ctx); + return MCBinaryExpr::createSub(LHS, RHS, Ctx); +} + +static bool canUsePrivateLabel(const MCAsmInfo &AsmInfo, + const MCSection &Section) { + if (!AsmInfo.isSectionAtomizableBySymbols(Section)) + return true; + + // If it is not dead stripped, it is safe to use private labels. + const MCSectionMachO &SMO = cast(Section); + if (SMO.hasAttribute(MachO::S_ATTR_NO_DEAD_STRIP)) + return true; + + return false; +} + +void TargetLoweringObjectFileMachO::getNameWithPrefix( + SmallVectorImpl &OutName, const GlobalValue *GV, Mangler &Mang, + const TargetMachine &TM) const { + SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM); + const MCSection *TheSection = SectionForGlobal(GV, GVKind, Mang, TM); + bool CannotUsePrivateLabel = + !canUsePrivateLabel(*TM.getMCAsmInfo(), *TheSection); + Mang.getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); +} + //===----------------------------------------------------------------------===// // COFF //===----------------------------------------------------------------------===// @@ -807,13 +857,11 @@ static int getSelectionForCOFF(const GlobalValue *GV) { } else { return COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE; } - } else if (GV->isWeakForLinker()) { - return COFF::IMAGE_COMDAT_SELECT_ANY; } return 0; } -const MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal( +MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal( const GlobalValue *GV, SectionKind Kind, Mangler &Mang, const TargetMachine &TM) const { int Selection = 0; @@ -855,10 +903,9 @@ static const char *getCOFFSectionNameForUniqueGlobal(SectionKind Kind) { return ".data"; } - -const MCSection *TargetLoweringObjectFileCOFF:: -SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler &Mang, const TargetMachine &TM) const { +MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal( + const GlobalValue *GV, SectionKind Kind, Mangler &Mang, + const TargetMachine &TM) const { // If we have -ffunction-sections then we should emit the global value to a // uniqued section specifically for it. bool EmitUniquedSection; @@ -886,6 +933,11 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, StringRef COMDATSymName = Sym->getName(); return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, Selection); + } else { + SmallString<256> TmpData; + Mang.getNameWithPrefix(TmpData, GV, /*CannotUsePrivateLabel=*/true); + return getContext().getCOFFSection(Name, Characteristics, Kind, TmpData, + Selection); } } @@ -907,12 +959,41 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, return DataSection; } -StringRef TargetLoweringObjectFileCOFF:: -getDepLibFromLinkerOpt(StringRef LinkerOption) const { - const char *LibCmd = "/DEFAULTLIB:"; - if (LinkerOption.startswith(LibCmd)) - return LinkerOption.substr(strlen(LibCmd)); - return StringRef(); +void TargetLoweringObjectFileCOFF::getNameWithPrefix( + SmallVectorImpl &OutName, const GlobalValue *GV, Mangler &Mang, + const TargetMachine &TM) const { + bool CannotUsePrivateLabel = false; + if (GV->hasPrivateLinkage() && + ((isa(GV) && TM.getFunctionSections()) || + (isa(GV) && TM.getDataSections()))) + CannotUsePrivateLabel = true; + + Mang.getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); +} + +MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable( + const Function &F, Mangler &Mang, const TargetMachine &TM) const { + // If the function can be removed, produce a unique section so that + // the table doesn't prevent the removal. + const Comdat *C = F.getComdat(); + bool EmitUniqueSection = TM.getFunctionSections() || C; + if (!EmitUniqueSection) + return ReadOnlySection; + + // FIXME: we should produce a symbol for F instead. + if (F.hasPrivateLinkage()) + return ReadOnlySection; + + MCSymbol *Sym = TM.getSymbol(&F, Mang); + StringRef COMDATSymName = Sym->getName(); + + SectionKind Kind = SectionKind::getReadOnly(); + const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); + unsigned Characteristics = getCOFFSectionFlags(Kind); + Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; + + return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, + COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE); } void TargetLoweringObjectFileCOFF:: @@ -937,7 +1018,7 @@ emitModuleFlags(MCStreamer &Streamer, // Emit the linker options to the linker .drectve section. According to the // spec, this section is a space-separated string containing flags for linker. - const MCSection *Sec = getDrectveSection(); + MCSection *Sec = getDrectveSection(); Streamer.SwitchSection(Sec); for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) { MDNode *MDOptions = cast(LinkerOptions->getOperand(i)); @@ -951,14 +1032,47 @@ emitModuleFlags(MCStreamer &Streamer, } } -const MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection( +MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection( unsigned Priority, const MCSymbol *KeySym) const { return getContext().getAssociativeCOFFSection( cast(StaticCtorSection), KeySym); } -const MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection( +MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection( unsigned Priority, const MCSymbol *KeySym) const { return getContext().getAssociativeCOFFSection( cast(StaticDtorSection), KeySym); } + +void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal( + raw_ostream &OS, const GlobalValue *GV, const Mangler &Mang) const { + if (!GV->hasDLLExportStorageClass() || GV->isDeclaration()) + return; + + const Triple &TT = getTargetTriple(); + + if (TT.isKnownWindowsMSVCEnvironment()) + OS << " /EXPORT:"; + else + OS << " -export:"; + + if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) { + std::string Flag; + raw_string_ostream FlagOS(Flag); + Mang.getNameWithPrefix(FlagOS, GV, false); + FlagOS.flush(); + if (Flag[0] == GV->getParent()->getDataLayout().getGlobalPrefix()) + OS << Flag.substr(1); + else + OS << Flag; + } else { + Mang.getNameWithPrefix(OS, GV, false); + } + + if (!GV->getValueType()->isFunctionTy()) { + if (TT.isKnownWindowsMSVCEnvironment()) + OS << ",DATA"; + else + OS << ",data"; + } +}