1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[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
This commit is contained in:
Petr Hosek 2021-01-31 22:42:35 -08:00
parent b5ada42319
commit 8007c5924c
17 changed files with 140 additions and 81 deletions

View File

@ -310,7 +310,7 @@ namespace llvm {
MCSectionELF *createELFSectionImpl(StringRef Section, unsigned Type, MCSectionELF *createELFSectionImpl(StringRef Section, unsigned Type,
unsigned Flags, SectionKind K, unsigned Flags, SectionKind K,
unsigned EntrySize, unsigned EntrySize,
const MCSymbolELF *Group, const MCSymbolELF *Group, bool IsComdat,
unsigned UniqueID, unsigned UniqueID,
const MCSymbolELF *LinkedToSym); const MCSymbolELF *LinkedToSym);
@ -482,24 +482,32 @@ namespace llvm {
MCSectionELF *getELFSection(const Twine &Section, unsigned Type, MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags) { unsigned Flags) {
return getELFSection(Section, Type, Flags, 0, ""); return getELFSection(Section, Type, Flags, 0, "", false);
} }
MCSectionELF *getELFSection(const Twine &Section, unsigned Type, MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize, unsigned Flags, unsigned EntrySize) {
const Twine &Group) { return getELFSection(Section, Type, Flags, EntrySize, "", false,
return getELFSection(Section, Type, Flags, EntrySize, Group,
MCSection::NonUniqueID, nullptr); MCSection::NonUniqueID, nullptr);
} }
MCSectionELF *getELFSection(const Twine &Section, unsigned Type, MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize, unsigned Flags, unsigned EntrySize,
const Twine &Group, unsigned UniqueID, 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, bool IsComdat,
unsigned UniqueID,
const MCSymbolELF *LinkedToSym); const MCSymbolELF *LinkedToSym);
MCSectionELF *getELFSection(const Twine &Section, unsigned Type, MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize, unsigned Flags, unsigned EntrySize,
const MCSymbolELF *Group, unsigned UniqueID, const MCSymbolELF *Group, bool IsComdat,
unsigned UniqueID,
const MCSymbolELF *LinkedToSym); const MCSymbolELF *LinkedToSym);
/// Get a section with the provided group identifier. This section is /// Get a section with the provided group identifier. This section is
@ -517,7 +525,8 @@ namespace llvm {
void renameELFSection(MCSectionELF *Section, StringRef Name); void renameELFSection(MCSectionELF *Section, StringRef Name);
MCSectionELF *createELFGroupSection(const MCSymbolELF *Group); MCSectionELF *createELFGroupSection(const MCSymbolELF *Group,
bool IsComdat);
void recordELFMergeableSectionInfo(StringRef SectionName, unsigned Flags, void recordELFMergeableSectionInfo(StringRef SectionName, unsigned Flags,
unsigned UniqueID, unsigned EntrySize); unsigned UniqueID, unsigned EntrySize);

View File

@ -13,6 +13,7 @@
#ifndef LLVM_MC_MCSECTIONELF_H #ifndef LLVM_MC_MCSECTIONELF_H
#define LLVM_MC_MCSECTIONELF_H #define LLVM_MC_MCSECTIONELF_H
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCSection.h" #include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSymbolELF.h" #include "llvm/MC/MCSymbolELF.h"
@ -38,7 +39,9 @@ class MCSectionELF final : public MCSection {
/// fixed-sized entries 'EntrySize' will be 0. /// fixed-sized entries 'EntrySize' will be 0.
unsigned EntrySize; 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 /// 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. /// section header index of the section where LinkedToSym is defined.
@ -49,13 +52,14 @@ private:
// The storage of Name is owned by MCContext's ELFUniquingMap. // The storage of Name is owned by MCContext's ELFUniquingMap.
MCSectionELF(StringRef Name, unsigned type, unsigned flags, SectionKind K, MCSectionELF(StringRef Name, unsigned type, unsigned flags, SectionKind K,
unsigned entrySize, const MCSymbolELF *group, unsigned UniqueID, unsigned entrySize, const MCSymbolELF *group, bool IsComdat,
MCSymbol *Begin, const MCSymbolELF *LinkedToSym) unsigned UniqueID, MCSymbol *Begin,
const MCSymbolELF *LinkedToSym)
: MCSection(SV_ELF, Name, K, Begin), Type(type), Flags(flags), : 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) { LinkedToSym(LinkedToSym) {
if (Group) if (Group.getPointer())
Group->setIsSignature(); Group.getPointer()->setIsSignature();
} }
// TODO Delete after we stop supporting generation of GNU-style .zdebug_* // TODO Delete after we stop supporting generation of GNU-style .zdebug_*
@ -71,7 +75,8 @@ public:
unsigned getFlags() const { return Flags; } unsigned getFlags() const { return Flags; }
unsigned getEntrySize() const { return EntrySize; } unsigned getEntrySize() const { return EntrySize; }
void setFlags(unsigned F) { Flags = F; } 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, void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
raw_ostream &OS, raw_ostream &OS,

View File

@ -1827,7 +1827,7 @@ bool AsmPrinter::doFinalization(Module &M) {
OutStreamer->SwitchSection( OutStreamer->SwitchSection(
OutContext.getELFSection(".llvm_sympart", ELF::SHT_LLVM_SYMPART, 0, 0, OutContext.getELFSection(".llvm_sympart", ELF::SHT_LLVM_SYMPART, 0, 0,
"", ++UniqueID, nullptr)); "", false, ++UniqueID, nullptr));
OutStreamer->emitBytes(GV.getPartition()); OutStreamer->emitBytes(GV.getPartition());
OutStreamer->emitZeros(1); OutStreamer->emitZeros(1);
OutStreamer->emitValue( OutStreamer->emitValue(
@ -3378,13 +3378,13 @@ void AsmPrinter::emitXRayTable() {
GroupName = F.getComdat()->getName(); GroupName = F.getComdat()->getName();
} }
InstMap = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, InstMap = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS,
Flags, 0, GroupName, Flags, 0, GroupName, F.hasComdat(),
MCSection::NonUniqueID, LinkedToSym); MCSection::NonUniqueID, LinkedToSym);
if (!TM.Options.XRayOmitFunctionIndex) if (!TM.Options.XRayOmitFunctionIndex)
FnSledIndex = OutContext.getELFSection( FnSledIndex = OutContext.getELFSection(
"xray_fn_idx", ELF::SHT_PROGBITS, Flags | ELF::SHF_WRITE, 0, "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()) { } else if (MF->getSubtarget().getTargetTriple().isOSBinFormatMachO()) {
InstMap = OutContext.getMachOSection("__DATA", "xray_instr_map", 0, InstMap = OutContext.getMachOSection("__DATA", "xray_instr_map", 0,
SectionKind::getReadOnlyWithRel()); SectionKind::getReadOnlyWithRel());
@ -3480,7 +3480,7 @@ void AsmPrinter::emitPatchableFunctionEntries() {
} }
OutStreamer->SwitchSection(OutContext.getELFSection( OutStreamer->SwitchSection(OutContext.getELFSection(
"__patchable_function_entries", ELF::SHT_PROGBITS, Flags, 0, GroupName, "__patchable_function_entries", ELF::SHT_PROGBITS, Flags, 0, GroupName,
MCSection::NonUniqueID, LinkedToSym)); F.hasComdat(), MCSection::NonUniqueID, LinkedToSym));
emitAlignment(Align(PointerSize)); emitAlignment(Align(PointerSize));
OutStreamer->emitSymbolValue(CurrentPatchableFunctionEntrySym, PointerSize); OutStreamer->emitSymbolValue(CurrentPatchableFunctionEntrySym, PointerSize);
} }

