diff options
Diffstat (limited to 'lib/CodeGen/TargetLoweringObjectFileImpl.cpp')
-rw-r--r-- | lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 158 |
1 files changed, 93 insertions, 65 deletions
diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 03f4a51..efd15e1 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -37,6 +37,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; using namespace dwarf; @@ -72,9 +73,10 @@ void TargetLoweringObjectFileELF::emitPersonalityValue(MCStreamer &Streamer, Flags, SectionKind::getDataRel(), 0, Label->getName()); - unsigned Size = TM.getDataLayout()->getPointerSize(); + unsigned Size = TM.getSubtargetImpl()->getDataLayout()->getPointerSize(); Streamer.SwitchSection(Sec); - Streamer.EmitValueToAlignment(TM.getDataLayout()->getPointerABIAlignment()); + Streamer.EmitValueToAlignment( + TM.getSubtargetImpl()->getDataLayout()->getPointerABIAlignment()); Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject); const MCExpr *E = MCConstantExpr::Create(Size, getContext()); Streamer.EmitELFSize(Label, E); @@ -287,7 +289,8 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, // FIXME: this is getting the alignment of the character, not the // alignment of the global! unsigned Align = - TM.getDataLayout()->getPreferredAlignment(cast<GlobalVariable>(GV)); + TM.getSubtargetImpl()->getDataLayout()->getPreferredAlignment( + cast<GlobalVariable>(GV)); const char *SizeSpec = ".rodata.str1."; if (Kind.isMergeable2ByteCString()) @@ -338,8 +341,9 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, /// 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 { +const MCSection * +TargetLoweringObjectFileELF::getSectionForConstant(SectionKind Kind, + const Constant *C) const { if (Kind.isMergeableConst4() && MergeableConst4Section) return MergeableConst4Section; if (Kind.isMergeableConst8() && MergeableConst8Section) @@ -354,44 +358,59 @@ getSectionForConstant(SectionKind Kind) const { return DataRelROSection; } -const MCSection *TargetLoweringObjectFileELF::getStaticCtorSection( - unsigned Priority, const MCSymbol *KeySym) const { - // The default scheme is .ctor / .dtor, so we have to invert the priority - // numbering. - if (Priority == 65535) - return StaticCtorSection; +static const 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; + SectionKind Kind = SectionKind::getDataRel(); + StringRef COMDAT = KeySym ? KeySym->getName() : ""; + + if (KeySym) + Flags |= ELF::SHF_GROUP; if (UseInitArray) { - std::string Name = std::string(".init_array.") + utostr(Priority); - return getContext().getELFSection(Name, ELF::SHT_INIT_ARRAY, - ELF::SHF_ALLOC | ELF::SHF_WRITE, - SectionKind::getDataRel()); + if (IsCtor) { + Type = ELF::SHT_INIT_ARRAY; + Name = ".init_array"; + } else { + Type = ELF::SHT_FINI_ARRAY; + Name = ".fini_array"; + } + if (Priority != 65535) { + Name += '.'; + Name += utostr(Priority); + } } else { - std::string Name = std::string(".ctors.") + utostr(65535 - Priority); - return getContext().getELFSection(Name, ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_WRITE, - SectionKind::getDataRel()); + // The default scheme is .ctor / .dtor, so we have to invert the priority + // numbering. + if (IsCtor) + Name = ".ctors"; + else + Name = ".dtors"; + if (Priority != 65535) { + Name += '.'; + Name += utostr(65535 - Priority); + } + Type = ELF::SHT_PROGBITS; } + + return Ctx.getELFSection(Name, Type, Flags, Kind, 0, COMDAT); } -const MCSection *TargetLoweringObjectFileELF::getStaticDtorSection( +const MCSection *TargetLoweringObjectFileELF::getStaticCtorSection( unsigned Priority, const MCSymbol *KeySym) const { - // The default scheme is .ctor / .dtor, so we have to invert the priority - // numbering. - if (Priority == 65535) - return StaticDtorSection; + return getStaticStructorSection(getContext(), UseInitArray, true, Priority, + KeySym); +} - if (UseInitArray) { - std::string Name = std::string(".fini_array.") + utostr(Priority); - return getContext().getELFSection(Name, ELF::SHT_FINI_ARRAY, - ELF::SHF_ALLOC | ELF::SHF_WRITE, - SectionKind::getDataRel()); - } else { - std::string Name = std::string(".dtors.") + utostr(65535 - Priority); - return getContext().getELFSection(Name, ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_WRITE, - SectionKind::getDataRel()); - } +const MCSection *TargetLoweringObjectFileELF::getStaticDtorSection( + unsigned Priority, const MCSymbol *KeySym) const { + return getStaticStructorSection(getContext(), UseInitArray, false, Priority, + KeySym); } void @@ -565,10 +584,29 @@ bool TargetLoweringObjectFileMachO::isSectionAtomizableBySymbols( if (SMO.getKind().isMergeable1ByteCString()) return false; + if (SMO.getSegmentName() == "__TEXT" && + SMO.getSectionName() == "__objc_classname" && + SMO.getType() == MachO::S_CSTRING_LITERALS) + return false; + + if (SMO.getSegmentName() == "__TEXT" && + SMO.getSectionName() == "__objc_methname" && + SMO.getType() == MachO::S_CSTRING_LITERALS) + return false; + + if (SMO.getSegmentName() == "__TEXT" && + SMO.getSectionName() == "__objc_methtype" && + SMO.getType() == MachO::S_CSTRING_LITERALS) + return false; + if (SMO.getSegmentName() == "__DATA" && SMO.getSectionName() == "__cfstring") return false; + // no_dead_strip sections are not atomized in practice. + if (SMO.hasAttribute(MachO::S_ATTR_NO_DEAD_STRIP)) + return false; + switch (SMO.getType()) { default: return true; @@ -610,17 +648,21 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, // FIXME: Alignment check should be handled by section classifier. if (Kind.isMergeable1ByteCString() && - TM.getDataLayout()->getPreferredAlignment(cast<GlobalVariable>(GV)) < 32) + TM.getSubtargetImpl()->getDataLayout()->getPreferredAlignment( + cast<GlobalVariable>(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<GlobalVariable>(GV)) < 32) + TM.getSubtargetImpl()->getDataLayout()->getPreferredAlignment( + cast<GlobalVariable>(GV)) < 32) return UStringSection; - if (Kind.isMergeableConst()) { + // With MachO only variables whose corresponding symbol starts with 'l' or + // 'L' can be merged, so we only try merging GVs with private linkage. + if (GV->hasPrivateLinkage() && Kind.isMergeableConst()) { if (Kind.isMergeableConst4()) return FourByteConstantSection; if (Kind.isMergeableConst8()) @@ -654,7 +696,8 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, } const MCSection * -TargetLoweringObjectFileMachO::getSectionForConstant(SectionKind Kind) const { +TargetLoweringObjectFileMachO::getSectionForConstant(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()) @@ -737,7 +780,7 @@ getCOFFSectionFlags(SectionKind K) { COFF::IMAGE_SCN_MEM_EXECUTE | COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_CNT_CODE; - else if (K.isBSS ()) + else if (K.isBSS()) Flags |= COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ | @@ -747,7 +790,7 @@ getCOFFSectionFlags(SectionKind K) { COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE; - else if (K.isReadOnly()) + else if (K.isReadOnly() || K.isReadOnlyWithRel()) Flags |= COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ; @@ -772,7 +815,7 @@ static const GlobalValue *getComdatGVForCOFF(const GlobalValue *GV) { if (ComdatGV->getComdat() != C) report_fatal_error("Associative COMDAT symbol '" + ComdatGVName + - "' is not a key for it's COMDAT."); + "' is not a key for its COMDAT."); return ComdatGV; } @@ -841,9 +884,9 @@ static const char *getCOFFSectionNameForUniqueGlobal(SectionKind Kind) { return ".bss"; if (Kind.isThreadLocal()) return ".tls$"; - if (Kind.isWriteable()) - return ".data"; - return ".rdata"; + if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) + return ".rdata"; + return ".data"; } @@ -891,7 +934,7 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, if (Kind.isThreadLocal()) return TLSDataSection; - if (Kind.isReadOnly()) + if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) return ReadOnlySection; // Note: we claim that common symbols are put in BSSSection, but they are @@ -958,29 +1001,14 @@ emitModuleFlags(MCStreamer &Streamer, } } -static const MCSection *getAssociativeCOFFSection(MCContext &Ctx, - const MCSection *Sec, - const MCSymbol *KeySym) { - // Return the normal section if we don't have to be associative. - if (!KeySym) - return Sec; - - // Make an associative section with the same name and kind as the normal - // section. - const MCSectionCOFF *SecCOFF = cast<MCSectionCOFF>(Sec); - unsigned Characteristics = - SecCOFF->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT; - return Ctx.getCOFFSection(SecCOFF->getSectionName(), Characteristics, - SecCOFF->getKind(), KeySym->getName(), - COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE); -} - const MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection( unsigned Priority, const MCSymbol *KeySym) const { - return getAssociativeCOFFSection(getContext(), StaticCtorSection, KeySym); + return getContext().getAssociativeCOFFSection( + cast<MCSectionCOFF>(StaticCtorSection), KeySym); } const MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection( unsigned Priority, const MCSymbol *KeySym) const { - return getAssociativeCOFFSection(getContext(), StaticDtorSection, KeySym); + return getContext().getAssociativeCOFFSection( + cast<MCSectionCOFF>(StaticDtorSection), KeySym); } |