svn commit: r319956 - head/contrib/llvm/tools/lld/ELF

Ed Maste emaste at FreeBSD.org
Wed Jun 14 18:56:34 UTC 2017


Author: emaste
Date: Wed Jun 14 18:56:33 2017
New Revision: 319956
URL: https://svnweb.freebsd.org/changeset/base/319956

Log:
  lld: Fix weak symbols on arm and aarch64
  
  Given
  
  .weak target
   .global _start
  _start:
   b target
  
  The intention is that the branch goes to the instruction after the
  branch, effectively turning it on a nop.  The branch adds the runtime
  PC, but we were adding it statically too.
  
  I noticed the oddity by inspection, but llvm-objdump seems to agree,
  since it now prints things like:
  
  b       #-4 <_start+0x4>
  
  Obtained from:  LLD commit r305212
  Differential Revision:  https://reviews.freebsd.org/D11191
  
  Reviewed by:	dim, Rafael Espíndola
  Obtained from:	LLD r305212
  MFC after:	3 days

Modified:
  head/contrib/llvm/tools/lld/ELF/InputSection.cpp

Modified: head/contrib/llvm/tools/lld/ELF/InputSection.cpp
==============================================================================
--- head/contrib/llvm/tools/lld/ELF/InputSection.cpp	Wed Jun 14 18:53:33 2017	(r319955)
+++ head/contrib/llvm/tools/lld/ELF/InputSection.cpp	Wed Jun 14 18:56:33 2017	(r319956)
@@ -255,7 +255,7 @@ static uint32_t getARMUndefinedRelativeWeakVA(uint32_t
                                               uint32_t P) {
   switch (Type) {
   case R_ARM_THM_JUMP11:
-    return P + 2;
+    return P + 2 + A;
   case R_ARM_CALL:
   case R_ARM_JUMP24:
   case R_ARM_PC24:
@@ -263,12 +263,12 @@ static uint32_t getARMUndefinedRelativeWeakVA(uint32_t
   case R_ARM_PREL31:
   case R_ARM_THM_JUMP19:
   case R_ARM_THM_JUMP24:
-    return P + 4;
+    return P + 4 + A;
   case R_ARM_THM_CALL:
     // We don't want an interworking BLX to ARM
-    return P + 5;
+    return P + 5 + A;
   default:
-    return A;
+    return P + A;
   }
 }
 
@@ -279,9 +279,9 @@ static uint64_t getAArch64UndefinedRelativeWeakVA(uint
   case R_AARCH64_CONDBR19:
   case R_AARCH64_JUMP26:
   case R_AARCH64_TSTBR14:
-    return P + 4;
+    return P + 4 + A;
   default:
-    return A;
+    return P + A;
   }
 }
 
@@ -344,20 +344,30 @@ getRelocTargetVA(uint32_t Type, typename ELFT::uint A,
     return In<ELFT>::MipsGot->getVA() + In<ELFT>::MipsGot->getTlsOffset() +
            In<ELFT>::MipsGot->getTlsIndexOff() - In<ELFT>::MipsGot->getGp();
   case R_PAGE_PC:
-  case R_PLT_PAGE_PC:
+  case R_PLT_PAGE_PC: {
+    uint64_t Dest;
     if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak())
-      return getAArch64Page(A);
-    return getAArch64Page(Body.getVA<ELFT>(A)) - getAArch64Page(P);
-  case R_PC:
+      Dest = getAArch64Page(A);
+    else
+      Dest = getAArch64Page(Body.getVA<ELFT>(A));
+    return Dest - getAArch64Page(P);
+  }
+  case R_PC: {
+    uint64_t Dest;
     if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak()) {
       // On ARM and AArch64 a branch to an undefined weak resolves to the
       // next instruction, otherwise the place.
       if (Config->EMachine == EM_ARM)
-        return getARMUndefinedRelativeWeakVA(Type, A, P);
-      if (Config->EMachine == EM_AARCH64)
-        return getAArch64UndefinedRelativeWeakVA(Type, A, P);
+        Dest = getARMUndefinedRelativeWeakVA(Type, A, P);
+      else if (Config->EMachine == EM_AARCH64)
+        Dest = getAArch64UndefinedRelativeWeakVA(Type, A, P);
+      else
+        Dest = Body.getVA<ELFT>(A);
+    } else {
+      Dest = Body.getVA<ELFT>(A);
     }
-    return Body.getVA<ELFT>(A) - P;
+    return Dest - P;
+  }
   case R_PLT:
     return Body.getPltVA<ELFT>() + A;
   case R_PLT_PC:


More information about the svn-src-head mailing list