Formatting & doxygen docs for new syscall emulation code.
authorSteve Reinhardt <stever@eecs.umich.edu>
Tue, 2 Dec 2003 06:39:27 +0000 (22:39 -0800)
committerSteve Reinhardt <stever@eecs.umich.edu>
Tue, 2 Dec 2003 06:39:27 +0000 (22:39 -0800)
arch/alpha/alpha_linux_process.cc:
arch/alpha/alpha_linux_process.hh:
arch/alpha/alpha_tru64_process.cc:
arch/alpha/alpha_tru64_process.hh:
sim/syscall_emul.cc:
sim/syscall_emul.hh:
    Formatting & doxygen.

--HG--
extra : convert_revision : 4f07dd37e254120800dd0d5c0eb47acc9c00cb3f

arch/alpha/alpha_linux_process.cc
arch/alpha/alpha_linux_process.hh
arch/alpha/alpha_tru64_process.cc
arch/alpha/alpha_tru64_process.hh
sim/syscall_emul.cc
sim/syscall_emul.hh

index 13d1f5366e338bdd6b94b64691511a5dc6d85301..d8a05849dd2f706ae4caf01cd85270b7b6d26405 100644 (file)
 
 using namespace std;
 
+///
+/// This class encapsulates the types, structures, constants,
+/// functions, and syscall-number mappings specific to the Alpha Linux
+/// syscall interface.
+///
 class Linux {
 
-public:
-
-//
-// basic Linux types
-//
-
-typedef uint64_t size_t;
-typedef uint64_t off_t;
-typedef int64_t time_t;
-typedef uint32_t uid_t;
-typedef uint32_t gid_t;
-
-// open(2) flags
-static const int TGT_O_RDONLY   = 00000000;
-static const int TGT_O_WRONLY   = 00000001;
-static const int TGT_O_RDWR     = 00000002;
-static const int TGT_O_NONBLOCK  = 00000004;
-static const int TGT_O_APPEND   = 00000010;
-static const int TGT_O_CREAT    = 00001000;
-static const int TGT_O_TRUNC    = 00002000;
-static const int TGT_O_EXCL     = 00004000;
-static const int TGT_O_NOCTTY   = 00010000;
-static const int TGT_O_SYNC     = 00040000;
-static const int TGT_O_DRD      = 00100000;
-static const int TGT_O_DIRECTIO  = 00200000;
-static const int TGT_O_CACHE    = 00400000;
-static const int TGT_O_DSYNC    = 02000000;
-static const int TGT_O_RSYNC    = 04000000;
-
-static OpenFlagTransTable openFlagTable[];
-static const int NUM_OPEN_FLAGS;
-
-//
-// Stat buffer.
-//
-
-struct tgt_stat {
-    uint32_t   st_dev;
-    uint32_t   st_ino;
-    uint32_t   st_mode;
-    uint32_t   st_nlink;
-    uint32_t   st_uid;
-    uint32_t   st_gid;
-    uint32_t   st_rdev;
-    int64_t    st_size;
-    uint64_t   st_atimeX;
-    uint64_t   st_mtimeX;
-    uint64_t   st_ctimeX;
-    uint32_t   st_blksize;
-    int32_t    st_blocks;
-    uint32_t   st_flags;
-    uint32_t   st_gen;
-};
-
-
-//
-// for uname()
-//
-
-static const int _SYS_NMLN = 65;
-
-struct utsname {
-    char sysname[_SYS_NMLN];
-    char nodename[_SYS_NMLN];
-    char release[_SYS_NMLN];
-    char version[_SYS_NMLN];
-    char machine[_SYS_NMLN];
-};
-
-
-//
-// for ioctl()
-//
-
-static const unsigned TIOCGETP   = 0x40067408;
-static const unsigned TIOCSETP   = 0x80067409;
-static const unsigned TIOCSETN   = 0x8006740a;
-static const unsigned TIOCSETC   = 0x80067411;
-static const unsigned TIOCGETC   = 0x40067412;
-static const unsigned FIONREAD   = 0x4004667f;
-static const unsigned TIOCISATTY = 0x2000745e;
-
-//
-// for getrlimit()
-//
-
-enum rlimit_resources {
-    RLIMIT_CPU = 0,
-    RLIMIT_FSIZE = 1,
-    RLIMIT_DATA = 2,
-    RLIMIT_STACK = 3,
-    RLIMIT_CORE = 4,
-    RLIMIT_RSS = 5,
-    RLIMIT_NOFILE = 6,
-    RLIMIT_AS = 7,
-    RLIMIT_VMEM = 7,
-    RLIMIT_NPROC = 8,
-    RLIMIT_MEMLOCK = 9,
-    RLIMIT_LOCKS = 10
-};
-
-struct rlimit {
-    uint64_t  rlim_cur;        // soft limit
-    uint64_t  rlim_max;        // hard limit
-};
-
-
-//
-// for mmap()
-//
+  public:
+
+    //@{
+    /// Basic Linux types.
+    typedef uint64_t size_t;
+    typedef uint64_t off_t;
+    typedef int64_t time_t;
+    typedef uint32_t uid_t;
+    typedef uint32_t gid_t;
+    //@}
+
+    //@{
+    /// open(2) flag values.
+    static const int TGT_O_RDONLY      = 00000000;     //!< O_RDONLY
+    static const int TGT_O_WRONLY      = 00000001;     //!< O_WRONLY
+    static const int TGT_O_RDWR                = 00000002;     //!< O_RDWR
+    static const int TGT_O_NONBLOCK    = 00000004;     //!< O_NONBLOCK
+    static const int TGT_O_APPEND      = 00000010;     //!< O_APPEND
+    static const int TGT_O_CREAT       = 00001000;     //!< O_CREAT
+    static const int TGT_O_TRUNC       = 00002000;     //!< O_TRUNC
+    static const int TGT_O_EXCL                = 00004000;     //!< O_EXCL
+    static const int TGT_O_NOCTTY      = 00010000;     //!< O_NOCTTY
+    static const int TGT_O_SYNC                = 00040000;     //!< O_SYNC
+    static const int TGT_O_DRD         = 00100000;     //!< O_DRD
+    static const int TGT_O_DIRECTIO    = 00200000;     //!< O_DIRECTIO
+    static const int TGT_O_CACHE       = 00400000;     //!< O_CACHE
+    static const int TGT_O_DSYNC       = 02000000;     //!< O_DSYNC
+    static const int TGT_O_RSYNC       = 04000000;     //!< O_RSYNC
+    //@}
+
+    /// This table maps the target open() flags to the corresponding
+    /// host open() flags.
+    static OpenFlagTransTable openFlagTable[];
+
+    /// Number of entries in openFlagTable[].
+    static const int NUM_OPEN_FLAGS;
+
+    /// Stat buffer.  Note that we can't call it 'stat' since that
+    /// gets #defined to something else on some systems.
+    struct tgt_stat {
+        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
+        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
+    };
+
+
+    /// 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.
+    };
+
+
+    //@{
+    /// ioctl() command codes.
+    static const unsigned TIOCGETP   = 0x40067408;
+    static const unsigned TIOCSETP   = 0x80067409;
+    static const unsigned TIOCSETN   = 0x8006740a;
+    static const unsigned TIOCSETC   = 0x80067411;
+    static const unsigned TIOCGETC   = 0x40067412;
+    static const unsigned FIONREAD   = 0x4004667f;
+    static const unsigned TIOCISATTY = 0x2000745e;
+    //@}
+
+    /// Resource enumeration for getrlimit().
+    enum rlimit_resources {
+        RLIMIT_CPU = 0,
+        RLIMIT_FSIZE = 1,
+        RLIMIT_DATA = 2,
+        RLIMIT_STACK = 3,
+        RLIMIT_CORE = 4,
+        RLIMIT_RSS = 5,
+        RLIMIT_NOFILE = 6,
+        RLIMIT_AS = 7,
+        RLIMIT_VMEM = 7,
+        RLIMIT_NPROC = 8,
+        RLIMIT_MEMLOCK = 9,
+        RLIMIT_LOCKS = 10
+    };
+
+    /// Limit struct for getrlimit/setrlimit.
+    struct rlimit {
+        uint64_t  rlim_cur;    //!< soft limit
+        uint64_t  rlim_max;    //!< hard limit
+    };
+
+
+    /// For mmap().
     static const unsigned TGT_MAP_ANONYMOUS = 0x10;
 
-//
-// for gettimeofday
-//
-
-struct timeval {
-    int64_t tv_sec;
-    int64_t tv_usec;
-};
-
-//
-// for getrusage
-//
-
-
-static const int RUSAGE_SELF = 0;
-static const int RUSAGE_CHILDREN = -1;
-static const int RUSAGE_BOTH = -2;
-
-struct rusage {
-     struct timeval ru_utime;  // user time used
-     struct timeval ru_stime;  // system time used
-     int64_t ru_maxrss;
-     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
-void
-copyOutStatBuf(FunctionalMemory *mem, Addr addr, struct stat *host)
-{
-    TypedBufferArg<Linux::tgt_stat> tgt(addr);
-
-    tgt->st_dev = host->st_dev;
-    tgt->st_ino = host->st_ino;
-    tgt->st_mode = host->st_mode;
-    tgt->st_nlink = host->st_nlink;
-    tgt->st_uid = host->st_uid;
-    tgt->st_gid = host->st_gid;
-    tgt->st_rdev = host->st_rdev;
-    tgt->st_size = host->st_size;
-    tgt->st_atimeX = host->st_atime;
-    tgt->st_mtimeX = host->st_mtime;
-    tgt->st_ctimeX = host->st_ctime;
-    tgt->st_blksize = host->st_blksize;
-    tgt->st_blocks = host->st_blocks;
-
-    tgt.copyOut(mem);
-}
-
-
-static const char *hostname;
-
-static
-int
-unameFunc(SyscallDesc *desc, int callnum, Process *process,
-          ExecContext *xc)
-{
-    TypedBufferArg<Linux::utsname> name(xc->getSyscallArg(0));
-
-    strcpy(name->sysname, "Linux");
-    strcpy(name->nodename, hostname);
-    strcpy(name->release, "2.4.20");
-    strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
-    strcpy(name->machine, "alpha");
-
-    name.copyOut(xc->mem);
-    return 0;
-}
-
-
-static
-int
-osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
-                   ExecContext *xc)
-{
-    unsigned op = xc->getSyscallArg(0);
-    // unsigned nbytes = xc->getSyscallArg(2);
-
-    switch (op) {
-
-      case 45: { // GSI_IEEE_FP_CONTROL
-          TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
-          // I don't think this exactly matches the HW FPCR
-          *fpcr = 0;
-          fpcr.copyOut(xc->mem);
-          return 1;
-      }
-
-      default:
-        cerr << "osf_getsysinfo: unknown op " << op << endl;
-        abort();
-        break;
+    /// For gettimeofday().
+    struct timeval {
+        int64_t tv_sec;                //!< seconds
+        int64_t tv_usec;       //!< microseconds
+    };
+
+    //@{
+    /// For getrusage().
+    static const int RUSAGE_SELF = 0;
+    static const int RUSAGE_CHILDREN = -1;
+    static const int RUSAGE_BOTH = -2;
+    //@}
+
+    /// For getrusage().
+    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 "
+    };
+
+    /// Helper function to convert a host stat buffer to a target stat
+    /// buffer.  Also copies the target buffer out to the simulated
+    /// memorty space.  Used by stat(), fstat(), and lstat().
+    static void
+    copyOutStatBuf(FunctionalMemory *mem, Addr addr, struct stat *host)
+    {
+        TypedBufferArg<Linux::tgt_stat> tgt(addr);
+
+        tgt->st_dev = host->st_dev;
+        tgt->st_ino = host->st_ino;
+        tgt->st_mode = host->st_mode;
+        tgt->st_nlink = host->st_nlink;
+        tgt->st_uid = host->st_uid;
+        tgt->st_gid = host->st_gid;
+        tgt->st_rdev = host->st_rdev;
+        tgt->st_size = host->st_size;
+        tgt->st_atimeX = host->st_atime;
+        tgt->st_mtimeX = host->st_mtime;
+        tgt->st_ctimeX = host->st_ctime;
+        tgt->st_blksize = host->st_blksize;
+        tgt->st_blocks = host->st_blocks;
+
+        tgt.copyOut(mem);
     }
 
-    return 0;
-}
+    /// The target system's hostname.
+    static const char *hostname;
 
+    /// Target uname() handler.
+    static int
+    unameFunc(SyscallDesc *desc, int callnum, Process *process,
+              ExecContext *xc)
+    {
+        TypedBufferArg<Linux::utsname> name(xc->getSyscallArg(0));
 
-static
-int
-osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
-                   ExecContext *xc)
-{
-    unsigned op = xc->getSyscallArg(0);
-    // unsigned nbytes = xc->getSyscallArg(2);
-
-    switch (op) {
-
-      case 14: { // SSI_IEEE_FP_CONTROL
-          TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
-          // I don't think this exactly matches the HW FPCR
-          fpcr.copyIn(xc->mem);
-          DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
-                   " setting FPCR to 0x%x\n", *(uint64_t*)fpcr);
-          return 1;
-      }
-
-      default:
-        cerr << "osf_getsysinfo: unknown op " << op << endl;
-        abort();
-        break;
-    }
-
-    return 0;
-}
-
-
-static
-int
-fcntlFunc(SyscallDesc *desc, int callnum, Process *process,
-           ExecContext *xc)
-{
-    int fd = xc->getSyscallArg(0);
+        strcpy(name->sysname, "Linux");
+        strcpy(name->nodename, hostname);
+        strcpy(name->release, "2.4.20");
+        strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
+        strcpy(name->machine, "alpha");
 
-    if (fd < 0 || process->sim_fd(fd) < 0)
-        return -EBADF;
+        name.copyOut(xc->mem);
+        return 0;
+    }
 
-    int cmd = xc->getSyscallArg(1);
-    switch (cmd) {
-      case 0: // F_DUPFD
-        // if we really wanted to support this, we'd need to do it
-        // in the target fd space.
-        warn("fcntl(%d, F_DUPFD) not supported, error returned\n", fd);
-        return -EMFILE;
+    /// Target osf_getsysyinfo() handler.  Even though this call is
+    /// borrowed from Tru64, the subcases that get used appear to be
+    /// different in practice from those used by Tru64 processes.
+    static int
+    osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
+                       ExecContext *xc)
+    {
+        unsigned op = xc->getSyscallArg(0);
+        // unsigned nbytes = xc->getSyscallArg(2);
+
+        switch (op) {
+
+          case 45: { // GSI_IEEE_FP_CONTROL
+              TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
+              // I don't think this exactly matches the HW FPCR
+              *fpcr = 0;
+              fpcr.copyOut(xc->mem);
+              return 1;
+          }
+
+          default:
+            cerr << "osf_getsysinfo: unknown op " << op << endl;
+            abort();
+            break;
+        }
 
-      case 1: // F_GETFD (get close-on-exec flag)
-      case 2: // F_SETFD (set close-on-exec flag)
         return 0;
+    }
 
