Giacomo Travaglini has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/51489 )

Change subject: misc: Using OS::size_t in syscall signature
......................................................................

misc: Using OS::size_t in syscall signature

Using the host size_t is confusing the guest ABI engine every time
the host and the guest adopt a different data model (ILP32 vs LP64)

For example when a LP64 machine is running an ILP32 application in SE
mode, "size_t" will wrongly inform the guest ABI engine to retrieve the
argument by loading a 64 bit (instead of 32) value from the stack

JIRA: https://gem5.atlassian.net/browse/GEM5-1074

Change-Id: Id7d7740ac429f534a4089331bedf21dc3951bbad
Signed-off-by: Giacomo Travaglini <giacomo.travagl...@arm.com>
---
M src/arch/mips/linux/se_workload.cc
M src/arch/sparc/linux/syscalls.cc
M src/arch/power/linux/se_workload.cc
M src/arch/riscv/linux/se_workload.cc
M src/arch/x86/linux/syscall_tbl32.cc
M src/sim/syscall_emul.cc
M src/sim/syscall_emul.hh
M src/arch/arm/freebsd/se_workload.cc
M src/arch/arm/linux/se_workload.cc
M src/arch/x86/linux/syscall_tbl64.cc
10 files changed, 239 insertions(+), 236 deletions(-)



diff --git a/src/arch/arm/freebsd/se_workload.cc b/src/arch/arm/freebsd/se_workload.cc
index 542510b..66e587e 100644
--- a/src/arch/arm/freebsd/se_workload.cc
+++ b/src/arch/arm/freebsd/se_workload.cc
@@ -136,7 +136,7 @@
     {    4, "write", writeFunc<ArmFreebsd64> },
     {   17, "obreak", brkFunc },
     {   54, "ioctl", ioctlFunc<ArmFreebsd64> },
-    {   58, "readlink", readlinkFunc },
+    {   58, "readlink", readlinkFunc<ArmFreebsd64> },
     {  117, "getrusage", getrusageFunc<ArmFreebsd64> },
     {  189, "fstat", fstatFunc<ArmFreebsd64> },
 #if !defined ( __GNU_LIBRARY__ )
diff --git a/src/arch/arm/linux/se_workload.cc b/src/arch/arm/linux/se_workload.cc
index 450d540..c715e1d 100644
--- a/src/arch/arm/linux/se_workload.cc
+++ b/src/arch/arm/linux/se_workload.cc
@@ -216,13 +216,13 @@
         { base + 81, "setgroups" },
         { base + 82, "reserved#82" },
         { base + 83, "symlink" },
-        { base + 85, "readlink", readlinkFunc },
+        { base + 85, "readlink", readlinkFunc<ArmLinux32> },
         { base + 86, "uselib" },
         { base + 87, "swapon" },
         { base + 88, "reboot" },
         { base + 89, "readdir" },
         { base + 90, "mmap", mmapFunc<ArmLinux32> },
-        { base + 91, "munmap", munmapFunc },
+        { base + 91, "munmap", munmapFunc<ArmLinux32> },
         { base + 92, "truncate", truncateFunc },
         { base + 93, "ftruncate", ftruncateFunc },
         { base + 94, "fchmod" },
@@ -413,9 +413,9 @@
         { base + 287, "getpeername" },
         { base + 288, "socketpair" },
         { base + 289, "send" },
-        { base + 290, "sendto", sendtoFunc },
+        { base + 290, "sendto", sendtoFunc<ArmLinux32> },
         { base + 291, "recv" },
-        { base + 292, "recvfrom", recvfromFunc },
+        { base + 292, "recvfrom", recvfromFunc<ArmLinux32> },
         { base + 293, "shutdown" },
         { base + 294, "setsockopt" },
         { base + 295, "getsockopt" },
@@ -708,8 +708,8 @@
         {  base + 203, "connect" },
         {  base + 204, "getsockname" },
         {  base + 205, "getpeername" },
-        {  base + 206, "sendto", sendtoFunc },
-        {  base + 207, "recvfrom", recvfromFunc },
+        {  base + 206, "sendto", sendtoFunc<ArmLinux64> },
+        {  base + 207, "recvfrom", recvfromFunc<ArmLinux64> },
         {  base + 208, "setsockopt" },
         {  base + 209, "getsockopt" },
         {  base + 210, "shutdown" },
