llvm-project
125 строк · 4.0 Кб
1# REQUIRES: x86
2
3# Make a DLL that exports exportfn1.
4# RUN: yaml2obj %p/Inputs/export.yaml -o %basename_t-exp.obj
5# RUN: lld-link /out:%basename_t-exp.dll /dll %basename_t-exp.obj /export:exportfn1 /implib:%basename_t-exp.lib
6
7# Make an object file that imports exportfn1.
8# RUN: llvm-mc -triple x86_64-windows-msvc %s -filetype=obj -o %basename_t.obj
9
10# Check that the Guard address-taken IAT entry tables are propagated to the final executable.
11# RUN: lld-link %basename_t.obj -guard:cf -guard:longjmp -entry:main -out:%basename_t-nodelay.exe %basename_t-exp.lib
12# RUN: llvm-readobj --file-headers --coff-load-config %basename_t-nodelay.exe | FileCheck %s --check-prefix CHECK
13
14# CHECK: ImageBase: 0x140000000
15# CHECK: LoadConfig [
16# CHECK: GuardCFFunctionTable: 0x140002114
17# CHECK: GuardCFFunctionCount: 1
18# CHECK: GuardFlags [ (0x10500)
19# CHECK: CF_FUNCTION_TABLE_PRESENT (0x400)
20# CHECK: CF_INSTRUMENTED (0x100)
21# CHECK: CF_LONGJUMP_TABLE_PRESENT (0x10000)
22# CHECK: ]
23# CHECK: GuardAddressTakenIatEntryTable: 0x140002118
24# CHECK: GuardAddressTakenIatEntryCount: 1
25# CHECK: ]
26# CHECK: GuardFidTable [
27# CHECK-NEXT: 0x14000{{.*}}
28# CHECK-NEXT: ]
29# CHECK: GuardIatTable [
30# CHECK-NEXT: 0x14000{{.*}}
31# CHECK-NEXT: ]
32
33
34# Check that the additional load thunk symbol is added to the GFIDs table.
35# RUN: lld-link %basename_t.obj -guard:cf -guard:longjmp -entry:main -out:%basename_t-delay.exe %basename_t-exp.lib -alternatename:__delayLoadHelper2=main -delayload:%basename_t-exp.dll
36# RUN: llvm-readobj --file-headers --coff-load-config %basename_t-delay.exe | FileCheck %s --check-prefix DELAY-CHECK
37
38# DELAY-CHECK: ImageBase: 0x140000000
39# DELAY-CHECK: LoadConfig [
40# DELAY-CHECK: GuardCFFunctionTable: 0x140002124
41# DELAY-CHECK: GuardCFFunctionCount: 2
42# DELAY-CHECK: GuardFlags [ (0x10500)
43# DELAY-CHECK: CF_FUNCTION_TABLE_PRESENT (0x400)
44# DELAY-CHECK: CF_INSTRUMENTED (0x100)
45# DELAY-CHECK: CF_LONGJUMP_TABLE_PRESENT (0x10000)
46# DELAY-CHECK: ]
47# DELAY-CHECK: GuardAddressTakenIatEntryTable: 0x14000212C
48# DELAY-CHECK: GuardAddressTakenIatEntryCount: 1
49# DELAY-CHECK: ]
50# DELAY-CHECK: GuardFidTable [
51# DELAY-CHECK-NEXT: 0x14000{{.*}}
52# DELAY-CHECK-NEXT: 0x14000{{.*}}
53# DELAY-CHECK-NEXT: ]
54# DELAY-CHECK: GuardIatTable [
55# DELAY-CHECK-NEXT: 0x14000{{.*}}
56# DELAY-CHECK-NEXT: ]
57
58
59# This assembly is reduced from C code like:
60# __declspec(noinline)
61# void IndirectCall(BOOL (func)(HANDLE)) {
62# (*func)(NULL);
63# }
64# int main(int argc, char** argv) {
65# IndirectCall(exportfn1);
66# }
67
68.text
69.def @feat.00;
70.scl 3;
71.type 0;
72.endef
73.globl @feat.00
74.set @feat.00, 2048
75.def IndirectCall; .scl 2; .type 32; .endef
76.globl IndirectCall # -- Begin function IndirectCall
77.p2align 4, 0x90
78IndirectCall: # @IndirectCall
79# %bb.0:
80subq $40, %rsp
81movq %rcx, 32(%rsp)
82movq 32(%rsp), %rax
83movq %rax, %rdx # This would otherwise be: movq __guard_dispatch_icall_fptr(%rip), %rdx
84xorl %ecx, %ecx
85callq *%rdx
86nop
87addq $40, %rsp
88retq
89# -- End function
90.def main; .scl 2; .type 32; .endef
91.globl main # -- Begin function main
92.p2align 4, 0x90
93main: # @main
94# %bb.0:
95subq $56, %rsp
96movq __imp_exportfn1(%rip), %rax
97movq %rdx, 48(%rsp)
98movl %ecx, 44(%rsp)
99movq %rax, %rcx
100callq IndirectCall
101xorl %eax, %eax
102addq $56, %rsp
103retq
104# -- End function
105.section .gfids$y,"dr"
106.section .giats$y,"dr"
107.symidx __imp_exportfn1
108.section .gljmp$y,"dr"
109
110# Load configuration directory entry (winnt.h _IMAGE_LOAD_CONFIG_DIRECTORY64).
111# The linker will define the __guard_* symbols.
112.section .rdata,"dr"
113.globl _load_config_used
114_load_config_used:
115.long 256
116.fill 124, 1, 0
117.quad __guard_fids_table
118.quad __guard_fids_count
119.long __guard_flags
120.fill 12, 1, 0
121.quad __guard_iat_table
122.quad __guard_iat_count
123.quad __guard_longjmp_table
124.quad __guard_fids_count
125.fill 84, 1, 0
126