Skip to content

Commit 16af973

Browse files
committed
[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
1 parent 76609f1 commit 16af973

17 files changed

+139
-80
lines changed

llvm/include/llvm/MC/MCContext.h

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ namespace llvm {
310310
MCSectionELF *createELFSectionImpl(StringRef Section, unsigned Type,
311311
unsigned Flags, SectionKind K,
312312
unsigned EntrySize,
313-
const MCSymbolELF *Group,
313+
const MCSymbolELF *Group, bool IsComdat,
314314
unsigned UniqueID,
315315
const MCSymbolELF *LinkedToSym);
316316

@@ -482,24 +482,32 @@ namespace llvm {
482482

483483
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
484484
unsigned Flags) {
485-
return getELFSection(Section, Type, Flags, 0, "");
485+
return getELFSection(Section, Type, Flags, 0, "", false);
486+
}
487+
488+
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
489+
unsigned Flags, unsigned EntrySize) {
490+
return getELFSection(Section, Type, Flags, EntrySize, "", false,
491+
MCSection::NonUniqueID, nullptr);
486492
}
487493

488494
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
489495
unsigned Flags, unsigned EntrySize,
490-
const Twine &Group) {
491-
return getELFSection(Section, Type, Flags, EntrySize, Group,
496+
const Twine &Group, bool IsComdat) {
497+
return getELFSection(Section, Type, Flags, EntrySize, Group, IsComdat,
492498
MCSection::NonUniqueID, nullptr);
493499
}
494500

495501
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
496502
unsigned Flags, unsigned EntrySize,
497-
const Twine &Group, unsigned UniqueID,
503+
const Twine &Group, bool IsComdat,
504+
unsigned UniqueID,
498505
const MCSymbolELF *LinkedToSym);
499506

500507
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
501508
unsigned Flags, unsigned EntrySize,
502-
const MCSymbolELF *Group, unsigned UniqueID,
509+
const MCSymbolELF *Group, bool IsComdat,
510+
unsigned UniqueID,
503511
const MCSymbolELF *LinkedToSym);
504512

