syscall_emul.cc revision 1999
17893SN/A/* 27893SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 37893SN/A * All rights reserved. 48825Snilay@cs.wisc.edu * 57893SN/A * Redistribution and use in source and binary forms, with or without 67893SN/A * modification, are permitted provided that the following conditions are 77893SN/A * met: redistributions of source code must retain the above copyright 87893SN/A * notice, this list of conditions and the following disclaimer; 97893SN/A * redistributions in binary form must reproduce the above copyright 107893SN/A * notice, this list of conditions and the following disclaimer in the 119885Sstever@gmail.com * documentation and/or other materials provided with the distribution; 128825Snilay@cs.wisc.edu * neither the name of the copyright holders nor the names of its 139885Sstever@gmail.com * contributors may be used to endorse or promote products derived from 149885Sstever@gmail.com * this software without specific prior written permission. 158825Snilay@cs.wisc.edu * 168825Snilay@cs.wisc.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 178825Snilay@cs.wisc.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 189449SAli.Saidi@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 199449SAli.Saidi@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 208464SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 218721SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 228825Snilay@cs.wisc.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 238825Snilay@cs.wisc.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247935SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257935SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 267935SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277935SN/A */ 287935SN/A 297935SN/A#include <unistd.h> 307935SN/A 318983Snate@binkert.org#include <string> 327893SN/A#include <iostream> 339885Sstever@gmail.com 349885Sstever@gmail.com#include "sim/syscall_emul.hh" 359885Sstever@gmail.com#include "base/trace.hh" 369885Sstever@gmail.com#include "cpu/exec_context.hh" 379885Sstever@gmail.com#include "cpu/base.hh" 387893SN/A#include "sim/process.hh" 397893SN/A 409885Sstever@gmail.com#include "sim/sim_events.hh" 417893SN/A 427893SN/Ausing namespace std; 438241SN/A 448241SN/Avoid 457893SN/ASyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc) 467893SN/A{ 477893SN/A DPRINTFR(SyscallVerbose, "%s: syscall %s called\n", 487893SN/A xc->cpu->name(), name); 499481Snilay@cs.wisc.edu 507893SN/A SyscallReturn retval = (*funcPtr)(this, callnum, process, xc); 517893SN/A 529885Sstever@gmail.com DPRINTFR(SyscallVerbose, "%s: syscall %s returns %d\n", 537893SN/A xc->cpu->name(), name, retval.value()); 547893SN/A 557893SN/A if (!(flags & SyscallDesc::SuppressReturnValue)) 567893SN/A xc->setSyscallReturn(retval); 577893SN/A} 587893SN/A 597893SN/A 607893SN/ASyscallReturn 617893SN/AunimplementedFunc(SyscallDesc *desc, int callnum, Process *process, 627893SN/A ExecContext *xc) 637893SN/A{ 648825Snilay@cs.wisc.edu fatal("syscall %s (#%d) unimplemented.", desc->name, callnum); 657893SN/A} 667893SN/A 677893SN/A 687893SN/ASyscallReturn 697893SN/AignoreFunc(SyscallDesc *desc, int callnum, Process *process, 707893SN/A ExecContext *xc) 717893SN/A{ 727893SN/A warn("ignoring syscall %s(%d, %d, ...)", desc->name, 737893SN/A xc->getSyscallArg(0), xc->getSyscallArg(1)); 747893SN/A 757893SN/A return 0; 767893SN/A} 777893SN/A 788825Snilay@cs.wisc.edu 799449SAli.Saidi@ARM.comSyscallReturn 807893SN/AexitFunc(SyscallDesc *desc, int callnum, Process *process, 817893SN/A ExecContext *xc) 827893SN/A{ 837893SN/A new SimExitEvent("syscall caused exit", xc->getSyscallArg(0) & 0xff); 847893SN/A 857893SN/A return 1; 867893SN/A} 878728SN/A 887893SN/A 897893SN/ASyscallReturn 907893SN/AgetpagesizeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 917893SN/A{ 927893SN/A return VMPageSize; 937893SN/A} 948825Snilay@cs.wisc.edu 957893SN/A 967893SN/ASyscallReturn 977893SN/AobreakFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 987893SN/A{ 997893SN/A // change brk addr to first arg 1007893SN/A Addr new_brk = xc->getSyscallArg(0); 1019885Sstever@gmail.com if (new_brk != 0) 1027893SN/A { 1037893SN/A p->brk_point = xc->getSyscallArg(0); 1047893SN/A } 1057893SN/A DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point); 1067893SN/A return p->brk_point; 1077893SN/A} 1087893SN/A 1097893SN/A 1107893SN/ASyscallReturn 1117893SN/AcloseFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 1128521SN/A{ 1139449SAli.Saidi@ARM.com int target_fd = xc->getSyscallArg(0); 1147893SN/A int status = close(p->sim_fd(target_fd)); 1157893SN/A if (status >= 0) 1167893SN/A p->free_fd(target_fd); 1177893SN/A return status; 1187893SN/A} 1197893SN/A 1207893SN/A 1217893SN/ASyscallReturn 1227893SN/AreadFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 1239885Sstever@gmail.com{ 1249885Sstever@gmail.com int fd = p->sim_fd(xc->getSyscallArg(0)); 1259885Sstever@gmail.com int nbytes = xc->getSyscallArg(2); 1269885Sstever@gmail.com BufferArg bufArg(xc->getSyscallArg(1), nbytes); 1279885Sstever@gmail.com 1289481Snilay@cs.wisc.edu int bytes_read = read(fd, bufArg.bufferPtr(), nbytes); 1299481Snilay@cs.wisc.edu 1309481Snilay@cs.wisc.edu if (bytes_read != -1) 1319481Snilay@cs.wisc.edu bufArg.copyOut(xc->mem); 1329481Snilay@cs.wisc.edu 1339481Snilay@cs.wisc.edu return bytes_read; 1349481Snilay@cs.wisc.edu} 1359481Snilay@cs.wisc.edu 1369481Snilay@cs.wisc.eduSyscallReturn 1379481Snilay@cs.wisc.eduwriteFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 1389481Snilay@cs.wisc.edu{ 1399481Snilay@cs.wisc.edu int fd = p->sim_fd(xc->getSyscallArg(0)); 1409481Snilay@cs.wisc.edu int nbytes = xc->getSyscallArg(2); 1419481Snilay@cs.wisc.edu BufferArg bufArg(xc->getSyscallArg(1), nbytes); 1429481Snilay@cs.wisc.edu 1439481Snilay@cs.wisc.edu bufArg.copyIn(xc->mem); 1447893SN/A 1457893SN/A int bytes_written = write(fd, bufArg.bufferPtr(), nbytes); 1469885Sstever@gmail.com 1478983Snate@binkert.org fsync(fd); 1487893SN/A 1499885Sstever@gmail.com return bytes_written; 1507893SN/A} 1519348SAli.Saidi@ARM.com 1528200SN/A 1537893SN/ASyscallReturn 1549348SAli.Saidi@ARM.comlseekFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 1557893SN/A{ 1568835SAli.Saidi@ARM.com int fd = p->sim_fd(xc->getSyscallArg(0)); 1579348SAli.Saidi@ARM.com uint64_t offs = xc->getSyscallArg(1); 1587893SN/A int whence = xc->getSyscallArg(2); 1598835SAli.Saidi@ARM.com 1609885Sstever@gmail.com off_t result = lseek(fd, offs, whence); 1617893SN/A 1627893SN/A return (result == (off_t)-1) ? -errno : result; 1637893SN/A} 1647893SN/A 1658983Snate@binkert.org 1667893SN/ASyscallReturn 1679885Sstever@gmail.communmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 1689885Sstever@gmail.com{ 1699885Sstever@gmail.com // given that we don't really implement mmap, munmap is really easy 1709885Sstever@gmail.com return 0; 1719885Sstever@gmail.com} 1729885Sstever@gmail.com 1739885Sstever@gmail.com 1749885Sstever@gmail.comconst char *hostname = "m5.eecs.umich.edu"; 1757893SN/A 1767893SN/ASyscallReturn 1778825Snilay@cs.wisc.edugethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 1787893SN/A{ 1798825Snilay@cs.wisc.edu int name_len = xc->getSyscallArg(1); 1808825Snilay@cs.wisc.edu BufferArg name(xc->getSyscallArg(0), name_len); 1818825Snilay@cs.wisc.edu 1828825Snilay@cs.wisc.edu strncpy((char *)name.bufferPtr(), hostname, name_len); 1839885Sstever@gmail.com 1849885Sstever@gmail.com name.copyOut(xc->mem); 1858825Snilay@cs.wisc.edu 1868983Snate@binkert.org return 0; 1877893SN/A} 1887893SN/A 1897893SN/ASyscallReturn 1907893SN/AunlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 1917893SN/A{ 1927893SN/A string path; 1937893SN/A 1947893SN/A if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 1957893SN/A return (TheISA::IntReg)-EFAULT; 1967893SN/A 1977893SN/A int result = unlink(path.c_str()); 1987893SN/A return (result == -1) ? -errno : result; 1997893SN/A} 2007893SN/A 2017893SN/ASyscallReturn 2027893SN/ArenameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 2037893SN/A{ 2047893SN/A string old_name; 2057893SN/A 2067893SN/A if (xc->mem->readString(old_name, xc->getSyscallArg(0)) != No_Fault) 2077893SN/A return -EFAULT; 2087893SN/A 2097893SN/A string new_name; 2107893SN/A 2117893SN/A if (xc->mem->readString(new_name, xc->getSyscallArg(1)) != No_Fault) 2127893SN/A return -EFAULT; 2137893SN/A 2147893SN/A int64_t result = rename(old_name.c_str(), new_name.c_str()); 2157893SN/A return (result == -1) ? -errno : result; 2167893SN/A} 2177893SN/A 2187893SN/ASyscallReturn 2197893SN/AtruncateFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 2207893SN/A{ 2217893SN/A string path; 2227893SN/A 2237893SN/A if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 2247893SN/A return -EFAULT; 2257893SN/A 2267893SN/A off_t length = xc->getSyscallArg(1); 2277893SN/A 2287893SN/A int result = truncate(path.c_str(), length); 2297893SN/A return (result == -1) ? -errno : result; 2307893SN/A} 2317893SN/A 2327893SN/ASyscallReturn 2337893SN/AftruncateFunc(SyscallDesc *desc, int num, Process *process, ExecContext *xc) 2347893SN/A{ 2357893SN/A int fd = process->sim_fd(xc->getSyscallArg(0)); 2367893SN/A 2377893SN/A if (fd < 0) 2387893SN/A return -EBADF; 2397893SN/A 2407893SN/A off_t length = xc->getSyscallArg(1); 2417893SN/A 2427893SN/A int result = ftruncate(fd, length); 2437893SN/A return (result == -1) ? -errno : result; 2447893SN/A} 2457893SN/A 2467893SN/ASyscallReturn 2477893SN/AchownFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) 2487893SN/A{ 2497893SN/A string path; 2507893SN/A 2517893SN/A if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) 2527893SN/A return -EFAULT; 2537893SN/A 2547893SN/A /* XXX endianess */ 2557893SN/A uint32_t owner = xc->getSyscallArg(1); 2567893SN/A uid_t hostOwner = owner; 2577893SN/A uint32_t group = xc->getSyscallArg(2); 2587893SN/A gid_t hostGroup = group; 2597893SN/A 2607893SN/A int result = chown(path.c_str(), hostOwner, hostGroup); 2617893SN/A return (result == -1) ? -errno : result; 2627893SN/A} 2637893SN/A 2647893SN/ASyscallReturn 2657893SN/AfchownFunc(SyscallDesc *desc, int num, Process *process, ExecContext *xc) 2667893SN/A{ 2677893SN/A int fd = process->sim_fd(xc->getSyscallArg(0)); 2687893SN/A 2697893SN/A if (fd < 0) 2707893SN/A return -EBADF; 2717893SN/A 2727893SN/A /* XXX endianess */ 2737893SN/A uint32_t owner = xc->getSyscallArg(1); 2747893SN/A uid_t hostOwner = owner; 2757893SN/A uint32_t group = xc->getSyscallArg(2); 2767893SN/A gid_t hostGroup = group; 2777893SN/A 2787893SN/A int result = fchown(fd, hostOwner, hostGroup); 2797893SN/A return (result == -1) ? -errno : result; 2807893SN/A} 2817893SN/A