[llvm] 16af973 - [MC][ELF] Support for zero flag section groups

Petr Hosek via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 16 14:23:55 PST 2021


Author: Petr Hosek
Date: 2021-02-16T14:23:40-08:00
New Revision: 16af97393346ad636298605930a8b503a55eb40a

URL: https://github.com/llvm/llvm-project/commit/16af97393346ad636298605930a8b503a55eb40a
DIFF: https://github.com/llvm/llvm-project/commit/16af97393346ad636298605930a8b503a55eb40a.diff

LOG: [MC][ELF] Support for zero flag section groups

This change introduces support for zero flag ELF section groups to LLVM.
LLVM already supports COMDAT sections, which in ELF are a special type
of ELF section groups. These are generally useful to enable linker GC
where you want a group of sections to always travel together, that is to
be either retained or discarded as a whole, but without the COMDAT
semantics. Other ELF assemblers already support zero flag ELF section
groups and this change helps us reach feature parity.

Differential Revision: https://reviews.llvm.org/D95851

Added: 
    llvm/test/CodeGen/X86/elf-group.ll

Modified: 
    llvm/include/llvm/MC/MCContext.h
    llvm/include/llvm/MC/MCSectionELF.h
    llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
    llvm/lib/MC/ELFObjectWriter.cpp
    llvm/lib/MC/MCContext.cpp
    llvm/lib/MC/MCELFStreamer.cpp
    llvm/lib/MC/MCObjectFileInfo.cpp
    llvm/lib/MC/MCParser/ELFAsmParser.cpp
    llvm/lib/MC/MCSectionELF.cpp
    llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
    llvm/lib/Target/ARM/ARMTargetObjectFile.cpp
    llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
    llvm/lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp
    llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
    llvm/lib/Target/XCore/XCoreTargetObjectFile.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index 49ab0ce8d6fd..1eb31deca081 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -310,7 +310,7 @@ namespace llvm {
     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 @@ namespace llvm {
 
     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 @@ namespace llvm {
 
     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
index 4136ea79de41..8b17df25a158 100644
--- 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,9 @@ class MCSectionELF final : public MCSection {
   /// fixed-sized entries 'EntrySize' will be 0.
   unsigned EntrySize;
 
-  const MCSymbolELF *Group;
+  /// The section group signature symbol (if not null) and a bool indicating
+  /// whether this is a GRP_COMDAT group.
+  const PointerIntPair<const MCSymbolELF *, 1, bool> 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 +52,14 @@ class MCSectionELF final : public MCSection {
 
   // 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 +75,8 @@ class MCSectionELF final : public MCSection {
   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
index 9123f207e836..764293e7f536 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1827,7 +1827,7 @@ bool AsmPrinter::doFinalization(Module &M) {
 
       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(
@@ -3378,13 +3378,13 @@ void AsmPrinter::emitXRayTable() {
       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());
@@ -3480,7 +3480,7 @@ void AsmPrinter::emitPatchableFunctionEntries() {
     }
     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
index cccac072a9e6..eef05557a353 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -315,7 +315,7 @@ void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer,
 
   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 @@ static const Comdat *getELFComdat(const GlobalValue *GV) {
   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 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
   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 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
   }
 
   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 @@ static MCSectionELF *selectELFSectionForGlobal(
     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 @@ static MCSectionELF *selectELFSectionForGlobal(
   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 @@ MCSection *TargetLoweringObjectFileELF::getSectionForLSDA(
 
   const auto *LSDA = cast<MCSectionELF>(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 @@ MCSection *TargetLoweringObjectFileELF::getSectionForLSDA(
   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 @@ MCSection *TargetLoweringObjectFileELF::getSectionForMachineBasicBlock(
     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 @@ static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray,
   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 @@ static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray,
     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 @@ MCSection *TargetLoweringObjectFileELF::getSectionForCommandLines() const {
   // -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
index 14556d3a7666..b99fce330c28 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -601,7 +601,7 @@ void ELFWriter::computeSymbolTable(
   // 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);
 
@@ -702,7 +702,7 @@ void ELFWriter::computeSymbolTable(
 
   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));
   }
@@ -1098,7 +1098,8 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
     if (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);
@@ -1123,7 +1124,7 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
   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);
   }
 
@@ -1133,7 +1134,7 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
 
     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
index 9dab8a6c0910..bbff59065898 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -419,7 +419,7 @@ MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type,
                                               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 @@ MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type,
   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 @@ MCSectionELF *MCContext::createELFRelSection(const Twine &Name, unsigned Type,
 
   return createELFSectionImpl(
       I->getKey(), Type, Flags, SectionKind::getReadOnly(), EntrySize, Group,
-      true, cast<MCSymbolELF>(RelInfoSection->getBeginSymbol()));
+      true, true, cast<MCSymbolELF>(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<MCSymbolELF>(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 *MCContext::getELFSection(const Twine &Section, unsigned Type,
 
   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 @@ MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
   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
index db45aef7d506..f51f0997a4b4 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -375,7 +375,7 @@ void MCELFStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
 
 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
index 0a682fb95767..9690eafe3653 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -371,19 +371,19 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
 
   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 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
   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 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
       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 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
       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 =
@@ -981,7 +981,7 @@ MCSection *MCObjectFileInfo::getDwarfComdatSection(const char *Name,
   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);
@@ -1011,7 +1011,7 @@ MCObjectFileInfo::getStackSizesSection(const MCSection &TextSec) const {
   }
 
   return Ctx->getELFSection(".stack_sizes", ELF::SHT_PROGBITS, Flags, 0,
-                            GroupName, ElfSec.getUniqueID(),
+                            GroupName, true, ElfSec.getUniqueID(),
                             cast<MCSymbolELF>(TextSec.getBeginSymbol()));
 }
 
@@ -1031,7 +1031,7 @@ MCObjectFileInfo::getBBAddrMapSection(const MCSection &TextSec) const {
   // 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<MCSymbolELF>(TextSec.getBeginSymbol()));
 }
 
@@ -1044,7 +1044,8 @@ MCObjectFileInfo::getPseudoProbeSection(const MCSection *TextSec) const {
       auto *S = static_cast<MCSectionELF *>(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;
@@ -1067,7 +1068,8 @@ MCObjectFileInfo::getPseudoProbeDescSection(StringRef FuncName) const {
       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
index 39ccaa45c9e1..7de19a067a61 100644
--- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
@@ -157,7 +157,7 @@ class ELFAsmParser : public MCAsmParserExtension {
   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 @@ bool ELFAsmParser::parseMergeSize(int64_t &Size) {
   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,9 @@ bool ELFAsmParser::parseGroup(StringRef &GroupName) {
       return TokError("invalid linkage");
     if (Linkage != "comdat")
       return TokError("Linkage must be 'comdat'");
+    IsComdat = true;
+  } else {
+    IsComdat = false;
   }
   return false;
 }
@@ -502,6 +505,7 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
   StringRef TypeName;
   int64_t Size = 0;
   StringRef GroupName;
+  bool IsComdat = false;
   unsigned Flags = 0;
   unsigned extraFlags = 0;
   const MCExpr *Subsection = nullptr;
@@ -574,7 +578,7 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
       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 +644,14 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
             cast_or_null<MCSectionELF>(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
index 300f209d213d..d18876507cd7 100644
--- a/llvm/lib/MC/MCSectionELF.cpp
+++ b/llvm/lib/MC/MCSectionELF.cpp
@@ -171,8 +171,9 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
 
   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
index ecace64a6530..672efdfe0c80 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -377,7 +377,7 @@ void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) {
     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
index 3f0e3360632d..b03bff92f373 100644
--- a/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp
+++ b/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp
@@ -49,7 +49,8 @@ void ARMElfTargetObjectFile::Initialize(MCContext &Ctx,
     // 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
index 07ca5c29f0ec..2fc104b87221 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
@@ -1203,7 +1203,8 @@ inline void ARMELFStreamer::SwitchToEHSection(StringRef Prefix,
   if (Group)
     Flags |= ELF::SHF_GROUP;
   MCSectionELF *EHSection = getContext().getELFSection(
-      EHSecName, Type, Flags, 0, Group, FnSection.getUniqueID(),
+      EHSecName, Type, Flags, 0, Group, /*IsComdat=*/true,
+      FnSection.getUniqueID(),
       static_cast<const MCSymbolELF *>(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
index a4a953bcd7c3..befa883d5877 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp
@@ -35,7 +35,7 @@ void MipsRegInfoRecord::EmitMipsOptionRecord() {
     // 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 @@ void MipsRegInfoRecord::EmitMipsOptionRecord() {
     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
index 6ec8fe805968..232d0eb33164 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
@@ -1309,7 +1309,7 @@ void MipsTargetELFStreamer::emitMipsAbiFlags() {
   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
index 9fec74a372fb..52a0a09d3ea5 100644
--- a/llvm/lib/Target/XCore/XCoreTargetObjectFile.cpp
+++ b/llvm/lib/Target/XCore/XCoreTargetObjectFile.cpp
@@ -46,13 +46,13 @@ void XCoreTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){
                         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/elf-group.ll b/llvm/test/CodeGen/X86/elf-group.ll
new file mode 100644
index 000000000000..79fa41e5ba8f
--- /dev/null
+++ b/llvm/test/CodeGen/X86/elf-group.ll
@@ -0,0 +1,19 @@
+; Checks that comdat with noduplicates kind is lowered to a zero-flag ELF
+; section group.
+; RUN: llc < %s -mtriple=x86_64-unknown-linux | FileCheck %s
+
+; CHECK: .section .text.f1,"axG", at progbits,f1{{$}}
+; CHECK: .section .text.f2,"axG", at progbits,f1{{$}}
+; CHECK: .section .bss.g1,"aGw", at nobits,f1{{$}}
+
+$f1 = comdat noduplicates
+
+define void @f1() comdat {
+  unreachable
+}
+
+define hidden void @f2() comdat($f1) {
+  unreachable
+}
+
+ at g1 = global i32 0, comdat($f1)


        


More information about the llvm-commits mailing list