View File

@ -315,7 +315,7 @@ void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer,
if (NamedMDNode *DependentLibraries = M.getNamedMetadata("llvm.dependent-libraries")) { if (NamedMDNode *DependentLibraries = M.getNamedMetadata("llvm.dependent-libraries")) {
auto *S = C.getELFSection(".deplibs", ELF::SHT_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); Streamer.SwitchSection(S);
@ -522,9 +522,11 @@ static const Comdat *getELFComdat(const GlobalValue *GV) {
if (!C) if (!C)
return nullptr; return nullptr;
if (C->getSelectionKind() != Comdat::Any) if (C->getSelectionKind() != Comdat::Any &&
report_fatal_error("ELF COMDATs only support SelectionKind::Any, '" + C->getSelectionKind() != Comdat::NoDuplicates)
C->getName() + "' cannot be lowered."); report_fatal_error("ELF COMDATs only support SelectionKind::Any and "
"SelectionKind::NoDuplicates, '" + C->getName() +
"' cannot be lowered.");
return C; return C;
} }
@ -669,9 +671,11 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
Kind = getELFKindForNamedSection(SectionName, Kind); Kind = getELFKindForNamedSection(SectionName, Kind);
StringRef Group = ""; StringRef Group = "";
bool IsComdat = false;
unsigned Flags = getELFSectionFlags(Kind); unsigned Flags = getELFSectionFlags(Kind);
if (const Comdat *C = getELFComdat(GO)) { if (const Comdat *C = getELFComdat(GO)) {
Group = C->getName(); Group = C->getName();
IsComdat = C->getSelectionKind() == Comdat::Any;
Flags |= ELF::SHF_GROUP; Flags |= ELF::SHF_GROUP;
} }
@ -730,8 +734,8 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
} }
MCSectionELF *Section = getContext().getELFSection( MCSectionELF *Section = getContext().getELFSection(
SectionName, getELFSectionType(SectionName, Kind), Flags, SectionName, getELFSectionType(SectionName, Kind), Flags, EntrySize,
EntrySize, Group, UniqueID, LinkedToSym); Group, IsComdat, UniqueID, LinkedToSym);
// Make sure that we did not get some other section with incompatible sh_link. // Make sure that we did not get some other section with incompatible sh_link.
// This should not be possible due to UniqueID code above. // This should not be possible due to UniqueID code above.
assert(Section->getLinkedToSymbol() == LinkedToSym && assert(Section->getLinkedToSymbol() == LinkedToSym &&
@ -763,9 +767,11 @@ static MCSectionELF *selectELFSectionForGlobal(
unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) { unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) {
StringRef Group = ""; StringRef Group = "";
bool IsComdat = false;
if (const Comdat *C = getELFComdat(GO)) { if (const Comdat *C = getELFComdat(GO)) {
Flags |= ELF::SHF_GROUP; Flags |= ELF::SHF_GROUP;
Group = C->getName(); Group = C->getName();
IsComdat = C->getSelectionKind() == Comdat::Any;
} }
// Get the section entry size based on the kind. // Get the section entry size based on the kind.
@ -788,7 +794,8 @@ static MCSectionELF *selectELFSectionForGlobal(
if (Kind.isExecuteOnly()) if (Kind.isExecuteOnly())
UniqueID = 0; UniqueID = 0;
return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags, return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags,
EntrySize, Group, UniqueID, AssociatedSymbol); EntrySize, Group, IsComdat, UniqueID,
AssociatedSymbol);
} }
MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal(
@ -843,11 +850,13 @@ MCSection *TargetLoweringObjectFileELF::getSectionForLSDA(
const auto *LSDA = cast<MCSectionELF>(LSDASection); const auto *LSDA = cast<MCSectionELF>(LSDASection);
unsigned Flags = LSDA->getFlags(); unsigned Flags = LSDA->getFlags();
StringRef Group;
const MCSymbolELF *LinkedToSym = nullptr; const MCSymbolELF *LinkedToSym = nullptr;
if (F.hasComdat()) { StringRef Group;
Group = F.getComdat()->getName(); bool IsComdat = false;
if (const Comdat *C = getELFComdat(&F)) {
Flags |= ELF::SHF_GROUP; 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 // 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. // or LLD, which support mixed SHF_LINK_ORDER & non-SHF_LINK_ORDER.
@ -863,7 +872,8 @@ MCSection *TargetLoweringObjectFileELF::getSectionForLSDA(
return getContext().getELFSection( return getContext().getELFSection(
(TM.getUniqueSectionNames() ? LSDA->getName() + "." + F.getName() (TM.getUniqueSectionNames() ? LSDA->getName() + "." + F.getName()
: LSDA->getName()), : LSDA->getName()),
LSDA->getType(), Flags, 0, Group, MCSection::NonUniqueID, LinkedToSym); LSDA->getType(), Flags, 0, Group, F.hasComdat(), MCSection::NonUniqueID,
LinkedToSym);
} }
bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection( bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection(
@ -929,8 +939,8 @@ MCSection *TargetLoweringObjectFileELF::getSectionForMachineBasicBlock(
GroupName = F.getComdat()->getName().str(); GroupName = F.getComdat()->getName().str();
} }
return getContext().getELFSection(Name, ELF::SHT_PROGBITS, Flags, return getContext().getELFSection(Name, ELF::SHT_PROGBITS, Flags,
0 /* Entry Size */, GroupName, UniqueID, 0 /* Entry Size */, GroupName,
nullptr); F.hasComdat(), UniqueID, nullptr);
} }
static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray, static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray,
@ -939,7 +949,7 @@ static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray,
std::string Name; std::string Name;
unsigned Type; unsigned Type;
unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE; unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE;
StringRef COMDAT = KeySym ? KeySym->getName() : ""; StringRef Comdat = KeySym ? KeySym->getName() : "";
if (KeySym) if (KeySym)
Flags |= ELF::SHF_GROUP; Flags |= ELF::SHF_GROUP;
@ -968,7 +978,7 @@ static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray,
Type = ELF::SHT_PROGBITS; 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( 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 // -frecord-gcc-switches which in turn attempts to mimic GCC's switch of the
// same name. // same name.
return getContext().getELFSection(".GCC.command.line", ELF::SHT_PROGBITS, return getContext().getELFSection(".GCC.command.line", ELF::SHT_PROGBITS,
ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, ""); ELF::SHF_MERGE | ELF::SHF_STRINGS, 1);
} }
void void

View File

@ -601,7 +601,7 @@ void ELFWriter::computeSymbolTable(
// Symbol table // Symbol table
unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
MCSectionELF *SymtabSection = 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)); SymtabSection->setAlignment(is64Bit() ? Align(8) : Align(4));
SymbolTableIndex = addToSectionTable(SymtabSection); SymbolTableIndex = addToSectionTable(SymtabSection);
@ -702,7 +702,7 @@ void ELFWriter::computeSymbolTable(
if (HasLargeSectionIndex) { if (HasLargeSectionIndex) {
MCSectionELF *SymtabShndxSection = 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); SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);
SymtabShndxSection->setAlignment(Align(4)); SymtabShndxSection->setAlignment(Align(4));
} }
@ -1098,7 +1098,8 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
if (SignatureSymbol) { if (SignatureSymbol) {
unsigned &GroupIdx = RevGroupMap[SignatureSymbol]; unsigned &GroupIdx = RevGroupMap[SignatureSymbol];
if (!GroupIdx) { if (!GroupIdx) {
MCSectionELF *Group = Ctx.createELFGroupSection(SignatureSymbol); MCSectionELF *Group =
Ctx.createELFGroupSection(SignatureSymbol, Section.isComdat());
GroupIdx = addToSectionTable(Group); GroupIdx = addToSectionTable(Group);
Group->setAlignment(Align(4)); Group->setAlignment(Align(4));
Groups.push_back(Group); Groups.push_back(Group);
@ -1123,7 +1124,7 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
if (!Asm.CGProfile.empty()) { if (!Asm.CGProfile.empty()) {
CGProfileSection = Ctx.getELFSection(".llvm.call-graph-profile", CGProfileSection = Ctx.getELFSection(".llvm.call-graph-profile",
ELF::SHT_LLVM_CALL_GRAPH_PROFILE, ELF::SHT_LLVM_CALL_GRAPH_PROFILE,
ELF::SHF_EXCLUDE, 16, ""); ELF::SHF_EXCLUDE, 16);
SectionIndexMap[CGProfileSection] = addToSectionTable(CGProfileSection); SectionIndexMap[CGProfileSection] = addToSectionTable(CGProfileSection);
} }
@ -1133,7 +1134,7 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
const MCSymbol *SignatureSymbol = Group->getGroup(); const MCSymbol *SignatureSymbol = Group->getGroup();
assert(SignatureSymbol); assert(SignatureSymbol);
write(uint32_t(ELF::GRP_COMDAT)); write(uint32_t(Group->isComdat() ? ELF::GRP_COMDAT : 0));
for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) { for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) {
uint32_t SecIndex = SectionIndexMap.lookup(Member); uint32_t SecIndex = SectionIndexMap.lookup(Member);
write(SecIndex); write(SecIndex);

View File

@ -419,7 +419,7 @@ MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type,
unsigned Flags, SectionKind K, unsigned Flags, SectionKind K,
unsigned EntrySize, unsigned EntrySize,
const MCSymbolELF *Group, const MCSymbolELF *Group,
unsigned UniqueID, bool Comdat, unsigned UniqueID,
const MCSymbolELF *LinkedToSym) { const MCSymbolELF *LinkedToSym) {
MCSymbolELF *R; MCSymbolELF *R;
MCSymbol *&Sym = Symbols[Section]; MCSymbol *&Sym = Symbols[Section];
@ -439,8 +439,9 @@ MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type,
R->setBinding(ELF::STB_LOCAL); R->setBinding(ELF::STB_LOCAL);
R->setType(ELF::STT_SECTION); R->setType(ELF::STT_SECTION);
auto *Ret = new (ELFAllocator.Allocate()) MCSectionELF( auto *Ret = new (ELFAllocator.Allocate())
Section, Type, Flags, K, EntrySize, Group, UniqueID, R, LinkedToSym); MCSectionELF(Section, Type, Flags, K, EntrySize, Group, Comdat, UniqueID,
R, LinkedToSym);
auto *F = new MCDataFragment(); auto *F = new MCDataFragment();
Ret->getFragmentList().insert(Ret->begin(), F); Ret->getFragmentList().insert(Ret->begin(), F);
@ -461,32 +462,34 @@ MCSectionELF *MCContext::createELFRelSection(const Twine &Name, unsigned Type,
return createELFSectionImpl( return createELFSectionImpl(
I->getKey(), Type, Flags, SectionKind::getReadOnly(), EntrySize, Group, 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, MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix,
const Twine &Suffix, unsigned Type, const Twine &Suffix, unsigned Type,
unsigned Flags, unsigned Flags,
unsigned EntrySize) { 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, MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize, unsigned Flags, unsigned EntrySize,
const Twine &Group, unsigned UniqueID, const Twine &Group, bool IsComdat,
unsigned UniqueID,
const MCSymbolELF *LinkedToSym) { const MCSymbolELF *LinkedToSym) {
MCSymbolELF *GroupSym = nullptr; MCSymbolELF *GroupSym = nullptr;
if (!Group.isTriviallyEmpty() && !Group.str().empty()) if (!Group.isTriviallyEmpty() && !Group.str().empty())
GroupSym = cast<MCSymbolELF>(getOrCreateSymbol(Group)); GroupSym = cast<MCSymbolELF>(getOrCreateSymbol(Group));
return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID, return getELFSection(Section, Type, Flags, EntrySize, GroupSym, IsComdat,
LinkedToSym); UniqueID, LinkedToSym);
} }
MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type, MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize, unsigned Flags, unsigned EntrySize,
const MCSymbolELF *GroupSym, const MCSymbolELF *GroupSym,
unsigned UniqueID, bool IsComdat, unsigned UniqueID,
const MCSymbolELF *LinkedToSym) { const MCSymbolELF *LinkedToSym) {
StringRef Group = ""; StringRef Group = "";
if (GroupSym) if (GroupSym)
@ -513,7 +516,7 @@ MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
MCSectionELF *Result = MCSectionELF *Result =
createELFSectionImpl(CachedName, Type, Flags, Kind, EntrySize, GroupSym, createELFSectionImpl(CachedName, Type, Flags, Kind, EntrySize, GroupSym,
UniqueID, LinkedToSym); IsComdat, UniqueID, LinkedToSym);
Entry.second = Result; Entry.second = Result;
recordELFMergeableSectionInfo(Result->getName(), Result->getFlags(), recordELFMergeableSectionInfo(Result->getName(), Result->getFlags(),
@ -522,9 +525,10 @@ MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
return Result; return Result;
} }
MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group) { MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group,
bool IsComdat) {
return createELFSectionImpl(".group", ELF::SHT_GROUP, 0, return createELFSectionImpl(".group", ELF::SHT_GROUP, 0,
SectionKind::getReadOnly(), 4, Group, SectionKind::getReadOnly(), 4, Group, IsComdat,
MCSection::NonUniqueID, nullptr); MCSection::NonUniqueID, nullptr);
} }

View File

@ -375,7 +375,7 @@ void MCELFStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
void MCELFStreamer::emitIdent(StringRef IdentString) { void MCELFStreamer::emitIdent(StringRef IdentString) {
MCSection *Comment = getAssembler().getContext().getELFSection( 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(); PushSection();
SwitchSection(Comment); SwitchSection(Comment);
if (!SeenIdent) { if (!SeenIdent) {

View File

@ -371,19 +371,19 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
MergeableConst4Section = MergeableConst4Section =
Ctx->getELFSection(".rodata.cst4", ELF::SHT_PROGBITS, Ctx->getELFSection(".rodata.cst4", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC | ELF::SHF_MERGE, 4, ""); ELF::SHF_ALLOC | ELF::SHF_MERGE, 4);
MergeableConst8Section = MergeableConst8Section =
Ctx->getELFSection(".rodata.cst8", ELF::SHT_PROGBITS, Ctx->getELFSection(".rodata.cst8", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC | ELF::SHF_MERGE, 8, ""); ELF::SHF_ALLOC | ELF::SHF_MERGE, 8);
MergeableConst16Section = MergeableConst16Section =
Ctx->getELFSection(".rodata.cst16", ELF::SHT_PROGBITS, Ctx->getELFSection(".rodata.cst16", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC | ELF::SHF_MERGE, 16, ""); ELF::SHF_ALLOC | ELF::SHF_MERGE, 16);
MergeableConst32Section = MergeableConst32Section =
Ctx->getELFSection(".rodata.cst32", ELF::SHT_PROGBITS, Ctx->getELFSection(".rodata.cst32", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC | ELF::SHF_MERGE, 32, ""); ELF::SHF_ALLOC | ELF::SHF_MERGE, 32);
// Exception Handling Sections. // Exception Handling Sections.
@ -412,7 +412,7 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
DwarfLineSection = Ctx->getELFSection(".debug_line", DebugSecType, 0); DwarfLineSection = Ctx->getELFSection(".debug_line", DebugSecType, 0);
DwarfLineStrSection = DwarfLineStrSection =
Ctx->getELFSection(".debug_line_str", DebugSecType, 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); DwarfFrameSection = Ctx->getELFSection(".debug_frame", DebugSecType, 0);
DwarfPubNamesSection = DwarfPubNamesSection =
Ctx->getELFSection(".debug_pubnames", DebugSecType, 0); 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); Ctx->getELFSection(".debug_gnu_pubtypes", DebugSecType, 0);
DwarfStrSection = DwarfStrSection =
Ctx->getELFSection(".debug_str", DebugSecType, 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); DwarfLocSection = Ctx->getELFSection(".debug_loc", DebugSecType, 0);
DwarfARangesSection = DwarfARangesSection =
Ctx->getELFSection(".debug_aranges", DebugSecType, 0); 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); Ctx->getELFSection(".debug_abbrev.dwo", DebugSecType, ELF::SHF_EXCLUDE);
DwarfStrDWOSection = Ctx->getELFSection( DwarfStrDWOSection = Ctx->getELFSection(
".debug_str.dwo", DebugSecType, ".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 = DwarfLineDWOSection =
Ctx->getELFSection(".debug_line.dwo", DebugSecType, ELF::SHF_EXCLUDE); Ctx->getELFSection(".debug_line.dwo", DebugSecType, ELF::SHF_EXCLUDE);
DwarfLocDWOSection = DwarfLocDWOSection =
@ -981,7 +981,7 @@ MCSection *MCObjectFileInfo::getDwarfComdatSection(const char *Name,
switch (TT.getObjectFormat()) { switch (TT.getObjectFormat()) {
case Triple::ELF: case Triple::ELF:
return Ctx->getELFSection(Name, ELF::SHT_PROGBITS, ELF::SHF_GROUP, 0, return Ctx->getELFSection(Name, ELF::SHT_PROGBITS, ELF::SHF_GROUP, 0,
utostr(Hash)); utostr(Hash), /*IsComdat=*/true);
case Triple::Wasm: case Triple::Wasm:
return Ctx->getWasmSection(Name, SectionKind::getMetadata(), utostr(Hash), return Ctx->getWasmSection(Name, SectionKind::getMetadata(), utostr(Hash),
MCContext::GenericSectionID); MCContext::GenericSectionID);
@ -1011,7 +1011,7 @@ MCObjectFileInfo::getStackSizesSection(const MCSection &TextSec) const {
} }
return Ctx->getELFSection(".stack_sizes", ELF::SHT_PROGBITS, Flags, 0, return Ctx->getELFSection(".stack_sizes", ELF::SHT_PROGBITS, Flags, 0,
GroupName, ElfSec.getUniqueID(), GroupName, true, ElfSec.getUniqueID(),
cast<MCSymbolELF>(TextSec.getBeginSymbol())); 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 // 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. // .llvm_bb_addr_map section associated with every unique text section.
return Ctx->getELFSection(".llvm_bb_addr_map", ELF::SHT_LLVM_BB_ADDR_MAP, 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())); cast<MCSymbolELF>(TextSec.getBeginSymbol()));
} }
@ -1044,7 +1044,8 @@ MCObjectFileInfo::getPseudoProbeSection(const MCSection *TextSec) const {
auto *S = static_cast<MCSectionELF *>(PseudoProbeSection); auto *S = static_cast<MCSectionELF *>(PseudoProbeSection);
auto Flags = S->getFlags() | ELF::SHF_GROUP; auto Flags = S->getFlags() | ELF::SHF_GROUP;
return Ctx->getELFSection(S->getName(), S->getType(), Flags, return Ctx->getELFSection(S->getName(), S->getType(), Flags,
S->getEntrySize(), Group->getName()); S->getEntrySize(), Group->getName(),
/*IsComdat=*/true);
} }
} }
return PseudoProbeSection; return PseudoProbeSection;
@ -1067,7 +1068,8 @@ MCObjectFileInfo::getPseudoProbeDescSection(StringRef FuncName) const {
auto Flags = S->getFlags() | ELF::SHF_GROUP; auto Flags = S->getFlags() | ELF::SHF_GROUP;
return Ctx->getELFSection(S->getName(), S->getType(), Flags, return Ctx->getELFSection(S->getName(), S->getType(), Flags,
S->getEntrySize(), S->getEntrySize(),
S->getName() + "_" + FuncName); S->getName() + "_" + FuncName,
/*IsComdat=*/true);
} }
} }
return PseudoProbeDescSection; return PseudoProbeDescSection;

