Changeset View
Changeset View
Standalone View
Standalone View
lib/CodeGen/TargetLoweringObjectFileImpl.cpp
Show First 20 Lines • Show All 205 Lines • ▼ Show 20 Lines | static const Comdat *getELFComdat(const GlobalValue *GV) { | ||||
if (C->getSelectionKind() != Comdat::Any) | if (C->getSelectionKind() != Comdat::Any) | ||||
report_fatal_error("ELF COMDATs only support SelectionKind::Any, '" + | report_fatal_error("ELF COMDATs only support SelectionKind::Any, '" + | ||||
C->getName() + "' cannot be lowered."); | C->getName() + "' cannot be lowered."); | ||||
return C; | return C; | ||||
} | } | ||||
static const MCSymbolELF *getAssociatedSymbol(MDNode *MD, const TargetMachine &TM) { | |||||
auto *VM = dyn_cast<ValueAsMetadata>(MD->getOperand(0)); | |||||
if (!VM) | |||||
report_fatal_error("MD_associated operand is not ValueAsMetadata"); | |||||
GlobalObject *GO = dyn_cast<GlobalObject>(VM->getValue()); | |||||
return dyn_cast<MCSymbolELF>(TM.getSymbol(GO)); | |||||
pcc: What if GO is null? (This could happen if we RAUW the GlobalObject with some other constant.)… | |||||
} | |||||
MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( | MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( | ||||
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { | const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { | ||||
StringRef SectionName = GO->getSection(); | StringRef SectionName = GO->getSection(); | ||||
// Infer section flags from the section name if we can. | // Infer section flags from the section name if we can. | ||||
Kind = getELFKindForNamedSection(SectionName, Kind); | Kind = getELFKindForNamedSection(SectionName, Kind); | ||||
StringRef Group = ""; | StringRef Group = ""; | ||||
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(); | ||||
Flags |= ELF::SHF_GROUP; | Flags |= ELF::SHF_GROUP; | ||||
} | } | ||||
return getContext().getELFSection(SectionName, | |||||
getELFSectionType(SectionName, Kind), Flags, | // A section can have at most one associated section. Put each global with | ||||
/*EntrySize=*/0, Group); | // MD_associated in a unique section. | ||||
unsigned UniqueID = MCContext::GenericSectionID; | |||||
const MCSymbolELF *AssociatedSymbol = nullptr; | |||||
if (MDNode *MD = GO->getMetadata(LLVMContext::MD_associated)) { | |||||
UniqueID = NextUniqueID++; | |||||
Flags |= ELF::SHF_LINK_ORDER; | |||||
AssociatedSymbol = getAssociatedSymbol(MD, TM); | |||||
I think you need to make sure AssociatedSymbol is non-null before setting the flag. Please also add a negative test for a non-GlobalObject constant. pcc: I think you need to make sure AssociatedSymbol is non-null before setting the flag. Please also… | |||||
} | |||||
MCSectionELF *Section = getContext().getELFSection( | |||||
SectionName, getELFSectionType(SectionName, Kind), Flags, | |||||
/*EntrySize=*/0, Group, UniqueID, AssociatedSymbol); | |||||
// Make sure that we did not get some other section with incompatible sh_link. | |||||
// This should not be possible due to UniqueID code above. | |||||
assert(Section->getAssociatedSymbol() == AssociatedSymbol); | |||||
return Section; | |||||
} | } | ||||
/// Return the section prefix name used by options FunctionsSections and | /// Return the section prefix name used by options FunctionsSections and | ||||
/// DataSections. | /// DataSections. | ||||
static StringRef getSectionPrefixForGlobal(SectionKind Kind) { | static StringRef getSectionPrefixForGlobal(SectionKind Kind) { | ||||
if (Kind.isText()) | if (Kind.isText()) | ||||
return ".text"; | return ".text"; | ||||
if (Kind.isReadOnly()) | if (Kind.isReadOnly()) | ||||
return ".rodata"; | return ".rodata"; | ||||
if (Kind.isBSS()) | if (Kind.isBSS()) | ||||
return ".bss"; | return ".bss"; | ||||
if (Kind.isThreadData()) | if (Kind.isThreadData()) | ||||
return ".tdata"; | return ".tdata"; | ||||
if (Kind.isThreadBSS()) | if (Kind.isThreadBSS()) | ||||
return ".tbss"; | return ".tbss"; | ||||
if (Kind.isData()) | if (Kind.isData()) | ||||
return ".data"; | return ".data"; | ||||
assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); | assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); | ||||
return ".data.rel.ro"; | return ".data.rel.ro"; | ||||
} | } | ||||
static MCSectionELF * | static MCSectionELF *selectELFSectionForGlobal( | ||||
selectELFSectionForGlobal(MCContext &Ctx, const GlobalObject *GO, | MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang, | ||||
SectionKind Kind, Mangler &Mang, | const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags, | ||||
const TargetMachine &TM, bool EmitUniqueSection, | unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) { | ||||
unsigned Flags, unsigned *NextUniqueID) { | |||||
unsigned EntrySize = 0; | unsigned EntrySize = 0; | ||||
if (Kind.isMergeableCString()) { | if (Kind.isMergeableCString()) { | ||||
if (Kind.isMergeable2ByteCString()) { | if (Kind.isMergeable2ByteCString()) { | ||||
EntrySize = 2; | EntrySize = 2; | ||||
} else if (Kind.isMergeable4ByteCString()) { | } else if (Kind.isMergeable4ByteCString()) { | ||||
EntrySize = 4; | EntrySize = 4; | ||||
} else { | } else { | ||||
EntrySize = 1; | EntrySize = 1; | ||||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | static MCSectionELF *selectELFSectionForGlobal( | ||||
if (EmitUniqueSection && !UniqueSectionNames) { | if (EmitUniqueSection && !UniqueSectionNames) { | ||||
UniqueID = *NextUniqueID; | UniqueID = *NextUniqueID; | ||||
(*NextUniqueID)++; | (*NextUniqueID)++; | ||||
} | } | ||||
// Use 0 as the unique ID for execute-only text | // Use 0 as the unique ID for execute-only text | ||||
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); | EntrySize, Group, UniqueID, AssociatedSymbol); | ||||
} | } | ||||
MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( | MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( | ||||
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { | const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { | ||||
unsigned Flags = getELFSectionFlags(Kind); | unsigned Flags = getELFSectionFlags(Kind); | ||||
// If we have -ffunction-section or -fdata-section then we should emit the | // If we have -ffunction-section or -fdata-section then we should emit the | ||||
// global value to a uniqued section specifically for it. | // global value to a uniqued section specifically for it. | ||||
bool EmitUniqueSection = false; | bool EmitUniqueSection = false; | ||||
if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) { | if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) { | ||||
if (Kind.isText()) | if (Kind.isText()) | ||||
EmitUniqueSection = TM.getFunctionSections(); | EmitUniqueSection = TM.getFunctionSections(); | ||||
else | else | ||||
EmitUniqueSection = TM.getDataSections(); | EmitUniqueSection = TM.getDataSections(); | ||||
} | } | ||||
EmitUniqueSection |= GO->hasComdat(); | EmitUniqueSection |= GO->hasComdat(); | ||||
return selectELFSectionForGlobal(getContext(), GO, Kind, getMangler(), TM, | const MCSymbolELF *AssociatedSymbol = nullptr; | ||||
EmitUniqueSection, Flags, &NextUniqueID); | if (MDNode *MD = GO->getMetadata(LLVMContext::MD_associated)) { | ||||
EmitUniqueSection = true; | |||||
Flags |= ELF::SHF_LINK_ORDER; | |||||
AssociatedSymbol = getAssociatedSymbol(MD, TM); | |||||
Not Done ReplyInline ActionsSame here. pcc: Same here. | |||||
} | |||||
EmitUniqueSection |= GO->getMetadata(LLVMContext::MD_associated) != nullptr; | |||||
Remove this line. pcc: Remove this line. | |||||
MCSectionELF *Section = selectELFSectionForGlobal( | |||||
getContext(), GO, Kind, getMangler(), TM, EmitUniqueSection, Flags, | |||||
&NextUniqueID, AssociatedSymbol); | |||||
assert(Section->getAssociatedSymbol() == AssociatedSymbol); | |||||
return Section; | |||||
} | } | ||||
MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( | MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( | ||||
const Function &F, const TargetMachine &TM) const { | const Function &F, const TargetMachine &TM) const { | ||||
// If the function can be removed, produce a unique section so that | // If the function can be removed, produce a unique section so that | ||||
// the table doesn't prevent the removal. | // the table doesn't prevent the removal. | ||||
const Comdat *C = F.getComdat(); | const Comdat *C = F.getComdat(); | ||||
bool EmitUniqueSection = TM.getFunctionSections() || C; | bool EmitUniqueSection = TM.getFunctionSections() || C; | ||||
if (!EmitUniqueSection) | if (!EmitUniqueSection) | ||||
return ReadOnlySection; | return ReadOnlySection; | ||||
return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(), | return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(), | ||||
getMangler(), TM, EmitUniqueSection, ELF::SHF_ALLOC, | getMangler(), TM, EmitUniqueSection, | ||||
&NextUniqueID); | ELF::SHF_ALLOC, &NextUniqueID, | ||||
/* AssociatedSymbol */ nullptr); | |||||
} | } | ||||
bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection( | bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection( | ||||
bool UsesLabelDifference, const Function &F) const { | bool UsesLabelDifference, const Function &F) const { | ||||
// We can always create relative relocations, so use another section | // We can always create relative relocations, so use another section | ||||
// that can be marked non-executable. | // that can be marked non-executable. | ||||
return false; | return false; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 794 Lines • Show Last 20 Lines |
What if GO is null? (This could happen if we RAUW the GlobalObject with some other constant.)
I think the right behavior in that case would be to return null from this function.