syscall_emul: [patch 8/22] refactor process class

Moves aux_vector into its own .hh and .cc files just to get it out of the
already crowded Process files. Arguably, it could stay there, but it's
probably better just to move it and give it files.

The changeset looks ugly around the Process header file, but the goal here is
to move methods and members around so that they're not defined randomly
throughout the entire header file. I expect this is likely one of the reasons
why I several unused variables related to this class. So, the methods are
declared first followed by members. I've tried to aggregate them together
so that similar entries reside near one another.

There are other changes coming to this code so this is by no means the
final product.
This commit is contained in:
Brandon Potter 2016-11-09 14:27:41 -06:00
parent ea8461885f
commit 49009f170a
13 changed files with 269 additions and 190 deletions

View file

@ -38,6 +38,7 @@
#include "cpu/thread_context.hh"
#include "debug/Loader.hh"
#include "mem/page_table.hh"
#include "sim/aux_vector.hh"
#include "sim/byteswap.hh"
#include "sim/process_impl.hh"
#include "sim/syscall_return.hh"

View file

@ -51,6 +51,7 @@
#include "cpu/thread_context.hh"
#include "debug/Stack.hh"
#include "mem/page_table.hh"
#include "sim/aux_vector.hh"
#include "sim/byteswap.hh"
#include "sim/process_impl.hh"
#include "sim/syscall_return.hh"

View file

@ -39,6 +39,7 @@
#include "cpu/thread_context.hh"
#include "debug/Loader.hh"
#include "mem/page_table.hh"
#include "sim/aux_vector.hh"
#include "sim/process.hh"
#include "sim/process_impl.hh"
#include "sim/syscall_return.hh"

View file

@ -40,6 +40,7 @@
#include "cpu/thread_context.hh"
#include "debug/Stack.hh"
#include "mem/page_table.hh"
#include "sim/aux_vector.hh"
#include "sim/process_impl.hh"
#include "sim/syscall_return.hh"
#include "sim/system.hh"

View file

@ -42,6 +42,7 @@
#include "cpu/thread_context.hh"
#include "debug/Loader.hh"
#include "mem/page_table.hh"
#include "sim/aux_vector.hh"
#include "sim/process.hh"
#include "sim/process_impl.hh"
#include "sim/syscall_return.hh"

View file

@ -42,6 +42,7 @@
#include "cpu/thread_context.hh"
#include "debug/Stack.hh"
#include "mem/page_table.hh"
#include "sim/aux_vector.hh"
#include "sim/process_impl.hh"
#include "sim/syscall_return.hh"
#include "sim/system.hh"

View file

@ -44,6 +44,9 @@
#include "arch/x86/process.hh"
#include <string>
#include <vector>
#include "arch/x86/isa_traits.hh"
#include "arch/x86/regs/misc.hh"
#include "arch/x86/regs/segment.hh"
@ -57,6 +60,7 @@
#include "debug/Stack.hh"
#include "mem/multi_level_page_table.hh"
#include "mem/page_table.hh"
#include "sim/aux_vector.hh"
#include "sim/process_impl.hh"
#include "sim/syscall_desc.hh"
#include "sim/syscall_return.hh"

View file

@ -43,6 +43,7 @@
#include <string>
#include <vector>
#include "sim/aux_vector.hh"
#include "sim/process.hh"
#include "mem/multi_level_page_table.hh"

View file

@ -75,6 +75,7 @@ Source('mathexpr.cc')
if env['TARGET_ISA'] != 'null':
SimObject('InstTracer.py')
SimObject('Process.py')
Source('aux_vector.cc')
Source('faults.cc')
Source('process.cc')
Source('fd_entry.cc')

77
src/sim/aux_vector.cc Normal file
View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2016 Advanced Micro Devices, Inc.
* All rights reserved.
*
* For use for simulation and test purposes only
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. Neither the name of the copyright holder 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 HOLDER 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.
*
* Author: Brandon Potter
*/
#include "sim/aux_vector.hh"
#include <inttypes.h>
#include "config/the_isa.hh"
#if THE_ISA == ALPHA_ISA
#include "arch/alpha/linux/process.hh"
#elif THE_ISA == SPARC_ISA
#include "arch/sparc/linux/process.hh"
#include "arch/sparc/solaris/process.hh"
#elif THE_ISA == MIPS_ISA
#include "arch/mips/linux/process.hh"
#elif THE_ISA == ARM_ISA
#include "arch/arm/freebsd/process.hh"
#include "arch/arm/linux/process.hh"
#elif THE_ISA == X86_ISA
#include "arch/x86/linux/process.hh"
#elif THE_ISA == RISCV_ISA
#include "arch/riscv/linux/process.hh"
#elif THE_ISA == POWER_ISA
#include "arch/power/linux/process.hh"
#else
#error "THE_ISA not set"
#endif
template<class IntType>
AuxVector<IntType>::AuxVector(IntType type, IntType val)
{
a_type = TheISA::htog(type);
a_val = TheISA::htog(val);
}
template struct AuxVector<uint32_t>;
template struct AuxVector<uint64_t>;

