process.hh revision 11801:cd7f3a1dbf55
16145Snate@binkert.org/*
26145Snate@binkert.org * Copyright (c) 2014 Advanced Micro Devices, Inc.
36145Snate@binkert.org * Copyright (c) 2001-2005 The Regents of The University of Michigan
46145Snate@binkert.org * All rights reserved.
56145Snate@binkert.org *
66145Snate@binkert.org * Redistribution and use in source and binary forms, with or without
76145Snate@binkert.org * modification, are permitted provided that the following conditions are
86145Snate@binkert.org * met: redistributions of source code must retain the above copyright
96145Snate@binkert.org * notice, this list of conditions and the following disclaimer;
106145Snate@binkert.org * redistributions in binary form must reproduce the above copyright
116145Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
126145Snate@binkert.org * documentation and/or other materials provided with the distribution;
136145Snate@binkert.org * neither the name of the copyright holders nor the names of its
146145Snate@binkert.org * contributors may be used to endorse or promote products derived from
156145Snate@binkert.org * this software without specific prior written permission.
166145Snate@binkert.org *
176145Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
186145Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
196145Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
206145Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
216145Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
226145Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
236145Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246145Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256145Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266145Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
276145Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286145Snate@binkert.org *
297454Snate@binkert.org * Authors: Nathan Binkert
307454Snate@binkert.org *          Steve Reinhardt
317454Snate@binkert.org */
327054Snate@binkert.org
337054Snate@binkert.org#ifndef __PROCESS_HH__
347054Snate@binkert.org#define __PROCESS_HH__
357054Snate@binkert.org
367054Snate@binkert.org#include <array>
376154Snate@binkert.org#include <map>
386154Snate@binkert.org#include <string>
396145Snate@binkert.org#include <vector>
407055Snate@binkert.org
417454Snate@binkert.org#include "arch/registers.hh"
427454Snate@binkert.org#include "base/statistics.hh"
437055Snate@binkert.org#include "base/types.hh"
446145Snate@binkert.org#include "config/the_isa.hh"
456145Snate@binkert.org#include "mem/se_translating_port_proxy.hh"
467054Snate@binkert.org#include "sim/fd_entry.hh"
477054Snate@binkert.org#include "sim/sim_object.hh"
486145Snate@binkert.org
496145Snate@binkert.orgstruct LiveProcessParams;
506145Snate@binkert.orgstruct ProcessParams;
516145Snate@binkert.org
527054Snate@binkert.orgclass EmulatedDriver;
536145Snate@binkert.orgclass PageTableBase;
547054Snate@binkert.orgclass SyscallDesc;
557454Snate@binkert.orgclass SyscallReturn;
566145Snate@binkert.orgclass System;
577054Snate@binkert.orgclass ThreadContext;
587454Snate@binkert.org
596145Snate@binkert.orgtemplate<class IntType>
606145Snate@binkert.orgstruct AuxVector
617054Snate@binkert.org{
627454Snate@binkert.org    IntType a_type;
636145Snate@binkert.org    IntType a_val;
647054Snate@binkert.org
656145Snate@binkert.org    AuxVector()
666145Snate@binkert.org    {}
677054Snate@binkert.org
687454Snate@binkert.org    AuxVector(IntType type, IntType val);
697054Snate@binkert.org};
706145Snate@binkert.org
717054Snate@binkert.orgclass Process : public SimObject
726145Snate@binkert.org{
737054Snate@binkert.org  public:
747054Snate@binkert.org
757054Snate@binkert.org    /// Pointer to object representing the system this process is
767454Snate@binkert.org    /// running on.
776145Snate@binkert.org    System *system;
787054Snate@binkert.org
797454Snate@binkert.org    // thread contexts associated with this process
807054Snate@binkert.org    std::vector<ContextID> contextIds;
817054Snate@binkert.org
827054Snate@binkert.org    // number of CPUs (esxec contexts, really) assigned to this process.
837054Snate@binkert.org    unsigned int numCpus() { return contextIds.size(); }
847054Snate@binkert.org
857054Snate@binkert.org    // record of blocked context
867454Snate@binkert.org    struct WaitRec
877054Snate@binkert.org    {
887454Snate@binkert.org        Addr waitChan;
897454Snate@binkert.org        ThreadContext *waitingContext;
906145Snate@binkert.org
916145Snate@binkert.org        WaitRec(Addr chan, ThreadContext *ctx)
927054Snate@binkert.org            : waitChan(chan), waitingContext(ctx)
937054Snate@binkert.org        {       }
946145Snate@binkert.org    };
957054Snate@binkert.org
967054Snate@binkert.org    // list of all blocked contexts
976145Snate@binkert.org    std::list<WaitRec> waitList;
986145Snate@binkert.org
997054Snate@binkert.org    Addr brk_point;             // top of the data segment
1007054Snate@binkert.org
1016145Snate@binkert.org    Addr stack_base;            // stack segment base (highest address)
1027054Snate@binkert.org    unsigned stack_size;        // initial stack size
1036145Snate@binkert.org    Addr stack_min;             // lowest address accessed on the stack
1046145Snate@binkert.org
1057054Snate@binkert.org    // The maximum size allowed for the stack.
1067054Snate@binkert.org    Addr max_stack_size;
1076145Snate@binkert.org
1087054Snate@binkert.org    // addr to use for next stack region (for multithreaded apps)
1097054Snate@binkert.org    Addr next_thread_stack_base;
1107054Snate@binkert.org
1117054Snate@binkert.org    // Base of region for mmaps (when user doesn't specify an address).
1127054Snate@binkert.org    Addr mmap_end;
1136145Snate@binkert.org
1146145Snate@binkert.org    // Does mmap region grow upward or downward from mmap_end?  Most
1156145Snate@binkert.org    // platforms grow downward, but a few (such as Alpha) grow upward
1167054Snate@binkert.org    // instead, so they can override thie method to return false.
1177054Snate@binkert.org    virtual bool mmapGrowsDown() const { return true; }
1186145Snate@binkert.org
1197054Snate@binkert.org    // Base of region for nxm data
1206145Snate@binkert.org    Addr nxm_start;
1216145Snate@binkert.org    Addr nxm_end;
1227054Snate@binkert.org
1237054Snate@binkert.org    Stats::Scalar num_syscalls;       // number of syscalls executed
1246145Snate@binkert.org
1257054Snate@binkert.org  protected:
1267054Snate@binkert.org    // constructor
1276145Snate@binkert.org    Process(ProcessParams *params);
1286145Snate@binkert.org
1297454Snate@binkert.org    void initState() override;
1307054Snate@binkert.org
1316145Snate@binkert.org    DrainState drain() override;
1327054Snate@binkert.org
1336145Snate@binkert.org  public:
1346145Snate@binkert.org
1357054Snate@binkert.org    // flag for using architecture specific page table
1367054Snate@binkert.org    bool useArchPT;
1376145Snate@binkert.org    // running KvmCPU in SE mode requires special initialization
1387054Snate@binkert.org    bool kvmInSE;
1397054Snate@binkert.org
1407054Snate@binkert.org    PageTableBase* pTable;
1417054Snate@binkert.org
1426145Snate@binkert.org  protected:
1437054Snate@binkert.org    /// Memory proxy for initialization (image loading)
1447054Snate@binkert.org    SETranslatingPortProxy initVirtMem;
1457054Snate@binkert.org
1466145Snate@binkert.org  private:
1477054Snate@binkert.org    static const int NUM_FDS = 1024;
1487054Snate@binkert.org
1497054Snate@binkert.org    // File descriptor remapping support.
1507054Snate@binkert.org    std::shared_ptr<std::array<FDEntry, NUM_FDS>> fd_array;
1517054Snate@binkert.org
1527054Snate@binkert.org    // Standard file descriptor options for initialization and checkpoints.
1536145Snate@binkert.org    std::map<std::string, int> imap;
1547054Snate@binkert.org    std::map<std::string, int> oemap;
1557054Snate@binkert.org
1566145Snate@binkert.org  public:
1577054Snate@binkert.org    // inherit file descriptor map from another process (necessary for clone)
1587054Snate@binkert.org    void inheritFDArray(Process *p);
1597054Snate@binkert.org
1607054Snate@binkert.org    // override of virtual SimObject method: register statistics
1617054Snate@binkert.org    void regStats() override;
1627054Snate@binkert.org
1637054Snate@binkert.org    // After getting registered with system object, tell process which
1647054Snate@binkert.org    // system-wide context id it is assigned.
1657054Snate@binkert.org    void assignThreadContext(ContextID context_id)
1667054Snate@binkert.org    {
1677054Snate@binkert.org        contextIds.push_back(context_id);
1687054Snate@binkert.org    }
1697054Snate@binkert.org
1706145Snate@binkert.org    // Find a free context to use
1717054Snate@binkert.org    ThreadContext *findFreeContext();
1726145Snate@binkert.org
1737054Snate@binkert.org    // provide program name for debug messages
1747054Snate@binkert.org    virtual const char *progName() const { return "<unknown>"; }
1757054Snate@binkert.org
1767054Snate@binkert.org    // generate new target fd for sim_fd
1777054Snate@binkert.org    int allocFD(int sim_fd, const std::string& filename, int flags, int mode,
1787054Snate@binkert.org                bool pipe);
1797454Snate@binkert.org
1807054Snate@binkert.org    // disassociate target fd with simulator fd and cleanup subsidiary fields
1817054Snate@binkert.org    void resetFDEntry(int tgt_fd);
1827054Snate@binkert.org
1837454Snate@binkert.org    // look up simulator fd for given target fd
1847454Snate@binkert.org    int getSimFD(int tgt_fd);
1857054Snate@binkert.org
1867054Snate@binkert.org    // look up fd entry for a given target fd
1877054Snate@binkert.org    FDEntry *getFDEntry(int tgt_fd);
1887054Snate@binkert.org
1897054Snate@binkert.org    // look up target fd for given host fd
1907054Snate@binkert.org    // Assumes a 1:1 mapping between target file descriptor and host file
1917454Snate@binkert.org    // descriptor. Given the current API, this must be true given that it's
1927454Snate@binkert.org    // not possible to map multiple target file descriptors to the same host
1937454Snate@binkert.org    // file descriptor
1947054Snate@binkert.org    int getTgtFD(int sim_fd);
1956145Snate@binkert.org
1966145Snate@binkert.org    // fix all offsets for currently open files and save them
1977054Snate@binkert.org    void fixFileOffsets();
1986145Snate@binkert.org
1996145Snate@binkert.org    // find all offsets for currently open files and save them
2007054Snate@binkert.org    void findFileOffsets();
2017054Snate@binkert.org
2026145Snate@binkert.org    // set the source of this read pipe for a checkpoint resume
2037054Snate@binkert.org    void setReadPipeSource(int read_pipe_fd, int source_fd);
2047054Snate@binkert.org
2057054Snate@binkert.org    virtual void syscall(int64_t callnum, ThreadContext *tc) = 0;
2067054Snate@binkert.org
2076145Snate@binkert.org    void allocateMem(Addr vaddr, int64_t size, bool clobber = false);
2086145Snate@binkert.org
2096145Snate@binkert.org    /// Attempt to fix up a fault at vaddr by allocating a page on the stack.
2107054Snate@binkert.org    /// @return Whether the fault has been fixed.
2117054Snate@binkert.org    bool fixupStackFault(Addr vaddr);
2126145Snate@binkert.org
2137054Snate@binkert.org    /**
2147054Snate@binkert.org     * Maps a contiguous range of virtual addresses in this process's
2157054Snate@binkert.org     * address space to a contiguous range of physical addresses.
2167054Snate@binkert.org     * This function exists primarily to expose the map operation to
2176145Snate@binkert.org     * python, so that configuration scripts can set up mappings in SE mode.
2186145Snate@binkert.org     *
2196145Snate@binkert.org     * @param vaddr The starting virtual address of the range.
2207054Snate@binkert.org     * @param paddr The starting physical address of the range.
2217054Snate@binkert.org     * @param size The length of the range in bytes.
2226145Snate@binkert.org     * @param cacheable Specifies whether accesses are cacheable.
2237054Snate@binkert.org     * @return True if the map operation was successful.  (At this
2247054Snate@binkert.org     *           point in time, the map operation always succeeds.)
2256145Snate@binkert.org     */
2266145Snate@binkert.org    bool map(Addr vaddr, Addr paddr, int size, bool cacheable = true);
227
228    void serialize(CheckpointOut &cp) const override;
229    void unserialize(CheckpointIn &cp) override;
230
231  public:
232    // Id of the owner of the process
233    uint64_t _uid;
234    uint64_t _euid;
235    uint64_t _gid;
236    uint64_t _egid;
237
238    // pid of the process and it's parent
239    uint64_t _pid;
240    uint64_t _ppid;
241
242};
243
244//
245// "Live" process with system calls redirected to host system
246//
247class ObjectFile;
248class LiveProcess : public Process
249{
250  protected:
251    ObjectFile *objFile;
252    std::vector<std::string> argv;
253    std::vector<std::string> envp;
254    std::string cwd;
255    std::string executable;
256
257    LiveProcess(LiveProcessParams *params, ObjectFile *objFile);
258
259    // Emulated drivers available to this process
260    std::vector<EmulatedDriver *> drivers;
261
262  public:
263
264    enum AuxiliaryVectorType {
265        M5_AT_NULL = 0,
266        M5_AT_IGNORE = 1,
267        M5_AT_EXECFD = 2,
268        M5_AT_PHDR = 3,
269        M5_AT_PHENT = 4,
270        M5_AT_PHNUM = 5,
271        M5_AT_PAGESZ = 6,
272        M5_AT_BASE = 7,
273        M5_AT_FLAGS = 8,
274        M5_AT_ENTRY = 9,
275        M5_AT_NOTELF = 10,
276        M5_AT_UID = 11,
277        M5_AT_EUID = 12,
278        M5_AT_GID = 13,
279        M5_AT_EGID = 14,
280        // The following may be specific to Linux
281        M5_AT_PLATFORM = 15,
282        M5_AT_HWCAP = 16,
283        M5_AT_CLKTCK = 17,
284
285        M5_AT_SECURE = 23,
286        M5_BASE_PLATFORM = 24,
287        M5_AT_RANDOM = 25,
288
289        M5_AT_EXECFN = 31,
290
291        M5_AT_VECTOR_SIZE = 44
292    };
293
294    inline uint64_t uid() { return _uid; }
295    inline uint64_t euid() { return _euid; }
296    inline uint64_t gid() { return _gid; }
297    inline uint64_t egid() { return _egid; }
298    inline uint64_t pid() { return _pid; }
299    inline uint64_t ppid() { return _ppid; }
300
301    // provide program name for debug messages
302    virtual const char *progName() const { return executable.c_str(); }
303
304    std::string
305    fullPath(const std::string &filename)
306    {
307        if (filename[0] == '/' || cwd.empty())
308            return filename;
309
310        std::string full = cwd;
311
312        if (cwd[cwd.size() - 1] != '/')
313            full += '/';
314
315        return full + filename;
316    }
317
318    std::string getcwd() const { return cwd; }
319
320    virtual void syscall(int64_t callnum, ThreadContext *tc);
321
322    virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i) = 0;
323    virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i, int width);
324    virtual void setSyscallArg(ThreadContext *tc,
325            int i, TheISA::IntReg val) = 0;
326    virtual void setSyscallReturn(ThreadContext *tc,
327            SyscallReturn return_value) = 0;
328
329    virtual SyscallDesc *getDesc(int callnum) = 0;
330
331    /**
332     * Find an emulated device driver.
333     *
334     * @param filename Name of the device (under /dev)
335     * @return Pointer to driver object if found, else NULL
336     */
337    EmulatedDriver *findDriver(std::string filename);
338
339    // This function acts as a callback to update the bias value in
340    // the object file because the parameters needed to calculate the
341    // bias are not available when the object file is created.
342    void updateBias();
343
344    ObjectFile *getInterpreter();
345
346    Addr getBias();
347    Addr getStartPC();
348
349    // this function is used to create the LiveProcess object, since
350    // we can't tell which subclass of LiveProcess to use until we
351    // open and look at the object file.
352    static LiveProcess *create(LiveProcessParams *params);
353};
354
355
356#endif // __PROCESS_HH__
357