[lld] r342447 - [COFF] Add support for delay loading DLLs for ARM64

Martin Storsjo via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 18 00:22:01 PDT 2018


Author: mstorsjo
Date: Tue Sep 18 00:22:01 2018
New Revision: 342447

URL: http://llvm.org/viewvc/llvm-project?rev=342447&view=rev
Log:
[COFF] Add support for delay loading DLLs for ARM64

Differential Revision: https://reviews.llvm.org/D52190

Added:
    lld/trunk/test/COFF/arm64-delayimport.yaml
Modified:
    lld/trunk/COFF/Chunks.cpp
    lld/trunk/COFF/Chunks.h
    lld/trunk/COFF/DLL.cpp

Modified: lld/trunk/COFF/Chunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.cpp?rev=342447&r1=342446&r2=342447&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.cpp (original)
+++ lld/trunk/COFF/Chunks.cpp Tue Sep 18 00:22:01 2018
@@ -191,7 +191,7 @@ void SectionChunk::applyRelARM(uint8_t *
 // Interpret the existing immediate value as a byte offset to the
 // target symbol, then update the instruction with the immediate as
 // the page offset from the current instruction to the target.
-static void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift) {
+void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift) {
   uint32_t Orig = read32le(Off);
   uint64_t Imm = ((Orig >> 29) & 0x3) | ((Orig >> 3) & 0x1FFFFC);
   S += Imm;
@@ -205,7 +205,7 @@ static void applyArm64Addr(uint8_t *Off,
 // Update the immediate field in a AARCH64 ldr, str, and add instruction.
 // Optionally limit the range of the written immediate by one or more bits
 // (RangeLimit).
-static void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit) {
+void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit) {
   uint32_t Orig = read32le(Off);
   Imm += (Orig >> 10) & 0xFFF;
   Orig &= ~(0xFFF << 10);
@@ -257,7 +257,7 @@ static void applySecRelLdr(const Section
     applyArm64Ldr(Off, (S - OS->getRVA()) & 0xfff);
 }
 
-static void applyArm64Branch26(uint8_t *Off, int64_t V) {
+void applyArm64Branch26(uint8_t *Off, int64_t V) {
   if (!isInt<28>(V))
     error("relocation out of range");
   or32(Off, (V & 0x0FFFFFFC) >> 2);

Modified: lld/trunk/COFF/Chunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.h?rev=342447&r1=342446&r2=342447&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.h (original)
+++ lld/trunk/COFF/Chunks.h Tue Sep 18 00:22:01 2018
@@ -474,6 +474,10 @@ private:
 void applyMOV32T(uint8_t *Off, uint32_t V);
 void applyBranch24T(uint8_t *Off, int32_t V);
 
+void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift);
+void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit);
+void applyArm64Branch26(uint8_t *Off, int64_t V);
+
 } // namespace coff
 } // namespace lld
 

Modified: lld/trunk/COFF/DLL.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DLL.cpp?rev=342447&r1=342446&r2=342447&view=diff
==============================================================================
--- lld/trunk/COFF/DLL.cpp (original)
+++ lld/trunk/COFF/DLL.cpp Tue Sep 18 00:22:01 2018
@@ -230,6 +230,36 @@ static const uint8_t ThunkARM[] = {
     0x60, 0x47,             // bx      ip
 };
 
