summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-10-30 00:44:55 -0700
committerGabe Black <gblack@eecs.umich.edu>2009-10-30 00:44:55 -0700
commit3f722b991fcb33ca21330501960406a8a58e2be2 (patch)
tree69f446fd29600df013ae0695399a986c779f363b /src/arch/x86
parent25d932868998db26054910078721433ab430c836 (diff)
downloadgem5-3f722b991fcb33ca21330501960406a8a58e2be2.tar.xz
Syscalls: Make system calls access arguments like a stack, not an array.
When accessing arguments for a syscall, the position of an argument depends on the policies of the ISA, how much space preceding arguments took up, and the "alignment" of the index for this particular argument into the number of possible storate locations. This change adjusts getSyscallArg to take its index parameter by reference instead of value and to adjust it to point to the possible location of the next argument on the stack, basically just after the current one. This way, the rules for the new argument can be applied locally without knowing about other arguments since those have already been taken into account implicitly. All system calls have also been changed to reflect the new interface. In a number of cases this made the implementation clearer since it encourages arguments to be collected in one place in order and then used as necessary later, as opposed to scattering them throughout the function or using them in place in long expressions. It also discourages using getSyscallArg over and over to retrieve the same value when a temporary would do the job.
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/linux/syscalls.cc11
-rw-r--r--src/arch/x86/process.cc19
-rw-r--r--src/arch/x86/process.hh5
3 files changed, 25 insertions, 10 deletions
diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc
index 14b3fa69b..4c29559fb 100644
--- a/src/arch/x86/linux/syscalls.cc
+++ b/src/arch/x86/linux/syscalls.cc
@@ -68,7 +68,8 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
+ int index = 0;
+ TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index));
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
@@ -94,8 +95,9 @@ archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
};
//First argument is the code, second is the address
- int code = process->getSyscallArg(tc, 0);
- uint64_t addr = process->getSyscallArg(tc, 1);
+ int index = 0;
+ int code = process->getSyscallArg(tc, index);
+ uint64_t addr = process->getSyscallArg(tc, index);
uint64_t fsBase, gsBase;
TranslatingPort *p = tc->getMemPort();
switch(code)
@@ -159,7 +161,8 @@ setThreadArea32Func(SyscallDesc *desc, int callnum,
assert((maxTLSEntry + 1) * sizeof(uint64_t) <= x86lp->gdtSize());
- TypedBufferArg<UserDesc32> userDesc(process->getSyscallArg(tc, 0));
+ int argIndex = 0;
+ TypedBufferArg<UserDesc32> userDesc(process->getSyscallArg(tc, argIndex));
TypedBufferArg<uint64_t>
gdt(x86lp->gdtStart() + minTLSEntry * sizeof(uint64_t),
numTLSEntries * sizeof(uint64_t));
diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc
index f7678443d..f7b3ce24a 100644
--- a/src/arch/x86/process.cc
+++ b/src/arch/x86/process.cc
@@ -698,10 +698,10 @@ X86LiveProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn return_value)
}
X86ISA::IntReg
-X86_64LiveProcess::getSyscallArg(ThreadContext *tc, int i)
+X86_64LiveProcess::getSyscallArg(ThreadContext *tc, int &i)
{
assert(i < NumArgumentRegs);
- return tc->readIntReg(ArgumentReg[i]);
+ return tc->readIntReg(ArgumentReg[i++]);
}
void
@@ -712,10 +712,21 @@ X86_64LiveProcess::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
}
X86ISA::IntReg
-I386LiveProcess::getSyscallArg(ThreadContext *tc, int i)
+I386LiveProcess::getSyscallArg(ThreadContext *tc, int &i)
{
assert(i < NumArgumentRegs32);
- return tc->readIntReg(ArgumentReg32[i]);
+ return tc->readIntReg(ArgumentReg32[i++]);
+}
+
+X86ISA::IntReg
+I386LiveProcess::getSyscallArg(ThreadContext *tc, int &i, int width)
+{
+ assert(width == 32 || width == 64);
+ assert(i < NumArgumentRegs);
+ uint64_t retVal = tc->readIntReg(ArgumentReg32[i++]) & mask(32);
+ if (width == 64)
+ retVal |= ((uint64_t)tc->readIntReg(ArgumentReg[i++]) << 32);
+ return retVal;
}
void
diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh
index cd6d99e66..4d031bd5a 100644
--- a/src/arch/x86/process.hh
+++ b/src/arch/x86/process.hh
@@ -105,7 +105,7 @@ namespace X86ISA
void argsInit(int intSize, int pageSize);
void startup();
- X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+ X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val);
};
@@ -130,7 +130,8 @@ namespace X86ISA
void startup();
void syscall(int64_t callnum, ThreadContext *tc);
- X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+ 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);
};
}