arch,sim: Merge Process::syscall and Process::getDesc.

When handling a system call, external code would call Process::syscall
which would extract the syscall number, that would call the base
class' doSyscall method, that would call into the subclass' getDesc
to get the appropriate descriptor, and then doSyscall would check
that a syscall was found and call into it.

Instead, we can just make the SyscallDescTable optionally check for
missing syscalls (in case we want to check multiple tables), and
make syscall look up the appropriate descriptor and call it. The base
implementation of syscall would then do the only bit of doSyscall that
is no longer being handled, incrementing the numSyscalls stat.

Change-Id: If102c156830ed2997d177dc6937cc85dddadf3f9
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24119
Tested-by: kokoro <noreply+kokoro@google.com>
Tested-by: Gem5 Cloud Project GCB service account <345032938727@cloudbuild.gserviceaccount.com>
Maintainer: Gabe Black <gabeblack@google.com>
Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu>
This commit is contained in:
Gabe Black
2020-01-01 03:07:22 -08:00
parent a63b853320
commit cd69bb5041
19 changed files with 48 additions and 159 deletions

View File

@@ -160,18 +160,6 @@ ArmFreebsdProcess64::ArmFreebsdProcess64(ProcessParams * params,
ArmProcess64(params, objFile, _arch)
{}
SyscallDesc*
ArmFreebsdProcess32::getDesc(int callnum)
{
return syscallDescs32.get(callnum);
}
SyscallDesc*
ArmFreebsdProcess64::getDesc(int callnum)
{
return syscallDescs64.get(callnum);
}
void
ArmFreebsdProcess32::initState()
{
@@ -189,11 +177,13 @@ ArmFreebsdProcess64::initState()
void
ArmFreebsdProcess32::syscall(ThreadContext *tc, Fault *fault)
{
doSyscall(tc->readIntReg(INTREG_R7), tc, fault);
ArmProcess32::syscall(tc, fault);
syscallDescs32.get(tc->readIntReg(INTREG_R7))->doSyscall(tc, fault);
}
void
ArmFreebsdProcess64::syscall(ThreadContext *tc, Fault *fault)
{
doSyscall(tc->readIntReg(INTREG_X8), tc, fault);
ArmProcess64::syscall(tc, fault);
syscallDescs64.get(tc->readIntReg(INTREG_X8))->doSyscall(tc, fault);
}

View File

@@ -87,8 +87,6 @@ class ArmFreebsdProcess32 : public ArmProcess32, public ArmFreebsdProcessBits
/// A page to hold "kernel" provided functions. The name might be wrong.
static const Addr commPage;
SyscallDesc* getDesc(int callnum) override;
struct SyscallABI : public ArmProcess32::SyscallABI,
public ArmFreebsdProcessBits::SyscallABI
{};
@@ -103,7 +101,6 @@ class ArmFreebsdProcess64 : public ArmProcess64, public ArmFreebsdProcessBits
void initState() override;
void syscall(ThreadContext *tc, Fault *fault) override;
SyscallDesc* getDesc(int callnum) override;
struct SyscallABI : public ArmProcess64::SyscallABI,
public ArmFreebsdProcessBits::SyscallABI

View File

@@ -861,30 +861,6 @@ ArmLinuxProcess64::ArmLinuxProcess64(ProcessParams * params,
const Addr ArmLinuxProcess32::commPage = 0xffff0000;
SyscallDesc*
ArmLinuxProcess32::getDesc(int callnum)
{
SyscallDesc *desc = syscallDescs32Low.get(callnum);
if (desc)
return desc;
desc = syscallDescs32Low.get(callnum);
if (desc)
return desc;
return privSyscallDescs32.get(callnum);
}
SyscallDesc*
ArmLinuxProcess64::getDesc(int callnum)
{
SyscallDesc *desc = syscallDescs64Low.get(callnum);
if (desc)
return desc;
desc = syscallDescs64Low.get(callnum);
if (desc)
return desc;
return privSyscallDescs64.get(callnum);
}
void
ArmLinuxProcess32::initState()
{
@@ -942,11 +918,27 @@ ArmLinuxProcess64::initState()
void
ArmLinuxProcess32::syscall(ThreadContext *tc, Fault *fault)
{
doSyscall(tc->readIntReg(INTREG_R7), tc, fault);
ArmProcess32::syscall(tc, fault);
int num = tc->readIntReg(INTREG_R7);
SyscallDesc *desc = syscallDescs32Low.get(num, false);
if (!desc)
desc = syscallDescs32Low.get(num, false);
if (!desc)
desc = privSyscallDescs32.get(num);
desc->doSyscall(tc, fault);
}
void
ArmLinuxProcess64::syscall(ThreadContext *tc, Fault *fault)
{
doSyscall(tc->readIntReg(INTREG_X8), tc, fault);
ArmProcess64::syscall(tc, fault);
int num = tc->readIntReg(INTREG_X8);
SyscallDesc *desc = syscallDescs64Low.get(num, false);
if (!desc)
desc = syscallDescs64Low.get(num, false);
if (!desc)
desc = privSyscallDescs64.get(num);
desc->doSyscall(tc, fault);
}

View File

@@ -87,8 +87,6 @@ class ArmLinuxProcess32 : public ArmProcess32, public ArmLinuxProcessBits
/// A page to hold "kernel" provided functions. The name might be wrong.
static const Addr commPage;
SyscallDesc* getDesc(int callnum) override;
struct SyscallABI : public ArmProcess32::SyscallABI,
public ArmLinuxProcessBits::SyscallABI
{};
@@ -103,7 +101,6 @@ class ArmLinuxProcess64 : public ArmProcess64, public ArmLinuxProcessBits
void initState() override;
void syscall(ThreadContext *tc, Fault *fault) override;
SyscallDesc* getDesc(int callnum) override;
struct SyscallABI : public ArmProcess64::SyscallABI,
public ArmLinuxProcessBits::SyscallABI

View File

@@ -479,14 +479,9 @@ MipsLinuxProcess::MipsLinuxProcess(ProcessParams * params,
MipsProcess(params, objFile)
{}
SyscallDesc*
MipsLinuxProcess::getDesc(int callnum)
{
return syscallDescs.get(callnum);
}
void
MipsLinuxProcess::syscall(ThreadContext *tc, Fault *fault)
{
doSyscall(tc->readIntReg(2), tc, fault);
MipsProcess::syscall(tc, fault);
syscallDescs.get(tc->readIntReg(2))->doSyscall(tc, fault);
}

View File

@@ -41,8 +41,6 @@ class MipsLinuxProcess : public MipsProcess
/// Constructor.
MipsLinuxProcess(ProcessParams * params, ObjectFile *objFile);
SyscallDesc* getDesc(int callnum) override;
/// The target system's hostname.
static const char *hostname;

View File

@@ -446,12 +446,6 @@ PowerLinuxProcess::PowerLinuxProcess(ProcessParams * params,
PowerProcess(params, objFile)
{}
SyscallDesc*
PowerLinuxProcess::getDesc(int callnum)
{
return syscallDescs.get(callnum);
}
void
PowerLinuxProcess::initState()
{
@@ -461,5 +455,6 @@ PowerLinuxProcess::initState()
void
PowerLinuxProcess::syscall(ThreadContext *tc, Fault *fault)
{
doSyscall(tc->readIntReg(0), tc, fault);
PowerProcess::syscall(tc, fault);
syscallDescs.get(tc->readIntReg(0))->doSyscall(tc, fault);
}

View File

@@ -40,8 +40,6 @@ class PowerLinuxProcess : public PowerProcess
public:
PowerLinuxProcess(ProcessParams * params, ObjectFile *objFile);
SyscallDesc *getDesc(int callnum) override;
void initState() override;
void syscall(ThreadContext *tc, Fault *fault) override;

View File

@@ -784,30 +784,20 @@ RiscvLinuxProcess64::RiscvLinuxProcess64(ProcessParams * params,
ObjectFile *objFile) : RiscvProcess64(params, objFile)
{}
SyscallDesc*
RiscvLinuxProcess64::getDesc(int callnum)
{
return syscallDescs.get(callnum);
}
void
RiscvLinuxProcess64::syscall(ThreadContext *tc, Fault *fault)
{
doSyscall(tc->readIntReg(SyscallNumReg), tc, fault);
RiscvProcess64::syscall(tc, fault);
syscallDescs.get(tc->readIntReg(SyscallNumReg))->doSyscall(tc, fault);
}
RiscvLinuxProcess32::RiscvLinuxProcess32(ProcessParams * params,
ObjectFile *objFile) : RiscvProcess32(params, objFile)
{}
SyscallDesc*
RiscvLinuxProcess32::getDesc(int callnum)
{
return syscallDescs.get(callnum);
}
void
RiscvLinuxProcess32::syscall(ThreadContext *tc, Fault *fault)
{
doSyscall(tc->readIntReg(SyscallNumReg), tc, fault);
RiscvProcess32::syscall(tc, fault);
syscallDescs.get(tc->readIntReg(SyscallNumReg))->doSyscall(tc, fault);
}

View File

@@ -44,8 +44,6 @@ class RiscvLinuxProcess64 : public RiscvProcess64
/// Constructor.
RiscvLinuxProcess64(ProcessParams * params, ObjectFile *objFile);
SyscallDesc* getDesc(int callnum) override;
/// The target system's hostname.
static const char *hostname;
@@ -64,8 +62,6 @@ class RiscvLinuxProcess32 : public RiscvProcess32
/// Constructor.
RiscvLinuxProcess32(ProcessParams * params, ObjectFile *objFile);
SyscallDesc* getDesc(int callnum) override;
/// The target system's hostname.
static const char *hostname;

View File

@@ -75,18 +75,6 @@ SparcLinuxObjectFileLoader loader;
} // anonymous namespace
SyscallDesc*
SparcLinuxProcess::getDesc(int callnum)
{
return syscallDescs.get(callnum);
}
SyscallDesc*
SparcLinuxProcess::getDesc32(int callnum)
{
return syscall32Descs.get(callnum);
}
Sparc32LinuxProcess::Sparc32LinuxProcess(ProcessParams * params,
ObjectFile *objFile)
: Sparc32Process(params, objFile)
@@ -95,7 +83,8 @@ Sparc32LinuxProcess::Sparc32LinuxProcess(ProcessParams * params,
void
Sparc32LinuxProcess::syscall(ThreadContext *tc, Fault *fault)
{
doSyscall(tc->readIntReg(1), tc, fault);
Sparc32Process::syscall(tc, fault);
syscall32Descs.get(tc->readIntReg(1))->doSyscall(tc, fault);
}
void
@@ -118,7 +107,8 @@ Sparc64LinuxProcess::Sparc64LinuxProcess(ProcessParams * params,
void
Sparc64LinuxProcess::syscall(ThreadContext *tc, Fault *fault)
{
doSyscall(tc->readIntReg(1), tc, fault);
Sparc64Process::syscall(tc, fault);
syscallDescs.get(tc->readIntReg(1))->doSyscall(tc, fault);
}
void

View File

@@ -47,12 +47,6 @@ class SparcLinuxProcess
/// 32 bit compatibility syscall descriptors, indexed by call number.
static SyscallDescTable<Sparc32Process::SyscallABI> syscall32Descs;
SyscallDesc *getDesc(int callnum);
SyscallDesc *getDesc32(int callnum);
static const int Num_Syscall_Descs;
static const int Num_Syscall32_Descs;
};
/// A process with emulated SPARC/Linux syscalls.
@@ -62,12 +56,6 @@ class Sparc32LinuxProcess : public SparcLinuxProcess, public Sparc32Process
/// Constructor.
Sparc32LinuxProcess(ProcessParams * params, ObjectFile *objFile);
SyscallDesc*
getDesc(int callnum) override
{
return SparcLinuxProcess::getDesc32(callnum);
}
void syscall(ThreadContext *tc, Fault *fault) override;
void handleTrap(int trapNum, ThreadContext *tc, Fault *fault) override;
@@ -80,12 +68,6 @@ class Sparc64LinuxProcess : public SparcLinuxProcess, public Sparc64Process
/// Constructor.
Sparc64LinuxProcess(ProcessParams * params, ObjectFile *objFile);
SyscallDesc*
getDesc(int callnum) override
{
return SparcLinuxProcess::getDesc(callnum);
}
void syscall(ThreadContext *tc, Fault *fault) override;
void handleTrap(int trapNum, ThreadContext *tc, Fault *fault) override;

View File

@@ -352,14 +352,9 @@ SparcSolarisProcess::SparcSolarisProcess(ProcessParams * params,
: Sparc64Process(params, objFile)
{}
SyscallDesc*
SparcSolarisProcess::getDesc(int callnum)
{
return syscallDescs.get(callnum);
}
void
SparcSolarisProcess::syscall(ThreadContext *tc, Fault *fault)
{
doSyscall(tc->readIntReg(1), tc, fault);
Sparc64Process::syscall(tc, fault);
syscallDescs.get(tc->readIntReg(1))->doSyscall(tc, fault);
}

View File

@@ -43,8 +43,6 @@ class SparcSolarisProcess : public Sparc64Process
/// Constructor.
SparcSolarisProcess(ProcessParams * params, ObjectFile *objFile);
SyscallDesc *getDesc(int callnum) override;
/// The target system's hostname.
static const char *hostname;

View File

@@ -576,13 +576,8 @@ static SyscallDescTable<X86_64LinuxProcess::SyscallABI> syscallDescs64 = {
void
X86_64LinuxProcess::syscall(ThreadContext *tc, Fault *fault)
{
doSyscall(tc->readIntReg(INTREG_RAX), tc, fault);
}
SyscallDesc *
X86_64LinuxProcess::getDesc(int callnum)
{
return syscallDescs64.get(callnum);
X86_64Process::syscall(tc, fault);
syscallDescs64.get(tc->readIntReg(INTREG_RAX))->doSyscall(tc, fault);
}
void
@@ -930,6 +925,7 @@ static SyscallDescTable<I386LinuxProcess::SyscallABI> syscallDescs32 = {
void
I386LinuxProcess::syscall(ThreadContext *tc, Fault *fault)
{
I386Process::syscall(tc, fault);
PCState pc = tc->pcState();
Addr eip = pc.pc();
if (eip >= vsyscallPage.base &&
@@ -937,13 +933,7 @@ I386LinuxProcess::syscall(ThreadContext *tc, Fault *fault)
pc.npc(vsyscallPage.base + vsyscallPage.vsysexitOffset);
tc->pcState(pc);
}
doSyscall(tc->readIntReg(INTREG_RAX), tc, fault);
}
SyscallDesc *
I386LinuxProcess::getDesc(int callnum)
{
return syscallDescs32.get(callnum);
syscallDescs32.get(tc->readIntReg(INTREG_RAX))->doSyscall(tc, fault);
}
void

View File

@@ -54,7 +54,6 @@ class X86_64LinuxProcess : public X86_64Process
public:
using X86_64Process::X86_64Process;
void syscall(ThreadContext *tc, Fault *fault) override;
SyscallDesc *getDesc(int callnum) override;
void clone(ThreadContext *old_tc, ThreadContext *new_tc, Process *process,
RegVal flags) override;
@@ -69,7 +68,6 @@ class I386LinuxProcess : public I386Process
public:
using I386Process::I386Process;
void syscall(ThreadContext *tc, Fault *fault) override;
SyscallDesc *getDesc(int callnum) override;
void clone(ThreadContext *old_tc, ThreadContext *new_tc, Process *process,
RegVal flags) override;

View File

@@ -419,18 +419,6 @@ Process::map(Addr vaddr, Addr paddr, int size, bool cacheable)
return true;
}
void
Process::doSyscall(int64_t callnum, ThreadContext *tc, Fault *fault)
{
numSyscalls++;
SyscallDesc *desc = getDesc(callnum);
if (desc == nullptr)
fatal("Syscall %d out of range", callnum);
desc->doSyscall(tc, fault);
}
EmulatedDriver *
Process::findDriver(std::string filename)
{

View File

@@ -60,9 +60,6 @@ class ThreadContext;
class Process : public SimObject
{
protected:
void doSyscall(int64_t callnum, ThreadContext *tc, Fault *fault);
public:
Process(ProcessParams *params, EmulationPageTable *pTable,
ObjectFile *obj_file);
@@ -74,8 +71,7 @@ class Process : public SimObject
void initState() override;
DrainState drain() override;
virtual void syscall(ThreadContext *tc, Fault *fault) = 0;
virtual SyscallDesc *getDesc(int callnum) = 0;
virtual void syscall(ThreadContext *tc, Fault *fault) { numSyscalls++; }
inline uint64_t uid() { return _uid; }
inline uint64_t euid() { return _euid; }

View File

@@ -192,11 +192,15 @@ class SyscallDescTable
}
SyscallDesc
*get(int num)
*get(int num, bool fatal_if_missing=true)
{
auto it = _descs.find(num);
if (it == _descs.end())
return nullptr;
if (it == _descs.end()) {
if (fatal_if_missing)
fatal("Syscall %d out of range", num);
else
return nullptr;
}
return &it->second;
}
};