syscall_emul.cc revision 4118
12810Srdreslin@umich.edu/* 28702Sandreas.hansson@arm.com * Copyright (c) 2003-2005 The Regents of The University of Michigan 38702Sandreas.hansson@arm.com * All rights reserved. 48702Sandreas.hansson@arm.com * 58702Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 68702Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 78702Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 88702Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 98702Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 108702Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 118702Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 128702Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 138702Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 142810Srdreslin@umich.edu * this software without specific prior written permission. 152810Srdreslin@umich.edu * 162810Srdreslin@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172810Srdreslin@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182810Srdreslin@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192810Srdreslin@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202810Srdreslin@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212810Srdreslin@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222810Srdreslin@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232810Srdreslin@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242810Srdreslin@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252810Srdreslin@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262810Srdreslin@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272810Srdreslin@umich.edu * 282810Srdreslin@umich.edu * Authors: Steve Reinhardt 292810Srdreslin@umich.edu * Ali Saidi 302810Srdreslin@umich.edu */ 312810Srdreslin@umich.edu 322810Srdreslin@umich.edu#include <fcntl.h> 332810Srdreslin@umich.edu#include <unistd.h> 342810Srdreslin@umich.edu 352810Srdreslin@umich.edu#include <string> 362810Srdreslin@umich.edu#include <iostream> 372810Srdreslin@umich.edu 382810Srdreslin@umich.edu#include "sim/syscall_emul.hh" 392810Srdreslin@umich.edu#include "base/chunk_generator.hh" 402810Srdreslin@umich.edu#include "base/trace.hh" 412810Srdreslin@umich.edu#include "cpu/thread_context.hh" 422810Srdreslin@umich.edu#include "cpu/base.hh" 434458Sstever@eecs.umich.edu#include "mem/page_table.hh" 448856Sandreas.hansson@arm.com#include "sim/process.hh" 452810Srdreslin@umich.edu 462810Srdreslin@umich.edu#include "sim/sim_exit.hh" 472810Srdreslin@umich.edu 482810Srdreslin@umich.eduusing namespace std; 492810Srdreslin@umich.eduusing namespace TheISA; 502810Srdreslin@umich.edu 512810Srdreslin@umich.eduvoid 522810Srdreslin@umich.eduSyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc) 532810Srdreslin@umich.edu{ 542810Srdreslin@umich.edu DPRINTFR(SyscallVerbose, "%d: %s: syscall %s called w/arguments %d,%d,%d,%d\n", 552810Srdreslin@umich.edu curTick,tc->getCpuPtr()->name(), name, 565338Sstever@gmail.com tc->getSyscallArg(0),tc->getSyscallArg(1), 575338Sstever@gmail.com tc->getSyscallArg(2),tc->getSyscallArg(3)); 585338Sstever@gmail.com 594458Sstever@eecs.umich.edu SyscallReturn retval = (*funcPtr)(this, callnum, process, tc); 604458Sstever@eecs.umich.edu 612813Srdreslin@umich.edu DPRINTFR(SyscallVerbose, "%d: %s: syscall %s returns %d\n", 623861Sstever@eecs.umich.edu curTick,tc->getCpuPtr()->name(), name, retval.value()); 632810Srdreslin@umich.edu 642810Srdreslin@umich.edu if (!(flags & SyscallDesc::SuppressReturnValue)) 652810Srdreslin@umich.edu tc->setSyscallReturn(retval); 662810Srdreslin@umich.edu} 674672Sstever@eecs.umich.edu 682810Srdreslin@umich.edu 694672Sstever@eecs.umich.eduSyscallReturn 702810Srdreslin@umich.eduunimplementedFunc(SyscallDesc *desc, int callnum, LiveProcess *process, 712810Srdreslin@umich.edu ThreadContext *tc) 722810Srdreslin@umich.edu{ 732810Srdreslin@umich.edu fatal("syscall %s (#%d) unimplemented.", desc->name, callnum); 742810Srdreslin@umich.edu 753860Sstever@eecs.umich.edu return 1; 763860Sstever@eecs.umich.edu} 772810Srdreslin@umich.edu 782810Srdreslin@umich.edu 792810Srdreslin@umich.eduSyscallReturn 808856Sandreas.hansson@arm.comignoreFunc(SyscallDesc *desc, int callnum, LiveProcess *process, 818856Sandreas.hansson@arm.com ThreadContext *tc) 828856Sandreas.hansson@arm.com{ 838856Sandreas.hansson@arm.com warn("ignoring syscall %s(%d, %d, ...)", desc->name, 848856Sandreas.hansson@arm.com tc->getSyscallArg(0), tc->getSyscallArg(1)); 853738Sstever@eecs.umich.edu 868856Sandreas.hansson@arm.com return 0; 873738Sstever@eecs.umich.edu} 888856Sandreas.hansson@arm.com 898856Sandreas.hansson@arm.com 903738Sstever@eecs.umich.eduSyscallReturn 918856Sandreas.hansson@arm.comexitFunc(SyscallDesc *desc, int callnum, LiveProcess *process, 924478Sstever@eecs.umich.edu ThreadContext *tc) 938975Sandreas.hansson@arm.com{ 948948Sandreas.hansson@arm.com if (tc->exit()) { 958975Sandreas.hansson@arm.com exitSimLoop("target called exit()", tc->getSyscallArg(0) & 0xff); 963738Sstever@eecs.umich.edu } 973738Sstever@eecs.umich.edu 983738Sstever@eecs.umich.edu return 1; 993738Sstever@eecs.umich.edu} 1008856Sandreas.hansson@arm.com 1018856Sandreas.hansson@arm.com 1028856Sandreas.hansson@arm.comSyscallReturn 1038856Sandreas.hansson@arm.comgetpagesizeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) 1048856Sandreas.hansson@arm.com{ 1058856Sandreas.hansson@arm.com return (int)VMPageSize; 1068856Sandreas.hansson@arm.com} 1078856Sandreas.hansson@arm.com 1088856Sandreas.hansson@arm.com 1098856Sandreas.hansson@arm.comSyscallReturn 1108856Sandreas.hansson@arm.comobreakFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) 1113738Sstever@eecs.umich.edu{ 1123738Sstever@eecs.umich.edu Addr junk; 1138856Sandreas.hansson@arm.com 1148914Sandreas.hansson@arm.com // change brk addr to first arg 1158914Sandreas.hansson@arm.com Addr new_brk = tc->getSyscallArg(0); 1168914Sandreas.hansson@arm.com if (new_brk != 0) { 1178914Sandreas.hansson@arm.com for (ChunkGenerator gen(p->brk_point, new_brk - p->brk_point, 1188914Sandreas.hansson@arm.com VMPageSize); !gen.done(); gen.next()) { 1198975Sandreas.hansson@arm.com if (!p->pTable->translate(gen.addr(), junk)) 1208914Sandreas.hansson@arm.com p->pTable->allocate(roundDown(gen.addr(), VMPageSize), 1218914Sandreas.hansson@arm.com VMPageSize); 1228914Sandreas.hansson@arm.com } 1238914Sandreas.hansson@arm.com p->brk_point = new_brk; 1248914Sandreas.hansson@arm.com } 1258914Sandreas.hansson@arm.com DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point); 1268914Sandreas.hansson@arm.com return p->brk_point; 1278914Sandreas.hansson@arm.com} 1288975Sandreas.hansson@arm.com 1298914Sandreas.hansson@arm.com 1308975Sandreas.hansson@arm.comSyscallReturn 1318914Sandreas.hansson@arm.comcloseFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) 1328914Sandreas.hansson@arm.com{ 1338914Sandreas.hansson@arm.com int target_fd = tc->getSyscallArg(0); 1348914Sandreas.hansson@arm.com int status = close(p->sim_fd(target_fd)); 1358914Sandreas.hansson@arm.com if (status >= 0) 1368914Sandreas.hansson@arm.com p->free_fd(target_fd); 1378914Sandreas.hansson@arm.com return status; 1388914Sandreas.hansson@arm.com} 1398914Sandreas.hansson@arm.com 1408914Sandreas.hansson@arm.com 1418914Sandreas.hansson@arm.comSyscallReturn 1428856Sandreas.hansson@arm.comreadFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) 1438856Sandreas.hansson@arm.com{ 1448856Sandreas.hansson@arm.com int fd = p->sim_fd(tc->getSyscallArg(0)); 1458856Sandreas.hansson@arm.com int nbytes = tc->getSyscallArg(2); 1463738Sstever@eecs.umich.edu BufferArg bufArg(tc->getSyscallArg(1), nbytes); 1478856Sandreas.hansson@arm.com 1483738Sstever@eecs.umich.edu int bytes_read = read(fd, bufArg.bufferPtr(), nbytes); 1498914Sandreas.hansson@arm.com 1508914Sandreas.hansson@arm.com if (bytes_read != -1) 1518914Sandreas.hansson@arm.com bufArg.copyOut(tc->getMemPort()); 1528856Sandreas.hansson@arm.com 1538856Sandreas.hansson@arm.com return bytes_read; 1543738Sstever@eecs.umich.edu} 1558856Sandreas.hansson@arm.com 1564478Sstever@eecs.umich.eduSyscallReturn 1578975Sandreas.hansson@arm.comwriteFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) 1588948Sandreas.hansson@arm.com{ 1598975Sandreas.hansson@arm.com int fd = p->sim_fd(tc->getSyscallArg(0)); 1603738Sstever@eecs.umich.edu int nbytes = tc->getSyscallArg(2); 1618948Sandreas.hansson@arm.com BufferArg bufArg(tc->getSyscallArg(1), nbytes); 1623738Sstever@eecs.umich.edu 1638948Sandreas.hansson@arm.com bufArg.copyIn(tc->getMemPort()); 1644458Sstever@eecs.umich.edu 1658856Sandreas.hansson@arm.com int bytes_written = write(fd, bufArg.bufferPtr(), nbytes); 1668856Sandreas.hansson@arm.com 1678856Sandreas.hansson@arm.com fsync(fd); 1688856Sandreas.hansson@arm.com 1698856Sandreas.hansson@arm.com return bytes_written; 1708856Sandreas.hansson@arm.com} 1718856Sandreas.hansson@arm.com 1723738Sstever@eecs.umich.edu 1733738Sstever@eecs.umich.eduSyscallReturn 1742810Srdreslin@umich.edulseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) 1752810Srdreslin@umich.edu{ 1764626Sstever@eecs.umich.edu int fd = p->sim_fd(tc->getSyscallArg(0)); 1772810Srdreslin@umich.edu uint64_t offs = tc->getSyscallArg(1); 1783861Sstever@eecs.umich.edu int whence = tc->getSyscallArg(2); 1792810Srdreslin@umich.edu 1804671Sstever@eecs.umich.edu off_t result = lseek(fd, offs, whence); 1814671Sstever@eecs.umich.edu 1824671Sstever@eecs.umich.edu return (result == (off_t)-1) ? -errno : result; 1832810Srdreslin@umich.edu} 1845707Shsul@eecs.umich.edu 1853860Sstever@eecs.umich.edu 1863860Sstever@eecs.umich.eduSyscallReturn 1873860Sstever@eecs.umich.edu_llseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) 1885875Ssteve.reinhardt@amd.com{ 1895875Ssteve.reinhardt@amd.com int fd = p->sim_fd(tc->getSyscallArg(0)); 1905875Ssteve.reinhardt@amd.com uint64_t offset_high = tc->getSyscallArg(1); 1915875Ssteve.reinhardt@amd.com uint32_t offset_low = tc->getSyscallArg(2); 1923860Sstever@eecs.umich.edu Addr result_ptr = tc->getSyscallArg(3); 1933860Sstever@eecs.umich.edu int whence = tc->getSyscallArg(4); 1943860Sstever@eecs.umich.edu 1953860Sstever@eecs.umich.edu uint64_t offset = (offset_high << 32) | offset_low; 1963860Sstever@eecs.umich.edu 1973860Sstever@eecs.umich.edu uint64_t result = lseek(fd, offset, whence); 1983860Sstever@eecs.umich.edu result = TheISA::htog(result); 1995707Shsul@eecs.umich.edu 2003860Sstever@eecs.umich.edu if (result == (off_t)-1) { 2015388Sstever@gmail.com //The seek failed. 2025388Sstever@gmail.com return -errno; 2034219Srdreslin@umich.edu } else { 2044219Srdreslin@umich.edu //The seek succeeded. 2054219Srdreslin@umich.edu //Copy "result" to "result_ptr" 2064219Srdreslin@umich.edu //XXX We'll assume that the size of loff_t is 64 bits on the 2074626Sstever@eecs.umich.edu //target platform 2083860Sstever@eecs.umich.edu BufferArg result_buf(result_ptr, sizeof(result)); 2093860Sstever@eecs.umich.edu memcpy(result_buf.bufferPtr(), &result, sizeof(result)); 2105350Sstever@gmail.com result_buf.copyOut(tc->getMemPort()); 2115350Sstever@gmail.com return 0; 2125350Sstever@gmail.com } 2135350Sstever@gmail.com 2145350Sstever@gmail.com 2155350Sstever@gmail.com return (result == (off_t)-1) ? -errno : result; 2165350Sstever@gmail.com} 2175350Sstever@gmail.com 2183860Sstever@eecs.umich.edu 2193860Sstever@eecs.umich.eduSyscallReturn 2203860Sstever@eecs.umich.edumunmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) 2214626Sstever@eecs.umich.edu{ 2223860Sstever@eecs.umich.edu // given that we don't really implement mmap, munmap is really easy 2233860Sstever@eecs.umich.edu return 0; 2243860Sstever@eecs.umich.edu} 2253860Sstever@eecs.umich.edu 2264626Sstever@eecs.umich.edu 2274626Sstever@eecs.umich.educonst char *hostname = "m5.eecs.umich.edu"; 2283860Sstever@eecs.umich.edu 2297667Ssteve.reinhardt@amd.comSyscallReturn 2307667Ssteve.reinhardt@amd.comgethostnameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) 2317667Ssteve.reinhardt@amd.com{ 2324628Sstever@eecs.umich.edu int name_len = tc->getSyscallArg(1); 2334626Sstever@eecs.umich.edu BufferArg name(tc->getSyscallArg(0), name_len); 2344670Sstever@eecs.umich.edu 2355319Sstever@gmail.com strncpy((char *)name.bufferPtr(), hostname, name_len); 2363860Sstever@eecs.umich.edu 2373860Sstever@eecs.umich.edu name.copyOut(tc->getMemPort()); 2383860Sstever@eecs.umich.edu 2393860Sstever@eecs.umich.edu return 0; 2403860Sstever@eecs.umich.edu} 2413860Sstever@eecs.umich.edu 2424670Sstever@eecs.umich.eduSyscallReturn 2435319Sstever@gmail.comunlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) 2443860Sstever@eecs.umich.edu{ 2453860Sstever@eecs.umich.edu string path; 2463860Sstever@eecs.umich.edu 2473860Sstever@eecs.umich.edu if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) 2483860Sstever@eecs.umich.edu return (TheISA::IntReg)-EFAULT; 2493860Sstever@eecs.umich.edu 2503860Sstever@eecs.umich.edu // Adjust path for current working directory 2513860Sstever@eecs.umich.edu path = p->fullPath(path); 2522810Srdreslin@umich.edu 2532810Srdreslin@umich.edu int result = unlink(path.c_str()); 2548831Smrinmoy.ghosh@arm.com return (result == -1) ? -errno : result; 2552810Srdreslin@umich.edu} 2562810Srdreslin@umich.edu 2572810Srdreslin@umich.eduSyscallReturn 2582810Srdreslin@umich.edurenameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) 2592810Srdreslin@umich.edu{ 2602982Sstever@eecs.umich.edu string old_name; 2612810Srdreslin@umich.edu 2622810Srdreslin@umich.edu if (!tc->getMemPort()->tryReadString(old_name, tc->getSyscallArg(0))) 2634626Sstever@eecs.umich.edu return -EFAULT; 2642810Srdreslin@umich.edu 2652810Srdreslin@umich.edu string new_name; 2664626Sstever@eecs.umich.edu 2674626Sstever@eecs.umich.edu if (!tc->getMemPort()->tryReadString(new_name, tc->getSyscallArg(1))) 2684626Sstever@eecs.umich.edu return -EFAULT; 2692810Srdreslin@umich.edu 2704626Sstever@eecs.umich.edu // Adjust path for current working directory 2712810Srdreslin@umich.edu old_name = p->fullPath(old_name); 2722810Srdreslin@umich.edu new_name = p->fullPath(new_name); 2734626Sstever@eecs.umich.edu 2744626Sstever@eecs.umich.edu int64_t result = rename(old_name.c_str(), new_name.c_str()); 2758702Sandreas.hansson@arm.com return (result == -1) ? -errno : result; 2762810Srdreslin@umich.edu} 2778702Sandreas.hansson@arm.com 2783293Srdreslin@umich.eduSyscallReturn 2793293Srdreslin@umich.edutruncateFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) 2802810Srdreslin@umich.edu{ 2812982Sstever@eecs.umich.edu string path; 2822810Srdreslin@umich.edu 2834626Sstever@eecs.umich.edu if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) 2842810Srdreslin@umich.edu return -EFAULT; 2852810Srdreslin@umich.edu 2862810Srdreslin@umich.edu off_t length = tc->getSyscallArg(1); 2872982Sstever@eecs.umich.edu 2882810Srdreslin@umich.edu // Adjust path for current working directory 2894626Sstever@eecs.umich.edu path = p->fullPath(path); 2902810Srdreslin@umich.edu 2914626Sstever@eecs.umich.edu int result = truncate(path.c_str(), length); 2924626Sstever@eecs.umich.edu return (result == -1) ? -errno : result; 2934626Sstever@eecs.umich.edu} 2944626Sstever@eecs.umich.edu 2954626Sstever@eecs.umich.eduSyscallReturn 2964626Sstever@eecs.umich.eduftruncateFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) 2974626Sstever@eecs.umich.edu{ 2982810Srdreslin@umich.edu int fd = process->sim_fd(tc->getSyscallArg(0)); 2992810Srdreslin@umich.edu 3002982Sstever@eecs.umich.edu if (fd < 0) 3012810Srdreslin@umich.edu return -EBADF; 3022982Sstever@eecs.umich.edu 3032810Srdreslin@umich.edu off_t length = tc->getSyscallArg(1); 3044626Sstever@eecs.umich.edu 3054626Sstever@eecs.umich.edu int result = ftruncate(fd, length); 3064626Sstever@eecs.umich.edu return (result == -1) ? -errno : result; 3075365Sstever@gmail.com} 3085365Sstever@gmail.com 3095365Sstever@gmail.comSyscallReturn 3105365Sstever@gmail.comchownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) 3115365Sstever@gmail.com{ 3125365Sstever@gmail.com string path; 3135365Sstever@gmail.com 3145365Sstever@gmail.com if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) 3155365Sstever@gmail.com return -EFAULT; 3164626Sstever@eecs.umich.edu 3174628Sstever@eecs.umich.edu /* XXX endianess */ 3184628Sstever@eecs.umich.edu uint32_t owner = tc->getSyscallArg(1); 3195365Sstever@gmail.com uid_t hostOwner = owner; 3205365Sstever@gmail.com uint32_t group = tc->getSyscallArg(2); 3215365Sstever@gmail.com gid_t hostGroup = group; 3225365Sstever@gmail.com 3235365Sstever@gmail.com // Adjust path for current working directory 3245365Sstever@gmail.com path = p->fullPath(path); 3255365Sstever@gmail.com 3264626Sstever@eecs.umich.edu int result = chown(path.c_str(), hostOwner, hostGroup); 3275365Sstever@gmail.com return (result == -1) ? -errno : result; 3285365Sstever@gmail.com} 3295365Sstever@gmail.com 3305365Sstever@gmail.comSyscallReturn 3315365Sstever@gmail.comfchownFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) 3325365Sstever@gmail.com{ 3334628Sstever@eecs.umich.edu int fd = process->sim_fd(tc->getSyscallArg(0)); 3344626Sstever@eecs.umich.edu 3354626Sstever@eecs.umich.edu if (fd < 0) 3364626Sstever@eecs.umich.edu return -EBADF; 3374626Sstever@eecs.umich.edu 3384626Sstever@eecs.umich.edu /* XXX endianess */ 3394626Sstever@eecs.umich.edu uint32_t owner = tc->getSyscallArg(1); 3404626Sstever@eecs.umich.edu uid_t hostOwner = owner; 3417667Ssteve.reinhardt@amd.com uint32_t group = tc->getSyscallArg(2); 3424626Sstever@eecs.umich.edu gid_t hostGroup = group; 3434626Sstever@eecs.umich.edu 3444626Sstever@eecs.umich.edu int result = fchown(fd, hostOwner, hostGroup); 3454626Sstever@eecs.umich.edu return (result == -1) ? -errno : result; 3464626Sstever@eecs.umich.edu} 3474626Sstever@eecs.umich.edu 3484626Sstever@eecs.umich.edu 3494626Sstever@eecs.umich.eduSyscallReturn 3504626Sstever@eecs.umich.edudupFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) 3514626Sstever@eecs.umich.edu{ 3524626Sstever@eecs.umich.edu int fd = process->sim_fd(tc->getSyscallArg(0)); 3532810Srdreslin@umich.edu 3544626Sstever@eecs.umich.edu if (fd < 0) 3552810Srdreslin@umich.edu return -EBADF; 3562810Srdreslin@umich.edu 3574626Sstever@eecs.umich.edu int result = dup(fd); 3584626Sstever@eecs.umich.edu return (result == -1) ? -errno : process->alloc_fd(result); 3592810Srdreslin@umich.edu} 3602810Srdreslin@umich.edu 3613861Sstever@eecs.umich.edu 3623861Sstever@eecs.umich.eduSyscallReturn 3633861Sstever@eecs.umich.edufcntlFunc(SyscallDesc *desc, int num, LiveProcess *process, 3643861Sstever@eecs.umich.edu ThreadContext *tc) 3653861Sstever@eecs.umich.edu{ 3664626Sstever@eecs.umich.edu int fd = tc->getSyscallArg(0); 3673861Sstever@eecs.umich.edu 3685875Ssteve.reinhardt@amd.com if (fd < 0 || process->sim_fd(fd) < 0) 3695875Ssteve.reinhardt@amd.com return -EBADF; 3705875Ssteve.reinhardt@amd.com 3715875Ssteve.reinhardt@amd.com int cmd = tc->getSyscallArg(1); 3725875Ssteve.reinhardt@amd.com switch (cmd) { 3738985SAli.Saidi@ARM.com case 0: // F_DUPFD 3748985SAli.Saidi@ARM.com // if we really wanted to support this, we'd need to do it 3758985SAli.Saidi@ARM.com // in the target fd space. 3768985SAli.Saidi@ARM.com warn("fcntl(%d, F_DUPFD) not supported, error returned\n", fd); 3778985SAli.Saidi@ARM.com return -EMFILE; 3788985SAli.Saidi@ARM.com 3792810Srdreslin@umich.edu case 1: // F_GETFD (get close-on-exec flag) 3802810Srdreslin@umich.edu case 2: // F_SETFD (set close-on-exec flag) 3812810Srdreslin@umich.edu return 0; 382 383 case 3: // F_GETFL (get file flags) 384 case 4: // F_SETFL (set file flags) 385 // not sure if this is totally valid, but we'll pass it through 386 // to the underlying OS 387 warn("fcntl(%d, %d) passed through to host\n", fd, cmd); 388 return fcntl(process->sim_fd(fd), cmd); 389 // return 0; 390 391 case 7: // F_GETLK (get lock) 392 case 8: // F_SETLK (set lock) 393 case 9: // F_SETLKW (set lock and wait) 394 // don't mess with file locking... just act like it's OK 395 warn("File lock call (fcntl(%d, %d)) ignored.\n", fd, cmd); 396 return 0; 397 398 default: 399 warn("Unknown fcntl command %d\n", cmd); 400 return 0; 401 } 402} 403 404SyscallReturn 405fcntl64Func(SyscallDesc *desc, int num, LiveProcess *process, 406 ThreadContext *tc) 407{ 408 int fd = tc->getSyscallArg(0); 409 410 if (fd < 0 || process->sim_fd(fd) < 0) 411 return -EBADF; 412 413 int cmd = tc->getSyscallArg(1); 414 switch (cmd) { 415 case 33: //F_GETLK64 416 warn("fcntl64(%d, F_GETLK64) not supported, error returned\n", fd); 417 return -EMFILE; 418 419 case 34: // F_SETLK64 420 case 35: // F_SETLKW64 421 warn("fcntl64(%d, F_SETLK(W)64) not supported, error returned\n", fd); 422 return -EMFILE; 423 424 default: 425 // not sure if this is totally valid, but we'll pass it through 426 // to the underlying OS 427 warn("fcntl64(%d, %d) passed through to host\n", fd, cmd); 428 return fcntl(process->sim_fd(fd), cmd); 429 // return 0; 430 } 431} 432 433SyscallReturn 434pipePseudoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, 435 ThreadContext *tc) 436{ 437 int fds[2], sim_fds[2]; 438 int pipe_retval = pipe(fds); 439 440 if (pipe_retval < 0) { 441 // error 442 return pipe_retval; 443 } 444 445 sim_fds[0] = process->alloc_fd(fds[0]); 446 sim_fds[1] = process->alloc_fd(fds[1]); 447 448 // Alpha Linux convention for pipe() is that fd[0] is returned as 449 // the return value of the function, and fd[1] is returned in r20. 450 tc->setIntReg(SyscallPseudoReturnReg, sim_fds[1]); 451 return sim_fds[0]; 452} 453 454 455SyscallReturn 456getpidPseudoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, 457 ThreadContext *tc) 458{ 459 // Make up a PID. There's no interprocess communication in 460 // fake_syscall mode, so there's no way for a process to know it's 461 // not getting a unique value. 462 463 tc->setIntReg(SyscallPseudoReturnReg, process->ppid()); 464 return process->pid(); 465} 466 467 468SyscallReturn 469getuidPseudoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, 470 ThreadContext *tc) 471{ 472 // Make up a UID and EUID... it shouldn't matter, and we want the 473 // simulation to be deterministic. 474 475 // EUID goes in r20. 476 tc->setIntReg(SyscallPseudoReturnReg, process->euid()); //EUID 477 return process->uid(); // UID 478} 479 480 481SyscallReturn 482getgidPseudoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, 483 ThreadContext *tc) 484{ 485 // Get current group ID. EGID goes in r20. 486 tc->setIntReg(SyscallPseudoReturnReg, process->egid()); //EGID 487 return process->gid(); 488} 489 490 491SyscallReturn 492setuidFunc(SyscallDesc *desc, int callnum, LiveProcess *process, 493 ThreadContext *tc) 494{ 495 // can't fathom why a benchmark would call this. 496 warn("Ignoring call to setuid(%d)\n", tc->getSyscallArg(0)); 497 return 0; 498} 499 500SyscallReturn 501getpidFunc(SyscallDesc *desc, int callnum, LiveProcess *process, 502 ThreadContext *tc) 503{ 504 // Make up a PID. There's no interprocess communication in 505 // fake_syscall mode, so there's no way for a process to know it's 506 // not getting a unique value. 507 508 tc->setIntReg(SyscallPseudoReturnReg, process->ppid()); //PID 509 return process->pid(); 510} 511 512SyscallReturn 513getppidFunc(SyscallDesc *desc, int callnum, LiveProcess *process, 514 ThreadContext *tc) 515{ 516 return process->ppid(); 517} 518 519SyscallReturn 520getuidFunc(SyscallDesc *desc, int callnum, LiveProcess *process, 521 ThreadContext *tc) 522{ 523 return process->uid(); // UID 524} 525 526SyscallReturn 527geteuidFunc(SyscallDesc *desc, int callnum, LiveProcess *process, 528 ThreadContext *tc) 529{ 530 return process->euid(); // UID 531} 532 533SyscallReturn 534getgidFunc(SyscallDesc *desc, int callnum, LiveProcess *process, 535 ThreadContext *tc) 536{ 537 return process->gid(); 538} 539 540SyscallReturn 541getegidFunc(SyscallDesc *desc, int callnum, LiveProcess *process, 542 ThreadContext *tc) 543{ 544 return process->egid(); 545} 546 547 548