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.
289 lines
8.0 KiB
289 lines
8.0 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.
|
|
*/
|
|
|
|
/*
|
|
* Expanded from just testing ret far to include tests for
|
|
* a number of other instructions with implicit registers
|
|
*/
|
|
#include <stdio.h>
|
|
|
|
typedef unsigned long long UINT64;
|
|
typedef signed long long INT64;
|
|
typedef unsigned int UINT32;
|
|
typedef unsigned short UINT16;
|
|
|
|
extern "C" int FarCallTest();
|
|
extern "C" void MaskMovQ(void *dest, UINT64 src, UINT64 mask);
|
|
extern "C" void * pushESP(void *stack);
|
|
extern "C" void * popESP(void *stack);
|
|
extern "C" void * push4ESP(void *stack);
|
|
extern "C" void * pop4ESP(void *stack);
|
|
extern "C" void * pushStarESP(void *stack);
|
|
extern "C" void * popStarESP(void *stack);
|
|
extern "C" void * pushFlags(void *stack);
|
|
extern "C" void * pushIZero(void *stack);
|
|
extern "C" void * pushWIZero(void *stack);
|
|
extern "C" void * pushIM1(void *stack);
|
|
extern "C" void * pushIs16(void *stack);
|
|
extern "C" void * pushMemAbs(void *stack);
|
|
extern "C" void * pushCS(void *stack);
|
|
extern "C" UINT16 readCS();
|
|
extern "C" void * pushFS(void *stack);
|
|
extern "C" UINT16 readFS();
|
|
|
|
/* Test maskMovQ */
|
|
static int tmq()
|
|
{
|
|
UINT64 dest = 0;
|
|
UINT64 mTrue= UINT64(0x80);
|
|
UINT64 mOnes= UINT64(0xff);
|
|
UINT64 mask = mTrue<<(7*8) | mTrue<<(5*8) | mTrue<<(3*8) | mTrue<<(1*8);
|
|
UINT64 src = UINT64(INT64(-1));
|
|
|
|
MaskMovQ(&dest, src, mask);
|
|
if (dest == (mOnes<<(7*8) | mOnes<<(5*8) | mOnes<<(3*8) | mOnes<<(1*8)))
|
|
{
|
|
printf ("MaskMov: OK\n");
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
printf ("***Fail*** MaskMov: result 0x%08x%08x\n", UINT32(dest>>32), UINT32(dest));
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/* test some unpleasant push and pop cases */
|
|
static int tPushPop()
|
|
{
|
|
void * stack[3];
|
|
void ** stackTop = &stack[2];
|
|
void *finalAddr= pushESP(stackTop);
|
|
int fails = 0;
|
|
|
|
// push %esp
|
|
if (finalAddr != &stack[1] ||
|
|
stack[1] != stackTop)
|
|
{
|
|
printf ("***Fail*** PushESP : top %p, result %p value %p\n", stackTop, finalAddr, stack[1]);
|
|
fails++;
|
|
}
|
|
else
|
|
{
|
|
printf ("push %%esp: OK\n");
|
|
}
|
|
|
|
// pop %esp
|
|
stack[0] = (void *)0x1234;
|
|
finalAddr = popESP(&stack[0]);
|
|
if (finalAddr != (void *)0x1234)
|
|
{
|
|
printf ("***Fail*** PopESP: result %p\n", finalAddr);
|
|
fails++;
|
|
}
|
|
else
|
|
{
|
|
printf ("pop %%esp: OK\n");
|
|
}
|
|
|
|
// push (%esp)
|
|
stack[0] = 0;
|
|
stack[1] = (void *)0xdefaced0;
|
|
stack[2] = 0;
|
|
finalAddr = pushStarESP(&stack[1]);
|
|
|
|
if (finalAddr != &stack[0] ||
|
|
stack[0] != stack[1] ||
|
|
stack[1] != (void *)0xdefaced0)
|
|
{
|
|
printf ("***Fail***: push (%%esp)\n");
|
|
fails++;
|
|
}
|
|
else
|
|
{
|
|
printf ("push (%%esp): OK\n");
|
|
}
|
|
|
|
// pop (%esp)
|
|
stack[0] = (void *)0xfaded;
|
|
stack[2] = 0;
|
|
finalAddr = popStarESP(&stack[0]);
|
|
|
|
if (finalAddr != &stack[1] ||
|
|
stack[0] != stack[1] ||
|
|
stack[1] != (void *)0xfaded ||
|
|
stack[2] != 0)
|
|
{
|
|
printf ("***Fail***: pop (%%esp)\n");
|
|
printf ("FinalAddr : %p should be %p\n", finalAddr, &stack[1]);
|
|
printf ("stack[0] : %p should be 0xfaded\n", stack[0]);
|
|
printf ("stack[1] : %p should be 0xfaded\n", stack[1]);
|
|
printf ("stack[2] : 0x%08x should be 0\n", UINT32(stack[2]));
|
|
fails++;
|
|
}
|
|
else
|
|
{
|
|
printf ("pop (%%esp): OK\n");
|
|
}
|
|
|
|
// push 4(%esp)
|
|
stack[0] = 0;
|
|
stack[1] = 0;
|
|
stack[2] = (void *)0xdefaced0;
|
|
finalAddr = push4ESP(&stack[1]);
|
|
|
|
if (finalAddr != &stack[0] ||
|
|
stack[0] != stack[2] ||
|
|
stack[2] != (void *)0xdefaced0)
|
|
{
|
|
printf ("***Fail***: push 4(%%esp)\n");
|
|
fails++;
|
|
}
|
|
else
|
|
{
|
|
printf ("push 4(%%esp): OK\n");
|
|
}
|
|
|
|
// pop 4(%esp)
|
|
stack[0] = (void *)-1;
|
|
stack[1] = (void *)0xfaded;
|
|
stack[2] = 0;
|
|
finalAddr = pop4ESP(&stack[0]);
|
|
|
|
if (finalAddr != &stack[1] ||
|
|
stack[0] != (void *)-1 ||
|
|
stack[1] != (void *)0xfaded ||
|
|
stack[2] != stack[0])
|
|
{
|
|
printf ("***Fail***: pop 4(%%esp)\n");
|
|
printf ("FinalAddr : %p should be %p\n", finalAddr, &stack[1]);
|
|
printf ("stack[0] : %p should be -1\n", stack[0]);
|
|
printf ("stack[1] : %p should be 0xfaded\n", stack[1]);
|
|
printf ("stack[2] : 0x%08x should be -1\n", UINT32(stack[2]));
|
|
fails++;
|
|
}
|
|
else
|
|
{
|
|
printf ("pop (%%esp): OK\n");
|
|
}
|
|
|
|
|
|
finalAddr = pushFlags(&stack[1]);
|
|
if (finalAddr != &stack[0])
|
|
{
|
|
printf ("***Fail***: pushFlags wrong ESP\n");
|
|
fails++;
|
|
}
|
|
|
|
printf ("Flags pushed : 0x%08x\n", UINT32(stack[0]) & ~4);
|
|
|
|
stack[0] = stack[1] = stack[2] = (void *)-1;
|
|
finalAddr = pushIZero(&stack[2]);
|
|
if (finalAddr != &stack[1] ||
|
|
stack[1] != 0)
|
|
{
|
|
printf ("***Fail***: pushl $0\n");
|
|
printf ("FinalAddr : %p should be %p\n", finalAddr, &stack[1]);
|
|
printf ("stack[1] : %p should be 0\n", stack[1]);
|
|
fails++;
|
|
}
|
|
else
|
|
printf ("pushl $0: OK\n");
|
|
|
|
stack[0] = stack[1] = stack[2] = (void *)-1;
|
|
finalAddr = pushWIZero(&stack[2]);
|
|
if (finalAddr != (((char *)&stack[1])+2) ||
|
|
stack[1] != (void *)0xffff)
|
|
{
|
|
printf ("***Fail***: pushw $0\n");
|
|
printf ("FinalAddr : %p should be %p\n", finalAddr, ((char *)&stack[1])+2);
|
|
printf ("stack[1] : %p should be 0xffff\n", stack[1]);
|
|
fails++;
|
|
}
|
|
else
|
|
printf ("pushw $0: OK\n");
|
|
|
|
stack[0] = stack[1] = stack[2] = (void *)0;
|
|
finalAddr = pushIM1(&stack[2]);
|
|
if (finalAddr != &stack[1] ||
|
|
stack[1] != (void *)-1)
|
|
{
|
|
printf ("***Fail***: pushl $-1\n");
|
|
printf ("FinalAddr : %p should be %p\n", finalAddr, &stack[1]);
|
|
printf ("stack[1] : %p should be -1\n", stack[1]);
|
|
fails++;
|
|
}
|
|
else
|
|
printf ("pushl $-1: OK\n");
|
|
|
|
stack[0] = stack[1] = stack[2] = (void *)0;
|
|
finalAddr = pushIs16(&stack[2]);
|
|
if (finalAddr != &stack[1] ||
|
|
stack[1] != (void *)0xffff8000)
|
|
{
|
|
printf ("***Fail***: pushl $0xffff8000\n");
|
|
printf ("FinalAddr : %p should be %p\n", finalAddr, &stack[1]);
|
|
printf ("stack[1] : %p should be 0xffff8000\n", stack[1]);
|
|
fails++;
|
|
}
|
|
else
|
|
printf ("pushl $0xffff8000: OK\n");
|
|
|
|
stack[0] = stack[1] = stack[2] = (void *)-1;
|
|
finalAddr = pushMemAbs(&stack[2]);
|
|
if (finalAddr != &stack[1] ||
|
|
stack[1] != (void *)0x01234567)
|
|
{
|
|
printf ("***Fail***: pushl absoluteAddress\n");
|
|
printf ("FinalAddr : %p should be %p\n", finalAddr, &stack[1]);
|
|
printf ("stack[1] : %p should be 0x01234567\n", stack[1]);
|
|
fails++;
|
|
}
|
|
else
|
|
printf ("pushl absoluteAddress: OK\n");
|
|
|
|
printf ("%%cs = 0x%04x\n", readCS());
|
|
stack[0] = stack[1] = stack[2] = (void *)-1;
|
|
finalAddr = pushCS(&stack[2]);
|
|
if (finalAddr != &stack[1])
|
|
printf ("FinalAddr : %p should be %p\n", finalAddr, &stack[1]);
|
|
printf ("After push %%cs, value pushed is %p\n", stack[1]);
|
|
|
|
stack[0] = stack[1] = stack[2] = (void *)0xaaaaaaaa;
|
|
finalAddr = pushCS(&stack[2]);
|
|
if (finalAddr != &stack[1])
|
|
printf ("FinalAddr : %p should be %p\n", finalAddr, &stack[1]);
|
|
printf ("After push %%cs, value pushed is %p\n", stack[1]);
|
|
|
|
printf ("%%fs = 0x%04x\n", readFS());
|
|
stack[0] = stack[1] = stack[2] = (void *)0xaaaaaaaa;
|
|
finalAddr = pushFS(&stack[2]);
|
|
if (finalAddr != &stack[1])
|
|
printf ("FinalAddr : %p should be %p\n", finalAddr, &stack[1]);
|
|
printf ("After push %%fs, value pushed is 0x%04x\n", UINT32(stack[1]) & 0x0000ffff);
|
|
|
|
return fails;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
int res = FarCallTest();
|
|
int fails = res != 5;
|
|
|
|
printf("Res is 0x%x\n", res);
|
|
|
|
fails += tmq();
|
|
fails += tPushPop();
|
|
|
|
return fails;
|
|
}
|
|
|