Be less aggressive at relaxing got access in this case.
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 27 Oct 2016 17:28:56 +0000 (17:28 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 27 Oct 2016 17:28:56 +0000 (17:28 +0000)
This fixes pr30803 by not relaxing that particular access. We could
also let adjustRelaxExpr know that the target is absolute so that it
uses R_RELAX_GOT_PC_NOPIC, but it is not clear if it is worth it.

llvm-svn: 285317

lld/ELF/Relocations.cpp
lld/test/ELF/x86-64-relax-got-abs.s [new file with mode: 0644]

index 875871b..e5dc0c4 100644 (file)
@@ -286,6 +286,10 @@ template <class ELFT> static bool isAbsolute(const SymbolBody &Body) {
   return false;
 }
 
+template <class ELFT> static bool isAbsoluteValue(const SymbolBody &Body) {
+  return isAbsolute<ELFT>(Body) || Body.isTls();
+}
+
 static bool needsPlt(RelExpr Expr) {
   return Expr == R_PLT_PC || Expr == R_PPC_PLT_OPD || Expr == R_PLT ||
          Expr == R_PLT_PAGE_PC || Expr == R_THUNK_PLT_PC;
@@ -322,7 +326,7 @@ static bool isStaticLinkTimeConstant(RelExpr E, uint32_t Type,
   if (!Config->Pic)
     return true;
 
-  bool AbsVal = isAbsolute<ELFT>(Body) || Body.isTls();
+  bool AbsVal = isAbsoluteValue<ELFT>(Body);
   bool RelE = isRelExpr(E);
   if (AbsVal && !RelE)
     return true;
@@ -433,7 +437,7 @@ static RelExpr adjustExpr(const elf::ObjectFile<ELFT> &File, SymbolBody &Body,
   } else if (!Preemptible) {
     if (needsPlt(Expr))
       Expr = fromPlt(Expr);
-    if (Expr == R_GOT_PC)
+    if (Expr == R_GOT_PC && !isAbsoluteValue<ELFT>(Body))
       Expr = Target->adjustRelaxExpr(Type, Data, Expr);
   }
   Expr = Target->getThunkExpr(Expr, Type, File, Body);
diff --git a/lld/test/ELF/x86-64-relax-got-abs.s b/lld/test/ELF/x86-64-relax-got-abs.s
new file mode 100644 (file)
index 0000000..c429120
--- /dev/null
@@ -0,0 +1,16 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-pc-linux %s \
+// RUN:   -o %t.o
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-objdump -d %t.so | FileCheck %s
+
+// We used to fail trying to relax this into a pc relocation to an absolute
+// value.
+
+// CHECK: movq  4185(%rip), %rax
+
+       movq    bar@GOTPCREL(%rip), %rax
+        .data
+        .global bar
+        .hidden bar
+        bar = 42