-      case 3: // F_GETFL (get file flags)
-      case 4: // F_SETFL (set file flags)
-        // not sure if this is totally valid, but we'll pass it through
-        // to the underlying OS
-        warn("fcntl(%d, %d) passed through to host\n", fd, cmd);
-        return fcntl(process->sim_fd(fd), cmd);
-        // return 0;
-
-      case 7: // F_GETLK  (get lock)
-      case 8: // F_SETLK  (set lock)
-      case 9: // F_SETLKW (set lock and wait)
-        // don't mess with file locking... just act like it's OK
-        warn("File lock call (fcntl(%d, %d)) ignored.\n", fd, cmd);
-        return 0;
+    /// Target osf_setsysinfo() handler.
+    static int
+    osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
+                       ExecContext *xc)
+    {
+        unsigned op = xc->getSyscallArg(0);
+        // unsigned nbytes = xc->getSyscallArg(2);
+
+        switch (op) {
+
+          case 14: { // SSI_IEEE_FP_CONTROL
+              TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
+              // I don't think this exactly matches the HW FPCR
+              fpcr.copyIn(xc->mem);
+              DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
+                       " setting FPCR to 0x%x\n", *(uint64_t*)fpcr);
+              return 1;
+          }
+
+          default:
+            cerr << "osf_getsysinfo: unknown op " << op << endl;
+            abort();
+            break;
+        }
 
-      default:
-        warn("Unknown fcntl command %d\n", cmd);
         return 0;
     }
-}
-
-static SyscallDesc syscallDescs[];
 
-static const int Num_Syscall_Descs;
+    /// Target fnctl() handler.
+    static int
+    fcntlFunc(SyscallDesc *desc, int callnum, Process *process,
+              ExecContext *xc)
+    {
+        int fd = xc->getSyscallArg(0);
+
+        if (fd < 0 || process->sim_fd(fd) < 0)
+            return -EBADF;
+
+        int cmd = xc->getSyscallArg(1);
+        switch (cmd) {
+          case 0: // F_DUPFD
+            // if we really wanted to support this, we'd need to do it
+            // in the target fd space.
+            warn("fcntl(%d, F_DUPFD) not supported, error returned\n", fd);
+            return -EMFILE;
+
+          case 1: // F_GETFD (get close-on-exec flag)
+          case 2: // F_SETFD (set close-on-exec flag)
+            return 0;
+
+          case 3: // F_GETFL (get file flags)
+          case 4: // F_SETFL (set file flags)
+            // not sure if this is totally valid, but we'll pass it through
+            // to the underlying OS
+            warn("fcntl(%d, %d) passed through to host\n", fd, cmd);
+            return fcntl(process->sim_fd(fd), cmd);
+            // return 0;
+
+          case 7: // F_GETLK  (get lock)
+          case 8: // F_SETLK  (set lock)
+          case 9: // F_SETLKW (set lock and wait)
+            // don't mess with file locking... just act like it's OK
+            warn("File lock call (fcntl(%d, %d)) ignored.\n", fd, cmd);
+            return 0;
+
+          default:
+            warn("Unknown fcntl command %d\n", cmd);
+            return 0;
+        }
+    }
 
-static const int Max_Syscall_Desc;
+    /// Array of syscall descriptors, indexed by call number.
+    static SyscallDesc syscallDescs[];
 
