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

Change subject: sim-se: replace memstate api with regions
......................................................................

sim-se: replace memstate api with regions

This changeset uses the region abstraction instead of using
memstate to track special beginning and end values for
code regions.

Change-Id: Ife486cc61aeaf2f9a741ff93b8c5a283108d307b
---
M src/arch/alpha/process.cc
M src/arch/x86/process.cc
M src/sim/SConscript
A src/sim/mem_state.cc
M src/sim/mem_state.hh
M src/sim/process.cc
M src/sim/process.hh
M src/sim/syscall_emul.cc
M src/sim/syscall_emul.hh
9 files changed, 135 insertions(+), 109 deletions(-)



diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc
index 3147695..d2f9731 100644
--- a/src/arch/alpha/process.cc
+++ b/src/arch/alpha/process.cc
@@ -54,21 +54,14 @@
       objFile)
 {
     fatal_if(params->useArchPT, "Arch page tables not implemented.");
-    Addr brk_point = roundUp(image.maxAddr(), PageBytes);

-    // Set up stack.  On Alpha, stack goes below the image.
-    Addr stack_base = image.minAddr() - (409600 + 4096);
+    MemState::Regions regs(regions(image));

-    // Set up region for mmaps.
-    Addr mmap_end = 0x10000;
+    Addr base = image.minAddr() - 0x63000;
+    regs["stack"] = {base, base + PageBytes, 0x63000, PageBytes};
+    regs["mmap"]  = {0x10000, 0x10000 + PageBytes, MaxAddr, PageBytes};

-    Addr max_stack_size = 8 * 1024 * 1024;
-
-    // Set pointer for next thread stack.  Reserve 8M for main stack.
-    Addr next_thread_stack_base = stack_base - max_stack_size;
-
-    memState = make_shared<MemState>(brk_point, stack_base, max_stack_size,
-                                     next_thread_stack_base, mmap_end);
+    memState = make_shared<MemState>(regs);
 }

 void
diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc
index 09ff71f..40f1c89 100644
--- a/src/arch/x86/process.cc
+++ b/src/arch/x86/process.cc
@@ -136,14 +136,10 @@
     vsyscallPage.vtimeOffset = 0x400;
     vsyscallPage.vgettimeofdayOffset = 0x0;

-    Addr brk_point = roundUp(image.maxAddr(), PageBytes);
-    Addr stack_base = 0x7FFFFFFFF000ULL;
-    Addr max_stack_size = 8 * 1024 * 1024;
-    Addr next_thread_stack_base = stack_base - max_stack_size;
-    Addr mmap_end = 0x7FFFF7FFF000ULL;
-
-    memState = make_shared<MemState>(brk_point, stack_base, max_stack_size,
-                                     next_thread_stack_base, mmap_end);
+    MemState::Regions regs(regions(image));
+    regs["stack"] = {0x7FFFFFFFF000, 0x7FFFFFFFE000, 0x800000, PageBytes};
+    regs["mmap"]  = {0x7FFFF7FFF000, 0x7FFFF7FFE000, MaxAddr, PageBytes};
+    memState = make_shared<MemState>(regs);
 }

 void
@@ -175,14 +171,10 @@
     vsyscallPage.vsyscallOffset = 0x400;
     vsyscallPage.vsysexitOffset = 0x410;

-    Addr brk_point = roundUp(image.maxAddr(), PageBytes);
-    Addr stack_base = _gdtStart;
-    Addr max_stack_size = 8 * 1024 * 1024;
-    Addr next_thread_stack_base = stack_base - max_stack_size;
-    Addr mmap_end = 0xB7FFF000ULL;
-
-    memState = make_shared<MemState>(brk_point, stack_base, max_stack_size,
-                                     next_thread_stack_base, mmap_end);
+    MemState::Regions regs(regions(image));
+    regs["stack"] = {0xFFFFD000, 0xFFFFC000, 0x800000, PageBytes};
+    regs["mmap"]  = {0xB7FFF000, 0xB7FFE000, MaxAddr, PageBytes};
+    memState = make_shared<MemState>(regs);
 }

 SyscallDesc*
@@ -945,14 +937,15 @@
         aux_padding +
         frame_size;

-    Addr stack_base = memState->getStackBase();
+    auto &region = memState->regions["stack"];
+    Addr stack_base = region.base();

     Addr stack_min = stack_base - space_needed;
     stack_min = roundDown(stack_min, align);

