diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2016-05-05 21:19:38 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2016-05-05 21:19:38 +0000 |
| commit | d39dadeb64beebee0032784ace9b88256bae70db (patch) | |
| tree | 8005b99c4c35a12ce059b1ece2a3969ba2a99df9 | |
| parent | 28a932742cf7277aacf4f15667249b6c1e13b2f5 (diff) | |
| download | bcm5719-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
| -rw-r--r-- | lld/ELF/Writer.cpp | 10 | ||||
| -rw-r--r-- | lld/test/ELF/copy-rel-pie-error.s | 12 |
2 files changed, 20 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."); diff --git a/lld/test/ELF/copy-rel-pie-error.s b/lld/test/ELF/copy-rel-pie-error.s new file mode 100644 index 00000000000..131f0c8ef54 --- /dev/null +++ b/lld/test/ELF/copy-rel-pie-error.s @@ -0,0 +1,12 @@ +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux +// RUN: llvm-mc %p/Inputs/copy-rel-pie.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux +// RUN: ld.lld %t2.o -o %t2.so -shared +// RUN: not ld.lld %t.o %t2.so -o %t.exe -pie 2>&1 | FileCheck %s + +// CHECK: relocation R_X86_64_64 cannot be used when making a shared object; recompile with -fPIC. +// CHECK: relocation R_X86_64_64 cannot be used when making a shared object; recompile with -fPIC. + +.global _start +_start: + .quad bar + .quad foo |

