From: Steve Reinhardt Date: Wed, 22 Oct 2014 22:53:34 +0000 (-0700) Subject: syscall_emul: Put BufferArg classes in a separate header. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=44af2c6a6913d35a2c34bd928dbfdef3c16dcaf9;p=gem5.git syscall_emul: Put BufferArg classes in a separate header. Move the BufferArg classes that support syscall buffer args (i.e., pointers into simulated user space) out of syscall_emul.hh and into a new header syscall_emul_buf.hh so they are accessible to emulated driver implementations. Take the opportunity to add some comments as well. --- diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 1c84e9f48..a4f9b238e 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -75,10 +75,10 @@ #include "cpu/thread_context.hh" #include "debug/SyscallVerbose.hh" #include "mem/page_table.hh" -#include "mem/se_translating_port_proxy.hh" #include "sim/byteswap.hh" #include "sim/emul_driver.hh" #include "sim/process.hh" +#include "sim/syscall_emul_buf.hh" #include "sim/syscallreturn.hh" #include "sim/system.hh" @@ -117,73 +117,6 @@ class SyscallDesc { }; -class BaseBufferArg { - - public: - - BaseBufferArg(Addr _addr, int _size) : addr(_addr), size(_size) - { - bufPtr = new uint8_t[size]; - // clear out buffer: in case we only partially populate this, - // and then do a copyOut(), we want to make sure we don't - // introduce any random junk into the simulated address space - memset(bufPtr, 0, size); - } - - virtual ~BaseBufferArg() { delete [] bufPtr; } - - // - // copy data into simulator space (read from target memory) - // - virtual bool copyIn(SETranslatingPortProxy &memproxy) - { - memproxy.readBlob(addr, bufPtr, size); - return true; // no EFAULT detection for now - } - - // - // copy data out of simulator space (write to target memory) - // - virtual bool copyOut(SETranslatingPortProxy &memproxy) - { - memproxy.writeBlob(addr, bufPtr, size); - return true; // no EFAULT detection for now - } - - protected: - Addr addr; - int size; - uint8_t *bufPtr; -}; - - -class BufferArg : public BaseBufferArg -{ - public: - BufferArg(Addr _addr, int _size) : BaseBufferArg(_addr, _size) { } - void *bufferPtr() { return bufPtr; } -}; - -template -class TypedBufferArg : public BaseBufferArg -{ - public: - // user can optionally specify a specific number of bytes to - // allocate to deal with those structs that have variable-size - // arrays at the end - TypedBufferArg(Addr _addr, int _size = sizeof(T)) - : BaseBufferArg(_addr, _size) - { } - - // type case - operator T*() { return (T *)bufPtr; } - - // dereference operators - T &operator*() { return *((T *)bufPtr); } - T* operator->() { return (T *)bufPtr; } - T &operator[](int i) { return ((T *)bufPtr)[i]; } -}; - ////////////////////////////////////////////////////////////////////// // // The following emulation functions are generic enough that they diff --git a/src/sim/syscall_emul_buf.hh b/src/sim/syscall_emul_buf.hh new file mode 100644 index 000000000..cbd10f2f6 --- /dev/null +++ b/src/sim/syscall_emul_buf.hh @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Steve Reinhardt + */ + +#ifndef __SIM_SYSCALL_EMUL_BUF_HH__ +#define __SIM_SYSCALL_EMUL_BUF_HH__ + +/// +/// @file syscall_emul_buf.hh +/// +/// This file defines buffer classes used to handle pointer arguments +/// in emulated syscalls. + +#include + +#include "base/types.hh" +#include "mem/se_translating_port_proxy.hh" + +/** + * Base class for BufferArg and TypedBufferArg, Not intended to be + * used directly. + * + * The BufferArg classes represent buffers in target user space that + * are passed by reference to an (emulated) system call. Each + * instance provides an internal (simulator-space) buffer of the + * appropriate size and tracks the user-space address. The copyIn() + * and copyOut() methods copy the user-space buffer to and from the + * simulator-space buffer, respectively. + */ +class BaseBufferArg { + + public: + + /** + * Allocate a buffer of size 'size' representing the memory at + * target address 'addr'. + */ + BaseBufferArg(Addr _addr, int _size) + : addr(_addr), size(_size), bufPtr(new uint8_t[size]) + { + // clear out buffer: in case we only partially populate this, + // and then do a copyOut(), we want to make sure we don't + // introduce any random junk into the simulated address space + memset(bufPtr, 0, size); + } + + virtual ~BaseBufferArg() { delete [] bufPtr; } + + /** + * copy data into simulator space (read from target memory) + */ + virtual bool copyIn(SETranslatingPortProxy &memproxy) + { + memproxy.readBlob(addr, bufPtr, size); + return true; // no EFAULT detection for now + } + + /** + * copy data out of simulator space (write to target memory) + */ + virtual bool copyOut(SETranslatingPortProxy &memproxy) + { + memproxy.writeBlob(addr, bufPtr, size); + return true; // no EFAULT detection for now + } + + protected: + const Addr addr; ///< address of buffer in target address space + const int size; ///< buffer size + uint8_t * const bufPtr; ///< pointer to buffer in simulator space +}; + +/** + * BufferArg represents an untyped buffer in target user space that is + * passed by reference to an (emulated) system call. + */ +class BufferArg : public BaseBufferArg +{ + public: + /** + * Allocate a buffer of size 'size' representing the memory at + * target address 'addr'. + */ + BufferArg(Addr _addr, int _size) : BaseBufferArg(_addr, _size) { } + + /** + * Return a pointer to the internal simulator-space buffer. + */ + void *bufferPtr() { return bufPtr; } +}; + +/** + * TypedBufferArg is a class template; instances of this template + * represent typed buffers in target user space that are passed by + * reference to an (emulated) system call. + * + * This template provides operator overloads for convenience, allowing + * for example the use of '->' to reference fields within a struct + * type. + */ +template +class TypedBufferArg : public BaseBufferArg +{ + public: + /** + * Allocate a buffer of type T representing the memory at target + * address 'addr'. The user can optionally specify a specific + * number of bytes to allocate to deal with structs that have + * variable-size arrays at the end. + */ + TypedBufferArg(Addr _addr, int _size = sizeof(T)) + : BaseBufferArg(_addr, _size) + { } + + /** + * Convert TypedBufferArg to a pointer to T that points to the + * internal buffer. + */ + operator T*() { return (T *)bufPtr; } + + /** + * Convert TypedBufferArg to a reference to T that references the + * internal buffer value. + */ + T &operator*() { return *((T *)bufPtr); } + + + /** + * Enable the use of '->' to reference fields where T is a struct + * type. + */ + T* operator->() { return (T *)bufPtr; } + + /** + * Enable the use of '[]' to reference fields where T is an array + * type. + */ + T &operator[](int i) { return ((T *)bufPtr)[i]; } +}; + + +#endif // __SIM_SYSCALL_EMUL_BUF_HH__