505513
/// Get a section with the provided group identifier. This section is
@@ -517,7 +525,8 @@ namespace llvm {
517525

518526
void renameELFSection(MCSectionELF *Section, StringRef Name);
519527

520-
MCSectionELF *createELFGroupSection(const MCSymbolELF *Group);
528+
MCSectionELF *createELFGroupSection(const MCSymbolELF *Group,
529+
bool IsComdat);
521530

522531
void recordELFMergeableSectionInfo(StringRef SectionName, unsigned Flags,
523532
unsigned UniqueID, unsigned EntrySize);

llvm/include/llvm/MC/MCSectionELF.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef LLVM_MC_MCSECTIONELF_H
1414
#define LLVM_MC_MCSECTIONELF_H
1515

16+
#include "llvm/ADT/PointerIntPair.h"
1617
#include "llvm/ADT/StringRef.h"
1718
#include "llvm/MC/MCSection.h"
1819
#include "llvm/MC/MCSymbolELF.h"
@@ -38,7 +39,9 @@ class MCSectionELF final : public MCSection {
3839
/// fixed-sized entries 'EntrySize' will be 0.
3940
unsigned EntrySize;
4041

41-
const MCSymbolELF *Group;
42+
/// The section group signature symbol (if not null) and a bool indicating
43+
/// whether this is a GRP_COMDAT group.
44+
const PointerIntPair<const MCSymbolELF *, 1, bool> Group;
4245

4346
/// Used by SHF_LINK_ORDER. If non-null, the sh_link field will be set to the
4447
/// section header index of the section where LinkedToSym is defined.
@@ -49,13 +52,14 @@ class MCSectionELF final : public MCSection {
4952

5053
// The storage of Name is owned by MCContext's ELFUniquingMap.
5154
MCSectionELF(StringRef Name, unsigned type, unsigned flags, SectionKind K,
52-
unsigned entrySize, const MCSymbolELF *group, unsigned UniqueID,
53-
MCSymbol *Begin, const MCSymbolELF *LinkedToSym)
55+
unsigned entrySize, const MCSymbolELF *group, bool IsComdat,
56+
unsigned UniqueID, MCSymbol *Begin,
57+
const MCSymbolELF *LinkedToSym)
5458
: MCSection(SV_ELF, Name, K, Begin), Type(type), Flags(flags),
55-
UniqueID(UniqueID), EntrySize(entrySize), Group(group),
59+
UniqueID(UniqueID), EntrySize(entrySize), Group(group, IsComdat),
5660
LinkedToSym(LinkedToSym) {
57-
if (Group)
58-
Group->setIsSignature();
61+
if (Group.getPointer())
62+
Group.getPointer()->setIsSignature();
5963
}
6064

6165
// TODO Delete after we stop supporting generation of GNU-style .zdebug_*
@@ -71,7 +75,8 @@ class MCSectionELF final : public MCSection {
7175
unsigned getFlags() const { return Flags; }
7276
unsigned getEntrySize() const { return EntrySize; }
7377
void setFlags(unsigned F) { Flags = F; }
74-
const MCSymbolELF *getGroup() const { return Group; }
78+
const MCSymbolELF *getGroup() const { return Group.getPointer(); }
79+
bool isComdat() const { return Group.getInt(); }
7580

7681
void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
7782
raw_ostream &OS,

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1827,7 +1827,7 @@ bool AsmPrinter::doFinalization(Module &M) {
18271827

18281828
OutStreamer->SwitchSection(
18291829
OutContext.getELFSection(".llvm_sympart", ELF::SHT_LLVM_SYMPART, 0, 0,
1830-
"", ++UniqueID, nullptr));
1830+
"", false, ++UniqueID, nullptr));
18311831
OutStreamer->emitBytes(GV.getPartition());
18321832
OutStreamer->emitZeros(1);
18331833
OutStreamer->emitValue(
@@ -3378,13 +3378,13 @@ void AsmPrinter::emitXRayTable() {
33783378
GroupName = F.getComdat()->getName();
33793379
}
33803380
InstMap = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS,
3381-
Flags, 0, GroupName,
3381+
Flags, 0, GroupName, F.hasComdat(),
33823382
MCSection::NonUniqueID, LinkedToSym);
33833383

33843384
if (!TM.Options.XRayOmitFunctionIndex)
33853385
FnSledIndex = OutContext.getELFSection(
33863386
"xray_fn_idx", ELF::SHT_PROGBITS, Flags | ELF::SHF_WRITE, 0,
3387-
GroupName, MCSection::NonUniqueID, LinkedToSym);
3387+
GroupName, F.hasComdat(), MCSection::NonUniqueID, LinkedToSym);
33883388
} else if (MF->getSubtarget().getTargetTriple().isOSBinFormatMachO()) {
33893389
InstMap = OutContext.getMachOSection("__DATA", "xray_instr_map", 0,
33903390
SectionKind::getReadOnlyWithRel());
@@ -3480,7 +3480,7 @@ void AsmPrinter::emitPatchableFunctionEntries() {
34803480
}
34813481
OutStreamer->SwitchSection(OutContext.getELFSection(
34823482
"__patchable_function_entries", ELF::SHT_PROGBITS, Flags, 0, GroupName,
3483-
MCSection::NonUniqueID, LinkedToSym));
3483+
F.hasComdat(), MCSection::NonUniqueID, LinkedToSym));
34843484
emitAlignment(Align(PointerSize));
34853485
OutStreamer->emitSymbolValue(CurrentPatchableFunctionEntrySym, PointerSize);
34863486
}

llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer,
315315

316316
if (NamedMDNode *DependentLibraries = M.getNamedMetadata("llvm.dependent-libraries")) {
317317
auto *S = C.getELFSection(".deplibs", ELF::SHT_LLVM_DEPENDENT_LIBRARIES,
318-
ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, "");
318+
ELF::SHF_MERGE | ELF::SHF_STRINGS, 1);
319319

320320
Streamer.SwitchSection(S);
321321

