?? syscall.c.svn-base
字號:
/*
* 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 + -