Processes: Make getting and setting system call arguments part of a process object.

This commit is contained in:
Gabe Black
2009-02-27 09:22:14 -08:00
parent 60aab03e85
commit 9a000c5173
47 changed files with 401 additions and 726 deletions

View File

@@ -56,7 +56,6 @@ isa_switch_hdrs = Split('''
regfile.hh
remote_gdb.hh
stacktrace.hh
syscallreturn.hh
tlb.hh
types.hh
utility.hh

View File

@@ -74,9 +74,8 @@ FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc)
Addr ppc_vaddr = 0;
Addr timer_vaddr = 0;
assert(NumArgumentRegs >= 3);
ppc_vaddr = (Addr)tc->readIntReg(ArgumentReg[1]);
timer_vaddr = (Addr)tc->readIntReg(ArgumentReg[2]);
ppc_vaddr = (Addr)tc->readIntReg(17);
timer_vaddr = (Addr)tc->readIntReg(18);
virtPort.write(ppc_vaddr, (uint32_t)Clock::Frequency);
virtPort.write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);

View File

@@ -152,12 +152,9 @@ const int ReturnAddressReg = 26;
const int ReturnValueReg = 0;
const int FramePointerReg = 15;
const int ArgumentReg[] = {16, 17, 18, 19, 20, 21};
const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int);
const int SyscallNumReg = ReturnValueReg;
const int SyscallPseudoReturnReg = ArgumentReg[4];
const int SyscallSuccessReg = 19;
const int SyscallNumReg = 0;
const int FirstArgumentReg = 16;
const int SyscallPseudoReturnReg = 20;
const int LogVMPageSize = 13; // 8K bytes
const int VMPageSize = (1 << LogVMPageSize);

View File

@@ -48,7 +48,7 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
@@ -67,13 +67,13 @@ static SyscallReturn
osf_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
unsigned op = tc->getSyscallArg(0);
// unsigned nbytes = tc->getSyscallArg(2);
unsigned op = process->getSyscallArg(tc, 0);
// unsigned nbytes = process->getSyscallArg(tc, 2);
switch (op) {
case 45: { // GSI_IEEE_FP_CONTROL
TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1));
TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
// I don't think this exactly matches the HW FPCR
*fpcr = 0;
fpcr.copyOut(tc->getMemPort());
@@ -94,13 +94,13 @@ static SyscallReturn
osf_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
unsigned op = tc->getSyscallArg(0);
// unsigned nbytes = tc->getSyscallArg(2);
unsigned op = process->getSyscallArg(tc, 0);
// unsigned nbytes = process->getSyscallArg(tc, 2);
switch (op) {
case 14: { // SSI_IEEE_FP_CONTROL
TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1));
TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
// I don't think this exactly matches the HW FPCR
fpcr.copyIn(tc->getMemPort());
DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "

View File

@@ -42,6 +42,8 @@
using namespace AlphaISA;
using namespace std;
static const int SyscallSuccessReg = 19;
AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams *params,
ObjectFile *objFile)
: LiveProcess(params, objFile)
@@ -156,12 +158,10 @@ AlphaLiveProcess::argsInit(int intSize, int pageSize)
(uint8_t*)&(auxv[x].a_val), intSize);
}
assert(NumArgumentRegs >= 2);
ThreadContext *tc = system->getThreadContext(contextIds[0]);
tc->setIntReg(ArgumentReg[0], argc);
tc->setIntReg(ArgumentReg[1], argv_array_base);
setSyscallArg(tc, 0, argc);
setSyscallArg(tc, 1, argv_array_base);
tc->setIntReg(StackPointerReg, stack_min);
Addr prog_entry = objFile->entryPoint();
@@ -195,3 +195,35 @@ AlphaLiveProcess::startup()
tc->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57);
}
AlphaISA::IntReg
AlphaLiveProcess::getSyscallArg(ThreadContext *tc, int i)
{
assert(i < 6);
return tc->readIntReg(FirstArgumentReg + i);
}
void
AlphaLiveProcess::setSyscallArg(ThreadContext *tc,
int i, AlphaISA::IntReg val)
{
assert(i < 6);
tc->setIntReg(FirstArgumentReg + i, val);
}
void
AlphaLiveProcess::setSyscallReturn(ThreadContext *tc,
SyscallReturn return_value)
{
// check for error condition. Alpha syscall convention is to
// indicate success/failure in reg a3 (r19) and put the
// return value itself in the standard return value reg (v0).
if (return_value.successful()) {
// no error
tc->setIntReg(SyscallSuccessReg, 0);
tc->setIntReg(ReturnValueReg, return_value.value());
} else {
// got an error, return details
tc->setIntReg(SyscallSuccessReg, (IntReg)-1);
tc->setIntReg(ReturnValueReg, -return_value.value());
}
}

View File

@@ -42,6 +42,11 @@ class AlphaLiveProcess : public LiveProcess
void startup();
void argsInit(int intSize, int pageSize);
public:
AlphaISA::IntReg getSyscallArg(ThreadContext *tc, int i);
void setSyscallArg(ThreadContext *tc, int i, AlphaISA::IntReg val);
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
};
#endif // __ARCH_ALPHA_PROCESS_HH__

View File

@@ -1,59 +0,0 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Steve Reinhardt
* Gabe Black
*/
#ifndef __ARCH_ALPHA_SYSCALLRETURN_HH__
#define __ARCH_ALPHA_SYSCALLRETURN_HH__
#include "cpu/thread_context.hh"
#include "sim/syscallreturn.hh"
namespace AlphaISA {
static inline void
setSyscallReturn(SyscallReturn return_value, ThreadContext *tc)
{
// check for error condition. Alpha syscall convention is to
// indicate success/failure in reg a3 (r19) and put the
// return value itself in the standard return value reg (v0).
if (return_value.successful()) {
// no error
tc->setIntReg(SyscallSuccessReg, 0);
tc->setIntReg(ReturnValueReg, return_value.value());
} else {
// got an error, return details
tc->setIntReg(SyscallSuccessReg, (IntReg)-1);
tc->setIntReg(ReturnValueReg, -return_value.value());
}
}
} // namespace AlphaISA
#endif // __ARCH_ALPHA_SYSCALLRETURN_HH__

View File

@@ -45,7 +45,7 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
TypedBufferArg<AlphaTru64::utsname> name(tc->getSyscallArg(0));
TypedBufferArg<AlphaTru64::utsname> name(process->getSyscallArg(tc, 0));
strcpy(name->sysname, "OSF1");
strcpy(name->nodename, "m5.eecs.umich.edu");
@@ -62,34 +62,35 @@ static SyscallReturn
getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
unsigned op = tc->getSyscallArg(0);
unsigned nbytes = tc->getSyscallArg(2);
unsigned op = process->getSyscallArg(tc, 0);
unsigned nbytes = process->getSyscallArg(tc, 2);
switch (op) {
case AlphaTru64::GSI_MAX_CPU: {
TypedBufferArg<uint32_t> max_cpu(tc->getSyscallArg(1));
TypedBufferArg<uint32_t> max_cpu(process->getSyscallArg(tc, 1));
*max_cpu = htog((uint32_t)process->numCpus());
max_cpu.copyOut(tc->getMemPort());
return 1;
}
case AlphaTru64::GSI_CPUS_IN_BOX: {
TypedBufferArg<uint32_t> cpus_in_box(tc->getSyscallArg(1));
TypedBufferArg<uint32_t> cpus_in_box(process->getSyscallArg(tc, 1));
*cpus_in_box = htog((uint32_t)process->numCpus());
cpus_in_box.copyOut(tc->getMemPort());
return 1;
}
case AlphaTru64::GSI_PHYSMEM: {
TypedBufferArg<uint64_t> physmem(tc->getSyscallArg(1));
TypedBufferArg<uint64_t> physmem(process->getSyscallArg(tc, 1));
*physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
physmem.copyOut(tc->getMemPort());
return 1;
}
case AlphaTru64::GSI_CPU_INFO: {
TypedBufferArg<AlphaTru64::cpu_info> infop(tc->getSyscallArg(1));
TypedBufferArg<AlphaTru64::cpu_info>
infop(process->getSyscallArg(tc, 1));
infop->current_cpu = htog(0);
infop->cpus_in_box = htog(process->numCpus());
@@ -106,14 +107,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
}
case AlphaTru64::GSI_PROC_TYPE: {
TypedBufferArg<uint64_t> proc_type(tc->getSyscallArg(1));
TypedBufferArg<uint64_t> proc_type(process->getSyscallArg(tc, 1));
*proc_type = htog((uint64_t)11);
proc_type.copyOut(tc->getMemPort());
return 1;
}
case AlphaTru64::GSI_PLATFORM_NAME: {
BufferArg bufArg(tc->getSyscallArg(1), nbytes);
BufferArg bufArg(process->getSyscallArg(tc, 1), nbytes);
strncpy((char *)bufArg.bufferPtr(),
"COMPAQ Professional Workstation XP1000",
nbytes);
@@ -122,7 +123,7 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
}
case AlphaTru64::GSI_CLK_TCK: {
TypedBufferArg<uint64_t> clk_hz(tc->getSyscallArg(1));
TypedBufferArg<uint64_t> clk_hz(process->getSyscallArg(tc, 1));
*clk_hz = htog((uint64_t)1024);
clk_hz.copyOut(tc->getMemPort());
return 1;
@@ -141,12 +142,12 @@ static SyscallReturn
setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
unsigned op = tc->getSyscallArg(0);
unsigned op = process->getSyscallArg(tc, 0);
switch (op) {
case AlphaTru64::SSI_IEEE_FP_CONTROL:
warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n",
tc->getSyscallArg(1));
process->getSyscallArg(tc, 1));
break;
default:
@@ -164,17 +165,17 @@ tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
{
using namespace std;
int id = tc->getSyscallArg(0); // table ID
int index = tc->getSyscallArg(1); // index into table
int id = process->getSyscallArg(tc, 0); // table ID
int index = process->getSyscallArg(tc, 1); // index into table
// arg 2 is buffer pointer; type depends on table ID
int nel = tc->getSyscallArg(3); // number of elements
int lel = tc->getSyscallArg(4); // expected element size
int nel = process->getSyscallArg(tc, 3); // number of elements
int lel = process->getSyscallArg(tc, 4); // expected element size
switch (id) {
case AlphaTru64::TBL_SYSINFO: {
if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo))
return -EINVAL;
TypedBufferArg<Tru64::tbl_sysinfo> elp(tc->getSyscallArg(2));
TypedBufferArg<Tru64::tbl_sysinfo> elp(process->getSyscallArg(tc, 2));
const int clk_hz = one_million;
elp->si_user = htog(curTick / (Clock::Frequency / clk_hz));

View File

@@ -42,11 +42,12 @@ uint64_t
getArgument(ThreadContext *tc, int number, bool fp)
{
#if FULL_SYSTEM
const int NumArgumentRegs = 6;
if (number < NumArgumentRegs) {
if (fp)
return tc->readFloatRegBits(ArgumentReg[number]);
return tc->readFloatRegBits(16 + number);
else
return tc->readIntReg(ArgumentReg[number]);
return tc->readIntReg(16 + number);
} else {
Addr sp = tc->readIntReg(StackPointerReg);
VirtualPort *vp = tc->getVirtPort();

View File

@@ -190,13 +190,6 @@ namespace MipsISA
// semantically meaningful register indices
const int ZeroReg = 0;
const int AssemblerReg = 1;
const int ReturnValueReg = 2;
const int ReturnValueReg1 = 2;
const int ReturnValueReg2 = 3;
const int ArgumentReg0 = 4;
const int ArgumentReg1 = 5;
const int ArgumentReg2 = 6;
const int ArgumentReg3 = 7;
const int KernelReg0 = 26;
const int KernelReg1 = 27;
const int GlobalPointerReg = 28;
@@ -204,12 +197,7 @@ namespace MipsISA
const int FramePointerReg = 30;
const int ReturnAddressReg = 31;
const int ArgumentReg[] = {4, 5, 6, 7};
const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int);
const int SyscallNumReg = ReturnValueReg1;
const int SyscallPseudoReturnReg = ReturnValueReg2;
const int SyscallSuccessReg = ArgumentReg3;
const int SyscallPseudoReturnReg = 3;
const int LogVMPageSize = 13; // 8K bytes
const int VMPageSize = (1 << LogVMPageSize);

View File

@@ -51,7 +51,7 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
strcpy(name->sysname, "Linux");
strcpy(name->nodename,"m5.eecs.umich.edu");
@@ -70,13 +70,13 @@ static SyscallReturn
sys_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
unsigned op = tc->getSyscallArg(0);
// unsigned nbytes = tc->getSyscallArg(2);
unsigned op = process->getSyscallArg(tc, 0);
// unsigned nbytes = process->getSyscallArg(tc, 2);
switch (op) {
case 45: { // GSI_IEEE_FP_CONTROL
TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1));
TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
// I don't think this exactly matches the HW FPCR
*fpcr = 0;
fpcr.copyOut(tc->getMemPort());
@@ -97,13 +97,13 @@ static SyscallReturn
sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
unsigned op = tc->getSyscallArg(0);
// unsigned nbytes = tc->getSyscallArg(2);
unsigned op = process->getSyscallArg(tc, 0);
// unsigned nbytes = process->getSyscallArg(tc, 2);
switch (op) {
case 14: { // SSI_IEEE_FP_CONTROL
TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1));
TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
// I don't think this exactly matches the HW FPCR
fpcr.copyIn(tc->getMemPort());
DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): "

View File

@@ -40,6 +40,10 @@
using namespace std;
using namespace MipsISA;
static const int SyscallSuccessReg = 7;
static const int FirstArgumentReg = 4;
static const int ReturnValueReg = 2;
MipsLiveProcess::MipsLiveProcess(LiveProcessParams * params,
ObjectFile *objFile)
: LiveProcess(params, objFile)
@@ -64,3 +68,33 @@ MipsLiveProcess::startup()
{
argsInit(MachineBytes, VMPageSize);
}
MipsISA::IntReg
MipsLiveProcess::getSyscallArg(ThreadContext *tc, int i)
{
assert(i < 6);
return tc->readIntReg(FirstArgumentReg + i);
}
void
MipsLiveProcess::setSyscallArg(ThreadContext *tc,
int i, MipsISA::IntReg val)
{
assert(i < 6);
tc->setIntReg(FirstArgumentReg + i, val);
}
void
MipsLiveProcess::setSyscallReturn(ThreadContext *tc,
SyscallReturn return_value)
{
if (return_value.successful()) {
// no error
tc->setIntReg(SyscallSuccessReg, 0);
tc->setIntReg(ReturnValueReg, return_value.value());
} else {
// got an error, return details
tc->setIntReg(SyscallSuccessReg, (IntReg) -1);
tc->setIntReg(ReturnValueReg, -return_value.value());
}
}

View File

@@ -47,6 +47,10 @@ class MipsLiveProcess : public LiveProcess
virtual void startup();
public:
MipsISA::IntReg getSyscallArg(ThreadContext *tc, int i);
void setSyscallArg(ThreadContext *tc, int i, MipsISA::IntReg val);
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
};

View File

@@ -1,55 +0,0 @@
/*
* Copyright (c) 2007 MIPS Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
* Korey Sewell
*/
#ifndef __ARCH_MIPS_SYSCALLRETURN_HH__
#define __ARCH_MIPS_SYSCALLRETURN_HH__
#include "sim/syscallreturn.hh"
#include "cpu/thread_context.hh"
namespace MipsISA
{
static inline void setSyscallReturn(SyscallReturn return_value,
ThreadContext *tc)
{
if (return_value.successful()) {
// no error
tc->setIntReg(SyscallSuccessReg, 0);
tc->setIntReg(ReturnValueReg1, return_value.value());
} else {
// got an error, return details
tc->setIntReg(SyscallSuccessReg, (IntReg) -1);
tc->setIntReg(ReturnValueReg1, -return_value.value());
}
}
}
#endif

View File

@@ -68,16 +68,12 @@ namespace SparcISA
// semantically meaningful register indices
const int ZeroReg = 0; // architecturally meaningful
// the rest of these depend on the ABI
const int StackPointerReg = 14;
const int ReturnAddressReg = 31; // post call, precall is 15
const int ReturnValueReg = 8; // Post return, 24 is pre-return.
const int StackPointerReg = 14;
const int FramePointerReg = 30;
const int ArgumentReg[] = {8, 9, 10, 11, 12, 13};
const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int);
// Some OS syscall use a second register (o1) to return a second value
const int SyscallPseudoReturnReg = ArgumentReg[1];
const int SyscallPseudoReturnReg = 9;
//8K. This value is implmentation specific; and should probably
//be somewhere else.

View File

@@ -32,7 +32,6 @@
#define __SPARC_LINUX_PROCESS_HH__
#include "arch/sparc/linux/linux.hh"
#include "arch/sparc/syscallreturn.hh"
#include "arch/sparc/process.hh"
#include "sim/process.hh"

View File

@@ -29,7 +29,6 @@
*/
#include "arch/sparc/linux/process.hh"
#include "arch/sparc/syscallreturn.hh"
#include "sim/syscall_emul.hh"
class LiveProcess;
@@ -42,7 +41,7 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
@@ -60,9 +59,9 @@ SyscallReturn getresuidFunc(SyscallDesc *desc, int num,
LiveProcess *p, ThreadContext *tc)
{
const IntReg id = htog(100);
Addr ruid = tc->getSyscallArg(0);
Addr euid = tc->getSyscallArg(1);
Addr suid = tc->getSyscallArg(2);
Addr ruid = p->getSyscallArg(tc, 0);
Addr euid = p->getSyscallArg(tc, 1);
Addr suid = p->getSyscallArg(tc, 2);
//Handle the EFAULT case
//Set the ruid
if(ruid)

View File

@@ -46,6 +46,9 @@
using namespace std;
using namespace SparcISA;
static const int FirstArgumentReg = 8;
static const int ReturnValueReg = 8;
SparcLiveProcess::SparcLiveProcess(LiveProcessParams * params,
ObjectFile *objFile, Addr _StackBias)
@@ -509,3 +512,63 @@ void Sparc64LiveProcess::flushWindows(ThreadContext *tc)
tc->setIntReg(NumIntArchRegs + 4, Canrestore);
tc->setMiscReg(MISCREG_CWP, origCWP);
}
IntReg
Sparc32LiveProcess::getSyscallArg(ThreadContext *tc, int i)
{
assert(i < 6);
return bits(tc->readIntReg(FirstArgumentReg + i), 31, 0);
}
void
Sparc32LiveProcess::setSyscallArg(ThreadContext *tc, int i, IntReg val)
{
assert(i < 6);
tc->setIntReg(FirstArgumentReg + i, bits(val, 31, 0));
}
IntReg
Sparc64LiveProcess::getSyscallArg(ThreadContext *tc, int i)
{
assert(i < 6);
return tc->readIntReg(FirstArgumentReg + i);
}
void
Sparc64LiveProcess::setSyscallArg(ThreadContext *tc, int i, IntReg val)
{
assert(i < 6);
tc->setIntReg(FirstArgumentReg + i, val);
}
void
SparcLiveProcess::setSyscallReturn(ThreadContext *tc,
SyscallReturn return_value)
{
// check for error condition. SPARC syscall convention is to
// indicate success/failure in reg the carry bit of the ccr
// and put the return value itself in the standard return value reg ().
if (return_value.successful()) {
// no error, clear XCC.C
tc->setIntReg(NumIntArchRegs + 2,
tc->readIntReg(NumIntArchRegs + 2) & 0xEE);
//tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) & 0xEE);
IntReg val = return_value.value();
if (bits(tc->readMiscRegNoEffect(
SparcISA::MISCREG_PSTATE), 3, 3)) {
val = bits(val, 31, 0);
}
tc->setIntReg(ReturnValueReg, val);
} else {
// got an error, set XCC.C
tc->setIntReg(NumIntArchRegs + 2,
tc->readIntReg(NumIntArchRegs + 2) | 0x11);
//tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) | 0x11);
IntReg val = -return_value.value();
if (bits(tc->readMiscRegNoEffect(
SparcISA::MISCREG_PSTATE), 3, 3)) {
val = bits(val, 31, 0);
}
tc->setIntReg(ReturnValueReg, val);
}
}

View File

@@ -69,6 +69,7 @@ class SparcLiveProcess : public LiveProcess
{ return spillStart; }
virtual void flushWindows(ThreadContext *tc) = 0;
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
};
class Sparc32LiveProcess : public SparcLiveProcess
@@ -93,6 +94,9 @@ class Sparc32LiveProcess : public SparcLiveProcess
void argsInit(int intSize, int pageSize);
void flushWindows(ThreadContext *tc);
SparcISA::IntReg getSyscallArg(ThreadContext *tc, int i);
void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val);
};
class Sparc64LiveProcess : public SparcLiveProcess
@@ -118,6 +122,9 @@ class Sparc64LiveProcess : public SparcLiveProcess
void argsInit(int intSize, int pageSize);
void flushWindows(ThreadContext *tc);
SparcISA::IntReg getSyscallArg(ThreadContext *tc, int i);
void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val);
};
#endif // __SPARC_PROCESS_HH__

View File

@@ -48,7 +48,7 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
TypedBufferArg<Solaris::utsname> name(tc->getSyscallArg(0));
TypedBufferArg<Solaris::utsname> name(process->getSyscallArg(tc, 0));
strcpy(name->sysname, "SunOS");
strcpy(name->nodename, "m5.eecs.umich.edu");

View File

@@ -1,74 +0,0 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
*/
#ifndef __ARCH_SPARC_SYSCALLRETURN_HH__
#define __ARCH_SPARC_SYSCALLRETURN_HH__
#include <inttypes.h>
#include "sim/syscallreturn.hh"
#include "arch/sparc/regfile.hh"
#include "cpu/thread_context.hh"
namespace SparcISA
{
static inline void setSyscallReturn(SyscallReturn return_value,
ThreadContext * tc)
{
// check for error condition. SPARC syscall convention is to
// indicate success/failure in reg the carry bit of the ccr
// and put the return value itself in the standard return value reg ().
if (return_value.successful()) {
// no error, clear XCC.C
tc->setIntReg(NumIntArchRegs + 2,
tc->readIntReg(NumIntArchRegs + 2) & 0xEE);
//tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) & 0xEE);
IntReg val = return_value.value();
if (bits(tc->readMiscRegNoEffect(
SparcISA::MISCREG_PSTATE), 3, 3)) {
val = bits(val, 31, 0);
}
tc->setIntReg(ReturnValueReg, val);
} else {
// got an error, set XCC.C
tc->setIntReg(NumIntArchRegs + 2,
tc->readIntReg(NumIntArchRegs + 2) | 0x11);
//tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) | 0x11);
IntReg val = -return_value.value();
if (bits(tc->readMiscRegNoEffect(
SparcISA::MISCREG_PSTATE), 3, 3)) {
val = bits(val, 31, 0);
}
tc->setIntReg(ReturnValueReg, val);
}
}
};
#endif

View File

@@ -46,8 +46,9 @@ namespace SparcISA {
//first 6 arguments which the caller may use but doesn't have to.
uint64_t getArgument(ThreadContext *tc, int number, bool fp) {
#if FULL_SYSTEM
const int NumArgumentRegs = 6;
if (number < NumArgumentRegs) {
return tc->readIntReg(ArgumentReg[number]);
return tc->readIntReg(8 + number);
} else {
Addr sp = tc->readIntReg(StackPointerReg);
VirtualPort *vp = tc->getVirtPort();

View File

@@ -106,19 +106,7 @@ namespace X86ISA
const int StackPointerReg = INTREG_RSP;
//X86 doesn't seem to have a link register
const int ReturnAddressReg = 0;
const int ReturnValueReg = INTREG_RAX;
const int FramePointerReg = INTREG_RBP;
const int ArgumentReg[] = {
INTREG_RDI,
INTREG_RSI,
INTREG_RDX,
//This argument register is r10 for syscalls and rcx for C.
INTREG_R10W,
//INTREG_RCX,
INTREG_R8W,
INTREG_R9W
};
const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int);
// Some OS syscalls use a second register (rdx) to return a second
// value

View File

@@ -60,7 +60,6 @@
#include "sim/process.hh"
#include "arch/x86/linux/linux.hh"
#include "arch/x86/syscallreturn.hh"
#include "arch/x86/process.hh"
namespace X86ISA {

View File

@@ -68,7 +68,7 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
@@ -94,8 +94,8 @@ archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
};
//First argument is the code, second is the address
int code = tc->getSyscallArg(0);
uint64_t addr = tc->getSyscallArg(1);
int code = process->getSyscallArg(tc, 0);
uint64_t addr = process->getSyscallArg(tc, 1);
uint64_t fsBase, gsBase;
TranslatingPort *p = tc->getMemPort();
switch(code)

View File

@@ -104,6 +104,18 @@
using namespace std;
using namespace X86ISA;
static const int ReturnValueReg = INTREG_RAX;
static const int ArgumentReg[] = {
INTREG_RDI,
INTREG_RSI,
INTREG_RDX,
//This argument register is r10 for syscalls and rcx for C.
INTREG_R10W,
//INTREG_RCX,
INTREG_R8W,
INTREG_R9W
};
static const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int);
X86LiveProcess::X86LiveProcess(LiveProcessParams * params, ObjectFile *objFile,
SyscallDesc *_syscallDescs, int _numSyscallDescs) :
@@ -574,3 +586,35 @@ I386LiveProcess::argsInit(int intSize, int pageSize)
{
X86LiveProcess::argsInit<uint32_t>(pageSize);
}
void
X86LiveProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn return_value)
{
tc->setIntReg(INTREG_RAX, return_value.value());
}
X86ISA::IntReg
X86_64LiveProcess::getSyscallArg(ThreadContext *tc, int i)
{
assert(i < NumArgumentRegs);
return tc->readIntReg(ArgumentReg[i]);
}
void
X86_64LiveProcess::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
{
assert(i < NumArgumentRegs);
return tc->setIntReg(ArgumentReg[i], val);
}
X86ISA::IntReg
I386LiveProcess::getSyscallArg(ThreadContext *tc, int i)
{
panic("32 bit getSyscallArg not implemented.\n");
}
void
I386LiveProcess::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
{
panic("32 bit setSyscallArg not implemented.\n");
}

View File

@@ -81,6 +81,8 @@ namespace X86ISA
public:
SyscallDesc* getDesc(int callnum);
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
};
class X86_64LiveProcess : public X86LiveProcess
@@ -92,6 +94,9 @@ namespace X86ISA
public:
void argsInit(int intSize, int pageSize);
void startup();
X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i);
void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val);
};
class I386LiveProcess : public X86LiveProcess
@@ -103,6 +108,9 @@ namespace X86ISA
public:
void argsInit(int intSize, int pageSize);
void startup();
X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i);
void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val);
};
}

View File

@@ -1,74 +0,0 @@
/*
* Copyright (c) 2007 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
* with or without modification, are permitted provided that the
* following conditions are met:
*
* The software must be used only for Non-Commercial Use which means any
* use which is NOT directed to receiving any direct monetary
* compensation for, or commercial advantage from such use. Illustrative
* examples of non-commercial use are academic research, personal study,
* teaching, education and corporate research & development.
* Illustrative examples of commercial use are distributing products for
* commercial advantage and providing services using the software for
* commercial advantage.
*
* If you wish to use this software or functionality therein that may be
* covered by patents for commercial use, please contact:
* Director of Intellectual Property Licensing
* Office of Strategy and Technology
* Hewlett-Packard Company
* 1501 Page Mill Road
* Palo Alto, California 94304
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. Redistributions
* in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. Neither the name of
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. No right of
* sublicense is granted herewith. Derivatives of the software and
* output created using the software may be prepared, but only for
* Non-Commercial Uses. Derivatives of the software may be shared with
* others provided: (i) the others agree to abide by the list of
* conditions herein which includes the Non-Commercial Use restrictions;
* and (ii) such Derivatives of the software include the above copyright
* notice to acknowledge the contribution from this software where
* applicable, this list of conditions and the disclaimer below.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
*/
#ifndef __ARCH_X86_SYSCALLRETURN_HH__
#define __ARCH_X86_SYSCALLRETURN_HH__
#include "base/misc.hh"
#include "cpu/thread_context.hh"
#include "sim/syscallreturn.hh"
namespace X86ISA
{
static inline void setSyscallReturn(SyscallReturn return_value,
ThreadContext * tc)
{
tc->setIntReg(INTREG_RAX, return_value.value());
}
};
#endif // __ARCH_X86_SYSCALLRETURN_HH__