diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h --- a/llvm/include/llvm/MC/MCContext.h +++ b/llvm/include/llvm/MC/MCContext.h @@ -310,7 +310,7 @@ MCSectionELF *createELFSectionImpl(StringRef Section, unsigned Type, unsigned Flags, SectionKind K, unsigned EntrySize, - const MCSymbolELF *Group, + const MCSymbolELF *Group, bool IsComdat, unsigned UniqueID, const MCSymbolELF *LinkedToSym); @@ -482,24 +482,32 @@ MCSectionELF *getELFSection(const Twine &Section, unsigned Type, unsigned Flags) { - return getELFSection(Section, Type, Flags, 0, ""); + return getELFSection(Section, Type, Flags, 0, "", false); + } + + MCSectionELF *getELFSection(const Twine &Section, unsigned Type, + unsigned Flags, unsigned EntrySize) { + return getELFSection(Section, Type, Flags, EntrySize, "", false, + MCSection::NonUniqueID, nullptr); } MCSectionELF *getELFSection(const Twine &Section, unsigned Type, unsigned Flags, unsigned EntrySize, - const Twine &Group) { - return getELFSection(Section, Type, Flags, EntrySize, Group, + const Twine &Group, bool IsComdat) { + return getELFSection(Section, Type, Flags, EntrySize, Group, IsComdat, MCSection::NonUniqueID, nullptr); } MCSectionELF *getELFSection(const Twine &Section, unsigned Type, unsigned Flags, unsigned EntrySize, - const Twine &Group, unsigned UniqueID, + const Twine &Group, bool IsComdat, + unsigned UniqueID, const MCSymbolELF *LinkedToSym); MCSectionELF *getELFSection(const Twine &Section, unsigned Type, unsigned Flags, unsigned EntrySize, - const MCSymbolELF *Group, unsigned UniqueID, + const MCSymbolELF *Group, bool IsComdat, + unsigned UniqueID, const MCSymbolELF *LinkedToSym); /// Get a section with the provided group identifier. This section is @@ -517,7 +525,8 @@ void renameELFSection(MCSectionELF *Section, StringRef Name); - MCSectionELF *createELFGroupSection(const MCSymbolELF *Group); + MCSectionELF *createELFGroupSection(const MCSymbolELF *Group, + bool IsComdat); void recordELFMergeableSectionInfo(StringRef SectionName, unsigned Flags, unsigned UniqueID, unsigned EntrySize); diff --git a/llvm/include/llvm/MC/MCSectionELF.h b/llvm/include/llvm/MC/MCSectionELF.h --- a/llvm/include/llvm/MC/MCSectionELF.h +++ b/llvm/include/llvm/MC/MCSectionELF.h @@ -13,6 +13,7 @@ #ifndef LLVM_MC_MCSECTIONELF_H #define LLVM_MC_MCSECTIONELF_H +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSymbolELF.h" @@ -38,7 +39,7 @@ /// fixed-sized entries 'EntrySize' will be 0. unsigned EntrySize; - const MCSymbolELF *Group; + const PointerIntPair Group; /// Used by SHF_LINK_ORDER. If non-null, the sh_link field will be set to the /// section header index of the section where LinkedToSym is defined. @@ -49,13 +50,14 @@ // The storage of Name is owned by MCContext's ELFUniquingMap. MCSectionELF(StringRef Name, unsigned type, unsigned flags, SectionKind K, - unsigned entrySize, const MCSymbolELF *group, unsigned UniqueID, - MCSymbol *Begin, const MCSymbolELF *LinkedToSym) + unsigned entrySize, const MCSymbolELF *group, bool IsComdat, + unsigned UniqueID, MCSymbol *Begin, + const MCSymbolELF *LinkedToSym) : MCSection(SV_ELF, Name, K, Begin), Type(type), Flags(flags), - UniqueID(UniqueID), EntrySize(entrySize), Group(group), + UniqueID(UniqueID), EntrySize(entrySize), Group(group, IsComdat), LinkedToSym(LinkedToSym) { - if (Group) - Group->setIsSignature(); + if (Group.getPointer()) + Group.getPointer()->setIsSignature(); } // TODO Delete after we stop supporting generation of GNU-style .zdebug_* @@ -71,7 +73,8 @@ unsigned getFlags() const { return Flags; } unsigned getEntrySize() const { return EntrySize; } void setFlags(unsigned F) { Flags = F; } - const MCSymbolELF *getGroup() const { return Group; } + const MCSymbolELF *getGroup() const { return Group.getPointer(); } + bool isComdat() const { return Group.getInt(); } void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T, raw_ostream &OS, diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1827,7 +1827,7 @@ OutStreamer->SwitchSection( OutContext.getELFSection(".llvm_sympart", ELF::SHT_LLVM_SYMPART, 0, 0, - "", ++UniqueID, nullptr)); + "", false, ++UniqueID, nullptr)); OutStreamer->emitBytes(GV.getPartition()); OutStreamer->emitZeros(1); OutStreamer->emitValue( @@ -3374,13 +3374,13 @@ GroupName = F.getComdat()->getName(); } InstMap = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, - Flags, 0, GroupName, + Flags, 0, GroupName, F.hasComdat(), MCSection::NonUniqueID, LinkedToSym); if (!TM.Options.XRayOmitFunctionIndex) FnSledIndex = OutContext.getELFSection( "xray_fn_idx", ELF::SHT_PROGBITS, Flags | ELF::SHF_WRITE, 0, - GroupName, MCSection::NonUniqueID, LinkedToSym); + GroupName, F.hasComdat(), MCSection::NonUniqueID, LinkedToSym); } else if (MF->getSubtarget().getTargetTriple().isOSBinFormatMachO()) { InstMap = OutContext.getMachOSection("__DATA", "xray_instr_map", 0, SectionKind::getReadOnlyWithRel()); @@ -3476,7 +3476,7 @@ } OutStreamer->SwitchSection(OutContext.getELFSection( "__patchable_function_entries", ELF::SHT_PROGBITS, Flags, 0, GroupName, - MCSection::NonUniqueID, LinkedToSym)); + F.hasComdat(), MCSection::NonUniqueID, LinkedToSym)); emitAlignment(Align(PointerSize)); OutStreamer->emitSymbolValue(CurrentPatchableFunctionEntrySym, PointerSize); } 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 @@ -315,7 +315,7 @@ if (NamedMDNode *DependentLibraries = M.getNamedMetadata("llvm.dependent-libraries")) { auto *S = C.getELFSection(".deplibs", ELF::SHT_LLVM_DEPENDENT_LIBRARIES, - ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, ""); + ELF::SHF_MERGE | ELF::SHF_STRINGS, 1); Streamer.SwitchSection(S); @@ -522,9 +522,11 @@ if (!C) return nullptr; - if (C->getSelectionKind() != Comdat::Any) - report_fatal_error("ELF COMDATs only support SelectionKind::Any, '" + - C->getName() + "' cannot be lowered."); + if (C->getSelectionKind() != Comdat::Any && + C->getSelectionKind() != Comdat::NoDuplicates) + report_fatal_error("ELF COMDATs only support SelectionKind::Any and " + "SelectionKind::NoDuplicates, '" + C->getName() + + "' cannot be lowered."); return C; } @@ -669,9 +671,11 @@ Kind = getELFKindForNamedSection(SectionName, Kind); StringRef Group = ""; + bool IsComdat = false; unsigned Flags = getELFSectionFlags(Kind); if (const Comdat *C = getELFComdat(GO)) { Group = C->getName(); + IsComdat = C->getSelectionKind() == Comdat::Any; Flags |= ELF::SHF_GROUP; } @@ -730,8 +734,8 @@ } MCSectionELF *Section = getContext().getELFSection( - SectionName, getELFSectionType(SectionName, Kind), Flags, - EntrySize, Group, UniqueID, LinkedToSym); + SectionName, getELFSectionType(SectionName, Kind), Flags, EntrySize, + Group, IsComdat, UniqueID, LinkedToSym); // Make sure that we did not get some other section with incompatible sh_link. // This should not be possible due to UniqueID code above. assert(Section->getLinkedToSymbol() == LinkedToSym && @@ -763,9 +767,11 @@ unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) { StringRef Group = ""; + bool IsComdat = false; if (const Comdat *C = getELFComdat(GO)) { Flags |= ELF::SHF_GROUP; Group = C->getName(); + IsComdat = C->getSelectionKind() == Comdat::Any; } // Get the section entry size based on the kind. @@ -788,7 +794,8 @@ if (Kind.isExecuteOnly()) UniqueID = 0; return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags, - EntrySize, Group, UniqueID, AssociatedSymbol); + EntrySize, Group, IsComdat, UniqueID, + AssociatedSymbol); } MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( @@ -843,11 +850,13 @@ const auto *LSDA = cast(LSDASection); unsigned Flags = LSDA->getFlags(); - StringRef Group; const MCSymbolELF *LinkedToSym = nullptr; - if (F.hasComdat()) { - Group = F.getComdat()->getName(); + StringRef Group = ""; + bool IsComdat = false; + if (const Comdat *C = getELFComdat(&F)) { Flags |= ELF::SHF_GROUP; + Group = C->getName(); + IsComdat = C->getSelectionKind() == Comdat::Any; } // Use SHF_LINK_ORDER to facilitate --gc-sections if we can use GNU ld>=2.36 // or LLD, which support mixed SHF_LINK_ORDER & non-SHF_LINK_ORDER. @@ -863,7 +872,8 @@ return getContext().getELFSection( (TM.getUniqueSectionNames() ? LSDA->getName() + "." + F.getName() : LSDA->getName()), - LSDA->getType(), Flags, 0, Group, MCSection::NonUniqueID, LinkedToSym); + LSDA->getType(), Flags, 0, Group, F.hasComdat(), MCSection::NonUniqueID, + LinkedToSym); } bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection( @@ -929,8 +939,8 @@ GroupName = F.getComdat()->getName().str(); } return getContext().getELFSection(Name, ELF::SHT_PROGBITS, Flags, - 0 /* Entry Size */, GroupName, UniqueID, - nullptr); + 0 /* Entry Size */, GroupName, + F.hasComdat(), UniqueID, nullptr); } static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray, @@ -939,7 +949,7 @@ std::string Name; unsigned Type; unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE; - StringRef COMDAT = KeySym ? KeySym->getName() : ""; + StringRef Comdat = KeySym ? KeySym->getName() : ""; if (KeySym) Flags |= ELF::SHF_GROUP; @@ -968,7 +978,7 @@ Type = ELF::SHT_PROGBITS; } - return Ctx.getELFSection(Name, Type, Flags, 0, COMDAT); + return Ctx.getELFSection(Name, Type, Flags, 0, Comdat, /*IsComdat=*/true); } MCSection *TargetLoweringObjectFileELF::getStaticCtorSection( @@ -1022,7 +1032,7 @@ // -frecord-gcc-switches which in turn attempts to mimic GCC's switch of the // same name. return getContext().getELFSection(".GCC.command.line", ELF::SHT_PROGBITS, - ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, ""); + ELF::SHF_MERGE | ELF::SHF_STRINGS, 1); } void diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -615,7 +615,7 @@ // Symbol table unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; MCSectionELF *SymtabSection = - Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize, ""); + Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize); SymtabSection->setAlignment(is64Bit() ? Align(8) : Align(4)); SymbolTableIndex = addToSectionTable(SymtabSection); @@ -717,7 +717,7 @@ if (HasLargeSectionIndex) { MCSectionELF *SymtabShndxSection = - Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 4, ""); + Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 4); SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection); SymtabShndxSection->setAlignment(Align(4)); } @@ -1125,7 +1125,8 @@ Asm.registerSymbol(*SignatureSymbol); unsigned &GroupIdx = RevGroupMap[SignatureSymbol]; if (!GroupIdx) { - MCSectionELF *Group = Ctx.createELFGroupSection(SignatureSymbol); + MCSectionELF *Group = + Ctx.createELFGroupSection(SignatureSymbol, Section.isComdat()); GroupIdx = addToSectionTable(Group); Group->setAlignment(Align(4)); Groups.push_back(Group); @@ -1150,7 +1151,7 @@ if (!Asm.CGProfile.empty()) { CGProfileSection = Ctx.getELFSection(".llvm.call-graph-profile", ELF::SHT_LLVM_CALL_GRAPH_PROFILE, - ELF::SHF_EXCLUDE, 16, ""); + ELF::SHF_EXCLUDE, 16); SectionIndexMap[CGProfileSection] = addToSectionTable(CGProfileSection); } @@ -1162,7 +1163,7 @@ const MCSymbol *SignatureSymbol = Group->getGroup(); assert(SignatureSymbol); - write(uint32_t(ELF::GRP_COMDAT)); + write(uint32_t(Group->isComdat() ? ELF::GRP_COMDAT : 0)); for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) { uint32_t SecIndex = SectionIndexMap.lookup(Member); write(SecIndex); diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/lib/MC/MCContext.cpp @@ -419,7 +419,7 @@ unsigned Flags, SectionKind K, unsigned EntrySize, const MCSymbolELF *Group, - unsigned UniqueID, + bool Comdat, unsigned UniqueID, const MCSymbolELF *LinkedToSym) { MCSymbolELF *R; MCSymbol *&Sym = Symbols[Section]; @@ -439,8 +439,9 @@ R->setBinding(ELF::STB_LOCAL); R->setType(ELF::STT_SECTION); - auto *Ret = new (ELFAllocator.Allocate()) MCSectionELF( - Section, Type, Flags, K, EntrySize, Group, UniqueID, R, LinkedToSym); + auto *Ret = new (ELFAllocator.Allocate()) + MCSectionELF(Section, Type, Flags, K, EntrySize, Group, Comdat, UniqueID, + R, LinkedToSym); auto *F = new MCDataFragment(); Ret->getFragmentList().insert(Ret->begin(), F); @@ -461,32 +462,34 @@ return createELFSectionImpl( I->getKey(), Type, Flags, SectionKind::getReadOnly(), EntrySize, Group, - true, cast(RelInfoSection->getBeginSymbol())); + true, true, cast(RelInfoSection->getBeginSymbol())); } MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix, const Twine &Suffix, unsigned Type, unsigned Flags, unsigned EntrySize) { - return getELFSection(Prefix + "." + Suffix, Type, Flags, EntrySize, Suffix); + return getELFSection(Prefix + "." + Suffix, Type, Flags, EntrySize, Suffix, + /*IsComdat=*/true); } MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type, unsigned Flags, unsigned EntrySize, - const Twine &Group, unsigned UniqueID, + const Twine &Group, bool IsComdat, + unsigned UniqueID, const MCSymbolELF *LinkedToSym) { MCSymbolELF *GroupSym = nullptr; if (!Group.isTriviallyEmpty() && !Group.str().empty()) GroupSym = cast(getOrCreateSymbol(Group)); - return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID, - LinkedToSym); + return getELFSection(Section, Type, Flags, EntrySize, GroupSym, IsComdat, + UniqueID, LinkedToSym); } MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type, unsigned Flags, unsigned EntrySize, const MCSymbolELF *GroupSym, - unsigned UniqueID, + bool IsComdat, unsigned UniqueID, const MCSymbolELF *LinkedToSym) { StringRef Group = ""; if (GroupSym) @@ -513,7 +516,7 @@ MCSectionELF *Result = createELFSectionImpl(CachedName, Type, Flags, Kind, EntrySize, GroupSym, - UniqueID, LinkedToSym); + IsComdat, UniqueID, LinkedToSym); Entry.second = Result; recordELFMergeableSectionInfo(Result->getName(), Result->getFlags(), @@ -522,9 +525,10 @@ return Result; } -MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group) { +MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group, + bool IsComdat) { return createELFSectionImpl(".group", ELF::SHT_GROUP, 0, - SectionKind::getReadOnly(), 4, Group, + SectionKind::getReadOnly(), 4, Group, IsComdat, MCSection::NonUniqueID, nullptr); } diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -375,7 +375,7 @@ void MCELFStreamer::emitIdent(StringRef IdentString) { MCSection *Comment = getAssembler().getContext().getELFSection( - ".comment", ELF::SHT_PROGBITS, ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, ""); + ".comment", ELF::SHT_PROGBITS, ELF::SHF_MERGE | ELF::SHF_STRINGS, 1); PushSection(); SwitchSection(Comment); if (!SeenIdent) { diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -371,19 +371,19 @@ MergeableConst4Section = Ctx->getELFSection(".rodata.cst4", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC | ELF::SHF_MERGE, 4, ""); + ELF::SHF_ALLOC | ELF::SHF_MERGE, 4); MergeableConst8Section = Ctx->getELFSection(".rodata.cst8", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC | ELF::SHF_MERGE, 8, ""); + ELF::SHF_ALLOC | ELF::SHF_MERGE, 8); MergeableConst16Section = Ctx->getELFSection(".rodata.cst16", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC | ELF::SHF_MERGE, 16, ""); + ELF::SHF_ALLOC | ELF::SHF_MERGE, 16); MergeableConst32Section = Ctx->getELFSection(".rodata.cst32", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC | ELF::SHF_MERGE, 32, ""); + ELF::SHF_ALLOC | ELF::SHF_MERGE, 32); // Exception Handling Sections. @@ -412,7 +412,7 @@ DwarfLineSection = Ctx->getELFSection(".debug_line", DebugSecType, 0); DwarfLineStrSection = Ctx->getELFSection(".debug_line_str", DebugSecType, - ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, ""); + ELF::SHF_MERGE | ELF::SHF_STRINGS, 1); DwarfFrameSection = Ctx->getELFSection(".debug_frame", DebugSecType, 0); DwarfPubNamesSection = Ctx->getELFSection(".debug_pubnames", DebugSecType, 0); @@ -424,7 +424,7 @@ Ctx->getELFSection(".debug_gnu_pubtypes", DebugSecType, 0); DwarfStrSection = Ctx->getELFSection(".debug_str", DebugSecType, - ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, ""); + ELF::SHF_MERGE | ELF::SHF_STRINGS, 1); DwarfLocSection = Ctx->getELFSection(".debug_loc", DebugSecType, 0); DwarfARangesSection = Ctx->getELFSection(".debug_aranges", DebugSecType, 0); @@ -464,7 +464,7 @@ Ctx->getELFSection(".debug_abbrev.dwo", DebugSecType, ELF::SHF_EXCLUDE); DwarfStrDWOSection = Ctx->getELFSection( ".debug_str.dwo", DebugSecType, - ELF::SHF_MERGE | ELF::SHF_STRINGS | ELF::SHF_EXCLUDE, 1, ""); + ELF::SHF_MERGE | ELF::SHF_STRINGS | ELF::SHF_EXCLUDE, 1); DwarfLineDWOSection = Ctx->getELFSection(".debug_line.dwo", DebugSecType, ELF::SHF_EXCLUDE); DwarfLocDWOSection = @@ -976,7 +976,7 @@ switch (TT.getObjectFormat()) { case Triple::ELF: return Ctx->getELFSection(Name, ELF::SHT_PROGBITS, ELF::SHF_GROUP, 0, - utostr(Hash)); + utostr(Hash), /*IsComdat=*/true); case Triple::Wasm: return Ctx->getWasmSection(Name, SectionKind::getMetadata(), utostr(Hash), MCContext::GenericSectionID); @@ -1006,7 +1006,7 @@ } return Ctx->getELFSection(".stack_sizes", ELF::SHT_PROGBITS, Flags, 0, - GroupName, ElfSec.getUniqueID(), + GroupName, true, ElfSec.getUniqueID(), cast(TextSec.getBeginSymbol())); } @@ -1026,7 +1026,7 @@ // Use the text section's begin symbol and unique ID to create a separate // .llvm_bb_addr_map section associated with every unique text section. return Ctx->getELFSection(".llvm_bb_addr_map", ELF::SHT_LLVM_BB_ADDR_MAP, - Flags, 0, GroupName, ElfSec.getUniqueID(), + Flags, 0, GroupName, true, ElfSec.getUniqueID(), cast(TextSec.getBeginSymbol())); } @@ -1039,7 +1039,8 @@ auto *S = static_cast(PseudoProbeSection); auto Flags = S->getFlags() | ELF::SHF_GROUP; return Ctx->getELFSection(S->getName(), S->getType(), Flags, - S->getEntrySize(), Group->getName()); + S->getEntrySize(), Group->getName(), + /*IsComdat=*/true); } } return PseudoProbeSection; @@ -1062,7 +1063,8 @@ auto Flags = S->getFlags() | ELF::SHF_GROUP; return Ctx->getELFSection(S->getName(), S->getType(), Flags, S->getEntrySize(), - S->getName() + "_" + FuncName); + S->getName() + "_" + FuncName, + /*IsComdat=*/true); } } return PseudoProbeDescSection; diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp --- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp +++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp @@ -157,7 +157,7 @@ unsigned parseSunStyleSectionFlags(); bool maybeParseSectionType(StringRef &TypeName); bool parseMergeSize(int64_t &Size); - bool parseGroup(StringRef &GroupName); + bool parseGroup(StringRef &GroupName, bool &IsComdat); bool parseLinkedToSym(MCSymbolELF *&LinkedToSym); bool maybeParseUniqueID(int64_t &UniqueID); }; @@ -424,7 +424,7 @@ return false; } -bool ELFAsmParser::parseGroup(StringRef &GroupName) { +bool ELFAsmParser::parseGroup(StringRef &GroupName, bool &IsComdat) { MCAsmLexer &L = getLexer(); if (L.isNot(AsmToken::Comma)) return TokError("expected group name"); @@ -442,6 +442,7 @@ return TokError("invalid linkage"); if (Linkage != "comdat") return TokError("Linkage must be 'comdat'"); + IsComdat = true; } return false; } @@ -502,6 +503,7 @@ StringRef TypeName; int64_t Size = 0; StringRef GroupName; + bool IsComdat = false; unsigned Flags = 0; unsigned extraFlags = 0; const MCExpr *Subsection = nullptr; @@ -574,7 +576,7 @@ if (parseMergeSize(Size)) return true; if (Group) - if (parseGroup(GroupName)) + if (parseGroup(GroupName, IsComdat)) return true; if (Flags & ELF::SHF_LINK_ORDER) if (parseLinkedToSym(LinkedToSym)) @@ -640,12 +642,14 @@ cast_or_null(CurrentSection.first)) if (const MCSymbol *Group = Section->getGroup()) { GroupName = Group->getName(); + IsComdat = Section->isComdat(); Flags |= ELF::SHF_GROUP; } } - MCSectionELF *Section = getContext().getELFSection( - SectionName, Type, Flags, Size, GroupName, UniqueID, LinkedToSym); + MCSectionELF *Section = + getContext().getELFSection(SectionName, Type, Flags, Size, GroupName, + IsComdat, UniqueID, LinkedToSym); getStreamer().SwitchSection(Section, Subsection); // x86-64 psABI names SHT_X86_64_UNWIND as the canonical type for .eh_frame, // but GNU as emits SHT_PROGBITS .eh_frame for .cfi_* directives. Don't error diff --git a/llvm/lib/MC/MCSectionELF.cpp b/llvm/lib/MC/MCSectionELF.cpp --- a/llvm/lib/MC/MCSectionELF.cpp +++ b/llvm/lib/MC/MCSectionELF.cpp @@ -171,8 +171,9 @@ if (Flags & ELF::SHF_GROUP) { OS << ","; - printName(OS, Group->getName()); - OS << ",comdat"; + printName(OS, Group.getPointer()->getName()); + if (isComdat()) + OS << ",comdat"; } if (Flags & ELF::SHF_LINK_ORDER) { diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -352,7 +352,7 @@ OutStreamer->SwitchSection(OutContext.getELFSection( ".text.hot", ELF::SHT_PROGBITS, ELF::SHF_EXECINSTR | ELF::SHF_ALLOC | ELF::SHF_GROUP, 0, - Sym->getName())); + Sym->getName(), /*IsComdat=*/true)); OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeFunction); OutStreamer->emitSymbolAttribute(Sym, MCSA_Weak); diff --git a/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp b/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp --- a/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp +++ b/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp @@ -49,7 +49,8 @@ // Since we cannot modify flags for an existing section, we create a new // section with the right flags, and use 0 as the unique ID for // execute-only text - TextSection = Ctx.getELFSection(".text", Type, Flags, 0, "", 0U, nullptr); + TextSection = + Ctx.getELFSection(".text", Type, Flags, 0, "", false, 0U, nullptr); } } diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -1203,7 +1203,7 @@ if (Group) Flags |= ELF::SHF_GROUP; MCSectionELF *EHSection = getContext().getELFSection( - EHSecName, Type, Flags, 0, Group, FnSection.getUniqueID(), + EHSecName, Type, Flags, 0, Group, false, FnSection.getUniqueID(), static_cast(FnSection.getBeginSymbol())); assert(EHSection && "Failed to get the required EH section"); diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp @@ -35,7 +35,7 @@ // 1-byte long nor fixed length but it matches the value GAS emits. MCSectionELF *Sec = Context.getELFSection(".MIPS.options", ELF::SHT_MIPS_OPTIONS, - ELF::SHF_ALLOC | ELF::SHF_MIPS_NOSTRIP, 1, ""); + ELF::SHF_ALLOC | ELF::SHF_MIPS_NOSTRIP, 1); MCA.registerSection(*Sec); Sec->setAlignment(Align(8)); Streamer->SwitchSection(Sec); @@ -53,7 +53,7 @@ Streamer->emitIntValue(ri_gp_value, 8); } else { MCSectionELF *Sec = Context.getELFSection(".reginfo", ELF::SHT_MIPS_REGINFO, - ELF::SHF_ALLOC, 24, ""); + ELF::SHF_ALLOC, 24); MCA.registerSection(*Sec); Sec->setAlignment(MTS->getABI().IsN32() ? Align(8) : Align(4)); Streamer->SwitchSection(Sec); diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -1309,7 +1309,7 @@ MCContext &Context = MCA.getContext(); MCStreamer &OS = getStreamer(); MCSectionELF *Sec = Context.getELFSection( - ".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS, ELF::SHF_ALLOC, 24, ""); + ".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS, ELF::SHF_ALLOC, 24); MCA.registerSection(*Sec); Sec->setAlignment(Align(8)); OS.SwitchSection(Sec); diff --git a/llvm/lib/Target/XCore/XCoreTargetObjectFile.cpp b/llvm/lib/Target/XCore/XCoreTargetObjectFile.cpp --- a/llvm/lib/Target/XCore/XCoreTargetObjectFile.cpp +++ b/llvm/lib/Target/XCore/XCoreTargetObjectFile.cpp @@ -46,13 +46,13 @@ ELF::SHF_ALLOC | ELF::XCORE_SHF_CP_SECTION); MergeableConst4Section = Ctx.getELFSection( ".cp.rodata.cst4", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, 4, ""); + ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, 4); MergeableConst8Section = Ctx.getELFSection( ".cp.rodata.cst8", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, 8, ""); + ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, 8); MergeableConst16Section = Ctx.getELFSection( ".cp.rodata.cst16", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, 16, ""); + ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, 16); CStringSection = Ctx.getELFSection(".cp.rodata.string", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS | diff --git a/llvm/test/CodeGen/X86/group.ll b/llvm/test/CodeGen/X86/group.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/group.ll @@ -0,0 +1,17 @@ +; RUN: llc < %s -mtriple=x86_64-unknown-linux | FileCheck %s + +; CHECK: .section .text.f1,"axG",@progbits,f1 +; CHECK: .section .text.f2,"axG",@progbits,f1 +; CHECK: .section .bss.g1,"aGw",@nobits,f1 + +$f1 = comdat noduplicates + +define void @f1() comdat { + unreachable +} + +define hidden void @f2() comdat($f1) { + unreachable +} + +@g1 = global i32 0, comdat($f1)