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 c9f5292e2..97ac77e2a 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 cdc18f165..a972f17e8 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 76f1f3963..02c9f27e9 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 375e0adea..46801cb00 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 f595480a7..7b759b604 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 233ffbd9e..dcf0c0878 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 3dca72016..710f88dbb 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 071e6c37b..857e883ac 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 69569e5a0..45ee00f22 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 55452b87f..ec7d2673e 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 ad93e9b18..028000410 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 3ffd709e9..963056ceb 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 e214788be..d5a7e08f5 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 56d04ebed..f9a638611 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 d05dbce07..cd76224ce 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 cebcb886e..c2fff8bf8 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 2e82b3d1b..8cd12b54a 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 7fd3571ec..7c152ae64 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 015a54b22..53e3ccd03 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; } }; -- 2.30.2