syscall_emul.cc revision 1458
1360SN/A/* 21458SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 3360SN/A * All rights reserved. 4360SN/A * 5360SN/A * Redistribution and use in source and binary forms, with or without 6360SN/A * modification, are permitted provided that the following conditions are 7360SN/A * met: redistributions of source code must retain the above copyright 8360SN/A * notice, this list of conditions and the following disclaimer; 9360SN/A * redistributions in binary form must reproduce the above copyright 10360SN/A * notice, this list of conditions and the following disclaimer in the 11360SN/A * documentation and/or other materials provided with the distribution; 12360SN/A * neither the name of the copyright holders nor the names of its 13360SN/A * contributors may be used to endorse or promote products derived from 14360SN/A * this software without specific prior written permission. 15360SN/A * 16360SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17360SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18360SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19360SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20360SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21360SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22360SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23360SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24360SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25360SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26360SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu */ 282665Ssaidi@eecs.umich.edu 292665Ssaidi@eecs.umich.edu#include <unistd.h> 30360SN/A 31360SN/A#include <string> 3211793Sbrandon.potter@amd.com#include <iostream> 3311793Sbrandon.potter@amd.com 342093SN/A#include "sim/syscall_emul.hh" 35360SN/A#include "base/trace.hh" 36360SN/A#include "cpu/exec_context.hh" 376712Snate@binkert.org#include "cpu/base_cpu.hh" 38360SN/A#include "sim/process.hh" 39360SN/A 407680Sgblack@eecs.umich.edu#include "sim/sim_events.hh" 412474SN/A 42360SN/Ausing namespace std; 436658Snate@binkert.org 442680Sktlim@umich.eduvoid 452474SN/ASyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc) 46360SN/A{ 478229Snate@binkert.org DPRINTFR(SyscallVerbose, "%s: syscall %s called\n", 4811794Sbrandon.potter@amd.com xc->cpu->name(), name); 4911794Sbrandon.potter@amd.com 506029Ssteve.reinhardt@amd.com SyscallReturn retval = (*funcPtr)(this, callnum, process, xc); 51360SN/A 52360SN/A DPRINTFR(SyscallVerbose, "%s: syscall %s returns %d\n", 532107SN/A xc->cpu->name(), name, retval.value()); 54360SN/A 551450SN/A if (!(flags & SyscallDesc::SuppressReturnValue)) 5611851Sbrandon.potter@amd.com xc->setSyscallReturn(retval); 572680Sktlim@umich.edu} 58360SN/A 5911794Sbrandon.potter@amd.com 602484SN/ASyscallReturn 612484SN/AunimplementedFunc(SyscallDesc *desc, int callnum, Process *process, 62360SN/A ExecContext *xc) 63360SN/A{ 64360SN/A cerr << "Error: syscall " << desc->name 651450SN/A << " (#" << callnum << ") unimplemented."; 6611851Sbrandon.potter@amd.com cerr << " Args: " << xc->getSyscallArg(0) << ", " << xc->getSyscallArg(1) 672680Sktlim@umich.edu << ", ..." << endl; 68360SN/A 6911794Sbrandon.potter@amd.com abort(); 7011794Sbrandon.potter@amd.com} 7111794Sbrandon.potter@amd.com 7210831Ssteve.reinhardt@amd.com 73360SN/ASyscallReturn 748149SChris.Emmons@ARM.comignoreFunc(SyscallDesc *desc, int callnum, Process *process, 758149SChris.Emmons@ARM.com ExecContext *xc) 768149SChris.Emmons@ARM.com{ 778149SChris.Emmons@ARM.com DCOUT(SyscallWarnings) << "Warning: ignoring syscall " << desc->name 788149SChris.Emmons@ARM.com << "(" << xc->getSyscallArg(0) 7911851Sbrandon.potter@amd.com << ", " << xc->getSyscallArg(1) 802680Sktlim@umich.edu << ", ...)" << endl; 81360SN/A 826029Ssteve.reinhardt@amd.com return 0; 836029Ssteve.reinhardt@amd.com} 846701Sgblack@eecs.umich.edu 855958Sgblack@eecs.umich.edu 866701Sgblack@eecs.umich.eduSyscallReturn 876029Ssteve.reinhardt@amd.comexitFunc(SyscallDesc *desc, int callnum, Process *process, 886029Ssteve.reinhardt@amd.com ExecContext *xc) 896029Ssteve.reinhardt@amd.com{ 902834Sksewell@umich.edu new SimExitEvent("syscall caused exit", xc->getSyscallArg(0) & 0xff); 91360SN/A 921458SN/A return 1; 93360SN/A} 94360SN/A 95360SN/A 961450SN/ASyscallReturn 9711851Sbrandon.potter@amd.comgetpagesizeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 986109Ssanchezd@stanford.edu{ 996109Ssanchezd@stanford.edu return VMPageSize; 10010483Swiseveri@student.ethz.ch} 10110483Swiseveri@student.ethz.ch 10210483Swiseveri@student.ethz.ch 10310483Swiseveri@student.ethz.chSyscallReturn 10410483Swiseveri@student.ethz.chobreakFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 10510483Swiseveri@student.ethz.ch{ 10610483Swiseveri@student.ethz.ch // change brk addr to first arg 10710483Swiseveri@student.ethz.ch Addr new_brk = xc->getSyscallArg(0); 10810483Swiseveri@student.ethz.ch if (new_brk != 0) 10910483Swiseveri@student.ethz.ch { 11010483Swiseveri@student.ethz.ch p->brk_point = xc->getSyscallArg(0); 1116109Ssanchezd@stanford.edu } 1126109Ssanchezd@stanford.edu DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point); 1136109Ssanchezd@stanford.edu return p->brk_point; 1146109Ssanchezd@stanford.edu} 1156109Ssanchezd@stanford.edu 1166109Ssanchezd@stanford.edu 11711851Sbrandon.potter@amd.comSyscallReturn 118360SN/AcloseFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 11910318Sandreas.hansson@arm.com{ 120360SN/A int fd = p->sim_fd(xc->getSyscallArg(0)); 121360SN/A return close(fd); 122360SN/A} 1231450SN/A 12411851Sbrandon.potter@amd.com 125360SN/ASyscallReturn 126360SN/AreadFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 1276701Sgblack@eecs.umich.edu{ 1286701Sgblack@eecs.umich.edu int fd = p->sim_fd(xc->getSyscallArg(0)); 1295748SSteve.Reinhardt@amd.com int nbytes = xc->getSyscallArg(2); 1305748SSteve.Reinhardt@amd.com BufferArg bufArg(xc->getSyscallArg(1), nbytes); 1315748SSteve.Reinhardt@amd.com 1325748SSteve.Reinhardt@amd.com int bytes_read = read(fd, bufArg.bufferPtr(), nbytes); 1335748SSteve.Reinhardt@amd.com 1345748SSteve.Reinhardt@amd.com if (bytes_read != -1) 1355748SSteve.Reinhardt@amd.com bufArg.copyOut(xc->mem); 1365748SSteve.Reinhardt@amd.com 1372474SN/A return bytes_read; 13810318Sandreas.hansson@arm.com} 1395748SSteve.Reinhardt@amd.com 14010318Sandreas.hansson@arm.comSyscallReturn 1416687Stjones1@inf.ed.ac.ukwriteFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 1426687Stjones1@inf.ed.ac.uk{ 1436687Stjones1@inf.ed.ac.uk int fd = p->sim_fd(xc->getSyscallArg(0)); 1446687Stjones1@inf.ed.ac.uk int nbytes = xc->getSyscallArg(2); 1458852Sandreas.hansson@arm.com BufferArg bufArg(xc->getSyscallArg(1), nbytes); 1466687Stjones1@inf.ed.ac.uk 1476687Stjones1@inf.ed.ac.uk bufArg.copyIn(xc->mem); 14810318Sandreas.hansson@arm.com 1496687Stjones1@inf.ed.ac.uk int bytes_written = write(fd, bufArg.bufferPtr(), nbytes); 1508852Sandreas.hansson@arm.com 15110318Sandreas.hansson@arm.com fsync(fd); 1526687Stjones1@inf.ed.ac.uk 1536687Stjones1@inf.ed.ac.uk return bytes_written; 1546687Stjones1@inf.ed.ac.uk} 15510318Sandreas.hansson@arm.com 1568852Sandreas.hansson@arm.com 1576687Stjones1@inf.ed.ac.ukSyscallReturn 1586687Stjones1@inf.ed.ac.uklseekFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 1592474SN/A{ 1601450SN/A int fd = p->sim_fd(xc->getSyscallArg(0)); 1615748SSteve.Reinhardt@amd.com uint64_t offs = xc->getSyscallArg(1); 1625748SSteve.Reinhardt@amd.com int whence = xc->getSyscallArg(2); 16311380Salexandru.dutu@amd.com 16411380Salexandru.dutu@amd.com off_t result = lseek(fd, offs, whence); 1651458SN/A 166360SN/A return (result == (off_t)-1) ? -errno : result; 167360SN/A} 168360SN/A 1691450SN/A 17011851Sbrandon.potter@amd.comSyscallReturn 171360SN/AmunmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 1726701Sgblack@eecs.umich.edu{ 17310931Sbrandon.potter@amd.com // given that we don't really implement mmap, munmap is really easy 17410931Sbrandon.potter@amd.com return 0; 17511856Sbrandon.potter@amd.com} 176360SN/A 177360SN/A 178360SN/Aconst char *hostname = "m5.eecs.umich.edu"; 1791450SN/A 18011851Sbrandon.potter@amd.comSyscallReturn 181360SN/AgethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 1826701Sgblack@eecs.umich.edu{ 18310931Sbrandon.potter@amd.com int name_len = xc->getSyscallArg(1); 1846701Sgblack@eecs.umich.edu BufferArg name(xc->getSyscallArg(0), name_len); 1856701Sgblack@eecs.umich.edu 18611856Sbrandon.potter@amd.com strncpy((char *)name.bufferPtr(), hostname, name_len); 18711856Sbrandon.potter@amd.com 18811856Sbrandon.potter@amd.com name.copyOut(xc->mem); 18911856Sbrandon.potter@amd.com 19011856Sbrandon.potter@amd.com return 0; 19111856Sbrandon.potter@amd.com} 1926701Sgblack@eecs.umich.edu 19310931Sbrandon.potter@amd.comSyscallReturn 194360SN/AunlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 19511684Snderumigny@gmail.com{ 1968706Sandreas.hansson@arm.com std::string path; 197360SN/A 1981458SN/A if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 199360SN/A return (TheISA::IntReg)-EFAULT; 200360SN/A 2011450SN/A int result = unlink(path.c_str()); 20211851Sbrandon.potter@amd.com return (result == -1) ? -errno : result; 203360SN/A} 2046701Sgblack@eecs.umich.edu 20510931Sbrandon.potter@amd.comSyscallReturn 2066701Sgblack@eecs.umich.edurenameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 2076701Sgblack@eecs.umich.edu{ 20811856Sbrandon.potter@amd.com std::string old_name; 20911856Sbrandon.potter@amd.com 21011856Sbrandon.potter@amd.com if (xc->mem->readString(old_name, xc->getSyscallArg(0)) != No_Fault) 21111856Sbrandon.potter@amd.com return -EFAULT; 21211856Sbrandon.potter@amd.com 21311856Sbrandon.potter@amd.com std::string new_name; 2146701Sgblack@eecs.umich.edu 2158706Sandreas.hansson@arm.com if (xc->mem->readString(new_name, xc->getSyscallArg(1)) != No_Fault) 216360SN/A return -EFAULT; 21710931Sbrandon.potter@amd.com 218360SN/A int64_t result = rename(old_name.c_str(),new_name.c_str()); 21910931Sbrandon.potter@amd.com return (result == -1) ? -errno : result; 220360SN/A} 2211458SN/A 222360SN/A