-    unsigned stack_size = stack_base - stack_min;
+    Addr stack_size = stack_base - stack_min;
     stack_size = roundUp(stack_size, pageSize);
-    memState->setStackSize(stack_size);
+    Addr num_pages = stack_size / pageSize;

     // map memory
     Addr stack_end = roundDown(stack_base - stack_size, pageSize);
@@ -1033,7 +1026,7 @@
     tc->pcState(getStartPC());

     // Align the "stack_min" to a page boundary.
-    memState->setStackMin(roundDown(stack_min, pageSize));
+    region.expand(num_pages);
 }

 void
diff --git a/src/sim/SConscript b/src/sim/SConscript
index d35787f..9a141c8 100644
--- a/src/sim/SConscript
+++ b/src/sim/SConscript
@@ -91,6 +91,7 @@
     Source('syscall_desc.cc')
     Source('region.cc')
     GTest('region.test', 'region.test.cc', 'region.cc')
+    Source('mem_state.cc')

 if env['TARGET_ISA'] != 'x86':
     Source('microcode_rom.cc')
diff --git a/src/sim/mem_state.cc b/src/sim/mem_state.cc
new file mode 100644
index 0000000..ed91231
--- /dev/null
+++ b/src/sim/mem_state.cc
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017-2019 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Brandon Potter
+ */
+
+#include "sim/mem_state.hh"
+
+MemState::MemState(Regions _regions)
+    : regions(_regions)
+{
+}
diff --git a/src/sim/mem_state.hh b/src/sim/mem_state.hh
index 03a7197..7e4af76 100644
--- a/src/sim/mem_state.hh
+++ b/src/sim/mem_state.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Advanced Micro Devices, Inc.
+ * Copyright (c) 2017-2019 Advanced Micro Devices, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,11 @@
 #ifndef SRC_SIM_MEM_STATE_HH
 #define SRC_SIM_MEM_STATE_HH

