138 lines · plain
1# REQUIRES: x862# RUN: llvm-mc -triple x86_64-windows-msvc %s -filetype=obj -o %t.obj3# RUN: lld-link %t.obj -guard:cf,nolongjmp -out:%t.exe -opt:noref -entry:main4# RUN: llvm-readobj --file-headers --coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-NOGC5# RUN: lld-link %t.obj -guard:cf,nolongjmp -out:%t.exe -opt:noref -entry:main -debug:dwarf6# RUN: llvm-readobj --file-headers --coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-NOGC7# RUN: lld-link %t.obj -guard:cf,nolongjmp -out:%t.exe -opt:ref -entry:main8# RUN: llvm-readobj --file-headers --coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-GC9 10# This assembly is meant to mimic what CL emits for this kind of C code when11# /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$y20# sections.21 22# Expect 3 entries: main, f, and g.23 24# CHECK-NOGC: ImageBase: 0x14000000025# CHECK-NOGC: LoadConfig [26# CHECK-NOGC: SEHandlerTable: 0x027# CHECK-NOGC: SEHandlerCount: 028# CHECK-NOGC: GuardCFCheckFunction: 0x029# CHECK-NOGC: GuardCFCheckDispatch: 0x030# CHECK-NOGC: GuardCFFunctionTable: 0x14000{{.*}}31# CHECK-NOGC: GuardCFFunctionCount: 332# 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: 0x037# CHECK-NOGC: GuardAddressTakenIatEntryCount: 038# CHECK-NOGC: GuardLongJumpTargetTable: 0x039# CHECK-NOGC: GuardLongJumpTargetCount: 040# 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: ]46 47# Expect 2 entries: main and f. fp2 was discarded, so g was only used as a48# direct call target.49 50# CHECK-GC: ImageBase: 0x14000000051# CHECK-GC: LoadConfig [52# CHECK-GC: SEHandlerTable: 0x053# CHECK-GC: SEHandlerCount: 054# CHECK-GC: GuardCFCheckFunction: 0x055# CHECK-GC: GuardCFCheckDispatch: 0x056# CHECK-GC: GuardCFFunctionTable: 0x14000{{.*}}57# CHECK-GC: GuardCFFunctionCount: 258# 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: 0x063# CHECK-GC: GuardAddressTakenIatEntryCount: 064# CHECK-GC: GuardLongJumpTargetTable: 0x065# CHECK-GC: GuardLongJumpTargetCount: 066# CHECK-GC: ]67# CHECK-GC: GuardFidTable [68# CHECK-GC-NEXT: 0x14000{{.*}}69# CHECK-GC-NEXT: 0x14000{{.*}}70# CHECK-GC-NEXT: ]71 72 73# We need @feat.00 to have 0x800 to indicate .gfids are present.74 .def @feat.00;75 .scl 3;76 .type 0;77 .endef78 .globl @feat.0079@feat.00 = 0x80180 81 .def main;82 .scl 2;83 .type 32;84 .endef85 .section .text,"xr",one_only,main86 .globl main87main:88 # Call g directly so that it is not dead stripped.89 callq g90 rex64 jmpq *fp1(%rip)91 92 .def f;93 .scl 3;94 .type 32;95 .endef96 .section .text,"xr",one_only,f97f:98 movl $42, %eax99 retq100 101 .section .data,"dw",one_only,fp1102 .globl fp1103fp1:104 .quad f105 106 .section .gfids$y,"dr",associative,fp1107 .symidx f108 109# Section GC will remove the following, so 'g' should not be present in the110# guard fid table.111 112 .def g;113 .scl 3;114 .type 32;115 .endef116 .section .text,"xr",one_only,g117g:118 movl $13, %eax119 retq120 121 .section .data,"dw",one_only,fp2122 .globl fp2123fp2:124 .quad g125 126 .section .gfids$y,"dr",associative,fp2127 .symidx g128 129 .section .rdata,"dr"130.globl _load_config_used131_load_config_used:132 .long 256133 .fill 124, 1, 0134 .quad __guard_fids_table135 .quad __guard_fids_count136 .long __guard_flags137 .fill 128, 1, 0138