/*
   LinuxTables.c : Data tables for Linux.
   Copyright (C) 2000, 2001 Karim Yaghmour (karym@opersys.com).
 
   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

   History : 
     K.Y,  19/06/2001, Moved event database into libltt.
     K.Y., 31/05/2000, Initial typing.
*/

#include <linux/sys.h>  /* for NR_syscalls */

#include <LinuxEvents.h>
#include <LinuxTables.h>
#include <EventDB.h>

/* Size of event structures */
int LinuxEventStructSize[TRACE_MAX + 1] =
{
  sizeof(trace_start)             /* TRACE_START */,
  sizeof(trace_syscall_entry)     /* TRACE_SYSCALL_ENTRY */,
  0                               /* TRACE_SYSCALL_EXIT */,
  sizeof(trace_trap_entry)        /* TRACE_TRAP_ENTRY */,
  0                               /* TRACE_TRAP_EXIT */,
  sizeof(trace_irq_entry)         /* TRACE_IRQ_ENTRY */,
  0                               /* TRACE_IRQ_EXIT */,
  sizeof(trace_schedchange)       /* TRACE_SCHEDCHANGE */,
  0                               /* TRACE_KERNEL_TIMER */,
  sizeof(trace_soft_irq)          /* TRACE_SOFT_IRQ */,
  sizeof(trace_process)           /* TRACE_PROCESS */,
  sizeof(trace_file_system)       /* TRACE_FILE_SYSTEM */,
  sizeof(trace_timer)             /* TRACE_TIMER */,
  sizeof(trace_memory)            /* TRACE_MEMORY */,
  sizeof(trace_socket)            /* TRACE_SOCKET */,
  sizeof(trace_ipc)               /* TRACE_IPC */,
  sizeof(trace_network)           /* TRACE_NETWORK */,
  sizeof(trace_buffer_start)      /* TRACE_BUFFER_START */,
  0                               /* TRACE_BUFFER_END */,
  sizeof(trace_new_event)         /* TRACE_NEW_EVENT */,
  sizeof(trace_custom)            /* TRACE_CUSTOM */
};

/* Event description strings */
char *LinuxEventID[TRACE_MAX + 1] = 
{
"Trace start",
"Syscall entry",
"Syscall exit",
"Trap entry",
"Trap exit",
"IRQ entry",
"IRQ exit",
"Sched change",
"Kernel timer",
"Soft IRQ",
"Process",
"File system",
"Timer",
"Memory",
"Socket",
"IPC",
"Network",
"",
"",
"Event creation",
"Custom event"
};

char* LinuxEventString(db* pmDB, int pmEventID, event* pmEvent)
{
  trace_custom*       pCustom;      /* Pointer to custom event */
  custom_event_desc*  pCustomType;  /* Pointer to custom event type */

  /* Is this a custom event */
  if(pmEventID == TRACE_CUSTOM)
    {
    /* Get the custom event's structure */
    pCustom = CUSTOM_EVENT(DBEventStruct(pmDB, pmEvent));

    /* Loop around list of custom event description */
    for(pCustomType = pmDB->CustomEvents.Next;
	pCustomType != &(pmDB->CustomEvents);
	pCustomType = pCustomType->Next)
      if(pCustomType->Event->id == RFT32(pmDB, pCustom->id))
	return (pCustomType->Event->type);
    }

  /* Return the default string */
  return LinuxEventID[pmEventID];
}

/* Event strings the user can specify at the command line to omit or trace */
char *LinuxEventOT[TRACE_MAX + 1] =
{
"START",
"SYS_ENTRY",
"SYS_EXIT",
"TRAP_ENTRY",
"TRAP_EXIT",
"IRQ_ENTRY",
"IRQ_EXIT",
"SCHED",
"KTIMER",
"SIRQ",
"PROCESS",
"FS",
"TIMER",
"MEM",
"SOCKET",
"IPC",
"NET"
};

/* "Maximum" number of system calls on a linux box */
#define MAX_LIN_SYSCALLS   256
#define NB_SYSCALLS_I386   223
#define NB_SYSCALLS_PPC    203

