linux.hh revision 2665
112838Sgabeblack@google.com/*
212838Sgabeblack@google.com * Copyright (c) 2004-2005 The Regents of The University of Michigan
312838Sgabeblack@google.com * All rights reserved.
412838Sgabeblack@google.com *
512838Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
612838Sgabeblack@google.com * modification, are permitted provided that the following conditions are
712838Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
812838Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
912838Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1012838Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1112838Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1212838Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1312838Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1412838Sgabeblack@google.com * this software without specific prior written permission.
1512838Sgabeblack@google.com *
1612838Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712838Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812838Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912838Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012838Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112838Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212838Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312838Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412838Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512838Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612838Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712838Sgabeblack@google.com *
2812838Sgabeblack@google.com * Authors: Ali Saidi
2912838Sgabeblack@google.com */
3012838Sgabeblack@google.com
3112952Sgabeblack@google.com#ifndef __LINUX_HH__
3212953Sgabeblack@google.com#define __LINUX_HH__
3312960Sgabeblack@google.com#include "config/full_system.hh"
3412838Sgabeblack@google.com
3513128Sgabeblack@google.com#if FULL_SYSTEM
3612838Sgabeblack@google.com
3712838Sgabeblack@google.comclass Linux {};
3812838Sgabeblack@google.com
3912838Sgabeblack@google.com#else //!FULL_SYSTEM
4012838Sgabeblack@google.com
4112838Sgabeblack@google.com#include <dirent.h>
4212838Sgabeblack@google.com#include <errno.h>
4312994Sgabeblack@google.com#include <fcntl.h>	// for host open() flags
4412838Sgabeblack@google.com#include <string.h>	// for memset()
4512838Sgabeblack@google.com#include <sys/stat.h>
4612838Sgabeblack@google.com#include <sys/types.h>
4712838Sgabeblack@google.com#include <unistd.h>
4812838Sgabeblack@google.com
4912994Sgabeblack@google.com#include "arch/isa_traits.hh"
5012838Sgabeblack@google.com#include "sim/syscall_emul.hh"
5112838Sgabeblack@google.com
5212994Sgabeblack@google.comclass TranslatingPort;
5312994Sgabeblack@google.com
5412994Sgabeblack@google.com///
5512994Sgabeblack@google.com/// This class encapsulates the types, structures, constants,
5612952Sgabeblack@google.com/// functions, and syscall-number mappings specific to the Alpha Linux
5712838Sgabeblack@google.com/// syscall interface.
5812838Sgabeblack@google.com///
5913087Sgabeblack@google.comclass Linux {
6013087Sgabeblack@google.com
6112939Sgabeblack@google.com  public:
6213087Sgabeblack@google.com
6313087Sgabeblack@google.com    //@{
6413087Sgabeblack@google.com    /// Basic Linux types.
6513087Sgabeblack@google.com    typedef uint64_t size_t;
6613087Sgabeblack@google.com    typedef uint64_t off_t;
6712939Sgabeblack@google.com    typedef int64_t time_t;
6812939Sgabeblack@google.com    typedef uint32_t uid_t;
6912939Sgabeblack@google.com    typedef uint32_t gid_t;
7012939Sgabeblack@google.com    //@}
7112939Sgabeblack@google.com
7212939Sgabeblack@google.com#if BSD_HOST
7313254Sgabeblack@google.com    typedef struct stat hst_stat;
7412939Sgabeblack@google.com    typedef struct stat hst_stat64;
7512939Sgabeblack@google.com#else
7612939Sgabeblack@google.com    typedef struct stat hst_stat ;
7712952Sgabeblack@google.com    typedef struct stat64 hst_stat64;
7812952Sgabeblack@google.com#endif
7912952Sgabeblack@google.com
8012952Sgabeblack@google.com    /// Stat buffer.  Note that we can't call it 'stat' since that
8112838Sgabeblack@google.com    /// gets #defined to something else on some systems.
8212952Sgabeblack@google.com    struct tgt_stat {
8312952Sgabeblack@google.com        uint32_t	st_dev;		//!< device
8412838Sgabeblack@google.com        uint32_t	st_ino;		//!< inode
8512838Sgabeblack@google.com        uint32_t	st_mode;	//!< mode
8612952Sgabeblack@google.com        uint32_t	st_nlink;	//!< link count
8712952Sgabeblack@google.com        uint32_t	st_uid;		//!< owner's user ID
8812838Sgabeblack@google.com        uint32_t	st_gid;		//!< owner's group ID
8912952Sgabeblack@google.com        uint32_t	st_rdev;	//!< device number
9012952Sgabeblack@google.com        int32_t		_pad1;		//!< for alignment
9112838Sgabeblack@google.com        int64_t		st_size;	//!< file size in bytes
9212838Sgabeblack@google.com        uint64_t	st_atimeX;	//!< time of last access
9312838Sgabeblack@google.com        uint64_t	st_mtimeX;	//!< time of last modification
9412838Sgabeblack@google.com        uint64_t	st_ctimeX;	//!< time of last status change
9512952Sgabeblack@google.com        uint32_t	st_blksize;	//!< optimal I/O block size
9612952Sgabeblack@google.com        int32_t		st_blocks;	//!< number of blocks allocated
9712838Sgabeblack@google.com        uint32_t	st_flags;	//!< flags
9812838Sgabeblack@google.com        uint32_t	st_gen;		//!< unknown
9912838Sgabeblack@google.com    };
10012838Sgabeblack@google.com
10112838Sgabeblack@google.com    // same for stat64
10212838Sgabeblack@google.com    struct tgt_stat64 {
10312952Sgabeblack@google.com        uint64_t	st_dev;
10412838Sgabeblack@google.com        uint64_t	st_ino;
10512838Sgabeblack@google.com        uint64_t	st_rdev;
10612838Sgabeblack@google.com        int64_t		st_size;
10712838Sgabeblack@google.com        uint64_t	st_blocks;
10812952Sgabeblack@google.com
10912838Sgabeblack@google.com        uint32_t	st_mode;
11012952Sgabeblack@google.com        uint32_t	st_uid;
11112952Sgabeblack@google.com        uint32_t	st_gid;
11212952Sgabeblack@google.com        uint32_t	st_blksize;
11312952Sgabeblack@google.com        uint32_t	st_nlink;
11412952Sgabeblack@google.com        uint32_t	__pad0;
11512838Sgabeblack@google.com
11612838Sgabeblack@google.com        uint64_t	tgt_st_atime;
11712838Sgabeblack@google.com        uint64_t 	st_atime_nsec;
11812838Sgabeblack@google.com        uint64_t	tgt_st_mtime;
11912952Sgabeblack@google.com        uint64_t	st_mtime_nsec;
12012838Sgabeblack@google.com        uint64_t	tgt_st_ctime;
12112952Sgabeblack@google.com        uint64_t	st_ctime_nsec;
12212952Sgabeblack@google.com        int64_t		___unused[3];
12312838Sgabeblack@google.com    };
12412838Sgabeblack@google.com
12512838Sgabeblack@google.com    /// Length of strings in struct utsname (plus 1 for null char).
12612952Sgabeblack@google.com    static const int _SYS_NMLN = 65;
12712838Sgabeblack@google.com
12812952Sgabeblack@google.com    /// Interface struct for uname().
12912838Sgabeblack@google.com    struct utsname {
13012838Sgabeblack@google.com        char sysname[_SYS_NMLN];	//!< System name.
13112838Sgabeblack@google.com        char nodename[_SYS_NMLN];	//!< Node name.
13212952Sgabeblack@google.com        char release[_SYS_NMLN];	//!< OS release.
13312838Sgabeblack@google.com        char version[_SYS_NMLN];	//!< OS version.
13412952Sgabeblack@google.com        char machine[_SYS_NMLN];	//!< Machine type.
13512838Sgabeblack@google.com    };
13612838Sgabeblack@google.com
13712952Sgabeblack@google.com    /// Limit struct for getrlimit/setrlimit.
13812952Sgabeblack@google.com    struct rlimit {
13912838Sgabeblack@google.com        uint64_t  rlim_cur;	//!< soft limit
14012952Sgabeblack@google.com        uint64_t  rlim_max;	//!< hard limit
14112952Sgabeblack@google.com    };
14212952Sgabeblack@google.com
14312838Sgabeblack@google.com    /// For gettimeofday().
14412838Sgabeblack@google.com    struct timeval {
14512838Sgabeblack@google.com        int64_t tv_sec;		//!< seconds
14612838Sgabeblack@google.com        int64_t tv_usec;	//!< microseconds
14712838Sgabeblack@google.com    };
14812838Sgabeblack@google.com
14912952Sgabeblack@google.com    // For writev/readv
15012838Sgabeblack@google.com    struct tgt_iovec {
15112838Sgabeblack@google.com        uint64_t iov_base; // void *
15212838Sgabeblack@google.com        uint64_t iov_len;
15312838Sgabeblack@google.com    };
15412838Sgabeblack@google.com
15512952Sgabeblack@google.com
15612838Sgabeblack@google.com    /// For getrusage().
15712838Sgabeblack@google.com    struct rusage {
15812838Sgabeblack@google.com        struct timeval ru_utime;	//!< user time used
15912838Sgabeblack@google.com        struct timeval ru_stime;	//!< system time used
16012838Sgabeblack@google.com        int64_t ru_maxrss;		//!< max rss
16112952Sgabeblack@google.com        int64_t ru_ixrss;		//!< integral shared memory size
16212952Sgabeblack@google.com        int64_t ru_idrss;		//!< integral unshared data "
16312838Sgabeblack@google.com        int64_t ru_isrss;		//!< integral unshared stack "
16412838Sgabeblack@google.com        int64_t ru_minflt;		//!< page reclaims - total vmfaults
16512838Sgabeblack@google.com        int64_t ru_majflt;		//!< page faults
16612838Sgabeblack@google.com        int64_t ru_nswap;		//!< swaps
16712838Sgabeblack@google.com        int64_t ru_inblock;		//!< block input operations
16812952Sgabeblack@google.com        int64_t ru_oublock;		//!< block output operations
16912952Sgabeblack@google.com        int64_t ru_msgsnd;		//!< messages sent
17012838Sgabeblack@google.com        int64_t ru_msgrcv;		//!< messages received
17112838Sgabeblack@google.com        int64_t ru_nsignals;		//!< signals received
17212838Sgabeblack@google.com        int64_t ru_nvcsw;		//!< voluntary context switches
17312838Sgabeblack@google.com        int64_t ru_nivcsw;		//!< involuntary "
17412838Sgabeblack@google.com    };
17512952Sgabeblack@google.com
17612838Sgabeblack@google.com    /// Helper function to convert a host stat buffer to a target stat
17712838Sgabeblack@google.com    /// buffer.  Also copies the target buffer out to the simulated
17812838Sgabeblack@google.com    /// memory space.  Used by stat(), fstat(), and lstat().
17912838Sgabeblack@google.com#if !BSD_HOST
18012838Sgabeblack@google.com    static void
18112952Sgabeblack@google.com    copyOutStatBuf(TranslatingPort *mem, Addr addr, hst_stat *host)
18212838Sgabeblack@google.com    {
18312838Sgabeblack@google.com        using namespace TheISA;
18412838Sgabeblack@google.com
18512838Sgabeblack@google.com        TypedBufferArg<Linux::tgt_stat> tgt(addr);
18612838Sgabeblack@google.com
18712952Sgabeblack@google.com        tgt->st_dev = htog(host->st_dev);
18812838Sgabeblack@google.com        tgt->st_ino = htog(host->st_ino);
18912838Sgabeblack@google.com        tgt->st_mode = htog(host->st_mode);
19012838Sgabeblack@google.com        tgt->st_nlink = htog(host->st_nlink);
19112838Sgabeblack@google.com        tgt->st_uid = htog(host->st_uid);
19212838Sgabeblack@google.com        tgt->st_gid = htog(host->st_gid);
19312952Sgabeblack@google.com        tgt->st_rdev = htog(host->st_rdev);
19412838Sgabeblack@google.com        tgt->st_size = htog(host->st_size);
19512838Sgabeblack@google.com        tgt->st_atimeX = htog(host->st_atime);
19612838Sgabeblack@google.com        tgt->st_mtimeX = htog(host->st_mtime);
19712838Sgabeblack@google.com        tgt->st_ctimeX = htog(host->st_ctime);
19812838Sgabeblack@google.com        tgt->st_blksize = htog(host->st_blksize);
19913128Sgabeblack@google.com        tgt->st_blocks = htog(host->st_blocks);
20013128Sgabeblack@google.com
20113128Sgabeblack@google.com        tgt.copyOut(mem);
20213303Sgabeblack@google.com    }
20313128Sgabeblack@google.com#else
20413128Sgabeblack@google.com    // Third version for bsd systems which no longer have any support for
20513128Sgabeblack@google.com    // the old stat() call and stat() is actually a stat64()
20612838Sgabeblack@google.com    static void
20712838Sgabeblack@google.com    copyOutStatBuf(TranslatingPort *mem, Addr addr, hst_stat64 *host)
20812838Sgabeblack@google.com    {
20912838Sgabeblack@google.com        using namespace TheISA;
21012838Sgabeblack@google.com
21112838Sgabeblack@google.com        TypedBufferArg<Linux::tgt_stat> tgt(addr);
21213128Sgabeblack@google.com
21313128Sgabeblack@google.com        tgt->st_dev = htog(host->st_dev);
21413128Sgabeblack@google.com        tgt->st_ino = htog(host->st_ino);
21512952Sgabeblack@google.com        tgt->st_mode = htog(host->st_mode);
21613128Sgabeblack@google.com        tgt->st_nlink = htog(host->st_nlink);
21712952Sgabeblack@google.com        tgt->st_uid = htog(host->st_uid);
21812838Sgabeblack@google.com        tgt->st_gid = htog(host->st_gid);
21912838Sgabeblack@google.com        tgt->st_rdev = htog(host->st_rdev);
22012838Sgabeblack@google.com        tgt->st_size = htog(host->st_size);
22112838Sgabeblack@google.com        tgt->st_atimeX = htog(host->st_atime);
22212838Sgabeblack@google.com        tgt->st_mtimeX = htog(host->st_mtime);
22313128Sgabeblack@google.com        tgt->st_ctimeX = htog(host->st_ctime);
22413128Sgabeblack@google.com        tgt->st_blksize = htog(host->st_blksize);
22513128Sgabeblack@google.com        tgt->st_blocks = htog(host->st_blocks);
22612952Sgabeblack@google.com
22713128Sgabeblack@google.com        tgt.copyOut(mem);
22812952Sgabeblack@google.com    }
22912838Sgabeblack@google.com#endif
23012838Sgabeblack@google.com
23112838Sgabeblack@google.com
23212838Sgabeblack@google.com    // Same for stat64
23312838Sgabeblack@google.com    static void
23413128Sgabeblack@google.com    copyOutStat64Buf(TranslatingPort *mem, int fd, Addr addr, hst_stat64 *host)
23513128Sgabeblack@google.com    {
23613128Sgabeblack@google.com        using namespace TheISA;
23712952Sgabeblack@google.com
23813128Sgabeblack@google.com        TypedBufferArg<Linux::tgt_stat64> tgt(addr);
23912952Sgabeblack@google.com
24012838Sgabeblack@google.com        // fd == 1 checks are because libc does some checks
24112838Sgabeblack@google.com        // that the stdout is interactive vs. a file
24212838Sgabeblack@google.com        // this makes it work on non-linux systems
24312838Sgabeblack@google.com        if (fd == 1)
24412838Sgabeblack@google.com            tgt->st_dev = htog((uint64_t)0xA);
24513128Sgabeblack@google.com        else
24613128Sgabeblack@google.com            tgt->st_dev = htog((uint64_t)host->st_dev);
24713128Sgabeblack@google.com        // XXX What about STAT64_HAS_BROKEN_ST_INO ???
24812952Sgabeblack@google.com        tgt->st_ino = htog((uint64_t)host->st_ino);
24913128Sgabeblack@google.com        if (fd == 1)
25012952Sgabeblack@google.com            tgt->st_rdev = htog((uint64_t)0x880d);
25112838Sgabeblack@google.com        else
25212838Sgabeblack@google.com            tgt->st_rdev = htog((uint64_t)host->st_rdev);
25312838Sgabeblack@google.com        tgt->st_size = htog((int64_t)host->st_size);
25412838Sgabeblack@google.com        tgt->st_blocks = htog((uint64_t)host->st_blocks);
25512838Sgabeblack@google.com
25613128Sgabeblack@google.com        if (fd == 1)
25713128Sgabeblack@google.com            tgt->st_mode = htog((uint32_t)0x2190);
25813128Sgabeblack@google.com        else
25912952Sgabeblack@google.com            tgt->st_mode = htog((uint32_t)host->st_mode);
26013128Sgabeblack@google.com        tgt->st_uid = htog((uint32_t)host->st_uid);
26112952Sgabeblack@google.com        tgt->st_gid = htog((uint32_t)host->st_gid);
26212838Sgabeblack@google.com        tgt->st_blksize = htog((uint32_t)host->st_blksize);
26312838Sgabeblack@google.com        tgt->st_nlink = htog((uint32_t)host->st_nlink);
26412838Sgabeblack@google.com        tgt->tgt_st_atime = htog((uint64_t)host->st_atime);
26512838Sgabeblack@google.com        tgt->tgt_st_mtime = htog((uint64_t)host->st_mtime);
26612838Sgabeblack@google.com        tgt->tgt_st_ctime = htog((uint64_t)host->st_ctime);
26713128Sgabeblack@google.com#if defined(STAT_HAVE_NSEC)
26813128Sgabeblack@google.com        tgt->st_atime_nsec = htog(host->st_atime_nsec);
26913128Sgabeblack@google.com        tgt->st_mtime_nsec = htog(host->st_mtime_nsec);
27012952Sgabeblack@google.com        tgt->st_ctime_nsec = htog(host->st_ctime_nsec);
27113128Sgabeblack@google.com#else
27212952Sgabeblack@google.com        tgt->st_atime_nsec = 0;
27312838Sgabeblack@google.com        tgt->st_mtime_nsec = 0;
27412838Sgabeblack@google.com        tgt->st_ctime_nsec = 0;
27512838Sgabeblack@google.com#endif
27612838Sgabeblack@google.com
27712838Sgabeblack@google.com        tgt.copyOut(mem);
27812952Sgabeblack@google.com    }
27913128Sgabeblack@google.com
28013128Sgabeblack@google.com};  // class Linux
28112952Sgabeblack@google.com
28212952Sgabeblack@google.com
28313128Sgabeblack@google.com#endif // FULL_SYSTEM
28412838Sgabeblack@google.com
28512838Sgabeblack@google.com#endif // __LINUX_HH__
28612838Sgabeblack@google.com