sim-se: add ability to get/set sock metadata
Add getsockopt, getsockname, setsockname, and getpeername system calls. Change-Id: Ifa1d9a95f15b4fb12859dbfd3c4bd248de2e3d32 Reviewed-on: https://gem5-review.googlesource.com/c/12116 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
bc74c58eaf
commit
7936e63336
@@ -273,11 +273,11 @@ static SyscallDesc syscallDescs64[] = {
|
||||
/* 48 */ SyscallDesc("shutdown", shutdownFunc),
|
||||
/* 49 */ SyscallDesc("bind", bindFunc),
|
||||
/* 50 */ SyscallDesc("listen", listenFunc),
|
||||
/* 51 */ SyscallDesc("getsockname", unimplementedFunc),
|
||||
/* 52 */ SyscallDesc("getpeername", unimplementedFunc),
|
||||
/* 51 */ SyscallDesc("getsockname", getsocknameFunc),
|
||||
/* 52 */ SyscallDesc("getpeername", getpeernameFunc),
|
||||
/* 53 */ SyscallDesc("socketpair", socketpairFunc<X86Linux64>),
|
||||
/* 54 */ SyscallDesc("setsockopt", unimplementedFunc),
|
||||
/* 55 */ SyscallDesc("getsockopt", unimplementedFunc),
|
||||
/* 54 */ SyscallDesc("setsockopt", setsockoptFunc),
|
||||
/* 55 */ SyscallDesc("getsockopt", getsockoptFunc),
|
||||
/* 56 */ SyscallDesc("clone", cloneFunc<X86Linux64>),
|
||||
/* 57 */ SyscallDesc("fork", unimplementedFunc),
|
||||
/* 58 */ SyscallDesc("vfork", unimplementedFunc),
|
||||
|
||||
@@ -1567,3 +1567,137 @@ sendmsgFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
|
||||
return (sent_size < 0) ? -local_errno : sent_size;
|
||||
}
|
||||
|
||||
SyscallReturn
|
||||
getsockoptFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
|
||||
{
|
||||
// union of all possible return value types from getsockopt
|
||||
union val {
|
||||
int i_val;
|
||||
long l_val;
|
||||
struct linger linger_val;
|
||||
struct timeval timeval_val;
|
||||
} val;
|
||||
|
||||
int index = 0;
|
||||
int tgt_fd = p->getSyscallArg(tc, index);
|
||||
int level = p->getSyscallArg(tc, index);
|
||||
int optname = p->getSyscallArg(tc, index);
|
||||
Addr valPtr = p->getSyscallArg(tc, index);
|
||||
Addr lenPtr = p->getSyscallArg(tc, index);
|
||||
|
||||
auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
|
||||
if (!sfdp)
|
||||
return -EBADF;
|
||||
int sim_fd = sfdp->getSimFD();
|
||||
|
||||
socklen_t len = sizeof(val);
|
||||
int status = getsockopt(sim_fd, level, optname, &val, &len);
|
||||
|
||||
if (status == -1)
|
||||
return -errno;
|
||||
|
||||
// copy val to valPtr and pass it on
|
||||
BufferArg valBuf(valPtr, sizeof(val));
|
||||
memcpy(valBuf.bufferPtr(), &val, sizeof(val));
|
||||
valBuf.copyOut(tc->getMemProxy());
|
||||
|
||||
// copy len to lenPtr and pass it on
|
||||
BufferArg lenBuf(lenPtr, sizeof(len));
|
||||
memcpy(lenBuf.bufferPtr(), &len, sizeof(len));
|
||||
lenBuf.copyOut(tc->getMemProxy());
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SyscallReturn
|
||||
getsocknameFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
|
||||
{
|
||||
int index = 0;
|
||||
int tgt_fd = p->getSyscallArg(tc, index);
|
||||
Addr addrPtr = p->getSyscallArg(tc, index);
|
||||
Addr lenPtr = p->getSyscallArg(tc, index);
|
||||
|
||||
auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
|
||||
if (!sfdp)
|
||||
return -EBADF;
|
||||
int sim_fd = sfdp->getSimFD();
|
||||
|
||||
// lenPtr is an in-out paramenter:
|
||||
// sending the address length in, conveying the final length out
|
||||
|
||||
// Read in the value of len from the passed pointer.
|
||||
BufferArg lenBuf(lenPtr, sizeof(socklen_t));
|
||||
lenBuf.copyIn(tc->getMemProxy());
|
||||
socklen_t len = *(socklen_t *)lenBuf.bufferPtr();
|
||||
|
||||
struct sockaddr sa;
|
||||
int status = getsockname(sim_fd, &sa, &len);
|
||||
|
||||
if (status == -1)
|
||||
return -errno;
|
||||
|
||||
// Copy address to addrPtr and pass it on.
|
||||
BufferArg addrBuf(addrPtr, sizeof(sa));
|
||||
memcpy(addrBuf.bufferPtr(), &sa, sizeof(sa));
|
||||
addrBuf.copyOut(tc->getMemProxy());
|
||||
|
||||
// Copy len to lenPtr and pass it on.
|
||||
*(socklen_t *)lenBuf.bufferPtr() = len;
|
||||
lenBuf.copyOut(tc->getMemProxy());
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SyscallReturn
|
||||
getpeernameFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
|
||||
{
|
||||
int index = 0;
|
||||
int tgt_fd = p->getSyscallArg(tc, index);
|
||||
Addr sockAddrPtr = p->getSyscallArg(tc, index);
|
||||
Addr addrlenPtr = p->getSyscallArg(tc, index);
|
||||
|
||||
auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
|
||||
if (!sfdp)
|
||||
return -EBADF;
|
||||
int sim_fd = sfdp->getSimFD();
|
||||
|
||||
BufferArg bufAddrlen(addrlenPtr, sizeof(unsigned));
|
||||
bufAddrlen.copyIn(tc->getMemProxy());
|
||||
BufferArg bufSock(sockAddrPtr, *(unsigned *)bufAddrlen.bufferPtr());
|
||||
|
||||
int retval = getpeername(sim_fd,
|
||||
(struct sockaddr *)bufSock.bufferPtr(),
|
||||
(unsigned *)bufAddrlen.bufferPtr());
|
||||
|
||||
if (retval != -1) {
|
||||
bufSock.copyOut(tc->getMemProxy());
|
||||
bufAddrlen.copyOut(tc->getMemProxy());
|
||||
}
|
||||
|
||||
return (retval == -1) ? -errno : retval;
|
||||
}
|
||||
|
||||
SyscallReturn
|
||||
setsockoptFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
|
||||
{
|
||||
int index = 0;
|
||||
int tgt_fd = p->getSyscallArg(tc, index);
|
||||
int level = p->getSyscallArg(tc, index);
|
||||
int optname = p->getSyscallArg(tc, index);
|
||||
Addr valPtr = p->getSyscallArg(tc, index);
|
||||
socklen_t len = p->getSyscallArg(tc, index);
|
||||
|
||||
BufferArg valBuf(valPtr, len);
|
||||
valBuf.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 = setsockopt(sim_fd, level, optname,
|
||||
(struct sockaddr *)valBuf.bufferPtr(), len);
|
||||
|
||||
return (status == -1) ? -errno : status;
|
||||
}
|
||||
|
||||
|
||||
@@ -302,6 +302,10 @@ SyscallReturn pipeImpl(SyscallDesc *desc, int num, Process *p,
|
||||
SyscallReturn getpidFunc(SyscallDesc *desc, int num,
|
||||
Process *p, ThreadContext *tc);
|
||||
|
||||
// Target getpeername() handler.
|
||||
SyscallReturn getpeernameFunc(SyscallDesc *desc, int num,
|
||||
Process *p, ThreadContext *tc);
|
||||
|
||||
// Target bind() handler.
|
||||
SyscallReturn bindFunc(SyscallDesc *desc, int num,
|
||||
Process *p, ThreadContext *tc);
|
||||
@@ -369,6 +373,18 @@ SyscallReturn accessFunc(SyscallDesc *desc, int num,
|
||||
Process *p, ThreadContext *tc,
|
||||
int index);
|
||||
|
||||
// Target getsockopt() handler.
|
||||
SyscallReturn getsockoptFunc(SyscallDesc *desc, int num,
|
||||
Process *p, ThreadContext *tc);
|
||||
|
||||
// Target setsockopt() handler.
|
||||
SyscallReturn setsockoptFunc(SyscallDesc *desc, int num,
|
||||
Process *p, ThreadContext *tc);
|
||||
|
||||
// Target getsockname() handler.
|
||||
SyscallReturn getsocknameFunc(SyscallDesc *desc, int num,
|
||||
Process *p, ThreadContext *tc);
|
||||
|
||||
/// Futex system call
|
||||
/// Implemented by Daniel Sanchez
|
||||
/// Used by printf's in multi-threaded apps
|
||||
|
||||
Reference in New Issue
Block a user