summaryrefslogtreecommitdiff
path: root/src/kern/linux/linux.hh
blob: b24ee389525108ed169475b125c50a9765ef4c75 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/*
 * Copyright (c) 2004-2009 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: Ali Saidi
 */

#ifndef __LINUX_HH__
#define __LINUX_HH__

#include "base/types.hh"

#include <string>

#include "kern/operatingsystem.hh"
#include "sim/process.hh"

class ThreadContext;

///
/// This class encapsulates the types, structures, constants,
/// functions, and syscall-number mappings specific to the Alpha Linux
/// syscall interface.
///
class Linux : public OperatingSystem
{

  public:

    //@{
    /// Basic Linux types.
    typedef uint64_t size_t;
    typedef uint64_t off_t;
    typedef int64_t time_t;
    typedef int64_t clock_t;
    typedef uint32_t uid_t;
    typedef uint32_t gid_t;
    //@}

    /// Stat buffer.  Note that we can't call it 'stat' since that
    /// gets #defined to something else on some systems. This type
    /// can be specialized by architecture specific "Linux" classes
    typedef struct {
        uint32_t        st_dev;         //!< device
        uint32_t        st_ino;         //!< inode
        uint32_t        st_mode;        //!< mode
        uint32_t        st_nlink;       //!< link count
        uint32_t        st_uid;         //!< owner's user ID
        uint32_t        st_gid;         //!< owner's group ID
        uint32_t        st_rdev;        //!< device number
        int32_t         _pad1;          //!< for alignment
        int64_t         st_size;        //!< file size in bytes
        uint64_t        st_atimeX;      //!< time of last access
        uint64_t        st_mtimeX;      //!< time of last modification
        uint64_t        st_ctimeX;      //!< time of last status change
        uint32_t        st_blksize;     //!< optimal I/O block size
        int32_t         st_blocks;      //!< number of blocks allocated
        uint32_t        st_flags;       //!< flags
        uint32_t        st_gen;         //!< unknown
    } tgt_stat;

    // same for stat64
    typedef struct {
        uint64_t        st_dev;
        uint64_t        st_ino;
        uint64_t        st_rdev;
        int64_t         st_size;
        uint64_t        st_blocks;

        uint32_t        st_mode;
        uint32_t        st_uid;
        uint32_t        st_gid;
        uint32_t        st_blksize;
        uint32_t        st_nlink;
        uint32_t        __pad0;

        uint64_t        st_atimeX;
        uint64_t        st_atime_nsec;
        uint64_t        st_mtimeX;
        uint64_t        st_mtime_nsec;
        uint64_t        st_ctimeX;
        uint64_t        st_ctime_nsec;
        int64_t         ___unused[3];
    } tgt_stat64;

    /// Length of strings in struct utsname (plus 1 for null char).
    static const int _SYS_NMLN = 65;

    /// Interface struct for uname().
    struct utsname {
        char sysname[_SYS_NMLN];        //!< System name.
        char nodename[_SYS_NMLN];       //!< Node name.
        char release[_SYS_NMLN];        //!< OS release.
        char version[_SYS_NMLN];        //!< OS version.
        char machine[_SYS_NMLN];        //!< Machine type.
    };

    /// Limit struct for getrlimit/setrlimit.
    struct rlimit {
        uint64_t  rlim_cur;     //!< soft limit
        uint64_t  rlim_max;     //!< hard limit
    };

    /// For gettimeofday().
    struct timeval {
        int64_t tv_sec;         //!< seconds
        int64_t tv_usec;        //!< microseconds
    };

    /// For clock_gettime().
    struct timespec {
        time_t tv_sec;         //!< seconds
        int64_t tv_nsec;        //!< nanoseconds
    };

    /// Clock ticks per second, for times().
    static const int M5_SC_CLK_TCK = 100;

    /// For times().
    struct tms {
        int64_t tms_utime;      //!< user time
        int64_t tms_stime;      //!< system time
        int64_t tms_cutime;     //!< user time of children
        int64_t tms_cstime;     //!< system time of children
    };

    // For writev/readv
    struct tgt_iovec {
        uint64_t iov_base; // void *
        uint64_t iov_len;
    };

    //@{
    /// ioctl() command codes.
    static const unsigned TGT_TCGETS     = 0x5401;
    static const unsigned TGT_TCGETA     = 0x5405;
    static const unsigned TGT_TCSETAW    = 0x5407;
    static const unsigned TGT_FIONREAD   = 0x541B;
    //@}

    /// Return true for the ioctl codes for which we return ENOTTY
    /// *without* printing a warning, since we know that ENOTTY is the
    /// correct thing to return (and not just a sign that we don't
    /// recognize the ioctl code.
    static bool
    isTtyReq(unsigned req)
    {
        switch (req) {
          case TGT_FIONREAD:
          case TGT_TCSETAW:
          case TGT_TCGETS:
          case TGT_TCGETA:
            return true;
          default:
            return false;
        }
    }