@@ -717,7 +717,7 @@
         {  base + 212, "recvmsg" },
         {  base + 213, "readahead" },
         {  base + 214, "brk", brkFunc },
-        {  base + 215, "munmap", munmapFunc },
+        {  base + 215, "munmap", munmapFunc<ArmLinux64> },
         {  base + 216, "mremap", mremapFunc<ArmLinux64> },
         {  base + 217, "add_key" },
         {  base + 218, "request_key" },
@@ -769,7 +769,7 @@
         { base + 1032, "lchown" },
         { base + 1033, "access", accessFunc },
         { base + 1034, "rename", renameFunc },
-        { base + 1035, "readlink", readlinkFunc },
+        { base + 1035, "readlink", readlinkFunc<ArmLinux64> },
         { base + 1036, "symlink" },
         { base + 1037, "utimes" },
         { base + 1038, "stat64", stat64Func<ArmLinux64> },
diff --git a/src/arch/mips/linux/se_workload.cc b/src/arch/mips/linux/se_workload.cc
index 647c0ca..09752d1 100644
--- a/src/arch/mips/linux/se_workload.cc
+++ b/src/arch/mips/linux/se_workload.cc
@@ -243,13 +243,13 @@
     { 4082, "reserved#82" },
     { 4083, "symlink" },
     { 4084, "unused#84" },
-    { 4085, "readlink", readlinkFunc },
+    { 4085, "readlink", readlinkFunc<MipsLinux> },
     { 4086, "uselib" },
     { 4087, "swapon", gethostnameFunc },
     { 4088, "reboot" },
     { 4089, "readdir" },
     { 4090, "mmap", mmapFunc<MipsLinux> },
-    { 4091, "munmap",munmapFunc },
+    { 4091, "munmap",munmapFunc<MipsLinux> },
     { 4092, "truncate", truncateFunc },
     { 4093, "ftruncate", ftruncateFunc },
     { 4094, "fchmod", fchmodFunc<MipsLinux> },
diff --git a/src/arch/power/linux/se_workload.cc b/src/arch/power/linux/se_workload.cc
index b49cb0b..975d5dd 100644
--- a/src/arch/power/linux/se_workload.cc
+++ b/src/arch/power/linux/se_workload.cc
@@ -192,13 +192,13 @@
     { 82, "reserved#82" },
     { 83, "symlink" },
     { 84, "unused#84" },
-    { 85, "readlink", readlinkFunc },
+    { 85, "readlink", readlinkFunc<PowerLinux> },
     { 86, "uselib" },
     { 87, "swapon", gethostnameFunc },
     { 88, "reboot" },
     { 89, "readdir" },
     { 90, "mmap", mmapFunc<PowerLinux> },
-    { 91, "munmap",munmapFunc },
+    { 91, "munmap",munmapFunc<PowerLinux> },
     { 92, "truncate", truncateFunc },
     { 93, "ftruncate", ftruncateFunc },
     { 94, "fchmod" },
diff --git a/src/arch/riscv/linux/se_workload.cc b/src/arch/riscv/linux/se_workload.cc
index 18627a7..3b0079d 100644
--- a/src/arch/riscv/linux/se_workload.cc
+++ b/src/arch/riscv/linux/se_workload.cc
@@ -338,7 +338,7 @@
     { 212,  "recvmsg" },
     { 213,  "readahead" },
     { 214,  "brk", brkFunc },
-    { 215,  "munmap", munmapFunc },
+    { 215,  "munmap", munmapFunc<RiscvLinux64> },
     { 216,  "mremap", mremapFunc<RiscvLinux64> },
     { 217,  "add_key" },
     { 218,  "request_key" },
@@ -406,7 +406,7 @@
     { 1032, "lchown" },
     { 1033, "access", accessFunc },
     { 1034, "rename", renameFunc },
-    { 1035, "readlink", readlinkFunc },
+    { 1035, "readlink", readlinkFunc<RiscvLinux64> },
     { 1036, "symlink" },
     { 1037, "utimes", utimesFunc<RiscvLinux64> },
     { 1038, "stat", stat64Func<RiscvLinux64> },
@@ -669,7 +669,7 @@
     { 212,  "recvmsg" },
     { 213,  "readahead" },
     { 214,  "brk", brkFunc },
