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

📄 syscall.c

📁 一个很有名的硬件模拟器。可以模拟CPU
💻 C
📖 第 1 页 / 共 4 页
字号:
struct ss_rusage{  struct ss_timeval ss_ru_utime;  struct ss_timeval ss_ru_stime;  sword_t ss_ru_maxrss;  sword_t ss_ru_ixrss;  sword_t ss_ru_idrss;  sword_t ss_ru_isrss;  sword_t ss_ru_minflt;  sword_t ss_ru_majflt;  sword_t ss_ru_nswap;  sword_t ss_ru_inblock;  sword_t ss_ru_oublock;  sword_t ss_ru_msgsnd;  sword_t ss_ru_msgrcv;  sword_t ss_ru_nsignals;  sword_t ss_ru_nvcsw;  sword_t ss_ru_nivcsw;};struct ss_timezone{  sword_t ss_tz_minuteswest;	/* minutes west of Greenwich */  sword_t ss_tz_dsttime;	/* type of dst correction */};struct ss_rlimit{  int ss_rlim_cur;		/* current (soft) limit */  int ss_rlim_max;		/* maximum value for rlim_cur */};/* open(2) flags for SimpleScalar target, syscall.c automagically maps   between these codes to/from host open(2) flags */#define SS_O_RDONLY		0#define SS_O_WRONLY		1#define SS_O_RDWR		2#define SS_O_APPEND		0x0008#define SS_O_CREAT		0x0200#define SS_O_TRUNC		0x0400#define SS_O_EXCL		0x0800#define SS_O_NONBLOCK		0x4000#define SS_O_NOCTTY		0x8000#define SS_O_SYNC		0x2000/* open(2) flags translation table for SimpleScalar target */struct {  int ss_flag;  int local_flag;} ss_flag_table[] = {  /* target flag */	/* host flag */#ifdef _MSC_VER  { SS_O_RDONLY,	_O_RDONLY },  { SS_O_WRONLY,	_O_WRONLY },  { SS_O_RDWR,		_O_RDWR },  { SS_O_APPEND,	_O_APPEND },  { SS_O_CREAT,		_O_CREAT },  { SS_O_TRUNC,		_O_TRUNC },  { SS_O_EXCL,		_O_EXCL },#ifdef _O_NONBLOCK  { SS_O_NONBLOCK,	_O_NONBLOCK },#endif#ifdef _O_NOCTTY  { SS_O_NOCTTY,	_O_NOCTTY },#endif#ifdef _O_SYNC  { SS_O_SYNC,		_O_SYNC },#endif#else /* !_MSC_VER */  { SS_O_RDONLY,	O_RDONLY },  { SS_O_WRONLY,	O_WRONLY },  { SS_O_RDWR,		O_RDWR },  { SS_O_APPEND,	O_APPEND },  { SS_O_CREAT,		O_CREAT },  { SS_O_TRUNC,		O_TRUNC },  { SS_O_EXCL,		O_EXCL },  { SS_O_NONBLOCK,	O_NONBLOCK },  { SS_O_NOCTTY,	O_NOCTTY },#ifdef O_SYNC  { SS_O_SYNC,		O_SYNC },#endif#endif /* _MSC_VER */};#define SS_NFLAGS	(sizeof(ss_flag_table)/sizeof(ss_flag_table[0]))#endif /* !MD_CROSS_ENDIAN *//* 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 */voidsys_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];  /* first, check if an EIO trace is being consumed... */  if (traceable && sim_eio_fd != NULL)    {      eio_read_trace(sim_eio_fd, sim_num_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 PISA 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    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 = regs->regs_R[5], local_flags = 0;	/* 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 */	/*fd*/regs->regs_R[2] =	  open(buf, local_flags, /*mode*/regs->regs_R[6]);		/* 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;	  }      }      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;      else	{	  /* got an error, return details */	  regs->regs_R[2] = errno;	  regs->regs_R[7] = 1;	}      break;    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;	else	  {	    /* got an error, return details */	    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;	  }      }      break;    case SS_SYS_chdir:      {	char buf[MAXBUFSIZE];	/* copy filename to host memory */	mem_strcpy(mem_fn, mem, Read, /*fname*/regs->regs_R[4], buf);	/* change the working directory */	/*result*/regs->regs_R[2] = chdir(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;	  }      }      break;    case SS_SYS_chmod:      {	char buf[MAXBUFSIZE];	/* copy filename to host memory */	mem_strcpy(mem_fn, mem, Read, /*fname*/regs->regs_R[4], buf);	/* chmod the file */	/*result*/regs->regs_R[2] = chmod(buf, /*mode*/regs->regs_R[5]);	/* 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;	  }      }      break;    case SS_SYS_chown:#ifdef _MSC_VER      warn("syscall chown() not yet implemented for MSC...");      regs->regs_R[7] = 0;#else /* !_MSC_VER */      {	char buf[MAXBUFSIZE];	/* copy filename to host memory */	mem_strcpy(mem_fn, mem, Read, /*fname*/regs->regs_R[4], buf);	/* chown the file */	/*result*/regs->regs_R[2] = chown(buf, /*owner*/regs->regs_R[5],				    /*group*/regs->regs_R[6]);	/* 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;	  }      }#endif /* _MSC_VER */      break;    case SS_SYS_brk:      {	md_addr_t addr;	/* round the new heap pointer to the its page boundary */	addr = ROUND_UP(/*base*/regs->regs_R[4], MD_PAGE_SIZE);	/* check whether heap area has merged with stack area */	if (addr >= ld_brk_point && addr < (md_addr_t)regs->regs_R[29])	  {	    regs->regs_R[2] = 0;	    regs->regs_R[7] = 0;	    ld_brk_point = addr;	  }	else	  {	    /* out of address space, indicate error */	    regs->regs_R[2] = ENOMEM;	    regs->regs_R[7] = 1;	  }      }      break;    case SS_SYS_lseek:      /* seek into file */      regs->regs_R[2] =	lseek(/*fd*/regs->regs_R[4],	      /*off*/regs->regs_R[5], /*dir*/regs->regs_R[6]);      /* 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;	}      break;    case SS_SYS_getpid:      /* get the simulator process id */      /*result*/regs->regs_R[2] = getpid();      /* 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;	}      break;    case SS_SYS_getuid:#ifdef _MSC_VER      warn("syscall getuid() not yet implemented for MSC...");      regs->regs_R[7] = 0;#else /* !_MSC_VER */      /* get current user id */      /*first result*/regs->regs_R[2] = getuid();      /* get effective user id */      /*second result*/regs->regs_R[3] = geteuid();      /* 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;	}#endif /* _MSC_VER */      break;    case SS_SYS_access:      {	char buf[MAXBUFSIZE];	/* copy filename to host memory */	mem_strcpy(mem_fn, mem, Read, /*fName*/regs->regs_R[4], buf);	/* check access on the file */	/*result*/regs->regs_R[2] = access(buf, /*mode*/regs->regs_R[5]);	/* check for an error condition */	if (regs->regs_R[2] != -1)	  regs->regs_R[7] = 0;	else	  {

⌨️ 快捷键说明

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