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: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: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: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
9
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.
21
22# Expect 3 entries: main, f, and g.
23
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:   GuardAddressTakenIatEntryTable: 0x0
34# CHECK-NOGC:   GuardAddressTakenIatEntryCount: 0
35# CHECK-NOGC:   GuardLongJumpTargetTable: 0x0
36# CHECK-NOGC:   GuardLongJumpTargetCount: 0
37# CHECK-NOGC: ]
38# CHECK-NOGC:      GuardFidTable [
39# CHECK-NOGC-NEXT:   0x14000{{.*}}
40# CHECK-NOGC-NEXT:   0x14000{{.*}}
41# CHECK-NOGC-NEXT:   0x14000{{.*}}
42# CHECK-NOGC-NEXT: ]
43
44# Expect 2 entries: main and f. fp2 was discarded, so g was only used as a
45# direct call target.
46
47# CHECK-GC: ImageBase: 0x140000000
48# CHECK-GC: LoadConfig [
49# CHECK-GC:   SEHandlerTable: 0x0
50# CHECK-GC:   SEHandlerCount: 0
51# CHECK-GC:   GuardCFCheckFunction: 0x0
52# CHECK-GC:   GuardCFCheckDispatch: 0x0
53# CHECK-GC:   GuardCFFunctionTable: 0x14000{{.*}}
54# CHECK-GC:   GuardCFFunctionCount: 2
55# CHECK-GC:   GuardFlags: 0x500
56# CHECK-GC:   GuardAddressTakenIatEntryTable: 0x0
57# CHECK-GC:   GuardAddressTakenIatEntryCount: 0
58# CHECK-GC:   GuardLongJumpTargetTable: 0x0
59# CHECK-GC:   GuardLongJumpTargetCount: 0
60# CHECK-GC: ]
61# CHECK-GC:      GuardFidTable [
62# CHECK-GC-NEXT:   0x14000{{.*}}
63# CHECK-GC-NEXT:   0x14000{{.*}}
64# CHECK-GC-NEXT: ]
65
66
67# We need @feat.00 to have 0x800 to indicate .gfids are present.
68        .def     @feat.00;
69        .scl    3;
70        .type   0;
71        .endef
72        .globl  @feat.00
73@feat.00 = 0x801
74
75        .def     main;
76        .scl    2;
77        .type   32;
78        .endef
79        .section        .text,"xr",one_only,main
80        .globl  main
81main:
82        # Call g directly so that it is not dead stripped.
83        callq g
84        rex64 jmpq      *fp1(%rip)
85
86        .def     f;
87        .scl    3;
88        .type   32;
89        .endef
90        .section        .text,"xr",one_only,f
91f:
92        movl $42, %eax
93        retq
94
95        .section        .data,"dw",one_only,fp1
96        .globl  fp1
97fp1:
98        .quad   f
99
100        .section        .gfids$y,"dr",associative,fp1
101        .symidx f
102
103# Section GC will remove the following, so 'g' should not be present in the
104# guard fid table.
105
106        .def     g;
107        .scl    3;
108        .type   32;
109        .endef
110        .section        .text,"xr",one_only,g
111g:
112        movl $13, %eax
113        retq
114
115        .section        .data,"dw",one_only,fp2
116        .globl  fp2
117fp2:
118        .quad   g
119
120        .section        .gfids$y,"dr",associative,fp2
121        .symidx g
122
123        .section .rdata,"dr"
124.globl _load_config_used
125_load_config_used:
126        .long 256
127        .fill 124, 1, 0
128        .quad __guard_fids_table
129        .quad __guard_fids_count
130        .long __guard_flags
131        .fill 128, 1, 0
132