syscall_emul: [patch 2/22] move SyscallDesc into its own .hh and .cc

The class was crammed into syscall_emul.hh which has tons of forward
declarations and template definitions. To clean it up a bit, moved the
class into separate files and commented the class with doxygen style
comments. Also, provided some encapsulation by adding some accessors and
a mutator.

The syscallreturn.hh file was renamed syscall_return.hh to make it consistent
with other similarly named files in the src/sim directory.

The DPRINTF_SYSCALL macro was moved into its own header file with the
include the Base and Verbose flags as well.

--HG--
rename : src/sim/syscallreturn.hh => src/sim/syscall_return.hh
This commit is contained in:
Brandon Potter 2016-11-09 14:27:40 -06:00
parent 7a8dda49a4
commit 1ced08c850
20 changed files with 301 additions and 105 deletions

View File

@ -38,6 +38,7 @@
#include "debug/SyscallVerbose.hh"
#include "kern/linux/linux.hh"
#include "sim/process.hh"
#include "sim/syscall_desc.hh"
#include "sim/syscall_emul.hh"
using namespace std;

View File

@ -45,6 +45,7 @@
#include "cpu/thread_context.hh"
#include "kern/freebsd/freebsd.hh"
#include "sim/process.hh"
#include "sim/syscall_desc.hh"
#include "sim/syscall_emul.hh"
#include "sim/system.hh"

View File

@ -52,6 +52,7 @@
#include "cpu/thread_context.hh"
#include "kern/linux/linux.hh"
#include "sim/process.hh"
#include "sim/syscall_desc.hh"
#include "sim/syscall_emul.hh"
#include "sim/system.hh"

View File

@ -40,6 +40,7 @@
#include "kern/linux/linux.hh"
#include "sim/eventq.hh"
#include "sim/process.hh"
#include "sim/syscall_desc.hh"
#include "sim/syscall_emul.hh"
#include "sim/system.hh"

View File

@ -40,6 +40,7 @@
#include "cpu/thread_context.hh"
#include "kern/linux/linux.hh"
#include "sim/process.hh"
#include "sim/syscall_desc.hh"
#include "sim/syscall_emul.hh"
#include "sim/system.hh"

View File

@ -44,6 +44,7 @@
#include "kern/linux/linux.hh"
#include "sim/eventq.hh"
#include "sim/process.hh"
#include "sim/syscall_desc.hh"
#include "sim/syscall_emul.hh"
#include "sim/system.hh"

View File

@ -38,6 +38,7 @@
#include "cpu/thread_context.hh"
#include "kern/linux/linux.hh"
#include "sim/process.hh"
#include "sim/syscall_desc.hh"
#include "sim/syscall_emul.hh"
using namespace std;

View File

@ -29,6 +29,7 @@
*/
#include "arch/sparc/linux/process.hh"
#include "sim/syscall_desc.hh"
#include "sim/syscall_emul.hh"
class LiveProcess;

View File

@ -36,6 +36,7 @@
#include "cpu/thread_context.hh"
#include "kern/solaris/solaris.hh"
#include "sim/process.hh"
#include "sim/syscall_desc.hh"
#include "sim/syscall_emul.hh"
using namespace std;

View File