77
src/sim/aux_vector.hh Normal file
View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2016 Advanced Micro Devices, Inc.
* All rights reserved.
*
* For use for simulation and test purposes only
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. Neither the name of the copyright holder 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 HOLDER 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.
*
* Author: Brandon Potter
*/
#ifndef __AUX_VECTOR_HH__
#define __AUX_VECTOR_HH__
template<class IntType>
struct AuxVector
{
IntType a_type;
IntType a_val;
AuxVector()
{}
AuxVector(IntType type, IntType val);
};
enum AuxiliaryVectorType {
M5_AT_NULL = 0,
M5_AT_IGNORE = 1,
M5_AT_EXECFD = 2,
M5_AT_PHDR = 3,
M5_AT_PHENT = 4,
M5_AT_PHNUM = 5,
M5_AT_PAGESZ = 6,
M5_AT_BASE = 7,
M5_AT_FLAGS = 8,
M5_AT_ENTRY = 9,
M5_AT_NOTELF = 10,
M5_AT_UID = 11,
M5_AT_EUID = 12,
M5_AT_GID = 13,
M5_AT_EGID = 14,
M5_AT_PLATFORM = 15,
M5_AT_HWCAP = 16,
M5_AT_CLKTCK = 17,
M5_AT_SECURE = 23,
M5_BASE_PLATFORM = 24,
M5_AT_RANDOM = 25,
M5_AT_EXECFN = 31,
M5_AT_VECTOR_SIZE = 44
};
#endif // __AUX_VECTOR_HH__

View file

@ -93,17 +93,6 @@ using namespace TheISA;
// current number of allocated processes
int num_processes = 0;
template<class IntType>
AuxVector<IntType>::AuxVector(IntType type, IntType val)
{
a_type = TheISA::htog(type);
a_val = TheISA::htog(val);
}
template struct AuxVector<uint32_t>;
template struct AuxVector<uint64_t>;
static int
openFile(const string& filename, int flags, mode_t mode)
{
@ -205,7 +194,6 @@ Process::Process(ProcessParams * params, ObjectFile * obj_file)
}
}
void
Process::regStats()
{
@ -497,7 +485,6 @@ Process::unserialize(CheckpointIn &cp)
// found.
}
bool
Process::map(Addr vaddr, Addr paddr, int size, bool cacheable)
{
@ -506,7 +493,6 @@ Process::map(Addr vaddr, Addr paddr, int size, bool cacheable)
return true;
}
void
Process::syscall(int64_t callnum, ThreadContext *tc)
{
@ -525,7 +511,6 @@ Process::getSyscallArg(ThreadContext *tc, int &i, int width)
return getSyscallArg(tc, i);
}
EmulatedDriver *
Process::findDriver(std::string filename)
{
@ -561,14 +546,12 @@ Process::updateBias()
interp->updateBias(ld_bias);
}
ObjectFile *
Process::getInterpreter()
{
return objFile->getInterpreter();
}
Addr
Process::getBias()
{
@ -577,7 +560,6 @@ Process::getBias()
return interp ? interp->bias() : objFile->bias();
}
Addr
Process::getStartPC()
{
@ -586,7 +568,6 @@ Process::getStartPC()
return interp ? interp->entryPoint() : objFile->entryPoint();
}
Process *
ProcessParams::create()
{
@ -634,7 +615,6 @@ ProcessParams::create()
}
break;
case ObjectFile::Solaris:
process = new SparcSolarisProcess(this, obj_file);
break;
@ -743,3 +723,17 @@ ProcessParams::create()
fatal("Unknown error creating process object.");
return process;
}
std::string
Process::fullPath(const std::string &file_name)
{
if (file_name[0] == '/' || cwd.empty())
return file_name;
std::string full = cwd;
if (cwd[cwd.size() - 1] != '/')
full += '/';
return full + file_name;
}

View file

