aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Target/TargetAsmInfo.h165
-rw-r--r--lib/Target/DarwinTargetAsmInfo.cpp18
-rw-r--r--lib/Target/ELFTargetAsmInfo.cpp65
-rw-r--r--lib/Target/TargetAsmInfo.cpp26
-rw-r--r--lib/Target/X86/X86TargetAsmInfo.cpp2
5 files changed, 173 insertions, 103 deletions
diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h
index 59fb8c9..f9105dd 100644
--- a/include/llvm/Target/TargetAsmInfo.h
+++ b/include/llvm/Target/TargetAsmInfo.h
@@ -32,66 +32,131 @@ namespace llvm {
}
/// SectionKind - This is a simple POD value that classifies the properties of
- /// a section.
+ /// a section. A global variable is classified into the deepest possible
+ /// classification, and then the target maps them onto their sections based on
+ /// what capabilities they have.
+ ///
+ /// The comments below describe these as if they were an inheritance hierarchy
+ /// in order to explain the predicates below.
struct SectionKind {
enum Kind {
- Text, ///< Text section.
- BSS, ///< BSS section.
-
- Data, ///< Data section.
- DataRel, ///< Data that has relocations.
- DataRelLocal, ///< Data that only has local relocations.
-
- // Readonly data.
- ROData, ///< Readonly data section.
- DataRelRO, ///< Readonly data with non-local relocations.
- DataRelROLocal, ///< Readonly data with local relocations only.
+ /// Text - Text section, used for functions and other executable code.
+ Text,
+
+ /// ReadOnly - Data that is never written to at program runtime by the
+ /// program or the dynamic linker. Things in the top-level readonly
+ /// SectionKind are not mergable.
+ ReadOnly,
+
+ /// MergableCString - This is a special section for nul-terminated
+ /// strings. The linker can unique the C strings, knowing their
+ /// semantics. Because it uniques based on the nul terminators, the
+ /// compiler can't put strings in this section that have embeded nuls
+ /// in them.
+ MergableCString,
+
+ /// MergableConst - These are sections for merging fixed-length
+ /// constants together. For example, this can be used to unique
+ /// constant pool entries etc.
+ MergableConst,
+
+
+ /// Writable - This is the base of all segments that need to be written
+ /// to during program runtime.
+
+ /// ThreadLocal - This is the base of all TLS segments. All TLS
+ /// objects must be writable, otherwise there is no reason for them to
+ /// be thread local!
+
+ /// ThreadBSS - Zero-initialized TLS data objects.
+ ThreadBSS,
- /// Mergable sections.
- RODataMergeStr, ///< Readonly data section: nul-terminated strings.
- RODataMergeConst, ///< Readonly data section: fixed-length constants.
+ /// ThreadData - Initialized TLS data objects.
+ ThreadData,
+
+ /// GlobalWritableData - Writable data that is global (not thread
+ /// local).
+
+ /// BSS - Zero initialized writable data.
+ BSS,
+
+ /// DataRel - This is the most general form of data that is written
+ /// to by the program, it can have random relocations to arbitrary
+ /// globals.
+ DataRel,
+
+ /// DataRelLocal - This is writable data that has a non-zero
+ /// initializer and has relocations in it, but all of the
+ /// relocations are known to be within the final linked image
+ /// the global is linked into.
+ DataRelLocal,
+
+ /// DataNoRel - This is writable data that has a non-zero
+ /// initializer, but whose initializer is known to have no
+ /// relocations.
+ DataNoRel,
+
+ /// ReadOnlyWithRel - These are global variables that are never
+ /// written to by the program, but that have relocations, so they
+ /// must be stuck in a writable section so that the dynamic linker
+ /// can write to them. If it chooses to, the dynamic linker can
+ /// mark the pages these globals end up on as read-only after it is
+ /// done with its relocation phase.
+ ReadOnlyWithRel,
+
+ /// ReadOnlyWithRelLocal - This is data that is readonly by the
+ /// program, but must be writable so that the dynamic linker
+ /// can perform relocations in it. This is used when we know
+ /// that all the relocations are to globals in this final
+ /// linked image.
+ ReadOnlyWithRelLocal
- /// Thread local data.
- ThreadData, ///< Initialized TLS data objects
- ThreadBSS ///< Uninitialized TLS data objects
} K : 8; // This is private.
- // FIXME: Eliminate.
- Kind getKind() const { return K; }
-
- bool isReadOnly() const {
- return K == ROData || K == RODataMergeConst || K == RODataMergeStr;
+ bool isText() const {
+ return K == Text;
}
- /// isReadOnlyWithDynamicInit - Return true if this data is readonly, but
- /// the dynamic linker has to write to it to apply relocations.
- bool isReadOnlyWithDynamicInit() const {
- return K == DataRelRO || K == DataRelROLocal;
+ bool isReadOnly() const {
+ return K == ReadOnly || K == MergableCString || K == MergableConst;
}
- bool isBSS() const {
- return K == BSS || K == ThreadBSS;
+ bool isMergableCString() const { return K == MergableCString; }
+ bool isMergableConst() const { return K == MergableConst; }
+
+ bool isWritable() const {
+ return isThreadLocal() || isGlobalWritableData();
}
- bool isTLS() const {
+ bool isThreadLocal() const {
return K == ThreadData || K == ThreadBSS;
}
- bool isCode() const {
- return K == Text;
+ bool isThreadBSS() const { return K == ThreadBSS; }
+ bool isThreadData() const { return K == ThreadData; }
+
+ bool isGlobalWritableData() const {
+ return isBSS() || isDataRel() || isReadOnlyWithRel();
}
- bool isWritable() const {
- return isTLS() ||
- K == Data ||
- K == DataRel || K == DataRelLocal ||
- K == DataRelRO || K == DataRelROLocal ||
- K == BSS;
+ bool isBSS() const { return K == BSS; }
+
+ bool isDataRel() const {
+ return K == DataRel || K == DataRelLocal || K == DataNoRel;
}
- bool isMergableString() const { return K == RODataMergeStr; }
- bool isMergableConstant() const {
- return K == RODataMergeStr || K == RODataMergeConst;
+ bool isDataRelLocal() const {
+ return K == DataRelLocal || K == DataNoRel;
+ }
+
+ bool isDataNoRel() const { return K == DataNoRel; }
+
+ bool isReadOnlyWithRel() const {
+ return K == ReadOnlyWithRel || K == ReadOnlyWithRelLocal;
+ }
+
+ bool isReadOnlyWithRelLocal() const {
+ return K == ReadOnlyWithRelLocal;
}
static SectionKind get(Kind K) {
@@ -99,17 +164,19 @@ namespace llvm {
return Res;
}
static SectionKind getText() { return get(Text); }
+ static SectionKind getReadOnly() { return get(ReadOnly); }
+ static SectionKind getMergableCString() { return get(MergableCString); }
+ static SectionKind getMergableConst() { return get(MergableConst); }
+ static SectionKind getThreadBSS() { return get(ThreadBSS); }
+ static SectionKind getThreadData() { return get(ThreadData); }
static SectionKind getBSS() { return get(BSS); }
- static SectionKind getData() { return get(Data); }
static SectionKind getDataRel() { return get(DataRel); }
static SectionKind getDataRelLocal() { return get(DataRelLocal); }
- static SectionKind getROData() { return get(ROData); }
- static SectionKind getDataRelRO() { return get(DataRelRO); }
- static SectionKind getDataRelROLocal() { return get(DataRelROLocal); }
- static SectionKind getRODataMergeStr() { return get(RODataMergeStr); }
- static SectionKind getRODataMergeConst() { return get(RODataMergeConst); }
- static SectionKind getThreadData() { return get(ThreadData); }
- static SectionKind getThreadBSS() { return get(ThreadBSS); }
+ static SectionKind getDataNoRel() { return get(DataNoRel); }
+ static SectionKind getReadOnlyWithRel() { return get(ReadOnlyWithRel); }
+ static SectionKind getReadOnlyWithRelLocal() {
+ return get(ReadOnlyWithRelLocal);
+ }
};
namespace SectionFlags {
diff --git a/lib/Target/DarwinTargetAsmInfo.cpp b/lib/Target/DarwinTargetAsmInfo.cpp
index 1356f67..7321b18 100644
--- a/lib/Target/DarwinTargetAsmInfo.cpp
+++ b/lib/Target/DarwinTargetAsmInfo.cpp
@@ -127,12 +127,12 @@ bool DarwinTargetAsmInfo::emitUsedDirectiveFor(const GlobalValue* GV,
const Section*
DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
SectionKind Kind) const {
- assert(!Kind.isTLS() && "Darwin doesn't support TLS");
+ assert(!Kind.isThreadLocal() && "Darwin doesn't support TLS");
// FIXME: Use sectionflags:linkonce instead of isWeakForLinker() here.
bool isWeak = GV->isWeakForLinker();
- if (Kind.isCode())
+ if (Kind.isText())
return isWeak ? TextCoalSection : TextSection;
// If this is weak/linkonce, put this in a coalescable section, either in text
@@ -144,24 +144,24 @@ DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
}
// FIXME: Alignment check should be handled by section classifier.
- if (Kind.isMergableString())
+ if (Kind.isMergableCString())
return MergeableStringSection(cast<GlobalVariable>(GV));
- if (Kind.isMergableConstant()) {
+ if (Kind.isMergableConst()) {
const Type *Ty = cast<GlobalVariable>(GV)->getInitializer()->getType();
const TargetData *TD = TM.getTargetData();
return getSectionForMergableConstant(TD->getTypeAllocSize(Ty), 0);
}
-
- // If this is marked const, put it into a const section. But if the dynamic
- // linker needs to write to it, put it in the data segment.
- if (Kind.isReadOnlyWithDynamicInit())
- return ConstDataSection;
// FIXME: ROData -> const in -static mode that is relocatable but they happen
// by the static linker. Why not mergable?
if (Kind.isReadOnly())
return getReadOnlySection();
+
+ // If this is marked const, put it into a const section. But if the dynamic
+ // linker needs to write to it, put it in the data segment.
+ if (Kind.isReadOnlyWithRel())
+ return ConstDataSection;
// Otherwise, just drop the variable in the normal data section.
return DataSection;
diff --git a/lib/Target/ELFTargetAsmInfo.cpp b/lib/Target/ELFTargetAsmInfo.cpp
index 880dfbc..c401109 100644
--- a/lib/Target/ELFTargetAsmInfo.cpp
+++ b/lib/Target/ELFTargetAsmInfo.cpp
@@ -49,28 +49,30 @@ ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM)
const Section*
ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
SectionKind Kind) const {
- switch (Kind.getKind()) {
- default: llvm_unreachable("Unknown section kind");
- case SectionKind::Text: return TextSection;
- case SectionKind::BSS: return getBSSSection_();
- case SectionKind::Data: return DataSection;
- case SectionKind::DataRel: return DataRelSection;
- case SectionKind::DataRelLocal: return DataRelLocalSection;
- case SectionKind::DataRelRO: return DataRelROSection;
- case SectionKind::DataRelROLocal: return DataRelROLocalSection;
- case SectionKind::ROData: return getReadOnlySection();
- case SectionKind::RODataMergeStr:
+ if (Kind.isText()) return TextSection;
+ if (Kind.isMergableCString())
return MergeableStringSection(cast<GlobalVariable>(GV));
- case SectionKind::RODataMergeConst: {
+ if (Kind.isMergableConst()) {
const Type *Ty = cast<GlobalVariable>(GV)->getInitializer()->getType();
const TargetData *TD = TM.getTargetData();
return getSectionForMergableConstant(TD->getTypeAllocSize(Ty), 0);
}
- case SectionKind::ThreadData:
- return TLSDataSection;
- case SectionKind::ThreadBSS:
- return TLSBSSSection;
- }
+ if (Kind.isReadOnly()) return getReadOnlySection();
+
+
+ if (Kind.isThreadData()) return TLSDataSection;
+ if (Kind.isThreadBSS()) return TLSBSSSection;
+
+ if (Kind.isBSS()) return getBSSSection_();
+
+
+ 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;
}
/// getSectionForMergableConstant - Given a mergable constant with the
@@ -129,21 +131,20 @@ unsigned ELFTargetAsmInfo::getFlagsForNamedSection(const char *Name) const {
const char *
ELFTargetAsmInfo::getSectionPrefixForUniqueGlobal(SectionKind Kind) const{
- switch (Kind.getKind()) {
- 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.";
- }
+ if (Kind.isText()) return ".gnu.linkonce.t.";
+ if (Kind.isReadOnly()) return ".gnu.linkonce.r.";
+
+ if (Kind.isThreadData()) return ".gnu.linkonce.td.";
+ if (Kind.isThreadBSS()) return ".gnu.linkonce.tb.";
+
+ if (Kind.isBSS()) return ".gnu.linkonce.b.";
+ if (Kind.isDataNoRel()) return ".gnu.linkonce.d.";
+ if (Kind.isDataRelLocal()) return ".gnu.linkonce.d.rel.local.";
+ if (Kind.isDataRel()) return ".gnu.linkonce.d.rel.";
+ if (Kind.isReadOnlyWithRelLocal()) return ".gnu.linkonce.d.rel.ro.local.";
+
+ assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
+ return ".gnu.linkonce.d.rel.ro.";
}
diff --git a/lib/Target/TargetAsmInfo.cpp b/lib/Target/TargetAsmInfo.cpp
index c3fb942..02e01be 100644
--- a/lib/Target/TargetAsmInfo.cpp
+++ b/lib/Target/TargetAsmInfo.cpp
@@ -204,11 +204,11 @@ static unsigned SectionFlagsForGlobal(const GlobalValue *GV,
unsigned Flags = SectionFlags::None;
if (GV->isWeakForLinker())
Flags |= SectionFlags::Linkonce;
- if (Kind.isBSS())
+ if (Kind.isBSS() || Kind.isThreadBSS())
Flags |= SectionFlags::BSS;
- if (Kind.isTLS())
+ if (Kind.isThreadLocal())
Flags |= SectionFlags::TLS;
- if (Kind.isCode())
+ if (Kind.isText())
Flags |= SectionFlags::Code;
if (Kind.isWritable())
Flags |= SectionFlags::Writable;
@@ -247,32 +247,32 @@ static SectionKind SectionKindForGlobal(const GlobalValue *GV,
// If initializer is a null-terminated string, put it in a "cstring"
// section if the target has it.
if (isConstantString(C))
- return SectionKind::getRODataMergeStr();
+ return SectionKind::getMergableCString();
// Otherwise, just drop it into a mergable constant section.
- return SectionKind::getRODataMergeConst();
+ return SectionKind::getMergableConst();
case Constant::LocalRelocation:
// In static relocation model, the linker will resolve all addresses, so
// the relocation entries will actually be constants by the time the app
// starts up.
if (ReloModel == Reloc::Static)
- return SectionKind::getROData();
+ return SectionKind::getReadOnly();
// Otherwise, the dynamic linker needs to fix it up, put it in the
// writable data.rel.local section.
- return SectionKind::getDataRelROLocal();
+ return SectionKind::getReadOnlyWithRelLocal();
case Constant::GlobalRelocations:
// In static relocation model, the linker will resolve all addresses, so
// the relocation entries will actually be constants by the time the app
// starts up.
if (ReloModel == Reloc::Static)
- return SectionKind::getROData();
+ return SectionKind::getReadOnly();
// Otherwise, the dynamic linker needs to fix it up, put it in the
// writable data.rel section.
- return SectionKind::getDataRelRO();
+ return SectionKind::getReadOnlyWithRel();
}
}
@@ -282,11 +282,11 @@ static SectionKind SectionKindForGlobal(const GlobalValue *GV,
// globals together onto fewer pages, improving the locality of the dynamic
// linker.
if (ReloModel == Reloc::Static)
- return SectionKind::getData();
+ return SectionKind::getDataNoRel();
switch (C->getRelocationInfo()) {
default: llvm_unreachable("unknown relocation info kind");
- case Constant::NoRelocation: return SectionKind::getData();
+ case Constant::NoRelocation: return SectionKind::getDataNoRel();
case Constant::LocalRelocation: return SectionKind::getDataRelLocal();
case Constant::GlobalRelocations: return SectionKind::getDataRel();
}
@@ -342,7 +342,9 @@ const Section *TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
const Section*
TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
SectionKind Kind) const {
- if (Kind.isCode())
+ assert(!Kind.isThreadLocal() && "Doesn't support TLS");
+
+ if (Kind.isText())
return getTextSection();
if (Kind.isBSS())
diff --git a/lib/Target/X86/X86TargetAsmInfo.cpp b/lib/Target/X86/X86TargetAsmInfo.cpp
index 39dfb00..9e7973a 100644
--- a/lib/Target/X86/X86TargetAsmInfo.cpp
+++ b/lib/Target/X86/X86TargetAsmInfo.cpp
@@ -267,7 +267,7 @@ X86COFFTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
const char *X86COFFTargetAsmInfo::
getSectionPrefixForUniqueGlobal(SectionKind Kind) const {
- if (Kind.isCode())
+ if (Kind.isText())
return ".text$linkonce";
if (Kind.isWritable())
return ".data$linkonce";