41 #include "arch/utility.hh"
44 #include "config/the_isa.hh"
54 using namespace TheISA;
60 fatal(
"syscall %s (#%d) unimplemented.", desc->
name(), callnum);
72 "\n (further warnings will be suppressed)" :
"");
89 futex_map.
wakeup(addr, tgid, 1);
101 int activeContexts = 0;
103 activeContexts +=
system->numRunningContexts();
104 if (activeContexts == 1) {
105 exitSimLoop(
"exiting with last active thread context", status & 0xff);
115 bool last_thread =
true;
116 Process *parent =
nullptr, *tg_lead =
nullptr;
167 for (
int i = 0;
i < p->
fds->getSize();
i++) {
169 p->
fds->closeFDEntry(
i);
180 return exitImpl(desc, callnum, p, tc,
false);
186 return exitImpl(desc, callnum, p, tc,
true);
203 std::shared_ptr<MemState> mem_state = p->
memState;
204 Addr brk_point = mem_state->getBrkPoint();
211 if (new_brk > brk_point) {
226 uint32_t size_needed = next_page - gen.addr();
228 if (gen.addr() +
PageBytes > next_page &&
229 next_page < new_brk &&
238 mem_state->setBrkPoint(new_brk);
240 mem_state->getBrkPoint());
241 return mem_state->getBrkPoint();
252 return process->
pid();
261 return p->
fds->closeFDEntry(tgt_fd);
273 auto hbfdp = std::dynamic_pointer_cast<
HBFDEntry>((*p->
fds)[tgt_fd]);
276 int sim_fd = hbfdp->getSimFD();
279 int bytes_read = read(sim_fd, bufArg.
bufferPtr(), nbytes);
295 auto hbfdp = std::dynamic_pointer_cast<
HBFDEntry>((*p->
fds)[tgt_fd]);
298 int sim_fd = hbfdp->getSimFD();
303 int bytes_written = write(sim_fd, bufArg.
bufferPtr(), nbytes);
307 return bytes_written;
319 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>((*p->
fds)[tgt_fd]);
322 int sim_fd = ffdp->getSimFD();
324 off_t result = lseek(sim_fd, offs, whence);
326 return (result == (off_t)-1) ? -errno : result;
340 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>((*p->
fds)[tgt_fd]);
343 int sim_fd = ffdp->getSimFD();
345 uint64_t
offset = (offset_high << 32) | offset_low;
347 uint64_t result = lseek(sim_fd, offset, whence);
350 if (result == (off_t)-1)
353 BufferArg result_buf(result_ptr,
sizeof(result));
354 memcpy(result_buf.
bufferPtr(), &result,
sizeof(result));
399 if (cwd.length() >=
size) {
404 result = cwd.length();
407 result = strlen((
char *)buf.
bufferPtr());
415 return (result == -1) ? -errno : result;
443 if (path !=
"/proc/self/exe") {
444 result = readlink(path.c_str(), (
char *)buf.
bufferPtr(), bufsiz);
458 char real_path[PATH_MAX];
459 char *check_real_path = realpath(p->
progName(), real_path);
460 if (!check_real_path) {
461 fatal(
"readlink('/proc/self/exe') unable to resolve path to "
464 strncpy((
char*)buf.
bufferPtr(), real_path, bufsiz);
465 size_t real_path_len = strlen(real_path);
466 if (real_path_len > bufsiz) {
471 result = real_path_len;
475 warn_once(
"readlink() called on '/proc/self/exe' may yield unexpected "
476 "results in various settings.\n Returning '%s'\n",
482 return (result == -1) ? -errno : result;
503 int result = unlink(path.c_str());
504 return (result == -1) ? -errno : result;
522 int result = mkdir(path.c_str(),
mode);
523 return (result == -1) ? -errno : result;
544 int64_t result = rename(old_name.c_str(), new_name.c_str());
545 return (result == -1) ? -errno : result;
562 int result = truncate(path.c_str(),
length);
563 return (result == -1) ? -errno : result;
573 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>((*p->
fds)[tgt_fd]);
576 int sim_fd = ffdp->getSimFD();
578 int result = ftruncate(sim_fd, length);
579 return (result == -1) ? -errno : result;
598 int result = truncate(path.c_str(),
length);
600 int result = truncate64(path.c_str(),
length);
602 return (result == -1) ? -errno : result;
612 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>((*p->
fds)[tgt_fd]);
615 int sim_fd = ffdp->getSimFD();
618 int result = ftruncate(sim_fd, length);
620 int result = ftruncate64(sim_fd, length);
622 return (result == -1) ? -errno : result;
631 mode_t oldMask = umask(0);
647 uid_t hostOwner = owner;
649 gid_t hostGroup = group;
654 int result = chown(path.c_str(), hostOwner, hostGroup);
655 return (result == -1) ? -errno : result;
664 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>((*p->
fds)[tgt_fd]);
667 int sim_fd = ffdp->getSimFD();
671 uid_t hostOwner = owner;
673 gid_t hostGroup = group;
675 int result = fchown(sim_fd, hostOwner, hostGroup);
676 return (result == -1) ? -errno : result;
691 auto old_hbfdp = std::dynamic_pointer_cast<
HBFDEntry>((*p->
fds)[tgt_fd]);
694 int sim_fd = old_hbfdp->getSimFD();
696 int result = dup(sim_fd);
700 auto new_hbfdp = std::dynamic_pointer_cast<HBFDEntry>(old_hbfdp->clone());
701 new_hbfdp->setSimFD(result);
702 new_hbfdp->setCOE(
false);
703 return p->
fds->allocFD(new_hbfdp);
712 auto old_hbp = std::dynamic_pointer_cast<
HBFDEntry>((*p->
fds)[old_tgt_fd]);
715 int old_sim_fd = old_hbp->getSimFD();
722 int res_fd = dup2(old_sim_fd, open(
"/dev/null", O_RDONLY));
727 auto new_hbp = std::dynamic_pointer_cast<HBFDEntry>((*p->
fds)[new_tgt_fd]);
729 p->
fds->closeFDEntry(new_tgt_fd);
730 new_hbp = std::dynamic_pointer_cast<HBFDEntry>(old_hbp->clone());
731 new_hbp->setSimFD(res_fd);
732 new_hbp->setCOE(
false);
734 return p->
fds->allocFD(new_hbp);
745 auto hbfdp = std::dynamic_pointer_cast<
HBFDEntry>((*p->
fds)[tgt_fd]);
748 int sim_fd = hbfdp->getSimFD();
750 int coe = hbfdp->getCOE();
754 return coe & FD_CLOEXEC;
758 arg ? hbfdp->setCOE(
true) : hbfdp->setCOE(
false);
771 int rv = fcntl(sim_fd, cmd, arg);
772 return (rv == -1) ? -errno : rv;
776 warn(
"fcntl: unsupported command %d\n", cmd);
787 auto hbfdp = std::dynamic_pointer_cast<
HBFDEntry>((*p->
fds)[tgt_fd]);
790 int sim_fd = hbfdp->getSimFD();
795 warn(
"fcntl64(%d, F_GETLK64) not supported, error returned\n", tgt_fd);
800 warn(
"fcntl64(%d, F_SETLK(W)64) not supported, error returned\n",
807 warn(
"fcntl64(%d, %d) passed through to host\n", tgt_fd, cmd);
808 return fcntl(sim_fd, cmd);
822 int sim_fds[2], tgt_fds[2];
824 int pipe_retval = pipe(sim_fds);
825 if (pipe_retval == -1)
828 auto rend = PipeFDEntry::EndType::read;
829 auto rpfd = std::make_shared<PipeFDEntry>(sim_fds[0], O_WRONLY, rend);
830 tgt_fds[0] = p->
fds->allocFD(rpfd);
832 auto wend = PipeFDEntry::EndType::write;
833 auto wpfd = std::make_shared<PipeFDEntry>(sim_fds[1], O_RDONLY, wend);
834 tgt_fds[1] = p->
fds->allocFD(wpfd);
840 rpfd->setPipeReadSource(tgt_fds[1]);
855 BufferArg tgt_handle(tgt_addr,
sizeof(
int[2]));
856 int *buf_ptr = (
int*)tgt_handle.
bufferPtr();
857 buf_ptr[0] = tgt_fds[0];
858 buf_ptr[1] = tgt_fds[1];
867 return pipeImpl(desc, callnum, process, tc,
true);
873 return pipeImpl(desc, callnum, process, tc,
false);
901 if (walk_ph && walk_ph->
pid() == process->
pid())
902 matched_ph = walk_ph;
907 matched_ph->
setpgid((pgid == 0) ? matched_ph->
pid() : pgid);
921 return process->
pid();
934 return process->
uid();
944 return process->
gid();
962 return process->
tgid();
969 return process->
pid();
976 return process->
ppid();
983 return process->
uid();
990 return process->
euid();
997 return process->
gid();
1004 return process->
egid();
1011 warn(
"Host OS cannot support calls to fallocate. Ignoring syscall");
1019 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>((*p->
fds)[tgt_fd]);
1022 int sim_fd = ffdp->getSimFD();
1024 int result = fallocate(sim_fd, mode, offset, len);
1044 int result = access(path.c_str(),
mode);
1045 return (result == -1) ? -errno : result;
SyscallReturn ftruncateFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Target ftruncate() handler.
virtual void halt()=0
Set the status to Halted.
virtual System * getSystemPtr()=0
SyscallReturn brkFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Target brk() handler: set brk address.
const std::string & name()
uint64_t childClearTID
Calls a futex wakeup at the address specified by this pointer when this process exits.
SyscallReturn fallocateFunc(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc)
SyscallReturn dupFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
FIXME: The file description is not shared among file descriptors created with dup.
SyscallReturn getcwdFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Target getcwd() handler.
void allocateMem(Addr vaddr, int64_t size, bool clobber=false)
bool copyIn(SETranslatingPortProxy &memproxy)
copy data into simulator space (read from target memory)
SyscallReturn pipeImpl(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc, bool pseudoPipe)
Internal pipe() handler.
SyscallReturn ignoreFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
Handler for unimplemented syscalls that we never intend to implement (signal handling, etc.) and should not affect the correct behavior of the program.
SyscallReturn setTidAddressFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
Target set_tid_address() handler.
SyscallReturn getppidFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
Target getppid() handler.
SyscallReturn getpagesizeFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Target getpagesize() handler.
SyscallReturn readlinkFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i)=0
Holds file descriptors for host-backed files; host-backed files are files which were opened on the ph...
SyscallReturn getgidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
Target getgidPseudo() handler.
virtual void setIntReg(int reg_idx, uint64_t val)=0
T roundUp(const T &val, const U &align)
SyscallReturn getpidFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
Target getpid() handler.
std::shared_ptr< MemState > memState
ThreadContext is the external interface to all thread state for anything outside of the CPU...
#define DPRINTF_SYSCALL(FLAGEXT, FMT,...)
This macro is intended to help with readability.
SyscallReturn truncate64Func(SyscallDesc *desc, int num, Process *process, ThreadContext *tc)
Target truncate64() handler.
SyscallReturn getegidFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
Target getegid() handler.
SyscallReturn _llseekFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Target _llseek() handler.
SyscallReturn fcntlFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Target fcntl() handler.
bool copyOut(SETranslatingPortProxy &memproxy)
copy data out of simulator space (write to target memory)
SyscallReturn munmapFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Target munmap() handler.
SyscallReturn writeFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Target write() handler.
SyscallReturn unimplementedFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
Handler for unimplemented syscalls that we haven't thought about.
SyscallReturn exitGroupFunc(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc)
Target exit_group() handler: terminate simulation. (exit all threads)
SyscallReturn lseekFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Target lseek() handler.
bool tryReadString(std::string &str, Addr addr) const
static SyscallReturn exitImpl(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc, bool group)
SyscallReturn fchownFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Target fchown() handler.
bool translate(Addr vaddr, Addr &paddr)
Translate function.
int wakeup(Addr addr, uint64_t tgid, int count)
Wakes up at most count waiting threads on a futex.
This class takes an arbitrary memory region (address/length pair) and generates a series of appropria...
SyscallReturn unlinkFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
const char * progName() const
std::vector< ThreadContext * > threadContexts
SyscallReturn gettidFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
Target gettid() handler.
Extends the base class to include a host-backed file descriptor field that records the integer used t...
void * bufferPtr()
Return a pointer to the internal simulator-space buffer.
SyscallReturn geteuidFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
Target geteuid() handler.
T roundDown(const T &val, const U &align)
const RegIndex SyscallPseudoReturnReg
virtual SETranslatingPortProxy & getMemProxy()=0
SyscallReturn getuidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
Target getuidPseudo() handler.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
std::string getcwd() const
virtual void memsetBlob(Addr addr, uint8_t val, int size) const
Fill size bytes starting at addr with byte value val.
std::list< BasicSignal > signalList
SyscallReturn mkdirFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Target mkdir() handler.
SyscallReturn setuidFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
Target setuid() handler.
std::string fullPath(const std::string &filename)
This class provides the wrapper interface for the system call implementations which are defined in th...
SyscallReturn truncateFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Target truncate() handler.
SyscallReturn getgidFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
Target getgid() handler.
SyscallReturn pipePseudoFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
Pseudo Funcs - These functions use a different return convension, returning a second value in a regis...
SyscallReturn renameFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Target rename() handler.
void exitSimLoop(const std::string &message, int exit_code, Tick when, Tick repeat, bool serialize)
Schedule an event to exit the simulation loop (returning to Python) at the end of the current cycle (...
SyscallReturn setpgidFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
Target setpgid() handler.
SyscallReturn fcntl64Func(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Target fcntl64() handler.
Declarations of a non-full system Page Table.
This file defines objects used to emulate syscalls from the target application on the host machine...
SyscallReturn getuidFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
Target getuid() handler.
bool done() const
Are we done? That is, did the last call to next() advance past the end of the region?
void setpgid(uint64_t pgid)
SyscallReturn umaskFunc(SyscallDesc *desc, int num, Process *process, ThreadContext *tc)
Target umask() handler.
SyscallReturn accessFunc(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc, int index)
SyscallReturn dup2Func(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Target dup2() handler.
SyscallReturn chownFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Target chown() handler.
FutexMap class holds a map of all futexes used in the system.
SyscallReturn unlinkHelper(SyscallDesc *desc, int num, Process *p, ThreadContext *tc, int index)
Target unlink() handler.
SyscallReturn gethostnameFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Target gethostname() handler.
SyscallReturn getpidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
Target getpidPseudo() handler.
BufferArg represents an untyped buffer in target user space that is passed by reference to an (emulat...
SyscallReturn exitFunc(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc)
Target exit() handler: terminate current context.
SyscallReturn ftruncate64Func(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Target ftruncate64() handler.
SyscallReturn closeFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Target close() handler.
Declaration and inline definition of ChunkGenerator object.
This class represents the return value from an emulated system call, including any errno setting...
bool needWarning()
Return false if WarnOnce is set and a warning has already been issued.
SyscallReturn pipeFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
Target pipe() handler.
static void exitFutexWake(ThreadContext *tc, Addr addr, uint64_t tgid)
SyscallReturn readFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
std::shared_ptr< FDArray > fds
static std::vector< System * > systemList