/* System call name according to it's ID for i386 */
char *LinuxI386SyscallID[NB_SYSCALLS_I386 + 1] =
{
"ni_syscall 0",		/* 0  -  old "setup" system call */
"exit",
"fork",
"read",
"write",
"open",			/* 5 */
"close",
"waitpid",
"creat",
"link",
"unlink",		/* 10 */
"execve",
"chdir",
"time",
"mknod",
"chmod",		/* 15 */
"lchown",
"ni_syscall 17",	/* old break syscall holder */
"stat",
"lseek",
"getpid",		/* 20 */
"mount",
"oldumount",
"setuid",
"getuid",
"stime",		/* 25 */
"ptrace",
"alarm",
"fstat",
"pause",
"utime",		/* 30 */
"ni_syscall 31",	/* old stty syscall holder */
"ni_syscall 32",	/* old gtty syscall holder */
"access",
"nice",
"ni_syscall 35",	/* 35 *//* old ftime syscall holder */
"sync",
"kill",
"rename",
"mkdir",
"rmdir",		/* 40 */
"dup",
"pipe",
"times",
"ni_syscall 44",	/* old prof syscall holder */
"brk",			/* 45 */
"setgid",
"getgid",
"signal",
"geteuid",
"getegid",		/* 50 */
"acct",
"umount",		/* recycled never used phys() */
"ni_syscall 53",	/* old lock syscall holder */
"ioctl",
"fcntl",		/* 55 */
"ni_syscall 56",	/* old mpx syscall holder */
"setpgid",
"ni_syscall 58",	/* old ulimit syscall holder */
"olduname",
"umask",		/* 60 */
"chroot",
"ustat",
"dup2",
"getppid",
"getpgrp",		/* 65 */
"setsid",
"sigaction",
"sgetmask",
"ssetmask",
"setreuid",		/* 70 */
"setregid",
"sigsuspend",
"sigpending",
"sethostname",
"setrlimit",		/* 75 */
"getrlimit",
"getrusage",
"gettimeofday",
"settimeofday",
"getgroups",		/* 80 */
"setgroups",
"old_select",
"symlink",
"lstat",
"readlink",		/* 85 */
"uselib",
"swapon",
"reboot",
"old_readdir",
"old_mmap",		/* 90 */
"munmap",
"truncate",
"ftruncate",
"fchmod",
"fchown",		/* 95 */
"getpriority",
"setpriority",
"ni_syscall 98",	/* old profil syscall holder */
"statfs",
"fstatfs",		/* 100 */
"ioperm",
"socketcall",
"syslog",
"setitimer",
"getitimer",		/* 105 */
"newstat",
"newlstat",
"newfstat",
"uname",
"iopl",			/* 110 */
"vhangup",
"idle",
"vm86old",
"wait4",
"swapoff",		/* 115 */
"sysinfo",
"ipc",
"fsync",
"sigreturn",
"clone",		/* 120 */
"setdomainname",
"newuname",
"modify_ldt",
"adjtimex",
"mprotect",		/* 125 */
"sigprocmask",
"create_module",
"init_module",
"delete_module",
"get_kernel_syms",	/* 130 */
"quotactl",
"getpgid",
"fchdir",
"bdflush",
"sysfs",		/* 135 */
"personality",
"ni_syscall",		/* for afs_syscall */
"setfsuid",
"setfsgid",
"llseek",		/* 140 */
"getdents",
"select",
"flock",
"msync",
"readv",		/* 145 */
"writev",
"getsid",
"fdatasync",
"sysctl",
"mlock",		/* 150 */
"munlock",
"mlockall",
"munlockall",
"sched_setparam",
"sched_getparam",	 /* 155 */
"sched_setscheduler",
"sched_getscheduler",
"sched_yield",
"sched_get_priority_max",
"sched_get_priority_min",  /* 160 */
"sched_rr_get_interval",
"nanosleep",
"mremap",
"setresuid",
"getresuid",		/* 165 */
"vm86",
"query_module",
"poll",
"nfsservctl",
"setresgid",		/* 170 */
"getresgid",
"prctl",
"rt_sigreturn",
"rt_sigaction",
"rt_sigprocmask",	/* 175 */
"rt_sigpending",
"rt_sigtimedwait",
"rt_sigqueueinfo",
"rt_sigsuspend",
"pread",		/* 180 */
"pwrite",
"chown",
"getcwd",
"capget",
"capset",		/* 185 */
"sigaltstack",
"sendfile",
"ni_syscall 188",	/* streams1 */
"ni_syscall 189",	/* streams2 */
"vfork",		/* 190 */
"sys_getrlimit",
"sys_mmap2",
"sys_truncate64",
"sys_ftruncate64",
"sys_stat64",		/* 195 */
"sys_lstat64",
"sys_fstat64",
"sys_lchown",
"sys_getuid",
"sys_getgid",		/* 200 */
"sys_geteuid",
"sys_getegid",
"sys_setreuid",
"sys_setregid",
"sys_getgroups",	/* 205 */
"sys_setgroups",
"sys_fchown",
"sys_setresuid",
"sys_getresuid",
"sys_setresgid",	/* 210 */
"sys_getresgid",
"sys_chown",
"sys_setuid",
"sys_setgid",
"sys_setfsuid",		/* 215 */
"sys_setfsgid",
"sys_pivot_root",
"sys_mincore",
"sys_madvise",
"sys_getdents64",	/* 220 */
"sys_fcntl64",
"sys_ni_syscall",	/* reserved for TUX */
""
};