+static const uint8_t ThunkARM64[] = {
+    0x11, 0x00, 0x00, 0x90, // adrp    x17, #0      __imp_<FUNCNAME>
+    0x31, 0x02, 0x00, 0x91, // add     x17, x17, #0 :lo12:__imp_<FUNCNAME>
+    0xfd, 0x7b, 0xb3, 0xa9, // stp     x29, x30, [sp, #-208]!
+    0xfd, 0x03, 0x00, 0x91, // mov     x29, sp
+    0xe0, 0x07, 0x01, 0xa9, // stp     x0, x1, [sp, #16]
+    0xe2, 0x0f, 0x02, 0xa9, // stp     x2, x3, [sp, #32]
+    0xe4, 0x17, 0x03, 0xa9, // stp     x4, x5, [sp, #48]
+    0xe6, 0x1f, 0x04, 0xa9, // stp     x6, x7, [sp, #64]
+    0xe0, 0x87, 0x02, 0xad, // stp     q0, q1, [sp, #80]
+    0xe2, 0x8f, 0x03, 0xad, // stp     q2, q3, [sp, #112]
+    0xe4, 0x97, 0x04, 0xad, // stp     q4, q5, [sp, #144]
+    0xe6, 0x9f, 0x05, 0xad, // stp     q6, q7, [sp, #176]
+    0xe1, 0x03, 0x11, 0xaa, // mov     x1, x17
+    0x00, 0x00, 0x00, 0x90, // adrp    x0, #0     DELAY_IMPORT_DESCRIPTOR
+    0x00, 0x00, 0x00, 0x91, // add     x0, x0, #0 :lo12:DELAY_IMPORT_DESCRIPTOR
+    0x00, 0x00, 0x00, 0x94, // bl      #0 __delayLoadHelper2
+    0xf0, 0x03, 0x00, 0xaa, // mov     x16, x0
+    0xe6, 0x9f, 0x45, 0xad, // ldp     q6, q7, [sp, #176]
+    0xe4, 0x97, 0x44, 0xad, // ldp     q4, q5, [sp, #144]
+    0xe2, 0x8f, 0x43, 0xad, // ldp     q2, q3, [sp, #112]
+    0xe0, 0x87, 0x42, 0xad, // ldp     q0, q1, [sp, #80]
+    0xe6, 0x1f, 0x44, 0xa9, // ldp     x6, x7, [sp, #64]
+    0xe4, 0x17, 0x43, 0xa9, // ldp     x4, x5, [sp, #48]
+    0xe2, 0x0f, 0x42, 0xa9, // ldp     x2, x3, [sp, #32]
+    0xe0, 0x07, 0x41, 0xa9, // ldp     x0, x1, [sp, #16]
+    0xfd, 0x7b, 0xcd, 0xa8, // ldp     x29, x30, [sp], #208
+    0x00, 0x02, 0x1f, 0xd6, // br      x16
+};
+
 // A chunk for the delay import thunk.
 class ThunkChunkX64 : public Chunk {
 public:
@@ -298,6 +328,28 @@ public:
   Defined *Helper = nullptr;
 };
 