View File

@ -157,7 +157,7 @@ private:
unsigned parseSunStyleSectionFlags(); unsigned parseSunStyleSectionFlags();
bool maybeParseSectionType(StringRef &TypeName); bool maybeParseSectionType(StringRef &TypeName);
bool parseMergeSize(int64_t &Size); bool parseMergeSize(int64_t &Size);
bool parseGroup(StringRef &GroupName); bool parseGroup(StringRef &GroupName, bool &IsComdat);
bool parseLinkedToSym(MCSymbolELF *&LinkedToSym); bool parseLinkedToSym(MCSymbolELF *&LinkedToSym);
bool maybeParseUniqueID(int64_t &UniqueID); bool maybeParseUniqueID(int64_t &UniqueID);
}; };
@ -424,7 +424,7 @@ bool ELFAsmParser::parseMergeSize(int64_t &Size) {
return false; return false;
} }
bool ELFAsmParser::parseGroup(StringRef &GroupName) { bool ELFAsmParser::parseGroup(StringRef &GroupName, bool &IsComdat) {
MCAsmLexer &L = getLexer(); MCAsmLexer &L = getLexer();
if (L.isNot(AsmToken::Comma)) if (L.isNot(AsmToken::Comma))
return TokError("expected group name"); return TokError("expected group name");
@ -442,6 +442,9 @@ bool ELFAsmParser::parseGroup(StringRef &GroupName) {
return TokError("invalid linkage"); return TokError("invalid linkage");
if (Linkage != "comdat") if (Linkage != "comdat")
return TokError("Linkage must be 'comdat'"); return TokError("Linkage must be 'comdat'");
IsComdat = true;
} else {
IsComdat = false;
} }
return false; return false;
} }
@ -502,6 +505,7 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
StringRef TypeName; StringRef TypeName;
int64_t Size = 0; int64_t Size = 0;
StringRef GroupName; StringRef GroupName;
bool IsComdat = false;
unsigned Flags = 0; unsigned Flags = 0;
unsigned extraFlags = 0; unsigned extraFlags = 0;
const MCExpr *Subsection = nullptr; const MCExpr *Subsection = nullptr;
@ -574,7 +578,7 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
if (parseMergeSize(Size)) if (parseMergeSize(Size))
return true; return true;
if (Group) if (Group)
if (parseGroup(GroupName)) if (parseGroup(GroupName, IsComdat))
return true; return true;
if (Flags & ELF::SHF_LINK_ORDER) if (Flags & ELF::SHF_LINK_ORDER)
if (parseLinkedToSym(LinkedToSym)) if (parseLinkedToSym(LinkedToSym))
@ -640,12 +644,14 @@ EndStmt:
cast_or_null<MCSectionELF>(CurrentSection.first)) cast_or_null<MCSectionELF>(CurrentSection.first))
if (const MCSymbol *Group = Section->getGroup()) { if (const MCSymbol *Group = Section->getGroup()) {
GroupName = Group->getName(); GroupName = Group->getName();
IsComdat = Section->isComdat();
Flags |= ELF::SHF_GROUP; Flags |= ELF::SHF_GROUP;
} }
} }
MCSectionELF *Section = getContext().getELFSection( MCSectionELF *Section =
SectionName, Type, Flags, Size, GroupName, UniqueID, LinkedToSym); getContext().getELFSection(SectionName, Type, Flags, Size, GroupName,
IsComdat, UniqueID, LinkedToSym);
getStreamer().SwitchSection(Section, Subsection); getStreamer().SwitchSection(Section, Subsection);
// x86-64 psABI names SHT_X86_64_UNWIND as the canonical type for .eh_frame, // 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 // but GNU as emits SHT_PROGBITS .eh_frame for .cfi_* directives. Don't error

