diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -653,6 +653,81 @@ }; } +/// Calculate an appropriate unique ID for a section, and update Flags, +/// EntrySize and NextUniqueID where appropriate. +static unsigned +calcUniqueIDUpdateFlagsAndSize(const GlobalObject *GO, StringRef SectionName, + SectionKind Kind, const TargetMachine &TM, + MCContext &Ctx, Mangler &Mang, unsigned &Flags, + unsigned &EntrySize, unsigned &NextUniqueID, + const bool Retain, const bool ForceUnique) { + // Increment uniqueID if we are forced to emit a unique section. + // This works perfectly fine with section attribute or pragma section as the + // sections with the same name are grouped together by the assembler. + if (ForceUnique) + return NextUniqueID++; + + // A section can have at most one associated section. Put each global with + // MD_associated in a unique section. + const bool Associated = GO->getMetadata(LLVMContext::MD_associated); + if (Associated) { + Flags |= ELF::SHF_LINK_ORDER; + return NextUniqueID++; + } + + if (Retain) { + if (Ctx.getAsmInfo()->useIntegratedAssembler() || + Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36)) + Flags |= ELF::SHF_GNU_RETAIN; + return NextUniqueID++; + } + + // If two symbols with differing sizes end up in the same mergeable section + // that section can be assigned an incorrect entry size. To avoid this we + // usually put symbols of the same size into distinct mergeable sections with + // the same name. Doing so relies on the ",unique ," assembly feature. This + // feature is not avalible until bintuils version 2.35 + // (https://sourceware.org/bugzilla/show_bug.cgi?id=25380). + const bool SupportsUnique = Ctx.getAsmInfo()->useIntegratedAssembler() || + Ctx.getAsmInfo()->binutilsIsAtLeast(2, 35); + if (!SupportsUnique) { + Flags &= ~ELF::SHF_MERGE; + EntrySize = 0; + return MCContext::GenericSectionID; + } + + const bool SymbolMergeable = Flags & ELF::SHF_MERGE; + const bool SeenSectionNameBefore = + Ctx.isELFGenericMergeableSection(SectionName); + // If this is the first ocurrence of this section name, treat it as the + // generic section + if (!SymbolMergeable && !SeenSectionNameBefore) + return MCContext::GenericSectionID; + + // Symbols must be placed into sections with compatible entry sizes. Generate + // unique sections for symbols that have not been assigned to compatible + // sections. + const auto PreviousID = + Ctx.getELFUniqueIDForEntsize(SectionName, Flags, EntrySize); + if (PreviousID) + return *PreviousID; + + // If the user has specified the same section name as would be created + // implicitly for this symbol e.g. .rodata.str1.1, then we don't need + // to unique the section as the entry size for this symbol will be + // compatible with implicitly created sections. + SmallString<128> ImplicitSectionNameStem = + getELFSectionNameForGlobal(GO, Kind, Mang, TM, EntrySize, false); + if (SymbolMergeable && + Ctx.isELFImplicitMergeableSectionNamePrefix(SectionName) && + SectionName.startswith(ImplicitSectionNameStem)) + return MCContext::GenericSectionID; + + // We have seen this section name before, but with different flags or entity + // size. Create a new unique ID. + return NextUniqueID++; +} + static MCSection *selectExplicitSectionGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM, MCContext &Ctx, Mangler &Mang, unsigned &NextUniqueID, @@ -693,69 +768,11 @@ } unsigned EntrySize = getEntrySizeForKind(Kind); + const unsigned UniqueID = calcUniqueIDUpdateFlagsAndSize( + GO, SectionName, Kind, TM, Ctx, Mang, Flags, EntrySize, NextUniqueID, + Retain, ForceUnique); - // A section can have at most one associated section. Put each global with - // MD_associated in a unique section. - unsigned UniqueID = MCContext::GenericSectionID; const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM); - const bool Associated = GO->getMetadata(LLVMContext::MD_associated); - if (Associated || Retain) { - UniqueID = NextUniqueID++; - if (Associated) - Flags |= ELF::SHF_LINK_ORDER; - if (Retain && (Ctx.getAsmInfo()->useIntegratedAssembler() || - Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36))) - Flags |= ELF::SHF_GNU_RETAIN; - } else { - if (Ctx.getAsmInfo()->useIntegratedAssembler() || - Ctx.getAsmInfo()->binutilsIsAtLeast(2, 35)) { - // Symbols must be placed into sections with compatible entry - // sizes. Generate unique sections for symbols that have not - // been assigned to compatible sections. - if (Flags & ELF::SHF_MERGE) { - auto maybeID = Ctx.getELFUniqueIDForEntsize(SectionName, Flags, - EntrySize); - if (maybeID) - UniqueID = *maybeID; - else { - // If the user has specified the same section name as would be created - // implicitly for this symbol e.g. .rodata.str1.1, then we don't need - // to unique the section as the entry size for this symbol will be - // compatible with implicitly created sections. - SmallString<128> ImplicitSectionNameStem = getELFSectionNameForGlobal( - GO, Kind, Mang, TM, EntrySize, false); - if (!(Ctx.isELFImplicitMergeableSectionNamePrefix(SectionName) && - SectionName.startswith(ImplicitSectionNameStem))) - UniqueID = NextUniqueID++; - } - } else { - // We need to unique the section if the user has explicity - // assigned a non-mergeable symbol to a section name for - // a generic mergeable section. - if (Ctx.isELFGenericMergeableSection(SectionName)) { - auto maybeID = Ctx.getELFUniqueIDForEntsize( - SectionName, Flags, EntrySize); - UniqueID = maybeID ? *maybeID : NextUniqueID++; - } - } - } else { - // If two symbols with differing sizes end up in the same mergeable - // section that section can be assigned an incorrect entry size. To avoid - // this we usually put symbols of the same size into distinct mergeable - // sections with the same name. Doing so relies on the ",unique ," - // assembly feature. This feature is not avalible until bintuils - // version 2.35 (https://sourceware.org/bugzilla/show_bug.cgi?id=25380). - Flags &= ~ELF::SHF_MERGE; - EntrySize = 0; - } - } - - // Increment uniqueID if we are forced to emit a unique section. - // This works perfectly fine with section attribute or pragma section as the - // sections with the same name are grouped together by the assembler. - if (ForceUnique && UniqueID == MCContext::GenericSectionID) - UniqueID = NextUniqueID++; - MCSectionELF *Section = Ctx.getELFSection( SectionName, getELFSectionType(SectionName, Kind), Flags, EntrySize, Group, IsComdat, UniqueID, LinkedToSym);