summaryrefslogtreecommitdiffstats
path: root/lld/ELF/Writer.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2016-05-05 21:19:38 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2016-05-05 21:19:38 +0000
commitd39dadeb64beebee0032784ace9b88256bae70db (patch)
tree8005b99c4c35a12ce059b1ece2a3969ba2a99df9 /lld/ELF/Writer.cpp
parent28a932742cf7277aacf4f15667249b6c1e13b2f5 (diff)
downloadbcm5719-llvm-d39dadeb64beebee0032784ace9b88256bae70db.tar.gz
bcm5719-llvm-d39dadeb64beebee0032784ace9b88256bae70db.zip
Don't produce a relocation to read only memory.
This is hopefully last case where we would produce a relocation to a read only section. llvm-svn: 268688
Diffstat (limited to 'lld/ELF/Writer.cpp')
-rw-r--r--lld/ELF/Writer.cpp10
1 files changed, 8 insertions, 2 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index dfb99d4b8b4..4079c761115 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -439,6 +439,12 @@ static bool needsPlt(RelExpr Expr) {
return Expr == R_PLT_PC || Expr == R_PPC_PLT_OPD || Expr == R_PLT;
}
+// True if this expression is of the form Sym - X, where X is a position in the
+// file (PC, or GOT for example).
+static bool isRelExpr(RelExpr Expr) {
+ return Expr == R_PC || Expr == R_GOTREL || Expr == R_PAGE_PC;
+}
+
template <class ELFT>
static bool isStaticLinkTimeConstant(RelExpr E, uint32_t Type,
const SymbolBody &Body) {
@@ -460,7 +466,7 @@ static bool isStaticLinkTimeConstant(RelExpr E, uint32_t Type,
return true;
bool AbsVal = isAbsolute<ELFT>(Body) || Body.isTls();
- bool RelE = E == R_PC || E == R_GOTREL || E == R_PAGE_PC;
+ bool RelE = isRelExpr(E);
if (AbsVal && !RelE)
return true;
if (!AbsVal && RelE)
@@ -520,7 +526,7 @@ RelExpr Writer<ELFT>::adjustExpr(SymbolBody &Body, bool IsWrite, RelExpr Expr,
// This relocation would require the dynamic linker to write a value to read
// only memory. We can hack around it if we are producing an executable and
// the refered symbol can be preemepted to refer to the executable.
- if (Config->Shared) {
+ if (Config->Shared || (Config->Pic && !isRelExpr(Expr))) {
StringRef S = getELFRelocationTypeName(Config->EMachine, Type);
error("relocation " + S + " cannot be used when making a shared "
"object; recompile with -fPIC.");
OpenPOWER on IntegriCloud