# Taken from http://people.freebsd.org/~peter/ezm3-amd64/ezm3-port.diff.gz
#
# Add new files for amd64 platform.
#
Index: libs/m3core/src/C/FBSD_AMD64/Csetjmp.i3
--- libs/m3core/src/C/FBSD_AMD64/Csetjmp.i3	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/C/FBSD_AMD64/Csetjmp.i3	Mon Feb 16 21:19:48 2004
@@ -0,0 +1,24 @@
+(* Copyright (C) 1990, Digital Equipment Corporation           *)
+(* All rights reserved.                                        *)
+(* See the file COPYRIGHT for a full description.              *)
+(*                                                             *)
+(* Last modified on Tue Oct 18 08:40:23 PDT 1994 by kalsow     *)
+(*      modified on Fri Apr 30 16:25:40 PDT 1993 by muller     *)
+(*      Olaf Wagner 12.09.1994                                 *)
+
+INTERFACE Csetjmp;		(* for FreeBSD *)
+
+FROM Ctypes IMPORT int, long;
+
+TYPE 
+  jmp_buf = ARRAY [0..11] OF long; (* actually, this is a sigjmp_buf,
+                                     just in case *)
+
+<*EXTERNAL "setjmp"   *> PROCEDURE setjmp (VAR env: jmp_buf): int;
+<*EXTERNAL "longjmp"  *> PROCEDURE longjmp (VAR env: jmp_buf; val: int);
+
+<*EXTERNAL "_setjmp" *>  PROCEDURE usetjmp (VAR env: jmp_buf): int;
+<*EXTERNAL "_longjmp" *> PROCEDURE ulongjmp (VAR env: jmp_buf; val: int);
+
+END Csetjmp.
+
Index: libs/m3core/src/C/FBSD_AMD64/Csignal.i3
--- libs/m3core/src/C/FBSD_AMD64/Csignal.i3	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/C/FBSD_AMD64/Csignal.i3	Mon Feb 16 21:19:48 2004
@@ -0,0 +1,18 @@
+(* Copyright (C) 1992, Digital Equipment Corporation                         *)
+(* All rights reserved.                                                      *)
+(* See the file COPYRIGHT for a full description.                            *)
+(*                                                                           *)
+(* Last modified on Mon Oct 17 09:12:23 PDT 1994 by kalsow                   *)
+(*      modified on Tue May  4 10:06:17 PDT 1993 by muller                   *)
+
+INTERFACE Csignal;
+
+FROM Ctypes IMPORT int;
+
+TYPE
+  Handler = PROCEDURE (s: int);
+
+<*EXTERNAL*>
+PROCEDURE signal (sig: int; func: Handler): Handler;
+
+END Csignal.
Index: libs/m3core/src/C/FBSD_AMD64/Cstdio.i3
--- libs/m3core/src/C/FBSD_AMD64/Cstdio.i3	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/C/FBSD_AMD64/Cstdio.i3	Mon Feb 16 21:19:48 2004
@@ -0,0 +1,74 @@
+(* Copyright (C) 1990, Digital Equipment Corporation.         *)
+(* All rights reserved.                                       *)
+(* See the file COPYRIGHT for a full description.             *)
+(*                                                            *)
+(* Last modified on Sat Jan  7 13:12:39 PST 1995 by kalsow    *)
+(*      modified on Thu May  6 09:18:19 PDT 1993 by muller    *)
+(*      Olaf Wagner 16.09.1994                                *)
+
+INTERFACE Cstdio;
+
+FROM Ctypes IMPORT int, void_star, char_star,
+                   unsigned_char_star, short_int, unsigned_char;
+
+FROM Utypes IMPORT off_t;
+
+CONST 
+  NIOBRW = 100;
+  NSTDBUF= 3;
+  EOF    = VAL(-1, int);
+
+TYPE
+  SBUF = RECORD
+            base : unsigned_char_star;
+            size : int;
+         END;
+
+  FILE = RECORD 
+        p     : unsigned_char_star;  (* current position in (some) buffer *)
+        r     : int;                 (* read space left for getc() *)
+        w     : int;                 (* write space left for putc() *)
+        flags : short_int;           (* flags, below; this FILE is free if 0 *)
+        file  : short_int;           (* fileno, if Unix descriptor, else -1 *)
+        bf    : SBUF;                (* the buffer (at least 1 byte, if !NULL) *)
+        lbfsize : int;               (* 0 or -_bf._size, for inline putc *)
+
+        (* operations *)
+        cookie : void_star;          (* cookie passed to io functions *)
+        xxclose: void_star;
+        xxread : void_star;
+        xxseek : void_star;
+        xxwrite: void_star;
+
+        (* separate buffer for long sequences of ungetc() *)
+        ub : SBUF;               (* ungetc buffer *)
+        up : unsigned_char_star; (* saved _p when _p is doing ungetc data *)
+        ur : int;                (* saved _r when _r is counting ungetc data *)
+                                 
+        (* tricks to meet minimum requirements even when malloc() fails *)
+        ubuf : ARRAY[0..2] OF unsigned_char; (* guarantee an ungetc() buffer *)
+        nbuf : ARRAY[0..0] OF unsigned_char; (* guarantee a getc() buffer *)
+
+        (* separate buffer for fgetln() when line crosses buffer boundary *)
+        lb   : SBUF;         (* buffer for fgetln() *)
+
+        (* Unix stdio files get aligned to block boundaries on fseek() *)
+        blksize : int;        (* stat.st_blksize (may be != _bf._size) *)
+        offset  : off_t;      (* current lseek offset *)
+ 
+        END;
+
+  FILE_star = UNTRACED REF FILE;
+
+<*EXTERNAL "__sF"*> VAR sF : ARRAY [0..NSTDBUF-1] OF FILE;
+                    VAR iF : ARRAY [0..NIOBRW-1]  OF FILE_star;
+
+<*EXTERNAL fbsd_feof*>      PROCEDURE feof (f: FILE_star): int;
+<*EXTERNAL fbsd_getc*>      PROCEDURE getc (f: FILE_star): int;
+<*EXTERNAL fbsd_ungetc*>    PROCEDURE ungetc (c: int; f: FILE_star): int;
+<*EXTERNAL fbsd_putc*>      PROCEDURE putc (c: int; f: FILE_star): int;
+<*EXTERNAL fbsd_fflush*>    PROCEDURE fflush (f: FILE_star): int;
+<*EXTERNAL fbsd_fdopen*>    PROCEDURE fdopen (fd: int; mode: char_star): FILE_star;
+<*EXTERNAL fbsd_fclose*>    PROCEDURE fclose (f: FILE_star): int;
+
+END Cstdio.
Index: libs/m3core/src/C/FBSD_AMD64/Cstdio.m3
--- libs/m3core/src/C/FBSD_AMD64/Cstdio.m3	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/C/FBSD_AMD64/Cstdio.m3	Mon Feb 16 21:19:48 2004
@@ -0,0 +1,17 @@
+(* Copyright (C) 1992, Digital Equipment Corporation          *)
+(* All rights reserved.                                       *)
+(* See the file COPYRIGHT for a full description.             *)
+(*                                                            *)
+(* Last modified on Mon Oct 17 09:17:55 PDT 1994 by kalsow    *)
+(*      Olaf Wagner 16.09.1994                                *)
+
+UNSAFE MODULE Cstdio;
+
+BEGIN
+   iF[0] := ADR(sF[0]);
+   iF[1] := ADR(sF[1]);
+   iF[2] := ADR(sF[2]);
+   FOR i := NSTDBUF TO NIOBRW-1 DO
+      iF[i] := NIL;
+   END;
+END Cstdio.
Index: libs/m3core/src/C/FBSD_AMD64/CstdioC.c
--- libs/m3core/src/C/FBSD_AMD64/CstdioC.c	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/C/FBSD_AMD64/CstdioC.c	Mon Feb 16 21:19:49 2004
@@ -0,0 +1,42 @@
+/* Copyright (C) 1994, Digital Equipment Corporation          */
+/* All rights reserved.                                       */
+/* See the file COPYRIGHT for a full description.             */
+/*                                                            */
+/* Last modified on Mon Oct 17 09:17:31 PDT 1994 by kalsow    */
+/*      Olaf Wagner 16.09.1994                                */
+
+#include <stdio.h>
+
+int fbsd_feof(FILE *f){
+   return feof(f);
+};
+
+int fbsd_getc(FILE *f){
+   return fgetc(f);
+};
+
+int fbsd_ungetc(int c, FILE *f){
+   return ungetc(c, f);
+};
+
+int fbsd_putc(int c, FILE *f){
+   return fputc(c, f);
+};
+
+int fbsd_fflush(FILE *f){
+   return fflush(f);
+};
+
+FILE* fbsd_fdopen(int fildes, char *mode){
+   FILE* f;
+   f = fdopen(fildes, mode);
+   if (f == NULL){
+       fprintf(stderr, "fd: %d, mode: %s\n", fildes, mode);
+       perror("fdopen failed ");
+   }
+   return f;
+}
+
+int fbsd_fclose(FILE *f){
+   return fclose(f);
+};
Index: libs/m3core/src/C/FBSD_AMD64/Cstring.i3
--- libs/m3core/src/C/FBSD_AMD64/Cstring.i3	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/C/FBSD_AMD64/Cstring.i3	Mon Feb 16 21:19:49 2004
@@ -0,0 +1,89 @@
+(* Copyright (C) 1989, Digital Equipment Corporation          *)
+(* All rights reserved.                                       *)
+(* See the file COPYRIGHT for a full description.             *)
+(*                                                            *)
+(* File: Cstring.i3                                           *)
+(* Last modified on Mon Oct 17 09:19:10 PDT 1994 by kalsow    *)
+(*      modified on Tue Apr 20 20:16:18 PDT 1993 by muller    *)
+(*      modified on Sat Jan 20 22:31:44 1990 by jerome        *)
+(*      Olaf Wagner 16.09.1994                                *)
+
+
+INTERFACE Cstring;
+
+FROM Ctypes IMPORT char_star, const_char_star, const_void_star,
+                   int, void_star, unsigned_long;
+
+TYPE
+  size_t =  unsigned_long;
+
+<*EXTERNAL*> 
+PROCEDURE memchr (s: const_void_star; c: int; n: size_t): void_star;
+
+<*EXTERNAL*>
+PROCEDURE memcpy (s1: void_star; s2: const_void_star; n: size_t): void_star;
+
+<*EXTERNAL*> 
+PROCEDURE memset (s: void_star; c: int; n: size_t): void_star;
+
+<*EXTERNAL*>
+PROCEDURE memcmp (s1: const_void_star; s2: const_void_star; n: size_t): int;
+
+<*EXTERNAL*>
+PROCEDURE strcpy (s1: char_star; s2: const_char_star): char_star;
+
+<*EXTERNAL*>
+PROCEDURE strncpy (s1: char_star; s2: const_char_star; n: size_t): char_star;
+
+<*EXTERNAL*>
+PROCEDURE strcat (s1: char_star; s2: const_char_star): char_star;
+
+<*EXTERNAL*>
+PROCEDURE strncat  (s1: char_star; s2: const_char_star; n: size_t): char_star;
+
+<*EXTERNAL*>
+PROCEDURE strchr (s: const_char_star; c: int): char_star;
+
+<*EXTERNAL*>
+PROCEDURE strrchr (s: const_char_star; c: int): char_star;
+
+<*EXTERNAL*>
+PROCEDURE strpbrk (s1: const_char_star; s2: const_char_star): char_star;
+
+<*EXTERNAL*>
+PROCEDURE strtok (s1: char_star; s2: const_char_star): char_star;
+
+<*EXTERNAL*>
+PROCEDURE strcmp (s1: const_char_star; s2: const_char_star): int;
+
+<*EXTERNAL*>
+PROCEDURE strncmp (s1: const_char_star; s2: const_char_star; n: size_t): int;
+
+<*EXTERNAL*>
+PROCEDURE strlen (s: const_char_star): size_t;
+
+<*EXTERNAL*>
+PROCEDURE strspn (s1: const_char_star; s2: const_char_star): int;
+
+<*EXTERNAL*>
+PROCEDURE strcspn (s1: const_char_star; s2: const_char_star): size_t;
+
+<*EXTERNAL*>
+PROCEDURE memmove (s1: void_star; s2: const_void_star; n: size_t): void_star;
+
+<*EXTERNAL*>
+PROCEDURE strcoll (s1: const_char_star; s2: const_char_star): int;
+
+(*
+<*EXTERNAL*>
+PROCEDURE strxrfm (s1: char_star; s2: const_char_star; n: size_t): size_t;
+*)
+
+<*EXTERNAL*>
+PROCEDURE strstr (s1: const_char_star; s2: const_char_star): char_star;
+
+<*EXTERNAL*>
+PROCEDURE strerror (errnum: int): char_star;
+
+END Cstring.
+
Index: libs/m3core/src/C/FBSD_AMD64/m3makefile
--- libs/m3core/src/C/FBSD_AMD64/m3makefile	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/C/FBSD_AMD64/m3makefile	Mon Feb 16 21:19:49 2004
@@ -0,0 +1,17 @@
+% Copyright (C) 1994, Digital Equipment Corporation
+% All rights reserved.
+% See the file COPYRIGHT for a full description.
+%
+% Last modified on Mon Oct 17 09:20:03 PDT 1994 by kalsow  
+%      modified on Fri Jun 18 13:20:32 PDT 1993 by harrison
+%      modified on Thu May  6 13:16:32 PDT 1993 by muller
+%      Olaf Wagner 16.09.1994
+
+Interface ("Csetjmp")
+Interface ("Csignal")
+Interface ("Cstring")
+Module ("Cstdio")
+
+c_source ("CstdioC")
+
+
Index: libs/m3core/src/Csupport/FBSD_AMD64/dtoa.c
--- libs/m3core/src/Csupport/FBSD_AMD64/dtoa.c	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/Csupport/FBSD_AMD64/dtoa.c	Mon Feb 16 21:20:04 2004
@@ -0,0 +1,28 @@
+/* Copyright (C) 1992, Digital Equipment Corporation                         */
+/* All rights reserved.                                                      */
+/* See the file COPYRIGHT for a full description.                            */
+
+/* Last modified on Fri Aug 13 09:02:20 PDT 1993 by kalsow                   */
+/*      modified on Tue Feb 11 14:23:53 PST 1992 by muller                   */
+
+#ifndef IEEE_8087
+#define IEEE_8087
+#endif
+
+#define Int_32 int
+
+
+#include "dtoa.h"
+
+/* Apparently libc defines both "__dtoa" and "dtoa".  ???  */
+
+char * __dtoa       
+#ifdef KR_headers
+        (d, mode, ndigits, decpt, sign, rve)
+        double d; int mode, ndigits, *decpt, *sign; char **rve;
+#else 
+        (double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
+#endif
+{
+  return dtoa(d, mode, ndigits, decpt, sign, rve);
+}
Index: libs/m3core/src/Csupport/FBSD_AMD64/m3makefile
--- libs/m3core/src/Csupport/FBSD_AMD64/m3makefile	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/Csupport/FBSD_AMD64/m3makefile	Mon Feb 16 21:20:04 2004
@@ -0,0 +1,10 @@
+% Copyright (C) 1992, Digital Equipment Corporation
+% All rights reserved.
+% See the file COPYRIGHT for a full description.
+%
+% Last modified on Mon Oct 17 09:28:11 PDT 1994 by kalsow
+%      modified on Fri Jun 18 13:18:18 PDT 1993 by harrison
+%      modified on Thu Feb  4 15:58:38 PST 1993 by mjordan
+%      modified on Mon Oct 12 13:51:24 PDT 1992 by muller
+
+c_source ("dtoa")
Index: libs/m3core/src/runtime/FBSD_AMD64/RTHeapDep.m3
--- libs/m3core/src/runtime/FBSD_AMD64/RTHeapDep.m3	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/runtime/FBSD_AMD64/RTHeapDep.m3	Mon Feb 16 21:20:26 2004
@@ -0,0 +1,172 @@
+(* Copyright (C) 1994, Digital Equipment Corporation             *)
+(* All rights reserved.                                          *)
+(* See the file COPYRIGHT for a full description.                *)
+(*                                                               *)
+(*| Last modified on Fri Jan 20 09:41:09 PST 1995 by kalsow      *)
+(*|      modified on Mon Oct 31 00:04:38 MET 1994 by Olaf Wagner *)
+(*|      modified on Thu Jan 28 19:24:55 PST 1993 by jdd         *)
+
+UNSAFE MODULE RTHeapDep;
+
+IMPORT RT0u, RTMachine, RTHeapRep, RTCollectorSRC;
+IMPORT Cstdlib, Ctypes, Umman, Unix, Uresource, Usignal, Utypes, Word;
+
+VAR
+  initialized                           := FALSE;
+  defaultSIGSEGV: Usignal.SignalHandler := NIL; (* previous handler *)
+  defaultSIGBUS:  Usignal.SignalHandler := NIL; (* previous handler *)
+
+PROCEDURE Protect (p: Page; n: CARDINAL; readable, writable: BOOLEAN) =
+  BEGIN
+    IF NOT initialized THEN Init(); initialized := TRUE; END;
+    IF NOT readable THEN writable := FALSE; END; (* processor limitation *)
+    VAR prot: Ctypes.int := 0;
+    BEGIN
+      IF readable THEN prot := Word.Or(prot, Umman.PROT_READ); END;
+      IF writable THEN prot := Word.Or(prot, Umman.PROT_WRITE); END;
+      VAR
+        ret := Umman.mprotect(LOOPHOLE(p * BytesPerPage, Utypes.caddr_t),
+                              n * BytesPerPage, prot);
+      BEGIN
+        (*
+        <* ASSERT ret = n * BytesPerPage *>
+        *)
+        <* ASSERT ret = 0 *>
+      END;
+    END;
+  END Protect;
+
+(* Init establishes a handler for SIGSEGV, caused by VM faults, and for all
+   other signals that cause core dumps. *)
+
+PROCEDURE Init () =
+  BEGIN
+    (* sanity check *)
+    VAR vmPageBytes := Unix.getpagesize();
+    BEGIN
+      <* ASSERT BytesPerPage >= vmPageBytes *>
+      <* ASSERT BytesPerPage MOD vmPageBytes = 0 *>
+    END;
+
+    (* establish SIGSEGV handler; remember previous handler *)
+    VAR
+      vec := Usignal.struct_sigvec{
+               sv_handler := Fault, sv_mask :=
+               Word.LeftShift(1, Usignal.SIGVTALRM - 1), sv_flags := 0};
+      ovec: Usignal.struct_sigvec;
+      ret := Usignal.sigvec(Usignal.SIGSEGV, vec, ovec);
+      vecb := Usignal.struct_sigvec{
+               sv_handler := Fault, sv_mask :=
+               Word.LeftShift(1, Usignal.SIGVTALRM - 1), sv_flags := 0};
+      ovecb: Usignal.struct_sigvec;
+      retb := Usignal.sigvec(Usignal.SIGBUS, vecb, ovecb);
+    BEGIN
+      <* ASSERT ret = 0 *>
+      <* ASSERT retb = 0 *>
+      defaultSIGSEGV := ovec.sv_handler;
+      defaultSIGBUS := ovecb.sv_handler;
+    END;
+
+    (* establish signal handler for all other signals that dump core, if no
+       handler exists *)
+    PROCEDURE OverrideDefault (sig: Ctypes.int) =
+      VAR
+        vec := Usignal.struct_sigvec{
+                 sv_handler := Core, sv_mask :=
+                 Word.LeftShift(1, Usignal.SIGVTALRM - 1), sv_flags := 0};
+        ovec: Usignal.struct_sigvec;
+        ret                         := Usignal.sigvec(sig, vec, ovec);
+      BEGIN
+        <* ASSERT ret = 0 *>
+        IF ovec.sv_handler # Usignal.SIG_DFL THEN
+          ret := Usignal.sigvec(sig, ovec, vec);
+          <* ASSERT ret = 0 *>
+        END;
+      END OverrideDefault;
+    BEGIN
+      OverrideDefault(Usignal.SIGQUIT);
+      OverrideDefault(Usignal.SIGILL);
+      OverrideDefault(Usignal.SIGTRAP);
+      OverrideDefault(Usignal.SIGIOT);
+      OverrideDefault(Usignal.SIGEMT);
+      OverrideDefault(Usignal.SIGFPE);
+      OverrideDefault(Usignal.SIGSYS);
+    END;
+  END Init;
+
+(* Fault is called upon a SIGSEGV or SIGBUS signal, caused by a VM fault.
+   If RTHeapRep.Fault is not able to handle the fault, it invokes the previous
+   action. *)
+
+PROCEDURE Fault (sig : Ctypes.int;
+                 code: Ctypes.int;
+                 scp : UNTRACED REF Usignal.struct_sigcontext) =
+  VAR
+    sf_addr := LOOPHOLE(scp.sc_addr, ADDRESS);
+
+  BEGIN
+    IF RTHeapRep.Fault(sf_addr) THEN
+      RETURN;
+    END;
+    IF defaultSIGSEGV = Usignal.SIG_IGN THEN RETURN; END;
+    IF defaultSIGSEGV = Usignal.SIG_DFL THEN
+      Core(sig, code, scp);
+    ELSE
+      defaultSIGSEGV(sig, code, scp);
+    END;
+  END Fault;
+
+(* Core is a signal handler for signals that dump core, to complete the
+   current collection before dumping core.  This makes core files easier to
+   debug, and avoids an Ultrix bug that creates incomplete core files if
+   heap pages are read-protected. *)
+
+VAR dumped_core := FALSE;
+
+PROCEDURE Core (             sig : Ctypes.int;
+                <* UNUSED *> code: Ctypes.int;
+                <* UNUSED *> scp : UNTRACED REF Usignal.struct_sigcontext) =
+  VAR
+    ovec: Usignal.struct_sigvec;
+    vec := Usignal.struct_sigvec{sv_handler := Usignal.SIG_DFL,
+                                 sv_mask := 0, sv_flags := 0};
+  BEGIN
+    INC(RT0u.inCritical);
+    IF NOT dumped_core THEN
+      dumped_core := TRUE;
+      EVAL RTHeapRep.Crash();      (* clean up the heap *)
+      EVAL Usignal.sigvec(sig, vec, ovec); (* establish default action *)
+      EVAL Usignal.sigsetmask(0);
+      (** EVAL Usignal.kill(Uprocess.getpid(), sig); (* dump core *) **)
+      Cstdlib.abort (); (* dump core *)
+      <* ASSERT FALSE *>
+    END;
+    DEC(RT0u.inCritical);
+  END Core;
+
+(* System-call faults are handled in RTHeapDepC.c *)
+
+PROCEDURE TimeUsed (): REAL =
+  VAR usage: Uresource.struct_rusage;
+  BEGIN
+    VAR ret := Uresource.getrusage(Uresource.RUSAGE_SELF, ADR(usage));
+    BEGIN
+      <* ASSERT ret # -1 *>
+    END;
+    RETURN (FLOAT(usage.ru_utime.tv_sec)
+              + FLOAT(usage.ru_utime.tv_usec) / 1000000.0)
+             + (FLOAT(usage.ru_utime.tv_sec)
+                  + FLOAT(usage.ru_utime.tv_usec) / 1000000.0);
+  END TimeUsed;
+
+PROCEDURE VMFaultTime (): REAL =
+  BEGIN
+    RETURN 0.010;                (* guess 10ms to handle a page fault *)
+  END VMFaultTime;
+
+BEGIN
+  IF VM THEN
+    RTMachine.RTHeapRep_Fault  := LOOPHOLE (RTHeapRep.Fault, ADDRESS);
+    RTMachine.RTCSRC_FinishVM  := LOOPHOLE (RTCollectorSRC.FinishVM, ADDRESS);
+  END;
+END RTHeapDep.
Index: libs/m3core/src/runtime/FBSD_AMD64/RTHeapDepC.c
--- libs/m3core/src/runtime/FBSD_AMD64/RTHeapDepC.c	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/runtime/FBSD_AMD64/RTHeapDepC.c	Mon Feb 16 21:20:26 2004
@@ -0,0 +1,2 @@
+void (*RTHeapRep_Fault)(char*);
+void (*RTCSRC_FinishVM)();
Index: libs/m3core/src/runtime/FBSD_AMD64/RTMachine.i3
--- libs/m3core/src/runtime/FBSD_AMD64/RTMachine.i3	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/runtime/FBSD_AMD64/RTMachine.i3	Mon Feb 16 21:20:26 2004
@@ -0,0 +1,85 @@
+(* Copyright (C) 1994, Digital Equipment Corporation.       *)
+(* All rights reserved.                                     *)
+(* See the file COPYRIGHT for a full description.           *)
+(*                                                          *)
+(* Last modified on Tue May  2 11:41:23 PDT 1995 by kalsow  *)
+
+(* This interface defines platform (machine + OS) dependent
+   types and constants. *)
+
+INTERFACE RTMachine;
+
+IMPORT Uucontext;
+
+(*--------------------------------------------------------- thread state ---*)
+
+TYPE
+  State = Uucontext.ucontext_t;
+  (* The machine state is saved in a "State".  This type is really
+     opaque to the client, i.e. it does not need to be an array. *)
+
+<*EXTERNAL "getcontext" *>
+PROCEDURE SaveState (VAR s: State): INTEGER;
+(* Capture the currently running thread's state *)
+
+CONST
+  FramePadBottom = 2;
+  FramePadTop    = 0;
+  (* Additional padding words from above and below an existing
+     thread's stack pointer to copy when creating a new thread *)
+
+(*------------------------------------------------------------------ heap ---*)
+
+(* The heap page size is machine-dependent, since it might depend on the
+   architecture's VM page size (if VM is TRUE).  Otherwise, 8192 bytes is a
+   reasonable page size.  The page size must be a power of two. *)
+
+CONST
+  BytesPerHeapPage    = 4096;        (* bytes per page *)
+  LogBytesPerHeapPage = 12;
+  AdrPerHeapPage      = 4096;        (* addresses per page *)
+  LogAdrPerHeapPage   = 12;
+
+(* The collector supports the use of VM protection to achieve incremental,
+   generational collection.  This is not possible on all architectures, and
+   it may not be implemented in all cases where it is possible.  The
+   boolean constant "VMHeap" is "TRUE" iff all necessary support is
+   present for this architecture.  "VMHeap" is "TRUE" for the DS3100,
+   whose implementation you might use as a reference. *)
+
+CONST
+  VMHeap = FALSE;
+
+(*** hooks for the C wrapper functions ***)
+
+<*EXTERNAL*> VAR RTHeapRep_Fault: ADDRESS;  (* => RTHeapRep.Fault *)
+<*EXTERNAL*> VAR RTCSRC_FinishVM: ADDRESS;  (* => RTCollectorSRC.FinishVM *)
+
+(*--------------------------------------------------------- thread stacks ---*)
+
+CONST
+  PointerAlignment = 8;
+  (* The C compiler allocates all pointers on 'PointerAlignment'-byte
+     boundaries.  The garbage collector scans thread stacks, but only
+     looks at these possible pointer locations.  Setting this value
+     smaller than is needed will only make your system run slower.
+     Setting it too large will cause the collector to collect storage
+     that is not free. *)
+
+CONST
+  StackFrameAlignment = 16;
+  (* Stack frames must be aligned to this constraint (in ADRSIZE units). 
+     It's not a big deal if this value is too large, but it may break 
+     the thread mechanism to make it too small. *)
+
+(*----------------------------------------------- exception stack walking ---*)
+(* The "FrameInfo" type must minimally include fields named "pc" and "sp". *)
+
+CONST
+  Has_stack_walker = FALSE;
+  (* Indicates whether this platform supports the stack walking functions
+     defined in the "RTStack" interface. *)
+
+TYPE FrameInfo = RECORD pc, sp: ADDRESS END;
+
+END RTMachine.
Index: libs/m3core/src/runtime/FBSD_AMD64/RTSignal.m3
--- libs/m3core/src/runtime/FBSD_AMD64/RTSignal.m3	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/runtime/FBSD_AMD64/RTSignal.m3	Mon Feb 16 21:20:26 2004
@@ -0,0 +1,101 @@
+(* Copyright (C) 1992, Digital Equipment Corporation          *)
+(* All rights reserved.                                       *)
+(* See the file COPYRIGHT for a full description.             *)
+(*                                                            *)
+(* Last modified on Mon Nov 21 10:31:19 PST 1994 by kalsow    *)
+(*      modified on Mon Mar 16 18:10:15 PST 1992 by muller    *)
+
+UNSAFE MODULE RTSignal;
+
+IMPORT RTMisc, RTProcess, Usignal, Uprocess;
+FROM Ctypes IMPORT int;
+
+TYPE
+  SigInfo = UNTRACED REF Usignal.struct_sigcontext;
+
+VAR
+  DefaultHandler   : Usignal.SignalHandler;
+  IgnoreSignal     : Usignal.SignalHandler;
+  initial_handlers : ARRAY [0..5] OF Usignal.struct_sigaction;
+
+PROCEDURE InstallHandlers () =
+  BEGIN
+    DefaultHandler := LOOPHOLE (0, Usignal.SignalHandler);
+    IgnoreSignal   := LOOPHOLE (1, Usignal.SignalHandler);
+
+    SetHandler (0, Usignal.SIGHUP,  Shutdown);
+    SetHandler (1, Usignal.SIGINT,  Interrupt);
+    SetHandler (2, Usignal.SIGQUIT, Quit);
+    SetHandler (3, Usignal.SIGSEGV, SegV);
+    SetHandler (4, Usignal.SIGPIPE, IgnoreSignal);
+    SetHandler (5, Usignal.SIGTERM, Shutdown);
+  END InstallHandlers;
+
+PROCEDURE SetHandler (id: INTEGER; sig: int;  handler: Usignal.SignalHandler) =
+  (* Note: we use the LOOPHOLE to prevent the runtime check for
+     nested procedure.  The runtime check crashes when
+     handler = IgnoreSignal = 1. *)
+  VAR new: Usignal.struct_sigaction;
+  BEGIN
+    new.sa_handler := LOOPHOLE (handler, Usignal.SignalHandler);
+    new.sa_flags   := 0;
+    EVAL Usignal.sigaction (sig, ADR(new), ADR(initial_handlers[id]));
+    IF (initial_handlers[id].sa_handler # DefaultHandler) THEN
+      (* don't override inherited, non-default handlers *)
+      EVAL Usignal.sigaction (sig, ADR(initial_handlers[id]), ADR(new));
+    END;
+  END SetHandler;
+
+PROCEDURE RestoreHandlers () =
+  BEGIN
+    RestoreHandler (0, Usignal.SIGHUP);
+    RestoreHandler (1, Usignal.SIGINT);
+    RestoreHandler (2, Usignal.SIGQUIT);
+    RestoreHandler (3, Usignal.SIGSEGV);
+    RestoreHandler (4, Usignal.SIGPIPE);
+    RestoreHandler (5, Usignal.SIGTERM);
+  END RestoreHandlers;
+
+PROCEDURE RestoreHandler (id: INTEGER;  sig: int) =
+  BEGIN
+    EVAL Usignal.sigaction (sig, ADR(initial_handlers[id]), NIL);
+  END RestoreHandler;
+
+PROCEDURE Shutdown (sig: int; <*UNUSED*> code: int; <*UNUSED*> scp: SigInfo) =
+  VAR new, old: Usignal.struct_sigaction;
+  BEGIN
+    new.sa_handler := DefaultHandler;
+    new.sa_flags   := 0;
+    RTProcess.InvokeExitors ();                   (* flush stdio... *)
+    EVAL Usignal.sigaction (sig, ADR(new), ADR(old));       (* restore default handler *)
+    EVAL Usignal.kill (Uprocess.getpid (), sig);  (* and resend the signal *)
+  END Shutdown;
+
+PROCEDURE Interrupt (sig: int;  code: int;  scp: SigInfo) =
+  VAR h := RTProcess.OnInterrupt (NIL);
+  BEGIN
+    IF (h = NIL) THEN
+      Shutdown (sig, code, scp);
+    ELSE
+      EVAL RTProcess.OnInterrupt (h); (* reinstall the handler *)
+      h ();
+    END;
+  END Interrupt;
+
+PROCEDURE Quit (<*UNUSED*> sig, code: int; scp: SigInfo) =
+  VAR pc := 0;
+  BEGIN
+    IF (scp # NIL) THEN pc := scp.sc_rip END;
+    RTMisc.FatalErrorPC (pc, "aborted");
+  END Quit;
+
+PROCEDURE SegV (<*UNUSED*> sig, code: int; scp: SigInfo) =
+  VAR pc := 0;
+  BEGIN
+    IF (scp # NIL) THEN pc := scp.sc_rip END;
+    RTMisc.FatalErrorPC (pc,
+      "Segmentation violation - possible attempt to dereference NIL");
+  END SegV;
+
+BEGIN
+END RTSignal.
Index: libs/m3core/src/runtime/FBSD_AMD64/RTThread.m3
--- libs/m3core/src/runtime/FBSD_AMD64/RTThread.m3	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/runtime/FBSD_AMD64/RTThread.m3	Mon Feb 16 21:20:26 2004
@@ -0,0 +1,112 @@
+(* Copyright (C) 1992, Digital Equipment Corporation          *)
+(* All rights reserved.                                       *)
+(* See the file COPYRIGHT for a full description.             *)
+(*                                                            *)
+(* Last modified on Wed Nov 23 13:01:14 PST 1994 by kalsow    *)
+(*      modified on Tue May  4 18:49:28 PDT 1993 by muller    *)
+(* ow 16.09.1994 *)
+(* ow 11.10.1994 *)
+
+UNSAFE MODULE RTThread;
+
+IMPORT Usignal, Unix, Umman, RTMisc, Uucontext;
+
+PROCEDURE SP (READONLY s: State): ADDRESS =
+  BEGIN
+    RETURN LOOPHOLE (s.uc_mcontext.mc_rsp, ADDRESS);
+  END SP;
+
+(*--------------------------------------------------------- thread stacks ---*)
+
+VAR page_bytes : CARDINAL := 0;
+VAR stack_slop : CARDINAL;
+
+PROCEDURE NewStack (size: INTEGER;  VAR(*OUT*)s: Stack) =
+  VAR i: INTEGER;  start: ADDRESS;
+  BEGIN
+    IF (page_bytes = 0) THEN
+      page_bytes := Unix.getpagesize ();
+      stack_slop := 2 * (page_bytes DIV BYTESIZE (INTEGER));
+    END;
+
+    (* allocate enough so that we're guaranteed to get a full, aligned page *)
+    INC (size, stack_slop);
+    s.words := NEW (StackSpace, size);
+
+    (* find the aligned page and unmap it *)
+    start := RTMisc.Align (ADR (s.words[0]), page_bytes);
+    i := Umman.mprotect (start, page_bytes, Umman.PROT_READ);
+    <* ASSERT i = 0 *>
+
+    (* finally, set the bounds of the usable region *)
+    s.first := start + page_bytes;
+    s.last  := ADR (s.words[0]) + size * ADRSIZE (s.words[0]);
+  END NewStack;
+
+PROCEDURE DisposeStack (VAR s: Stack) =
+  VAR i: INTEGER;  start := RTMisc.Align (ADR (s.words[0]), page_bytes);
+  BEGIN
+    (* find the aligned page and re-map it *)
+    i := Umman.mprotect (start, page_bytes, Umman.PROT_READ+Umman.PROT_WRITE);
+    <* ASSERT i = 0 *>
+
+    (* and finally, free the storage *)
+    DISPOSE (s.words);
+    s.words := NIL;
+    s.first := NIL;
+    s.last  := NIL;
+  END DisposeStack;
+
+PROCEDURE FlushStackCache () =
+  VAR d: State;
+  BEGIN
+    Transfer (d, d);
+  END FlushStackCache;
+
+(*-------------------------------------------------- modifying the models ---*)
+
+PROCEDURE UpdateStateForNewSP (VAR s: State; offset: INTEGER) =
+  BEGIN
+    INC (s.uc_mcontext.mc_rsp, offset);
+  END UpdateStateForNewSP;
+
+PROCEDURE UpdateFrameForNewSP (<*UNUSED*> a: ADDRESS;
+                               <*UNUSED*> offset: INTEGER) =
+  BEGIN
+  END UpdateFrameForNewSP;
+
+(*------------------------------------ manipulating the SIGVTALRM handler ---*)
+
+PROCEDURE setup_sigvtalrm (handler: Usignal.SignalHandler) =
+  VAR sv, osv: Usignal.struct_sigvec;  i: INTEGER;
+  BEGIN
+    sv.sv_handler := handler;
+    sv.sv_mask    := Usignal.empty_sv_mask;
+    sv.sv_flags   := 0;
+    i := Usignal.sigvec (Usignal.SIGVTALRM, sv, osv);
+    <*ASSERT i = 0*>
+  END setup_sigvtalrm;
+
+PROCEDURE allow_sigvtalrm () =
+  VAR svt, old : Uucontext.sigset_t;
+      i        : INTEGER;
+  BEGIN
+    EVAL Usignal.sigemptyset(svt);
+    EVAL Usignal.sigaddset(svt, Usignal.SIGVTALRM);
+    i := Usignal.sigprocmask(Usignal.SIG_UNBLOCK, svt, old);
+    <*ASSERT i = 0 *>
+  END allow_sigvtalrm;
+
+PROCEDURE disallow_sigvtalrm () =
+  VAR svt, old : Uucontext.sigset_t;
+      i        : INTEGER;
+  BEGIN
+    EVAL Usignal.sigemptyset(svt);
+    EVAL Usignal.sigaddset(svt, Usignal.SIGVTALRM);
+    i := Usignal.sigprocmask(Usignal.SIG_BLOCK, svt, old);
+    <*ASSERT i = 0 *>
+  END disallow_sigvtalrm;
+
+BEGIN
+END RTThread.
+
Index: libs/m3core/src/runtime/FBSD_AMD64/RTThreadC.c
--- libs/m3core/src/runtime/FBSD_AMD64/RTThreadC.c	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/runtime/FBSD_AMD64/RTThreadC.c	Mon Feb 16 21:20:26 2004
@@ -0,0 +1,30 @@
+/* Copyright (C) 1994, Digital Equipment Corporation           */
+/* All rights reserved.                                        */
+/* See the file COPYRIGHT for a full description.              */
+/*                                                             */
+/* Last modified on Mon Nov  7 13:23:14 PST 1994 by kalsow     */
+/*      modified on Tue Jan 19 15:20:48 PST 1993 by burrows    */
+
+/* This file implements the coroutine transfer: RTThread.Transfer */
+
+#include <sys/types.h>
+#include <ucontext.h>
+
+void RTThread__Transfer (ucontext_t *from, ucontext_t *to)
+{
+	if (getcontext(from) == 0) {
+		to->uc_mcontext.mc_rax = 1;	/* emulate longjmp return */
+		setcontext(to);			/* fire it up */
+	}
+}
+
+
+/* global thread ID used by 'etp' */
+long ThreadF__myId = 1;
+
+/* low-level runtime lock */
+long RT0u__inCritical = 0;
+
+/* global, per-thread linked list of exception handlers */
+void* RTThread__handlerStack = 0;
+
Index: libs/m3core/src/runtime/FBSD_AMD64/m3makefile
--- libs/m3core/src/runtime/FBSD_AMD64/m3makefile	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/runtime/FBSD_AMD64/m3makefile	Mon Feb 16 21:20:26 2004
@@ -0,0 +1,15 @@
+% Copyright (C) 1994, Digital Equipment Corporation
+% All rights reserved.
+% See the file COPYRIGHT for a full description.
+%
+% Last modified on Mon Nov 21 10:43:13 PST 1994 by kalsow
+%      modified on Mon Dec 14 19:59:03 PST 1992 by jdd
+%      modified on Wed May 20 17:21:29 PDT 1992 by muller
+
+Interface      ("RTMachine")
+implementation ("RTHeapDep")
+implementation ("RTSignal")
+implementation ("RTThread")
+c_source       ("RTThreadC")
+c_source       ("RTHeapDepC")
+c_source       ("malloc")
Index: libs/m3core/src/runtime/FBSD_AMD64/malloc.c
--- libs/m3core/src/runtime/FBSD_AMD64/malloc.c	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/runtime/FBSD_AMD64/malloc.c	Mon Feb 16 21:20:26 2004
@@ -0,0 +1,1157 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@FreeBSD.ORG> wrote this file.  As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * From FreeBSD: malloc.c,v 1.32 1997/08/31 05:59:39 phk Exp
+ * Modified for Modula-3 thread safety by jdp@polstra.com (John Polstra).
+ *
+ */
+
+#define _THREAD_SAFE	1	/* Turn on thread safety for Modula-3 */
+
+/*
+ * Defining EXTRA_SANITY will enable extra checks which are related
+ * to internal conditions and consistency in malloc.c. This has a
+ * noticeable runtime performance hit, and generally will not do you
+ * any good unless you fiddle with the internals of malloc or want
+ * to catch random pointer corruption as early as possible.
+ */
+#ifndef MALLOC_EXTRA_SANITY
+#undef MALLOC_EXTRA_SANITY
+#endif
+
+/*
+ * What to use for Junk.  This is the byte value we use to fill with
+ * when the 'J' option is enabled.
+ */
+#define SOME_JUNK	0xd0		/* as in "Duh" :-) */
+
+/*
+ * The basic parameters you can tweak.
+ *
+ * malloc_pageshift	pagesize = 1 << malloc_pageshift
+ *			It's probably best if this is the native
+ *			page size, but it doesn't have to be.
+ *
+ * malloc_minsize	minimum size of an allocation in bytes.
+ *			If this is too small it's too much work
+ *			to manage them.  This is also the smallest
+ *			unit of alignment used for the storage
+ *			returned by malloc/realloc.
+ *
+ */
+
+#if defined(__FreeBSD__)
+#   if defined(__i386__)
+#       define malloc_pageshift		12U
+#       define malloc_minsize		16U
+#   endif
+#   if defined(__amd64__)
+#       define malloc_pageshift		12U
+#       define malloc_minsize		16U
+#   endif
+#endif /* __FreeBSD__ */
+
+#if defined(__sparc__) && defined(sun)
+#   define malloc_pageshift		12U
+#   define malloc_minsize		16U
+#   define MAP_ANON			(0)
+    static int fdzero;
+#   define MMAP_FD	fdzero
+#   define INIT_MMAP() \
+	{ if ((fdzero=open("/dev/zero", O_RDWR, 0000)) == -1) \
+	    wrterror("open of /dev/zero"); }
+#   define MADV_FREE			MADV_DONTNEED
+#endif /* __sparc__ */
+
+#if defined(__linux__)
+#   if defined(__i386__)
+#       define malloc_pageshift		12U
+#       define malloc_minsize		16U
+#   endif
+#endif /* __linux__ */
+
+#if defined(__alpha)
+#   define malloc_pageshift		13U
+#   define malloc_minsize		16U
+#endif /* __alpha */
+
+/* Insert your combination here... */
+#if defined(__FOOCPU__) && defined(__BAROS__)
+#   define malloc_pageshift		12U
+#   define malloc_minsize		16U
+#endif /* __FOOCPU__ && __BAROS__ */
+
+
+/*
+ * No user serviceable parts behind this point.
+ */
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * This structure describes a page worth of chunks.
+ */
+
+struct pginfo {
+    struct pginfo	*next;	/* next on the free list */
+    void		*page;	/* Pointer to the page */
+    u_short		size;	/* size of this page's chunks */
+    u_short		shift;	/* How far to shift for this size chunks */
+    u_short		free;	/* How many free chunks */
+    u_short		total;	/* How many chunk */
+    u_int		bits[1]; /* Which chunks are free */
+};
+
+/*
+ * This structure describes a number of free pages.
+ */
+
+struct pgfree {
+    struct pgfree	*next;	/* next run of free pages */
+    struct pgfree	*prev;	/* prev run of free pages */
+    void		*page;	/* pointer to free pages */
+    void		*end;	/* pointer to end of free pages */
+    size_t		size;	/* number of bytes free */
+};
+
+/*
+ * How many bits per u_int in the bitmap.
+ * Change only if not 8 bits/byte
+ */
+#define	MALLOC_BITS	(8*sizeof(u_int))
+
+/*
+ * Magic values to put in the page_directory
+ */
+#define MALLOC_NOT_MINE	((struct pginfo*) 0)
+#define MALLOC_FREE 	((struct pginfo*) 1)
+#define MALLOC_FIRST	((struct pginfo*) 2)
+#define MALLOC_FOLLOW	((struct pginfo*) 3)
+#define MALLOC_MAGIC	((struct pginfo*) 4)
+
+#ifndef malloc_pageshift
+#define malloc_pageshift		12U
+#endif
+
+#ifndef malloc_minsize
+#define malloc_minsize			16U
+#endif
+
+#if !defined(malloc_pagesize)
+#define malloc_pagesize			(1UL<<malloc_pageshift)
+#endif
+
+#if ((1<<malloc_pageshift) != malloc_pagesize)
+#error	"(1<<malloc_pageshift) != malloc_pagesize"
+#endif
+
+#ifndef malloc_maxsize
+#define malloc_maxsize			((malloc_pagesize)>>1)
+#endif
+
+/* A mask for the offset inside a page.  */
+#define malloc_pagemask	((malloc_pagesize)-1)
+
+#define pageround(foo) (((foo) + (malloc_pagemask))&(~(malloc_pagemask)))
+#define ptr2index(foo) (((u_long)(foo) >> malloc_pageshift)-malloc_origo)
+
+#ifdef _THREAD_SAFE
+extern long RT0u__inCritical;  /* Flag set when in a critical region */
+#define THREAD_LOCK()		(++RT0u__inCritical)
+#define THREAD_UNLOCK()		(--RT0u__inCritical)
+#endif
+
+#ifndef THREAD_LOCK
+#define THREAD_LOCK()
+#endif
+
+#ifndef THREAD_UNLOCK
+#define THREAD_UNLOCK()
+#endif
+
+#ifndef MMAP_FD
+#define MMAP_FD (-1)
+#endif
+
+#ifndef INIT_MMAP
+#define INIT_MMAP()
+#endif
+
+/* This is needed at least by HP-UX 10.20 */
+#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
+#define MAP_ANON MAP_ANONYMOUS
+#endif
+
+/* Set when initialization has been done */
+static unsigned malloc_started;	
+
+/* Recusion flag for public interface. */
+static int malloc_active;
+
+/* Number of free pages we cache */
+static unsigned malloc_cache = 16;
+
+/* The offset from pagenumber to index into the page directory */
+static u_long malloc_origo;
+
+/* The last index in the page directory we care about */
+static u_long last_index;
+
+/* Pointer to page directory. Allocated "as if with" malloc */
+static struct	pginfo **page_dir;
+
+/* How many slots in the page directory */
+static unsigned	malloc_ninfo;
+
+/* Free pages line up here */
+static struct pgfree free_list;
+
+/* Abort(), user doesn't handle problems.  */
+static int malloc_abort;
+
+/* Are we trying to die ?  */
+static int suicide;
+
+/* always realloc ?  */
+static int malloc_realloc;
+
+/* pass the kernel a hint on free pages ?  */
+static int malloc_hint = 1;
+
+/* xmalloc behaviour ?  */
+static int malloc_xmalloc;
+
+/* sysv behaviour for malloc(0) ?  */
+static int malloc_sysv;
+
+/* zero fill ?  */
+static int malloc_zero;
+
+/* junk fill ?  */
+static int malloc_junk;
+
+#ifdef HAS_UTRACE
+
+/* utrace ?  */
+static int malloc_utrace;
+
+struct ut { void *p; size_t s; void *r; };
+
+void utrace __P((struct ut *, int));
+
+#define UTRACE(a, b, c) \
+	if (malloc_utrace) \
+		{struct ut u; u.p=a; u.s = b; u.r=c; utrace(&u, sizeof u);}
+#else /* !HAS_UTRACE */
+#define UTRACE(a,b,c)
+#endif /* HAS_UTRACE */
+
+/* my last break. */
+static void *malloc_brk;
+
+/* one location cache for free-list holders */
+static struct pgfree *px;
+
+/* compile-time options */
+char *malloc_options;
+
+/* Name of the current public function */
+static char *malloc_func;
+
+/* Macro for mmap */
+#define MMAP(size) \
+	mmap((caddr_t)0, (size), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, \
+	    MMAP_FD, 0);
+
+/*
+ * Necessary function declarations
+ */
+static int extend_pgdir(u_long index);
+static void *imalloc(size_t size);
+static void ifree(void *ptr);
+static void *irealloc(void *ptr, size_t size);
+
+static void
+wrterror(char *p)
+{
+    char *q = " error: ";
+    write(STDERR_FILENO, malloc_func, strlen(malloc_func));
+    write(STDERR_FILENO, q, strlen(q));
+    write(STDERR_FILENO, p, strlen(p));
+    suicide = 1;
+    abort();
+}
+
+static void
+wrtwarning(char *p)
+{
+    char *q = " warning: ";
+    if (malloc_abort)
+	wrterror(p);
+    write(STDERR_FILENO, malloc_func, strlen(malloc_func));
+    write(STDERR_FILENO, q, strlen(q));
+    write(STDERR_FILENO, p, strlen(p));
+}
+
+
+/*
+ * Allocate a number of pages from the OS
+ */
+static caddr_t
+map_pages(int pages)
+{
+    caddr_t result, tail;
+
+    result = (caddr_t)pageround((u_long)sbrk(0));
+    tail = result + (pages << malloc_pageshift);
+
+    if (brk(tail)) {
+#ifdef EXTRA_SANITY
+	wrterror("(ES): map_pages fails\n");
+#endif /* EXTRA_SANITY */
+	return 0;
+    }
+
+    last_index = ptr2index(tail) - 1;
+    malloc_brk = tail;
+
+    if ((last_index+1) >= malloc_ninfo && !extend_pgdir(last_index))
+	return 0;;
+
+    return result;
+}
+
+/*
+ * Extend page directory
+ */
+static int
+extend_pgdir(u_long index)
+{
+    struct  pginfo **new, **old;
+    int i, oldlen;
+
+    /* Make it this many pages */
+    i = index * sizeof *page_dir;
+    i /= malloc_pagesize;
+    i += 2;
+
+    /* remember the old mapping size */
+    oldlen = malloc_ninfo * sizeof *page_dir;
+
+    /*
+     * NOTE: we allocate new pages and copy the directory rather than tempt
+     * fate by trying to "grow" the region.. There is nothing to prevent
+     * us from accidently re-mapping space that's been allocated by our caller
+     * via dlopen() or other mmap().
+     *
+     * The copy problem is not too bad, as there is 4K of page index per
+     * 4MB of malloc arena.
+     *
+     * We can totally avoid the copy if we open a file descriptor to associate
+     * the anon mappings with.  Then, when we remap the pages at the new
+     * address, the old pages will be "magically" remapped..  But this means
+     * keeping open a "secret" file descriptor.....
+     */
+
+    /* Get new pages */
+    new = (struct pginfo**) MMAP(i * malloc_pagesize);
+    if (new == (struct pginfo **)-1)
+	return 0;
+
+    /* Copy the old stuff */
+    memcpy(new, page_dir,
+	    malloc_ninfo * sizeof *page_dir);
+
+    /* register the new size */
+    malloc_ninfo = i * malloc_pagesize / sizeof *page_dir;
+
+    /* swap the pointers */
+    old = page_dir;
+    page_dir = new;
+
+    /* Now free the old stuff */
+    munmap((caddr_t)old, oldlen);
+    return 1;
+}
+
+/*
+ * Initialize the world
+ */
+static void
+malloc_init ()
+{
+    char *p, b[64];
+    int i, j;
+
+    INIT_MMAP();
+
+#ifdef EXTRA_SANITY
+    malloc_junk = 1;
+#endif /* EXTRA_SANITY */
+
+    for (i = 0; i < 3; i++) {
+	if (i == 0) {
+	    j = readlink("/etc/malloc.conf", b, sizeof b - 1);
+	    if (j <= 0)
+		continue;
+	    b[j] = '\0';
+	    p = b;
+	} else if (i == 1) {
+	    p = getenv("MALLOC_OPTIONS");
+	} else {
+	    p = malloc_options;
+	}
+	for (; p && *p; p++) {
+	    switch (*p) {
+		case '>': malloc_cache   <<= 1; break;
+		case '<': malloc_cache   >>= 1; break;
+		case 'a': malloc_abort   = 0; break;
+		case 'A': malloc_abort   = 1; break;
+		case 'h': malloc_hint    = 0; break;
+		case 'H': malloc_hint    = 1; break;
+		case 'r': malloc_realloc = 0; break;
+		case 'R': malloc_realloc = 1; break;
+		case 'j': malloc_junk    = 0; break;
+		case 'J': malloc_junk    = 1; break;
+#ifdef HAS_UTRACE
+		case 'u': malloc_utrace  = 0; break;
+		case 'U': malloc_utrace  = 1; break;
+#endif
+		case 'v': malloc_sysv    = 0; break;
+		case 'V': malloc_sysv    = 1; break;
+		case 'x': malloc_xmalloc = 0; break;
+		case 'X': malloc_xmalloc = 1; break;
+		case 'z': malloc_zero    = 0; break;
+		case 'Z': malloc_zero    = 1; break;
+		default:
+		    j = malloc_abort;
+		    malloc_abort = 0;
+		    wrtwarning("unknown char in MALLOC_OPTIONS\n");
+		    malloc_abort = j;
+		    break;
+	    }
+	}
+    }
+
+    UTRACE(0, 0, 0);
+
+    /*
+     * We want junk in the entire allocation, and zero only in the part
+     * the user asked for.
+     */
+    if (malloc_zero)
+	malloc_junk=1;
+
+    /*
+     * If we run with junk (or implicitly from above: zero), we want to
+     * force realloc() to get new storage, so we can DTRT with it.
+     */
+    if (malloc_junk)
+	malloc_realloc=1;
+
+    /* Allocate one page for the page directory */
+    page_dir = (struct pginfo **) MMAP(malloc_pagesize);
+
+    if (page_dir == (struct pginfo **) -1)
+	wrterror("mmap(2) failed, check limits.\n");
+
+    /*
+     * We need a maximum of malloc_pageshift buckets, steal these from the
+     * front of the page_directory;
+     */
+    malloc_origo = ((u_long)pageround((u_long)sbrk(0))) >> malloc_pageshift;
+    malloc_origo -= malloc_pageshift;
+
+    malloc_ninfo = malloc_pagesize / sizeof *page_dir;
+
+    /* Recalculate the cache size in bytes, and make sure it's nonzero */
+
+    if (!malloc_cache)
+	malloc_cache++;
+
+    malloc_cache <<= malloc_pageshift;
+
+    /*
+     * This is a nice hack from Kaleb Keithly (kaleb@x.org).
+     * We can sbrk(2) further back when we keep this on a low address.
+     */
+    px = (struct pgfree *) imalloc (sizeof *px);
+
+    /* Been here, done that */
+    malloc_started++;
+}
+
+/*
+ * Allocate a number of complete pages
+ */
+static void *
+malloc_pages(size_t size)
+{
+    void *p, *delay_free = 0;
+    int i;
+    struct pgfree *pf;
+    u_long index;
+
+    size = pageround(size);
+
+    p = 0;
+
+    /* Look for free pages before asking for more */
+    for(pf = free_list.next; pf; pf = pf->next) {
+
+#ifdef EXTRA_SANITY
+	if (pf->size & malloc_pagemask)
+	    wrterror("(ES): junk length entry on free_list\n");
+	if (!pf->size)
+	    wrterror("(ES): zero length entry on free_list\n");
+	if (pf->page == pf->end)
+	    wrterror("(ES): zero entry on free_list\n");
+	if (pf->page > pf->end) 
+	    wrterror("(ES): sick entry on free_list\n");
+	if ((void*)pf->page >= (void*)sbrk(0))
+	    wrterror("(ES): entry on free_list past brk\n");
+	if (page_dir[ptr2index(pf->page)] != MALLOC_FREE) 
+	    wrterror("(ES): non-free first page on free-list\n");
+	if (page_dir[ptr2index(pf->end)-1] != MALLOC_FREE)
+	    wrterror("(ES): non-free last page on free-list\n");
+#endif /* EXTRA_SANITY */
+
+	if (pf->size < size)
+	    continue;
+
+	if (pf->size == size) {
+	    p = pf->page;
+	    if (pf->next)
+		    pf->next->prev = pf->prev;
+	    pf->prev->next = pf->next;
+	    delay_free = pf;
+	    break;
+	} 
+
+	p = pf->page;
+	pf->page = (char *)pf->page + size;
+	pf->size -= size;
+	break;
+    }
+
+#ifdef EXTRA_SANITY
+    if (p && page_dir[ptr2index(p)] != MALLOC_FREE)
+	wrterror("(ES): allocated non-free page on free-list\n");
+#endif /* EXTRA_SANITY */
+
+    size >>= malloc_pageshift;
+
+    /* Map new pages */
+    if (!p)
+	p = map_pages(size);
+
+    if (p) {
+
+	index = ptr2index(p);
+	page_dir[index] = MALLOC_FIRST;
+	for (i=1;i<size;i++)
+	    page_dir[index+i] = MALLOC_FOLLOW;
+
+	if (malloc_junk)
+	    memset(p, SOME_JUNK, size << malloc_pageshift);
+    }
+
+    if (delay_free) {
+	if (!px)
+	    px = delay_free;
+	else
+	    ifree(delay_free);
+    }
+
+    return p;
+}
+
+/*
+ * Allocate a page of fragments
+ */
+
+static __inline__ int
+malloc_make_chunks(int bits)
+{
+    struct  pginfo *bp;
+    void *pp;
+    int i, k, l;
+
+    /* Allocate a new bucket */
+    pp = malloc_pages(malloc_pagesize);
+    if (!pp)
+	return 0;
+
+    /* Find length of admin structure */
+    l = offsetof(struct pginfo, bits[0]);
+    l += sizeof bp->bits[0] *
+	(((malloc_pagesize >> bits)+MALLOC_BITS-1) / MALLOC_BITS);
+
+    /* Don't waste more than two chunks on this */
+    if ((1<<(bits)) <= l+l) {
+	bp = (struct  pginfo *)pp;
+    } else {
+	bp = (struct  pginfo *)imalloc(l);
+	if (!bp) {
+	    ifree(pp);
+	    return 0;
+	}
+    }
+
+    bp->size = (1<<bits);
+    bp->shift = bits;
+    bp->total = bp->free = malloc_pagesize >> bits;
+    bp->page = pp;
+
+    /* set all valid bits in the bitmap */
+    k = bp->total;
+    i = 0;
+
+    /* Do a bunch at a time */
+    for(;k-i >= MALLOC_BITS; i += MALLOC_BITS)
+	bp->bits[i / MALLOC_BITS] = ~0;
+
+    for(; i < k; i++)
+        bp->bits[i/MALLOC_BITS] |= 1<<(i%MALLOC_BITS);
+
+    if (bp == bp->page) {
+	/* Mark the ones we stole for ourselves */
+	for(i=0;l > 0;i++) {
+	    bp->bits[i/MALLOC_BITS] &= ~(1<<(i%MALLOC_BITS));
+	    bp->free--;
+	    bp->total--;
+	    l -= (1 << bits);
+	}
+    }
+
+    /* MALLOC_LOCK */
+
+    page_dir[ptr2index(pp)] = bp;
+
+    bp->next = page_dir[bits];
+    page_dir[bits] = bp;
+
+    /* MALLOC_UNLOCK */
+
+    return 1;
+}
+
+/*
+ * Allocate a fragment
+ */
+static void *
+malloc_bytes(size_t size)
+{
+    int i,j;
+    u_int u;
+    struct  pginfo *bp;
+    int k;
+    u_int *lp;
+
+    /* Don't bother with anything less than this */
+    if (size < malloc_minsize)
+	size = malloc_minsize;
+
+    /* Find the right bucket */
+    j = 1;
+    i = size-1;
+    while (i >>= 1)
+	j++;
+
+    /* If it's empty, make a page more of that size chunks */
+    if (!page_dir[j] && !malloc_make_chunks(j))
+	return 0;
+
+    bp = page_dir[j];
+
+    /* Find first word of bitmap which isn't empty */
+    for (lp = bp->bits; !*lp; lp++)
+	;
+
+    /* Find that bit, and tweak it */
+    u = 1;
+    k = 0;
+    while (!(*lp & u)) {
+	u += u;
+	k++;
+    }
+    *lp ^= u;
+
+    /* If there are no more free, remove from free-list */
+    if (!--bp->free) {
+	page_dir[j] = bp->next;
+	bp->next = 0;
+    }
+
+    /* Adjust to the real offset of that chunk */
+    k += (lp-bp->bits)*MALLOC_BITS;
+    k <<= bp->shift;
+
+    if (malloc_junk)
+	memset((u_char*)bp->page + k, SOME_JUNK, bp->size);
+
+    return (u_char *)bp->page + k;
+}
+
+/*
+ * Allocate a piece of memory
+ */
+static void *
+imalloc(size_t size)
+{
+    void *result;
+
+    if (suicide)
+	abort();
+
+    if ((size + malloc_pagesize) < size)	/* Check for overflow */
+	result = 0;
+    else if (size <= malloc_maxsize)
+	result =  malloc_bytes(size);
+    else
+	result =  malloc_pages(size);
+
+    if (malloc_abort && !result)
+	wrterror("allocation failed.\n");
+
+    if (malloc_zero && result)
+	memset(result, 0, size);
+
+    return result;
+}
+
+/*
+ * Change the size of an allocation.
+ */
+static void *
+irealloc(void *ptr, size_t size)
+{
+    void *p;
+    u_long osize, index;
+    struct pginfo **mp;
+    int i;
+
+    if (suicide)
+	abort();
+
+    index = ptr2index(ptr);
+
+    if (index < malloc_pageshift) {
+	wrtwarning("junk pointer, too low to make sense.\n");
+	return 0;
+    }
+
+    if (index > last_index) {
+	wrtwarning("junk pointer, too high to make sense.\n");
+	return 0;
+    }
+
+    mp = &page_dir[index];
+
+    if (*mp == MALLOC_FIRST) {			/* Page allocation */
+
+	/* Check the pointer */
+	if ((u_long)ptr & malloc_pagemask) {
+	    wrtwarning("modified (page-) pointer.\n");
+	    return 0;
+	}
+
+	/* Find the size in bytes */
+	for (osize = malloc_pagesize; *++mp == MALLOC_FOLLOW;)
+	    osize += malloc_pagesize;
+
+        if (!malloc_realloc && 			/* unless we have to, */
+	  size <= osize && 			/* .. or are too small, */
+	  size > (osize - malloc_pagesize)) {	/* .. or can free a page, */
+	    return ptr;				/* don't do anything. */
+	}
+
+    } else if (*mp >= MALLOC_MAGIC) {		/* Chunk allocation */
+
+	/* Check the pointer for sane values */
+	if (((u_long)ptr & ((*mp)->size-1))) {
+	    wrtwarning("modified (chunk-) pointer.\n");
+	    return 0;
+	}
+
+	/* Find the chunk index in the page */
+	i = ((u_long)ptr & malloc_pagemask) >> (*mp)->shift;
+
+	/* Verify that it isn't a free chunk already */
+        if ((*mp)->bits[i/MALLOC_BITS] & (1<<(i%MALLOC_BITS))) {
+	    wrtwarning("chunk is already free.\n");
+	    return 0;
+	}
+
+	osize = (*mp)->size;
+
+	if (!malloc_realloc &&		/* Unless we have to, */
+	  size < osize && 		/* ..or are too small, */
+	  (size > osize/2 ||	 	/* ..or could use a smaller size, */
+	  osize == malloc_minsize)) {	/* ..(if there is one) */
+	    return ptr;			/* ..Don't do anything */
+	}
+
+    } else {
+	wrtwarning("pointer to wrong page.\n");
+	return 0;
+    }
+
+    p = imalloc(size);
+
+    if (p) {
+	/* copy the lesser of the two sizes, and free the old one */
+	if (!size || !osize)
+	    ;
+	else if (osize < size)
+	    memcpy(p, ptr, osize);
+	else
+	    memcpy(p, ptr, size);
+	ifree(ptr);
+    } 
+    return p;
+}
+
+/*
+ * Free a sequence of pages
+ */
+
+static __inline__ void
+free_pages(void *ptr, int index, struct pginfo *info)
+{
+    int i;
+    struct pgfree *pf, *pt=0;
+    u_long l;
+    void *tail;
+
+    if (info == MALLOC_FREE) {
+	wrtwarning("page is already free.\n");
+	return;
+    }
+
+    if (info != MALLOC_FIRST) {
+	wrtwarning("pointer to wrong page.\n");
+	return;
+    }
+
+    if ((u_long)ptr & malloc_pagemask) {
+	wrtwarning("modified (page-) pointer.\n");
+	return;
+    }
+
+    /* Count how many pages and mark them free at the same time */
+    page_dir[index] = MALLOC_FREE;
+    for (i = 1; page_dir[index+i] == MALLOC_FOLLOW; i++)
+	page_dir[index + i] = MALLOC_FREE;
+
+    l = i << malloc_pageshift;
+
+    if (malloc_junk)
+	memset(ptr, SOME_JUNK, l);
+
+#ifdef MADV_FREE
+    if (malloc_hint)
+	madvise(ptr, l, MADV_FREE);
+#endif
+
+    tail = (char *)ptr+l;
+
+    /* add to free-list */
+    if (!px)
+	px = imalloc(sizeof *pt);	/* This cannot fail... */
+    px->page = ptr;
+    px->end =  tail;
+    px->size = l;
+    if (!free_list.next) {
+
+	/* Nothing on free list, put this at head */
+	px->next = free_list.next;
+	px->prev = &free_list;
+	free_list.next = px;
+	pf = px;
+	px = 0;
+
+    } else {
+
+	/* Find the right spot, leave pf pointing to the modified entry. */
+	tail = (char *)ptr+l;
+
+	for(pf = free_list.next; pf->end < ptr && pf->next; pf = pf->next)
+	    ; /* Race ahead here */
+
+	if (pf->page > tail) {
+	    /* Insert before entry */
+	    px->next = pf;
+	    px->prev = pf->prev;
+	    pf->prev = px;
+	    px->prev->next = px;
+	    pf = px;
+	    px = 0;
+	} else if (pf->end == ptr ) {
+	    /* Append to the previous entry */
+	    pf->end = (char *)pf->end + l;
+	    pf->size += l;
+	    if (pf->next && pf->end == pf->next->page ) {
+		/* And collapse the next too. */
+		pt = pf->next;
+		pf->end = pt->end;
+		pf->size += pt->size;
+		pf->next = pt->next;
+		if (pf->next)
+		    pf->next->prev = pf;
+	    }
+	} else if (pf->page == tail) {
+	    /* Prepend to entry */
+	    pf->size += l;
+	    pf->page = ptr;
+	} else if (!pf->next) {
+	    /* Append at tail of chain */
+	    px->next = 0;
+	    px->prev = pf;
+	    pf->next = px;
+	    pf = px;
+	    px = 0;
+	} else {
+	    wrterror("freelist is destroyed.\n");
+	}
+    }
+    
+    /* Return something to OS ? */
+    if (!pf->next &&				/* If we're the last one, */
+      pf->size > malloc_cache &&		/* ..and the cache is full, */
+      pf->end == malloc_brk &&			/* ..and none behind us, */
+      malloc_brk == sbrk(0)) {			/* ..and it's OK to do... */
+
+	/*
+	 * Keep the cache intact.  Notice that the '>' above guarantees that
+	 * the pf will always have at least one page afterwards.
+	 */
+	pf->end = (char *)pf->page + malloc_cache;
+	pf->size = malloc_cache;
+
+	brk(pf->end);
+	malloc_brk = pf->end;
+
+	index = ptr2index(pf->end);
+	last_index = index - 1;
+
+	for(i=index;i <= last_index;)
+	    page_dir[i++] = MALLOC_NOT_MINE;
+
+	/* XXX: We could realloc/shrink the pagedir here I guess. */
+    }
+    if (pt)
+	ifree(pt);
+}
+
+/*
+ * Free a chunk, and possibly the page it's on, if the page becomes empty.
+ */
+
+static __inline__ void
+free_bytes(void *ptr, int index, struct pginfo *info)
+{
+    int i;
+    struct pginfo **mp;
+    void *vp;
+
+    /* Find the chunk number on the page */
+    i = ((u_long)ptr & malloc_pagemask) >> info->shift;
+
+    if (((u_long)ptr & (info->size-1))) {
+	wrtwarning("modified (chunk-) pointer.\n");
+	return;
+    }
+
+    if (info->bits[i/MALLOC_BITS] & (1<<(i%MALLOC_BITS))) {
+	wrtwarning("chunk is already free.\n");
+	return;
+    }
+
+    if (malloc_junk)
+	memset(ptr, SOME_JUNK, info->size);
+
+    info->bits[i/MALLOC_BITS] |= 1<<(i%MALLOC_BITS);
+    info->free++;
+
+    mp = page_dir + info->shift;
+
+    if (info->free == 1) {
+
+	/* Page became non-full */
+
+	mp = page_dir + info->shift;
+	/* Insert in address order */
+	while (*mp && (*mp)->next && (*mp)->next->page < info->page)
+	    mp = &(*mp)->next;
+	info->next = *mp;
+	*mp = info;
+	return;
+    }
+
+    if (info->free != info->total)
+	return;
+
+    /* Find & remove this page in the queue */
+    while (*mp != info) {
+	mp = &((*mp)->next);
+#ifdef EXTRA_SANITY
+	if (!*mp)
+		wrterror("(ES): Not on queue\n");
+#endif /* EXTRA_SANITY */
+    }
+    *mp = info->next;
+
+    /* Free the page & the info structure if need be */
+    page_dir[ptr2index(info->page)] = MALLOC_FIRST;
+    vp = info->page;		/* Order is important ! */
+    if(vp != (void*)info) 
+	ifree(info);
+    ifree(vp);
+}
+
+static void
+ifree(void *ptr)
+{
+    struct pginfo *info;
+    int index;
+
+    /* This is legal */
+    if (!ptr)
+	return;
+
+    if (!malloc_started) {
+	wrtwarning("malloc() has never been called.\n");
+	return;
+    }
+
+    /* If we're already sinking, don't make matters any worse. */
+    if (suicide)
+	return;
+
+    index = ptr2index(ptr);
+
+    if (index < malloc_pageshift) {
+	wrtwarning("junk pointer, too low to make sense.\n");
+	return;
+    }
+
+    if (index > last_index) {
+	wrtwarning("junk pointer, too high to make sense.\n");
+	return;
+    }
+
+    info = page_dir[index];
+
+    if (info < MALLOC_MAGIC)
+        free_pages(ptr, index, info);
+    else
+	free_bytes(ptr, index, info);
+    return;
+}
+
+/*
+ * These are the public exported interface routines.
+ */
+
+
+void *
+malloc(size_t size)
+{
+    register void *r;
+
+    malloc_func = " in malloc():";
+    THREAD_LOCK();
+    if (malloc_active++) {
+	wrtwarning("recursive call.\n");
+        malloc_active--;
+	return (0);
+    }
+    if (!malloc_started)
+	malloc_init();
+    if (malloc_sysv && !size)
+	r = 0;
+    else
+	r = imalloc(size);
+    UTRACE(0, size, r);
+    malloc_active--;
+    THREAD_UNLOCK();
+    if (malloc_xmalloc && !r)
+	wrterror("out of memory.\n");
+    return (r);
+}
+
+void
+free(void *ptr)
+{
+    malloc_func = " in free():";
+    THREAD_LOCK();
+    if (malloc_active++) {
+	wrtwarning("recursive call.\n");
+        malloc_active--;
+	return;
+    }
+    ifree(ptr);
+    UTRACE(ptr, 0, 0);
+    malloc_active--;
+    THREAD_UNLOCK();
+    return;
+}
+
+void *
+realloc(void *ptr, size_t size)
+{
+    register void *r;
+
+    malloc_func = " in realloc():";
+    THREAD_LOCK();
+    if (malloc_active++) {
+	wrtwarning("recursive call.\n");
+        malloc_active--;
+	return (0);
+    }
+    if (ptr && !malloc_started) {
+	wrtwarning("malloc() has never been called.\n");
+	ptr = 0;
+    }		
+    if (!malloc_started)
+	malloc_init();
+    if (malloc_sysv && !size) {
+	ifree(ptr);
+	r = 0;
+    } else if (!ptr) {
+	r = imalloc(size);
+    } else {
+        r = irealloc(ptr, size);
+    }
+    UTRACE(ptr, size, r);
+    malloc_active--;
+    THREAD_UNLOCK();
+    if (malloc_xmalloc && !r)
+	wrterror("out of memory.\n");
+    return (r);
+}
+
+void *
+calloc(size_t num, size_t size)
+{
+    register void *r;
+
+    size *= num;
+    r = malloc(size);
+    if (r)
+	memset(r, 0, size);
+    return (r);
+}
Index: libs/m3core/src/unix/freebsd-4.amd64/Umman.i3
--- libs/m3core/src/unix/freebsd-4.amd64/Umman.i3	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/unix/freebsd-4.amd64/Umman.i3	Mon Feb 16 21:21:14 2004
@@ -0,0 +1,53 @@
+(* Copyright (C) 1992, Digital Equipment Corporation                         *)
+(* All rights reserved.                                                      *)
+(* See the file COPYRIGHT for a full description.                            *)
+(*                                                                           *)
+(* Last modified on Fri Apr 30 14:41:23 PDT 1993 by muller                   *)
+(* ow Sat Oct 29 14:10:19 MET 1994 adapted for FreeBSD                       *)
+INTERFACE Umman;
+
+FROM Ctypes IMPORT int;
+FROM Utypes IMPORT caddr_t, size_t, off_t;
+
+(*** sys/mman.h ***)
+
+CONST
+  PROT_NONE        = 16_0000;
+  PROT_READ        = 16_0001;
+  PROT_WRITE       = 16_0002;
+  PROT_EXEC        = 16_0004;
+     
+  MAP_FILE         = 16_0000;
+  MAP_ANON         = 16_1000;
+
+  MAP_PRIVATE      = 16_0002;
+  MAP_SHARED       = 16_0001;
+  MAP_COPY         = 16_0004;
+
+  MAP_FIXED        = 16_0010;
+  MAP_RENAME       = 16_0020;
+  MAP_NORESERVE    = 16_0040;
+  MAP_INHERIT      = 16_0080;
+  MAP_NOEXTEND     = 16_0100;
+  MAP_HASSEMAPHORE = 16_0200;
+
+  MADV_NORMAL      = 0;
+  MADV_RANDOM      = 1;
+  MADV_SEQUENTIAL  = 2;
+  MADV_WILLNEED    = 3;
+  MADV_DONTNEED    = 4;
+
+<*EXTERNAL*>
+PROCEDURE mmap (addr: caddr_t; len: size_t; prot,flags,fd: int; off: off_t)
+  : caddr_t;
+
+<*EXTERNAL*>
+PROCEDURE munmap (addr: caddr_t; len: size_t): int;
+
+<*EXTERNAL*>
+PROCEDURE mprotect (addr: caddr_t; len: size_t; prot:int): int;
+
+<*EXTERNAL*>
+PROCEDURE msync (addr: caddr_t; len: size_t): int;
+
+END Umman.
Index: libs/m3core/src/unix/freebsd-4.amd64/Unix.i3
--- libs/m3core/src/unix/freebsd-4.amd64/Unix.i3	Sat Apr 29 14:44:00 2006
+++ libs/m3core/src/unix/freebsd-4.amd64/Unix.i3	Sat Apr 29 14:45:45 2006
@@ -0,0 +1,971 @@
+(* Copyright (C) 1994, Digital Equipment Corporation            *)
+(* All rights reserved.                                         *)
+(* See the file COPYRIGHT for a full description.               *)
+(*                                                              *)
+(* Last modified on Sat Jan  7 14:41:42 PST 1995 by kalsow      *)
+(*      modified on Sun Nov  6 16:39:26 MET 1994 by Olaf Wagner *)
+(*      modified on Sat Apr 16 by rrw1000@hermes.cam.ac.uk      *)
+(*      modified on Tue Jun  8 16:26:41 PDT 1993 by mcjones     *)
+(*      modified on Mon Jan 11 14:34:49 PST 1993 by muller      *)
+(*                                                              *)
+(* ow 01.10.1994 adjusted file mode flags for FreeBSD           *)
+(* ow Sun Nov  6 16:39:26 MET 1994                              *)
+(*    Most of the system calls have been checked and adjusted   *)
+(*    for FreeBSD now. Still to be done completedly: ioctl      *)
+
+INTERFACE Unix;
+
+FROM Word IMPORT Or, And, Shift;
+
+FROM Ctypes IMPORT short, int, long, char_star, 
+                   char_star_star;
+FROM Utypes IMPORT dev_t, off_t, mode_t, pid_t, (*tcflag_t,*) u_long, 
+                   (*cc_t, speed_t,*) uid_t, gid_t, size_t;
+FROM Utime IMPORT struct_timeval;
+
+CONST
+  MaxPathLen = 1024;
+
+(*** file flags ***)
+CONST
+  FREAD =      16_0000;        (* descriptor read/receive'able *)
+  FWRITE =     16_0001;        (* descriptor write/send'ale *)
+  FCREAT =     16_0200;        (* create if nonexistant *)
+  FEXCL =      16_0800;        (* error if already created *)
+  FTRUNC  =    16_0400;        (* truncate to zero length *)
+  FAPPEND =    16_0008;        (* append on each write *)
+  FNBLOCK =    16_0004;        (* POSIX no delay *)
+  FNDELAY =    FNBLOCK;        (* no delay *)
+  FSYNCRON =   16_0080;        (* write file syncronously *)
+  FMARK =      16_1000;        (* makr during gc() *)
+  FDEFER =     16_2000;        (* fefer for next gc pass *)
+  FASYNC =     16_0040;        (* signal pgrp when data ready *)
+  FSHLOCK =    16_0010;        (* shared lock present *)
+  FEXLOCK =    16_0020;        (* exclusive lock present *)
+
+CONST
+  MSETUID = 8_4000;
+  MSETGID = 8_2000;
+  MSTICKY = 8_1000;
+  MROWNER = 8_0400;
+  MWOWNER = 8_0200;
+  MXOWNER = 8_0100;
+  MRGROUP = 8_0040;
+  MWGROUP = 8_0020;
+  MXGROUP = 8_0010;
+  MROTHER = 8_0004;
+  MWOTHER = 8_0002;
+  MXOTHER = 8_0001;
+  Mrwrr = MROWNER + MWOWNER + MRGROUP + MROTHER;
+  Mrwrwrw = MROWNER + MWOWNER + MRGROUP + MWGROUP + MROTHER + MWOTHER;
+
+
+
+(*** access - determine the accessibility of file ***)
+<*EXTERNAL*> PROCEDURE access (path: char_star; mod: int): int;
+(* ok *)
+
+(*** acct - turn accounting on or off ***)
+<*EXTERNAL*> PROCEDURE acct (path: char_star): int;
+(* ok *)
+
+(*** brk, sbrk - change data segment space allocation *)
+<*EXTERNAL*> PROCEDURE brk (addr: ADDRESS): int;
+(* ok *)
+<*EXTERNAL*> PROCEDURE sbrk (inc: int): char_star;
+(* ok *)
+
+(*** chdir - change working directory ***)
+<*EXTERNAL*> PROCEDURE chdir (path: char_star): int;
+(* ok *)
+
+(*** chmod, fchmod - change mde of file ***)
+<*EXTERNAL*> PROCEDURE chmod (path: char_star; mode: mode_t): int;
+<*EXTERNAL*> PROCEDURE fchmod (fd, mode: mode_t): int;
+(* ok *)
+
+(*** chown, fchown, lchown - change owner and group of a file ***)
+<*EXTERNAL*> PROCEDURE chown (path: char_star; owner: uid_t; group: gid_t): int;
+<*EXTERNAL*> PROCEDURE fchown (fd: int; owner: uid_t; group: gid_t): int;
+<*EXTERNAL*> PROCEDURE lchown (path: char_star; owner: uid_t; group: gid_t): int;
+(* ok *)
+
+(*** chroot - change root directory ***)
+<*EXTERNAL*> PROCEDURE chroot (dirname: char_star): int;
+(* ok *)
+
+(*** close - delete a descriptor ***)
+<*EXTERNAL*> PROCEDURE close (d: int): int;
+(* ok *)
+
+(*** creat - create a new file ***)
+<*EXTERNAL*> PROCEDURE creat (name: char_star; mode: mode_t): int;
+(* ok, but obsolete *)
+
+(*** dup, dup2 - duplicate an open file descriptor ***)
+<*EXTERNAL*> PROCEDURE dup (oldd: int): int;
+<*EXTERNAL*> PROCEDURE dup2 (oldd, newd: int): int;
+(* ok *)
+
+(*** execve - execute a file ***)
+<*EXTERNAL*> PROCEDURE execve (name: char_star; 
+                           argv, envp: char_star_star): int;
+(* ok *)
+
+(*** exit - terminate a process ***)
+<*EXTERNAL*> PROCEDURE exit (i: int);
+(* ok *)
+
+(*** _exit - terminate a process without performing C I/O library cleanup ***)
+<*EXTERNAL "_exit"*> PROCEDURE underscore_exit (i: int);
+(* ok *)
+
+(*** fcntl - file control ***)
+CONST   (* request *)
+  F_DUPFD =  0;   (* Duplicate fd *)
+  F_GETFD =  1;   (* Get close-on-exec flag *)
+  F_SETFD =  2;   (* Set close-on-exec flag *)
+  F_GETFL =  3;   (* Get fd status flags *)
+  F_SETFL =  4;   (* Set fd status flags *)
+
+  (* in these three cases, you need to pass LOOPHOLE (ADR (v), long) 
+     for arg, where v is a variable of type struct_flock *)
+  F_GETOWN = 5;   (* Set owner *)
+  F_SETOWN = 6;   (* Get owner *)
+
+  F_GETLK  = 7;   (* Get file lock *)
+  F_SETLK  = 8;   (* Set file lock *)
+  F_SETLKW = 9;   (* Set file lock and wait *)
+
+CONST (* fd flags *)
+  FD_CLOEXEC = 1;    (* Close file descriptor on exec() *)
+
+TYPE
+  struct_flock = RECORD
+    l_start:  off_t := 0;
+    l_len:    off_t := 0;
+    l_pid:    pid_t := 0;
+    l_type:   short; (* see below *)
+    l_whence: short;
+  END;
+(* ok *)
+
+CONST (* l_type values *)
+  F_RDLCK = 1; (* Read lock *) 
+  F_WRLCK = 3; (* Write lock *)
+  F_UNLCK = 2; (* Remove lock(s) *)
+
+<*EXTERNAL*> PROCEDURE fcntl (fd, request: int; arg: long): int;
+(* ok *)
+
+(*** flock - apply or remove an advisory lock on an open file ***)
+CONST
+  LOCK_SH = 1;   (* shared lock *)
+  LOCK_EX = 2;   (* exclusive lock *)
+  LOCK_NB = 4;   (* don't block when locking *)
+  LOCK_UN = 8;   (* unlock *)
+
+<*EXTERNAL*> PROCEDURE flock (fd, operation: int): int;
+(* ok *)
+
+(*** fork - create a new process ***)
+<*EXTERNAL*> PROCEDURE fork (): pid_t;
+(* ok *)
+
+(*** fsync - synchronize a file's in-core state with that on disk ***)
+<*EXTERNAL*> PROCEDURE fsync (fd: int): int;
+(* ok *)
+
+(*** getdirentries - gets directory entries in a generic directory format ***)
+<*EXTERNAL*> PROCEDURE getdirentries (fd: int; buf: ADDRESS;
+                                  nbytes: int; VAR basep: long): int;
+(* ok *)
+
+(*** getdomainname, setdomainname - get or set name of current domain ***)
+<*EXTERNAL*> PROCEDURE getdomainname (name: char_star; namelen: int): int;
+<*EXTERNAL*> PROCEDURE setdomainname (name: char_star; namelen: int): int;
+(* ok *)
+
+(*** getdtablesize - get descriptor table size ***)
+<*EXTERNAL*> PROCEDURE getdtablesize (): int;
+(* ok *)
+
+(*** getgroups - get group access list ***)
+<*EXTERNAL*> PROCEDURE getgroups (gidsetsize: int; VAR gidset: int): int;
+(* ok *)
+
+(*** gethostid, sethostid - get/set unique identifier of current host ***)
+<*EXTERNAL*> PROCEDURE gethostid (): long;
+<*EXTERNAL*> PROCEDURE sethostid (hostid: long): int;
+(* ok *)
+
+
+(*** gethostname, sethostname - get/set name of current host ***)
+<*EXTERNAL*> PROCEDURE gethostname (name: char_star; namelen: int): int;
+<*EXTERNAL*> PROCEDURE sethostname (name: char_star; namelen: int): int;
+(* ok *)
+
+(*** getpagesize - get system page size ***)
+<*EXTERNAL*> PROCEDURE getpagesize (): int;
+(* ok *)
+
+(*** getwd - get current working directory pathname ***)
+<*EXTERNAL*> PROCEDURE getwd (pathname: char_star): char_star;
+<*EXTERNAL*> PROCEDURE getcwd (pathname: char_star; size: size_t): char_star;
+(* ok *)
+
+(*** ioctl - control device ***)
+(* this is a temptative declaration of the types of the arguments. 
+   it shoulb probably done in another way, so it is commented. We really need
+   only the sizes of these records; see below
+
+TYPE
+  struct_sgttyb_ULTRIX = RECORD
+	sg_ispeed: char;		(* input speed *)
+	sg_ospeed: char;		(* output speed *)
+	sg_erase:  char;		(* erase character *)
+	sg_kill:   char;		(* kill character *)
+	sg_flags:  short;		(* mode flags *)
+        END;
+(* ok *)
+
+  struct_tchars = RECORD
+	t_intrc:  char;		/* Interrupt			*/
+	t_quitc:  char;		/* Quit 			*/
+	t_startc: char;		/* Start output 		*/
+	t_stopc:  char;		/* Stop output			*/
+	t_eofc:   char; 	/* End-of-file (EOF)		*/
+	t_brkc:   char; 	/* Input delimiter (like nl)	*/
+	END;
+(* ok *)
+
+  struct_ltchars = RECORD
+	t_suspc:  char;		/* Stop process signal		*/
+	t_dsuspc: char;		/* Delayed stop process signal	*/
+	t_rprntc: char;		/* Reprint line 		*/
+	t_flushc: char;		/* Flush output (toggles)	*/
+	t_werasc: char;		/* Word erase			*/
+	t_lnextc: char;		/* Literal next character	*/
+	END;
+(* ok *)
+
+  struct_winsize = RECORD
+	ws_row, ws_col:       u_short; 	/* Window charact. size */
+	ws_xpixel, ws_ypixel: u_short;	/* Window pixel size	*/
+	END;
+(* ok *)
+
+(*
+  struct_termio = RECORD
+	c_iflag:   u_short;	/* input modes */
+	c_oflag:   u_short;	/* output modes */
+	c_cflag:   u_short;	/* control modes */
+	c_lflag:   u_short;	/* line discipline modes */
+	c_line:    char;	/* line discipline */
+	c_cc[NCC]: u_char;	/* control chars */
+	END;
+*)
+
+  struct_termios = RECORD
+	c_iflag:    tcflag_t;		/* Input Modes 		*/
+	c_oflag:    tcflag_t;        	/* Output Modes		*/
+	c_cflag:    tcflag_t;        	/* Control Modes	*/
+	c_lflag:    tcflag_t;        	/* Local Modes 		*/
+	c_cc[NCCS]: cc_t;          	/* Control Characters	*/
+	c_ispeed,
+	c_ospeed:   speed_t;
+	END;
+(* ok *)
+
+(* This is how far I got. I don't think anybody will ever need it,
+   so I stop here. ow Sun Nov  6 17:12:47 MET 1994 *)
+  struct_rtentry = RECORD
+	u_long	        rt_hash;	/* to speed lookups */
+	struct_sockaddr rt_dst;	       /* key */
+	struct_sockaddr rt_gateway;	/* value */
+	short	        rt_flags;	/* up/down?, host/net */
+	short      	rt_refcnt;	/* # held references */
+	u_long	        rt_use;		/* raw # packets forwarded */
+	struct_ifnet    *rt_ifp;       /* the answer: interface to use */
+	struct_rtentry *rt_next;       /* next in list */
+	END;
+
+  struct_ifreq_1 = RECORD
+	char	ifr_name[16];		/* if name, e.g. "en0" */
+	struct_sockaddr ifru_addr;
+        END;
+  struct_ifreq_2 = RECORD
+	char	ifr_name[16];		/* if name, e.g. "en0" */
+	u_short         ifru_flags;
+	END;
+  struct_ifreq_3 = RECORD
+	char	ifr_name[16];		/* if name, e.g. "en0" */
+	int	ifru_metric;
+	END;
+  struct_ifreq_4 = RECORD
+	char	ifr_name[16];		/* if name, e.g. "en0" */
+	caddr_t ifru_data;
+	END;
+
+  struct_ifconf_1 = RECORD
+	int	ifc_len;		/* size of associated buffer */
+	caddr_t	ifcu_buf;
+	END;
+  struct_ifconf_2 = RECORD
+	int	ifc_len;		/* size of associated buffer */
+	struct	ifreq *ifcu_req;
+	END;
+
+  struct_ctrreq_1 = RECORD
+	char	ctr_name[IFNAMSIZ];	/* if name */
+	char	ctr_type;		/* type of interface */
+	struct_estat ctrc_ether;/* ethernet counters */
+	END;
+  struct_ctrreq_2 = RECORD
+	char	ctr_name[IFNAMSIZ];	/* if name */
+	char	ctr_type;		/* type of interface */
+	struct_dstat ctrc_ddcmp;/* DDCMP pt-to-pt counters */
+	END;
+
+  struct_ifdevea = RECORD
+        char    ifr_name[IFNAMSIZ];             /* if name, e.g. "en0" */
+        u_char default_pa[6];                   /* default hardware address */
+        u_char current_pa[6];                   /* current physical address */
+	END;
+
+  struct_arpreq = RECORD
+	struct_sockaddr arp_pa;		/* protocol address */
+	struct_sockaddr arp_ha;		/* hardware address */
+	int             arp_flags;	/* flags */
+	END;
+
+  struct_ifstate = RECORD
+        char    ifr_name[IFNAMSIZ];     /* if name, e.g. "en0" */
+	u_short	if_family;		/* current family ownership */
+	u_short	if_next_family;		/* next family ownership */
+	u_short	if_mode:3,		/* mode of device */
+		if_ustate:1,		/* user requested state */
+		if_nomuxhdr:1,		/* if set, omit mux header */
+		if_dstate:4,		/* current state of device */
+		if_xferctl:1,		/* xfer control to nxt family */
+		if_rdstate:1,		/* read current state */
+		if_wrstate:1,		/* set current state */
+		if_reserved:4;
+	END;
+
+  struct_solicit_1 = RECORD
+	END;
+
+  struct_response_1 = RECORD
+	END;
+
+  struct_lat_ucom = RECORD
+	END;
+
+  struct_lat_ini = RECORD
+	END;
+
+#define MAXLTADESTSIZE 16
+#define MAXLTASERVSIZE 16
+#define MAXLTAPORTSIZE 16
+ 
+  struct_ltattyi = RECORD
+	char lta_dest_port[MAXLTADESTSIZE+1];
+	char lta_server_name[MAXLTASERVSIZE+1];
+	char lta_server_port[MAXLTAPORTSIZE+1];
+	END;
+
+  struct_pt = RECORD
+	END;
+
+  struct_el = RECORD
+	END;
+
+  struct_mtop = RECORD
+	short	mt_op;			/* Operations defined below	*/
+	daddr_t mt_count;		/* How many of them		*/
+	END;
+
+  struct_mtget = RECORD
+	short	mt_type;		/* Type of device defined below */
+	short	mt_dsreg;		/* ``drive status'' register	*/
+	short	mt_erreg;		/* ``error'' register		*/
+	short	mt_resid;		/* Residual count		*/
+	END;
+
+  struct_dkop = RECORD
+	short	dk_op;			/* Operations defined below	*/
+	daddr_t dk_count;		/* How many of them		*/
+	END;
+
+  struct_dkget = RECORD
+	short	dk_type;		/* Type of device defined below */
+	short	dk_dsreg;		/* ``drive status'' register	*/
+	short	dk_erreg;		/* ``error'' register		*/
+	short	dk_resid;		/* Residual count		*/
+	END;
+
+  struct_dkacc = RECORD
+	short	dk_opcode;		/* Operation code for access	*/
+	long	dk_lbn;			/* Disk sector number		*/
+	long	dk_length;		/* Length of transfer		*/
+	unsigned dk_status;		/* Status of operation		*/
+	unsigned dk_flags;		/* Status flags			*/
+	END;
+
+  struct_devget = RECORD
+	short	category;		/* Category			*/
+	short	bus;			/* Bus				*/
+	char	interface[DEV_SIZE];	/* Interface (string)		*/
+	char	device[DEV_SIZE];	/* Device (string)		*/
+	short	adpt_num;		/* Adapter number		*/
+	short	nexus_num;		/* Nexus or node on adapter no. */
+	short	bus_num;		/* Bus number			*/
+	short	ctlr_num;		/* Controller number		*/
+	short	rctlr_num;		/* Remote controller number	*/
+	short	slave_num;		/* Plug or line number		*/
+	char	dev_name[DEV_SIZE];	/* Ultrix device pneumonic	*/
+	short	unit_num;		/* Ultrix device unit number	*/
+	unsigned soft_count;		/* Driver soft error count	*/
+	unsigned hard_count;		/* Driver hard error count	*/
+	long	stat;			/* Generic status mask		*/
+	long	category_stat;		/* Category specific mask	*/
+	END;
+*)
+
+CONST
+  IOCPARM_MASK = 16_1fff;          
+  IOC_VOID  = Shift (1, 29);       (* no parameters *)
+  IOC_OUT   = Shift (1, 30);       (* copy out parameters *)
+  IOC_IN    = Shift (1, 31);       (* copy in parameters *)
+  IOC_INOUT = Or (IOC_IN, IOC_OUT);
+
+
+  NOARG  = IOC_VOID;
+  R      = IOC_OUT;
+  W      = IOC_IN;
+  RW     = IOC_INOUT;
+(* if we had the structure declarations, we would use these 
+  INT    = Shift (And (BYTESIZE (INTEGER),              IOCPARM_MASK), 16);
+  SG     = Shift (And (BYTESIZE (struct_sgttyb_ULTRIX), IOCPARM_MASK), 16);
+  TCHAR  = Shift (And (BYTESIZE (struct_tchars),        IOCPARM_MASK), 16);
+  LC     = Shift (And (BYTESIZE (struct_ltchars),       IOCPARM_MASK), 16);
+  WS     = Shift (And (BYTESIZE (struct_winsize),       IOCPARM_MASK), 16);
+  TIO    = Shift (And (BYTESIZE (struct_termio),        IOCPARM_MASK), 16);
+  IOS    = Shift (And (BYTESIZE (struct_termios),       IOCPARM_MASK), 16);
+  RTE    = Shift (And (BYTESIZE (struct_rtentry),       IOCPARM_MASK), 16);
+  IFR    = Shift (And (BYTESIZE (struct_ifreq),         IOCPARM_MASK), 16);
+  IFC    = Shift (And (BYTESIZE (struct_ifconf),        IOCPARM_MASK), 16);
+  CTR    = Shift (And (BYTESIZE (struct_ctrreq),        IOCPARM_MASK), 16);
+  IFD    = Shift (And (BYTESIZE (struct_ifdevea),       IOCPARM_MASK), 16);
+  ARP    = Shift (And (BYTESIZE (struct_arpreq),        IOCPARM_MASK), 16);
+  IFS    = Shift (And (BYTESIZE (struct_ifstate),       IOCPARM_MASK), 16);
+  SOL    = Shift (And (BYTESIZE (struct_solicit_1),     IOCPARM_MASK), 16);
+  RES    = Shift (And (BYTESIZE (struct_response_1),    IOCPARM_MASK), 16);
+  LAU    = Shift (And (BYTESIZE (struct_lat_ucom),      IOCPARM_MASK), 16);
+  LAI    = Shift (And (BYTESIZE (struct_lat_ini),       IOCPARM_MASK), 16);
+  LTA    = Shift (And (BYTESIZE (struct_ltattyi),       IOCPARM_MASK), 16);
+  PT     = Shift (And (BYTESIZE (struct_pt),            IOCPARM_MASK), 16);
+  EL     = Shift (And (BYTESIZE (struct_el),            IOCPARM_MASK), 16);
+  MTO    = Shift (And (BYTESIZE (struct_mtop),          IOCPARM_MASK), 16);
+  MTG    = Shift (And (BYTESIZE (struct_mtget),         IOCPARM_MASK), 16);
+  DKO    = Shift (And (BYTESIZE (struct_dkop),          IOCPARM_MASK), 16);
+  DKG    = Shift (And (BYTESIZE (struct_dkget),         IOCPARM_MASK), 16);
+  DKA    = Shift (And (BYTESIZE (struct_dkacc),         IOCPARM_MASK), 16);
+  DEV    = Shift (And (BYTESIZE (struct_devget),        IOCPARM_MASK), 16);
+  
+but instead we use these *)
+
+  INT    = Shift (And (BYTESIZE (INTEGER),              IOCPARM_MASK), 16);
+  SG     = Shift (And (0,                               IOCPARM_MASK), 16);
+  TCHAR  = Shift (And (0,                               IOCPARM_MASK), 16);
+  LC     = Shift (And (0,                               IOCPARM_MASK), 16);
+  WS     = Shift (And (0,                               IOCPARM_MASK), 16);
+  TIO    = Shift (And (0,                               IOCPARM_MASK), 16);
+  IOS    = Shift (And (0,                               IOCPARM_MASK), 16);
+  RTE    = Shift (And (0,                               IOCPARM_MASK), 16);
+  IFR    = Shift (And (0,                               IOCPARM_MASK), 16);
+  IFC    = Shift (And (0,                               IOCPARM_MASK), 16);
+  CTR    = Shift (And (0,                               IOCPARM_MASK), 16);
+  IFD    = Shift (And (0,                               IOCPARM_MASK), 16);
+  ARP    = Shift (And (0,                               IOCPARM_MASK), 16);
+  IFS    = Shift (And (0,                               IOCPARM_MASK), 16);
+  SOL    = Shift (And (0,                               IOCPARM_MASK), 16);
+  RES    = Shift (And (0,                               IOCPARM_MASK), 16);
+  LAU    = Shift (And (0,                               IOCPARM_MASK), 16);
+  LAI    = Shift (And (0,                               IOCPARM_MASK), 16);
+  LTA    = Shift (And (0,                               IOCPARM_MASK), 16);
+  PT     = Shift (And (0,                               IOCPARM_MASK), 16);
+  EL     = Shift (And (0,                               IOCPARM_MASK), 16);
+  MTO    = Shift (And (0,                               IOCPARM_MASK), 16);
+  MTG    = Shift (And (0,                               IOCPARM_MASK), 16);
+  DKO    = Shift (And (0,                               IOCPARM_MASK), 16);
+  DKG    = Shift (And (0,                               IOCPARM_MASK), 16);
+  DKA    = Shift (And (0,                               IOCPARM_MASK), 16);
+  DEV    = Shift (And (0,                               IOCPARM_MASK), 16);
+  
+CONST (* the tty i/o controls *)
+  TC = Shift (ORD ('t'), 8);
+
+  TIOCGETD = Or (Or (R, INT), Or (TC, 0));      (* get line discipline *)
+  TIOCSETD = Or (Or (W, INT), Or (TC, 1));      (* set line discipline *)
+    OTTYDISC =   16_00;         (* Old, v7 std tty driver       *)
+    NETLDISC =   16_01;         (* Line discipline for berk net *)
+    NTTYDISC =   16_02;         (* New tty discipline           *)
+    TABLDISC =   16_03;         (* Hitachi tablet discipline    *)
+    NTABLDISC =  16_04;         (* Gtco tablet discipline       *)
+    HCLDISC =    16_05;         (* Half cooked discipline       *)
+    TERMIODISC = 16_06;         (* termio line discipline       *)
+    SLPDISC =    16_07;         (* BSD Serial Line IP           *)
+        (* Line disc #'s 16-23 are reserved for local extension.*)
+  TIOCHPCL = Or (NOARG,       Or (TC, 2));      (* hangup on last close *)
+  TIOCMODG = Or (Or (R, INT), Or (TC, 3));      (* get modem control state *)
+  TIOCMODS = Or (Or (R, INT), Or (TC, 4));      (* set modem control state *)
+    TIOCM_LE =  16_001;         (* line enable *)
+    TIOCM_DTR = 16_002;         (* data terminal ready *)
+    TIOCM_RTS = 16_004;         (* request to send *)
+    TIOCM_ST  = 16_008;         (* secondary transmit *)
+    TIOCM_SR =  16_010;         (* secondary receive *)
+    TIOCM_CTS = 16_020;         (* clear to send *)
+    TIOCM_CAR = 16_040;         (* carrier detect *)
+    TIOCM_CD =  TIOCM_CAR;
+    TIOCM_RNG = 16_080;         (* ring *)
+    TIOCM_RI =  TIOCM_RNG;
+    TIOCM_DSR = 16_100;         (* data set ready *)
+  TIOCGETP =  Or (Or (R, SG),  Or (TC,  8));    (* get tty params *)
+  TIOCSETP =  Or (Or (W, SG),  Or (TC,  9));    (* set tty params *)
+  TIOCSETN =  Or (Or (W, SG),  Or (TC, 10));    (* no flush tty *)
+  TIOCEXCL =  Or (NOARG,       Or (TC, 13));    (* set exclusive use of tty *)
+  TIOCNXCL =  Or (NOARG,       Or (TC, 14));    (* reset exclus. use of tty *)
+  TIOCFLUSH = Or (Or (W, INT), Or (TC, 16));    (* flush buffers *)  
+  TIOCSETC =  Or (Or (W, TC),  Or (TC, 17));    (* set special chars *)
+  TIOCGETC =  Or (Or (R, TC),  Or (TC, 18));    (* get special chars *)
+
+
+    TANDEM = 16_0001;           (* send stopc on output q. full *)
+    CBREAK = 16_0002;           (* half-cooked mode *)
+
+
+  (* locals, from 127 down *)
+
+  TIOCLBIS = Or (Or (W, INT), Or (TC, 127));    (* bis local mode bits *)
+  TIOCLBIC = Or (Or (W, INT), Or (TC, 126)); (* bic local mode bits *)
+  TIOCLSET = Or (Or (W, INT), Or (TC, 125)); (* set local modes *)
+  TIOCLGET = Or (Or (R, INT), Or (TC, 124)); (* get local modes *)
+    CRTBS =	Shift (1, 16); 	(* Do backspacing for crt	*)
+    PRTERA =	Shift (1, 17); 	(* \ ... / erase		*)
+    CRTERA =	Shift (1, 18); 	(* " \b " to wipe out char	*)
+    TILDE =	Shift (1, 19); 	(* Hazeltine tilde kludge	*)
+    MDMBUF =	Shift (1, 20); 	(* Start/stop output on c.intr. *)
+    LITOUT =	Shift (1, 21); 	(* Literal output		*)
+    TOSTOP =	Shift (1, 22); 	(* SIGSTOP on background output *)
+    FLUSHO =	Shift (1, 23); 	(* Flush output to terminal	*)
+    NOHANG =	Shift (1, 24); 	(* No SIGHUP on carrier drop	*)
+    AUTOFLOW =	Shift (1, 25); 	(* IAUTO hardware start/stop	*)
+    CRTKIL =	Shift (1, 26); 	(* Kill line with " \b "	*)
+    PASS8 =	Shift (1, 27); 	(* Allow 8-bit with canonical   *)
+    CTLECH =	Shift (1, 28); 	(* Echo control chars as ^X	*)
+    PENDIN =	Shift (1, 29); 	(* tp->t_rawq needs reread	*)
+    DECCTQ =	Shift (1, 30); 	(* Only ^Q starts after ^S	*)
+    BNOFLSH =	Shift (1, 31); 	(* No output flush on signal	*)
+    LCRTBS =    Shift (CRTBS, -16);
+    LPRTERA =   Shift (PRTERA, -16);
+    LCRTERA =   Shift (CRTERA, -16);
+    LTILDE =    Shift (TILDE, -16);
+    LMDMBUF =   Shift (MDMBUF, -16);
+    LLITOUT =   Shift (LITOUT, -16);
+    LTOSTOP =   Shift (TOSTOP, -16);
+    LFLUSHO =   Shift (FLUSHO, -16);
+    LNOHANG =   Shift (NOHANG, -16);
+    LAUTOFLOW = Shift (AUTOFLOW, -16);
+    LCRTKIL =   Shift (CRTKIL, -16);
+    LPASS8 =    Shift (PASS8, -16);
+    LCTLECH =   Shift (CTLECH, -16);
+    LPENDIN =   Shift (PENDIN, -16);
+    LDECCTQ =   Shift (DECCTQ, -16);
+    LBNOFLSH =  Shift (BNOFLSH, -16);
+  TIOCSBRK =  Or (NOARG,       Or (TC, 123)); (* set break bit *)
+  TIOCCBRK =  Or (NOARG,       Or (TC, 122)); (* clear break bit *)
+  TIOCSDTR =  Or (NOARG,       Or (TC, 121)); (* set data term. ready *)
+  TIOCCDTR =  Or (NOARG,       Or (TC, 120)); (* clear data term. ready *)
+  TIOCGPGRP = Or (Or (R, INT), Or (TC, 119)); (* get pgrp of tty *)
+  TIOCSPGRP = Or (Or (W, INT), Or (TC, 118)); (* set pgrp of tty *)
+  TIOCSLTC  = Or (Or (R, LC),  Or (TC, 117)); (* set loc. sp. chars *)
+  TIOCGLTC  = Or (Or (R, LC),  Or (TC, 116)); (* get loc. sp. chars *)
+  TIOCOUTQ =  Or (Or (R, INT), Or (TC, 115)); (* output queue size *)
+  TIOCSTI =   Or (Or (W, INT), Or (TC, 114)); (* simulate term. input *)
+  TIOCNOTTY = Or (NOARG,       Or (TC, 113)); (* void tty association *)
+  TIOCPKT =   Or (Or (W, INT), Or (TC, 112)); (* Pty: setclr. p. mode *)
+    TIOCPKT_DATA  =      16_00;     (* Data packet *)
+    TIOCPKT_FLUSHREAD =  16_01;     (* Flush packet *)
+    TIOCPKT_FLUSHWRITE = 16_02;     (* Flush packet *)
+    TIOCPKT_STOP =       16_04;     (* Stop output *)
+    TIOCPKT_START =      16_08;     (* Start output *)
+    TIOCPKT_NOSTOP =     16_10;     (* No more ^S, ^Q *)
+    TIOCPKT_DOSTOP =     16_20;     (* Now do ^S ^Q *)
+    TIOCPKT_IOCTL =      16_40;     (* Wake up if change term char. *)
+    
+  TIOCSTOP =    Or (NOARG,       Or (TC, 111)); (* Stop output, like ^S *)
+  TIOCSTART =   Or (NOARG,       Or (TC, 110)); (* Start out., like ^Q  *)
+  TIOCMSET =    Or (Or (W, INT), Or (TC, 109)); (* Set all modem bits   *)
+  TIOCMBIS =    Or (Or (W, INT), Or (TC, 108)); (* Bis modem bits       *)
+  TIOCMBIC =    Or (Or (W, INT), Or (TC, 107)); (* Bic modem bits       *)
+  TIOCMGET =    Or (Or (R, INT), Or (TC, 106)); (* Get all modem bits   *)
+  TIOCREMOTE =  Or (Or (W, INT), Or (TC, 105)); (* Remote input editing *)
+  TIOCGWINSZ =  Or (Or (R, WS),  Or (TC, 104)); (* Get win. sz. *)
+  TIOCSWINSZ =  Or (Or (W, WS),  Or (TC, 103)); (* Set win. sz. *)
+  TIOCUCNTL =   Or (Or (W, INT), Or (TC, 102)); (* Pty: set/clr u.c.mode*)
+  TIOCSMLB =    Or (NOARG,       Or (TC, 101)); (* Turn on loopback mode*)
+  TIOCCMLB =    Or (NOARG,       Or (TC, 100)); (* Turn off loop. mode  *)
+  TIOCNMODEM =  Or (Or (W, INT), Or (TC, 99)); (* Ignore modem status   *)
+  TIOCMODEM =   Or (Or (W, INT), Or (TC, 98)); (* Look at modem status *)
+  TIOCWONLINE = Or (NOARG,       Or (TC, 97)); (* Wait on online device*)
+  TIOCNCAR =    Or (NOARG,       Or (TC, 96)); (* Ignore soft carrier   *)
+  TIOCCAR =     Or (NOARG,       Or (TC, 95)); (* Don't ignore s. car. *)
+  TCSBRK =      Or (NOARG,       Or (TC, 94)); (* Flush q's w/ cnd. brk*)
+  TCXONC =      Or (NOARG,       Or (TC, 93)); (* Start/stop control    *)
+  TCFLSH =      Or (NOARG,       Or (TC, 92)); (* Cnd. q flushing       *)
+  TCGETA =      Or (Or (R, TIO), Or (TC, 91)); (* Get parameters        *)
+  TCSETA =      Or (Or (W, TIO), Or (TC, 90)); (* Set parameters        *)
+  TCSETAW =     Or (Or (W, TIO), Or (TC, 89)); (* Drain & set           *)
+  TCSETAF =     Or (Or (W, TIO), Or (TC, 88)); (* Drain, flush, & set   *)
+  TIOCMASTER =  Or (Or (W, INT), Or (TC, 87)); (* master ctrls flags   *)
+  TIOAUTO =     Or (NOARG,       Or (TC, 86)); (* Autoflow status       *)
+  TIOCSINUSE =  FIOSINUSE;              (* Test and set mutex   *)
+  TIOCCINUSE =  FIOCINUSE;              (* Clear mutex          *)
+  
+  TCGETP =     Or (Or (R, IOS), Or (TC, 85));    (* Get parameters      *)
+  TCSANOW =    Or (Or (W, IOS), Or (TC, 84));    (* Set parameters      *)
+  TCSADRAIN =  Or (Or (W, IOS), Or (TC, 83)); (* Drain & set            *)
+  TCSADFLUSH = Or (Or (W, IOS), Or (TC, 82)); (* Drain, flush, & set    *)
+
+
+  (* File i/o controls *)
+  FC = Shift (ORD ('f'), 8);
+
+  FIOCLEX =   Or (NOARG,       Or (FC,   1));  (* Set exclusive use on fd*)
+  FIONCLEX =  Or (NOARG,       Or (FC,   2));  (* Remove exclusive use   *)
+  FIOSINUSE = Or (NOARG,       Or (FC,   3));  (* Test & set IINUSE in inode *)
+  FIOCINUSE = Or (NOARG,       Or (FC,   4));  (* Clear mutex            *)
+  FIONREAD =  Or (Or (R, INT), Or (FC, 127)); (* Get # bytes to read    *)
+  FIONBIO =   Or (Or (W, INT), Or (FC, 126)); (* Set/clear non-bl.i/o *)
+  FIOASYNC =  Or (Or (W, INT), Or (FC, 125)); (* Set/clear async i/o    *)
+  FIOSETOWN = Or (Or (W, INT), Or (FC, 124)); (* Set owner              *)
+  FIOGETOWN = Or (Or (R, INT), Or (FC, 123)); (* Get owner              *)
+  FIONBUF =   Or (Or (W, INT), Or (FC, 122)); (* N_buff i/o buf *)
+  FIONONBUF = Or (NOARG,       Or (FC, 121)); (* N_buff i/o on buf      *)
+  FIONBDONE = Or (Or (W, INT), Or (FC, 120)); (* N_buff i/o done buf    *)
+
+  (* Socket i/o controls *)
+  SC = Shift (ORD ('s'), 8);
+  RC = Shift (ORD ('r'), 8);
+  IC = Shift (ORD ('i'), 8);
+
+  SIOCSHIWAT =     Or (Or (W, INT),  Or (SC,  0));  (* Set high watermark *)
+  SIOCGHIWAT =     Or (Or (R, INT),  Or (SC,  1));  (* Get high watermark *)
+  SIOCSLOWAT =     Or (Or (W, INT),  Or (SC,  2));  (* Set low watermark  *)
+  SIOCGLOWAT =     Or (Or (R, INT),  Or (SC,  3));  (* Get low watermark  *)
+  SIOCATMARK =     Or (Or (R, INT),  Or (SC,  7));  (* At oob mark?       *)
+  SIOCSPGRP =      Or (Or (W, INT),  Or (SC,  8));  (* Set process group  *)
+  SIOCGPGRP =      Or (Or (R, INT),  Or (SC,  9));  (* Get process group  *)
+  SIOCADDRT =      Or (Or (W, RTE),  Or (RC, 10));  (* Add route  *)
+  SIOCDELRT =      Or (Or (W, RTE),  Or (RC, 11));  (* Delete route *)
+  SIOCSIFADDR =    Or (Or (W, IFR),  Or (IC, 12));  (* Set ifnet ad.*)
+  SIOCGIFADDR =    Or (Or (RW, IFR), Or (IC, 13));  (*  Get ifnet ad.*)
+  SIOCSIFDSTADDR = Or (Or (W, IFR),  Or (IC, 14));  (* Set p-p addr.*)
+  SIOCGIFDSTADDR = Or (Or (RW, IFR), Or (IC, 15));  (* Get p-p addr.*)
+  SIOCSIFFLAGS =   Or (Or (W, IFR),  Or (IC, 16));  (* Set ifnet fl.*)
+  SIOCGIFFLAGS =   Or (Or (RW, IFR), Or (IC, 17));  (* Get ifnet fl.*)
+  SIOCGIFBRDADDR = Or (Or (RW, IFR), Or (IC, 18));  (*  Get broad.ad.*)
+  SIOCSIFBRDADDR = Or (Or (W, IFR),  Or (IC, 19));  (* Set broad.ad.*)
+  SIOCGIFCONF =    Or (Or (RW, IFC), Or (IC, 20));  (*  Get ifnet ls.*)
+  SIOCGIFNETMASK = Or (Or (RW, IFR), Or (IC, 21));  (*  Get n.a.mask *)
+  SIOCSIFNETMASK = Or (Or (W, IFR),  Or (IC, 22));  (* Set n.a.mask *)
+  SIOCSPHYSADDR =  Or (Or (RW, IFR), Or (IC, 23));  (*  Set phys. ad.*)
+  SIOCADDMULTI =   Or (Or (RW, IFR), Or (IC, 24));  (*  Add m.c. ad. *)
+  SIOCDELMULTI =   Or (Or (RW, IFR), Or (IC, 25));  (*  Dele. m.c.ad.*)
+  SIOCRDCTRS =     Or (Or (RW, CTR), Or (IC, 26));  (*  Read if cntr.*)
+  SIOCRDZCTRS =    Or (Or (RW, CTR), Or (IC, 27));  (*  Read/0 if c. *)
+  SIOCRPHYSADDR =  Or (Or (RW, IFD), Or (IC, 28));  (*  Read phy. ad.*)
+  SIOCSARP =       Or (Or (W, ARP),  Or (IC, 30));  (* Set arp entry *)
+  SIOCGARP =       Or (Or (RW, ARP), Or (IC, 31));  (* Get arp entry *)
+  SIOCDARP =       Or (Or (W, ARP),  Or (IC, 32));  (* Del. arp ent. *)
+  SIOCENABLBACK =  Or (Or (W, IFR),  Or (IC, 33));  (* Set in.ex.lb. *)
+  SIOCDISABLBACK = Or (Or (W, IFR),  Or (IC, 34));  (* Cl.in.ex.lpb. *)
+  SIOCSTATE =      Or (Or (RW, IFS), Or (IC, 35));  (*  Device state *)
+  LIOCSOL =        Or (Or (RW, SOL), Or (IC, 36));  (*  send solicit msg *)
+  LIOCRES =        Or (Or (RW, RES), Or (IC, 37));  (*  get response msg *)
+  LIOCCMD =        Or (Or (RW, LAU), Or (IC, 38));  (*  send command msg *)
+  LIOCINI =        Or (Or (RW, LAI), Or (IC, 39));  (*  lat tty init *)
+  SIOCARPREQ =     Or (Or (RW, IFR), Or (IC, 40));  (*  arp request pkt *)
+  SIOCGIFMETRIC =  Or (Or (RW, IFR), Or (IC, 41));  (* get IF metric *)
+  SIOCSIFMETRIC =  Or (Or (W, IFR),  Or (IC, 42));  (* set IF metric *)
+  LIOCTTYI =       Or (Or (R, LTA),  Or (IC, 43));  (* lat tty info *)
+
+
+  (* Disk partition table i/o controls *)
+  PC = Shift (ORD ('p'), 8);
+
+  DIOCGETPT = Or (Or (R, PT), Or (PC, 1));   (* Get disk paritition  *)
+  DIOCSETPT = Or (Or (W, PT), Or (PC, 2));   (* Set disk paritition  *)
+  DIOCDGTPT = Or (Or (R, PT), Or (PC, 3));   (* Get default disk par. *)
+
+  (* Error logging i/o controls *)
+  EC = Shift (ORD ('e'), 8);
+
+  ELSETPID =  Or (Or (RW, EL),  Or (EC, 0));  (* Set proc. id. *)
+  ELGETPID =  Or (Or (R, INT),  Or (EC, 1));  (* Get proc. id. *)
+  ELMOVPTR =  Or (Or (W, INT),  Or (EC, 2));  (* Update elpts. *)
+  ELREINIT =  Or (NOARG,        Or (EC, 3));  (* Reinit elbuf  *)
+  ELCLRPID =  Or (NOARG,        Or (EC, 4));  (* Clr. proc.id. *)
+  ELWARNOFF = Or (NOARG,        Or (EC, 5));  (* disable warn. *)
+  ELWARNON =  Or (NOARG,        Or (EC, 6));  (* disable warn. *)
+  ELGETTIME = Or (Or (R, INT),  Or (EC, 7));  (* Get strt time *)
+
+  (* Tape i/o controls *)
+  MC = Shift (ORD ('m'), 8);
+
+  MTIOCTOP = Or (Or (W, MTO), Or (MC, 1));              (* Do a tape op. *)
+  MTIOCGET = Or (Or (R, MTG), Or (MC, 2));              (* Get status   *)
+
+  (* Disk i/o controls *)
+  DC = Shift (ORD ('d'), 8);
+
+  DKIOCHDR = Or (NOARG,        Or (DC, 1));             (* Header r/w   *)
+  DKIOCDOP = Or (Or (W, DKO),  Or (DC, 2));             (* Do a disk op. *)
+  DKIOCGET = Or (Or (R, DKG),  Or (DC, 3));             (* Get status   *)
+  DKIOCACC = Or (Or (RW, DKA), Or (DC, 4));             (* Disk access  *)
+
+  (* Generic device information i/o controls *)
+  VC = Shift (ORD ('v'), 8);
+
+  DEVIOCGET = Or (Or (R, DEV), Or (VC, 1));             (* Get dev.info. *)
+
+
+
+CONST
+  R_OK = 8_4;
+  W_OK = 8_2;
+  X_OK = 8_1;
+  F_OK = 8_0;
+
+(* Somebody will have to work really hard to get all those ioctl
+   parameters right. Beware when using them! *)
+<*EXTERNAL *> PROCEDURE ioctl (d: int; request: u_long; 
+                                         argp: ADDRESS): int;
+(* ok *)
+
+(*** link - link to a file ***)
+<*EXTERNAL*> PROCEDURE link (name1, name2: char_star): int;
+(* ok *)
+
+(*** lseek, tell - move read/write pointer ***)
+CONST (* whence *)
+  L_SET  = 0;
+  L_INCR = 1;
+  L_XTND = 2;
+
+<*EXTERNAL*>
+ PROCEDURE lseek (d: int; offset: off_t; whence: int): off_t;
+(* ok *)
+
+(*** mkfifo - make a FIFO (named pipe) ***)
+<*EXTERNAL*> PROCEDURE mkfifo (path: char_star; mode: mode_t): int;
+
+(*** mkdir - make a directory file ***)
+<*EXTERNAL*> PROCEDURE mkdir (path: char_star; mode: mode_t): int;
+(* ok *)
+
+(*** mknod - make a directory or a special file ***)
+CONST (* mode *)
+  fifo_special =               8_010000;
+  character_special =          8_020000;
+  directory =                  8_040000;
+  block_special =              8_060000;
+  ordinary_file =              8_000000;
+  ordinary_filea =             8_100000;
+  regular_file =               8_100000;
+  symbolic_link =              8_120000;
+  socket =                     8_140000;
+  set_uid_on_exec =            8_004000;
+  set_gid_on_exec =            8_002000;
+  save_text_image_after_exec = 8_001000;
+
+  (* lower bits used for the access permissions *)
+
+<*EXTERNAL*> PROCEDURE mknod (path: char_star; mode: mode_t; dev: dev_t): int;
+(* ok *)
+
+(*** mount, umount - mount or unmount a file system ***)
+CONST (* rwflag *)
+  writable = 0;
+  write_protected = 1;
+
+<*EXTERNAL*> PROCEDURE mount (type: int;
+                              dir: char_star; flags: int; 
+                              data: ADDRESS): int;
+(* ok *)
+
+<*EXTERNAL*> PROCEDURE unmount (dir: char_star; flags: int): int;
+(* ok *)
+
+
+(*** open - open for reading or writing ***)
+CONST (* flags *)
+  O_RDONLY =    8_0;            (* open for reading *)
+  O_WRONLY =    8_1;            (* open for writing *)
+  O_RDWR   =    8_2;            (* open for read & write *)
+  O_CREAT  =    FCREAT;         (* open with file create *)
+  O_EXCL   =    FEXCL;          (* error on create if file exists *)
+  O_NOCTTY =    8_000;
+  O_TRUNC  =    FTRUNC;         (* open with truncation *)
+  O_APPEND =    FAPPEND;        (* append on each write *)
+  O_NONBLOCK =  FNBLOCK;        (* POSIX non-blocking I/O *)
+  O_NDELAY =    FNDELAY;        (* non-blocking open *)
+  O_FSYNC =     FSYNCRON;       (* syncronous write *)
+
+  M3_NONBLOCK = O_NONBLOCK;  (* -1 => would block, 0 => EOF *)
+
+<*EXTERNAL*> PROCEDURE open (name: char_star; 
+                             flags, mode: int): int;
+(* ok *)
+
+(*** pipe - create an interprocess channel ***)
+CONST
+  readEnd = 0;
+  writeEnd = 1;
+<*EXTERNAL*> PROCEDURE pipe (VAR fildes: ARRAY [0..1] OF int): int;
+(* ok *)
+
+(* not implemented
+(*** plock - lock process, text, or data in memory ***)
+CONST (* op *)
+  UNLOCK =   0;         (* unlock all segments *)
+  PROCLOCK = 1;         (* lock text and data into memory *)
+  TXTLOCK =  2;         (* lock text segment only *)
+  DATLOCK =  4;         (* lock data segment ony *)
+<*EXTERNAL*> PROCEDURE plock (op: int): int;
+*)
+
+(*** profil - execution time profile ***)
+<*EXTERNAL*> PROCEDURE profil (buff: ADDRESS; 
+                               size, offset, scale: int): int;
+(* ok *)
+
+(*** ptrace - process trace ***)
+<*EXTERNAL*> PROCEDURE ptrace (request: int; pid: pid_t;
+                               addr: ADDRESS;
+                               data: int): int;
+(* ok *)
+
+(*** readlink - read value of a symbolic link ***)
+<*EXTERNAL*> PROCEDURE readlink (path: char_star; buf: ADDRESS; bufsize: int): int;
+(* ok *)
+
+(*** reboot - reboot system or halt processor ***)
+CONST (* howto *)
+  RB_HALT =    16_8;            (* dont' reboot, just halt *)
+  RB_ASKNAME = 16_1;            (* ask for file name to reboot from *)
+  RB_SINGLE =  16_2;            (* reboot to single user only *)
+  RB_AUTOREBOOT = 16_0;         (* flag for system auto-booting itself *)
+
+<*EXTERNAL*> PROCEDURE reboot (howto: int): int;
+(* ok *)
+
+(*** rename - change the name of a file ***)
+<*EXTERNAL*> PROCEDURE rename (from, to: char_star): int;
+(* ok *)
+
+(*** rmdir - remove a directory file ***)
+<*EXTERNAL*> PROCEDURE rmdir (path: char_star): int;
+(* ok *)
+
+(*** select - synchronous I/O mutiplexing ***)
+CONST
+  MAX_FDSET = 256;
+
+TYPE
+  FDSet = SET OF [0 .. MAX_FDSET - 1];
+
+<*EXTERNAL*> PROCEDURE select (nfds: int;
+               readfds, writefds, exceptfds: UNTRACED REF FDSet;
+               timeout: UNTRACED REF struct_timeval): int;
+(* ok *)
+
+(*** setgroups - set group access list ***)
+<*EXTERNAL*> PROCEDURE setgroups (ngroups: int; VAR gidset: int): int;
+(* ok *)
+
+(* not implemented
+(*** setquota - enable/disable quotas on a file system ***)
+<*EXTERNAL*> PROCEDURE setquota (special, file: char_star): int;
+*)
+
+(*** shutdown - shut down full-duplex connection ***)
+<*EXTERNAL*> PROCEDURE shutdown (s, how: int): int;
+(* ok *)
+
+(*** swapon - add a swap device for interleaved paging/swapping ***)
+<*EXTERNAL*> PROCEDURE swapon (special: char_star): int;
+(* ok *)
+
+(*** symlink - make symbolic link to a file ***)
+<*EXTERNAL*> PROCEDURE symlink (name1, name2: char_star): int;
+(* ok *)
+
+(*** sync - update super-block ***)
+<*EXTERNAL*> PROCEDURE sync ();
+(* ok *)
+
+(*** truncate, ftruncate - truncate a file to a specified length ***)
+<*EXTERNAL*> 
+   PROCEDURE truncate (path: char_star; length: off_t): int;
+<*EXTERNAL*> 
+   PROCEDURE ftruncate (fd, length: off_t): int;
+(* ok *)
+
+(* not implemented 
+(*** ulimit - get and set user limits ***)
+<*EXTERNAL*> PROCEDURE ulimit (cmd: int; newlimit: long): long;
+*)
+
+(*** umask - set file creation mask ***)
+<*EXTERNAL*> PROCEDURE umask (numask: mode_t): mode_t;
+(* ok *)
+
+(*** unlink - remove directory entry ***)
+<*EXTERNAL*> PROCEDURE unlink (path: char_star): int;
+(* ok *)
+
+(*** utimes - set file times ***)
+<*EXTERNAL*> PROCEDURE utimes (file: char_star;
+                    tvp: UNTRACED REF ARRAY [0..1] OF struct_timeval): int;
+(* ok *)
+
+(*** vfork - spawn new process in a virtual memory efficient way ***)
+<*EXTERNAL*> PROCEDURE vfork (): int;
+(* ok *)
+
+(* not implemented, obsolete
+(*** vhangup - virtually hang up the current control terminal ***)
+<*EXTERNAL*> PROCEDURE vhangup (): int;
+*)
+
+(* not implemented
+(*** rexec(3x) - return stream to a remote command ***)
+<*EXTERNAL*> PROCEDURE rexec (VAR ahost: char_star; 
+                              inport: u_short;
+                              user, passwd, cmd: char_star;
+                              fd2p: int_star): int;
+*)
+
+(*** isatty(3) ***)
+<*EXTERNAL*> PROCEDURE isatty (filedes: int): int;
+(* ok *)
+
+(*** system(3) ***)
+<*EXTERNAL*> PROCEDURE system (string: char_star): int;
+(* ok *)
+
+
+END Unix.
Index: libs/m3core/src/unix/freebsd-4.amd64/Usignal.i3
--- libs/m3core/src/unix/freebsd-4.amd64/Usignal.i3	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/unix/freebsd-4.amd64/Usignal.i3	Mon Feb 16 21:21:14 2004
@@ -0,0 +1,235 @@
+(* Copyright (C) 1990, Digital Equipment Corporation.         *)
+(* All rights reserved.                                       *)
+(* See the file COPYRIGHT for a full description.             *)
+(*                                                            *)
+(*      modified on Sat Apr 16 by rrw1000@hermes.cam.ac.uk    *)
+(*      modified on Tue Mar  2 17:18:02 PST 1993 by muller    *)
+(* ow 03.10.1994 *)
+
+INTERFACE Usignal;
+
+FROM Ctypes IMPORT int, unsigned_int, long;
+FROM Uucontext IMPORT sigset_t;
+
+(*** <signal.h> ***)
+
+CONST
+  SIGHUP    =  1;      (* hangup *)
+  SIGINT    =  2;      (* interrupt *)
+  SIGQUIT   =  3;      (* quit *)
+  SIGILL    =  4;      (* illegal instruction (not reset when caught) *)
+  SIGTRAP   =  5;      (* trace trap (not reset when caught) *)
+  SIGIOT    =  6;      (* IOT instruction *)
+  SIGEMT    =  7;      (* EMT instruction *)
+  SIGFPE    =  8;      (* floating point exception *)
+      FPE_INTOVF_TRAP      =  1;  (* integer overflow *)
+      FPE_INTDIV_TRAP      =  2;  (* integer divide by zero *)
+      FPE_FLTDIV_TRAP      =  3;  (* floating/decimal divide by zero *)
+      FPE_FLTOVF_TRAP      =  4;  (* floating overflow *)
+      FPE_FLTUND_TRAP      =  5;  (* floating underflow *)
+      FPE_FPU_NP_TRAP      =  6;  (* floating point unit not present *)
+      FPE_SUBRNG_TRAP      =  7;  (* subrange out of bounds *)
+  SIGKILL   =  9;      (* kill (cannot be caught or ignored) *)
+  SIGBUS    =  10;     (* bus error *)
+      BUS_PAGE_FAULT       = 12;  (* page fault protection base *)
+      BUS_SEGNP_FAULT      = 26;  (* segment not present *)
+      BUS_STK_FAULT        = 27;  (* stack fault *)
+  SIGSEGV   =  11;     (* segmentation violation *)
+  SIGSYS    =  12;     (* bad argument to system call *)
+  SIGPIPE   =  13;     (* write on a pipe with no one to read it *)
+  SIGALRM   =  14;     (* alarm clock *)
+  SIGTERM   =  15;     (* software termination signal from kill *)
+  SIGURG    =  16;     (* urgent condition on IO channel *)
+  SIGSTOP   =  17;     (* sendable stop signal not from tty *)
+  SIGTSTP   =  18;     (* stop signal from tty *)
+  SIGCONT   =  19;     (* continue a stopped process *)
+  SIGCHLD   =  20;     (* to parent on child stop or exit *)
+  SIGTTIN   =  21;     (* to readers pgrp upon background tty read *)
+  SIGTTOU   =  22;     (* like TTIN for output if (tp->t_local&LTOSTOP) *)
+  SIGIO     =  23;     (* input/output possible signal *)
+  SIGXCPU   =  24;     (* exceeded CPU time limit *)
+  SIGXFSZ   =  25;     (* exceeded file size limit *)
+  SIGVTALRM =  26;     (* virtual time alarm *)
+  SIGPROF   =  27;     (* profiling time alarm *)
+  SIGWINCH  =  28;     (* window size changes *)
+  SIGINFO   =  29;     (* information request *)
+  SIGUSR1   =  30;     (* user defined signal 1 *)
+  SIGUSR2   =  31;     (* user defined signal 2 *)
+
+  (* System V definitions *)
+  SIGCLD    = SIGCHLD;
+  SIGABRT   = SIGIOT;
+
+
+(* Signal vector "template" used in sigaction call. *)
+TYPE
+  SignalHandler = PROCEDURE (sig, code: int;
+                             scp: UNTRACED REF struct_sigcontext);
+
+  struct_sigvec  = RECORD
+    sv_handler: SignalHandler;     (* signal handler *)
+    sv_mask:    int;               (* signal mask to apply *)
+    sv_flags:   int;               (* see signal options below *)
+  END;
+    
+
+CONST
+  empty_sigset_t = sigset_t{ 0, .. };
+  empty_sv_mask  : int = 0;
+
+CONST
+ (* Valid flags defined for sv_flags field of sigvec structure. *)
+  SV_ONSTACK     = 16_0001;   (* run on special signal stack *)
+  SV_RESTART     = 16_0002;   (* restart system calls on sigs *)
+  SV_RESETHAND   = 16_0004;   (* reset to SIG_DFL when taking signal *)
+  SV_NOCLDSTOP   = 16_0008;   (* do not generate SIGCHLD on child stop *)
+  SV_NODEFER     = 16_0010;   (* don't mask the signal we're delivering *)
+
+  (* Defines for sigprocmask() call. POSIX. *)
+  SIG_BLOCK    = 1;    (* Add these signals to block mask *)
+  SIG_UNBLOCK  = 2;    (* Remove these signals from block mask *)
+  SIG_SETMASK  = 3;    (* Set block mask to this mask *)
+
+TYPE
+  struct_sigaction = RECORD
+    sa_handler  : SignalHandler;        (* signal handler *)
+    sa_flags    : int;                  (* signal action flags *)
+    sa_mask     : sigset_t;             (* signals to block while in handler *)
+  END;
+
+  struct_sigaction_star = UNTRACED REF struct_sigaction;
+
+CONST
+ (* Valid flags defined for sa_flags field of sigaction structure. *)
+  SA_ONSTACK     = 16_0001;   (* run on special signal stack *)
+  SA_RESTART     = 16_0002;   (* restart system calls on sigs *)
+  SA_RESETHAND   = 16_0004;   (* reset to SIG_DFL when taking signal *)
+  SA_NOCLDSTOP   = 16_0008;   (* do not generate SIGCHLD on child stop *)
+  SA_NODEFER     = 16_0010;   (* don't mask the signal we're delivering *)
+
+TYPE
+  struct_sigstack = RECORD 
+    ss_sp:      ADDRESS; (* signal stack pointer *)
+    ss_onstack: int;     (* current status *)
+  END;
+
+(*
+ * Information pushed on stack when a signal is delivered.
+ * This is used by the kernel to restore state following
+ * execution of the signal handler.  It is also made available
+ * to the handler to allow it to properly restore state if
+ * a non-standard exit is performed.
+ *)
+
+TYPE
+  struct_sigcontext = RECORD
+    sc_mask    : sigset_t; (* signal mask to restore *)
+    sc_onstack : long;     (* sigstack state to restore *)
+    sc_rdi     : long;
+    sc_rsi     : long;
+    sc_rdx     : long;
+    sc_rcx     : long;
+    sc_r8      : long;
+    sc_r9      : long;
+    sc_rax     : long;
+    sc_rbx     : long;
+    sc_rbp     : long;
+    sc_r10     : long;
+    sc_r11     : long;     (* frame pointer *)
+    sc_r12     : long;
+    sc_r13     : long;
+    sc_r14     : long;
+    sc_r15     : long;
+    sc_trapno  : long;
+    sc_addr    : long;
+    sc_flags   : long;
+    sc_err     : long;
+    sc_rip     : long;     (* program counter *)
+    sc_cs      : long;
+    sc_rflags  : long;
+    sc_rsp     : long;     (* stack pinter *)
+    sc_ss      : long;
+    sc_len     : long;
+  END;
+
+(* Do not modifiy these variables *)
+VAR (*CONST*)
+  BADSIG, SIG_ERR, SIG_DFL, SIG_IGN, SIG_HOLD: SignalHandler;
+
+
+(* Convert a signal number to a mask suitable for sigblock(). *)
+<*INLINE*> PROCEDURE sigmask (n: int): int;
+
+
+(*** kill(2) - send signal to a process ***)
+
+<*EXTERNAL*> PROCEDURE kill (pid, sig: int): int;
+
+
+(*** killpg(2) - send signal to a process or process group ***)
+
+<*EXTERNAL*> PROCEDURE killpg (pgrp, sig: int): int;
+
+
+(*** sigblock(2) - block signals ***)
+
+<*EXTERNAL*> PROCEDURE sigblock (mask: int): int;
+
+
+(*** sigpause(2) - atomically release blocked signals and wait for
+                   interrupt ***)
+
+<*EXTERNAL*> PROCEDURE sigpause (sigmask: int): int;
+
+
+(*** sigpending(2) - examine pending signals ***)
+
+<*EXTERNAL*> PROCEDURE sigpending (VAR set: sigset_t): int;
+
+
+(*** sigsetmask(2) - set current signal mask ***)
+
+<*EXTERNAL*> PROCEDURE sigsetmask (mask: int): unsigned_int;
+
+
+(*** sigstack(2) - set and/or get signal stack context ***)
+
+(* FIXME - It is OK for ss and/or oss to be NIL, so we shouldn't use VAR *)
+<*EXTERNAL*> PROCEDURE sigstack (VAR ss, oss: struct_sigstack): int;
+
+(*** sigsuspend(2) - release blocked signals and wait for interrupt ***)
+
+<*EXTERNAL*>
+PROCEDURE sigsuspend (VAR sigmask: sigset_t): int;
+
+(*** sigaction(2) - software signal facilities ***)
+
+<*EXTERNAL*>
+PROCEDURE sigaction (sig: int;  act, oact: struct_sigaction_star): int;
+
+(*** sigvec(2) - software signal facilities ***)
+
+(* FIXME - It is OK for vec and/or ovec to be NIL, so we shouldn't use VAR *)
+<*EXTERNAL*>
+PROCEDURE sigvec (sig: int; VAR vec, ovec: struct_sigvec): int;
+
+(* FIXME - It is OK for vec and/or ovec to be NIL, so we shouldn't use VAR *)
+<*EXTERNAL*>
+PROCEDURE sigprocmask (how: int; VAR set, oldset: sigset_t) : int;
+
+<*EXTERNAL*>
+PROCEDURE sigemptyset (VAR set: sigset_t) : int;
+
+<*EXTERNAL*>
+PROCEDURE sigfillset (VAR set: sigset_t) : int;
+
+<*EXTERNAL*>
+PROCEDURE sigaddset (VAR set: sigset_t; signo: int) : int;
+
+<*EXTERNAL*>
+PROCEDURE sigdelset (VAR set: sigset_t; signo: int) : int;
+
+<*EXTERNAL*>
+PROCEDURE sigismember(VAR set: sigset_t; signo: int) : int;
+
+END Usignal.
Index: libs/m3core/src/unix/freebsd-4.amd64/Ustat.i3
--- libs/m3core/src/unix/freebsd-4.amd64/Ustat.i3	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/unix/freebsd-4.amd64/Ustat.i3	Mon Feb 16 21:21:14 2004
@@ -0,0 +1,95 @@
+(* Copyright (C) 1989, Digital Equipment Corporation           *)
+(* All rights reserved.                                        *)
+(* See the file COPYRIGHT for a full description.              *)
+(*                                                             *)
+(* Last modified on Wed Mar 15 16:47:47 PST 1995 by kalsow     *)
+(*      modified on Sat Feb 18 23:43:23 MET 1995 by ow         *)
+(*      modified on Tue Mar 24 20:42:39 PST 1992 by muller     *)
+
+INTERFACE Ustat;
+
+FROM Ctypes IMPORT int, char_star, long;
+FROM Utypes IMPORT u_short, u_long, dev_t, ino_t, off_t;
+FROM Utypes IMPORT mode_t, nlink_t, uid_t, gid_t, time_t, int32_t,
+  u_int32_t, int64_t;
+
+CONST
+  S_IFMT  : u_short = 8_0170000;
+  S_IFSOCK: u_short = 8_0140000;
+  S_IFLNK : u_short = 8_0120000;
+  S_IFREG : u_short = 8_0100000;
+  S_IFPIPE: u_short = 8_0000000; (* no such constant in stat.h!*)
+  S_IFBLK : u_short = 8_0060000;
+  S_IFDIR : u_short = 8_0040000;
+  S_IFCHR : u_short = 8_0020000;
+  S_IFIFO : u_short = 8_0010000;
+  S_IFPORT          = S_IFIFO;
+  S_ISUID : u_short = 8_0004000;
+  S_ISGID : u_short = 8_0002000;
+  S_ISVTX : u_short = 8_0001000;
+  S_IREAD : u_short = 8_0000400;
+  S_IWRITE: u_short = 8_0000200;
+  S_IEXEC : u_short = 8_0000100;
+  S_GREAD : u_short = 8_0000040;
+  S_GWRITE: u_short = 8_0000020;
+  S_GEXEC : u_short = 8_0000010;
+  S_OREAD : u_short = 8_0000004;
+  S_OWRITE: u_short = 8_0000002;
+  S_OEXEC : u_short = 8_0000001;
+
+TYPE
+  struct_stat = RECORD
+    st_dev       : dev_t;
+    st_ino       : ino_t;
+    st_mode      : mode_t;
+    st_nlink     : nlink_t;
+    st_uid       : uid_t;
+    st_gid       : gid_t;
+    st_rdev      : dev_t;
+    st_atime     : time_t;
+    st_atimensec : long;
+    st_mtime     : time_t;
+    st_mtimensec : long;
+    st_ctime     : time_t;
+    st_ctimensec : long;
+    st_size      : off_t;
+    st_blocks    : int64_t;
+    st_blksize   : u_int32_t;
+    st_flags     : u_int32_t;
+    st_gen       : u_int32_t;
+    st_lspare    : int32_t;
+    st_qspare1   : int64_t;
+    st_qspare2   : int64_t;
+  END;
+
+  struct_stat_star = UNTRACED REF struct_stat;
+
+<*EXTERNAL*> PROCEDURE stat (path: char_star; buf: struct_stat_star): int;
+
+<*EXTERNAL*> PROCEDURE lstat (path: char_star; buf: struct_stat_star): int;
+
+<*EXTERNAL*> PROCEDURE fstat (fd: int;  buf: struct_stat_star): int;
+
+(* chflags, fchflags *)
+CONST
+  (* Definitions of flags stored in file flags word. *)
+  (* Super-user and owner changeable flags. *)
+  UF_SETTABLE  = 16_0000ffff;      (* mask of owner changeable flags *)
+  UF_NODUMP    = 16_00000001;      (* do not dump file *)
+  UF_IMMUTABLE = 16_00000002;      (* file may not be changed *)
+  UF_APPEND    = 16_00000004;      (* writes to file may only append *)
+  UF_OPAQUE    = 16_00000008;      (* directory is opaque wrt. union *)
+
+  (* Super-user changeable flags. *)
+  SF_SETTABLE  = 16_ffff0000;      (* mask of superuser changeable flags *)
+  SF_ARCHIVED  = 16_00010000;      (* file is archived *)
+  SF_IMMUTABLE = 16_00020000;      (* file may not be changed *)
+  SF_APPEND    = 16_00040000;      (* writes to file may only append *)
+
+<*EXTERNAL*>
+PROCEDURE chflags(path: char_star; flags: u_long): int;
+
+<*EXTERNAL*>
+PROCEDURE fchflags(fd: int; flags: u_long): int;
+
+END Ustat.
Index: libs/m3core/src/unix/freebsd-4.amd64/Utypes.i3
--- libs/m3core/src/unix/freebsd-4.amd64/Utypes.i3	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/unix/freebsd-4.amd64/Utypes.i3	Mon Feb 16 21:21:15 2004
@@ -0,0 +1,116 @@
+(* Copyright (C) 1994, Digital Equipment Corporation.         *)
+(* All rights reserved.                                       *)
+(* See the file COPYRIGHT for a full description.             *)
+(*                                                            *)
+(* Last modified on Sat Jan  7 14:47:05 PST 1995 by kalsow    *)
+(*      modified on Sat Apr 16 by rrw1000@hermes.cam.ac.uk    *)
+(*      modified on Mon Jan 11 14:34:58 PST 1993 by muller    *)
+(* ow Sun Nov  6 17:12:47 MET 1994                            *)
+
+INTERFACE Utypes;
+
+FROM Ctypes IMPORT 
+	long, unsigned_long, int, unsigned_int, short, unsigned_short,
+        char, unsigned_char;
+
+(*** <sys/types.h> ***)
+
+(*
+ * Basic system types and major/minor device constructing/busting macros.
+ *)
+
+(* major part of a device *)
+PROCEDURE major (x: int): int;
+
+(* minor part of a device *)
+PROCEDURE minor (x: int): int;
+
+(* make a device number *)
+PROCEDURE makedev (x, y: int): dev_t;
+
+TYPE
+  u_char  = unsigned_char;
+  u_short = unsigned_short;
+  u_int   = unsigned_int;
+  uint    = unsigned_int;               (* sys V compatibility *)
+  u_long  = unsigned_long;
+  ushort  = unsigned_short;             (* sys III compat *)
+
+  int8_t    = char;
+  u_int8_t  = u_char;
+  int16_t   = short;
+  u_int16_t = u_short;
+  int32_t   = int;
+  u_int32_t = u_int;
+  int64_t   = long;
+  u_int64_t = u_long;
+
+(* #ifdef vax *)
+  struct__physadr = RECORD r: ARRAY [0..0] OF int; END;
+  physadr         = UNTRACED REF struct__physadr;
+
+  struct_label_t = RECORD val: ARRAY [0..13] OF int; END;
+  label_t        = struct_label_t;
+(*#endif*)
+
+  quad         = int64_t;
+  quad_t       = int64_t;
+  daddr_t      = int32_t; 
+  caddr_t      = ADDRESS;
+  ino_t        = u_int32_t;
+  swblk_t      = int32_t;
+  size_t       = unsigned_long;
+  time_t       = int64_t;
+  dev_t        = u_int32_t;
+  off_t        = int64_t;
+  key_t        = long;
+  clock_t      = int;
+  mode_t       = u_int16_t;
+  nlink_t      = u_int16_t;
+  uid_t        = u_int32_t;
+  pid_t        = int;
+  gid_t        = u_int32_t;
+
+  tcflag_t     = u_long;
+  cc_t         = u_char;
+  speed_t      = long;
+
+  in_addr_t    = u_int32_t;
+  in_port_t    = u_int16_t;
+
+CONST
+  NBBY = 8;                           (* number of bits in a byte *)
+
+  (*
+   * Select uses bit masks of file descriptors in longs.
+   * These macros manipulate such bit fields (the filesystem macros use chars).
+   * FD_SETSIZE may be defined by the user, but the default here
+   * should be >= NOFILE (param.h).
+   *)
+  FD_SETSIZE = 256;
+
+  (* How many things we'll allow select to use. 0 if unlimited *)
+  MAXSELFD = 256;
+
+TYPE
+  fd_mask        = long;
+ 
+CONST
+  NFDBITS = BYTESIZE (fd_mask) * NBBY;      (* bits per mask (power of 2!)*)
+  NFDSHIFT = 5;                             (* Shift based on above *)
+
+PROCEDURE howmany (x, y: int): int;
+
+TYPE
+  struct_fd_set = RECORD
+       fds_bits: ARRAY [0 .. 
+                        (FD_SETSIZE + NFDBITS - 1) DIV NFDBITS -1] OF fd_mask;
+    END;
+  fd_set = struct_fd_set;
+
+PROCEDURE FD_SET   (n: int; p: UNTRACED REF fd_set): int;
+PROCEDURE FD_CLEAR (n: int; p: UNTRACED REF fd_set): int;
+PROCEDURE FD_ISSET (n: int; p: UNTRACED REF fd_set): int;
+PROCEDURE FD_ZERO  (p: UNTRACED REF fd_set);
+
+END Utypes.
Index: libs/m3core/src/unix/freebsd-4.amd64/Uucontext.i3
--- libs/m3core/src/unix/freebsd-4.amd64/Uucontext.i3	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/unix/freebsd-4.amd64/Uucontext.i3	Mon Feb 16 21:21:15 2004
@@ -0,0 +1,73 @@
+INTERFACE Uucontext;
+
+FROM Ctypes IMPORT int, long, char_star, unsigned_int;
+FROM Utypes IMPORT size_t;
+
+(* ucontext.h *)
+
+TYPE
+
+  sigset_t = ARRAY [0..3] OF unsigned_int;
+
+  struct_sigaltstack = RECORD
+    ss_sp      : char_star;
+    ss_size    : size_t;
+    ss_flags   : int;
+  END;
+  stack_t = struct_sigaltstack;
+
+  register_t = long;
+  mcontext_t = RECORD
+    mc_onstack : register_t;
+    mc_rdi     : register_t;
+    mc_rsi     : register_t;
+    mc_rdx     : register_t;
+    mc_rcx     : register_t;
+    mc_r8      : register_t;
+    mc_r9      : register_t;
+    mc_rax     : register_t;
+    mc_rbx     : register_t;
+    mc_rbp     : register_t;
+    mc_r10     : register_t;
+    mc_r11     : register_t;
+    mc_r12     : register_t;
+    mc_r13     : register_t;
+    mc_r14     : register_t;
+    mc_r15     : register_t;
+    mc_trapno  : register_t;
+    mc_addr    : register_t;
+    mc_flags   : register_t;
+    mc_err     : register_t;
+    mc_rip     : register_t;
+    mc_cs      : register_t;
+    mc_rflags  : register_t;
+    mc_rsp     : register_t;
+    mc_ss      : register_t;
+    mc_len     : long;
+    mc_fpformat : long;
+    mc_ownedfp : long;
+    mc_fpstate : ARRAY[0..63] OF long;
+    mc_spare   : ARRAY[1..8] OF long;
+  END;
+
+  struct_ucontext = RECORD
+    uc_sigmask : sigset_t;
+    uc_mcontext: mcontext_t;
+    uc_link    : UNTRACED REF struct_ucontext;
+    uc_stack   : stack_t;
+    uc_flags   : int;
+    uc_spare  : ARRAY [1..4] OF int;
+  END;
+  ucontext_t = struct_ucontext;
+  ucontext_t_star = UNTRACED REF ucontext_t;
+
+<*EXTERNAL*>
+PROCEDURE swapcontext(VAR oucp, ucp: ucontext_t): int;
+
+<*EXTERNAL*>
+PROCEDURE getcontext(VAR ucp: ucontext_t): int;
+
+<*EXTERNAL*>
+PROCEDURE setcontext(VAR ucp: ucontext_t): int;
+
+END Uucontext.
Index: libs/m3core/src/unix/freebsd-4.amd64/m3makefile
--- libs/m3core/src/unix/freebsd-4.amd64/m3makefile	Wed Dec 31 16:00:00 1969
+++ libs/m3core/src/unix/freebsd-4.amd64/m3makefile	Mon Feb 16 21:21:15 2004
@@ -0,0 +1,14 @@
+% Copyright (C) 1992, Digital Equipment Corporation
+% All rights reserved.
+% See the file COPYRIGHT for a full description.
+%
+% Last modified on Sat Jan  7 14:53:09 PST 1995 by kalsow  
+%      modified on Wed Jun  9 17:03:32 PDT 1993 by harrison
+%      modified on Tue Mar  2 17:17:34 PST 1993 by muller
+
+Interface ("Umman")
+Interface ("Unix")
+Interface ("Usignal")
+Interface ("Ustat")
+Interface ("Utypes")
+Interface ("Uucontext")
Index: m3config/src/FBSD_AMD64
--- m3config/src/FBSD_AMD64	Wed Dec 31 16:00:00 1969
+++ m3config/src/FBSD_AMD64	Mon Feb 16 21:22:25 2004
@@ -0,0 +1,57 @@
+%
+% FreeBSD/amd64 5.x configuration.
+%
+
+readonly TARGET = "FBSD_AMD64"
+
+include("COMMON")
+
+INSTALL_ROOT = "/usr/local"
+X11ROOT = "/usr/X11R6/lib"
+
+PLATFORM_SUPPORTS_MOTIF  = ""
+PLATFORM_SUPPORTS_SHARED_LIB = "T"
+INSTALL_IMPLS = ""
+SKIP_M3GDB = "T"
+SKIP_GNUEMACS = "T"
+NO_ST_SPARE = "T"
+
+CC = ["cc","-c"]
+GNU_CC = "cc"
+LINK = ["cc"]
+MAKELIB = [ "ar", "cru" ]
+MAKESHLIB = ["cc","-shared"]
+RANLIB = ["ranlib"]
+RPATH_FLAG = "-R"
+RPATH_prefix = ""
+RPATH_LIB_USE_ONLY = "T"
+
+% FreeBSD requires a version number on each shared library.  Don't try
+% to derive these from the PM3 version number.  That approach does not
+% work out well in practice.
+SHLIB_VERSION = "7"
+
+proc m3_make_shared_lib (lib, objects, imported_libs) is
+  local lib_so = format ("lib%s.so", lib)
+  local lib_sox = format ("%s.%s", lib_so, SHLIB_VERSION)
+  local cmd = [MAKESHLIB_CMD, "-o", lib_so, "-Wl,-soname," & lib_sox, objects]
+  
+  if VERBOSE write(cmd, CR) end  
+  return exec(cmd)
+end
+
+proc m3_note_shlib(lib) is
+  if Options{"shared_lib"}[0] and PLATFORM_SUPPORTS_SHARED_LIB
+    local lib_so = format ("lib%s.so", lib)
+    local lib_sox = format ("%s.%s", lib_so, SHLIB_VERSION)
+
+    if defined ("_all")
+      install_derived(lib_so)
+      install_alias_link(lib_so,
+	LIB_TO_PKG_USE & SL & PACKAGE & SL & BUILD_DIR, lib_sox, LIB_INSTALL)
+    end
+    deriveds (lib_so, [""])
+  end
+end 
+
+setDefault("","")