-    { 215,  "munmap", munmapFunc },
+    { 215,  "munmap", munmapFunc<RiscvLinux32> },
     { 216,  "mremap", mremapFunc<RiscvLinux32> },
     { 217,  "add_key" },
     { 218,  "request_key" },
@@ -737,7 +737,7 @@
     { 1032, "lchown" },
     { 1033, "access", accessFunc },
     { 1034, "rename", renameFunc },
-    { 1035, "readlink", readlinkFunc },
+    { 1035, "readlink", readlinkFunc<RiscvLinux32> },
     { 1036, "symlink" },
     { 1037, "utimes", utimesFunc<RiscvLinux32> },
     { 1038, "stat", statFunc<RiscvLinux32> },
diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc
index ae89b37..093fc9c 100644
--- a/src/arch/sparc/linux/syscalls.cc
+++ b/src/arch/sparc/linux/syscalls.cc
@@ -143,7 +143,7 @@
     {  55, "reboot" }, // 32 bit
     {  56, "mmap2" }, // 32 bit
     {  57, "symlink" },
-    {  58, "readlink", readlinkFunc }, // 32 bit
+    {  58, "readlink", readlinkFunc<Sparc32Linux> }, // 32 bit
     {  59, "execve" }, // 32 bit
     {  60, "umask" }, // 32 bit
     {  61, "chroot" },
@@ -158,7 +158,7 @@
     {  70, "getegid32" },
     {  71, "mmap", mmapFunc<Sparc32Linux> },
     {  72, "setreuid32" },
-    {  73, "munmap", munmapFunc },
+    {  73, "munmap", munmapFunc<Sparc32Linux> },
     {  74, "mprotect", ignoreFunc },
     {  75, "madvise" },
     {  76, "vhangup" },
@@ -446,7 +446,7 @@
     { 55, "reboot" },
     { 56, "mmap2" },
     { 57, "symlink" },
-    { 58, "readlink", readlinkFunc },
+    { 58, "readlink", readlinkFunc<SparcLinux> },
     { 59, "execve" },
     { 60, "umask" },
     { 61, "chroot" },
@@ -461,7 +461,7 @@
     { 70, "getegid32" },
     { 71, "mmap", mmapFunc<SparcLinux> },
     { 72, "setreuid32" },
-    { 73, "munmap", munmapFunc },
+    { 73, "munmap", munmapFunc<SparcLinux> },
     { 74, "mprotect", ignoreFunc },
     { 75, "madvise" },
     { 76, "vhangup" },
diff --git a/src/arch/x86/linux/syscall_tbl32.cc b/src/arch/x86/linux/syscall_tbl32.cc
index 112719c..43b2a71 100644
--- a/src/arch/x86/linux/syscall_tbl32.cc
+++ b/src/arch/x86/linux/syscall_tbl32.cc
@@ -124,13 +124,13 @@
     {  82, "select", selectFunc<X86Linux32> },
     {  83, "symlink" },
     {  84, "oldlstat" },
-    {  85, "readlink", readlinkFunc },
+    {  85, "readlink", readlinkFunc<X86Linux32> },
     {  86, "uselib" },
     {  87, "swapon" },
     {  88, "reboot" },
     {  89, "readdir" },
     {  90, "mmap" },
-    {  91, "munmap", munmapFunc },
+    {  91, "munmap", munmapFunc<X86Linux32> },
     {  92, "truncate", truncateFunc },
     {  93, "ftruncate", ftruncateFunc },
     {  94, "fchmod" },
@@ -352,7 +352,7 @@
     { 302, "renameat" },
     { 303, "linkat" },
     { 304, "symlinkat" },
-    { 305, "readlinkat", readlinkFunc },
+    { 305, "readlinkat", readlinkFunc<X86Linux32> },
     { 306, "fchmodat" },
     { 307, "faccessat" },
     { 308, "pselect6" },
diff --git a/src/arch/x86/linux/syscall_tbl64.cc b/src/arch/x86/linux/syscall_tbl64.cc
index 5c983c0..b6c5103 100644
--- a/src/arch/x86/linux/syscall_tbl64.cc
+++ b/src/arch/x86/linux/syscall_tbl64.cc
@@ -50,7 +50,7 @@
     {   8, "lseek", lseekFunc },
     {   9, "mmap", mmapFunc<X86Linux64> },
     {  10, "mprotect", ignoreFunc },