/* System call name according to it's ID for PPC */
char *LinuxPPCSyscallID[NB_SYSCALLS_PPC + 1] =
{
"ni_syscall 0",	       /* 0  -  old "setup()" system call */
"exit",
"fork",
"read",
"write",
"open",	               /* 5 */
"close",
"waitpid",
"creat",
"link",
"unlink",             /* 10 */
"execve",
"chdir",
"time",
"mknod",
"chmod",	      /* 15 */
"lchown",
"ni_syscall 17",      /* old break syscall holder */
"stat",
"lseek",
"getpid",	      /* 20 */
"mount",
"oldumount",
"setuid",
"getuid",
"stime",	      /* 25 */
"ptrace",
"alarm",
"fstat",
"pause",
"utime",	      /* 30 */
"ni_syscall 31",      /* old stty syscall holder */
"ni_syscall 32",      /* old gtty syscall holder */
"access",
"nice",
"ni_syscall 35",      /* 35 */	/* old ftime syscall holder */
"sync",
"kill",
"rename",
"mkdir",
"rmdir",	      /* 40 */
"dup",
"pipe",
"times",
"ni_syscall 44",      /* old prof syscall holder */
"brk",		      /* 45 */
"setgid",
"getgid",
"signal",
"geteuid",
"getegid",	      /* 50 */
"acct",
"umount",	      /* recycled never used phys() */
"ni_syscall 53",      /* old lock syscall holder */
"ioctl",
"fcntl",	      /* 55 */
"ni_syscall 56",      /* old mpx syscall holder */
"setpgid",
"ni_syscall 57",      /* old ulimit syscall holder */
"olduname",
"umask",	      /* 60 */
"chroot",
"ustat",
"dup2",
"getppid",
"getpgrp",	      /* 65 */
"setsid",
"sigaction",
"sgetmask",
"ssetmask",
"setreuid",	      /* 70 */
"setregid",
"sigsuspend",
"sigpending",
"sethostname",
"setrlimit",	      /* 75 */
"getrlimit",
"getrusage",
"gettimeofday",
"settimeofday",
"getgroups",	      /* 80 */
"setgroups",
"select",
"symlink",
"lstat",
"readlink",	      /* 85 */
"uselib",
"swapon",
"reboot",
"old_readdir",
"mmap",		      /* 90 */
"munmap",
"truncate",
"ftruncate",
"fchmod",
"fchown",	      /* 95 */
"getpriority",
"setpriority",
"ni_syscall 98",      /* old profil syscall holder */
"statfs",
"fstatfs",	      /* 100 */
"ioperm",
"socketcall",
"syslog",
"setitimer",
"getitimer",	      /* 105 */
"newstat",
"newlstat",
"newfstat",
"uname",
"iopl",		      /* 110 */
"vhangup",
"idle",
"vm86",
"wait4",
"swapoff",	      /* 115 */
"sysinfo",
"ipc",
"fsync",
"sigreturn",
"clone",	      /* 120 */
"setdomainname",
"newuname",
"modify_ldt",
"adjtimex",
"mprotect",	      /* 125 */
"sigprocmask",
"create_module",
"init_module",
"delete_module",
"get_kernel_syms",    /* 130 */
"quotactl",
"getpgid",
"fchdir",
"bdflush",
"sysfs",	      /* 135 */
"personality",
"ni_syscall 137",     /* for afs_syscall */
"setfsuid",
"setfsgid",
"llseek",	      /* 140 */
"getdents",
"select",
"flock",
"msync",
"readv",	      /* 145 */
"writev",
"getsid",
"fdatasync",
"sysctl",
"mlock",	      /* 150 */
"munlock",
"mlockall",
"munlockall",
"sched_setparam",
"sched_getparam",     /* 155 */
"sched_setscheduler",
"sched_getscheduler",
"sched_yield",
"sched_get_priority_max",
"sched_get_priority_min", /* 160 */
"sched_rr_get_interval",
"nanosleep",
"mremap",
"setresuid",
"getresuid",	      /* 165 */
"query_module",
"poll",
"nfsservctl",
"setresgid",
"getresgid",	      /* 170 */
"prctl",
"rt_sigreturn",
"rt_sigaction",
"rt_sigprocmask",	
"rt_sigpending",      /* 175 */
"rt_sigtimedwait",
"rt_sigqueueinfo",
"rt_sigsuspend",
"pread",
"pwrite",	      /* 180 */
"chown",
"getcwd",
"capget",
"capset",
"sigaltstack",	      /* 185 */
"sendfile",
"ni_syscall 187",     /* streams1 */
"ni_syscall 188",     /* streams2 */
"vfork",
"sys_getrlimit",	/* 190 */
"sys_ni_syscall",	/* 191 */	/* Unused */
"sys_ni_syscall",	/* 192 - reserved - mmap2 */
"sys_ni_syscall",	/* 193 - reserved - truncate64 */
"sys_ni_syscall",	/* 194 - reserved - ftruncate64 */
"sys_ni_syscall",	/* 195 - reserved - stat64 */
"sys_ni_syscall",	/* 196 - reserved - lstat64 */
"sys_ni_syscall",	/* 197 - reserved - fstat64 */
"sys_pciconfig_read",	/* 198 */
"sys_pciconfig_write", 	/* 199 */
"sys_pciconfig_iobase", /* 200 */
"sys_ni_syscall",	/* 201 - reserved - MacOnLinux - new */
"sys_getdents64",	/* 202 */
"",
};

