[lld] r305212 - Fix weak symbols on arm and aarch64.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 12 11:05:01 PDT 2017


Author: rafael
Date: Mon Jun 12 13:05:01 2017
New Revision: 305212

URL: http://llvm.org/viewvc/llvm-project?rev=305212&view=rev
Log:
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>

Modified:
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/test/ELF/aarch64-undefined-weak.s
    lld/trunk/test/ELF/arm-thumb-no-undefined-thunk.s
    lld/trunk/test/ELF/arm-thumb-undefined-weak.s
    lld/trunk/test/ELF/arm-undefined-weak.s

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=305212&r1=305211&r2=305212&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Mon Jun 12 13:05:01 2017
@@ -403,7 +403,7 @@ static uint32_t getARMUndefinedRelativeW
                                               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:
@@ -411,12 +411,12 @@ static uint32_t getARMUndefinedRelativeW
   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;
   }
 }
 
@@ -427,9 +427,9 @@ static uint64_t getAArch64UndefinedRelat
   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;
   }
 }
 
@@ -515,20 +515,30 @@ static uint64_t getRelocTargetVA(uint32_
     return InX::MipsGot->getVA() + InX::MipsGot->getTlsOffset() +
            InX::MipsGot->getTlsIndexOff() - InX::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(A)) - getAArch64Page(P);
-  case R_PC:
+      Dest = getAArch64Page(A);
+    else
+      Dest = getAArch64Page(Body.getVA(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(A);
+    } else {
+      Dest = Body.getVA(A);
     }
-    return Body.getVA(A) - P;
+    return Dest - P;
+  }
   case R_PLT:
     return Body.getPltVA() + A;
   case R_PLT_PC:

Modified: lld/trunk/test/ELF/aarch64-undefined-weak.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/aarch64-undefined-weak.s?rev=305212&r1=305211&r2=305212&view=diff
==============================================================================
--- lld/trunk/test/ELF/aarch64-undefined-weak.s (original)
+++ lld/trunk/test/ELF/aarch64-undefined-weak.s Mon Jun 12 13:05:01 2017
@@ -33,12 +33,12 @@ _start:
 
 // CHECK: Disassembly of section .text:
 // 131076 = 0x20004
-// CHECK:         20000: {{.*}} b       #131076
-// CHECK-NEXT:    20004: {{.*}} bl      #131080
-// CHECK-NEXT:    20008: {{.*}} b.eq    #131084
-// CHECK-NEXT:    2000c: {{.*}} cbz     x1, #131088
+// CHECK:         20000: {{.*}} b       #4
+// CHECK-NEXT:    20004: {{.*}} bl      #4
+// CHECK-NEXT:    20008: {{.*}} b.eq    #4
+// CHECK-NEXT:    2000c: {{.*}} cbz     x1, #4
 // CHECK-NEXT:    20010: {{.*}} adr     x0, #0
-// CHECK-NEXT:    20014: {{.*}} adrp    x0, #0
+// CHECK-NEXT:    20014: {{.*}} adrp    x0, #-131072
 // CHECK:         20018: {{.*}} .word   0x00000000
 // CHECK-NEXT:    2001c: {{.*}} .word   0x00000000
 // CHECK-NEXT:    20020: {{.*}} .word   0x00000000

Modified: lld/trunk/test/ELF/arm-thumb-no-undefined-thunk.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-no-undefined-thunk.s?rev=305212&r1=305211&r2=305212&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-no-undefined-thunk.s (original)
+++ lld/trunk/test/ELF/arm-thumb-no-undefined-thunk.s Mon Jun 12 13:05:01 2017
@@ -19,6 +19,6 @@ _start:
 // CHECK: Disassembly of section .text:
 // CHECK-NEXT: _start:
 // 69636 = 0x11004 = next instruction
-// CHECK:         11000: {{.*}} bl      #69636
-// CHECK-NEXT:    11004: {{.*}} b.w     #69640
-// CHECK-NEXT:    11008: {{.*}} b.w     #69644
+// CHECK:         11000: {{.*}} bl      #0
+// CHECK-NEXT:    11004: {{.*}} b.w     #0 <_start+0x8>
+// CHECK-NEXT:    11008: {{.*}} b.w     #0 <_start+0xC>

Modified: lld/trunk/test/ELF/arm-thumb-undefined-weak.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-undefined-weak.s?rev=305212&r1=305211&r2=305212&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-undefined-weak.s (original)
+++ lld/trunk/test/ELF/arm-thumb-undefined-weak.s Mon Jun 12 13:05:01 2017
@@ -29,10 +29,10 @@ _start:
 
 // CHECK: Disassembly of section .text:
 // 69636 = 0x11004
-// CHECK:         11000: {{.*}} beq.w   #69636
-// CHECK-NEXT:    11004: {{.*}} b.w     #69640
-// CHECK-NEXT:    11008: {{.*}} bl      #69644
+// CHECK:         11000: {{.*}} beq.w   #0 <_start+0x4>
+// CHECK-NEXT:    11004: {{.*}} b.w     #0 <_start+0x8>
+// CHECK-NEXT:    11008: {{.*}} bl      #0
 // blx is transformed into bl so we don't change state
-// CHECK-NEXT:    1100c: {{.*}} bl      #69648
+// CHECK-NEXT:    1100c: {{.*}} bl      #0
 // CHECK-NEXT:    11010: {{.*}} movt    r0, #0
 // CHECK-NEXT:    11014: {{.*}} movw    r0, #0

Modified: lld/trunk/test/ELF/arm-undefined-weak.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-undefined-weak.s?rev=305212&r1=305211&r2=305212&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-undefined-weak.s (original)
+++ lld/trunk/test/ELF/arm-undefined-weak.s Mon Jun 12 13:05:01 2017
@@ -29,10 +29,10 @@ _start:
 
 // CHECK: Disassembly of section .text:
 // 69636 = 0x11004
-// CHECK:         11000: {{.*}} b       #69636
-// CHECK-NEXT:    11004: {{.*}} bl      #69640
+// CHECK:         11000: {{.*}} b       #-4 <_start+0x4>
+// CHECK-NEXT:    11004: {{.*}} bl      #-4 <_start+0x8>
 // blx is transformed into bl so we don't change state
-// CHECK-NEXT:    11008: {{.*}} bl      #69644
+// CHECK-NEXT:    11008: {{.*}} bl      #-4 <_start+0xC>
 // CHECK-NEXT:    1100c: {{.*}} movt    r0, #0
 // CHECK-NEXT:    11010: {{.*}} movw    r0, #0
 // CHECK:         11014: {{.*}} .word   0x00000000




More information about the llvm-commits mailing list