    /// Resource constants for getrlimit().
    static const unsigned TGT_RLIMIT_CPU = 0;
    static const unsigned TGT_RLIMIT_FSIZE = 1;
    static const unsigned TGT_RLIMIT_DATA = 2;
    static const unsigned TGT_RLIMIT_STACK = 3;
    static const unsigned TGT_RLIMIT_CORE = 4;
    static const unsigned TGT_RLIMIT_RSS = 5;
    static const unsigned TGT_RLIMIT_NPROC = 6;
    static const unsigned TGT_RLIMIT_NOFILE = 7;
    static const unsigned TGT_RLIMIT_MEMLOCK = 8;
    static const unsigned TGT_RLIMIT_AS = 9;
    static const unsigned TGT_RLIMIT_LOCKS = 10;
    static const unsigned TGT_RLIMIT_SIGPENDING = 11;
    static const unsigned TGT_RLIMIT_MSGQUEUE = 12;
    static const unsigned TGT_RLIMIT_NICE = 13;
    static const unsigned TGT_RLIMIT_RTPRIO = 14;
    static const unsigned TGT_RLIMIT_RTTIME = 15;
    static const unsigned TGT_RLIM_NLIMITS = 16;

    /// For getrusage().
    static const int TGT_RUSAGE_SELF     = 0;
    static const int TGT_RUSAGE_CHILDREN = -1;
    static const int TGT_RUSAGE_BOTH     = -2;

    struct rusage {
        struct timeval ru_utime;        //!< user time used
        struct timeval ru_stime;        //!< system time used
        int64_t ru_maxrss;              //!< max rss
        int64_t ru_ixrss;               //!< integral shared memory size
        int64_t ru_idrss;               //!< integral unshared data "
        int64_t ru_isrss;               //!< integral unshared stack "
        int64_t ru_minflt;              //!< page reclaims - total vmfaults
        int64_t ru_majflt;              //!< page faults
        int64_t ru_nswap;               //!< swaps
        int64_t ru_inblock;             //!< block input operations
        int64_t ru_oublock;             //!< block output operations
        int64_t ru_msgsnd;              //!< messages sent
        int64_t ru_msgrcv;              //!< messages received
        int64_t ru_nsignals;            //!< signals received
        int64_t ru_nvcsw;               //!< voluntary context switches
        int64_t ru_nivcsw;              //!< involuntary "
    };

    static int openSpecialFile(std::string path, Process *process,
                               ThreadContext *tc);
    static std::string procMeminfo(Process *process, ThreadContext *tc);
    static std::string etcPasswd(Process *process, ThreadContext *tc);

    // For futex system call
    static const unsigned TGT_FUTEX_WAIT  = 0;
    static const unsigned TGT_FUTEX_WAKE  = 1;
    static const unsigned TGT_EAGAIN      = 11;
    static const unsigned TGT_EWOULDBLOCK = TGT_EAGAIN;
    static const unsigned TGT_FUTEX_PRIVATE_FLAG = 128;

    // for *at syscalls
    static const int TGT_AT_FDCWD   = -100;

    // for MREMAP
    static const unsigned TGT_MREMAP_MAYMOVE    = 0x1;
    static const unsigned TGT_MREMAP_FIXED      = 0x2;

    static const unsigned TGT_CLONE_VM              = 0x00000100;
    static const unsigned TGT_CLONE_FS              = 0x00000200;
    static const unsigned TGT_CLONE_FILES           = 0x00000400;
    static const unsigned TGT_CLONE_SIGHAND         = 0x00000800;
    static const unsigned TGT_CLONE_PTRACE          = 0x00002000;
    static const unsigned TGT_CLONE_VFORK           = 0x00004000;
    static const unsigned TGT_CLONE_PARENT          = 0x00008000;
    static const unsigned TGT_CLONE_THREAD          = 0x00010000;
    static const unsigned TGT_CLONE_NEWNS           = 0x00020000;
    static const unsigned TGT_CLONE_SYSVSEM         = 0x00040000;
    static const unsigned TGT_CLONE_SETTLS          = 0x00080000;
    static const unsigned TGT_CLONE_PARENT_SETTID   = 0x00100000;
    static const unsigned TGT_CLONE_CHILD_CLEARTID  = 0x00200000;
    static const unsigned TGT_CLONE_DETACHED        = 0x00400000;
    static const unsigned TGT_CLONE_UNTRACED        = 0x00800000;
    static const unsigned TGT_CLONE_CHILD_SETTID    = 0x01000000;
    static const unsigned TGT_CLONE_NEWUTS          = 0x04000000;
    static const unsigned TGT_CLONE_NEWIPC          = 0x08000000;
    static const unsigned TGT_CLONE_NEWUSER         = 0x10000000;
    static const unsigned TGT_CLONE_NEWPID          = 0x20000000;
    static const unsigned TGT_CLONE_NEWNET          = 0x40000000;
    static const unsigned TGT_CLONE_IO              = 0x80000000;
};  // class Linux

#endif // __LINUX_HH__