gem5 v24.1.0.1
Loading...
Searching...
No Matches
syscall_emul.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 Arm Limited
3 *
4 * The license below extends only to copyright in the software and
5 * shall not be construed as granting a license to any other
6 * intellectual property including but not limited to intellectual
7 * property relating to a hardware implementation of the
8 * functionality of the software licensed hereunder. You may use the
9 * software subject to the license terms below provided that you
10 * ensure that this notice is replicated unmodified and in its
11 * entirety in all distributions of the software, modified or
12 * unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2003-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 */
40
41#include "sim/syscall_emul.hh"
42
43#include <fcntl.h>
44#include <sys/syscall.h>
45#include <unistd.h>
46
47#include <csignal>
48#include <iostream>
49#include <mutex>
50#include <string>
51#include <unordered_map>
52
54#include "base/trace.hh"
55#include "cpu/thread_context.hh"
56#include "dev/net/dist_iface.hh"
57#include "mem/page_table.hh"
59#include "sim/byteswap.hh"
60#include "sim/process.hh"
61#include "sim/proxy_ptr.hh"
62#include "sim/sim_exit.hh"
64#include "sim/syscall_desc.hh"
65#include "sim/system.hh"
66
67namespace gem5
68{
69
70void
71warnUnsupportedOS(std::string syscall_name)
72{
73 warn("Cannot invoke %s on host operating system.", syscall_name);
74}
75
76SyscallReturn
78{
79 fatal("syscall %s (#%d) unimplemented.", desc->name(), desc->num());
80}
81
82
83SyscallReturn
85{
86 warn("ignoring syscall %s(...)", desc->name());
87 return 0;
88}
89
90SyscallReturn
92{
93 static std::unordered_map<SyscallDesc *, bool> bool_map;
94
95 bool &warned = bool_map[desc];
96 if (!warned) {
97 warn("ignoring syscall %s(...)\n"
98 " (further warnings will be suppressed)", desc->name());
99 warned = true;
100 }
101
102 return 0;
103}
104
105static void
107{
108 // Clear value at address pointed to by thread's childClearTID field.
109 BufferArg ctidBuf(addr, sizeof(long));
110 long *ctid = (long *)ctidBuf.bufferPtr();
111 *ctid = 0;
112 ctidBuf.copyOut(SETranslatingPortProxy(tc));
113
114 FutexMap &futex_map = tc->getSystemPtr()->futexMap;
115 // Wake one of the waiting threads.
116 futex_map.wakeup(addr, tgid, 1);
117}
118
119static SyscallReturn
120exitImpl(SyscallDesc *desc, ThreadContext *tc, bool group, int status)
121{
122 auto p = tc->getProcessPtr();
123
124 System *sys = tc->getSystemPtr();
125
126 if (group)
127 *p->exitGroup = true;
128
129 if (p->childClearTID)
130 exitFutexWake(tc, p->childClearTID, p->tgid());
131
132 bool last_thread = true;
133 Process *parent = nullptr, *tg_lead = nullptr;
134 for (int i = 0; last_thread && i < sys->threads.size(); i++) {
135 Process *walk;
136 if (!(walk = sys->threads[i]->getProcessPtr()))
137 continue;
138
145 if (walk->pid() == p->tgid())
146 tg_lead = walk;
147
148 auto *tc = sys->threads[i];
149 if ((tc->status() != ThreadContext::Halted) &&
150 (tc->status() != ThreadContext::Halting) &&
151 (walk != p)) {
158 if (walk->tgid() == p->tgid()) {
171 if (*(p->exitGroup)) {
172 tc->halt();
173 } else {
174 last_thread = false;
175 }
176 }
177
187 if (*p->sigchld && (p->ppid() != 0) && (walk->pid() == p->ppid()))
188 parent = walk;
189 }
190 }
191
192 if (last_thread) {
193 if (parent) {
194 assert(tg_lead);
195 sys->signalList.push_back(BasicSignal(tg_lead, parent, SIGCHLD));
196 }
197
203 for (int i = 0; i < p->fds->getSize(); i++) {
204 if ((*p->fds)[i])
205 p->fds->closeFDEntry(i);
206 }
207 }
208
213 if (!p->vforkContexts.empty()) {
214 ThreadContext *vtc = sys->threads[p->vforkContexts.front()];
215 assert(vtc->status() == ThreadContext::Suspended);
216 vtc->activate();
217 }
218
219 tc->halt();
220
225 int activeContexts = 0;
226 for (auto &system: sys->systemList)
227 activeContexts += system->threads.numRunning();
228
229 if (activeContexts == 0) {
239 if (!DistIface::readyToExit(0)) {
240 return status;
241 }
242
243 exitSimLoop("exiting with last active thread context", status & 0xff);
244 return status;
245 }
246
247 return status;
248}
249
250SyscallReturn
252{
253 return exitImpl(desc, tc, false, status);
254}
255
256SyscallReturn
258{
259 return exitImpl(desc, tc, true, status);
260}
261
262SyscallReturn
264{
265 return (int)tc->getProcessPtr()->pTable->pageSize();
266}
267
268
269SyscallReturn
271{
272 // change brk addr to first arg
273 auto p = tc->getProcessPtr();
274
275 std::shared_ptr<MemState> mem_state = p->memState;
276 Addr brk_point = mem_state->getBrkPoint();
277
278 // in Linux at least, brk(0) returns the current break value
279 // (note that the syscall and the glibc function have different behavior)
280 if (new_brk == 0 || (new_brk == brk_point))
281 return brk_point;
282
283 mem_state->updateBrkRegion(brk_point, new_brk);
284
285 DPRINTF_SYSCALL(Verbose, "brk: break point changed to: %#X\n",
286 mem_state->getBrkPoint());
287
288 return mem_state->getBrkPoint();
289}
290
291SyscallReturn
293{
294 auto process = tc->getProcessPtr();
295
296 process->childClearTID = tidPtr;
297 return process->pid();
298}
299
300SyscallReturn
301closeFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd)
302{
303 auto p = tc->getProcessPtr();
304 return p->fds->closeFDEntry(tgt_fd);
305}
306
307
308SyscallReturn
310 int tgt_fd, uint32_t offset_high, uint32_t offset_low,
311 VPtr<> result_ptr, int whence)
312{
313 auto p = tc->getProcessPtr();
314
315 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*p->fds)[tgt_fd]);
316 if (!ffdp)
317 return -EBADF;
318 int sim_fd = ffdp->getSimFD();
319
320 uint64_t offset = ((uint64_t) offset_high << 32) | offset_low;
321
322 uint64_t result = lseek(sim_fd, offset, whence);
323 result = htog(result, tc->getSystemPtr()->getGuestByteOrder());
324
325 if (result == (off_t)-1)
326 return -errno;
327 // Assuming that the size of loff_t is 64 bits on the target platform
328 BufferArg result_buf(result_ptr, sizeof(result));
329 std::memcpy(result_buf.bufferPtr(), &result, sizeof(result));
330 result_buf.copyOut(SETranslatingPortProxy(tc));
331 return 0;
332}
333
334
335const char *hostname = "m5.eecs.umich.edu";
336
339 VPtr<> buf_ptr, int name_len)
340{
341 BufferArg name(buf_ptr, name_len);
342 strncpy((char *)name.bufferPtr(), hostname, name_len);
343 name.copyOut(SETranslatingPortProxy(tc));
344 return 0;
345}
346
347SyscallReturn
349{
350 std::string path;
351 if (!SETranslatingPortProxy(tc).tryReadString(path, pathname))
352 return -EFAULT;
353
354 return unlinkImpl(desc, tc, path);
355}
356
357SyscallReturn
358unlinkImpl(SyscallDesc *desc, ThreadContext *tc, std::string path)
359{
360 auto p = tc->getProcessPtr();
361 path = p->checkPathRedirect(path);
362
363 int result = unlink(path.c_str());
364 return (result == -1) ? -errno : result;
365}
366
367SyscallReturn
369 VPtr<> pathname, VPtr<> new_pathname)
370{
371 std::string path;
372 std::string new_path;
373 auto p = tc->getProcessPtr();
374
375 SETranslatingPortProxy virt_mem(tc);
376 if (!virt_mem.tryReadString(path, pathname))
377 return -EFAULT;
378 if (!virt_mem.tryReadString(new_path, new_pathname))
379 return -EFAULT;
380
381 path = p->absolutePath(path, true);
382 new_path = p->absolutePath(new_path, true);
383
384 int result = link(path.c_str(), new_path.c_str());
385 return (result == -1) ? -errno : result;
386}
387
388SyscallReturn
390 VPtr<> pathname, VPtr<> new_pathname)
391{
392 std::string path;
393 std::string new_path;
394 auto p = tc->getProcessPtr();
395
396 SETranslatingPortProxy virt_mem(tc);
397 if (!virt_mem.tryReadString(path, pathname))
398 return -EFAULT;
399 if (!virt_mem.tryReadString(new_path, new_pathname))
400 return -EFAULT;
401
402 path = p->absolutePath(path, true);
403 new_path = p->absolutePath(new_path, true);
404
405 int result = symlink(path.c_str(), new_path.c_str());
406 return (result == -1) ? -errno : result;
407}
408
409SyscallReturn
410mkdirFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, mode_t mode)
411{
412 std::string path;
413 if (!SETranslatingPortProxy(tc).tryReadString(path, pathname))
414 return -EFAULT;
415
416 return mkdirImpl(desc, tc, path, mode);
417}
418
419SyscallReturn
420mkdirImpl(SyscallDesc *desc, ThreadContext *tc, std::string path, mode_t mode)
421{
422 auto p = tc->getProcessPtr();
423 path = p->checkPathRedirect(path);
424
425 auto result = mkdir(path.c_str(), mode);
426 return (result == -1) ? -errno : result;
427}
428
429SyscallReturn
431 VPtr<> newpath)
432{
433 SETranslatingPortProxy proxy(tc);
434 std::string old_name;
435 if (!proxy.tryReadString(old_name, oldpath))
436 return -EFAULT;
437
438 std::string new_name;
439 if (!proxy.tryReadString(new_name, newpath))
440 return -EFAULT;
441
442 return renameImpl(desc, tc, old_name, new_name);
443}
444
445SyscallReturn
447 std::string old_name, std::string new_name)
448{
449 auto p = tc->getProcessPtr();
450
451 // Adjust path for cwd and redirection
452 old_name = p->checkPathRedirect(old_name);
453 new_name = p->checkPathRedirect(new_name);
454
455 int64_t result = rename(old_name.c_str(), new_name.c_str());
456 return (result == -1) ? -errno : result;
457}
458
459
460SyscallReturn
462 VPtr<> pathname, int64_t length)
463{
464 auto process = tc->getProcessPtr();
465 std::string path;
466
467 if (!SETranslatingPortProxy(tc).tryReadString(path, pathname))
468 return -EFAULT;
469
470 // Adjust path for cwd and redirection
471 path = process->checkPathRedirect(path);
472
473#if NO_STAT64
474 int result = truncate(path.c_str(), length);
475#else
476 int result = truncate64(path.c_str(), length);
477#endif
478 return (result == -1) ? -errno : result;
479}
480
481SyscallReturn
483 int tgt_fd, int64_t length)
484{
485 auto p = tc->getProcessPtr();
486
487 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*p->fds)[tgt_fd]);
488 if (!ffdp)
489 return -EBADF;
490 int sim_fd = ffdp->getSimFD();
491
492#if NO_STAT64
493 int result = ftruncate(sim_fd, length);
494#else
495 int result = ftruncate64(sim_fd, length);
496#endif
497 return (result == -1) ? -errno : result;
498}
499
500SyscallReturn
502{
503 // Letting the simulated program change the simulator's umask seems like
504 // a bad idea. Compromise by just returning the current umask but not
505 // changing anything.
506 mode_t oldMask = umask(0);
507 umask(oldMask);
508 return (int)oldMask;
509}
510
511SyscallReturn
513 VPtr<> pathname, uint32_t owner, uint32_t group)
514{
515 std::string path;
516 if (!SETranslatingPortProxy(tc).tryReadString(path, pathname))
517 return -EFAULT;
518
519 return chownImpl(desc, tc, path, owner, group);
520}
521
522SyscallReturn
524 std::string path, uint32_t owner, uint32_t group)
525{
526 auto p = tc->getProcessPtr();
527
528 /* XXX endianess */
529 uid_t hostOwner = owner;
530 gid_t hostGroup = group;
531
532 // Adjust path for cwd and redirection
533 path = p->checkPathRedirect(path);
534
535 int result = chown(path.c_str(), hostOwner, hostGroup);
536 return (result == -1) ? -errno : result;
537}
538
539SyscallReturn
541 int tgt_fd, uint32_t owner, uint32_t group)
542{
543 auto p = tc->getProcessPtr();
544
545 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*p->fds)[tgt_fd]);
546 if (!ffdp)
547 return -EBADF;
548 int sim_fd = ffdp->getSimFD();
549
550 /* XXX endianess */
551 uid_t hostOwner = owner;
552 gid_t hostGroup = group;
553
554 int result = fchown(sim_fd, hostOwner, hostGroup);
555 return (result == -1) ? -errno : result;
556}
557
564SyscallReturn
565dupFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd)
566{
567 auto p = tc->getProcessPtr();
568
569 auto old_hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
570 if (!old_hbfdp)
571 return -EBADF;
572 int sim_fd = old_hbfdp->getSimFD();
573
574 int result = dup(sim_fd);
575 if (result == -1)
576 return -errno;
577
578 auto new_hbfdp = std::dynamic_pointer_cast<HBFDEntry>(old_hbfdp->clone());
579 new_hbfdp->setSimFD(result);
580 new_hbfdp->setCOE(false);
581 return p->fds->allocFD(new_hbfdp);
582}
583
584SyscallReturn
585dup2Func(SyscallDesc *desc, ThreadContext *tc, int old_tgt_fd, int new_tgt_fd)
586{
587 auto p = tc->getProcessPtr();
588 auto old_hbp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[old_tgt_fd]);
589 if (!old_hbp)
590 return -EBADF;
591 int old_sim_fd = old_hbp->getSimFD();
592
598 int res_fd = dup2(old_sim_fd, open("/dev/null", O_RDONLY));
599 if (res_fd == -1)
600 return -errno;
601
602 auto new_hbp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[new_tgt_fd]);
603 if (new_hbp)
604 p->fds->closeFDEntry(new_tgt_fd);
605 new_hbp = std::dynamic_pointer_cast<HBFDEntry>(old_hbp->clone());
606 new_hbp->setSimFD(res_fd);
607 new_hbp->setCOE(false);
608
609 return p->fds->allocFD(new_hbp);
610}
611
612SyscallReturn
614 int tgt_fd, int cmd, guest_abi::VarArgs<int> varargs)
615{
616 auto p = tc->getProcessPtr();
617
618 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
619 if (!hbfdp)
620 return -EBADF;
621 int sim_fd = hbfdp->getSimFD();
622
623 int coe = hbfdp->getCOE();
624
625 switch (cmd) {
626 case F_GETFD:
627 return coe & FD_CLOEXEC;
628
629 case F_SETFD: {
630 int arg = varargs.get<int>();
631 arg ? hbfdp->setCOE(true) : hbfdp->setCOE(false);
632 return 0;
633 }
634
635 // Rely on the host to maintain the file status flags for this file
636 // description rather than maintain it ourselves. Admittedly, this
637 // is suboptimal (and possibly error prone), but it is difficult to
638 // maintain the flags by tracking them across the different descriptors
639 // (that refer to this file description) caused by clone, dup, and
640 // subsequent fcntls.
641 case F_GETFL:
642 case F_SETFL: {
643 int arg = varargs.get<int>();
644 int rv = fcntl(sim_fd, cmd, arg);
645 return (rv == -1) ? -errno : rv;
646 }
647
648 default:
649 warn("fcntl: unsupported command %d\n", cmd);
650 return 0;
651 }
652}
653
654SyscallReturn
655fcntl64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int cmd)
656{
657 auto p = tc->getProcessPtr();
658
659 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
660 if (!hbfdp)
661 return -EBADF;
662 int sim_fd = hbfdp->getSimFD();
663
664 switch (cmd) {
665 case 33: //F_GETLK64
666 warn("fcntl64(%d, F_GETLK64) not supported, error returned\n", tgt_fd);
667 return -EMFILE;
668
669 case 34: // F_SETLK64
670 case 35: // F_SETLKW64
671 warn("fcntl64(%d, F_SETLK(W)64) not supported, error returned\n",
672 tgt_fd);
673 return -EMFILE;
674
675 default:
676 // not sure if this is totally valid, but we'll pass it through
677 // to the underlying OS
678 warn("fcntl64(%d, %d) passed through to host\n", tgt_fd, cmd);
679 return fcntl(sim_fd, cmd);
680 }
681}
682
683SyscallReturn
685{
686 return pipe2Func(desc, tc, 0, 0);
687}
688
689SyscallReturn
691{
692 return pipe2Func(desc, tc, tgt_addr, 0);
693}
694
695SyscallReturn
697{
698 auto p = tc->getProcessPtr();
699
700 int sim_fds[2], tgt_fds[2];
701
702 int pipe_retval = pipe(sim_fds);
703 if (pipe_retval == -1)
704 return -errno;
705
706 auto rend = PipeFDEntry::EndType::read;
707 auto rpfd = std::make_shared<PipeFDEntry>(sim_fds[0], O_WRONLY, rend);
708 tgt_fds[0] = p->fds->allocFD(rpfd);
709 int sim_fd_rpfd = rpfd->getSimFD();
710
711 auto wend = PipeFDEntry::EndType::write;
712 auto wpfd = std::make_shared<PipeFDEntry>(sim_fds[1], O_RDONLY, wend);
713 tgt_fds[1] = p->fds->allocFD(wpfd);
714 int sim_fd_wpfd = wpfd->getSimFD();
715
720 rpfd->setPipeReadSource(tgt_fds[1]);
721
727 if (tgt_addr == 0)
728 return SyscallReturn(tgt_fds[0], tgt_fds[1]);
729
734 BufferArg tgt_handle(tgt_addr, sizeof(int[2]));
735 int *buf_ptr = (int*)tgt_handle.bufferPtr();
736 buf_ptr[0] = tgt_fds[0];
737 buf_ptr[1] = tgt_fds[1];
738 tgt_handle.copyOut(SETranslatingPortProxy(tc));
739
740 if (flags) {
741 // pipe2 only uses O_NONBLOCK, O_CLOEXEC, and (O_NONBLOCK | O_CLOEXEC)
742 // if flags set to anything else, return EINVAL
743 if ((flags != O_CLOEXEC) && (flags != O_NONBLOCK) &&
744 (flags != (O_CLOEXEC | O_NONBLOCK))) {
745 return -EINVAL;
746 }
747
748 /*
749 If O_NONBLOCK is passed in as a flag to pipe2, set O_NONBLOCK file
750 status flag for two new open file descriptors.
751 */
752 if (flags & O_NONBLOCK) {
753 /*
754 O_NONBLOCK is set when the programmer wants to avoid a separate
755 call(s) to fcntl in their code, so mirror the fcntl
756 implementation for handling file descriptors -- rely on host to
757 maintain file status flags.
758 */
759 if (fcntl(sim_fd_rpfd, F_SETFL, O_NONBLOCK)) {
760 return -errno;
761 }
762 if (fcntl(sim_fd_wpfd, F_SETFL, O_NONBLOCK)) {
763 return -errno;
764 }
765 }
766
767 /*
768 If O_CLOEXEC is passed in as a flag to pipe2, set close-on-exec
769 (FD_CLOEXEC) file status flag for two new open file descriptors.
770 */
771 if (flags & O_CLOEXEC) {
772 rpfd->setCOE(true);
773 wpfd->setCOE(true);
774 }
775 }
776
777 return 0;
778}
779
780SyscallReturn
782{
783 auto process = tc->getProcessPtr();
784 return process->pgid();
785}
786
787SyscallReturn
788setpgidFunc(SyscallDesc *desc, ThreadContext *tc, int pid, int pgid)
789{
790 auto process = tc->getProcessPtr();
791
792 if (pgid < 0)
793 return -EINVAL;
794
795 if (pid == 0) {
796 process->pgid(process->pid());
797 return 0;
798 }
799
800 Process *matched_ph = nullptr;
801 System *sysh = tc->getSystemPtr();
802
803 // Retrieves process pointer from active/suspended thread contexts.
804 for (auto *tc: sysh->threads) {
805 if (tc->status() != ThreadContext::Halted) {
806 Process *temp_h = tc->getProcessPtr();
807 Process *walk_ph = (Process*)temp_h;
808
809 if (walk_ph && walk_ph->pid() == process->pid())
810 matched_ph = walk_ph;
811 }
812 }
813
814 assert(matched_ph);
815 matched_ph->pgid((pgid == 0) ? matched_ph->pid() : pgid);
816
817 return 0;
818}
819
820
821SyscallReturn
823{
824 auto process = tc->getProcessPtr();
825 return process->tgid();
826}
827
828SyscallReturn
830{
831 auto process = tc->getProcessPtr();
832 return process->pid();
833}
834
835SyscallReturn
837{
838 auto process = tc->getProcessPtr();
839 return process->ppid();
840}
841
842SyscallReturn
844{
845 auto process = tc->getProcessPtr();
846 return process->uid(); // UID
847}
848
849SyscallReturn
851{
852 auto process = tc->getProcessPtr();
853 return process->euid(); // UID
854}
855
856SyscallReturn
858{
859 auto process = tc->getProcessPtr();
860 return process->gid();
861}
862
863SyscallReturn
865{
866 auto process = tc->getProcessPtr();
867 return process->egid();
868}
869
870SyscallReturn
872 VPtr<> pathname, mode_t mode)
873{
874 std::string path;
875 if (!SETranslatingPortProxy(tc).tryReadString(path, pathname))
876 return -EFAULT;
877
878 return accessImpl(desc, tc, path, mode);
879}
880
881SyscallReturn
883 std::string path, mode_t mode)
884{
885 auto p = tc->getProcessPtr();
886 // Adjust path for cwd and redirection
887 path = p->checkPathRedirect(path);
888
889 int result = access(path.c_str(), mode);
890 return (result == -1) ? -errno : result;
891}
892
893SyscallReturn
895 VPtr<> pathname, mode_t mode, dev_t dev)
896{
897 std::string path;
898 if (!SETranslatingPortProxy(tc).tryReadString(path, pathname))
899 return -EFAULT;
900
901 return mknodImpl(desc, tc, path, mode, dev);
902}
903
904SyscallReturn
906 std::string path, mode_t mode, dev_t dev)
907{
908 auto p = tc->getProcessPtr();
909 path = p->checkPathRedirect(path);
910
911 auto result = mknod(path.c_str(), mode, dev);
912 return (result == -1) ? -errno : result;
913}
914
915SyscallReturn
917{
918 auto p = tc->getProcessPtr();
919 std::string path;
920 if (!SETranslatingPortProxy(tc).tryReadString(path, pathname))
921 return -EFAULT;
922
923 std::string tgt_cwd;
924 if (startswith(path, "/")) {
925 tgt_cwd = path;
926 } else {
927 char buf[PATH_MAX];
928 if (!realpath((p->tgtCwd + "/" + path).c_str(), buf))
929 return -errno;
930 tgt_cwd = buf;
931 }
932 std::string host_cwd = p->checkPathRedirect(tgt_cwd);
933
934 int result = chdir(host_cwd.c_str());
935
936 if (result == -1)
937 return -errno;
938
939 p->hostCwd = host_cwd;
940 p->tgtCwd = tgt_cwd;
941 return result;
942}
943
944SyscallReturn
946{
947 std::string path;
948 if (!SETranslatingPortProxy(tc).tryReadString(path, pathname))
949 return -EFAULT;
950
951 return rmdirImpl(desc, tc, path);
952}
953
954SyscallReturn
955rmdirImpl(SyscallDesc *desc, ThreadContext *tc, std::string path)
956{
957 auto p = tc->getProcessPtr();
958 path = p->checkPathRedirect(path);
959
960 auto result = rmdir(path.c_str());
961 return (result == -1) ? -errno : result;
962}
963
964#if defined(SYS_getdents) || defined(SYS_getdents64)
965template<typename DE, int SYS_NUM>
966static SyscallReturn
967getdentsImpl(SyscallDesc *desc, ThreadContext *tc,
968 int tgt_fd, VPtr<> buf_ptr, unsigned count)
969{
970 auto p = tc->getProcessPtr();
971
972 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
973 if (!hbfdp)
974 return -EBADF;
975 int sim_fd = hbfdp->getSimFD();
976
977 BufferArg buf_arg(buf_ptr, count);
978 auto status = syscall(SYS_NUM, sim_fd, buf_arg.bufferPtr(), count);
979
980 if (status == -1)
981 return -errno;
982
983 unsigned traversed = 0;
984 while (traversed < status) {
985 DE *buffer = (DE*)((Addr)buf_arg.bufferPtr() + traversed);
986
987 auto host_reclen = buffer->d_reclen;
988
994 const ByteOrder bo = tc->getSystemPtr()->getGuestByteOrder();
995 buffer->d_ino = htog(buffer->d_ino, bo);
996 buffer->d_off = htog(buffer->d_off, bo);
997 buffer->d_reclen = htog(buffer->d_reclen, bo);
998
999 traversed += host_reclen;
1000 }
1001
1002 buf_arg.copyOut(SETranslatingPortProxy(tc));
1003 return status;
1004}
1005#endif
1006
1007#if defined(SYS_getdents)
1008SyscallReturn
1009getdentsFunc(SyscallDesc *desc, ThreadContext *tc,
1010 int tgt_fd, VPtr<> buf_ptr, unsigned count)
1011{
1012 typedef struct linux_dirent
1013 {
1014 unsigned long d_ino;
1015 unsigned long d_off;
1016 unsigned short d_reclen;
1017 char dname[];
1018 } LinDent;
1019
1020 return getdentsImpl<LinDent, SYS_getdents>(desc, tc,
1021 tgt_fd, buf_ptr, count);
1022}
1023#endif
1024
1025#if defined(SYS_getdents64)
1026SyscallReturn
1027getdents64Func(SyscallDesc *desc, ThreadContext *tc,
1028 int tgt_fd, VPtr<> buf_ptr, unsigned count)
1029{
1030 typedef struct linux_dirent64
1031 {
1032 ino64_t d_ino;
1033 off64_t d_off;
1034 unsigned short d_reclen;
1035 char dname[];
1036 } LinDent64;
1037
1038 return getdentsImpl<LinDent64, SYS_getdents64>(desc, tc,
1039 tgt_fd, buf_ptr, count);
1040}
1041#endif
1042
1043SyscallReturn
1044shutdownFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int how)
1045{
1046 auto p = tc->getProcessPtr();
1047
1048 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1049 if (!sfdp)
1050 return -EBADF;
1051 int sim_fd = sfdp->getSimFD();
1052
1053 int retval = shutdown(sim_fd, how);
1054
1055 return (retval == -1) ? -errno : retval;
1056}
1057
1058SyscallReturn
1060 int tgt_fd, VPtr<> buf_ptr, int addrlen)
1061{
1062 auto p = tc->getProcessPtr();
1063
1064 BufferArg bufSock(buf_ptr, addrlen);
1065 bufSock.copyIn(SETranslatingPortProxy(tc));
1066
1067 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1068 if (!sfdp)
1069 return -EBADF;
1070 int sim_fd = sfdp->getSimFD();
1071
1072 int status = ::bind(sim_fd,
1073 (struct sockaddr *)bufSock.bufferPtr(),
1074 addrlen);
1075
1076 return (status == -1) ? -errno : status;
1077}
1078
1079SyscallReturn
1080listenFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int backlog)
1081{
1082 auto p = tc->getProcessPtr();
1083
1084 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1085 if (!sfdp)
1086 return -EBADF;
1087 int sim_fd = sfdp->getSimFD();
1088
1089 int status = listen(sim_fd, backlog);
1090
1091 return (status == -1) ? -errno : status;
1092}
1093
1094SyscallReturn
1096 int tgt_fd, VPtr<> buf_ptr, int addrlen)
1097{
1098 auto p = tc->getProcessPtr();
1099
1100 BufferArg addr(buf_ptr, addrlen);
1101 addr.copyIn(SETranslatingPortProxy(tc));
1102
1103 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1104 if (!sfdp)
1105 return -EBADF;
1106 int sim_fd = sfdp->getSimFD();
1107
1108 int status = connect(sim_fd,
1109 (struct sockaddr *)addr.bufferPtr(),
1110 (socklen_t)addrlen);
1111
1112 return (status == -1) ? -errno : status;
1113}
1114
1115
1116SyscallReturn
1118 int tgt_fd, VPtr<> msgPtr, int flags)
1119{
1120 auto p = tc->getProcessPtr();
1121
1122 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1123 if (!sfdp)
1124 return -EBADF;
1125 int sim_fd = sfdp->getSimFD();
1126
1145 SETranslatingPortProxy proxy(tc);
1146
1152 BufferArg msgBuf(msgPtr, sizeof(struct msghdr));
1153 msgBuf.copyIn(proxy);
1154 struct msghdr *msgHdr = (struct msghdr *)msgBuf.bufferPtr();
1155
1161 Addr msg_name_phold = 0;
1162 Addr msg_iov_phold = 0;
1163 Addr iovec_base_phold[msgHdr->msg_iovlen];
1164 Addr msg_control_phold = 0;
1165
1169 BufferArg *nameBuf = NULL;
1170 if (msgHdr->msg_name) {
1171 /*1*/msg_name_phold = (Addr)msgHdr->msg_name;
1172 /*2*/nameBuf = new BufferArg(msg_name_phold, msgHdr->msg_namelen);
1173 /*3*/nameBuf->copyIn(proxy);
1174 /*4*/msgHdr->msg_name = nameBuf->bufferPtr();
1175 }
1176
1182 BufferArg *iovBuf = NULL;
1183 BufferArg *iovecBuf[msgHdr->msg_iovlen];
1184 for (int i = 0; i < msgHdr->msg_iovlen; i++) {
1185 iovec_base_phold[i] = 0;
1186 iovecBuf[i] = NULL;
1187 }
1188
1189 if (msgHdr->msg_iov) {
1190 /*1*/msg_iov_phold = (Addr)msgHdr->msg_iov;
1191 /*2*/iovBuf = new BufferArg(msg_iov_phold, msgHdr->msg_iovlen *
1192 sizeof(struct iovec));
1193 /*3*/iovBuf->copyIn(proxy);
1194 for (int i = 0; i < msgHdr->msg_iovlen; i++) {
1195 if (((struct iovec *)iovBuf->bufferPtr())[i].iov_base) {
1196 /*1*/iovec_base_phold[i] =
1197 (Addr)((struct iovec *)iovBuf->bufferPtr())[i].iov_base;
1198 /*2*/iovecBuf[i] = new BufferArg(iovec_base_phold[i],
1199 ((struct iovec *)iovBuf->bufferPtr())[i].iov_len);
1200 /*3*/iovecBuf[i]->copyIn(proxy);
1201 /*4*/((struct iovec *)iovBuf->bufferPtr())[i].iov_base =
1202 iovecBuf[i]->bufferPtr();
1203 }
1204 }
1205 /*4*/msgHdr->msg_iov = (struct iovec *)iovBuf->bufferPtr();
1206 }
1207
1211 BufferArg *controlBuf = NULL;
1212 if (msgHdr->msg_control) {
1213 /*1*/msg_control_phold = (Addr)msgHdr->msg_control;
1214 /*2*/controlBuf = new BufferArg(msg_control_phold,
1215 CMSG_ALIGN(msgHdr->msg_controllen));
1216 /*3*/controlBuf->copyIn(proxy);
1217 /*4*/msgHdr->msg_control = controlBuf->bufferPtr();
1218 }
1219
1220 ssize_t recvd_size = recvmsg(sim_fd, msgHdr, flags);
1221
1222 if (recvd_size < 0)
1223 return -errno;
1224
1225 if (msgHdr->msg_name) {
1226 nameBuf->copyOut(proxy);
1227 delete(nameBuf);
1228 msgHdr->msg_name = (void *)msg_name_phold;
1229 }
1230
1231 if (msgHdr->msg_iov) {
1232 for (int i = 0; i< msgHdr->msg_iovlen; i++) {
1233 if (((struct iovec *)iovBuf->bufferPtr())[i].iov_base) {
1234 iovecBuf[i]->copyOut(proxy);
1235 delete iovecBuf[i];
1236 ((struct iovec *)iovBuf->bufferPtr())[i].iov_base =
1237 (void *)iovec_base_phold[i];
1238 }
1239 }
1240 iovBuf->copyOut(proxy);
1241 delete iovBuf;
1242 msgHdr->msg_iov = (struct iovec *)msg_iov_phold;
1243 }
1244
1245 if (msgHdr->msg_control) {
1246 controlBuf->copyOut(proxy);
1247 delete(controlBuf);
1248 msgHdr->msg_control = (void *)msg_control_phold;
1249 }
1250
1251 msgBuf.copyOut(proxy);
1252
1253 return recvd_size;
1254}
1255
1256SyscallReturn
1258 int tgt_fd, VPtr<> msgPtr, int flags)
1259{
1260 auto p = tc->getProcessPtr();
1261
1262 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1263 if (!sfdp)
1264 return -EBADF;
1265 int sim_fd = sfdp->getSimFD();
1266
1267 SETranslatingPortProxy proxy(tc);
1268
1272 BufferArg msgBuf(msgPtr, sizeof(struct msghdr));
1273 msgBuf.copyIn(proxy);
1274 struct msghdr msgHdr = *((struct msghdr *)msgBuf.bufferPtr());
1275
1280 struct iovec *iovPtr = msgHdr.msg_iov;
1281 BufferArg iovBuf((Addr)iovPtr, sizeof(struct iovec) * msgHdr.msg_iovlen);
1282 iovBuf.copyIn(proxy);
1283 struct iovec *iov = (struct iovec *)iovBuf.bufferPtr();
1284 msgHdr.msg_iov = iov;
1285
1291 BufferArg **bufferArray = (BufferArg **)malloc(msgHdr.msg_iovlen
1292 * sizeof(BufferArg *));
1293
1299 for (int iovIndex = 0 ; iovIndex < msgHdr.msg_iovlen; iovIndex++) {
1300 Addr basePtr = (Addr) iov[iovIndex].iov_base;
1301 bufferArray[iovIndex] = new BufferArg(basePtr, iov[iovIndex].iov_len);
1302 bufferArray[iovIndex]->copyIn(proxy);
1303 iov[iovIndex].iov_base = bufferArray[iovIndex]->bufferPtr();
1304 }
1305
1306 ssize_t sent_size = sendmsg(sim_fd, &msgHdr, flags);
1307 int local_errno = errno;
1308
1312 for (int iovIndex = 0 ; iovIndex < msgHdr.msg_iovlen; iovIndex++) {
1313 BufferArg *baseBuf = ( BufferArg *)bufferArray[iovIndex];
1314 delete(baseBuf);
1315 }
1316
1320 free(bufferArray);
1321
1322 return (sent_size < 0) ? -local_errno : sent_size;
1323}
1324
1325SyscallReturn
1327 int tgt_fd, int level, int optname, VPtr<> valPtr,
1328 VPtr<> lenPtr)
1329{
1330 // union of all possible return value types from getsockopt
1331 union val
1332 {
1333 int i_val;
1334 long l_val;
1335 struct linger linger_val;
1336 struct timeval timeval_val;
1337 } val;
1338
1339 auto p = tc->getProcessPtr();
1340
1341 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1342 if (!sfdp)
1343 return -EBADF;
1344 int sim_fd = sfdp->getSimFD();
1345
1346 socklen_t len = sizeof(val);
1347 int status = getsockopt(sim_fd, level, optname, &val, &len);
1348
1349 if (status == -1)
1350 return -errno;
1351
1352 SETranslatingPortProxy proxy(tc);
1353
1354 // copy val to valPtr and pass it on
1355 BufferArg valBuf(valPtr, sizeof(val));
1356 memcpy(valBuf.bufferPtr(), &val, sizeof(val));
1357 valBuf.copyOut(proxy);
1358
1359 // copy len to lenPtr and pass it on
1360 BufferArg lenBuf(lenPtr, sizeof(len));
1361 memcpy(lenBuf.bufferPtr(), &len, sizeof(len));
1362 lenBuf.copyOut(proxy);
1363
1364 return status;
1365}
1366
1367SyscallReturn
1369 int tgt_fd, VPtr<> addrPtr, VPtr<> lenPtr)
1370{
1371 auto p = tc->getProcessPtr();
1372
1373 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1374 if (!sfdp)
1375 return -EBADF;
1376 int sim_fd = sfdp->getSimFD();
1377
1378 // lenPtr is an in-out paramenter:
1379 // sending the address length in, conveying the final length out
1380
1381 SETranslatingPortProxy proxy(tc);
1382
1383 // Read in the value of len from the passed pointer.
1384 BufferArg lenBuf(lenPtr, sizeof(socklen_t));
1385 lenBuf.copyIn(proxy);
1386 socklen_t len = *(socklen_t *)lenBuf.bufferPtr();
1387
1388 struct sockaddr sa;
1389 int status = getsockname(sim_fd, &sa, &len);
1390
1391 if (status == -1)
1392 return -errno;
1393
1394 // Copy address to addrPtr and pass it on.
1395 BufferArg addrBuf(addrPtr, sizeof(sa));
1396 memcpy(addrBuf.bufferPtr(), &sa, sizeof(sa));
1397 addrBuf.copyOut(proxy);
1398
1399 // Copy len to lenPtr and pass it on.
1400 *(socklen_t *)lenBuf.bufferPtr() = len;
1401 lenBuf.copyOut(proxy);
1402
1403 return status;
1404}
1405
1406SyscallReturn
1408 int tgt_fd, VPtr<> sockAddrPtr, VPtr<> addrlenPtr)
1409{
1410 auto p = tc->getProcessPtr();
1411
1412 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1413 if (!sfdp)
1414 return -EBADF;
1415 int sim_fd = sfdp->getSimFD();
1416
1417 SETranslatingPortProxy proxy(tc);
1418
1419 BufferArg bufAddrlen(addrlenPtr, sizeof(unsigned));
1420 bufAddrlen.copyIn(proxy);
1421 BufferArg bufSock(sockAddrPtr, *(unsigned *)bufAddrlen.bufferPtr());
1422
1423 int retval = getpeername(sim_fd,
1424 (struct sockaddr *)bufSock.bufferPtr(),
1425 (unsigned *)bufAddrlen.bufferPtr());
1426
1427 if (retval != -1) {
1428 bufSock.copyOut(proxy);
1429 bufAddrlen.copyOut(proxy);
1430 }
1431
1432 return (retval == -1) ? -errno : retval;
1433}
1434
1435SyscallReturn
1437 int tgt_fd, int level, int optname, VPtr<> valPtr,
1438 socklen_t len)
1439{
1440 auto p = tc->getProcessPtr();
1441
1442 BufferArg valBuf(valPtr, len);
1443 valBuf.copyIn(SETranslatingPortProxy(tc));
1444
1445 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
1446 if (!sfdp)
1447 return -EBADF;
1448 int sim_fd = sfdp->getSimFD();
1449
1450 int status = setsockopt(sim_fd, level, optname,
1451 (struct sockaddr *)valBuf.bufferPtr(), len);
1452
1453 return (status == -1) ? -errno : status;
1454}
1455
1456SyscallReturn
1459{
1460 // unsigned is the same size (4) on all Linux supported ISAs.
1461 if (cpu)
1462 *cpu = htog(tc->contextId(), tc->getSystemPtr()->getGuestByteOrder());
1463
1464 // Set a fixed NUMA node 0.
1465 if (node)
1466 *node = 0;
1467
1468 return 0;
1469}
1470
1471} // 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 Arm Limited 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 _llseekFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint32_t offset_high, uint32_t offset_low, VPtr<> result_ptr, int whence)
Target _llseek() handler.
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 setpgidFunc(SyscallDesc *desc, ThreadContext *tc, int pid, int pgid)
Target setpgid() handler.
SyscallReturn geteuidFunc(SyscallDesc *desc, ThreadContext *tc)
Target geteuid() handler.
SyscallReturn symlinkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr<> new_pathname)
Target symlink() handler.
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 setTidAddressFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> tidPtr)
Target set_tid_address() 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 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 Mon Jan 13 2025 04:28:42 for gem5 by doxygen 1.9.8