From cd69bb50414450c3bb5ef41dce676b75fd42c0ee Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 1 Jan 2020 03:07:22 -0800 Subject: [PATCH] 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 Tested-by: Gem5 Cloud Project GCB service account <345032938727@cloudbuild.gserviceaccount.com> Maintainer: Gabe Black Reviewed-by: Bobby R. Bruce --- src/arch/arm/freebsd/process.cc | 18 +++---------- src/arch/arm/freebsd/process.hh | 3 --- src/arch/arm/linux/process.cc | 44 +++++++++++++------------------ src/arch/arm/linux/process.hh | 3 --- src/arch/mips/linux/process.cc | 9 ++----- src/arch/mips/linux/process.hh | 2 -- src/arch/power/linux/process.cc | 9 ++----- src/arch/power/linux/process.hh | 2 -- src/arch/riscv/linux/process.cc | 18 +++---------- src/arch/riscv/linux/process.hh | 4 --- src/arch/sparc/linux/process.cc | 18 +++---------- src/arch/sparc/linux/process.hh | 18 ------------- src/arch/sparc/solaris/process.cc | 9 ++----- src/arch/sparc/solaris/process.hh | 2 -- src/arch/x86/linux/process.cc | 18 +++---------- src/arch/x86/linux/process.hh | 2 -- src/sim/process.cc | 12 --------- src/sim/process.hh | 6 +---- src/sim/syscall_desc.hh | 10 ++++--- 19 files changed, 48 insertions(+), 159 deletions(-) diff --git a/src/arch/arm/freebsd/process.cc b/src/arch/arm/freebsd/process.cc index c9f5292e29..97ac77e2a8 100644 --- a/src/arch/arm/freebsd/process.cc +++ b/src/arch/arm/freebsd/process.cc @@ -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); } diff --git a/src/arch/arm/freebsd/process.hh b/src/arch/arm/freebsd/process.hh index cdc18f1659..a972f17e81 100644 --- a/src/arch/arm/freebsd/process.hh +++ b/src/arch/arm/freebsd/process.hh @@ -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 diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc index 76f1f39638..02c9f27e90 100644 --- a/src/arch/arm/linux/process.cc +++ b/src/arch/arm/linux/process.cc @@ -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); } diff --git a/src/arch/arm/linux/process.hh b/src/arch/arm/linux/process.hh index 375e0adead..46801cb003 100644 --- a/src/arch/arm/linux/process.hh +++ b/src/arch/arm/linux/process.hh @@ -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 diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index f595480a71..7b759b6043 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -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); } diff --git a/src/arch/mips/linux/process.hh b/src/arch/mips/linux/process.hh index 233ffbd9e4..dcf0c08782 100644 --- a/src/arch/mips/linux/process.hh +++ b/src/arch/mips/linux/process.hh @@ -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; diff --git a/src/arch/power/linux/process.cc b/src/arch/power/linux/process.cc index 3dca720164..710f88dbba 100644 --- a/src/arch/power/linux/process.cc +++ b/src/arch/power/linux/process.cc @@ -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); } diff --git a/src/arch/power/linux/process.hh b/src/arch/power/linux/process.hh index 071e6c37bb..857e883acb 100644 --- a/src/arch/power/linux/process.hh +++ b/src/arch/power/linux/process.hh @@ -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; diff --git a/src/arch/riscv/linux/process.cc b/src/arch/riscv/linux/process.cc index 69569e5a04..45ee00f222 100644 --- a/src/arch/riscv/linux/process.cc +++ b/src/arch/riscv/linux/process.cc @@ -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); } diff --git a/src/arch/riscv/linux/process.hh b/src/arch/riscv/linux/process.hh index 55452b87f1..ec7d2673e4 100644 --- a/src/arch/riscv/linux/process.hh +++ b/src/arch/riscv/linux/process.hh @@ -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; diff --git a/src/arch/sparc/linux/process.cc b/src/arch/sparc/linux/process.cc index ad93e9b18d..028000410c 100644 --- a/src/arch/sparc/linux/process.cc +++ b/src/arch/sparc/linux/process.cc @@ -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 diff --git a/src/arch/sparc/linux/process.hh b/src/arch/sparc/linux/process.hh index 3ffd709e99..963056ceb9 100644 --- a/src/arch/sparc/linux/process.hh +++ b/src/arch/sparc/linux/process.hh @@ -47,12 +47,6 @@ class SparcLinuxProcess /// 32 bit compatibility syscall descriptors, indexed by call number. static SyscallDescTable 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; diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc index e214788bec..d5a7e08f52 100644 --- a/src/arch/sparc/solaris/process.cc +++ b/src/arch/sparc/solaris/process.cc @@ -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); } diff --git a/src/arch/sparc/solaris/process.hh b/src/arch/sparc/solaris/process.hh index 56d04ebed8..f9a6386116 100644 --- a/src/arch/sparc/solaris/process.hh +++ b/src/arch/sparc/solaris/process.hh @@ -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; diff --git a/src/arch/x86/linux/process.cc b/src/arch/x86/linux/process.cc index d05dbce073..cd76224ce0 100644 --- a/src/arch/x86/linux/process.cc +++ b/src/arch/x86/linux/process.cc @@ -576,13 +576,8 @@ static SyscallDescTable 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 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 diff --git a/src/arch/x86/linux/process.hh b/src/arch/x86/linux/process.hh index cebcb886e1..c2fff8bf88 100644 --- a/src/arch/x86/linux/process.hh +++ b/src/arch/x86/linux/process.hh @@ -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; diff --git a/src/sim/process.cc b/src/sim/process.cc index 2e82b3d1bc..8cd12b54ac 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -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) { diff --git a/src/sim/process.hh b/src/sim/process.hh index 7fd3571ec7..7c152ae641 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -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; } diff --git a/src/sim/syscall_desc.hh b/src/sim/syscall_desc.hh index 015a54b222..53e3ccd036 100644 --- a/src/sim/syscall_desc.hh +++ b/src/sim/syscall_desc.hh @@ -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; } };