Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 1 | /* |
Ali Saidi | ad9b28f | 2005-03-10 14:20:12 -0500 | [diff] [blame] | 2 | * Copyright (c) 2003-2005 The Regents of The University of Michigan |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 3 | * All rights reserved. |
| 4 | * |
| 5 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions are |
| 7 | * met: redistributions of source code must retain the above copyright |
| 8 | * notice, this list of conditions and the following disclaimer; |
| 9 | * redistributions in binary form must reproduce the above copyright |
| 10 | * notice, this list of conditions and the following disclaimer in the |
| 11 | * documentation and/or other materials provided with the distribution; |
| 12 | * neither the name of the copyright holders nor the names of its |
| 13 | * contributors may be used to endorse or promote products derived from |
| 14 | * this software without specific prior written permission. |
| 15 | * |
| 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 18 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 19 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 20 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 21 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Ali Saidi | cb0cf2d | 2006-05-31 19:26:56 -0400 | [diff] [blame] | 27 | * |
| 28 | * Authors: Steve Reinhardt |
| 29 | * Ali Saidi |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 30 | */ |
| 31 | |
Ali Saidi | 53d2c93 | 2006-02-18 23:44:22 -0500 | [diff] [blame] | 32 | #include <fcntl.h> |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 33 | #include <unistd.h> |
| 34 | |
Nathan Binkert | 2c5fe6f | 2009-11-04 16:57:01 -0800 | [diff] [blame] | 35 | #include <cstdio> |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 36 | #include <iostream> |
Nathan Binkert | 2c5fe6f | 2009-11-04 16:57:01 -0800 | [diff] [blame] | 37 | #include <string> |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 38 | |
Gabe Black | 0dd1f7f | 2010-09-14 00:29:38 -0700 | [diff] [blame] | 39 | #include "arch/utility.hh" |
Ali Saidi | 97e4249 | 2006-03-15 17:04:50 -0500 | [diff] [blame] | 40 | #include "base/chunk_generator.hh" |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 41 | #include "base/trace.hh" |
Nathan Binkert | d9f39c8 | 2009-09-23 08:34:21 -0700 | [diff] [blame] | 42 | #include "config/the_isa.hh" |
Nathan Binkert | 13c005a | 2005-06-04 20:50:10 -0400 | [diff] [blame] | 43 | #include "cpu/base.hh" |
Nathan Binkert | 39a0556 | 2011-04-15 10:44:06 -0700 | [diff] [blame] | 44 | #include "cpu/thread_context.hh" |
Nathan Binkert | eddac53 | 2011-04-15 10:44:32 -0700 | [diff] [blame] | 45 | #include "debug/SyscallVerbose.hh" |
Ali Saidi | 97e4249 | 2006-03-15 17:04:50 -0500 | [diff] [blame] | 46 | #include "mem/page_table.hh" |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 47 | #include "sim/process.hh" |
Steve Reinhardt | 29e34a7 | 2006-06-09 23:01:31 -0400 | [diff] [blame] | 48 | #include "sim/sim_exit.hh" |
Nathan Binkert | 39a0556 | 2011-04-15 10:44:06 -0700 | [diff] [blame] | 49 | #include "sim/syscall_emul.hh" |
| 50 | #include "sim/system.hh" |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 51 | |
| 52 | using namespace std; |
Gabe Black | 463aa6d | 2006-02-19 02:34:37 -0500 | [diff] [blame] | 53 | using namespace TheISA; |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 54 | |
| 55 | void |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 56 | SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc) |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 57 | { |
Gabe Black | d6ff792 | 2009-10-31 13:20:22 -0700 | [diff] [blame] | 58 | #if TRACING_ON |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 59 | int index = 0; |
Gabe Black | d6ff792 | 2009-10-31 13:20:22 -0700 | [diff] [blame] | 60 | #endif |
Steve Reinhardt | 03b3925 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 61 | DPRINTFR(SyscallVerbose, |
| 62 | "%d: %s: syscall %s called w/arguments %d,%d,%d,%d\n", |
Steve Reinhardt | 6f11879 | 2011-01-07 21:50:29 -0800 | [diff] [blame] | 63 | curTick(), tc->getCpuPtr()->name(), name, |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 64 | process->getSyscallArg(tc, index), |
| 65 | process->getSyscallArg(tc, index), |
| 66 | process->getSyscallArg(tc, index), |
| 67 | process->getSyscallArg(tc, index)); |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 68 | |
Kevin Lim | eb0e416 | 2006-06-06 17:32:21 -0400 | [diff] [blame] | 69 | SyscallReturn retval = (*funcPtr)(this, callnum, process, tc); |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 70 | |
Korey Sewell | 4f430e9 | 2006-04-10 12:23:17 -0400 | [diff] [blame] | 71 | DPRINTFR(SyscallVerbose, "%d: %s: syscall %s returns %d\n", |
Steve Reinhardt | 6f11879 | 2011-01-07 21:50:29 -0800 | [diff] [blame] | 72 | curTick(),tc->getCpuPtr()->name(), name, retval.value()); |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 73 | |
Ali Saidi | 232134a | 2005-03-09 15:52:10 -0500 | [diff] [blame] | 74 | if (!(flags & SyscallDesc::SuppressReturnValue)) |
Gabe Black | 9a000c5 | 2009-02-27 09:22:14 -0800 | [diff] [blame] | 75 | process->setSyscallReturn(tc, retval); |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 76 | } |
| 77 | |
| 78 | |
Ali Saidi | 232134a | 2005-03-09 15:52:10 -0500 | [diff] [blame] | 79 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 80 | unimplementedFunc(SyscallDesc *desc, int callnum, LiveProcess *process, |
Kevin Lim | eb0e416 | 2006-06-06 17:32:21 -0400 | [diff] [blame] | 81 | ThreadContext *tc) |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 82 | { |
Steve Reinhardt | 99bf6ed | 2005-11-10 21:05:31 -0500 | [diff] [blame] | 83 | fatal("syscall %s (#%d) unimplemented.", desc->name, callnum); |
Korey Sewell | 8ddd509 | 2006-03-18 10:51:28 -0500 | [diff] [blame] | 84 | |
| 85 | return 1; |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 86 | } |
| 87 | |
| 88 | |
Ali Saidi | 232134a | 2005-03-09 15:52:10 -0500 | [diff] [blame] | 89 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 90 | ignoreFunc(SyscallDesc *desc, int callnum, LiveProcess *process, |
Kevin Lim | eb0e416 | 2006-06-06 17:32:21 -0400 | [diff] [blame] | 91 | ThreadContext *tc) |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 92 | { |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 93 | int index = 0; |
Steve Reinhardt | 99bf6ed | 2005-11-10 21:05:31 -0500 | [diff] [blame] | 94 | warn("ignoring syscall %s(%d, %d, ...)", desc->name, |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 95 | process->getSyscallArg(tc, index), process->getSyscallArg(tc, index)); |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 96 | |
Ali Saidi | ad9b28f | 2005-03-10 14:20:12 -0500 | [diff] [blame] | 97 | return 0; |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 98 | } |
| 99 | |
| 100 | |
Ali Saidi | 232134a | 2005-03-09 15:52:10 -0500 | [diff] [blame] | 101 | SyscallReturn |
Chris Emmons | ccaaa98 | 2011-03-17 19:20:20 -0500 | [diff] [blame] | 102 | ignoreWarnOnceFunc(SyscallDesc *desc, int callnum, LiveProcess *process, |
| 103 | ThreadContext *tc) |
| 104 | { |
| 105 | int index = 0; |
| 106 | warn_once("ignoring syscall %s(%d, %d, ...)", desc->name, |
| 107 | process->getSyscallArg(tc, index), process->getSyscallArg(tc, index)); |
| 108 | |
| 109 | return 0; |
| 110 | } |
| 111 | |
| 112 | |
| 113 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 114 | exitFunc(SyscallDesc *desc, int callnum, LiveProcess *process, |
Kevin Lim | eb0e416 | 2006-06-06 17:32:21 -0400 | [diff] [blame] | 115 | ThreadContext *tc) |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 116 | { |
Steve Reinhardt | 8882dc1 | 2009-04-15 13:13:47 -0700 | [diff] [blame] | 117 | if (process->system->numRunningContexts() == 1) { |
| 118 | // Last running context... exit simulator |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 119 | int index = 0; |
Gabe Black | 9a000c5 | 2009-02-27 09:22:14 -0800 | [diff] [blame] | 120 | exitSimLoop("target called exit()", |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 121 | process->getSyscallArg(tc, index) & 0xff); |
Steve Reinhardt | 8882dc1 | 2009-04-15 13:13:47 -0700 | [diff] [blame] | 122 | } else { |
| 123 | // other running threads... just halt this one |
| 124 | tc->halt(); |
Korey Sewell | f4c5609 | 2006-07-03 12:19:35 -0400 | [diff] [blame] | 125 | } |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 126 | |
Ali Saidi | ad9b28f | 2005-03-10 14:20:12 -0500 | [diff] [blame] | 127 | return 1; |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 128 | } |
| 129 | |
| 130 | |
Ali Saidi | 232134a | 2005-03-09 15:52:10 -0500 | [diff] [blame] | 131 | SyscallReturn |
Daniel Sanchez | b0e9654 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 132 | exitGroupFunc(SyscallDesc *desc, int callnum, LiveProcess *process, |
| 133 | ThreadContext *tc) |
| 134 | { |
| 135 | // really should just halt all thread contexts belonging to this |
| 136 | // process in case there's another process running... |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 137 | int index = 0; |
Daniel Sanchez | b0e9654 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 138 | exitSimLoop("target called exit()", |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 139 | process->getSyscallArg(tc, index) & 0xff); |
Daniel Sanchez | b0e9654 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 140 | |
| 141 | return 1; |
| 142 | } |
| 143 | |
| 144 | |
| 145 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 146 | getpagesizeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 147 | { |
Gabe Black | 463aa6d | 2006-02-19 02:34:37 -0500 | [diff] [blame] | 148 | return (int)VMPageSize; |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 149 | } |
| 150 | |
| 151 | |
Ali Saidi | 232134a | 2005-03-09 15:52:10 -0500 | [diff] [blame] | 152 | SyscallReturn |
Steve Reinhardt | 4514f56 | 2008-11-15 09:30:10 -0800 | [diff] [blame] | 153 | brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 154 | { |
| 155 | // change brk addr to first arg |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 156 | int index = 0; |
| 157 | Addr new_brk = p->getSyscallArg(tc, index); |
Steve Reinhardt | 4514f56 | 2008-11-15 09:30:10 -0800 | [diff] [blame] | 158 | |
| 159 | // in Linux at least, brk(0) returns the current break value |
| 160 | // (note that the syscall and the glibc function have different behavior) |
| 161 | if (new_brk == 0) |
| 162 | return p->brk_point; |
| 163 | |
| 164 | if (new_brk > p->brk_point) { |
| 165 | // might need to allocate some new pages |
Ali Saidi | 97e4249 | 2006-03-15 17:04:50 -0500 | [diff] [blame] | 166 | for (ChunkGenerator gen(p->brk_point, new_brk - p->brk_point, |
| 167 | VMPageSize); !gen.done(); gen.next()) { |
Steve Reinhardt | 4514f56 | 2008-11-15 09:30:10 -0800 | [diff] [blame] | 168 | if (!p->pTable->translate(gen.addr())) |
Steve Reinhardt | 6f9d294 | 2011-10-22 22:30:08 -0700 | [diff] [blame] | 169 | p->allocateMem(roundDown(gen.addr(), VMPageSize), VMPageSize); |
Timothy M. Jones | 03da1e5 | 2009-10-24 10:53:58 -0700 | [diff] [blame] | 170 | |
| 171 | // if the address is already there, zero it out |
| 172 | else { |
| 173 | uint8_t zero = 0; |
Andreas Hansson | 9e3c8de | 2012-02-24 11:45:30 -0500 | [diff] [blame^] | 174 | SETranslatingPortProxy &tp = tc->getMemProxy(); |
Timothy M. Jones | 03da1e5 | 2009-10-24 10:53:58 -0700 | [diff] [blame] | 175 | |
| 176 | // split non-page aligned accesses |
| 177 | Addr next_page = roundUp(gen.addr(), VMPageSize); |
| 178 | uint32_t size_needed = next_page - gen.addr(); |
Andreas Hansson | 9e3c8de | 2012-02-24 11:45:30 -0500 | [diff] [blame^] | 179 | tp.memsetBlob(gen.addr(), zero, size_needed); |
Timothy M. Jones | 03da1e5 | 2009-10-24 10:53:58 -0700 | [diff] [blame] | 180 | if (gen.addr() + VMPageSize > next_page && |
| 181 | next_page < new_brk && |
| 182 | p->pTable->translate(next_page)) |
| 183 | { |
| 184 | size_needed = VMPageSize - size_needed; |
Andreas Hansson | 9e3c8de | 2012-02-24 11:45:30 -0500 | [diff] [blame^] | 185 | tp.memsetBlob(next_page, zero, size_needed); |
Timothy M. Jones | 03da1e5 | 2009-10-24 10:53:58 -0700 | [diff] [blame] | 186 | } |
| 187 | } |
Ali Saidi | 97e4249 | 2006-03-15 17:04:50 -0500 | [diff] [blame] | 188 | } |
Ali Saidi | 232134a | 2005-03-09 15:52:10 -0500 | [diff] [blame] | 189 | } |
Steve Reinhardt | 4514f56 | 2008-11-15 09:30:10 -0800 | [diff] [blame] | 190 | |
| 191 | p->brk_point = new_brk; |
Ali Saidi | ad9b28f | 2005-03-10 14:20:12 -0500 | [diff] [blame] | 192 | DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point); |
| 193 | return p->brk_point; |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 194 | } |
| 195 | |
| 196 | |
Ali Saidi | 232134a | 2005-03-09 15:52:10 -0500 | [diff] [blame] | 197 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 198 | closeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 199 | { |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 200 | int index = 0; |
| 201 | int target_fd = p->getSyscallArg(tc, index); |
Timothy M. Jones | 0d301ca | 2010-07-22 18:47:52 +0100 | [diff] [blame] | 202 | int sim_fd = p->sim_fd(target_fd); |
| 203 | int status = 0; |
| 204 | if (sim_fd > 2) |
| 205 | status = close(sim_fd); |
Steve Reinhardt | 4410876 | 2005-11-10 21:08:33 -0500 | [diff] [blame] | 206 | if (status >= 0) |
| 207 | p->free_fd(target_fd); |
| 208 | return status; |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 209 | } |
| 210 | |
| 211 | |
Ali Saidi | 232134a | 2005-03-09 15:52:10 -0500 | [diff] [blame] | 212 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 213 | readFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 214 | { |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 215 | int index = 0; |
| 216 | int fd = p->sim_fd(p->getSyscallArg(tc, index)); |
| 217 | Addr bufPtr = p->getSyscallArg(tc, index); |
| 218 | int nbytes = p->getSyscallArg(tc, index); |
| 219 | BufferArg bufArg(bufPtr, nbytes); |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 220 | |
| 221 | int bytes_read = read(fd, bufArg.bufferPtr(), nbytes); |
| 222 | |
| 223 | if (bytes_read != -1) |
Andreas Hansson | f85286b | 2012-01-17 12:55:08 -0600 | [diff] [blame] | 224 | bufArg.copyOut(tc->getMemProxy()); |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 225 | |
Ali Saidi | ad9b28f | 2005-03-10 14:20:12 -0500 | [diff] [blame] | 226 | return bytes_read; |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 227 | } |
| 228 | |
Ali Saidi | 232134a | 2005-03-09 15:52:10 -0500 | [diff] [blame] | 229 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 230 | writeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 231 | { |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 232 | int index = 0; |
| 233 | int fd = p->sim_fd(p->getSyscallArg(tc, index)); |
| 234 | Addr bufPtr = p->getSyscallArg(tc, index); |
| 235 | int nbytes = p->getSyscallArg(tc, index); |
| 236 | BufferArg bufArg(bufPtr, nbytes); |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 237 | |
Andreas Hansson | f85286b | 2012-01-17 12:55:08 -0600 | [diff] [blame] | 238 | bufArg.copyIn(tc->getMemProxy()); |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 239 | |
| 240 | int bytes_written = write(fd, bufArg.bufferPtr(), nbytes); |
| 241 | |
| 242 | fsync(fd); |
| 243 | |
Ali Saidi | ad9b28f | 2005-03-10 14:20:12 -0500 | [diff] [blame] | 244 | return bytes_written; |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 245 | } |
| 246 | |
| 247 | |
Ali Saidi | 232134a | 2005-03-09 15:52:10 -0500 | [diff] [blame] | 248 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 249 | lseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 250 | { |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 251 | int index = 0; |
| 252 | int fd = p->sim_fd(p->getSyscallArg(tc, index)); |
| 253 | uint64_t offs = p->getSyscallArg(tc, index); |
| 254 | int whence = p->getSyscallArg(tc, index); |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 255 | |
| 256 | off_t result = lseek(fd, offs, whence); |
| 257 | |
Ali Saidi | ad9b28f | 2005-03-10 14:20:12 -0500 | [diff] [blame] | 258 | return (result == (off_t)-1) ? -errno : result; |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 259 | } |
| 260 | |
| 261 | |
Ali Saidi | 232134a | 2005-03-09 15:52:10 -0500 | [diff] [blame] | 262 | SyscallReturn |
Gabe Black | 23dc509 | 2007-03-03 03:34:55 +0000 | [diff] [blame] | 263 | _llseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) |
| 264 | { |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 265 | int index = 0; |
| 266 | int fd = p->sim_fd(p->getSyscallArg(tc, index)); |
| 267 | uint64_t offset_high = p->getSyscallArg(tc, index); |
| 268 | uint32_t offset_low = p->getSyscallArg(tc, index); |
| 269 | Addr result_ptr = p->getSyscallArg(tc, index); |
| 270 | int whence = p->getSyscallArg(tc, index); |
Gabe Black | 23dc509 | 2007-03-03 03:34:55 +0000 | [diff] [blame] | 271 | |
| 272 | uint64_t offset = (offset_high << 32) | offset_low; |
| 273 | |
| 274 | uint64_t result = lseek(fd, offset, whence); |
| 275 | result = TheISA::htog(result); |
| 276 | |
| 277 | if (result == (off_t)-1) { |
| 278 | //The seek failed. |
| 279 | return -errno; |
| 280 | } else { |
Steve Reinhardt | 03b3925 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 281 | // The seek succeeded. |
| 282 | // Copy "result" to "result_ptr" |
| 283 | // XXX We'll assume that the size of loff_t is 64 bits on the |
| 284 | // target platform |
Gabe Black | 23dc509 | 2007-03-03 03:34:55 +0000 | [diff] [blame] | 285 | BufferArg result_buf(result_ptr, sizeof(result)); |
| 286 | memcpy(result_buf.bufferPtr(), &result, sizeof(result)); |
Andreas Hansson | f85286b | 2012-01-17 12:55:08 -0600 | [diff] [blame] | 287 | result_buf.copyOut(tc->getMemProxy()); |
Gabe Black | 23dc509 | 2007-03-03 03:34:55 +0000 | [diff] [blame] | 288 | return 0; |
| 289 | } |
| 290 | |
| 291 | |
| 292 | return (result == (off_t)-1) ? -errno : result; |
| 293 | } |
| 294 | |
| 295 | |
| 296 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 297 | munmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 298 | { |
| 299 | // given that we don't really implement mmap, munmap is really easy |
Ali Saidi | ad9b28f | 2005-03-10 14:20:12 -0500 | [diff] [blame] | 300 | return 0; |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 301 | } |
| 302 | |
| 303 | |
| 304 | const char *hostname = "m5.eecs.umich.edu"; |
| 305 | |
Ali Saidi | 232134a | 2005-03-09 15:52:10 -0500 | [diff] [blame] | 306 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 307 | gethostnameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 308 | { |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 309 | int index = 0; |
| 310 | Addr bufPtr = p->getSyscallArg(tc, index); |
| 311 | int name_len = p->getSyscallArg(tc, index); |
| 312 | BufferArg name(bufPtr, name_len); |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 313 | |
| 314 | strncpy((char *)name.bufferPtr(), hostname, name_len); |
| 315 | |
Andreas Hansson | f85286b | 2012-01-17 12:55:08 -0600 | [diff] [blame] | 316 | name.copyOut(tc->getMemProxy()); |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 317 | |
Ali Saidi | ad9b28f | 2005-03-10 14:20:12 -0500 | [diff] [blame] | 318 | return 0; |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 319 | } |
| 320 | |
Ali Saidi | 232134a | 2005-03-09 15:52:10 -0500 | [diff] [blame] | 321 | SyscallReturn |
Michael Adler | 2cd04fd | 2008-07-23 14:41:33 -0700 | [diff] [blame] | 322 | getcwdFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) |
| 323 | { |
| 324 | int result = 0; |
Vince Weaver | 7da221c | 2009-11-09 10:02:55 -0500 | [diff] [blame] | 325 | int index = 0; |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 326 | Addr bufPtr = p->getSyscallArg(tc, index); |
| 327 | unsigned long size = p->getSyscallArg(tc, index); |
| 328 | BufferArg buf(bufPtr, size); |
Michael Adler | 2cd04fd | 2008-07-23 14:41:33 -0700 | [diff] [blame] | 329 | |
| 330 | // Is current working directory defined? |
| 331 | string cwd = p->getcwd(); |
| 332 | if (!cwd.empty()) { |
| 333 | if (cwd.length() >= size) { |
| 334 | // Buffer too small |
| 335 | return -ERANGE; |
| 336 | } |
| 337 | strncpy((char *)buf.bufferPtr(), cwd.c_str(), size); |
| 338 | result = cwd.length(); |
| 339 | } |
| 340 | else { |
| 341 | if (getcwd((char *)buf.bufferPtr(), size) != NULL) { |
| 342 | result = strlen((char *)buf.bufferPtr()); |
| 343 | } |
| 344 | else { |
| 345 | result = -1; |
| 346 | } |
| 347 | } |
| 348 | |
Andreas Hansson | f85286b | 2012-01-17 12:55:08 -0600 | [diff] [blame] | 349 | buf.copyOut(tc->getMemProxy()); |
Michael Adler | 2cd04fd | 2008-07-23 14:41:33 -0700 | [diff] [blame] | 350 | |
| 351 | return (result == -1) ? -errno : result; |
| 352 | } |
| 353 | |
| 354 | |
| 355 | SyscallReturn |
| 356 | readlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) |
| 357 | { |
| 358 | string path; |
| 359 | |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 360 | int index = 0; |
Andreas Hansson | 9e3c8de | 2012-02-24 11:45:30 -0500 | [diff] [blame^] | 361 | if (!tc->getMemProxy().tryReadString(path, p->getSyscallArg(tc, index))) |
Michael Adler | 2cd04fd | 2008-07-23 14:41:33 -0700 | [diff] [blame] | 362 | return (TheISA::IntReg)-EFAULT; |
| 363 | |
| 364 | // Adjust path for current working directory |
| 365 | path = p->fullPath(path); |
| 366 | |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 367 | Addr bufPtr = p->getSyscallArg(tc, index); |
| 368 | size_t bufsiz = p->getSyscallArg(tc, index); |
| 369 | |
| 370 | BufferArg buf(bufPtr, bufsiz); |
Michael Adler | 2cd04fd | 2008-07-23 14:41:33 -0700 | [diff] [blame] | 371 | |
| 372 | int result = readlink(path.c_str(), (char *)buf.bufferPtr(), bufsiz); |
| 373 | |
Andreas Hansson | f85286b | 2012-01-17 12:55:08 -0600 | [diff] [blame] | 374 | buf.copyOut(tc->getMemProxy()); |
Michael Adler | 2cd04fd | 2008-07-23 14:41:33 -0700 | [diff] [blame] | 375 | |
| 376 | return (result == -1) ? -errno : result; |
| 377 | } |
| 378 | |
| 379 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 380 | unlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) |
David Oehmke | 95c248c | 2004-02-05 12:16:17 -0500 | [diff] [blame] | 381 | { |
Steve Reinhardt | 22eccce | 2005-06-03 16:19:34 -0400 | [diff] [blame] | 382 | string path; |
David Oehmke | 95c248c | 2004-02-05 12:16:17 -0500 | [diff] [blame] | 383 | |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 384 | int index = 0; |
Andreas Hansson | 9e3c8de | 2012-02-24 11:45:30 -0500 | [diff] [blame^] | 385 | if (!tc->getMemProxy().tryReadString(path, p->getSyscallArg(tc, index))) |
Ali Saidi | 232134a | 2005-03-09 15:52:10 -0500 | [diff] [blame] | 386 | return (TheISA::IntReg)-EFAULT; |
David Oehmke | 95c248c | 2004-02-05 12:16:17 -0500 | [diff] [blame] | 387 | |
Nathan Binkert | 31d829d | 2006-11-16 12:43:11 -0800 | [diff] [blame] | 388 | // Adjust path for current working directory |
| 389 | path = p->fullPath(path); |
| 390 | |
David Oehmke | 95c248c | 2004-02-05 12:16:17 -0500 | [diff] [blame] | 391 | int result = unlink(path.c_str()); |
Ali Saidi | ad9b28f | 2005-03-10 14:20:12 -0500 | [diff] [blame] | 392 | return (result == -1) ? -errno : result; |
David Oehmke | 95c248c | 2004-02-05 12:16:17 -0500 | [diff] [blame] | 393 | } |
| 394 | |
Michael Adler | 2cd04fd | 2008-07-23 14:41:33 -0700 | [diff] [blame] | 395 | |
| 396 | SyscallReturn |
| 397 | mkdirFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) |
| 398 | { |
| 399 | string path; |
| 400 | |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 401 | int index = 0; |
Andreas Hansson | 9e3c8de | 2012-02-24 11:45:30 -0500 | [diff] [blame^] | 402 | if (!tc->getMemProxy().tryReadString(path, p->getSyscallArg(tc, index))) |
Michael Adler | 2cd04fd | 2008-07-23 14:41:33 -0700 | [diff] [blame] | 403 | return (TheISA::IntReg)-EFAULT; |
| 404 | |
| 405 | // Adjust path for current working directory |
| 406 | path = p->fullPath(path); |
| 407 | |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 408 | mode_t mode = p->getSyscallArg(tc, index); |
Michael Adler | 2cd04fd | 2008-07-23 14:41:33 -0700 | [diff] [blame] | 409 | |
| 410 | int result = mkdir(path.c_str(), mode); |
| 411 | return (result == -1) ? -errno : result; |
| 412 | } |
| 413 | |
Ali Saidi | 232134a | 2005-03-09 15:52:10 -0500 | [diff] [blame] | 414 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 415 | renameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) |
David Oehmke | 95c248c | 2004-02-05 12:16:17 -0500 | [diff] [blame] | 416 | { |
Steve Reinhardt | 22eccce | 2005-06-03 16:19:34 -0400 | [diff] [blame] | 417 | string old_name; |
David Oehmke | 95c248c | 2004-02-05 12:16:17 -0500 | [diff] [blame] | 418 | |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 419 | int index = 0; |
Andreas Hansson | 9e3c8de | 2012-02-24 11:45:30 -0500 | [diff] [blame^] | 420 | if (!tc->getMemProxy().tryReadString(old_name, p->getSyscallArg(tc, index))) |
Ali Saidi | ad9b28f | 2005-03-10 14:20:12 -0500 | [diff] [blame] | 421 | return -EFAULT; |
David Oehmke | 95c248c | 2004-02-05 12:16:17 -0500 | [diff] [blame] | 422 | |
Steve Reinhardt | 22eccce | 2005-06-03 16:19:34 -0400 | [diff] [blame] | 423 | string new_name; |
David Oehmke | 95c248c | 2004-02-05 12:16:17 -0500 | [diff] [blame] | 424 | |
Andreas Hansson | 9e3c8de | 2012-02-24 11:45:30 -0500 | [diff] [blame^] | 425 | if (!tc->getMemProxy().tryReadString(new_name, p->getSyscallArg(tc, index))) |
Ali Saidi | ad9b28f | 2005-03-10 14:20:12 -0500 | [diff] [blame] | 426 | return -EFAULT; |
David Oehmke | 95c248c | 2004-02-05 12:16:17 -0500 | [diff] [blame] | 427 | |
Nathan Binkert | 31d829d | 2006-11-16 12:43:11 -0800 | [diff] [blame] | 428 | // Adjust path for current working directory |
| 429 | old_name = p->fullPath(old_name); |
| 430 | new_name = p->fullPath(new_name); |
| 431 | |
Steve Reinhardt | 22eccce | 2005-06-03 16:19:34 -0400 | [diff] [blame] | 432 | int64_t result = rename(old_name.c_str(), new_name.c_str()); |
Ali Saidi | ad9b28f | 2005-03-10 14:20:12 -0500 | [diff] [blame] | 433 | return (result == -1) ? -errno : result; |
David Oehmke | 95c248c | 2004-02-05 12:16:17 -0500 | [diff] [blame] | 434 | } |
Steve Reinhardt | 7976794 | 2003-12-01 19:34:38 -0800 | [diff] [blame] | 435 | |
Steve Reinhardt | 22eccce | 2005-06-03 16:19:34 -0400 | [diff] [blame] | 436 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 437 | truncateFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) |
Steve Reinhardt | 22eccce | 2005-06-03 16:19:34 -0400 | [diff] [blame] | 438 | { |
| 439 | string path; |
| 440 | |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 441 | int index = 0; |
Andreas Hansson | 9e3c8de | 2012-02-24 11:45:30 -0500 | [diff] [blame^] | 442 | if (!tc->getMemProxy().tryReadString(path, p->getSyscallArg(tc, index))) |
Steve Reinhardt | 22eccce | 2005-06-03 16:19:34 -0400 | [diff] [blame] | 443 | return -EFAULT; |
| 444 | |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 445 | off_t length = p->getSyscallArg(tc, index); |
Steve Reinhardt | 22eccce | 2005-06-03 16:19:34 -0400 | [diff] [blame] | 446 | |
Nathan Binkert | 31d829d | 2006-11-16 12:43:11 -0800 | [diff] [blame] | 447 | // Adjust path for current working directory |
| 448 | path = p->fullPath(path); |
| 449 | |
Steve Reinhardt | 22eccce | 2005-06-03 16:19:34 -0400 | [diff] [blame] | 450 | int result = truncate(path.c_str(), length); |
| 451 | return (result == -1) ? -errno : result; |
| 452 | } |
| 453 | |
| 454 | SyscallReturn |
Steve Reinhardt | 03b3925 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 455 | ftruncateFunc(SyscallDesc *desc, int num, |
| 456 | LiveProcess *process, ThreadContext *tc) |
Steve Reinhardt | 22eccce | 2005-06-03 16:19:34 -0400 | [diff] [blame] | 457 | { |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 458 | int index = 0; |
| 459 | int fd = process->sim_fd(process->getSyscallArg(tc, index)); |
Steve Reinhardt | 22eccce | 2005-06-03 16:19:34 -0400 | [diff] [blame] | 460 | |
| 461 | if (fd < 0) |
| 462 | return -EBADF; |
| 463 | |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 464 | off_t length = process->getSyscallArg(tc, index); |
Steve Reinhardt | 22eccce | 2005-06-03 16:19:34 -0400 | [diff] [blame] | 465 | |
| 466 | int result = ftruncate(fd, length); |
| 467 | return (result == -1) ? -errno : result; |
| 468 | } |
Kevin Lim | 6da93ea | 2005-11-22 12:08:08 -0500 | [diff] [blame] | 469 | |
| 470 | SyscallReturn |
Vince Weaver | 9ad3aca | 2009-10-30 12:31:55 -0400 | [diff] [blame] | 471 | truncate64Func(SyscallDesc *desc, int num, |
| 472 | LiveProcess *process, ThreadContext *tc) |
| 473 | { |
| 474 | int index = 0; |
| 475 | string path; |
| 476 | |
Andreas Hansson | 9e3c8de | 2012-02-24 11:45:30 -0500 | [diff] [blame^] | 477 | if (!tc->getMemProxy().tryReadString(path, process->getSyscallArg(tc, index))) |
Vince Weaver | 9ad3aca | 2009-10-30 12:31:55 -0400 | [diff] [blame] | 478 | return -EFAULT; |
| 479 | |
Ali Saidi | 4e9ce18 | 2009-11-14 11:49:01 -0600 | [diff] [blame] | 480 | int64_t length = process->getSyscallArg(tc, index, 64); |
Vince Weaver | 9ad3aca | 2009-10-30 12:31:55 -0400 | [diff] [blame] | 481 | |
| 482 | // Adjust path for current working directory |
| 483 | path = process->fullPath(path); |
| 484 | |
Ali Saidi | 4e9ce18 | 2009-11-14 11:49:01 -0600 | [diff] [blame] | 485 | #if NO_STAT64 |
| 486 | int result = truncate(path.c_str(), length); |
| 487 | #else |
Vince Weaver | 9ad3aca | 2009-10-30 12:31:55 -0400 | [diff] [blame] | 488 | int result = truncate64(path.c_str(), length); |
Ali Saidi | 4e9ce18 | 2009-11-14 11:49:01 -0600 | [diff] [blame] | 489 | #endif |
Vince Weaver | 9ad3aca | 2009-10-30 12:31:55 -0400 | [diff] [blame] | 490 | return (result == -1) ? -errno : result; |
| 491 | } |
| 492 | |
| 493 | SyscallReturn |
Timothy M. Jones | c32d919 | 2009-10-24 10:53:58 -0700 | [diff] [blame] | 494 | ftruncate64Func(SyscallDesc *desc, int num, |
| 495 | LiveProcess *process, ThreadContext *tc) |
| 496 | { |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 497 | int index = 0; |
| 498 | int fd = process->sim_fd(process->getSyscallArg(tc, index)); |
Timothy M. Jones | c32d919 | 2009-10-24 10:53:58 -0700 | [diff] [blame] | 499 | |
| 500 | if (fd < 0) |
| 501 | return -EBADF; |
| 502 | |
Ali Saidi | 4e9ce18 | 2009-11-14 11:49:01 -0600 | [diff] [blame] | 503 | int64_t length = process->getSyscallArg(tc, index, 64); |
Timothy M. Jones | c32d919 | 2009-10-24 10:53:58 -0700 | [diff] [blame] | 504 | |
Ali Saidi | 4e9ce18 | 2009-11-14 11:49:01 -0600 | [diff] [blame] | 505 | #if NO_STAT64 |
| 506 | int result = ftruncate(fd, length); |
| 507 | #else |
Timothy M. Jones | c32d919 | 2009-10-24 10:53:58 -0700 | [diff] [blame] | 508 | int result = ftruncate64(fd, length); |
Ali Saidi | 4e9ce18 | 2009-11-14 11:49:01 -0600 | [diff] [blame] | 509 | #endif |
Timothy M. Jones | c32d919 | 2009-10-24 10:53:58 -0700 | [diff] [blame] | 510 | return (result == -1) ? -errno : result; |
| 511 | } |
| 512 | |
| 513 | SyscallReturn |
Michael Adler | 2cd04fd | 2008-07-23 14:41:33 -0700 | [diff] [blame] | 514 | umaskFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) |
| 515 | { |
| 516 | // Letting the simulated program change the simulator's umask seems like |
| 517 | // a bad idea. Compromise by just returning the current umask but not |
| 518 | // changing anything. |
| 519 | mode_t oldMask = umask(0); |
| 520 | umask(oldMask); |
Nathan Binkert | 678abbc | 2008-08-03 18:19:53 -0700 | [diff] [blame] | 521 | return (int)oldMask; |
Michael Adler | 2cd04fd | 2008-07-23 14:41:33 -0700 | [diff] [blame] | 522 | } |
| 523 | |
| 524 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 525 | chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) |
Kevin Lim | 6da93ea | 2005-11-22 12:08:08 -0500 | [diff] [blame] | 526 | { |
| 527 | string path; |
| 528 | |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 529 | int index = 0; |
Andreas Hansson | 9e3c8de | 2012-02-24 11:45:30 -0500 | [diff] [blame^] | 530 | if (!tc->getMemProxy().tryReadString(path, p->getSyscallArg(tc, index))) |
Kevin Lim | 6da93ea | 2005-11-22 12:08:08 -0500 | [diff] [blame] | 531 | return -EFAULT; |
| 532 | |
| 533 | /* XXX endianess */ |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 534 | uint32_t owner = p->getSyscallArg(tc, index); |
Kevin Lim | 6da93ea | 2005-11-22 12:08:08 -0500 | [diff] [blame] | 535 | uid_t hostOwner = owner; |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 536 | uint32_t group = p->getSyscallArg(tc, index); |
Kevin Lim | 6da93ea | 2005-11-22 12:08:08 -0500 | [diff] [blame] | 537 | gid_t hostGroup = group; |
| 538 | |
Nathan Binkert | 31d829d | 2006-11-16 12:43:11 -0800 | [diff] [blame] | 539 | // Adjust path for current working directory |
| 540 | path = p->fullPath(path); |
| 541 | |
Kevin Lim | 6da93ea | 2005-11-22 12:08:08 -0500 | [diff] [blame] | 542 | int result = chown(path.c_str(), hostOwner, hostGroup); |
| 543 | return (result == -1) ? -errno : result; |
| 544 | } |
| 545 | |
| 546 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 547 | fchownFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) |
Kevin Lim | 6da93ea | 2005-11-22 12:08:08 -0500 | [diff] [blame] | 548 | { |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 549 | int index = 0; |
| 550 | int fd = process->sim_fd(process->getSyscallArg(tc, index)); |
Kevin Lim | 6da93ea | 2005-11-22 12:08:08 -0500 | [diff] [blame] | 551 | |
| 552 | if (fd < 0) |
| 553 | return -EBADF; |
| 554 | |
| 555 | /* XXX endianess */ |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 556 | uint32_t owner = process->getSyscallArg(tc, index); |
Kevin Lim | 6da93ea | 2005-11-22 12:08:08 -0500 | [diff] [blame] | 557 | uid_t hostOwner = owner; |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 558 | uint32_t group = process->getSyscallArg(tc, index); |
Kevin Lim | 6da93ea | 2005-11-22 12:08:08 -0500 | [diff] [blame] | 559 | gid_t hostGroup = group; |
| 560 | |
| 561 | int result = fchown(fd, hostOwner, hostGroup); |
| 562 | return (result == -1) ? -errno : result; |
| 563 | } |
Ali Saidi | 53d2c93 | 2006-02-18 23:44:22 -0500 | [diff] [blame] | 564 | |
| 565 | |
| 566 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 567 | dupFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) |
Steve Reinhardt | c538436 | 2006-08-28 07:39:56 -0700 | [diff] [blame] | 568 | { |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 569 | int index = 0; |
| 570 | int fd = process->sim_fd(process->getSyscallArg(tc, index)); |
Steve Reinhardt | c538436 | 2006-08-28 07:39:56 -0700 | [diff] [blame] | 571 | if (fd < 0) |
| 572 | return -EBADF; |
| 573 | |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 574 | Process::FdMap *fdo = process->sim_fd_obj(fd); |
Rick Strong | 376c728 | 2007-11-29 00:22:46 -0500 | [diff] [blame] | 575 | |
Steve Reinhardt | c538436 | 2006-08-28 07:39:56 -0700 | [diff] [blame] | 576 | int result = dup(fd); |
Steve Reinhardt | 03b3925 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 577 | return (result == -1) ? -errno : |
| 578 | process->alloc_fd(result, fdo->filename, fdo->flags, fdo->mode, false); |
Steve Reinhardt | c538436 | 2006-08-28 07:39:56 -0700 | [diff] [blame] | 579 | } |
| 580 | |
| 581 | |
| 582 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 583 | fcntlFunc(SyscallDesc *desc, int num, LiveProcess *process, |
Kevin Lim | eb0e416 | 2006-06-06 17:32:21 -0400 | [diff] [blame] | 584 | ThreadContext *tc) |
Ali Saidi | 53d2c93 | 2006-02-18 23:44:22 -0500 | [diff] [blame] | 585 | { |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 586 | int index = 0; |
| 587 | int fd = process->getSyscallArg(tc, index); |
Ali Saidi | 53d2c93 | 2006-02-18 23:44:22 -0500 | [diff] [blame] | 588 | |
| 589 | if (fd < 0 || process->sim_fd(fd) < 0) |
| 590 | return -EBADF; |
| 591 | |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 592 | int cmd = process->getSyscallArg(tc, index); |
Ali Saidi | 53d2c93 | 2006-02-18 23:44:22 -0500 | [diff] [blame] | 593 | switch (cmd) { |
| 594 | case 0: // F_DUPFD |
| 595 | // if we really wanted to support this, we'd need to do it |
| 596 | // in the target fd space. |
| 597 | warn("fcntl(%d, F_DUPFD) not supported, error returned\n", fd); |
| 598 | return -EMFILE; |
| 599 | |
| 600 | case 1: // F_GETFD (get close-on-exec flag) |
| 601 | case 2: // F_SETFD (set close-on-exec flag) |
| 602 | return 0; |
| 603 | |
| 604 | case 3: // F_GETFL (get file flags) |
| 605 | case 4: // F_SETFL (set file flags) |
| 606 | // not sure if this is totally valid, but we'll pass it through |
| 607 | // to the underlying OS |
| 608 | warn("fcntl(%d, %d) passed through to host\n", fd, cmd); |
| 609 | return fcntl(process->sim_fd(fd), cmd); |
| 610 | // return 0; |
| 611 | |
| 612 | case 7: // F_GETLK (get lock) |
| 613 | case 8: // F_SETLK (set lock) |
| 614 | case 9: // F_SETLKW (set lock and wait) |
| 615 | // don't mess with file locking... just act like it's OK |
| 616 | warn("File lock call (fcntl(%d, %d)) ignored.\n", fd, cmd); |
| 617 | return 0; |
| 618 | |
| 619 | default: |
| 620 | warn("Unknown fcntl command %d\n", cmd); |
| 621 | return 0; |
| 622 | } |
| 623 | } |
| 624 | |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 625 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 626 | fcntl64Func(SyscallDesc *desc, int num, LiveProcess *process, |
Korey Sewell | 4cc31e1 | 2006-06-09 17:07:13 -0400 | [diff] [blame] | 627 | ThreadContext *tc) |
| 628 | { |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 629 | int index = 0; |
| 630 | int fd = process->getSyscallArg(tc, index); |
Korey Sewell | 4cc31e1 | 2006-06-09 17:07:13 -0400 | [diff] [blame] | 631 | |
| 632 | if (fd < 0 || process->sim_fd(fd) < 0) |
| 633 | return -EBADF; |
| 634 | |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 635 | int cmd = process->getSyscallArg(tc, index); |
Korey Sewell | 4cc31e1 | 2006-06-09 17:07:13 -0400 | [diff] [blame] | 636 | switch (cmd) { |
| 637 | case 33: //F_GETLK64 |
| 638 | warn("fcntl64(%d, F_GETLK64) not supported, error returned\n", fd); |
| 639 | return -EMFILE; |
| 640 | |
| 641 | case 34: // F_SETLK64 |
| 642 | case 35: // F_SETLKW64 |
| 643 | warn("fcntl64(%d, F_SETLK(W)64) not supported, error returned\n", fd); |
| 644 | return -EMFILE; |
| 645 | |
| 646 | default: |
| 647 | // not sure if this is totally valid, but we'll pass it through |
| 648 | // to the underlying OS |
| 649 | warn("fcntl64(%d, %d) passed through to host\n", fd, cmd); |
| 650 | return fcntl(process->sim_fd(fd), cmd); |
| 651 | // return 0; |
| 652 | } |
| 653 | } |
| 654 | |
| 655 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 656 | pipePseudoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, |
Kevin Lim | eb0e416 | 2006-06-06 17:32:21 -0400 | [diff] [blame] | 657 | ThreadContext *tc) |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 658 | { |
| 659 | int fds[2], sim_fds[2]; |
| 660 | int pipe_retval = pipe(fds); |
| 661 | |
| 662 | if (pipe_retval < 0) { |
| 663 | // error |
| 664 | return pipe_retval; |
| 665 | } |
| 666 | |
Rick Strong | 376c728 | 2007-11-29 00:22:46 -0500 | [diff] [blame] | 667 | sim_fds[0] = process->alloc_fd(fds[0], "PIPE-READ", O_WRONLY, -1, true); |
| 668 | sim_fds[1] = process->alloc_fd(fds[1], "PIPE-WRITE", O_RDONLY, -1, true); |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 669 | |
Rick Strong | 376c728 | 2007-11-29 00:22:46 -0500 | [diff] [blame] | 670 | process->setReadPipeSource(sim_fds[0], sim_fds[1]); |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 671 | // Alpha Linux convention for pipe() is that fd[0] is returned as |
| 672 | // the return value of the function, and fd[1] is returned in r20. |
Kevin Lim | eb0e416 | 2006-06-06 17:32:21 -0400 | [diff] [blame] | 673 | tc->setIntReg(SyscallPseudoReturnReg, sim_fds[1]); |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 674 | return sim_fds[0]; |
| 675 | } |
| 676 | |
| 677 | |
| 678 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 679 | getpidPseudoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, |
Kevin Lim | eb0e416 | 2006-06-06 17:32:21 -0400 | [diff] [blame] | 680 | ThreadContext *tc) |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 681 | { |
| 682 | // Make up a PID. There's no interprocess communication in |
| 683 | // fake_syscall mode, so there's no way for a process to know it's |
| 684 | // not getting a unique value. |
| 685 | |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 686 | tc->setIntReg(SyscallPseudoReturnReg, process->ppid()); |
| 687 | return process->pid(); |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 688 | } |
| 689 | |
| 690 | |
| 691 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 692 | getuidPseudoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, |
Kevin Lim | eb0e416 | 2006-06-06 17:32:21 -0400 | [diff] [blame] | 693 | ThreadContext *tc) |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 694 | { |
| 695 | // Make up a UID and EUID... it shouldn't matter, and we want the |
| 696 | // simulation to be deterministic. |
| 697 | |
| 698 | // EUID goes in r20. |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 699 | tc->setIntReg(SyscallPseudoReturnReg, process->euid()); //EUID |
Ali Saidi | 3a3e356 | 2008-09-10 14:26:15 -0400 | [diff] [blame] | 700 | return process->uid(); // UID |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 701 | } |
| 702 | |
| 703 | |
| 704 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 705 | getgidPseudoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, |
Kevin Lim | eb0e416 | 2006-06-06 17:32:21 -0400 | [diff] [blame] | 706 | ThreadContext *tc) |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 707 | { |
| 708 | // Get current group ID. EGID goes in r20. |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 709 | tc->setIntReg(SyscallPseudoReturnReg, process->egid()); //EGID |
| 710 | return process->gid(); |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 711 | } |
| 712 | |
| 713 | |
| 714 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 715 | setuidFunc(SyscallDesc *desc, int callnum, LiveProcess *process, |
Kevin Lim | eb0e416 | 2006-06-06 17:32:21 -0400 | [diff] [blame] | 716 | ThreadContext *tc) |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 717 | { |
| 718 | // can't fathom why a benchmark would call this. |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 719 | int index = 0; |
| 720 | warn("Ignoring call to setuid(%d)\n", process->getSyscallArg(tc, index)); |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 721 | return 0; |
| 722 | } |
| 723 | |
| 724 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 725 | getpidFunc(SyscallDesc *desc, int callnum, LiveProcess *process, |
Kevin Lim | eb0e416 | 2006-06-06 17:32:21 -0400 | [diff] [blame] | 726 | ThreadContext *tc) |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 727 | { |
| 728 | // Make up a PID. There's no interprocess communication in |
| 729 | // fake_syscall mode, so there's no way for a process to know it's |
| 730 | // not getting a unique value. |
| 731 | |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 732 | tc->setIntReg(SyscallPseudoReturnReg, process->ppid()); //PID |
| 733 | return process->pid(); |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 734 | } |
| 735 | |
| 736 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 737 | getppidFunc(SyscallDesc *desc, int callnum, LiveProcess *process, |
Kevin Lim | eb0e416 | 2006-06-06 17:32:21 -0400 | [diff] [blame] | 738 | ThreadContext *tc) |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 739 | { |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 740 | return process->ppid(); |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 741 | } |
| 742 | |
| 743 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 744 | getuidFunc(SyscallDesc *desc, int callnum, LiveProcess *process, |
Kevin Lim | eb0e416 | 2006-06-06 17:32:21 -0400 | [diff] [blame] | 745 | ThreadContext *tc) |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 746 | { |
Ali Saidi | 3a3e356 | 2008-09-10 14:26:15 -0400 | [diff] [blame] | 747 | return process->uid(); // UID |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 748 | } |
| 749 | |
| 750 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 751 | geteuidFunc(SyscallDesc *desc, int callnum, LiveProcess *process, |
Kevin Lim | eb0e416 | 2006-06-06 17:32:21 -0400 | [diff] [blame] | 752 | ThreadContext *tc) |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 753 | { |
Ali Saidi | 3a3e356 | 2008-09-10 14:26:15 -0400 | [diff] [blame] | 754 | return process->euid(); // UID |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 755 | } |
| 756 | |
| 757 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 758 | getgidFunc(SyscallDesc *desc, int callnum, LiveProcess *process, |
Kevin Lim | eb0e416 | 2006-06-06 17:32:21 -0400 | [diff] [blame] | 759 | ThreadContext *tc) |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 760 | { |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 761 | return process->gid(); |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 762 | } |
| 763 | |
| 764 | SyscallReturn |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 765 | getegidFunc(SyscallDesc *desc, int callnum, LiveProcess *process, |
Kevin Lim | eb0e416 | 2006-06-06 17:32:21 -0400 | [diff] [blame] | 766 | ThreadContext *tc) |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 767 | { |
Gabe Black | 30b87e9 | 2006-09-17 03:00:55 -0400 | [diff] [blame] | 768 | return process->egid(); |
Ali Saidi | ce3a634 | 2006-03-09 15:42:09 -0500 | [diff] [blame] | 769 | } |
| 770 | |
Ali Saidi | 53d2c93 | 2006-02-18 23:44:22 -0500 | [diff] [blame] | 771 | |
Daniel Sanchez | b0e9654 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 772 | SyscallReturn |
| 773 | cloneFunc(SyscallDesc *desc, int callnum, LiveProcess *process, |
| 774 | ThreadContext *tc) |
| 775 | { |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 776 | int index = 0; |
| 777 | IntReg flags = process->getSyscallArg(tc, index); |
| 778 | IntReg newStack = process->getSyscallArg(tc, index); |
| 779 | |
Daniel Sanchez | b0e9654 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 780 | DPRINTF(SyscallVerbose, "In sys_clone:\n"); |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 781 | DPRINTF(SyscallVerbose, " Flags=%llx\n", flags); |
| 782 | DPRINTF(SyscallVerbose, " Child stack=%llx\n", newStack); |
Daniel Sanchez | b0e9654 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 783 | |
| 784 | |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 785 | if (flags != 0x10f00) { |
Steve Reinhardt | 03b3925 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 786 | warn("This sys_clone implementation assumes flags " |
| 787 | "CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD " |
| 788 | "(0x10f00), and may not work correctly with given flags " |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 789 | "0x%llx\n", flags); |
Daniel Sanchez | b0e9654 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 790 | } |
| 791 | |
Steve Reinhardt | 03b3925 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 792 | ThreadContext* ctc; // child thread context |
Daniel Sanchez | b0e9654 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 793 | if ( ( ctc = process->findFreeContext() ) != NULL ) { |
| 794 | DPRINTF(SyscallVerbose, " Found unallocated thread context\n"); |
| 795 | |
| 796 | ctc->clearArchRegs(); |
| 797 | |
Steve Reinhardt | 03b3925 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 798 | // Arch-specific cloning code |
Daniel Sanchez | b0e9654 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 799 | #if THE_ISA == ALPHA_ISA or THE_ISA == X86_ISA |
Steve Reinhardt | 03b3925 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 800 | // Cloning the misc. regs for these archs is enough |
Daniel Sanchez | b0e9654 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 801 | TheISA::copyMiscRegs(tc, ctc); |
| 802 | #elif THE_ISA == SPARC_ISA |
| 803 | TheISA::copyRegs(tc, ctc); |
| 804 | |
Steve Reinhardt | 03b3925 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 805 | // TODO: Explain what this code actually does :-) |
Daniel Sanchez | b0e9654 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 806 | ctc->setIntReg(NumIntArchRegs + 6, 0); |
| 807 | ctc->setIntReg(NumIntArchRegs + 4, 0); |
| 808 | ctc->setIntReg(NumIntArchRegs + 3, NWindows - 2); |
| 809 | ctc->setIntReg(NumIntArchRegs + 5, NWindows); |
Gabe Black | 64fe7af | 2009-07-10 01:01:47 -0700 | [diff] [blame] | 810 | ctc->setMiscReg(MISCREG_CWP, 0); |
Daniel Sanchez | b0e9654 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 811 | ctc->setIntReg(NumIntArchRegs + 7, 0); |
| 812 | ctc->setMiscRegNoEffect(MISCREG_TL, 0); |
| 813 | ctc->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY); |
| 814 | |
| 815 | for (int y = 8; y < 32; y++) |
| 816 | ctc->setIntReg(y, tc->readIntReg(y)); |
Chris Emmons | ccaaa98 | 2011-03-17 19:20:20 -0500 | [diff] [blame] | 817 | #elif THE_ISA == ARM_ISA |
| 818 | TheISA::copyRegs(tc, ctc); |
Daniel Sanchez | b0e9654 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 819 | #else |
| 820 | fatal("sys_clone is not implemented for this ISA\n"); |
| 821 | #endif |
| 822 | |
Steve Reinhardt | 03b3925 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 823 | // Set up stack register |
Gabe Black | 3f722b9 | 2009-10-30 00:44:55 -0700 | [diff] [blame] | 824 | ctc->setIntReg(TheISA::StackPointerReg, newStack); |
Daniel Sanchez | b0e9654 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 825 | |
Steve Reinhardt | 03b3925 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 826 | // Set up syscall return values in parent and child |
| 827 | ctc->setIntReg(ReturnValueReg, 0); // return value, child |
Daniel Sanchez | b0e9654 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 828 | |
Steve Reinhardt | 03b3925 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 829 | // Alpha needs SyscallSuccessReg=0 in child |
Daniel Sanchez | b0e9654 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 830 | #if THE_ISA == ALPHA_ISA |
Steve Reinhardt | 52b6764 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 831 | ctc->setIntReg(TheISA::SyscallSuccessReg, 0); |
Daniel Sanchez | b0e9654 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 832 | #endif |
| 833 | |
Steve Reinhardt | 03b3925 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 834 | // In SPARC/Linux, clone returns 0 on pseudo-return register if |
| 835 | // parent, non-zero if child |
Daniel Sanchez | b0e9654 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 836 | #if THE_ISA == SPARC_ISA |
| 837 | tc->setIntReg(TheISA::SyscallPseudoReturnReg, 0); |
| 838 | ctc->setIntReg(TheISA::SyscallPseudoReturnReg, 1); |
| 839 | #endif |
| 840 | |
Gabe Black | 6f4bd2c | 2010-10-31 00:07:20 -0700 | [diff] [blame] | 841 | ctc->pcState(tc->nextInstAddr()); |
Daniel Sanchez | b0e9654 | 2009-04-21 08:17:36 -0700 | [diff] [blame] | 842 | |
| 843 | ctc->activate(); |
| 844 | |
| 845 | // Should return nonzero child TID in parent's syscall return register, |
| 846 | // but for our pthread library any non-zero value will work |
| 847 | return 1; |
| 848 | } else { |
| 849 | fatal("Called sys_clone, but no unallocated thread contexts found!\n"); |
| 850 | return 0; |
| 851 | } |
| 852 | } |
| 853 | |