-static
-void
-doSyscall(int callnum, Process *process, ExecContext *xc)
-{
-    if (callnum < 0 || callnum > Max_Syscall_Desc) {
-        fatal("Syscall %d out of range", callnum);
-    }
+    /// Number of syscalls in syscallDescs[].
+    static const int Num_Syscall_Descs;
 
-    SyscallDesc *desc = &syscallDescs[callnum];
+    /// Max supported syscall number.
+    static const int Max_Syscall_Desc;
 
-    desc->doSyscall(callnum, process, xc);
-}
+    /// Do the specified syscall.  Just looks the call number up in
+    /// the table and invokes the appropriate handler.
+    static void
+    doSyscall(int callnum, Process *process, ExecContext *xc)
+    {
+        if (callnum < 0 || callnum > Max_Syscall_Desc) {
+            fatal("Syscall %d out of range", callnum);
+        }
 
+        SyscallDesc *desc = &syscallDescs[callnum];
 
+        desc->doSyscall(callnum, process, xc);
+    }
 };  // class Linux
 
 
 // open(2) flags translation table
 OpenFlagTransTable Linux::openFlagTable[] = {
-  /* target flag */    /* host flag */
 #ifdef _MSC_VER
   { Linux::TGT_O_RDONLY,       _O_RDONLY },
   { Linux::TGT_O_WRONLY,       _O_WRONLY },
@@ -406,7 +405,8 @@ OpenFlagTransTable Linux::openFlagTable[] = {
 #endif /* _MSC_VER */
 };
 
-const int Linux::NUM_OPEN_FLAGS = (sizeof(Linux::openFlagTable)/sizeof(Linux::openFlagTable[0]));
+const int Linux::NUM_OPEN_FLAGS =
+        (sizeof(Linux::openFlagTable)/sizeof(Linux::openFlagTable[0]));
 
 const char *Linux::hostname = "m5.eecs.umich.edu";
 
index 0d2f7641f3f7446d405297ebae2e912156b21470..4b893619204a1b6cdebaaacc2420627bbc3977e6 100644 (file)
 
 #include "sim/process.hh"
 
+
+/// A process with emulated Alpha/Linux syscalls.
 class AlphaLinuxProcess : public LiveProcess
 {
   public:
+    /// Constructor.
     AlphaLinuxProcess(const std::string &name,
                       ObjectFile *objFile,
                       int stdin_fd, int stdout_fd, int stderr_fd,
                       std::vector<std::string> &argv,
                       std::vector<std::string> &envp);
 
+    /// Syscall emulation function.
     virtual void syscall(ExecContext *xc);
 };
 
index 85648e68c6b0b06f0685b761c59a6b78dafc50c1..aece4de5a7ecb08c2ed39467a6e4b86b7f66daf3 100644 (file)
 
 using namespace std;
 
+///
+/// This class encapsulates the types, structures, constants,
+/// functions, and syscall-number mappings specific to the Alpha Tru64
+/// syscall interface.
+///
 class Tru64 {
 
-public:
-
-//
-// basic Tru64 types
-//
-
-typedef uint64_t size_t;
-typedef uint64_t off_t;
-typedef uint16_t nlink_t;
-typedef int32_t  dev_t;
-typedef uint32_t uid_t;
-typedef uint32_t gid_t;
-typedef uint32_t time_t;
-typedef uint32_t mode_t;
-typedef uint32_t ino_t;
-
-// open(2) flags
-static const int TGT_O_RDONLY   = 00000000;
-static const int TGT_O_WRONLY   = 00000001;
-static const int TGT_O_RDWR     = 00000002;
-static const int TGT_O_NONBLOCK  = 00000004;
-static const int TGT_O_APPEND   = 00000010;
-static const int TGT_O_CREAT    = 00001000;
-static const int TGT_O_TRUNC    = 00002000;
-static const int TGT_O_EXCL     = 00004000;
-static const int TGT_O_NOCTTY   = 00010000;
-static const int TGT_O_SYNC     = 00040000;
-static const int TGT_O_DRD      = 00100000;
-static const int TGT_O_DIRECTIO  = 00200000;
-static const int TGT_O_CACHE    = 00400000;
-static const int TGT_O_DSYNC    = 02000000;
-static const int TGT_O_RSYNC    = 04000000;
-
-static OpenFlagTransTable openFlagTable[];
-static const int NUM_OPEN_FLAGS;
-
-//
-// Stat buffer.  Note that Tru64 v5.0+ use a new "F64" stat structure,
-// and a new set of syscall numbers for stat calls.  Backwards
-// compatibility with v4.x should be feasible by implementing another
-// set of stat functions using the old structure definition and
-// binding them to the old syscall numbers, but we haven't done that
-// yet.
-//
-
-struct F64_stat {
-    dev_t      st_dev;
-    int32_t    st_retired1;
-    mode_t     st_mode;
-    nlink_t    st_nlink;
-    uint16_t   st_nlink_reserved;
-    uid_t      st_uid;
-    gid_t      st_gid;
-    dev_t      st_rdev;
-    dev_t      st_ldev;
-    off_t      st_size;
-    time_t     st_retired2;
-    int32_t    st_uatime;
-    time_t     st_retired3;
-    int32_t    st_umtime;
-    time_t     st_retired4;
-    int32_t    st_uctime;
-    int32_t    st_retired5;
-    int32_t    st_retired6;
-    uint32_t   st_flags;
-    uint32_t   st_gen;
-    uint64_t   st_spare[4];
-    ino_t      st_ino;
-    int32_t    st_ino_reserved;
-    time_t     st_atimeX;
-    int32_t    st_atime_reserved;
-    time_t     st_mtimeX;
-    int32_t    st_mtime_reserved;
-    time_t     st_ctimeX;
-    int32_t    st_ctime_reserved;
-    uint64_t   st_blksize;
-    uint64_t   st_blocks;
-};
-
-
-//
-// for getdirentries()
-//
-
-struct dirent
-{
-    ino_t d_ino;               /* file number of entry */
-    uint16_t d_reclen;         /* length of this record */
-    uint16_t d_namlen;         /* length of string in d_name */
-    char d_name[256];          /* dummy name length */
-};
-
-
-//
-// for uname()
-//
-
-static const int _SYS_NMLN = 32;
-
-struct utsname {
-    char sysname[_SYS_NMLN];
-    char nodename[_SYS_NMLN];
-    char release[_SYS_NMLN];
-    char version[_SYS_NMLN];
-    char machine[_SYS_NMLN];
-};
-
-
-//
-// for ioctl()
-//
-
-static const unsigned TIOCGETP   = 0x40067408;
-static const unsigned TIOCSETP   = 0x80067409;
-static const unsigned TIOCSETN   = 0x8006740a;
-static const unsigned TIOCSETC   = 0x80067411;
-static const unsigned TIOCGETC   = 0x40067412;
-static const unsigned FIONREAD   = 0x4004667f;
-static const unsigned TIOCISATTY = 0x2000745e;
-
-//
-// for getrlimit()
-//
-
-enum rlimit_resources {
-    RLIMIT_CPU = 0,
-    RLIMIT_FSIZE = 1,
-    RLIMIT_DATA = 2,
-    RLIMIT_STACK = 3,
-    RLIMIT_CORE = 4,
-    RLIMIT_RSS = 5,
-    RLIMIT_NOFILE = 6,
-    RLIMIT_AS = 7,
-    RLIMIT_VMEM = 7
-};
-
-struct rlimit {
-    uint64_t  rlim_cur;        // soft limit
-    uint64_t  rlim_max;        // hard limit
-};
-
-
-//
-// for mmap()
-//
+  public:
+
+    //@{
+    /// Basic Tru64 types.
+    typedef uint64_t size_t;
+    typedef uint64_t off_t;
+    typedef uint16_t nlink_t;
+    typedef int32_t  dev_t;
+    typedef uint32_t uid_t;
+    typedef uint32_t gid_t;
+    typedef uint32_t time_t;
+    typedef uint32_t mode_t;
+    typedef uint32_t ino_t;
+    //@}
+
+    //@{
+    /// open(2) flag values.
+    static const int TGT_O_RDONLY      = 00000000;
+    static const int TGT_O_WRONLY      = 00000001;
+    static const int TGT_O_RDWR                = 00000002;
+    static const int TGT_O_NONBLOCK    = 00000004;
+    static const int TGT_O_APPEND      = 00000010;
+    static const int TGT_O_CREAT       = 00001000;
+    static const int TGT_O_TRUNC       = 00002000;
+    static const int TGT_O_EXCL                = 00004000;
+    static const int TGT_O_NOCTTY      = 00010000;
+    static const int TGT_O_SYNC                = 00040000;
+    static const int TGT_O_DRD         = 00100000;
+    static const int TGT_O_DIRECTIO    = 00200000;
+    static const int TGT_O_CACHE       = 00400000;
+    static const int TGT_O_DSYNC       = 02000000;
+    static const int TGT_O_RSYNC       = 04000000;
+    //@}
+
+    /// This table maps the target open() flags to the corresponding
+    /// host open() flags.
+    static OpenFlagTransTable openFlagTable[];
+
+    /// Number of entries in openFlagTable[].
+    static const int NUM_OPEN_FLAGS;
+
+    /// Stat buffer.  Note that Tru64 v5.0+ use a new "F64" stat structure,
+    /// and a new set of syscall numbers for stat calls.  Backwards
+    /// compatibility with v4.x should be feasible by implementing
+    /// another set of stat functions using the old structure
+    /// definition and binding them to the old syscall numbers, but we
+    /// haven't done that yet.
+    struct F64_stat {
+        dev_t  st_dev;                 //!< st_dev
+        int32_t        st_retired1;            //!< st_retired1
+        mode_t st_mode;                //!< st_mode
+        nlink_t        st_nlink;               //!< st_nlink
+        uint16_t st_nlink_reserved;    //!< st_nlink_reserved
+        uid_t  st_uid;                 //!< st_uid
+        gid_t  st_gid;                 //!< st_gid
+        dev_t  st_rdev;                //!< st_rdev
+        dev_t  st_ldev;                //!< st_ldev
+        off_t  st_size;                //!< st_size
+        time_t st_retired2;            //!< st_retired2
+        int32_t        st_uatime;              //!< st_uatime
+        time_t st_retired3;            //!< st_retired3
+        int32_t        st_umtime;              //!< st_umtime
+        time_t st_retired4;            //!< st_retired4
+        int32_t        st_uctime;              //!< st_uctime
+        int32_t        st_retired5;            //!< st_retired5
+        int32_t        st_retired6;            //!< st_retired6
+        uint32_t       st_flags;       //!< st_flags
+        uint32_t       st_gen;         //!< st_gen
+        uint64_t       st_spare[4];    //!< st_spare[4]
+        ino_t  st_ino;                 //!< st_ino
+        int32_t        st_ino_reserved;        //!< st_ino_reserved
+        time_t st_atimeX;              //!< st_atime
+        int32_t        st_atime_reserved;      //!< st_atime_reserved
+        time_t st_mtimeX;              //!< st_mtime
+        int32_t        st_mtime_reserved;      //!< st_mtime_reserved
+        time_t st_ctimeX;              //!< st_ctime
+        int32_t        st_ctime_reserved;      //!< st_ctime_reserved
+        uint64_t       st_blksize;     //!< st_blksize
+        uint64_t       st_blocks;      //!< st_blocks
+    };
+
+
+    /// For getdirentries().
+    struct dirent
+    {
+        ino_t d_ino;           //!< file number of entry
+        uint16_t d_reclen;     //!< length of this record
+        uint16_t d_namlen;     //!< length of string in d_name
+        char d_name[256];      //!< dummy name length
+    };
+
+
+    /// Length of strings in struct utsname (plus 1 for null char).
+    static const int _SYS_NMLN = 32;
+
+    /// 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.
+    };
+
+    //@{
+    /// ioctl() command codes.
+    static const unsigned TIOCGETP   = 0x40067408;
+    static const unsigned TIOCSETP   = 0x80067409;
+    static const unsigned TIOCSETN   = 0x8006740a;
+    static const unsigned TIOCSETC   = 0x80067411;
+    static const unsigned TIOCGETC   = 0x40067412;
+    static const unsigned FIONREAD   = 0x4004667f;
+    static const unsigned TIOCISATTY = 0x2000745e;
+    //@}
+
+    /// Resource enumeration for getrlimit().
+    enum rlimit_resources {
+        RLIMIT_CPU = 0,
+        RLIMIT_FSIZE = 1,
+        RLIMIT_DATA = 2,
+        RLIMIT_STACK = 3,
+        RLIMIT_CORE = 4,
+        RLIMIT_RSS = 5,
+        RLIMIT_NOFILE = 6,
+        RLIMIT_AS = 7,
+        RLIMIT_VMEM = 7
+    };
+
+    /// Limit struct for getrlimit/setrlimit.
+    struct rlimit {
+        uint64_t  rlim_cur;    //!< soft limit
+        uint64_t  rlim_max;    //!< hard limit
+    };
+
+
+    /// For mmap().
     static const unsigned TGT_MAP_ANONYMOUS = 0x10;
 
 
-//
-// for getsysinfo()
-//
-
-static const unsigned GSI_PLATFORM_NAME = 103; // get platform name as string
-static const unsigned GSI_CPU_INFO = 59;       // CPU information
-static const unsigned GSI_PROC_TYPE = 60;      // get proc_type
-static const unsigned GSI_MAX_CPU = 30;        // max # cpu's on this machine
-static const unsigned GSI_CPUS_IN_BOX = 55;    // number of processors in system
-static const unsigned GSI_PHYSMEM = 19;        // Amount of physical memory in KB
-static const unsigned GSI_CLK_TCK = 42;        // clock freq in Hz
-
-struct cpu_info {
-    uint32_t     current_cpu;
-    uint32_t     cpus_in_box;
-    uint32_t     cpu_type;
-    uint32_t     ncpus;
-    uint64_t cpus_present;
-    uint64_t cpus_running;
-    uint64_t cpu_binding;
-    uint64_t cpu_ex_binding;
-    uint32_t     mhz;
-    uint32_t     unused[3];      // future expansion
-};
-
-//
-// for gettimeofday
-//
-
-struct timeval {
-    uint32_t tv_sec;
-    uint32_t tv_usec;
-};
-
-//
-// for getrusage
-//
-
-
-static const int RUSAGE_THREAD = 1;
-static const int RUSAGE_SELF = 0;
-static const int RUSAGE_CHILDREN = -1;
-
-struct rusage {
-     struct timeval ru_utime;  // user time used
-     struct timeval ru_stime;  // system time used
-     uint64_t ru_maxrss;
-     uint64_t ru_ixrss;                // integral shared memory size
-     uint64_t ru_idrss;                // integral unshared data "
-     uint64_t ru_isrss;                // integral unshared stack "
-     uint64_t ru_minflt;               // page reclaims - total vmfaults
-     uint64_t ru_majflt;               // page faults
-     uint64_t ru_nswap;                // swaps
-     uint64_t ru_inblock;      // block input operations
-     uint64_t ru_oublock;      // block output operations
-     uint64_t ru_msgsnd;               // messages sent
-     uint64_t ru_msgrcv;               // messages received
-     uint64_t ru_nsignals;     // signals received
-     uint64_t ru_nvcsw;                // voluntary context switches
-     uint64_t ru_nivcsw;               // involuntary "
-};
-
-//
-// for sigreturn
-//
-
-struct sigcontext {
-     int64_t sc_onstack;       // sigstack state to restore
-     int64_t sc_mask;          // signal mask to restore
-     int64_t sc_pc;            // pc at time of signal
-     int64_t sc_ps;            // psl to retore
-     int64_t sc_regs[32];      // processor regs 0 to 31
-     int64_t sc_ownedfp;       // fp has been used
-     int64_t sc_fpregs[32];    // fp regs 0 to 31
-     uint64_t sc_fpcr;         // floating point control reg
-     uint64_t sc_fp_control;   // software fpcr
-     int64_t sc_reserved1;     // reserved for kernel
-     uint32_t sc_kreserved1;   // reserved for kernel
-     uint32_t sc_kreserved2;   // reserved for kernel
-     size_t  sc_ssize; // stack size
-     caddr_t sc_sbase; // stack start
-     uint64_t sc_traparg_a0;   // a0 argument to trap on exc
-     uint64_t sc_traparg_a1;   // a1 argument to trap on exc
-     uint64_t sc_traparg_a2;   // a2 argument to trap on exc
-     uint64_t sc_fp_trap_pc;   // imprecise pc
-     uint64_t sc_fp_trigger_sum;       // Exception summary at trigg
-     uint64_t sc_fp_trigger_inst; // Instruction at trigger pc
-};
-
-
-//
-// for table
-//
-static const int TBL_SYSINFO = 12;
-
-struct tbl_sysinfo {
-    uint64_t si_user;  // User time
-    uint64_t si_nice;  // Nice time
-    uint64_t si_sys;   // System time
-    uint64_t si_idle;  // Idle time
-    uint64_t si_hz;
-    uint64_t si_phz;
-    uint64_t si_boottime;      // Boot time in seconds
-    uint64_t wait;             // Wait time
-    uint32_t  si_max_procs;    // rpb->rpb_numprocs
-    uint32_t  pad;
-};
-
-
-//
-// for stack_create
-//
-
-struct vm_stack {
-    // void *
-    Addr       address;        // address hint
-    size_t     rsize;          // red zone size
-    size_t     ysize;          // yellow zone size
-    size_t     gsize;          // green zone size
-    size_t     swap;           // amount of swap to reserve
-    size_t     incr;           // growth increment
-    uint64_t   align;          // address alignment
-    uint64_t   flags;          // MAP_FIXED etc.
-    // struct memalloc_attr *
-    Addr       attr;           // allocation policy
-    uint64_t reserved;
-};
-
-//
-// return values for nxm calls
-//
-enum {
-    KERN_NOT_RECEIVER = 7,
-    KERN_NOT_IN_SET = 12
-};
-
-//
-// for nxm_task_init
-//
-
-static const int NXM_TASK_INIT_VP = 2; // initial thread is VP
-
-struct nxm_task_attr {
-    int64_t nxm_callback;
-    unsigned int nxm_version;
-    unsigned short nxm_uniq_offset;
-    unsigned short flags;
-    int nxm_quantum;
-    int pad1;
-    int64_t pad2;
-};
-
-typedef uint64_t   sigset_t;
-
-struct ushared_state {
-    sigset_t        sigmask;        // thread signal mask
-    sigset_t        sig;            // thread pending mask
-    // struct nxm_pth_state *
-    Addr pth_id; // out-of-line state
-    int             flags;          // shared flags
+    //@{
+    /// For getsysinfo().
+    static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
+    static const unsigned GSI_CPU_INFO = 59;   //!< CPU information
+    static const unsigned GSI_PROC_TYPE = 60;  //!< get proc_type
+    static const unsigned GSI_MAX_CPU = 30;   //!< max # cpu's on this machine
+    static const unsigned GSI_CPUS_IN_BOX = 55;        //!< number of CPUs in system
+    static const unsigned GSI_PHYSMEM = 19;    //!< Physical memory in KB
+    static const unsigned GSI_CLK_TCK = 42;    //!< clock freq in Hz
+    //@}
+
+    /// For getsysinfo() GSI_CPU_INFO option.
+    struct cpu_info {
+        uint32_t     current_cpu;      //!< current_cpu
+        uint32_t     cpus_in_box;      //!< cpus_in_box
+        uint32_t     cpu_type;         //!< cpu_type
+        uint32_t     ncpus;            //!< ncpus
+        uint64_t     cpus_present;     //!< cpus_present
+        uint64_t     cpus_running;     //!< cpus_running
+        uint64_t     cpu_binding;      //!< cpu_binding
+        uint64_t     cpu_ex_binding;   //!< cpu_ex_binding
+        uint32_t     mhz;              //!< mhz
+        uint32_t     unused[3];                //!< future expansion
+    };
+
+    /// For gettimeofday.
+    struct timeval {
+        uint32_t tv_sec;       //!< seconds
+        uint32_t tv_usec;      //!< microseconds
+    };
+
+    //@{
+    /// For getrusage().
+    static const int RUSAGE_THREAD = 1;
+    static const int RUSAGE_SELF = 0;
+    static const int RUSAGE_CHILDREN = -1;
+    //@}
+
+    /// For getrusage().
+    struct rusage {
+        struct timeval ru_utime;       //!< user time used
+        struct timeval ru_stime;       //!< system time used
+        uint64_t ru_maxrss;            //!< ru_maxrss
+        uint64_t ru_ixrss;             //!< integral shared memory size
+        uint64_t ru_idrss;             //!< integral unshared data "
+        uint64_t ru_isrss;             //!< integral unshared stack "
+        uint64_t ru_minflt;            //!< page reclaims - total vmfaults
+        uint64_t ru_majflt;            //!< page faults
+        uint64_t ru_nswap;             //!< swaps
+        uint64_t ru_inblock;           //!< block input operations
+        uint64_t ru_oublock;           //!< block output operations
+        uint64_t ru_msgsnd;            //!< messages sent
+        uint64_t ru_msgrcv;            //!< messages received
+        uint64_t ru_nsignals;          //!< signals received
+        uint64_t ru_nvcsw;             //!< voluntary context switches
+        uint64_t ru_nivcsw;            //!< involuntary "
+    };
+
+    /// For sigreturn().
+    struct sigcontext {
+        int64_t sc_onstack;            //!< sigstack state to restore
+        int64_t sc_mask;               //!< signal mask to restore
+        int64_t sc_pc;                 //!< pc at time of signal
+        int64_t sc_ps;                 //!< psl to retore
+        int64_t sc_regs[32];           //!< processor regs 0 to 31
+        int64_t sc_ownedfp;            //!< fp has been used
+        int64_t sc_fpregs[32];         //!< fp regs 0 to 31
+        uint64_t sc_fpcr;              //!< floating point control reg
+        uint64_t sc_fp_control;                //!< software fpcr
+        int64_t sc_reserved1;          //!< reserved for kernel
+        uint32_t sc_kreserved1;                //!< reserved for kernel
+        uint32_t sc_kreserved2;                //!< reserved for kernel
+        size_t  sc_ssize;              //!< stack size
+        caddr_t sc_sbase;              //!< stack start
+        uint64_t sc_traparg_a0;                //!< a0 argument to trap on exc
+        uint64_t sc_traparg_a1;                //!< a1 argument to trap on exc
+        uint64_t sc_traparg_a2;                //!< a2 argument to trap on exc
+        uint64_t sc_fp_trap_pc;                //!< imprecise pc
+        uint64_t sc_fp_trigger_sum;    //!< Exception summary at trigg
+        uint64_t sc_fp_trigger_inst;   //!< Instruction at trigger pc
+    };
+
+
+    /// For table().
+    static const int TBL_SYSINFO = 12;
+
+    /// For table().
+    struct tbl_sysinfo {
+        uint64_t si_user;      //!< User time
+        uint64_t si_nice;      //!< Nice time
+        uint64_t si_sys;       //!< System time
+        uint64_t si_idle;      //!< Idle time
+        uint64_t si_hz;                //!< hz
+        uint64_t si_phz;       //!< phz
+        uint64_t si_boottime;  //!< Boot time in seconds
+        uint64_t wait;         //!< Wait time
+        uint32_t  si_max_procs;        //!< rpb->rpb_numprocs
+        uint32_t  pad;         //!< padding
+    };
+
+
+    /// For stack_create.
+    struct vm_stack {
+        // was void *
+        Addr   address;        //!< address hint
+        size_t rsize;          //!< red zone size
+        size_t ysize;          //!< yellow zone size
+        size_t gsize;          //!< green zone size
+        size_t swap;           //!< amount of swap to reserve
+        size_t incr;           //!< growth increment
+        uint64_t       align;          //!< address alignment
+        uint64_t       flags;          //!< MAP_FIXED etc.
+        // was struct memalloc_attr *
+        Addr   attr;           //!< allocation policy
+        uint64_t reserved;     //!< reserved
+    };
+
+    /// Return values for nxm calls.
+    enum {
+        KERN_NOT_RECEIVER = 7,
+        KERN_NOT_IN_SET = 12
+    };
+
+    /// For nxm_task_init.
+    static const int NXM_TASK_INIT_VP = 2;     //!< initial thread is VP
+
+    /// Task attribute structure.
+    struct nxm_task_attr {
+        int64_t nxm_callback;  //!< nxm_callback
+        unsigned int nxm_version;      //!< nxm_version
+        unsigned short nxm_uniq_offset;        //!< nxm_uniq_offset
+        unsigned short flags;  //!< flags
+        int nxm_quantum;       //!< nxm_quantum
+        int pad1;              //!< pad1
+        int64_t pad2;          //!< pad2
+    };
+
+    /// Signal set.
+    typedef uint64_t   sigset_t;
+
+    /// Thread state shared between user & kernel.
+    struct ushared_state {
+        sigset_t        sigmask;        //!< thread signal mask
+        sigset_t        sig;            //!< thread pending mask
+        // struct nxm_pth_state *
+        Addr pth_id; //!< out-of-line state
+        int             flags;          //!< shared flags
 #define US_SIGSTACK     0x1             // thread called sigaltstack
 #define US_ONSTACK      0x2             // thread is running on altstack
 #define US_PROFILE      0x4             // thread called profil
@@ -370,7 +353,7 @@ struct ushared_state {
 #define US_YZONE        0x40            // thread has zoned out
 #define US_FP_OWNED     0x80            // thread used floating point
 
-    int             cancel_state;   // thread's cancelation state
+        int             cancel_state;   //!< thread's cancelation state
 #define US_CANCEL         0x1           // cancel pending
 #define US_NOCANCEL       0X2           // synch cancel disabled
 #define US_SYS_NOCANCEL   0x4           // syscall cancel disabled
@@ -379,954 +362,951 @@ struct ushared_state {
 #define US_CANCEL_MASK  (US_CANCEL|US_NOCANCEL|US_SYS_NOCANCEL| \
                          US_ASYNC_NOCANCEL)
 
-    // These are semi-shared. They are always visible to
-    // the kernel but are never context-switched by the library.
-
-    int             nxm_ssig;       // scheduler's synchronous signals
-    int             reserved1;
-    int64_t            nxm_active;     // scheduler active
-    int64_t            reserved2;
-};
-
-struct nxm_sched_state {
-    struct          ushared_state nxm_u;    // state own by user thread
-    unsigned int    nxm_bits;               // scheduler state / slot
-    int             nxm_quantum;            // quantum count-down value
-    int             nxm_set_quantum;        // quantum reset value
-    int             nxm_sysevent;           // syscall state
-    // struct nxm_upcall *
-    Addr           nxm_uc_ret; // stack ptr of null thread
-    // void *
-    Addr nxm_tid;               // scheduler's thread id
-    int64_t            nxm_va;                 // page fault address
-    // struct nxm_pth_state *
-    Addr nxm_pthid; // id of null thread
-    uint64_t   nxm_bound_pcs_count;    // bound PCS thread count
-    int64_t            pad[2];
-};
-
-struct nxm_shared {
-    int64_t nxm_callback;              // address of upcall routine
-    unsigned int nxm_version;       // version number
-    unsigned short nxm_uniq_offset; // correction factor for TEB
-    unsigned short pad1;
-    int64_t space[2];                  // future growth
-    struct nxm_sched_state nxm_ss[1]; // array of shared areas
-};
-
-enum nxm_slot_state_t {
-    NXM_SLOT_AVAIL,
-    NXM_SLOT_BOUND,
-    NXM_SLOT_UNBOUND,
-    NXM_SLOT_EMPTY
-};
-
-
-struct nxm_config_info {
-    int nxm_nslots_per_rad;         // max number of VP slots per RAD
-    int nxm_nrads;                  // max number of RADs
-    // nxm_slot_state_t *
-    Addr nxm_slot_state; // per-VP slot state
-    // struct nxm_shared *
-    Addr nxm_rad[1];  // per-RAD shared areas
-};
-
-//
-// for nxm_thread_create
-//
-
-enum nxm_thread_type {
-    NXM_TYPE_SCS       = 0,
-    NXM_TYPE_VP                = 1,
-    NXM_TYPE_MANAGER   = 2
-};
-
-
-struct nxm_thread_attr {
-    int version;
-    int type;
-    int cancel_flags;
-    int priority;
-    int policy;
-    int signal_type;
-    // void *
-    Addr pthid;
-    sigset_t sigmask;
-    struct {
-        uint64_t pc;
-        uint64_t sp;
-        uint64_t a0;
-    } registers;
-    uint64_t pad2[2];
-};
-
-static
-void
-copyOutStatBuf(FunctionalMemory *mem, Addr addr, struct stat *host)
-{
-    TypedBufferArg<Tru64::F64_stat> tgt(addr);
-
-    tgt->st_dev = host->st_dev;
-    tgt->st_ino = host->st_ino;
-    tgt->st_mode = host->st_mode;
-    tgt->st_nlink = host->st_nlink;
-    tgt->st_uid = host->st_uid;
-    tgt->st_gid = host->st_gid;
-    tgt->st_rdev = host->st_rdev;
-    tgt->st_size = host->st_size;
-    tgt->st_atimeX = host->st_atime;
-    tgt->st_mtimeX = host->st_mtime;
-    tgt->st_ctimeX = host->st_ctime;
-    tgt->st_blksize = host->st_blksize;
-    tgt->st_blocks = host->st_blocks;
-
-    tgt.copyOut(mem);
-}
-
-static const char *hostname;
-
-static
-int
-unameFunc(SyscallDesc *desc, int callnum, Process *process,
-          ExecContext *xc)
-{
-    TypedBufferArg<Tru64::utsname> name(xc->getSyscallArg(0));
-
-    strcpy(name->sysname, "OSF1");
-    strcpy(name->nodename, hostname);
-    strcpy(name->release, "V5.1");
-    strcpy(name->version, "732");
-    strcpy(name->machine, "alpha");
-
-    name.copyOut(xc->mem);
-    return 0;
-}
-
-
-static
-int
-getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
-               ExecContext *xc)
-{
-    unsigned op = xc->getSyscallArg(0);
-    unsigned nbytes = xc->getSyscallArg(2);
-
-    switch (op) {
-
-      case Tru64::GSI_MAX_CPU: {
-          TypedBufferArg<uint32_t> max_cpu(xc->getSyscallArg(1));
-          *max_cpu = process->numCpus();
-          max_cpu.copyOut(xc->mem);
-          return 1;
-      }
-
-      case Tru64::GSI_CPUS_IN_BOX: {
-          TypedBufferArg<uint32_t> cpus_in_box(xc->getSyscallArg(1));
-          *cpus_in_box = process->numCpus();
-          cpus_in_box.copyOut(xc->mem);
-          return 1;
-      }
-
-      case Tru64::GSI_PHYSMEM: {
-          TypedBufferArg<uint64_t> physmem(xc->getSyscallArg(1));
-          *physmem = 1024 * 1024;      // physical memory in KB
-          physmem.copyOut(xc->mem);
-          return 1;
-      }
-
-      case Tru64::GSI_CPU_INFO: {
-          TypedBufferArg<Tru64::cpu_info> infop(xc->getSyscallArg(1));
-
-          infop->current_cpu = 0;
-          infop->cpus_in_box = process->numCpus();
-          infop->cpu_type = 57;
-          infop->ncpus = process->numCpus();
-          int cpumask = (1 << process->numCpus()) - 1;
-          infop->cpus_present = infop->cpus_running = cpumask;
-          infop->cpu_binding = 0;
-          infop->cpu_ex_binding = 0;
-          infop->mhz = 667;
-
-          infop.copyOut(xc->mem);
-          return 1;
-        }
-
-      case Tru64::GSI_PROC_TYPE: {
-          TypedBufferArg<uint64_t> proc_type(xc->getSyscallArg(1));
-          *proc_type = 11;
-          proc_type.copyOut(xc->mem);
-          return 1;
-      }
-
-      case Tru64::GSI_PLATFORM_NAME: {
-          BufferArg bufArg(xc->getSyscallArg(1), nbytes);
-          strncpy((char *)bufArg.bufferPtr(),
-                  "COMPAQ Professional Workstation XP1000",
-                  nbytes);
-          bufArg.copyOut(xc->mem);
-          return 1;
-      }
-
-      case Tru64::GSI_CLK_TCK: {
-          TypedBufferArg<uint64_t> clk_hz(xc->getSyscallArg(1));
-          *clk_hz = 1024;
-          clk_hz.copyOut(xc->mem);
-          return 1;
-      }
-
-      default:
-        cerr << "getsysinfo: unknown op " << op << endl;
-        abort();
-        break;
+        // These are semi-shared. They are always visible to
+        // the kernel but are never context-switched by the library.
+
+        int             nxm_ssig;       //!< scheduler's synchronous signals
+        int             reserved1;     //!< reserved1
+        int64_t            nxm_active;     //!< scheduler active
+        int64_t            reserved2;  //!< reserved2
+    };
+
+    struct nxm_sched_state {
+        struct          ushared_state nxm_u;    //!< state own by user thread
+        unsigned int    nxm_bits;               //!< scheduler state / slot
+        int             nxm_quantum;            //!< quantum count-down value
+        int             nxm_set_quantum;        //!< quantum reset value
+        int             nxm_sysevent;           //!< syscall state
+        // struct nxm_upcall *
+        Addr       nxm_uc_ret; //!< stack ptr of null thread
+        // void *
+        Addr nxm_tid;               //!< scheduler's thread id
+        int64_t            nxm_va;                 //!< page fault address
+        // struct nxm_pth_state *
+        Addr nxm_pthid; //!< id of null thread
+        uint64_t   nxm_bound_pcs_count;    //!< bound PCS thread count
+        int64_t            pad[2];        //!< pad
+    };
+
+    /// nxm_shared.
+    struct nxm_shared {
+        int64_t nxm_callback;              //!< address of upcall routine
+        unsigned int nxm_version;       //!< version number
+        unsigned short nxm_uniq_offset; //!< correction factor for TEB
+        unsigned short pad1;           //!< pad1
+        int64_t space[2];                  //!< future growth
+        struct nxm_sched_state nxm_ss[1]; //!< array of shared areas
+    };
+
+    /// nxm_slot_state_t.
+    enum nxm_slot_state_t {
+        NXM_SLOT_AVAIL,
+        NXM_SLOT_BOUND,
+        NXM_SLOT_UNBOUND,
+        NXM_SLOT_EMPTY
+    };
+
+    /// nxm_config_info
+    struct nxm_config_info {
+        int nxm_nslots_per_rad;         //!< max number of VP slots per RAD
+        int nxm_nrads;                  //!< max number of RADs
+        // nxm_slot_state_t *
+        Addr nxm_slot_state; //!< per-VP slot state
+        // struct nxm_shared *
+        Addr nxm_rad[1];  //!< per-RAD shared areas
+    };
+
+    /// For nxm_thread_create.
+    enum nxm_thread_type {
+        NXM_TYPE_SCS   = 0,
+        NXM_TYPE_VP            = 1,
+        NXM_TYPE_MANAGER       = 2
+    };
+
+    /// Thread attributes.
+    struct nxm_thread_attr {
+        int version;   //!< version
+        int type;      //!< type
+        int cancel_flags;      //!< cancel_flags
+        int priority;  //!< priority
+        int policy;    //!< policy
+        int signal_type;       //!< signal_type
+        // void *
+        Addr pthid;    //!< pthid
+        sigset_t sigmask;      //!< sigmask
+        /// Initial register values.
+        struct {
+            uint64_t pc;       //!< pc
+            uint64_t sp;       //!< sp
+            uint64_t a0;       //!< a0
+        } registers;
+        uint64_t pad2[2];      //!< pad2
+    };
+
+    /// Helper function to convert a host stat buffer to a target stat
+    /// buffer.  Also copies the target buffer out to the simulated
+    /// memorty space.  Used by stat(), fstat(), and lstat().
+    static void
+    copyOutStatBuf(FunctionalMemory *mem, Addr addr, struct stat *host)
+    {
+        TypedBufferArg<Tru64::F64_stat> tgt(addr);
+
+        tgt->st_dev = host->st_dev;
+        tgt->st_ino = host->st_ino;
+        tgt->st_mode = host->st_mode;
+        tgt->st_nlink = host->st_nlink;
+        tgt->st_uid = host->st_uid;
+        tgt->st_gid = host->st_gid;
+        tgt->st_rdev = host->st_rdev;
+        tgt->st_size = host->st_size;
+        tgt->st_atimeX = host->st_atime;
+        tgt->st_mtimeX = host->st_mtime;
+        tgt->st_ctimeX = host->st_ctime;
+        tgt->st_blksize = host->st_blksize;
+        tgt->st_blocks = host->st_blocks;
+
+        tgt.copyOut(mem);
     }
 
-    return 0;
-}
 
-static
-int
-fcntlFunc(SyscallDesc *desc, int callnum, Process *process,
-           ExecContext *xc)
-{
-    int fd = xc->getSyscallArg(0);
+    /// The target system's hostname.
+    static const char *hostname;
 
-    if (fd < 0 || process->sim_fd(fd) < 0)
-        return -EBADF;
+    /// Target uname() handler.
+    static int
+    unameFunc(SyscallDesc *desc, int callnum, Process *process,
+              ExecContext *xc)
+    {
+        TypedBufferArg<Tru64::utsname> name(xc->getSyscallArg(0));
 
-    int cmd = xc->getSyscallArg(1);
-    switch (cmd) {
-      case 0: // F_DUPFD
-        // if we really wanted to support this, we'd need to do it
-        // in the target fd space.
-        warn("fcntl(%d, F_DUPFD) not supported, error returned\n", fd);
-        return -EMFILE;
+        strcpy(name->sysname, "OSF1");
+        strcpy(name->nodename, hostname);
+        strcpy(name->release, "V5.1");
+        strcpy(name->version, "732");
+        strcpy(name->machine, "alpha");
 
-      case 1: // F_GETFD (get close-on-exec flag)
-      case 2: // F_SETFD (set close-on-exec flag)
+        name.copyOut(xc->mem);
         return 0;
+    }
 
-      case 3: // F_GETFL (get file flags)
-      case 4: // F_SETFL (set file flags)
-        // not sure if this is totally valid, but we'll pass it through
-        // to the underlying OS
-        warn("fcntl(%d, %d) passed through to host\n", fd, cmd);
-        return fcntl(process->sim_fd(fd), cmd);
-        // return 0;
-
-      case 7: // F_GETLK  (get lock)
-      case 8: // F_SETLK  (set lock)
-      case 9: // F_SETLKW (set lock and wait)
-        // don't mess with file locking... just act like it's OK
-        warn("File lock call (fcntl(%d, %d)) ignored.\n", fd, cmd);
-        return 0;
 
-      default:
-        warn("Unknown fcntl command %d\n", cmd);
+    /// Target getsysyinfo() handler.
+    static int
+    getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
+                   ExecContext *xc)
+    {
+        unsigned op = xc->getSyscallArg(0);
+        unsigned nbytes = xc->getSyscallArg(2);
+
+        switch (op) {
+
+          case Tru64::GSI_MAX_CPU: {
+              TypedBufferArg<uint32_t> max_cpu(xc->getSyscallArg(1));
+              *max_cpu = process->numCpus();
+              max_cpu.copyOut(xc->mem);
+              return 1;
+          }
+
+          case Tru64::GSI_CPUS_IN_BOX: {
+              TypedBufferArg<uint32_t> cpus_in_box(xc->getSyscallArg(1));
+              *cpus_in_box = process->numCpus();
+              cpus_in_box.copyOut(xc->mem);
+              return 1;
+          }
+
+          case Tru64::GSI_PHYSMEM: {
+              TypedBufferArg<uint64_t> physmem(xc->getSyscallArg(1));
+              *physmem = 1024 * 1024;  // physical memory in KB
+              physmem.copyOut(xc->mem);
+              return 1;
+          }
+
+          case Tru64::GSI_CPU_INFO: {
+              TypedBufferArg<Tru64::cpu_info> infop(xc->getSyscallArg(1));
+
+              infop->current_cpu = 0;
+              infop->cpus_in_box = process->numCpus();
+              infop->cpu_type = 57;
+              infop->ncpus = process->numCpus();
+              int cpumask = (1 << process->numCpus()) - 1;
+              infop->cpus_present = infop->cpus_running = cpumask;
+              infop->cpu_binding = 0;
+              infop->cpu_ex_binding = 0;
+              infop->mhz = 667;
+
+              infop.copyOut(xc->mem);
+              return 1;
+          }
+
+          case Tru64::GSI_PROC_TYPE: {
+              TypedBufferArg<uint64_t> proc_type(xc->getSyscallArg(1));
+              *proc_type = 11;
+              proc_type.copyOut(xc->mem);
+              return 1;
+          }
+
+          case Tru64::GSI_PLATFORM_NAME: {
+              BufferArg bufArg(xc->getSyscallArg(1), nbytes);
+              strncpy((char *)bufArg.bufferPtr(),
+                      "COMPAQ Professional Workstation XP1000",
+                      nbytes);
+              bufArg.copyOut(xc->mem);
+              return 1;
+          }
+
+          case Tru64::GSI_CLK_TCK: {
+              TypedBufferArg<uint64_t> clk_hz(xc->getSyscallArg(1));
+              *clk_hz = 1024;
+              clk_hz.copyOut(xc->mem);
+              return 1;
+          }
+
+          default:
+            cerr << "getsysinfo: unknown op " << op << endl;
+            abort();
+            break;
+        }
+
         return 0;
     }
-}
 
+    /// Target fnctl() handler.
+    static int
+    fcntlFunc(SyscallDesc *desc, int callnum, Process *process,
+              ExecContext *xc)
+    {
+        int fd = xc->getSyscallArg(0);
+
+        if (fd < 0 || process->sim_fd(fd) < 0)
+            return -EBADF;
+
+        int cmd = xc->getSyscallArg(1);
+        switch (cmd) {
+          case 0: // F_DUPFD
+            // if we really wanted to support this, we'd need to do it
+            // in the target fd space.
+            warn("fcntl(%d, F_DUPFD) not supported, error returned\n", fd);
+            return -EMFILE;
+
+          case 1: // F_GETFD (get close-on-exec flag)
+          case 2: // F_SETFD (set close-on-exec flag)
+            return 0;
+
+          case 3: // F_GETFL (get file flags)
+          case 4: // F_SETFL (set file flags)
+            // not sure if this is totally valid, but we'll pass it through
+            // to the underlying OS
+            warn("fcntl(%d, %d) passed through to host\n", fd, cmd);
+            return fcntl(process->sim_fd(fd), cmd);
+            // return 0;
+
+          case 7: // F_GETLK  (get lock)
+          case 8: // F_SETLK  (set lock)
+          case 9: // F_SETLKW (set lock and wait)
+            // don't mess with file locking... just act like it's OK
+            warn("File lock call (fcntl(%d, %d)) ignored.\n", fd, cmd);
+            return 0;
+
+          default:
+            warn("Unknown fcntl command %d\n", cmd);
+            return 0;
+        }
+    }
 
-static
-int
-getdirentriesFunc(SyscallDesc *desc, int callnum, Process *process,
-                  ExecContext *xc)
-{
-    int fd = process->sim_fd(xc->getSyscallArg(0));
-    Addr tgt_buf = xc->getSyscallArg(1);
-    int tgt_nbytes = xc->getSyscallArg(2);
-    Addr tgt_basep = xc->getSyscallArg(3);
 
-    char * const host_buf = new char[tgt_nbytes];
+    /// Target getdirentries() handler.
+    static int
+    getdirentriesFunc(SyscallDesc *desc, int callnum, Process *process,
+                      ExecContext *xc)
+    {
+        int fd = process->sim_fd(xc->getSyscallArg(0));
+        Addr tgt_buf = xc->getSyscallArg(1);
+        int tgt_nbytes = xc->getSyscallArg(2);
+        Addr tgt_basep = xc->getSyscallArg(3);
+
+        char * const host_buf = new char[tgt_nbytes];
+
+        // just pass basep through uninterpreted.
+        TypedBufferArg<int64_t> basep(tgt_basep);
+        basep.copyIn(xc->mem);
+        ::off_t host_basep = (off_t)*basep;
+        int host_result = getdirentries(fd, host_buf, tgt_nbytes, &host_basep);
+
+        // check for error
+        if (host_result < 0) {
+            delete [] host_buf;
+            return -errno;
+        }
 
-    // just pass basep through uninterpreted.
-    TypedBufferArg<int64_t> basep(tgt_basep);
-    basep.copyIn(xc->mem);
-    ::off_t host_basep = (off_t)*basep;
-    int host_result = getdirentries(fd, host_buf, tgt_nbytes, &host_basep);
+        // no error: copy results back to target space
+        Addr tgt_buf_ptr = tgt_buf;
+        char *host_buf_ptr = host_buf;
+        char *host_buf_end = host_buf + host_result;
+        while (host_buf_ptr < host_buf_end) {
+            struct dirent *host_dp = (struct dirent *)host_buf_ptr;
+            int namelen = strlen(host_dp->d_name);
+
+            // Actual size includes padded string rounded up for alignment.
+            // Subtract 256 for dummy char array in Tru64::dirent definition.
+            // Add 1 to namelen for terminating null char.
+            int tgt_bufsize = sizeof(Tru64::dirent) - 256 + RoundUp(namelen+1, 8);
+            TypedBufferArg<Tru64::dirent> tgt_dp(tgt_buf_ptr, tgt_bufsize);
+            tgt_dp->d_ino = host_dp->d_ino;
+            tgt_dp->d_reclen = tgt_bufsize;
+            tgt_dp->d_namlen = namelen;
+            strcpy(tgt_dp->d_name, host_dp->d_name);
+            tgt_dp.copyOut(xc->mem);
+
+            tgt_buf_ptr += tgt_bufsize;
+            host_buf_ptr += host_dp->d_reclen;
+        }
 
-    // check for error
-    if (host_result < 0) {
         delete [] host_buf;
-        return -errno;
-    }
-
-    // no error: copy results back to target space
-    Addr tgt_buf_ptr = tgt_buf;
-    char *host_buf_ptr = host_buf;
-    char *host_buf_end = host_buf + host_result;
-    while (host_buf_ptr < host_buf_end) {
-        struct dirent *host_dp = (struct dirent *)host_buf_ptr;
-        int namelen = strlen(host_dp->d_name);
-
-        // Actual size includes padded string rounded up for alignment.
-        // Subtract 256 for dummy char array in Tru64::dirent definition.
-        // Add 1 to namelen for terminating null char.
-        int tgt_bufsize = sizeof(Tru64::dirent) - 256 + RoundUp(namelen+1, 8);
-        TypedBufferArg<Tru64::dirent> tgt_dp(tgt_buf_ptr, tgt_bufsize);
-        tgt_dp->d_ino = host_dp->d_ino;
-        tgt_dp->d_reclen = tgt_bufsize;
-        tgt_dp->d_namlen = namelen;
-        strcpy(tgt_dp->d_name, host_dp->d_name);
-        tgt_dp.copyOut(xc->mem);
-
-        tgt_buf_ptr += tgt_bufsize;
-        host_buf_ptr += host_dp->d_reclen;
-    }
 
-    delete [] host_buf;
+        *basep = host_basep;
+        basep.copyOut(xc->mem);
 
-    *basep = host_basep;
-    basep.copyOut(xc->mem);
+        return (tgt_buf_ptr - tgt_buf);
+    }
 
-    return (tgt_buf_ptr - tgt_buf);
-}
+    /// Target sigreturn() handler.
+    static int
+    sigreturnFunc(SyscallDesc *desc, int callnum, Process *process,
+                  ExecContext *xc)
+    {
+        RegFile *regs = &xc->regs;
+        TypedBufferArg<Tru64::sigcontext> sc(xc->getSyscallArg(0));
 
+        sc.copyIn(xc->mem);
 
-static
-int
-sigreturnFunc(SyscallDesc *desc, int callnum, Process *process,
-              ExecContext *xc)
-{
-    RegFile *regs = &xc->regs;
-    TypedBufferArg<Tru64::sigcontext> sc(xc->getSyscallArg(0));
+        // Restore state from sigcontext structure.
+        // Note that we'll advance PC <- NPC before the end of the cycle,
+        // so we need to restore the desired PC into NPC.
+        // The current regs->pc will get clobbered.
+        regs->npc = sc->sc_pc;
 
-    sc.copyIn(xc->mem);
+        for (int i = 0; i < 31; ++i) {
+            regs->intRegFile[i] = sc->sc_regs[i];
+            regs->floatRegFile.q[i] = sc->sc_fpregs[i];
+        }
 
-    // Restore state from sigcontext structure.
-    // Note that we'll advance PC <- NPC before the end of the cycle,
-    // so we need to restore the desired PC into NPC.
-    // The current regs->pc will get clobbered.
-    regs->npc = sc->sc_pc;
+        regs->miscRegs.fpcr = sc->sc_fpcr;
 
-    for (int i = 0; i < 31; ++i) {
-        regs->intRegFile[i] = sc->sc_regs[i];
-        regs->floatRegFile.q[i] = sc->sc_fpregs[i];
+        return 0;
     }
 
-    regs->miscRegs.fpcr = sc->sc_fpcr;
-
-    return 0;
-}
-
-static
-int
-tableFunc(SyscallDesc *desc, int callnum, Process *process,
-          ExecContext *xc)
-{
-    int id = xc->getSyscallArg(0);             // table ID
-    int index = xc->getSyscallArg(1);  // index into table
-    // arg 2 is buffer pointer; type depends on table ID
-    int nel = xc->getSyscallArg(3);            // number of elements
-    int lel = xc->getSyscallArg(4);            // expected element size
-
-    switch (id) {
-      case Tru64::TBL_SYSINFO: {
-          if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo))
-              return -EINVAL;
-          TypedBufferArg<Tru64::tbl_sysinfo> elp(xc->getSyscallArg(2));
-
-          const int clk_hz = one_million;
-          elp->si_user = curTick / (ticksPerSecond / clk_hz);
-          elp->si_nice = 0;
-          elp->si_sys = 0;
-          elp->si_idle = 0;
-          elp->wait = 0;
-          elp->si_hz = clk_hz;
-          elp->si_phz = clk_hz;
-          elp->si_boottime = seconds_since_epoch; // seconds since epoch?
-          elp->si_max_procs = process->numCpus();
-          elp.copyOut(xc->mem);
-          return 0;
-      }
-
-      default:
-        cerr << "table(): id " << id << " unknown." << endl;
-        return -EINVAL;
+    /// Target table() handler.
+    static int
+    tableFunc(SyscallDesc *desc, int callnum, Process *process,
+              ExecContext *xc)
+    {
+        int id = xc->getSyscallArg(0);         // table ID
+        int index = xc->getSyscallArg(1);      // index into table
+        // arg 2 is buffer pointer; type depends on table ID
+        int nel = xc->getSyscallArg(3);                // number of elements
+        int lel = xc->getSyscallArg(4);                // expected element size
+
+        switch (id) {
+          case Tru64::TBL_SYSINFO: {
+              if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo))
+                  return -EINVAL;
+              TypedBufferArg<Tru64::tbl_sysinfo> elp(xc->getSyscallArg(2));
+
+              const int clk_hz = one_million;
+              elp->si_user = curTick / (ticksPerSecond / clk_hz);
+              elp->si_nice = 0;
+              elp->si_sys = 0;
+              elp->si_idle = 0;
+              elp->wait = 0;
+              elp->si_hz = clk_hz;
+              elp->si_phz = clk_hz;
+              elp->si_boottime = seconds_since_epoch; // seconds since epoch?
+              elp->si_max_procs = process->numCpus();
+              elp.copyOut(xc->mem);
+              return 0;
+          }
+
+          default:
+            cerr << "table(): id " << id << " unknown." << endl;
+            return -EINVAL;
+        }
     }
-}
 
