From: Gabe Black Date: Sat, 7 Dec 2019 01:46:38 +0000 (-0800) Subject: x86: Define a local ABI for system calls. X-Git-Tag: v20.0.0.0~384 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=112e1cdfca116a56e852515e7da374ddb5d53c8b;p=gem5.git x86: Define a local ABI for system calls. These ABIs (one 32 bit and one 64 bit) take advantage of the GenericSyscallABI and X86Linux::SyscallABI partial ABIs set up earlier. This removes x86's dependence on the getSyscallArg and setSyscallReturn Process methods. Change-Id: Ia07834cea1afa827d77e590af5397e2a1e0e2099 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23443 Reviewed-by: Bobby R. Bruce Maintainer: Gabe Black Tested-by: kokoro --- diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index 7fb362784..e373dafbb 100644 --- a/src/arch/x86/linux/linux.hh +++ b/src/arch/x86/linux/linux.hh @@ -65,9 +65,7 @@ class X86Linux : public Linux ctc->setIntReg(X86ISA::StackPointerReg, stack); } - class SyscallABI - { - }; + class SyscallABI {}; }; namespace GuestABI @@ -81,7 +79,10 @@ struct ResultsetIntReg(ABI::ReturnValueReg, ret.encodedValue()); + if (ret.suppressed() || ret.needsRetry()) + return; + + tc->setIntReg(X86ISA::INTREG_RAX, ret.encodedValue()); } }; diff --git a/src/arch/x86/linux/process.cc b/src/arch/x86/linux/process.cc index ee3f4cc9c..36a75d79c 100644 --- a/src/arch/x86/linux/process.cc +++ b/src/arch/x86/linux/process.cc @@ -250,7 +250,11 @@ setThreadArea32Func(SyscallDesc *desc, int callnum, ThreadContext *tc, return 0; } -static SyscallDescABI syscallDescs64[] = { +const std::vector X86_64LinuxProcess::SyscallABI::ArgumentRegs = { + INTREG_RDI, INTREG_RSI, INTREG_RDX, INTREG_R10W, INTREG_R8W, INTREG_R9W +}; + +static SyscallDescABI syscallDescs64[] = { /* 0 */ { "read", readFunc }, /* 1 */ { "write", writeFunc }, /* 2 */ { "open", openFunc }, @@ -590,7 +594,11 @@ X86_64LinuxProcess::clone(ThreadContext *old_tc, ThreadContext *new_tc, X86_64Process::clone(old_tc, new_tc, (X86_64Process*)process, flags); } -static SyscallDescABI syscallDescs32[] = { +const std::vector I386LinuxProcess::SyscallABI::ArgumentRegs = { + INTREG_EBX, INTREG_ECX, INTREG_EDX, INTREG_ESI, INTREG_EDI, INTREG_EBP +}; + +static SyscallDescABI syscallDescs32[] = { /* 0 */ { "restart_syscall" }, /* 1 */ { "exit", exitFunc }, /* 2 */ { "fork" }, diff --git a/src/arch/x86/linux/process.hh b/src/arch/x86/linux/process.hh index 53e8c4793..a236a9e12 100644 --- a/src/arch/x86/linux/process.hh +++ b/src/arch/x86/linux/process.hh @@ -41,6 +41,7 @@ #include "arch/x86/linux/linux.hh" #include "arch/x86/process.hh" #include "sim/process.hh" +#include "sim/syscall_abi.hh" struct ProcessParams; struct ThreadContext; @@ -55,6 +56,11 @@ class X86_64LinuxProcess : public X86_64Process void syscall(ThreadContext *tc, Fault *fault) override; void clone(ThreadContext *old_tc, ThreadContext *new_tc, Process *process, RegVal flags) override; + + struct SyscallABI : public GenericSyscallABI64, public X86Linux::SyscallABI + { + static const std::vector ArgumentRegs; + }; }; class I386LinuxProcess : public I386Process @@ -65,7 +71,36 @@ class I386LinuxProcess : public I386Process void syscall(ThreadContext *tc, Fault *fault) override; void clone(ThreadContext *old_tc, ThreadContext *new_tc, Process *process, RegVal flags) override; + + struct SyscallABI : public GenericSyscallABI32, public X86Linux::SyscallABI + { + static const std::vector ArgumentRegs; + }; }; } // namespace X86ISA + +namespace GuestABI +{ + +template +struct Argument::value>::type> +{ + using ABI = X86ISA::I386LinuxProcess::SyscallABI; + + static Arg + get(ThreadContext *tc, typename ABI::Position &position) + { + panic_if(position + 1 >= ABI::ArgumentRegs.size(), + "Ran out of syscall argument registers."); + auto low = ABI::ArgumentRegs[position++]; + auto high = ABI::ArgumentRegs[position++]; + return (Arg)ABI::mergeRegs(tc, low, high); + } +}; + +} // namespace GuestABI + #endif // __X86_LINUX_PROCESS_HH__