/*
 * 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 "arch/registers.hh"
#include "base/loader/memory_image.hh"
#include "base/statistics.hh"
#include "base/types.hh"
#include "config/the_isa.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 Loader
{
class ObjectFile;
} // namespace Loader

struct ProcessParams;

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

class Process : public SimObject
{
  public:
    Process(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();

    // override of virtual SimObject method: register statistics
    void regStats() override;

    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;

    Stats::Scalar numSyscalls;  // track how many system calls are executed

    // 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(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(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;
};

#endif // __PROCESS_HH__
