solaris.hh revision 2665
12600SN/A/* 22600SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 32600SN/A * All rights reserved. 42600SN/A * 52600SN/A * Redistribution and use in source and binary forms, with or without 62600SN/A * modification, are permitted provided that the following conditions are 72600SN/A * met: redistributions of source code must retain the above copyright 82600SN/A * notice, this list of conditions and the following disclaimer; 92600SN/A * redistributions in binary form must reproduce the above copyright 102600SN/A * notice, this list of conditions and the following disclaimer in the 112600SN/A * documentation and/or other materials provided with the distribution; 122600SN/A * neither the name of the copyright holders nor the names of its 132600SN/A * contributors may be used to endorse or promote products derived from 142600SN/A * this software without specific prior written permission. 152600SN/A * 162600SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172600SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182600SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192600SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202600SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212600SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222600SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232600SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242600SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252600SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262600SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Ali Saidi 292600SN/A */ 302600SN/A 312600SN/A#ifndef __SOLARIS_HH__ 322600SN/A#define __SOLARIS_HH__ 332600SN/A#include "config/full_system.hh" 342600SN/A 352600SN/A#if FULL_SYSTEM 362600SN/A 372600SN/Aclass Solaris {}; 382600SN/A 392600SN/A#else //!FULL_SYSTEM 402600SN/A 412600SN/A#include <dirent.h> 422600SN/A#include <errno.h> 432600SN/A#include <fcntl.h> // for host open() flags 442600SN/A#include <string.h> // for memset() 452600SN/A#include <sys/stat.h> 462600SN/A#include <sys/types.h> 472600SN/A#include <unistd.h> 482600SN/A 492600SN/A#include "arch/isa_traits.hh" 502600SN/A#include "sim/syscall_emul.hh" 512600SN/A 522600SN/Aclass TranslatingPort; 532600SN/A 542600SN/A/// 552600SN/A/// This class encapsulates the types, structures, constants, 562600SN/A/// functions, and syscall-number mappings specific to the Solaris 572600SN/A/// syscall interface. 582600SN/A/// 592600SN/Aclass Solaris { 602600SN/A 612600SN/A public: 622600SN/A 632600SN/A //@{ 642600SN/A /// Basic Solaris types. 652600SN/A typedef uint64_t size_t; 662600SN/A typedef uint64_t off_t; 672600SN/A typedef int64_t time_t; 682600SN/A typedef int32_t uid_t; 692600SN/A typedef int32_t gid_t; 702600SN/A typedef uint64_t rlim_t; 712600SN/A typedef uint64_t ino_t; 722600SN/A typedef uint64_t dev_t; 732600SN/A typedef uint32_t mode_t; 742600SN/A typedef uint32_t nlink_t; 752600SN/A //@} 762600SN/A 772600SN/A#if BSD_HOST 782600SN/A typedef struct stat hst_stat; 792600SN/A typedef struct stat hst_stat64; 802600SN/A#else 812600SN/A typedef struct stat hst_stat ; 822600SN/A typedef struct stat64 hst_stat64; 832600SN/A#endif 842600SN/A struct tgt_timespec { 852600SN/A int64_t tv_sec; 862600SN/A int64_t tv_nsec; 872600SN/A }; 882600SN/A 892600SN/A /// Stat buffer. Note that we can't call it 'stat' since that 902600SN/A /// gets #defined to something else on some systems. 912600SN/A struct tgt_stat { 922600SN/A uint64_t st_dev; //!< device 932600SN/A uint64_t st_ino; //!< inode 942600SN/A uint32_t st_mode; //!< mode 952600SN/A uint32_t st_nlink; //!< link count 962600SN/A int32_t st_uid; //!< owner's user ID 972600SN/A int32_t st_gid; //!< owner's group ID 982600SN/A uint64_t st_rdev; //!< device number 992600SN/A int64_t st_size; //!< file size in bytes 1002600SN/A struct tgt_timespec st_atimeX; //!< time of last access 1012600SN/A struct tgt_timespec st_mtimeX; //!< time of last modification 1022600SN/A struct tgt_timespec st_ctimeX; //!< time of last status change 1032600SN/A int32_t st_blksize; //!< optimal I/O block size 1042600SN/A int64_t st_blocks; //!< number of blocks allocated 1052600SN/A char st_fstype[16]; 1062600SN/A }; 1072600SN/A 1082600SN/A // same for stat64 1092600SN/A struct tgt_stat64 { 1102600SN/A uint64_t st_dev; //!< device 1112600SN/A uint64_t st_ino; //!< inode 1122600SN/A uint32_t st_mode; //!< mode 1132600SN/A uint32_t st_nlink; //!< link count 1142600SN/A int32_t st_uid; //!< owner's user ID 1152600SN/A int32_t st_gid; //!< owner's group ID 1162600SN/A uint64_t st_rdev; //!< device number 1172600SN/A int64_t st_size; //!< file size in bytes 1182600SN/A struct tgt_timespec st_atimeX; //!< time of last access 1192600SN/A struct tgt_timespec st_mtimeX; //!< time of last modification 1202600SN/A struct tgt_timespec st_ctimeX; //!< time of last status change 1212600SN/A int32_t st_blksize; //!< optimal I/O block size 1222600SN/A int64_t st_blocks; //!< number of blocks allocated 1232600SN/A char st_fstype[16]; 1242600SN/A }; 1252600SN/A 1262600SN/A /// Length of strings in struct utsname (plus 1 for null char). 1272600SN/A static const int _SYS_NMLN = 257; 1282600SN/A 1292600SN/A /// Interface struct for uname(). 1302600SN/A struct utsname { 1312600SN/A char sysname[_SYS_NMLN]; //!< System name. 1322600SN/A char nodename[_SYS_NMLN]; //!< Node name. 1332600SN/A char release[_SYS_NMLN]; //!< OS release. 1342600SN/A char version[_SYS_NMLN]; //!< OS version. 1352600SN/A char machine[_SYS_NMLN]; //!< Machine type. 1362600SN/A }; 1372600SN/A 1382600SN/A /// Limit struct for getrlimit/setrlimit. 1392600SN/A struct rlimit { 1402600SN/A uint64_t rlim_cur; //!< soft limit 1412600SN/A uint64_t rlim_max; //!< hard limit 1422600SN/A }; 1432600SN/A 1442600SN/A /// For gettimeofday(). 1452600SN/A struct timeval { 1462600SN/A int64_t tv_sec; //!< seconds 1472600SN/A int64_t tv_usec; //!< microseconds 1482600SN/A }; 1492600SN/A 1502600SN/A // For writev/readv 1512600SN/A struct tgt_iovec { 1522600SN/A uint64_t iov_base; // void * 1532600SN/A uint64_t iov_len; 1542600SN/A }; 1552600SN/A 1562600SN/A 1572600SN/A /// For getrusage(). 1582600SN/A struct rusage { 1592600SN/A struct timeval ru_utime; //!< user time used 1602600SN/A struct timeval ru_stime; //!< system time used 1612600SN/A int64_t ru_maxrss; //!< max rss 1622600SN/A int64_t ru_ixrss; //!< integral shared memory size 1632600SN/A int64_t ru_idrss; //!< integral unshared data " 1642600SN/A int64_t ru_isrss; //!< integral unshared stack " 1652600SN/A int64_t ru_minflt; //!< page reclaims - total vmfaults 1662600SN/A int64_t ru_majflt; //!< page faults 1672600SN/A int64_t ru_nswap; //!< swaps 1682600SN/A int64_t ru_inblock; //!< block input operations 1692600SN/A int64_t ru_oublock; //!< block output operations 1702600SN/A int64_t ru_msgsnd; //!< messages sent 1712600SN/A int64_t ru_msgrcv; //!< messages received 1722600SN/A int64_t ru_nsignals; //!< signals received 1732600SN/A int64_t ru_nvcsw; //!< voluntary context switches 1742600SN/A int64_t ru_nivcsw; //!< involuntary " 1752600SN/A }; 1762600SN/A 1772600SN/A /// Helper function to convert a host stat buffer to a target stat 1782600SN/A /// buffer. Also copies the target buffer out to the simulated 1792600SN/A /// memory space. Used by stat(), fstat(), and lstat(). 1802600SN/A#if !BSD_HOST 1812600SN/A static void 1822600SN/A copyOutStatBuf(TranslatingPort *mem, Addr addr, hst_stat *host) 1832600SN/A { 1842600SN/A using namespace TheISA; 1852600SN/A 1862600SN/A TypedBufferArg<Solaris::tgt_stat> tgt(addr); 1872600SN/A 1882600SN/A tgt->st_dev = htog(host->st_dev); 1892600SN/A tgt->st_ino = htog(host->st_ino); 1902600SN/A tgt->st_mode = htog(host->st_mode); 1912600SN/A tgt->st_nlink = htog(host->st_nlink); 1922600SN/A tgt->st_uid = htog(host->st_uid); 1932600SN/A tgt->st_gid = htog(host->st_gid); 1942600SN/A tgt->st_rdev = htog(host->st_rdev); 1952600SN/A tgt->st_size = htog(host->st_size); 1962600SN/A tgt->st_atimeX.tv_sec = htog((uint64_t)host->st_atime); 1972600SN/A tgt->st_mtimeX.tv_sec = htog((uint64_t)host->st_mtime); 1982600SN/A tgt->st_ctimeX.tv_sec = htog((uint64_t)host->st_ctime); 1992600SN/A#if defined(STAT_HAVE_NSEC) 2002600SN/A tgt->st_atimeX.tv_nsec = htog(host->st_atime_nsec); 2012600SN/A tgt->st_mtimeX.tv_nsec = htog(host->st_mtime_nsec); 2022600SN/A tgt->st_ctimeX.tv_nsec = htog(host->st_ctime_nsec); 2032600SN/A#else 2042600SN/A tgt->st_atimeX.tv_nsec = 0; 2052600SN/A tgt->st_mtimeX.tv_nsec = 0; 2062600SN/A tgt->st_ctimeX.tv_nsec = 0; 2072600SN/A#endif 2082600SN/A tgt->st_blksize = htog(host->st_blksize); 2092600SN/A tgt->st_blocks = htog(host->st_blocks); 2102600SN/A strncpy(tgt->st_fstype, "????", 16); 2112600SN/A 2122600SN/A tgt.copyOut(mem); 2132600SN/A } 2142600SN/A#else 2152600SN/A // Third version for bsd systems which no longer have any support for 2162600SN/A // the old stat() call and stat() is actually a stat64() 2172600SN/A static void 2182600SN/A copyOutStatBuf(TranslatingPort *mem, Addr addr, hst_stat64 *host) 2192600SN/A { 2202600SN/A using namespace TheISA; 2212600SN/A 2222600SN/A TypedBufferArg<Solaris::tgt_stat> tgt(addr); 2232600SN/A 2242600SN/A tgt->st_dev = htog(host->st_dev); 2252600SN/A tgt->st_ino = htog(host->st_ino); 2262600SN/A tgt->st_mode = htog(host->st_mode); 2272600SN/A tgt->st_nlink = htog(host->st_nlink); 2282600SN/A tgt->st_uid = htog(host->st_uid); 2292600SN/A tgt->st_gid = htog(host->st_gid); 2302600SN/A tgt->st_rdev = htog(host->st_rdev); 2312600SN/A tgt->st_size = htog(host->st_size); 2322600SN/A tgt->st_atimeX.tv_sec = htog((uint64_t)host->st_atime); 2332600SN/A tgt->st_mtimeX.tv_sec = htog((uint64_t)host->st_mtime); 2342600SN/A tgt->st_ctimeX.tv_sec = htog((uint64_t)host->st_ctime); 2352600SN/A#if defined(STAT_HAVE_NSEC) 2362600SN/A tgt->st_atimeX.tv_nsec = htog(host->st_atime_nsec); 2372600SN/A tgt->st_mtimeX.tv_nsec = htog(host->st_mtime_nsec); 2382600SN/A tgt->st_ctimeX.tv_nsec = htog(host->st_ctime_nsec); 2392600SN/A#else 2402600SN/A tgt->st_atimeX.tv_nsec = 0; 2412600SN/A tgt->st_mtimeX.tv_nsec = 0; 2422600SN/A tgt->st_ctimeX.tv_nsec = 0; 2432600SN/A#endif 2442600SN/A tgt->st_blksize = htog(host->st_blksize); 2452600SN/A tgt->st_blocks = htog(host->st_blocks); 2462600SN/A strncpy(tgt->st_fstype, "????", 16); 2472600SN/A 2482600SN/A tgt.copyOut(mem); 2492600SN/A } 2502600SN/A#endif 2512600SN/A 2522600SN/A 2532600SN/A // Same for stat64 2542600SN/A static void 2552600SN/A copyOutStat64Buf(TranslatingPort *mem, int fd, Addr addr, hst_stat64 *host) 2562600SN/A { 2572600SN/A using namespace TheISA; 2582600SN/A 2592600SN/A TypedBufferArg<Solaris::tgt_stat64> tgt(addr); 2602600SN/A 2612600SN/A // fd == 1 checks are because libc does some checks 2622600SN/A // that the stdout is interactive vs. a file 2632600SN/A // this makes it work on non-solaris systems 2642600SN/A if (fd == 1) 2652600SN/A tgt->st_dev = htog((uint64_t)0xA); 2662600SN/A else 2672600SN/A tgt->st_dev = htog((uint64_t)host->st_dev); 2682600SN/A // XXX What about STAT64_HAS_BROKEN_ST_INO ??? 2692600SN/A tgt->st_ino = htog((uint64_t)host->st_ino); 2702600SN/A if (fd == 1) 2712600SN/A tgt->st_rdev = htog((uint64_t)0x880d); 2722600SN/A else 2732600SN/A tgt->st_rdev = htog((uint64_t)host->st_rdev); 2742600SN/A tgt->st_size = htog((int64_t)host->st_size); 2752600SN/A tgt->st_blocks = htog((uint64_t)host->st_blocks); 2762600SN/A 2772600SN/A if (fd == 1) 2782600SN/A tgt->st_mode = htog((uint32_t)0x2190); 2792600SN/A else 2802600SN/A tgt->st_mode = htog((uint32_t)host->st_mode); 2812600SN/A tgt->st_uid = htog((uint32_t)host->st_uid); 2822600SN/A tgt->st_gid = htog((uint32_t)host->st_gid); 2832600SN/A tgt->st_blksize = htog((uint32_t)host->st_blksize); 2842600SN/A tgt->st_nlink = htog((uint32_t)host->st_nlink); 2852600SN/A tgt->st_atimeX.tv_sec = htog((uint64_t)host->st_atime); 2862600SN/A tgt->st_mtimeX.tv_sec = htog((uint64_t)host->st_mtime); 2872600SN/A tgt->st_ctimeX.tv_sec = htog((uint64_t)host->st_ctime); 2882600SN/A#if defined(STAT_HAVE_NSEC) 2892600SN/A tgt->st_atimeX.tv_nsec = htog(host->st_atime_nsec); 2902600SN/A tgt->st_mtimeX.tv_nsec = htog(host->st_mtime_nsec); 2912600SN/A tgt->st_ctimeX.tv_nsec = htog(host->st_ctime_nsec); 2922600SN/A#else 2932600SN/A tgt->st_atimeX.tv_nsec = 0; 2942600SN/A tgt->st_mtimeX.tv_nsec = 0; 2952600SN/A tgt->st_ctimeX.tv_nsec = 0; 2962600SN/A#endif 2972600SN/A 2982600SN/A tgt.copyOut(mem); 2992600SN/A } 3002600SN/A 3012600SN/A}; // class Solaris 3022600SN/A 3032600SN/A 3042600SN/A#endif // FULL_SYSTEM 3052600SN/A 3062600SN/A#endif // __SOLARIS_HH__ 307