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