summaryrefslogtreecommitdiff
path: root/src/arch/x86/process.cc
diff options
context:
space:
mode:
authorVince Weaver <vince@csl.cornell.edu>2009-11-04 00:47:12 -0500
committerVince Weaver <vince@csl.cornell.edu>2009-11-04 00:47:12 -0500
commita1042db29098da395d0de96c652c41904feb425a (patch)
treea6ce96e097b8082c6404c819851f0cbe86fa8ca9 /src/arch/x86/process.cc
parent9b0a747dd41d3383769be1cd737733902875a528 (diff)
downloadgem5-a1042db29098da395d0de96c652c41904feb425a.tar.xz
X86: Enable x86_64 vsyscall support
64-bit vsyscall is different than 32-bit. There are only two syscalls, time and gettimeofday. On a real system, there is complicated code that implements these without entering the kernel. That would be complicated to implement in m5. Instead we just place code that calls the regular syscalls (this is how tools such as valgrind handle this case). This is needed for the perlbmk spec2k benchmark.
Diffstat (limited to 'src/arch/x86/process.cc')
-rw-r--r--src/arch/x86/process.cc24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc
index f7b3ce24a..7cc889d7c 100644
--- a/src/arch/x86/process.cc
+++ b/src/arch/x86/process.cc
@@ -139,6 +139,12 @@ X86_64LiveProcess::X86_64LiveProcess(LiveProcessParams *params,
int _numSyscallDescs) :
X86LiveProcess(params, objFile, _syscallDescs, _numSyscallDescs)
{
+
+ vsyscallPage.base = 0xffffffffff600000ULL;
+ vsyscallPage.size = VMPageSize;
+ vsyscallPage.vtimeOffset = 0x400;
+ vsyscallPage.vgettimeofdayOffset = 0x410;
+
// 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.
@@ -205,6 +211,24 @@ X86_64LiveProcess::startup()
argsInit(sizeof(uint64_t), VMPageSize);
+ // Set up the vsyscall page for this process.
+ pTable->allocate(vsyscallPage.base, vsyscallPage.size);
+ uint8_t vtimeBlob[] = {
+ 0x48,0xc7,0xc0,0xc9,0x00,0x00,0x00, // mov $0xc9,%rax
+ 0x0f,0x05, // syscall
+ 0xc3 // retq
+ };
+ initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vtimeOffset,
+ vtimeBlob, sizeof(vtimeBlob));
+
+ uint8_t vgettimeofdayBlob[] = {
+ 0x48,0xc7,0xc0,0x60,0x00,0x00,0x00, // mov $0x60,%rax
+ 0x0f,0x05, // syscall
+ 0xc3 // retq
+ };
+ initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vgettimeofdayOffset,
+ vgettimeofdayBlob, sizeof(vgettimeofdayBlob));
+
for (int i = 0; i < contextIds.size(); i++) {
ThreadContext * tc = system->getThreadContext(contextIds[i]);