Gabe Black has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/32254 )
Change subject: wip
......................................................................
wip
Change-Id: If79ce0733a7a61274a818e39ecb9cf383cc4e8ba
---
M src/arch/arm/aapcs32.hh
M src/arch/sparc/linux/syscalls.cc
M src/arch/x86/linux/process.cc
M src/kern/linux/events.hh
M src/sim/proxy_ptr.hh
M src/sim/syscall_emul.cc
M src/sim/syscall_emul.hh
7 files changed, 373 insertions(+), 357 deletions(-)
diff --git a/src/arch/arm/aapcs32.hh b/src/arch/arm/aapcs32.hh
index 01663ff..7f40bd3 100644
--- a/src/arch/arm/aapcs32.hh
+++ b/src/arch/arm/aapcs32.hh
@@ -37,6 +37,7 @@
#include "arch/arm/utility.hh"
#include "base/intmath.hh"
#include "cpu/thread_context.hh"
+#include "mem/port_proxy.hh"
#include "sim/guest_abi.hh"
#include "sim/proxy_ptr.hh"
diff --git a/src/arch/sparc/linux/syscalls.cc
b/src/arch/sparc/linux/syscalls.cc
index 304f2cf..32f6ef3 100644
--- a/src/arch/sparc/linux/syscalls.cc
+++ b/src/arch/sparc/linux/syscalls.cc
@@ -27,6 +27,7 @@
*/
#include "arch/sparc/linux/process.hh"
+#include "sim/proxy_ptr.hh"
#include "sim/syscall_desc.hh"
#include "sim/syscall_emul.hh"
@@ -53,28 +54,19 @@
SyscallReturn
getresuidFunc(SyscallDesc *desc, ThreadContext *tc,
- Addr ruid, Addr euid, Addr suid)
+ VPtr<uint64_t> ruid, VPtr<uint64_t> euid, VPtr<uint64_t>
suid)
{
const uint64_t id = htobe(100);
// Handle the EFAULT case
// Set the ruid
- if (ruid) {
- BufferArg ruidBuff(ruid, sizeof(uint64_t));
- memcpy(ruidBuff.bufferPtr(), &id, sizeof(uint64_t));
- ruidBuff.copyOut(tc->getVirtProxy());
- }
+ if (ruid)
+ *ruid = id;
// Set the euid
- if (euid) {
- BufferArg euidBuff(euid, sizeof(uint64_t));
- memcpy(euidBuff.bufferPtr(), &id, sizeof(uint64_t));
- euidBuff.copyOut(tc->getVirtProxy());
- }
+ if (euid)
+ *euid = id;
// Set the suid
- if (suid) {
- BufferArg suidBuff(suid, sizeof(uint64_t));
- memcpy(suidBuff.bufferPtr(), &id, sizeof(uint64_t));
- suidBuff.copyOut(tc->getVirtProxy());
- }
+ if (suid)
+ *suid = id;
return 0;
}
diff --git a/src/arch/x86/linux/process.cc b/src/arch/x86/linux/process.cc
index 9460a4b..97fb3e3 100644
--- a/src/arch/x86/linux/process.cc
+++ b/src/arch/x86/linux/process.cc
@@ -178,12 +178,8 @@
assert((maxTLSEntry + 1) * sizeof(uint64_t) <= x86p->gdtSize());
- TypedBufferArg<uint64_t>
- gdt(x86p->gdtStart() + minTLSEntry * sizeof(uint64_t),
- numTLSEntries * sizeof(uint64_t));
-
- if (!gdt.copyIn(tc->getVirtProxy()))
- panic("Failed to copy in GDT for %s.\n", desc->name());
+ VBuf<uint64_t> gdt(x86p->gdtStart() + minTLSEntry * sizeof(uint64_t),
+ numTLSEntries, tc);
if (userDesc->entry_number == (uint32_t)(-1)) {
// Find a free TLS entry.
@@ -234,9 +230,6 @@
gdt[index] = (uint64_t)segDesc;
- if (!gdt.copyOut(tc->getVirtProxy()))
- panic("Failed to copy out GDT for %s.\n", desc->name());
-
return 0;
}
diff --git a/src/kern/linux/events.hh b/src/kern/linux/events.hh
index c5a297b..2ca97a4 100644
--- a/src/kern/linux/events.hh
+++ b/src/kern/linux/events.hh
@@ -48,6 +48,7 @@
#include "debug/DebugPrintf.hh"
#include "kern/linux/printk.hh"
#include "kern/system_events.hh"
+#include "mem/se_translating_port_proxy.hh"
#include "sim/guest_abi.hh"
class ThreadContext;
diff --git a/src/sim/proxy_ptr.hh b/src/sim/proxy_ptr.hh
index a59bbff..0f481c1 100644
--- a/src/sim/proxy_ptr.hh
+++ b/src/sim/proxy_ptr.hh
@@ -85,6 +85,13 @@
}
void
+ discard()
+ {
+ markClean();
+ load();
+ }
+
+ void
load()
{
panic_if(isDirty(), "Overwriting dirty ProxyPtr.");
@@ -265,6 +272,13 @@
this->buffer->flush(force);
}
+ void
+ discard()
+ {
+ if (this->buffer)
+ this->buffer->discard();
+ }
+
template <typename A>
typename std::enable_if<std::is_integral<A>::value, PP>::type
operator + (A a) const
@@ -364,11 +378,158 @@
return os;
}
+template <typename T, typename Proxy>
+class ConstProxyBuf
+{
+ protected:
+ ProxyPtrBuffer<Proxy> buffer;
+
+ Addr _count;
+
+ void
+ boundsCheck(int i)
+ {
+ panic_if(i < 0 || i >= this->count(),
+ "Out of bounds access in ProxyBuf.");
+ }
+
+ public:
+ using Type = T;
+
+ Addr count() const { return _count; }
+ Addr addr() const { return buffer.addr(); }
+
+ template <typename ...Args,
+ typename std::enable_if<std::is_constructible<
+ Proxy, Args&&...>::value, int>::type = 0>
+ explicit ConstProxyBuf(Addr _ptr, Addr __count, Args&&... args) :
+ buffer(std::make_shared<Proxy>(args...), _ptr, sizeof(T) *
__count),
+ _count(__count)
+ {
+ panic_if(!_ptr, "ProxyBuf with zero address.");
+ }
+
+ const T &
+ operator [](int i) const
+ {
+ boundsCheck(i);
+ return *(&buffer.template asConst<T>() + i);
+ }
+
+ operator const T*() const
+ {
+ return &buffer.template asConst<T>();
+ }
+};
+
+template <typename Proxy>
+class ConstProxyBuf<void, Proxy> : public ConstProxyBuf<uint8_t, Proxy>
+{
+ public:
+ using ConstProxyBuf<uint8_t, Proxy>::ConstProxyBuf;
+
+ operator const void *() const
+ {
+ return &this->buffer.template asConst<uint8_t>();
+ }
+
+ template <typename T>
+ operator const T *() const
+ {
+ return &this->buffer.template asConst<T>();
+ }
+
+ const void *
+ operator + (Addr a) const
+ {
+ return &this->buffer.template asConst<uint8_t>() + a;
+ }
+};
+
+template <typename T, typename Proxy>
+class ProxyBuf : public ConstProxyBuf<T, Proxy>
+{
+ public:
+ void flush(bool force=false) { this->buffer.flush(force); }
+ void discard() { this->buffer.discard(); }
+
+ using CPB = ConstProxyBuf<T, Proxy>;
+ using CPB::ConstProxyBuf;
+
+ template <typename ...Args,
+ typename std::enable_if<std::is_constructible<
+ Proxy, Args&&...>::value, int>::type = 0>
+ explicit ProxyBuf(Addr _ptr, Addr __count, Args&&... args) :
+ CPB(_ptr, __count, args...)
+ {}
+
+ using CPB::operator [];
+ T &
+ operator [](int i)
+ {
+ this->boundsCheck(i);
+ return *(&this->buffer.template as<T>() + i);
+ }
+
+ using CPB::operator const T*;
+ operator T*()
+ {
+ return &this->buffer.template as<T>();
+ }
+};
+
+template <typename Proxy>
+class ProxyBuf<void, Proxy> : public ProxyBuf<uint8_t, Proxy>
+{
+ public:
+ using ProxyBuf<uint8_t, Proxy>::ProxyBuf;
+
+ operator void *()
+ {
+ return &this->buffer.template as<uint8_t>();
+ }
+
+ template <typename T,
+ typename std::enable_if<!std::is_void<T>::value, int>::type
= 0>
+ operator T *()
+ {
+ return &this->buffer.template as<T>();
+ }
+
+ void *
+ operator + (Addr a)
+ {
+ return &this->buffer.template as<uint8_t>() + a;
+ }
+
+ operator const void *() const
+ {
+ return &this->buffer.template asConst<uint8_t>();
+ }
+
+ template <typename T,
+ typename std::enable_if<!std::is_void<T>::value, int>::type
= 0>
+ operator const T *() const
+ {
+ return &this->buffer.template asConst<T>();
+ }
+
+ const void *
+ operator + (Addr a) const
+ {
+ return &this->buffer.template asConst<uint8_t>() + a;
+ }
+};
+
class SETranslatingPortProxy;
template <typename T>
using ConstVPtr = ConstProxyPtr<T, SETranslatingPortProxy>;
template <typename T>
using VPtr = ProxyPtr<T, SETranslatingPortProxy>;
+template <typename T=void>
+using ConstVBuf = ConstProxyBuf<T, SETranslatingPortProxy>;
+template <typename T=void>
+using VBuf = ProxyBuf<T, SETranslatingPortProxy>;
#endif // __SIM_PROXY_PTR_HH__
diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc
index b271a5f..6b229f7 100644
--- a/src/sim/syscall_emul.cc
+++ b/src/sim/syscall_emul.cc
@@ -92,17 +92,14 @@
}
static void
-exitFutexWake(ThreadContext *tc, Addr addr, uint64_t tgid)
+exitFutexWake(ThreadContext *tc, VPtr<long> ctid, uint64_t tgid)
{
// Clear value at address pointed to by thread's childClearTID field.
- BufferArg ctidBuf(addr, sizeof(long));
- long *ctid = (long *)ctidBuf.bufferPtr();
*ctid = 0;
- ctidBuf.copyOut(tc->getVirtProxy());
FutexMap &futex_map = tc->getSystemPtr()->futexMap;
// Wake one of the waiting threads.
- futex_map.wakeup(addr, tgid, 1);
+ futex_map.wakeup(ctid.addr(), tgid, 1);
}
static SyscallReturn
@@ -116,7 +113,7 @@
*p->exitGroup = true;
if (p->childClearTID)
- exitFutexWake(tc, p->childClearTID, p->tgid());
+ exitFutexWake(tc, VPtr<long>(p->childClearTID, tc), p->tgid());
bool last_thread = true;
Process *parent = nullptr, *tg_lead = nullptr;
@@ -303,7 +300,7 @@
SyscallReturn
_llseekFunc(SyscallDesc *desc, ThreadContext *tc,
int tgt_fd, uint64_t offset_high, uint32_t offset_low,
- Addr result_ptr, int whence)
+ VPtr<uint64_t> result_ptr, int whence)
{
auto p = tc->getProcessPtr();
@@ -320,9 +317,7 @@
if (result == (off_t)-1)
return -errno;
// Assuming that the size of loff_t is 64 bits on the target platform
- BufferArg result_buf(result_ptr, sizeof(result));
- memcpy(result_buf.bufferPtr(), &result, sizeof(result));
- result_buf.copyOut(tc->getVirtProxy());
+ *result_ptr = result;
return 0;
}
@@ -354,9 +349,8 @@
gethostnameFunc(SyscallDesc *desc, ThreadContext *tc,
Addr buf_ptr, int name_len)
{
- BufferArg name(buf_ptr, name_len);
- strncpy((char *)name.bufferPtr(), hostname, name_len);
- name.copyOut(tc->getVirtProxy());
+ VBuf<char> name(buf_ptr, name_len, tc);
+ strncpy(name, hostname, name_len);
return 0;
}
@@ -366,7 +360,7 @@
{
int result = 0;
auto p = tc->getProcessPtr();
- BufferArg buf(buf_ptr, size);
+ VBuf<char> buf(buf_ptr, size, tc);
// Is current working directory defined?
string cwd = p->tgtCwd;
@@ -375,18 +369,16 @@
// Buffer too small
return -ERANGE;
}
- strncpy((char *)buf.bufferPtr(), cwd.c_str(), size);
+ strncpy(buf, cwd.c_str(), size);
result = cwd.length();
} else {
- if (getcwd((char *)buf.bufferPtr(), size)) {
- result = strlen((char *)buf.bufferPtr());
+ if (getcwd(buf, size)) {
+ result = strlen(buf);
} else {
result = -1;
}
}
- buf.copyOut(tc->getVirtProxy());
-
return (result == -1) ? -errno : result;
}
@@ -403,11 +395,11 @@
// Adjust path for cwd and redirection
path = p->checkPathRedirect(path);
- BufferArg buf(buf_ptr, bufsiz);
+ VBuf<char> buf(buf_ptr, bufsiz, tc);
int result = -1;
if (path != "/proc/self/exe") {
- result = readlink(path.c_str(), (char *)buf.bufferPtr(), bufsiz);
+ result = readlink(path.c_str(), buf, bufsiz);
} else {
// Emulate readlink() called on '/proc/self/exe' should return the
// absolute path of the binary running in the simulated system (the
@@ -427,7 +419,7 @@
fatal("readlink('/proc/self/exe') unable to resolve path to "
"executable: %s", p->progName());
}
- strncpy((char*)buf.bufferPtr(), real_path, bufsiz);
+ strncpy(buf, real_path, bufsiz);
size_t real_path_len = strlen(real_path);
if (real_path_len > bufsiz) {
// readlink will truncate the contents of the
@@ -439,12 +431,9 @@
// Issue a warning about potential unexpected results
warn_once("readlink() called on '/proc/self/exe' may yield
unexpected "
- "results in various settings.\n Returning '%s'\n",
- (char*)buf.bufferPtr());
+ "results in various settings.\n Returning '%s'\n",
buf);
}
- buf.copyOut(tc->getVirtProxy());
-
return (result == -1) ? -errno : result;
}
@@ -837,11 +826,9 @@
* Copy the target file descriptors into buffer space and then copy
* the buffer space back into the target address space.
*/
- BufferArg tgt_handle(tgt_addr, sizeof(int[2]));
- int *buf_ptr = (int*)tgt_handle.bufferPtr();
- buf_ptr[0] = tgt_fds[0];
- buf_ptr[1] = tgt_fds[1];
- tgt_handle.copyOut(tc->getVirtProxy());
+ VBuf<int> tgt_handle(tgt_addr, 2, tc);
+ tgt_handle[0] = tgt_fds[0];
+ tgt_handle[1] = tgt_fds[1];
if (flags) {
// pipe2 only uses O_NONBLOCK, O_CLOEXEC, and (O_NONBLOCK |
O_CLOEXEC)
@@ -1080,15 +1067,15 @@
return -EBADF;
int sim_fd = hbfdp->getSimFD();
- BufferArg buf_arg(buf_ptr, count);
- auto status = syscall(SYS_NUM, sim_fd, buf_arg.bufferPtr(), count);
+ VBuf<> buf_arg(buf_ptr, count, tc);
+ auto status = syscall(SYS_NUM, sim_fd, (void *)buf_arg, count);
if (status == -1)
return -errno;
unsigned traversed = 0;
while (traversed < status) {
- DE *buffer = (DE*)((Addr)buf_arg.bufferPtr() + traversed);
+ DE *buffer = (DE *)(buf_arg + traversed);
auto host_reclen = buffer->d_reclen;
@@ -1105,7 +1092,6 @@
traversed += host_reclen;
}
- buf_arg.copyOut(tc->getVirtProxy());
return status;
}
#endif
@@ -1165,17 +1151,14 @@
{
auto p = tc->getProcessPtr();
- BufferArg bufSock(buf_ptr, addrlen);
- bufSock.copyIn(tc->getVirtProxy());
+ ConstVBuf<> bufSock(buf_ptr, addrlen, tc);
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);
+ int status = ::bind(sim_fd, bufSock, addrlen);
return (status == -1) ? -errno : status;
}
@@ -1201,17 +1184,14 @@
{
auto p = tc->getProcessPtr();
- BufferArg addr(buf_ptr, addrlen);
- addr.copyIn(tc->getVirtProxy());
+ ConstVBuf<> addr(buf_ptr, addrlen, tc);
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);
+ int status = connect(sim_fd, addr, (socklen_t)addrlen);
return (status == -1) ? -errno : status;
}
@@ -1219,7 +1199,7 @@
SyscallReturn
recvfromFunc(SyscallDesc *desc, ThreadContext *tc,
int tgt_fd, Addr bufrPtr, size_t bufrLen, int flags,
- Addr addrPtr, Addr addrlenPtr)
+ Addr addrPtr, VPtr<socklen_t> addrlenPtr)
{
auto p = tc->getProcessPtr();
@@ -1229,49 +1209,39 @@
int sim_fd = sfdp->getSimFD();
// Reserve buffer space.
- BufferArg bufrBuf(bufrPtr, bufrLen);
+ VBuf<> bufrBuf(bufrPtr, bufrLen, tc);
// Get address length.
- socklen_t addrLen = 0;
- if (addrlenPtr != 0) {
- // Read address length parameter.
- BufferArg addrlenBuf(addrlenPtr, sizeof(socklen_t));
- addrlenBuf.copyIn(tc->getVirtProxy());
- addrLen = *((socklen_t *)addrlenBuf.bufferPtr());
- }
+ socklen_t addrLen = addrlenPtr ? *addrlenPtr : 0;
- struct sockaddr sa, *sap = NULL;
- if (addrLen != 0) {
- BufferArg addrBuf(addrPtr, addrLen);
- addrBuf.copyIn(tc->getVirtProxy());
- memcpy(&sa, (struct sockaddr *)addrBuf.bufferPtr(),
- sizeof(struct sockaddr));
+ struct sockaddr sa;
+ struct sockaddr *sap = nullptr;
+ if (addrPtr) {
+ VBuf<> addrBuf(addrPtr, addrLen, tc);
+ memcpy(&sa, addrBuf,
+ std::min<size_t>(sizeof(struct sockaddr), addrLen));
sap = &sa;
}
- ssize_t recvd_size = recvfrom(sim_fd,
- (void *)bufrBuf.bufferPtr(),
- bufrLen, flags, sap, (socklen_t
*)&addrLen);
+ ssize_t recvd_size = recvfrom(sim_fd, bufrBuf, bufrLen,
+ flags, sap, &addrLen);
- if (recvd_size == -1)
+ if (recvd_size == -1) {
+ addrlenPtr.discard();
+ bufrBuf.discard();
return -errno;
-
- // Pass the received data out.
- bufrBuf.copyOut(tc->getVirtProxy());
+ }
// Copy address to addrPtr and pass it on.
- if (sap != NULL) {
- BufferArg addrBuf(addrPtr, addrLen);
- memcpy(addrBuf.bufferPtr(), sap, sizeof(sa));
- addrBuf.copyOut(tc->getVirtProxy());
+ if (sap) {
+ VBuf<> addrBuf(addrPtr, addrLen, tc);
+ memcpy(addrBuf, sap,
+ std::min<size_t>(sizeof(struct sockaddr), addrLen));
}
// Copy len to addrlenPtr and pass it on.
- if (addrLen != 0) {
- BufferArg addrlenBuf(addrlenPtr, sizeof(socklen_t));
- *(socklen_t *)addrlenBuf.bufferPtr() = addrLen;
- addrlenBuf.copyOut(tc->getVirtProxy());
- }
+ if (addrlenPtr)
+ *addrlenPtr = addrLen;
return recvd_size;
}
@@ -1289,28 +1259,25 @@
int sim_fd = sfdp->getSimFD();
// Reserve buffer space.
- BufferArg bufrBuf(bufrPtr, bufrLen);
- bufrBuf.copyIn(tc->getVirtProxy());
+ VBuf<> bufrBuf(bufrPtr, bufrLen, tc);
struct sockaddr sa, *sap = nullptr;
memset(&sa, 0, sizeof(sockaddr));
- if (addrLen != 0) {
- BufferArg addrBuf(addrPtr, addrLen);
- addrBuf.copyIn(tc->getVirtProxy());
- memcpy(&sa, (sockaddr*)addrBuf.bufferPtr(), addrLen);
+ if (addrPtr) {
+ VBuf<> addrBuf(addrPtr, addrLen, tc);
+ memcpy(&sa, addrBuf, addrLen);
sap = &sa;
}
- ssize_t sent_size = sendto(sim_fd,
- (void *)bufrBuf.bufferPtr(),
- bufrLen, flags, sap, (socklen_t)addrLen);
+ ssize_t sent_size = sendto(sim_fd, bufrBuf, bufrLen,
+ flags, sap, (socklen_t)addrLen);
return (sent_size == -1) ? -errno : sent_size;
}
SyscallReturn
recvmsgFunc(SyscallDesc *desc, ThreadContext *tc,
- int tgt_fd, Addr msgPtr, int flags)
+ int tgt_fd, VPtr<struct msghdr> msgHdr, int flags)
{
auto p = tc->getProcessPtr();
@@ -1337,118 +1304,93 @@
* };
*/
- /**
- * The plan with this system call is to replace all of the pointers in
the
- * structure and the substructure with BufferArg class pointers. We
will
- * copy every field from the structures into our BufferArg classes.
+ /*
+ * Create a local version of msg_name and point the header at it.
*/
- BufferArg msgBuf(msgPtr, sizeof(struct msghdr));
- msgBuf.copyIn(tc->getVirtProxy());
- struct msghdr *msgHdr = (struct msghdr *)msgBuf.bufferPtr();
-
- /**
- * We will use these address place holders to retain the pointers which
- * we are going to replace with our own buffers in our simulator
address
- * space.
- */
- Addr msg_name_phold = 0;
- Addr msg_iov_phold = 0;
- Addr iovec_base_phold[msgHdr->msg_iovlen];
- Addr msg_control_phold = 0;
-
- /**
- * Record msg_name pointer then replace with buffer pointer.
- */
- BufferArg *nameBuf = NULL;
+ std::unique_ptr<VBuf<>> nameBuf;
if (msgHdr->msg_name) {
- /*1*/msg_name_phold = (Addr)msgHdr->msg_name;
- /*2*/nameBuf = new BufferArg(msg_name_phold, msgHdr->msg_namelen);
- /*3*/nameBuf->copyIn(tc->getVirtProxy());
- /*4*/msgHdr->msg_name = nameBuf->bufferPtr();
+ nameBuf.reset(new VBuf<>(
+ (Addr)msgHdr->msg_name, msgHdr->msg_namelen, tc));
+ msgHdr->msg_name = *nameBuf;
}
- /**
- * Record msg_iov pointer then replace with buffer pointer. Also, setup
- * an array of buffer pointers for the iovec structs record and replace
- * their pointers with buffer pointers.
+ /*
+ * Create local versions of msg_iov and the buffers it points to, and
+ * record them in the header.
*/
- BufferArg *iovBuf = NULL;
- BufferArg *iovecBuf[msgHdr->msg_iovlen];
- for (int i = 0; i < msgHdr->msg_iovlen; i++) {
- iovec_base_phold[i] = 0;
- iovecBuf[i] = NULL;
- }
+ std::vector<std::unique_ptr<VBuf<>>> iovecs;
+ std::unique_ptr<VBuf<struct iovec>> iov;
if (msgHdr->msg_iov) {
- /*1*/msg_iov_phold = (Addr)msgHdr->msg_iov;
- /*2*/iovBuf = new BufferArg(msg_iov_phold, msgHdr->msg_iovlen *
- sizeof(struct iovec));
- /*3*/iovBuf->copyIn(tc->getVirtProxy());
- for (int i = 0; i < msgHdr->msg_iovlen; i++) {
- if (((struct iovec *)iovBuf->bufferPtr())[i].iov_base) {
- /*1*/iovec_base_phold[i] =
- (Addr)((struct iovec
*)iovBuf->bufferPtr())[i].iov_base;
- /*2*/iovecBuf[i] = new BufferArg(iovec_base_phold[i],
- ((struct iovec *)iovBuf->bufferPtr())[i].iov_len);
- /*3*/iovecBuf[i]->copyIn(tc->getVirtProxy());
- /*4*/((struct iovec *)iovBuf->bufferPtr())[i].iov_base =
- iovecBuf[i]->bufferPtr();
+ // Get the guest msg_iov array.
+ iov.reset(new VBuf<struct iovec>(
+ (Addr)msgHdr->msg_iov, msgHdr->msg_iovlen, tc));
+
+ // For each element in the array...
+ for (int i = 0; i < iov->count(); i++) {
+ auto vec = (*iov)[i];
+ // If it points to anything...
+ if (vec.iov_base) {
+ // Create a local version of it.
+ iovecs[i].reset(
+ new VBuf<>((Addr)vec.iov_base, vec.iov_len, tc));
+ vec.iov_base = *iovecs[i];
}
}
- /*4*/msgHdr->msg_iov = (struct iovec *)iovBuf->bufferPtr();
+ // Install the host version of msg_iov in msgHdr.
+ msgHdr->msg_iov = *iov;
}
- /**
- * Record msg_control pointer then replace with buffer pointer.
+ /*
+ * Create a local version of msg_control and point the header at it.
*/
- BufferArg *controlBuf = NULL;
+ std::unique_ptr<VBuf<>> controlBuf;
if (msgHdr->msg_control) {
- /*1*/msg_control_phold = (Addr)msgHdr->msg_control;
- /*2*/controlBuf = new BufferArg(msg_control_phold,
-
CMSG_ALIGN(msgHdr->msg_controllen));
- /*3*/controlBuf->copyIn(tc->getVirtProxy());
- /*4*/msgHdr->msg_control = controlBuf->bufferPtr();
+ controlBuf.reset(new VBuf<>((Addr)msgHdr->msg_control,
+ CMSG_ALIGN(msgHdr->msg_controllen),
tc));
+ msgHdr->msg_control = *controlBuf;
}
ssize_t recvd_size = recvmsg(sim_fd, msgHdr, flags);
- if (recvd_size < 0)
+ if (recvd_size < 0) {
+ // If something bad happened, throw away all our modifications.
+ msgHdr.discard();
+ if (iov)
+ iov->discard();
+ if (nameBuf)
+ nameBuf->discard();
+ for (auto &iovec: iovecs)
+ if (iovec)
+ iovec->discard();
+ if (controlBuf)
+ controlBuf->discard();
return -errno;
-
- if (msgHdr->msg_name) {
- nameBuf->copyOut(tc->getVirtProxy());
- delete(nameBuf);
- msgHdr->msg_name = (void *)msg_name_phold;
}
- if (msgHdr->msg_iov) {
- for (int i = 0; i< msgHdr->msg_iovlen; i++) {
- if (((struct iovec *)iovBuf->bufferPtr())[i].iov_base) {
- iovecBuf[i]->copyOut(tc->getVirtProxy());
- delete iovecBuf[i];
- ((struct iovec *)iovBuf->bufferPtr())[i].iov_base =
- (void *)iovec_base_phold[i];
- }
- }
- iovBuf->copyOut(tc->getVirtProxy());
- delete iovBuf;
- msgHdr->msg_iov = (struct iovec *)msg_iov_phold;
+ /*
+ * Point the msgHdr back to the guest versions of things. The data
+ * buffers will write themselves back out.
+ */
+ if (controlBuf)
+ msgHdr->msg_control = (void *)controlBuf->addr();
+
+ if (iov) {
+ msgHdr->msg_iov = (struct iovec *)iov->addr();
+ for (int i = 0; i < iovecs.size(); i++)
+ if (iovecs[i])
+ (*iov)[i].iov_base = (void *)iovecs[i]->addr();
}
- if (msgHdr->msg_control) {
- controlBuf->copyOut(tc->getVirtProxy());
- delete(controlBuf);
- msgHdr->msg_control = (void *)msg_control_phold;
- }
-
- msgBuf.copyOut(tc->getVirtProxy());
+ if (nameBuf)
+ msgHdr->msg_name = (void *)nameBuf->addr();
return recvd_size;
}
SyscallReturn
sendmsgFunc(SyscallDesc *desc, ThreadContext *tc,
- int tgt_fd, Addr msgPtr, int flags)
+ int tgt_fd, VPtr<struct msghdr> msgHdr, int flags)
{
auto p = tc->getProcessPtr();
@@ -1458,57 +1400,46 @@
int sim_fd = sfdp->getSimFD();
/**
- * Reserve buffer space.
- */
- BufferArg msgBuf(msgPtr, sizeof(struct msghdr));
- msgBuf.copyIn(tc->getVirtProxy());
- struct msghdr msgHdr = *((struct msghdr *)msgBuf.bufferPtr());
-
- /**
* Assuming msgHdr.msg_iovlen >= 1, then there is no point calling
* recvmsg without a buffer.
*/
- struct iovec *iovPtr = msgHdr.msg_iov;
- BufferArg iovBuf((Addr)iovPtr, sizeof(struct iovec) *
msgHdr.msg_iovlen);
+ BufferArg iovBuf((Addr)msgHdr->msg_iov,
+ sizeof(struct iovec) * msgHdr->msg_iovlen);
iovBuf.copyIn(tc->getVirtProxy());
- struct iovec *iov = (struct iovec *)iovBuf.bufferPtr();
- msgHdr.msg_iov = iov;
+ struct iovec *iovs = (struct iovec *)iovBuf.bufferPtr();
+ msgHdr->msg_iov = iovs;
/**
* Cannot instantiate buffers till inside the loop.
* Create array to hold buffer addresses, to be used during copyIn of
* send data.
*/
- BufferArg **bufferArray = (BufferArg **)malloc(msgHdr.msg_iovlen
- * sizeof(BufferArg *));
+ std::vector<BufferArg *> bufferArray(msgHdr->msg_iovlen);
/**
* Iterate through the iovec structures:
* Get the base buffer addreses, reserve iov_len amount of space for
each.
* Put the buf address into the bufferArray for later retrieval.
*/
- for (int iovIndex = 0 ; iovIndex < msgHdr.msg_iovlen; iovIndex++) {
- Addr basePtr = (Addr) iov[iovIndex].iov_base;
- bufferArray[iovIndex] = new BufferArg(basePtr,
iov[iovIndex].iov_len);
- bufferArray[iovIndex]->copyIn(tc->getVirtProxy());
- iov[iovIndex].iov_base = bufferArray[iovIndex]->bufferPtr();
+ for (int idx = 0; idx < msgHdr->msg_iovlen; idx++) {
+ auto &buf = bufferArray[idx];
+ auto &iov = iovs[idx];
+ Addr basePtr = (Addr)iov.iov_base;
+ buf = new BufferArg(basePtr, iov.iov_len);
+ buf->copyIn(tc->getVirtProxy());
+ iov.iov_base = buf->bufferPtr();
}
- ssize_t sent_size = sendmsg(sim_fd, &msgHdr, flags);
+ ssize_t sent_size = sendmsg(sim_fd, msgHdr, flags);
int local_errno = errno;
/**
* Free dynamically allocated memory.
*/
- for (int iovIndex = 0 ; iovIndex < msgHdr.msg_iovlen; iovIndex++) {
- BufferArg *baseBuf = ( BufferArg *)bufferArray[iovIndex];
- delete(baseBuf);
- }
+ for (auto &ptr: bufferArray)
+ delete ptr;
- /**
- * Malloced above.
- */
- free(bufferArray);
+ msgHdr.discard();
return (sent_size < 0) ? -local_errno : sent_size;
}
@@ -1639,8 +1570,6 @@
getcpuFunc(SyscallDesc *desc, ThreadContext *tc,
VPtr<uint32_t> cpu, VPtr<uint32_t> node, VPtr<uint32_t> tcache)
{
- bool error = false;
-
// unsigned is the same size (4) on all Linux supported ISAs.
if (cpu)
*cpu = htog(tc->contextId(),
tc->getSystemPtr()->getGuestByteOrder());
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index 31c1d4c..27d8278 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -163,7 +163,8 @@
/// Target _llseek() handler.
SyscallReturn _llseekFunc(SyscallDesc *desc, ThreadContext *tc,
int tgt_fd, uint64_t offset_high,
- uint32_t offset_low, Addr result_ptr, int
whence);
+ uint32_t offset_low, VPtr<uint64_t> result_ptr,
+ int whence);
/// Target munmap() handler.
SyscallReturn munmapFunc(SyscallDesc *desc, ThreadContext *tc, Addr start,
@@ -316,15 +317,16 @@
// Target recvfrom() handler.
SyscallReturn recvfromFunc(SyscallDesc *desc, ThreadContext *tc,
int tgt_fd, Addr bufrPtr, size_t bufrLen,
- int flags, Addr addrPtr, Addr addrlenPtr);
+ int flags, Addr addrPtr,
+ VPtr<socklen_t> addrlenPtr);
// Target recvmsg() handler.
SyscallReturn recvmsgFunc(SyscallDesc *desc, ThreadContext *tc,
- int tgt_fd, Addr msgPtr, int flags);
+ int tgt_fd, VPtr<struct msghdr> msgHdr, int
flags);
// Target sendmsg() handler.
SyscallReturn sendmsgFunc(SyscallDesc *desc, ThreadContext *tc,
- int tgt_fd, Addr msgPtr, int flags);
+ int tgt_fd, VPtr<struct msghdr> msgHdr, int
flags);
// Target getuid() handler.
SyscallReturn getuidFunc(SyscallDesc *desc, ThreadContext *tc);
@@ -356,7 +358,8 @@
Addr valPtr, socklen_t len);
SyscallReturn getcpuFunc(SyscallDesc *desc, ThreadContext *tc,
- Addr cpu_ptr, Addr node_ptr, Addr tcache_ptr);
+ VPtr<uint32_t> cpu, VPtr<uint32_t> node,
+ VPtr<uint32_t> tcache);
// Target getsockname() handler.
SyscallReturn getsocknameFunc(SyscallDesc *desc, ThreadContext *tc,
@@ -385,16 +388,14 @@
if (OS::TGT_FUTEX_WAIT == op || OS::TGT_FUTEX_WAIT_BITSET == op) {
// Ensure futex system call accessed atomically.
- BufferArg buf(uaddr, sizeof(int));
- buf.copyIn(tc->getVirtProxy());
- int mem_val = *(int*)buf.bufferPtr();
+ VPtr<int> buf(uaddr, tc);
/*
* The value in memory at uaddr is not equal with the expected val
* (a different thread must have changed it before the system call
was
* invoked). In this case, we need to throw an error.
*/
- if (val != mem_val)
+ if (val != *buf)
return -OS::TGT_EWOULDBLOCK;
if (OS::TGT_FUTEX_WAIT == op) {
@@ -412,14 +413,12 @@
OS::TGT_FUTEX_CMP_REQUEUE == op) {
// Ensure futex system call accessed atomically.
- BufferArg buf(uaddr, sizeof(int));
- buf.copyIn(tc->getVirtProxy());
- int mem_val = *(int*)buf.bufferPtr();
+ VPtr<int> buf(uaddr, tc);
/*
* For CMP_REQUEUE, the whole operation is only started only if
* val3 is still the value of the futex pointed to by uaddr.
*/
- if (OS::TGT_FUTEX_CMP_REQUEUE && val3 != mem_val)
+ if (OS::TGT_FUTEX_CMP_REQUEUE && val3 != *buf)
return -OS::TGT_EWOULDBLOCK;
return futex_map.requeue(uaddr, process->tgid(), val, timeout,
uaddr2);
} else if (OS::TGT_FUTEX_WAKE_OP == op) {
@@ -445,9 +444,8 @@
*
*/
// get value from simulated-space
- BufferArg buf(uaddr2, sizeof(int));
- buf.copyIn(tc->getVirtProxy());
- int oldval = *(int*)buf.bufferPtr();
+ VPtr<int> buf(uaddr2, tc);
+ int oldval = *buf;
int newval = oldval;
// extract op, oparg, cmp, cmparg from val3
int wake_cmparg = val3 & 0xfff;
@@ -469,8 +467,7 @@
else if (wake_op == OS::TGT_FUTEX_OP_XOR)
newval ^= wake_oparg;
// copy updated value back to simulated-space
- *(int*)buf.bufferPtr() = newval;
- buf.copyOut(tc->getVirtProxy());
+ *buf = newval;
// perform the first wake-up
int woken1 = futex_map.wakeup(uaddr, process->tgid(), val);
int woken2 = 0;
@@ -694,22 +691,18 @@
switch (req) {
case SIOCGIFCONF: {
- BufferArg conf_arg(addr, sizeof(ifconf));
- conf_arg.copyIn(tc->getVirtProxy());
+ VPtr<ifconf> conf(addr, tc);
- ifconf *conf = (ifconf*)conf_arg.bufferPtr();
Addr ifc_buf_addr = (Addr)conf->ifc_buf;
- BufferArg ifc_buf_arg(ifc_buf_addr, conf->ifc_len);
- ifc_buf_arg.copyIn(tc->getVirtProxy());
+ VBuf<char> ifc_buf_arg(ifc_buf_addr, conf->ifc_len, tc);
- conf->ifc_buf = (char*)ifc_buf_arg.bufferPtr();
+ conf->ifc_buf = (char *)ifc_buf_arg;
- status = ioctl(sfdp->getSimFD(), req, conf_arg.bufferPtr());
- if (status != -1) {
- conf->ifc_buf = (char*)ifc_buf_addr;
- ifc_buf_arg.copyOut(tc->getVirtProxy());
- conf_arg.copyOut(tc->getVirtProxy());
- }
+ status = ioctl(sfdp->getSimFD(), req, conf);
+ if (status != -1)
+ conf->ifc_buf = (char *)ifc_buf_addr;
+ else
+ conf.discard();
return status;
}
@@ -723,12 +716,11 @@
case SIOCGIFHWADDR:
#endif
case SIOCGIFMTU: {
- BufferArg req_arg(addr, sizeof(ifreq));
- req_arg.copyIn(tc->getVirtProxy());
+ VPtr<ifreq> arg(addr, tc);
- status = ioctl(sfdp->getSimFD(), req, req_arg.bufferPtr());
- if (status != -1)
- req_arg.copyOut(tc->getVirtProxy());
+ status = ioctl(sfdp->getSimFD(), req, arg);
+ if (status == -1)
+ arg.discard();
return status;
}
}
@@ -999,8 +991,7 @@
{
auto p = tc->getProcessPtr();
- BufferArg fdsBuf(fdsPtr, sizeof(struct pollfd) * nfds);
- fdsBuf.copyIn(tc->getVirtProxy());
+ VBuf<struct pollfd> fdsBuf(fdsPtr, nfds, tc);
/**
* Record the target file descriptors in a local variable. We need to
@@ -1010,13 +1001,13 @@
*/
int temp_tgt_fds[nfds];
for (int index = 0; index < nfds; index++) {
- temp_tgt_fds[index] = ((struct pollfd
*)fdsBuf.bufferPtr())[index].fd;
+ temp_tgt_fds[index] = fdsBuf[index].fd;
auto tgt_fd = temp_tgt_fds[index];
auto hbfdp =
std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
if (!hbfdp)
return -EBADF;
auto host_fd = hbfdp->getSimFD();
- ((struct pollfd *)fdsBuf.bufferPtr())[index].fd = host_fd;
+ fdsBuf[index].fd = host_fd;
}
/**
@@ -1027,7 +1018,7 @@
*/
int status;
if (tmout < 0) {
- status = poll((struct pollfd *)fdsBuf.bufferPtr(), nfds, 0);
+ status = poll(fdsBuf, nfds, 0);
if (status == 0) {
/**
* If blocking indefinitely, check the signal list to see if a
@@ -1042,7 +1033,7 @@
return SyscallReturn::retry();
}
} else
- status = poll((struct pollfd *)fdsBuf.bufferPtr(), nfds, 0);
+ status = poll(fdsBuf, nfds, 0);
if (status == -1)
return -errno;
@@ -1053,15 +1044,9 @@
*/
for (int index = 0; index < nfds; index++) {
auto tgt_fd = temp_tgt_fds[index];
- ((struct pollfd *)fdsBuf.bufferPtr())[index].fd = tgt_fd;
+ fdsBuf[index].fd = tgt_fd;
}
- /**
- * Copy out the pollfd struct because the host may have updated fields
- * in the structure.
- */
- fdsBuf.copyOut(tc->getVirtProxy());
-
return status;
}
@@ -1406,7 +1391,7 @@
template <class OS>
SyscallReturn
cloneFunc(SyscallDesc *desc, ThreadContext *tc, RegVal flags, RegVal
newStack,
- Addr ptidPtr, Addr ctidPtr, Addr tlsPtr)
+ VPtr<long> ptid, VPtr<long> ctid, Addr tlsPtr)
{
auto p = tc->getProcessPtr();
@@ -1467,12 +1452,8 @@
cp->assignThreadContext(ctc->contextId());
owner->revokeThreadContext(ctc->contextId());
- if (flags & OS::TGT_CLONE_PARENT_SETTID) {
- BufferArg ptidBuf(ptidPtr, sizeof(long));
- long *ptid = (long *)ptidBuf.bufferPtr();
+ if (flags & OS::TGT_CLONE_PARENT_SETTID)
*ptid = cp->pid();
- ptidBuf.copyOut(tc->getVirtProxy());
- }
if (flags & OS::TGT_CLONE_THREAD) {
cp->pTable->shared = true;
@@ -1488,15 +1469,11 @@
*cp->sigchld = true;
}
- if (flags & OS::TGT_CLONE_CHILD_SETTID) {
- BufferArg ctidBuf(ctidPtr, sizeof(long));
- long *ctid = (long *)ctidBuf.bufferPtr();
+ if (flags & OS::TGT_CLONE_CHILD_SETTID)
*ctid = cp->pid();
- ctidBuf.copyOut(ctc->getVirtProxy());
- }
if (flags & OS::TGT_CLONE_CHILD_CLEARTID)
- cp->childClearTID = (uint64_t)ctidPtr;
+ cp->childClearTID = *ctid;
ctc->clearArchRegs();
@@ -1521,9 +1498,10 @@
template <class OS>
SyscallReturn
cloneBackwardsFunc(SyscallDesc *desc, ThreadContext *tc, RegVal flags,
- RegVal newStack, Addr ptidPtr, Addr tlsPtr, Addr
ctidPtr)
+ RegVal newStack, VPtr<long> ptid,
+ Addr tlsPtr, VPtr<long> ctid)
{
- return cloneFunc<OS>(desc, tc, flags, newStack, ptidPtr, ctidPtr,
tlsPtr);
+ return cloneFunc<OS>(desc, tc, flags, newStack, ptid, ctid, tlsPtr);
}
/// Target fstatfs() handler.
@@ -1776,11 +1754,9 @@
return -EBADF;
int sim_fd = ffdp->getSimFD();
- BufferArg bufArg(bufPtr, nbytes);
+ VBuf<> bufArg(bufPtr, nbytes, tc);
- int bytes_read = pread(sim_fd, bufArg.bufferPtr(), nbytes, offset);
-
- bufArg.copyOut(tc->getVirtProxy());
+ int bytes_read = pread(sim_fd, bufArg, nbytes, offset);
return (bytes_read == -1) ? -errno : bytes_read;
}
@@ -1797,10 +1773,9 @@
return -EBADF;
int sim_fd = ffdp->getSimFD();
- BufferArg bufArg(bufPtr, nbytes);
- bufArg.copyIn(tc->getVirtProxy());
+ VBuf<> bufArg(bufPtr, nbytes, tc);
- int bytes_written = pwrite(sim_fd, bufArg.bufferPtr(), nbytes, offset);
+ int bytes_written = pwrite(sim_fd, bufArg, nbytes, offset);
return (bytes_written == -1) ? -errno : bytes_written;
}
@@ -1967,25 +1942,21 @@
auto p = tc->getProcessPtr();
std::string path;
- PortProxy & mem_proxy = tc->getVirtProxy();
+ PortProxy &mem_proxy = tc->getVirtProxy();
if (!mem_proxy.tryReadString(path, pathname))
return -EFAULT;
if (access(path.c_str(), F_OK) == -1)
return -EACCES;
- auto read_in = [](std::vector<std::string> &vect,
- PortProxy &mem_proxy, Addr mem_loc)
+ auto read_in = [mem_proxy, tc](
+ std::vector<std::string> &vect, Addr mem_loc)
{
- for (int inc = 0; ; inc++) {
- BufferArg b((mem_loc + sizeof(Addr) * inc), sizeof(Addr));
- b.copyIn(mem_proxy);
-
- if (!*(Addr*)b.bufferPtr())
- break;
-
- vect.push_back(std::string());
- mem_proxy.tryReadString(vect[inc], *(Addr*)b.bufferPtr());
+ // This shouldn't assume all pointers are the size of Addr.
+ for (ConstVPtr<Addr> b(mem_loc, tc); *b; b = b + 1) {
+ std::string str;
+ mem_proxy.tryReadString(str, *b);
+ vect.push_back(str);
}
};
@@ -1997,8 +1968,8 @@
*/
ProcessParams *pp = new ProcessParams();
pp->executable = path;
- read_in(pp->cmd, mem_proxy, argv_mem_loc);
- read_in(pp->env, mem_proxy, envp_mem_loc);
+ read_in(pp->cmd, argv_mem_loc);
+ read_in(pp->env, envp_mem_loc);
pp->uid = p->uid();
pp->egid = p->egid();
pp->euid = p->euid();
@@ -2199,18 +2170,17 @@
{
auto p = tc->getProcessPtr();
- BufferArg svBuf((Addr)svPtr, 2 * sizeof(int));
- int status = socketpair(domain, type, prot, (int *)svBuf.bufferPtr());
- if (status == -1)
+ VBuf<int> fds(svPtr, 2, tc);
+ int status = socketpair(domain, type, prot, fds);
+ if (status == -1) {
+ fds.discard();
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->getVirtProxy());
return status;
}
@@ -2401,11 +2371,11 @@
&& !(hbfdp->getFlags() & OS::TGT_O_NONBLOCK))
return SyscallReturn::retry();
- BufferArg buf_arg(buf_ptr, nbytes);
- int bytes_read = read(sim_fd, buf_arg.bufferPtr(), nbytes);
+ VBuf<> buf_arg(buf_ptr, nbytes, tc);
+ int bytes_read = read(sim_fd, buf_arg, nbytes);
- if (bytes_read > 0)
- buf_arg.copyOut(tc->getVirtProxy());
+ if (bytes_read <= 0)
+ buf_arg.discard();
return (bytes_read == -1) ? -errno : bytes_read;
}
@@ -2422,8 +2392,7 @@
return -EBADF;
int sim_fd = hbfdp->getSimFD();
- BufferArg buf_arg(buf_ptr, nbytes);
- buf_arg.copyIn(tc->getVirtProxy());
+ VBuf<> buf_arg(buf_ptr, nbytes, tc);
struct pollfd pfd;
pfd.fd = sim_fd;
@@ -2441,7 +2410,7 @@
return SyscallReturn::retry();
}
- int bytes_written = write(sim_fd, buf_arg.bufferPtr(), nbytes);
+ int bytes_written = write(sim_fd, buf_arg, nbytes);
if (bytes_written != -1)
fsync(sim_fd);
@@ -2452,7 +2421,7 @@
template <class OS>
SyscallReturn
wait4Func(SyscallDesc *desc, ThreadContext *tc,
- pid_t pid, Addr statPtr, int options, Addr rusagePtr)
+ pid_t pid, VPtr<int> status, int options, Addr rusagePtr)
{
auto p = tc->getProcessPtr();
@@ -2497,9 +2466,7 @@
success:
// Set status to EXITED for WIFEXITED evaluations.
const int EXITED = 0;
- BufferArg statusBuf(statPtr, sizeof(int));
- *(int *)statusBuf.bufferPtr() = EXITED;
- statusBuf.copyOut(tc->getVirtProxy());
+ *status = EXITED;
// Return the child PID.
pid_t retval = iter->sender->pid();
@@ -2510,16 +2477,11 @@
template <class OS>
SyscallReturn
acceptFunc(SyscallDesc *desc, ThreadContext *tc,
- int tgt_fd, Addr addrPtr, Addr lenPtr)
+ int tgt_fd, VPtr<struct sockaddr> addrPtr, VPtr<socklen_t>
lenPtr)
{
- struct sockaddr sa;
- socklen_t addrLen;
int host_fd;
auto p = tc->getProcessPtr();
- BufferArg *lenBufPtr = nullptr;
- BufferArg *addrBufPtr = nullptr;
-
auto sfdp =
std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
if (!sfdp)
return -EBADF;
@@ -2537,35 +2499,12 @@
if ((poll(&pfd, 1, 0) == 0) && !(sfdp->getFlags() &
OS::TGT_O_NONBLOCK))
return SyscallReturn::retry();
- if (lenPtr) {
- lenBufPtr = new BufferArg(lenPtr, sizeof(socklen_t));
- lenBufPtr->copyIn(tc->getVirtProxy());
- memcpy(&addrLen, (socklen_t *)lenBufPtr->bufferPtr(),
- sizeof(socklen_t));
- }
+ host_fd = accept(sim_fd, addrPtr, lenPtr);
- if (addrPtr) {
- addrBufPtr = new BufferArg(addrPtr, sizeof(struct sockaddr));
- addrBufPtr->copyIn(tc->getVirtProxy());
- memcpy(&sa, (struct sockaddr *)addrBufPtr->bufferPtr(),
- sizeof(struct sockaddr));
- }
-
- host_fd = accept(sim_fd, &sa, &addrLen);
-
- if (host_fd == -1)
+ if (host_fd == -1) {
+ addrPtr.discard();
+ lenPtr.discard();
return -errno;
-
- if (addrPtr) {
- memcpy(addrBufPtr->bufferPtr(), &sa, sizeof(sa));
- addrBufPtr->copyOut(tc->getVirtProxy());
- delete(addrBufPtr);
- }
-
- if (lenPtr) {
- *(socklen_t *)lenBufPtr->bufferPtr() = addrLen;
- lenBufPtr->copyOut(tc->getVirtProxy());
- delete(lenBufPtr);
}
auto afdp = std::make_shared<SocketFDEntry>(host_fd, sfdp->_domain,
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/32254
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: If79ce0733a7a61274a818e39ecb9cf383cc4e8ba
Gerrit-Change-Number: 32254
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s