linux.hh revision 2665
1451SN/A/* 21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 3451SN/A * All rights reserved. 4451SN/A * 5451SN/A * Redistribution and use in source and binary forms, with or without 6451SN/A * modification, are permitted provided that the following conditions are 7451SN/A * met: redistributions of source code must retain the above copyright 8451SN/A * notice, this list of conditions and the following disclaimer; 9451SN/A * redistributions in binary form must reproduce the above copyright 10451SN/A * notice, this list of conditions and the following disclaimer in the 11451SN/A * documentation and/or other materials provided with the distribution; 12451SN/A * neither the name of the copyright holders nor the names of its 13451SN/A * contributors may be used to endorse or promote products derived from 14451SN/A * this software without specific prior written permission. 15451SN/A * 16451SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17451SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18451SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19451SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20451SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21451SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22451SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23451SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24451SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25451SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26451SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Ali Saidi 29451SN/A */ 30451SN/A 31451SN/A#ifndef __LINUX_HH__ 32451SN/A#define __LINUX_HH__ 332093SN/A#include "config/full_system.hh" 342093SN/A 352093SN/A#if FULL_SYSTEM 36451SN/A 37451SN/Aclass Linux {}; 38451SN/A 392093SN/A#else //!FULL_SYSTEM 402093SN/A 412093SN/A#include <dirent.h> 422093SN/A#include <errno.h> 432093SN/A#include <fcntl.h> // for host open() flags 442093SN/A#include <string.h> // for memset() 452093SN/A#include <sys/stat.h> 462093SN/A#include <sys/types.h> 472093SN/A#include <unistd.h> 482093SN/A 492553SN/A#include "arch/isa_traits.hh" 502093SN/A#include "sim/syscall_emul.hh" 512093SN/A 522423SN/Aclass TranslatingPort; 532423SN/A 542093SN/A/// 552093SN/A/// This class encapsulates the types, structures, constants, 562093SN/A/// functions, and syscall-number mappings specific to the Alpha Linux 572093SN/A/// syscall interface. 582093SN/A/// 592093SN/Aclass Linux { 602093SN/A 612093SN/A public: 622093SN/A 632093SN/A //@{ 642093SN/A /// Basic Linux types. 652093SN/A typedef uint64_t size_t; 662093SN/A typedef uint64_t off_t; 672093SN/A typedef int64_t time_t; 682093SN/A typedef uint32_t uid_t; 692093SN/A typedef uint32_t gid_t; 702093SN/A //@} 712093SN/A 722093SN/A#if BSD_HOST 732093SN/A typedef struct stat hst_stat; 742093SN/A typedef struct stat hst_stat64; 752093SN/A#else 762093SN/A typedef struct stat hst_stat ; 772093SN/A typedef struct stat64 hst_stat64; 782093SN/A#endif 792093SN/A 802093SN/A /// Stat buffer. Note that we can't call it 'stat' since that 812093SN/A /// gets #defined to something else on some systems. 822093SN/A struct tgt_stat { 832093SN/A uint32_t st_dev; //!< device 842093SN/A uint32_t st_ino; //!< inode 852093SN/A uint32_t st_mode; //!< mode 862093SN/A uint32_t st_nlink; //!< link count 872093SN/A uint32_t st_uid; //!< owner's user ID 882093SN/A uint32_t st_gid; //!< owner's group ID 892093SN/A uint32_t st_rdev; //!< device number 902093SN/A int32_t _pad1; //!< for alignment 912093SN/A int64_t st_size; //!< file size in bytes 922093SN/A uint64_t st_atimeX; //!< time of last access 932093SN/A uint64_t st_mtimeX; //!< time of last modification 942093SN/A uint64_t st_ctimeX; //!< time of last status change 952093SN/A uint32_t st_blksize; //!< optimal I/O block size 962093SN/A int32_t st_blocks; //!< number of blocks allocated 972093SN/A uint32_t st_flags; //!< flags 982093SN/A uint32_t st_gen; //!< unknown 992093SN/A }; 1002093SN/A 1012093SN/A // same for stat64 1022093SN/A struct tgt_stat64 { 1032093SN/A uint64_t st_dev; 1042093SN/A uint64_t st_ino; 1052093SN/A uint64_t st_rdev; 1062093SN/A int64_t st_size; 1072093SN/A uint64_t st_blocks; 1082093SN/A 1092093SN/A uint32_t st_mode; 1102093SN/A uint32_t st_uid; 1112093SN/A uint32_t st_gid; 1122093SN/A uint32_t st_blksize; 1132093SN/A uint32_t st_nlink; 1142093SN/A uint32_t __pad0; 1152093SN/A 1162093SN/A uint64_t tgt_st_atime; 1172093SN/A uint64_t st_atime_nsec; 1182093SN/A uint64_t tgt_st_mtime; 1192093SN/A uint64_t st_mtime_nsec; 1202093SN/A uint64_t tgt_st_ctime; 1212093SN/A uint64_t st_ctime_nsec; 1222093SN/A int64_t ___unused[3]; 1232093SN/A }; 1242093SN/A 1252093SN/A /// Length of strings in struct utsname (plus 1 for null char). 1262093SN/A static const int _SYS_NMLN = 65; 1272093SN/A 1282093SN/A /// Interface struct for uname(). 1292093SN/A struct utsname { 1302093SN/A char sysname[_SYS_NMLN]; //!< System name. 1312093SN/A char nodename[_SYS_NMLN]; //!< Node name. 1322093SN/A char release[_SYS_NMLN]; //!< OS release. 1332093SN/A char version[_SYS_NMLN]; //!< OS version. 1342093SN/A char machine[_SYS_NMLN]; //!< Machine type. 1352093SN/A }; 1362093SN/A 1372093SN/A /// Limit struct for getrlimit/setrlimit. 1382093SN/A struct rlimit { 1392093SN/A uint64_t rlim_cur; //!< soft limit 1402093SN/A uint64_t rlim_max; //!< hard limit 1412093SN/A }; 1422093SN/A 1432093SN/A /// For gettimeofday(). 1442093SN/A struct timeval { 1452093SN/A int64_t tv_sec; //!< seconds 1462093SN/A int64_t tv_usec; //!< microseconds 1472093SN/A }; 1482093SN/A 1492093SN/A // For writev/readv 1502093SN/A struct tgt_iovec { 1512093SN/A uint64_t iov_base; // void * 1522093SN/A uint64_t iov_len; 1532093SN/A }; 1542093SN/A 1552093SN/A 1562093SN/A /// For getrusage(). 1572093SN/A struct rusage { 1582093SN/A struct timeval ru_utime; //!< user time used 1592093SN/A struct timeval ru_stime; //!< system time used 1602093SN/A int64_t ru_maxrss; //!< max rss 1612093SN/A int64_t ru_ixrss; //!< integral shared memory size 1622093SN/A int64_t ru_idrss; //!< integral unshared data " 1632093SN/A int64_t ru_isrss; //!< integral unshared stack " 1642093SN/A int64_t ru_minflt; //!< page reclaims - total vmfaults 1652093SN/A int64_t ru_majflt; //!< page faults 1662093SN/A int64_t ru_nswap; //!< swaps 1672093SN/A int64_t ru_inblock; //!< block input operations 1682093SN/A int64_t ru_oublock; //!< block output operations 1692093SN/A int64_t ru_msgsnd; //!< messages sent 1702093SN/A int64_t ru_msgrcv; //!< messages received 1712093SN/A int64_t ru_nsignals; //!< signals received 1722093SN/A int64_t ru_nvcsw; //!< voluntary context switches 1732093SN/A int64_t ru_nivcsw; //!< involuntary " 1742093SN/A }; 1752093SN/A 1762093SN/A /// Helper function to convert a host stat buffer to a target stat 1772093SN/A /// buffer. Also copies the target buffer out to the simulated 1782093SN/A /// memory space. Used by stat(), fstat(), and lstat(). 1792093SN/A#if !BSD_HOST 1802093SN/A static void 1812423SN/A copyOutStatBuf(TranslatingPort *mem, Addr addr, hst_stat *host) 1822093SN/A { 1832450SN/A using namespace TheISA; 1842450SN/A 1852093SN/A TypedBufferArg<Linux::tgt_stat> tgt(addr); 1862093SN/A 1872093SN/A tgt->st_dev = htog(host->st_dev); 1882093SN/A tgt->st_ino = htog(host->st_ino); 1892093SN/A tgt->st_mode = htog(host->st_mode); 1902093SN/A tgt->st_nlink = htog(host->st_nlink); 1912093SN/A tgt->st_uid = htog(host->st_uid); 1922093SN/A tgt->st_gid = htog(host->st_gid); 1932093SN/A tgt->st_rdev = htog(host->st_rdev); 1942093SN/A tgt->st_size = htog(host->st_size); 1952093SN/A tgt->st_atimeX = htog(host->st_atime); 1962093SN/A tgt->st_mtimeX = htog(host->st_mtime); 1972093SN/A tgt->st_ctimeX = htog(host->st_ctime); 1982093SN/A tgt->st_blksize = htog(host->st_blksize); 1992093SN/A tgt->st_blocks = htog(host->st_blocks); 2002093SN/A 2012093SN/A tgt.copyOut(mem); 2022093SN/A } 2032093SN/A#else 2042093SN/A // Third version for bsd systems which no longer have any support for 2052093SN/A // the old stat() call and stat() is actually a stat64() 2062093SN/A static void 2072423SN/A copyOutStatBuf(TranslatingPort *mem, Addr addr, hst_stat64 *host) 2082093SN/A { 2092450SN/A using namespace TheISA; 2102450SN/A 2112093SN/A TypedBufferArg<Linux::tgt_stat> tgt(addr); 2122093SN/A 2132093SN/A tgt->st_dev = htog(host->st_dev); 2142093SN/A tgt->st_ino = htog(host->st_ino); 2152093SN/A tgt->st_mode = htog(host->st_mode); 2162093SN/A tgt->st_nlink = htog(host->st_nlink); 2172093SN/A tgt->st_uid = htog(host->st_uid); 2182093SN/A tgt->st_gid = htog(host->st_gid); 2192093SN/A tgt->st_rdev = htog(host->st_rdev); 2202093SN/A tgt->st_size = htog(host->st_size); 2212093SN/A tgt->st_atimeX = htog(host->st_atime); 2222093SN/A tgt->st_mtimeX = htog(host->st_mtime); 2232093SN/A tgt->st_ctimeX = htog(host->st_ctime); 2242093SN/A tgt->st_blksize = htog(host->st_blksize); 2252093SN/A tgt->st_blocks = htog(host->st_blocks); 2262093SN/A 2272093SN/A tgt.copyOut(mem); 2282093SN/A } 2292093SN/A#endif 2302093SN/A 2312093SN/A 2322093SN/A // Same for stat64 2332093SN/A static void 2342423SN/A copyOutStat64Buf(TranslatingPort *mem, int fd, Addr addr, hst_stat64 *host) 2352093SN/A { 2362450SN/A using namespace TheISA; 2372450SN/A 2382093SN/A TypedBufferArg<Linux::tgt_stat64> tgt(addr); 2392093SN/A 2402093SN/A // fd == 1 checks are because libc does some checks 2412093SN/A // that the stdout is interactive vs. a file 2422093SN/A // this makes it work on non-linux systems 2432093SN/A if (fd == 1) 2442093SN/A tgt->st_dev = htog((uint64_t)0xA); 2452093SN/A else 2462093SN/A tgt->st_dev = htog((uint64_t)host->st_dev); 2472093SN/A // XXX What about STAT64_HAS_BROKEN_ST_INO ??? 2482093SN/A tgt->st_ino = htog((uint64_t)host->st_ino); 2492093SN/A if (fd == 1) 2502093SN/A tgt->st_rdev = htog((uint64_t)0x880d); 2512093SN/A else 2522093SN/A tgt->st_rdev = htog((uint64_t)host->st_rdev); 2532093SN/A tgt->st_size = htog((int64_t)host->st_size); 2542093SN/A tgt->st_blocks = htog((uint64_t)host->st_blocks); 2552093SN/A 2562093SN/A if (fd == 1) 2572093SN/A tgt->st_mode = htog((uint32_t)0x2190); 2582093SN/A else 2592093SN/A tgt->st_mode = htog((uint32_t)host->st_mode); 2602093SN/A tgt->st_uid = htog((uint32_t)host->st_uid); 2612093SN/A tgt->st_gid = htog((uint32_t)host->st_gid); 2622093SN/A tgt->st_blksize = htog((uint32_t)host->st_blksize); 2632093SN/A tgt->st_nlink = htog((uint32_t)host->st_nlink); 2642093SN/A tgt->tgt_st_atime = htog((uint64_t)host->st_atime); 2652093SN/A tgt->tgt_st_mtime = htog((uint64_t)host->st_mtime); 2662093SN/A tgt->tgt_st_ctime = htog((uint64_t)host->st_ctime); 2672093SN/A#if defined(STAT_HAVE_NSEC) 2682093SN/A tgt->st_atime_nsec = htog(host->st_atime_nsec); 2692093SN/A tgt->st_mtime_nsec = htog(host->st_mtime_nsec); 2702093SN/A tgt->st_ctime_nsec = htog(host->st_ctime_nsec); 2712093SN/A#else 2722093SN/A tgt->st_atime_nsec = 0; 2732093SN/A tgt->st_mtime_nsec = 0; 2742093SN/A tgt->st_ctime_nsec = 0; 2752093SN/A#endif 2762093SN/A 2772093SN/A tgt.copyOut(mem); 2782093SN/A } 2792093SN/A 2802093SN/A}; // class Linux 2812093SN/A 2822093SN/A 2832093SN/A#endif // FULL_SYSTEM 2842093SN/A 285451SN/A#endif // __LINUX_HH__ 286