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.
175 lines
4.2 KiB
175 lines
4.2 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.
|
|
*/
|
|
|
|
/*
|
|
* This test verifies that Pin properly saves and restores the applicaton's
|
|
* XMM registers when emulating a synchronous signal (i.e. fault). The
|
|
* application's main thread does a memory copy operation using the XMM
|
|
* registers. However, the copy causes a fault by accessing an illegal memory
|
|
* location. A handler catches the fault and fixes the address of the illegal
|
|
* memory location. It also modifies the XMM registers. If Pin doesn't
|
|
* properly save/restore the XMM registers in the handler, the main thread's
|
|
* memory copy will be corrupted.
|
|
*/
|
|
// features.h does not exist on FreeBSD
|
|
#ifdef TARGET_LINUX
|
|
// features initializes the system's state, including the state of __USE_GNU
|
|
#include <features.h>
|
|
#endif
|
|
|
|
// If __USE_GNU is defined, we don't need to do anything.
|
|
// If we defined it ourselves, we need to undefine it later.
|
|
#ifndef __USE_GNU
|
|
#define __USE_GNU
|
|
#define APP_UNDEF_USE_GNU
|
|
#endif
|
|
|
|
#if defined(TARGET_MAC)
|
|
# include <sys/ucontext.h>
|
|
#else
|
|
# include <ucontext.h>
|
|
#endif
|
|
|
|
// If we defined __USE_GNU ourselves, we need to undefine it here.
|
|
#ifdef APP_UNDEF_USE_GNU
|
|
#undef __USE_GNU
|
|
#undef APP_UNDEF_USE_GNU
|
|
#endif
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <signal.h>
|
|
#include <stdlib.h>
|
|
|
|
#define SIZE 32
|
|
#define ALIGN 16
|
|
|
|
char *SigBuf1;
|
|
char *SigBuf2;
|
|
unsigned long Glob;
|
|
|
|
|
|
static void XmmCheck();
|
|
static void CheckBuf(const char *, size_t);
|
|
static char *Allocate(size_t, size_t);
|
|
static void Handle(int, siginfo_t *, void *);
|
|
|
|
extern void CopyWithXmmFault(char *, char *, int);
|
|
extern void CopyWithXmm(char *, char *, int);
|
|
|
|
int main()
|
|
{
|
|
struct sigaction sigact;
|
|
int i;
|
|
|
|
|
|
SigBuf1 = Allocate(SIZE, ALIGN);
|
|
SigBuf2 = Allocate(SIZE, ALIGN);
|
|
for (i = 0; i < SIZE; i++)
|
|
SigBuf1[i] = (char)i;
|
|
|
|
sigact.sa_sigaction = Handle;
|
|
sigact.sa_flags = SA_SIGINFO;
|
|
sigemptyset(&sigact.sa_mask);
|
|
if (sigaction(SIGSEGV, &sigact, 0) == -1)
|
|
{
|
|
fprintf(stderr, "Unable to set up handler\n");
|
|
return 1;
|
|
}
|
|
if (sigaction(SIGBUS, &sigact, 0) == -1)
|
|
{
|
|
fprintf(stderr, "Unable to set up handler\n");
|
|
return 1;
|
|
}
|
|
|
|
XmmCheck();
|
|
return 0;
|
|
}
|
|
|
|
|
|
static void XmmCheck()
|
|
{
|
|
char *p1;
|
|
char *p2;
|
|
int i;
|
|
|
|
p1 = Allocate(SIZE, ALIGN);
|
|
p2 = Allocate(SIZE, ALIGN);
|
|
memset(p2, 0, SIZE);
|
|
|
|
for (i = 0; i < SIZE; i++)
|
|
p1[i] = "abcdefghijklmnopqrstuvwxyz"[i%26];
|
|
|
|
/* This routine causes a fault by accessing an illegal memory location */
|
|
CopyWithXmmFault(p2, p1, SIZE);
|
|
|
|
/* Verify that the memory was copied correctly */
|
|
CheckBuf(p2, SIZE);
|
|
}
|
|
|
|
|
|
static void CheckBuf(const char *p, size_t size)
|
|
{
|
|
int i;
|
|
char c;
|
|
|
|
for (i = 0; i < size; i++)
|
|
{
|
|
c = "abcdefghijklmnopqrstuvwxyz"[i%26];
|
|
if (p[i] != c)
|
|
{
|
|
fprintf(stderr, "Element %d wrong: is '%c' should be '%c'\n", i, p[i], c);
|
|
exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static char *Allocate(size_t size, size_t align)
|
|
{
|
|
char *p;
|
|
size_t low;
|
|
|
|
p = malloc(size + (align-1));
|
|
low = (size_t)p % align;
|
|
if (low)
|
|
return p + (align-low);
|
|
else
|
|
return p;
|
|
}
|
|
|
|
|
|
static void Handle(int sig, siginfo_t *i, void *vctxt)
|
|
{
|
|
ucontext_t *ctxt = vctxt;
|
|
|
|
/* Fix the illegal memory address access */
|
|
#if defined(TARGET_IA32)
|
|
#if defined(TARGET_MAC)
|
|
ctxt->uc_mcontext->__ss.__eax = (unsigned long)&Glob;
|
|
#else
|
|
ctxt->uc_mcontext.gregs[REG_EAX] = (unsigned long)&Glob;
|
|
#endif
|
|
#elif defined(TARGET_IA32E)
|
|
#if defined(TARGET_BSD)
|
|
ctxt->uc_mcontext.mc_rax = (unsigned long)&Glob;
|
|
#elif defined(TARGET_MAC)
|
|
ctxt->uc_mcontext->__ss.__rax = (unsigned long)&Glob;
|
|
#else
|
|
ctxt->uc_mcontext.gregs[REG_RAX] = (unsigned long)&Glob;
|
|
#endif
|
|
#endif
|
|
|
|
/* This changes the values of the XMM registers */
|
|
CopyWithXmm(SigBuf2, SigBuf1, SIZE);
|
|
}
|