Brandon Potter has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/12311

Change subject: syscall_emul: generate /proc/self/maps file
......................................................................

syscall_emul: generate /proc/self/maps file

This change generates /proc/self/maps for the currently
running process. It assummes a system with one process
and one thread per process. This is needed by the OpenCL
runtime, as it calls pthread_getattr_np.

Change-Id: Iee0f35842ef5571f6b0717194bc746a585a945e6
---
M configs/common/FileSystemConfig.py
M src/arch/alpha/process.cc
M src/arch/x86/linux/process.cc
M src/arch/x86/process.cc
M src/kern/linux/linux.cc
M src/kern/linux/linux.hh
M src/mem/vma.hh
M src/sim/mem_state.cc
M src/sim/mem_state.hh
M src/sim/syscall_emul.hh
10 files changed, 92 insertions(+), 23 deletions(-)



diff --git a/configs/common/FileSystemConfig.py b/configs/common/FileSystemConfig.py
index aa0829e..a29c74e 100644
--- a/configs/common/FileSystemConfig.py
+++ b/configs/common/FileSystemConfig.py
@@ -101,6 +101,10 @@
     for i in xrange(options.num_cpus):
         file_append((procdir, 'stat'), 'cpu%d 0 0 0 0 0 0 0\n' % i)

+    mapsdir = joinpath(procdir, 'self')
+    makedirs(mapsdir)
+    file_append((mapsdir, 'maps'), '')
+
     # Set up /sys
     sysdir = joinpath(fsdir, 'sys')
     replace_tree(sysdir)
diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc
index bc7c974..627e859 100644
--- a/src/arch/alpha/process.cc
+++ b/src/arch/alpha/process.cc
@@ -145,9 +145,10 @@
     memState->setStackMin(roundDown(memState->getStackMin(), pageSize));
memState->setStackSize(memState->getStackBase() - memState->getStackMin());
     // map memory
-    memState->allocateMem(memState->getStackMin(),
-                          roundUp(memState->getStackSize(), pageSize)
-                          -1, 0);
+    memState->mapVMARegion(memState->getStackBase() -
+                           memState->getMaxStackSize(),
+                           memState->getMaxStackSize(), -1, 0,
+                           std::string("stack"));

     // map out initial stack contents
Addr argv_array_base = memState->getStackMin() + intSize; // room for argc
diff --git a/src/arch/x86/linux/process.cc b/src/arch/x86/linux/process.cc
index 2928fa7..65e1699 100644
--- a/src/arch/x86/linux/process.cc
+++ b/src/arch/x86/linux/process.cc
@@ -448,7 +448,7 @@
     /* 218 */ SyscallDesc("set_tid_address", setTidAddressFunc),
     /* 219 */ SyscallDesc("restart_syscall", unimplementedFunc),
     /* 220 */ SyscallDesc("semtimedop", unimplementedFunc),
-    /* 221 */ SyscallDesc("fadvise64", unimplementedFunc),
+    /* 221 */ SyscallDesc("fadvise64", ignoreFunc),
     /* 222 */ SyscallDesc("timer_create", unimplementedFunc),
     /* 223 */ SyscallDesc("timer_settime", unimplementedFunc),
     /* 224 */ SyscallDesc("timer_gettime", unimplementedFunc),
diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc
index dd47cc1..b1b39a8 100644
--- a/src/arch/x86/process.cc
+++ b/src/arch/x86/process.cc
@@ -221,7 +221,8 @@
     auto p_table = memState->_pTable;

     // Set up the vsyscall page for this process.
