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:
parent
b5ada42319
commit
8007c5924c
@ -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);
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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");
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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 |
|
||||||
|
19
test/CodeGen/X86/elf-group.ll
Normal file
19
test/CodeGen/X86/elf-group.ll
Normal 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)
|
Loading…
Reference in New Issue
Block a user