| # REQUIRES: x86 |
| # Make a DLL that exports exportfn1. |
| # RUN: yaml2obj %p/Inputs/export.yaml -o %basename_t-exp.obj |
| # RUN: lld-link /out:%basename_t-exp.dll /dll %basename_t-exp.obj /export:exportfn1 /implib:%basename_t-exp.lib |
| # RUN: split-file %s %t |
| # RUN: llvm-mc -triple x86_64-windows-msvc %t/main.s -filetype=obj -o %t/main.obj |
| |
| # RUN: lld-link %t/main.obj -guard:cf,longjmp,ehcont -out:%t-missing.exe -entry:main %basename_t-exp.lib 2>&1 | FileCheck %s --check-prefix=WARN_MISSING |
| # WARN_MISSING: warning: Control Flow Guard is enabled but '_load_config_used' is missing |
| |
| # RUN: llvm-mc -triple x86_64-windows-msvc %t/loadcfg-invalid.s -filetype=obj -o %t/loadcfg-invalid.obj |
| # RUN: lld-link %t/main.obj %t/loadcfg-invalid.obj -guard:cf,longjmp,ehcont -out:%t-invalid.exe -entry:main %basename_t-exp.lib 2>&1 | FileCheck %s --check-prefix=WARN_INVALID |
| # WARN_INVALID: warning: GuardCFFunctionTable not set correctly in '_load_config_used' |
| # WARN_INVALID-NEXT: warning: GuardCFFunctionCount not set correctly in '_load_config_used' |
| # WARN_INVALID-NEXT: warning: GuardFlags not set correctly in '_load_config_used' |
| # WARN_INVALID-NEXT: warning: GuardAddressTakenIatEntryTable not set correctly in '_load_config_used' |
| # WARN_INVALID-NEXT: warning: GuardAddressTakenIatEntryCount not set correctly in '_load_config_used' |
| # WARN_INVALID-NEXT: warning: GuardLongJumpTargetTable not set correctly in '_load_config_used' |
| # WARN_INVALID-NEXT: warning: GuardLongJumpTargetCount not set correctly in '_load_config_used' |
| # WARN_INVALID-NEXT: warning: GuardEHContinuationTable not set correctly in '_load_config_used' |
| # WARN_INVALID-NEXT: warning: GuardEHContinuationCount not set correctly in '_load_config_used' |
| |
| # RUN: llvm-mc -triple x86_64-windows-msvc %t/loadcfg-small112.s -filetype=obj -o %t/loadcfg-small112.obj |
| # RUN: lld-link %t/main.obj %t/loadcfg-small112.obj -guard:cf,longjmp -out:%t-small112.exe -entry:main %basename_t-exp.lib 2>&1 | FileCheck %s --check-prefix=WARN_SMALL_112 |
| # WARN_SMALL_112: warning: '_load_config_used' structure too small to include GuardFlags |
| |
| # RUN: llvm-mc -triple x86_64-windows-msvc %t/loadcfg-small148.s -filetype=obj -o %t/loadcfg-small148.obj |
| # RUN: lld-link %t/main.obj %t/loadcfg-small148.obj -guard:cf,longjmp -out:%t-small148.exe -entry:main %basename_t-exp.lib 2>&1 | FileCheck %s --check-prefix=WARN_SMALL_148 |
| # WARN_SMALL_148: warning: '_load_config_used' structure too small to include GuardLongJumpTargetCount |
| |
| # RUN: llvm-mc -triple x86_64-windows-msvc %t/loadcfg-small244.s -filetype=obj -o %t/loadcfg-small244.obj |
| # RUN: lld-link %t/main.obj %t/loadcfg-small244.obj -guard:cf,longjmp,ehcont -out:%t-small244.exe -entry:main %basename_t-exp.lib 2>&1 | FileCheck %s --check-prefix=WARN_SMALL_244 |
| # WARN_SMALL_244: warning: '_load_config_used' structure too small to include GuardEHContinuationCount |
| |
| # RUN: llvm-mc -triple x86_64-windows-msvc %t/loadcfg-misaligned1.s -filetype=obj -o %t/loadcfg-misaligned1.obj |
| # RUN: lld-link %t/main.obj %t/loadcfg-misaligned1.obj -guard:cf,longjmp,ehcont -out:%t-misaligned1.exe -entry:main %basename_t-exp.lib 2>&1 | FileCheck %s --check-prefix=WARN_ALIGN1 |
| # WARN_ALIGN1: warning: '_load_config_used' is misaligned (expected alignment to be 8 bytes, got 4 instead) |
| |
| # RUN: llvm-mc -triple x86_64-windows-msvc %t/loadcfg-misaligned2.s -filetype=obj -o %t/loadcfg-misaligned2.obj |
| # RUN: lld-link %t/main.obj %t/loadcfg-misaligned2.obj -guard:cf,longjmp,ehcont -out:%t-misaligned2.exe -entry:main %basename_t-exp.lib 2>&1 | FileCheck %s --check-prefix=WARN_ALIGN2 |
| # WARN_ALIGN2: warning: '_load_config_used' is misaligned (section offset is 0x{{[0-9A-F]*}}2 not aligned to 8 bytes) |
| |
| # RUN: llvm-mc -triple x86_64-windows-msvc %t/loadcfg-full.s -filetype=obj -o %t/loadcfg-full.obj |
| # RUN: lld-link %t/main.obj %t/loadcfg-full.obj -guard:cf,longjmp,ehcont -out:%t.exe -entry:main %basename_t-exp.lib 2>&1 | FileCheck %s --check-prefix=NOWARN --allow-empty |
| # NOWARN-NOT: warning |
| |
| # Sanity check to make sure the no-warn version has the expected data. |
| # RUN: llvm-readobj --file-headers --coff-load-config %t.exe | FileCheck --check-prefix=CHECK %s |
| # CHECK: ImageBase: 0x140000000 |
| # CHECK: LoadConfig [ |
| # CHECK: SEHandlerTable: 0x0 |
| # CHECK: SEHandlerCount: 0 |
| # CHECK: GuardCFCheckFunction: 0x0 |
| # CHECK: GuardCFCheckDispatch: 0x0 |
| # CHECK: GuardCFFunctionTable: 0x14000{{([0-9A-F]{4})}} |
| # CHECK: GuardCFFunctionCount: 1 |
| # CHECK: GuardFlags [ (0x410500) |
| # CHECK: CF_FUNCTION_TABLE_PRESENT (0x400) |
| # CHECK: CF_INSTRUMENTED (0x100) |
| # CHECK: CF_LONGJUMP_TABLE_PRESENT (0x10000) |
| # CHECK: EH_CONTINUATION_TABLE_PRESENT (0x400000) |
| # CHECK: ] |
| # CHECK: GuardAddressTakenIatEntryTable: 0x14000{{([0-9A-F]{4})}} |
| # CHECK: GuardAddressTakenIatEntryCount: 1 |
| # CHECK: GuardLongJumpTargetTable: 0x14000{{([0-9A-F]{4})}} |
| # CHECK: GuardLongJumpTargetCount: 1 |
| # CHECK: GuardEHContinuationTable: 0x14000{{([0-9A-F]{4})}} |
| # CHECK: GuardEHContinuationCount: 1 |
| # CHECK: ] |
| # CHECK-NEXT: GuardFidTable [ |
| # CHECK-NEXT: 0x14000{{([0-9A-F]{4})}} |
| # CHECK-NEXT: ] |
| # CHECK-NEXT: GuardIatTable [ |
| # CHECK-NEXT: 0x14000{{([0-9A-F]{4})}} |
| # CHECK-NEXT: ] |
| # CHECK-NEXT: GuardLJmpTable [ |
| # CHECK-NEXT: 0x14000{{([0-9A-F]{4})}} |
| # CHECK-NEXT: ] |
| # CHECK-NEXT: GuardEHContTable [ |
| # CHECK-NEXT: 0x14000{{([0-9A-F]{4})}} |
| # CHECK-NEXT: ] |
| |
| |
| #--- main.s |
| |
| # We need @feat.00 to have 0x4000 | 0x800 to indicate /guard:cf and /guard:ehcont. |
| .def @feat.00; |
| .scl 3; |
| .type 0; |
| .endef |
| .globl @feat.00 |
| @feat.00 = 0x4800 |
| .def main; .scl 2; .type 32; .endef |
| .globl main # -- Begin function main |
| .p2align 4, 0x90 |
| main: |
| mov %eax, %eax |
| movq __imp_exportfn1(%rip), %rax |
| callq *%rax |
| nop |
| # Fake setjmp target |
| $cfgsj_main0: |
| mov %ebx, %ebx |
| nop |
| # Fake ehcont target |
| $ehgcr_0_1: |
| mov %ecx, %ecx |
| nop |
| retq |
| # -- End function |
| .section .gfids$y,"dr" |
| .symidx main |
| .section .giats$y,"dr" |
| .symidx __imp_exportfn1 |
| .section .gljmp$y,"dr" |
| .symidx $cfgsj_main0 |
| .section .gehcont$y,"dr" |
| .symidx $ehgcr_0_1 |
| .addrsig_sym main |
| .addrsig_sym __imp_exportfn1 |
| .section .rdata,"dr" |
| |
| #--- loadcfg-invalid.s |
| |
| .globl _load_config_used |
| .p2align 3 |
| _load_config_used: |
| .long 312 |
| .fill 308, 1, 0 |
| |
| #--- loadcfg-small112.s |
| |
| .globl _load_config_used |
| .p2align 3 |
| _load_config_used: |
| .long 112 |
| .fill 108, 1, 0 |
| |
| #--- loadcfg-small148.s |
| |
| .globl _load_config_used |
| .p2align 3 |
| _load_config_used: |
| .long 148 |
| .fill 124, 1, 0 |
| .quad __guard_fids_table |
| .quad __guard_fids_count |
| .long __guard_flags |
| |
| #--- loadcfg-small244.s |
| |
| .globl _load_config_used |
| .p2align 3 |
| _load_config_used: |
| .long 244 |
| .fill 124, 1, 0 |
| .quad __guard_fids_table |
| .quad __guard_fids_count |
| .long __guard_flags |
| .fill 12, 1, 0 |
| .quad __guard_iat_table |
| .quad __guard_iat_count |
| .quad __guard_longjmp_table |
| .quad __guard_longjmp_count |
| .fill 52, 1, 0 # Up to HotPatchTableOffset |
| |
| #--- loadcfg-misaligned1.s |
| |
| .globl _load_config_used |
| .fill 2, 1, 0 # offset by 2 |
| .p2align 2 # then align to 0x04 |
| _load_config_used: |
| .long 312 |
| .fill 124, 1, 0 |
| .quad __guard_fids_table |
| .quad __guard_fids_count |
| .long __guard_flags |
| .fill 12, 1, 0 |
| .quad __guard_iat_table |
| .quad __guard_iat_count |
| .quad __guard_longjmp_table |
| .quad __guard_longjmp_count |
| .fill 72, 1, 0 |
| .quad __guard_eh_cont_table |
| .quad __guard_eh_cont_count |
| .fill 32, 1, 0 |
| |
| #--- loadcfg-misaligned2.s |
| |
| .globl _load_config_used |
| .p2align 4 # align to 0x10 |
| .fill 2, 1, 0 # then offset by 2 |
| _load_config_used: |
| .long 312 |
| .fill 124, 1, 0 |
| .quad __guard_fids_table |
| .quad __guard_fids_count |
| .long __guard_flags |
| .fill 12, 1, 0 |
| .quad __guard_iat_table |
| .quad __guard_iat_count |
| .quad __guard_longjmp_table |
| .quad __guard_longjmp_count |
| .fill 72, 1, 0 |
| .quad __guard_eh_cont_table |
| .quad __guard_eh_cont_count |
| .fill 32, 1, 0 |
| |
| #--- loadcfg-full.s |
| |
| .globl _load_config_used |
| .p2align 3 |
| _load_config_used: |
| .long 312 |
| .fill 124, 1, 0 |
| .quad __guard_fids_table |
| .quad __guard_fids_count |
| .long __guard_flags |
| .fill 12, 1, 0 |
| .quad __guard_iat_table |
| .quad __guard_iat_count |
| .quad __guard_longjmp_table |
| .quad __guard_longjmp_count |
| .fill 72, 1, 0 |
| .quad __guard_eh_cont_table |
| .quad __guard_eh_cont_count |
| .fill 32, 1, 0 |