/*
 * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
 * Copyright (c) 2001-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.
 */

#ifndef __PROCESS_HH__
#define __PROCESS_HH__

#include <inttypes.h>

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "base/loader/memory_image.hh"
#include "base/statistics.hh"
#include "base/types.hh"
#include "mem/se_translating_port_proxy.hh"
#include "sim/fd_array.hh"
#include "sim/fd_entry.hh"
#include "sim/mem_state.hh"
#include "sim/sim_object.hh"

namespace gem5
{

GEM5_DEPRECATED_NAMESPACE(Loader, loader);
namespace loader
{
class ObjectFile;
} // namespace loader

struct ProcessParams;

class EmulatedDriver;
class EmulationPageTable;
class SEWorkload;
class SyscallDesc;
class SyscallReturn;
class System;
class ThreadContext;

class Process : public SimObject
{
  public:
    Process(const ProcessParams &params, EmulationPageTable *pTable,
            loader::ObjectFile *obj_file);

    void serialize(CheckpointOut &cp) const override;
    void unserialize(CheckpointIn &cp) override;

    void init() override;
    void initState() override;
    DrainState drain() override;

    virtual void syscall(ThreadContext *tc) { numSyscalls++; }

    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; }
    inline uint64_t pgid() { return _pgid; }
    inline void pgid(uint64_t pgid) { _pgid = pgid; }
    inline uint64_t tgid() { return _tgid; }

    const char *progName() const { return executable.c_str(); }

    /**
     * Find an emulated device driver.
     *
     * @param filename Name of the device (under /dev)
     * @return Pointer to driver object if found, else nullptr
     */
    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();
    Addr getBias();
    Addr getStartPC();
    loader::ObjectFile *getInterpreter();

    // This function allocates physical memory as backing store, and then maps
    // it into the virtual address space of the process. The range of virtual
    // addresses being configured starts at the address "vaddr" and is of size
    // "size" bytes. If some part of this range of virtual addresses is already
    // configured, this function will error out unless "clobber" is set. If
    // clobber is set, then those existing mappings will be replaced.
    //
    // If the beginning or end of the virtual address range does not perfectly
    // align to page boundaries, it will be expanded in either direction until
    // it does. This function will therefore set up *at least* the range
    // requested, and may configure more if necessary.
    void allocateMem(Addr vaddr, int64_t size, bool clobber=false);

    /// Attempt to fix up a fault at vaddr by allocating a page on the stack.
    /// @return Whether the fault has been fixed.
    bool fixupFault(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);
    }

    /**
     * After delegating a thread context to a child process
     * no longer should relate to the ThreadContext
     */
    void revokeThreadContext(int context_id);

    /**
     * Does mmap region grow upward or downward from mmapEnd?  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.
     * This function exists primarily to expose the map operation to
     * python, so that configuration scripts can set up mappings in SE mode.
     *
     * @param vaddr The starting virtual address of the range.
     * @param paddr The starting physical address of the range.
     * @param size The length of the range in bytes.
     * @param cacheable Specifies whether accesses are cacheable.
     * @return True if the map operation was successful.  (At this
     *           point in time, the map operation always succeeds.)
     */
    bool map(Addr vaddr, Addr paddr, int size, bool cacheable = true);

    void replicatePage(Addr vaddr, Addr new_paddr, ThreadContext *old_tc,
                       ThreadContext *new_tc, bool alloc_page);

    virtual void clone(ThreadContext *old_tc, ThreadContext *new_tc,
                       Process *new_p, RegVal flags);

    // thread contexts associated with this process
    std::vector<ContextID> contextIds;

    // system object which owns this process
    System *system;

    SEWorkload *seWorkload;

    // flag for using architecture specific page table
    bool useArchPT;
    // running KVM requires special initialization
    bool kvmInSE;
    // flag for using the process as a thread which shares page tables
    bool useForClone;

    EmulationPageTable *pTable;

    // Memory proxy for initial image load.
    std::unique_ptr<SETranslatingPortProxy> initVirtMem;

    /**
     * Each instance of a Loader subclass will have a chance to try to load
     * an object file when tryLoaders is called. If they can't because they
     * aren't compatible with it (wrong arch, wrong OS, etc), then they
     * silently fail by returning nullptr so other loaders can try.
     */
    class Loader
    {
      public:
        Loader();

        /* Loader instances are singletons. */
        Loader(const Loader &) = delete;
        void operator=(const Loader &) = delete;

        virtual ~Loader() {}

        /**
         * Each subclass needs to implement this method. If the loader is
         * compatible with the passed in object file, it should return the
         * created Process object corresponding to it. If not, it should fail
         * silently and return nullptr. If there's a non-compatibliity related
         * error like file IO errors, etc., those should fail non-silently
         * with a panic or fail as normal.
         */
        virtual Process *load(const ProcessParams &params,
                              loader::ObjectFile *obj_file) = 0;
    };

    // Try all the Loader instance's "load" methods one by one until one is
    // successful. If none are, complain and fail.
    static Process *tryLoaders(const ProcessParams &params,
                               loader::ObjectFile *obj_file);

    loader::ObjectFile *objFile;
    loader::MemoryImage image;
    loader::MemoryImage interpImage;
    std::vector<std::string> argv;
    std::vector<std::string> envp;
    std::string executable;

    /**
     * Return an absolute path given a relative path paired with the current
     * working directory of the process running under simulation.
     *
     * @param path The relative path (generally a filename) that needs the
     * current working directory prepended.
     * @param host_fs A flag which determines whether to return a
     * path for the host filesystem or the filesystem of the process running
     * under simulation. Only matters if filesysem redirection is used to
     * replace files (or directories) that would normally appear via the
     * host filesystem.
     * @return String containing an absolute path.
     */
    std::string absolutePath(const std::string &path, bool host_fs);

    /**
     * Redirect file path if it matches any keys initialized by system object.
     * @param filename An input parameter containing either a relative path
     * or an absolute path. If given a relative path, the path will be
     * prepended to the current working directory of the simulation with
     * respect to the host filesystem.
     * @return String containing an absolute path.
     */
    std::string checkPathRedirect(const std::string &filename);

    /**
     * The cwd members are used to track changes to the current working
     * directory for the purpose of executing system calls which depend on
     * relative paths (i.e. open, chdir).
     *
     * The tgt member and host member may differ if the path for the current
     * working directory is redirected to point to a different location
     * (i.e. `cd /proc` should point to '$(gem5_repo)/m5out/fs/proc'
     * instead of '/proc').
     */
    std::string tgtCwd;
    std::string hostCwd;

    // Syscall emulation uname release.
    std::string release;

    // Id of the owner of the process
    uint64_t _uid;
    uint64_t _euid;
    uint64_t _gid;
    uint64_t _egid;

    // pid of the process and it's parent
    uint64_t _pid;
    uint64_t _ppid;
    uint64_t _pgid;
    uint64_t _tgid;

    // Emulated drivers available to this process
    std::vector<EmulatedDriver *> drivers;

    std::shared_ptr<FDArray> fds;

    bool *exitGroup;
    std::shared_ptr<MemState> memState;

    /**
     * Calls a futex wakeup at the address specified by this pointer when
     * this process exits.
     */
    uint64_t childClearTID;

    // Process was forked with SIGCHLD set.
    bool *sigchld;

    // Contexts to wake up when this thread exits or calls execve
    std::vector<ContextID> vforkContexts;

    // Track how many system calls are executed
    statistics::Scalar numSyscalls;
};

} // namespace gem5

#endif // __PROCESS_HH__