+class ThunkChunkARM64 : public Chunk {
+public:
+  ThunkChunkARM64(Defined *I, Chunk *D, Defined *H)
+      : Imp(I), Desc(D), Helper(H) {}
+
+  size_t getSize() const override { return sizeof(ThunkARM64); }
+
+  void writeTo(uint8_t *Buf) const override {
+    memcpy(Buf + OutputSectionOff, ThunkARM64, sizeof(ThunkARM64));
+    applyArm64Addr(Buf + OutputSectionOff + 0, Imp->getRVA(), RVA + 0, 12);
+    applyArm64Imm(Buf + OutputSectionOff + 4, Imp->getRVA() & 0xfff, 0);
+    applyArm64Addr(Buf + OutputSectionOff + 52, Desc->getRVA(), RVA + 52, 12);
+    applyArm64Imm(Buf + OutputSectionOff + 56, Desc->getRVA() & 0xfff, 0);
+    applyArm64Branch26(Buf + OutputSectionOff + 60,
+                       Helper->getRVA() - RVA - 60);
+  }
+
+  Defined *Imp = nullptr;
+  Chunk *Desc = nullptr;
+  Defined *Helper = nullptr;
+};
+
 // A chunk for the import descriptor table.
 class DelayAddressChunk : public Chunk {
 public:
@@ -555,6 +607,8 @@ Chunk *DelayLoadContents::newThunkChunk(
     return make<ThunkChunkX86>(S, Dir, Helper);
   case ARMNT:
     return make<ThunkChunkARM>(S, Dir, Helper);
+  case ARM64:
+    return make<ThunkChunkARM64>(S, Dir, Helper);
   default:
     llvm_unreachable("unsupported machine type");
   }

Added: lld/trunk/test/COFF/arm64-delayimport.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/arm64-delayimport.yaml?rev=342447&view=auto
==============================================================================
--- lld/trunk/test/COFF/arm64-delayimport.yaml (added)
+++ lld/trunk/test/COFF/arm64-delayimport.yaml Tue Sep 18 00:22:01 2018
@@ -0,0 +1,91 @@
+# REQUIRES: aarch64
+
+# RUN: yaml2obj < %s > %t.obj
+# RUN: lld-link /entry:main /subsystem:console /out:%t.exe %t.obj %p/Inputs/library-arm64.lib /alternatename:__delayLoadHelper2=main /delayload:library.dll
+# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix DISASM
+# RUN: llvm-readobj -coff-imports %t.exe | FileCheck %s -check-prefix IMPORTS
+
+# DISASM:  140001014:      11 00 00 d0     adrp    x17, #8192
+# DISASM:  140001018:      31 22 00 91     add     x17, x17, #8
+# DISASM:  14000101c:      fd 7b b3 a9     stp     x29, x30, [sp, #-208]!
+# DISASM:  140001020:      fd 03 00 91     mov     x29, sp
+# DISASM:  140001024:      e0 07 01 a9     stp     x0, x1, [sp, #16]
+# DISASM:  140001028:      e2 0f 02 a9     stp     x2, x3, [sp, #32]
+# DISASM:  14000102c:      e4 17 03 a9     stp     x4, x5, [sp, #48]
+# DISASM:  140001030:      e6 1f 04 a9     stp     x6, x7, [sp, #64]
+# DISASM:  140001034:      e0 87 02 ad     stp     q0, q1, [sp, #80]
+# DISASM:  140001038:      e2 8f 03 ad     stp     q2, q3, [sp, #112]
+# DISASM:  14000103c:      e4 97 04 ad     stp     q4, q5, [sp, #144]
+# DISASM:  140001040:      e6 9f 05 ad     stp     q6, q7, [sp, #176]
+# DISASM:  140001044:      e1 03 11 aa     mov     x1, x17
+# DISASM:  140001048:      00 00 00 b0     adrp    x0, #4096
+# DISASM:  14000104c:      00 00 00 91     add     x0, x0, #0
+# DISASM:  140001050:      ec ff ff 97     bl      #-80 <.text>
+# DISASM:  140001054:      f0 03 00 aa     mov     x16, x0
+# DISASM:  140001058:      e6 9f 45 ad     ldp     q6, q7, [sp, #176]
+# DISASM:  14000105c:      e4 97 44 ad     ldp     q4, q5, [sp, #144]
+# DISASM:  140001060:      e2 8f 43 ad     ldp     q2, q3, [sp, #112]
+# DISASM:  140001064:      e0 87 42 ad     ldp     q0, q1, [sp, #80]
+# DISASM:  140001068:      e6 1f 44 a9     ldp     x6, x7, [sp, #64]
+# DISASM:  14000106c:      e4 17 43 a9     ldp     x4, x5, [sp, #48]
+# DISASM:  140001070:      e2 0f 42 a9     ldp     x2, x3, [sp, #32]
+# DISASM:  140001074:      e0 07 41 a9     ldp     x0, x1, [sp, #16]
+# DISASM:  140001078:      fd 7b cd a8     ldp     x29, x30, [sp], #208
+# DISASM:  14000107c:      00 02 1f d6     br      x16
+
+# IMPORTS: Format: COFF-ARM64
+# IMPORTS: Arch: aarch64
+# IMPORTS: AddressSize: 64bit
+# IMPORTS: DelayImport {
+# IMPORTS:   Name: library.dll
+# IMPORTS:   Attributes: 0x1
+# IMPORTS:   ModuleHandle: 0x3000
+# IMPORTS:   ImportAddressTable: 0x3008
+# IMPORTS:   ImportNameTable: 0x2040
+# IMPORTS:   BoundDelayImportTable: 0x0
+# IMPORTS:   UnloadDelayImportTable: 0x0
+# IMPORTS:   Import {
+# IMPORTS:     Symbol: function (0)
+# IMPORTS:     Address: 0x140001014
+# IMPORTS:   }
+# IMPORTS: }
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_ARM64
+  Characteristics: [  ]
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     00000094C0035FD6
+    Relocations:
+      - VirtualAddress:  0
+        SymbolName:      function
+        Type:            IMAGE_REL_ARM64_BRANCH26
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          8
+      NumberOfRelocations: 1
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          1
+  - Name:            main
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            function
+    Value:           0
+    SectionNumber:   0
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...




More information about the llvm-commits mailing list