forked from OSchip/llvm-project
117 lines
3.7 KiB
ArmAsm
117 lines
3.7 KiB
ArmAsm
# 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
|
|
|
|
# Make an object file that imports exportfn1.
|
|
# RUN: llvm-mc -triple x86_64-windows-msvc %s -filetype=obj -o %basename_t.obj
|
|
|
|
# Check that the Guard address-taken IAT entry tables are propagated to the final executable.
|
|
# RUN: lld-link %basename_t.obj -guard:cf -entry:main -out:%basename_t-nodelay.exe %basename_t-exp.lib
|
|
# RUN: llvm-readobj --file-headers --coff-load-config %basename_t-nodelay.exe | FileCheck %s --check-prefix CHECK
|
|
|
|
# CHECK: ImageBase: 0x140000000
|
|
# CHECK: LoadConfig [
|
|
# CHECK: GuardCFFunctionTable: 0x140002114
|
|
# CHECK: GuardCFFunctionCount: 1
|
|
# CHECK: GuardFlags: 0x10500
|
|
# CHECK: GuardAddressTakenIatEntryTable: 0x140002118
|
|
# CHECK: GuardAddressTakenIatEntryCount: 1
|
|
# CHECK: ]
|
|
# CHECK: GuardFidTable [
|
|
# CHECK-NEXT: 0x14000{{.*}}
|
|
# CHECK-NEXT: ]
|
|
# CHECK: GuardIatTable [
|
|
# CHECK-NEXT: 0x14000{{.*}}
|
|
# CHECK-NEXT: ]
|
|
|
|
|
|
# Check that the additional load thunk symbol is added to the GFIDs table.
|
|
# RUN: lld-link %basename_t.obj -guard:cf -entry:main -out:%basename_t-delay.exe %basename_t-exp.lib -alternatename:__delayLoadHelper2=main -delayload:%basename_t-exp.dll
|
|
# RUN: llvm-readobj --file-headers --coff-load-config %basename_t-delay.exe | FileCheck %s --check-prefix DELAY-CHECK
|
|
|
|
# DELAY-CHECK: ImageBase: 0x140000000
|
|
# DELAY-CHECK: LoadConfig [
|
|
# DELAY-CHECK: GuardCFFunctionTable: 0x140002114
|
|
# DELAY-CHECK: GuardCFFunctionCount: 2
|
|
# DELAY-CHECK: GuardFlags: 0x10500
|
|
# DELAY-CHECK: GuardAddressTakenIatEntryTable: 0x14000211C
|
|
# DELAY-CHECK: GuardAddressTakenIatEntryCount: 1
|
|
# DELAY-CHECK: ]
|
|
# DELAY-CHECK: GuardFidTable [
|
|
# DELAY-CHECK-NEXT: 0x14000{{.*}}
|
|
# DELAY-CHECK-NEXT: 0x14000{{.*}}
|
|
# DELAY-CHECK-NEXT: ]
|
|
# DELAY-CHECK: GuardIatTable [
|
|
# DELAY-CHECK-NEXT: 0x14000{{.*}}
|
|
# DELAY-CHECK-NEXT: ]
|
|
|
|
|
|
# This assembly is reduced from C code like:
|
|
# __declspec(noinline)
|
|
# void IndirectCall(BOOL (func)(HANDLE)) {
|
|
# (*func)(NULL);
|
|
# }
|
|
# int main(int argc, char** argv) {
|
|
# IndirectCall(exportfn1);
|
|
# }
|
|
|
|
.text
|
|
.def @feat.00;
|
|
.scl 3;
|
|
.type 0;
|
|
.endef
|
|
.globl @feat.00
|
|
.set @feat.00, 2048
|
|
.def IndirectCall; .scl 2; .type 32; .endef
|
|
.globl IndirectCall # -- Begin function IndirectCall
|
|
.p2align 4, 0x90
|
|
IndirectCall: # @IndirectCall
|
|
# %bb.0:
|
|
subq $40, %rsp
|
|
movq %rcx, 32(%rsp)
|
|
movq 32(%rsp), %rax
|
|
movq %rax, %rdx # This would otherwise have be: movq __guard_dispatch_icall_fptr(%rip), %rdx
|
|
xorl %ecx, %ecx
|
|
callq *%rdx
|
|
nop
|
|
addq $40, %rsp
|
|
retq
|
|
# -- End function
|
|
.def main; .scl 2; .type 32; .endef
|
|
.globl main # -- Begin function main
|
|
.p2align 4, 0x90
|
|
main: # @main
|
|
# %bb.0:
|
|
subq $56, %rsp
|
|
movq __imp_exportfn1(%rip), %rax
|
|
movq %rdx, 48(%rsp)
|
|
movl %ecx, 44(%rsp)
|
|
movq %rax, %rcx
|
|
callq IndirectCall
|
|
xorl %eax, %eax
|
|
addq $56, %rsp
|
|
retq
|
|
# -- End function
|
|
.section .gfids$y,"dr"
|
|
.section .giats$y,"dr"
|
|
.symidx __imp_exportfn1
|
|
.section .gljmp$y,"dr"
|
|
|
|
# Load configuration directory entry (winnt.h _IMAGE_LOAD_CONFIG_DIRECTORY64).
|
|
# The linker will define the __guard_* symbols.
|
|
.section .rdata,"dr"
|
|
.globl _load_config_used
|
|
_load_config_used:
|
|
.long 256
|
|
.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_fids_count
|
|
.fill 84, 1, 0 |