diff -r a0ca00815cc4 -r 51641cf3c89c src/arch/x86/linux/process.hh --- a/src/arch/x86/linux/process.hh Fri Sep 28 09:35:25 2012 -0400 +++ b/src/arch/x86/linux/process.hh Mon Sep 24 17:15:57 2012 +0200 @@ -53,9 +53,14 @@ static SyscallDesc syscallDescs[]; static const int numSyscalls; + static const unsigned int gdt_user_cs; // Linux: GDT_ENTRY_DEFAULT_USER_CS + static const unsigned int gdt_user_ds; // Linux: GDT_ENTRY_DEFAULT_USER_DS + public: /// Constructor. X86_64LinuxProcess(LiveProcessParams * params, ObjectFile *objFile); + + void initState(); }; class I386LinuxProcess : public I386LiveProcess @@ -65,9 +70,14 @@ static SyscallDesc syscallDescs[]; static const int numSyscalls; + static const unsigned int gdt_user_cs; // Linux: GDT_ENTRY_DEFAULT_USER_CS + static const unsigned int gdt_user_ds; // Linux: GDT_ENTRY_DEFAULT_USER_DS + public: /// Constructor. I386LinuxProcess(LiveProcessParams * params, ObjectFile *objFile); + + void initState(); }; } // namespace X86ISA diff -r a0ca00815cc4 -r 51641cf3c89c src/arch/x86/linux/process.cc --- a/src/arch/x86/linux/process.cc Fri Sep 28 09:35:25 2012 -0400 +++ b/src/arch/x86/linux/process.cc Mon Sep 24 17:15:57 2012 +0200 @@ -48,12 +48,99 @@ using namespace std; using namespace X86ISA; +static +void +setSegmentEntry(SETranslatingPortProxy & vmem, + Addr gdt_start, + unsigned int entry, + const SegDescriptor &sdesc) +{ + // Addr dest = gdt_start + entry * sizeof(uint64_t); + // uint64_t value = static_cast(sdesc); + vmem.write(gdt_start + entry * sizeof(uint64_t), + static_cast(sdesc)); +} + +static +void +setDefaultSegments (SETranslatingPortProxy & vmem, + Addr gdt_start, + const unsigned int gdt_user_cs, + const unsigned int gdt_user_ds) +{ + SegDescriptor user_cs = 0; + user_cs.baseHigh = 0; + user_cs.baseLow = 0; + user_cs.g = 1; + user_cs.d = 1; + user_cs.b = 1; + user_cs.l = 0; + user_cs.avl = 0; + user_cs.limitHigh = ~0; + user_cs.limitLow = ~0; + user_cs.p = 1; + user_cs.dpl = 3; + user_cs.s = 1; + user_cs.type.codeOrData = 1; + user_cs.type.c = 0; + user_cs.type.r = 1; + user_cs.type.a = 0; + setSegmentEntry(vmem, gdt_start, gdt_user_cs, user_cs); + + SegDescriptor user_ds = 0; + user_ds.baseHigh = 0; + user_ds.baseLow = 0; + user_ds.g = 1; + user_ds.d = 1; + user_ds.b = 1; + user_ds.l = 0; + user_ds.avl = 0; + user_ds.limitHigh = ~0; + user_ds.limitLow = ~0; + user_ds.p = 1; + user_ds.dpl = 3; + user_ds.s = 1; + user_ds.type.codeOrData = 0; + user_ds.type.e = 0; + user_ds.type.w = 1; + user_ds.type.a = 0; + setSegmentEntry(vmem, gdt_start, gdt_user_ds, user_ds); +} + + +// Linux: include/asm-x86/segment.h (when !defined(CONFIG_X86_32)) +const unsigned int X86_64LinuxProcess::gdt_user_cs = 5; +const unsigned int X86_64LinuxProcess::gdt_user_ds = 6; +// NOTE: We're ignoring GDT_ENTRY_DEFAULT_USER32_CS as GEM5 will use +// I386LinuxProcess instead. + + X86_64LinuxProcess::X86_64LinuxProcess(LiveProcessParams * params, ObjectFile *objFile) : X86_64LiveProcess(params, objFile, syscallDescs, numSyscalls) {} +void +X86_64LinuxProcess::initState() +{ + this->X86_64LiveProcess::initState(); + setDefaultSegments(initVirtMem, _gdtStart, gdt_user_cs, gdt_user_ds); +} + + +// Linux: include/asm-x86/segment.h (when defined(CONFIG_X86_32)) +const unsigned int I386LinuxProcess::gdt_user_cs = 14; +const unsigned int I386LinuxProcess::gdt_user_ds = 15; + + I386LinuxProcess::I386LinuxProcess(LiveProcessParams * params, ObjectFile *objFile) : I386LiveProcess(params, objFile, syscallDescs, numSyscalls) {} + +void +I386LinuxProcess::initState() +{ + this->I386LiveProcess::initState(); + setDefaultSegments(initVirtMem, _gdtStart, gdt_user_cs, gdt_user_ds); +} diff -r a0ca00815cc4 -r 51641cf3c89c src/arch/x86/process.hh --- a/src/arch/x86/process.hh Fri Sep 28 09:35:25 2012 -0400 +++ b/src/arch/x86/process.hh Mon Sep 24 17:15:57 2012 +0200 @@ -100,7 +100,7 @@ public: void argsInit(int intSize, int pageSize); - void initState(); + virtual void initState(); X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val); @@ -124,7 +124,7 @@ public: void argsInit(int intSize, int pageSize); - void initState(); + virtual void initState(); void syscall(int64_t callnum, ThreadContext *tc); X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i);