@ -46,6 +46,7 @@
#include "cpu/thread_context.hh"
#include "kern/linux/linux.hh"
#include "sim/process.hh"
#include "sim/syscall_desc.hh"
#include "sim/syscall_emul.hh"
using namespace std;
@ -159,7 +160,7 @@ setThreadArea32Func(SyscallDesc *desc, int callnum,
return -EFAULT;
if (!gdt.copyIn(tc->getMemProxy()))
panic("Failed to copy in GDT for %s.\n", desc->name);
panic("Failed to copy in GDT for %s.\n", desc->name());
if (userDesc->entry_number == (uint32_t)(-1)) {
// Find a free TLS entry.
@ -213,7 +214,7 @@ setThreadArea32Func(SyscallDesc *desc, int callnum,
if (!userDesc.copyOut(tc->getMemProxy()))
return -EFAULT;
if (!gdt.copyOut(tc->getMemProxy()))
panic("Failed to copy out GDT for %s.\n", desc->name);
panic("Failed to copy out GDT for %s.\n", desc->name());
return 0;
}

View File

@ -58,7 +58,7 @@
#include "mem/multi_level_page_table.hh"
#include "mem/page_table.hh"
#include "sim/process_impl.hh"
#include "sim/syscall_emul.hh"
#include "sim/syscall_desc.hh"
#include "sim/system.hh"
using namespace std;

View File

@ -80,6 +80,7 @@ if env['TARGET_ISA'] != 'null':
Source('fd_entry.cc')
Source('pseudo_inst.cc')
Source('syscall_emul.cc')
Source('syscall_desc.cc')
DebugFlag('Checkpoint')
DebugFlag('Config')

View File

@ -66,7 +66,7 @@
#include "sim/debug.hh"
#include "sim/process_impl.hh"
#include "sim/stats.hh"
#include "sim/syscall_emul.hh"
#include "sim/syscall_desc.hh"
#include "sim/system.hh"
#if THE_ISA == ALPHA_ISA

View File

@ -44,7 +44,7 @@
#include "mem/se_translating_port_proxy.hh"
#include "sim/fd_entry.hh"
#include "sim/sim_object.hh"
#include "sim/syscallreturn.hh"
#include "sim/syscall_return.hh"
class PageTable;
struct ProcessParams;

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2012-2013, 2015 ARM Limited
* Copyright (c) 2015-2016 Advanced Micro Devices, Inc.
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* 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
* Kevin Lim
* Brandon Potter
*/
#ifndef __SIM_SYSCALL_DEBUG_MACROS_HH__
#define __SIM_SYSCALL_DEBUG_MACROS_HH__
#include "debug/SyscallBase.hh"
#include "debug/SyscallVerbose.hh"
/**
* This macro is intended to help with readability.
* FLAGEXT specifies to which flag to assign the message: SyscallBase,
* SyscallVerbose, etc..; notice that 'Syscall' is already prepended.
* FMT is the message to be appended to the header information. The header
* information contains the cpuid and thread id.
*/
#define DPRINTF_SYSCALL(FLAGEXT, FMT, ...) \
DPRINTFS(Syscall##FLAGEXT, tc->getCpuPtr(), "T%d : syscall " FMT, \
tc->threadId(), __VA_ARGS__)
#endif // __SIM_SYSCALL_DEBUG_MACROS_HH__

88
src/sim/syscall_desc.cc Normal file
View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 2016 Advanced Micro Devices, Inc.
* 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
* Ali Saidi
* Brandon Potter
*/
#include "sim/syscall_desc.hh"
#include "base/trace.hh"
#include "config/the_isa.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "sim/process.hh"
#include "sim/syscall_debug_macros.hh"
#include "sim/syscall_return.hh"
void
SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc)
{
TheISA::IntReg arg[6] M5_VAR_USED;
/**
* Step through the first six parameters for the system call and
* retrieve their values. Note that index is incremented as a
* side-effect of the calling method.
*/
for (int index = 0; index < 6; )
arg[index] = process->getSyscallArg(tc, index);
/**
* Linux supports up to six system call arguments through registers
* so we want to print all six. Check to the relevant man page to
* verify how many are actually used by a given system call.
*/
DPRINTF_SYSCALL(Base, "%s called w/arguments %d, %d, %d, %d, %d, %d\n",
_name, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
/** Invoke the system call */
SyscallReturn retval = (*executor)(this, callnum, process, tc);
/**
* If the system call needs to be restarted, most likely due to
* blocking behavior, warn that the system call will retry;
* alternatively, print the return value.
*/
if (retval.needsRetry())
DPRINTF_SYSCALL(Base, "%s needs retry\n", _name);
else
DPRINTF_SYSCALL(Base, "%s returns %d\n", _name, retval.encodedValue());
if (!(_flags & SyscallDesc::SuppressReturnValue) && !retval.needsRetry())
process->setSyscallReturn(tc, retval);
}
bool
SyscallDesc::needWarning()
{
bool suppress_warning = warnOnce() && _warned;
_warned = true;
return !suppress_warning;
}

125
src/sim/syscall_desc.hh Normal file
View File

@ -0,0 +1,125 @@
/*
* Copyright (c) 2012-2013, 2015 ARM Limited
* Copyright (c) 2015-2016 Advanced Micro Devices, Inc.
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* 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
* Kevin Lim
* Brandon Potter
*/
#ifndef __SIM_SYSCALL_DESC_HH__
#define __SIM_SYSCALL_DESC_HH__
#include <string>
class LiveProcess;
class SyscallReturn;
class ThreadContext;
/**
* This class provides the wrapper interface for the system call
* implementations which are defined in the sim/syscall_emul files and
* bound to the ISAs in the architecture specific code
* (i.e. arch/X86/linux/process.cc).
*/
class SyscallDesc {
public:
/** Typedef the function pointer here to clean up code below */
typedef SyscallReturn (*SyscallExecutor)(SyscallDesc*, int num,
LiveProcess*, ThreadContext*);
SyscallDesc(const char *name, SyscallExecutor sys_exec, int flags = 0)
: _name(name), executor(sys_exec), _flags(flags), _warned(false)
{
}
/** Provide a mechanism to specify behavior for abnormal system calls */
enum Flags {
/**
* Do not set return registers according to executor return value.
* Used for system calls with non-standard return conventions that
* explicitly set the thread context regs (e.g., sigreturn, clone)
*/
SuppressReturnValue = 1,
/** Warn only once for unimplemented system calls */
WarnOnce = 2
/* X2 = 4, // Remove these comments when the next field is added; */
/* X3 = 8, // point is to make it obvious that this defines vector */
};
/**
* Interface for invoking the system call funcion pointer. Note that
* this acts as a gateway for all system calls and serves a good point
* to add filters for behaviors or apply checks for all system calls.
* @param callnum Number associated with call (by operating system)
* @param proc Handle for the owning Process to pass information
* @param tc Handle for owning ThreadContext to pass information
*/
void doSyscall(int callnum, LiveProcess *proc, ThreadContext *tc);
/**
* Return false if WarnOnce is set and a warning has already been issued.
* Otherwise, return true. Updates state as a side effect to help
* keep track of issued warnings.
*/
bool needWarning();
bool warnOnce() const { return (_flags & WarnOnce); }
std::string name() { return _name; }
private:
/** System call name (e.g., open, mmap, clone, socket, etc.) */
std::string _name;
/** Mechanism for ISAs to connect to the emul function definitions */
SyscallExecutor executor;
/**
* Holds values set with the preceding enum; note that this has been
* used primarily for features that are mutually exclusive, but there's
* no reason that this needs to be true going forward.
*/
int _flags;
/** Set if WarnOnce is specified in flags AFTER first call */
bool _warned;
};
#endif // __SIM_SYSCALL_DESC_HH__

View File

@ -44,56 +44,21 @@
#include "config/the_isa.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "debug/SyscallBase.hh"
#include "debug/SyscallVerbose.hh"
#include "mem/page_table.hh"
#include "sim/process.hh"
#include "sim/sim_exit.hh"
#include "sim/syscall_debug_macros.hh"
#include "sim/syscall_desc.hh"
#include "sim/system.hh"
using namespace std;
using namespace TheISA;
void
SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc)
{
if (DTRACE(SyscallBase)) {
int index = 0;
IntReg arg[6] M5_VAR_USED;
// we can't just put the calls to getSyscallArg() in the
// DPRINTF arg list, because C++ doesn't guarantee their order
for (int i = 0; i < 6; ++i)
arg[i] = process->getSyscallArg(tc, index);
// Linux supports up to six system call arguments through registers
// so we want to print all six. Check to the relevant man page to
// verify how many are actually used by a given system call.
DPRINTF_SYSCALL(Base,
"%s called w/arguments %d, %d, %d, %d, %d, %d\n",
name, arg[0], arg[1], arg[2], arg[3], arg[4],
arg[5]);
}
SyscallReturn retval = (*funcPtr)(this, callnum, process, tc);
if (retval.needsRetry()) {
DPRINTF_SYSCALL(Base, "%s needs retry\n", name);
} else {
DPRINTF_SYSCALL(Base, "%s returns %d\n", name,
retval.encodedValue());
}
if (!(flags & SyscallDesc::SuppressReturnValue) && !retval.needsRetry())
process->setSyscallReturn(tc, retval);
}
SyscallReturn
unimplementedFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
fatal("syscall %s (#%d) unimplemented.", desc->name, callnum);
fatal("syscall %s (#%d) unimplemented.", desc->name(), callnum);
return 1;
}
@ -103,20 +68,11 @@ SyscallReturn
ignoreFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
int index = 0;
const char *extra_text = "";
if (desc->warnOnce()) {
if (desc->warned)
return 0;
desc->warned = true;
extra_text = "\n (further warnings will be suppressed)";
if (desc->needWarning()) {
warn("ignoring syscall %s(...)%s", desc->name(), desc->warnOnce() ?
"\n (further warnings will be suppressed)" : "");
}
warn("ignoring syscall %s(%d, ...)%s", desc->name,
process->getSyscallArg(tc, index), extra_text);
return 0;
}

