[lld] 7c81649 - [COFF] Align ARM64 range extension thunks at instruction boundary

Tom Tan via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 10 19:19:52 PST 2020


Author: Tom Tan
Date: 2020-01-10T19:03:17-08:00
New Revision: 7c816492197aefbaa2ea3ba0e391f7c6905956bc

URL: https://github.com/llvm/llvm-project/commit/7c816492197aefbaa2ea3ba0e391f7c6905956bc
DIFF: https://github.com/llvm/llvm-project/commit/7c816492197aefbaa2ea3ba0e391f7c6905956bc.diff

LOG: [COFF] Align ARM64 range extension thunks at instruction boundary

RangeExtensionThunkARM64 is created for out-of-range branches on Windows ARM64
because branch instructions has limited bits to encode target address.
Currently, RangeExtensionThunkARM64 is appended to its referencing COFF section
from object file at link time without any alignment requirement, so if size of
the preceding COFF section is not aligned to instruction boundary (4 bytes),
RangeExtensionThunkARM64 will emit thunk instructions at unaligned address
which is never a valid branch target on ARM64, and usually triggers invalid
instruction exception when branching to it.

This PR fixes it by requiring such thunks to align at 4 bytes.

Differential revision: https://reviews.llvm.org/D72473

Added: 
    

Modified: 
    lld/COFF/Chunks.h
    lld/test/COFF/arm64-thunks.s

Removed: 
    


################################################################################
diff  --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h
index 9ccc194c151a..7ae4ee735f4a 100644
--- a/lld/COFF/Chunks.h
+++ b/lld/COFF/Chunks.h
@@ -510,7 +510,7 @@ class RangeExtensionThunkARM : public NonSectionChunk {
 
 class RangeExtensionThunkARM64 : public NonSectionChunk {
 public:
-  explicit RangeExtensionThunkARM64(Defined *t) : target(t) {}
+  explicit RangeExtensionThunkARM64(Defined *t) : target(t) { setAlignment(4); }
   size_t getSize() const override;
   void writeTo(uint8_t *buf) const override;
 

diff  --git a/lld/test/COFF/arm64-thunks.s b/lld/test/COFF/arm64-thunks.s
index 49004544c438..eb71241d4199 100644
--- a/lld/test/COFF/arm64-thunks.s
+++ b/lld/test/COFF/arm64-thunks.s
@@ -3,10 +3,11 @@
 // RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s
 // RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s
 
-// VERBOSE: Added 1 thunks with margin {{.*}} in 1 passes
+// VERBOSE: Added 2 thunks with margin {{.*}} in 1 passes
 
     .globl main
     .globl func1
+    .globl func2
     .text
 main:
     tbz w0, #0, func1
@@ -15,6 +16,14 @@ main:
     .space 0x8000
     .section .text$b, "xr"
 func1:
+    tbz w0, #0, func2
+    ret
+    .space 1
+    .section .text$c, "xr"
+    .space 0x8000
+    .section .text$d, "xr"
+    .align 2
+func2:
     ret
 
 // DISASM: 0000000140001000 .text:
@@ -24,4 +33,11 @@ func1:
 // DISASM: 14000100c:      10 52 00 91     add     x16, x16, #20
 // DISASM: 140001010:      00 02 1f d6     br      x16
 
-// DISASM: 140009014:      c0 03 5f d6     ret
+// DISASM: 140009014:      60 00 00 36     tbz     w0, #0, #12 <.text+0x8020>
+// DISASM: 140009018:      c0 03 5f d6     ret
+
+// DISASM: 140009020:      50 00 00 90     adrp    x16, #32768
+// DISASM: 140009024:      10 b2 00 91     add     x16, x16, #44
+// DISASM: 140009028:      00 02 1f d6     br      x16
+
+// DISASM: 14001102c:      c0 03 5f d6     ret


        


More information about the llvm-commits mailing list