
/*--------------------------------------------------------------------*/
/*--- x86/Linux-specific kernel interface.         vki-x86-linux.h ---*/
/*--------------------------------------------------------------------*/

/*
   This file is part of Valgrind, a dynamic binary instrumentation
   framework.

   Copyright (C) 2000-2005 Julian Seward 
      jseward@acm.org

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307, USA.

   The GNU General Public License is contained in the file COPYING.
*/

#ifndef __VKI_AMD64_LINUX_H
#define __VKI_AMD64_LINUX_H

// amd64 is little-endian.
#define VKI_LITTLE_ENDIAN  1


//----------------------------------------------------------------------
// From somewhere
//----------------------------------------------------------------------

/* PAGE_SHIFT determines the page size */
#define VKI_PAGE_SHIFT	12
#define VKI_PAGE_SIZE	(1UL << VKI_PAGE_SHIFT)
#define VKI_MAX_PAGE_SHIFT      VKI_PAGE_SHIFT
#define VKI_MAX_PAGE_SIZE       VKI_PAGE_SIZE

//----------------------------------------------------------------------
// From sys/signal.h
//----------------------------------------------------------------------

#define VKI_MINSIGSTKSZ	2048

#define VKI_SIG_BLOCK          1	/* for blocking signals */
#define VKI_SIG_UNBLOCK        2	/* for unblocking signals */
#define VKI_SIG_SETMASK        3	/* for setting the signal mask */

/* Type of a signal handler.  */
typedef void __vki_signalfn_t(int);
typedef __vki_signalfn_t *__vki_sighandler_t;

#define VKI_SIG_DFL	((__vki_sighandler_t)0)	/* default signal handling */
#define VKI_SIG_IGN	((__vki_sighandler_t)1)	/* ignore signal */

#define _VKI_NSIG	128
#define _VKI_NSIG_BPW	64
#define _VKI_NSIG_WORDS	(_VKI_NSIG / _VKI_NSIG_BPW)

/* Beware, not longword aligned in struct sigaction */
typedef struct {
	vki_uint64_t sig[_VKI_NSIG_WORDS];
} vki_sigset_t;

#define VKI_SIGHUP		 1
#define VKI_SIGINT		 2
#define VKI_SIGQUIT		 3
#define VKI_SIGILL		 4
#define VKI_SIGTRAP		 5
#define VKI_SIGABRT		 6
#define VKI_SIGEMT		 7
#define VKI_SIGFPE		 8
#define VKI_SIGKILL		 9
#define VKI_SIGBUS		10
#define VKI_SIGSEGV		11
#define VKI_SIGSYS		12
#define VKI_SIGPIPE		13
#define VKI_SIGALRM		14
#define VKI_SIGTERM		15
#define VKI_SIGURG		16
#define VKI_SIGSTOP		17
#define VKI_SIGTSTP		18
#define VKI_SIGCONT		19
#define VKI_SIGCHLD		20
#define VKI_SIGTTIN		21
#define VKI_SIGTTOU		22
#define VKI_SIGIO		23
#define VKI_SIGXCPU		24
#define VKI_SIGXFSZ		25
#define VKI_SIGVTALRM		26
#define VKI_SIGPROF		27
#define VKI_SIGWINCH		28
#define VKI_SIGINFO		29
#define VKI_SIGUSR1		30
#define VKI_SIGUSR2		31
#define	VKI_SIGTHR		32

#define VKI_SIGRTMIN	65
#define VKI_SIGRTMAX	126

#define VKI_SA_ONSTACK		0x0001
#define VKI_SA_RESTART		0x0002
#define VKI_SA_RESETHAND	0x0004
#define VKI_SA_NOCLDSTOP	0x0008
#define VKI_SA_NODEFER		0x0010
#define VKI_SA_NOCLDWAIT	0x0020
#define VKI_SA_SIGINFO		0x0040

#define VKI_SS_ONSTACK	0x0001
#define VKI_SS_DISABLE	0x0004

#define VKI_SA_ONESHOT          VKI_SA_RESETHAND
#define VKI_SA_NOMASK		VKI_SA_NODEFER

struct vki_sigaction {
	__vki_sighandler_t ksa_handler;
	unsigned int sa_flags;
	vki_sigset_t sa_mask __attribute__((__packed__));
	unsigned int __sa_pad;
};

typedef struct vki_sigaltstack {
	void *ss_sp;
	vki_size_t ss_size;
	int ss_flags;
} vki_stack_t;

//----------------------------------------------------------------------
// From linux-2.6.8.1/include/asm-i386/sigcontext.h
//----------------------------------------------------------------------

