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 ®ion = 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 ®ion = 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 ®ion = 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 ®ion = 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 ®ion = 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