syscall_emul.cc revision 1458
111308Santhony.gutierrez@amd.com/* 211308Santhony.gutierrez@amd.com * Copyright (c) 2003-2005 The Regents of The University of Michigan 311308Santhony.gutierrez@amd.com * All rights reserved. 411308Santhony.gutierrez@amd.com * 511308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without 611308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are 711308Santhony.gutierrez@amd.com * met: redistributions of source code must retain the above copyright 811308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer; 911308Santhony.gutierrez@amd.com * redistributions in binary form must reproduce the above copyright 1011308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer in the 1111308Santhony.gutierrez@amd.com * documentation and/or other materials provided with the distribution; 1211308Santhony.gutierrez@amd.com * neither the name of the copyright holders nor the names of its 1311308Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from 1411308Santhony.gutierrez@amd.com * this software without specific prior written permission. 1511308Santhony.gutierrez@amd.com * 1611308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1711308Santhony.gutierrez@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1811308Santhony.gutierrez@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1911308Santhony.gutierrez@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2011308Santhony.gutierrez@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2111308Santhony.gutierrez@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2211308Santhony.gutierrez@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2311308Santhony.gutierrez@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2411308Santhony.gutierrez@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2511308Santhony.gutierrez@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2611308Santhony.gutierrez@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2711308Santhony.gutierrez@amd.com */ 2811308Santhony.gutierrez@amd.com 2911308Santhony.gutierrez@amd.com#include <unistd.h> 3011308Santhony.gutierrez@amd.com 3111308Santhony.gutierrez@amd.com#include <string> 3211308Santhony.gutierrez@amd.com#include <iostream> 3311308Santhony.gutierrez@amd.com 3411308Santhony.gutierrez@amd.com#include "sim/syscall_emul.hh" 3511308Santhony.gutierrez@amd.com#include "base/trace.hh" 3611308Santhony.gutierrez@amd.com#include "cpu/exec_context.hh" 3711308Santhony.gutierrez@amd.com#include "cpu/base_cpu.hh" 3811308Santhony.gutierrez@amd.com#include "sim/process.hh" 3911308Santhony.gutierrez@amd.com 4011308Santhony.gutierrez@amd.com#include "sim/sim_events.hh" 4111308Santhony.gutierrez@amd.com 4211308Santhony.gutierrez@amd.comusing namespace std; 4311308Santhony.gutierrez@amd.com 4411308Santhony.gutierrez@amd.comvoid 4511534Sjohn.kalamatianos@amd.comSyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc) 4611308Santhony.gutierrez@amd.com{ 4711308Santhony.gutierrez@amd.com DPRINTFR(SyscallVerbose, "%s: syscall %s called\n", 4811308Santhony.gutierrez@amd.com xc->cpu->name(), name); 4911308Santhony.gutierrez@amd.com 5011308Santhony.gutierrez@amd.com SyscallReturn retval = (*funcPtr)(this, callnum, process, xc); 5111308Santhony.gutierrez@amd.com 5211308Santhony.gutierrez@amd.com DPRINTFR(SyscallVerbose, "%s: syscall %s returns %d\n", 5311308Santhony.gutierrez@amd.com xc->cpu->name(), name, retval.value()); 5411308Santhony.gutierrez@amd.com 5511308Santhony.gutierrez@amd.com if (!(flags & SyscallDesc::SuppressReturnValue)) 5611308Santhony.gutierrez@amd.com xc->setSyscallReturn(retval); 5711308Santhony.gutierrez@amd.com} 5811308Santhony.gutierrez@amd.com 5911308Santhony.gutierrez@amd.com 6011308Santhony.gutierrez@amd.comSyscallReturn 6111308Santhony.gutierrez@amd.comunimplementedFunc(SyscallDesc *desc, int callnum, Process *process, 6211308Santhony.gutierrez@amd.com ExecContext *xc) 6311308Santhony.gutierrez@amd.com{ 6411308Santhony.gutierrez@amd.com cerr << "Error: syscall " << desc->name 6511308Santhony.gutierrez@amd.com << " (#" << callnum << ") unimplemented."; 6611308Santhony.gutierrez@amd.com cerr << " Args: " << xc->getSyscallArg(0) << ", " << xc->getSyscallArg(1) 6711308Santhony.gutierrez@amd.com << ", ..." << endl; 6811308Santhony.gutierrez@amd.com 6911308Santhony.gutierrez@amd.com abort(); 7011308Santhony.gutierrez@amd.com} 7111308Santhony.gutierrez@amd.com 7211308Santhony.gutierrez@amd.com 7311308Santhony.gutierrez@amd.comSyscallReturn 7411308Santhony.gutierrez@amd.comignoreFunc(SyscallDesc *desc, int callnum, Process *process, 7511308Santhony.gutierrez@amd.com ExecContext *xc) 7611308Santhony.gutierrez@amd.com{ 7711308Santhony.gutierrez@amd.com DCOUT(SyscallWarnings) << "Warning: ignoring syscall " << desc->name 7811308Santhony.gutierrez@amd.com << "(" << xc->getSyscallArg(0) 7911308Santhony.gutierrez@amd.com << ", " << xc->getSyscallArg(1) 8011308Santhony.gutierrez@amd.com << ", ...)" << endl; 8111308Santhony.gutierrez@amd.com 8211308Santhony.gutierrez@amd.com return 0; 8311308Santhony.gutierrez@amd.com} 8411308Santhony.gutierrez@amd.com 8511308Santhony.gutierrez@amd.com 8611308Santhony.gutierrez@amd.comSyscallReturn 8711308Santhony.gutierrez@amd.comexitFunc(SyscallDesc *desc, int callnum, Process *process, 8811308Santhony.gutierrez@amd.com ExecContext *xc) 8911308Santhony.gutierrez@amd.com{ 9011308Santhony.gutierrez@amd.com new SimExitEvent("syscall caused exit", xc->getSyscallArg(0) & 0xff); 9111308Santhony.gutierrez@amd.com 9211308Santhony.gutierrez@amd.com return 1; 9311308Santhony.gutierrez@amd.com} 9411308Santhony.gutierrez@amd.com 9511308Santhony.gutierrez@amd.com 9611308Santhony.gutierrez@amd.comSyscallReturn 9711308Santhony.gutierrez@amd.comgetpagesizeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 9811308Santhony.gutierrez@amd.com{ 9911308Santhony.gutierrez@amd.com return VMPageSize; 10011308Santhony.gutierrez@amd.com} 10111308Santhony.gutierrez@amd.com 10211308Santhony.gutierrez@amd.com 10311308Santhony.gutierrez@amd.comSyscallReturn 10411308Santhony.gutierrez@amd.comobreakFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 10511308Santhony.gutierrez@amd.com{ 10611308Santhony.gutierrez@amd.com // change brk addr to first arg 10711308Santhony.gutierrez@amd.com Addr new_brk = xc->getSyscallArg(0); 10811308Santhony.gutierrez@amd.com if (new_brk != 0) 10911308Santhony.gutierrez@amd.com { 11011308Santhony.gutierrez@amd.com p->brk_point = xc->getSyscallArg(0); 11111308Santhony.gutierrez@amd.com } 11211308Santhony.gutierrez@amd.com DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point); 11311308Santhony.gutierrez@amd.com return p->brk_point; 11411308Santhony.gutierrez@amd.com} 11511308Santhony.gutierrez@amd.com 11611308Santhony.gutierrez@amd.com 11711308Santhony.gutierrez@amd.comSyscallReturn 11811308Santhony.gutierrez@amd.comcloseFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 11911308Santhony.gutierrez@amd.com{ 12011308Santhony.gutierrez@amd.com int fd = p->sim_fd(xc->getSyscallArg(0)); 12111308Santhony.gutierrez@amd.com return close(fd); 12211308Santhony.gutierrez@amd.com} 12311308Santhony.gutierrez@amd.com 12411308Santhony.gutierrez@amd.com 12511308Santhony.gutierrez@amd.comSyscallReturn 12611308Santhony.gutierrez@amd.comreadFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 12711308Santhony.gutierrez@amd.com{ 12811308Santhony.gutierrez@amd.com int fd = p->sim_fd(xc->getSyscallArg(0)); 12911308Santhony.gutierrez@amd.com int nbytes = xc->getSyscallArg(2); 13011308Santhony.gutierrez@amd.com BufferArg bufArg(xc->getSyscallArg(1), nbytes); 13111308Santhony.gutierrez@amd.com 13211308Santhony.gutierrez@amd.com int bytes_read = read(fd, bufArg.bufferPtr(), nbytes); 13311308Santhony.gutierrez@amd.com 13411308Santhony.gutierrez@amd.com if (bytes_read != -1) 13511308Santhony.gutierrez@amd.com bufArg.copyOut(xc->mem); 13611308Santhony.gutierrez@amd.com 13711308Santhony.gutierrez@amd.com return bytes_read; 13811308Santhony.gutierrez@amd.com} 13911308Santhony.gutierrez@amd.com 14011308Santhony.gutierrez@amd.comSyscallReturn 14111308Santhony.gutierrez@amd.comwriteFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 14211308Santhony.gutierrez@amd.com{ 14311308Santhony.gutierrez@amd.com int fd = p->sim_fd(xc->getSyscallArg(0)); 14411308Santhony.gutierrez@amd.com int nbytes = xc->getSyscallArg(2); 14511308Santhony.gutierrez@amd.com BufferArg bufArg(xc->getSyscallArg(1), nbytes); 14611308Santhony.gutierrez@amd.com 14711308Santhony.gutierrez@amd.com bufArg.copyIn(xc->mem); 14811308Santhony.gutierrez@amd.com 14911308Santhony.gutierrez@amd.com int bytes_written = write(fd, bufArg.bufferPtr(), nbytes); 15011308Santhony.gutierrez@amd.com 15111308Santhony.gutierrez@amd.com fsync(fd); 15211308Santhony.gutierrez@amd.com 15311308Santhony.gutierrez@amd.com return bytes_written; 15411308Santhony.gutierrez@amd.com} 15511308Santhony.gutierrez@amd.com 15611308Santhony.gutierrez@amd.com 15711308Santhony.gutierrez@amd.comSyscallReturn 15811308Santhony.gutierrez@amd.comlseekFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 15911308Santhony.gutierrez@amd.com{ 16011308Santhony.gutierrez@amd.com int fd = p->sim_fd(xc->getSyscallArg(0)); 16111308Santhony.gutierrez@amd.com uint64_t offs = xc->getSyscallArg(1); 16211308Santhony.gutierrez@amd.com int whence = xc->getSyscallArg(2); 16311308Santhony.gutierrez@amd.com 16411308Santhony.gutierrez@amd.com off_t result = lseek(fd, offs, whence); 16511308Santhony.gutierrez@amd.com 16611308Santhony.gutierrez@amd.com return (result == (off_t)-1) ? -errno : result; 16711308Santhony.gutierrez@amd.com} 16811308Santhony.gutierrez@amd.com 16911308Santhony.gutierrez@amd.com 17011308Santhony.gutierrez@amd.comSyscallReturn 17111308Santhony.gutierrez@amd.communmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 17211308Santhony.gutierrez@amd.com{ 17311308Santhony.gutierrez@amd.com // given that we don't really implement mmap, munmap is really easy 17411308Santhony.gutierrez@amd.com return 0; 17511308Santhony.gutierrez@amd.com} 17611308Santhony.gutierrez@amd.com 17711308Santhony.gutierrez@amd.com 17811308Santhony.gutierrez@amd.comconst char *hostname = "m5.eecs.umich.edu"; 17911308Santhony.gutierrez@amd.com 18011308Santhony.gutierrez@amd.comSyscallReturn 18111308Santhony.gutierrez@amd.comgethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 18211308Santhony.gutierrez@amd.com{ 18311308Santhony.gutierrez@amd.com int name_len = xc->getSyscallArg(1); 18411308Santhony.gutierrez@amd.com BufferArg name(xc->getSyscallArg(0), name_len); 18511308Santhony.gutierrez@amd.com 18611308Santhony.gutierrez@amd.com strncpy((char *)name.bufferPtr(), hostname, name_len); 18711308Santhony.gutierrez@amd.com 18811308Santhony.gutierrez@amd.com name.copyOut(xc->mem); 18911308Santhony.gutierrez@amd.com 19011308Santhony.gutierrez@amd.com return 0; 19111308Santhony.gutierrez@amd.com} 19211308Santhony.gutierrez@amd.com 19311308Santhony.gutierrez@amd.comSyscallReturn 19411308Santhony.gutierrez@amd.comunlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 19511308Santhony.gutierrez@amd.com{ 19611308Santhony.gutierrez@amd.com std::string path; 19711308Santhony.gutierrez@amd.com 19811308Santhony.gutierrez@amd.com if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 19911308Santhony.gutierrez@amd.com return (TheISA::IntReg)-EFAULT; 20011308Santhony.gutierrez@amd.com 20111308Santhony.gutierrez@amd.com int result = unlink(path.c_str()); 20211308Santhony.gutierrez@amd.com return (result == -1) ? -errno : result; 20311308Santhony.gutierrez@amd.com} 20411308Santhony.gutierrez@amd.com 20511308Santhony.gutierrez@amd.comSyscallReturn 20611308Santhony.gutierrez@amd.comrenameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 20711308Santhony.gutierrez@amd.com{ 20811308Santhony.gutierrez@amd.com std::string old_name; 20911308Santhony.gutierrez@amd.com 21011308Santhony.gutierrez@amd.com if (xc->mem->readString(old_name, xc->getSyscallArg(0)) != No_Fault) 21111308Santhony.gutierrez@amd.com return -EFAULT; 21211308Santhony.gutierrez@amd.com 21311308Santhony.gutierrez@amd.com std::string new_name; 21411308Santhony.gutierrez@amd.com 21511308Santhony.gutierrez@amd.com if (xc->mem->readString(new_name, xc->getSyscallArg(1)) != No_Fault) 21611308Santhony.gutierrez@amd.com return -EFAULT; 21711308Santhony.gutierrez@amd.com 21811308Santhony.gutierrez@amd.com int64_t result = rename(old_name.c_str(),new_name.c_str()); 21911308Santhony.gutierrez@amd.com return (result == -1) ? -errno : result; 22011308Santhony.gutierrez@amd.com} 22111308Santhony.gutierrez@amd.com 22211308Santhony.gutierrez@amd.com