⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syscall.c.svn-base

📁 模拟多核状态下龙芯处理器的功能
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
/*
 * syscall.c - proxy system call handler routines
 *
 * This file is a part of the SimpleScalar tool suite written by
 * Todd M. Austin as a part of the Multiscalar Research Project.
 *  
 * The tool suite is currently maintained by Doug Burger and Todd M. Austin.
 * 
 * Copyright (C) 1994, 1995, 1996, 1997, 1998 by Todd M. Austin
 *
 * This source file is distributed "as is" in the hope that it will be
 * useful.  The tool set comes with no warranty, and no author or
 * distributor accepts any responsibility for the consequences of its
 * use. 
 * 
 * Everyone is granted permission to copy, modify and redistribute
 * this tool set under the following conditions:
 * 
 *    This source code is distributed for non-commercial use only. 
 *    Please contact the maintainer for restrictions applying to 
 *    commercial use.
 *
 *    Permission is granted to anyone to make or distribute copies
 *    of this source code, either as received or modified, in any
 *    medium, provided that all copyright notices, permission and
 *    nonwarranty notices are preserved, and that the distributor
 *    grants the recipient permission for further redistribution as
 *    permitted by this document.
 *
 *    Permission is granted to distribute this file in compiled
 *    or executable form under the same conditions that apply for
 *    source code, provided that either:
 *
 *    A. it is accompanied by the corresponding machine-readable
 *       source code,
 *    B. it is accompanied by a written offer, with no time limit,
 *       to give anyone a machine-readable copy of the corresponding
 *       source code in return for reimbursement of the cost of
 *       distribution.  This written offer must permit verbatim
 *       duplication by anyone, or
 *    C. it is distributed by someone who received only the
 *       executable form, and is accompanied by a copy of the
 *       written offer of source code that they received concurrently.
 *
 * In other words, you are welcome to use, share and improve this
 * source file.  You are forbidden to forbid anyone else to use, share
 * and improve what you give them.
 *
 * INTERNET: dburger@cs.wisc.edu
 * US Mail:  1210 W. Dayton Street, Madison, WI 53706
 *
 * $Id: syscall.c,v 1.1.1.1 2006/09/08 09:21:43 cvsuser Exp $
 *
 * $Log: syscall.c,v $
 * Revision 1.1.1.1  2006/09/08 09:21:43  cvsuser
 * Godson-3 simulator
 *
 * Revision 1.1  2005/01/27 03:18:24  fxzhang
 * create godson2 cvs
 *
 * Revision 1.1.1.1  2004/12/05 14:36:32  fxzhang
 * initial import of ss-mips
 *
 * Revision 1.6  2004/11/19 12:49:50  fxzhang
 * sim outorder
 *
 * Revision 1.5  2004/11/18 04:30:32  fxzhang
 * dump simpoint enhancements
 *
 * Revision 1.4  2004/11/17 05:04:58  fxzhang
 * dump checkpoint support start running
 *
 * Revision 1.3  2004/08/04 08:54:57  fxzhang
 * add aux vector
 * fix mmap support
 *
 * Revision 1.2  2004/08/03 09:50:06  fxzhang
 * merge back changes on AMD64
 *
 * Revision 1.3  2004/07/30 02:48:22  fxzhang
 * fix stat64/lstat64
 *
 * Revision 1.2  2004/07/15 07:31:03  fxzhang
 * fix syscall on x86-64
 *
 * Revision 1.1.1.1  2004/07/15 01:26:34  fxzhang
 * import
 *
 * Revision 1.1.1.1  2004/07/10 16:46:49  fxzhang
 * initial
 *
 * Revision 1.1.1.1  2000/05/26 15:21:54  taustin
 * SimpleScalar Tool Set
 *
 *
 * Revision 1.10  1999/12/13 19:01:07  taustin
 * cross endian execution support added
 *
 * Revision 1.9  1999/03/08 06:41:12  taustin
 * added SVR4 host support
 *
 * Revision 1.8  1998/09/03 22:20:15  taustin
 * added <utime.h> for Linux
 *
 * Revision 1.7  1998/08/31 17:13:29  taustin
 * fixed typo in setrlimit()
 *
 * Revision 1.6  1998/08/27 17:07:37  taustin
 * implemented host interface description in host.h
 * added target interface support
 * moved target-dependent definitions to target files
 * added support for register and memory contexts
 * added support for MS VC++ and CYGWIN32 hosts
 *
 * Revision 1.5  1997/04/16  22:12:17  taustin
 * added Ultrix host support
 *
 * Revision 1.4  1997/03/11  01:37:37  taustin
 * updated copyright
 * long/int tweaks made for ALPHA target support
 * syscall structures are now more MIPS across platforms
 * various target supports added
 *
 * Revision 1.3  1996/12/27  15:56:09  taustin
 * updated comments
 * removed system prototypes
 *
 * Revision 1.1  1996/12/05  18:52:32  taustin
 * Initial revision
 *
 */

 /* This file runs only on linux/x86 now, I am fed up with the kludges
  * for all kinds of platform --fxzhang.
  */

