Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lld / test / COFF / gfids-gc.s
blobc64295aea113be5b376c1e43ac47ad8a7c44d76a
1 # REQUIRES: x86
2 # RUN: llvm-mc -triple x86_64-windows-msvc %s -filetype=obj -o %t.obj
3 # RUN: lld-link %t.obj -guard:cf,nolongjmp -out:%t.exe -opt:noref -entry:main
4 # RUN: llvm-readobj --file-headers --coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-NOGC
5 # RUN: lld-link %t.obj -guard:cf,nolongjmp -out:%t.exe -opt:noref -entry:main -debug:dwarf
6 # RUN: llvm-readobj --file-headers --coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-NOGC
7 # RUN: lld-link %t.obj -guard:cf,nolongjmp -out:%t.exe -opt:ref -entry:main
8 # RUN: llvm-readobj --file-headers --coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-GC
10 # This assembly is meant to mimic what CL emits for this kind of C code when
11 # /Gw (-fdata-sections) is enabled:
12 # int f() { return 42; }
13 # int g() { return 13; }
14 # int (*fp1)() = &f;
15 # int (*fp2)() = &g;
16 # int main() {
17 # return fp1();
18 # }
19 # Compile with 'cl -c -guard:cf -Gw -O1' and note the two associative .gfids$y
20 # sections.
22 # Expect 3 entries: main, f, and g.
24 # CHECK-NOGC: ImageBase: 0x140000000
25 # CHECK-NOGC: LoadConfig [
26 # CHECK-NOGC: SEHandlerTable: 0x0
27 # CHECK-NOGC: SEHandlerCount: 0
28 # CHECK-NOGC: GuardCFCheckFunction: 0x0
29 # CHECK-NOGC: GuardCFCheckDispatch: 0x0
30 # CHECK-NOGC: GuardCFFunctionTable: 0x14000{{.*}}
31 # CHECK-NOGC: GuardCFFunctionCount: 3
32 # CHECK-NOGC: GuardFlags [ (0x500)
33 # CHECK-NOGC: CF_FUNCTION_TABLE_PRESENT (0x400)
34 # CHECK-NOGC: CF_INSTRUMENTED (0x100)
35 # CHECK-NOGC: ]
36 # CHECK-NOGC: GuardAddressTakenIatEntryTable: 0x0
37 # CHECK-NOGC: GuardAddressTakenIatEntryCount: 0
38 # CHECK-NOGC: GuardLongJumpTargetTable: 0x0
39 # CHECK-NOGC: GuardLongJumpTargetCount: 0
40 # CHECK-NOGC: ]
41 # CHECK-NOGC: GuardFidTable [
42 # CHECK-NOGC-NEXT: 0x14000{{.*}}
43 # CHECK-NOGC-NEXT: 0x14000{{.*}}
44 # CHECK-NOGC-NEXT: 0x14000{{.*}}
45 # CHECK-NOGC-NEXT: ]
47 # Expect 2 entries: main and f. fp2 was discarded, so g was only used as a
48 # direct call target.
50 # CHECK-GC: ImageBase: 0x140000000
51 # CHECK-GC: LoadConfig [
52 # CHECK-GC: SEHandlerTable: 0x0
53 # CHECK-GC: SEHandlerCount: 0
54 # CHECK-GC: GuardCFCheckFunction: 0x0
55 # CHECK-GC: GuardCFCheckDispatch: 0x0
56 # CHECK-GC: GuardCFFunctionTable: 0x14000{{.*}}
57 # CHECK-GC: GuardCFFunctionCount: 2
58 # CHECK-GC: GuardFlags [ (0x500)
59 # CHECK-GC: CF_FUNCTION_TABLE_PRESENT (0x400)
60 # CHECK-GC: CF_INSTRUMENTED (0x100)
61 # CHECK-GC: ]
62 # CHECK-GC: GuardAddressTakenIatEntryTable: 0x0
63 # CHECK-GC: GuardAddressTakenIatEntryCount: 0
64 # CHECK-GC: GuardLongJumpTargetTable: 0x0
65 # CHECK-GC: GuardLongJumpTargetCount: 0
66 # CHECK-GC: ]
67 # CHECK-GC: GuardFidTable [
68 # CHECK-GC-NEXT: 0x14000{{.*}}
69 # CHECK-GC-NEXT: 0x14000{{.*}}
70 # CHECK-GC-NEXT: ]
73 # We need @feat.00 to have 0x800 to indicate .gfids are present.
74 .def @feat.00;
75 .scl 3;
76 .type 0;
77 .endef
78 .globl @feat.00
79 @feat.00 = 0x801
81 .def main;
82 .scl 2;
83 .type 32;
84 .endef
85 .section .text,"xr",one_only,main
86 .globl main
87 main:
88 # Call g directly so that it is not dead stripped.
89 callq g
90 rex64 jmpq *fp1(%rip)
92 .def f;
93 .scl 3;
94 .type 32;
95 .endef
96 .section .text,"xr",one_only,f
98 movl $42, %eax
99 retq
101 .section .data,"dw",one_only,fp1
102 .globl fp1
103 fp1:
104 .quad f
106 .section .gfids$y,"dr",associative,fp1
107 .symidx f
109 # Section GC will remove the following, so 'g' should not be present in the
110 # guard fid table.
112 .def g;
113 .scl 3;
114 .type 32;
115 .endef
116 .section .text,"xr",one_only,g
118 movl $13, %eax
119 retq
121 .section .data,"dw",one_only,fp2
122 .globl fp2
123 fp2:
124 .quad g
126 .section .gfids$y,"dr",associative,fp2
127 .symidx g
129 .section .rdata,"dr"
130 .globl _load_config_used
131 _load_config_used:
132 .long 256
133 .fill 124, 1, 0
134 .quad __guard_fids_table
135 .quad __guard_fids_count
136 .long __guard_flags
137 .fill 128, 1, 0