-    {  11, "munmap", munmapFunc },
+    {  11, "munmap", munmapFunc<X86Linux64> },
     {  12, "brk", brkFunc },
     {  13, "rt_sigaction", ignoreWarnOnceFunc },
     {  14, "rt_sigprocmask", ignoreWarnOnceFunc },
@@ -83,8 +83,8 @@
     {  41, "socket", socketFunc<X86Linux64> },
     {  42, "connect", connectFunc },
     {  43, "accept", acceptFunc<X86Linux64> },
-    {  44, "sendto", sendtoFunc },
-    {  45, "recvfrom", recvfromFunc },
+    {  44, "sendto", sendtoFunc<X86Linux64> },
+    {  45, "recvfrom", recvfromFunc<X86Linux64> },
     {  46, "sendmsg", sendmsgFunc },
     {  47, "recvmsg", recvmsgFunc },
     {  48, "shutdown", shutdownFunc },
@@ -132,7 +132,7 @@
     {  86, "link", linkFunc },
     {  87, "unlink", unlinkFunc },
     {  88, "symlink", symlinkFunc },
-    {  89, "readlink", readlinkFunc },
+    {  89, "readlink", readlinkFunc<X86Linux64> },
     {  90, "chmod", ignoreFunc },
     {  91, "fchmod" },
     {  92, "chown" },
@@ -314,7 +314,7 @@
     { 264, "renameat" },
     { 265, "linkat" },
     { 266, "symlinkat" },
-    { 267, "readlinkat", readlinkFunc },
+    { 267, "readlinkat", readlinkFunc<X86Linux64> },
     { 268, "fchmodat" },
     { 269, "faccessat" },
     { 270, "pselect6" },
diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc
index 3a732c0..45f14be 100644
--- a/src/sim/syscall_emul.cc
+++ b/src/sim/syscall_emul.cc
@@ -336,26 +336,6 @@
 }


-SyscallReturn
-munmapFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> start, size_t length)
-{
-    // Even if the system is currently not capable of recycling physical
-    // pages, there is no reason we can't unmap them so that we trigger
-    // appropriate seg faults when the application mistakenly tries to
-    // access them again.
-    auto p = tc->getProcessPtr();
-
-    if (p->pTable->pageOffset(start))
-        return -EINVAL;
-
-    length = roundUp(length, p->pTable->pageSize());
-
-    p->memState->unmapRegion(start, length);
-
-    return 0;
-}
-
-
 const char *hostname = "m5.eecs.umich.edu";

 SyscallReturn
@@ -399,71 +379,6 @@
 }

 SyscallReturn
-readlinkFunc(SyscallDesc *desc, ThreadContext *tc,
-             VPtr<> pathname, VPtr<> buf_ptr, size_t bufsiz)
-{
-    std::string path;
-    if (!SETranslatingPortProxy(tc).tryReadString(path, pathname))
-        return -EFAULT;
-
-    return readlinkImpl(desc, tc, path, buf_ptr, bufsiz);
-}
-
-SyscallReturn
-readlinkImpl(SyscallDesc *desc, ThreadContext *tc,
-             std::string path, VPtr<> buf_ptr, size_t bufsiz)
-{
-    auto p = tc->getProcessPtr();
-
-    // Adjust path for cwd and redirection
-    path = p->checkPathRedirect(path);
-
-    BufferArg buf(buf_ptr, bufsiz);
-
-    int result = -1;
-    if (path != "/proc/self/exe") {
-        result = readlink(path.c_str(), (char *)buf.bufferPtr(), bufsiz);
-    } else {
-        // Emulate readlink() called on '/proc/self/exe' should return the
-        // absolute path of the binary running in the simulated system (the
-        // Process' executable). It is possible that using this path in
-        // the simulated system will result in unexpected behavior if:
-        //  1) One binary runs another (e.g., -c time -o "my_binary"), and
-        //     called binary calls readlink().
- // 2) The host's full path to the running benchmark changes from one - // simulation to another. This can result in different simulated - // performance since the simulated system will process the binary
-        //     path differently, even if the binary itself does not change.
-
-        // Get the absolute canonical path to the running application
-        char real_path[PATH_MAX];
-        char *check_real_path = realpath(p->progName(), real_path);
-        if (!check_real_path) {
-            fatal("readlink('/proc/self/exe') unable to resolve path to "
-                  "executable: %s", p->progName());
-        }
-        strncpy((char*)buf.bufferPtr(), real_path, bufsiz);
-        size_t real_path_len = strlen(real_path);
-        if (real_path_len > bufsiz) {
-            // readlink will truncate the contents of the
-            // path to ensure it is no more than bufsiz
-            result = bufsiz;
-        } else {
-            result = real_path_len;
-        }
-
-        // Issue a warning about potential unexpected results
- warn_once("readlink() called on '/proc/self/exe' may yield unexpected "
-                  "results in various settings.\n      Returning '%s'\n",
-                  (char*)buf.bufferPtr());
-    }
-
-    buf.copyOut(SETranslatingPortProxy(tc));
-
-    return (result == -1) ? -errno : result;
-}
-
-SyscallReturn
 unlinkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname)
 {
     std::string path;
@@ -1263,99 +1178,6 @@
     return (status == -1) ? -errno : status;
 }