+#include <map>
+#include <string>
+
+#include "sim/region.hh"
+
 /**
  * This class holds the memory state for the Process class and all of its
  * derived, architecture-specific children.
@@ -48,53 +53,12 @@
 class MemState
 {
   public:
-    MemState(Addr brk_point, Addr stack_base, Addr max_stack_size,
-             Addr next_thread_stack_base, Addr mmap_end)
-        : _brkPoint(brk_point), _stackBase(stack_base), _stackSize(0),
-          _maxStackSize(max_stack_size), _stackMin(0),
-          _nextThreadStackBase(next_thread_stack_base), _mmapEnd(mmap_end)
-    { }
+    using Regions = std::map<std::string, Region>;
+    using RegionIterator = Regions::iterator;

-    MemState&
-    operator=(const MemState &in)
-    {
-        if (this == &in)
-            return *this;
+    MemState(Regions);

-        _brkPoint = in._brkPoint;
-        _stackBase = in._stackBase;
-        _stackSize = in._stackSize;
-        _maxStackSize = in._maxStackSize;
-        _stackMin = in._stackMin;
-        _nextThreadStackBase = in._nextThreadStackBase;
-        _mmapEnd = in._mmapEnd;
-        return *this;
-    }
-
-    Addr getBrkPoint() const { return _brkPoint; }
-    Addr getStackBase() const { return _stackBase; }
-    Addr getStackSize() const { return _stackSize; }
-    Addr getMaxStackSize() const { return _maxStackSize; }
-    Addr getStackMin() const { return _stackMin; }
-    Addr getNextThreadStackBase() const { return _nextThreadStackBase; }
-    Addr getMmapEnd() const { return _mmapEnd; }
-
-    void setBrkPoint(Addr brk_point) { _brkPoint = brk_point; }
-    void setStackBase(Addr stack_base) { _stackBase = stack_base; }
-    void setStackSize(Addr stack_size) { _stackSize = stack_size; }
-    void setMaxStackSize(Addr max_stack) { _maxStackSize = max_stack; }
-    void setStackMin(Addr stack_min) { _stackMin = stack_min; }
-    void setNextThreadStackBase(Addr ntsb) { _nextThreadStackBase = ntsb; }
-    void setMmapEnd(Addr mmap_end) { _mmapEnd = mmap_end; }
-
-  private:
-    Addr _brkPoint;
-    Addr _stackBase;
-    Addr _stackSize;
-    Addr _maxStackSize;
-    Addr _stackMin;
-    Addr _nextThreadStackBase;
-    Addr _mmapEnd;
+    Regions regions;
 };

 #endif
diff --git a/src/sim/process.cc b/src/sim/process.cc
index bc9f289..41d6b02 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -371,9 +371,10 @@
 bool
 Process::fixupStackFault(Addr vaddr)
 {
-    Addr stack_min = memState->getStackMin();
-    Addr stack_base = memState->getStackBase();
-    Addr max_stack_size = memState->getMaxStackSize();
+    auto &stack_region = memState->regions["stack"];
+    Addr stack_min = stack_region.cursor();
+    Addr stack_base = stack_region.base();
+    Addr max_stack_size = stack_region.max();

     // Check if this is already on the stack and there's just no page there
     // yet.
@@ -389,10 +390,10 @@
             stack_min -= TheISA::PageBytes;
             if (stack_base - stack_min > max_stack_size)
                 fatal("Maximum stack size exceeded\n");
+            stack_region.expand(1);
             allocateMem(stack_min, TheISA::PageBytes);
             inform("Increasing stack size by one page.");
         }
-        memState->setStackMin(stack_min);
         return true;
     }
     return false;
@@ -507,21 +508,49 @@
// Determine how large the interpreters footprint will be in the process
     // address space.
     Addr interp_mapsize = roundUp(interp->mapSize(), TheISA::PageBytes);
+    Addr num_pages = interp_mapsize / TheISA::PageBytes;

- // We are allocating the memory area; set the bias to the lowest address
-    // in the allocated memory region.
-    Addr mmap_end = memState->getMmapEnd();
+    auto &region = memState->regions["mmap"];
+    Addr mmap_end = region.cursor();
+    region.expand(num_pages);
+
+ // Set the load bias to the lowest address in the allocated memory region.
     Addr ld_bias = mmapGrowsDown() ? mmap_end - interp_mapsize : mmap_end;
-
-    // Adjust the process mmap area to give the interpreter room; the real
-    // execve system call would just invoke the kernel's internal mmap
-    // functions to make these adjustments.
-    mmap_end = mmapGrowsDown() ? ld_bias : mmap_end + interp_mapsize;
-    memState->setMmapEnd(mmap_end);
-
     interp->updateBias(ld_bias);
 }

+MemState::Regions
+Process::regions(const MemoryImage& img, std::string name_prepend)
+{
+    using Segment = MemoryImage::Segment;
+    auto segs = img.segments();
+
+    std::sort(segs.begin(), segs.end(), std::less<Segment>());
+
+    const auto is_executable =
+        [](const Segment& seg) { return seg.executable(); };
+    auto piv = std::stable_partition(segs.begin(),
+                                     segs.end(),
+                                     is_executable);
+
+    auto &bot_seg_text = *segs.begin();
+    auto &top_seg_text = *(piv - 1);
+    auto t_base = roundDown(bot_seg_text.base, PageBytes);
+    auto t_end = roundUp(top_seg_text.base + top_seg_text.size, PageBytes);
+    Region t(t_base, t_end, t_end - t_base, PageBytes);
+    assert(t.valid());
+
+    auto &bot_seg_data = *piv;
+    auto &top_seg_data = segs.back();
+    auto d_base = roundDown(bot_seg_data.base, PageBytes);
+    auto d_end = roundUp(top_seg_data.base + top_seg_data.size, PageBytes);
+    Region d(d_base, d_end, MaxAddr, PageBytes);
+    assert(d.valid());
+
+    return {{name_prepend + "text", t},
+            {name_prepend + "data", d}};
+}
+
 ObjectFile *
 Process::getInterpreter()
 {
diff --git a/src/sim/process.hh b/src/sim/process.hh
index a28d58e..0c18137 100644
--- a/src/sim/process.hh
+++ b/src/sim/process.hh
@@ -291,6 +291,11 @@

     // Process was forked with SIGCHLD set.
     bool *sigchld;
+
+  protected:
+    MemState::Regions regions(const MemoryImage& img,
+                              std::string name_prepend = "");
+
 };

 #endif // __PROCESS_HH__
diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc
index 49fee7e..d380b0e 100644
--- a/src/sim/syscall_emul.cc
+++ b/src/sim/syscall_emul.cc
@@ -247,7 +247,8 @@
     Addr new_brk = p->getSyscallArg(tc, index);

     std::shared_ptr<MemState> mem_state = p->memState;
-    Addr brk_point = mem_state->getBrkPoint();
+    auto &region = mem_state->regions["data"];
+    Addr brk_point = region.cursor();

     // in Linux at least, brk(0) returns the current break value
// (note that the syscall and the glibc function have different behavior)
@@ -259,11 +260,11 @@
         for (ChunkGenerator gen(brk_point,
                                 new_brk - brk_point,
                                 PageBytes); !gen.done(); gen.next()) {
-            if (!p->pTable->translate(gen.addr()))
+            if (!p->pTable->translate(gen.addr())) {
+                region.expand(1);
p->allocateMem(roundDown(gen.addr(), PageBytes), PageBytes);
-
-            // if the address is already there, zero it out
-            else {
+            } else {
+                // if the address is already there, zero it out
                 uint8_t zero = 0;
                 PortProxy &tp = tc->getVirtProxy();

@@ -281,10 +282,9 @@
         }
     }

-    mem_state->setBrkPoint(new_brk);
     DPRINTF_SYSCALL(Verbose, "brk: break point changed to: %#X\n",
-                    mem_state->getBrkPoint());
-    return mem_state->getBrkPoint();
+                    region.cursor());
+    return region.cursor();
 }

 SyscallReturn
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index 2d4ef25..df1e7bc 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -1181,28 +1181,31 @@

     if (new_length > old_length) {
         std::shared_ptr<MemState> mem_state = process->memState;
-        Addr mmap_end = mem_state->getMmapEnd();
+        auto &region = mem_state->regions["mmap"];
+        Addr mmap_end = region.cursor();

         if ((start + old_length) == mmap_end &&
             (!use_provided_address || provided_address == start)) {
             // This case cannot occur when growing downward, as
             // start is greater than or equal to mmap_end.
-            uint64_t diff = new_length - old_length;
+            Addr diff = new_length - old_length;
+            Addr num_pages = diff / TheISA::PageBytes;
             process->allocateMem(mmap_end, diff);
-            mem_state->setMmapEnd(mmap_end + diff);
+            region.expand(num_pages);
             return start;
         } else {
if (!use_provided_address && !(flags & OS::TGT_MREMAP_MAYMOVE)) {
                 warn("can't remap here and MREMAP_MAYMOVE flag not set\n");
                 return -ENOMEM;
             } else {
-                uint64_t new_start = provided_address;
+                Addr new_start = provided_address;
                 if (!use_provided_address) {
                     new_start = process->mmapGrowsDown() ?
                                 mmap_end - new_length : mmap_end;
                     mmap_end = process->mmapGrowsDown() ?
                                new_start : mmap_end + new_length;
-                    mem_state->setMmapEnd(mmap_end);
+                    Addr num_pages = new_length / TheISA::PageBytes;
+                    region.expand(num_pages);
                 }

                 process->pTable->remap(start, old_length, new_start);
@@ -1214,9 +1217,9 @@
                                      new_length - old_length,
                                      use_provided_address /* clobber */);
                 if (use_provided_address &&
-                    ((new_start + new_length > mem_state->getMmapEnd() &&
+                    ((new_start + new_length > region.cursor() &&
                       !process->mmapGrowsDown()) ||
-                    (new_start < mem_state->getMmapEnd() &&
+                    (new_start < region.cursor() &&
                       process->mmapGrowsDown()))) {
// something fishy going on here, at least notify the user
                     // @todo: increase mmap_end?
@@ -1820,12 +1823,14 @@
     // start address unless MAP_FIXED is specified.
     if (!(tgt_flags & OS::TGT_MAP_FIXED)) {
         std::shared_ptr<MemState> mem_state = p->memState;
-        Addr mmap_end = mem_state->getMmapEnd();
+        auto &region = mem_state->regions["mmap"];
+        Addr mmap_end = region.cursor();

         start = p->mmapGrowsDown() ? mmap_end - length : mmap_end;
         mmap_end = p->mmapGrowsDown() ? start : mmap_end + length;

-        mem_state->setMmapEnd(mmap_end);
+        Addr num_pages = length / TheISA::PageBytes;
+        region.expand(num_pages);
     }

     DPRINTF_SYSCALL(Verbose, " mmap range is 0x%x - 0x%x\n",

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/23146
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: Ife486cc61aeaf2f9a741ff93b8c5a283108d307b
Gerrit-Change-Number: 23146
Gerrit-PatchSet: 1
Gerrit-Owner: Brandon Potter <brandon.pot...@amd.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to