-    memState->mapVMARegion(vsyscallPage.base, vsyscallPage.size, -1, 0);
+    memState->mapVMARegion(vsyscallPage.base, vsyscallPage.size,
+                           -1, 0, std::string("vsyscall"));
     const auto &virt_mem = memState->getVirtMem();
     uint8_t vtimeBlob[] = {
         0x48,0xc7,0xc0,0xc9,0x00,0x00,0x00,    // mov    $0xc9,%rax
@@ -986,7 +987,8 @@
     Addr max_stack_size = memState->getMaxStackSize();
     Addr stack_end = roundDown(stack_base - max_stack_size, pageSize);

-    memState->mapVMARegion(stack_end, max_stack_size, -1, 0);
+    memState->mapVMARegion(stack_end, max_stack_size, -1, 0,
+                           std::string("stack"));

DPRINTF(Stack, "Mapping the stack: 0x%x %dB\n", stack_end, max_stack_size);

diff --git a/src/kern/linux/linux.cc b/src/kern/linux/linux.cc
index b1538a9..5ce515b 100644
--- a/src/kern/linux/linux.cc
+++ b/src/kern/linux/linux.cc
@@ -35,6 +35,8 @@

 #include "cpu/base.hh"
 #include "debug/SyscallVerbose.hh"
+#include "mem/vma.hh"
+#include "sim/mem_state.hh"
 #include "sim/process.hh"
 #include "sim/system.hh"

@@ -55,6 +57,8 @@
     } else if (path.compare(0, 11, "/etc/passwd") == 0) {
         data = Linux::etcPasswd(process, tc);
         matched = true;
+    } else if (path.compare(0, 15, "/proc/self/maps") == 0) {
+        data = Linux::procSelfMaps(process, tc);
} else if (path.compare(0, 30, "/sys/devices/system/cpu/online") == 0) {
         data = Linux::cpuOnline(process, tc);
         matched = true;
@@ -92,6 +96,24 @@
 }

 std::string
