mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2026-07-19 23:24:47 -04:00
ELF: Create unique SHF_GNU_RETAIN sections for llvm.used global objects
If a global object is listed in `@llvm.used`, place it in a unique section with the `SHF_GNU_RETAIN` flag. The section is a GC root under `ld --gc-sections` with LLD>=13 or GNU ld>=2.36. For front ends which do not expect to see multiple sections of the same name, consider emitting `@llvm.compiler.used` instead of `@llvm.used`. SHF_GNU_RETAIN is restricted to ELFOSABI_GNU and ELFOSABI_FREEBSD in binutils. We don't do the restriction - see the rationale in D95749. The integrated assembler has supported SHF_GNU_RETAIN since D95730. GNU as>=2.36 supports section flag 'R'. We don't need to worry about GNU ld support because older GNU ld just ignores the unknown SHF_GNU_RETAIN. With this change, `__attribute__((retain))` functions/variables emitted by clang will get the SHF_GNU_RETAIN flag. Differential Revision: https://reviews.llvm.org/D97448
This commit is contained in:
@@ -293,6 +293,14 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
|
||||
}
|
||||
}
|
||||
|
||||
void TargetLoweringObjectFileELF::getModuleMetadata(Module &M) {
|
||||
SmallVector<GlobalValue *, 4> Vec;
|
||||
collectUsedGlobalVariables(M, Vec, false);
|
||||
for (GlobalValue *GV : Vec)
|
||||
if (auto *GO = dyn_cast<GlobalObject>(GV))
|
||||
Used.insert(GO);
|
||||
}
|
||||
|
||||
void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer,
|
||||
Module &M) const {
|
||||
auto &C = getContext();
|
||||
@@ -687,9 +695,15 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
|
||||
// MD_associated in a unique section.
|
||||
unsigned UniqueID = MCContext::GenericSectionID;
|
||||
const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM);
|
||||
if (GO->getMetadata(LLVMContext::MD_associated)) {
|
||||
const bool Associated = GO->getMetadata(LLVMContext::MD_associated);
|
||||
const bool Retain = Used.count(GO);
|
||||
if (Associated || Retain) {
|
||||
UniqueID = NextUniqueID++;
|
||||
Flags |= ELF::SHF_LINK_ORDER;
|
||||
if (Associated)
|
||||
Flags |= ELF::SHF_LINK_ORDER;
|
||||
if (Retain && (getContext().getAsmInfo()->useIntegratedAssembler() ||
|
||||
getContext().getAsmInfo()->binutilsIsAtLeast(2, 36)))
|
||||
Flags |= ELF::SHF_GNU_RETAIN;
|
||||
} else {
|
||||
if (getContext().getAsmInfo()->useIntegratedAssembler() ||
|
||||
getContext().getAsmInfo()->binutilsIsAtLeast(2, 35)) {
|
||||
@@ -802,13 +816,18 @@ static MCSectionELF *selectELFSectionForGlobal(
|
||||
|
||||
static MCSection *selectELFSectionForGlobal(
|
||||
MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang,
|
||||
const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags,
|
||||
unsigned *NextUniqueID) {
|
||||
const TargetMachine &TM, bool Retain, bool EmitUniqueSection,
|
||||
unsigned Flags, unsigned *NextUniqueID) {
|
||||
const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM);
|
||||
if (LinkedToSym) {
|
||||
EmitUniqueSection = true;
|
||||
Flags |= ELF::SHF_LINK_ORDER;
|
||||
}
|
||||
if (Retain && (Ctx.getAsmInfo()->useIntegratedAssembler() ||
|
||||
Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36))) {
|
||||
EmitUniqueSection = true;
|
||||
Flags |= ELF::SHF_GNU_RETAIN;
|
||||
}
|
||||
|
||||
MCSectionELF *Section = selectELFSectionForGlobal(
|
||||
Ctx, GO, Kind, Mang, TM, EmitUniqueSection, Flags,
|
||||
@@ -832,16 +851,17 @@ MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal(
|
||||
}
|
||||
EmitUniqueSection |= GO->hasComdat();
|
||||
return selectELFSectionForGlobal(getContext(), GO, Kind, getMangler(), TM,
|
||||
EmitUniqueSection, Flags, &NextUniqueID);
|
||||
Used.count(GO), EmitUniqueSection, Flags,
|
||||
&NextUniqueID);
|
||||
}
|
||||
|
||||
MCSection *TargetLoweringObjectFileELF::getUniqueSectionForFunction(
|
||||
const Function &F, const TargetMachine &TM) const {
|
||||
SectionKind Kind = SectionKind::getText();
|
||||
unsigned Flags = getELFSectionFlags(Kind);
|
||||
return selectELFSectionForGlobal(getContext(), &F, Kind, getMangler(), TM,
|
||||
/* EmitUniqueSection = */ true, Flags,
|
||||
&NextUniqueID);
|
||||
return selectELFSectionForGlobal(
|
||||
getContext(), &F, Kind, getMangler(), TM, Used.count(&F),
|
||||
/*EmitUniqueSection=*/true, Flags, &NextUniqueID);
|
||||
}
|
||||
|
||||
MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(
|
||||
|
||||
Reference in New Issue
Block a user