34#include "debug/Vma.hh"
45 Addr max_stack_size,
Addr next_thread_stack_base,
47 : _ownerProcess(owner),
48 _pageBytes(owner->pTable->pageSize()), _brkPoint(brk_point),
49 _stackBase(stack_base), _stackSize(max_stack_size),
50 _maxStackSize(max_stack_size), _stackMin(stack_base - max_stack_size),
51 _nextThreadStackBase(next_thread_stack_base),
84 Addr end_addr = start_addr + length;
85 const AddrRange range(start_addr, end_addr);
87 if (
vma.intersects(range))
95 for (
auto start = start_addr; start < end_addr;
98 panic(
"Someone allocated physical memory at VA %p without "
99 "creating a VMA!\n", start);
130 if (new_brk < old_brk) {
131 const auto length = page_aligned_old_brk - page_aligned_new_brk;
147 if (page_aligned_new_brk > page_aligned_old_brk) {
148 auto length = page_aligned_new_brk - page_aligned_old_brk;
154 if (!
isUnmapped(page_aligned_old_brk, length)) {
165 mapRegion(page_aligned_old_brk, length,
"heap");
173 const std::string& region_name,
int sim_fd,
Addr offset)
175 DPRINTF(Vma,
"memstate: creating vma (%s) [0x%x - 0x%x]\n",
176 region_name.c_str(), start_addr, start_addr + length);
194 Addr end_addr = start_addr + length;
195 const AddrRange range(start_addr, end_addr);
199 if (
vma->isStrictSuperset(range)) {
200 DPRINTF(Vma,
"memstate: split vma [0x%x - 0x%x] into "
201 "[0x%x - 0x%x] and [0x%x - 0x%x]\n",
203 vma->start(), start_addr,
204 end_addr,
vma->end());
210 _vmaList.back().sliceRegionRight(start_addr);
215 vma->sliceRegionLeft(end_addr);
222 }
else if (
vma->isSubset(range)) {
223 DPRINTF(Vma,
"memstate: destroying vma [0x%x - 0x%x]\n",
224 vma->start(),
vma->end());
232 }
else if (
vma->intersects(range)) {
236 if (
vma->start() < start_addr) {
237 DPRINTF(Vma,
"memstate: resizing vma [0x%x - 0x%x] "
238 "into [0x%x - 0x%x]\n",
240 vma->start(), start_addr);
244 vma->sliceRegionRight(start_addr);
246 DPRINTF(Vma,
"memstate: resizing vma [0x%x - 0x%x] "
247 "into [0x%x - 0x%x]\n",
249 end_addr,
vma->end());
253 vma->sliceRegionLeft(end_addr);
269 tc->getMMUPtr()->flushAll();
285 }
while (length > 0);
291 Addr end_addr = start_addr + length;
292 const AddrRange range(start_addr, end_addr);
296 if (
vma->isStrictSuperset(range)) {
301 _vmaList.back().sliceRegionRight(start_addr);
307 _vmaList.back().sliceRegionLeft(end_addr);
313 vma->sliceRegionLeft(start_addr);
314 vma->sliceRegionRight(end_addr);
315 vma->remap(new_start_addr);
322 }
else if (
vma->isSubset(range)) {
326 vma->remap(
vma->start() - start_addr + new_start_addr);
327 }
else if (
vma->intersects(range)) {
333 if (
vma->start() < start_addr) {
337 _vmaList.back().sliceRegionRight(start_addr);
342 vma->sliceRegionLeft(start_addr);
343 vma->remap(new_start_addr);
348 _vmaList.back().sliceRegionLeft(end_addr);
353 vma->sliceRegionRight(end_addr);
354 vma->remap(new_start_addr +
vma->start() - start_addr);
370 tc->getMMUPtr()->flushAll();
388 }
while (length > 0);
409 if (
vma.hasHostBuf()) {
445 fatal(
"Maximum stack size exceeded\n");
448 inform(
"Increasing stack size by one page.");
468 DPRINTF(Vma,
"memstate: cannot extend vma for mmap region at %p. "
469 "Virtual address range is already reserved! Skipping a page "
470 "and trying again!\n", start);
475 DPRINTF(Vma,
"memstate: extending mmap region (old %p) (new %p)\n",
487 std::stringstream file_content;
490 std::stringstream line;
491 line << std::hex <<
vma.start() <<
"-";
492 line << std::hex <<
vma.end() <<
" ";
493 line <<
"r-xp 00000000 00:00 0 ";
494 line <<
"[" <<
vma.getName() <<
"]" << std::endl;
495 file_content << line.str();
498 return file_content.str();
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
const Entry * lookup(Addr vaddr)
Lookup function.
virtual void remap(Addr vaddr, int64_t size, Addr new_vaddr)
virtual void unmap(Addr vaddr, int64_t size)
virtual bool isUnmapped(Addr vaddr, int64_t size)
Check if any pages in a region are already allocated.
This class holds the memory state for the Process class and all of its derived, architecture-specific...
std::list< VMA > _vmaList
The _vmaList member is a list of virtual memory areas in the target application space that have been ...
Process * _ownerProcess
Owner process of MemState.
Addr extendMmap(Addr length)
bool fixupFault(Addr vaddr)
Attempt to fix up a fault at vaddr by allocating a page.
Addr _nextThreadStackBase
void updateBrkRegion(Addr old_brk, Addr new_brk)
Change the end of a process' program break.
std::string printVmaList()
Print the list of VMAs in a format similar to /proc/self/maps.
bool isUnmapped(Addr start_addr, Addr length)
Check if any page in the virtual address range from start_addr to start_addr + length is already mapp...
void resetOwner(Process *owner)
Change the Process owner in case this MemState is copied.
MemState & operator=(const MemState &in)
MemState(Process *owner, Addr brk_point, Addr stack_base, Addr max_stack_size, Addr next_thread_stack_base, Addr mmap_end)
void unmapRegion(Addr start_addr, Addr length)
Unmap a pre-existing region.
void remapRegion(Addr start_addr, Addr new_start_addr, Addr length)
Remap a pre-existing region.
void mapRegion(Addr start_addr, Addr length, const std::string &name="anon", int sim_fd=-1, Addr offset=0)
Add a new memory region.
virtual bool mmapGrowsDown() const
Does mmap region grow upward or downward from mmapEnd? Most platforms grow downward,...
void allocateMem(Addr vaddr, int64_t size, bool clobber=false)
std::vector< ContextID > contextIds
EmulationPageTable * pTable
static constexpr T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
static constexpr T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
#define panic(...)
This implements a cprintf based panic() function.
#define fatal(...)
This implements a cprintf based fatal() function.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.