@@ -522,9 +522,11 @@ static const Comdat *getELFComdat(const GlobalValue *GV) {
522522
if (!C)
523523
return nullptr;
524524

525-
if (C->getSelectionKind() != Comdat::Any)
526-
report_fatal_error("ELF COMDATs only support SelectionKind::Any, '" +
527-
C->getName() + "' cannot be lowered.");
525+
if (C->getSelectionKind() != Comdat::Any &&
526+
C->getSelectionKind() != Comdat::NoDuplicates)
527+
report_fatal_error("ELF COMDATs only support SelectionKind::Any and "
528+
"SelectionKind::NoDuplicates, '" + C->getName() +
529+
"' cannot be lowered.");
528530

529531
return C;
530532
}
@@ -669,9 +671,11 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
669671
Kind = getELFKindForNamedSection(SectionName, Kind);
670672

671673
StringRef Group = "";
674+
bool IsComdat = false;
672675
unsigned Flags = getELFSectionFlags(Kind);
673676
if (const Comdat *C = getELFComdat(GO)) {
674677
Group = C->getName();
678+
IsComdat = C->getSelectionKind() == Comdat::Any;
675679
Flags |= ELF::SHF_GROUP;
676680
}
677681

@@ -730,8 +734,8 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
730734
}
731735

732736
MCSectionELF *Section = getContext().getELFSection(
733-
SectionName, getELFSectionType(SectionName, Kind), Flags,
734-
EntrySize, Group, UniqueID, LinkedToSym);
737+
SectionName, getELFSectionType(SectionName, Kind), Flags, EntrySize,
738+
Group, IsComdat, UniqueID, LinkedToSym);
735739
// Make sure that we did not get some other section with incompatible sh_link.
736740
// This should not be possible due to UniqueID code above.
737741
assert(Section->getLinkedToSymbol() == LinkedToSym &&
@@ -763,9 +767,11 @@ static MCSectionELF *selectELFSectionForGlobal(
763767
unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) {
764768

765769
StringRef Group = "";
770+
bool IsComdat = false;
766771
if (const Comdat *C = getELFComdat(GO)) {
767772
Flags |= ELF::SHF_GROUP;
768773
Group = C->getName();
774+
IsComdat = C->getSelectionKind() == Comdat::Any;
769775
}
770776

771777
// Get the section entry size based on the kind.
@@ -788,7 +794,8 @@ static MCSectionELF *selectELFSectionForGlobal(
788794
if (Kind.isExecuteOnly())
789795
UniqueID = 0;
790796
return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags,
791-
EntrySize, Group, UniqueID, AssociatedSymbol);
797+
EntrySize, Group, IsComdat, UniqueID,
798+
AssociatedSymbol);
792799
}
793800

794801
MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal(
@@ -843,11 +850,13 @@ MCSection *TargetLoweringObjectFileELF::getSectionForLSDA(
843850

844851
const auto *LSDA = cast<MCSectionELF>(LSDASection);
845852
unsigned Flags = LSDA->getFlags();
846-
StringRef Group;
847853
const MCSymbolELF *LinkedToSym = nullptr;
848-
if (F.hasComdat()) {
849-
Group = F.getComdat()->getName();
854+
StringRef Group;
855+
bool IsComdat = false;
856+
if (const Comdat *C = getELFComdat(&F)) {
850857
Flags |= ELF::SHF_GROUP;
858+
Group = C->getName();
859+
IsComdat = C->getSelectionKind() == Comdat::Any;
851860
}
852861
// Use SHF_LINK_ORDER to facilitate --gc-sections if we can use GNU ld>=2.36
853862
// or LLD, which support mixed SHF_LINK_ORDER & non-SHF_LINK_ORDER.
@@ -863,7 +872,8 @@ MCSection *TargetLoweringObjectFileELF::getSectionForLSDA(
863872
return getContext().getELFSection(
864873
(TM.getUniqueSectionNames() ? LSDA->getName() + "." + F.getName()
865874
: LSDA->getName()),
866-
LSDA->getType(), Flags, 0, Group, MCSection::NonUniqueID, LinkedToSym);
875+
LSDA->getType(), Flags, 0, Group, F.hasComdat(), MCSection::NonUniqueID,
876+
LinkedToSym);
867877
}
868878

869879
bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection(
@@ -929,8 +939,8 @@ MCSection *TargetLoweringObjectFileELF::getSectionForMachineBasicBlock(
929939
GroupName = F.getComdat()->getName().str();
930940
}
931941
return getContext().getELFSection(Name, ELF::SHT_PROGBITS, Flags,
932-
0 /* Entry Size */, GroupName, UniqueID,
933-
nullptr);
942+
0 /* Entry Size */, GroupName,
943+
F.hasComdat(), UniqueID, nullptr);
934944
}
935945

936946
static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray,
@@ -939,7 +949,7 @@ static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray,
939949
std::string Name;
940950
unsigned Type;
941951
unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE;
942-
StringRef COMDAT = KeySym ? KeySym->getName() : "";
952+
StringRef Comdat = KeySym ? KeySym->getName() : "";
943953

944954
if (KeySym)
945955
Flags |= ELF::SHF_GROUP;
@@ -968,7 +978,7 @@ static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray,
968978
Type = ELF::SHT_PROGBITS;
969979
}
970980

