exitSimLoop("halt instruction encountered");
}}, IsNonSpeculative);
0x83: callsys({{
- xc->syscall(R0, &fault);
+ xc->syscall(&fault);
}}, IsSerializeAfter, IsNonSpeculative, IsSyscall);
// Read uniq reg into ABI return value register (r0)
0x9e: rduniq({{ R0 = Runiq; }}, IsIprAccess);
return NULL;
return &syscallDescs[callnum];
}
+
+void
+AlphaLinuxProcess::syscall(ThreadContext *tc, Fault *fault)
+{
+ doSyscall(tc->readIntReg(0), tc, fault);
+}
+
/// Constructor.
AlphaLinuxProcess(ProcessParams * params, ObjectFile *objFile);
+ void syscall(ThreadContext *tc, Fault *fault) override;
+
virtual SyscallDesc* getDesc(int callnum);
/// Array of syscall descriptors, indexed by call number.
}
void
- syscall(int64_t callnum, Fault *fault) override
+ syscall(Fault *fault) override
{
panic("%s not implemented.", __FUNCTION__);
}
// As of now, there isn't a 32 bit thumb version of this instruction.
assert(!machInst.bigThumb);
- uint32_t callNum;
- CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
- OperatingMode mode = (OperatingMode)(uint8_t)cpsr.mode;
- if (opModeIs64(mode))
- callNum = tc->readIntReg(INTREG_X8);
- else
- callNum = tc->readIntReg(INTREG_R7);
Fault fault;
- tc->syscall(callNum, &fault);
+ tc->syscall(&fault);
// Advance the PC since that won't happen automatically.
PCState pc = tc->pcState();
ArmProcess64::initState();
// The 64 bit equivalent of the comm page would be set up here.
}
+
+void
+ArmFreebsdProcess32::syscall(ThreadContext *tc, Fault *fault)
+{
+ doSyscall(tc->readIntReg(INTREG_R7), tc, fault);
+}
+
+void
+ArmFreebsdProcess64::syscall(ThreadContext *tc, Fault *fault)
+{
+ doSyscall(tc->readIntReg(INTREG_X8), tc, fault);
+}
void initState();
+ void syscall(ThreadContext *tc, Fault *fault) override;
+
/// Explicitly import the otherwise hidden getSyscallArg
using ArmProcess::getSyscallArg;
ObjectFile::Arch _arch);
void initState();
+ void syscall(ThreadContext *tc, Fault *fault) override;
SyscallDesc* getDesc(int callnum);
};
ArmProcess64::initState();
// The 64 bit equivalent of the comm page would be set up here.
}
+
+void
+ArmLinuxProcess32::syscall(ThreadContext *tc, Fault *fault)
+{
+ doSyscall(tc->readIntReg(INTREG_R7), tc, fault);
+}
+
+void
+ArmLinuxProcess64::syscall(ThreadContext *tc, Fault *fault)
+{
+ doSyscall(tc->readIntReg(INTREG_X8), tc, fault);
+}
void initState();
+ void syscall(ThreadContext *tc, Fault *fault) override;
+
/// Explicitly import the otherwise hidden getSyscallArg
using ArmProcess::getSyscallArg;
ObjectFile::Arch _arch);
void initState();
+ void syscall(ThreadContext *tc, Fault *fault) override;
SyscallDesc* getDesc(int callnum);
};
0x2: movz({{ Rd = (Rt == 0) ? Rs : Rd; }});
0x3: movn({{ Rd = (Rt != 0) ? Rs : Rd; }});
0x4: decode FullSystemInt {
- 0: syscall_se({{ xc->syscall(R2, &fault); }},
+ 0: syscall_se({{ xc->syscall(&fault); }},
IsSerializeAfter, IsNonSpeculative);
default: syscall({{ fault = std::make_shared<SystemCallFault>(); }});
}
#Immediate Value operand
'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3),
- #Operands used for Link or Syscall Insts
+ #Operands used for Link Insts
'R31': ('IntReg', 'uw','31','IsInteger', 4),
- 'R2': ('IntReg', 'uw','2', 'IsInteger', 5),
#Special Integer Reg operands
'LO0': ('IntReg', 'uw','INTREG_LO', 'IsInteger', 6),
return &syscallDescs[m5_sys_idx];
}
-
-
-
-
+void
+MipsLinuxProcess::syscall(ThreadContext *tc, Fault *fault)
+{
+ doSyscall(tc->readIntReg(2), tc, fault);
+}
/// ID of the thread group leader for the process
uint64_t __tgid;
+ void syscall(ThreadContext *tc, Fault *fault) override;
+
/// Array of syscall descriptors, indexed by call number.
static SyscallDesc syscallDescs[];
const int Num_Syscall_Descs;
55: stfdu({{ Mem_df = Fs; }});
}
- 17: IntOp::sc({{ xc->syscall(R0, &fault); }},
+ 17: IntOp::sc({{ xc->syscall(&fault); }},
[ IsSyscall, IsNonSpeculative, IsSerializeAfter ]);
format FloatArithOp {
'Rsv': ('IntReg', 'uw', 'INTREG_RSV', 'IsInteger', 9),
'RsvLen': ('IntReg', 'uw', 'INTREG_RSV_LEN', 'IsInteger', 9),
'RsvAddr': ('IntReg', 'uw', 'INTREG_RSV_ADDR', 'IsInteger', 9),
-
- # Hack for non-full-system syscall emulation
- 'R0': ('IntReg', 'uw', '0', None, 1),
}};
PowerProcess::initState();
}
+void
+PowerLinuxProcess::syscall(ThreadContext *tc, Fault *fault)
+{
+ doSyscall(tc->readIntReg(0), tc, fault);
+}
+
RegVal
PowerLinuxProcess::getSyscallArg(ThreadContext *tc, int &i)
{
void initState();
+ void syscall(ThreadContext *tc, Fault *fault) override;
+
RegVal getSyscallArg(ThreadContext *tc, int &i);
/// Explicitly import the otherwise hidden getSyscallArg
using Process::getSyscallArg;
SyscallFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
{
Fault *fault = NoFault;
- tc->syscall(tc->readIntReg(SyscallNumReg), fault);
+ tc->syscall(fault);
}
} // namespace RiscvISA
&syscallDescs.at(callnum) : nullptr;
}
+void
+RiscvLinuxProcess64::syscall(ThreadContext *tc, Fault *fault)
+{
+ doSyscall(tc->readIntReg(SyscallNumReg), tc, fault);
+}
+
RiscvLinuxProcess32::RiscvLinuxProcess32(ProcessParams * params,
ObjectFile *objFile) : RiscvProcess32(params, objFile)
{}
return syscallDescs.find(callnum) != syscallDescs.end() ?
&syscallDescs.at(callnum) : nullptr;
}
+
+void
+RiscvLinuxProcess32::syscall(ThreadContext *tc, Fault *fault)
+{
+ doSyscall(tc->readIntReg(SyscallNumReg), tc, fault);
+}
/// ID of the thread group leader for the process
uint64_t __tgid;
+ void syscall(ThreadContext *tc, Fault *fault) override;
+
/// Array of syscall descriptors, indexed by call number.
static std::map<int, SyscallDesc> syscallDescs;
};
/// ID of the thread group leader for the process
uint64_t __tgid;
+ void syscall(ThreadContext *tc, Fault *fault) override;
+
/// Array of syscall descriptors, indexed by call number.
static std::map<int, SyscallDesc> syscallDescs;
};
: Sparc32Process(params, objFile)
{}
-void Sparc32LinuxProcess::handleTrap(int trapNum, ThreadContext *tc,
- Fault *fault)
+void
+Sparc32LinuxProcess::syscall(ThreadContext *tc, Fault *fault)
+{
+ doSyscall(tc->readIntReg(1), tc, fault);
+}
+
+void
+Sparc32LinuxProcess::handleTrap(int trapNum, ThreadContext *tc, Fault *fault)
{
switch (trapNum) {
case 0x10: //Linux 32 bit syscall trap
- tc->syscall(tc->readIntReg(1), fault);
+ tc->syscall(fault);
break;
default:
SparcProcess::handleTrap(trapNum, tc, fault);
: Sparc64Process(params, objFile)
{}
-void Sparc64LinuxProcess::handleTrap(int trapNum, ThreadContext *tc,
- Fault *fault)
+void
+Sparc64LinuxProcess::syscall(ThreadContext *tc, Fault *fault)
+{
+ doSyscall(tc->readIntReg(1), tc, fault);
+}
+
+void
+Sparc64LinuxProcess::handleTrap(int trapNum, ThreadContext *tc, Fault *fault)
{
switch (trapNum) {
// case 0x10: // Linux 32 bit syscall trap
case 0x6d: // Linux 64 bit syscall trap
- tc->syscall(tc->readIntReg(1), fault);
+ tc->syscall(fault);
break;
default:
SparcProcess::handleTrap(trapNum, tc, fault);
return SparcLinuxProcess::getDesc32(callnum);
}
+ void syscall(ThreadContext *tc, Fault *fault) override;
+
void handleTrap(int trapNum, ThreadContext *tc, Fault *fault);
};
return SparcLinuxProcess::getDesc(callnum);
}
+ void syscall(ThreadContext *tc, Fault *fault) override;
+
void handleTrap(int trapNum, ThreadContext *tc, Fault *fault);
};
return NULL;
return &syscallDescs[callnum];
}
+
+void
+SparcSolarisProcess::syscall(ThreadContext *tc, Fault *fault)
+{
+ doSyscall(tc->readIntReg(1), tc, fault);
+}
/// The target system's hostname.
static const char *hostname;
+ void syscall(ThreadContext *tc, Fault *fault) override;
+
/// Array of syscall descriptors, indexed by call number.
static SyscallDesc syscallDescs[];
// will sign extend it, and there's no easy way to
// specify only checking the first byte.
0xffffffffffffff80:
- SyscallInst::int80('xc->syscall(Rax, &fault)',
+ SyscallInst::int80('xc->syscall(&fault)',
IsSyscall, IsNonSpeculative,
IsSerializeAfter);
}
}
}
0x05: decode FullSystemInt {
- 0: SyscallInst::syscall('xc->syscall(Rax, &fault)',
+ 0: SyscallInst::syscall('xc->syscall(&fault)',
IsSyscall, IsNonSpeculative,
IsSerializeAfter);
default: decode MODE_MODE {
0x2: Inst::RDMSR();
0x3: rdpmc();
0x4: decode FullSystemInt {
- 0: SyscallInst::sysenter('xc->syscall(Rax, &fault)',
+ 0: SyscallInst::sysenter('xc->syscall(&fault)',
IsSyscall, IsNonSpeculative,
IsSerializeAfter);
default: sysenter();
sizeof(syscallDescs64) / sizeof(SyscallDesc))
{}
-void X86_64LinuxProcess::clone(ThreadContext *old_tc, ThreadContext *new_tc,
- Process *process, RegVal flags)
+void
+X86_64LinuxProcess::syscall(ThreadContext *tc, Fault *fault)
+{
+ doSyscall(tc->readIntReg(INTREG_RAX), tc, fault);
+}
+
+void
+X86_64LinuxProcess::clone(ThreadContext *old_tc, ThreadContext *new_tc,
+ Process *process, RegVal flags)
{
X86_64Process::clone(old_tc, new_tc, (X86_64Process*)process, flags);
}
sizeof(syscallDescs32) / sizeof(SyscallDesc))
{}
-void I386LinuxProcess::clone(ThreadContext *old_tc, ThreadContext *new_tc,
- Process *process, RegVal flags)
+void
+I386LinuxProcess::syscall(ThreadContext *tc, Fault *fault)
+{
+ PCState pc = tc->pcState();
+ Addr eip = pc.pc();
+ if (eip >= vsyscallPage.base &&
+ eip < vsyscallPage.base + vsyscallPage.size) {
+ pc.npc(vsyscallPage.base + vsyscallPage.vsysexitOffset);
+ tc->pcState(pc);
+ }
+ doSyscall(tc->readIntReg(INTREG_RAX), tc, fault);
+}
+
+void
+I386LinuxProcess::clone(ThreadContext *old_tc, ThreadContext *new_tc,
+ Process *process, RegVal flags)
{
I386Process::clone(old_tc, new_tc, (I386Process*)process, flags);
}
public:
/// Constructor.
X86_64LinuxProcess(ProcessParams * params, ObjectFile *objFile);
+ void syscall(ThreadContext *tc, Fault *fault) override;
void clone(ThreadContext *old_tc, ThreadContext *new_tc, Process *process,
RegVal flags);
};
public:
/// Constructor.
I386LinuxProcess(ProcessParams * params, ObjectFile *objFile);
+ void syscall(ThreadContext *tc, Fault *fault) override;
void clone(ThreadContext *old_tc, ThreadContext *new_tc, Process *process,
RegVal flags);
};
next_thread_stack_base, mmap_end);
}
-void
-I386Process::syscall(int64_t callnum, ThreadContext *tc, Fault *fault)
-{
- PCState pc = tc->pcState();
- Addr eip = pc.pc();
- if (eip >= vsyscallPage.base &&
- eip < vsyscallPage.base + vsyscallPage.size) {
- pc.npc(vsyscallPage.base + vsyscallPage.vsysexitOffset);
- tc->pcState(pc);
- }
- X86Process::syscall(callnum, tc, fault);
-}
-
I386Process::I386Process(ProcessParams *params, ObjectFile *objFile,
SyscallDesc *_syscallDescs, int _numSyscallDescs)
void argsInit(int pageSize);
void initState() override;
- void syscall(int64_t callnum, ThreadContext *tc,
- Fault *fault) override;
RegVal getSyscallArg(ThreadContext *tc, int &i) override;
RegVal getSyscallArg(ThreadContext *tc, int &i, int width) override;
void clone(ThreadContext *old_tc, ThreadContext *new_tc,
DPRINTF(PseudoInst, "PseudoInst::m5Syscall()\n");
Fault fault;
- tc->syscall(tc->readIntReg(INTREG_RAX), &fault);
+ tc->syscall(&fault);
}
/*
void wakeup(ThreadID tid) override { }
// Assume that the normal CPU's call to syscall was successful.
// The checker's state would have already been updated by the syscall.
- void syscall(int64_t callnum, Fault *fault) override { }
+ void syscall(Fault *fault) override { }
void
handleError()
/** Executes a syscall in SE mode. */
void
- syscall(int64_t callnum, Fault *fault) override
+ syscall(Fault *fault) override
{
- return actualTC->syscall(callnum, fault);
+ return actualTC->syscall(fault);
}
Status status() const override { return actualTC->status(); }
*/
/**
- * Executes a syscall specified by the callnum.
+ * Executes a syscall.
*/
- virtual void syscall(int64_t callnum, Fault *fault) = 0;
+ virtual void syscall(Fault *fault) = 0;
/** @} */
}
void
- syscall(int64_t callnum, Fault *fault) override
+ syscall(Fault *fault) override
{
- thread.syscall(callnum, fault);
+ thread.syscall(fault);
}
ThreadContext *tcBase() override { return thread.getTC(); }
template <class Impl>
void
-FullO3CPU<Impl>::syscall(int64_t callnum, ThreadID tid, Fault *fault)
+FullO3CPU<Impl>::syscall(ThreadID tid, Fault *fault)
{
DPRINTF(O3CPU, "[tid:%i] Executing syscall().\n\n", tid);
++(this->thread[tid]->funcExeInst);
// Execute the actual syscall.
- this->thread[tid]->syscall(callnum, fault);
+ this->thread[tid]->syscall(fault);
// Decrease funcExeInst by one as the normal commit will handle
// incrementing it.
/** Executes a syscall.
* @todo: Determine if this needs to be virtual.
*/
- void syscall(int64_t callnum, ThreadID tid, Fault *fault);
+ void syscall(ThreadID tid, Fault *fault);
/** Starts draining the CPU's pipeline of all instructions in
* order to stop all memory accesses. */
void trap(const Fault &fault);
/** Emulates a syscall. */
- void syscall(int64_t callnum, Fault *fault) override;
+ void syscall(Fault *fault) override;
public:
template <class Impl>
void
-BaseO3DynInst<Impl>::syscall(int64_t callnum, Fault *fault)
+BaseO3DynInst<Impl>::syscall(Fault *fault)
{
// HACK: check CPU's nextPC before and after syscall. If it
// changes, update this instruction's nextPC because the syscall
// must have changed the nextPC.
TheISA::PCState curPC = this->cpu->pcState(this->threadNumber);
- this->cpu->syscall(callnum, this->threadNumber, fault);
+ this->cpu->syscall(this->threadNumber, fault);
TheISA::PCState newPC = this->cpu->pcState(this->threadNumber);
if (!(curPC == newPC)) {
this->pcState(newPC);
/** Executes a syscall in SE mode. */
void
- syscall(int64_t callnum, Fault *fault) override
+ syscall(Fault *fault) override
{
- return cpu->syscall(callnum, thread->threadId(), fault);
+ return cpu->syscall(thread->threadId(), fault);
}
/** Reads the funcExeInst counter. */
ThreadContext *getTC() { return tc; }
/** Handles the syscall. */
- void syscall(int64_t callnum, Fault *fault)
+ void syscall(Fault *fault)
{
- fatal_if(FullSystem, "System call emulation is unavailable!");
- process->syscall(callnum, tc, fault);
+ process->syscall(tc, fault);
}
void dumpFuncProfile()
* Executes a syscall specified by the callnum.
*/
void
- syscall(int64_t callnum, Fault *fault) override
+ syscall(Fault *fault) override
{
- thread->syscall(callnum, fault);
+ thread->syscall(fault);
}
/** Returns a pointer to the ThreadContext. */
}
void
- syscall(int64_t callnum, Fault *fault) override
+ syscall(Fault *fault) override
{
- fatal_if(FullSystem, "System call emulation is unavailable!");
- process->syscall(callnum, this, fault);
+ process->syscall(this, fault);
}
RegVal readIntRegFlat(RegIndex idx) const override { return intRegs[idx]; }
// Same with st cond failures.
virtual Counter readFuncExeInst() const = 0;
- virtual void syscall(int64_t callnum, Fault *fault) = 0;
+ virtual void syscall(Fault *fault) = 0;
// This function exits the thread context in the CPU and returns
// 1 if the CPU has no more active threads (meaning it's OK to exit);
}
void
-Process::syscall(int64_t callnum, ThreadContext *tc, Fault *fault)
+Process::doSyscall(int64_t callnum, ThreadContext *tc, Fault *fault)
{
numSyscalls++;
class Process : public SimObject
{
+ protected:
+ void doSyscall(int64_t callnum, ThreadContext *tc, Fault *fault);
+
public:
Process(ProcessParams *params, EmulationPageTable *pTable,
ObjectFile *obj_file);
void initState() override;
DrainState drain() override;
- virtual void syscall(int64_t callnum, ThreadContext *tc, Fault *fault);
+ virtual void syscall(ThreadContext *tc, Fault *fault) = 0;
virtual RegVal getSyscallArg(ThreadContext *tc, int &i) = 0;
virtual RegVal getSyscallArg(ThreadContext *tc, int &i, int width);
virtual void setSyscallReturn(ThreadContext *tc,