[lld] [LLD] Match delayLoad thunk with MSVC (PR #149521)

Evgenii Kudriashov via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 18 07:37:50 PDT 2025


https://github.com/e-kud created https://github.com/llvm/llvm-project/pull/149521

Previously we saved registers in the shadow space of callee before calling __delayLoadHelper2. Now we save arguments in the shadow space of the caller and allocate shadow space for the callee.

Fixes #51941

>From d83312cdec8e339683a23ba4e8c37d3cba041194 Mon Sep 17 00:00:00 2001
From: Evgenii Kudriashov <evgenii.kudriashov at intel.com>
Date: Fri, 18 Jul 2025 07:25:16 -0700
Subject: [PATCH] [LLD] Match delayLoad thunk with MSVC

Previously we saved registers in the shadow space of callee before
calling __delayLoadHelper2. Now we save arguments in the shadow space of
the caller and allocate shadow space for the callee.

Fixes #51941

Co-authored-by: Benjamin Santerre <benjamin.santerre at gmail.com>
---
 lld/COFF/DLL.cpp                     | 48 ++++++++++++++--------------
 lld/test/COFF/delayimports.test      |  2 +-
 lld/test/COFF/delayimporttables.yaml |  4 +--
 3 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/lld/COFF/DLL.cpp b/lld/COFF/DLL.cpp
index c327da28ce138..d98126fea7234 100644
--- a/lld/COFF/DLL.cpp
+++ b/lld/COFF/DLL.cpp
@@ -244,28 +244,28 @@ static const uint8_t thunkX64[] = {
 };
 
 static const uint8_t tailMergeX64[] = {
-    0x51,                               // push    rcx
-    0x52,                               // push    rdx
-    0x41, 0x50,                         // push    r8
-    0x41, 0x51,                         // push    r9
-    0x48, 0x83, 0xEC, 0x48,             // sub     rsp, 48h
-    0x66, 0x0F, 0x7F, 0x04, 0x24,       // movdqa  xmmword ptr [rsp], xmm0
-    0x66, 0x0F, 0x7F, 0x4C, 0x24, 0x10, // movdqa  xmmword ptr [rsp+10h], xmm1
-    0x66, 0x0F, 0x7F, 0x54, 0x24, 0x20, // movdqa  xmmword ptr [rsp+20h], xmm2
-    0x66, 0x0F, 0x7F, 0x5C, 0x24, 0x30, // movdqa  xmmword ptr [rsp+30h], xmm3
-    0x48, 0x8B, 0xD0,                   // mov     rdx, rax
-    0x48, 0x8D, 0x0D, 0, 0, 0, 0,       // lea     rcx, [___DELAY_IMPORT_...]
-    0xE8, 0, 0, 0, 0,                   // call    __delayLoadHelper2
-    0x66, 0x0F, 0x6F, 0x04, 0x24,       // movdqa  xmm0, xmmword ptr [rsp]
-    0x66, 0x0F, 0x6F, 0x4C, 0x24, 0x10, // movdqa  xmm1, xmmword ptr [rsp+10h]
-    0x66, 0x0F, 0x6F, 0x54, 0x24, 0x20, // movdqa  xmm2, xmmword ptr [rsp+20h]
-    0x66, 0x0F, 0x6F, 0x5C, 0x24, 0x30, // movdqa  xmm3, xmmword ptr [rsp+30h]
-    0x48, 0x83, 0xC4, 0x48,             // add     rsp, 48h
-    0x41, 0x59,                         // pop     r9
-    0x41, 0x58,                         // pop     r8
-    0x5A,                               // pop     rdx
-    0x59,                               // pop     rcx
-    0xFF, 0xE0,                         // jmp     rax
+    0x48, 0x89, 0x4C, 0x24, 0x08,             // mov     qword ptr [rsp+8], rcx
+    0x48, 0x89, 0x54, 0x24, 0x10,             // mov     qword ptr [rsp+10h], rdx
+    0x4C, 0x89, 0x44, 0x24, 0x18,             // mov     qword ptr [rsp+18h], r8
+    0x4C, 0x89, 0x4C, 0x24, 0x20,             // mov     qword ptr [rsp+20h], r9
+    0x48, 0x83, 0xEC, 0x68,                   // sub     rsp, 68h
+    0x66, 0x0F, 0x7F, 0x44, 0x24, 0x20,       // movdqa  xmmword ptr [rsp+20h], xmm0
+    0x66, 0x0F, 0x7F, 0x4C, 0x24, 0x30,       // movdqa  xmmword ptr [rsp+30h], xmm1
+    0x66, 0x0F, 0x7F, 0x54, 0x24, 0x40,       // movdqa  xmmword ptr [rsp+40h], xmm2
+    0x66, 0x0F, 0x7F, 0x5C, 0x24, 0x50,       // movdqa  xmmword ptr [rsp+50h], xmm3
+    0x48, 0x8B, 0xD0,                         // mov     rdx, rax
+    0x48, 0x8D, 0x0D, 0, 0, 0, 0,             // lea     rcx, [___DELAY_IMPORT_...]
+    0xE8, 0, 0, 0, 0,                         // call    __delayLoadHelper2
+    0x66, 0x0F, 0x6F, 0x44, 0x24, 0x20,       // movdqa  xmm0, xmmword ptr [rsp+20h]
+    0x66, 0x0F, 0x6F, 0x4C, 0x24, 0x30,       // movdqa  xmm1, xmmword ptr [rsp+30h]
+    0x66, 0x0F, 0x6F, 0x54, 0x24, 0x40,       // movdqa  xmm2, xmmword ptr [rsp+40h]
+    0x66, 0x0F, 0x6F, 0x5C, 0x24, 0x50,       // movdqa  xmm3, xmmword ptr [rsp+50h]
+    0x48, 0x8B, 0x4C, 0x24, 0x70,             // mov     rcx, qword ptr [rsp+70h]
+    0x48, 0x8B, 0x54, 0x24, 0x78,             // mov     rdx, qword ptr [rsp+78h]
+    0x4C, 0x8B, 0x84, 0x24, 0x80, 00, 00, 00, // mov     r8, qword ptr [rsp+80h]
+    0x4C, 0x8B, 0x8C, 0x24, 0x88, 00, 00, 00, // mov     r9, qword ptr [rsp+88h]
+    0x48, 0x83, 0xC4, 0x68,                   // add     rsp, 68h
+    0xFF, 0xE0,                               // jmp     rax
 };
 
 static const uint8_t tailMergeUnwindInfoX64[] = {
@@ -378,8 +378,8 @@ class TailMergeChunkX64 : public NonSectionCodeChunk {
 
   void writeTo(uint8_t *buf) const override {
     memcpy(buf, tailMergeX64, sizeof(tailMergeX64));
-    write32le(buf + 39, desc->getRVA() - rva - 43);
-    write32le(buf + 44, helper->getRVA() - rva - 48);
+    write32le(buf + 54, desc->getRVA() - rva - 58);
+    write32le(buf + 59, helper->getRVA() - rva - 63);
   }
 
   Chunk *desc = nullptr;
diff --git a/lld/test/COFF/delayimports.test b/lld/test/COFF/delayimports.test
index f410eef35fd1d..1521155d8764f 100644
--- a/lld/test/COFF/delayimports.test
+++ b/lld/test/COFF/delayimports.test
@@ -44,7 +44,7 @@ BASEREL-NEXT:   }
 UNWIND:      UnwindInformation [
 UNWIND-NEXT:   RuntimeFunction {
 UNWIND-NEXT:     StartAddress: (0x14000108A)
-UNWIND-NEXT:     EndAddress: (0x1400010DD)
+UNWIND-NEXT:     EndAddress: (0x140001101)
 UNWIND-NEXT:     UnwindInfoAddress: (0x140002000)
 UNWIND-NEXT:     UnwindInfo {
 UNWIND-NEXT:       Version: 1
diff --git a/lld/test/COFF/delayimporttables.yaml b/lld/test/COFF/delayimporttables.yaml
index cf54c0a7140a1..a4e0cf0cc992c 100644
--- a/lld/test/COFF/delayimporttables.yaml
+++ b/lld/test/COFF/delayimporttables.yaml
@@ -37,11 +37,11 @@
 # CHECK-NEXT:   UnloadDelayImportTable: 0x0
 # CHECK-NEXT:   Import {
 # CHECK-NEXT:     Symbol: left (0)
-# CHECK-NEXT:     Address: 0x1400010B8
+# CHECK-NEXT:     Address: 0x1400010DC
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Import {
 # CHECK-NEXT:     Symbol: right (0)
-# CHECK-NEXT:     Address: 0x1400010C4
+# CHECK-NEXT:     Address: 0x1400010E8
 # CHECK-NEXT:   }
 # CHECK-NEXT: }
 



More information about the llvm-commits mailing list