971-
return Ctx.getELFSection(Name, Type, Flags, 0, COMDAT);
981+
return Ctx.getELFSection(Name, Type, Flags, 0, Comdat, /*IsComdat=*/true);
972982
}
973983

974984
MCSection *TargetLoweringObjectFileELF::getStaticCtorSection(
@@ -1022,7 +1032,7 @@ MCSection *TargetLoweringObjectFileELF::getSectionForCommandLines() const {
10221032
// -frecord-gcc-switches which in turn attempts to mimic GCC's switch of the
10231033
// same name.
10241034
return getContext().getELFSection(".GCC.command.line", ELF::SHT_PROGBITS,
1025-
ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, "");
1035+
ELF::SHF_MERGE | ELF::SHF_STRINGS, 1);
10261036
}
10271037

10281038
void

llvm/lib/MC/ELFObjectWriter.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ void ELFWriter::computeSymbolTable(
601601
// Symbol table
602602
unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
603603
MCSectionELF *SymtabSection =
604-
Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize, "");
604+
Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize);
605605
SymtabSection->setAlignment(is64Bit() ? Align(8) : Align(4));
606606
SymbolTableIndex = addToSectionTable(SymtabSection);
607607

@@ -702,7 +702,7 @@ void ELFWriter::computeSymbolTable(
702702

703703
if (HasLargeSectionIndex) {
704704
MCSectionELF *SymtabShndxSection =
705-
Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 4, "");
705+
Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 4);
706706
SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);
707707
SymtabShndxSection->setAlignment(Align(4));
708708
}
@@ -1098,7 +1098,8 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
10981098
if (SignatureSymbol) {
10991099
unsigned &GroupIdx = RevGroupMap[SignatureSymbol];
11001100
if (!GroupIdx) {
1101-
MCSectionELF *Group = Ctx.createELFGroupSection(SignatureSymbol);
1101+
MCSectionELF *Group =
1102+
Ctx.createELFGroupSection(SignatureSymbol, Section.isComdat());
11021103
GroupIdx = addToSectionTable(Group);
11031104
Group->setAlignment(Align(4));
11041105
Groups.push_back(Group);
@@ -1123,7 +1124,7 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
11231124
if (!Asm.CGProfile.empty()) {
11241125
CGProfileSection = Ctx.getELFSection(".llvm.call-graph-profile",
11251126
ELF::SHT_LLVM_CALL_GRAPH_PROFILE,
1126-
ELF::SHF_EXCLUDE, 16, "");
1127+
ELF::SHF_EXCLUDE, 16);
11271128
SectionIndexMap[CGProfileSection] = addToSectionTable(CGProfileSection);
11281129
}
11291130

@@ -1133,7 +1134,7 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
11331134

11341135
const MCSymbol *SignatureSymbol = Group->getGroup();
11351136
assert(SignatureSymbol);
1136-
write(uint32_t(ELF::GRP_COMDAT));
1137+
write(uint32_t(Group->isComdat() ? ELF::GRP_COMDAT : 0));
11371138
for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) {
11381139
uint32_t SecIndex = SectionIndexMap.lookup(Member);
11391140
write(SecIndex);

0 commit comments

Comments
 (0)