mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 00:11:00 +00:00
Support SHF_MERGE sections in COMDATs.
This patch unifies the comdat and non-comdat code paths. By doing this it add missing features to the comdat side and removes the fixed section assumptions from the non-comdat side. In ELF there is no one true section for "4 byte mergeable" constants. We are better off computing the required properties of the section and asking the context for it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230411 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6bc72f8262
commit
76bdd01e0e
@ -164,9 +164,7 @@ static unsigned getELFSectionType(StringRef Name, SectionKind K) {
|
|||||||
return ELF::SHT_PROGBITS;
|
return ELF::SHT_PROGBITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned getELFSectionFlags(SectionKind K) {
|
||||||
static unsigned
|
|
||||||
getELFSectionFlags(SectionKind K, bool InCOMDAT) {
|
|
||||||
unsigned Flags = 0;
|
unsigned Flags = 0;
|
||||||
|
|
||||||
if (!K.isMetadata())
|
if (!K.isMetadata())
|
||||||
@ -181,10 +179,7 @@ getELFSectionFlags(SectionKind K, bool InCOMDAT) {
|
|||||||
if (K.isThreadLocal())
|
if (K.isThreadLocal())
|
||||||
Flags |= ELF::SHF_TLS;
|
Flags |= ELF::SHF_TLS;
|
||||||
|
|
||||||
// FIXME: There is nothing in ELF preventing an SHF_MERGE from being
|
if (K.isMergeableCString() || K.isMergeableConst())
|
||||||
// in a comdat. We just avoid it for now because we don't print
|
|
||||||
// those .sections correctly.
|
|
||||||
if (!InCOMDAT && (K.isMergeableCString() || K.isMergeableConst()))
|
|
||||||
Flags |= ELF::SHF_MERGE;
|
Flags |= ELF::SHF_MERGE;
|
||||||
|
|
||||||
if (K.isMergeableCString())
|
if (K.isMergeableCString())
|
||||||
@ -214,7 +209,7 @@ const MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
|
|||||||
Kind = getELFKindForNamedSection(SectionName, Kind);
|
Kind = getELFKindForNamedSection(SectionName, Kind);
|
||||||
|
|
||||||
StringRef Group = "";
|
StringRef Group = "";
|
||||||
unsigned Flags = getELFSectionFlags(Kind, GV->hasComdat());
|
unsigned Flags = getELFSectionFlags(Kind);
|
||||||
if (const Comdat *C = getELFComdat(GV)) {
|
if (const Comdat *C = getELFComdat(GV)) {
|
||||||
Group = C->getName();
|
Group = C->getName();
|
||||||
Flags |= ELF::SHF_GROUP;
|
Flags |= ELF::SHF_GROUP;
|
||||||
@ -249,97 +244,74 @@ static StringRef getSectionPrefixForGlobal(SectionKind Kind) {
|
|||||||
return ".data.rel.ro";
|
return ".data.rel.ro";
|
||||||
}
|
}
|
||||||
|
|
||||||
static const MCSection *
|
const MCSection *TargetLoweringObjectFileELF::
|
||||||
getUniqueELFSection(MCContext &Ctx, const GlobalValue &GV, SectionKind Kind,
|
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
|
||||||
Mangler &Mang, const TargetMachine &TM, unsigned Flags) {
|
Mangler &Mang, const TargetMachine &TM) const {
|
||||||
StringRef Prefix = getSectionPrefixForGlobal(Kind);
|
unsigned Flags = getELFSectionFlags(Kind);
|
||||||
|
|
||||||
SmallString<128> Name(Prefix);
|
// If we have -ffunction-section or -fdata-section then we should emit the
|
||||||
bool UniqueSectionNames = TM.getUniqueSectionNames();
|
// global value to a uniqued section specifically for it.
|
||||||
if (UniqueSectionNames) {
|
bool EmitUniqueSection = false;
|
||||||
Name.push_back('.');
|
if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) {
|
||||||
TM.getNameWithPrefix(Name, &GV, Mang, true);
|
if (Kind.isText())
|
||||||
|
EmitUniqueSection = TM.getFunctionSections();
|
||||||
|
else
|
||||||
|
EmitUniqueSection = TM.getDataSections();
|
||||||
}
|
}
|
||||||
|
EmitUniqueSection |= GV->hasComdat();
|
||||||
|
|
||||||
|
unsigned EntrySize = 0;
|
||||||
|
if (Kind.isMergeableCString()) {
|
||||||
|
if (Kind.isMergeable2ByteCString()) {
|
||||||
|
EntrySize = 2;
|
||||||
|
} else if (Kind.isMergeable4ByteCString()) {
|
||||||
|
EntrySize = 4;
|
||||||
|
} else {
|
||||||
|
EntrySize = 1;
|
||||||
|
assert(Kind.isMergeable1ByteCString() && "unknown string width");
|
||||||
|
}
|
||||||
|
} else if (Kind.isMergeableConst()) {
|
||||||
|
if (Kind.isMergeableConst4()) {
|
||||||
|
EntrySize = 4;
|
||||||
|
} else if (Kind.isMergeableConst8()) {
|
||||||
|
EntrySize = 8;
|
||||||
|
} else {
|
||||||
|
assert(Kind.isMergeableConst16() && "unknown data width");
|
||||||
|
EntrySize = 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StringRef Group = "";
|
StringRef Group = "";
|
||||||
if (const Comdat *C = getELFComdat(&GV)) {
|
if (const Comdat *C = getELFComdat(GV)) {
|
||||||
Flags |= ELF::SHF_GROUP;
|
Flags |= ELF::SHF_GROUP;
|
||||||
Group = C->getName();
|
Group = C->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags, 0, Group,
|
bool UniqueSectionNames = TM.getUniqueSectionNames();
|
||||||
!UniqueSectionNames);
|
SmallString<128> Name;
|
||||||
}
|
|
||||||
|
|
||||||
const MCSection *TargetLoweringObjectFileELF::
|
|
||||||
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
|
|
||||||
Mangler &Mang, const TargetMachine &TM) const {
|
|
||||||
unsigned Flags = getELFSectionFlags(Kind, GV->hasComdat());
|
|
||||||
|
|
||||||
// If we have -ffunction-section or -fdata-section then we should emit the
|
|
||||||
// global value to a uniqued section specifically for it.
|
|
||||||
bool EmitUniquedSection = false;
|
|
||||||
if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) {
|
|
||||||
if (Kind.isText())
|
|
||||||
EmitUniquedSection = TM.getFunctionSections();
|
|
||||||
else
|
|
||||||
EmitUniquedSection = TM.getDataSections();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EmitUniquedSection || GV->hasComdat())
|
|
||||||
return getUniqueELFSection(getContext(), *GV, Kind, Mang, TM, Flags);
|
|
||||||
|
|
||||||
if (Kind.isText()) return TextSection;
|
|
||||||
|
|
||||||
if (Kind.isMergeableCString()) {
|
if (Kind.isMergeableCString()) {
|
||||||
|
|
||||||
// We also need alignment here.
|
// We also need alignment here.
|
||||||
// FIXME: this is getting the alignment of the character, not the
|
// FIXME: this is getting the alignment of the character, not the
|
||||||
// alignment of the global!
|
// alignment of the global!
|
||||||
unsigned Align =
|
unsigned Align =
|
||||||
TM.getDataLayout()->getPreferredAlignment(cast<GlobalVariable>(GV));
|
TM.getDataLayout()->getPreferredAlignment(cast<GlobalVariable>(GV));
|
||||||
|
|
||||||
unsigned EntrySize = 1;
|
|
||||||
if (Kind.isMergeable2ByteCString())
|
|
||||||
EntrySize = 2;
|
|
||||||
else if (Kind.isMergeable4ByteCString())
|
|
||||||
EntrySize = 4;
|
|
||||||
else
|
|
||||||
assert(Kind.isMergeable1ByteCString() && "unknown string width");
|
|
||||||
|
|
||||||
std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + ".";
|
std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + ".";
|
||||||
std::string Name = SizeSpec + utostr(Align);
|
Name = SizeSpec + utostr(Align);
|
||||||
return getContext().getELFSection(
|
} else if (Kind.isMergeableConst()) {
|
||||||
Name, ELF::SHT_PROGBITS,
|
Name = ".rodata.cst";
|
||||||
ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS, EntrySize, "");
|
Name += utostr(EntrySize);
|
||||||
|
} else {
|
||||||
|
Name = getSectionPrefixForGlobal(Kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Kind.isMergeableConst()) {
|
if (EmitUniqueSection && UniqueSectionNames) {
|
||||||
if (Kind.isMergeableConst4() && MergeableConst4Section)
|
Name.push_back('.');
|
||||||
return MergeableConst4Section;
|
TM.getNameWithPrefix(Name, GV, Mang, true);
|
||||||
if (Kind.isMergeableConst8() && MergeableConst8Section)
|
|
||||||
return MergeableConst8Section;
|
|
||||||
if (Kind.isMergeableConst16() && MergeableConst16Section)
|
|
||||||
return MergeableConst16Section;
|
|
||||||
return ReadOnlySection; // .const
|
|
||||||
}
|
}
|
||||||
|
return getContext().getELFSection(Name, getELFSectionType(Name, Kind), Flags,
|
||||||
if (Kind.isReadOnly()) return ReadOnlySection;
|
EntrySize, Group,
|
||||||
|
EmitUniqueSection && !UniqueSectionNames);
|
||||||
if (Kind.isThreadData()) return TLSDataSection;
|
|
||||||
if (Kind.isThreadBSS()) return TLSBSSSection;
|
|
||||||
|
|
||||||
// Note: we claim that common symbols are put in BSSSection, but they are
|
|
||||||
// really emitted with the magic .comm directive, which creates a symbol table
|
|
||||||
// entry but not a section.
|
|
||||||
if (Kind.isBSS() || Kind.isCommon()) return BSSSection;
|
|
||||||
|
|
||||||
if (Kind.isDataNoRel()) return DataSection;
|
|
||||||
if (Kind.isDataRelLocal()) return DataRelLocalSection;
|
|
||||||
if (Kind.isDataRel()) return DataRelSection;
|
|
||||||
if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
|
|
||||||
|
|
||||||
assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
|
|
||||||
return DataRelROSection;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(
|
const MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(
|
||||||
@ -351,8 +323,7 @@ const MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(
|
|||||||
if (!EmitUniqueSection)
|
if (!EmitUniqueSection)
|
||||||
return ReadOnlySection;
|
return ReadOnlySection;
|
||||||
|
|
||||||
return getUniqueELFSection(getContext(), F, SectionKind::getReadOnly(), Mang,
|
return SelectSectionForGlobal(&F, SectionKind::getReadOnly(), Mang, TM);
|
||||||
TM, ELF::SHF_ALLOC);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection(
|
bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection(
|
||||||
|
@ -41,6 +41,6 @@ bb5:
|
|||||||
$G16 = comdat any
|
$G16 = comdat any
|
||||||
@G16 = unnamed_addr constant i32 42, comdat
|
@G16 = unnamed_addr constant i32 42, comdat
|
||||||
|
|
||||||
; LINUX: .section .rodata.G16,"aG",@progbits,G16,comdat
|
; LINUX: .section .rodata.cst4.G16,"aGM",@progbits,4,G16,comdat
|
||||||
; LINUX-SECTIONS: .section .rodata.G16,"aG",@progbits,G16,comdat
|
; LINUX-SECTIONS: .section .rodata.cst4.G16,"aGM",@progbits,4,G16,comdat
|
||||||
; LINUX-SECTIONS-SHORT: .section .rodata,"aG",@progbits,G16,comdat
|
; LINUX-SECTIONS-SHORT: .section .rodata.cst4,"aGM",@progbits,4,G16,comdat
|
||||||
|
Loading…
Reference in New Issue
Block a user