struct _vki_fpstate {
	unsigned short 	cwd;
	unsigned short	swd;
	unsigned short	twd;
	unsigned short	fop;
	unsigned long	rip;
	unsigned long	rdp;
	unsigned int	mxcsr;
	unsigned int	mxcsr_mask;
	unsigned int	st_space[32];	/* 8*16 bytes for each FP-reg */
	unsigned int	xmm_space[64];	/* 16*16 bytes for each XMM-reg */
	unsigned int	reserved2[24];
};

struct vki_sigcontext {
	vki_sigset_t mask;
	long    onstack;
	long    rdi;
	long    rsi;
	long    rdx;
	long    rcx;
	long    r8;
	long    r9;
	long    rax;
	long    rbx;
	long    rbp;
	long    r10;
	long    r11;
	long    r12;
	long    r13;
	long    r14;
	long    r15;
	long    trapno;
	long    addr;
	long    flags;
	long    err;
	long    rip;
	long    cs;
	long    rflags;
	long    rsp;
	long    ss;
	long    len;                 /* sizeof(mcontext_t) */
	long	fpformat;
	long	ownedfp;
	struct _vki_fpstate fpstate;
	long	spare2[8];
};

//----------------------------------------------------------------------
// From linux-2.6.8.1/include/asm-i386/user.h
//----------------------------------------------------------------------

struct vki_user_i387_struct {
	unsigned short	cwd;
	unsigned short	swd;
	unsigned short	twd;
	unsigned short	fop;
	unsigned long	fip;
	unsigned long	fdp;
	unsigned int	mxcsr;
	unsigned int	mxcsr_mask;
	unsigned int	st_space[32];	/* 8*16 bytes for each FP-reg = 128 bytes */
	unsigned int	xmm_space[64];	/* 16*16 bytes for each XMM-reg = 128 bytes */
	unsigned int	padding[24];
};


/* AAA check that this linux layout is appropriate */
struct vki_user_regs_struct {
	unsigned long r15,r14,r13,r12,rbp,rbx,r11,r10;
	unsigned long r9,r8,rax,rcx,rdx,rsi,rdi,orig_rax;
	unsigned long rip,cs,eflags;
	unsigned long rsp,ss;
	unsigned long fs_base, gs_base;
	unsigned long ds,es,fs,gs;
};

//----------------------------------------------------------------------
// From linux-2.6.8.1/include/asm-i386/elf.h
//----------------------------------------------------------------------

typedef unsigned long vki_elf_greg_t;

#define VKI_ELF_NGREG (sizeof (struct vki_user_regs_struct) / sizeof(vki_elf_greg_t))
typedef vki_elf_greg_t vki_elf_gregset_t[VKI_ELF_NGREG];

typedef struct vki_user_i387_struct vki_elf_fpregset_t;

#define VKI_AT_SYSINFO		32

//----------------------------------------------------------------------
// From linux-2.6.8.1/include/asm-i386/ucontext.h
//----------------------------------------------------------------------

/* AAA fix for 64 bit */
struct vki_mcontext {
	long    onstack;             /* XXX - sigcontext compat. */
	long    rdi;                 /* machine state (struct trapframe) */
	long    rsi;
	long    rdx;
	long    rcx;
	long    r8;
	long    r9;
	long    rax;
	long    rbx;
	long    rbp;
	long    r10;
	long    r11;
	long    r12;
	long    r13;
	long    r14;
	long    r15;
	long    trapno;
	long    addr;
	long    flags;
	long    err;
	long    rip;
	long    cs;
	long    rflags;
	long    rsp;
        long    ss;

	long	len;
	long	fpformat;
	long	ownedfp;
	struct _vki_fpstate fpstate;
	long	spare2[8];
};
#define VKI_FPFMT_NODEV		0x10000
#define VKI_FPFMT_XMM		0x10002

#define VKI_FPOWNED_NONE	0x20000
#define VKI_FPOWNED_FPU		0x20001
#define VKI_FPOWNED_PCB		0x20002

struct vki_ucontext {
	vki_sigset_t		uc_sigmask;
	struct vki_mcontext	uc_mcontext;
	struct vki_ucontext	*uc_link;
	vki_stack_t		uc_stack;
	int			uc_flags;
#define	VKI_UCF_SWAPPED	1
	unsigned int		__spare__[4];
};

//----------------------------------------------------------------------
// And that's it!
//----------------------------------------------------------------------

#endif // __VKI_AMD64_LINUX_H

/*--------------------------------------------------------------------*/
/*--- end                                                          ---*/
/*--------------------------------------------------------------------*/
