/* 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>),
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__
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;
+}
#endif
#include <fcntl.h>
#include <sys/mman.h>
+#include <sys/socket.h>
#include <sys/stat.h>
#if (NO_STATFS == 0)
#include <sys/statfs.h>
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);
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,
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__