+Linux::procSelfMaps(Process *process, ThreadContext *tc)
+{
+    std::stringstream file_content;
+    auto mem_state = process->memState;
+
+    for (auto vma : mem_state->vmaList()) {
+        std::stringstream line;
+        line << std::hex << vma.getStart() << "-";
+        line << std::hex << vma.getEnd() << " ";
+        line << "r-xp 00000000 00:00 0 ";
+        line << "[" << vma.getName() << "]" << std::endl;
+        file_content << line.str();
+    }
+
+    return file_content.str();
+}
+
+std::string
 Linux::cpuOnline(Process *process, ThreadContext *tc)
 {
     return csprintf("0-%d\n",
diff --git a/src/kern/linux/linux.hh b/src/kern/linux/linux.hh
index e559e05..04b5c97 100644
--- a/src/kern/linux/linux.hh
+++ b/src/kern/linux/linux.hh
@@ -236,6 +236,7 @@
                                ThreadContext *tc);
     static std::string procMeminfo(Process *process, ThreadContext *tc);
     static std::string etcPasswd(Process *process, ThreadContext *tc);
+    static std::string procSelfMaps(Process *process, ThreadContext *tc);
     static std::string cpuOnline(Process *process, ThreadContext *tc);

     // For futex system call
diff --git a/src/mem/vma.hh b/src/mem/vma.hh
index 841714d..f7ebbbf 100644
--- a/src/mem/vma.hh
+++ b/src/mem/vma.hh
@@ -31,6 +31,8 @@
 #ifndef SRC_MEM_VMA_HH
 #define SRC_MEM_VMA_HH

+#include <string>
+
 #include "base/addr_range.hh"
 #include "base/mapped_buf.hh"
 #include "base/types.hh"
@@ -39,9 +41,9 @@
 class VMA : public AddrRange
 {
   public:
-    VMA(Addr sa, uint64_t len, int fd, int off)
+    VMA(Addr sa, Addr len, int fd, int off, std::string vma_name)
         : AddrRange(sa, sa + len - 1), _origHostBuf(nullptr),
-          _hostBuf(nullptr), _hostBufLen(0)
+          _hostBuf(nullptr), _hostBufLen(0), _vmaName(vma_name)
     {
         if (fd != -1) {
_origHostBuf = std::make_shared<MappedFileBuffer>(fd, len, off);
@@ -92,8 +94,13 @@
      */
     void sliceRegionLeft(Addr slice_addr);

+    Addr getStart() { return _start; }
+    Addr getEnd() { return _end; }
+    std::string getName() { return _vmaName; }
+
   private:
     void CHECK();
+
     /**
      * The host file backing will be chopped up and reassigned as pages are
      * mapped, remapped, and unmapped. In addition to the current host
@@ -112,6 +119,14 @@
      * Length of host buffer for this virtual memory area.
      */
     Addr _hostBufLen;
+
+    /**
+     * Human-readable name associated with the virtual memory area.
+     * The name is useful for debugging and also exposing vma state through
+     * the psuedo file system (i.e. Linux's /proc/self/maps) to the
+     * application.
+     */
+    std::string _vmaName;
 };

 #endif
diff --git a/src/sim/mem_state.cc b/src/sim/mem_state.cc
index 794d25b..3f18033 100644
--- a/src/sim/mem_state.cc
+++ b/src/sim/mem_state.cc
@@ -42,12 +42,13 @@
 MemState::MemState(Process *owner, Addr brk_point, Addr stack_base,
                    Addr max_stack_size, Addr next_thread_stack_base,
                    Addr mmap_end, System *system,
-                   std::shared_ptr<EmulationPageTable> p_table)
+                   std::shared_ptr<EmulationPageTable> p_table,
+                   Addr vsyscall_point, Addr vsyscall_size)
     : _pTable(p_table), _ownerProcesses{owner}, _brkPoint(brk_point),
       _stackBase(stack_base), _maxStackSize(max_stack_size),
       _nextThreadStackBase(next_thread_stack_base),
-      _mmapEnd(mmap_end),
-      _endBrkPoint(brk_point),
+      _mmapEnd(mmap_end), _vsyscallPoint(vsyscall_point),
+      _vsyscallSize(vsyscall_size), _endBrkPoint(brk_point),
       _virtMem(system->getSystemPort(), system->cacheLineSize(), this,
                SETranslatingPortProxy::Always)
 {
@@ -146,16 +147,18 @@
          * implemented if it actually becomes necessary; probably only
          * necessary if the list becomes too long to walk.
          */
-        mapVMARegion(_endBrkPoint, new_brk - _endBrkPoint, -1, 0);
+        mapVMARegion(_endBrkPoint, new_brk - _endBrkPoint, -1, 0,
+                     std::string("heap"));
         _endBrkPoint = new_brk;
     }
 }

 void
-MemState::mapVMARegion(Addr start_addr, Addr length, int sim_fd, Addr offset) +MemState::mapVMARegion(Addr start_addr, Addr length, int sim_fd, Addr offset,
+                       std::string vma_name)
 {
-    DPRINTF(SyscallVerbose, "vma: creating region [0x%x - 0x%x]\n",
-            start_addr, start_addr + length - 1);
+    DPRINTF(SyscallVerbose, "vma: creating region (%s) [0x%x - 0x%x]\n",
+            vma_name.c_str(), start_addr, start_addr + length - 1);

     /**
      * Avoid creating a region that has preexisting mappings. This should
@@ -168,7 +171,7 @@
     /**
      * Record the region in our list structure.
      */
-    _vmaList.emplace_back(start_addr, length, sim_fd, offset);
+    _vmaList.emplace_back(start_addr, length, sim_fd, offset, vma_name);
 }

 void
diff --git a/src/sim/mem_state.hh b/src/sim/mem_state.hh
index b74c3e5..fd6e40cb 100644
--- a/src/sim/mem_state.hh
+++ b/src/sim/mem_state.hh
@@ -35,6 +35,7 @@

 #include <list>
 #include <memory>
+#include <string>
 #include <vector>

 #include "mem/page_table.hh"
@@ -64,7 +65,8 @@
     MemState(Process *owner, Addr brk_point, Addr stack_base,
              Addr max_stack_size, Addr next_thread_stack_base,
              Addr mmap_end, System *system,
-             std::shared_ptr<EmulationPageTable> p_table);
+             std::shared_ptr<EmulationPageTable> p_table,
+             Addr vsyscall_point = 0, Addr vsyscall_size = 0);

     MemState& operator=(const MemState &in);