View File

@ -79,63 +79,16 @@
#include "config/the_isa.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "debug/SyscallBase.hh"
#include "debug/SyscallVerbose.hh"
#include "mem/page_table.hh"
#include "sim/byteswap.hh"
#include "sim/emul_driver.hh"
#include "sim/process.hh"
#include "sim/syscall_debug_macros.hh"
#include "sim/syscall_emul_buf.hh"
#include "sim/syscallreturn.hh"
#include "sim/syscall_return.hh"
#include "sim/system.hh"
// This wrapper macro helps out with readability a bit. FLAGEXT specifies
// the verbosity and FMT is the message to be appended to the syscall
// header information. The syscall header information contains the cpuid
// and thread id.
#define DPRINTF_SYSCALL(FLAGEXT, FMT, ...) \
DPRINTFS(Syscall##FLAGEXT, tc->getCpuPtr(), "T%d : syscall " FMT, \
tc->threadId(), __VA_ARGS__)
///
/// System call descriptor.
///
class SyscallDesc {
public:
/// Typedef for target syscall handler functions.
typedef SyscallReturn (*FuncPtr)(SyscallDesc *, int num,
LiveProcess *, ThreadContext *);
const char *name; //!< Syscall name (e.g., "open").
FuncPtr funcPtr; //!< Pointer to emulation function.
int flags; //!< Flags (see Flags enum).
bool warned; //!< Have we warned about unimplemented syscall?
/// Flag values for controlling syscall behavior.
enum Flags {
/// Don't set return regs according to funcPtr return value.
/// Used for syscalls with non-standard return conventions
/// that explicitly set the ThreadContext regs (e.g.,
/// sigreturn).
SuppressReturnValue = 1,
WarnOnce = 2
};
/// Constructor.
SyscallDesc(const char *_name, FuncPtr _funcPtr, int _flags = 0)
: name(_name), funcPtr(_funcPtr), flags(_flags), warned(false)
{
}
/// Emulate the syscall. Public interface for calling through funcPtr.
void doSyscall(int callnum, LiveProcess *proc, ThreadContext *tc);
/// Is the WarnOnce flag set?
bool warnOnce() const { return (flags & WarnOnce); }
};
class SyscallDesc;
//////////////////////////////////////////////////////////////////////
//