syscall_emul_buf.hh revision 14020
110497Ssteve.reinhardt@amd.com/* 210497Ssteve.reinhardt@amd.com * Copyright (c) 2003-2005 The Regents of The University of Michigan 310497Ssteve.reinhardt@amd.com * All rights reserved. 410497Ssteve.reinhardt@amd.com * 510497Ssteve.reinhardt@amd.com * Redistribution and use in source and binary forms, with or without 610497Ssteve.reinhardt@amd.com * modification, are permitted provided that the following conditions are 710497Ssteve.reinhardt@amd.com * met: redistributions of source code must retain the above copyright 810497Ssteve.reinhardt@amd.com * notice, this list of conditions and the following disclaimer; 910497Ssteve.reinhardt@amd.com * redistributions in binary form must reproduce the above copyright 1010497Ssteve.reinhardt@amd.com * notice, this list of conditions and the following disclaimer in the 1110497Ssteve.reinhardt@amd.com * documentation and/or other materials provided with the distribution; 1210497Ssteve.reinhardt@amd.com * neither the name of the copyright holders nor the names of its 1310497Ssteve.reinhardt@amd.com * contributors may be used to endorse or promote products derived from 1410497Ssteve.reinhardt@amd.com * this software without specific prior written permission. 1510497Ssteve.reinhardt@amd.com * 1610497Ssteve.reinhardt@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1710497Ssteve.reinhardt@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1810497Ssteve.reinhardt@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1910497Ssteve.reinhardt@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2010497Ssteve.reinhardt@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2110497Ssteve.reinhardt@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2210497Ssteve.reinhardt@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2310497Ssteve.reinhardt@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2410497Ssteve.reinhardt@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2510497Ssteve.reinhardt@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2610497Ssteve.reinhardt@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2710497Ssteve.reinhardt@amd.com * 2810497Ssteve.reinhardt@amd.com * Authors: Steve Reinhardt 2910497Ssteve.reinhardt@amd.com */ 3010497Ssteve.reinhardt@amd.com 3110497Ssteve.reinhardt@amd.com#ifndef __SIM_SYSCALL_EMUL_BUF_HH__ 3210497Ssteve.reinhardt@amd.com#define __SIM_SYSCALL_EMUL_BUF_HH__ 3310497Ssteve.reinhardt@amd.com 3410497Ssteve.reinhardt@amd.com/// 3510497Ssteve.reinhardt@amd.com/// @file syscall_emul_buf.hh 3610497Ssteve.reinhardt@amd.com/// 3710497Ssteve.reinhardt@amd.com/// This file defines buffer classes used to handle pointer arguments 3810497Ssteve.reinhardt@amd.com/// in emulated syscalls. 3910497Ssteve.reinhardt@amd.com 4010497Ssteve.reinhardt@amd.com#include <cstring> 4110497Ssteve.reinhardt@amd.com 4210497Ssteve.reinhardt@amd.com#include "base/types.hh" 4310497Ssteve.reinhardt@amd.com#include "mem/se_translating_port_proxy.hh" 4410497Ssteve.reinhardt@amd.com 4510497Ssteve.reinhardt@amd.com/** 4610497Ssteve.reinhardt@amd.com * Base class for BufferArg and TypedBufferArg, Not intended to be 4710497Ssteve.reinhardt@amd.com * used directly. 4810497Ssteve.reinhardt@amd.com * 4910497Ssteve.reinhardt@amd.com * The BufferArg classes represent buffers in target user space that 5010497Ssteve.reinhardt@amd.com * are passed by reference to an (emulated) system call. Each 5110497Ssteve.reinhardt@amd.com * instance provides an internal (simulator-space) buffer of the 5210497Ssteve.reinhardt@amd.com * appropriate size and tracks the user-space address. The copyIn() 5310497Ssteve.reinhardt@amd.com * and copyOut() methods copy the user-space buffer to and from the 5410497Ssteve.reinhardt@amd.com * simulator-space buffer, respectively. 5510497Ssteve.reinhardt@amd.com */ 5610497Ssteve.reinhardt@amd.comclass BaseBufferArg { 5710497Ssteve.reinhardt@amd.com 5810497Ssteve.reinhardt@amd.com public: 5910497Ssteve.reinhardt@amd.com 6010497Ssteve.reinhardt@amd.com /** 6110497Ssteve.reinhardt@amd.com * Allocate a buffer of size 'size' representing the memory at 6210497Ssteve.reinhardt@amd.com * target address 'addr'. 6310497Ssteve.reinhardt@amd.com */ 6410497Ssteve.reinhardt@amd.com BaseBufferArg(Addr _addr, int _size) 6510497Ssteve.reinhardt@amd.com : addr(_addr), size(_size), bufPtr(new uint8_t[size]) 6610497Ssteve.reinhardt@amd.com { 6710497Ssteve.reinhardt@amd.com // clear out buffer: in case we only partially populate this, 6810497Ssteve.reinhardt@amd.com // and then do a copyOut(), we want to make sure we don't 6910497Ssteve.reinhardt@amd.com // introduce any random junk into the simulated address space 7010497Ssteve.reinhardt@amd.com memset(bufPtr, 0, size); 7110497Ssteve.reinhardt@amd.com } 7210497Ssteve.reinhardt@amd.com 7310498Ssteve.reinhardt@amd.com ~BaseBufferArg() { delete [] bufPtr; } 7410497Ssteve.reinhardt@amd.com 7510497Ssteve.reinhardt@amd.com /** 7610497Ssteve.reinhardt@amd.com * copy data into simulator space (read from target memory) 7710497Ssteve.reinhardt@amd.com */ 7814020Sgabeblack@google.com bool 7914020Sgabeblack@google.com copyIn(PortProxy &memproxy) 8010497Ssteve.reinhardt@amd.com { 8110497Ssteve.reinhardt@amd.com memproxy.readBlob(addr, bufPtr, size); 8210497Ssteve.reinhardt@amd.com return true; // no EFAULT detection for now 8310497Ssteve.reinhardt@amd.com } 8410497Ssteve.reinhardt@amd.com 8510497Ssteve.reinhardt@amd.com /** 8610497Ssteve.reinhardt@amd.com * copy data out of simulator space (write to target memory) 8710497Ssteve.reinhardt@amd.com */ 8814020Sgabeblack@google.com bool 8914020Sgabeblack@google.com copyOut(PortProxy &memproxy) 9010497Ssteve.reinhardt@amd.com { 9110497Ssteve.reinhardt@amd.com memproxy.writeBlob(addr, bufPtr, size); 9210497Ssteve.reinhardt@amd.com return true; // no EFAULT detection for now 9310497Ssteve.reinhardt@amd.com } 9410497Ssteve.reinhardt@amd.com 9510497Ssteve.reinhardt@amd.com protected: 9610497Ssteve.reinhardt@amd.com const Addr addr; ///< address of buffer in target address space 9710497Ssteve.reinhardt@amd.com const int size; ///< buffer size 9810497Ssteve.reinhardt@amd.com uint8_t * const bufPtr; ///< pointer to buffer in simulator space 9910497Ssteve.reinhardt@amd.com}; 10010497Ssteve.reinhardt@amd.com 10110497Ssteve.reinhardt@amd.com/** 10210497Ssteve.reinhardt@amd.com * BufferArg represents an untyped buffer in target user space that is 10310497Ssteve.reinhardt@amd.com * passed by reference to an (emulated) system call. 10410497Ssteve.reinhardt@amd.com */ 10510497Ssteve.reinhardt@amd.comclass BufferArg : public BaseBufferArg 10610497Ssteve.reinhardt@amd.com{ 10710497Ssteve.reinhardt@amd.com public: 10810497Ssteve.reinhardt@amd.com /** 10910497Ssteve.reinhardt@amd.com * Allocate a buffer of size 'size' representing the memory at 11010497Ssteve.reinhardt@amd.com * target address 'addr'. 11110497Ssteve.reinhardt@amd.com */ 11210497Ssteve.reinhardt@amd.com BufferArg(Addr _addr, int _size) : BaseBufferArg(_addr, _size) { } 11310497Ssteve.reinhardt@amd.com 11410497Ssteve.reinhardt@amd.com /** 11510497Ssteve.reinhardt@amd.com * Return a pointer to the internal simulator-space buffer. 11610497Ssteve.reinhardt@amd.com */ 11710497Ssteve.reinhardt@amd.com void *bufferPtr() { return bufPtr; } 11810497Ssteve.reinhardt@amd.com}; 11910497Ssteve.reinhardt@amd.com 12010497Ssteve.reinhardt@amd.com/** 12110497Ssteve.reinhardt@amd.com * TypedBufferArg is a class template; instances of this template 12210497Ssteve.reinhardt@amd.com * represent typed buffers in target user space that are passed by 12310497Ssteve.reinhardt@amd.com * reference to an (emulated) system call. 12410497Ssteve.reinhardt@amd.com * 12510497Ssteve.reinhardt@amd.com * This template provides operator overloads for convenience, allowing 12610497Ssteve.reinhardt@amd.com * for example the use of '->' to reference fields within a struct 12710497Ssteve.reinhardt@amd.com * type. 12810497Ssteve.reinhardt@amd.com */ 12910497Ssteve.reinhardt@amd.comtemplate <class T> 13010497Ssteve.reinhardt@amd.comclass TypedBufferArg : public BaseBufferArg 13110497Ssteve.reinhardt@amd.com{ 13210497Ssteve.reinhardt@amd.com public: 13310497Ssteve.reinhardt@amd.com /** 13410497Ssteve.reinhardt@amd.com * Allocate a buffer of type T representing the memory at target 13510497Ssteve.reinhardt@amd.com * address 'addr'. The user can optionally specify a specific 13610497Ssteve.reinhardt@amd.com * number of bytes to allocate to deal with structs that have 13710497Ssteve.reinhardt@amd.com * variable-size arrays at the end. 13810497Ssteve.reinhardt@amd.com */ 13910497Ssteve.reinhardt@amd.com TypedBufferArg(Addr _addr, int _size = sizeof(T)) 14010497Ssteve.reinhardt@amd.com : BaseBufferArg(_addr, _size) 14110497Ssteve.reinhardt@amd.com { } 14210497Ssteve.reinhardt@amd.com 14310497Ssteve.reinhardt@amd.com /** 14410497Ssteve.reinhardt@amd.com * Convert TypedBufferArg<T> to a pointer to T that points to the 14510497Ssteve.reinhardt@amd.com * internal buffer. 14610497Ssteve.reinhardt@amd.com */ 14710497Ssteve.reinhardt@amd.com operator T*() { return (T *)bufPtr; } 14810497Ssteve.reinhardt@amd.com 14910497Ssteve.reinhardt@amd.com /** 15010497Ssteve.reinhardt@amd.com * Convert TypedBufferArg<T> to a reference to T that references the 15110497Ssteve.reinhardt@amd.com * internal buffer value. 15210497Ssteve.reinhardt@amd.com */ 15310497Ssteve.reinhardt@amd.com T &operator*() { return *((T *)bufPtr); } 15410497Ssteve.reinhardt@amd.com 15510497Ssteve.reinhardt@amd.com 15610497Ssteve.reinhardt@amd.com /** 15710497Ssteve.reinhardt@amd.com * Enable the use of '->' to reference fields where T is a struct 15810497Ssteve.reinhardt@amd.com * type. 15910497Ssteve.reinhardt@amd.com */ 16010497Ssteve.reinhardt@amd.com T* operator->() { return (T *)bufPtr; } 16110497Ssteve.reinhardt@amd.com 16210497Ssteve.reinhardt@amd.com /** 16310497Ssteve.reinhardt@amd.com * Enable the use of '[]' to reference fields where T is an array 16410497Ssteve.reinhardt@amd.com * type. 16510497Ssteve.reinhardt@amd.com */ 16610497Ssteve.reinhardt@amd.com T &operator[](int i) { return ((T *)bufPtr)[i]; } 16710497Ssteve.reinhardt@amd.com}; 16810497Ssteve.reinhardt@amd.com 16910497Ssteve.reinhardt@amd.com 17010497Ssteve.reinhardt@amd.com#endif // __SIM_SYSCALL_EMUL_BUF_HH__ 171