📄 syscall.c
字号:
/* * 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 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.5 1997/04/16 22:12:17 taustin Exp taustin $ * * $Log: syscall.c,v $ * 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 portable 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 * * */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.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 <sys/file.h>#include <sys/stat.h>#include <sys/uio.h>#include <setjmp.h>#include <sys/times.h>#include <limits.h>#include <sys/ioctl.h>#if !defined(linux) && !defined(sparc) && !defined(hpux) && !defined(__hpux) && !defined(__CYGWIN32__) && !defined(ultrix)#include <sys/select.h>#endif#ifdef linux#include <bsd/sgtty.h>#endif /* linux */#ifdef __CYGWIN32__#include <sgtty.h>#endif /* __CYGWIN32__ */#if defined(sparc) && defined(__unix__)#if defined(__svr4__) || defined(__USLC__)#include <dirent.h>#else#include <sys/dir.h>#endif/* dorks */#undef NL0#undef NL1#undef CR0#undef CR1#undef CR2#undef CR3#undef TAB0#undef TAB1#undef TAB2#undef XTABS#undef BS0#undef BS1#undef FF0#undef FF1#undef ECHO#undef NOFLSH#undef TOSTOP#undef FLUSHO#undef PENDIN#endif#if defined(hpux) || defined(__hpux)#undef CR0#endif#ifdef __FreeBSD__#include <sys/ioctl_compat.h>#else#include <termio.h>#endif#if defined(hpux) || defined(__hpux)/* et tu, dorks! */#undef HUPCL#undef ECHO#undef B50#undef B75#undef B110#undef B134#undef B150#undef B200#undef B300#undef B600#undef B1200#undef B1800#undef B2400#undef B4800#undef B9600#undef B19200#undef B38400#undef NL0#undef NL1#undef CR0#undef CR1#undef CR2#undef CR3#undef TAB0#undef TAB1#undef BS0#undef BS1#undef FF0#undef FF1#undef EXTA#undef EXTB#undef B900#undef B3600#undef B7200#undef XTABS#include <sgtty.h>#include <utime.h>#endif#include "misc.h"#include "ss.h"#include "regs.h"#include "memory.h"#include "loader.h"#include "sim.h"#include "endian.h"#include "syscall.h"/* open(2) flags translation table for SimpleScalar target */struct { int ss_flag; int local_flag;} ss_flag_table[] = { /* target flag */ /* host flag */ { 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};#define SS_NFLAGS (sizeof(ss_flag_table)/sizeof(ss_flag_table[0]))/* 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 */voidss_syscall(mem_access_fn mem_fn, /* generic memory accessor */ SS_INST_TYPE inst) /* system call inst */{ SS_WORD_TYPE syscode = regs_R[2]; switch (syscode) { case SS_SYS_exit: /* exit jumps to the target set in main() */ longjmp(sim_exit_buf, /* exitcode + fudge */regs_R[4]+1); break;#if 0 case SS_SYS_fork: /* FIXME: this is broken... */ regs_R[2] = fork(); if (regs_R[2] != -1) { regs_R[7] = 0; /* parent process */ if (regs_R[2] != 0) 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_R[31]; /* pid */regs_R[2] = vfork(); if (regs_R[2] != -1) regs_R[7] = 0; else fatal("vfork() in SYS_vfork failed"); if (regs_R[2] != 0) { regs_R[3] = 0; regs_R[7] = 0; 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_R[6], sizeof(char)))) fatal("out of memory in SYS_read"); /* read data from file */ /*nread*/regs_R[2] = read(/*fd*/regs_R[4], buf, /*nbytes*/regs_R[6]); /* check for error condition */ if (regs_R[2] != -1) regs_R[7] = 0; else { /* got an error, return details */ regs_R[2] = errno; regs_R[7] = 1; } /* copy results back into host memory */ mem_bcopy(mem_fn, Write, /*buf*/regs_R[5], buf, /*nread*/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_R[6], sizeof(char)))) fatal("out of memory in SYS_write"); /* copy inputs into host memory */ mem_bcopy(mem_fn, Read, /*buf*/regs_R[5], buf, /*nbytes*/regs_R[6]); /* write data to file */ /*nwritten*/regs_R[2] = write(/*fd*/regs_R[4], buf, /*nbytes*/regs_R[6]); /* check for an error condition */ if (regs_R[2] == regs_R[6]) /*result*/regs_R[7] = 0; else { /* got an error, return details */ regs_R[2] = errno; 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_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, Read, /*fname*/regs_R[4], buf); /* open the file */ /*fd*/regs_R[2] = open(buf, local_flags, /*mode*/regs_R[6]); /* check for an error condition */ if (regs_R[2] != -1) regs_R[7] = 0; else { /* got an error, return details */ regs_R[2] = errno; 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_R[4] == 0 || /*fd*/regs_R[4] == 1 || /*fd*/regs_R[4] == 2) { regs_R[7] = 0; break; } /* close the file */ regs_R[2] = close(/*fd*/regs_R[4]); /* check for an error condition */ if (regs_R[2] != -1) regs_R[7] = 0; else { /* got an error, return details */ regs_R[2] = errno; regs_R[7] = 1; } break; case SS_SYS_creat: { char buf[MAXBUFSIZE]; /* copy filename to host memory */ mem_strcpy(mem_fn, Read, /*fname*/regs_R[4], buf); /* create the file */ /*fd*/regs_R[2] = creat(buf, /*mode*/regs_R[5]); /* check for an error condition */ if (regs_R[2] != -1) regs_R[7] = 0; else { /* got an error, return details */ regs_R[2] = errno; regs_R[7] = 1; } } break; case SS_SYS_unlink: { char buf[MAXBUFSIZE]; /* copy filename to host memory */ mem_strcpy(mem_fn, Read, /*fname*/regs_R[4], buf); /* delete the file */ /*result*/regs_R[2] = unlink(buf); /* check for an error condition */ if (regs_R[2] != -1) regs_R[7] = 0; else { /* got an error, return details */ regs_R[2] = errno; regs_R[7] = 1; } } break; case SS_SYS_chdir: { char buf[MAXBUFSIZE]; /* copy filename to host memory */ mem_strcpy(mem_fn, Read, /*fname*/regs_R[4], buf); /* change the working directory */ /*result*/regs_R[2] = chdir(buf); /* check for an error condition */ if (regs_R[2] != -1) regs_R[7] = 0; else { /* got an error, return details */ regs_R[2] = errno; regs_R[7] = 1; } } break; case SS_SYS_chmod: { char buf[MAXBUFSIZE]; /* copy filename to host memory */ mem_strcpy(mem_fn, Read, /*fname*/regs_R[4], buf); /* chmod the file */ /*result*/regs_R[2] = chmod(buf, /*mode*/regs_R[5]); /* check for an error condition */ if (regs_R[2] != -1) regs_R[7] = 0; else { /* got an error, return details */ regs_R[2] = errno; regs_R[7] = 1; } } break; case SS_SYS_chown: { char buf[MAXBUFSIZE]; /* copy filename to host memory */ mem_strcpy(mem_fn, Read, /*fname*/regs_R[4], buf); /* chown the file */ /*result*/regs_R[2] = chown(buf, /*owner*/regs_R[5], /*group*/regs_R[6]); /* check for an error condition */ if (regs_R[2] != -1) regs_R[7] = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -