summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/linux/process.cc24
-rw-r--r--src/arch/x86/linux/process.hh7
-rw-r--r--src/arch/x86/process.cc64
-rw-r--r--src/arch/x86/process.hh47
-rw-r--r--src/arch/x86/types.hh7
5 files changed, 125 insertions, 24 deletions
diff --git a/src/arch/x86/linux/process.cc b/src/arch/x86/linux/process.cc
index 56688fc89..c2d67eb81 100644
--- a/src/arch/x86/linux/process.cc
+++ b/src/arch/x86/linux/process.cc
@@ -276,10 +276,10 @@ static SyscallDesc syscallDescs64[] = {
/* 53 */ SyscallDesc("socketpair", unimplementedFunc),
/* 54 */ SyscallDesc("setsockopt", unimplementedFunc),
/* 55 */ SyscallDesc("getsockopt", unimplementedFunc),
- /* 56 */ SyscallDesc("clone", cloneFunc),
+ /* 56 */ SyscallDesc("clone", cloneFunc<X86Linux64>),
/* 57 */ SyscallDesc("fork", unimplementedFunc),
/* 58 */ SyscallDesc("vfork", unimplementedFunc),
- /* 59 */ SyscallDesc("execve", unimplementedFunc),
+ /* 59 */ SyscallDesc("execve", execveFunc<X86Linux64>),
/* 60 */ SyscallDesc("exit", exitFunc),
/* 61 */ SyscallDesc("wait4", unimplementedFunc),
/* 62 */ SyscallDesc("kill", unimplementedFunc),
@@ -438,7 +438,7 @@ static SyscallDesc syscallDescs64[] = {
/* 215 */ SyscallDesc("epoll_wait_old", unimplementedFunc),
/* 216 */ SyscallDesc("remap_file_pages", unimplementedFunc),
/* 217 */ SyscallDesc("getdents64", unimplementedFunc),
- /* 218 */ SyscallDesc("set_tid_address", unimplementedFunc),
+ /* 218 */ SyscallDesc("set_tid_address", setTidAddressFunc),
/* 219 */ SyscallDesc("restart_syscall", unimplementedFunc),
/* 220 */ SyscallDesc("semtimedop", unimplementedFunc),
/* 221 */ SyscallDesc("fadvise64", unimplementedFunc),
@@ -542,6 +542,12 @@ X86_64LinuxProcess::X86_64LinuxProcess(ProcessParams * params,
sizeof(syscallDescs64) / sizeof(SyscallDesc))
{}
+void X86_64LinuxProcess::clone(ThreadContext *old_tc, ThreadContext *new_tc,
+ Process *process, TheISA::IntReg flags)
+{
+ X86_64Process::clone(old_tc, new_tc, (X86_64Process*)process, flags);
+}
+
static SyscallDesc syscallDescs32[] = {
/* 0 */ SyscallDesc("restart_syscall", unimplementedFunc),
/* 1 */ SyscallDesc("exit", exitFunc),
@@ -554,7 +560,7 @@ static SyscallDesc syscallDescs32[] = {
/* 8 */ SyscallDesc("creat", unimplementedFunc),
/* 9 */ SyscallDesc("link", unimplementedFunc),
/* 10 */ SyscallDesc("unlink", unimplementedFunc),
- /* 11 */ SyscallDesc("execve", unimplementedFunc),
+ /* 11 */ SyscallDesc("execve", execveFunc<X86Linux32>),
/* 12 */ SyscallDesc("chdir", unimplementedFunc),
/* 13 */ SyscallDesc("time", timeFunc<X86Linux32>),
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
@@ -663,7 +669,7 @@ static SyscallDesc syscallDescs32[] = {
/* 117 */ SyscallDesc("ipc", unimplementedFunc),
/* 118 */ SyscallDesc("fsync", unimplementedFunc),
/* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
- /* 120 */ SyscallDesc("clone", unimplementedFunc),
+ /* 120 */ SyscallDesc("clone", cloneFunc<X86Linux32>),
/* 121 */ SyscallDesc("setdomainname", unimplementedFunc),
/* 122 */ SyscallDesc("uname", unameFunc),
/* 123 */ SyscallDesc("modify_ldt", unimplementedFunc),
@@ -801,7 +807,7 @@ static SyscallDesc syscallDescs32[] = {
/* 255 */ SyscallDesc("epoll_ctl", unimplementedFunc),
/* 256 */ SyscallDesc("epoll_wait", unimplementedFunc),
/* 257 */ SyscallDesc("remap_file_pages", unimplementedFunc),
- /* 258 */ SyscallDesc("set_tid_address", unimplementedFunc),
+ /* 258 */ SyscallDesc("set_tid_address", setTidAddressFunc),
/* 259 */ SyscallDesc("timer_create", unimplementedFunc),
/* 260 */ SyscallDesc("timer_settime", unimplementedFunc),
/* 261 */ SyscallDesc("timer_gettime", unimplementedFunc),
@@ -873,3 +879,9 @@ I386LinuxProcess::I386LinuxProcess(ProcessParams * params, ObjectFile *objFile)
: I386Process(params, objFile, syscallDescs32,
sizeof(syscallDescs32) / sizeof(SyscallDesc))
{}
+
+void I386LinuxProcess::clone(ThreadContext *old_tc, ThreadContext *new_tc,
+ Process *process, TheISA::IntReg flags)
+{
+ I386Process::clone(old_tc, new_tc, (I386Process*)process, flags);
+}
diff --git a/src/arch/x86/linux/process.hh b/src/arch/x86/linux/process.hh
index 70370960b..bafa9cc6c 100644
--- a/src/arch/x86/linux/process.hh
+++ b/src/arch/x86/linux/process.hh
@@ -44,6 +44,9 @@
#include "arch/x86/process.hh"
#include "sim/process.hh"
+struct ProcessParams;
+struct ThreadContext;
+
namespace X86ISA {
class X86_64LinuxProcess : public X86_64Process
@@ -51,6 +54,8 @@ class X86_64LinuxProcess : public X86_64Process
public:
/// Constructor.
X86_64LinuxProcess(ProcessParams * params, ObjectFile *objFile);
+ void clone(ThreadContext *old_tc, ThreadContext *new_tc, Process *process,
+ TheISA::IntReg flags);
};
class I386LinuxProcess : public I386Process
@@ -58,6 +63,8 @@ class I386LinuxProcess : public I386Process
public:
/// Constructor.
I386LinuxProcess(ProcessParams * params, ObjectFile *objFile);
+ void clone(ThreadContext *old_tc, ThreadContext *new_tc, Process *process,
+ TheISA::IntReg flags);
};
} // namespace X86ISA
diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc
index 35ea70430..a929897ca 100644
--- a/src/arch/x86/process.cc
+++ b/src/arch/x86/process.cc
@@ -100,8 +100,17 @@ X86Process::X86Process(ProcessParams * params, ObjectFile *objFile,
: Process(params, objFile), syscallDescs(_syscallDescs),
numSyscallDescs(_numSyscallDescs)
{
- brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
- brk_point = roundUp(brk_point, PageBytes);
+ memState->brkPoint = objFile->dataBase() + objFile->dataSize()
+ + objFile->bssSize();
+ memState->brkPoint = roundUp(memState->brkPoint, PageBytes);
+}
+
+void X86Process::clone(ThreadContext *old_tc, ThreadContext *new_tc,
+ Process *p, TheISA::IntReg flags)
+{
+ Process::clone(old_tc, new_tc, p, flags);
+ X86Process *process = (X86Process*)p;
+ *process = *this;
}
X86_64Process::X86_64Process(ProcessParams *params, ObjectFile *objFile,
@@ -117,10 +126,10 @@ X86_64Process::X86_64Process(ProcessParams *params, ObjectFile *objFile,
// 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.
- stack_base = (Addr)0x7FFFFFFFF000ULL;
+ memState->stackBase = (Addr)0x7FFFFFFFF000ULL;
// Set pointer for next thread stack. Reserve 8M for main stack.
- next_thread_stack_base = stack_base - (8 * 1024 * 1024);
+ memState->nextThreadStackBase = memState->stackBase - (8 * 1024 * 1024);
// "mmap_base" is a function which defines where mmap region starts in
// the process address space.
@@ -130,7 +139,7 @@ X86_64Process::X86_64Process(ProcessParams *params, ObjectFile *objFile,
// 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.
- mmap_end = (Addr)0x7FFFF7FFF000ULL;
+ memState->mmapEnd = (Addr)0x7FFFF7FFF000ULL;
}
void
@@ -159,10 +168,10 @@ I386Process::I386Process(ProcessParams *params, ObjectFile *objFile,
vsyscallPage.vsyscallOffset = 0x400;
vsyscallPage.vsysexitOffset = 0x410;
- stack_base = _gdtStart;
+ memState->stackBase = _gdtStart;
// Set pointer for next thread stack. Reserve 8M for main stack.
- next_thread_stack_base = stack_base - (8 * 1024 * 1024);
+ memState->nextThreadStackBase = memState->stackBase - (8 * 1024 * 1024);
// "mmap_base" is a function which defines where mmap region starts in
// the process address space.
@@ -172,7 +181,7 @@ I386Process::I386Process(ProcessParams *params, ObjectFile *objFile,
// 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.
- mmap_end = (Addr)0xB7FFF000ULL;
+ memState->mmapEnd = (Addr)0xB7FFF000ULL;
}
SyscallDesc*
@@ -946,18 +955,21 @@ X86Process::argsInit(int pageSize,
aux_padding +
frame_size;
- stack_min = stack_base - space_needed;
- stack_min = roundDown(stack_min, align);
- stack_size = roundUp(stack_base - stack_min, pageSize);
+ memState->stackMin = memState->stackBase - space_needed;
+ memState->stackMin = roundDown(memState->stackMin, align);
+ memState->stackSize = roundUp(memState->stackBase - memState->stackMin,
+ pageSize);
// map memory
- Addr stack_end = roundDown(stack_base - stack_size, pageSize);
+ Addr stack_end = roundDown(memState->stackBase - memState->stackSize,
+ pageSize);
- DPRINTF(Stack, "Mapping the stack: 0x%x %dB\n", stack_end, stack_size);
- allocateMem(stack_end, stack_size);
+ DPRINTF(Stack, "Mapping the stack: 0x%x %dB\n",
+ stack_end, memState->stackSize);
+ allocateMem(stack_end, memState->stackSize);
// map out initial stack contents
- IntType sentry_base = stack_base - sentry_size;
+ IntType sentry_base = memState->stackBase - 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;
@@ -976,7 +988,7 @@ X86Process::argsInit(int pageSize,
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", stack_min);
+ DPRINTF(Stack, "0x%x - stack min\n", memState->stackMin);
// write contents to stack
@@ -1023,14 +1035,14 @@ X86Process::argsInit(int pageSize,
ThreadContext *tc = system->getThreadContext(contextIds[0]);
//Set the stack pointer register
- tc->setIntReg(StackPointerReg, stack_min);
+ tc->setIntReg(StackPointerReg, memState->stackMin);
// 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.
- stack_min = roundDown(stack_min, pageSize);
+ memState->stackMin = roundDown(memState->stackMin, pageSize);
}
void
@@ -1074,6 +1086,14 @@ X86_64Process::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
return tc->setIntReg(ArgumentReg[i], val);
}
+void
+X86_64Process::clone(ThreadContext *old_tc, ThreadContext *new_tc,
+ Process *p, TheISA::IntReg flags)
+{
+ X86Process::clone(old_tc, new_tc, p, flags);
+ ((X86_64Process*)p)->vsyscallPage = vsyscallPage;
+}
+
X86ISA::IntReg
I386Process::getSyscallArg(ThreadContext *tc, int &i)
{
@@ -1098,3 +1118,11 @@ I386Process::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
assert(i < NumArgumentRegs);
return tc->setIntReg(ArgumentReg[i], val);
}
+
+void
+I386Process::clone(ThreadContext *old_tc, ThreadContext *new_tc,
+ Process *p, TheISA::IntReg flags)
+{
+ X86Process::clone(old_tc, new_tc, p, flags);
+ ((I386Process*)p)->vsyscallPage = vsyscallPage;
+}
diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh
index 9e3fafbdd..4240ee625 100644
--- a/src/arch/x86/process.hh
+++ b/src/arch/x86/process.hh
@@ -82,6 +82,21 @@ namespace X86ISA
SyscallDesc* getDesc(int callnum);
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
+ void clone(ThreadContext *old_tc, ThreadContext *new_tc,
+ Process *process, TheISA::IntReg flags);
+
+ X86Process &
+ operator=(const X86Process &in)
+ {
+ if (this == &in)
+ return *this;
+
+ _gdtStart = in._gdtStart;
+ _gdtSize = in._gdtSize;
+ syscallDescs = in.syscallDescs;
+
+ return *this;
+ }
};
class X86_64Process : public X86Process
@@ -97,6 +112,20 @@ namespace X86ISA
Addr size;
Addr vtimeOffset;
Addr vgettimeofdayOffset;
+
+ VSyscallPage &
+ operator=(const VSyscallPage &in)
+ {
+ if (this == &in)
+ return *this;
+
+ base = in.base;
+ size = in.size;
+ vtimeOffset = in.vtimeOffset;
+ vgettimeofdayOffset = in.vgettimeofdayOffset;
+
+ return *this;
+ }
};
VSyscallPage vsyscallPage;
@@ -108,6 +137,8 @@ namespace X86ISA
/// Explicitly import the otherwise hidden getSyscallArg
using Process::getSyscallArg;
void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val);
+ void clone(ThreadContext *old_tc, ThreadContext *new_tc,
+ Process *process, TheISA::IntReg flags);
};
class I386Process : public X86Process
@@ -123,6 +154,20 @@ namespace X86ISA
Addr size;
Addr vsyscallOffset;
Addr vsysexitOffset;
+
+ VSyscallPage &
+ operator=(const VSyscallPage &in)
+ {
+ if (this == &in)
+ return *this;
+
+ base = in.base;
+ size = in.size;
+ vsyscallOffset = in.vsyscallOffset;
+ vsysexitOffset = in.vsysexitOffset;
+
+ return *this;
+ }
};
VSyscallPage vsyscallPage;
@@ -134,6 +179,8 @@ namespace X86ISA
X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i, int width);
void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val);
+ void clone(ThreadContext *old_tc, ThreadContext *new_tc,
+ Process *process, TheISA::IntReg flags);
};
/**
diff --git a/src/arch/x86/types.hh b/src/arch/x86/types.hh
index 6451056ee..954f9f16e 100644
--- a/src/arch/x86/types.hh
+++ b/src/arch/x86/types.hh
@@ -305,6 +305,13 @@ namespace X86ISA
PCState() {}
PCState(Addr val) { set(val); }
+ void
+ setNPC(Addr val)
+ {
+ Base::setNPC(val);
+ _size = 0;
+ }
+
uint8_t size() const { return _size; }
void size(uint8_t newSize) { _size = newSize; }