summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/lib/Target/Mips/MipsTargetObjectFile.cpp
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2018-04-06 14:26:03 +0000
committerpatrick <patrick@openbsd.org>2018-04-06 14:26:03 +0000
commitbdabc2f19ffb9e20600dad6e8a300842a7bda50e (patch)
treec50e7b2e5449b074651bb82a58517a8ebc4a8cf7 /gnu/llvm/lib/Target/Mips/MipsTargetObjectFile.cpp
parentPrint a 'p' flag for file descriptors that were opened after pledge(2). (diff)
downloadwireguard-openbsd-bdabc2f19ffb9e20600dad6e8a300842a7bda50e.tar.xz
wireguard-openbsd-bdabc2f19ffb9e20600dad6e8a300842a7bda50e.zip
Import LLVM 6.0.1 release including clang, lld and lldb.
"where is the kaboom?" deraadt@
Diffstat (limited to 'gnu/llvm/lib/Target/Mips/MipsTargetObjectFile.cpp')
-rw-r--r--gnu/llvm/lib/Target/Mips/MipsTargetObjectFile.cpp40
1 files changed, 38 insertions, 2 deletions
diff --git a/gnu/llvm/lib/Target/Mips/MipsTargetObjectFile.cpp b/gnu/llvm/lib/Target/Mips/MipsTargetObjectFile.cpp
index 4d73c399103..f767c832198 100644
--- a/gnu/llvm/lib/Target/Mips/MipsTargetObjectFile.cpp
+++ b/gnu/llvm/lib/Target/Mips/MipsTargetObjectFile.cpp
@@ -36,6 +36,12 @@ ExternSData("mextern-sdata", cl::Hidden,
"current object."),
cl::init(true));
+static cl::opt<bool>
+EmbeddedData("membedded-data", cl::Hidden,
+ cl::desc("MIPS: Try to allocate variables in the following"
+ " sections if possible: .rodata, .sdata, .data ."),
+ cl::init(false));
+
void MipsTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){
TargetLoweringObjectFileELF::Initialize(Ctx, TM);
InitializeELF(TM.Options.UseInitArray);
@@ -77,8 +83,9 @@ bool MipsTargetObjectFile::IsGlobalInSmallSection(
bool MipsTargetObjectFile::
IsGlobalInSmallSection(const GlobalObject *GO, const TargetMachine &TM,
SectionKind Kind) const {
- return (IsGlobalInSmallSectionImpl(GO, TM) &&
- (Kind.isData() || Kind.isBSS() || Kind.isCommon()));
+ return IsGlobalInSmallSectionImpl(GO, TM) &&
+ (Kind.isData() || Kind.isBSS() || Kind.isCommon() ||
+ Kind.isReadOnly());
}
/// Return true if this global address should be placed into small data/bss
@@ -99,6 +106,22 @@ IsGlobalInSmallSectionImpl(const GlobalObject *GO,
if (!GVA)
return false;
+ // If the variable has an explicit section, it is placed in that section but
+ // it's addressing mode may change.
+ if (GVA->hasSection()) {
+ StringRef Section = GVA->getSection();
+
+ // Explicitly placing any variable in the small data section overrides
+ // the global -G value.
+ if (Section == ".sdata" || Section == ".sbss")
+ return true;
+
+ // Otherwise reject accessing it through the gp pointer. There are some
+ // historic cases which GCC doesn't appear to respect any more. These
+ // are .lit4, .lit8 and .srdata. For the moment reject these as well.
+ return false;
+ }
+
// Enforce -mlocal-sdata.
if (!LocalSData && GVA->hasLocalLinkage())
return false;
@@ -108,7 +131,18 @@ IsGlobalInSmallSectionImpl(const GlobalObject *GO,
GVA->hasCommonLinkage()))
return false;
+ // Enforce -membedded-data.
+ if (EmbeddedData && GVA->isConstant())
+ return false;
+
Type *Ty = GVA->getValueType();
+
+ // It is possible that the type of the global is unsized, i.e. a declaration
+ // of a extern struct. In this case don't presume it is in the small data
+ // section. This happens e.g. when building the FreeBSD kernel.
+ if (!Ty->isSized())
+ return false;
+
return IsInSmallSection(
GVA->getParent()->getDataLayout().getTypeAllocSize(Ty));
}
@@ -123,6 +157,8 @@ MCSection *MipsTargetObjectFile::SelectSectionForGlobal(
return SmallBSSSection;
if (Kind.isData() && IsGlobalInSmallSection(GO, TM, Kind))
return SmallDataSection;
+ if (Kind.isReadOnly() && IsGlobalInSmallSection(GO, TM, Kind))
+ return SmallDataSection;
// Otherwise, we work the same as ELF.
return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, Kind, TM);