AlphaProcess::AlphaProcess(ProcessParams *params, ObjectFile *objFile)
: Process(params, objFile)
{
- memState->brkPoint = objFile->dataBase() + objFile->dataSize() +
- objFile->bssSize();
- memState->brkPoint = roundUp(memState->brkPoint, PageBytes);
+ Addr brk_point = objFile->dataBase() + objFile->dataSize() +
+ objFile->bssSize();
+ brk_point = roundUp(brk_point, PageBytes);
// Set up stack. On Alpha, stack goes below text section. This
// code should get moved to some architecture-specific spot.
- memState->stackBase = objFile->textBase() - (409600+4096);
+ Addr stack_base = objFile->textBase() - (409600+4096);
- // Set up region for mmaps. Tru64 seems to start just above 0 and
- // grow up from there.
- memState->mmapEnd = 0x10000;
+ // Set up region for mmaps.
+ Addr mmap_end = 0x10000;
+
+ Addr max_stack_size = 8 * 1024 * 1024;
// Set pointer for next thread stack. Reserve 8M for main stack.
- memState->nextThreadStackBase = memState->stackBase - (8 * 1024 * 1024);
+ 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);
}
void
space_needed = 32*1024;
// set bottom of stack
- memState->stackMin = memState->stackBase - space_needed;
+ memState->setStackMin(memState->getStackBase() - space_needed);
// align it
- memState->stackMin = roundDown(memState->stackMin, pageSize);
- memState->stackSize = memState->stackBase - memState->stackMin;
+ memState->setStackMin(roundDown(memState->getStackMin(), pageSize));
+ memState->setStackSize(memState->getStackBase() - memState->getStackMin());
// map memory
- allocateMem(memState->stackMin, roundUp(memState->stackSize, pageSize));
+ allocateMem(memState->getStackMin(), roundUp(memState->getStackSize(),
+ pageSize));
// map out initial stack contents
- Addr argv_array_base = memState->stackMin + intSize; // room for argc
+ Addr argv_array_base = memState->getStackMin() + intSize; // room for argc
Addr envp_array_base = argv_array_base + argv_array_size;
Addr auxv_array_base = envp_array_base + envp_array_size;
Addr arg_data_base = auxv_array_base + auxv_array_size;
else
panic("Unknown int size");
- initVirtMem.writeBlob(memState->stackMin, (uint8_t*)&argc, intSize);
+ initVirtMem.writeBlob(memState->getStackMin(), (uint8_t*)&argc, intSize);
copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
setSyscallArg(tc, 0, argc);
setSyscallArg(tc, 1, argv_array_base);
- tc->setIntReg(StackPointerReg, memState->stackMin);
+ tc->setIntReg(StackPointerReg, memState->getStackMin());
tc->pcState(getStartPC());
}
ObjectFile::Arch _arch)
: ArmProcess(params, objFile, _arch)
{
- memState->stackBase = 0xbf000000L;
-
- // Set pointer for next thread stack. Reserve 8M for main stack.
- memState->nextThreadStackBase = memState->stackBase - (8 * 1024 * 1024);
-
- // Set up break point (Top of Heap)
- memState->brkPoint = objFile->dataBase() + objFile->dataSize() +
- objFile->bssSize();
- memState->brkPoint = roundUp(memState->brkPoint, PageBytes);
-
- // Set up region for mmaps. For now, start at bottom of kuseg space.
- memState->mmapEnd = 0x40000000L;
+ Addr brk_point = roundUp(objFile->dataBase() + objFile->dataSize() +
+ objFile->bssSize(), PageBytes);
+ Addr stack_base = 0xbf000000L;
+ Addr max_stack_size = 8 * 1024 * 1024;
+ Addr next_thread_stack_base = stack_base - max_stack_size;
+ Addr mmap_end = 0x40000000L;
+
+ memState = make_shared<MemState>(brk_point, stack_base, max_stack_size,
+ next_thread_stack_base, mmap_end);
}
ArmProcess64::ArmProcess64(ProcessParams *params, ObjectFile *objFile,
ObjectFile::Arch _arch)
: ArmProcess(params, objFile, _arch)
{
- memState->stackBase = 0x7fffff0000L;
-
- // Set pointer for next thread stack. Reserve 8M for main stack.
- memState->nextThreadStackBase = memState->stackBase - (8 * 1024 * 1024);
-
- // Set up break point (Top of Heap)
- memState->brkPoint = objFile->dataBase() + objFile->dataSize() +
- objFile->bssSize();
- memState->brkPoint = roundUp(memState->brkPoint, PageBytes);
-
- // Set up region for mmaps. For now, start at bottom of kuseg space.
- memState->mmapEnd = 0x4000000000L;
+ Addr brk_point = roundUp(objFile->dataBase() + objFile->dataSize() +
+ objFile->bssSize(), PageBytes);
+ Addr stack_base = 0x7fffff0000L;
+ Addr max_stack_size = 8 * 1024 * 1024;
+ Addr next_thread_stack_base = stack_base - max_stack_size;
+ Addr mmap_end = 0x4000000000L;
+
+ memState = make_shared<MemState>(brk_point, stack_base, max_stack_size,
+ next_thread_stack_base, mmap_end);
}
void
int space_needed = frame_size + aux_padding;
- memState->stackMin = memState->stackBase - space_needed;
- memState->stackMin = roundDown(memState->stackMin, align);
- memState->stackSize = memState->stackBase - memState->stackMin;
+ memState->setStackMin(memState->getStackBase() - space_needed);
+ memState->setStackMin(roundDown(memState->getStackMin(), align));
+ memState->setStackSize(memState->getStackBase() - memState->getStackMin());
// map memory
- allocateMem(roundDown(memState->stackMin, pageSize),
- roundUp(memState->stackSize, pageSize));
+ allocateMem(roundDown(memState->getStackMin(), pageSize),
+ roundUp(memState->getStackSize(), pageSize));
// map out initial stack contents
- IntType sentry_base = memState->stackBase - sentry_size;
+ IntType sentry_base = memState->getStackBase() - sentry_size;
IntType aux_data_base = sentry_base - aux_data_size;
IntType env_data_base = aux_data_base - env_data_size;
IntType arg_data_base = env_data_base - arg_data_size;
DPRINTF(Stack, "0x%x - envp array\n", envp_array_base);
DPRINTF(Stack, "0x%x - argv array\n", argv_array_base);
DPRINTF(Stack, "0x%x - argc \n", argc_base);
- DPRINTF(Stack, "0x%x - stack min\n", memState->stackMin);
+ DPRINTF(Stack, "0x%x - stack min\n", memState->getStackMin());
// write contents to stack
ThreadContext *tc = system->getThreadContext(contextIds[0]);
//Set the stack pointer register
- tc->setIntReg(spIndex, memState->stackMin);
+ tc->setIntReg(spIndex, memState->getStackMin());
//A pointer to a function to run when the program exits. We'll set this
//to zero explicitly to make sure this isn't used.
tc->setIntReg(ArgumentReg0, 0);
tc->pcState(pc);
//Align the "stackMin" to a page boundary.
- memState->stackMin = roundDown(memState->stackMin, pageSize);
+ memState->setStackMin(roundDown(memState->getStackMin(), pageSize));
}
ArmISA::IntReg
{
// Set up stack. On MIPS, stack starts at the top of kuseg
// user address space. MIPS stack grows down from here
- memState->stackBase = 0x7FFFFFFF;
+ Addr stack_base = 0x7FFFFFFF;
+
+ Addr max_stack_size = 8 * 1024 * 1024;
// Set pointer for next thread stack. Reserve 8M for main stack.
- memState->nextThreadStackBase = memState->stackBase - (8 * 1024 * 1024);
+ Addr next_thread_stack_base = stack_base - max_stack_size;
// Set up break point (Top of Heap)
- memState->brkPoint = objFile->dataBase() + objFile->dataSize() +
- objFile->bssSize();
- memState->brkPoint = roundUp(memState->brkPoint, PageBytes);
+ Addr brk_point = objFile->dataBase() + objFile->dataSize() +
+ objFile->bssSize();
+ brk_point = roundUp(brk_point, PageBytes);
// Set up region for mmaps. Start it 1GB above the top of the heap.
- memState->mmapEnd = memState->brkPoint + 0x40000000L;
+ Addr mmap_end = brk_point + 0x40000000L;
+
+ memState = make_shared<MemState>(brk_point, stack_base, max_stack_size,
+ next_thread_stack_base, mmap_end);
}
void
env_data_size;
// set bottom of stack
- memState->stackMin = memState->stackBase - space_needed;
+ memState->setStackMin(memState->getStackBase() - space_needed);
// align it
- memState->stackMin = roundDown(memState->stackMin, pageSize);
- memState->stackSize = memState->stackBase - memState->stackMin;
+ memState->setStackMin(roundDown(memState->getStackMin(), pageSize));
+ memState->setStackSize(memState->getStackBase() - memState->getStackMin());
// map memory
- allocateMem(memState->stackMin, roundUp(memState->stackSize, pageSize));
+ allocateMem(memState->getStackMin(), roundUp(memState->getStackSize(),
+ pageSize));
- // map out initial stack contents
- IntType argv_array_base = memState->stackMin + intSize; // room for argc
+ // map out initial stack contents; leave room for argc
+ IntType argv_array_base = memState->getStackMin() + intSize;
IntType envp_array_base = argv_array_base + argv_array_size;
IntType auxv_array_base = envp_array_base + envp_array_size;
IntType arg_data_base = auxv_array_base + auxv_array_size;
argc = htog((IntType)argc);
- initVirtMem.writeBlob(memState->stackMin, (uint8_t*)&argc, intSize);
+ initVirtMem.writeBlob(memState->getStackMin(), (uint8_t*)&argc, intSize);
copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
setSyscallArg(tc, 0, argc);
setSyscallArg(tc, 1, argv_array_base);
- tc->setIntReg(StackPointerReg, memState->stackMin);
+ tc->setIntReg(StackPointerReg, memState->getStackMin());
tc->pcState(getStartPC());
}
PowerProcess::PowerProcess(ProcessParams *params, ObjectFile *objFile)
: Process(params, objFile)
{
- memState->stackBase = 0xbf000000L;
+ // Set up break point (Top of Heap)
+ Addr brk_point = objFile->dataBase() + objFile->dataSize() +
+ objFile->bssSize();
+ brk_point = roundUp(brk_point, PageBytes);
- // Set pointer for next thread stack. Reserve 8M for main stack.
- memState->nextThreadStackBase = memState->stackBase - (8 * 1024 * 1024);
+ Addr stack_base = 0xbf000000L;
- // Set up break point (Top of Heap)
- memState->brkPoint = objFile->dataBase() + objFile->dataSize() +
- objFile->bssSize();
- memState->brkPoint = roundUp(memState->brkPoint, 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;
// Set up region for mmaps. For now, start at bottom of kuseg space.
- memState->mmapEnd = 0x70000000L;
+ Addr mmap_end = 0x70000000L;
+
+ memState = make_shared<MemState>(brk_point, stack_base, max_stack_size,
+ next_thread_stack_base, mmap_end);
}
void
int space_needed = frame_size + aux_padding;
- memState->stackMin = memState->stackBase - space_needed;
- memState->stackMin = roundDown(memState->stackMin, align);
- memState->stackSize = memState->stackBase - memState->stackMin;
+ Addr stack_min = memState->getStackBase() - space_needed;
+ stack_min = roundDown(stack_min, align);
+
+ memState->setStackSize(memState->getStackBase() - stack_min);
// map memory
- allocateMem(roundDown(memState->stackMin, pageSize),
- roundUp(memState->stackSize, pageSize));
+ allocateMem(roundDown(stack_min, pageSize),
+ roundUp(memState->getStackSize(), pageSize));
// map out initial stack contents
- uint32_t sentry_base = memState->stackBase - sentry_size;
+ uint32_t sentry_base = memState->getStackBase() - sentry_size;
uint32_t aux_data_base = sentry_base - aux_data_size;
uint32_t env_data_base = aux_data_base - env_data_size;
uint32_t arg_data_base = env_data_base - arg_data_size;
DPRINTF(Stack, "0x%x - envp array\n", envp_array_base);
DPRINTF(Stack, "0x%x - argv array\n", argv_array_base);
DPRINTF(Stack, "0x%x - argc \n", argc_base);
- DPRINTF(Stack, "0x%x - stack min\n", memState->stackMin);
+ DPRINTF(Stack, "0x%x - stack min\n", stack_min);
// write contents to stack
ThreadContext *tc = system->getThreadContext(contextIds[0]);
//Set the stack pointer register
- tc->setIntReg(StackPointerReg, memState->stackMin);
+ tc->setIntReg(StackPointerReg, stack_min);
tc->pcState(getStartPC());
//Align the "stack_min" to a page boundary.
- memState->stackMin = roundDown(memState->stackMin, pageSize);
+ memState->setStackMin(roundDown(stack_min, pageSize));
}
PowerISA::IntReg
{
// Set up stack. On RISC-V, stack starts at the top of kuseg
// user address space. RISC-V stack grows down from here
- memState->stackBase = (Addr)0x7FFFFFFF;
+ Addr stack_base = 0x7FFFFFFF;
+
+ Addr max_stack_size = 8 * 1024 * 1024;
// Set pointer for next thread stack. Reserve 8M for main stack.
- memState->nextThreadStackBase = memState->stackBase - (8 * 1024 * 1024);
+ Addr next_thread_stack_base = stack_base - max_stack_size;
// Set up break point (Top of Heap)
- memState->brkPoint = objFile->bssBase() + objFile->bssSize();
+ Addr brk_point = objFile->bssBase() + objFile->bssSize();
// Set up region for mmaps. Start it 1GB above the top of the heap.
- memState->mmapEnd = memState->brkPoint + 0x40000000L;
+ Addr mmap_end = brk_point + 0x40000000L;
+
+ memState = make_shared<MemState>(brk_point, stack_base, max_stack_size,
+ next_thread_stack_base, mmap_end);
}
void
env_data_size += env.size() + 1;
int auxv_array_size = 2 * sizeof(IntType)*auxv.size();
- memState->stackSize = sizeof(IntType) + argv_array_size + 2 *
+ Addr stack_size = sizeof(IntType) + argv_array_size + 2 * sizeof(Addr) +
sizeof(Addr) + arg_data_size + 2 * sizeof(Addr);
if (!envp.empty()) {
- memState->stackSize += 2 * sizeof(Addr) + envp_array_size + 2 *
+ stack_size += 2 * sizeof(Addr) + envp_array_size + 2 *
sizeof(Addr) + env_data_size;
}
if (!auxv.empty())
- memState->stackSize += 2 * sizeof(Addr) + auxv_array_size;
- memState->stackMin = roundDown(memState->stackBase - memState->stackSize,
- pageSize);
- allocateMem(memState->stackMin, roundUp(memState->stackSize, pageSize));
+ stack_size += 2 * sizeof(Addr) + auxv_array_size;
+
+ memState->setStackSize(stack_size);
+
+ Addr stack_min = roundDown(memState->getStackBase() -
+ stack_size, pageSize);
+ allocateMem(stack_min, roundUp(memState->getStackSize(), pageSize));
+
+ memState->setStackMin(stack_min);
- Addr argv_array_base = memState->stackMin + sizeof(IntType);
+ Addr argv_array_base = memState->getStackMin() + sizeof(IntType);
Addr arg_data_base = argv_array_base + argv_array_size + 2 * sizeof(Addr);
Addr envp_array_base = arg_data_base + arg_data_size;
if (!envp.empty())
}
}
- Addr sp = memState->stackMin;
+ Addr sp = memState->getStackMin();
initVirtMem.writeBlob(sp, (uint8_t *)&argc, sizeof(IntType));
sp += sizeof(IntType);
for (Addr arg_pointer: arg_pointers) {
}
ThreadContext *tc = system->getThreadContext(contextIds[0]);
- tc->setIntReg(StackPointerReg, memState->stackMin);
+ tc->setIntReg(StackPointerReg, memState->getStackMin());
tc->pcState(getStartPC());
}
Addr _StackBias)
: Process(params, objFile), StackBias(_StackBias)
{
-
- // XXX all the below need to be updated for SPARC - Ali
- memState->brkPoint = objFile->dataBase() + objFile->dataSize() +
- objFile->bssSize();
- memState->brkPoint = roundUp(memState->brkPoint, PageBytes);
-
- // Set pointer for next thread stack. Reserve 8M for main stack.
- memState->nextThreadStackBase = memState->stackBase - (8 * 1024 * 1024);
-
// Initialize these to 0s
fillStart = 0;
spillStart = 0;
aux_padding +
frame_size;
- memState->stackMin = memState->stackBase - space_needed;
- memState->stackMin = roundDown(memState->stackMin, align);
- memState->stackSize = memState->stackBase - memState->stackMin;
+ memState->setStackMin(memState->getStackBase() - space_needed);
+ memState->setStackMin(roundDown(memState->getStackMin(), align));
+ memState->setStackSize(memState->getStackBase() - memState->getStackMin());
// Allocate space for the stack
- allocateMem(roundDown(memState->stackMin, pageSize),
- roundUp(memState->stackSize, pageSize));
+ allocateMem(roundDown(memState->getStackMin(), pageSize),
+ roundUp(memState->getStackSize(), pageSize));
// map out initial stack contents
- IntType sentry_base = memState->stackBase - sentry_size;
+ IntType sentry_base = memState->getStackBase() - sentry_size;
IntType file_name_base = sentry_base - file_name_size;
IntType env_data_base = file_name_base - env_data_size;
IntType arg_data_base = env_data_base - arg_data_size;
DPRINTF(Stack, "%#x - argv array\n", argv_array_base);
DPRINTF(Stack, "%#x - argc \n", argc_base);
DPRINTF(Stack, "%#x - window save\n", window_save_base);
- DPRINTF(Stack, "%#x - stack min\n", memState->stackMin);
+ DPRINTF(Stack, "%#x - stack min\n", memState->getStackMin());
- assert(window_save_base == memState->stackMin);
+ assert(window_save_base == memState->getStackMin());
// write contents to stack
// Set up space for the trap handlers into the processes address space.
// Since the stack grows down and there is reserved address space abov
// it, we can put stuff above it and stay out of the way.
- fillStart = memState->stackBase;
+ fillStart = memState->getStackBase();
spillStart = fillStart + sizeof(MachInst) * numFillInsts;
ThreadContext *tc = system->getThreadContext(contextIds[0]);
// assert(NumArgumentRegs >= 2);
// tc->setIntReg(ArgumentReg[0], argc);
// tc->setIntReg(ArgumentReg[1], argv_array_base);
- tc->setIntReg(StackPointerReg, memState->stackMin - StackBias);
+ tc->setIntReg(StackPointerReg, memState->getStackMin() - StackBias);
// %g1 is a pointer to a function that should be run at exit. Since we
// don't have anything like that, it should be set to 0.
tc->pcState(getStartPC());
// Align the "stack_min" to a page boundary.
- memState->stackMin = roundDown(memState->stackMin, pageSize);
+ memState->setStackMin(roundDown(memState->getStackMin(), pageSize));
}
void
#ifndef __SPARC_PROCESS_HH__
#define __SPARC_PROCESS_HH__
+#include <memory>
#include <string>
#include <vector>
+#include "arch/sparc/isa_traits.hh"
+#include "base/loader/object_file.hh"
#include "mem/page_table.hh"
#include "sim/byteswap.hh"
#include "sim/process.hh"
-class ObjectFile;
-
class SparcProcess : public Process
{
protected:
Sparc32Process(ProcessParams * params, ObjectFile *objFile)
: SparcProcess(params, objFile, 0)
{
+ Addr brk_point = objFile->dataBase() + objFile->dataSize() +
+ objFile->bssSize();
+ brk_point = roundUp(brk_point, SparcISA::PageBytes);
+
+ // Reserve 8M for main stack.
+ Addr max_stack_size = 8 * 1024 * 1024;
+
// Set up stack. On SPARC Linux, stack goes from the top of memory
// downward, less the hole for the kernel address space.
- memState->stackBase = (Addr)0xf0000000ULL;
+ Addr stack_base = 0xf0000000ULL;
+
+ // Set pointer for next thread stack.
+ Addr next_thread_stack_base = stack_base - max_stack_size;
// Set up region for mmaps.
- memState->mmapEnd = 0x70000000;
+ Addr mmap_end = 0x70000000;
+
+ memState = std::make_shared<MemState>(brk_point, stack_base,
+ max_stack_size,
+ next_thread_stack_base,
+ mmap_end);
}
void initState();
Sparc64Process(ProcessParams * params, ObjectFile *objFile)
: SparcProcess(params, objFile, 2047)
{
+ Addr brk_point = objFile->dataBase() + objFile->dataSize() +
+ objFile->bssSize();
+ brk_point = roundUp(brk_point, SparcISA::PageBytes);
+
+ Addr max_stack_size = 8 * 1024 * 1024;
+
// Set up stack. On SPARC Linux, stack goes from the top of memory
// downward, less the hole for the kernel address space.
- memState->stackBase = (Addr)0x80000000000ULL;
+ Addr stack_base = 0x80000000000ULL;
+
+ // Set pointer for next thread stack. Reserve 8M for main stack.
+ Addr next_thread_stack_base = stack_base - max_stack_size;
// Set up region for mmaps.
- memState->mmapEnd = 0xfffff80000000000ULL;
+ Addr mmap_end = 0xfffff80000000000ULL;
+
+ memState = std::make_shared<MemState>(brk_point, stack_base,
+ max_stack_size,
+ next_thread_stack_base,
+ mmap_end);
}
void initState();
: Process(params, objFile), syscallDescs(_syscallDescs),
numSyscallDescs(_numSyscallDescs)
{
- memState->brkPoint = objFile->dataBase() + objFile->dataSize()
- + objFile->bssSize();
- memState->brkPoint = roundUp(memState->brkPoint, PageBytes);
}
void X86Process::clone(ThreadContext *old_tc, ThreadContext *new_tc,
vsyscallPage.vtimeOffset = 0x400;
vsyscallPage.vgettimeofdayOffset = 0x0;
- // Set up stack. On X86_64 Linux, stack goes from the top of memory
- // downward, less the hole for the kernel address space plus one page
- // for undertermined purposes.
- memState->stackBase = (Addr)0x7FFFFFFFF000ULL;
-
- // Set pointer for next thread stack. Reserve 8M for main stack.
- memState->nextThreadStackBase = memState->stackBase - (8 * 1024 * 1024);
-
- // "mmap_base" is a function which defines where mmap region starts in
- // the process address space.
- // mmap_base: PAGE_ALIGN(TASK_SIZE-MIN_GAP-mmap_rnd())
- // TASK_SIZE: (1<<47)-PAGE_SIZE
- // MIN_GAP: 128*1024*1024+stack_maxrandom_size()
- // We do not use any address space layout randomization in gem5
- // therefore the random fields become zero; the smallest gap space was
- // chosen but gap could potentially be much larger.
- memState->mmapEnd = (Addr)0x7FFFF7FFF000ULL;
+ Addr brk_point = roundUp(objFile->dataBase() + objFile->dataSize() +
+ objFile->bssSize(), 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);
}
void
vsyscallPage.vsyscallOffset = 0x400;
vsyscallPage.vsysexitOffset = 0x410;
- memState->stackBase = _gdtStart;
-
- // Set pointer for next thread stack. Reserve 8M for main stack.
- memState->nextThreadStackBase = memState->stackBase - (8 * 1024 * 1024);
+ Addr brk_point = roundUp(objFile->dataBase() + objFile->dataSize() +
+ objFile->bssSize(), 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;
- // "mmap_base" is a function which defines where mmap region starts in
- // the process address space.
- // mmap_base: PAGE_ALIGN(TASK_SIZE-MIN_GAP-mmap_rnd())
- // TASK_SIZE: 0xC0000000
- // MIN_GAP: 128*1024*1024+stack_maxrandom_size()
- // We do not use any address space layout randomization in gem5
- // therefore the random fields become zero; the smallest gap space was
- // chosen but gap could potentially be much larger.
- memState->mmapEnd = (Addr)0xB7FFF000ULL;
+ memState = make_shared<MemState>(brk_point, stack_base, max_stack_size,
+ next_thread_stack_base, mmap_end);
}
SyscallDesc*
aux_padding +
frame_size;
- memState->stackMin = memState->stackBase - space_needed;
- memState->stackMin = roundDown(memState->stackMin, align);
- memState->stackSize = roundUp(memState->stackBase - memState->stackMin,
- pageSize);
+ Addr stack_base = memState->getStackBase();
+
+ Addr stack_min = stack_base - space_needed;
+ stack_min = roundDown(stack_min, align);
+
+ unsigned stack_size = stack_base - stack_min;
+ stack_size = roundUp(stack_size, pageSize);
+ memState->setStackSize(stack_size);
// map memory
- Addr stack_end = roundDown(memState->stackBase - memState->stackSize,
- pageSize);
+ Addr stack_end = roundDown(stack_base - stack_size, pageSize);
- DPRINTF(Stack, "Mapping the stack: 0x%x %dB\n",
- stack_end, memState->stackSize);
- allocateMem(stack_end, memState->stackSize);
+ DPRINTF(Stack, "Mapping the stack: 0x%x %dB\n", stack_end, stack_size);
+ allocateMem(stack_end, stack_size);
// map out initial stack contents
- IntType sentry_base = memState->stackBase - sentry_size;
+ IntType sentry_base = stack_base - sentry_size;
IntType file_name_base = sentry_base - file_name_size;
IntType env_data_base = file_name_base - env_data_size;
IntType arg_data_base = env_data_base - arg_data_size;
DPRINTF(Stack, "0x%x - envp array\n", envp_array_base);
DPRINTF(Stack, "0x%x - argv array\n", argv_array_base);
DPRINTF(Stack, "0x%x - argc \n", argc_base);
- DPRINTF(Stack, "0x%x - stack min\n", memState->stackMin);
+ DPRINTF(Stack, "0x%x - stack min\n", stack_min);
// write contents to stack
ThreadContext *tc = system->getThreadContext(contextIds[0]);
//Set the stack pointer register
- tc->setIntReg(StackPointerReg, memState->stackMin);
+ tc->setIntReg(StackPointerReg, stack_min);
// There doesn't need to be any segment base added in since we're dealing
// with the flat segmentation model.
tc->pcState(getStartPC());
//Align the "stack_min" to a page boundary.
- memState->stackMin = roundDown(memState->stackMin, pageSize);
+ memState->setStackMin(roundDown(stack_min, pageSize));
}
void
if (proc->mmapGrowsDown()) {
DPRINTF(HSAIL, "GROWS DOWN");
- start = mem_state->mmapEnd - length;
- mem_state->mmapEnd = start;
+ start = mem_state->getMmapEnd() - length;
+ mem_state->setMmapEnd(start);
} else {
DPRINTF(HSAIL, "GROWS UP");
- start = mem_state->mmapEnd;
- mem_state->mmapEnd += length;
+ start = mem_state->getMmapEnd();
+ mem_state->setMmapEnd(start + length);
// assertion to make sure we don't overwrite the stack (it grows down)
- assert(mem_state->stackBase - proc->maxStackSize > mem_state->mmapEnd);
+ assert(mem_state->getStackBase() - mem_state->getMaxStackSize() >
+ mem_state->getMmapEnd());
}
DPRINTF(HSAIL,"Shader::mmap start= %#x, %#x\n", start, length);
--- /dev/null
+/*
+ * Copyright (c) 2017 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
+ */
+
+#ifndef SRC_SIM_MEM_STATE_HH
+#define SRC_SIM_MEM_STATE_HH
+
+/**
+ * This class holds the memory state for the Process class and all of its
+ * derived, architecture-specific children.
+ *
+ * The fields held in this class dynamically change as the process object
+ * is run in the simulator. They are updated by system calls and faults;
+ * each change represents a modification to the process address space.
+ * The stack, heap, and mmap boundaries are held with this class along with
+ * the base of the next thread stack.
+ *
+ * The class is meant to be allocated dynamically and shared through a
+ * pointer interface because two process can potentially share their virtual
+ * address space if certain options are passed into the clone(2).
+ */
+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)
+ { }
+
+ MemState&
+ operator=(const MemState &in)
+ {
+ if (this == &in)
+ return *this;
+
+ _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;
+};
+
+#endif
_pid(params->pid), _ppid(params->ppid),
_pgid(params->pgid), drivers(params->drivers),
fds(make_shared<FDArray>(params->input, params->output, params->errout)),
- maxStackSize(params->maxStackSize),
childClearTID(0)
{
if (_pid >= System::maxPID)
_tgid = params->pid;
exitGroup = new bool();
- memState = new MemState();
sigchld = new bool();
if (!debugSymbolTable) {
np->pTable = pTable;
ntc->getMemProxy().setPageTable(np->pTable);
- delete np->memState;
np->memState = memState;
} else {
/**
bool
Process::fixupStackFault(Addr vaddr)
{
+ Addr stack_min = memState->getStackMin();
+ Addr stack_base = memState->getStackBase();
+ Addr max_stack_size = memState->getMaxStackSize();
+
// Check if this is already on the stack and there's just no page there
// yet.
- if (vaddr >= memState->stackMin && vaddr < memState->stackBase) {
+ if (vaddr >= stack_min && vaddr < stack_base) {
allocateMem(roundDown(vaddr, PageBytes), PageBytes);
return true;
}
// We've accessed the next page of the stack, so extend it to include
// this address.
- if (vaddr < memState->stackMin
- && vaddr >= memState->stackBase - maxStackSize) {
- while (vaddr < memState->stackMin) {
- memState->stackMin -= TheISA::PageBytes;
- if (memState->stackBase - memState->stackMin > maxStackSize)
+ if (vaddr < stack_min && vaddr >= stack_base - max_stack_size) {
+ while (vaddr < stack_min) {
+ stack_min -= TheISA::PageBytes;
+ if (stack_base - stack_min > max_stack_size)
fatal("Maximum stack size exceeded\n");
- allocateMem(memState->stackMin, TheISA::PageBytes);
+ allocateMem(stack_min, TheISA::PageBytes);
inform("Increasing stack size by one page.");
};
+ memState->setStackMin(stack_min);
return true;
}
return false;
void
Process::serialize(CheckpointOut &cp) const
{
- SERIALIZE_SCALAR(memState->brkPoint);
- SERIALIZE_SCALAR(memState->stackBase);
- SERIALIZE_SCALAR(memState->stackSize);
- SERIALIZE_SCALAR(memState->stackMin);
- SERIALIZE_SCALAR(memState->nextThreadStackBase);
- SERIALIZE_SCALAR(memState->mmapEnd);
pTable->serialize(cp);
/**
* Checkpoints for file descriptors currently do not work. Need to
void
Process::unserialize(CheckpointIn &cp)
{
- UNSERIALIZE_SCALAR(memState->brkPoint);
- UNSERIALIZE_SCALAR(memState->stackBase);
- UNSERIALIZE_SCALAR(memState->stackSize);
- UNSERIALIZE_SCALAR(memState->stackMin);
- UNSERIALIZE_SCALAR(memState->nextThreadStackBase);
- UNSERIALIZE_SCALAR(memState->mmapEnd);
pTable->unserialize(cp);
/**
* Checkpoints for file descriptors currently do not work. Need to
// We are allocating the memory area; set the bias to the lowest address
// in the allocated memory region.
- Addr *end = &memState->mmapEnd;
- Addr ld_bias = mmapGrowsDown() ? *end - interp_mapsize : *end;
+ Addr mmap_end = memState->getMmapEnd();
+ 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.
- *end = mmapGrowsDown() ? ld_bias : *end + interp_mapsize;
+ mmap_end = mmapGrowsDown() ? ld_bias : mmap_end + interp_mapsize;
+ memState->setMmapEnd(mmap_end);
interp->updateBias(ld_bias);
}
#include "mem/se_translating_port_proxy.hh"
#include "sim/fd_array.hh"
#include "sim/fd_entry.hh"
+#include "sim/mem_state.hh"
#include "sim/sim_object.hh"
struct ProcessParams;
class Process : public SimObject
{
public:
-
- struct MemState
- {
- Addr brkPoint;
- Addr stackBase;
- unsigned stackSize;
- Addr stackMin;
- Addr nextThreadStackBase;
- Addr mmapEnd;
-
- MemState()
- : brkPoint(0), stackBase(0), stackSize(0), stackMin(0),
- nextThreadStackBase(0), mmapEnd(0)
- { }
-
- MemState&
- operator=(const MemState &in)
- {
- if (this == &in)
- return *this;
-
- brkPoint = in.brkPoint;
- stackBase = in.stackBase;
- stackSize = in.stackSize;
- stackMin = in.stackMin;
- nextThreadStackBase = in.nextThreadStackBase;
- mmapEnd = in.mmapEnd;
- return *this;
- }
-
- void serialize(CheckpointOut &cp) const;
- void unserialize(CheckpointIn &cp);
- };
-
Process(ProcessParams *params, ObjectFile *obj_file);
void serialize(CheckpointOut &cp) const override;
std::shared_ptr<FDArray> fds;
bool *exitGroup;
-
- Addr maxStackSize;
- MemState *memState;
+ std::shared_ptr<MemState> memState;
/**
* Calls a futex wakeup at the address specified by this pointer when
int index = 0;
Addr new_brk = p->getSyscallArg(tc, index);
+ std::shared_ptr<MemState> mem_state = p->memState;
+ Addr brk_point = mem_state->getBrkPoint();
+
// in Linux at least, brk(0) returns the current break value
// (note that the syscall and the glibc function have different behavior)
if (new_brk == 0)
- return p->memState->brkPoint;
+ return brk_point;
- if (new_brk > p->memState->brkPoint) {
+ if (new_brk > brk_point) {
// might need to allocate some new pages
- for (ChunkGenerator gen(p->memState->brkPoint,
- new_brk - p->memState->brkPoint,
+ for (ChunkGenerator gen(brk_point,
+ new_brk - brk_point,
PageBytes); !gen.done(); gen.next()) {
if (!p->pTable->translate(gen.addr()))
p->allocateMem(roundDown(gen.addr(), PageBytes), PageBytes);
// if the address is already there, zero it out
else {
- uint8_t zero = 0;
+ uint8_t zero = 0;
SETranslatingPortProxy &tp = tc->getMemProxy();
// split non-page aligned accesses
}
}
- p->memState->brkPoint = new_brk;
+ mem_state->setBrkPoint(new_brk);
DPRINTF_SYSCALL(Verbose, "brk: break point changed to: %#X\n",
- p->memState->brkPoint);
- return p->memState->brkPoint;
+ mem_state->getBrkPoint());
+ return mem_state->getBrkPoint();
}
SyscallReturn
new_length = roundUp(new_length, TheISA::PageBytes);
if (new_length > old_length) {
- if ((start + old_length) == process->memState->mmapEnd &&
+ std::shared_ptr<MemState> mem_state = process->memState;
+ Addr mmap_end = mem_state->getMmapEnd();
+
+ if ((start + old_length) == mmap_end &&
(!use_provided_address || provided_address == start)) {
uint64_t diff = new_length - old_length;
- process->allocateMem(process->memState->mmapEnd, diff);
- process->memState->mmapEnd += diff;
+ process->allocateMem(mmap_end, diff);
+ mem_state->setMmapEnd(mmap_end + diff);
return start;
} else {
if (!use_provided_address && !(flags & OS::TGT_MREMAP_MAYMOVE)) {
return -ENOMEM;
} else {
uint64_t new_start = use_provided_address ?
- provided_address : process->memState->mmapEnd;
+ provided_address : mmap_end;
process->pTable->remap(start, old_length, new_start);
warn("mremapping to new vaddr %08p-%08p, adding %d\n",
new_start, new_start + new_length,
new_length - old_length,
use_provided_address /* clobber */);
if (!use_provided_address)
- process->memState->mmapEnd += new_length;
+ mem_state->setMmapEnd(mmap_end + new_length);
if (use_provided_address &&
- new_start + new_length > process->memState->mmapEnd) {
+ new_start + new_length > mem_state->getMmapEnd()) {
// something fishy going on here, at least notify the user
// @todo: increase mmap_end?
warn("mmap region limit exceeded with MREMAP_FIXED\n");
pp->executable.assign(*(new std::string(p->progName())));
pp->cmd.push_back(*(new std::string(p->progName())));
pp->system = p->system;
- pp->maxStackSize = p->maxStackSize;
pp->cwd.assign(p->getcwd());
pp->input.assign("stdin");
pp->output.assign("stdout");
// Extend global mmap region if necessary. Note that we ignore the
// start address unless MAP_FIXED is specified.
if (!(tgt_flags & OS::TGT_MAP_FIXED)) {
- Addr *end = &p->memState->mmapEnd;
- start = p->mmapGrowsDown() ? *end - length : *end;
- *end = p->mmapGrowsDown() ? start : *end + length;
+ std::shared_ptr<MemState> mem_state = p->memState;
+ Addr mmap_end = mem_state->getMmapEnd();
+
+ start = p->mmapGrowsDown() ? mmap_end - length : mmap_end;
+ mmap_end = p->mmapGrowsDown() ? start : mmap_end + length;
+
+ mem_state->setMmapEnd(mmap_end);
}
DPRINTF_SYSCALL(Verbose, " mmap range is 0x%x - 0x%x\n",
pp->errout.assign("cerr");
pp->cwd.assign(p->getcwd());
pp->system = p->system;
- pp->maxStackSize = p->maxStackSize;
/**
* Prevent process object creation with identical PIDs (which will trip
* a fatal check in Process constructor). The execve call is supposed to