syscall_emul.cc revision 1458
112SN/A/* 21762SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 312SN/A * All rights reserved. 412SN/A * 512SN/A * Redistribution and use in source and binary forms, with or without 612SN/A * modification, are permitted provided that the following conditions are 712SN/A * met: redistributions of source code must retain the above copyright 812SN/A * notice, this list of conditions and the following disclaimer; 912SN/A * redistributions in binary form must reproduce the above copyright 1012SN/A * notice, this list of conditions and the following disclaimer in the 1112SN/A * documentation and/or other materials provided with the distribution; 1212SN/A * neither the name of the copyright holders nor the names of its 1312SN/A * contributors may be used to endorse or promote products derived from 1412SN/A * this software without specific prior written permission. 1512SN/A * 1612SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612SN/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> 3012SN/A 3112SN/A#include <string> 3212SN/A#include <iostream> 3312SN/A 34468SN/A#include "sim/syscall_emul.hh" 35468SN/A#include "base/trace.hh" 36468SN/A#include "cpu/exec_context.hh" 37661SN/A#include "cpu/base_cpu.hh" 38468SN/A#include "sim/process.hh" 392634Sstever@eecs.umich.edu 40468SN/A#include "sim/sim_events.hh" 4156SN/A 422439SN/Ausing namespace std; 4312SN/A 4456SN/Avoid 4512SN/ASyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc) 4656SN/A{ 4712SN/A DPRINTFR(SyscallVerbose, "%s: syscall %s called\n", 482423SN/A xc->cpu->name(), name); 492423SN/A 5012SN/A SyscallReturn retval = (*funcPtr)(this, callnum, process, xc); 5112SN/A 5212SN/A DPRINTFR(SyscallVerbose, "%s: syscall %s returns %d\n", 5312SN/A xc->cpu->name(), name, retval.value()); 5412SN/A 5512SN/A if (!(flags & SyscallDesc::SuppressReturnValue)) 56443SN/A xc->setSyscallReturn(retval); 57443SN/A} 582207SN/A 592207SN/A 60443SN/ASyscallReturn 61468SN/AunimplementedFunc(SyscallDesc *desc, int callnum, Process *process, 621708SN/A ExecContext *xc) 631708SN/A{ 64443SN/A cerr << "Error: syscall " << desc->name 65468SN/A << " (#" << callnum << ") unimplemented."; 66443SN/A cerr << " Args: " << xc->getSyscallArg(0) << ", " << xc->getSyscallArg(1) 67468SN/A << ", ..." << endl; 68443SN/A 69443SN/A abort(); 70468SN/A} 71468SN/A 72443SN/A 73443SN/ASyscallReturn 74443SN/AignoreFunc(SyscallDesc *desc, int callnum, Process *process, 752476SN/A ExecContext *xc) 762207SN/A{ 772207SN/A DCOUT(SyscallWarnings) << "Warning: ignoring syscall " << desc->name 782207SN/A << "(" << xc->getSyscallArg(0) 792207SN/A << ", " << xc->getSyscallArg(1) 802207SN/A << ", ...)" << endl; 812207SN/A 822620SN/A return 0; 832207SN/A} 842207SN/A 852207SN/A 862472SN/ASyscallReturn 872207SN/AexitFunc(SyscallDesc *desc, int callnum, Process *process, 882207SN/A ExecContext *xc) 892207SN/A{ 902600SN/A new SimExitEvent("syscall caused exit", xc->getSyscallArg(0) & 0xff); 912207SN/A 922207SN/A return 1; 932207SN/A} 942207SN/A 952207SN/A 962207SN/ASyscallReturn 972238SN/AgetpagesizeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 982207SN/A{ 992207SN/A return VMPageSize; 1002207SN/A} 1012207SN/A 1022207SN/A 1032238SN/ASyscallReturn 1042207SN/AobreakFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 1052207SN/A{ 1062238SN/A // change brk addr to first arg 1072207SN/A Addr new_brk = xc->getSyscallArg(0); 1082207SN/A if (new_brk != 0) 1092207SN/A { 1102207SN/A p->brk_point = xc->getSyscallArg(0); 1112238SN/A } 1122238SN/A DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point); 1132600SN/A return p->brk_point; 1142238SN/A} 1152238SN/A 1162238SN/A 1172238SN/ASyscallReturn 1182238SN/AcloseFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 1192238SN/A{ 1202238SN/A int fd = p->sim_fd(xc->getSyscallArg(0)); 1212238SN/A return close(fd); 1222238SN/A} 1232238SN/A 1242600SN/A 1252238SN/ASyscallReturn 1262238SN/AreadFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 1272238SN/A{ 1282238SN/A int fd = p->sim_fd(xc->getSyscallArg(0)); 1292238SN/A int nbytes = xc->getSyscallArg(2); 1302238SN/A BufferArg bufArg(xc->getSyscallArg(1), nbytes); 1312238SN/A 1322238SN/A int bytes_read = read(fd, bufArg.bufferPtr(), nbytes); 1332238SN/A 1342238SN/A if (bytes_read != -1) 1352238SN/A bufArg.copyOut(xc->mem); 1362238SN/A 1372238SN/A return bytes_read; 1382238SN/A} 1392238SN/A 1402238SN/ASyscallReturn 1412238SN/AwriteFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 1422238SN/A{ 1432238SN/A int fd = p->sim_fd(xc->getSyscallArg(0)); 1442238SN/A int nbytes = xc->getSyscallArg(2); 1452238SN/A BufferArg bufArg(xc->getSyscallArg(1), nbytes); 1462238SN/A 1472600SN/A bufArg.copyIn(xc->mem); 1482600SN/A 1492600SN/A int bytes_written = write(fd, bufArg.bufferPtr(), nbytes); 1502600SN/A 1512600SN/A fsync(fd); 1522238SN/A 1532238SN/A return bytes_written; 1542238SN/A} 1552472SN/A 1562238SN/A 1572207SN/ASyscallReturn 15812SN/AlseekFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 15912SN/A{ 16012SN/A int fd = p->sim_fd(xc->getSyscallArg(0)); 16112SN/A uint64_t offs = xc->getSyscallArg(1); 16212SN/A int whence = xc->getSyscallArg(2); 163360SN/A 164360SN/A off_t result = lseek(fd, offs, whence); 165360SN/A 166443SN/A return (result == (off_t)-1) ? -errno : result; 16712SN/A} 168443SN/A 169443SN/A 17012SN/ASyscallReturn 171468SN/AmunmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 1721708SN/A{ 1731708SN/A // given that we don't really implement mmap, munmap is really easy 17412SN/A return 0; 175468SN/A} 176443SN/A 177468SN/A 178443SN/Aconst char *hostname = "m5.eecs.umich.edu"; 17912SN/A 180468SN/ASyscallReturn 181468SN/AgethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 182443SN/A{ 18312SN/A int name_len = xc->getSyscallArg(1); 18412SN/A BufferArg name(xc->getSyscallArg(0), name_len); 185468SN/A 18612SN/A strncpy((char *)name.bufferPtr(), hostname, name_len); 1872472SN/A 188468SN/A name.copyOut(xc->mem); 189468SN/A 190468SN/A return 0; 191468SN/A} 192468SN/A 193468SN/ASyscallReturn 194468SN/AunlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 195468SN/A{ 196468SN/A std::string path; 197468SN/A 198468SN/A if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 199468SN/A return (TheISA::IntReg)-EFAULT; 200468SN/A 201468SN/A int result = unlink(path.c_str()); 202468SN/A return (result == -1) ? -errno : result; 203468SN/A} 204468SN/A 205468SN/ASyscallReturn 2062420SN/ArenameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 207468SN/A{ 208468SN/A std::string old_name; 209468SN/A 210468SN/A if (xc->mem->readString(old_name, xc->getSyscallArg(0)) != No_Fault) 211468SN/A return -EFAULT; 212468SN/A 2132420SN/A std::string new_name; 2142476SN/A 215468SN/A if (xc->mem->readString(new_name, xc->getSyscallArg(1)) != No_Fault) 216468SN/A return -EFAULT; 2172420SN/A 218468SN/A int64_t result = rename(old_name.c_str(),new_name.c_str()); 219468SN/A return (result == -1) ? -errno : result; 220468SN/A} 221468SN/A 222468SN/A