-SyscallReturn
-recvfromFunc(SyscallDesc *desc, ThreadContext *tc,
-             int tgt_fd, VPtr<> bufrPtr, size_t bufrLen, int flags,
-             VPtr<> addrPtr, VPtr<> addrlenPtr)
-{
-    auto p = tc->getProcessPtr();
-
- auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
-    if (!sfdp)
-        return -EBADF;
-    int sim_fd = sfdp->getSimFD();
-
-    // Reserve buffer space.
-    BufferArg bufrBuf(bufrPtr, bufrLen);
-
-    SETranslatingPortProxy proxy(tc);
-
-    // Get address length.
-    socklen_t addrLen = 0;
-    if (addrlenPtr != 0) {
-        // Read address length parameter.
-        BufferArg addrlenBuf(addrlenPtr, sizeof(socklen_t));
-        addrlenBuf.copyIn(proxy);
-        addrLen = *((socklen_t *)addrlenBuf.bufferPtr());
-    }
-
-    struct sockaddr sa, *sap = NULL;
-    if (addrLen != 0) {
-        BufferArg addrBuf(addrPtr, addrLen);
-        addrBuf.copyIn(proxy);
-        memcpy(&sa, (struct sockaddr *)addrBuf.bufferPtr(),
-               sizeof(struct sockaddr));
-        sap = &sa;
-    }
-
-    ssize_t recvd_size = recvfrom(sim_fd,
-                                  (void *)bufrBuf.bufferPtr(),
- bufrLen, flags, sap, (socklen_t *)&addrLen);
-
-    if (recvd_size == -1)
-        return -errno;
-
-    // Pass the received data out.
-    bufrBuf.copyOut(proxy);
-
-    // Copy address to addrPtr and pass it on.
-    if (sap != NULL) {
-        BufferArg addrBuf(addrPtr, addrLen);
-        memcpy(addrBuf.bufferPtr(), sap, sizeof(sa));
-        addrBuf.copyOut(proxy);
-    }
-
-    // Copy len to addrlenPtr and pass it on.
-    if (addrLen != 0) {
-        BufferArg addrlenBuf(addrlenPtr, sizeof(socklen_t));
-        *(socklen_t *)addrlenBuf.bufferPtr() = addrLen;
-        addrlenBuf.copyOut(proxy);
-    }
-
-    return recvd_size;
-}
-
-SyscallReturn
-sendtoFunc(SyscallDesc *desc, ThreadContext *tc,
-           int tgt_fd, VPtr<> bufrPtr, size_t bufrLen, int flags,
-           VPtr<> addrPtr, socklen_t addrLen)
-{
-    auto p = tc->getProcessPtr();
-
- auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
-    if (!sfdp)
-        return -EBADF;
-    int sim_fd = sfdp->getSimFD();
-
-    // Reserve buffer space.
-    BufferArg bufrBuf(bufrPtr, bufrLen);
-    bufrBuf.copyIn(SETranslatingPortProxy(tc));
-
-    struct sockaddr sa, *sap = nullptr;
-    memset(&sa, 0, sizeof(sockaddr));
-    if (addrLen != 0) {
-        BufferArg addrBuf(addrPtr, addrLen);
-        addrBuf.copyIn(SETranslatingPortProxy(tc));
-        memcpy(&sa, (sockaddr*)addrBuf.bufferPtr(), addrLen);
-        sap = &sa;
-    }
-
-    ssize_t sent_size = sendto(sim_fd,
-                               (void *)bufrBuf.bufferPtr(),
-                               bufrLen, flags, sap, (socklen_t)addrLen);
-
-    return (sent_size == -1) ? -errno : sent_size;
-}

 SyscallReturn
 recvmsgFunc(SyscallDesc *desc, ThreadContext *tc,
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index e46f059..0923e63 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -172,10 +172,6 @@
                           int tgt_fd, uint64_t offset_high,
uint32_t offset_low, VPtr<> result_ptr, int whence);

