summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrandon Potter <brandon.potter@amd.com>2018-04-18 15:00:14 -0400
committerAnthony Gutierrez <anthony.gutierrez@amd.com>2019-01-22 02:12:11 +0000
commit7936e63336a736ca7d857e4fb7578895b249382e (patch)
treeadfa0a7e2087b1059c5d93b48fd71fa95a198d2b
parentbc74c58eaf55005a6a4b2e67657da4121554943c (diff)
downloadgem5-7936e63336a736ca7d857e4fb7578895b249382e.tar.xz
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>
-rw-r--r--src/arch/x86/linux/process.cc8
-rw-r--r--src/sim/syscall_emul.cc134
-rw-r--r--src/sim/syscall_emul.hh16
3 files changed, 154 insertions, 4 deletions
diff --git a/src/arch/x86/linux/process.cc b/src/arch/x86/linux/process.cc
index 03a88fc6e..2fe99e0be 100644
--- a/src/arch/x86/linux/process.cc
+++ b/src/arch/x86/linux/process.cc
@@ -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),
diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc
index 74ca1e924..25e0b6856 100644
--- a/src/sim/syscall_emul.cc
+++ b/src/sim/syscall_emul.cc
@@ -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;
+}
+
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index 67fa9e3d3..c52589f3a 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -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