You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
624 lines
13 KiB
624 lines
13 KiB
/*
|
|
* Copyright 2002-2019 Intel Corporation.
|
|
*
|
|
* This software is provided to you as Sample Source Code as defined in the accompanying
|
|
* End User License Agreement for the Intel(R) Software Development Products ("Agreement")
|
|
* section 1.L.
|
|
*
|
|
* This software and the related documents are provided as is, with no express or implied
|
|
* warranties, other than those that are expressly stated in the License.
|
|
*/
|
|
|
|
# Each test sets these to register values at the time of the fault.
|
|
#
|
|
.comm ExpectedPC,8,8
|
|
.comm ExpectedR8,8,8
|
|
.comm ExpectedR9,8,8
|
|
.comm ExpectedR10,8,8
|
|
.comm ExpectedR11,8,8
|
|
.comm ExpectedR12,8,8
|
|
.comm ExpectedR13,8,8
|
|
.comm ExpectedR14,8,8
|
|
.comm ExpectedR15,8,8
|
|
.comm ExpectedRDI,8,8
|
|
.comm ExpectedRSI,8,8
|
|
.comm ExpectedRBP,8,8
|
|
.comm ExpectedRBX,8,8
|
|
.comm ExpectedRDX,8,8
|
|
.comm ExpectedRAX,8,8
|
|
.comm ExpectedRCX,8,8
|
|
.comm ExpectedRSP,8,8
|
|
.comm ExpectedEFLAGS,8,8
|
|
|
|
# Some scratch memory used by the tests below.
|
|
#
|
|
.comm Scratch,4096,8
|
|
|
|
|
|
.text
|
|
|
|
# SetRegisters()
|
|
#
|
|
# Set the integer registers and their associated 'Expected*' variables
|
|
# to weird values.
|
|
#
|
|
.align 4
|
|
.globl SetRegisters
|
|
SetRegisters:
|
|
# Set flags to:
|
|
#
|
|
# AC=0, OF=1, DF=1, TF=0, SF=0, ZF=1, AF=1, PF=0, CF=1
|
|
#
|
|
movq $0xc51, %rax
|
|
pushq %rax
|
|
popfq
|
|
movq $0xc51, ExpectedEFLAGS(%rip)
|
|
|
|
movq $1, %r8
|
|
movq $2, %r9
|
|
movq $3, %r10
|
|
movq $4, %r11
|
|
movq $5, %r12
|
|
movq $6, %r13
|
|
movq $7, %r14
|
|
movq $8, %r15
|
|
movq $9, %rdi
|
|
movq $10, %rsi
|
|
movq $11, %rbp
|
|
movq $12, %rbx
|
|
movq $13, %rdx
|
|
movq $14, %rax
|
|
movq $15, %rcx
|
|
|
|
movq %r8, ExpectedR8(%rip)
|
|
movq %r9, ExpectedR9(%rip)
|
|
movq %r10, ExpectedR10(%rip)
|
|
movq %r11, ExpectedR11(%rip)
|
|
movq %r12, ExpectedR12(%rip)
|
|
movq %r13, ExpectedR13(%rip)
|
|
movq %r14, ExpectedR14(%rip)
|
|
movq %r15, ExpectedR15(%rip)
|
|
movq %rdi, ExpectedRDI(%rip)
|
|
movq %rsi, ExpectedRSI(%rip)
|
|
movq %rbp, ExpectedRBP(%rip)
|
|
movq %rbx, ExpectedRBX(%rip)
|
|
movq %rdx, ExpectedRDX(%rip)
|
|
movq %rax, ExpectedRAX(%rip)
|
|
movq %rcx, ExpectedRCX(%rip)
|
|
ret
|
|
|
|
|
|
# DoFaultRetSp()
|
|
#
|
|
# Cause RET to fault by making $SP invalid.
|
|
#
|
|
.align 4
|
|
.globl DoFaultRetSp
|
|
DoFaultRetSp:
|
|
call SetRegisters
|
|
push %rcx
|
|
lea DoFaultRetSpLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq $0, ExpectedRSP(%rip)
|
|
movq $0, %rsp
|
|
DoFaultRetSpLab:
|
|
ret
|
|
|
|
|
|
# DoFaultRetTarg()
|
|
#
|
|
# Cause RET to fault due to invalid target.
|
|
#
|
|
.align 4
|
|
.globl DoFaultRetTarg
|
|
DoFaultRetTarg:
|
|
call SetRegisters
|
|
movq $0, ExpectedPC(%rip)
|
|
mov %rsp, ExpectedRSP(%rip)
|
|
pushq $0
|
|
ret
|
|
|
|
|
|
# DoFaultRetImmSp()
|
|
#
|
|
# Cause "RET <imm>" to fault by making $SP invalid.
|
|
#
|
|
.align 4
|
|
.globl DoFaultRetImmSp
|
|
DoFaultRetImmSp:
|
|
call SetRegisters
|
|
push %rcx
|
|
lea DoFaultRetImmSpLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq $0, ExpectedRSP(%rip)
|
|
movq $0, %rsp
|
|
DoFaultRetImmSpLab:
|
|
ret $0x40
|
|
|
|
|
|
# DoFaultRetImmTarg()
|
|
#
|
|
# Cause "RET <imm>" to fault due to invalid target.
|
|
#
|
|
.align 4
|
|
.globl DoFaultRetImmTarg
|
|
DoFaultRetImmTarg:
|
|
movq $0, ExpectedPC(%rip)
|
|
# Save the stack pointer in rax
|
|
mov %rsp, %rax
|
|
addq $0x40, %rax
|
|
mov %rax, ExpectedRSP(%rip)
|
|
call SetRegisters
|
|
pushq $0
|
|
ret $0x40
|
|
|
|
|
|
# DoFaultCallSp()
|
|
#
|
|
# Cause direct CALL to fault because $SP is invalid.
|
|
#
|
|
.align 4
|
|
.globl DoFaultCallSp
|
|
DoFaultCallSp:
|
|
call SetRegisters
|
|
push %rcx
|
|
lea DoFaultCallSpLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq $0, ExpectedRSP(%rip)
|
|
movq $0, %rsp
|
|
DoFaultCallSpLab:
|
|
call DoFaultCallSp
|
|
|
|
|
|
# DoFaultCallTarg()
|
|
#
|
|
# Cause direct CALL to fault because target is invalid.
|
|
#
|
|
.align 4
|
|
.globl DoFaultCallTarg
|
|
DoFaultCallTarg:
|
|
push %rcx
|
|
lea Unmapped(%rip), %rcx
|
|
mov %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
# Save the stack pointer in rax
|
|
mov %rsp, %rax
|
|
subq $8, %rax
|
|
mov %rax, ExpectedRSP(%rip)
|
|
call SetRegisters
|
|
call Unmapped
|
|
|
|
|
|
# DoFaultCallRegSp()
|
|
#
|
|
# Cause "CALL *%rx" to fault because $SP is invalid.
|
|
#
|
|
.align 4
|
|
.globl DoFaultCallRegSp
|
|
DoFaultCallRegSp:
|
|
call SetRegisters
|
|
push %rcx
|
|
lea DoFaultCallRegSpLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
lea DoFaultCallRegSp(%rip), %rdi
|
|
movq %rdi, ExpectedRDI(%rip)
|
|
movq $0, ExpectedRSP(%rip)
|
|
movq $0, %rsp
|
|
lea DoFaultCallRegSp(%rip), %rdi
|
|
DoFaultCallRegSpLab:
|
|
call *%rdi
|
|
|
|
|
|
# DoFaultCallRegTarg()
|
|
#
|
|
# Cause "CALL *%rx" to fault because target is invalid.
|
|
#
|
|
.align 4
|
|
.globl DoFaultCallRegTarg
|
|
DoFaultCallRegTarg:
|
|
push %rcx
|
|
lea Unmapped(%rip), %rcx
|
|
mov %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
# Save the stack pointer in rax
|
|
mov %rsp, %rax
|
|
subq $8, %rax
|
|
mov %rax, ExpectedRSP(%rip)
|
|
call SetRegisters
|
|
lea Unmapped(%rip), %rdi
|
|
mov %rdi, ExpectedRDI(%rip)
|
|
call *%rdi
|
|
|
|
|
|
# DoFaultCallMemSp()
|
|
#
|
|
# Cause "CALL *[mem]" to fault because $SP is invalid.
|
|
#
|
|
.align 4
|
|
.globl DoFaultCallMemSp
|
|
DoFaultCallMemSp:
|
|
call SetRegisters
|
|
push %rcx
|
|
lea DoFaultCallMemSpLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
lea DoFaultCallMemSp(%rip), %rcx
|
|
movq %rcx, Scratch(%rip)
|
|
pop %rcx
|
|
movq $0, ExpectedRSP(%rip)
|
|
movq $0, %rsp
|
|
DoFaultCallMemSpLab:
|
|
call *Scratch(%rip)
|
|
|
|
|
|
# DoFaultCallMemTarg()
|
|
#
|
|
# Cause "CALL *[mem]" to fault because target is invalid.
|
|
#
|
|
.align 4
|
|
.globl DoFaultCallMemTarg
|
|
DoFaultCallMemTarg:
|
|
lea Unmapped(%rip), %rax
|
|
mov %rax, ExpectedPC(%rip)
|
|
# Save the stack pointer in rax
|
|
mov %rsp, %rax
|
|
subq $8, %rax
|
|
mov %rax, ExpectedRSP(%rip)
|
|
call SetRegisters
|
|
push %rcx
|
|
lea Unmapped(%rip), %rcx
|
|
movq %rcx, Scratch(%rip)
|
|
pop %rcx
|
|
call *Scratch(%rip)
|
|
|
|
|
|
# DoFaultCallMemBadMem()
|
|
#
|
|
# Cause "CALL *[mem]" to fault because [mem] is invalid.
|
|
#
|
|
.align 4
|
|
.globl DoFaultCallMemBadMem
|
|
DoFaultCallMemBadMem:
|
|
push %rcx
|
|
lea DoFaultCallMemBadMemLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq %rsp, ExpectedRSP(%rip)
|
|
call SetRegisters
|
|
DoFaultCallMemBadMemLab:
|
|
call *Unmapped(%rip)
|
|
|
|
|
|
# DoFaultSegMov()
|
|
#
|
|
# Cause MOV to fault because of illegal segment selector.
|
|
#
|
|
.align 4
|
|
.globl DoFaultSegMov
|
|
DoFaultSegMov:
|
|
movq $0, %rax
|
|
mov %gs, %ax
|
|
call SetRegisters
|
|
push %rcx
|
|
lea DoFaultSegMovLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq %rsp, ExpectedRSP(%rip)
|
|
DoFaultSegMovLab:
|
|
mov %gs:0, %rdi
|
|
ret
|
|
|
|
|
|
# DoFaultStringOp()
|
|
#
|
|
# Cause MOVS to fault.
|
|
#
|
|
.align 4
|
|
.globl DoFaultStringOp
|
|
DoFaultStringOp:
|
|
call SetRegisters
|
|
lea DoFaultStringOpLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
movq $5, ExpectedRCX(%rip)
|
|
lea Unmapped(%rip), %rcx
|
|
mov %rcx, ExpectedRSI(%rip)
|
|
lea Scratch+5*4(%rip), %rcx
|
|
mov %rcx, ExpectedRDI(%rip)
|
|
movq %rsp, ExpectedRSP(%rip)
|
|
movq $0x851, ExpectedEFLAGS(%rip) # Expect Flags to have DF=0
|
|
movq $10, %rcx
|
|
lea Unmapped-5*4(%rip), %rsi
|
|
lea Scratch(%rip), %rdi
|
|
cld
|
|
DoFaultStringOpLab:
|
|
rep movsd
|
|
ret
|
|
|
|
|
|
# DoFaultPushF()
|
|
#
|
|
# Cause PUSHF to fault by making $SP invalid.
|
|
#
|
|
.align 4
|
|
.globl DoFaultPushF
|
|
DoFaultPushF:
|
|
call SetRegisters
|
|
push %rcx
|
|
lea DoFaultPushFLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq $0, ExpectedRSP(%rip)
|
|
movq $0, %rsp
|
|
DoFaultPushFLab:
|
|
pushf
|
|
|
|
|
|
# DoFaultPopF()
|
|
#
|
|
# Cause POPF to fault by making $SP invalid.
|
|
#
|
|
.align 4
|
|
.globl DoFaultPopF
|
|
DoFaultPopF:
|
|
call SetRegisters
|
|
push %rcx
|
|
lea DoFaultPopFLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq $0, ExpectedRSP(%rip)
|
|
movq $0, %rsp
|
|
DoFaultPopFLab:
|
|
popf
|
|
|
|
|
|
# DoFaultPush()
|
|
#
|
|
# Cause PUSH to fault by making $SP invalid.
|
|
#
|
|
.align 4
|
|
.globl DoFaultPush
|
|
DoFaultPush:
|
|
call SetRegisters
|
|
push %rcx
|
|
lea DoFaultPushLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq $0, ExpectedRSP(%rip)
|
|
movq $0, %rsp
|
|
DoFaultPushLab:
|
|
pushq %rdi
|
|
|
|
|
|
# DoFaultPop()
|
|
#
|
|
# Cause POP to fault by making $SP invalid.
|
|
#
|
|
.align 4
|
|
.globl DoFaultPop
|
|
DoFaultPop:
|
|
call SetRegisters
|
|
push %rcx
|
|
lea DoFaultPopLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq $0, ExpectedRSP(%rip)
|
|
movq $0, %rsp
|
|
DoFaultPopLab:
|
|
popq %rdi
|
|
|
|
|
|
# DoFaultPushMem()
|
|
#
|
|
# Cause "PUSH *[mem]" to fault because [mem] is invalid.
|
|
#
|
|
.align 4
|
|
.globl DoFaultPushMem
|
|
DoFaultPushMem:
|
|
call SetRegisters
|
|
push %rcx
|
|
lea DoFaultPushMemLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq %rsp, ExpectedRSP(%rip)
|
|
DoFaultPushMemLab:
|
|
push Unmapped(%rip)
|
|
|
|
|
|
# DoFaultPopMem()
|
|
#
|
|
# Cause "POP *[mem]" to fault because [mem] is invalid.
|
|
#
|
|
.align 4
|
|
.globl DoFaultPopMem
|
|
DoFaultPopMem:
|
|
call SetRegisters
|
|
push %rcx
|
|
lea DoFaultPopMemLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq %rsp, ExpectedRSP(%rip)
|
|
DoFaultPopMemLab:
|
|
popq Unmapped(%rip)
|
|
|
|
|
|
# DoFaultEnter()
|
|
#
|
|
# Cause ENTER to fault by making $SP invalid.
|
|
#
|
|
.align 4
|
|
.globl DoFaultEnter
|
|
DoFaultEnter:
|
|
call SetRegisters
|
|
push %rcx
|
|
lea DoFaultEnterLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq $0, ExpectedRSP(%rip)
|
|
movq $0, %rsp
|
|
DoFaultEnterLab:
|
|
enterq $0, $0
|
|
|
|
|
|
# DoFaultLeave()
|
|
#
|
|
# Cause LEAVE to fault by making $SP invalid.
|
|
#
|
|
.align 4
|
|
.globl DoFaultLeave
|
|
DoFaultLeave:
|
|
call SetRegisters
|
|
push %rcx
|
|
lea DoFaultLeaveLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq $0, ExpectedRSP(%rip)
|
|
movq $0, %rsp
|
|
DoFaultLeaveLab:
|
|
leave
|
|
|
|
|
|
# DoFaultMaskmovdqu()
|
|
#
|
|
# Cause MASKMOVDQU to fault.
|
|
#
|
|
.align 4
|
|
.globl DoFaultMaskmovdqu
|
|
DoFaultMaskmovdqu:
|
|
subq $16, %rsp
|
|
call SetRegisters
|
|
movl $0xffffffff, 0(%rsp)
|
|
movl $0xffffffff, 4(%rsp)
|
|
movl $0xffffffff, 8(%rsp)
|
|
movl $0xffffffff, 12(%rsp)
|
|
movq 0(%rsp), %xmm0
|
|
movq 0(%rsp), %xmm1
|
|
lea Unmapped(%rip), %rdi
|
|
push %rcx
|
|
lea DoFaultMaskmovdquLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq %rsp, ExpectedRSP(%rip)
|
|
movq %rdi, ExpectedRDI(%rip)
|
|
DoFaultMaskmovdquLab:
|
|
maskmovdqu %xmm0, %xmm1
|
|
|
|
|
|
# DoFaultBitTest()
|
|
#
|
|
# Cause BT to fault.
|
|
#
|
|
.align 4
|
|
.globl DoFaultBitTest
|
|
DoFaultBitTest:
|
|
call SetRegisters
|
|
push %rcx
|
|
lea DoFaultBitTestLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq %rsp, ExpectedRSP(%rip)
|
|
movq $16, ExpectedRDI(%rip)
|
|
movq $16, %rdi
|
|
lea Unmapped(%rip), %rcx
|
|
movq %rcx, ExpectedRCX(%rip)
|
|
DoFaultBitTestLab:
|
|
bt %rdi, (%rcx)
|
|
|
|
|
|
# DoFaultMovSegSelector()
|
|
#
|
|
# Cause "MOV %fs, [mem]" to fault.
|
|
#
|
|
.align 4
|
|
.globl DoFaultMovSegSelector
|
|
DoFaultMovSegSelector:
|
|
call SetRegisters
|
|
push %rcx
|
|
lea DoFaultMovSegSelectorLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq %rsp, ExpectedRSP(%rip)
|
|
lea Unmapped(%rip), %rcx
|
|
movq %rcx, ExpectedRCX(%rip)
|
|
DoFaultMovSegSelectorLab:
|
|
mov %fs, (%rcx)
|
|
|
|
|
|
# DoFaultJumpMemBadMem()
|
|
#
|
|
# Cause "JMP *[mem]" to fault because [mem] is invalid.
|
|
#
|
|
.align 4
|
|
.globl DoFaultJumpMemBadMem
|
|
DoFaultJumpMemBadMem:
|
|
push %rcx
|
|
lea DoFaultJumpMemBadMemLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq %rsp, ExpectedRSP(%rip)
|
|
call SetRegisters
|
|
DoFaultJumpMemBadMemLab:
|
|
jmp *Unmapped(%rip)
|
|
|
|
|
|
# DoFaultBadLoad()
|
|
#
|
|
# Cause "MOV [mem], %rx" to fault.
|
|
#
|
|
.align 4
|
|
.globl DoFaultBadLoad
|
|
DoFaultBadLoad:
|
|
push %rcx
|
|
lea DoFaultBadLoadLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq %rsp, ExpectedRSP(%rip)
|
|
call SetRegisters
|
|
DoFaultBadLoadLab:
|
|
mov Unmapped(%rip), %rdi
|
|
|
|
|
|
# DoFaultBadStore()
|
|
#
|
|
# Cause "MOV %rx, [mem]" to fault.
|
|
#
|
|
.align 4
|
|
.globl DoFaultBadStore
|
|
DoFaultBadStore:
|
|
push %rcx
|
|
lea DoFaultBadStoreLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq %rsp, ExpectedRSP(%rip)
|
|
call SetRegisters
|
|
DoFaultBadStoreLab:
|
|
mov %rdi, Unmapped(%rip)
|
|
|
|
|
|
# DoFaultCmov()
|
|
#
|
|
# Cause "CMOVcc %rx, [mem]" to fault.
|
|
#
|
|
.align 4
|
|
.globl DoFaultCmov
|
|
DoFaultCmov:
|
|
push %rcx
|
|
lea DoFaultCmovLab(%rip), %rcx
|
|
movq %rcx, ExpectedPC(%rip)
|
|
pop %rcx
|
|
movq %rsp, ExpectedRSP(%rip)
|
|
call SetRegisters
|
|
DoFaultCmovLab:
|
|
cmovb Unmapped(%rip), %rdi # SetRegisters() sets CF=1, so the condition is true.
|
|
|
|
|
|
# Unmapped()
|
|
#
|
|
# This label is on an unmapped page. (The C++ part of the test program unmaps the page.)
|
|
.align 4096
|
|
.globl Unmapped
|
|
Unmapped:
|
|
.zero 4096
|