-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[LLD][COFF] Move delay IAT into its own .didat section. #137100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
This allows IMAGE_GUARD_PROTECT_DELAYLOAD_IAT|IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION flags to work. Add tests showing the .didat section is created with the proper characteristics.
12cc711 to
12e03d4
Compare
|
real-world test code: #include <assert.h>
#include <stdio.h>
#include <winsock2.h>
#include <windows.h>
__attribute__((__used__))
const IMAGE_LOAD_CONFIG_DIRECTORY _load_config_used = {
.Size = sizeof(_load_config_used),
.GuardFlags = 0x3000, /*IMAGE_GUARD_PROTECT_DELAYLOAD_IAT|IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION*/
};
int global_var = 42;
int main(void) {
unsigned short ret;
setvbuf(stdout, NULL, _IONBF, 0);
printf("MAIN: starting\n");
printf("MAIN: incremented global var = %d\n", ++global_var);
printf("MAIN: about to call htons\n");
ret = htons(0x1234);
printf("MAIN: htons returned %hx\n", ret);
printf("MAIN: incremented global var = %d\n", ++global_var);
printf("MAIN: OK\n");
return 0;
}build with (mingw-w64, but the code should work the same with clang-cl with different commandline options and maybe a different way to specify Before this PR, main.exe crashes when the loader tries to set up TLS stuff, which is now in a read-only page apparently. After, it works properly. |
|
@llvm/pr-subscribers-lld-coff @llvm/pr-subscribers-platform-windows Author: None (jeremyd2019) ChangesThis allows Add tests showing the Closes #134546 Patch is 35.75 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/137100.diff 12 Files Affected:
diff --git a/lld/COFF/DLL.cpp b/lld/COFF/DLL.cpp
index 0440507b71756..5d3813ddc6bd5 100644
--- a/lld/COFF/DLL.cpp
+++ b/lld/COFF/DLL.cpp
@@ -891,7 +891,7 @@ void IdataContents::create(COFFLinkerContext &ctx) {
dirs.push_back(make<NullChunk>(sizeof(ImportDirectoryTableEntry), 4));
}
-std::vector<Chunk *> DelayLoadContents::getChunks() {
+std::vector<Chunk *> DelayLoadContents::getRDataChunks() {
std::vector<Chunk *> v;
v.insert(v.end(), dirs.begin(), dirs.end());
v.insert(v.end(), names.begin(), names.end());
@@ -900,13 +900,6 @@ std::vector<Chunk *> DelayLoadContents::getChunks() {
return v;
}
-std::vector<Chunk *> DelayLoadContents::getDataChunks() {
- std::vector<Chunk *> v;
- v.insert(v.end(), moduleHandles.begin(), moduleHandles.end());
- v.insert(v.end(), addresses.begin(), addresses.end());
- return v;
-}
-
uint64_t DelayLoadContents::getDirSize() {
return dirs.size() * sizeof(delay_import_directory_table_entry);
}
diff --git a/lld/COFF/DLL.h b/lld/COFF/DLL.h
index 5105b79f15d31..83e2894371a72 100644
--- a/lld/COFF/DLL.h
+++ b/lld/COFF/DLL.h
@@ -43,8 +43,9 @@ class DelayLoadContents {
void add(DefinedImportData *sym) { imports.push_back(sym); }
bool empty() { return imports.empty(); }
void create();
- std::vector<Chunk *> getChunks();
- std::vector<Chunk *> getDataChunks();
+ ArrayRef<Chunk *> getChunks() { return addresses; }
+ std::vector<Chunk *> getRDataChunks();
+ ArrayRef<Chunk *> getDataChunks() { return moduleHandles; }
ArrayRef<Chunk *> getCodeChunks() { return thunks; }
ArrayRef<Chunk *> getCodePData() { return pdata; }
ArrayRef<Chunk *> getCodeUnwindInfo() { return unwindinfo; }
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index e3ff647209e72..ef5e7cdf69209 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -2015,7 +2015,6 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
// Add default section merging rules after user rules. User rules take
// precedence, but we will emit a warning if there is a conflict.
parseMerge(".idata=.rdata");
- parseMerge(".didat=.rdata");
parseMerge(".edata=.rdata");
parseMerge(".xdata=.rdata");
parseMerge(".00cfg=.rdata");
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index a5582cc8074d1..3e289d8783fa6 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -1083,7 +1083,7 @@ void Writer::createSections() {
pdataSec = createSection(".pdata", data | r);
idataSec = createSection(".idata", data | r);
edataSec = createSection(".edata", data | r);
- didatSec = createSection(".didat", data | r);
+ didatSec = createSection(".didat", data | r | w);
if (isArm64EC(ctx.config.machine))
a64xrmSec = createSection(".a64xrm", data | r);
rsrcSec = createSection(".rsrc", data | r);
@@ -1329,6 +1329,8 @@ void Writer::appendImportThunks() {
delayIdata.create();
for (Chunk *c : delayIdata.getChunks())
didatSec->addChunk(c);
+ for (Chunk *c : delayIdata.getRDataChunks())
+ rdataSec->addChunk(c);
for (Chunk *c : delayIdata.getDataChunks())
dataSec->addChunk(c);
for (Chunk *c : delayIdata.getCodeChunks())
diff --git a/lld/test/COFF/arm64-delayimport.yaml b/lld/test/COFF/arm64-delayimport.yaml
index abb9f25d5c379..28099ee76aeea 100644
--- a/lld/test/COFF/arm64-delayimport.yaml
+++ b/lld/test/COFF/arm64-delayimport.yaml
@@ -4,9 +4,10 @@
# 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 --no-print-imm-hex -d %t.exe | FileCheck %s --check-prefix DISASM
# RUN: llvm-readobj --coff-imports %t.exe | FileCheck %s -check-prefix IMPORTS
+# RUN: llvm-readobj --section-headers %t.exe | FileCheck %s -check-prefix SECTION
-# DISASM: 140001014: d0000011 adrp x17, 0x140003000
-# DISASM: 140001018: 91002231 add x17, x17, #8
+# DISASM: 140001014: f0000011 adrp x17, 0x140004000
+# DISASM: 140001018: 91000231 add x17, x17, #0
# DISASM: 14000101c: 14000001 b 0x140001020 <.text+0x20>
# DISASM: 140001020: a9b37bfd stp x29, x30, [sp, #-208]!
# DISASM: 140001024: 910003fd mov x29, sp
@@ -41,7 +42,7 @@
# IMPORTS: Name: library.dll
# IMPORTS: Attributes: 0x1
# IMPORTS: ModuleHandle: 0x3000
-# IMPORTS: ImportAddressTable: 0x3008
+# IMPORTS: ImportAddressTable: 0x4000
# IMPORTS: ImportNameTable: 0x2040
# IMPORTS: BoundDelayImportTable: 0x0
# IMPORTS: UnloadDelayImportTable: 0x0
@@ -50,6 +51,21 @@
# IMPORTS: Address: 0x140001014
# IMPORTS: }
# IMPORTS: }
+# SECTION: Name: .didat (2E 64 69 64 61 74 00 00)
+# SECTION-NEXT: VirtualSize: 0x10
+# SECTION-NEXT: VirtualAddress: 0x4000
+# SECTION-NEXT: RawDataSize: 512
+# SECTION-NEXT: PointerToRawData: 0x{{[0-9A-F]+}}
+# SECTION-NEXT: PointerToRelocations: 0x0
+# SECTION-NEXT: PointerToLineNumbers: 0x0
+# SECTION-NEXT: RelocationCount: 0
+# SECTION-NEXT: LineNumberCount: 0
+# SECTION-NEXT: Characteristics [ (0xC0000040)
+# SECTION-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
+# SECTION-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
+# SECTION-NEXT: IMAGE_SCN_MEM_WRITE (0x80000000)
+# SECTION-NEXT: ]
+# SECTION-NEXT: }
--- !COFF
header:
diff --git a/lld/test/COFF/arm64ec-delayimport.test b/lld/test/COFF/arm64ec-delayimport.test
index 1e0bd899ba323..c1a34740418e4 100644
--- a/lld/test/COFF/arm64ec-delayimport.test
+++ b/lld/test/COFF/arm64ec-delayimport.test
@@ -12,9 +12,9 @@ RUN: lld-link -machine:arm64ec -dll -noentry -out:out.dll loadconfig-arm64ec.obj
RUN: helper-mangled.obj test-arm64ec.lib test2-arm64ec.lib -delayload:test.dll -map
RUN: llvm-readobj --hex-dump=.test out.dll | FileCheck --check-prefix=TESTSEC %s
-TESTSEC: 0x18000a000 00600000 88700000 00200000 10100000
-TESTSEC-NEXT: 0x18000a010 08600000 90700000 10200000 30100000
-TESTSEC-NEXT: 0x18000a020 1c100000 3c100000 00300000
+TESTSEC: 0x18000b000 00600000 00900000 00200000 10100000
+TESTSEC-NEXT: 0x18000b010 08600000 08900000 10200000 30100000
+TESTSEC-NEXT: 0x18000b020 1c100000 3c100000 00300000
RUN: llvm-objdump -d out.dll | FileCheck --check-prefix=DISASM %s
DISASM: 0000000180001000 <.text>:
@@ -25,16 +25,16 @@ DISASM-NEXT: 18000100c: d65f03c0 ret
DISASM-NEXT: 180001010: b0000030 adrp x16, 0x180006000
DISASM-NEXT: 180001014: f9400210 ldr x16, [x16]
DISASM-NEXT: 180001018: d61f0200 br x16
-DISASM-NEXT: 18000101c: d000002b adrp x11, 0x180007000
-DISASM-NEXT: 180001020: f940456b ldr x11, [x11, #0x88]
+DISASM-NEXT: 18000101c: 9000004b adrp x11, 0x180009000
+DISASM-NEXT: 180001020: f940016b ldr x11, [x11]
DISASM-NEXT: 180001024: 9000000a adrp x10, 0x180001000 <.text>
DISASM-NEXT: 180001028: 9101414a add x10, x10, #0x50
DISASM-NEXT: 18000102c: 17fffff5 b 0x180001000 <.text>
DISASM-NEXT: 180001030: b0000030 adrp x16, 0x180006000
DISASM-NEXT: 180001034: f9400610 ldr x16, [x16, #0x8]
DISASM-NEXT: 180001038: d61f0200 br x16
-DISASM-NEXT: 18000103c: d000002b adrp x11, 0x180007000
-DISASM-NEXT: 180001040: f940496b ldr x11, [x11, #0x90]
+DISASM-NEXT: 18000103c: 9000004b adrp x11, 0x180009000
+DISASM-NEXT: 180001040: f940056b ldr x11, [x11, #0x8]
DISASM-NEXT: 180001044: 9000000a adrp x10, 0x180001000 <.text>
DISASM-NEXT: 180001048: 9101614a add x10, x10, #0x58
DISASM-NEXT: 18000104c: 17ffffed b 0x180001000 <.text>
@@ -43,13 +43,13 @@ DISASM-NEXT: 180001054: d65f03c0 ret
DISASM-NEXT: 180001058: 52800060 mov w0, #0x3 // =3
DISASM-NEXT: 18000105c: d65f03c0 ret
DISASM-NEXT: ...
-DISASM-NEXT: 180002000: ff 25 82 50 00 00 jmpq *0x5082(%rip) # 0x180007088
+DISASM-NEXT: 180002000: ff 25 fa 6f 00 00 jmpq *0x6ffa(%rip) # 0x180009000
DISASM-NEXT: ...
DISASM-NEXT: 18000200e: 00 00 addb %al, (%rax)
-DISASM-NEXT: 180002010: ff 25 7a 50 00 00 jmpq *0x507a(%rip) # 0x180007090
-DISASM-NEXT: 180002016: 48 8d 05 6b 50 00 00 leaq 0x506b(%rip), %rax # 0x180007088
+DISASM-NEXT: 180002010: ff 25 f2 6f 00 00 jmpq *0x6ff2(%rip) # 0x180009008
+DISASM-NEXT: 180002016: 48 8d 05 e3 6f 00 00 leaq 0x6fe3(%rip), %rax # 0x180009000
DISASM-NEXT: 18000201d: e9 0c 00 00 00 jmp 0x18000202e <.text+0x102e>
-DISASM-NEXT: 180002022: 48 8d 05 67 50 00 00 leaq 0x5067(%rip), %rax # 0x180007090
+DISASM-NEXT: 180002022: 48 8d 05 df 6f 00 00 leaq 0x6fdf(%rip), %rax # 0x180009008
DISASM-NEXT: 180002029: e9 00 00 00 00 jmp 0x18000202e <.text+0x102e>
DISASM-NEXT: 18000202e: 51 pushq %rcx
DISASM-NEXT: 18000202f: 52 pushq %rdx
@@ -61,7 +61,7 @@ DISASM-NEXT: 18000203d: 66 0f 7f 4c 24 10 movdqa %xmm1, 0x10(%rsp)
DISASM-NEXT: 180002043: 66 0f 7f 54 24 20 movdqa %xmm2, 0x20(%rsp)
DISASM-NEXT: 180002049: 66 0f 7f 5c 24 30 movdqa %xmm3, 0x30(%rsp)
DISASM-NEXT: 18000204f: 48 8b d0 movq %rax, %rdx
-DISASM-NEXT: 180002052: 48 8d 0d a7 21 00 00 leaq 0x21a7(%rip), %rcx # 0x180004200
+DISASM-NEXT: 180002052: 48 8d 0d a7 1f 00 00 leaq 0x1fa7(%rip), %rcx # 0x180004000
DISASM-NEXT: 180002059: e8 aa ef ff ff callq 0x180001008 <.text+0x8>
DISASM-NEXT: 18000205e: 66 0f 6f 04 24 movdqa (%rsp), %xmm0
DISASM-NEXT: 180002063: 66 0f 6f 4c 24 10 movdqa 0x10(%rsp), %xmm1
@@ -77,15 +77,15 @@ DISASM-NEXT: 18000207f: ff e0 jmpq *%rax
RUN: llvm-readobj --coff-load-config out.dll | FileCheck --check-prefix=LOADCFG %s
LOADCFG: CHPEMetadata [
LOADCFG: AuxiliaryDelayloadIAT: 0x6000
-LOADCFG-NEXT: AuxiliaryDelayloadIATCopy: 0x4000
+LOADCFG-NEXT: AuxiliaryDelayloadIATCopy: 0x4078
RUN: llvm-readobj --coff-imports out.dll | FileCheck --check-prefix=IMPORTS %s
IMPORTS: DelayImport {
IMPORTS-NEXT: Name: test.dll
IMPORTS-NEXT: Attributes: 0x1
IMPORTS-NEXT: ModuleHandle: 0x7080
-IMPORTS-NEXT: ImportAddressTable: 0x7088
-IMPORTS-NEXT: ImportNameTable: 0x4240
+IMPORTS-NEXT: ImportAddressTable: 0x9000
+IMPORTS-NEXT: ImportNameTable: 0x4040
IMPORTS-NEXT: BoundDelayImportTable: 0x0
IMPORTS-NEXT: UnloadDelayImportTable: 0x0
IMPORTS-NEXT: Import {
@@ -109,17 +109,17 @@ MAP-NEXT: 0001:00000058 func2_exit_thunk 0000000180001058 t
MAP-NEXT: 0001:00001000 func 0000000180002000 test-arm64ec:test.dll
MAP-NEXT: 0001:00001010 func2 0000000180002010 test-arm64ec:test.dll
MAP-NEXT: 0002:00000000 __imp_data 0000000180003000 test2-arm64ec:test2.dll
-MAP-NEXT: 0000:00000000 __hybrid_auxiliary_delayload_iat_copy 0000000180004000 <linker-defined>
-MAP-NEXT: 0002:00001000 __auximpcopy_func 0000000180004000 test-arm64ec:test.dll
-MAP-NEXT: 0002:00001008 __auximpcopy_func2 0000000180004008 test-arm64ec:test.dll
+MAP-NEXT: 0000:00000000 __hybrid_auxiliary_delayload_iat_copy 0000000180004078 <linker-defined>
+MAP-NEXT: 0002:00001078 __auximpcopy_func 0000000180004078 test-arm64ec:test.dll
+MAP-NEXT: 0002:00001080 __auximpcopy_func2 0000000180004080 test-arm64ec:test.dll
MAP: 0002:00003000 __imp_func 0000000180006000 test-arm64ec:test.dll
MAP-NEXT: 0002:00003008 __imp_func2 0000000180006008 test-arm64ec:test.dll
-MAP: 0003:00000088 __imp_aux_func 0000000180007088 test-arm64ec:test.dll
-MAP-NEXT: 0003:00000090 __imp_aux_func2 0000000180007090 test-arm64ec:test.dll
+MAP: 0005:00000000 __imp_aux_func 0000000180009000 test-arm64ec:test.dll
+MAP-NEXT: 0005:00000008 __imp_aux_func2 0000000180009008 test-arm64ec:test.dll
RUN: llvm-readobj --hex-dump=.rdata out.dll | FileCheck --check-prefix=RDATA %s
-RDATA: 0x180004000 1c100080 01000000 3c100080 01000000
-RDATA-NEXT: 0x180004010 00000000 00000000
+RDATA: 0x180004070 {{[0-9a-f]{8} [0-9a-f]{8} }}1c100080 01000000
+RDATA-NEXT: 0x180004080 3c100080 01000000 00000000 00000000
RDATA: 0x180006000 1c100080 01000000 3c100080 01000000
RDATA-NEXT: 0x180006010 00000000 00000000
@@ -127,11 +127,11 @@ RUN: llvm-readobj --coff-basereloc out.dll | FileCheck --check-prefix=RELOC %s
RELOC: BaseReloc [
RELOC-NEXT: Entry {
RELOC-NEXT: Type: DIR64
-RELOC-NEXT: Address: 0x4000
+RELOC-NEXT: Address: 0x4078
RELOC-NEXT: }
RELOC-NEXT: Entry {
RELOC-NEXT: Type: DIR64
-RELOC-NEXT: Address: 0x4008
+RELOC-NEXT: Address: 0x4080
RELOC-NEXT: }
RELOC: Address: 0x6000
RELOC-NEXT: }
@@ -141,7 +141,7 @@ RELOC-NEXT: Address: 0x6008
RELOC-NEXT: }
RUN: llvm-readobj --hex-dump=.pdata out.dll | FileCheck --check-prefix=PDATA %s
-PDATA: 0x180008000 2e200000 81200000 18400000
+PDATA: 0x180008000 2e200000 81200000 90400000
Verify that a demangled version of __delayLoadHelper2 can be used.
diff --git a/lld/test/COFF/arm64x-delayimport.test b/lld/test/COFF/arm64x-delayimport.test
index 56923ef748d09..e2a20ac6b653e 100644
--- a/lld/test/COFF/arm64x-delayimport.test
+++ b/lld/test/COFF/arm64x-delayimport.test
@@ -20,8 +20,8 @@ IMPORTS: DelayImport {
IMPORTS-NEXT: Name: test.dll
IMPORTS-NEXT: Attributes: 0x1
IMPORTS-NEXT: ModuleHandle: 0x6080
-IMPORTS-NEXT: ImportAddressTable: 0x6088
-IMPORTS-NEXT: ImportNameTable: 0x4390
+IMPORTS-NEXT: ImportAddressTable: 0x8000
+IMPORTS-NEXT: ImportNameTable: 0x4180
IMPORTS-NEXT: BoundDelayImportTable: 0x0
IMPORTS-NEXT: UnloadDelayImportTable: 0x0
IMPORTS-NEXT: Import {
@@ -34,8 +34,8 @@ IMPORTS: DelayImport {
IMPORTS-NEXT: Name: test.dll
IMPORTS-NEXT: Attributes: 0x1
IMPORTS-NEXT: ModuleHandle: 0x6080
-IMPORTS-NEXT: ImportAddressTable: 0x6098
-IMPORTS-NEXT: ImportNameTable: 0x43A0
+IMPORTS-NEXT: ImportAddressTable: 0x8010
+IMPORTS-NEXT: ImportNameTable: 0x4190
IMPORTS-NEXT: BoundDelayImportTable: 0x0
IMPORTS-NEXT: UnloadDelayImportTable: 0x0
IMPORTS-NEXT: Import {
@@ -46,20 +46,20 @@ IMPORTS-NEXT: }
IMPORTS-NEXT: }
RUN: llvm-readobj --hex-dump=.test out.dll | FileCheck --check-prefix=TESTSEC %s
-TESTSEC: 0x180009000 10500000 98600000 00300000 10200000
+TESTSEC: 0x18000a000 10500000 10800000 00300000 10200000
RUN: llvm-readobj --hex-dump=.testa out.dll | FileCheck --check-prefix=TESTSECA %s
-TESTSECA: 0x18000a000 88600000 08100000
+TESTSECA: 0x18000b000 00800000 08100000
RUN: llvm-objdump -d out.dll | FileCheck --check-prefix=DISASM %s
DISASM: 0000000180001000 <.text>:
DISASM-NEXT: 180001000: 52800060 mov w0, #0x3 // =3
DISASM-NEXT: 180001004: d65f03c0 ret
-DISASM-NEXT: 180001008: b0000030 adrp x16, 0x180006000
-DISASM-NEXT: 18000100c: f9404610 ldr x16, [x16, #0x88]
+DISASM-NEXT: 180001008: f0000030 adrp x16, 0x180008000
+DISASM-NEXT: 18000100c: f9400210 ldr x16, [x16]
DISASM-NEXT: 180001010: d61f0200 br x16
-DISASM-NEXT: 180001014: b0000031 adrp x17, 0x180006000
-DISASM-NEXT: 180001018: 91022231 add x17, x17, #0x88
+DISASM-NEXT: 180001014: f0000031 adrp x17, 0x180008000
+DISASM-NEXT: 180001018: 91000231 add x17, x17, #0x0
DISASM-NEXT: 18000101c: 14000001 b 0x180001020 <.text+0x20>
DISASM-NEXT: 180001020: a9b37bfd stp x29, x30, [sp, #-0xd0]!
DISASM-NEXT: 180001024: 910003fd mov x29, sp
@@ -73,7 +73,7 @@ DISASM-NEXT: 180001040: ad0497e4 stp q4, q5, [sp, #0x90]
DISASM-NEXT: 180001044: ad059fe6 stp q6, q7, [sp, #0xb0]
DISASM-NEXT: 180001048: aa1103e1 mov x1, x17
DISASM-NEXT: 18000104c: f0000000 adrp x0, 0x180004000
-DISASM-NEXT: 180001050: 910d4000 add x0, x0, #0x350
+DISASM-NEXT: 180001050: 91050000 add x0, x0, #0x140
DISASM-NEXT: 180001054: 97ffffeb bl 0x180001000 <.text>
DISASM-NEXT: 180001058: aa0003f0 mov x16, x0
DISASM-NEXT: 18000105c: ad459fe6 ldp q6, q7, [sp, #0xb0]
@@ -94,16 +94,16 @@ DISASM-NEXT: 18000200c: d65f03c0 ret
DISASM-NEXT: 180002010: f0000010 adrp x16, 0x180005000
DISASM-NEXT: 180002014: f9400a10 ldr x16, [x16, #0x10]
DISASM-NEXT: 180002018: d61f0200 br x16
-DISASM-NEXT: 18000201c: 9000002b adrp x11, 0x180006000
-DISASM-NEXT: 180002020: f9404d6b ldr x11, [x11, #0x98]
+DISASM-NEXT: 18000201c: d000002b adrp x11, 0x180008000
+DISASM-NEXT: 180002020: f940096b ldr x11, [x11, #0x10]
DISASM-NEXT: 180002024: 9000000a adrp x10, 0x180002000 <.text+0x1000>
DISASM-NEXT: 180002028: 9100c14a add x10, x10, #0x30
DISASM-NEXT: 18000202c: 17fffff5 b 0x180002000 <.text+0x1000>
DISASM-NEXT: 180002030: 52800080 mov w0, #0x4 // =4
DISASM-NEXT: 180002034: d65f03c0 ret
DISASM-NEXT: ...
-DISASM-NEXT: 180003000: ff 25 92 30 00 00 jmpq *0x3092(%rip) # 0x180006098
-DISASM-NEXT: 180003006: 48 8d 05 8b 30 00 00 leaq 0x308b(%rip), %rax # 0x180006098
+DISASM-NEXT: 180003000: ff 25 0a 50 00 00 jmpq *0x500a(%rip) # 0x180008010
+DISASM-NEXT: 180003006: 48 8d 05 03 50 00 00 leaq 0x5003(%rip), %rax # 0x180008010
DISASM-NEXT: 18000300d: e9 00 00 00 00 jmp 0x180003012 <.text+0x2012>
DISASM-NEXT: 180003012: 51 pushq %rcx
DISASM-NEXT: 180003013: 52 pushq %rdx
@@ -115,7 +115,7 @@ DISASM-NEXT: 180003021: 66 0f 7f 4c 24 10 movdqa %xmm1, 0x10(%rsp)
DISASM-NEXT: 180003027: 66 0f 7f 54 24 20 movdqa %xmm2, 0x20(%rsp)
DISASM-NEXT: 18000302d: 66 0f 7f 5c 24 30 movdqa %xmm3, 0x30(%rsp)
DISASM-NEXT: 180003033: 48 8b d0 movq %rax, %rdx
-DISASM-NEXT: 180003036: 48 8d 0d 13 13 00 00 leaq 0x1313(%rip), %rcx # 0x180004350
+DISASM-NEXT: 180003036: 48 8d 0d 03 11 00 00 leaq 0x1103(%rip), %rcx # 0x180004140
DISASM-NEXT: 18000303d: e8 c6 ef ff ff callq 0x180002008 <.text+0x1008>
DISASM-NEXT: 180003042: 66 0f 6f 04 24 movdqa (%rsp), %xmm0
DISASM-NEXT: 180003047: 66 0f 6f 4c 24 10 movdqa 0x10(%rsp), %xmm1
@@ -130,7 +130,7 @@ DISASM-NEXT: 180003063: ff e0 jmpq *%rax
RUN: llvm-readobj --coff-load-config out.dll | FileCheck --check-prefix=LOADCFG %s
LOADCFG: AuxiliaryDelayloadIAT: 0x5000
-LOADCFG-NEXT: AuxiliaryDelayloadIATCopy: 0x4140
+LOADCFG-NEXT: AuxiliaryDelayloadIATCopy: 0x41C0
RUN: llvm-readobj --hex-dump=.rdata out.dll | FileCheck --check-prefix=AUXIAT %s
AUXIAT: 0x180005000 00000000 00000000 00000000 00000000
@@ -147,8 +147,8 @@ NATIVE-IMPORTS: DelayImport {
NATIVE-IMPORTS-NEXT: Name: test.dll
NATIVE-IMPORTS-NEXT: Attributes: 0x1
NATIVE-IMPORTS-NEXT: ModuleHandle: 0x5080
-NATIVE-IMPORTS-NEXT: ImportAddressTable: 0x5088
-NATIVE-IMPORTS-NEXT: ImportNameTable: 0x3370
+NATIVE-IMPORTS-NEXT: ImportAddressTable: 0x6000
+NATIVE-IMPORTS-NEXT: ImportNameTable: 0x3180
NATIVE-IMPORTS-NEXT: BoundDelayImportTable: 0x0
NATIVE-IMPORTS-NEXT: UnloadDelayImportTable: 0x0
NATIVE-IMPORTS-NEXT: Import {
@@ -164,25 +164,25 @@ NATIVE-IMPORTS-NEXT: DelayImport {
NATIVE-IMPORTS-NEXT: Name: test.dll
NATIVE-IMPORTS-NEXT: Attributes: 0x1
NATIVE-IMPORTS-NEXT: ModuleHandle: 0x5080
-NATIVE-IMPORTS-NEXT: ImportAddressTable: 0x5098
-NATIVE-IMPORTS-NEXT: ImportNameTable: 0x3380
+NATIVE-IMPORTS-NEXT: ImportAddressTable: 0x6010
+NATIVE-IMPORTS-NEXT: ImportNameTable: 0x3190
NATIVE-IMPORTS-NEXT: BoundDelayImportTable: 0x0
NATIVE-IMPORTS-NEXT: UnloadDelayImportTable: 0x0
NATIVE-IMPORTS-NEXT: }
NATIVE-IMPORTS-NEXT: }
RUN: llvm-readobj --hex-dump=.testa out-native.dll | FileCheck --check-prefix=NATIVE-TESTSECA %s
-...
[truncated]
|
|
@llvm/pr-subscribers-lld Author: None (jeremyd2019) ChangesThis allows Add tests showing the Closes #134546 Patch is 35.75 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/137100.diff 12 Files Affected:
diff --git a/lld/COFF/DLL.cpp b/lld/COFF/DLL.cpp
index 0440507b71756..5d3813ddc6bd5 100644
--- a/lld/COFF/DLL.cpp
+++ b/lld/COFF/DLL.cpp
@@ -891,7 +891,7 @@ void IdataContents::create(COFFLinkerContext &ctx) {
dirs.push_back(make<NullChunk>(sizeof(ImportDirectoryTableEntry), 4));
}
-std::vector<Chunk *> DelayLoadContents::getChunks() {
+std::vector<Chunk *> DelayLoadContents::getRDataChunks() {
std::vector<Chunk *> v;
v.insert(v.end(), dirs.begin(), dirs.end());
v.insert(v.end(), names.begin(), names.end());
@@ -900,13 +900,6 @@ std::vector<Chunk *> DelayLoadContents::getChunks() {
return v;
}
-std::vector<Chunk *> DelayLoadContents::getDataChunks() {
- std::vector<Chunk *> v;
- v.insert(v.end(), moduleHandles.begin(), moduleHandles.end());
- v.insert(v.end(), addresses.begin(), addresses.end());
- return v;
-}
-
uint64_t DelayLoadContents::getDirSize() {
return dirs.size() * sizeof(delay_import_directory_table_entry);
}
diff --git a/lld/COFF/DLL.h b/lld/COFF/DLL.h
index 5105b79f15d31..83e2894371a72 100644
--- a/lld/COFF/DLL.h
+++ b/lld/COFF/DLL.h
@@ -43,8 +43,9 @@ class DelayLoadContents {
void add(DefinedImportData *sym) { imports.push_back(sym); }
bool empty() { return imports.empty(); }
void create();
- std::vector<Chunk *> getChunks();
- std::vector<Chunk *> getDataChunks();
+ ArrayRef<Chunk *> getChunks() { return addresses; }
+ std::vector<Chunk *> getRDataChunks();
+ ArrayRef<Chunk *> getDataChunks() { return moduleHandles; }
ArrayRef<Chunk *> getCodeChunks() { return thunks; }
ArrayRef<Chunk *> getCodePData() { return pdata; }
ArrayRef<Chunk *> getCodeUnwindInfo() { return unwindinfo; }
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index e3ff647209e72..ef5e7cdf69209 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -2015,7 +2015,6 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
// Add default section merging rules after user rules. User rules take
// precedence, but we will emit a warning if there is a conflict.
parseMerge(".idata=.rdata");
- parseMerge(".didat=.rdata");
parseMerge(".edata=.rdata");
parseMerge(".xdata=.rdata");
parseMerge(".00cfg=.rdata");
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index a5582cc8074d1..3e289d8783fa6 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -1083,7 +1083,7 @@ void Writer::createSections() {
pdataSec = createSection(".pdata", data | r);
idataSec = createSection(".idata", data | r);
edataSec = createSection(".edata", data | r);
- didatSec = createSection(".didat", data | r);
+ didatSec = createSection(".didat", data | r | w);
if (isArm64EC(ctx.config.machine))
a64xrmSec = createSection(".a64xrm", data | r);
rsrcSec = createSection(".rsrc", data | r);
@@ -1329,6 +1329,8 @@ void Writer::appendImportThunks() {
delayIdata.create();
for (Chunk *c : delayIdata.getChunks())
didatSec->addChunk(c);
+ for (Chunk *c : delayIdata.getRDataChunks())
+ rdataSec->addChunk(c);
for (Chunk *c : delayIdata.getDataChunks())
dataSec->addChunk(c);
for (Chunk *c : delayIdata.getCodeChunks())
diff --git a/lld/test/COFF/arm64-delayimport.yaml b/lld/test/COFF/arm64-delayimport.yaml
index abb9f25d5c379..28099ee76aeea 100644
--- a/lld/test/COFF/arm64-delayimport.yaml
+++ b/lld/test/COFF/arm64-delayimport.yaml
@@ -4,9 +4,10 @@
# 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 --no-print-imm-hex -d %t.exe | FileCheck %s --check-prefix DISASM
# RUN: llvm-readobj --coff-imports %t.exe | FileCheck %s -check-prefix IMPORTS
+# RUN: llvm-readobj --section-headers %t.exe | FileCheck %s -check-prefix SECTION
-# DISASM: 140001014: d0000011 adrp x17, 0x140003000
-# DISASM: 140001018: 91002231 add x17, x17, #8
+# DISASM: 140001014: f0000011 adrp x17, 0x140004000
+# DISASM: 140001018: 91000231 add x17, x17, #0
# DISASM: 14000101c: 14000001 b 0x140001020 <.text+0x20>
# DISASM: 140001020: a9b37bfd stp x29, x30, [sp, #-208]!
# DISASM: 140001024: 910003fd mov x29, sp
@@ -41,7 +42,7 @@
# IMPORTS: Name: library.dll
# IMPORTS: Attributes: 0x1
# IMPORTS: ModuleHandle: 0x3000
-# IMPORTS: ImportAddressTable: 0x3008
+# IMPORTS: ImportAddressTable: 0x4000
# IMPORTS: ImportNameTable: 0x2040
# IMPORTS: BoundDelayImportTable: 0x0
# IMPORTS: UnloadDelayImportTable: 0x0
@@ -50,6 +51,21 @@
# IMPORTS: Address: 0x140001014
# IMPORTS: }
# IMPORTS: }
+# SECTION: Name: .didat (2E 64 69 64 61 74 00 00)
+# SECTION-NEXT: VirtualSize: 0x10
+# SECTION-NEXT: VirtualAddress: 0x4000
+# SECTION-NEXT: RawDataSize: 512
+# SECTION-NEXT: PointerToRawData: 0x{{[0-9A-F]+}}
+# SECTION-NEXT: PointerToRelocations: 0x0
+# SECTION-NEXT: PointerToLineNumbers: 0x0
+# SECTION-NEXT: RelocationCount: 0
+# SECTION-NEXT: LineNumberCount: 0
+# SECTION-NEXT: Characteristics [ (0xC0000040)
+# SECTION-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
+# SECTION-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
+# SECTION-NEXT: IMAGE_SCN_MEM_WRITE (0x80000000)
+# SECTION-NEXT: ]
+# SECTION-NEXT: }
--- !COFF
header:
diff --git a/lld/test/COFF/arm64ec-delayimport.test b/lld/test/COFF/arm64ec-delayimport.test
index 1e0bd899ba323..c1a34740418e4 100644
--- a/lld/test/COFF/arm64ec-delayimport.test
+++ b/lld/test/COFF/arm64ec-delayimport.test
@@ -12,9 +12,9 @@ RUN: lld-link -machine:arm64ec -dll -noentry -out:out.dll loadconfig-arm64ec.obj
RUN: helper-mangled.obj test-arm64ec.lib test2-arm64ec.lib -delayload:test.dll -map
RUN: llvm-readobj --hex-dump=.test out.dll | FileCheck --check-prefix=TESTSEC %s
-TESTSEC: 0x18000a000 00600000 88700000 00200000 10100000
-TESTSEC-NEXT: 0x18000a010 08600000 90700000 10200000 30100000
-TESTSEC-NEXT: 0x18000a020 1c100000 3c100000 00300000
+TESTSEC: 0x18000b000 00600000 00900000 00200000 10100000
+TESTSEC-NEXT: 0x18000b010 08600000 08900000 10200000 30100000
+TESTSEC-NEXT: 0x18000b020 1c100000 3c100000 00300000
RUN: llvm-objdump -d out.dll | FileCheck --check-prefix=DISASM %s
DISASM: 0000000180001000 <.text>:
@@ -25,16 +25,16 @@ DISASM-NEXT: 18000100c: d65f03c0 ret
DISASM-NEXT: 180001010: b0000030 adrp x16, 0x180006000
DISASM-NEXT: 180001014: f9400210 ldr x16, [x16]
DISASM-NEXT: 180001018: d61f0200 br x16
-DISASM-NEXT: 18000101c: d000002b adrp x11, 0x180007000
-DISASM-NEXT: 180001020: f940456b ldr x11, [x11, #0x88]
+DISASM-NEXT: 18000101c: 9000004b adrp x11, 0x180009000
+DISASM-NEXT: 180001020: f940016b ldr x11, [x11]
DISASM-NEXT: 180001024: 9000000a adrp x10, 0x180001000 <.text>
DISASM-NEXT: 180001028: 9101414a add x10, x10, #0x50
DISASM-NEXT: 18000102c: 17fffff5 b 0x180001000 <.text>
DISASM-NEXT: 180001030: b0000030 adrp x16, 0x180006000
DISASM-NEXT: 180001034: f9400610 ldr x16, [x16, #0x8]
DISASM-NEXT: 180001038: d61f0200 br x16
-DISASM-NEXT: 18000103c: d000002b adrp x11, 0x180007000
-DISASM-NEXT: 180001040: f940496b ldr x11, [x11, #0x90]
+DISASM-NEXT: 18000103c: 9000004b adrp x11, 0x180009000
+DISASM-NEXT: 180001040: f940056b ldr x11, [x11, #0x8]
DISASM-NEXT: 180001044: 9000000a adrp x10, 0x180001000 <.text>
DISASM-NEXT: 180001048: 9101614a add x10, x10, #0x58
DISASM-NEXT: 18000104c: 17ffffed b 0x180001000 <.text>
@@ -43,13 +43,13 @@ DISASM-NEXT: 180001054: d65f03c0 ret
DISASM-NEXT: 180001058: 52800060 mov w0, #0x3 // =3
DISASM-NEXT: 18000105c: d65f03c0 ret
DISASM-NEXT: ...
-DISASM-NEXT: 180002000: ff 25 82 50 00 00 jmpq *0x5082(%rip) # 0x180007088
+DISASM-NEXT: 180002000: ff 25 fa 6f 00 00 jmpq *0x6ffa(%rip) # 0x180009000
DISASM-NEXT: ...
DISASM-NEXT: 18000200e: 00 00 addb %al, (%rax)
-DISASM-NEXT: 180002010: ff 25 7a 50 00 00 jmpq *0x507a(%rip) # 0x180007090
-DISASM-NEXT: 180002016: 48 8d 05 6b 50 00 00 leaq 0x506b(%rip), %rax # 0x180007088
+DISASM-NEXT: 180002010: ff 25 f2 6f 00 00 jmpq *0x6ff2(%rip) # 0x180009008
+DISASM-NEXT: 180002016: 48 8d 05 e3 6f 00 00 leaq 0x6fe3(%rip), %rax # 0x180009000
DISASM-NEXT: 18000201d: e9 0c 00 00 00 jmp 0x18000202e <.text+0x102e>
-DISASM-NEXT: 180002022: 48 8d 05 67 50 00 00 leaq 0x5067(%rip), %rax # 0x180007090
+DISASM-NEXT: 180002022: 48 8d 05 df 6f 00 00 leaq 0x6fdf(%rip), %rax # 0x180009008
DISASM-NEXT: 180002029: e9 00 00 00 00 jmp 0x18000202e <.text+0x102e>
DISASM-NEXT: 18000202e: 51 pushq %rcx
DISASM-NEXT: 18000202f: 52 pushq %rdx
@@ -61,7 +61,7 @@ DISASM-NEXT: 18000203d: 66 0f 7f 4c 24 10 movdqa %xmm1, 0x10(%rsp)
DISASM-NEXT: 180002043: 66 0f 7f 54 24 20 movdqa %xmm2, 0x20(%rsp)
DISASM-NEXT: 180002049: 66 0f 7f 5c 24 30 movdqa %xmm3, 0x30(%rsp)
DISASM-NEXT: 18000204f: 48 8b d0 movq %rax, %rdx
-DISASM-NEXT: 180002052: 48 8d 0d a7 21 00 00 leaq 0x21a7(%rip), %rcx # 0x180004200
+DISASM-NEXT: 180002052: 48 8d 0d a7 1f 00 00 leaq 0x1fa7(%rip), %rcx # 0x180004000
DISASM-NEXT: 180002059: e8 aa ef ff ff callq 0x180001008 <.text+0x8>
DISASM-NEXT: 18000205e: 66 0f 6f 04 24 movdqa (%rsp), %xmm0
DISASM-NEXT: 180002063: 66 0f 6f 4c 24 10 movdqa 0x10(%rsp), %xmm1
@@ -77,15 +77,15 @@ DISASM-NEXT: 18000207f: ff e0 jmpq *%rax
RUN: llvm-readobj --coff-load-config out.dll | FileCheck --check-prefix=LOADCFG %s
LOADCFG: CHPEMetadata [
LOADCFG: AuxiliaryDelayloadIAT: 0x6000
-LOADCFG-NEXT: AuxiliaryDelayloadIATCopy: 0x4000
+LOADCFG-NEXT: AuxiliaryDelayloadIATCopy: 0x4078
RUN: llvm-readobj --coff-imports out.dll | FileCheck --check-prefix=IMPORTS %s
IMPORTS: DelayImport {
IMPORTS-NEXT: Name: test.dll
IMPORTS-NEXT: Attributes: 0x1
IMPORTS-NEXT: ModuleHandle: 0x7080
-IMPORTS-NEXT: ImportAddressTable: 0x7088
-IMPORTS-NEXT: ImportNameTable: 0x4240
+IMPORTS-NEXT: ImportAddressTable: 0x9000
+IMPORTS-NEXT: ImportNameTable: 0x4040
IMPORTS-NEXT: BoundDelayImportTable: 0x0
IMPORTS-NEXT: UnloadDelayImportTable: 0x0
IMPORTS-NEXT: Import {
@@ -109,17 +109,17 @@ MAP-NEXT: 0001:00000058 func2_exit_thunk 0000000180001058 t
MAP-NEXT: 0001:00001000 func 0000000180002000 test-arm64ec:test.dll
MAP-NEXT: 0001:00001010 func2 0000000180002010 test-arm64ec:test.dll
MAP-NEXT: 0002:00000000 __imp_data 0000000180003000 test2-arm64ec:test2.dll
-MAP-NEXT: 0000:00000000 __hybrid_auxiliary_delayload_iat_copy 0000000180004000 <linker-defined>
-MAP-NEXT: 0002:00001000 __auximpcopy_func 0000000180004000 test-arm64ec:test.dll
-MAP-NEXT: 0002:00001008 __auximpcopy_func2 0000000180004008 test-arm64ec:test.dll
+MAP-NEXT: 0000:00000000 __hybrid_auxiliary_delayload_iat_copy 0000000180004078 <linker-defined>
+MAP-NEXT: 0002:00001078 __auximpcopy_func 0000000180004078 test-arm64ec:test.dll
+MAP-NEXT: 0002:00001080 __auximpcopy_func2 0000000180004080 test-arm64ec:test.dll
MAP: 0002:00003000 __imp_func 0000000180006000 test-arm64ec:test.dll
MAP-NEXT: 0002:00003008 __imp_func2 0000000180006008 test-arm64ec:test.dll
-MAP: 0003:00000088 __imp_aux_func 0000000180007088 test-arm64ec:test.dll
-MAP-NEXT: 0003:00000090 __imp_aux_func2 0000000180007090 test-arm64ec:test.dll
+MAP: 0005:00000000 __imp_aux_func 0000000180009000 test-arm64ec:test.dll
+MAP-NEXT: 0005:00000008 __imp_aux_func2 0000000180009008 test-arm64ec:test.dll
RUN: llvm-readobj --hex-dump=.rdata out.dll | FileCheck --check-prefix=RDATA %s
-RDATA: 0x180004000 1c100080 01000000 3c100080 01000000
-RDATA-NEXT: 0x180004010 00000000 00000000
+RDATA: 0x180004070 {{[0-9a-f]{8} [0-9a-f]{8} }}1c100080 01000000
+RDATA-NEXT: 0x180004080 3c100080 01000000 00000000 00000000
RDATA: 0x180006000 1c100080 01000000 3c100080 01000000
RDATA-NEXT: 0x180006010 00000000 00000000
@@ -127,11 +127,11 @@ RUN: llvm-readobj --coff-basereloc out.dll | FileCheck --check-prefix=RELOC %s
RELOC: BaseReloc [
RELOC-NEXT: Entry {
RELOC-NEXT: Type: DIR64
-RELOC-NEXT: Address: 0x4000
+RELOC-NEXT: Address: 0x4078
RELOC-NEXT: }
RELOC-NEXT: Entry {
RELOC-NEXT: Type: DIR64
-RELOC-NEXT: Address: 0x4008
+RELOC-NEXT: Address: 0x4080
RELOC-NEXT: }
RELOC: Address: 0x6000
RELOC-NEXT: }
@@ -141,7 +141,7 @@ RELOC-NEXT: Address: 0x6008
RELOC-NEXT: }
RUN: llvm-readobj --hex-dump=.pdata out.dll | FileCheck --check-prefix=PDATA %s
-PDATA: 0x180008000 2e200000 81200000 18400000
+PDATA: 0x180008000 2e200000 81200000 90400000
Verify that a demangled version of __delayLoadHelper2 can be used.
diff --git a/lld/test/COFF/arm64x-delayimport.test b/lld/test/COFF/arm64x-delayimport.test
index 56923ef748d09..e2a20ac6b653e 100644
--- a/lld/test/COFF/arm64x-delayimport.test
+++ b/lld/test/COFF/arm64x-delayimport.test
@@ -20,8 +20,8 @@ IMPORTS: DelayImport {
IMPORTS-NEXT: Name: test.dll
IMPORTS-NEXT: Attributes: 0x1
IMPORTS-NEXT: ModuleHandle: 0x6080
-IMPORTS-NEXT: ImportAddressTable: 0x6088
-IMPORTS-NEXT: ImportNameTable: 0x4390
+IMPORTS-NEXT: ImportAddressTable: 0x8000
+IMPORTS-NEXT: ImportNameTable: 0x4180
IMPORTS-NEXT: BoundDelayImportTable: 0x0
IMPORTS-NEXT: UnloadDelayImportTable: 0x0
IMPORTS-NEXT: Import {
@@ -34,8 +34,8 @@ IMPORTS: DelayImport {
IMPORTS-NEXT: Name: test.dll
IMPORTS-NEXT: Attributes: 0x1
IMPORTS-NEXT: ModuleHandle: 0x6080
-IMPORTS-NEXT: ImportAddressTable: 0x6098
-IMPORTS-NEXT: ImportNameTable: 0x43A0
+IMPORTS-NEXT: ImportAddressTable: 0x8010
+IMPORTS-NEXT: ImportNameTable: 0x4190
IMPORTS-NEXT: BoundDelayImportTable: 0x0
IMPORTS-NEXT: UnloadDelayImportTable: 0x0
IMPORTS-NEXT: Import {
@@ -46,20 +46,20 @@ IMPORTS-NEXT: }
IMPORTS-NEXT: }
RUN: llvm-readobj --hex-dump=.test out.dll | FileCheck --check-prefix=TESTSEC %s
-TESTSEC: 0x180009000 10500000 98600000 00300000 10200000
+TESTSEC: 0x18000a000 10500000 10800000 00300000 10200000
RUN: llvm-readobj --hex-dump=.testa out.dll | FileCheck --check-prefix=TESTSECA %s
-TESTSECA: 0x18000a000 88600000 08100000
+TESTSECA: 0x18000b000 00800000 08100000
RUN: llvm-objdump -d out.dll | FileCheck --check-prefix=DISASM %s
DISASM: 0000000180001000 <.text>:
DISASM-NEXT: 180001000: 52800060 mov w0, #0x3 // =3
DISASM-NEXT: 180001004: d65f03c0 ret
-DISASM-NEXT: 180001008: b0000030 adrp x16, 0x180006000
-DISASM-NEXT: 18000100c: f9404610 ldr x16, [x16, #0x88]
+DISASM-NEXT: 180001008: f0000030 adrp x16, 0x180008000
+DISASM-NEXT: 18000100c: f9400210 ldr x16, [x16]
DISASM-NEXT: 180001010: d61f0200 br x16
-DISASM-NEXT: 180001014: b0000031 adrp x17, 0x180006000
-DISASM-NEXT: 180001018: 91022231 add x17, x17, #0x88
+DISASM-NEXT: 180001014: f0000031 adrp x17, 0x180008000
+DISASM-NEXT: 180001018: 91000231 add x17, x17, #0x0
DISASM-NEXT: 18000101c: 14000001 b 0x180001020 <.text+0x20>
DISASM-NEXT: 180001020: a9b37bfd stp x29, x30, [sp, #-0xd0]!
DISASM-NEXT: 180001024: 910003fd mov x29, sp
@@ -73,7 +73,7 @@ DISASM-NEXT: 180001040: ad0497e4 stp q4, q5, [sp, #0x90]
DISASM-NEXT: 180001044: ad059fe6 stp q6, q7, [sp, #0xb0]
DISASM-NEXT: 180001048: aa1103e1 mov x1, x17
DISASM-NEXT: 18000104c: f0000000 adrp x0, 0x180004000
-DISASM-NEXT: 180001050: 910d4000 add x0, x0, #0x350
+DISASM-NEXT: 180001050: 91050000 add x0, x0, #0x140
DISASM-NEXT: 180001054: 97ffffeb bl 0x180001000 <.text>
DISASM-NEXT: 180001058: aa0003f0 mov x16, x0
DISASM-NEXT: 18000105c: ad459fe6 ldp q6, q7, [sp, #0xb0]
@@ -94,16 +94,16 @@ DISASM-NEXT: 18000200c: d65f03c0 ret
DISASM-NEXT: 180002010: f0000010 adrp x16, 0x180005000
DISASM-NEXT: 180002014: f9400a10 ldr x16, [x16, #0x10]
DISASM-NEXT: 180002018: d61f0200 br x16
-DISASM-NEXT: 18000201c: 9000002b adrp x11, 0x180006000
-DISASM-NEXT: 180002020: f9404d6b ldr x11, [x11, #0x98]
+DISASM-NEXT: 18000201c: d000002b adrp x11, 0x180008000
+DISASM-NEXT: 180002020: f940096b ldr x11, [x11, #0x10]
DISASM-NEXT: 180002024: 9000000a adrp x10, 0x180002000 <.text+0x1000>
DISASM-NEXT: 180002028: 9100c14a add x10, x10, #0x30
DISASM-NEXT: 18000202c: 17fffff5 b 0x180002000 <.text+0x1000>
DISASM-NEXT: 180002030: 52800080 mov w0, #0x4 // =4
DISASM-NEXT: 180002034: d65f03c0 ret
DISASM-NEXT: ...
-DISASM-NEXT: 180003000: ff 25 92 30 00 00 jmpq *0x3092(%rip) # 0x180006098
-DISASM-NEXT: 180003006: 48 8d 05 8b 30 00 00 leaq 0x308b(%rip), %rax # 0x180006098
+DISASM-NEXT: 180003000: ff 25 0a 50 00 00 jmpq *0x500a(%rip) # 0x180008010
+DISASM-NEXT: 180003006: 48 8d 05 03 50 00 00 leaq 0x5003(%rip), %rax # 0x180008010
DISASM-NEXT: 18000300d: e9 00 00 00 00 jmp 0x180003012 <.text+0x2012>
DISASM-NEXT: 180003012: 51 pushq %rcx
DISASM-NEXT: 180003013: 52 pushq %rdx
@@ -115,7 +115,7 @@ DISASM-NEXT: 180003021: 66 0f 7f 4c 24 10 movdqa %xmm1, 0x10(%rsp)
DISASM-NEXT: 180003027: 66 0f 7f 54 24 20 movdqa %xmm2, 0x20(%rsp)
DISASM-NEXT: 18000302d: 66 0f 7f 5c 24 30 movdqa %xmm3, 0x30(%rsp)
DISASM-NEXT: 180003033: 48 8b d0 movq %rax, %rdx
-DISASM-NEXT: 180003036: 48 8d 0d 13 13 00 00 leaq 0x1313(%rip), %rcx # 0x180004350
+DISASM-NEXT: 180003036: 48 8d 0d 03 11 00 00 leaq 0x1103(%rip), %rcx # 0x180004140
DISASM-NEXT: 18000303d: e8 c6 ef ff ff callq 0x180002008 <.text+0x1008>
DISASM-NEXT: 180003042: 66 0f 6f 04 24 movdqa (%rsp), %xmm0
DISASM-NEXT: 180003047: 66 0f 6f 4c 24 10 movdqa 0x10(%rsp), %xmm1
@@ -130,7 +130,7 @@ DISASM-NEXT: 180003063: ff e0 jmpq *%rax
RUN: llvm-readobj --coff-load-config out.dll | FileCheck --check-prefix=LOADCFG %s
LOADCFG: AuxiliaryDelayloadIAT: 0x5000
-LOADCFG-NEXT: AuxiliaryDelayloadIATCopy: 0x4140
+LOADCFG-NEXT: AuxiliaryDelayloadIATCopy: 0x41C0
RUN: llvm-readobj --hex-dump=.rdata out.dll | FileCheck --check-prefix=AUXIAT %s
AUXIAT: 0x180005000 00000000 00000000 00000000 00000000
@@ -147,8 +147,8 @@ NATIVE-IMPORTS: DelayImport {
NATIVE-IMPORTS-NEXT: Name: test.dll
NATIVE-IMPORTS-NEXT: Attributes: 0x1
NATIVE-IMPORTS-NEXT: ModuleHandle: 0x5080
-NATIVE-IMPORTS-NEXT: ImportAddressTable: 0x5088
-NATIVE-IMPORTS-NEXT: ImportNameTable: 0x3370
+NATIVE-IMPORTS-NEXT: ImportAddressTable: 0x6000
+NATIVE-IMPORTS-NEXT: ImportNameTable: 0x3180
NATIVE-IMPORTS-NEXT: BoundDelayImportTable: 0x0
NATIVE-IMPORTS-NEXT: UnloadDelayImportTable: 0x0
NATIVE-IMPORTS-NEXT: Import {
@@ -164,25 +164,25 @@ NATIVE-IMPORTS-NEXT: DelayImport {
NATIVE-IMPORTS-NEXT: Name: test.dll
NATIVE-IMPORTS-NEXT: Attributes: 0x1
NATIVE-IMPORTS-NEXT: ModuleHandle: 0x5080
-NATIVE-IMPORTS-NEXT: ImportAddressTable: 0x5098
-NATIVE-IMPORTS-NEXT: ImportNameTable: 0x3380
+NATIVE-IMPORTS-NEXT: ImportAddressTable: 0x6010
+NATIVE-IMPORTS-NEXT: ImportNameTable: 0x3190
NATIVE-IMPORTS-NEXT: BoundDelayImportTable: 0x0
NATIVE-IMPORTS-NEXT: UnloadDelayImportTable: 0x0
NATIVE-IMPORTS-NEXT: }
NATIVE-IMPORTS-NEXT: }
RUN: llvm-readobj --hex-dump=.testa out-native.dll | FileCheck --check-prefix=NATIVE-TESTSECA %s
-...
[truncated]
|
|
I have proposed a patch to do the same in binutils at https://inbox.sourceware.org/binutils/[email protected]/T/#u |
| idataSec = createSection(".idata", data | r); | ||
| edataSec = createSection(".edata", data | r); | ||
| didatSec = createSection(".didat", data | r); | ||
| didatSec = createSection(".didat", data | r | w); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MSVC dloadsup.h sayeth:
// This delay load helper module does not support merging the delay // load section to a read only section because memory management // would not guarantee that there is commit available - and thus a // low memory failure path where the delay load failure hook could // not be safely invoked (the delay load section would still be // read only) might be encountered. // // It is a build time configuration problem to produce such a // binary so abort here and now so that the problem can be // identified & fixed.
Additionally, making this section read-only by default would make such a binary incompatible with OS versions that have ResolveDelayLoadedAPI and don't support IMAGE_GUARD_PROTECT_DELAYLOAD_IAT - they wouldn't know to make the section read-write before writing to it (I know Wine is such a situation).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should put this under some condition. Something like:
if (delay_load_protected) // Check /didatownsection or guard flags directly?
didatSec = createSection(".didat", data | r | w);
else
didatSec = createSection(".didat", data | r);|
That doesn't seem to match what I see with the MSVC linker, at least with default options. Did you figure out how to make link.exe use a separate section? |
|
I don't know about MSVC. Here's another doc which specifies this behavior though: https://learn.microsoft.com/en-us/windows/win32/secbp/pe-metadata#import-handling see the second bullet point about "Protected delay load" |
|
Note that lld-link aims to be compatible with MSVC. The MinGW mode differs in several respects, but even that shouldn't diverge unnecessarily when it can be avoided. I did some experimentation with MSVC, I feel this PR mixes a few distinct concerns:
That said, to allow dlltool to create long-form delay-load import libraries, we could just fix (1) and condition merging of Side note: While improving GNU dlltool is helpful in the short term, it would be ideal if binutils gained native |
|
I don't understand why the docs are pretty clear about should may and recommended but MSVC doesn't actually implement what the docs say. Maybe I've read too many RFCs and I'm putting too much weight on the word should 😉
(emphasis added) |
So is that like Wine, where it aims to be bug-for-bug compatible, or does the spec control and if MS link doesn't conform that's a bug on their side? |
Somewhere inbetween I would say. I don't think it's a goal of lld-link to mirror any MS link.exe bug per se, but if it is relevant for actual user cases, it is sometimes done. For this particular case though, I don't feel very attached to following the spec to the letter if that's not what actually is being done in MS link.exe. I guess the primary question that still stands open is how to enable |
To me, that means |
|
Binutils 2.45 now includes the patch for it to act like this. |
@jeremyd2019 There's a hidden MS link option that produces the protected delay load DLLs: |
Unless I am not misunderstanding something, I do not know a single case where |
Also, the official doc quote above is a bit misleading IMO. It is mixing up with control flow guard (CFGuard or CFG here), which is completely irrelevant in terms of CFG. The purpose of emitting |
|
@mstorsjo I like this PR, and would like to see get this merged. Based on my previous comments about how MS link works I think the right direction for this would be something like:
I am actually not in favor of doing these by default and unconditionally as that is not backward-compatible. What do you think? |
This allows
IMAGE_GUARD_PROTECT_DELAYLOAD_IAT|IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTIONflags to work (documented at https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#load-configuration-layout).Add tests showing the
.didatsection is created with the proper characteristics.Closes #134546