#include <stdio.h>
#include <stdlib.h>

#include "host.h"
#include "misc.h"
#include "machine.h"
#include "regs.h"
#include "memory.h"
#include "loader.h"
#include "sim.h"
#include "endian.h"
#include "eio.h"
#include "syscall.h"

//#define DUMP_SIMPOINT   /* enable simpoint dumping */

/* live execution only support on same-endian hosts... */
#ifdef MD_CROSS_ENDIAN
#error "live execution only support on same-endian hosts!\n"
#endif

#include <unistd.h>
#include <ustat.h>
#include <sys/types.h>
#include <sys/param.h>
#include <errno.h>
#include <time.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <signal.h>
#include <linux/utsname.h>		/* struct new_utsname and old_utsname are defined here */
#include <linux/kernel.h>
#include <sys/timex.h>		/* struct timex is defined here */
#include <termios.h>

#include <sys/types.h>
#include <sys/stat.h> 
#include <fcntl.h>
#include <sys/statfs.h>
#include <sys/uio.h>
#include <setjmp.h>
#include <sys/times.h>
#include <limits.h>
#include <sys/ioctl.h>
#include <utime.h>
#include <sgtty.h>
#include <sys/dir.h>

/* mips relative data structures are defined in this file */
#include "target-mips/mips_data_structure.h"	
/* linux/mips syscall number and various syscall kernel data structure here */
#include "target-mips/syscalls.h"	



/* syscall proxy handler, architect registers and memory are assumed to be
   precise when this function is called, register and memory are updated with
   the results of the sustem call */
