gem5 v24.0.0.0
Loading...
Searching...
No Matches
syscall_emul.cc
Go to the documentation of this file.
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;
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.
27 */
28
29#include "sim/syscall_emul.hh"
30
31#include <fcntl.h>
32#include <sys/syscall.h>
33#include <unistd.h>
34
35#include <csignal>
36#include <iostream>
37#include <mutex>
38#include <string>
39#include <unordered_map>
40
42#include "base/trace.hh"
43#include "cpu/thread_context.hh"
44#include "dev/net/dist_iface.hh"
45#include "mem/page_table.hh"
47#include "sim/byteswap.hh"
48#include "sim/process.hh"
49#include "sim/proxy_ptr.hh"
50#include "sim/sim_exit.hh"
52#include "sim/syscall_desc.hh"
53#include "sim/system.hh"
54
55namespace gem5
56{
57
58void
59warnUnsupportedOS(std::string syscall_name)
60{
61 warn("Cannot invoke %s on host operating system.", syscall_name);
62}
63
64SyscallReturn
66{
67 fatal("syscall %s (#%d) unimplemented.", desc->name(), desc->num());
68}
69
70
71SyscallReturn
73{
74 warn("ignoring syscall %s(...)", desc->name());
75 return 0;
76}
77
78SyscallReturn
80{
81 static std::unordered_map<SyscallDesc *, bool> bool_map;
82
83 bool &warned = bool_map[desc];
84 if (!warned) {
85 warn("ignoring syscall %s(...)\n"
86 " (further warnings will be suppressed)", desc->name());
87 warned = true;
88 }
89
90 return 0;
91}
92
93static void
95{
96 // Clear value at address pointed to by thread's childClearTID field.
97 BufferArg ctidBuf(addr, sizeof(long));
98 long *ctid = (long *)ctidBuf.bufferPtr();
99 *ctid = 0;
100 ctidBuf.copyOut(SETranslatingPortProxy(tc));
101
102 FutexMap &futex_map = tc->getSystemPtr()->futexMap;
103 // Wake one of the waiting threads.
104 futex_map.wakeup(addr, tgid, 1);
105}
106
107static SyscallReturn
108exitImpl(SyscallDesc *desc, ThreadContext *tc, bool group, int status)
109{
110 auto p = tc->getProcessPtr();
111
112 System *sys = tc->getSystemPtr();
113
114 if (group)
115 *p->exitGroup = true;
116
117 if (p->childClearTID)
118 exitFutexWake(tc, p->childClearTID, p->tgid());
119
120 bool last_thread = true;
121 Process *parent = nullptr, *tg_lead = nullptr;
122 for (int i = 0; last_thread && i < sys->threads.size(); i++) {
123 Process *walk;
124 if (!(walk = sys->threads[i]->getProcessPtr()))
125 continue;
126
133 if (walk->pid() == p->tgid())
134 tg_lead = walk;
135
136 auto *tc = sys->threads[i];
137 if ((tc->status() != ThreadContext::Halted) &&
138 (tc->status() != ThreadContext::Halting) &&
139 (walk != p)) {
146 if (walk->tgid() == p->tgid()) {
159 if (*(p->exitGroup)) {
160 tc->halt();
161 } else {
162 last_thread = false;
163 }
164 }
165
175 if (*p->sigchld && (p->ppid() != 0) && (walk->pid() == p->ppid()))
176 parent = walk;
177 }
178 }
179
180 if (last_thread) {
181 if (parent) {
182 assert(tg_lead);
183 sys->signalList.push_back(BasicSignal(tg_lead, parent, SIGCHLD));
184 }
185
191 for (int i = 0; i < p->fds->getSize(); i++) {
192 if ((*p->fds)[i])
193 p->fds->closeFDEntry(i);
194 }
195 }
196
201 if (!p->vforkContexts.empty()) {
202 ThreadContext *vtc = sys->threads[p->vforkContexts.front()];
203 assert(vtc->status() == ThreadContext::Suspended);
204 vtc->activate();
205 }
206
207 tc->halt();
208
213 int activeContexts = 0;
214 for (auto &system: sys->systemList)
215 activeContexts += system->threads.numRunning();
216
217 if (activeContexts == 0) {
227 if (!DistIface::readyToExit(0)) {
228 return status;
229 }
230
231 exitSimLoop("exiting with last active thread context", status & 0xff);
232 return status;
233 }
234
235 return status;
236}
237
238SyscallReturn
240{
241 return exitImpl(desc, tc, false, status);
242}
243
244SyscallReturn
246{
247 return exitImpl(desc, tc, true, status);
248}
249
250SyscallReturn
252{
253 return (int)tc->getProcessPtr()->pTable->pageSize();
254}
255
256
257SyscallReturn
259{
260 // change brk addr to first arg
261 auto p = tc->getProcessPtr();
262
263 std::shared_ptr<MemState> mem_state = p->memState;
264 Addr brk_point = mem_state->getBrkPoint();
265
266 // in Linux at least, brk(0) returns the current break value
267 // (note that the syscall and the glibc function have different behavior)
268 if (new_brk == 0 || (new_brk == brk_point))
269 return brk_point;
270
271 mem_state->updateBrkRegion(brk_point, new_brk);
272
273 DPRINTF_SYSCALL(Verbose, "brk: break point changed to: %#X\n",
274 mem_state->getBrkPoint());
275
276 return mem_state->getBrkPoint();
277}
278
279SyscallReturn
280setTidAddressFunc(SyscallDesc *desc, ThreadContext *tc, uint64_t tidPtr)
281{
282 auto process = tc->getProcessPtr();
283
284 process->childClearTID = tidPtr;
285 return process->pid();
286}
287
288SyscallReturn
289closeFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd)
290{
291 auto p = tc->getProcessPtr();
292 return p->fds->closeFDEntry(tgt_fd);
293}
294
295SyscallReturn
297 int tgt_fd, uint64_t offs, int whence)
298{
299 auto p = tc->getProcessPtr();
300
301 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*p->fds)[tgt_fd]);
302 if (!ffdp)
303 return -EBADF;
304 int sim_fd = ffdp->getSimFD();
305
306 off_t result = lseek(sim_fd, offs, whence);
307
308 return (result == (off_t)-1) ? -errno : result;
309}
310
311
312SyscallReturn
314 int tgt_fd, uint64_t offset_high, uint32_t offset_low,
315 VPtr<> result_ptr, int whence)
316{
317 auto p = tc->getProcessPtr();
318
319 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*p->fds)[tgt_fd]);
320 if (!ffdp)
321 return -EBADF;
322 int sim_fd = ffdp->getSimFD();
323
324 uint64_t offset = (offset_high << 32) | offset_low;
325
326 uint64_t result = lseek(sim_fd, offset, whence);
327 result = htog(result, tc->getSystemPtr()->getGuestByteOrder());
328
329 if (result == (off_t)-1)
330 return -errno;
331 // Assuming that the size of loff_t is 64 bits on the target platform
332 BufferArg result_buf(result_ptr, sizeof(result));
333 std::memcpy(result_buf.bufferPtr(), &result, sizeof(result));
334 result_buf.copyOut(SETranslatingPortProxy(tc));
335 return 0;
336}
337
338
339const char *hostname = "m5.eecs.umich.edu";
340
343 VPtr<> buf_ptr, int name_len)
344{
345 BufferArg name(buf_ptr, name_len);
346 strncpy((char *)name.bufferPtr(), hostname, name_len);
347 name.copyOut(SETranslatingPortProxy(tc));
348 return 0;
349}
350
351SyscallReturn
353 VPtr<> buf_ptr, unsigned long size)
354{
355 int result = 0;
356 auto p = tc->getProcessPtr();
357 BufferArg buf(buf_ptr, size);
358
359 // Is current working directory defined?
360 std::string cwd = p->tgtCwd;
361 if (!cwd.empty()) {
362 if (cwd.length() >= size) {
363 // Buffer too small
364 return -ERANGE;
365 }
366 strncpy((char *)buf.bufferPtr(), cwd.c_str(), size);
367 result = cwd.length();
368 } else {
369 if (getcwd((char *)buf.bufferPtr(), size)) {
370 result = strlen((char *)buf.bufferPtr());
371 } else {
372 result = -1;
373 }
374 }
375
377
378 return (result == -1) ? -errno : result;
379}
380
381SyscallReturn
383{
384 std::string path;
385 if (!SETranslatingPortProxy(tc).tryReadString(path, pathname))
386 return -EFAULT;
387
388 return unlinkImpl(desc, tc, path);
389}
390
391SyscallReturn
392unlinkImpl(SyscallDesc *desc, ThreadContext *tc, std::string path)
393{
394 auto p = tc->getProcessPtr();
395 path = p->checkPathRedirect(path);
396
397 int result = unlink(path.c_str());
398 return (result == -1) ? -errno : result;
399}
400
401SyscallReturn
403 VPtr<> pathname, VPtr<> new_pathname)
404{
405 std::string path;
406 std::string new_path;
407 auto p = tc->getProcessPtr();
408
409 SETranslatingPortProxy virt_mem(tc);
410 if (!virt_mem.tryReadString(path, pathname))
411 return -EFAULT;
412 if (!virt_mem.tryReadString(new_path, new_pathname))
413 return -EFAULT;
414
415 path = p->absolutePath(path, true);
416 new_path = p->absolutePath(new_path, true);
417
418 int result = link(path.c_str(), new_path.c_str());
419 return (result == -1) ? -errno : result;
420}
421
422SyscallReturn
424 VPtr<> pathname, VPtr<> new_pathname)
425{
426 std::string path;
427 std::string new_path;
428 auto p = tc->getProcessPtr();
429
430 SETranslatingPortProxy virt_mem(tc);
431 if (!virt_mem.tryReadString(path, pathname))
432 return -EFAULT;
433 if (!virt_mem.tryReadString(new_path, new_pathname))
434 return -EFAULT;
435
436 path = p->absolutePath(path, true);
437 new_path = p->absolutePath(new_path, true);
438
439 int result = symlink(path.c_str(), new_path.c_str());
440 return (result == -1) ? -errno : result;
441}
442
443SyscallReturn
444mkdirFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, mode_t mode)
445{
446 std::string path;
447 if (!SETranslatingPortProxy(tc).tryReadString(path, pathname))
448 return -EFAULT;
449
450 return mkdirImpl(desc, tc, path, mode);
451}
452
453SyscallReturn
454mkdirImpl(SyscallDesc *desc, ThreadContext *tc, std::string path, mode_t mode)
455{
456 auto p = tc->getProcessPtr();
457 path = p->checkPathRedirect(path);
458
459 auto result = mkdir(path.c_str(), mode);
460 return (result == -1) ? -errno : result;
461}
462
463SyscallReturn
465 VPtr<> newpath)
466{
467 SETranslatingPortProxy proxy(tc);
468 std::string old_name;
469 if (!proxy.tryReadString(old_name, oldpath))
470 return -EFAULT;
471
472 std::string new_name;
473 if (!proxy.tryReadString(new_name, newpath))
474 return -EFAULT;
475
476 return renameImpl(desc, tc, old_name, new_name);
477}
478
479SyscallReturn
481 std::string old_name, std::string new_name)
482{
483 auto p = tc->getProcessPtr();
484
485 // Adjust path for cwd and redirection
486 old_name = p->checkPathRedirect(old_name);
487 new_name = p->checkPathRedirect(new_name);
488
489 int64_t result = rename(old_name.c_str(), new_name.c_str());
490 return (result == -1) ? -errno : result;
491}
492
493
494SyscallReturn
496 VPtr<> pathname, int64_t length)
497{
498 auto process = tc->getProcessPtr();
499 std::string path;
500
501 if (!SETranslatingPortProxy(tc).tryReadString(path, pathname))
502 return -EFAULT;
503
504 // Adjust path for cwd and redirection
505 path = process->checkPathRedirect(path);
506
507#if NO_STAT64
508 int result = truncate(path.c_str(), length);
509#else
510 int result = truncate64(path.c_str(), length);
511#endif
512 return (result == -1) ? -errno : result;
513}
514
515SyscallReturn
517 int tgt_fd, int64_t length)
518{
519 auto p = tc->getProcessPtr();
520
521 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*p->fds)[tgt_fd]);
522 if (!ffdp)
523 return -EBADF;
524 int sim_fd = ffdp->getSimFD();
525
526#if NO_STAT64
527 int result = ftruncate(sim_fd, length);
528#else
529 int result = ftruncate64(sim_fd, length);
530#endif
531 return (result == -1) ? -errno : result;
532}
533
534SyscallReturn
536{
537 // Letting the simulated program change the simulator's umask seems like
538 // a bad idea. Compromise by just returning the current umask but not
539 // changing anything.
540 mode_t oldMask = umask(0);
541 umask(oldMask);
542 return (int)oldMask;
543}
544
545SyscallReturn
547 VPtr<> pathname, uint32_t owner, uint32_t group)
548{
549 std::string path;
550 if (!SETranslatingPortProxy(tc).tryReadString(path, pathname))
551 return -EFAULT;
552
553 return chownImpl(desc, tc, path, owner, group);
554}
555
556SyscallReturn
558 std::string path, uint32_t owner, uint32_t group)
559{
560 auto p = tc->getProcessPtr();
561
562 /* XXX endianess */
563 uid_t hostOwner = owner;
564 gid_t hostGroup = group;
565
566 // Adjust path for cwd and redirection
567 path = p->checkPathRedirect(path);
568
569 int result = chown(path.c_str(), hostOwner, hostGroup);
570 return (result == -1) ? -errno : result;
571}
572
573SyscallReturn
575 int tgt_fd, uint32_t owner, uint32_t group)
576{
577 auto p = tc->getProcessPtr();
578
579 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*p->fds)[tgt_fd]);
580 if (!ffdp)
581 return -EBADF;
582 int sim_fd = ffdp->getSimFD();
583
584 /* XXX endianess */
585 uid_t hostOwner = owner;
586 gid_t hostGroup = group;
587
588 int result = fchown(sim_fd, hostOwner, hostGroup);
589 return (result == -1) ? -errno : result;
590}
591
598SyscallReturn
599dupFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd)
600{
601 auto p = tc->getProcessPtr();
602
603 auto old_hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
604 if (!old_hbfdp)
605 return -EBADF;
606 int sim_fd = old_hbfdp->getSimFD();
607
608 int result = dup(sim_fd);
609 if (result == -1)
610 return -errno;
611
612 auto new_hbfdp = std::dynamic_pointer_cast<HBFDEntry>(old_hbfdp->clone());
613 new_hbfdp->setSimFD(result);
614 new_hbfdp->setCOE(false);
615 return p->fds->allocFD(new_hbfdp);
616}
617
618SyscallReturn
619dup2Func(SyscallDesc *desc, ThreadContext *tc, int old_tgt_fd, int new_tgt_fd)
620{
621 auto p = tc->getProcessPtr();
622 auto old_hbp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[old_tgt_fd]);
623 if (!old_hbp)
624 return -EBADF;
625 int old_sim_fd = old_hbp->getSimFD();
626
632 int res_fd = dup2(old_sim_fd, open("/dev/null", O_RDONLY));
633 if (res_fd == -1)
634 return -errno;
635
636 auto new_hbp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[new_tgt_fd]);
637 if (new_hbp)
638 p->fds->closeFDEntry(new_tgt_fd);
639 new_hbp = std::dynamic_pointer_cast<HBFDEntry>(old_hbp->clone());
640 new_hbp->setSimFD(res_fd);
641 new_hbp->setCOE(false);
642
643 return p->fds->allocFD(new_hbp);
644}
645
646SyscallReturn
648 int tgt_fd, int cmd, guest_abi::VarArgs<int> varargs)
649{
650 auto p = tc->getProcessPtr();
651
652 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
653 if (!hbfdp)
654 return -EBADF;
655 int sim_fd = hbfdp->getSimFD();
656
657 int coe = hbfdp->getCOE();
658
659 switch (cmd) {
660 case F_GETFD:
661 return coe & FD_CLOEXEC;
662
663 case F_SETFD: {
664 int arg = varargs.get<int>();
665 arg ? hbfdp->setCOE(true) : hbfdp->setCOE(false);
666 return 0;
667 }
668
669 // Rely on the host to maintain the file status flags for this file
670 // description rather than maintain it ourselves. Admittedly, this
671 // is suboptimal (and possibly error prone), but it is difficult to
672 // maintain the flags by tracking them across the different descriptors
673 // (that refer to this file description) caused by clone, dup, and
674 // subsequent fcntls.
675 case F_GETFL:
676 case F_SETFL: {
677 int arg = varargs.get<int>();
678 int rv = fcntl(sim_fd, cmd, arg);
679 return (rv == -1) ? -errno : rv;
680 }
681
682 default:
683 warn("fcntl: unsupported command %d\n", cmd);
684 return 0;
685 }
686}
687
688SyscallReturn
689fcntl64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int cmd)
690{
691 auto p = tc->getProcessPtr();
692
693 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
694 if (!hbfdp)
695 return -EBADF;
696 int sim_fd = hbfdp->getSimFD();
697
698 switch (cmd) {
699 case 33: //F_GETLK64
700 warn("fcntl64(%d, F_GETLK64) not supported, error returned\n", tgt_fd);
701 return -EMFILE;
702
703 case 34: // F_SETLK64
704 case 35: // F_SETLKW64
705 warn("fcntl64(%d, F_SETLK(W)64) not supported, error returned\n",
706 tgt_fd);
707 return -EMFILE;
708
709 default:
710 // not sure if this is totally valid, but we'll pass it through
711 // to the underlying OS
712 warn("fcntl64(%d, %d) passed through to host\n", tgt_fd, cmd);
713 return fcntl(sim_fd, cmd);
714 }
715}
716
717SyscallReturn
719{
720 return pipe2Func(desc, tc, 0, 0);
721}
722
723SyscallReturn
725{
726 return pipe2Func(desc, tc, tgt_addr, 0);
727}
728
729SyscallReturn
731{
732 auto p = tc->getProcessPtr();
733
734 int sim_fds[2], tgt_fds[2];
735
736 int pipe_retval = pipe(sim_fds);
737 if (pipe_retval == -1)
738 return -errno;
739
740 auto rend = PipeFDEntry::EndType::read;
741 auto rpfd = std::make_shared<PipeFDEntry>(sim_fds[0], O_WRONLY, rend);
742 tgt_fds[0] = p->fds->allocFD(rpfd);
743 int sim_fd_rpfd = rpfd->getSimFD();
744
745 auto wend = PipeFDEntry::EndType::write;
746 auto wpfd = std::make_shared<PipeFDEntry>(sim_fds[1], O_RDONLY, wend);
747 tgt_fds[1] = p->fds->allocFD(wpfd);
748 int sim_fd_wpfd = wpfd->getSimFD();
749
754 rpfd->setPipeReadSource(tgt_fds[1]);
755
761 if (tgt_addr == 0)
762 return SyscallReturn(tgt_fds[0], tgt_fds[1]);
763
768 BufferArg tgt_handle(tgt_addr, sizeof(int[2]));
769 int *buf_ptr = (int*)tgt_handle.bufferPtr();
770 buf_ptr[0] = tgt_fds[0];
771 buf_ptr[1] = tgt_fds[1];
772 tgt_handle.copyOut(SETranslatingPortProxy(tc));
773
774 if (flags) {
775 // pipe2 only uses O_NONBLOCK, O_CLOEXEC, and (O_NONBLOCK | O_CLOEXEC)
776 // if flags set to anything else, return EINVAL
777 if ((flags != O_CLOEXEC) && (flags != O_NONBLOCK) &&
778 (flags != (O_CLOEXEC | O_NONBLOCK))) {
779 return -EINVAL;
780 }
781
782 /*
783 If O_NONBLOCK is passed in as a flag to pipe2, set O_NONBLOCK file
784 status flag for two new open file descriptors.
785 */
786 if (flags & O_NONBLOCK) {
787 /*
788 O_NONBLOCK is set when the programmer wants to avoid a separate
789 call(s) to fcntl in their code, so mirror the fcntl
790 implementation for handling file descriptors -- rely on host to
791 maintain file status flags.
792 */
793 if (fcntl(sim_fd_rpfd, F_SETFL, O_NONBLOCK)) {
794 return -errno;
795 }
796 if (fcntl(sim_fd_wpfd, F_SETFL, O_NONBLOCK)) {
797 return -errno;
798 }
799 }
800
801 /*
802 If O_CLOEXEC is passed in as a flag to pipe2, set close-on-exec
803 (FD_CLOEXEC) file status flag for two new open file descriptors.
804 */
805 if (flags & O_CLOEXEC) {
806 rpfd->setCOE(true);
807 wpfd->setCOE(true);
808 }
809 }
810
811 return 0;
812}
813
814SyscallReturn
816{
817 auto process = tc->getProcessPtr();
818 return process->pgid();
819}
820
821SyscallReturn
822setpgidFunc(SyscallDesc *desc, ThreadContext *tc, int pid, int pgid)
823{
824 auto process = tc->getProcessPtr();
825
826 if (pgid < 0)
827 return -EINVAL;
828
829 if (pid == 0) {
830 process->pgid(process->pid());
831 return 0;
832 }
833
834 Process *matched_ph = nullptr;
835 System *sysh = tc->getSystemPtr();
836
837 // Retrieves process pointer from active/suspended thread contexts.
838 for (auto *tc: sysh->threads) {
839 if (tc->status() != ThreadContext::Halted) {
840 Process *temp_h = tc->getProcessPtr();
841 Process *walk_ph = (Process*)temp_h;
842
843 if (walk_ph && walk_ph->pid() == process->pid())
844 matched_ph = walk_ph;
845 }
846 }
847
848 assert(matched_ph);
849 matched_ph->pgid((pgid == 0) ? matched_ph->pid() : pgid);
850
851 return 0;
852}
853
854
855SyscallReturn
857{
858 auto process = tc->getProcessPtr();
859 return process->tgid();
860}
861
862SyscallReturn
864{
865 auto process = tc->getProcessPtr();
866 return process->pid();
867}
868
869SyscallReturn
871{
872 auto process = tc->getProcessPtr();
873 return process->ppid();
874}
875
876SyscallReturn
878{
879 auto process = tc->getProcessPtr();
880 return process->uid(); // UID
881}
882
883SyscallReturn
885{
886 auto process = tc->getProcessPtr();
887 return process->euid(); // UID
888}
889
890SyscallReturn
892{
893 auto process = tc->getProcessPtr();
894 return process->gid();
895}
896
897SyscallReturn
899{
900 auto process = tc->getProcessPtr();
901 return process->egid();
902}
903
904SyscallReturn
906 VPtr<> pathname, mode_t mode)
907{
908 std::string path;
909 if (!SETranslatingPortProxy(tc).tryReadString(path, pathname))
910 return -EFAULT;
911
912 return accessImpl(desc, tc, path, mode);
913}
914
915SyscallReturn
917 std::string path, mode_t mode)
918{
919 auto p = tc->getProcessPtr();
920 // Adjust path for cwd and redirection
921 path = p->checkPathRedirect(path);
922
923 int result = access(path.c_str(), mode);
924 return (result == -1) ? -errno : result;
925}
926
927SyscallReturn
929 VPtr<> pathname, mode_t mode, dev_t dev)
930{
931 std::string path;
932 if (!SETranslatingPortProxy(tc).tryReadString(path, pathname))
933 return -EFAULT;
934
935 return mknodImpl(desc, tc, path, mode, dev);
936}
937
938SyscallReturn
940 std::string path, mode_t mode, dev_t dev)
941{
942 auto p = tc->getProcessPtr();
943 path = p->checkPathRedirect(path);
944
945 auto result = mknod(path.c_str(), mode, dev);
946 return (result == -1) ? -errno : result;
947}
948
949SyscallReturn
951{
952 auto p = tc->getProcessPtr();
953 std::string path;
954 if (!SETranslatingPortProxy(tc).tryReadString(path, pathname))
955 return -EFAULT;
956
957 std::string tgt_cwd;
958 if (startswith(path, "/")) {
959 tgt_cwd = path;
960 } else {
961 char buf[PATH_MAX];
962 if (!realpath((p->tgtCwd + "/" + path).c_str(), buf))
963 return -errno;
964 tgt_cwd = buf;
965 }
966 std::string host_cwd = p->checkPathRedirect(tgt_cwd);
967
968 int result = chdir(host_cwd.c_str());
969
970 if (result == -1)
971 return -errno;
972
973 p->hostCwd = host_cwd;
974 p->tgtCwd = tgt_cwd;
975 return result;
976}
977
978SyscallReturn
980{
981 std::string path;
982 if (!SETranslatingPortProxy(tc).tryReadString(path, pathname))
983 return -EFAULT;
984
985 return rmdirImpl(desc, tc, path);
986}
987
988SyscallReturn
989rmdirImpl(SyscallDesc *desc, ThreadContext *tc, std::string path)
990{
991 auto p = tc->getProcessPtr();
992 path = p->checkPathRedirect(path);
993
994 auto result = rmdir(path.c_str());
995 return (result == -1) ? -errno : result;
996}
997
998#if defined(SYS_getdents) || defined(SYS_getdents64)
999template<typename DE, int SYS_NUM>
1000static SyscallReturn
1001getdentsImpl(SyscallDesc *desc, ThreadContext *tc,
1002 int tgt_fd, VPtr<> buf_ptr, unsigned count)
1003{
1004 auto p = tc->getProcessPtr();
1005
1006 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
1007 if (!hbfdp)
1008 return -EBADF;
1009 int sim_fd = hbfdp->getSimFD();
1010
1011 BufferArg buf_arg(buf_ptr, count);
1012 auto status = syscall(SYS_NUM, sim_fd, buf_arg.bufferPtr(), count);
1013
1014 if (status == -1)
1015 return -errno;
1016
1017 unsigned traversed = 0;
1018 while (traversed < status) {
1019 DE *buffer = (DE*)((Addr)buf_arg.bufferPtr() + traversed);
1020
1021 auto host_reclen = buffer->d_reclen;
1022
1028 const ByteOrder bo = tc->getSystemPtr()->getGuestByteOrder();
1029 buffer->d_ino = htog(buffer->d_ino, bo);
1030 buffer->d_off = htog(buffer->d_off, bo);
1031 buffer->d_reclen = htog(buffer->d_reclen, bo);
1032
1033 traversed += host_reclen;
1034 }
1035
1036 buf_arg.copyOut(SETranslatingPortProxy(tc));
1037 return status;
1038}
1039#endif
1040
1041#if defined(SYS_getdents)
1042SyscallReturn
1043getdentsFunc(SyscallDesc *desc, ThreadContext *tc,
1044 int tgt_fd, VPtr<> buf_ptr, unsigned count)
1045{
1046 typedef struct linux_dirent
1047 {
1048 unsigned long d_ino;
1049 unsigned long d_off;
1050 unsigned short d_reclen;
1051 char dname[];
1052 } LinDent;
1053
1054 return getdentsImpl<LinDent, SYS_getdents>(desc, tc,
1055 tgt_fd, buf_ptr, count);
1056}
1057#endif
1058
1059#if defined(SYS_getdents64)
1060SyscallReturn
1061getdents64Func(SyscallDesc *desc, ThreadContext *tc,
1062 int tgt_fd, VPtr<> buf_ptr, unsigned count)
1063{
1064 typedef struct linux_dirent64
1065 {
1066 ino64_t d_ino;
1067 off64_t d_off;
1068 unsigned short d_reclen;
1069 char dname[];
1070 } LinDent64;
1071
1072 return getdentsImpl<LinDent64, SYS_getdents64>(desc, tc,
1073 tgt_fd, buf_ptr, count);
1074}
1075#endif
1076
1077SyscallReturn
1078shutdownFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int how)
1079{
1080 auto p = tc->getProcessPtr();
1081
1082 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1083 if (!sfdp)
1084 return -EBADF;
1085 int sim_fd = sfdp->getSimFD();
1086
1087 int retval = shutdown(sim_fd, how);
1088
1089 return (retval == -1) ? -errno : retval;
1090}
1091
1092SyscallReturn
1094 int tgt_fd, VPtr<> buf_ptr, int addrlen)
1095{
1096 auto p = tc->getProcessPtr();
1097
1098 BufferArg bufSock(buf_ptr, addrlen);
1099 bufSock.copyIn(SETranslatingPortProxy(tc));
1100
1101 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1102 if (!sfdp)
1103 return -EBADF;
1104 int sim_fd = sfdp->getSimFD();
1105
1106 int status = ::bind(sim_fd,
1107 (struct sockaddr *)bufSock.bufferPtr(),
1108 addrlen);
1109
1110 return (status == -1) ? -errno : status;
1111}
1112
1113SyscallReturn
1114listenFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int backlog)
1115{
1116 auto p = tc->getProcessPtr();
1117
1118 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1119 if (!sfdp)
1120 return -EBADF;
1121 int sim_fd = sfdp->getSimFD();
1122
1123 int status = listen(sim_fd, backlog);
1124
1125 return (status == -1) ? -errno : status;
1126}
1127
1128SyscallReturn
1130 int tgt_fd, VPtr<> buf_ptr, int addrlen)
1131{
1132 auto p = tc->getProcessPtr();
1133
1134 BufferArg addr(buf_ptr, addrlen);
1135 addr.copyIn(SETranslatingPortProxy(tc));
1136
1137 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1138 if (!sfdp)
1139 return -EBADF;
1140 int sim_fd = sfdp->getSimFD();
1141
1142 int status = connect(sim_fd,
1143 (struct sockaddr *)addr.bufferPtr(),
1144 (socklen_t)addrlen);
1145
1146 return (status == -1) ? -errno : status;
1147}
1148
1149
1150SyscallReturn
1152 int tgt_fd, VPtr<> msgPtr, int flags)
1153{
1154 auto p = tc->getProcessPtr();
1155
1156 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1157 if (!sfdp)
1158 return -EBADF;
1159 int sim_fd = sfdp->getSimFD();
1160
1179 SETranslatingPortProxy proxy(tc);
1180
1186 BufferArg msgBuf(msgPtr, sizeof(struct msghdr));
1187 msgBuf.copyIn(proxy);
1188 struct msghdr *msgHdr = (struct msghdr *)msgBuf.bufferPtr();
1189
1195 Addr msg_name_phold = 0;
1196 Addr msg_iov_phold = 0;
1197 Addr iovec_base_phold[msgHdr->msg_iovlen];
1198 Addr msg_control_phold = 0;
1199
1203 BufferArg *nameBuf = NULL;
1204 if (msgHdr->msg_name) {
1205 /*1*/msg_name_phold = (Addr)msgHdr->msg_name;
1206 /*2*/nameBuf = new BufferArg(msg_name_phold, msgHdr->msg_namelen);
1207 /*3*/nameBuf->copyIn(proxy);
1208 /*4*/msgHdr->msg_name = nameBuf->bufferPtr();
1209 }
1210
1216 BufferArg *iovBuf = NULL;
1217 BufferArg *iovecBuf[msgHdr->msg_iovlen];
1218 for (int i = 0; i < msgHdr->msg_iovlen; i++) {
1219 iovec_base_phold[i] = 0;
1220 iovecBuf[i] = NULL;
1221 }
1222
1223 if (msgHdr->msg_iov) {
1224 /*1*/msg_iov_phold = (Addr)msgHdr->msg_iov;
1225 /*2*/iovBuf = new BufferArg(msg_iov_phold, msgHdr->msg_iovlen *
1226 sizeof(struct iovec));
1227 /*3*/iovBuf->copyIn(proxy);
1228 for (int i = 0; i < msgHdr->msg_iovlen; i++) {
1229 if (((struct iovec *)iovBuf->bufferPtr())[i].iov_base) {
1230 /*1*/iovec_base_phold[i] =
1231 (Addr)((struct iovec *)iovBuf->bufferPtr())[i].iov_base;
1232 /*2*/iovecBuf[i] = new BufferArg(iovec_base_phold[i],
1233 ((struct iovec *)iovBuf->bufferPtr())[i].iov_len);
1234 /*3*/iovecBuf[i]->copyIn(proxy);
1235 /*4*/((struct iovec *)iovBuf->bufferPtr())[i].iov_base =
1236 iovecBuf[i]->bufferPtr();
1237 }
1238 }
1239 /*4*/msgHdr->msg_iov = (struct iovec *)iovBuf->bufferPtr();
1240 }
1241
1245 BufferArg *controlBuf = NULL;
1246 if (msgHdr->msg_control) {
1247 /*1*/msg_control_phold = (Addr)msgHdr->msg_control;
1248 /*2*/controlBuf = new BufferArg(msg_control_phold,
1249 CMSG_ALIGN(msgHdr->msg_controllen));
1250 /*3*/controlBuf->copyIn(proxy);
1251 /*4*/msgHdr->msg_control = controlBuf->bufferPtr();
1252 }
1253
1254 ssize_t recvd_size = recvmsg(sim_fd, msgHdr, flags);
1255
1256 if (recvd_size < 0)
1257 return -errno;
1258
1259 if (msgHdr->msg_name) {
1260 nameBuf->copyOut(proxy);
1261 delete(nameBuf);
1262 msgHdr->msg_name = (void *)msg_name_phold;
1263 }
1264
1265 if (msgHdr->msg_iov) {
1266 for (int i = 0; i< msgHdr->msg_iovlen; i++) {
1267 if (((struct iovec *)iovBuf->bufferPtr())[i].iov_base) {
1268 iovecBuf[i]->copyOut(proxy);
1269 delete iovecBuf[i];
1270 ((struct iovec *)iovBuf->bufferPtr())[i].iov_base =
1271 (void *)iovec_base_phold[i];
1272 }
1273 }
1274 iovBuf->copyOut(proxy);
1275 delete iovBuf;
1276 msgHdr->msg_iov = (struct iovec *)msg_iov_phold;
1277 }
1278
1279 if (msgHdr->msg_control) {
1280 controlBuf->copyOut(proxy);
1281 delete(controlBuf);
1282 msgHdr->msg_control = (void *)msg_control_phold;
1283 }
1284
1285 msgBuf.copyOut(proxy);
1286
1287 return recvd_size;
1288}
1289
1290SyscallReturn
1292 int tgt_fd, VPtr<> msgPtr, int flags)
1293{
1294 auto p = tc->getProcessPtr();
1295
1296 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1297 if (!sfdp)
1298 return -EBADF;
1299 int sim_fd = sfdp->getSimFD();
1300
1301 SETranslatingPortProxy proxy(tc);
1302
1306 BufferArg msgBuf(msgPtr, sizeof(struct msghdr));
1307 msgBuf.copyIn(proxy);
1308 struct msghdr msgHdr = *((struct msghdr *)msgBuf.bufferPtr());
1309
1314 struct iovec *iovPtr = msgHdr.msg_iov;
1315 BufferArg iovBuf((Addr)iovPtr, sizeof(struct iovec) * msgHdr.msg_iovlen);
1316 iovBuf.copyIn(proxy);
1317 struct iovec *iov = (struct iovec *)iovBuf.bufferPtr();
1318 msgHdr.msg_iov = iov;
1319
1325 BufferArg **bufferArray = (BufferArg **)malloc(msgHdr.msg_iovlen
1326 * sizeof(BufferArg *));
1327
1333 for (int iovIndex = 0 ; iovIndex < msgHdr.msg_iovlen; iovIndex++) {
1334 Addr basePtr = (Addr) iov[iovIndex].iov_base;
1335 bufferArray[iovIndex] = new BufferArg(basePtr, iov[iovIndex].iov_len);
1336 bufferArray[iovIndex]->copyIn(proxy);
1337 iov[iovIndex].iov_base = bufferArray[iovIndex]->bufferPtr();
1338 }
1339
1340 ssize_t sent_size = sendmsg(sim_fd, &msgHdr, flags);
1341 int local_errno = errno;
1342
1346 for (int iovIndex = 0 ; iovIndex < msgHdr.msg_iovlen; iovIndex++) {
1347 BufferArg *baseBuf = ( BufferArg *)bufferArray[iovIndex];
1348 delete(baseBuf);
1349 }
1350
1354 free(bufferArray);
1355
1356 return (sent_size < 0) ? -local_errno : sent_size;
1357}
1358
1359SyscallReturn
1361 int tgt_fd, int level, int optname, VPtr<> valPtr,
1362 VPtr<> lenPtr)
1363{
1364 // union of all possible return value types from getsockopt
1365 union val
1366 {
1367 int i_val;
1368 long l_val;
1369 struct linger linger_val;
1370 struct timeval timeval_val;
1371 } val;
1372
1373 auto p = tc->getProcessPtr();
1374
1375 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1376 if (!sfdp)
1377 return -EBADF;
1378 int sim_fd = sfdp->getSimFD();
1379
1380 socklen_t len = sizeof(val);
1381 int status = getsockopt(sim_fd, level, optname, &val, &len);
1382
1383 if (status == -1)
1384 return -errno;
1385
1386 SETranslatingPortProxy proxy(tc);
1387
1388 // copy val to valPtr and pass it on
1389 BufferArg valBuf(valPtr, sizeof(val));
1390 memcpy(valBuf.bufferPtr(), &val, sizeof(val));
1391 valBuf.copyOut(proxy);
1392
1393 // copy len to lenPtr and pass it on
1394 BufferArg lenBuf(lenPtr, sizeof(len));
1395 memcpy(lenBuf.bufferPtr(), &len, sizeof(len));
1396 lenBuf.copyOut(proxy);
1397
1398 return status;
1399}
1400
1401SyscallReturn
1403 int tgt_fd, VPtr<> addrPtr, VPtr<> lenPtr)
1404{
1405 auto p = tc->getProcessPtr();
1406
1407 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1408 if (!sfdp)
1409 return -EBADF;
1410 int sim_fd = sfdp->getSimFD();
1411
1412 // lenPtr is an in-out paramenter:
1413 // sending the address length in, conveying the final length out
1414
1415 SETranslatingPortProxy proxy(tc);
1416
1417 // Read in the value of len from the passed pointer.
1418 BufferArg lenBuf(lenPtr, sizeof(socklen_t));
1419 lenBuf.copyIn(proxy);
1420 socklen_t len = *(socklen_t *)lenBuf.bufferPtr();
1421
1422 struct sockaddr sa;
1423 int status = getsockname(sim_fd, &sa, &len);
1424
1425 if (status == -1)
1426 return -errno;
1427
1428 // Copy address to addrPtr and pass it on.
1429 BufferArg addrBuf(addrPtr, sizeof(sa));
1430 memcpy(addrBuf.bufferPtr(), &sa, sizeof(sa));
1431 addrBuf.copyOut(proxy);
1432
1433 // Copy len to lenPtr and pass it on.
1434 *(socklen_t *)lenBuf.bufferPtr() = len;
1435 lenBuf.copyOut(proxy);
1436
1437 return status;
1438}
1439
1440SyscallReturn
1442 int tgt_fd, VPtr<> sockAddrPtr, VPtr<> addrlenPtr)
1443{
1444 auto p = tc->getProcessPtr();
1445
1446 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1447 if (!sfdp)
1448 return -EBADF;
1449 int sim_fd = sfdp->getSimFD();
1450
1451 SETranslatingPortProxy proxy(tc);
1452
1453 BufferArg bufAddrlen(addrlenPtr, sizeof(unsigned));
1454 bufAddrlen.copyIn(proxy);
1455 BufferArg bufSock(sockAddrPtr, *(unsigned *)bufAddrlen.bufferPtr());
1456
1457 int retval = getpeername(sim_fd,
1458 (struct sockaddr *)bufSock.bufferPtr(),
1459 (unsigned *)bufAddrlen.bufferPtr());
1460
1461 if (retval != -1) {
1462 bufSock.copyOut(proxy);
1463 bufAddrlen.copyOut(proxy);
1464 }
1465
1466 return (retval == -1) ? -errno : retval;
1467}
1468
1469SyscallReturn
1471 int tgt_fd, int level, int optname, VPtr<> valPtr,
1472 socklen_t len)
1473{
1474 auto p = tc->getProcessPtr();
1475
1476 BufferArg valBuf(valPtr, len);
1477 valBuf.copyIn(SETranslatingPortProxy(tc));
1478
1479 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1480 if (!sfdp)
1481 return -EBADF;
1482 int sim_fd = sfdp->getSimFD();
1483
1484 int status = setsockopt(sim_fd, level, optname,
1485 (struct sockaddr *)valBuf.bufferPtr(), len);
1486
1487 return (status == -1) ? -errno : status;
1488}
1489
1490SyscallReturn
1493{
1494 // unsigned is the same size (4) on all Linux supported ISAs.
1495 if (cpu)
1496 *cpu = htog(tc->contextId(), tc->getSystemPtr()->getGuestByteOrder());
1497
1498 // Set a fixed NUMA node 0.
1499 if (node)
1500 *node = 0;
1501
1502 return 0;
1503}
1504
1505} // namespace gem5
Declaration and inline definition of ChunkGenerator object.
bool copyIn(const PortProxy &memproxy)
copy data into simulator space (read from target memory)
bool copyOut(const PortProxy &memproxy)
copy data out of simulator space (write to target memory)
BufferArg represents an untyped buffer in target user space that is passed by reference to an (emulat...
void * bufferPtr()
Return a pointer to the internal simulator-space buffer.
static bool readyToExit(Tick delay)
Initiate the exit from the simulation.
FutexMap class holds a map of all futexes used in the system.
Definition futex_map.hh:110
int wakeup(Addr addr, uint64_t tgid, int count)
Wakes up at most count waiting threads on a futex.
Definition futex_map.cc:59
bool tryReadString(std::string &str, Addr addr) const
Reads the string at guest address addr into the std::string str.
uint64_t egid()
Definition process.hh:85
std::shared_ptr< MemState > memState
Definition process.hh:289
uint64_t pid()
Definition process.hh:86
uint64_t uid()
Definition process.hh:82
uint64_t pgid()
Definition process.hh:88
std::shared_ptr< FDArray > fds
Definition process.hh:286
uint64_t ppid()
Definition process.hh:87
std::string checkPathRedirect(const std::string &filename)
Redirect file path if it matches any keys initialized by system object.
Definition process.cc:424
uint64_t gid()
Definition process.hh:84
uint64_t tgid()
Definition process.hh:90
uint64_t euid()
Definition process.hh:83
EmulationPageTable * pTable
Definition process.hh:184
uint64_t childClearTID
Calls a futex wakeup at the address specified by this pointer when this process exits.
Definition process.hh:295
This class provides the wrapper interface for the system call implementations which are defined in th...
std::string name() const
This class represents the return value from an emulated system call, including any errno setting.
int size() const
Definition system.hh:210
std::list< BasicSignal > signalList
Definition system.hh:607
FutexMap futexMap
Definition system.hh:598
ByteOrder getGuestByteOrder() const
Get the guest byte order.
Definition system.hh:388
static std::vector< System * > systemList
Definition system.hh:593
Threads threads
Definition system.hh:310
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual void activate()=0
Set the status to Active.
virtual System * getSystemPtr()=0
virtual void halt()=0
Set the status to Halted.
@ Halted
Permanently shut down.
@ Halting
Trying to exit and waiting for an event to completely exit.
@ Suspended
Temporarily inactive.
virtual Status status() const =0
virtual Process * getProcessPtr()=0
virtual ContextID contextId() const =0
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:200
uint8_t flags
Definition helpers.cc:87
#define warn(...)
Definition logging.hh:256
Bitfield< 3 > sa
Bitfield< 18, 16 > len
Bitfield< 4, 0 > mode
Definition misc_types.hh:74
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 23, 0 > offset
Definition types.hh:144
Bitfield< 5, 0 > status
Bitfield< 0 > p
Bitfield< 25, 21 > bo
Definition types.hh:82
Bitfield< 15 > system
Definition misc.hh:1032
Bitfield< 63 > val
Definition misc.hh:804
Bitfield< 20 > level
Definition intmessage.hh:51
Bitfield< 3 > addr
Definition types.hh:84
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
SyscallReturn linkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr<> new_pathname)
Target link() handler.
SyscallReturn getppidFunc(SyscallDesc *desc, ThreadContext *tc)
Target getppid() handler.
SyscallReturn exitGroupFunc(SyscallDesc *desc, ThreadContext *tc, int status)
Target exit_group() handler: terminate simulation. (exit all threads)
SyscallReturn gettidFunc(SyscallDesc *desc, ThreadContext *tc)
Target gettid() handler.
SyscallReturn recvmsgFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> msgPtr, int flags)
void warnUnsupportedOS(std::string syscall_name)
SyscallReturn brkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> new_brk)
Target brk() handler: set brk address.
SyscallReturn pipe2Func(SyscallDesc *desc, ThreadContext *tc, VPtr<> tgt_addr, int flags)
Target pipe() handler.
SyscallReturn getpidFunc(SyscallDesc *desc, ThreadContext *tc)
Target getpid() handler.
bool startswith(const char *s, const char *prefix)
Return true if 's' starts with the prefix string 'prefix'.
Definition str.hh:230
SyscallReturn chdirFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname)
Target chdir() handler.
SyscallReturn truncate64Func(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, int64_t length)
Target truncate64() handler.
SyscallReturn getuidFunc(SyscallDesc *desc, ThreadContext *tc)
SyscallReturn pipePseudoFunc(SyscallDesc *desc, ThreadContext *tc)
Pseudo Funcs - These functions use a different return convension, returning a second value in a regis...
static void exitFutexWake(ThreadContext *tc, VPtr<> addr, uint64_t tgid)
SyscallReturn chownFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, uint32_t owner, uint32_t group)
Target chown() handler.
const char * hostname
SyscallReturn renameImpl(SyscallDesc *desc, ThreadContext *tc, std::string old_name, std::string new_name)
SyscallReturn mknodImpl(SyscallDesc *desc, ThreadContext *tc, std::string path, mode_t mode, dev_t dev)
SyscallReturn renameFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> oldpath, VPtr<> newpath)
Target rename() handler.
SyscallReturn mknodFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, mode_t mode, dev_t dev)
Target mknod() handler.
SyscallReturn _llseekFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint64_t offset_high, uint32_t offset_low, VPtr<> result_ptr, int whence)
Target _llseek() handler.
SyscallReturn setTidAddressFunc(SyscallDesc *desc, ThreadContext *tc, uint64_t tidPtr)
Target set_tid_address() handler.
SyscallReturn setpgidFunc(SyscallDesc *desc, ThreadContext *tc, int pid, int pgid)
Target setpgid() handler.
SyscallReturn geteuidFunc(SyscallDesc *desc, ThreadContext *tc)
Target geteuid() handler.
SyscallReturn getcwdFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> buf_ptr, unsigned long size)
Target getcwd() handler.
SyscallReturn symlinkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr<> new_pathname)
Target symlink() handler.
ProxyPtr< T, SETranslatingPortProxy > VPtr
Definition proxy_ptr.hh:400
SyscallReturn unlinkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname)
Target unlink() handler.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
SyscallReturn accessImpl(SyscallDesc *desc, ThreadContext *tc, std::string path, mode_t mode)
SyscallReturn chownImpl(SyscallDesc *desc, ThreadContext *tc, std::string path, uint32_t owner, uint32_t group)
SyscallReturn pipeFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> tgt_addr)
Target pipe() handler.
SyscallReturn getsockoptFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int level, int optname, VPtr<> valPtr, VPtr<> lenPtr)
SyscallReturn fcntl64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int cmd)
Target fcntl64() handler.
SyscallReturn ignoreWarnOnceFunc(SyscallDesc *desc, ThreadContext *tc)
Like above, but only prints a warning once per syscall desc it's used with.
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 (...
Definition sim_events.cc:88
SyscallReturn setsockoptFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int level, int optname, VPtr<> valPtr, socklen_t len)
SyscallReturn getpagesizeFunc(SyscallDesc *desc, ThreadContext *tc)
Target getpagesize() handler.
SyscallReturn rmdirFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname)
SyscallReturn mkdirFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, mode_t mode)
Target mkdir() handler.
SyscallReturn getpgrpFunc(SyscallDesc *desc, ThreadContext *tc)
Target getpgrpFunc() handler.
SyscallReturn unlinkImpl(SyscallDesc *desc, ThreadContext *tc, std::string path)
SyscallReturn dupFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd)
FIXME: The file description is not shared among file descriptors created with dup.
SyscallReturn listenFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int backlog)
SyscallReturn ftruncate64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int64_t length)
Target ftruncate64() handler.
SyscallReturn fchownFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint32_t owner, uint32_t group)
Target fchown() handler.
SyscallReturn fcntlFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int cmd, guest_abi::VarArgs< int > varargs)
Target fcntl() handler.
T htog(T value, ByteOrder guest_byte_order)
Definition byteswap.hh:187
SyscallReturn bindFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> buf_ptr, int addrlen)
SyscallReturn getegidFunc(SyscallDesc *desc, ThreadContext *tc)
Target getegid() handler.
SyscallReturn shutdownFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int how)
Target shutdown() handler.
SyscallReturn getcpuFunc(SyscallDesc *desc, ThreadContext *tc, VPtr< uint32_t > cpu, VPtr< uint32_t > node, VPtr< uint32_t > tcache)
SyscallReturn getsocknameFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> addrPtr, VPtr<> lenPtr)
SyscallReturn mkdirImpl(SyscallDesc *desc, ThreadContext *tc, std::string path, mode_t mode)
SyscallReturn getpeernameFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> sockAddrPtr, VPtr<> addrlenPtr)
SyscallReturn lseekFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint64_t offs, int whence)
Target lseek() handler.
SyscallReturn unimplementedFunc(SyscallDesc *desc, ThreadContext *tc)
Handler for unimplemented syscalls that we haven't thought about.
SyscallReturn gethostnameFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> buf_ptr, int name_len)
Target gethostname() handler.
SyscallReturn accessFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, mode_t mode)
Target access() handler.
SyscallReturn sendmsgFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> msgPtr, int flags)
SyscallReturn ignoreFunc(SyscallDesc *desc, ThreadContext *tc)
Handler for unimplemented syscalls that we never intend to implement (signal handling,...
SyscallReturn rmdirImpl(SyscallDesc *desc, ThreadContext *tc, std::string path)
static SyscallReturn exitImpl(SyscallDesc *desc, ThreadContext *tc, bool group, int status)
SyscallReturn connectFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> buf_ptr, int addrlen)
SyscallReturn exitFunc(SyscallDesc *desc, ThreadContext *tc, int status)
Target exit() handler: terminate current context.
SyscallReturn dup2Func(SyscallDesc *desc, ThreadContext *tc, int old_tgt_fd, int new_tgt_fd)
Target dup2() handler.
SyscallReturn getgidFunc(SyscallDesc *desc, ThreadContext *tc)
Target getgid() handler.
SyscallReturn closeFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd)
Target close() handler.
SyscallReturn umaskFunc(SyscallDesc *desc, ThreadContext *tc)
Target umask() handler.
Declarations of a non-full system Page Table.
#define DPRINTF_SYSCALL(FLAGEXT, FMT,...)
This macro is intended to help with readability.
This file defines objects used to emulate syscalls from the target application on the host machine.
const std::string & name()
Definition trace.cc:48

Generated on Tue Jun 18 2024 16:24:06 for gem5 by doxygen 1.11.0