forked from OSchip/llvm-project
this is (unfortunately) several changes mixed together:
1. Spell SectionFlags::Writeable as "Writable". 2. Add predicates for deriving SectionFlags from SectionKinds. 3. Sink ELF-specific getSectionPrefixForUniqueGlobal impl into ELFTargetAsmInfo. 4. Fix SectionFlagsForGlobal to know that BSS/ThreadBSS has the BSS bit set (the real fix for PR4619). 5. Fix isSuitableForBSS to not put globals with explicit sections set in BSS (which was the reason #4 wasn't fixed earlier). 6. Remove my previous hack for PR4619. llvm-svn: 77085
This commit is contained in:
parent
7b5e51091e
commit
60f3b73e11
|
@ -43,12 +43,6 @@ namespace llvm {
|
|||
virtual const Section *
|
||||
getSectionForMergableConstant(uint64_t Size, unsigned ReloInfo) const;
|
||||
|
||||
virtual const char *
|
||||
getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const {
|
||||
// Darwin doesn't use uniqued sections for weak symbols.
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
const Section* MergeableStringSection(const GlobalVariable *GV) const;
|
||||
};
|
||||
|
|
|
@ -37,6 +37,8 @@ namespace llvm {
|
|||
/// ".tbss" gets the TLS bit set etc.
|
||||
virtual unsigned getFlagsForNamedSection(const char *Section) const;
|
||||
|
||||
const char *getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const;
|
||||
|
||||
virtual const Section* SelectSectionForGlobal(const GlobalValue *GV,
|
||||
SectionKind::Kind Kind) const;
|
||||
virtual std::string printSectionFlags(unsigned flags) const;
|
||||
|
|
|
@ -62,13 +62,35 @@ namespace llvm {
|
|||
K == SectionKind::RODataMergeConst ||
|
||||
K == SectionKind::RODataMergeStr);
|
||||
}
|
||||
|
||||
static inline bool isBSS(Kind K) {
|
||||
return K == BSS || K == ThreadBSS;
|
||||
}
|
||||
|
||||
static inline bool isTLS(Kind K) {
|
||||
return K == ThreadData || K == ThreadBSS;
|
||||
}
|
||||
|
||||
static inline bool isCode(Kind K) {
|
||||
return K == Text;
|
||||
}
|
||||
|
||||
static inline bool isWritable(Kind K) {
|
||||
return isTLS(K) ||
|
||||
K == SectionKind::Data ||
|
||||
K == SectionKind::DataRel ||
|
||||
K == SectionKind::DataRelLocal ||
|
||||
K == SectionKind::DataRelRO ||
|
||||
K == SectionKind::DataRelROLocal ||
|
||||
K == SectionKind::BSS;
|
||||
}
|
||||
}
|
||||
|
||||
namespace SectionFlags {
|
||||
const unsigned Invalid = -1U;
|
||||
const unsigned None = 0;
|
||||
const unsigned Code = 1 << 0; ///< Section contains code
|
||||
const unsigned Writeable = 1 << 1; ///< Section is writeable
|
||||
const unsigned Writable = 1 << 1; ///< Section is writable
|
||||
const unsigned BSS = 1 << 2; ///< Section contains only zeroes
|
||||
const unsigned Mergeable = 1 << 3; ///< Section contains mergeable data
|
||||
const unsigned Strings = 1 << 4; ///< Section contains C-type strings
|
||||
|
@ -582,7 +604,9 @@ namespace llvm {
|
|||
/// global. This is important for globals that need to be merged across
|
||||
/// translation units.
|
||||
virtual const char *
|
||||
getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const;
|
||||
getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// getFlagsForNamedSection - If this target wants to be able to infer
|
||||
/// section flags based on the name of the section specified for a global
|
||||
|
|
|
@ -222,7 +222,7 @@ unsigned ELFWriter::getElfSectionFlags(unsigned Flags) {
|
|||
|
||||
if (Flags & SectionFlags::Code)
|
||||
ElfSectionFlags |= ELFSection::SHF_EXECINSTR;
|
||||
if (Flags & SectionFlags::Writeable)
|
||||
if (Flags & SectionFlags::Writable)
|
||||
ElfSectionFlags |= ELFSection::SHF_WRITE;
|
||||
if (Flags & SectionFlags::Mergeable)
|
||||
ElfSectionFlags |= ELFSection::SHF_MERGE;
|
||||
|
|
|
@ -36,7 +36,7 @@ SPULinuxTargetAsmInfo::SPULinuxTargetAsmInfo(const SPUTargetMachine &TM) :
|
|||
// BSS section needs to be emitted as ".section"
|
||||
BSSSection = "\t.section\t.bss";
|
||||
BSSSection_ = getUnnamedSection("\t.section\t.bss",
|
||||
SectionFlags::Writeable | SectionFlags::BSS,
|
||||
SectionFlags::Writable | SectionFlags::BSS,
|
||||
true);
|
||||
|
||||
SupportsDebugInformation = true;
|
||||
|
|
|
@ -50,7 +50,7 @@ DarwinTargetAsmInfo::DarwinTargetAsmInfo(const TargetMachine &TM)
|
|||
SectionFlags::None);
|
||||
ConstDataSection = getUnnamedSection(".const_data", SectionFlags::None);
|
||||
DataCoalSection = getNamedSection("\t__DATA,__datacoal_nt,coalesced",
|
||||
SectionFlags::Writeable);
|
||||
SectionFlags::Writable);
|
||||
|
||||
|
||||
// Common settings for all Darwin targets.
|
||||
|
@ -127,6 +127,7 @@ bool DarwinTargetAsmInfo::emitUsedDirectiveFor(const GlobalValue* GV,
|
|||
const Section*
|
||||
DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
|
||||
SectionKind::Kind Kind) const {
|
||||
// FIXME: Use sectionflags:linkonce instead of isWeakForLinker() here.
|
||||
bool isWeak = GV->isWeakForLinker();
|
||||
bool isNonStatic = TM.getRelocationModel() != Reloc::Static;
|
||||
|
||||
|
|
|
@ -29,20 +29,20 @@ ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM)
|
|||
: TargetAsmInfo(TM) {
|
||||
|
||||
BSSSection_ = getUnnamedSection("\t.bss",
|
||||
SectionFlags::Writeable | SectionFlags::BSS);
|
||||
SectionFlags::Writable | SectionFlags::BSS);
|
||||
ReadOnlySection = getNamedSection("\t.rodata", SectionFlags::None);
|
||||
TLSDataSection = getNamedSection("\t.tdata",
|
||||
SectionFlags::Writeable | SectionFlags::TLS);
|
||||
SectionFlags::Writable | SectionFlags::TLS);
|
||||
TLSBSSSection = getNamedSection("\t.tbss",
|
||||
SectionFlags::Writeable | SectionFlags::TLS | SectionFlags::BSS);
|
||||
SectionFlags::Writable | SectionFlags::TLS | SectionFlags::BSS);
|
||||
|
||||
DataRelSection = getNamedSection("\t.data.rel", SectionFlags::Writeable);
|
||||
DataRelSection = getNamedSection("\t.data.rel", SectionFlags::Writable);
|
||||
DataRelLocalSection = getNamedSection("\t.data.rel.local",
|
||||
SectionFlags::Writeable);
|
||||
SectionFlags::Writable);
|
||||
DataRelROSection = getNamedSection("\t.data.rel.ro",
|
||||
SectionFlags::Writeable);
|
||||
SectionFlags::Writable);
|
||||
DataRelROLocalSection = getNamedSection("\t.data.rel.ro.local",
|
||||
SectionFlags::Writeable);
|
||||
SectionFlags::Writable);
|
||||
}
|
||||
|
||||
|
||||
|
@ -145,6 +145,28 @@ unsigned ELFTargetAsmInfo::getFlagsForNamedSection(const char *Name) const {
|
|||
}
|
||||
|
||||
|
||||
|
||||
const char *
|
||||
ELFTargetAsmInfo::getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const{
|
||||
switch (Kind) {
|
||||
default: llvm_unreachable("Unknown section kind");
|
||||
case SectionKind::Text: return ".gnu.linkonce.t.";
|
||||
case SectionKind::Data: return ".gnu.linkonce.d.";
|
||||
case SectionKind::DataRel: return ".gnu.linkonce.d.rel.";
|
||||
case SectionKind::DataRelLocal: return ".gnu.linkonce.d.rel.local.";
|
||||
case SectionKind::DataRelRO: return ".gnu.linkonce.d.rel.ro.";
|
||||
case SectionKind::DataRelROLocal: return ".gnu.linkonce.d.rel.ro.local.";
|
||||
case SectionKind::BSS: return ".gnu.linkonce.b.";
|
||||
case SectionKind::ROData:
|
||||
case SectionKind::RODataMergeConst:
|
||||
case SectionKind::RODataMergeStr: return ".gnu.linkonce.r.";
|
||||
case SectionKind::ThreadData: return ".gnu.linkonce.td.";
|
||||
case SectionKind::ThreadBSS: return ".gnu.linkonce.tb.";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const Section*
|
||||
ELFTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const {
|
||||
const TargetData *TD = TM.getTargetData();
|
||||
|
@ -177,7 +199,7 @@ std::string ELFTargetAsmInfo::printSectionFlags(unsigned flags) const {
|
|||
Flags += 'a';
|
||||
if (flags & SectionFlags::Code)
|
||||
Flags += 'x';
|
||||
if (flags & SectionFlags::Writeable)
|
||||
if (flags & SectionFlags::Writable)
|
||||
Flags += 'w';
|
||||
if (flags & SectionFlags::Mergeable)
|
||||
Flags += 'M';
|
||||
|
|
|
@ -292,7 +292,7 @@ void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
|
|||
const char *SectionName = PAN::getFrameSectionName(CurrentFnName).c_str();
|
||||
|
||||
const Section *fPDataSection = TAI->getNamedSection(SectionName,
|
||||
SectionFlags::Writeable);
|
||||
SectionFlags::Writable);
|
||||
SwitchToSection(fPDataSection);
|
||||
|
||||
// Emit function frame label
|
||||
|
|
|
@ -38,9 +38,9 @@ PIC16TargetAsmInfo(const PIC16TargetMachine &TM)
|
|||
AsciiDirective = " dt ";
|
||||
AscizDirective = NULL;
|
||||
BSSSection_ = getNamedSection("udata.# UDATA",
|
||||
SectionFlags::Writeable | SectionFlags::BSS);
|
||||
SectionFlags::Writable | SectionFlags::BSS);
|
||||
ReadOnlySection = getNamedSection("romdata.# ROMDATA", SectionFlags::None);
|
||||
DataSection = getNamedSection("idata.# IDATA", SectionFlags::Writeable);
|
||||
DataSection = getNamedSection("idata.# IDATA", SectionFlags::Writable);
|
||||
SwitchToSectionDirective = "";
|
||||
// Need because otherwise a .text symbol is emitted by DwarfWriter
|
||||
// in BeginModule, and gpasm cribbs for that .text symbol.
|
||||
|
|
|
@ -75,7 +75,7 @@ PPCLinuxTargetAsmInfo::PPCLinuxTargetAsmInfo(const PPCTargetMachine &TM) :
|
|||
|
||||
// PPC/Linux normally uses named section for BSS.
|
||||
BSSSection_ = getNamedSection("\t.bss",
|
||||
SectionFlags::Writeable | SectionFlags::BSS,
|
||||
SectionFlags::Writable | SectionFlags::BSS,
|
||||
/* Override */ true);
|
||||
|
||||
// Debug Information
|
||||
|
|
|
@ -28,7 +28,7 @@ SparcELFTargetAsmInfo::SparcELFTargetAsmInfo(const TargetMachine &TM):
|
|||
|
||||
// Sparc normally uses named section for BSS.
|
||||
BSSSection_ = getNamedSection("\t.bss",
|
||||
SectionFlags::Writeable | SectionFlags::BSS,
|
||||
SectionFlags::Writable | SectionFlags::BSS,
|
||||
/* Override */ true);
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ std::string SparcELFTargetAsmInfo::printSectionFlags(unsigned flags) const {
|
|||
Flags += ",#alloc";
|
||||
if (flags & SectionFlags::Code)
|
||||
Flags += ",#execinstr";
|
||||
if (flags & SectionFlags::Writeable)
|
||||
if (flags & SectionFlags::Writable)
|
||||
Flags += ",#write";
|
||||
if (flags & SectionFlags::TLS)
|
||||
Flags += ",#tls";
|
||||
|
|
|
@ -122,7 +122,7 @@ TargetAsmInfo::TargetAsmInfo(const TargetMachine &tm) : TM(tm) {
|
|||
DwarfExceptionSection = ".gcc_except_table";
|
||||
AsmTransCBE = 0;
|
||||
TextSection = getUnnamedSection("\t.text", SectionFlags::Code);
|
||||
DataSection = getUnnamedSection("\t.data", SectionFlags::Writeable);
|
||||
DataSection = getUnnamedSection("\t.data", SectionFlags::Writable);
|
||||
}
|
||||
|
||||
TargetAsmInfo::~TargetAsmInfo() {
|
||||
|
@ -160,9 +160,22 @@ unsigned TargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
|
|||
}
|
||||
|
||||
static bool isSuitableForBSS(const GlobalVariable *GV) {
|
||||
// Leave constant zeros in readonly constant sections, so they can be shared
|
||||
Constant *C = GV->getInitializer();
|
||||
return (C->isNullValue() && !GV->isConstant() && !NoZerosInBSS);
|
||||
|
||||
// Must have zero initializer.
|
||||
if (!C->isNullValue())
|
||||
return false;
|
||||
|
||||
// Leave constant zeros in readonly constant sections, so they can be shared.
|
||||
if (GV->isConstant())
|
||||
return false;
|
||||
|
||||
// If the global has an explicit section specified, don't put it in BSS.
|
||||
if (!GV->getSection().empty())
|
||||
return false;
|
||||
|
||||
// Otherwise, put it in BSS unless the target really doesn't want us to.
|
||||
return !NoZerosInBSS;
|
||||
}
|
||||
|
||||
static bool isConstantString(const Constant *C) {
|
||||
|
@ -183,36 +196,18 @@ static bool isConstantString(const Constant *C) {
|
|||
|
||||
static unsigned SectionFlagsForGlobal(const GlobalValue *GV,
|
||||
SectionKind::Kind Kind) {
|
||||
// Decode flags from global and section kind.
|
||||
unsigned Flags = SectionFlags::None;
|
||||
|
||||
// Decode flags from global itself.
|
||||
switch (Kind) {
|
||||
case SectionKind::Text:
|
||||
Flags |= SectionFlags::Code;
|
||||
break;
|
||||
case SectionKind::ThreadData:
|
||||
case SectionKind::ThreadBSS:
|
||||
Flags |= SectionFlags::TLS;
|
||||
// FALLS THROUGH
|
||||
case SectionKind::Data:
|
||||
case SectionKind::DataRel:
|
||||
case SectionKind::DataRelLocal:
|
||||
case SectionKind::DataRelRO:
|
||||
case SectionKind::DataRelROLocal:
|
||||
case SectionKind::BSS:
|
||||
Flags |= SectionFlags::Writeable;
|
||||
break;
|
||||
case SectionKind::ROData:
|
||||
case SectionKind::RODataMergeStr:
|
||||
case SectionKind::RODataMergeConst:
|
||||
// No additional flags here
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unexpected section kind!");
|
||||
}
|
||||
|
||||
if (GV->isWeakForLinker())
|
||||
Flags |= SectionFlags::Linkonce;
|
||||
if (SectionKind::isBSS(Kind))
|
||||
Flags |= SectionFlags::BSS;
|
||||
if (SectionKind::isTLS(Kind))
|
||||
Flags |= SectionFlags::TLS;
|
||||
if (SectionKind::isCode(Kind))
|
||||
Flags |= SectionFlags::Code;
|
||||
if (SectionKind::isWritable(Kind))
|
||||
Flags |= SectionFlags::Writable;
|
||||
|
||||
return Flags;
|
||||
}
|
||||
|
@ -331,11 +326,6 @@ const Section *TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
|
|||
|
||||
// FIXME: Use mangler interface (PR4584).
|
||||
std::string Name = Prefix+GV->getNameStr();
|
||||
|
||||
// Pick up the flags for the uniquing section.
|
||||
// FIXME: HACK.
|
||||
Flags |= getFlagsForNamedSection(Name.c_str());
|
||||
|
||||
return getNamedSection(Name.c_str(), Flags);
|
||||
}
|
||||
}
|
||||
|
@ -348,10 +338,10 @@ const Section *TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
|
|||
const Section*
|
||||
TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
|
||||
SectionKind::Kind Kind) const {
|
||||
if (Kind == SectionKind::Text)
|
||||
if (SectionKind::isCode(Kind))
|
||||
return getTextSection();
|
||||
|
||||
if (Kind == SectionKind::BSS)
|
||||
if (SectionKind::isBSS(SectionKind::BSS))
|
||||
if (const Section *S = getBSSSection_())
|
||||
return S;
|
||||
|
||||
|
@ -374,27 +364,6 @@ TargetAsmInfo::getSectionForMergableConstant(uint64_t Size,
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const char *
|
||||
TargetAsmInfo::getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const {
|
||||
switch (Kind) {
|
||||
default: llvm_unreachable("Unknown section kind");
|
||||
case SectionKind::Text: return ".gnu.linkonce.t.";
|
||||
case SectionKind::Data: return ".gnu.linkonce.d.";
|
||||
case SectionKind::DataRel: return ".gnu.linkonce.d.rel.";
|
||||
case SectionKind::DataRelLocal: return ".gnu.linkonce.d.rel.local.";
|
||||
case SectionKind::DataRelRO: return ".gnu.linkonce.d.rel.ro.";
|
||||
case SectionKind::DataRelROLocal: return ".gnu.linkonce.d.rel.ro.local.";
|
||||
case SectionKind::BSS: return ".gnu.linkonce.b.";
|
||||
case SectionKind::ROData:
|
||||
case SectionKind::RODataMergeConst:
|
||||
case SectionKind::RODataMergeStr: return ".gnu.linkonce.r.";
|
||||
case SectionKind::ThreadData: return ".gnu.linkonce.td.";
|
||||
case SectionKind::ThreadBSS: return ".gnu.linkonce.tb.";
|
||||
}
|
||||
}
|
||||
|
||||
const Section *TargetAsmInfo::getNamedSection(const char *Name, unsigned Flags,
|
||||
bool Override) const {
|
||||
Section &S = Sections[Name];
|
||||
|
|
|
@ -282,7 +282,6 @@ getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const {
|
|||
case SectionKind::RODataMergeConst:
|
||||
case SectionKind::RODataMergeStr: return ".rdata$linkonce";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::string X86COFFTargetAsmInfo::printSectionFlags(unsigned flags) const {
|
||||
|
@ -290,7 +289,7 @@ std::string X86COFFTargetAsmInfo::printSectionFlags(unsigned flags) const {
|
|||
|
||||
if (flags & SectionFlags::Code)
|
||||
Flags += 'x';
|
||||
if (flags & SectionFlags::Writeable)
|
||||
if (flags & SectionFlags::Writable)
|
||||
Flags += 'w';
|
||||
|
||||
Flags += "\"";
|
||||
|
@ -322,7 +321,7 @@ X86WinTargetAsmInfo::X86WinTargetAsmInfo(const X86TargetMachine &TM):
|
|||
AlignmentIsInBytes = true;
|
||||
|
||||
TextSection = getUnnamedSection("_text", SectionFlags::Code);
|
||||
DataSection = getUnnamedSection("_data", SectionFlags::Writeable);
|
||||
DataSection = getUnnamedSection("_data", SectionFlags::Writable);
|
||||
|
||||
JumpTableDataSection = NULL;
|
||||
SwitchToSectionDirective = "";
|
||||
|
|
|
@ -25,8 +25,8 @@ XCoreTargetAsmInfo::XCoreTargetAsmInfo(const XCoreTargetMachine &TM)
|
|||
: ELFTargetAsmInfo(TM) {
|
||||
SupportsDebugInformation = true;
|
||||
TextSection = getUnnamedSection("\t.text", SectionFlags::Code);
|
||||
DataSection = getNamedSection("\t.dp.data", SectionFlags::Writeable);
|
||||
BSSSection_ = getNamedSection("\t.dp.bss", SectionFlags::Writeable |
|
||||
DataSection = getNamedSection("\t.dp.data", SectionFlags::Writable);
|
||||
BSSSection_ = getNamedSection("\t.dp.bss", SectionFlags::Writable |
|
||||
SectionFlags::BSS);
|
||||
|
||||
// TLS globals are lowered in the backend to arrays indexed by the current
|
||||
|
@ -36,7 +36,7 @@ XCoreTargetAsmInfo::XCoreTargetAsmInfo(const XCoreTargetMachine &TM)
|
|||
TLSBSSSection = BSSSection_;
|
||||
|
||||
if (TM.getSubtargetImpl()->isXS1A())
|
||||
ReadOnlySection = getNamedSection("\t.dp.rodata", SectionFlags::Writeable);
|
||||
ReadOnlySection = getNamedSection("\t.dp.rodata", SectionFlags::Writable);
|
||||
else
|
||||
ReadOnlySection = getNamedSection("\t.cp.rodata", SectionFlags::None);
|
||||
Data16bitsDirective = "\t.short\t";
|
||||
|
|
Loading…
Reference in New Issue