diff options
author | Tomas Matheson <tomas.matheson@arm.com> | 2021-04-22 15:41:33 +0100 |
---|---|---|
committer | Tomas Matheson <tomas.matheson@arm.com> | 2021-05-26 11:51:29 +0100 |
commit | e79e8041c5ff6a611390b6c3c8484d2cc80ab21d (patch) | |
tree | 9d9a7dcbf69b7c312114a67248eba55a78c07743 /llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | |
parent | a2d6ef58765301fa95776cd17033a0974a487bf4 (diff) | |
download | llvm-e79e8041c5ff6a611390b6c3c8484d2cc80ab21d.zip llvm-e79e8041c5ff6a611390b6c3c8484d2cc80ab21d.tar.gz llvm-e79e8041c5ff6a611390b6c3c8484d2cc80ab21d.tar.bz2 |
[MC][NFCI] Factor out ELF section unique ID calculation
Precursor to D100944. The logic for determining the unique ID had become
quite difficult to reason about, so I have factored this out into a
separate function.
Differential Revision: https://reviews.llvm.org/D102336
Diffstat (limited to 'llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp')
-rw-r--r-- | llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 139 |
1 files changed, 78 insertions, 61 deletions
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 3112229..00a8fca4 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -653,6 +653,81 @@ public: }; } +/// 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 @@ static MCSection *selectExplicitSectionGlobal( } 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); |