-/// Target munmap() handler.
-SyscallReturn munmapFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> start,
-                         size_t length);
-
 /// Target shutdown() handler.
 SyscallReturn shutdownFunc(SyscallDesc *desc, ThreadContext *tc,
                            int tgt_fd, int how);
@@ -188,12 +184,6 @@
 SyscallReturn getcwdFunc(SyscallDesc *desc, ThreadContext *tc,
                          VPtr<> buf_ptr, unsigned long size);

-/// Target readlink() handler.
-SyscallReturn readlinkFunc(SyscallDesc *desc, ThreadContext *tc,
-                           VPtr<> pathname, VPtr<> buf, size_t bufsiz);
-SyscallReturn readlinkImpl(SyscallDesc *desc, ThreadContext *tc,
-                           std::string path, VPtr<> buf, size_t bufsiz);
-
 /// Target unlink() handler.
 SyscallReturn unlinkFunc(SyscallDesc *desc, ThreadContext *tc,
                          VPtr<> pathname);
@@ -325,16 +315,6 @@
                              int tgt_fd, VPtr<> buf_ptr, unsigned count);
 #endif

-// Target sendto() handler.
-SyscallReturn sendtoFunc(SyscallDesc *desc, ThreadContext *tc,
- int tgt_fd, VPtr<> bufrPtr, size_t bufrLen, int flags,
-                         VPtr<> addrPtr, socklen_t addrLen);
-
-// Target recvfrom() handler.
-SyscallReturn recvfromFunc(SyscallDesc *desc, ThreadContext *tc,
-                           int tgt_fd, VPtr<> bufrPtr, size_t bufrLen,
-                           int flags, VPtr<> addrPtr, VPtr<> addrlenPtr);
-
 // Target recvmsg() handler.
 SyscallReturn recvmsgFunc(SyscallDesc *desc, ThreadContext *tc,
                           int tgt_fd, VPtr<> msgPtr, int flags);
@@ -979,7 +959,8 @@
 template <class OS>
 SyscallReturn
 readlinkatFunc(SyscallDesc *desc, ThreadContext *tc,
-               int dirfd, VPtr<> pathname, VPtr<> buf, size_t bufsiz)
+               int dirfd, VPtr<> pathname, VPtr<> buf_ptr,
+               typename OS::size_t bufsiz)
 {
     std::string path;
     if (!SETranslatingPortProxy(tc).tryReadString(path, pathname))
@@ -990,7 +971,65 @@
         return res;
     }

-    return readlinkImpl(desc, tc, path, buf, bufsiz);
+    auto p = tc->getProcessPtr();
+
+    // Adjust path for cwd and redirection
+    path = p->checkPathRedirect(path);
+
+    BufferArg buf(buf_ptr, bufsiz);
+
+    int result = -1;
+    if (path != "/proc/self/exe") {
+        result = readlink(path.c_str(), (char *)buf.bufferPtr(), bufsiz);
+    } else {
+        // Emulate readlink() called on '/proc/self/exe' should return the
+        // absolute path of the binary running in the simulated system (the
+        // Process' executable). It is possible that using this path in
+        // the simulated system will result in unexpected behavior if:
+        //  1) One binary runs another (e.g., -c time -o "my_binary"), and
+        //     called binary calls readlink().
+ // 2) The host's full path to the running benchmark changes from one + // simulation to another. This can result in different simulated + // performance since the simulated system will process the binary
+        //     path differently, even if the binary itself does not change.
+
+        // Get the absolute canonical path to the running application
+        char real_path[PATH_MAX];
+        char *check_real_path = realpath(p->progName(), real_path);
+        if (!check_real_path) {
+            fatal("readlink('/proc/self/exe') unable to resolve path to "
+                  "executable: %s", p->progName());
+        }
+        strncpy((char*)buf.bufferPtr(), real_path, bufsiz);
+        typename OS::size_t real_path_len = strlen(real_path);
+        if (real_path_len > bufsiz) {
+            // readlink will truncate the contents of the
+            // path to ensure it is no more than bufsiz
+            result = bufsiz;
+        } else {
+            result = real_path_len;
+        }
+
+        // Issue a warning about potential unexpected results
+ warn_once("readlink() called on '/proc/self/exe' may yield unexpected "
+                  "results in various settings.\n      Returning '%s'\n",
+                  (char*)buf.bufferPtr());
+    }
+
+    buf.copyOut(SETranslatingPortProxy(tc));
+
+    return (result == -1) ? -errno : result;
+}
+
+/// Target readlink() handler
+template <class OS>
+SyscallReturn
+readlinkFunc(SyscallDesc *desc, ThreadContext *tc,
+             VPtr<> pathname, VPtr<> buf_ptr,
+             typename OS::size_t bufsiz)
+{
+    return readlinkatFunc<OS>(desc, tc, OS::TGT_AT_FDCWD,
+        pathname, buf_ptr, bufsiz);
 }

 /// Target renameat() handler.
