ctc->setIntReg(X86ISA::StackPointerReg, stack);
}
- class SyscallABI
- {
- };
+ class SyscallABI {};
};
namespace GuestABI
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());
}
};
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> },
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" },
#include "arch/x86/linux/linux.hh"
#include "arch/x86/process.hh"
#include "sim/process.hh"
+#include "sim/syscall_abi.hh"
struct ProcessParams;
struct ThreadContext;
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
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__