-static SyscallDesc syscallDescs[];
+    /// Array of syscall descriptors, indexed by call number.
+    static SyscallDesc syscallDescs[];
 
-static const int Num_Syscall_Descs;
-static const int Max_Syscall_Desc;
+    /// Number of syscalls in syscallDescs[].
+    static const int Num_Syscall_Descs;
 
-//
-// Mach syscalls -- identified by negated syscall numbers
-//
+    /// Max supported syscall number.
+    static const int Max_Syscall_Desc;
 
-// Create a stack region for a thread.
-static
-int
-stack_createFunc(SyscallDesc *desc, int callnum, Process *process,
-                 ExecContext *xc)
-{
-    TypedBufferArg<Tru64::vm_stack> argp(xc->getSyscallArg(0));
+    //
+    // Mach syscalls -- identified by negated syscall numbers
+    //
 
-    argp.copyIn(xc->mem);
+    /// Create a stack region for a thread.
+    static int
+    stack_createFunc(SyscallDesc *desc, int callnum, Process *process,
+                     ExecContext *xc)
+    {
+        TypedBufferArg<Tru64::vm_stack> argp(xc->getSyscallArg(0));
+
+        argp.copyIn(xc->mem);
+
+        // if the user chose an address, just let them have it.  Otherwise
+        // pick one for them.
+        if (argp->address == 0) {
+            argp->address = process->next_thread_stack_base;
+            int stack_size = (argp->rsize + argp->ysize + argp->gsize);
+            process->next_thread_stack_base -= stack_size;
+            argp.copyOut(xc->mem);
+        }
 
-    // if the user chose an address, just let them have it.  Otherwise
-    // pick one for them.
-    if (argp->address == 0) {
-        argp->address = process->next_thread_stack_base;
-        int stack_size = (argp->rsize + argp->ysize + argp->gsize);
-        process->next_thread_stack_base -= stack_size;
-        argp.copyOut(xc->mem);
+        return 0;
     }
 
-    return 0;
-}
-
-static
-const int NXM_LIB_VERSION = 301003;
-
-//
-// This call sets up the interface between the user and kernel
-// schedulers by creating a shared-memory region.  The shared memory
-// region has several structs, some global, some per-RAD, some per-VP.
-//
-static
-int
-nxm_task_initFunc(SyscallDesc *desc, int callnum, Process *process,
-                 ExecContext *xc)
-{
-    TypedBufferArg<Tru64::nxm_task_attr> attrp(xc->getSyscallArg(0));
-    TypedBufferArg<Addr> configptr_ptr(xc->getSyscallArg(1));
+    /// NXM library version stamp.
+    static
+    const int NXM_LIB_VERSION = 301003;
 
-    attrp.copyIn(xc->mem);
-
-    if (attrp->nxm_version != NXM_LIB_VERSION) {
-        cerr << "nxm_task_init: thread library version mismatch! "
-             << "got " << attrp->nxm_version
-             << ", expected " << NXM_LIB_VERSION << endl;
-        abort();
-    }
+    /// This call sets up the interface between the user and kernel
+    /// schedulers by creating a shared-memory region.  The shared memory
+    /// region has several structs, some global, some per-RAD, some per-VP.
+    static int
+    nxm_task_initFunc(SyscallDesc *desc, int callnum, Process *process,
+                      ExecContext *xc)
+    {
+        TypedBufferArg<Tru64::nxm_task_attr> attrp(xc->getSyscallArg(0));
+        TypedBufferArg<Addr> configptr_ptr(xc->getSyscallArg(1));
 
-    if (attrp->flags != Tru64::NXM_TASK_INIT_VP) {
-        cerr << "nxm_task_init: bad flag value " << attrp->flags
-             << " (expected " << Tru64::NXM_TASK_INIT_VP << ")" << endl;
-        abort();
-    }
+        attrp.copyIn(xc->mem);
 
-    const Addr base_addr = 0x12000; // was 0x3f0000000LL;
-    Addr cur_addr = base_addr; // next addresses to use
-    // first comes the config_info struct
-    Addr config_addr = cur_addr;
-    cur_addr += sizeof(Tru64::nxm_config_info);
-    // next comes the per-cpu state vector
-    Addr slot_state_addr = cur_addr;
-    int slot_state_size = process->numCpus() * sizeof(Tru64::nxm_slot_state_t);
-    cur_addr += slot_state_size;
-    // now the per-RAD state struct (we only support one RAD)
-    cur_addr = 0x14000;        // bump up addr for alignment
-    Addr rad_state_addr = cur_addr;
-    int rad_state_size =
-        (sizeof(Tru64::nxm_shared)
-         + (process->numCpus()-1) * sizeof(Tru64::nxm_sched_state));
-    cur_addr += rad_state_size;
-
-    // now initialize a config_info struct and copy it out to user space
-    TypedBufferArg<Tru64::nxm_config_info> config(config_addr);
-
-    config->nxm_nslots_per_rad = process->numCpus();
-    config->nxm_nrads = 1;     // only one RAD in our system!
-    config->nxm_slot_state = slot_state_addr;
-    config->nxm_rad[0] = rad_state_addr;
-
-    config.copyOut(xc->mem);
-
-    // initialize the slot_state array and copy it out
-    TypedBufferArg<Tru64::nxm_slot_state_t> slot_state(slot_state_addr,
-                                                     slot_state_size);
-    for (int i = 0; i < process->numCpus(); ++i) {
-        // CPU 0 is bound to the calling process; all others are available
-        slot_state[i] = (i == 0) ? Tru64::NXM_SLOT_BOUND : Tru64::NXM_SLOT_AVAIL;
-    }
+        if (attrp->nxm_version != NXM_LIB_VERSION) {
+            cerr << "nxm_task_init: thread library version mismatch! "
+                 << "got " << attrp->nxm_version
+                 << ", expected " << NXM_LIB_VERSION << endl;
+            abort();
+        }
 
-    slot_state.copyOut(xc->mem);
-
-    // same for the per-RAD "shared" struct.  Note that we need to
-    // allocate extra bytes for the per-VP array which is embedded at
-    // the end.
-    TypedBufferArg<Tru64::nxm_shared> rad_state(rad_state_addr,
-                                              rad_state_size);
-
-    rad_state->nxm_callback = attrp->nxm_callback;
-    rad_state->nxm_version = attrp->nxm_version;
-    rad_state->nxm_uniq_offset = attrp->nxm_uniq_offset;
-    for (int i = 0; i < process->numCpus(); ++i) {
-        Tru64::nxm_sched_state *ssp = &rad_state->nxm_ss[i];
-        ssp->nxm_u.sigmask = 0;
-        ssp->nxm_u.sig = 0;
-        ssp->nxm_u.flags = 0;
-        ssp->nxm_u.cancel_state = 0;
-        ssp->nxm_u.nxm_ssig = 0;
-        ssp->nxm_bits = 0;
-        ssp->nxm_quantum = attrp->nxm_quantum;
-        ssp->nxm_set_quantum = attrp->nxm_quantum;
-        ssp->nxm_sysevent = 0;
-
-        if (i == 0) {
-            uint64_t uniq = xc->regs.miscRegs.uniq;
-            ssp->nxm_u.pth_id = uniq + attrp->nxm_uniq_offset;
-            ssp->nxm_u.nxm_active = uniq | 1;
+        if (attrp->flags != Tru64::NXM_TASK_INIT_VP) {
+            cerr << "nxm_task_init: bad flag value " << attrp->flags
+                 << " (expected " << Tru64::NXM_TASK_INIT_VP << ")" << endl;
+            abort();
         }
-        else {
-            ssp->nxm_u.pth_id = 0;
-            ssp->nxm_u.nxm_active = 0;
+
+        const Addr base_addr = 0x12000; // was 0x3f0000000LL;
+        Addr cur_addr = base_addr; // next addresses to use
+        // first comes the config_info struct
+        Addr config_addr = cur_addr;
+        cur_addr += sizeof(Tru64::nxm_config_info);
+        // next comes the per-cpu state vector
+        Addr slot_state_addr = cur_addr;
+        int slot_state_size =
+            process->numCpus() * sizeof(Tru64::nxm_slot_state_t);
+        cur_addr += slot_state_size;
+        // now the per-RAD state struct (we only support one RAD)
+        cur_addr = 0x14000;    // bump up addr for alignment
+        Addr rad_state_addr = cur_addr;
+        int rad_state_size =
+            (sizeof(Tru64::nxm_shared)
+             + (process->numCpus()-1) * sizeof(Tru64::nxm_sched_state));
+        cur_addr += rad_state_size;
+
+        // now initialize a config_info struct and copy it out to user space
+        TypedBufferArg<Tru64::nxm_config_info> config(config_addr);
+
+        config->nxm_nslots_per_rad = process->numCpus();
+        config->nxm_nrads = 1; // only one RAD in our system!
+        config->nxm_slot_state = slot_state_addr;
+        config->nxm_rad[0] = rad_state_addr;
+
+        config.copyOut(xc->mem);
+
+        // initialize the slot_state array and copy it out
+        TypedBufferArg<Tru64::nxm_slot_state_t> slot_state(slot_state_addr,
+                                                           slot_state_size);
+        for (int i = 0; i < process->numCpus(); ++i) {
+            // CPU 0 is bound to the calling process; all others are available
+            slot_state[i] =
+                (i == 0) ? Tru64::NXM_SLOT_BOUND : Tru64::NXM_SLOT_AVAIL;
         }
-    }
 
-    rad_state.copyOut(xc->mem);
+        slot_state.copyOut(xc->mem);
 
-    //
-    // copy pointer to shared config area out to user
-    //
-    *configptr_ptr = config_addr;
-    configptr_ptr.copyOut(xc->mem);
+        // same for the per-RAD "shared" struct.  Note that we need to
+        // allocate extra bytes for the per-VP array which is embedded at
+        // the end.
+        TypedBufferArg<Tru64::nxm_shared> rad_state(rad_state_addr,
+                                                    rad_state_size);
 
-    return 0;
-}
+        rad_state->nxm_callback = attrp->nxm_callback;
+        rad_state->nxm_version = attrp->nxm_version;
+        rad_state->nxm_uniq_offset = attrp->nxm_uniq_offset;
+        for (int i = 0; i < process->numCpus(); ++i) {
+            Tru64::nxm_sched_state *ssp = &rad_state->nxm_ss[i];
+            ssp->nxm_u.sigmask = 0;
+            ssp->nxm_u.sig = 0;
+            ssp->nxm_u.flags = 0;
+            ssp->nxm_u.cancel_state = 0;
+            ssp->nxm_u.nxm_ssig = 0;
+            ssp->nxm_bits = 0;
+            ssp->nxm_quantum = attrp->nxm_quantum;
+            ssp->nxm_set_quantum = attrp->nxm_quantum;
+            ssp->nxm_sysevent = 0;
+
+            if (i == 0) {
+                uint64_t uniq = xc->regs.miscRegs.uniq;
+                ssp->nxm_u.pth_id = uniq + attrp->nxm_uniq_offset;
+                ssp->nxm_u.nxm_active = uniq | 1;
+            }
+            else {
+                ssp->nxm_u.pth_id = 0;
+                ssp->nxm_u.nxm_active = 0;
+            }
+        }
 
+        rad_state.copyOut(xc->mem);
 
-static void
-init_exec_context(ExecContext *ec,
-                  Tru64::nxm_thread_attr *attrp, uint64_t uniq_val)
-{
-    memset(&ec->regs, 0, sizeof(ec->regs));
+        //
+        // copy pointer to shared config area out to user
+        //
+        *configptr_ptr = config_addr;
+        configptr_ptr.copyOut(xc->mem);
 
-    ec->regs.intRegFile[ArgumentReg0] = attrp->registers.a0;
-    ec->regs.intRegFile[27/*t12*/] = attrp->registers.pc;
-    ec->regs.intRegFile[StackPointerReg] = attrp->registers.sp;
-    ec->regs.miscRegs.uniq = uniq_val;
+        return 0;
+    }
 
-    ec->regs.pc = attrp->registers.pc;
-    ec->regs.npc = attrp->registers.pc + sizeof(MachInst);
+    /// Initialize execution context.
+    static void
+    init_exec_context(ExecContext *ec,
+                      Tru64::nxm_thread_attr *attrp, uint64_t uniq_val)
+    {
+        memset(&ec->regs, 0, sizeof(ec->regs));
 
-    ec->setStatus(ExecContext::Active);
-}
+        ec->regs.intRegFile[ArgumentReg0] = attrp->registers.a0;
+        ec->regs.intRegFile[27/*t12*/] = attrp->registers.pc;
+        ec->regs.intRegFile[StackPointerReg] = attrp->registers.sp;
+        ec->regs.miscRegs.uniq = uniq_val;
 
-static
-int
-nxm_thread_createFunc(SyscallDesc *desc, int callnum, Process *process,
-                      ExecContext *xc)
-{
-    TypedBufferArg<Tru64::nxm_thread_attr> attrp(xc->getSyscallArg(0));
-    TypedBufferArg<uint64_t> kidp(xc->getSyscallArg(1));
-    int thread_index = xc->getSyscallArg(2);
-
-    // get attribute args
-    attrp.copyIn(xc->mem);
-
-    if (attrp->version != NXM_LIB_VERSION) {
-        cerr << "nxm_thread_create: thread library version mismatch! "
-             << "got " << attrp->version
-             << ", expected " << NXM_LIB_VERSION << endl;
-        abort();
-    }
+        ec->regs.pc = attrp->registers.pc;
+        ec->regs.npc = attrp->registers.pc + sizeof(MachInst);
 
-    if (thread_index < 0 | thread_index > process->numCpus()) {
-        cerr << "nxm_thread_create: bad thread index " << thread_index
-             << endl;
-        abort();
+        ec->setStatus(ExecContext::Active);
     }
 
-    // On a real machine, the per-RAD shared structure is in
-    // shared memory, so both the user and kernel can get at it.
-    // We don't have that luxury, so we just copy it in and then
-    // back out again.
-    int rad_state_size =
-        (sizeof(Tru64::nxm_shared) +
-         (process->numCpus()-1) * sizeof(Tru64::nxm_sched_state));
+    /// Create thread.
+    static int
+    nxm_thread_createFunc(SyscallDesc *desc, int callnum, Process *process,
+                          ExecContext *xc)
+    {
+        TypedBufferArg<Tru64::nxm_thread_attr> attrp(xc->getSyscallArg(0));
+        TypedBufferArg<uint64_t> kidp(xc->getSyscallArg(1));
+        int thread_index = xc->getSyscallArg(2);
+
+        // get attribute args
+        attrp.copyIn(xc->mem);
+
+        if (attrp->version != NXM_LIB_VERSION) {
+            cerr << "nxm_thread_create: thread library version mismatch! "
+                 << "got " << attrp->version
+                 << ", expected " << NXM_LIB_VERSION << endl;
+            abort();
+        }
 
-    TypedBufferArg<Tru64::nxm_shared> rad_state(0x14000,
-                                              rad_state_size);
-    rad_state.copyIn(xc->mem);
+        if (thread_index < 0 | thread_index > process->numCpus()) {
+            cerr << "nxm_thread_create: bad thread index " << thread_index
+                 << endl;
+            abort();
+        }
 
-    uint64_t uniq_val = attrp->pthid - rad_state->nxm_uniq_offset;
+        // On a real machine, the per-RAD shared structure is in
+        // shared memory, so both the user and kernel can get at it.
+        // We don't have that luxury, so we just copy it in and then
+        // back out again.
+        int rad_state_size =
+            (sizeof(Tru64::nxm_shared) +
+             (process->numCpus()-1) * sizeof(Tru64::nxm_sched_state));
 
-    if (attrp->type == Tru64::NXM_TYPE_MANAGER) {
-        // DEC pthreads seems to always create one of these (in
-        // addition to N application threads), but we don't use it,
-        // so don't bother creating it.
+        TypedBufferArg<Tru64::nxm_shared> rad_state(0x14000,
+                                                    rad_state_size);
+        rad_state.copyIn(xc->mem);
 
-        // This is supposed to be a port number.  Make something up.
-        *kidp = 99;
-        kidp.copyOut(xc->mem);
+        uint64_t uniq_val = attrp->pthid - rad_state->nxm_uniq_offset;
 
-        return 0;
-    } else if (attrp->type == Tru64::NXM_TYPE_VP) {
-        // A real "virtual processor" kernel thread.  Need to fork
-        // this thread on another CPU.
-        Tru64::nxm_sched_state *ssp = &rad_state->nxm_ss[thread_index];
+        if (attrp->type == Tru64::NXM_TYPE_MANAGER) {
+            // DEC pthreads seems to always create one of these (in
+            // addition to N application threads), but we don't use it,
+            // so don't bother creating it.
 
-        if (ssp->nxm_u.nxm_active != 0)
-            return Tru64::KERN_NOT_RECEIVER;
+            // This is supposed to be a port number.  Make something up.
+            *kidp = 99;
+            kidp.copyOut(xc->mem);
 
-        ssp->nxm_u.pth_id = attrp->pthid;
-        ssp->nxm_u.nxm_active = uniq_val | 1;
+            return 0;
+        } else if (attrp->type == Tru64::NXM_TYPE_VP) {
+            // A real "virtual processor" kernel thread.  Need to fork
+            // this thread on another CPU.
+            Tru64::nxm_sched_state *ssp = &rad_state->nxm_ss[thread_index];
 
-        rad_state.copyOut(xc->mem);
+            if (ssp->nxm_u.nxm_active != 0)
+                return Tru64::KERN_NOT_RECEIVER;
 
-        Addr slot_state_addr = 0x12000 + sizeof(Tru64::nxm_config_info);
-        int slot_state_size = process->numCpus() * sizeof(Tru64::nxm_slot_state_t);
+            ssp->nxm_u.pth_id = attrp->pthid;
+            ssp->nxm_u.nxm_active = uniq_val | 1;
 
-        TypedBufferArg<Tru64::nxm_slot_state_t> slot_state(slot_state_addr,
-                                                         slot_state_size);
+            rad_state.copyOut(xc->mem);
 
-        slot_state.copyIn(xc->mem);
+            Addr slot_state_addr = 0x12000 + sizeof(Tru64::nxm_config_info);
+            int slot_state_size =
+                process->numCpus() * sizeof(Tru64::nxm_slot_state_t);
 
-        if (slot_state[thread_index] != Tru64::NXM_SLOT_AVAIL) {
-            cerr << "nxm_thread_createFunc: requested VP slot "
-                 << thread_index << " not available!" << endl;
-            fatal("");
-        }
+            TypedBufferArg<Tru64::nxm_slot_state_t>
+                slot_state(slot_state_addr,
+                           slot_state_size);
 
-        slot_state[thread_index] = Tru64::NXM_SLOT_BOUND;
+            slot_state.copyIn(xc->mem);
 
-        slot_state.copyOut(xc->mem);
+            if (slot_state[thread_index] != Tru64::NXM_SLOT_AVAIL) {
+                cerr << "nxm_thread_createFunc: requested VP slot "
+                     << thread_index << " not available!" << endl;
+                fatal("");
+            }
 
-        // Find a free simulator execution context.
-        for (int i = 0; i < process->numCpus(); ++i) {
-            ExecContext *xc = process->execContexts[i];
+            slot_state[thread_index] = Tru64::NXM_SLOT_BOUND;
 
-            if (xc->status() == ExecContext::Unallocated) {
-                // inactive context... grab it
-                init_exec_context(xc, attrp, uniq_val);
+            slot_state.copyOut(xc->mem);
 
-                // This is supposed to be a port number, but we'll try
-                // and get away with just sticking the thread index
-                // here.
-                *kidp = thread_index;
-                kidp.copyOut(xc->mem);
+            // Find a free simulator execution context.
+            for (int i = 0; i < process->numCpus(); ++i) {
+                ExecContext *xc = process->execContexts[i];
 
-                return 0;
+                if (xc->status() == ExecContext::Unallocated) {
+                    // inactive context... grab it
+                    init_exec_context(xc, attrp, uniq_val);
+
+                    // This is supposed to be a port number, but we'll try
+                    // and get away with just sticking the thread index
+                    // here.
+                    *kidp = thread_index;
+                    kidp.copyOut(xc->mem);
+
+                    return 0;
+                }
             }
+
+            // fell out of loop... no available inactive context
+            cerr << "nxm_thread_create: no idle contexts available." << endl;
+            abort();
+        } else {
+            cerr << "nxm_thread_create: can't handle thread type "
+                 << attrp->type << endl;
+            abort();
         }
 
-        // fell out of loop... no available inactive context
-        cerr << "nxm_thread_create: no idle contexts available." << endl;
-        abort();
-    } else {
-        cerr << "nxm_thread_create: can't handle thread type "
-             << attrp->type << endl;
-        abort();
+        return 0;
     }
 
-    return 0;
-}
-
+    /// Thread idle call (like yield()).
+    static int
+    nxm_idleFunc(SyscallDesc *desc, int callnum, Process *process,
+                 ExecContext *xc)
+    {
+        return 0;
+    }
 
-static
-int
-nxm_idleFunc(SyscallDesc *desc, int callnum, Process *process,
-             ExecContext *xc)
-{
-    return 0;
-}
+    /// Block thread.
+    static int
+    nxm_thread_blockFunc(SyscallDesc *desc, int callnum, Process *process,
+                         ExecContext *xc)
+    {
+        uint64_t tid = xc->getSyscallArg(0);
+        uint64_t secs = xc->getSyscallArg(1);
+        uint64_t flags = xc->getSyscallArg(2);
+        uint64_t action = xc->getSyscallArg(3);
+        uint64_t usecs = xc->getSyscallArg(4);
 
-static
-int
-nxm_thread_blockFunc(SyscallDesc *desc, int callnum, Process *process,
-                     ExecContext *xc)
-{
-    uint64_t tid = xc->getSyscallArg(0);
-    uint64_t secs = xc->getSyscallArg(1);
-    uint64_t flags = xc->getSyscallArg(2);
-    uint64_t action = xc->getSyscallArg(3);
-    uint64_t usecs = xc->getSyscallArg(4);
+        cout << xc->cpu->name() << ": nxm_thread_block " << tid << " " << secs
+             << " " << flags << " " << action << " " << usecs << endl;
 
-    cout << xc->cpu->name() << ": nxm_thread_block " << tid << " " << secs
-         << " " << flags << " " << action << " " << usecs << endl;
+        return 0;
+    }
 
-    return 0;
-}
+    /// block.
+    static int
+    nxm_blockFunc(SyscallDesc *desc, int callnum, Process *process,
+                  ExecContext *xc)
+    {
+        Addr uaddr = xc->getSyscallArg(0);
+        uint64_t val = xc->getSyscallArg(1);
+        uint64_t secs = xc->getSyscallArg(2);
+        uint64_t usecs = xc->getSyscallArg(3);
+        uint64_t flags = xc->getSyscallArg(4);
 
+        BaseCPU *cpu = xc->cpu;
 
-static
-int
-nxm_blockFunc(SyscallDesc *desc, int callnum, Process *process,
-              ExecContext *xc)
-{
-    Addr uaddr = xc->getSyscallArg(0);
-    uint64_t val = xc->getSyscallArg(1);
-    uint64_t secs = xc->getSyscallArg(2);
-    uint64_t usecs = xc->getSyscallArg(3);
-    uint64_t flags = xc->getSyscallArg(4);
+        cout << cpu->name() << ": nxm_block "
+             << hex << uaddr << dec << " " << val
+             << " " << secs << " " << usecs
+             << " " << flags << endl;
 
-    BaseCPU *cpu = xc->cpu;
+        return 0;
+    }
 
-    cout << cpu->name() << ": nxm_block " << hex << uaddr << dec << " " << val
-         << " " << secs << " " << usecs
-         << " " << flags << endl;
+    /// Unblock thread.
+    static int
+    nxm_unblockFunc(SyscallDesc *desc, int callnum, Process *process,
+                    ExecContext *xc)
+    {
+        Addr uaddr = xc->getSyscallArg(0);
 
-    return 0;
-}
+        cout << xc->cpu->name() << ": nxm_unblock "
+             << hex << uaddr << dec << endl;
 
+        return 0;
+    }
 
-static
-int
-nxm_unblockFunc(SyscallDesc *desc, int callnum, Process *process,
-              ExecContext *xc)
-{
-    Addr uaddr = xc->getSyscallArg(0);
+    /// Switch thread priority.
+    static int
+    swtch_priFunc(SyscallDesc *desc, int callnum, Process *process,
+                  ExecContext *xc)
+    {
+        // Attempts to switch to another runnable thread (if there is
+        // one).  Returns false if there are no other threads to run
+        // (i.e., the thread can reasonably spin-wait) or true if there
+        // are other threads.
+        //
+        // Since we assume at most one "kernel" thread per CPU, it's
+        // always safe to return false here.
+        return false;
+    }
 
-    cout << xc->cpu->name() << ": nxm_unblock "
-         << hex << uaddr << dec << endl;
 
-    return 0;
-}
+    /// Activate exec context waiting on a channel.  Just activate one
+    /// by default.
+    static int
+    activate_waiting_context(Addr uaddr, Process *process,
+                             bool activate_all = false)
+    {
+        int num_activated = 0;
 
+        list<Process::WaitRec>::iterator i = process->waitList.begin();
+        list<Process::WaitRec>::iterator end = process->waitList.end();
 
-static
-int
-swtch_priFunc(SyscallDesc *desc, int callnum, Process *process,
-              ExecContext *xc)
-{
-    // Attempts to switch to another runnable thread (if there is
-    // one).  Returns false if there are no other threads to run
-    // (i.e., the thread can reasonably spin-wait) or true if there
-    // are other threads.
-    //
-    // Since we assume at most one "kernel" thread per CPU, it's
-    // always safe to return false here.
-    return false;
-}
+        while (i != end && (num_activated == 0 || activate_all)) {
+            if (i->waitChan == uaddr) {
+                // found waiting process: make it active
+                ExecContext *newCtx = i->waitingContext;
+                assert(newCtx->status() == ExecContext::Suspended);
+                newCtx->setStatus(ExecContext::Active);
 
+                // get rid of this record
+                i = process->waitList.erase(i);
 
-// just activate one by default
-static int
-activate_waiting_context(Addr uaddr, Process *process,
-                         bool activate_all = false)
-{
-    int num_activated = 0;
+                ++num_activated;
+            } else {
+                ++i;
+            }
+        }
 
-    list<Process::WaitRec>::iterator i = process->waitList.begin();
-    list<Process::WaitRec>::iterator end = process->waitList.end();
+        return num_activated;
+    }
 
-    while (i != end && (num_activated == 0 || activate_all)) {
-        if (i->waitChan == uaddr) {
-            // found waiting process: make it active
-            ExecContext *newCtx = i->waitingContext;
-            assert(newCtx->status() == ExecContext::Suspended);
-            newCtx->setStatus(ExecContext::Active);
+    /// M5 hacked-up lock acquire.
+    static void
+    m5_lock_mutex(Addr uaddr, Process *process, ExecContext *xc)
+    {
+        TypedBufferArg<uint64_t> lockp(uaddr);
 
-            // get rid of this record
-            i = process->waitList.erase(i);
+        lockp.copyIn(xc->mem);
 
-            ++num_activated;
+        if (*lockp == 0) {
+            // lock is free: grab it
+            *lockp = 1;
+            lockp.copyOut(xc->mem);
         } else {
-            ++i;
+            // lock is busy: disable until free
+            process->waitList.push_back(Process::WaitRec(uaddr, xc));
+            xc->setStatus(ExecContext::Suspended);
         }
     }
 
-    return num_activated;
-}
-
+    /// M5 unlock call.
+    static void
+    m5_unlock_mutex(Addr uaddr, Process *process, ExecContext *xc)
+    {
+        TypedBufferArg<uint64_t> lockp(uaddr);
 
-static void
-m5_lock_mutex(Addr uaddr, Process *process, ExecContext *xc)
-{
-    TypedBufferArg<uint64_t> lockp(uaddr);
+        lockp.copyIn(xc->mem);
+        assert(*lockp != 0);
 
-    lockp.copyIn(xc->mem);
+        // Check for a process waiting on the lock.
+        int num_waiting = activate_waiting_context(uaddr, process);
 
-    if (*lockp == 0) {
-        // lock is free: grab it
-        *lockp = 1;
-        lockp.copyOut(xc->mem);
-    } else {
-        // lock is busy: disable until free
-        process->waitList.push_back(Process::WaitRec(uaddr, xc));
-        xc->setStatus(ExecContext::Suspended);
+        // clear lock field if no waiting context is taking over the lock
+        if (num_waiting == 0) {
+            *lockp = 0;
+            lockp.copyOut(xc->mem);
+        }
     }
-}
 
-static void
-m5_unlock_mutex(Addr uaddr, Process *process, ExecContext *xc)
-{
-    TypedBufferArg<uint64_t> lockp(uaddr);
-
-    lockp.copyIn(xc->mem);
-    assert(*lockp != 0);
+    /// Lock acquire syscall handler.
+    static int
+    m5_mutex_lockFunc(SyscallDesc *desc, int callnum, Process *process,
+                      ExecContext *xc)
+    {
+        Addr uaddr = xc->getSyscallArg(0);
 
-    // Check for a process waiting on the lock.
-    int num_waiting = activate_waiting_context(uaddr, process);
+        m5_lock_mutex(uaddr, process, xc);
 
-    // clear lock field if no waiting context is taking over the lock
-    if (num_waiting == 0) {
-        *lockp = 0;
-        lockp.copyOut(xc->mem);
+        // Return 0 since we will always return to the user with the lock
+        // acquired.  We will just keep the context inactive until that is
+        // true.
+        return 0;
     }
-}
-
-
-static
-int
-m5_mutex_lockFunc(SyscallDesc *desc, int callnum, Process *process,
-                  ExecContext *xc)
-{
-    Addr uaddr = xc->getSyscallArg(0);
-
-    m5_lock_mutex(uaddr, process, xc);
-
-    // Return 0 since we will always return to the user with the lock
-    // acquired.  We will just keep the context inactive until that is
-    // true.
-    return 0;
-}
 
+    /// Try lock (non-blocking).
+    static int
+    m5_mutex_trylockFunc(SyscallDesc *desc, int callnum, Process *process,
+                         ExecContext *xc)
+    {
+        Addr uaddr = xc->getSyscallArg(0);
+        TypedBufferArg<uint64_t> lockp(uaddr);
+
+        lockp.copyIn(xc->mem);
+
+        if (*lockp == 0) {
+            // lock is free: grab it
+            *lockp = 1;
+            lockp.copyOut(xc->mem);
+            return 0;
+        } else {
+            return 1;
+        }
+    }
 
-static
-int
-m5_mutex_trylockFunc(SyscallDesc *desc, int callnum, Process *process,
-                     ExecContext *xc)
-{
-    Addr uaddr = xc->getSyscallArg(0);
-    TypedBufferArg<uint64_t> lockp(uaddr);
+    /// Unlock syscall handler.
+    static int
+    m5_mutex_unlockFunc(SyscallDesc *desc, int callnum, Process *process,
+                        ExecContext *xc)
+    {
+        Addr uaddr = xc->getSyscallArg(0);
 
-    lockp.copyIn(xc->mem);
+        m5_unlock_mutex(uaddr, process, xc);
 
-    if (*lockp == 0) {
-        // lock is free: grab it
-        *lockp = 1;
-        lockp.copyOut(xc->mem);
         return 0;
-    } else {
-        return 1;
     }
-}
-
-
-static
-int
-m5_mutex_unlockFunc(SyscallDesc *desc, int callnum, Process *process,
-                    ExecContext *xc)
-{
-    Addr uaddr = xc->getSyscallArg(0);
-
-    m5_unlock_mutex(uaddr, process, xc);
-
-    return 0;
-}
 
+    /// Signal ocndition.
+    static int
+    m5_cond_signalFunc(SyscallDesc *desc, int callnum, Process *process,
+                       ExecContext *xc)
+    {
+        Addr cond_addr = xc->getSyscallArg(0);
 
-static
-int
-m5_cond_signalFunc(SyscallDesc *desc, int callnum, Process *process,
-                   ExecContext *xc)
-{
-    Addr cond_addr = xc->getSyscallArg(0);
-
-    // Wqake up one process waiting on the condition variable.
-    activate_waiting_context(cond_addr, process);
-
-    return 0;
-}
-
+        // Wake up one process waiting on the condition variable.
+        activate_waiting_context(cond_addr, process);
 
-static
-int
-m5_cond_broadcastFunc(SyscallDesc *desc, int callnum, Process *process,
-                      ExecContext *xc)
-{
-    Addr cond_addr = xc->getSyscallArg(0);
-
-    // Wake up all processes waiting on the condition variable.
-    activate_waiting_context(cond_addr, process, true);
-
-    return 0;
-}
-
-
-static
-int
-m5_cond_waitFunc(SyscallDesc *desc, int callnum, Process *process,
-                 ExecContext *xc)
-{
-    Addr cond_addr = xc->getSyscallArg(0);
-    Addr lock_addr = xc->getSyscallArg(1);
-    TypedBufferArg<uint64_t> condp(cond_addr);
-    TypedBufferArg<uint64_t> lockp(lock_addr);
-
-    // user is supposed to acquire lock before entering
-    lockp.copyIn(xc->mem);
-    assert(*lockp != 0);
-
-    m5_unlock_mutex(lock_addr, process, xc);
+        return 0;
+    }
 
-    process->waitList.push_back(Process::WaitRec(cond_addr, xc));
-    xc->setStatus(ExecContext::Suspended);
+    /// Wake up all processes waiting on the condition variable.
+    static int
+    m5_cond_broadcastFunc(SyscallDesc *desc, int callnum, Process *process,
+                          ExecContext *xc)
+    {
+        Addr cond_addr = xc->getSyscallArg(0);
 
-    return 0;
-}
+        activate_waiting_context(cond_addr, process, true);
 
+        return 0;
+    }
 
-static
-int
-m5_thread_exitFunc(SyscallDesc *desc, int callnum, Process *process,
-                   ExecContext *xc)
-{
-    assert(xc->status() == ExecContext::Active);
-    xc->setStatus(ExecContext::Unallocated);
+    /// Wait on a condition.
+    static int
+    m5_cond_waitFunc(SyscallDesc *desc, int callnum, Process *process,
+                     ExecContext *xc)
+    {
+        Addr cond_addr = xc->getSyscallArg(0);
+        Addr lock_addr = xc->getSyscallArg(1);
+        TypedBufferArg<uint64_t> condp(cond_addr);
+        TypedBufferArg<uint64_t> lockp(lock_addr);
 
-    return 0;
-}
+        // user is supposed to acquire lock before entering
+        lockp.copyIn(xc->mem);
+        assert(*lockp != 0);
 
+        m5_unlock_mutex(lock_addr, process, xc);
 
-static SyscallDesc machSyscallDescs[];
+        process->waitList.push_back(Process::WaitRec(cond_addr, xc));
+        xc->setStatus(ExecContext::Suspended);
 
-static const int Num_Mach_Syscall_Descs;
-static const int Max_Mach_Syscall_Desc;
+        return 0;
+    }
 
-// Since negated values are used to identify Mach syscalls, the
-// minimum (signed) valid syscall number is the negated max Mach
-// syscall number.
-static const int Min_Syscall_Desc;
+    /// Thread exit.
+    static int
+    m5_thread_exitFunc(SyscallDesc *desc, int callnum, Process *process,
+                       ExecContext *xc)
+    {
+        assert(xc->status() == ExecContext::Active);
+        xc->setStatus(ExecContext::Unallocated);
 
-//
-// helper function for invoking syscalls
-//
-static
-void
-doSyscall(int callnum, Process *process, ExecContext *xc)
-{
-    if (callnum < Min_Syscall_Desc || callnum > Max_Syscall_Desc) {
-        cerr << "Syscall " << callnum << " out of range" << endl;
-        abort();
+        return 0;
     }
 
-    SyscallDesc *desc =
-        (callnum < 0) ? &machSyscallDescs[-callnum] : &syscallDescs[callnum];
+    /// Array of syscall descriptors for Mach syscalls, indexed by
+    /// (negated) call number.
+    static SyscallDesc machSyscallDescs[];
+
+    /// Number of syscalls in machSyscallDescs[].
+    static const int Num_Mach_Syscall_Descs;
+
+    /// Max supported Mach syscall number.
+    static const int Max_Mach_Syscall_Desc;
+
+    /// Since negated values are used to identify Mach syscalls, the
+    /// minimum (signed) valid syscall number is the negated max Mach
+    /// syscall number.
+    static const int Min_Syscall_Desc;
+
+    /// Do the specified syscall.  Just looks the call number up in
+    /// the table and invokes the appropriate handler.
+    static void
+    doSyscall(int callnum, Process *process, ExecContext *xc)
+    {
+        if (callnum < Min_Syscall_Desc || callnum > Max_Syscall_Desc) {
+            cerr << "Syscall " << callnum << " out of range" << endl;
+            abort();
+        }
 
-    desc->doSyscall(callnum, process, xc);
-}
+        SyscallDesc *desc =
+            (callnum < 0) ?
+            &machSyscallDescs[-callnum] : &syscallDescs[callnum];
 
-//
-// Indirect syscall invocation (call #0)
-//
-static
-int
-indirectSyscallFunc(SyscallDesc *desc, int callnum, Process *process,
-                    ExecContext *xc)
-{
-    int new_callnum = xc->getSyscallArg(0);
+        desc->doSyscall(callnum, process, xc);
+    }
 
-    for (int i = 0; i < 5; ++i)
-        xc->setSyscallArg(i, xc->getSyscallArg(i+1));
+    /// Indirect syscall invocation (call #0).
+    static int
+    indirectSyscallFunc(SyscallDesc *desc, int callnum, Process *process,
+                        ExecContext *xc)
+    {
+        int new_callnum = xc->getSyscallArg(0);
 
-    doSyscall(new_callnum, process, xc);
+        for (int i = 0; i < 5; ++i)
+            xc->setSyscallArg(i, xc->getSyscallArg(i+1));
 
-    return 0;
-}
+        doSyscall(new_callnum, process, xc);
 
+        return 0;
+    }
 
 };  // class Tru64
 
 
 // open(2) flags translation table
 OpenFlagTransTable Tru64::openFlagTable[] = {
-  /* target flag */    /* host flag */
 #ifdef _MSC_VER
   { Tru64::TGT_O_RDONLY,       _O_RDONLY },
   { Tru64::TGT_O_WRONLY,       _O_WRONLY },
index 2b03d66b2d2644d2a25b7dcc6c299dd56ed411ad..8e5a64b518f902ab16ef7156840fc6ee96444961 100644 (file)
 
 #include "sim/process.hh"
 
+/// A process with emulated Alpha Tru64 syscalls.
 class AlphaTru64Process : public LiveProcess
 {
   public:
+    /// Constructor.
     AlphaTru64Process(const std::string &name,
                       ObjectFile *objFile,
                       int stdin_fd, int stdout_fd, int stderr_fd,
                       std::vector<std::string> &argv,
                       std::vector<std::string> &envp);
 
+    /// Syscall emulation function.
     virtual void syscall(ExecContext *xc);
 };
 
index 0e4e78612c6ed97e0f37a12f2cf565823a8d0f24..9955d442196f7587d2133cf4365d07f75242fac8 100644 (file)
@@ -57,9 +57,6 @@ SyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc)
 }
 
 
-//
-// Handler for unimplemented syscalls that we haven't thought about.
-//
 int
 unimplementedFunc(SyscallDesc *desc, int callnum, Process *process,
                   ExecContext *xc)
@@ -73,12 +70,6 @@ unimplementedFunc(SyscallDesc *desc, int callnum, Process *process,
 }
 
 
-//
-// Handler for unimplemented syscalls that we never intend to
-// implement (signal handling, etc.) and should not affect the correct
-// behavior of the program.  Print a warning only if the appropriate
-// trace flag is enabled.  Return success to the target program.
-//
 int
 ignoreFunc(SyscallDesc *desc, int callnum, Process *process,
            ExecContext *xc)
index a02b4a6081ea03fe2231705ad60e978cc04d464e..1031b0823a153dc5143882665d0c6cb603c1f67a 100644 (file)
@@ -51,6 +51,7 @@ class SyscallDesc {
 
   public:
 
+    /// Typedef for target syscall handler functions.
     typedef int (*FuncPtr)(SyscallDesc *, int num,
                            Process *, ExecContext *);
 
@@ -58,7 +59,6 @@ class SyscallDesc {
     FuncPtr funcPtr;   //!< Pointer to emulation function.
     int flags;         //!< Flags (see Flags enum).
 
-
     /// Flag values for controlling syscall behavior.
     enum Flags {
         /// Don't set return regs according to funcPtr return value.
@@ -155,17 +155,40 @@ class TypedBufferArg : public BaseBufferArg
 //////////////////////////////////////////////////////////////////////
 
 
+/// Handler for unimplemented syscalls that we haven't thought about.
 int unimplementedFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc);
+
+/// Handler for unimplemented syscalls that we never intend to
+/// implement (signal handling, etc.) and should not affect the correct
+/// behavior of the program.  Print a warning only if the appropriate
+/// trace flag is enabled.  Return success to the target program.
 int ignoreFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc);
 
+/// Target exit() handler: terminate simulation.
 int exitFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc);
+
+/// Target getpagesize() handler.
 int getpagesizeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc);
+
+/// Target obreak() handler: set brk address.
 int obreakFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc);
+
+/// Target close() handler.
 int closeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc);
+
+/// Target read() handler.
 int readFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc);
+
+/// Target write() handler.
 int writeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc);
+
+/// Target lseek() handler.
 int lseekFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc);
+
+/// Target munmap() handler.
 int munmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc);
+
+/// Target gethostname() handler.
 int gethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc);
 
 //////////////////////////////////////////////////////////////////////
@@ -175,6 +198,9 @@ int gethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc);
 //
 //////////////////////////////////////////////////////////////////////
 
+/// Target ioctl() handler.  For the most part, programs call ioctl()
+/// only to find out if their stdout is a tty, to determine whether to
+/// do line or block buffering.
 template <class OS>
 int
 ioctlFunc(SyscallDesc *desc, int callnum, Process *process,
@@ -204,12 +230,15 @@ ioctlFunc(SyscallDesc *desc, int callnum, Process *process,
     }
 }
 
+/// This struct is used to build an target-OS-dependent table that
+/// maps the target's open() flags to the host open() flags.
 struct OpenFlagTransTable {
-    int tgtFlag;
-    int hostFlag;
+    int tgtFlag;       //!< Target system flag value.
+    int hostFlag;      //!< Corresponding host system flag value.
 };
 
 
+/// Target open() handler.
 template <class OS>
 int
 openFunc(SyscallDesc *desc, int callnum, Process *process,
@@ -254,6 +283,7 @@ openFunc(SyscallDesc *desc, int callnum, Process *process,
 }
 
 
+/// Target stat() handler.
 template <class OS>
 int
 statFunc(SyscallDesc *desc, int callnum, Process *process,
@@ -276,6 +306,7 @@ statFunc(SyscallDesc *desc, int callnum, Process *process,
 }
 
 
+/// Target lstat() handler.
 template <class OS>
 int
 lstatFunc(SyscallDesc *desc, int callnum, Process *process,
@@ -297,6 +328,7 @@ lstatFunc(SyscallDesc *desc, int callnum, Process *process,
     return 0;
 }
 
+/// Target fstat() handler.
 template <class OS>
 int
 fstatFunc(SyscallDesc *desc, int callnum, Process *process,
@@ -321,18 +353,18 @@ fstatFunc(SyscallDesc *desc, int callnum, Process *process,
 }
 
 
+/// Target mmap() handler.
+///
+/// We don't really handle mmap().  If the target is mmaping an
+/// anonymous region or /dev/zero, we can get away with doing basically
+/// nothing (since memory is initialized to zero and the simulator
+/// doesn't really check addresses anyway).  Always print a warning,
+/// since this could be seriously broken if we're not mapping
+/// /dev/zero.
 //
-// We don't really handle mmap().  If the target is mmaping an
-// anonymous region or /dev/zero, we can get away with doing basically
-// nothing (since memory is initialized to zero and the simulator
-// doesn't really check addresses anyway).  Always print a warning,
-// since this could be seriously broken if we're not mapping
-// /dev/zero.
-//
-// Someday we should explicitly check for /dev/zero in open, flag the
-// file descriptor, and fail (or implement!) a non-anonymous mmap to
-// anything else.
-//
+/// Someday we should explicitly check for /dev/zero in open, flag the
+/// file descriptor, and fail (or implement!) a non-anonymous mmap to
+/// anything else.
 template <class OS>
 int
 mmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
@@ -341,7 +373,7 @@ mmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
     uint64_t length = xc->getSyscallArg(1);
     // int prot = xc->getSyscallArg(2);
     int flags = xc->getSyscallArg(3);
-    int fd = p->sim_fd(xc->getSyscallArg(4));
+    // int fd = p->sim_fd(xc->getSyscallArg(4));
     // int offset = xc->getSyscallArg(5);
 
     if (start == 0) {
@@ -352,13 +384,13 @@ mmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
 
     if (!(flags & OS::TGT_MAP_ANONYMOUS)) {
         DPRINTF(SyscallWarnings, "Warning: allowing mmap of file @ fd %d.  "
-                "This will break if not /dev/zero.", fd);
+                "This will break if not /dev/zero.", xc->getSyscallArg(4));
     }
 
     return start;
 }
 
-
+/// Target getrlimit() handler.
 template <class OS>
 int
 getrlimitFunc(SyscallDesc *desc, int callnum, Process *process,
@@ -383,16 +415,16 @@ getrlimitFunc(SyscallDesc *desc, int callnum, Process *process,
     return 0;
 }
 
-// 1M usecs in 1 sec, for readability
+/// A readable name for 1,000,000, for converting microseconds to seconds.
 const int one_million = 1000000;
 
-// seconds since the epoch (1/1/1970)... about a billion, by my reckoning
+/// Approximate seconds since the epoch (1/1/1970).  About a billion,
+/// by my reckoning.  We want to keep this a constant (not use the
+/// real-world time) to keep simulations repeatable.
 const unsigned seconds_since_epoch = 1000000000;
 
-//
-// helper function: populate struct timeval with approximation of
-// current elapsed time
-//
+/// Helper function to convert current elapsed time to seconds and
+/// microseconds.
 template <class T1, class T2>
 void
 getElapsedTime(T1 &sec, T2 &usec)
@@ -405,6 +437,7 @@ getElapsedTime(T1 &sec, T2 &usec)
 }
 
 
+/// Target gettimeofday() handler.
 template <class OS>
 int
 gettimeofdayFunc(SyscallDesc *desc, int callnum, Process *process,
@@ -421,6 +454,7 @@ gettimeofdayFunc(SyscallDesc *desc, int callnum, Process *process,
 }
 
 
+/// Target getrusage() function.
 template <class OS>
 int
 getrusageFunc(SyscallDesc *desc, int callnum, Process *process,