/* Number of traps possible on i386 */
#define NB_TRAPS_I386   19

/* Trap according to it's ID on i386 */
char *LinuxI386TrapID[NB_TRAPS_I386] =
{
"divide error",
"debug",
"nmi",
"int3",
"overflow",
"bounds",
"invalidop",
"device notavailable",
"double fault",
"copro segment overrun",
"invalid TSS",
"segment not present",
"stack segment",
"GPF", /* most people know this one by name */
"page fault",
"spurious interrupt",
"copro error",
"alignment check",
"reserved"
};

/* Number of traps possible on PPC (see arch/ppc/kernel/head.S for details) */
#define NB_TRAPS_PPC   48 /* From 0x0100 to 0x2f00 */

/* Trap according to it's ID on PPC (see PowerPC manual for more details) */
char *LinuxPPCTrapID[NB_TRAPS_PPC] =
{
"0x0000", /* Nothing for the first one */ 
"Reset",
"Machine check",
"Data Access",
"Instruction Access",
"External Interrupt",
"Alignment",
"Program Check",
"FP Unavailable",
"Decrementer",
"0x0A00",
"0x0B00",
"System call",
"Trace",
"0x0E00",
"0x0F00",
"Instruction TLB Miss",
"Data TLB Miss on Load",
"Data TLB Miss on Store",
"Instruction Address Breakpoint",
"0x1400 (sys management)",
"0x1500",
"0x1600",
"TAU",
"0x1800",
"0x1900",
"0x1A00",
"0x1B00",
"0x1C00",
"0x1D00",
"0x1E00",
"0x1F00",
"Run mode",
"0x2100",
"0x2200",
"0x2300",
"0x2400",
"0x2500",
"0x2600",
"0x2700",
"0x2800",
"0x2900",
"0x2A00",
"0x2B00",
"0x2C00",
"0x2D00",
"0x2E00",
"0x2F00"
};

static char* NullString = "";

/* System call name according to it's ID */
char* LinuxSyscallString(db*  pmDB, int pmID)
{
  switch(pmDB->ArchType)
    {
    case TRACE_ARCH_TYPE_I386:
      if(pmID <= NB_SYSCALLS_I386)
	return LinuxI386SyscallID[pmID];
      else
	return NullString;
      break;

    case TRACE_ARCH_TYPE_PPC:
      if(pmID <= NB_SYSCALLS_PPC)
	return LinuxPPCSyscallID[pmID];
      else
	return NullString;
      break;
    };

  /* Just in case */
  return NullString;
}

/* Trap according to it's ID */
char *LinuxTrapString(db*  pmDB, int pmID)
{
  switch(pmDB->ArchType)
    {
    case TRACE_ARCH_TYPE_I386:
      if(pmID <= NB_TRAPS_I386)
	return LinuxI386TrapID[pmID];
      else
	return NullString;
      break;

    case TRACE_ARCH_TYPE_PPC:
      if(pmID <= NB_TRAPS_PPC)
	return LinuxPPCTrapID[pmID];
      else
	return NullString;
      break;
    };

  /* Just in case */
  return NullString;
}
 
