sim-se: add socket-based functionality
Add socket, socketpair, bind, list, connect and shutdown system calls. Change-Id: I635af3fca410f96fe28f8fe497e3d457a9dbc470 Reviewed-on: https://gem5-review.googlesource.com/c/12113 Reviewed-by: Anthony Gutierrez <anthony.gutierrez@amd.com> Maintainer: Anthony Gutierrez <anthony.gutierrez@amd.com>
This commit is contained in:
committed by
Anthony Gutierrez
parent
2c9f7ebca5
commit
a2ed7d5575
@@ -263,19 +263,19 @@ static SyscallDesc syscallDescs64[] = {
|
||||
/* 38 */ SyscallDesc("setitimer", unimplementedFunc),
|
||||
/* 39 */ SyscallDesc("getpid", getpidFunc),
|
||||
/* 40 */ SyscallDesc("sendfile", unimplementedFunc),
|
||||
/* 41 */ SyscallDesc("socket", unimplementedFunc),
|
||||
/* 42 */ SyscallDesc("connect", unimplementedFunc),
|
||||
/* 41 */ SyscallDesc("socket", socketFunc<X86Linux64>),
|
||||
/* 42 */ SyscallDesc("connect", connectFunc),
|
||||
/* 43 */ SyscallDesc("accept", unimplementedFunc),
|
||||
/* 44 */ SyscallDesc("sendto", unimplementedFunc),
|
||||
/* 45 */ SyscallDesc("recvfrom", unimplementedFunc),
|
||||
/* 46 */ SyscallDesc("sendmsg", unimplementedFunc),
|
||||
/* 47 */ SyscallDesc("recvmsg", unimplementedFunc),
|
||||
/* 48 */ SyscallDesc("shutdown", unimplementedFunc),
|
||||
/* 49 */ SyscallDesc("bind", unimplementedFunc),
|
||||
/* 50 */ SyscallDesc("listen", unimplementedFunc),
|
||||
/* 48 */ SyscallDesc("shutdown", shutdownFunc),
|
||||
/* 49 */ SyscallDesc("bind", bindFunc),
|
||||
/* 50 */ SyscallDesc("listen", listenFunc),
|
||||
/* 51 */ SyscallDesc("getsockname", unimplementedFunc),
|
||||
/* 52 */ SyscallDesc("getpeername", unimplementedFunc),
|
||||
/* 53 */ SyscallDesc("socketpair", unimplementedFunc),
|
||||
/* 53 */ SyscallDesc("socketpair", socketpairFunc<X86Linux64>),
|
||||
/* 54 */ SyscallDesc("setsockopt", unimplementedFunc),
|
||||
/* 55 */ SyscallDesc("getsockopt", unimplementedFunc),
|
||||
/* 56 */ SyscallDesc("clone", cloneFunc<X86Linux64>),
|
||||
|
||||
@@ -211,4 +211,30 @@ class DeviceFDEntry : public FDEntry
|
||||
std::string _fileName;
|
||||
};
|
||||
|
||||
class SocketFDEntry: public HBFDEntry
|
||||
{
|
||||
public:
|
||||
SocketFDEntry(int sim_fd, int domain, int type, int protocol,
|
||||
bool close_on_exec = false)
|
||||
: HBFDEntry(0, sim_fd, close_on_exec),
|
||||
_domain(domain), _type(type), _protocol(protocol)
|
||||
{ }
|
||||
|
||||
SocketFDEntry(SocketFDEntry const& reg, bool close_on_exec = false)
|
||||
: HBFDEntry(reg._flags, reg._simFD, close_on_exec),
|
||||
_domain(reg._domain), _type(reg._type), _protocol(reg._protocol)
|
||||
{ }
|
||||
|
||||
std::shared_ptr<FDEntry>
|
||||
clone() const override
|
||||
{
|
||||
return std::make_shared<SocketFDEntry>(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
int _domain;
|
||||
int _type;
|
||||
int _protocol;
|
||||
};
|
||||
|
||||
#endif // __FD_ENTRY_HH__
|
||||
|
||||
@@ -1224,3 +1224,83 @@ getdents64Func(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc)
|
||||
return getdentsImpl<LinDent64, SYS_getdents64>(desc, callnum, p, tc);
|
||||
}
|
||||
#endif
|
||||
|
||||
SyscallReturn
|
||||
shutdownFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
|
||||
{
|
||||
int index = 0;
|
||||
int tgt_fd = p->getSyscallArg(tc, index);
|
||||
int how = p->getSyscallArg(tc, index);
|
||||
|
||||
auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
|
||||
if (!sfdp)
|
||||
return -EBADF;
|
||||
int sim_fd = sfdp->getSimFD();
|
||||
|
||||
int retval = shutdown(sim_fd, how);
|
||||
|
||||
return (retval == -1) ? -errno : retval;
|
||||
}
|
||||
|
||||
SyscallReturn
|
||||
bindFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
|
||||
{
|
||||
int index = 0;
|
||||
int tgt_fd = p->getSyscallArg(tc, index);
|
||||
Addr buf_ptr = p->getSyscallArg(tc, index);
|
||||
int addrlen = p->getSyscallArg(tc, index);
|
||||
|
||||
BufferArg bufSock(buf_ptr, addrlen);
|
||||
bufSock.copyIn(tc->getMemProxy());
|
||||
|
||||
auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
|
||||
if (!sfdp)
|
||||
return -EBADF;
|
||||
int sim_fd = sfdp->getSimFD();
|
||||
|
||||
int status = ::bind(sim_fd,
|
||||
(struct sockaddr *)bufSock.bufferPtr(),
|
||||
addrlen);
|
||||
|
||||
return (status == -1) ? -errno : status;
|
||||
}
|
||||
|
||||
SyscallReturn
|
||||
listenFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
|
||||
{
|
||||
int index = 0;
|
||||
int tgt_fd = p->getSyscallArg(tc, index);
|
||||
int backlog = p->getSyscallArg(tc, index);
|
||||
|
||||
auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
|
||||
if (!sfdp)
|
||||
return -EBADF;
|
||||
int sim_fd = sfdp->getSimFD();
|
||||
|
||||
int status = listen(sim_fd, backlog);
|
||||
|
||||
return (status == -1) ? -errno : status;
|
||||
}
|
||||
|
||||
SyscallReturn
|
||||
connectFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
|
||||
{
|
||||
int index = 0;
|
||||
int tgt_fd = p->getSyscallArg(tc, index);
|
||||
Addr buf_ptr = p->getSyscallArg(tc, index);
|
||||
int addrlen = p->getSyscallArg(tc, index);
|
||||
|
||||
BufferArg addr(buf_ptr, addrlen);
|
||||
addr.copyIn(tc->getMemProxy());
|
||||
|
||||
auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
|
||||
if (!sfdp)
|
||||
return -EBADF;
|
||||
int sim_fd = sfdp->getSimFD();
|
||||
|
||||
int status = connect(sim_fd,
|
||||
(struct sockaddr *)addr.bufferPtr(),
|
||||
(socklen_t)addrlen);
|
||||
|
||||
return (status == -1) ? -errno : status;
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#if (NO_STATFS == 0)
|
||||
#include <sys/statfs.h>
|
||||
@@ -181,6 +182,10 @@ SyscallReturn _llseekFunc(SyscallDesc *desc, int num,
|
||||
SyscallReturn munmapFunc(SyscallDesc *desc, int num,
|
||||
Process *p, ThreadContext *tc);
|
||||
|
||||
/// Target shutdown() handler.
|
||||
SyscallReturn shutdownFunc(SyscallDesc *desc, int num,
|
||||
Process *p, ThreadContext *tc);
|
||||
|
||||
/// Target gethostname() handler.
|
||||
SyscallReturn gethostnameFunc(SyscallDesc *desc, int num,
|
||||
Process *p, ThreadContext *tc);
|
||||
@@ -303,6 +308,18 @@ SyscallReturn pipeImpl(SyscallDesc *desc, int num, Process *p,
|
||||
SyscallReturn getpidFunc(SyscallDesc *desc, int num,
|
||||
Process *p, ThreadContext *tc);
|
||||
|
||||
// Target bind() handler.
|
||||
SyscallReturn bindFunc(SyscallDesc *desc, int num,
|
||||
Process *p, ThreadContext *tc);
|
||||
|
||||
// Target listen() handler.
|
||||
SyscallReturn listenFunc(SyscallDesc *desc, int num,
|
||||
Process *p, ThreadContext *tc);
|
||||
|
||||
// Target connect() handler.
|
||||
SyscallReturn connectFunc(SyscallDesc *desc, int num,
|
||||
Process *p, ThreadContext *tc);
|
||||
|
||||
#if defined(SYS_getdents)
|
||||
// Target getdents() handler.
|
||||
SyscallReturn getdentsFunc(SyscallDesc *desc, int num,
|
||||
@@ -2080,5 +2097,49 @@ tgkillFunc(SyscallDesc *desc, int num, Process *process, ThreadContext *tc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class OS>
|
||||
SyscallReturn
|
||||
socketFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
|
||||
{
|
||||
int index = 0;
|
||||
int domain = p->getSyscallArg(tc, index);
|
||||
int type = p->getSyscallArg(tc, index);
|
||||
int prot = p->getSyscallArg(tc, index);
|
||||
|
||||
int sim_fd = socket(domain, type, prot);
|
||||
if (sim_fd == -1)
|
||||
return -errno;
|
||||
|
||||
auto sfdp = std::make_shared<SocketFDEntry>(sim_fd, domain, type, prot);
|
||||
int tgt_fd = p->fds->allocFD(sfdp);
|
||||
|
||||
return tgt_fd;
|
||||
}
|
||||
|
||||
template <class OS>
|
||||
SyscallReturn
|
||||
socketpairFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
|
||||
{
|
||||
int index = 0;
|
||||
int domain = p->getSyscallArg(tc, index);
|
||||
int type = p->getSyscallArg(tc, index);
|
||||
int prot = p->getSyscallArg(tc, index);
|
||||
Addr svPtr = p->getSyscallArg(tc, index);
|
||||
|
||||
BufferArg svBuf((Addr)svPtr, 2 * sizeof(int));
|
||||
int status = socketpair(domain, type, prot, (int *)svBuf.bufferPtr());
|
||||
if (status == -1)
|
||||
return -errno;
|
||||
|
||||
int *fds = (int *)svBuf.bufferPtr();
|
||||
|
||||
auto sfdp1 = std::make_shared<SocketFDEntry>(fds[0], domain, type, prot);
|
||||
fds[0] = p->fds->allocFD(sfdp1);
|
||||
auto sfdp2 = std::make_shared<SocketFDEntry>(fds[1], domain, type, prot);
|
||||
fds[1] = p->fds->allocFD(sfdp2);
|
||||
svBuf.copyOut(tc->getMemProxy());
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif // __SIM_SYSCALL_EMUL_HH__
|
||||
|
||||
Reference in New Issue
Block a user