Processes: Make getting and setting system call arguments part of a process object.
This commit is contained in:
@@ -56,7 +56,6 @@ isa_switch_hdrs = Split('''
|
||||
regfile.hh
|
||||
remote_gdb.hh
|
||||
stacktrace.hh
|
||||
syscallreturn.hh
|
||||
tlb.hh
|
||||
types.hh
|
||||
utility.hh
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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): "
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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__
|
||||
@@ -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));
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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): "
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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__
|
||||
@@ -277,21 +277,6 @@ class CheckerThreadContext : public ThreadContext
|
||||
bool misspeculating() { return actualTC->misspeculating(); }
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
IntReg getSyscallArg(int i) { return actualTC->getSyscallArg(i); }
|
||||
|
||||
// used to shift args for indirect syscall
|
||||
void setSyscallArg(int i, IntReg val)
|
||||
{
|
||||
checkerTC->setSyscallArg(i, val);
|
||||
actualTC->setSyscallArg(i, val);
|
||||
}
|
||||
|
||||
void setSyscallReturn(SyscallReturn return_value)
|
||||
{
|
||||
checkerTC->setSyscallReturn(return_value);
|
||||
actualTC->setSyscallReturn(return_value);
|
||||
}
|
||||
|
||||
Counter readFuncExeInst() { return actualTC->readFuncExeInst(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1281,32 +1281,6 @@ InOrderCPU::syscall(int64_t callnum, int tid)
|
||||
nonSpecInstActive[tid] = false;
|
||||
}
|
||||
|
||||
IntReg
|
||||
InOrderCPU::getSyscallArg(int idx, int tid)
|
||||
{
|
||||
return readIntReg(ArgumentReg0 + idx, tid);
|
||||
}
|
||||
|
||||
void
|
||||
InOrderCPU::setSyscallArg(int idx, IntReg val, int tid)
|
||||
{
|
||||
setIntReg(ArgumentReg0 + idx, val, tid);
|
||||
}
|
||||
|
||||
void
|
||||
InOrderCPU::setSyscallReturn(SyscallReturn return_value, int tid)
|
||||
{
|
||||
if (return_value.successful()) {
|
||||
// no error
|
||||
setIntReg(SyscallSuccessReg, 0, tid);
|
||||
setIntReg(ReturnValueReg, return_value.value(), tid);
|
||||
} else {
|
||||
// got an error, return details
|
||||
setIntReg(SyscallSuccessReg, (IntReg) -1, tid);
|
||||
setIntReg(ReturnValueReg, -return_value.value(), tid);
|
||||
}
|
||||
}
|
||||
|
||||
Fault
|
||||
InOrderCPU::read(DynInstPtr inst)
|
||||
{
|
||||
|
||||
@@ -511,15 +511,6 @@ class InOrderCPU : public BaseCPU
|
||||
/** Executes a syscall.*/
|
||||
void syscall(int64_t callnum, int tid);
|
||||
|
||||
/** Gets a syscall argument. */
|
||||
IntReg getSyscallArg(int i, int tid);
|
||||
|
||||
/** Used to shift args for indirect syscall. */
|
||||
void setSyscallArg(int i, IntReg val, int tid);
|
||||
|
||||
/** Sets the return value of a syscall. */
|
||||
void setSyscallReturn(SyscallReturn return_value, int tid);
|
||||
|
||||
public:
|
||||
/** Per-Thread List of all the instructions in flight. */
|
||||
std::list<DynInstPtr> instList[ThePipeline::MaxThreads];
|
||||
|
||||
@@ -262,21 +262,3 @@ InOrderThreadContext::setMiscReg(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
cpu->setMiscReg(misc_reg, val, thread->readTid());
|
||||
}
|
||||
|
||||
TheISA::IntReg
|
||||
InOrderThreadContext::getSyscallArg(int i)
|
||||
{
|
||||
return cpu->getSyscallArg(i, thread->readTid());
|
||||
}
|
||||
|
||||
void
|
||||
InOrderThreadContext::setSyscallArg(int i, IntReg val)
|
||||
{
|
||||
cpu->setSyscallArg(i, val, thread->readTid());
|
||||
}
|
||||
|
||||
void
|
||||
InOrderThreadContext::setSyscallReturn(SyscallReturn return_value)
|
||||
{
|
||||
cpu->setSyscallReturn(return_value, thread->readTid());
|
||||
}
|
||||
|
||||
@@ -236,15 +236,6 @@ class InOrderThreadContext : public ThreadContext
|
||||
* misspeculating, this is set as false. */
|
||||
virtual bool misspeculating() { return false; }
|
||||
|
||||
/** Gets a syscall argument by index. */
|
||||
virtual IntReg getSyscallArg(int i);
|
||||
|
||||
/** Sets a syscall argument. */
|
||||
virtual void setSyscallArg(int i, IntReg val);
|
||||
|
||||
/** Sets the syscall return value. */
|
||||
virtual void setSyscallReturn(SyscallReturn return_value);
|
||||
|
||||
/** Executes a syscall in SE mode. */
|
||||
virtual void syscall(int64_t callnum)
|
||||
{ return cpu->syscall(callnum, thread->readTid()); }
|
||||
|
||||
@@ -420,34 +420,6 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
|
||||
lockFlag = false;
|
||||
}
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
|
||||
template <class Impl>
|
||||
TheISA::IntReg
|
||||
FullO3CPU<Impl>::getSyscallArg(int i, int tid)
|
||||
{
|
||||
assert(i < TheISA::NumArgumentRegs);
|
||||
TheISA::IntReg idx = TheISA::flattenIntIndex(this->tcBase(tid),
|
||||
TheISA::ArgumentReg[i]);
|
||||
TheISA::IntReg val = this->readArchIntReg(idx, tid);
|
||||
#if THE_ISA == SPARC_ISA
|
||||
if (bits(this->readMiscRegNoEffect(SparcISA::MISCREG_PSTATE, tid), 3, 3))
|
||||
val = bits(val, 31, 0);
|
||||
#endif
|
||||
return val;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::setSyscallArg(int i, TheISA::IntReg val, int tid)
|
||||
{
|
||||
assert(i < TheISA::NumArgumentRegs);
|
||||
TheISA::IntReg idx = TheISA::flattenIntIndex(this->tcBase(tid),
|
||||
TheISA::ArgumentReg[i]);
|
||||
this->setArchIntReg(idx, val, tid);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class Impl>
|
||||
FullO3CPU<Impl>::~FullO3CPU()
|
||||
{
|
||||
@@ -1000,13 +972,6 @@ FullO3CPU<Impl>::syscall(int64_t callnum, int tid)
|
||||
--(this->thread[tid]->funcExeInst);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
|
||||
{
|
||||
TheISA::setSyscallReturn(return_value, this->tcBase(tid));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <class Impl>
|
||||
|
||||
@@ -193,13 +193,6 @@ class FullO3CPU : public BaseO3CPU
|
||||
activateThreadEvent[tid].squash();
|
||||
}
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
TheISA::IntReg getSyscallArg(int i, int tid);
|
||||
|
||||
/** Used to shift args for indirect syscall. */
|
||||
void setSyscallArg(int i, TheISA::IntReg val, int tid);
|
||||
#endif
|
||||
|
||||
/** The tick event used for scheduling CPU ticks. */
|
||||
ActivateThreadEvent activateThreadEvent[Impl::MaxThreads];
|
||||
|
||||
@@ -354,10 +347,6 @@ class FullO3CPU : public BaseO3CPU
|
||||
* @todo: Determine if this needs to be virtual.
|
||||
*/
|
||||
void syscall(int64_t callnum, int tid);
|
||||
|
||||
/** Sets the return value of a syscall. */
|
||||
void setSyscallReturn(SyscallReturn return_value, int tid);
|
||||
|
||||
#endif
|
||||
|
||||
/** Starts draining the CPU's pipeline of all instructions in
|
||||
|
||||
@@ -247,15 +247,6 @@ class O3ThreadContext : public ThreadContext
|
||||
virtual bool misspeculating() { return false; }
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
/** Gets a syscall argument by index. */
|
||||
virtual IntReg getSyscallArg(int i);
|
||||
|
||||
/** Sets a syscall argument. */
|
||||
virtual void setSyscallArg(int i, IntReg val);
|
||||
|
||||
/** Sets the syscall return value. */
|
||||
virtual void setSyscallReturn(SyscallReturn return_value);
|
||||
|
||||
/** Executes a syscall in SE mode. */
|
||||
virtual void syscall(int64_t callnum)
|
||||
{ return cpu->syscall(callnum, thread->threadId()); }
|
||||
|
||||
@@ -482,28 +482,3 @@ O3ThreadContext<Impl>::setMiscReg(int misc_reg,
|
||||
}
|
||||
}
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
|
||||
template <class Impl>
|
||||
TheISA::IntReg
|
||||
O3ThreadContext<Impl>::getSyscallArg(int i)
|
||||
{
|
||||
return cpu->getSyscallArg(i, thread->threadId());
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
O3ThreadContext<Impl>::setSyscallArg(int i, IntReg val)
|
||||
{
|
||||
cpu->setSyscallArg(i, val, thread->threadId());
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
O3ThreadContext<Impl>::setSyscallReturn(SyscallReturn return_value)
|
||||
{
|
||||
cpu->setSyscallReturn(return_value, thread->threadId());
|
||||
}
|
||||
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
|
||||
@@ -246,22 +246,6 @@ class OzoneCPU : public BaseCPU
|
||||
bool misspeculating() { return false; }
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
TheISA::IntReg getSyscallArg(int i)
|
||||
{
|
||||
assert(i < TheISA::NumArgumentRegs);
|
||||
return thread->renameTable[TheISA::ArgumentReg[i]]->readIntResult();
|
||||
}
|
||||
|
||||
// used to shift args for indirect syscall
|
||||
void setSyscallArg(int i, TheISA::IntReg val)
|
||||
{
|
||||
assert(i < TheISA::NumArgumentRegs);
|
||||
thread->renameTable[TheISA::ArgumentReg[i]]->setIntResult(i);
|
||||
}
|
||||
|
||||
void setSyscallReturn(SyscallReturn return_value)
|
||||
{ cpu->setSyscallReturn(return_value, thread->threadId()); }
|
||||
|
||||
Counter readFuncExeInst() { return thread->funcExeInst; }
|
||||
|
||||
void setFuncExeInst(Counter new_val)
|
||||
@@ -468,7 +452,6 @@ class OzoneCPU : public BaseCPU
|
||||
void processInterrupts();
|
||||
#else
|
||||
void syscall(uint64_t &callnum);
|
||||
void setSyscallReturn(SyscallReturn return_value, int tid);
|
||||
#endif
|
||||
|
||||
ThreadContext *tcBase() { return tc; }
|
||||
|
||||
@@ -648,26 +648,6 @@ OzoneCPU<Impl>::syscall(uint64_t &callnum)
|
||||
frontEnd->renameTable.copyFrom(thread.renameTable);
|
||||
backEnd->renameTable.copyFrom(thread.renameTable);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
OzoneCPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
|
||||
{
|
||||
// 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
|
||||
thread.renameTable[SyscallSuccessReg]->setIntResult(0);
|
||||
thread.renameTable[ReturnValueReg]->setIntResult(
|
||||
return_value.value());
|
||||
} else {
|
||||
// got an error, return details
|
||||
thread.renameTable[SyscallSuccessReg]->setIntResult((IntReg) -1);
|
||||
thread.renameTable[ReturnValueReg]->setIntResult(
|
||||
-return_value.value());
|
||||
}
|
||||
}
|
||||
#else
|
||||
template <class Impl>
|
||||
Fault
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
|
||||
#include "arch/isa_traits.hh"
|
||||
#include "arch/regfile.hh"
|
||||
#include "arch/syscallreturn.hh"
|
||||
#include "arch/tlb.hh"
|
||||
#include "config/full_system.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
@@ -367,33 +366,6 @@ class SimpleThread : public ThreadState
|
||||
{ storeCondFailures = sc_failures; }
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
TheISA::IntReg getSyscallArg(int i)
|
||||
{
|
||||
assert(i < TheISA::NumArgumentRegs);
|
||||
TheISA::IntReg val = regs.readIntReg(
|
||||
TheISA::flattenIntIndex(getTC(), TheISA::ArgumentReg[i]));
|
||||
#if THE_ISA == SPARC_ISA
|
||||
if (bits(this->readMiscRegNoEffect(
|
||||
SparcISA::MISCREG_PSTATE), 3, 3)) {
|
||||
val = bits(val, 31, 0);
|
||||
}
|
||||
#endif
|
||||
return val;
|
||||
}
|
||||
|
||||
// used to shift args for indirect syscall
|
||||
void setSyscallArg(int i, TheISA::IntReg val)
|
||||
{
|
||||
assert(i < TheISA::NumArgumentRegs);
|
||||
regs.setIntReg(TheISA::flattenIntIndex(getTC(),
|
||||
TheISA::ArgumentReg[i]), val);
|
||||
}
|
||||
|
||||
void setSyscallReturn(SyscallReturn return_value)
|
||||
{
|
||||
TheISA::setSyscallReturn(return_value, getTC());
|
||||
}
|
||||
|
||||
void syscall(int64_t callnum)
|
||||
{
|
||||
process->syscall(callnum, tc);
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include "sim/faults.hh"
|
||||
#include "sim/host.hh"
|
||||
#include "sim/serialize.hh"
|
||||
#include "sim/syscallreturn.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
|
||||
// @todo: Figure out a more architecture independent way to obtain the ITB and
|
||||
@@ -258,13 +257,6 @@ class ThreadContext
|
||||
virtual bool misspeculating() = 0;
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
virtual IntReg getSyscallArg(int i) = 0;
|
||||
|
||||
// used to shift args for indirect syscall
|
||||
virtual void setSyscallArg(int i, IntReg val) = 0;
|
||||
|
||||
virtual void setSyscallReturn(SyscallReturn return_value) = 0;
|
||||
|
||||
// Same with st cond failures.
|
||||
virtual Counter readFuncExeInst() = 0;
|
||||
|
||||
@@ -457,15 +449,6 @@ class ProxyThreadContext : public ThreadContext
|
||||
bool misspeculating() { return actualTC->misspeculating(); }
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
IntReg getSyscallArg(int i) { return actualTC->getSyscallArg(i); }
|
||||
|
||||
// used to shift args for indirect syscall
|
||||
void setSyscallArg(int i, IntReg val)
|
||||
{ actualTC->setSyscallArg(i, val); }
|
||||
|
||||
void setSyscallReturn(SyscallReturn return_value)
|
||||
{ actualTC->setSyscallReturn(return_value); }
|
||||
|
||||
void syscall(int64_t callnum)
|
||||
{ actualTC->syscall(callnum); }
|
||||
|
||||
|
||||
@@ -437,10 +437,10 @@ class Tru64 : public OperatingSystem
|
||||
#ifdef __CYGWIN__
|
||||
panic("getdirent not implemented on cygwin!");
|
||||
#else
|
||||
int fd = process->sim_fd(tc->getSyscallArg(0));
|
||||
Addr tgt_buf = tc->getSyscallArg(1);
|
||||
int tgt_nbytes = tc->getSyscallArg(2);
|
||||
Addr tgt_basep = tc->getSyscallArg(3);
|
||||
int fd = process->sim_fd(process->getSyscallArg(tc, 0));
|
||||
Addr tgt_buf = process->getSyscallArg(tc, 1);
|
||||
int tgt_nbytes = process->getSyscallArg(tc, 2);
|
||||
Addr tgt_basep = process->getSyscallArg(tc, 3);
|
||||
|
||||
char * const host_buf = new char[tgt_nbytes];
|
||||
|
||||
@@ -496,7 +496,7 @@ class Tru64 : public OperatingSystem
|
||||
using namespace TheISA;
|
||||
|
||||
using TheISA::RegFile;
|
||||
TypedBufferArg<Tru64::sigcontext> sc(tc->getSyscallArg(0));
|
||||
TypedBufferArg<Tru64::sigcontext> sc(process->getSyscallArg(tc, 0));
|
||||
|
||||
sc.copyIn(tc->getMemPort());
|
||||
|
||||
@@ -528,7 +528,7 @@ class Tru64 : public OperatingSystem
|
||||
{
|
||||
using namespace TheISA;
|
||||
|
||||
TypedBufferArg<Tru64::vm_stack> argp(tc->getSyscallArg(0));
|
||||
TypedBufferArg<Tru64::vm_stack> argp(process->getSyscallArg(tc, 0));
|
||||
|
||||
argp.copyIn(tc->getMemPort());
|
||||
|
||||
@@ -576,8 +576,9 @@ class Tru64 : public OperatingSystem
|
||||
using namespace std;
|
||||
using namespace TheISA;
|
||||
|
||||
TypedBufferArg<Tru64::nxm_task_attr> attrp(tc->getSyscallArg(0));
|
||||
TypedBufferArg<Addr> configptr_ptr(tc->getSyscallArg(1));
|
||||
TypedBufferArg<Tru64::nxm_task_attr>
|
||||
attrp(process->getSyscallArg(tc, 0));
|
||||
TypedBufferArg<Addr> configptr_ptr(process->getSyscallArg(tc, 1));
|
||||
|
||||
attrp.copyIn(tc->getMemPort());
|
||||
|
||||
@@ -683,14 +684,14 @@ class Tru64 : public OperatingSystem
|
||||
|
||||
/// Initialize thread context.
|
||||
static void
|
||||
init_thread_context(ThreadContext *tc,
|
||||
init_thread_context(LiveProcess *process, ThreadContext *tc,
|
||||
Tru64::nxm_thread_attr *attrp, uint64_t uniq_val)
|
||||
{
|
||||
using namespace TheISA;
|
||||
|
||||
tc->clearArchRegs();
|
||||
|
||||
tc->setIntReg(TheISA::ArgumentReg[0], gtoh(attrp->registers.a0));
|
||||
process->setSyscallArg(tc, 0, gtoh(attrp->registers.a0));
|
||||
tc->setIntReg(27/*t12*/, gtoh(attrp->registers.pc));
|
||||
tc->setIntReg(TheISA::StackPointerReg, gtoh(attrp->registers.sp));
|
||||
tc->setMiscRegNoEffect(AlphaISA::MISCREG_UNIQ, uniq_val);
|
||||
@@ -709,9 +710,10 @@ class Tru64 : public OperatingSystem
|
||||
using namespace std;
|
||||
using namespace TheISA;
|
||||
|
||||
TypedBufferArg<Tru64::nxm_thread_attr> attrp(tc->getSyscallArg(0));
|
||||
TypedBufferArg<uint64_t> kidp(tc->getSyscallArg(1));
|
||||
int thread_index = tc->getSyscallArg(2);
|
||||
TypedBufferArg<Tru64::nxm_thread_attr>
|
||||
attrp(process->getSyscallArg(tc, 0));
|
||||
TypedBufferArg<uint64_t> kidp(process->getSyscallArg(tc, 1));
|
||||
int thread_index = process->getSyscallArg(tc, 2);
|
||||
|
||||
// get attribute args
|
||||
attrp.copyIn(tc->getMemPort());
|
||||
@@ -792,7 +794,7 @@ class Tru64 : public OperatingSystem
|
||||
ThreadContext *tc = process->findFreeContext();
|
||||
if (tc) {
|
||||
// inactive context... grab it
|
||||
init_thread_context(tc, attrp, uniq_val);
|
||||
init_thread_context(process, tc, attrp, uniq_val);
|
||||
|
||||
// This is supposed to be a port number, but we'll try
|
||||
// and get away with just sticking the thread index
|
||||
@@ -830,11 +832,11 @@ class Tru64 : public OperatingSystem
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
uint64_t tid = tc->getSyscallArg(0);
|
||||
uint64_t secs = tc->getSyscallArg(1);
|
||||
uint64_t flags = tc->getSyscallArg(2);
|
||||
uint64_t action = tc->getSyscallArg(3);
|
||||
uint64_t usecs = tc->getSyscallArg(4);
|
||||
uint64_t tid = process->getSyscallArg(tc, 0);
|
||||
uint64_t secs = process->getSyscallArg(tc, 1);
|
||||
uint64_t flags = process->getSyscallArg(tc, 2);
|
||||
uint64_t action = process->getSyscallArg(tc, 3);
|
||||
uint64_t usecs = process->getSyscallArg(tc, 4);
|
||||
|
||||
cout << tc->getCpuPtr()->name() << ": nxm_thread_block " << tid << " "
|
||||
<< secs << " " << flags << " " << action << " " << usecs << endl;
|
||||
@@ -849,11 +851,11 @@ class Tru64 : public OperatingSystem
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
Addr uaddr = tc->getSyscallArg(0);
|
||||
uint64_t val = tc->getSyscallArg(1);
|
||||
uint64_t secs = tc->getSyscallArg(2);
|
||||
uint64_t usecs = tc->getSyscallArg(3);
|
||||
uint64_t flags = tc->getSyscallArg(4);
|
||||
Addr uaddr = process->getSyscallArg(tc, 0);
|
||||
uint64_t val = process->getSyscallArg(tc, 1);
|
||||
uint64_t secs = process->getSyscallArg(tc, 2);
|
||||
uint64_t usecs = process->getSyscallArg(tc, 3);
|
||||
uint64_t flags = process->getSyscallArg(tc, 4);
|
||||
|
||||
BaseCPU *cpu = tc->getCpuPtr();
|
||||
|
||||
@@ -872,7 +874,7 @@ class Tru64 : public OperatingSystem
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
Addr uaddr = tc->getSyscallArg(0);
|
||||
Addr uaddr = process->getSyscallArg(tc, 0);
|
||||
|
||||
cout << tc->getCpuPtr()->name() << ": nxm_unblock "
|
||||
<< hex << uaddr << dec << endl;
|
||||
@@ -973,7 +975,7 @@ class Tru64 : public OperatingSystem
|
||||
m5_mutex_lockFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
Addr uaddr = tc->getSyscallArg(0);
|
||||
Addr uaddr = process->getSyscallArg(tc, 0);
|
||||
|
||||
m5_lock_mutex(uaddr, process, tc);
|
||||
|
||||
@@ -990,7 +992,7 @@ class Tru64 : public OperatingSystem
|
||||
{
|
||||
using namespace TheISA;
|
||||
|
||||
Addr uaddr = tc->getSyscallArg(0);
|
||||
Addr uaddr = process->getSyscallArg(tc, 0);
|
||||
TypedBufferArg<uint64_t> lockp(uaddr);
|
||||
|
||||
lockp.copyIn(tc->getMemPort());
|
||||
@@ -1010,7 +1012,7 @@ class Tru64 : public OperatingSystem
|
||||
m5_mutex_unlockFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
Addr uaddr = tc->getSyscallArg(0);
|
||||
Addr uaddr = process->getSyscallArg(tc, 0);
|
||||
|
||||
m5_unlock_mutex(uaddr, process, tc);
|
||||
|
||||
@@ -1022,7 +1024,7 @@ class Tru64 : public OperatingSystem
|
||||
m5_cond_signalFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
Addr cond_addr = tc->getSyscallArg(0);
|
||||
Addr cond_addr = process->getSyscallArg(tc, 0);
|
||||
|
||||
// Wake up one process waiting on the condition variable.
|
||||
activate_waiting_context(cond_addr, process);
|
||||
@@ -1035,7 +1037,7 @@ class Tru64 : public OperatingSystem
|
||||
m5_cond_broadcastFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
Addr cond_addr = tc->getSyscallArg(0);
|
||||
Addr cond_addr = process->getSyscallArg(tc, 0);
|
||||
|
||||
activate_waiting_context(cond_addr, process, true);
|
||||
|
||||
@@ -1049,8 +1051,8 @@ class Tru64 : public OperatingSystem
|
||||
{
|
||||
using namespace TheISA;
|
||||
|
||||
Addr cond_addr = tc->getSyscallArg(0);
|
||||
Addr lock_addr = tc->getSyscallArg(1);
|
||||
Addr cond_addr = process->getSyscallArg(tc, 0);
|
||||
Addr lock_addr = process->getSyscallArg(tc, 1);
|
||||
TypedBufferArg<uint64_t> condp(cond_addr);
|
||||
TypedBufferArg<uint64_t> lockp(lock_addr);
|
||||
|
||||
@@ -1082,10 +1084,10 @@ class Tru64 : public OperatingSystem
|
||||
indirectSyscallFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int new_callnum = tc->getSyscallArg(0);
|
||||
int new_callnum = process->getSyscallArg(tc, 0);
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
tc->setSyscallArg(i, tc->getSyscallArg(i+1));
|
||||
process->setSyscallArg(tc, i, process->getSyscallArg(tc, i+1));
|
||||
|
||||
|
||||
SyscallDesc *new_desc = process->getDesc(new_callnum);
|
||||
|
||||
@@ -51,7 +51,7 @@ BadAddrEvent::process(ThreadContext *tc)
|
||||
// annotation for vmunix::badaddr in:
|
||||
// simos/simulation/apps/tcl/osf/tlaser.tcl
|
||||
|
||||
uint64_t a0 = tc->readIntReg(ArgumentReg[0]);
|
||||
uint64_t a0 = tc->readIntReg(16);
|
||||
|
||||
AddrRangeList resp;
|
||||
bool snoop;
|
||||
|
||||
@@ -616,12 +616,10 @@ LiveProcess::argsInit(int intSize, int pageSize)
|
||||
copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
|
||||
copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
|
||||
|
||||
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();
|
||||
|
||||
@@ -44,9 +44,11 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "arch/types.hh"
|
||||
#include "base/statistics.hh"
|
||||
#include "sim/host.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
#include "sim/syscallreturn.hh"
|
||||
|
||||
class GDBListener;
|
||||
class PageTable;
|
||||
@@ -321,6 +323,11 @@ class LiveProcess : public Process
|
||||
std::string getcwd() const { return cwd; }
|
||||
|
||||
virtual void syscall(int64_t callnum, ThreadContext *tc);
|
||||
virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int i) = 0;
|
||||
virtual void setSyscallArg(ThreadContext *tc,
|
||||
int i, TheISA::IntReg val) = 0;
|
||||
virtual void setSyscallReturn(ThreadContext *tc,
|
||||
SyscallReturn return_value) = 0;
|
||||
|
||||
virtual SyscallDesc* getDesc(int callnum) = 0;
|
||||
|
||||
|
||||
@@ -53,8 +53,8 @@ SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc)
|
||||
{
|
||||
DPRINTFR(SyscallVerbose, "%d: %s: syscall %s called w/arguments %d,%d,%d,%d\n",
|
||||
curTick,tc->getCpuPtr()->name(), name,
|
||||
tc->getSyscallArg(0),tc->getSyscallArg(1),
|
||||
tc->getSyscallArg(2),tc->getSyscallArg(3));
|
||||
process->getSyscallArg(tc, 0), process->getSyscallArg(tc, 1),
|
||||
process->getSyscallArg(tc, 2), process->getSyscallArg(tc, 3));
|
||||
|
||||
SyscallReturn retval = (*funcPtr)(this, callnum, process, tc);
|
||||
|
||||
@@ -62,7 +62,7 @@ SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc)
|
||||
curTick,tc->getCpuPtr()->name(), name, retval.value());
|
||||
|
||||
if (!(flags & SyscallDesc::SuppressReturnValue))
|
||||
tc->setSyscallReturn(retval);
|
||||
process->setSyscallReturn(tc, retval);
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ ignoreFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
warn("ignoring syscall %s(%d, %d, ...)", desc->name,
|
||||
tc->getSyscallArg(0), tc->getSyscallArg(1));
|
||||
process->getSyscallArg(tc, 0), process->getSyscallArg(tc, 1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -92,7 +92,8 @@ exitFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
if (tc->exit()) {
|
||||
exitSimLoop("target called exit()", tc->getSyscallArg(0) & 0xff);
|
||||
exitSimLoop("target called exit()",
|
||||
process->getSyscallArg(tc, 0) & 0xff);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -110,7 +111,7 @@ SyscallReturn
|
||||
brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
// change brk addr to first arg
|
||||
Addr new_brk = tc->getSyscallArg(0);
|
||||
Addr new_brk = p->getSyscallArg(tc, 0);
|
||||
|
||||
// in Linux at least, brk(0) returns the current break value
|
||||
// (note that the syscall and the glibc function have different behavior)
|
||||
@@ -136,7 +137,7 @@ brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
SyscallReturn
|
||||
closeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
int target_fd = tc->getSyscallArg(0);
|
||||
int target_fd = p->getSyscallArg(tc, 0);
|
||||
int status = close(p->sim_fd(target_fd));
|
||||
if (status >= 0)
|
||||
p->free_fd(target_fd);
|
||||
@@ -147,9 +148,9 @@ closeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
SyscallReturn
|
||||
readFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
int fd = p->sim_fd(tc->getSyscallArg(0));
|
||||
int nbytes = tc->getSyscallArg(2);
|
||||
BufferArg bufArg(tc->getSyscallArg(1), nbytes);
|
||||
int fd = p->sim_fd(p->getSyscallArg(tc, 0));
|
||||
int nbytes = p->getSyscallArg(tc, 2);
|
||||
BufferArg bufArg(p->getSyscallArg(tc, 1), nbytes);
|
||||
|
||||
int bytes_read = read(fd, bufArg.bufferPtr(), nbytes);
|
||||
|
||||
@@ -162,9 +163,9 @@ readFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
SyscallReturn
|
||||
writeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
int fd = p->sim_fd(tc->getSyscallArg(0));
|
||||
int nbytes = tc->getSyscallArg(2);
|
||||
BufferArg bufArg(tc->getSyscallArg(1), nbytes);
|
||||
int fd = p->sim_fd(p->getSyscallArg(tc, 0));
|
||||
int nbytes = p->getSyscallArg(tc, 2);
|
||||
BufferArg bufArg(p->getSyscallArg(tc, 1), nbytes);
|
||||
|
||||
bufArg.copyIn(tc->getMemPort());
|
||||
|
||||
@@ -179,9 +180,9 @@ writeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
SyscallReturn
|
||||
lseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
int fd = p->sim_fd(tc->getSyscallArg(0));
|
||||
uint64_t offs = tc->getSyscallArg(1);
|
||||
int whence = tc->getSyscallArg(2);
|
||||
int fd = p->sim_fd(p->getSyscallArg(tc, 0));
|
||||
uint64_t offs = p->getSyscallArg(tc, 1);
|
||||
int whence = p->getSyscallArg(tc, 2);
|
||||
|
||||
off_t result = lseek(fd, offs, whence);
|
||||
|
||||
@@ -192,11 +193,11 @@ lseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
SyscallReturn
|
||||
_llseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
int fd = p->sim_fd(tc->getSyscallArg(0));
|
||||
uint64_t offset_high = tc->getSyscallArg(1);
|
||||
uint32_t offset_low = tc->getSyscallArg(2);
|
||||
Addr result_ptr = tc->getSyscallArg(3);
|
||||
int whence = tc->getSyscallArg(4);
|
||||
int fd = p->sim_fd(p->getSyscallArg(tc, 0));
|
||||
uint64_t offset_high = p->getSyscallArg(tc, 1);
|
||||
uint32_t offset_low = p->getSyscallArg(tc, 2);
|
||||
Addr result_ptr = p->getSyscallArg(tc, 3);
|
||||
int whence = p->getSyscallArg(tc, 4);
|
||||
|
||||
uint64_t offset = (offset_high << 32) | offset_low;
|
||||
|
||||
@@ -235,8 +236,8 @@ const char *hostname = "m5.eecs.umich.edu";
|
||||
SyscallReturn
|
||||
gethostnameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
int name_len = tc->getSyscallArg(1);
|
||||
BufferArg name(tc->getSyscallArg(0), name_len);
|
||||
int name_len = p->getSyscallArg(tc, 1);
|
||||
BufferArg name(p->getSyscallArg(tc, 0), name_len);
|
||||
|
||||
strncpy((char *)name.bufferPtr(), hostname, name_len);
|
||||
|
||||
@@ -249,8 +250,8 @@ SyscallReturn
|
||||
getcwdFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
int result = 0;
|
||||
unsigned long size = tc->getSyscallArg(1);
|
||||
BufferArg buf(tc->getSyscallArg(0), size);
|
||||
unsigned long size = p->getSyscallArg(tc, 1);
|
||||
BufferArg buf(p->getSyscallArg(tc, 0), size);
|
||||
|
||||
// Is current working directory defined?
|
||||
string cwd = p->getcwd();
|
||||
@@ -282,14 +283,14 @@ readlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))
|
||||
if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0)))
|
||||
return (TheISA::IntReg)-EFAULT;
|
||||
|
||||
// Adjust path for current working directory
|
||||
path = p->fullPath(path);
|
||||
|
||||
size_t bufsiz = tc->getSyscallArg(2);
|
||||
BufferArg buf(tc->getSyscallArg(1), bufsiz);
|
||||
size_t bufsiz = p->getSyscallArg(tc, 2);
|
||||
BufferArg buf(p->getSyscallArg(tc, 1), bufsiz);
|
||||
|
||||
int result = readlink(path.c_str(), (char *)buf.bufferPtr(), bufsiz);
|
||||
|
||||
@@ -303,7 +304,7 @@ unlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))
|
||||
if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0)))
|
||||
return (TheISA::IntReg)-EFAULT;
|
||||
|
||||
// Adjust path for current working directory
|
||||
@@ -319,13 +320,13 @@ mkdirFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))
|
||||
if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0)))
|
||||
return (TheISA::IntReg)-EFAULT;
|
||||
|
||||
// Adjust path for current working directory
|
||||
path = p->fullPath(path);
|
||||
|
||||
mode_t mode = tc->getSyscallArg(1);
|
||||
mode_t mode = p->getSyscallArg(tc, 1);
|
||||
|
||||
int result = mkdir(path.c_str(), mode);
|
||||
return (result == -1) ? -errno : result;
|
||||
@@ -336,12 +337,12 @@ renameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
string old_name;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(old_name, tc->getSyscallArg(0)))
|
||||
if (!tc->getMemPort()->tryReadString(old_name, p->getSyscallArg(tc, 0)))
|
||||
return -EFAULT;
|
||||
|
||||
string new_name;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(new_name, tc->getSyscallArg(1)))
|
||||
if (!tc->getMemPort()->tryReadString(new_name, p->getSyscallArg(tc, 1)))
|
||||
return -EFAULT;
|
||||
|
||||
// Adjust path for current working directory
|
||||
@@ -357,10 +358,10 @@ truncateFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))
|
||||
if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0)))
|
||||
return -EFAULT;
|
||||
|
||||
off_t length = tc->getSyscallArg(1);
|
||||
off_t length = p->getSyscallArg(tc, 1);
|
||||
|
||||
// Adjust path for current working directory
|
||||
path = p->fullPath(path);
|
||||
@@ -372,12 +373,12 @@ truncateFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
SyscallReturn
|
||||
ftruncateFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc)
|
||||
{
|
||||
int fd = process->sim_fd(tc->getSyscallArg(0));
|
||||
int fd = process->sim_fd(process->getSyscallArg(tc, 0));
|
||||
|
||||
if (fd < 0)
|
||||
return -EBADF;
|
||||
|
||||
off_t length = tc->getSyscallArg(1);
|
||||
off_t length = process->getSyscallArg(tc, 1);
|
||||
|
||||
int result = ftruncate(fd, length);
|
||||
return (result == -1) ? -errno : result;
|
||||
@@ -399,13 +400,13 @@ chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))
|
||||
if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0)))
|
||||
return -EFAULT;
|
||||
|
||||
/* XXX endianess */
|
||||
uint32_t owner = tc->getSyscallArg(1);
|
||||
uint32_t owner = p->getSyscallArg(tc, 1);
|
||||
uid_t hostOwner = owner;
|
||||
uint32_t group = tc->getSyscallArg(2);
|
||||
uint32_t group = p->getSyscallArg(tc, 2);
|
||||
gid_t hostGroup = group;
|
||||
|
||||
// Adjust path for current working directory
|
||||
@@ -418,15 +419,15 @@ chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
SyscallReturn
|
||||
fchownFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc)
|
||||
{
|
||||
int fd = process->sim_fd(tc->getSyscallArg(0));
|
||||
int fd = process->sim_fd(process->getSyscallArg(tc, 0));
|
||||
|
||||
if (fd < 0)
|
||||
return -EBADF;
|
||||
|
||||
/* XXX endianess */
|
||||
uint32_t owner = tc->getSyscallArg(1);
|
||||
uint32_t owner = process->getSyscallArg(tc, 1);
|
||||
uid_t hostOwner = owner;
|
||||
uint32_t group = tc->getSyscallArg(2);
|
||||
uint32_t group = process->getSyscallArg(tc, 2);
|
||||
gid_t hostGroup = group;
|
||||
|
||||
int result = fchown(fd, hostOwner, hostGroup);
|
||||
@@ -437,11 +438,11 @@ fchownFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc)
|
||||
SyscallReturn
|
||||
dupFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc)
|
||||
{
|
||||
int fd = process->sim_fd(tc->getSyscallArg(0));
|
||||
int fd = process->sim_fd(process->getSyscallArg(tc, 0));
|
||||
if (fd < 0)
|
||||
return -EBADF;
|
||||
|
||||
Process::FdMap *fdo = process->sim_fd_obj(tc->getSyscallArg(0));
|
||||
Process::FdMap *fdo = process->sim_fd_obj(process->getSyscallArg(tc, 0));
|
||||
|
||||
int result = dup(fd);
|
||||
return (result == -1) ? -errno : process->alloc_fd(result, fdo->filename, fdo->flags, fdo->mode, false);
|
||||
@@ -452,12 +453,12 @@ SyscallReturn
|
||||
fcntlFunc(SyscallDesc *desc, int num, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int fd = tc->getSyscallArg(0);
|
||||
int fd = process->getSyscallArg(tc, 0);
|
||||
|
||||
if (fd < 0 || process->sim_fd(fd) < 0)
|
||||
return -EBADF;
|
||||
|
||||
int cmd = tc->getSyscallArg(1);
|
||||
int cmd = process->getSyscallArg(tc, 1);
|
||||
switch (cmd) {
|
||||
case 0: // F_DUPFD
|
||||
// if we really wanted to support this, we'd need to do it
|
||||
@@ -494,12 +495,12 @@ SyscallReturn
|
||||
fcntl64Func(SyscallDesc *desc, int num, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int fd = tc->getSyscallArg(0);
|
||||
int fd = process->getSyscallArg(tc, 0);
|
||||
|
||||
if (fd < 0 || process->sim_fd(fd) < 0)
|
||||
return -EBADF;
|
||||
|
||||
int cmd = tc->getSyscallArg(1);
|
||||
int cmd = process->getSyscallArg(tc, 1);
|
||||
switch (cmd) {
|
||||
case 33: //F_GETLK64
|
||||
warn("fcntl64(%d, F_GETLK64) not supported, error returned\n", fd);
|
||||
@@ -583,7 +584,7 @@ setuidFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
// can't fathom why a benchmark would call this.
|
||||
warn("Ignoring call to setuid(%d)\n", tc->getSyscallArg(0));
|
||||
warn("Ignoring call to setuid(%d)\n", process->getSyscallArg(tc, 0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -467,8 +467,8 @@ SyscallReturn
|
||||
ioctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int fd = tc->getSyscallArg(0);
|
||||
unsigned req = tc->getSyscallArg(1);
|
||||
int fd = process->getSyscallArg(tc, 0);
|
||||
unsigned req = process->getSyscallArg(tc, 1);
|
||||
|
||||
DPRINTF(SyscallVerbose, "ioctl(%d, 0x%x, ...)\n", fd, req);
|
||||
|
||||
@@ -502,7 +502,7 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
{
|
||||
std::string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))
|
||||
if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
|
||||
return -EFAULT;
|
||||
|
||||
if (path == "/dev/sysdev0") {
|
||||
@@ -512,8 +512,8 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int tgtFlags = tc->getSyscallArg(1);
|
||||
int mode = tc->getSyscallArg(2);
|
||||
int tgtFlags = process->getSyscallArg(tc, 1);
|
||||
int mode = process->getSyscallArg(tc, 2);
|
||||
int hostFlags = 0;
|
||||
|
||||
// translate open flags
|
||||
@@ -560,10 +560,10 @@ chmodFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
{
|
||||
std::string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))
|
||||
if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
|
||||
return -EFAULT;
|
||||
|
||||
uint32_t mode = tc->getSyscallArg(1);
|
||||
uint32_t mode = process->getSyscallArg(tc, 1);
|
||||
mode_t hostMode = 0;
|
||||
|
||||
// XXX translate mode flags via OS::something???
|
||||
@@ -587,13 +587,13 @@ SyscallReturn
|
||||
fchmodFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int fd = tc->getSyscallArg(0);
|
||||
int fd = process->getSyscallArg(tc, 0);
|
||||
if (fd < 0 || process->sim_fd(fd) < 0) {
|
||||
// doesn't map to any simulator fd: not a valid target fd
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
uint32_t mode = tc->getSyscallArg(1);
|
||||
uint32_t mode = process->getSyscallArg(tc, 1);
|
||||
mode_t hostMode = 0;
|
||||
|
||||
// XXX translate mode flags via OS::someting???
|
||||
@@ -612,10 +612,10 @@ template <class OS>
|
||||
SyscallReturn
|
||||
mremapFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc)
|
||||
{
|
||||
Addr start = tc->getSyscallArg(0);
|
||||
uint64_t old_length = tc->getSyscallArg(1);
|
||||
uint64_t new_length = tc->getSyscallArg(2);
|
||||
uint64_t flags = tc->getSyscallArg(3);
|
||||
Addr start = process->getSyscallArg(tc, 0);
|
||||
uint64_t old_length = process->getSyscallArg(tc, 1);
|
||||
uint64_t new_length = process->getSyscallArg(tc, 2);
|
||||
uint64_t flags = process->getSyscallArg(tc, 3);
|
||||
|
||||
if ((start % TheISA::VMPageSize != 0) ||
|
||||
(new_length % TheISA::VMPageSize != 0)) {
|
||||
@@ -661,7 +661,7 @@ statFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
{
|
||||
std::string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))
|
||||
if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
|
||||
return -EFAULT;
|
||||
|
||||
// Adjust path for current working directory
|
||||
@@ -673,7 +673,8 @@ statFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
if (result < 0)
|
||||
return -errno;
|
||||
|
||||
copyOutStatBuf<OS>(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf);
|
||||
copyOutStatBuf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1),
|
||||
&hostBuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -687,7 +688,7 @@ stat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
{
|
||||
std::string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))
|
||||
if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
|
||||
return -EFAULT;
|
||||
|
||||
// Adjust path for current working directory
|
||||
@@ -704,7 +705,8 @@ stat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
if (result < 0)
|
||||
return -errno;
|
||||
|
||||
copyOutStat64Buf<OS>(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf);
|
||||
copyOutStat64Buf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1),
|
||||
&hostBuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -716,7 +718,7 @@ SyscallReturn
|
||||
fstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int fd = tc->getSyscallArg(0);
|
||||
int fd = process->getSyscallArg(tc, 0);
|
||||
if (fd < 0 || process->sim_fd(fd) < 0) {
|
||||
// doesn't map to any simulator fd: not a valid target fd
|
||||
return -EBADF;
|
||||
@@ -733,7 +735,7 @@ fstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
if (result < 0)
|
||||
return -errno;
|
||||
|
||||
copyOutStat64Buf<OS>(tc->getMemPort(), tc->getSyscallArg(1),
|
||||
copyOutStat64Buf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1),
|
||||
&hostBuf, (fd == 1));
|
||||
|
||||
return 0;
|
||||
@@ -748,7 +750,7 @@ lstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
{
|
||||
std::string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))
|
||||
if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
|
||||
return -EFAULT;
|
||||
|
||||
// Adjust path for current working directory
|
||||
@@ -760,7 +762,8 @@ lstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
if (result < 0)
|
||||
return -errno;
|
||||
|
||||
copyOutStatBuf<OS>(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf);
|
||||
copyOutStatBuf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1),
|
||||
&hostBuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -773,7 +776,7 @@ lstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
{
|
||||
std::string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))
|
||||
if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
|
||||
return -EFAULT;
|
||||
|
||||
// Adjust path for current working directory
|
||||
@@ -790,7 +793,8 @@ lstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
if (result < 0)
|
||||
return -errno;
|
||||
|
||||
copyOutStat64Buf<OS>(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf);
|
||||
copyOutStat64Buf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1),
|
||||
&hostBuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -801,7 +805,7 @@ SyscallReturn
|
||||
fstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int fd = process->sim_fd(tc->getSyscallArg(0));
|
||||
int fd = process->sim_fd(process->getSyscallArg(tc, 0));
|
||||
|
||||
DPRINTF(SyscallVerbose, "fstat(%d, ...)\n", fd);
|
||||
|
||||
@@ -814,7 +818,7 @@ fstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
if (result < 0)
|
||||
return -errno;
|
||||
|
||||
copyOutStatBuf<OS>(tc->getMemPort(), tc->getSyscallArg(1),
|
||||
copyOutStatBuf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1),
|
||||
&hostBuf, (fd == 1));
|
||||
|
||||
return 0;
|
||||
@@ -829,7 +833,7 @@ statfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
{
|
||||
std::string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))
|
||||
if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
|
||||
return -EFAULT;
|
||||
|
||||
// Adjust path for current working directory
|
||||
@@ -842,7 +846,7 @@ statfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
return -errno;
|
||||
|
||||
OS::copyOutStatfsBuf(tc->getMemPort(),
|
||||
(Addr)(tc->getSyscallArg(1)), &hostBuf);
|
||||
(Addr)(process->getSyscallArg(tc, 1)), &hostBuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -854,7 +858,7 @@ SyscallReturn
|
||||
fstatfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int fd = process->sim_fd(tc->getSyscallArg(0));
|
||||
int fd = process->sim_fd(process->getSyscallArg(tc, 0));
|
||||
|
||||
if (fd < 0)
|
||||
return -EBADF;
|
||||
@@ -865,7 +869,7 @@ fstatfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
if (result < 0)
|
||||
return -errno;
|
||||
|
||||
OS::copyOutStatfsBuf(tc->getMemPort(), tc->getSyscallArg(1),
|
||||
OS::copyOutStatfsBuf(tc->getMemPort(), process->getSyscallArg(tc, 1),
|
||||
&hostBuf);
|
||||
|
||||
return 0;
|
||||
@@ -878,15 +882,15 @@ SyscallReturn
|
||||
writevFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int fd = tc->getSyscallArg(0);
|
||||
int fd = process->getSyscallArg(tc, 0);
|
||||
if (fd < 0 || process->sim_fd(fd) < 0) {
|
||||
// doesn't map to any simulator fd: not a valid target fd
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
TranslatingPort *p = tc->getMemPort();
|
||||
uint64_t tiov_base = tc->getSyscallArg(1);
|
||||
size_t count = tc->getSyscallArg(2);
|
||||
uint64_t tiov_base = process->getSyscallArg(tc, 1);
|
||||
size_t count = process->getSyscallArg(tc, 2);
|
||||
struct iovec hiov[count];
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
@@ -930,12 +934,12 @@ template <class OS>
|
||||
SyscallReturn
|
||||
mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
Addr start = tc->getSyscallArg(0);
|
||||
uint64_t length = tc->getSyscallArg(1);
|
||||
// int prot = tc->getSyscallArg(2);
|
||||
int flags = tc->getSyscallArg(3);
|
||||
// int fd = p->sim_fd(tc->getSyscallArg(4));
|
||||
// int offset = tc->getSyscallArg(5);
|
||||
Addr start = p->getSyscallArg(tc, 0);
|
||||
uint64_t length = p->getSyscallArg(tc, 1);
|
||||
// int prot = p->getSyscallArg(tc, 2);
|
||||
int flags = p->getSyscallArg(tc, 3);
|
||||
// int fd = p->sim_fd(p->getSyscallArg(tc, 4));
|
||||
// int offset = p->getSyscallArg(tc, 5);
|
||||
|
||||
|
||||
if ((start % TheISA::VMPageSize) != 0 ||
|
||||
@@ -958,7 +962,7 @@ mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
|
||||
if (!(flags & OS::TGT_MAP_ANONYMOUS)) {
|
||||
warn("allowing mmap of file @ fd %d. "
|
||||
"This will break if not /dev/zero.", tc->getSyscallArg(4));
|
||||
"This will break if not /dev/zero.", p->getSyscallArg(tc, 4));
|
||||
}
|
||||
|
||||
return start;
|
||||
@@ -970,8 +974,8 @@ SyscallReturn
|
||||
getrlimitFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
unsigned resource = tc->getSyscallArg(0);
|
||||
TypedBufferArg<typename OS::rlimit> rlp(tc->getSyscallArg(1));
|
||||
unsigned resource = process->getSyscallArg(tc, 0);
|
||||
TypedBufferArg<typename OS::rlimit> rlp(process->getSyscallArg(tc, 1));
|
||||
|
||||
switch (resource) {
|
||||
case OS::TGT_RLIMIT_STACK:
|
||||
@@ -1005,7 +1009,7 @@ SyscallReturn
|
||||
gettimeofdayFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
TypedBufferArg<typename OS::timeval> tp(tc->getSyscallArg(0));
|
||||
TypedBufferArg<typename OS::timeval> tp(process->getSyscallArg(tc, 0));
|
||||
|
||||
getElapsedTime(tp->tv_sec, tp->tv_usec);
|
||||
tp->tv_sec += seconds_since_epoch;
|
||||
@@ -1026,10 +1030,10 @@ utimesFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
{
|
||||
std::string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))
|
||||
if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
|
||||
return -EFAULT;
|
||||
|
||||
TypedBufferArg<typename OS::timeval [2]> tp(tc->getSyscallArg(1));
|
||||
TypedBufferArg<typename OS::timeval [2]> tp(process->getSyscallArg(tc, 1));
|
||||
tp.copyIn(tc->getMemPort());
|
||||
|
||||
struct timeval hostTimeval[2];
|
||||
@@ -1055,8 +1059,8 @@ SyscallReturn
|
||||
getrusageFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int who = tc->getSyscallArg(0); // THREAD, SELF, or CHILDREN
|
||||
TypedBufferArg<typename OS::rusage> rup(tc->getSyscallArg(1));
|
||||
int who = process->getSyscallArg(tc, 0); // THREAD, SELF, or CHILDREN
|
||||
TypedBufferArg<typename OS::rusage> rup(process->getSyscallArg(tc, 1));
|
||||
|
||||
rup->ru_utime.tv_sec = 0;
|
||||
rup->ru_utime.tv_usec = 0;
|
||||
|
||||
Reference in New Issue
Block a user