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