@@ -88,7 +90,8 @@

     const SETranslatingPortProxy& getVirtMem() const { return _virtMem; }

- void mapVMARegion(Addr start_addr, Addr length, int sim_fd, Addr offset);
+    void mapVMARegion(Addr start_addr, Addr length, int sim_fd,
+                      Addr offset, std::string vma_name);

     void unmapVMARegion(Addr start_addr, Addr length);

@@ -202,6 +205,8 @@
         paramIn(cp, "mmapEnd", _mmapEnd);
     }

+    const std::list<VMA> & vmaList() { return _vmaList; }
+
   private:
     void replicatePage(const MemState &in, Addr vaddr, Addr new_paddr,
                        bool alloc_page);
@@ -226,6 +231,8 @@
     Addr _stackMin;
     Addr _nextThreadStackBase;
     Addr _mmapEnd;
+    Addr _vsyscallPoint;
+    Addr _vsyscallSize;

     /**
      * Keeps record of the furthest mapped heap location for the VMAs.
@@ -233,7 +240,7 @@
     Addr _endBrkPoint;

     /**
-     * The _vmaList member is list of virtual memory areas in the target
+     * The _vmaList member is a list of virtual memory areas in the target
      * application space that have been allocated by the target. In most
      * operating systems, lazy allocation is used and these structures (or
      * equivalent ones) are used to track the valid address ranges.
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index 619cc04..d506a6e 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -774,7 +774,8 @@
     int sim_fd = -1;
     std::string used_path;
     std::vector<std::string> special_paths =
-            { "/proc/meminfo/", "/system/", "/platform/", "/etc/passwd" };
+            { "/proc/meminfo/", "/system/", "/platform/", "/etc/passwd",
+              "/proc/self/maps"};
     for (auto entry : special_paths) {
         if (startswith(path, entry)) {
             sim_fd = OS::openSpecialFile(abs_path, p, tc);
@@ -1089,7 +1090,7 @@
             // This case cannot occur when growing downward, as
             // start is greater than or equal to mmap_end.
             uint64_t diff = new_length - old_length;
-            mem_state->mapVMARegion(mmap_end, diff, -1, 0);
+            mem_state->mapVMARegion(mmap_end, diff, -1, 0, "remapped!?");
             mem_state->setMmapEnd(mmap_end + diff);
             return start;
         } else {
@@ -1126,7 +1127,8 @@
                 }
                 warn("returning %08p as start\n", new_start);
                 mem_state->remapVMARegion(start, new_start, old_length);
-                mem_state->mapVMARegion(new_start, new_length, -1, 0);
+                mem_state->mapVMARegion(new_start, new_length,
+                                        -1, 0, "remapped!?");
                 return new_start;
             }
         }
@@ -1807,10 +1809,22 @@
     }

     /**
+     * Figure out a human-readable name for the mapping.
+     */
+    std::string vma_name;
+    if (tgt_flags & OS::TGT_MAP_ANONYMOUS) {
+        vma_name = std::string("anon");
+    } else {
+        std::shared_ptr<FDEntry> fdep = (*p->fds)[tgt_fd];
+        auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(fdep);
+        vma_name = ffdp->getFileName();
+    }
+
+    /**
      * Setup the correct VMA for this region.  The physical pages will be
      * mapped lazily.
      */
-    mem_state->mapVMARegion(start, length, sim_fd, offset);
+    mem_state->mapVMARegion(start, length, sim_fd, offset, vma_name);

     return start;
 }

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

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: Iee0f35842ef5571f6b0717194bc746a585a945e6
Gerrit-Change-Number: 12311
Gerrit-PatchSet: 1
Gerrit-Owner: Brandon Potter <brandon.pot...@amd.com>
Gerrit-Reviewer: Alexandru Duțu <alexandru.d...@amd.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to