/* Test that all instructions that make syscalls are handled correctly.
Note that it isn't possible to run this program natively. */
#include <stdio.h>
#include <sys/syscall.h>
#include <sys/trap.h>
#define SYSCALL(instr, scnum, out) \
do { \
__asm__ __volatile__( \
"movl %1,%%eax\n" \
"leal 0f,%%edx\n" /* Set return address for SYSENTER. */ \
instr "\n" \
"0:\n" \
"movl %%eax,%0\n" \
: "=m" (out) \
: "i" (scnum) \
: "eax", "edx", "cc", "memory"); \
} while (0)
static void check_pid(int pid, int pid2, const char *instr)
{
if (pid == pid2)
return;
fprintf(stderr, "Pid values differ, instruction: %s\n", instr);
}
int main(void)
{
int pid, pid2, dummy;
/* Normal Solaris/x86 syscall instructions. */
SYSCALL("int $0x91", SYS_getpid, pid);
/* AMD's syscall instruction. */
SYSCALL("syscall", SYS_getpid, pid2);
check_pid(pid, pid2, "syscall");
/* Intel's sysenter instruction. */
SYSCALL("sysenter", SYS_getpid, pid2);
check_pid(pid, pid2, "sysenter");
/* Linux syscall instructions that are handled as "int $0x91". */
SYSCALL("int $0x80", SYS_getpid, pid2);
check_pid(pid, pid2, "int $0x80");
SYSCALL("int $0x81", SYS_getpid, pid2);
check_pid(pid, pid2, "int $0x81");
SYSCALL("int $0x82", SYS_getpid, pid2);
check_pid(pid, pid2, "int $0x82");
/* Fasttraps. */
SYSCALL("int $0xd2", T_GETHRTIME, dummy);
return 0;
}