@@ -1625,7 +1664,8 @@
 template <class OS>
 SyscallReturn
 readvFunc(SyscallDesc *desc, ThreadContext *tc,
-          int tgt_fd, uint64_t tiov_base, size_t count)
+          int tgt_fd, uint64_t tiov_base,
+          typename OS::size_t count)
 {
     auto p = tc->getProcessPtr();

@@ -1637,7 +1677,7 @@
     SETranslatingPortProxy prox(tc);
     typename OS::tgt_iovec tiov[count];
     struct iovec hiov[count];
-    for (size_t i = 0; i < count; ++i) {
+    for (typename OS::size_t i = 0; i < count; ++i) {
         prox.readBlob(tiov_base + (i * sizeof(typename OS::tgt_iovec)),
                       &tiov[i], sizeof(typename OS::tgt_iovec));
         hiov[i].iov_len = gtoh(tiov[i].iov_len, OS::byteOrder);
@@ -1647,7 +1687,7 @@
     int result = readv(sim_fd, hiov, count);
     int local_errno = errno;

-    for (size_t i = 0; i < count; ++i) {
+    for (typename OS::size_t i = 0; i < count; ++i) {
         if (result != -1) {
             prox.writeBlob(htog(tiov[i].iov_base, OS::byteOrder),
                            hiov[i].iov_base, hiov[i].iov_len);
@@ -1662,7 +1702,8 @@
 template <class OS>
 SyscallReturn
 writevFunc(SyscallDesc *desc, ThreadContext *tc,
-           int tgt_fd, uint64_t tiov_base, size_t count)
+           int tgt_fd, uint64_t tiov_base,
+           typename OS::size_t count)
 {
     auto p = tc->getProcessPtr();

@@ -1673,7 +1714,7 @@

     SETranslatingPortProxy prox(tc);
     struct iovec hiov[count];
-    for (size_t i = 0; i < count; ++i) {
+    for (typename OS::size_t i = 0; i < count; ++i) {
         typename OS::tgt_iovec tiov;

         prox.readBlob(tiov_base + i*sizeof(typename OS::tgt_iovec),
@@ -1686,7 +1727,7 @@

     int result = writev(sim_fd, hiov, count);

-    for (size_t i = 0; i < count; ++i)
+    for (typename OS::size_t i = 0; i < count; ++i)
         delete [] (char *)hiov[i].iov_base;

     return (result == -1) ? -errno : result;
@@ -2695,7 +2736,8 @@
 template <class OS>
 SyscallReturn
 schedGetaffinityFunc(SyscallDesc *desc, ThreadContext *tc,
-                     pid_t pid, size_t cpusetsize, VPtr<> cpu_set_mask)
+                     pid_t pid, typename OS::size_t cpusetsize,
+                     VPtr<> cpu_set_mask)
 {
 #if defined(__linux__)
     if (cpusetsize < CPU_ALLOC_SIZE(tc->getSystemPtr()->threads.size()))
@@ -2715,6 +2757,126 @@
 #endif
 }

+// Target recvfrom() handler.
+template <class OS>
+SyscallReturn
+recvfromFunc(SyscallDesc *desc, ThreadContext *tc,
+             int tgt_fd, VPtr<> buf_ptr, typename OS::size_t buf_len,
+             int flags, VPtr<> addr_ptr, VPtr<> addrlen_ptr)
+{
+    auto p = tc->getProcessPtr();
+
+ auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
+    if (!sfdp)
+        return -EBADF;
+    int sim_fd = sfdp->getSimFD();
+
+    // Reserve buffer space.
+    BufferArg buf(buf_ptr, buf_len);
+
+    SETranslatingPortProxy proxy(tc);
+
+    // Get address length.
+    socklen_t addr_len = 0;
+    if (addrlen_ptr != 0) {
+        // Read address length parameter.
+        BufferArg addrlen_buf(addrlen_ptr, sizeof(socklen_t));
+        addrlen_buf.copyIn(proxy);
+        addr_len = *((socklen_t *)addrlen_buf.bufferPtr());
+    }
+
+    struct sockaddr sa, *sap = NULL;
+    if (addr_len != 0) {
+        BufferArg addr_buf(addr_ptr, addr_len);
+        addr_buf.copyIn(proxy);
+        memcpy(&sa, (struct sockaddr *)addr_buf.bufferPtr(),
+               sizeof(struct sockaddr));
+        sap = &sa;
+    }
+
+    ssize_t recvd_size = recvfrom(sim_fd,
+                                  (void *)buf.bufferPtr(),
+ buf_len, flags, sap, (socklen_t *)&addr_len);
+
+    if (recvd_size == -1)
+        return -errno;
+
+    // Pass the received data out.
+    buf.copyOut(proxy);
+
+    // Copy address to addr_ptr and pass it on.
+    if (sap != NULL) {
+        BufferArg addr_buf(addr_ptr, addr_len);
+        memcpy(addr_buf.bufferPtr(), sap, sizeof(sa));
+        addr_buf.copyOut(proxy);
+    }
+
+    // Copy len to addrlen_ptr and pass it on.
+    if (addr_len != 0) {
+        BufferArg addrlen_buf(addrlen_ptr, sizeof(socklen_t));
+        *(socklen_t *)addrlen_buf.bufferPtr() = addr_len;
+        addrlen_buf.copyOut(proxy);
+    }
+
+    return recvd_size;
+}
+
+// Target sendto() handler.
+template <typename OS>
+SyscallReturn
+sendtoFunc(SyscallDesc *desc, ThreadContext *tc,
+ int tgt_fd, VPtr<> buf_ptr, typename OS::size_t buf_len, int flags,
+           VPtr<> addr_ptr, socklen_t addr_len)
+{
+    auto p = tc->getProcessPtr();
+
+ auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
+    if (!sfdp)
+        return -EBADF;
+    int sim_fd = sfdp->getSimFD();
+
+    // Reserve buffer space.
+    BufferArg buf(buf_ptr, buf_len);
+    buf.copyIn(SETranslatingPortProxy(tc));
+
+    struct sockaddr sa, *sap = nullptr;
+    memset(&sa, 0, sizeof(sockaddr));
+    if (addr_len != 0) {
+        BufferArg addr_buf(addr_ptr, addr_len);
+        addr_buf.copyIn(SETranslatingPortProxy(tc));
+        memcpy(&sa, (sockaddr*)addr_buf.bufferPtr(), addr_len);
+        sap = &sa;
+    }
+
+    ssize_t sent_size = sendto(sim_fd,
+                               (void *)buf.bufferPtr(),
+                               buf_len, flags, sap, (socklen_t)addr_len);
+
+    return (sent_size == -1) ? -errno : sent_size;
+}
+
+/// Target munmap() handler.
+template <typename OS>
+SyscallReturn
+munmapFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> start,
+           typename OS::size_t length)
+{
+    // Even if the system is currently not capable of recycling physical
+    // pages, there is no reason we can't unmap them so that we trigger
+    // appropriate seg faults when the application mistakenly tries to
+    // access them again.
+    auto p = tc->getProcessPtr();
+
+    if (p->pTable->pageOffset(start))
+        return -EINVAL;
+
+    length = roundUp(length, p->pTable->pageSize());
+
+    p->memState->unmapRegion(start, length);
+
+    return 0;
+}
+
 } // namespace gem5

 #endif // __SIM_SYSCALL_EMUL_HH__

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/51489
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Id7d7740ac429f534a4089331bedf21dc3951bbad
Gerrit-Change-Number: 51489
Gerrit-PatchSet: 1
Gerrit-Owner: Giacomo Travaglini <giacomo.travagl...@arm.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to