@ -33,6 +33,8 @@
#ifndef __PROCESS_HH__
#define __PROCESS_HH__
#include <inttypes.h>
#include <array>
#include <map>
#include <string>
@ -56,30 +58,9 @@ class SyscallReturn;
class System;
class ThreadContext;
template<class IntType>
struct AuxVector
{
IntType a_type;
IntType a_val;
AuxVector()
{}
AuxVector(IntType type, IntType val);
};
class Process : public SimObject
{
public:
/// Pointer to object representing the system this process is
/// running on.
System *system;
// thread contexts associated with this process
std::vector<ContextID> contextIds;
// record of blocked context
struct WaitRec
{
Addr waitChan;
@ -87,82 +68,59 @@ class Process : public SimObject
WaitRec(Addr chan, ThreadContext *ctx)
: waitChan(chan), waitingContext(ctx)
{ }
{ }
};
// list of all blocked contexts
std::list<WaitRec> waitList;
Process(ProcessParams *params, ObjectFile *obj_file);
Addr brk_point; // top of the data segment
Addr stack_base; // stack segment base (highest address)
unsigned stack_size; // initial stack size
Addr stack_min; // lowest address accessed on the stack
// The maximum size allowed for the stack.
Addr max_stack_size;
// addr to use for next stack region (for multithreaded apps)
Addr next_thread_stack_base;
// Base of region for mmaps (when user doesn't specify an address).
Addr mmap_end;
// Does mmap region grow upward or downward from mmap_end? Most
// platforms grow downward, but a few (such as Alpha) grow upward
// instead, so they can override thie method to return false.
virtual bool mmapGrowsDown() const { return true; }
Stats::Scalar num_syscalls; // number of syscalls executed
protected:
// constructor
Process(ProcessParams *params);
void serialize(CheckpointOut &cp) const override;
void unserialize(CheckpointIn &cp) override;
void initState() override;
DrainState drain() override;
public:
void syscall(int64_t callnum, ThreadContext *tc);
virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i) = 0;
virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i, int width);
virtual void setSyscallArg(ThreadContext *tc, int i,
TheISA::IntReg val) = 0;
virtual void setSyscallReturn(ThreadContext *tc,
SyscallReturn return_value) = 0;
virtual SyscallDesc *getDesc(int callnum) = 0;
// flag for using architecture specific page table
bool useArchPT;
// running KvmCPU in SE mode requires special initialization
bool kvmInSE;
inline uint64_t uid() { return _uid; }
inline uint64_t euid() { return _euid; }
inline uint64_t gid() { return _gid; }
inline uint64_t egid() { return _egid; }
inline uint64_t pid() { return _pid; }
inline uint64_t ppid() { return _ppid; }
PageTableBase* pTable;
const char *progName() const { return executable.c_str(); }
std::string fullPath(const std::string &filename);
std::string getcwd() const { return cwd; }
protected:
/// Memory proxy for initialization (image loading)
SETranslatingPortProxy initVirtMem;
/**
* Find an emulated device driver.
*
* @param filename Name of the device (under /dev)
* @return Pointer to driver object if found, else NULL
*/
EmulatedDriver *findDriver(std::string filename);
private:
static const int NUM_FDS = 1024;
// This function acts as a callback to update the bias value in
// the object file because the parameters needed to calculate the
// bias are not available when the object file is created.
void updateBias();
Addr getBias();
Addr getStartPC();
ObjectFile *getInterpreter();
// File descriptor remapping support.
std::shared_ptr<std::array<FDEntry, NUM_FDS>> fd_array;
// Standard file descriptor options for initialization and checkpoints.
std::map<std::string, int> imap;
std::map<std::string, int> oemap;
public:
// inherit file descriptor map from another process (necessary for clone)
void inheritFDArray(Process *p);
// override of virtual SimObject method: register statistics
void regStats() override;
// After getting registered with system object, tell process which
// system-wide context id it is assigned.
void assignThreadContext(ContextID context_id)
{
contextIds.push_back(context_id);
}
// Find a free context to use
ThreadContext *findFreeContext();
// generate new target fd for sim_fd
int allocFD(int sim_fd, const std::string& filename, int flags, int mode,
bool pipe);
@ -199,6 +157,24 @@ class Process : public SimObject
/// @return Whether the fault has been fixed.
bool fixupStackFault(Addr vaddr);
// After getting registered with system object, tell process which
// system-wide context id it is assigned.
void
assignThreadContext(ContextID context_id)
{
contextIds.push_back(context_id);
}
// Find a free context to use
ThreadContext *findFreeContext();
/**
* Does mmap region grow upward or downward from mmap_end? Most
* platforms grow downward, but a few (such as Alpha) grow upward
* instead, so they can override this method to return false.
*/
virtual bool mmapGrowsDown() const { return true; }
/**
* Maps a contiguous range of virtual addresses in this process's
* address space to a contiguous range of physical addresses.
@ -214,19 +190,47 @@ class Process : public SimObject
*/
bool map(Addr vaddr, Addr paddr, int size, bool cacheable = true);
void serialize(CheckpointOut &cp) const override;
void unserialize(CheckpointIn &cp) override;
// list of all blocked contexts
std::list<WaitRec> waitList;
// thread contexts associated with this process
std::vector<ContextID> contextIds;
// system object which owns this process
System *system;
Addr brk_point; // top of the data segment
Addr stack_base; // stack segment base
unsigned stack_size; // initial stack size
Addr stack_min; // furthest address accessed from stack base
Addr max_stack_size; // the maximum size allowed for the stack
Addr next_thread_stack_base; // addr for next region w/ multithreaded apps
Addr mmap_end; // base of automatic mmap region allocs
Stats::Scalar num_syscalls; // track how many system calls are executed
bool useArchPT; // flag for using architecture specific page table
bool kvmInSE; // running KVM requires special initialization
PageTableBase* pTable;
SETranslatingPortProxy initVirtMem; // memory proxy for initial image load
static const int NUM_FDS = 1024;
// File descriptor remapping support.
std::shared_ptr<std::array<FDEntry, NUM_FDS>> fd_array;
// Standard file descriptor options for initialization and checkpoints.
std::map<std::string, int> imap;
std::map<std::string, int> oemap;
protected:
ObjectFile *objFile;
std::vector<std::string> argv;
std::vector<std::string> envp;
std::string cwd;
std::string executable;
Process(ProcessParams *params, ObjectFile *obj_file);
public:
// Id of the owner of the process
uint64_t _uid;
uint64_t _euid;
@ -239,91 +243,6 @@ class Process : public SimObject
// Emulated drivers available to this process
std::vector<EmulatedDriver *> drivers;
enum AuxiliaryVectorType {
M5_AT_NULL = 0,
M5_AT_IGNORE = 1,
M5_AT_EXECFD = 2,
M5_AT_PHDR = 3,
M5_AT_PHENT = 4,
M5_AT_PHNUM = 5,
M5_AT_PAGESZ = 6,
M5_AT_BASE = 7,
M5_AT_FLAGS = 8,
M5_AT_ENTRY = 9,
M5_AT_NOTELF = 10,
M5_AT_UID = 11,
M5_AT_EUID = 12,
M5_AT_GID = 13,
M5_AT_EGID = 14,
// The following may be specific to Linux
M5_AT_PLATFORM = 15,
M5_AT_HWCAP = 16,
M5_AT_CLKTCK = 17,
M5_AT_SECURE = 23,
M5_BASE_PLATFORM = 24,
M5_AT_RANDOM = 25,
M5_AT_EXECFN = 31,
M5_AT_VECTOR_SIZE = 44
};
inline uint64_t uid() { return _uid; }
inline uint64_t euid() { return _euid; }
inline uint64_t gid() { return _gid; }
inline uint64_t egid() { return _egid; }
inline uint64_t pid() { return _pid; }
inline uint64_t ppid() { return _ppid; }
// provide program name for debug messages
const char *progName() const { return executable.c_str(); }
std::string
fullPath(const std::string &filename)
{
if (filename[0] == '/' || cwd.empty())
return filename;
std::string full = cwd;
if (cwd[cwd.size() - 1] != '/')
full += '/';
return full + filename;
}
std::string getcwd() const { return cwd; }
void syscall(int64_t callnum, ThreadContext *tc);
virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i) = 0;
virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i, int width);
virtual void setSyscallArg(ThreadContext *tc,
int i, TheISA::IntReg val) = 0;
virtual void setSyscallReturn(ThreadContext *tc,
SyscallReturn return_value) = 0;
virtual SyscallDesc *getDesc(int callnum) = 0;
/**
* Find an emulated device driver.
*
* @param filename Name of the device (under /dev)
* @return Pointer to driver object if found, else NULL
*/
EmulatedDriver *findDriver(std::string filename);
// This function acts as a callback to update the bias value in
// the object file because the parameters needed to calculate the
// bias are not available when the object file is created.
void updateBias();
ObjectFile *getInterpreter();
Addr getBias();
Addr getStartPC();
};
#endif // __PROCESS_HH__