31 */ 32 33#include <fcntl.h> 34#include <unistd.h> 35 36#include <string> 37#include <iostream> 38 39#include "sim/syscall_emul.hh" 40#include "base/chunk_generator.hh" 41#include "base/trace.hh" 42#include "cpu/thread_context.hh" 43#include "cpu/base.hh" 44#include "mem/page_table.hh" 45#include "sim/process.hh" 46 47#include "sim/sim_exit.hh" 48 49using namespace std; 50using namespace TheISA; 51 52void 53SyscallDesc::doSyscall(int callnum, Process *process, ThreadContext *tc) 54{ 55 DPRINTFR(SyscallVerbose, "%d: %s: syscall %s called w/arguments %d,%d,%d,%d\n", 56 curTick,tc->getCpuPtr()->name(), name, 57 tc->getSyscallArg(0),tc->getSyscallArg(1), 58 tc->getSyscallArg(2),tc->getSyscallArg(3)); 59 60 SyscallReturn retval = (*funcPtr)(this, callnum, process, tc); 61 62 DPRINTFR(SyscallVerbose, "%d: %s: syscall %s returns %d\n", 63 curTick,tc->getCpuPtr()->name(), name, retval.value()); 64 65 if (!(flags & SyscallDesc::SuppressReturnValue)) 66 tc->setSyscallReturn(retval); 67} 68 69 70SyscallReturn 71unimplementedFunc(SyscallDesc *desc, int callnum, Process *process, 72 ThreadContext *tc) 73{ 74 fatal("syscall %s (#%d) unimplemented.", desc->name, callnum); 75 76 return 1; 77} 78 79 80SyscallReturn 81ignoreFunc(SyscallDesc *desc, int callnum, Process *process, 82 ThreadContext *tc) 83{ 84 warn("ignoring syscall %s(%d, %d, ...)", desc->name, 85 tc->getSyscallArg(0), tc->getSyscallArg(1)); 86 87 return 0; 88} 89 90 91SyscallReturn 92exitFunc(SyscallDesc *desc, int callnum, Process *process, 93 ThreadContext *tc) 94{
| 30 */ 31 32#include <fcntl.h> 33#include <unistd.h> 34 35#include <string> 36#include <iostream> 37 38#include "sim/syscall_emul.hh" 39#include "base/chunk_generator.hh" 40#include "base/trace.hh" 41#include "cpu/thread_context.hh" 42#include "cpu/base.hh" 43#include "mem/page_table.hh" 44#include "sim/process.hh" 45 46#include "sim/sim_exit.hh" 47 48using namespace std; 49using namespace TheISA; 50 51void 52SyscallDesc::doSyscall(int callnum, Process *process, ThreadContext *tc) 53{ 54 DPRINTFR(SyscallVerbose, "%d: %s: syscall %s called w/arguments %d,%d,%d,%d\n", 55 curTick,tc->getCpuPtr()->name(), name, 56 tc->getSyscallArg(0),tc->getSyscallArg(1), 57 tc->getSyscallArg(2),tc->getSyscallArg(3)); 58 59 SyscallReturn retval = (*funcPtr)(this, callnum, process, tc); 60 61 DPRINTFR(SyscallVerbose, "%d: %s: syscall %s returns %d\n", 62 curTick,tc->getCpuPtr()->name(), name, retval.value()); 63 64 if (!(flags & SyscallDesc::SuppressReturnValue)) 65 tc->setSyscallReturn(retval); 66} 67 68 69SyscallReturn 70unimplementedFunc(SyscallDesc *desc, int callnum, Process *process, 71 ThreadContext *tc) 72{ 73 fatal("syscall %s (#%d) unimplemented.", desc->name, callnum); 74 75 return 1; 76} 77 78 79SyscallReturn 80ignoreFunc(SyscallDesc *desc, int callnum, Process *process, 81 ThreadContext *tc) 82{ 83 warn("ignoring syscall %s(%d, %d, ...)", desc->name, 84 tc->getSyscallArg(0), tc->getSyscallArg(1)); 85 86 return 0; 87} 88 89 90SyscallReturn 91exitFunc(SyscallDesc *desc, int callnum, Process *process, 92 ThreadContext *tc) 93{
|
96 97 return 1; 98} 99 100 101SyscallReturn 102getpagesizeFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 103{ 104 return (int)VMPageSize; 105} 106 107 108SyscallReturn 109obreakFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 110{ 111 Addr junk; 112 113 // change brk addr to first arg 114 Addr new_brk = tc->getSyscallArg(0); 115 if (new_brk != 0) { 116 for (ChunkGenerator gen(p->brk_point, new_brk - p->brk_point, 117 VMPageSize); !gen.done(); gen.next()) { 118 if (!p->pTable->translate(gen.addr(), junk)) 119 p->pTable->allocate(roundDown(gen.addr(), VMPageSize), 120 VMPageSize); 121 } 122 p->brk_point = new_brk; 123 } 124 DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point); 125 return p->brk_point; 126} 127 128 129SyscallReturn 130closeFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 131{ 132 int target_fd = tc->getSyscallArg(0); 133 int status = close(p->sim_fd(target_fd)); 134 if (status >= 0) 135 p->free_fd(target_fd); 136 return status; 137} 138 139 140SyscallReturn 141readFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 142{ 143 int fd = p->sim_fd(tc->getSyscallArg(0)); 144 int nbytes = tc->getSyscallArg(2); 145 BufferArg bufArg(tc->getSyscallArg(1), nbytes); 146 147 int bytes_read = read(fd, bufArg.bufferPtr(), nbytes); 148 149 if (bytes_read != -1) 150 bufArg.copyOut(tc->getMemPort()); 151 152 return bytes_read; 153} 154 155SyscallReturn 156writeFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 157{ 158 int fd = p->sim_fd(tc->getSyscallArg(0)); 159 int nbytes = tc->getSyscallArg(2); 160 BufferArg bufArg(tc->getSyscallArg(1), nbytes); 161 162 bufArg.copyIn(tc->getMemPort()); 163 164 int bytes_written = write(fd, bufArg.bufferPtr(), nbytes); 165 166 fsync(fd); 167 168 return bytes_written; 169} 170 171 172SyscallReturn 173lseekFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 174{ 175 int fd = p->sim_fd(tc->getSyscallArg(0)); 176 uint64_t offs = tc->getSyscallArg(1); 177 int whence = tc->getSyscallArg(2); 178 179 off_t result = lseek(fd, offs, whence); 180 181 return (result == (off_t)-1) ? -errno : result; 182} 183 184 185SyscallReturn 186munmapFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 187{ 188 // given that we don't really implement mmap, munmap is really easy 189 return 0; 190} 191 192 193const char *hostname = "m5.eecs.umich.edu"; 194 195SyscallReturn 196gethostnameFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 197{ 198 int name_len = tc->getSyscallArg(1); 199 BufferArg name(tc->getSyscallArg(0), name_len); 200 201 strncpy((char *)name.bufferPtr(), hostname, name_len); 202 203 name.copyOut(tc->getMemPort()); 204 205 return 0; 206} 207 208SyscallReturn 209unlinkFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 210{ 211 string path; 212 213 if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) 214 return (TheISA::IntReg)-EFAULT; 215 216 int result = unlink(path.c_str()); 217 return (result == -1) ? -errno : result; 218} 219 220SyscallReturn 221renameFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 222{ 223 string old_name; 224 225 if (!tc->getMemPort()->tryReadString(old_name, tc->getSyscallArg(0))) 226 return -EFAULT; 227 228 string new_name; 229 230 if (!tc->getMemPort()->tryReadString(new_name, tc->getSyscallArg(1))) 231 return -EFAULT; 232 233 int64_t result = rename(old_name.c_str(), new_name.c_str()); 234 return (result == -1) ? -errno : result; 235} 236 237SyscallReturn 238truncateFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 239{ 240 string path; 241 242 if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) 243 return -EFAULT; 244 245 off_t length = tc->getSyscallArg(1); 246 247 int result = truncate(path.c_str(), length); 248 return (result == -1) ? -errno : result; 249} 250 251SyscallReturn 252ftruncateFunc(SyscallDesc *desc, int num, Process *process, ThreadContext *tc) 253{ 254 int fd = process->sim_fd(tc->getSyscallArg(0)); 255 256 if (fd < 0) 257 return -EBADF; 258 259 off_t length = tc->getSyscallArg(1); 260 261 int result = ftruncate(fd, length); 262 return (result == -1) ? -errno : result; 263} 264 265SyscallReturn 266chownFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 267{ 268 string path; 269 270 if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) 271 return -EFAULT; 272 273 /* XXX endianess */ 274 uint32_t owner = tc->getSyscallArg(1); 275 uid_t hostOwner = owner; 276 uint32_t group = tc->getSyscallArg(2); 277 gid_t hostGroup = group; 278 279 int result = chown(path.c_str(), hostOwner, hostGroup); 280 return (result == -1) ? -errno : result; 281} 282 283SyscallReturn 284fchownFunc(SyscallDesc *desc, int num, Process *process, ThreadContext *tc) 285{ 286 int fd = process->sim_fd(tc->getSyscallArg(0)); 287 288 if (fd < 0) 289 return -EBADF; 290 291 /* XXX endianess */ 292 uint32_t owner = tc->getSyscallArg(1); 293 uid_t hostOwner = owner; 294 uint32_t group = tc->getSyscallArg(2); 295 gid_t hostGroup = group; 296 297 int result = fchown(fd, hostOwner, hostGroup); 298 return (result == -1) ? -errno : result; 299} 300 301 302SyscallReturn 303fcntlFunc(SyscallDesc *desc, int num, Process *process, 304 ThreadContext *tc) 305{ 306 int fd = tc->getSyscallArg(0); 307 308 if (fd < 0 || process->sim_fd(fd) < 0) 309 return -EBADF; 310 311 int cmd = tc->getSyscallArg(1); 312 switch (cmd) { 313 case 0: // F_DUPFD 314 // if we really wanted to support this, we'd need to do it 315 // in the target fd space. 316 warn("fcntl(%d, F_DUPFD) not supported, error returned\n", fd); 317 return -EMFILE; 318 319 case 1: // F_GETFD (get close-on-exec flag) 320 case 2: // F_SETFD (set close-on-exec flag) 321 return 0; 322 323 case 3: // F_GETFL (get file flags) 324 case 4: // F_SETFL (set file flags) 325 // not sure if this is totally valid, but we'll pass it through 326 // to the underlying OS 327 warn("fcntl(%d, %d) passed through to host\n", fd, cmd); 328 return fcntl(process->sim_fd(fd), cmd); 329 // return 0; 330 331 case 7: // F_GETLK (get lock) 332 case 8: // F_SETLK (set lock) 333 case 9: // F_SETLKW (set lock and wait) 334 // don't mess with file locking... just act like it's OK 335 warn("File lock call (fcntl(%d, %d)) ignored.\n", fd, cmd); 336 return 0; 337 338 default: 339 warn("Unknown fcntl command %d\n", cmd); 340 return 0; 341 } 342} 343 344SyscallReturn 345fcntl64Func(SyscallDesc *desc, int num, Process *process, 346 ThreadContext *tc) 347{ 348 int fd = tc->getSyscallArg(0); 349 350 if (fd < 0 || process->sim_fd(fd) < 0) 351 return -EBADF; 352 353 int cmd = tc->getSyscallArg(1); 354 switch (cmd) { 355 case 33: //F_GETLK64 356 warn("fcntl64(%d, F_GETLK64) not supported, error returned\n", fd); 357 return -EMFILE; 358 359 case 34: // F_SETLK64 360 case 35: // F_SETLKW64 361 warn("fcntl64(%d, F_SETLK(W)64) not supported, error returned\n", fd); 362 return -EMFILE; 363 364 default: 365 // not sure if this is totally valid, but we'll pass it through 366 // to the underlying OS 367 warn("fcntl64(%d, %d) passed through to host\n", fd, cmd); 368 return fcntl(process->sim_fd(fd), cmd); 369 // return 0; 370 } 371} 372 373SyscallReturn 374pipePseudoFunc(SyscallDesc *desc, int callnum, Process *process, 375 ThreadContext *tc) 376{ 377 int fds[2], sim_fds[2]; 378 int pipe_retval = pipe(fds); 379 380 if (pipe_retval < 0) { 381 // error 382 return pipe_retval; 383 } 384 385 sim_fds[0] = process->alloc_fd(fds[0]); 386 sim_fds[1] = process->alloc_fd(fds[1]); 387 388 // Alpha Linux convention for pipe() is that fd[0] is returned as 389 // the return value of the function, and fd[1] is returned in r20. 390 tc->setIntReg(SyscallPseudoReturnReg, sim_fds[1]); 391 return sim_fds[0]; 392} 393 394 395SyscallReturn 396getpidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, 397 ThreadContext *tc) 398{ 399 // Make up a PID. There's no interprocess communication in 400 // fake_syscall mode, so there's no way for a process to know it's 401 // not getting a unique value. 402 403 tc->setIntReg(SyscallPseudoReturnReg, 99); 404 return 100; 405} 406 407 408SyscallReturn 409getuidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, 410 ThreadContext *tc) 411{ 412 // Make up a UID and EUID... it shouldn't matter, and we want the 413 // simulation to be deterministic. 414 415 // EUID goes in r20. 416 tc->setIntReg(SyscallPseudoReturnReg, 100); //EUID 417 return 100; // UID 418} 419 420 421SyscallReturn 422getgidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, 423 ThreadContext *tc) 424{ 425 // Get current group ID. EGID goes in r20. 426 tc->setIntReg(SyscallPseudoReturnReg, 100); //EGID 427 return 100; 428} 429 430 431SyscallReturn 432setuidFunc(SyscallDesc *desc, int callnum, Process *process, 433 ThreadContext *tc) 434{ 435 // can't fathom why a benchmark would call this. 436 warn("Ignoring call to setuid(%d)\n", tc->getSyscallArg(0)); 437 return 0; 438} 439 440SyscallReturn 441getpidFunc(SyscallDesc *desc, int callnum, Process *process, 442 ThreadContext *tc) 443{ 444 // Make up a PID. There's no interprocess communication in 445 // fake_syscall mode, so there's no way for a process to know it's 446 // not getting a unique value. 447 448 tc->setIntReg(SyscallPseudoReturnReg, 99); //PID 449 return 100; 450} 451 452SyscallReturn 453getppidFunc(SyscallDesc *desc, int callnum, Process *process, 454 ThreadContext *tc) 455{ 456 return 99; 457} 458 459SyscallReturn 460getuidFunc(SyscallDesc *desc, int callnum, Process *process, 461 ThreadContext *tc) 462{ 463 return 100; // UID 464} 465 466SyscallReturn 467geteuidFunc(SyscallDesc *desc, int callnum, Process *process, 468 ThreadContext *tc) 469{ 470 return 100; // UID 471} 472 473SyscallReturn 474getgidFunc(SyscallDesc *desc, int callnum, Process *process, 475 ThreadContext *tc) 476{ 477 return 100; 478} 479 480SyscallReturn 481getegidFunc(SyscallDesc *desc, int callnum, Process *process, 482 ThreadContext *tc) 483{ 484 return 100; 485} 486 487
| 97 98 return 1; 99} 100 101 102SyscallReturn 103getpagesizeFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 104{ 105 return (int)VMPageSize; 106} 107 108 109SyscallReturn 110obreakFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 111{ 112 Addr junk; 113 114 // change brk addr to first arg 115 Addr new_brk = tc->getSyscallArg(0); 116 if (new_brk != 0) { 117 for (ChunkGenerator gen(p->brk_point, new_brk - p->brk_point, 118 VMPageSize); !gen.done(); gen.next()) { 119 if (!p->pTable->translate(gen.addr(), junk)) 120 p->pTable->allocate(roundDown(gen.addr(), VMPageSize), 121 VMPageSize); 122 } 123 p->brk_point = new_brk; 124 } 125 DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point); 126 return p->brk_point; 127} 128 129 130SyscallReturn 131closeFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 132{ 133 int target_fd = tc->getSyscallArg(0); 134 int status = close(p->sim_fd(target_fd)); 135 if (status >= 0) 136 p->free_fd(target_fd); 137 return status; 138} 139 140 141SyscallReturn 142readFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 143{ 144 int fd = p->sim_fd(tc->getSyscallArg(0)); 145 int nbytes = tc->getSyscallArg(2); 146 BufferArg bufArg(tc->getSyscallArg(1), nbytes); 147 148 int bytes_read = read(fd, bufArg.bufferPtr(), nbytes); 149 150 if (bytes_read != -1) 151 bufArg.copyOut(tc->getMemPort()); 152 153 return bytes_read; 154} 155 156SyscallReturn 157writeFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 158{ 159 int fd = p->sim_fd(tc->getSyscallArg(0)); 160 int nbytes = tc->getSyscallArg(2); 161 BufferArg bufArg(tc->getSyscallArg(1), nbytes); 162 163 bufArg.copyIn(tc->getMemPort()); 164 165 int bytes_written = write(fd, bufArg.bufferPtr(), nbytes); 166 167 fsync(fd); 168 169 return bytes_written; 170} 171 172 173SyscallReturn 174lseekFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 175{ 176 int fd = p->sim_fd(tc->getSyscallArg(0)); 177 uint64_t offs = tc->getSyscallArg(1); 178 int whence = tc->getSyscallArg(2); 179 180 off_t result = lseek(fd, offs, whence); 181 182 return (result == (off_t)-1) ? -errno : result; 183} 184 185 186SyscallReturn 187munmapFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 188{ 189 // given that we don't really implement mmap, munmap is really easy 190 return 0; 191} 192 193 194const char *hostname = "m5.eecs.umich.edu"; 195 196SyscallReturn 197gethostnameFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 198{ 199 int name_len = tc->getSyscallArg(1); 200 BufferArg name(tc->getSyscallArg(0), name_len); 201 202 strncpy((char *)name.bufferPtr(), hostname, name_len); 203 204 name.copyOut(tc->getMemPort()); 205 206 return 0; 207} 208 209SyscallReturn 210unlinkFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 211{ 212 string path; 213 214 if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) 215 return (TheISA::IntReg)-EFAULT; 216 217 int result = unlink(path.c_str()); 218 return (result == -1) ? -errno : result; 219} 220 221SyscallReturn 222renameFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 223{ 224 string old_name; 225 226 if (!tc->getMemPort()->tryReadString(old_name, tc->getSyscallArg(0))) 227 return -EFAULT; 228 229 string new_name; 230 231 if (!tc->getMemPort()->tryReadString(new_name, tc->getSyscallArg(1))) 232 return -EFAULT; 233 234 int64_t result = rename(old_name.c_str(), new_name.c_str()); 235 return (result == -1) ? -errno : result; 236} 237 238SyscallReturn 239truncateFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 240{ 241 string path; 242 243 if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) 244 return -EFAULT; 245 246 off_t length = tc->getSyscallArg(1); 247 248 int result = truncate(path.c_str(), length); 249 return (result == -1) ? -errno : result; 250} 251 252SyscallReturn 253ftruncateFunc(SyscallDesc *desc, int num, Process *process, ThreadContext *tc) 254{ 255 int fd = process->sim_fd(tc->getSyscallArg(0)); 256 257 if (fd < 0) 258 return -EBADF; 259 260 off_t length = tc->getSyscallArg(1); 261 262 int result = ftruncate(fd, length); 263 return (result == -1) ? -errno : result; 264} 265 266SyscallReturn 267chownFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 268{ 269 string path; 270 271 if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) 272 return -EFAULT; 273 274 /* XXX endianess */ 275 uint32_t owner = tc->getSyscallArg(1); 276 uid_t hostOwner = owner; 277 uint32_t group = tc->getSyscallArg(2); 278 gid_t hostGroup = group; 279 280 int result = chown(path.c_str(), hostOwner, hostGroup); 281 return (result == -1) ? -errno : result; 282} 283 284SyscallReturn 285fchownFunc(SyscallDesc *desc, int num, Process *process, ThreadContext *tc) 286{ 287 int fd = process->sim_fd(tc->getSyscallArg(0)); 288 289 if (fd < 0) 290 return -EBADF; 291 292 /* XXX endianess */ 293 uint32_t owner = tc->getSyscallArg(1); 294 uid_t hostOwner = owner; 295 uint32_t group = tc->getSyscallArg(2); 296 gid_t hostGroup = group; 297 298 int result = fchown(fd, hostOwner, hostGroup); 299 return (result == -1) ? -errno : result; 300} 301 302 303SyscallReturn 304fcntlFunc(SyscallDesc *desc, int num, Process *process, 305 ThreadContext *tc) 306{ 307 int fd = tc->getSyscallArg(0); 308 309 if (fd < 0 || process->sim_fd(fd) < 0) 310 return -EBADF; 311 312 int cmd = tc->getSyscallArg(1); 313 switch (cmd) { 314 case 0: // F_DUPFD 315 // if we really wanted to support this, we'd need to do it 316 // in the target fd space. 317 warn("fcntl(%d, F_DUPFD) not supported, error returned\n", fd); 318 return -EMFILE; 319 320 case 1: // F_GETFD (get close-on-exec flag) 321 case 2: // F_SETFD (set close-on-exec flag) 322 return 0; 323 324 case 3: // F_GETFL (get file flags) 325 case 4: // F_SETFL (set file flags) 326 // not sure if this is totally valid, but we'll pass it through 327 // to the underlying OS 328 warn("fcntl(%d, %d) passed through to host\n", fd, cmd); 329 return fcntl(process->sim_fd(fd), cmd); 330 // return 0; 331 332 case 7: // F_GETLK (get lock) 333 case 8: // F_SETLK (set lock) 334 case 9: // F_SETLKW (set lock and wait) 335 // don't mess with file locking... just act like it's OK 336 warn("File lock call (fcntl(%d, %d)) ignored.\n", fd, cmd); 337 return 0; 338 339 default: 340 warn("Unknown fcntl command %d\n", cmd); 341 return 0; 342 } 343} 344 345SyscallReturn 346fcntl64Func(SyscallDesc *desc, int num, Process *process, 347 ThreadContext *tc) 348{ 349 int fd = tc->getSyscallArg(0); 350 351 if (fd < 0 || process->sim_fd(fd) < 0) 352 return -EBADF; 353 354 int cmd = tc->getSyscallArg(1); 355 switch (cmd) { 356 case 33: //F_GETLK64 357 warn("fcntl64(%d, F_GETLK64) not supported, error returned\n", fd); 358 return -EMFILE; 359 360 case 34: // F_SETLK64 361 case 35: // F_SETLKW64 362 warn("fcntl64(%d, F_SETLK(W)64) not supported, error returned\n", fd); 363 return -EMFILE; 364 365 default: 366 // not sure if this is totally valid, but we'll pass it through 367 // to the underlying OS 368 warn("fcntl64(%d, %d) passed through to host\n", fd, cmd); 369 return fcntl(process->sim_fd(fd), cmd); 370 // return 0; 371 } 372} 373 374SyscallReturn 375pipePseudoFunc(SyscallDesc *desc, int callnum, Process *process, 376 ThreadContext *tc) 377{ 378 int fds[2], sim_fds[2]; 379 int pipe_retval = pipe(fds); 380 381 if (pipe_retval < 0) { 382 // error 383 return pipe_retval; 384 } 385 386 sim_fds[0] = process->alloc_fd(fds[0]); 387 sim_fds[1] = process->alloc_fd(fds[1]); 388 389 // Alpha Linux convention for pipe() is that fd[0] is returned as 390 // the return value of the function, and fd[1] is returned in r20. 391 tc->setIntReg(SyscallPseudoReturnReg, sim_fds[1]); 392 return sim_fds[0]; 393} 394 395 396SyscallReturn 397getpidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, 398 ThreadContext *tc) 399{ 400 // Make up a PID. There's no interprocess communication in 401 // fake_syscall mode, so there's no way for a process to know it's 402 // not getting a unique value. 403 404 tc->setIntReg(SyscallPseudoReturnReg, 99); 405 return 100; 406} 407 408 409SyscallReturn 410getuidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, 411 ThreadContext *tc) 412{ 413 // Make up a UID and EUID... it shouldn't matter, and we want the 414 // simulation to be deterministic. 415 416 // EUID goes in r20. 417 tc->setIntReg(SyscallPseudoReturnReg, 100); //EUID 418 return 100; // UID 419} 420 421 422SyscallReturn 423getgidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, 424 ThreadContext *tc) 425{ 426 // Get current group ID. EGID goes in r20. 427 tc->setIntReg(SyscallPseudoReturnReg, 100); //EGID 428 return 100; 429} 430 431 432SyscallReturn 433setuidFunc(SyscallDesc *desc, int callnum, Process *process, 434 ThreadContext *tc) 435{ 436 // can't fathom why a benchmark would call this. 437 warn("Ignoring call to setuid(%d)\n", tc->getSyscallArg(0)); 438 return 0; 439} 440 441SyscallReturn 442getpidFunc(SyscallDesc *desc, int callnum, Process *process, 443 ThreadContext *tc) 444{ 445 // Make up a PID. There's no interprocess communication in 446 // fake_syscall mode, so there's no way for a process to know it's 447 // not getting a unique value. 448 449 tc->setIntReg(SyscallPseudoReturnReg, 99); //PID 450 return 100; 451} 452 453SyscallReturn 454getppidFunc(SyscallDesc *desc, int callnum, Process *process, 455 ThreadContext *tc) 456{ 457 return 99; 458} 459 460SyscallReturn 461getuidFunc(SyscallDesc *desc, int callnum, Process *process, 462 ThreadContext *tc) 463{ 464 return 100; // UID 465} 466 467SyscallReturn 468geteuidFunc(SyscallDesc *desc, int callnum, Process *process, 469 ThreadContext *tc) 470{ 471 return 100; // UID 472} 473 474SyscallReturn 475getgidFunc(SyscallDesc *desc, int callnum, Process *process, 476 ThreadContext *tc) 477{ 478 return 100; 479} 480 481SyscallReturn 482getegidFunc(SyscallDesc *desc, int callnum, Process *process, 483 ThreadContext *tc) 484{ 485 return 100; 486} 487 488
|