View File

@ -171,8 +171,9 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
if (Flags & ELF::SHF_GROUP) { if (Flags & ELF::SHF_GROUP) {
OS << ","; OS << ",";
printName(OS, Group->getName()); printName(OS, Group.getPointer()->getName());
OS << ",comdat"; if (isComdat())
OS << ",comdat";
} }
if (Flags & ELF::SHF_LINK_ORDER) { if (Flags & ELF::SHF_LINK_ORDER) {

View File

@ -377,7 +377,7 @@ void AArch64AsmPrinter::EmitHwasanMemaccessSymbols(Module &M) {
OutStreamer->SwitchSection(OutContext.getELFSection( OutStreamer->SwitchSection(OutContext.getELFSection(
".text.hot", ELF::SHT_PROGBITS, ".text.hot", ELF::SHT_PROGBITS,
ELF::SHF_EXECINSTR | ELF::SHF_ALLOC | ELF::SHF_GROUP, 0, 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_ELF_TypeFunction);
OutStreamer->emitSymbolAttribute(Sym, MCSA_Weak); OutStreamer->emitSymbolAttribute(Sym, MCSA_Weak);

View File

@ -49,7 +49,8 @@ void ARMElfTargetObjectFile::Initialize(MCContext &Ctx,
// Since we cannot modify flags for an existing section, we create a new // 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 // section with the right flags, and use 0 as the unique ID for
// execute-only text // execute-only text
TextSection = Ctx.getELFSection(".text", Type, Flags, 0, "", 0U, nullptr); TextSection =
Ctx.getELFSection(".text", Type, Flags, 0, "", false, 0U, nullptr);
} }
} }

View File

@ -1203,7 +1203,8 @@ inline void ARMELFStreamer::SwitchToEHSection(StringRef Prefix,
if (Group) if (Group)
Flags |= ELF::SHF_GROUP; Flags |= ELF::SHF_GROUP;
MCSectionELF *EHSection = getContext().getELFSection( 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())); static_cast<const MCSymbolELF *>(FnSection.getBeginSymbol()));
assert(EHSection && "Failed to get the required EH section"); assert(EHSection && "Failed to get the required EH section");

View File

@ -35,7 +35,7 @@ void MipsRegInfoRecord::EmitMipsOptionRecord() {
// 1-byte long nor fixed length but it matches the value GAS emits. // 1-byte long nor fixed length but it matches the value GAS emits.
MCSectionELF *Sec = MCSectionELF *Sec =
Context.getELFSection(".MIPS.options", ELF::SHT_MIPS_OPTIONS, 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); MCA.registerSection(*Sec);
Sec->setAlignment(Align(8)); Sec->setAlignment(Align(8));
Streamer->SwitchSection(Sec); Streamer->SwitchSection(Sec);
@ -53,7 +53,7 @@ void MipsRegInfoRecord::EmitMipsOptionRecord() {
Streamer->emitIntValue(ri_gp_value, 8); Streamer->emitIntValue(ri_gp_value, 8);
} else { } else {
MCSectionELF *Sec = Context.getELFSection(".reginfo", ELF::SHT_MIPS_REGINFO, MCSectionELF *Sec = Context.getELFSection(".reginfo", ELF::SHT_MIPS_REGINFO,
ELF::SHF_ALLOC, 24, ""); ELF::SHF_ALLOC, 24);
MCA.registerSection(*Sec); MCA.registerSection(*Sec);
Sec->setAlignment(MTS->getABI().IsN32() ? Align(8) : Align(4)); Sec->setAlignment(MTS->getABI().IsN32() ? Align(8) : Align(4));
Streamer->SwitchSection(Sec); Streamer->SwitchSection(Sec);

View File

@ -1309,7 +1309,7 @@ void MipsTargetELFStreamer::emitMipsAbiFlags() {
MCContext &Context = MCA.getContext(); MCContext &Context = MCA.getContext();
MCStreamer &OS = getStreamer(); MCStreamer &OS = getStreamer();
MCSectionELF *Sec = Context.getELFSection( 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); MCA.registerSection(*Sec);
Sec->setAlignment(Align(8)); Sec->setAlignment(Align(8));
OS.SwitchSection(Sec); OS.SwitchSection(Sec);

View File

@ -46,13 +46,13 @@ void XCoreTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){
ELF::SHF_ALLOC | ELF::XCORE_SHF_CP_SECTION); ELF::SHF_ALLOC | ELF::XCORE_SHF_CP_SECTION);
MergeableConst4Section = Ctx.getELFSection( MergeableConst4Section = Ctx.getELFSection(
".cp.rodata.cst4", ELF::SHT_PROGBITS, ".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( MergeableConst8Section = Ctx.getELFSection(
".cp.rodata.cst8", ELF::SHT_PROGBITS, ".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( MergeableConst16Section = Ctx.getELFSection(
".cp.rodata.cst16", ELF::SHT_PROGBITS, ".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 = CStringSection =
Ctx.getELFSection(".cp.rodata.string", ELF::SHT_PROGBITS, Ctx.getELFSection(".cp.rodata.string", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS | ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS |

View File

@ -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",@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)