Skip to content

Commit 12e03d4

Browse files
committed
[LLD][COFF] Move delay IAT into its own .didat section.
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.
1 parent 0547e84 commit 12e03d4

12 files changed

+162
-101
lines changed

lld/COFF/DLL.cpp

+1-8
Original file line numberDiff line numberDiff line change
@@ -891,7 +891,7 @@ void IdataContents::create(COFFLinkerContext &ctx) {
891891
dirs.push_back(make<NullChunk>(sizeof(ImportDirectoryTableEntry), 4));
892892
}
893893

894-
std::vector<Chunk *> DelayLoadContents::getChunks() {
894+
std::vector<Chunk *> DelayLoadContents::getRDataChunks() {
895895
std::vector<Chunk *> v;
896896
v.insert(v.end(), dirs.begin(), dirs.end());
897897
v.insert(v.end(), names.begin(), names.end());
@@ -900,13 +900,6 @@ std::vector<Chunk *> DelayLoadContents::getChunks() {
900900
return v;
901901
}
902902

903-
std::vector<Chunk *> DelayLoadContents::getDataChunks() {
904-
std::vector<Chunk *> v;
905-
v.insert(v.end(), moduleHandles.begin(), moduleHandles.end());
906-
v.insert(v.end(), addresses.begin(), addresses.end());
907-
return v;
908-
}
909-
910903
uint64_t DelayLoadContents::getDirSize() {
911904
return dirs.size() * sizeof(delay_import_directory_table_entry);
912905
}

lld/COFF/DLL.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ class DelayLoadContents {
4343
void add(DefinedImportData *sym) { imports.push_back(sym); }
4444
bool empty() { return imports.empty(); }
4545
void create();
46-
std::vector<Chunk *> getChunks();
47-
std::vector<Chunk *> getDataChunks();
46+
ArrayRef<Chunk *> getChunks() { return addresses; }
47+
std::vector<Chunk *> getRDataChunks();
48+
ArrayRef<Chunk *> getDataChunks() { return moduleHandles; }
4849
ArrayRef<Chunk *> getCodeChunks() { return thunks; }
4950
ArrayRef<Chunk *> getCodePData() { return pdata; }
5051
ArrayRef<Chunk *> getCodeUnwindInfo() { return unwindinfo; }

lld/COFF/Driver.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -2015,7 +2015,6 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
20152015
// Add default section merging rules after user rules. User rules take
20162016
// precedence, but we will emit a warning if there is a conflict.
20172017
parseMerge(".idata=.rdata");
2018-
parseMerge(".didat=.rdata");
20192018
parseMerge(".edata=.rdata");
20202019
parseMerge(".xdata=.rdata");
20212020
parseMerge(".00cfg=.rdata");

lld/COFF/Writer.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -1083,7 +1083,7 @@ void Writer::createSections() {
10831083
pdataSec = createSection(".pdata", data | r);
10841084
idataSec = createSection(".idata", data | r);
10851085
edataSec = createSection(".edata", data | r);
1086-
didatSec = createSection(".didat", data | r);
1086+
didatSec = createSection(".didat", data | r | w);
10871087
if (isArm64EC(ctx.config.machine))
10881088
a64xrmSec = createSection(".a64xrm", data | r);
10891089
rsrcSec = createSection(".rsrc", data | r);
@@ -1329,6 +1329,8 @@ void Writer::appendImportThunks() {
13291329
delayIdata.create();
13301330
for (Chunk *c : delayIdata.getChunks())
13311331
didatSec->addChunk(c);
1332+
for (Chunk *c : delayIdata.getRDataChunks())
1333+
rdataSec->addChunk(c);
13321334
for (Chunk *c : delayIdata.getDataChunks())
13331335
dataSec->addChunk(c);
13341336
for (Chunk *c : delayIdata.getCodeChunks())

lld/test/COFF/arm64-delayimport.yaml

+19-3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
# RUN: lld-link /entry:main /subsystem:console /out:%t.exe %t.obj %p/Inputs/library-arm64.lib /alternatename:__delayLoadHelper2=main /delayload:library.dll
55
# RUN: llvm-objdump --no-print-imm-hex -d %t.exe | FileCheck %s --check-prefix DISASM
66
# RUN: llvm-readobj --coff-imports %t.exe | FileCheck %s -check-prefix IMPORTS
7+
# RUN: llvm-readobj --section-headers %t.exe | FileCheck %s -check-prefix SECTION
78

8-
# DISASM: 140001014: d0000011 adrp x17, 0x140003000
9-
# DISASM: 140001018: 91002231 add x17, x17, #8
9+
# DISASM: 140001014: f0000011 adrp x17, 0x140004000
10+
# DISASM: 140001018: 91000231 add x17, x17, #0
1011
# DISASM: 14000101c: 14000001 b 0x140001020 <.text+0x20>
1112
# DISASM: 140001020: a9b37bfd stp x29, x30, [sp, #-208]!
1213
# DISASM: 140001024: 910003fd mov x29, sp
@@ -41,7 +42,7 @@
4142
# IMPORTS: Name: library.dll
4243
# IMPORTS: Attributes: 0x1
4344
# IMPORTS: ModuleHandle: 0x3000
44-
# IMPORTS: ImportAddressTable: 0x3008
45+
# IMPORTS: ImportAddressTable: 0x4000
4546
# IMPORTS: ImportNameTable: 0x2040
4647
# IMPORTS: BoundDelayImportTable: 0x0
4748
# IMPORTS: UnloadDelayImportTable: 0x0
@@ -50,6 +51,21 @@
5051
# IMPORTS: Address: 0x140001014
5152
# IMPORTS: }
5253
# IMPORTS: }
54+
# SECTION: Name: .didat (2E 64 69 64 61 74 00 00)
55+
# SECTION-NEXT: VirtualSize: 0x10
56+
# SECTION-NEXT: VirtualAddress: 0x4000
57+
# SECTION-NEXT: RawDataSize: 512
58+
# SECTION-NEXT: PointerToRawData: 0x{{[0-9A-F]+}}
59+
# SECTION-NEXT: PointerToRelocations: 0x0
60+
# SECTION-NEXT: PointerToLineNumbers: 0x0
61+
# SECTION-NEXT: RelocationCount: 0
62+
# SECTION-NEXT: LineNumberCount: 0
63+
# SECTION-NEXT: Characteristics [ (0xC0000040)
64+
# SECTION-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
65+
# SECTION-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
66+
# SECTION-NEXT: IMAGE_SCN_MEM_WRITE (0x80000000)
67+
# SECTION-NEXT: ]
68+
# SECTION-NEXT: }
5369

5470
--- !COFF
5571
header:

lld/test/COFF/arm64ec-delayimport.test

+25-25
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ RUN: lld-link -machine:arm64ec -dll -noentry -out:out.dll loadconfig-arm64ec.obj
1212
RUN: helper-mangled.obj test-arm64ec.lib test2-arm64ec.lib -delayload:test.dll -map
1313

1414
RUN: llvm-readobj --hex-dump=.test out.dll | FileCheck --check-prefix=TESTSEC %s
15-
TESTSEC: 0x18000a000 00600000 88700000 00200000 10100000
16-
TESTSEC-NEXT: 0x18000a010 08600000 90700000 10200000 30100000
17-
TESTSEC-NEXT: 0x18000a020 1c100000 3c100000 00300000
15+
TESTSEC: 0x18000b000 00600000 00900000 00200000 10100000
16+
TESTSEC-NEXT: 0x18000b010 08600000 08900000 10200000 30100000
17+
TESTSEC-NEXT: 0x18000b020 1c100000 3c100000 00300000
1818

1919
RUN: llvm-objdump -d out.dll | FileCheck --check-prefix=DISASM %s
2020
DISASM: 0000000180001000 <.text>:
@@ -25,16 +25,16 @@ DISASM-NEXT: 18000100c: d65f03c0 ret
2525
DISASM-NEXT: 180001010: b0000030 adrp x16, 0x180006000
2626
DISASM-NEXT: 180001014: f9400210 ldr x16, [x16]
2727
DISASM-NEXT: 180001018: d61f0200 br x16
28-
DISASM-NEXT: 18000101c: d000002b adrp x11, 0x180007000
29-
DISASM-NEXT: 180001020: f940456b ldr x11, [x11, #0x88]
28+
DISASM-NEXT: 18000101c: 9000004b adrp x11, 0x180009000
29+
DISASM-NEXT: 180001020: f940016b ldr x11, [x11]
3030
DISASM-NEXT: 180001024: 9000000a adrp x10, 0x180001000 <.text>
3131
DISASM-NEXT: 180001028: 9101414a add x10, x10, #0x50
3232
DISASM-NEXT: 18000102c: 17fffff5 b 0x180001000 <.text>
3333
DISASM-NEXT: 180001030: b0000030 adrp x16, 0x180006000
3434
DISASM-NEXT: 180001034: f9400610 ldr x16, [x16, #0x8]
3535
DISASM-NEXT: 180001038: d61f0200 br x16
36-
DISASM-NEXT: 18000103c: d000002b adrp x11, 0x180007000
37-
DISASM-NEXT: 180001040: f940496b ldr x11, [x11, #0x90]
36+
DISASM-NEXT: 18000103c: 9000004b adrp x11, 0x180009000
37+
DISASM-NEXT: 180001040: f940056b ldr x11, [x11, #0x8]
3838
DISASM-NEXT: 180001044: 9000000a adrp x10, 0x180001000 <.text>
3939
DISASM-NEXT: 180001048: 9101614a add x10, x10, #0x58
4040
DISASM-NEXT: 18000104c: 17ffffed b 0x180001000 <.text>
@@ -43,13 +43,13 @@ DISASM-NEXT: 180001054: d65f03c0 ret
4343
DISASM-NEXT: 180001058: 52800060 mov w0, #0x3 // =3
4444
DISASM-NEXT: 18000105c: d65f03c0 ret
4545
DISASM-NEXT: ...
46-
DISASM-NEXT: 180002000: ff 25 82 50 00 00 jmpq *0x5082(%rip) # 0x180007088
46+
DISASM-NEXT: 180002000: ff 25 fa 6f 00 00 jmpq *0x6ffa(%rip) # 0x180009000
4747
DISASM-NEXT: ...
4848
DISASM-NEXT: 18000200e: 00 00 addb %al, (%rax)
49-
DISASM-NEXT: 180002010: ff 25 7a 50 00 00 jmpq *0x507a(%rip) # 0x180007090
50-
DISASM-NEXT: 180002016: 48 8d 05 6b 50 00 00 leaq 0x506b(%rip), %rax # 0x180007088
49+
DISASM-NEXT: 180002010: ff 25 f2 6f 00 00 jmpq *0x6ff2(%rip) # 0x180009008
50+
DISASM-NEXT: 180002016: 48 8d 05 e3 6f 00 00 leaq 0x6fe3(%rip), %rax # 0x180009000
5151
DISASM-NEXT: 18000201d: e9 0c 00 00 00 jmp 0x18000202e <.text+0x102e>
52-
DISASM-NEXT: 180002022: 48 8d 05 67 50 00 00 leaq 0x5067(%rip), %rax # 0x180007090
52+
DISASM-NEXT: 180002022: 48 8d 05 df 6f 00 00 leaq 0x6fdf(%rip), %rax # 0x180009008
5353
DISASM-NEXT: 180002029: e9 00 00 00 00 jmp 0x18000202e <.text+0x102e>
5454
DISASM-NEXT: 18000202e: 51 pushq %rcx
5555
DISASM-NEXT: 18000202f: 52 pushq %rdx
@@ -61,7 +61,7 @@ DISASM-NEXT: 18000203d: 66 0f 7f 4c 24 10 movdqa %xmm1, 0x10(%rsp)
6161
DISASM-NEXT: 180002043: 66 0f 7f 54 24 20 movdqa %xmm2, 0x20(%rsp)
6262
DISASM-NEXT: 180002049: 66 0f 7f 5c 24 30 movdqa %xmm3, 0x30(%rsp)
6363
DISASM-NEXT: 18000204f: 48 8b d0 movq %rax, %rdx
64-
DISASM-NEXT: 180002052: 48 8d 0d a7 21 00 00 leaq 0x21a7(%rip), %rcx # 0x180004200
64+
DISASM-NEXT: 180002052: 48 8d 0d a7 1f 00 00 leaq 0x1fa7(%rip), %rcx # 0x180004000
6565
DISASM-NEXT: 180002059: e8 aa ef ff ff callq 0x180001008 <.text+0x8>
6666
DISASM-NEXT: 18000205e: 66 0f 6f 04 24 movdqa (%rsp), %xmm0
6767
DISASM-NEXT: 180002063: 66 0f 6f 4c 24 10 movdqa 0x10(%rsp), %xmm1
@@ -77,15 +77,15 @@ DISASM-NEXT: 18000207f: ff e0 jmpq *%rax
7777
RUN: llvm-readobj --coff-load-config out.dll | FileCheck --check-prefix=LOADCFG %s
7878
LOADCFG: CHPEMetadata [
7979
LOADCFG: AuxiliaryDelayloadIAT: 0x6000
80-
LOADCFG-NEXT: AuxiliaryDelayloadIATCopy: 0x4000
80+
LOADCFG-NEXT: AuxiliaryDelayloadIATCopy: 0x4078
8181

8282
RUN: llvm-readobj --coff-imports out.dll | FileCheck --check-prefix=IMPORTS %s
8383
IMPORTS: DelayImport {
8484
IMPORTS-NEXT: Name: test.dll
8585
IMPORTS-NEXT: Attributes: 0x1
8686
IMPORTS-NEXT: ModuleHandle: 0x7080
87-
IMPORTS-NEXT: ImportAddressTable: 0x7088
88-
IMPORTS-NEXT: ImportNameTable: 0x4240
87+
IMPORTS-NEXT: ImportAddressTable: 0x9000
88+
IMPORTS-NEXT: ImportNameTable: 0x4040
8989
IMPORTS-NEXT: BoundDelayImportTable: 0x0
9090
IMPORTS-NEXT: UnloadDelayImportTable: 0x0
9191
IMPORTS-NEXT: Import {
@@ -109,29 +109,29 @@ MAP-NEXT: 0001:00000058 func2_exit_thunk 0000000180001058 t
109109
MAP-NEXT: 0001:00001000 func 0000000180002000 test-arm64ec:test.dll
110110
MAP-NEXT: 0001:00001010 func2 0000000180002010 test-arm64ec:test.dll
111111
MAP-NEXT: 0002:00000000 __imp_data 0000000180003000 test2-arm64ec:test2.dll
112-
MAP-NEXT: 0000:00000000 __hybrid_auxiliary_delayload_iat_copy 0000000180004000 <linker-defined>
113-
MAP-NEXT: 0002:00001000 __auximpcopy_func 0000000180004000 test-arm64ec:test.dll
114-
MAP-NEXT: 0002:00001008 __auximpcopy_func2 0000000180004008 test-arm64ec:test.dll
112+
MAP-NEXT: 0000:00000000 __hybrid_auxiliary_delayload_iat_copy 0000000180004078 <linker-defined>
113+
MAP-NEXT: 0002:00001078 __auximpcopy_func 0000000180004078 test-arm64ec:test.dll
114+
MAP-NEXT: 0002:00001080 __auximpcopy_func2 0000000180004080 test-arm64ec:test.dll
115115
MAP: 0002:00003000 __imp_func 0000000180006000 test-arm64ec:test.dll
116116
MAP-NEXT: 0002:00003008 __imp_func2 0000000180006008 test-arm64ec:test.dll
117-
MAP: 0003:00000088 __imp_aux_func 0000000180007088 test-arm64ec:test.dll
118-
MAP-NEXT: 0003:00000090 __imp_aux_func2 0000000180007090 test-arm64ec:test.dll
117+
MAP: 0005:00000000 __imp_aux_func 0000000180009000 test-arm64ec:test.dll
118+
MAP-NEXT: 0005:00000008 __imp_aux_func2 0000000180009008 test-arm64ec:test.dll
119119

120120
RUN: llvm-readobj --hex-dump=.rdata out.dll | FileCheck --check-prefix=RDATA %s
121-
RDATA: 0x180004000 1c100080 01000000 3c100080 01000000
122-
RDATA-NEXT: 0x180004010 00000000 00000000
121+
RDATA: 0x180004070 {{[0-9a-f]{8} [0-9a-f]{8} }}1c100080 01000000
122+
RDATA-NEXT: 0x180004080 3c100080 01000000 00000000 00000000
123123
RDATA: 0x180006000 1c100080 01000000 3c100080 01000000
124124
RDATA-NEXT: 0x180006010 00000000 00000000
125125

126126
RUN: llvm-readobj --coff-basereloc out.dll | FileCheck --check-prefix=RELOC %s
127127
RELOC: BaseReloc [
128128
RELOC-NEXT: Entry {
129129
RELOC-NEXT: Type: DIR64
130-
RELOC-NEXT: Address: 0x4000
130+
RELOC-NEXT: Address: 0x4078
131131
RELOC-NEXT: }
132132
RELOC-NEXT: Entry {
133133
RELOC-NEXT: Type: DIR64
134-
RELOC-NEXT: Address: 0x4008
134+
RELOC-NEXT: Address: 0x4080
135135
RELOC-NEXT: }
136136
RELOC: Address: 0x6000
137137
RELOC-NEXT: }
@@ -141,7 +141,7 @@ RELOC-NEXT: Address: 0x6008
141141
RELOC-NEXT: }
142142

143143
RUN: llvm-readobj --hex-dump=.pdata out.dll | FileCheck --check-prefix=PDATA %s
144-
PDATA: 0x180008000 2e200000 81200000 18400000
144+
PDATA: 0x180008000 2e200000 81200000 90400000
145145

146146
Verify that a demangled version of __delayLoadHelper2 can be used.
147147

0 commit comments

Comments
 (0)