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 <bbruce@ucdavis.edu> Maintainer: Gabe Black <gabeblack@google.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -65,9 +65,7 @@ class X86Linux : public Linux
|
||||
ctc->setIntReg(X86ISA::StackPointerReg, stack);
|
||||
}
|
||||
|
||||
class SyscallABI
|
||||
{
|
||||
};
|
||||
class SyscallABI {};
|
||||
};
|
||||
|
||||
namespace GuestABI
|
||||
@@ -81,7 +79,10 @@ struct Result<ABI, SyscallReturn,
|
||||
static void
|
||||
store(ThreadContext *tc, const SyscallReturn &ret)
|
||||
{
|
||||
tc->setIntReg(ABI::ReturnValueReg, ret.encodedValue());
|
||||
if (ret.suppressed() || ret.needsRetry())
|
||||
return;
|
||||
|
||||
tc->setIntReg(X86ISA::INTREG_RAX, ret.encodedValue());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -250,7 +250,11 @@ setThreadArea32Func(SyscallDesc *desc, int callnum, ThreadContext *tc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SyscallDescABI<DefaultSyscallABI> syscallDescs64[] = {
|
||||
const std::vector<IntRegIndex> X86_64LinuxProcess::SyscallABI::ArgumentRegs = {
|
||||
INTREG_RDI, INTREG_RSI, INTREG_RDX, INTREG_R10W, INTREG_R8W, INTREG_R9W
|
||||
};
|
||||
|
||||
static SyscallDescABI<X86_64LinuxProcess::SyscallABI> syscallDescs64[] = {
|
||||
/* 0 */ { "read", readFunc<X86Linux64> },
|
||||
/* 1 */ { "write", writeFunc<X86Linux64> },
|
||||
/* 2 */ { "open", openFunc<X86Linux64> },
|
||||
@@ -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<DefaultSyscallABI> syscallDescs32[] = {
|
||||
const std::vector<IntRegIndex> I386LinuxProcess::SyscallABI::ArgumentRegs = {
|
||||
INTREG_EBX, INTREG_ECX, INTREG_EDX, INTREG_ESI, INTREG_EDI, INTREG_EBP
|
||||
};
|
||||
|
||||
static SyscallDescABI<I386LinuxProcess::SyscallABI> syscallDescs32[] = {
|
||||
/* 0 */ { "restart_syscall" },
|
||||
/* 1 */ { "exit", exitFunc },
|
||||
/* 2 */ { "fork" },
|
||||
|
||||
@@ -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<IntRegIndex> 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<IntRegIndex> ArgumentRegs;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace X86ISA
|
||||
|
||||
namespace GuestABI
|
||||
{
|
||||
|
||||
template <typename Arg>
|
||||
struct Argument<X86ISA::I386LinuxProcess::SyscallABI, Arg,
|
||||
typename std::enable_if<
|
||||
X86ISA::I386LinuxProcess::SyscallABI::IsWide<Arg>::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__
|
||||
|
||||
Reference in New Issue
Block a user