syscall_emul.cc (6110:5051aafec8d5) | syscall_emul.cc (6111:5666d4eb6bbd) |
---|---|
1/* 2 * Copyright (c) 2003-2005 The Regents of The University of Michigan 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; --- 38 unchanged lines hidden (view full) --- 47#include "sim/sim_exit.hh" 48 49using namespace std; 50using namespace TheISA; 51 52void 53SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc) 54{ | 1/* 2 * Copyright (c) 2003-2005 The Regents of The University of Michigan 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; --- 38 unchanged lines hidden (view full) --- 47#include "sim/sim_exit.hh" 48 49using namespace std; 50using namespace TheISA; 51 52void 53SyscallDesc::doSyscall(int callnum, LiveProcess *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, | 55 DPRINTFR(SyscallVerbose, 56 "%d: %s: syscall %s called w/arguments %d,%d,%d,%d\n", 57 curTick, tc->getCpuPtr()->name(), name, |
57 process->getSyscallArg(tc, 0), process->getSyscallArg(tc, 1), 58 process->getSyscallArg(tc, 2), process->getSyscallArg(tc, 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 --- 156 unchanged lines hidden (view full) --- 221 222 uint64_t result = lseek(fd, offset, whence); 223 result = TheISA::htog(result); 224 225 if (result == (off_t)-1) { 226 //The seek failed. 227 return -errno; 228 } else { | 58 process->getSyscallArg(tc, 0), process->getSyscallArg(tc, 1), 59 process->getSyscallArg(tc, 2), process->getSyscallArg(tc, 3)); 60 61 SyscallReturn retval = (*funcPtr)(this, callnum, process, tc); 62 63 DPRINTFR(SyscallVerbose, "%d: %s: syscall %s returns %d\n", 64 curTick,tc->getCpuPtr()->name(), name, retval.value()); 65 --- 156 unchanged lines hidden (view full) --- 222 223 uint64_t result = lseek(fd, offset, whence); 224 result = TheISA::htog(result); 225 226 if (result == (off_t)-1) { 227 //The seek failed. 228 return -errno; 229 } else { |
229 //The seek succeeded. 230 //Copy "result" to "result_ptr" 231 //XXX We'll assume that the size of loff_t is 64 bits on the 232 //target platform | 230 // The seek succeeded. 231 // Copy "result" to "result_ptr" 232 // XXX We'll assume that the size of loff_t is 64 bits on the 233 // target platform |
233 BufferArg result_buf(result_ptr, sizeof(result)); 234 memcpy(result_buf.bufferPtr(), &result, sizeof(result)); 235 result_buf.copyOut(tc->getMemPort()); 236 return 0; 237 } 238 239 240 return (result == (off_t)-1) ? -errno : result; --- 143 unchanged lines hidden (view full) --- 384 // Adjust path for current working directory 385 path = p->fullPath(path); 386 387 int result = truncate(path.c_str(), length); 388 return (result == -1) ? -errno : result; 389} 390 391SyscallReturn | 234 BufferArg result_buf(result_ptr, sizeof(result)); 235 memcpy(result_buf.bufferPtr(), &result, sizeof(result)); 236 result_buf.copyOut(tc->getMemPort()); 237 return 0; 238 } 239 240 241 return (result == (off_t)-1) ? -errno : result; --- 143 unchanged lines hidden (view full) --- 385 // Adjust path for current working directory 386 path = p->fullPath(path); 387 388 int result = truncate(path.c_str(), length); 389 return (result == -1) ? -errno : result; 390} 391 392SyscallReturn |
392ftruncateFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) | 393ftruncateFunc(SyscallDesc *desc, int num, 394 LiveProcess *process, ThreadContext *tc) |
393{ 394 int fd = process->sim_fd(process->getSyscallArg(tc, 0)); 395 396 if (fd < 0) 397 return -EBADF; 398 399 off_t length = process->getSyscallArg(tc, 1); 400 --- 57 unchanged lines hidden (view full) --- 458{ 459 int fd = process->sim_fd(process->getSyscallArg(tc, 0)); 460 if (fd < 0) 461 return -EBADF; 462 463 Process::FdMap *fdo = process->sim_fd_obj(process->getSyscallArg(tc, 0)); 464 465 int result = dup(fd); | 395{ 396 int fd = process->sim_fd(process->getSyscallArg(tc, 0)); 397 398 if (fd < 0) 399 return -EBADF; 400 401 off_t length = process->getSyscallArg(tc, 1); 402 --- 57 unchanged lines hidden (view full) --- 460{ 461 int fd = process->sim_fd(process->getSyscallArg(tc, 0)); 462 if (fd < 0) 463 return -EBADF; 464 465 Process::FdMap *fdo = process->sim_fd_obj(process->getSyscallArg(tc, 0)); 466 467 int result = dup(fd); |
466 return (result == -1) ? -errno : process->alloc_fd(result, fdo->filename, fdo->flags, fdo->mode, false); | 468 return (result == -1) ? -errno : 469 process->alloc_fd(result, fdo->filename, fdo->flags, fdo->mode, false); |
467} 468 469 470SyscallReturn 471fcntlFunc(SyscallDesc *desc, int num, LiveProcess *process, 472 ThreadContext *tc) 473{ 474 int fd = process->getSyscallArg(tc, 0); --- 180 unchanged lines hidden (view full) --- 655 656 657SyscallReturn 658cloneFunc(SyscallDesc *desc, int callnum, LiveProcess *process, 659 ThreadContext *tc) 660{ 661 DPRINTF(SyscallVerbose, "In sys_clone:\n"); 662 DPRINTF(SyscallVerbose, " Flags=%llx\n", process->getSyscallArg(tc, 0)); | 470} 471 472 473SyscallReturn 474fcntlFunc(SyscallDesc *desc, int num, LiveProcess *process, 475 ThreadContext *tc) 476{ 477 int fd = process->getSyscallArg(tc, 0); --- 180 unchanged lines hidden (view full) --- 658 659 660SyscallReturn 661cloneFunc(SyscallDesc *desc, int callnum, LiveProcess *process, 662 ThreadContext *tc) 663{ 664 DPRINTF(SyscallVerbose, "In sys_clone:\n"); 665 DPRINTF(SyscallVerbose, " Flags=%llx\n", process->getSyscallArg(tc, 0)); |
663 DPRINTF(SyscallVerbose, " Child stack=%llx\n", process->getSyscallArg(tc, 1)); | 666 DPRINTF(SyscallVerbose, " Child stack=%llx\n", 667 process->getSyscallArg(tc, 1)); |
664 665 666 if (process->getSyscallArg(tc, 0) != 0x10f00) { | 668 669 670 if (process->getSyscallArg(tc, 0) != 0x10f00) { |
667 warn("This sys_clone implementation assumes flags CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD (0x10f00), and may not work correctly with given flags 0x%llx\n", process->getSyscallArg(tc, 0)); | 671 warn("This sys_clone implementation assumes flags " 672 "CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD " 673 "(0x10f00), and may not work correctly with given flags " 674 "0x%llx\n", process->getSyscallArg(tc, 0)); |
668 } 669 | 675 } 676 |
670 ThreadContext* ctc; //child thread context | 677 ThreadContext* ctc; // child thread context |
671 if ( ( ctc = process->findFreeContext() ) != NULL ) { 672 DPRINTF(SyscallVerbose, " Found unallocated thread context\n"); 673 674 ctc->clearArchRegs(); 675 | 678 if ( ( ctc = process->findFreeContext() ) != NULL ) { 679 DPRINTF(SyscallVerbose, " Found unallocated thread context\n"); 680 681 ctc->clearArchRegs(); 682 |
676 //Arch-specific cloning code | 683 // Arch-specific cloning code |
677 #if THE_ISA == ALPHA_ISA or THE_ISA == X86_ISA | 684 #if THE_ISA == ALPHA_ISA or THE_ISA == X86_ISA |
678 //Cloning the misc. regs for these archs is enough | 685 // Cloning the misc. regs for these archs is enough |
679 TheISA::copyMiscRegs(tc, ctc); 680 #elif THE_ISA == SPARC_ISA 681 TheISA::copyRegs(tc, ctc); 682 | 686 TheISA::copyMiscRegs(tc, ctc); 687 #elif THE_ISA == SPARC_ISA 688 TheISA::copyRegs(tc, ctc); 689 |
683 //TODO: Explain what this code actually does :-) | 690 // TODO: Explain what this code actually does :-) |
684 ctc->setIntReg(NumIntArchRegs + 6, 0); 685 ctc->setIntReg(NumIntArchRegs + 4, 0); 686 ctc->setIntReg(NumIntArchRegs + 3, NWindows - 2); 687 ctc->setIntReg(NumIntArchRegs + 5, NWindows); 688 ctc->setMiscRegNoEffect(MISCREG_CWP, 0); 689 ctc->setIntReg(NumIntArchRegs + 7, 0); 690 ctc->setMiscRegNoEffect(MISCREG_TL, 0); 691 ctc->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY); 692 693 for (int y = 8; y < 32; y++) 694 ctc->setIntReg(y, tc->readIntReg(y)); 695 #else 696 fatal("sys_clone is not implemented for this ISA\n"); 697 #endif 698 | 691 ctc->setIntReg(NumIntArchRegs + 6, 0); 692 ctc->setIntReg(NumIntArchRegs + 4, 0); 693 ctc->setIntReg(NumIntArchRegs + 3, NWindows - 2); 694 ctc->setIntReg(NumIntArchRegs + 5, NWindows); 695 ctc->setMiscRegNoEffect(MISCREG_CWP, 0); 696 ctc->setIntReg(NumIntArchRegs + 7, 0); 697 ctc->setMiscRegNoEffect(MISCREG_TL, 0); 698 ctc->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY); 699 700 for (int y = 8; y < 32; y++) 701 ctc->setIntReg(y, tc->readIntReg(y)); 702 #else 703 fatal("sys_clone is not implemented for this ISA\n"); 704 #endif 705 |
699 //Set up stack register | 706 // Set up stack register |
700 ctc->setIntReg(TheISA::StackPointerReg, process->getSyscallArg(tc, 1)); 701 | 707 ctc->setIntReg(TheISA::StackPointerReg, process->getSyscallArg(tc, 1)); 708 |
702 //Set up syscall return values in parent and child 703 ctc->setIntReg(ReturnValueReg, 0); //return value, child | 709 // Set up syscall return values in parent and child 710 ctc->setIntReg(ReturnValueReg, 0); // return value, child |
704 | 711 |
705 //Alpha needs SyscallSuccessReg=0 in child | 712 // Alpha needs SyscallSuccessReg=0 in child |
706 #if THE_ISA == ALPHA_ISA 707 ctc->setIntReg(TheISA::SyscallSuccessReg, 0); 708 #endif 709 | 713 #if THE_ISA == ALPHA_ISA 714 ctc->setIntReg(TheISA::SyscallSuccessReg, 0); 715 #endif 716 |
710 //In SPARC/Linux, clone returns 0 on pseudo-return register if parent, non-zero if child | 717 // In SPARC/Linux, clone returns 0 on pseudo-return register if 718 // parent, non-zero if child |
711 #if THE_ISA == SPARC_ISA 712 tc->setIntReg(TheISA::SyscallPseudoReturnReg, 0); 713 ctc->setIntReg(TheISA::SyscallPseudoReturnReg, 1); 714 #endif 715 716 ctc->setPC(tc->readNextPC()); 717 ctc->setNextPC(tc->readNextPC() + sizeof(TheISA::MachInst)); 718 | 719 #if THE_ISA == SPARC_ISA 720 tc->setIntReg(TheISA::SyscallPseudoReturnReg, 0); 721 ctc->setIntReg(TheISA::SyscallPseudoReturnReg, 1); 722 #endif 723 724 ctc->setPC(tc->readNextPC()); 725 ctc->setNextPC(tc->readNextPC() + sizeof(TheISA::MachInst)); 726 |
719 //In SPARC, need NNPC too... | 727 // In SPARC, need NNPC too... |
720 #if THE_ISA == SPARC_ISA 721 ctc->setNextNPC(tc->readNextNPC() + sizeof(TheISA::MachInst)); 722 #endif 723 724 ctc->activate(); 725 726 // Should return nonzero child TID in parent's syscall return register, 727 // but for our pthread library any non-zero value will work 728 return 1; 729 } else { 730 fatal("Called sys_clone, but no unallocated thread contexts found!\n"); 731 return 0; 732 } 733} 734 | 728 #if THE_ISA == SPARC_ISA 729 ctc->setNextNPC(tc->readNextNPC() + sizeof(TheISA::MachInst)); 730 #endif 731 732 ctc->activate(); 733 734 // Should return nonzero child TID in parent's syscall return register, 735 // but for our pthread library any non-zero value will work 736 return 1; 737 } else { 738 fatal("Called sys_clone, but no unallocated thread contexts found!\n"); 739 return 0; 740 } 741} 742 |