void
sys_syscall(struct regs_t *regs,	/* registers to access */
	    mem_access_fn mem_fn,	/* generic memory accessor */
	    struct mem_t *mem,		/* memory space to access */
	    md_inst_t inst,		/* system call inst */
	    int traceable)		/* traceable system call? */
{
  word_t syscode = regs->regs_R[2];

  //warn("syscall %d,a0=%x,a1=%x,a2=%x\n",syscode,regs->regs_R[4],regs->regs_R[5],regs->regs_R[6]);

  /* first, check if an EIO trace is being consumed... */
  if (traceable && sim_eio_fd != NULL)
    {
      eio_read_trace(sim_eio_fd, sim_pop_insn, regs, mem_fn, mem, inst);

      /* fini... */
      return;
    }
#ifdef MD_CROSS_ENDIAN
  else if (syscode == SS_SYS_exit)
    {
      /* exit jumps to the target set in main() */
      longjmp(sim_exit_buf, /* exitcode + fudge */regs->regs_R[4]+1);
    }
  else
    fatal("cannot execute MIPS system call on cross-endian host");

#else /* !MD_CROSS_ENDIAN */

  /* no, OK execute the live system call... */
  switch (syscode)
    {
    case SS_SYS_exit:
      /* exit jumps to the target set in main() */
      longjmp(sim_exit_buf, /* exitcode + fudge */regs->regs_R[4]+1);
      break;

#if 0
	/* simplescalar does not support multithread */
    case SS_SYS_fork:
      /* FIXME: this is broken... */
      regs->regs_R[2] = fork();
      if (regs->regs_R[2] != -1)
	{
	  regs->regs_R[7] = 0;
	  /* parent process */
	  if (regs->regs_R[2] != 0)
	  regs->regs_R[3] = 0;
	}
      else
	fatal("SYS_fork failed");
      break;
#endif

#if 0
    case SS_SYS_vfork:
      /* FIXME: this is broken... */
      int r31_parent = regs->regs_R[31];
      /* pid */regs->regs_R[2] = vfork();
      if (regs->regs_R[2] != -1)
	regs->regs_R[7] = 0;
      else
	fatal("vfork() in SYS_vfork failed");
      if (regs->regs_R[2] != 0)
	{
	  regs->regs_R[3] = 0;
	  regs->regs_R[7] = 0;
	  regs->regs_R[31] = r31_parent;
	}
      break;
#endif

    case SS_SYS_read:
      {
	char *buf;

	/* allocate same-sized input buffer in host memory */
	if (!(buf = (char *)calloc(/*nbytes*/regs->regs_R[6], sizeof(char))))
	  fatal("out of memory in SYS_read");

	/* read data from file */
	/*nread*/regs->regs_R[2] =
	  read(/*fd*/regs->regs_R[4], buf, /*nbytes*/regs->regs_R[6]);

	/* check for error condition */
	if (regs->regs_R[2] != -1)
	  regs->regs_R[7] = 0;
	else
	  {
	    /* got an error, return details */
	    regs->regs_R[2] = errno;
	    regs->regs_R[7] = 1;
	  }

	/* copy results back into host memory */
	mem_bcopy(mem_fn, mem,
		  Write, /*buf*/regs->regs_R[5],
		  buf, /*nread*/regs->regs_R[2]);

	/* done with input buffer */
	free(buf);
      }
      break;


    case SS_SYS_write:
      {
	char *buf;

	/* allocate same-sized output buffer in host memory */
	if (!(buf = (char *)calloc(/*nbytes*/regs->regs_R[6], sizeof(char))))
	  fatal("out of memory in SYS_write");

	/* copy inputs into host memory */
	mem_bcopy(mem_fn, mem,
		  Read, /*buf*/regs->regs_R[5],
		  buf, /*nbytes*/regs->regs_R[6]);

	/* write data to file */
	if (sim_progfd && MD_OUTPUT_SYSCALL(regs))
	  {
	    /* redirect program output to file */

	    /*nwritten*/regs->regs_R[2] =
	      fwrite(buf, 1, /*nbytes*/regs->regs_R[6], sim_progfd);
	  }
	else
	  {
	    /* perform program output request */

	    /*nwritten*/regs->regs_R[2] =
	      write(/*fd*/regs->regs_R[4],
		    buf, /*nbytes*/regs->regs_R[6]);
	  }

	/* check for an error condition */
	if (regs->regs_R[2] == regs->regs_R[6])
	  /*result*/regs->regs_R[7] = 0;
	else
	  {
	    /* got an error, return details */
	    regs->regs_R[2] = errno;
	    regs->regs_R[7] = 1;
	  }

	/* done with output buffer */
	free(buf);
      }
      break;


    case SS_SYS_open:
      {
	char buf[MAXBUFSIZE];
	unsigned int i;
	int ss_flags,ss_flags_save;
	int local_flags = 0;

	ss_flags_save = ss_flags = regs->regs_R[5];

	/* translate open(2) flags */
	for (i=0; i<SS_NFLAGS; i++)
	  {
	    if (ss_flags & ss_flag_table[i].ss_flag)
	      {
		ss_flags &= ~ss_flag_table[i].ss_flag;
		local_flags |= ss_flag_table[i].local_flag;
	      }
	  }
	/* any target flags left? */
	if (ss_flags != 0)
	  fatal("syscall: open: cannot decode flags: 0x%08x", ss_flags);

	/* copy filename to host memory */
	mem_strcpy(mem_fn, mem, Read, /*fname*/regs->regs_R[4], buf);

	/* open the file */
#ifdef __CYGWIN32__
	/*fd*/regs->regs_R[2] =
	  open(buf, local_flags|O_BINARY, /*mode*/regs->regs_R[6]);
#else /* !__CYGWIN32__ */
	/*fd*/regs->regs_R[2] =
	  open(buf, local_flags, /*mode*/regs->regs_R[6]);
#endif /* __CYGWIN32__ */
	
	/* check for an error condition */
	if (regs->regs_R[2] != -1) {
	  regs->regs_R[7] = 0;

#ifdef DUMP_SIMPOINT
	  {
	    extern void record_file_open(int fd,int flags,int mode,char *buf);
	    record_file_open(regs->regs_R[2],ss_flags_save,regs->regs_R[6],buf);
	  }
#endif
	} else
	  {
	    /* got an error, return details */
	    regs->regs_R[2] = errno;
	    regs->regs_R[7] = 1;
	  }
      }
      break;


    case SS_SYS_close:
      /* don't close stdin, stdout, or stderr as this messes up sim logs */
      if (/*fd*/regs->regs_R[4] == 0
	  || /*fd*/regs->regs_R[4] == 1
	  || /*fd*/regs->regs_R[4] == 2)
	{
	  regs->regs_R[7] = 0;
	  break;
	}

      /* close the file */
      regs->regs_R[2] = close(/*fd*/regs->regs_R[4]);

      /* check for an error condition */
      if (regs->regs_R[2] != -1) {
	regs->regs_R[7] = 0;
#ifdef DUMP_SIMPOINT
      /* ignore errors */
	{
	  extern void record_file_close(int fd);
	  record_file_close(regs->regs_R[4]);
	}
#endif
      }
      else
	{
	  /* got an error, return details */
	  regs->regs_R[2] = errno;
	  regs->regs_R[7] = 1;
	}
      break;


#if 0
	/* simplescalar does not support multithread */
    case SS_SYS_waitpid:
    break;
#endif


    case SS_SYS_creat:
      {
	char buf[MAXBUFSIZE];

	/* copy filename to host memory */
	mem_strcpy(mem_fn, mem, Read, /*fname*/regs->regs_R[4], buf);

	/* create the file */
	/*fd*/regs->regs_R[2] = creat(buf, /*mode*/regs->regs_R[5]);

	/* check for an error condition */
	if (regs->regs_R[2] != -1) {
	  regs->regs_R[7] = 0;

#ifdef DUMP_SIMPOINT
	  {
	    extern void record_file_open(int fd,int flags,int mode,char *buf);
	    record_file_open(regs->regs_R[2],SS_O_CREAT|SS_O_WRONLY|SS_O_TRUNC,regs->regs_R[5],buf);
	  }
#endif
	}else
	  {
	    /* got an error, return details */
	    regs->regs_R[2] = errno;
	    regs->regs_R[7] = 1;
	  }
      }
      break;


	case SS_SYS_link:
	{
	  char old_name[MAXBUFSIZE], new_name[MAXBUFSIZE];

	  /* copy old file name and new file name to host memory */
	  mem_strcpy(mem_fn, mem, Read, /*oldname*/regs->regs_R[4], old_name);
	  mem_strcpy(mem_fn, mem, Read, /*newname*/regs->regs_R[5], new_name);

	  /* link files */
	  regs->regs_R[2] = link(old_name, new_name);
	  if (regs->regs_R[2] != -1)
	  	regs->regs_R[7] = 0;
	  else
	  	{
	      regs->regs_R[2] = errno;
	      regs->regs_R[7] = 1;
	  	}
	}
	break;

	
    case SS_SYS_unlink:
      {
	char buf[MAXBUFSIZE];

	/* copy filename to host memory */
	mem_strcpy(mem_fn, mem, Read, /*fname*/regs->regs_R[4], buf);

	/* delete the file */
	/*result*/regs->regs_R[2] = unlink(buf);

	/* check for an error condition */
	if (regs->regs_R[2] != -1)
	  regs->regs_R[7] = 0;
	else
	  {
	    /* got an error, return details */
	    regs->regs_R[2] = errno;
	    regs->regs_R[7] = 1;
	  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -