]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/prof, libmach: delete
authorRuss Cox <rsc@golang.org>
Mon, 14 Apr 2014 15:09:25 +0000 (11:09 -0400)
committerRuss Cox <rsc@golang.org>
Mon, 14 Apr 2014 15:09:25 +0000 (11:09 -0400)
We have never released cmd/prof and don't plan to.
Now that nm, addr2line, and objdump have been rewritten in Go,
cmd/prof is the only thing keeping us from deleting libmach.

Delete cmd/prof, and then since nothing is using libmach, delete libmach.

13,000 lines of C deleted.

LGTM=minux.ma
R=golang-codereviews, minux.ma
CC=golang-codereviews, iant, r
https://golang.org/cl/87020044

40 files changed:
include/bootexec.h [deleted file]
include/mach.h [deleted file]
include/plan9/mach.h [deleted file]
include/plan9/ureg_amd64.h [deleted file]
include/plan9/ureg_arm.h [deleted file]
include/plan9/ureg_x86.h [deleted file]
include/ureg_amd64.h [deleted file]
include/ureg_arm.h [deleted file]
include/ureg_x86.h [deleted file]
src/cmd/dist/build.c
src/cmd/prof/Makefile [deleted file]
src/cmd/prof/doc.go [deleted file]
src/cmd/prof/main.c [deleted file]
src/libmach/5.c [deleted file]
src/libmach/5db.c [deleted file]
src/libmach/6.c [deleted file]
src/libmach/8.c [deleted file]
src/libmach/8db.c [deleted file]
src/libmach/Makefile [deleted file]
src/libmach/access.c [deleted file]
src/libmach/darwin.c [deleted file]
src/libmach/dragonfly.c [deleted file]
src/libmach/elf.h [deleted file]
src/libmach/executable.c [deleted file]
src/libmach/fakeobj.c [deleted file]
src/libmach/freebsd.c [deleted file]
src/libmach/linux.c [deleted file]
src/libmach/machdata.c [deleted file]
src/libmach/macho.h [deleted file]
src/libmach/map.c [deleted file]
src/libmach/netbsd.c [deleted file]
src/libmach/obj.c [deleted file]
src/libmach/obj.h [deleted file]
src/libmach/openbsd.c [deleted file]
src/libmach/plan9.c [deleted file]
src/libmach/setmach.c [deleted file]
src/libmach/solaris.c [deleted file]
src/libmach/swap.c [deleted file]
src/libmach/sym.c [deleted file]
src/libmach/windows.c [deleted file]

diff --git a/include/bootexec.h b/include/bootexec.h
deleted file mode 100644 (file)
index 49721ea..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-// Inferno libmach/bootexec.h
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/bootexec.h
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-struct coffsect
-{
-       char    name[8];
-       uint32  phys;
-       uint32  virt;
-       uint32  size;
-       uint32  fptr;
-       uint32  fptrreloc;
-       uint32  fptrlineno;
-       uint32  nrelocnlineno;
-       uint32  flags;
-};
-
-/*
- * proprietary exec headers, needed to bootstrap various machines
- */
-struct mipsexec
-{
-       short   mmagic;         /* (0x160) mips magic number */
-       short   nscns;          /* (unused) number of sections */
-       int32   timdat;         /* (unused) time & date stamp */
-       int32   symptr;         /* offset to symbol table */
-       int32   nsyms;          /* size of symbol table */
-       short   opthdr;         /* (0x38) sizeof(optional hdr) */
-       short   pcszs;          /* flags */
-       short   amagic;         /* see above */
-       short   vstamp;         /* version stamp */
-       int32   tsize;          /* text size in bytes */
-       int32   dsize;          /* initialized data */
-       int32   bsize;          /* uninitialized data */
-       int32   mentry;         /* entry pt.                            */
-       int32   text_start;     /* base of text used for this file      */
-       int32   data_start;     /* base of data used for this file      */
-       int32   bss_start;      /* base of bss used for this file       */
-       int32   gprmask;        /* general purpose register mask        */
-union{
-       int32   cprmask[4];     /* co-processor register masks          */
-       int32   pcsize;
-};
-       int32   gp_value;       /* the gp value used for this object    */
-};
-
-struct mips4kexec
-{
-       struct mipsexec h;
-       struct coffsect itexts;
-       struct coffsect idatas;
-       struct coffsect ibsss;
-};
-
-struct sparcexec
-{
-       short   sjunk;          /* dynamic bit and version number */
-       short   smagic;         /* 0407 */
-       uint32  stext;
-       uint32  sdata;
-       uint32  sbss;
-       uint32  ssyms;
-       uint32  sentry;
-       uint32  strsize;
-       uint32  sdrsize;
-};
-
-struct nextexec
-{
-/* UNUSED
-       struct  nexthdr{
-               uint32  nmagic;
-               uint32  ncputype;
-               uint32  ncpusubtype;
-               uint32  nfiletype;
-               uint32  ncmds;
-               uint32  nsizeofcmds;
-               uint32  nflags;
-       };
-
-       struct nextcmd{
-               uint32  cmd;
-               uint32  cmdsize;
-               uchar   segname[16];
-               uint32  vmaddr;
-               uint32  vmsize;
-               uint32  fileoff;
-               uint32  filesize;
-               uint32  maxprot;
-               uint32  initprot;
-               uint32  nsects;
-               uint32  flags;
-       }textc;
-       struct nextsect{
-               char    sectname[16];
-               char    segname[16];
-               uint32  addr;
-               uint32  size;
-               uint32  offset;
-               uint32  align;
-               uint32  reloff;
-               uint32  nreloc;
-               uint32  flags;
-               uint32  reserved1;
-               uint32  reserved2;
-       }texts;
-       struct nextcmd  datac;
-       struct nextsect datas;
-       struct nextsect bsss;
-       struct nextsym{
-               uint32  cmd;
-               uint32  cmdsize;
-               uint32  symoff;
-               uint32  nsyms;
-               uint32  spoff;
-               uint32  pcoff;
-       }symc;
-*/
-};
-
-struct i386exec
-{
-/* UNUSED
-       struct  i386coff{
-               uint32  isectmagic;
-               uint32  itime;
-               uint32  isyms;
-               uint32  insyms;
-               uint32  iflags;
-       };
-       struct  i386hdr{
-               uint32  imagic;
-               uint32  itextsize;
-               uint32  idatasize;
-               uint32  ibsssize;
-               uint32  ientry;
-               uint32  itextstart;
-               uint32  idatastart;
-       };
-       struct coffsect itexts;
-       struct coffsect idatas;
-       struct coffsect ibsss;
-       struct coffsect icomments;
-*/
-};
diff --git a/include/mach.h b/include/mach.h
deleted file mode 100644 (file)
index cf7151c..0000000
+++ /dev/null
@@ -1,411 +0,0 @@
-// Inferno libmach/a.out.h and libmach/mach.h
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/a.out.h
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/mach.h
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-/*
- *     Architecture-dependent application data
- */
-
-typedef        struct  Exec    Exec;
-struct Exec
-{
-       int32   magic;          /* magic number */
-       int32   text;           /* size of text segment */
-       int32   data;           /* size of initialized data */
-       int32   bss;            /* size of uninitialized data */
-       int32   syms;           /* size of symbol table */
-       int32   entry;          /* entry point */
-       int32   spsz;           /* size of pc/sp offset table */
-       int32   pcsz;           /* size of pc/line number table */
-};
-
-#define HDR_MAGIC      0x00008000              /* header expansion */
-
-#define        _MAGIC(f, b)    ((f)|((((4*(b))+0)*(b))+7))
-#define        A_MAGIC         _MAGIC(0, 8)            /* 68020 */
-#define        I_MAGIC         _MAGIC(0, 11)           /* intel 386 */
-#define        J_MAGIC         _MAGIC(0, 12)           /* intel 960 (retired) */
-#define        K_MAGIC         _MAGIC(0, 13)           /* sparc */
-#define        V_MAGIC         _MAGIC(0, 16)           /* mips 3000 BE */
-#define        X_MAGIC         _MAGIC(0, 17)           /* att dsp 3210 (retired) */
-#define        M_MAGIC         _MAGIC(0, 18)           /* mips 4000 BE */
-#define        D_MAGIC         _MAGIC(0, 19)           /* amd 29000 (retired) */
-#define        E_MAGIC         _MAGIC(0, 20)           /* arm */
-#define        Q_MAGIC         _MAGIC(0, 21)           /* powerpc */
-#define        N_MAGIC         _MAGIC(0, 22)           /* mips 4000 LE */
-#define        L_MAGIC         _MAGIC(0, 23)           /* dec alpha */
-#define        P_MAGIC         _MAGIC(0, 24)           /* mips 3000 LE */
-#define        U_MAGIC         _MAGIC(0, 25)           /* sparc64 */
-#define        S_MAGIC         _MAGIC(HDR_MAGIC, 26)   /* amd64 */
-#define        T_MAGIC         _MAGIC(HDR_MAGIC, 27)   /* powerpc64 */
-
-#define        MIN_MAGIC       8
-#define        MAX_MAGIC       27                      /* <= 90 */
-
-#define        DYN_MAGIC       0x80000000              /* dlm */
-
-typedef        struct  Sym     Sym;
-struct Sym
-{
-       vlong   value;
-       uint    sig;
-       char    type;
-       char    *name;
-       vlong   gotype;
-       int     sequence;       // order in file
-};
-
-
-/*
- *     Supported architectures:
- *             mips,
- *             68020,
- *             i386,
- *             amd64,
- *             sparc,
- *             sparc64,
- *             mips2 (R4000)
- *             arm
- *             powerpc,
- *             powerpc64
- *             alpha
- */
-enum
-{
-       MMIPS,                  /* machine types */
-       MSPARC,
-       M68020,
-       MI386,
-       MI960,                  /* retired */
-       M3210,                  /* retired */
-       MMIPS2,
-       NMIPS2,
-       M29000,                 /* retired */
-       MARM,
-       MPOWER,
-       MALPHA,
-       NMIPS,
-       MSPARC64,
-       MAMD64,
-       MPOWER64,
-                               /* types of executables */
-       FNONE = 0,              /* unidentified */
-       FMIPS,                  /* v.out */
-       FMIPSB,                 /* mips bootable */
-       FSPARC,                 /* k.out */
-       FSPARCB,                /* Sparc bootable */
-       F68020,                 /* 2.out */
-       F68020B,                /* 68020 bootable */
-       FNEXTB,                 /* Next bootable */
-       FI386,                  /* 8.out */
-       FI386B,                 /* I386 bootable */
-       FI960,                  /* retired */
-       FI960B,                 /* retired */
-       F3210,                  /* retired */
-       FMIPS2BE,               /* 4.out */
-       F29000,                 /* retired */
-       FARM,                   /* 5.out */
-       FARMB,                  /* ARM bootable */
-       FPOWER,                 /* q.out */
-       FPOWERB,                /* power pc bootable */
-       FMIPS2LE,               /* 0.out */
-       FALPHA,                 /* 7.out */
-       FALPHAB,                /* DEC Alpha bootable */
-       FMIPSLE,                /* 3k little endian */
-       FSPARC64,               /* u.out */
-       FAMD64,                 /* 6.out */
-       FAMD64B,                /* 6.out bootable */
-       FPOWER64,               /* 9.out */
-       FPOWER64B,              /* 9.out bootable */
-       FWINPE,                 /* windows PE executable */
-
-       ANONE = 0,              /* dissembler types */
-       AMIPS,
-       AMIPSCO,                /* native mips */
-       ASPARC,
-       ASUNSPARC,              /* native sun */
-       A68020,
-       AI386,
-       AI8086,                 /* oh god */
-       AI960,                  /* retired */
-       A29000,                 /* retired */
-       AARM,
-       APOWER,
-       AALPHA,
-       ASPARC64,
-       AAMD64,
-       APOWER64,
-                               /* object file types */
-       Obj68020 = 0,           /* .2 */
-       ObjSparc,               /* .k */
-       ObjMips,                /* .v */
-       Obj386,                 /* .8 */
-       Obj960,                 /* retired */
-       Obj3210,                /* retired */
-       ObjMips2,               /* .4 */
-       Obj29000,               /* retired */
-       ObjArm,                 /* .5 */
-       ObjPower,               /* .q */
-       ObjMips2le,             /* .0 */
-       ObjAlpha,               /* .7 */
-       ObjSparc64,             /* .u */
-       ObjAmd64,               /* .6 */
-       ObjSpim,                /* .0 */
-       ObjPower64,             /* .9 */
-       Maxobjtype,
-
-       CNONE  = 0,             /* symbol table classes */
-       CAUTO,
-       CPARAM,
-       CSTAB,
-       CTEXT,
-       CDATA,
-       CANY,                   /* to look for any class */
-};
-
-typedef        struct  Map     Map;
-typedef        struct  Symbol  Symbol;
-typedef        struct  Reglist Reglist;
-typedef        struct  Mach    Mach;
-typedef        struct  Machdata Machdata;
-typedef        struct  Seg     Seg;
-
-typedef int Maprw(Map *m, Seg *s, uvlong addr, void *v, uint n, int isread);
-
-struct Seg {
-       char    *name;          /* the segment name */
-       int     fd;             /* file descriptor */
-       int     inuse;          /* in use - not in use */
-       int     cache;          /* should cache reads? */
-       uvlong  b;              /* base */
-       uvlong  e;              /* end */
-       vlong   f;              /* offset within file */
-       Maprw   *rw;            /* read/write fn for seg */
-};
-
-/*
- *     Structure to map a segment to data
- */
-struct Map {
-       int     pid;
-       int     tid;
-       int     nsegs;  /* number of segments */
-       Seg     seg[1]; /* actually n of these */
-};
-
-/*
- *     Internal structure describing a symbol table entry
- */
-struct Symbol {
-       void    *handle;                /* used internally - owning func */
-       struct {
-               char    *name;
-               vlong   value;          /* address or stack offset */
-               char    type;           /* as in a.out.h */
-               char    class;          /* as above */
-               int     index;          /* in findlocal, globalsym, textsym */
-       };
-};
-
-/*
- *     machine register description
- */
-struct Reglist {
-       char    *rname;                 /* register name */
-       short   roffs;                  /* offset in u-block */
-       char    rflags;                 /* INTEGER/FLOAT, WRITABLE */
-       char    rformat;                /* print format: 'x', 'X', 'f', '8', '3', 'Y', 'W' */
-};
-
-enum {                                 /* bits in rflags field */
-       RINT    = (0<<0),
-       RFLT    = (1<<0),
-       RRDONLY = (1<<1),
-};
-
-/*
- *     Machine-dependent data is stored in two structures:
- *             Mach  - miscellaneous general parameters
- *             Machdata - jump vector of service functions used by debuggers
- *
- *     Mach is defined in ?.c and set in executable.c
- *
- *     Machdata is defined in ?db.c
- *             and set in the debugger startup.
- */
-struct Mach{
-       char    *name;
-       int     mtype;                  /* machine type code */
-       Reglist *reglist;               /* register set */
-       int32   regsize;                /* sizeof registers in bytes */
-       int32   fpregsize;              /* sizeof fp registers in bytes */
-       char    *pc;                    /* pc name */
-       char    *sp;                    /* sp name */
-       char    *link;                  /* link register name */
-       char    *sbreg;                 /* static base register name */
-       uvlong  sb;                     /* static base register value */
-       int     pgsize;                 /* page size */
-       uvlong  kbase;                  /* kernel base address */
-       uvlong  ktmask;                 /* ktzero = kbase & ~ktmask */
-       uvlong  utop;                   /* user stack top */
-       int     pcquant;                /* quantization of pc */
-       int     szaddr;                 /* sizeof(void*) */
-       int     szreg;                  /* sizeof(register) */
-       int     szfloat;                /* sizeof(float) */
-       int     szdouble;               /* sizeof(double) */
-};
-
-extern Mach    *mach;                  /* Current machine */
-
-typedef uvlong (*Rgetter)(Map*, char*);
-typedef        void    (*Tracer)(Map*, uvlong, uvlong, Symbol*);
-
-struct Machdata {              /* Machine-dependent debugger support */
-       uchar   bpinst[4];                      /* break point instr. */
-       short   bpsize;                         /* size of break point instr. */
-
-       ushort  (*swab)(ushort);                /* ushort to local byte order */
-       uint32  (*swal)(uint32);                        /* uint32 to local byte order */
-       uvlong  (*swav)(uvlong);                /* uvlong to local byte order */
-       int     (*ctrace)(Map*, uvlong, uvlong, uvlong, Tracer); /* C traceback */
-       uvlong  (*findframe)(Map*, uvlong, uvlong, uvlong, uvlong);/* frame finder */
-       char*   (*excep)(Map*, Rgetter);        /* last exception */
-       uint32  (*bpfix)(uvlong);               /* breakpoint fixup */
-       int     (*sftos)(char*, int, void*);    /* single precision float */
-       int     (*dftos)(char*, int, void*);    /* double precision float */
-       int     (*foll)(Map*, uvlong, Rgetter, uvlong*);/* follow set */
-       int     (*das)(Map*, uvlong, char, char*, int); /* symbolic disassembly */
-       int     (*hexinst)(Map*, uvlong, char*, int);   /* hex disassembly */
-       int     (*instsize)(Map*, uvlong);      /* instruction size */
-};
-
-/*
- *     Common a.out header describing all architectures
- */
-typedef struct Fhdr
-{
-       char    *name;          /* identifier of executable */
-       uchar   type;           /* file type - see codes above */
-       uchar   hdrsz;          /* header size */
-       uchar   _magic;         /* _MAGIC() magic */
-       uchar   spare;
-       int32   magic;          /* magic number */
-       uvlong  txtaddr;        /* text address */
-       vlong   txtoff;         /* start of text in file */
-       uvlong  dataddr;        /* start of data segment */
-       vlong   datoff;         /* offset to data seg in file */
-       vlong   symoff;         /* offset of symbol table in file */
-       uvlong  entry;          /* entry point */
-       vlong   sppcoff;        /* offset of sp-pc table in file */
-       vlong   lnpcoff;        /* offset of line number-pc table in file */
-       int32   txtsz;          /* text size */
-       int32   datsz;          /* size of data seg */
-       int32   bsssz;          /* size of bss */
-       int32   symsz;          /* size of symbol table */
-       int32   sppcsz;         /* size of sp-pc table */
-       int32   lnpcsz;         /* size of line number-pc table */
-} Fhdr;
-
-extern int     asstype;        /* dissembler type - machdata.c */
-extern Machdata *machdata;     /* jump vector - machdata.c */
-
-int            beieee80ftos(char*, int, void*);
-int            beieeesftos(char*, int, void*);
-int            beieeedftos(char*, int, void*);
-ushort         beswab(ushort);
-uint32         beswal(uint32);
-uvlong         beswav(uvlong);
-uvlong         ciscframe(Map*, uvlong, uvlong, uvlong, uvlong);
-int            cisctrace(Map*, uvlong, uvlong, uvlong, Tracer);
-int            crackhdr(int fd, Fhdr*);
-uvlong         file2pc(char*, int32);
-int            fileelem(Sym**, uchar *, char*, int);
-int32          fileline(char*, int, uvlong);
-int            filesym(int, char*, int);
-int            findlocal(Symbol*, char*, Symbol*);
-int            findseg(Map*, char*);
-int            findsym(uvlong, int, Symbol *);
-int            fnbound(uvlong, uvlong*);
-int            fpformat(Map*, Reglist*, char*, int, int);
-int            get1(Map*, uvlong, uchar*, int);
-int            get2(Map*, uvlong, ushort*);
-int            get4(Map*, uvlong, uint32*);
-int            get8(Map*, uvlong, uvlong*);
-int            geta(Map*, uvlong, uvlong*);
-int            getauto(Symbol*, int, int, Symbol*);
-Sym*           getsym(int);
-int            globalsym(Symbol *, int);
-char*          _hexify(char*, uint32, int);
-int            ieeesftos(char*, int, uint32);
-int            ieeedftos(char*, int, uint32, uint32);
-int            isar(Biobuf*);
-int            leieee80ftos(char*, int, void*);
-int            leieeesftos(char*, int, void*);
-int            leieeedftos(char*, int, void*);
-ushort         leswab(ushort);
-uint32         leswal(uint32);
-uvlong         leswav(uvlong);
-uvlong         line2addr(int32, uvlong, uvlong);
-Map*           loadmap(Map*, int, Fhdr*);
-int            localaddr(Map*, char*, char*, uvlong*, Rgetter);
-int            localsym(Symbol*, int);
-int            lookup(char*, char*, Symbol*);
-void           machbytype(int);
-int            machbyname(char*);
-int            nextar(Biobuf*, int, char*);
-Map*           newmap(Map*, int);
-void           objtraverse(void(*)(Sym*, void*), void*);
-int            objtype(Biobuf*, char**);
-uvlong         pc2sp(uvlong);
-int32          pc2line(uvlong);
-int            put1(Map*, uvlong, uchar*, int);
-int            put2(Map*, uvlong, ushort);
-int            put4(Map*, uvlong, uint32);
-int            put8(Map*, uvlong, uvlong);
-int            puta(Map*, uvlong, uvlong);
-int            readar(Biobuf*, int, vlong, int);
-int            readobj(Biobuf*, int);
-uvlong         riscframe(Map*, uvlong, uvlong, uvlong, uvlong);
-int            risctrace(Map*, uvlong, uvlong, uvlong, Tracer);
-int            setmap(Map*, int, uvlong, uvlong, vlong, char*, Maprw *rw);
-Sym*           symbase(int32*);
-int            syminit(int, Fhdr*);
-int            symoff(char*, int, uvlong, int);
-void           textseg(uvlong, Fhdr*);
-int            textsym(Symbol*, int);
-void           unusemap(Map*, int);
-
-Map*           attachproc(int pid, Fhdr *fp);
-int            ctlproc(int pid, char *msg);
-void           detachproc(Map *m);
-int            procnotes(int pid, char ***pnotes);
-char*          proctextfile(int pid);
-int            procthreadpids(int pid, int *tid, int ntid);
-char*  procstatus(int);
-
-Maprw  fdrw;
diff --git a/include/plan9/mach.h b/include/plan9/mach.h
deleted file mode 100644 (file)
index 636f44f..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../mach.h"
diff --git a/include/plan9/ureg_amd64.h b/include/plan9/ureg_amd64.h
deleted file mode 100644 (file)
index a7d6ed1..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../ureg_amd64.h"
diff --git a/include/plan9/ureg_arm.h b/include/plan9/ureg_arm.h
deleted file mode 100644 (file)
index fdb0d27..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../ureg_arm.h"
diff --git a/include/plan9/ureg_x86.h b/include/plan9/ureg_x86.h
deleted file mode 100644 (file)
index 6fc4819..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../ureg_x86.h"
diff --git a/include/ureg_amd64.h b/include/ureg_amd64.h
deleted file mode 100644 (file)
index 9c793bc..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-// Inferno utils/libmach/ureg6.h
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/ureg6.h
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-typedef struct UregAmd64 UregAmd64;
-struct UregAmd64 {
-       u64int  ax;
-       u64int  bx;
-       u64int  cx;
-       u64int  dx;
-       u64int  si;
-       u64int  di;
-       u64int  bp;
-       u64int  r8;
-       u64int  r9;
-       u64int  r10;
-       u64int  r11;
-       u64int  r12;
-       u64int  r13;
-       u64int  r14;
-       u64int  r15;
-
-       u16int  ds;
-       u16int  es;
-       u16int  fs;
-       u16int  gs;
-
-       u64int  type;
-       u64int  error;          /* error code (or zero) */
-       u64int  ip;             /* pc */
-       u64int  cs;             /* old context */
-       u64int  flags;          /* old flags */
-       u64int  sp;             /* sp */
-       u64int  ss;             /* old stack segment */
-};
diff --git a/include/ureg_arm.h b/include/ureg_arm.h
deleted file mode 100644 (file)
index 11f98aa..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-// Inferno utils/libmach/ureg5.h
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/ureg5.h
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-typedef struct UregArm UregArm;
-struct UregArm {
-       uint    r0;
-       uint    r1;
-       uint    r2;
-       uint    r3;
-       uint    r4;
-       uint    r5;
-       uint    r6;
-       uint    r7;
-       uint    r8;
-       uint    r9;
-       uint    r10;
-       uint    r11;
-       uint    r12;
-       uint    r13;
-       uint    r14;
-       uint    link;
-       uint    type;
-       uint    psr;
-       uint    pc;
-};
diff --git a/include/ureg_x86.h b/include/ureg_x86.h
deleted file mode 100644 (file)
index 641016d..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-// Inferno utils/libmach/ureg8.h
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/ureg8.h
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-typedef struct Ureg386 Ureg386;
-struct Ureg386
-{
-       uint32  di;             /* general registers */
-       uint32  si;             /* ... */
-       uint32  bp;             /* ... */
-       uint32  nsp;
-       uint32  bx;             /* ... */
-       uint32  dx;             /* ... */
-       uint32  cx;             /* ... */
-       uint32  ax;             /* ... */
-       uint32  gs;             /* data segments */
-       uint32  fs;             /* ... */
-       uint32  es;             /* ... */
-       uint32  ds;             /* ... */
-       uint32  trap;           /* trap type */
-       uint32  ecode;          /* error code (or zero) */
-       uint32  pc;             /* pc */
-       uint32  cs;             /* old context */
-       uint32  flags;          /* old flags */
-       union {
-               uint32  usp;
-               uint32  sp;
-       };
-       uint32  ss;             /* old stack segment */
-};
index 3ef9f6592c8c2d6dc72db94ba4a0019e17305b23..8cb7dcd73bdfc693c1640faa5c77e0fd6dffccac 100644 (file)
@@ -373,7 +373,6 @@ static char *oldtool[] = {
 // Unreleased directories (relative to $GOROOT) that should
 // not be in release branches.
 static char *unreleased[] = {
-       "src/cmd/prof",
        "src/pkg/old",
 };
 
@@ -517,19 +516,6 @@ static struct {
                "$GOROOT/include/libc.h",
                "$GOROOT/include/bio.h",
        }},
-       {"libmach", {
-               "$GOROOT/include/u.h",
-               "$GOROOT/include/utf.h",
-               "$GOROOT/include/fmt.h",
-               "$GOROOT/include/libc.h",
-               "$GOROOT/include/bio.h",
-               "$GOROOT/include/ar.h",
-               "$GOROOT/include/bootexec.h",
-               "$GOROOT/include/mach.h",
-               "$GOROOT/include/ureg_amd64.h",
-               "$GOROOT/include/ureg_arm.h",
-               "$GOROOT/include/ureg_x86.h",
-       }},
        {"liblink", {
                "$GOROOT/include/u.h",
                "$GOROOT/include/utf.h",
@@ -607,7 +593,6 @@ static struct {
        }},
        {"cmd/", {
                "$GOROOT/pkg/obj/$GOOS_$GOARCH/liblink.a",
-               "$GOROOT/pkg/obj/$GOOS_$GOARCH/libmach.a",
                "$GOROOT/pkg/obj/$GOOS_$GOARCH/libbio.a",
                "$GOROOT/pkg/obj/$GOOS_$GOARCH/lib9.a",
        }},
@@ -696,13 +681,6 @@ install(char *dir)
                goto out;
        }
 
-       // For release, cmd/prof is not included.
-       if((streq(dir, "cmd/prof")) && !isdir(bstr(&path))) {
-               if(vflag > 1)
-                       errprintf("skipping %s - does not exist\n", dir);
-               goto out;
-       }
-
        // set up gcc command line on first run.
        if(gccargs.len == 0) {
                bprintf(&b, "%s %s", defaultcc, defaultcflags);
@@ -1327,13 +1305,10 @@ dopack(char *dst, char *src, char **extra, int nextra)
 static char *buildorder[] = {
        "lib9",
        "libbio",
-       "libmach",
        "liblink",
 
        "misc/pprof",
 
-       "cmd/prof",
-
        "cmd/cc",  // must be before c
        "cmd/gc",  // must be before g
        "cmd/%sl",  // must be before a, c, g
@@ -1408,10 +1383,8 @@ static char *cleantab[] = {
        "cmd/cc",
        "cmd/gc",
        "cmd/go",       
-       "cmd/prof",
        "lib9",
        "libbio",
-       "libmach",
        "liblink",
        "pkg/bufio",
        "pkg/bytes",
@@ -1467,8 +1440,6 @@ clean(void)
        vinit(&dir);
 
        for(i=0; i<nelem(cleantab); i++) {
-               if((streq(cleantab[i], "cmd/prof")) && !isdir(cleantab[i]))
-                       continue;
                bpathf(&path, "%s/src/%s", goroot, cleantab[i]);
                xreaddir(&dir, bstr(&path));
                // Remove generated files.
diff --git a/src/cmd/prof/Makefile b/src/cmd/prof/Makefile
deleted file mode 100644 (file)
index 3f528d7..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2012 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-include ../../Make.dist
diff --git a/src/cmd/prof/doc.go b/src/cmd/prof/doc.go
deleted file mode 100644 (file)
index 2640167..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-
-Prof is a rudimentary real-time profiler.
-
-Given a command to run or the process id (pid) of a command already
-running, it samples the program's state at regular intervals and reports
-on its behavior.  With no options, it prints a histogram of the locations
-in the code that were sampled during execution.
-
-Since it is a real-time profiler, unlike a traditional profiler it samples
-the program's state even when it is not running, such as when it is
-asleep or waiting for I/O.  Each thread contributes equally to the
-statistics.
-
-Usage:
-       go tool prof -p pid [-t total_secs] [-d delta_msec] [6.out args ...]
-
-The output modes (default -h) are:
-
-       -P file.prof:
-               Write the profile information to file.prof, in the format used by pprof.
-               At the moment, this only works on Linux amd64 binaries and requires that the
-               binary be written using 6l -e to produce ELF debug info.
-               See http://code.google.com/p/google-perftools for details.
-       -h: histograms
-               How many times a sample occurred at each location.
-       -f: dynamic functions
-               At each sample period, print the name of the executing function.
-       -l: dynamic file and line numbers
-               At each sample period, print the file and line number of the executing instruction.
-       -r: dynamic registers
-               At each sample period, print the register contents.
-       -s: dynamic function stack traces
-               At each sample period, print the symbolic stack trace.
-
-Flag -t sets the maximum real time to sample, in seconds, and -d
-sets the sampling interval in milliseconds.  The default is to sample
-every 100ms until the program completes.
-
-It is installed as go tool prof and is architecture-independent.
-
-*/
-package main
diff --git a/src/cmd/prof/main.c b/src/cmd/prof/main.c
deleted file mode 100644 (file)
index dc4d045..0000000
+++ /dev/null
@@ -1,905 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !plan9
-
-#include <u.h>
-#include <time.h>
-#include <libc.h>
-#include <bio.h>
-#include <ctype.h>
-#include <ureg_amd64.h>
-#include <ureg_x86.h>
-#include <mach.h>
-
-char* file = "6.out";
-static Fhdr fhdr;
-int have_syms;
-int fd;
-struct UregAmd64 ureg_amd64;
-struct Ureg386 ureg_x86;
-int total_sec = 0;
-int delta_msec = 100;
-int nsample;
-int nsamplethread;
-
-// pprof data, stored as sequences of N followed by N PC values.
-// See http://code.google.com/p/google-perftools .
-uvlong *ppdata;        // traces
-Biobuf*        pproffd;        // file descriptor to write trace info
-long   ppstart;        // start position of current trace
-long   nppdata;        // length of data
-long   ppalloc;        // size of allocated data
-char   ppmapdata[10*1024];     // the map information for the output file
-
-// output formats
-int pprof;     // print pprof output to named file
-int functions; // print functions
-int histograms;        // print histograms
-int linenums;  // print file and line numbers rather than function names
-int registers; // print registers
-int stacks;            // print stack traces
-
-int pid;               // main process pid
-
-int nthread;   // number of threads
-int thread[32];        // thread pids
-Map *map[32];  // thread maps
-
-void
-Usage(void)
-{
-       fprint(2, "Usage: prof -p pid [-t total_secs] [-d delta_msec]\n");
-       fprint(2, "       prof [-t total_secs] [-d delta_msec] 6.out args ...\n");
-       fprint(2, "\tformats (default -h):\n");
-       fprint(2, "\t\t-P file.prof: write [c]pprof output to file.prof\n");
-       fprint(2, "\t\t-h: histograms\n");
-       fprint(2, "\t\t-f: dynamic functions\n");
-       fprint(2, "\t\t-l: dynamic file and line numbers\n");
-       fprint(2, "\t\t-r: dynamic registers\n");
-       fprint(2, "\t\t-s: dynamic function stack traces\n");
-       fprint(2, "\t\t-hs: include stack info in histograms\n");
-       exit(2);
-}
-
-typedef struct PC PC;
-struct PC {
-       uvlong pc;
-       uvlong callerpc;
-       unsigned int count;
-       PC* next;
-};
-
-enum {
-       Ncounters = 256
-};
-
-PC *counters[Ncounters];
-
-// Set up by setarch() to make most of the code architecture-independent.
-typedef struct Arch Arch;
-struct Arch {
-       char*   name;
-       void    (*regprint)(void);
-       int     (*getregs)(Map*);
-       int     (*getPC)(Map*);
-       int     (*getSP)(Map*);
-       uvlong  (*uregPC)(void);
-       uvlong  (*uregSP)(void);
-       void    (*ppword)(uvlong w);
-};
-
-void
-amd64_regprint(void)
-{
-       fprint(2, "ax\t0x%llux\n", ureg_amd64.ax);
-       fprint(2, "bx\t0x%llux\n", ureg_amd64.bx);
-       fprint(2, "cx\t0x%llux\n", ureg_amd64.cx);
-       fprint(2, "dx\t0x%llux\n", ureg_amd64.dx);
-       fprint(2, "si\t0x%llux\n", ureg_amd64.si);
-       fprint(2, "di\t0x%llux\n", ureg_amd64.di);
-       fprint(2, "bp\t0x%llux\n", ureg_amd64.bp);
-       fprint(2, "r8\t0x%llux\n", ureg_amd64.r8);
-       fprint(2, "r9\t0x%llux\n", ureg_amd64.r9);
-       fprint(2, "r10\t0x%llux\n", ureg_amd64.r10);
-       fprint(2, "r11\t0x%llux\n", ureg_amd64.r11);
-       fprint(2, "r12\t0x%llux\n", ureg_amd64.r12);
-       fprint(2, "r13\t0x%llux\n", ureg_amd64.r13);
-       fprint(2, "r14\t0x%llux\n", ureg_amd64.r14);
-       fprint(2, "r15\t0x%llux\n", ureg_amd64.r15);
-       fprint(2, "ds\t0x%llux\n", ureg_amd64.ds);
-       fprint(2, "es\t0x%llux\n", ureg_amd64.es);
-       fprint(2, "fs\t0x%llux\n", ureg_amd64.fs);
-       fprint(2, "gs\t0x%llux\n", ureg_amd64.gs);
-       fprint(2, "type\t0x%llux\n", ureg_amd64.type);
-       fprint(2, "error\t0x%llux\n", ureg_amd64.error);
-       fprint(2, "pc\t0x%llux\n", ureg_amd64.ip);
-       fprint(2, "cs\t0x%llux\n", ureg_amd64.cs);
-       fprint(2, "flags\t0x%llux\n", ureg_amd64.flags);
-       fprint(2, "sp\t0x%llux\n", ureg_amd64.sp);
-       fprint(2, "ss\t0x%llux\n", ureg_amd64.ss);
-}
-
-int
-amd64_getregs(Map *map)
-{
-       int i;
-       union {
-               uvlong regs[1];
-               struct UregAmd64 ureg;
-       } u;
-
-       for(i = 0; i < sizeof ureg_amd64; i+=8) {
-               if(get8(map, (uvlong)i, &u.regs[i/8]) < 0)
-                       return -1;
-       }
-       ureg_amd64 = u.ureg;
-       return 0;
-}
-
-int
-amd64_getPC(Map *map)
-{
-       uvlong x;
-       int r;
-
-       r = get8(map, offsetof(struct UregAmd64, ip), &x);
-       ureg_amd64.ip = x;
-       return r;
-}
-
-int
-amd64_getSP(Map *map)
-{
-       uvlong x;
-       int r;
-
-       r = get8(map, offsetof(struct UregAmd64, sp), &x);
-       ureg_amd64.sp = x;
-       return r;
-}
-
-uvlong
-amd64_uregPC(void)
-{
-       return ureg_amd64.ip;
-}
-
-uvlong
-amd64_uregSP(void)
-{
-       return ureg_amd64.sp;
-}
-
-void
-amd64_ppword(uvlong w)
-{
-       uchar buf[8];
-
-       buf[0] = w;
-       buf[1] = w >> 8;
-       buf[2] = w >> 16;
-       buf[3] = w >> 24;
-       buf[4] = w >> 32;
-       buf[5] = w >> 40;
-       buf[6] = w >> 48;
-       buf[7] = w >> 56;
-       Bwrite(pproffd, buf, 8);
-}
-
-void
-x86_regprint(void)
-{
-       fprint(2, "ax\t0x%ux\n", ureg_x86.ax);
-       fprint(2, "bx\t0x%ux\n", ureg_x86.bx);
-       fprint(2, "cx\t0x%ux\n", ureg_x86.cx);
-       fprint(2, "dx\t0x%ux\n", ureg_x86.dx);
-       fprint(2, "si\t0x%ux\n", ureg_x86.si);
-       fprint(2, "di\t0x%ux\n", ureg_x86.di);
-       fprint(2, "bp\t0x%ux\n", ureg_x86.bp);
-       fprint(2, "ds\t0x%ux\n", ureg_x86.ds);
-       fprint(2, "es\t0x%ux\n", ureg_x86.es);
-       fprint(2, "fs\t0x%ux\n", ureg_x86.fs);
-       fprint(2, "gs\t0x%ux\n", ureg_x86.gs);
-       fprint(2, "cs\t0x%ux\n", ureg_x86.cs);
-       fprint(2, "flags\t0x%ux\n", ureg_x86.flags);
-       fprint(2, "pc\t0x%ux\n", ureg_x86.pc);
-       fprint(2, "sp\t0x%ux\n", ureg_x86.sp);
-       fprint(2, "ss\t0x%ux\n", ureg_x86.ss);
-}
-
-int
-x86_getregs(Map *map)
-{
-       int i;
-
-       for(i = 0; i < sizeof ureg_x86; i+=4) {
-               if(get4(map, (uvlong)i, &((uint32*)&ureg_x86)[i/4]) < 0)
-                       return -1;
-       }
-       return 0;
-}
-
-int
-x86_getPC(Map* map)
-{
-       return get4(map, offsetof(struct Ureg386, pc), &ureg_x86.pc);
-}
-
-int
-x86_getSP(Map* map)
-{
-       return get4(map, offsetof(struct Ureg386, sp), &ureg_x86.sp);
-}
-
-uvlong
-x86_uregPC(void)
-{
-       return (uvlong)ureg_x86.pc;
-}
-
-uvlong
-x86_uregSP(void)
-{
-       return (uvlong)ureg_x86.sp;
-}
-
-void
-x86_ppword(uvlong w)
-{
-       uchar buf[4];
-
-       buf[0] = w;
-       buf[1] = w >> 8;
-       buf[2] = w >> 16;
-       buf[3] = w >> 24;
-       Bwrite(pproffd, buf, 4);
-}
-
-Arch archtab[] = {
-       {
-               "amd64",
-               amd64_regprint,
-               amd64_getregs,
-               amd64_getPC,
-               amd64_getSP,
-               amd64_uregPC,
-               amd64_uregSP,
-               amd64_ppword,
-       },
-       {
-               "386",
-               x86_regprint,
-               x86_getregs,
-               x86_getPC,
-               x86_getSP,
-               x86_uregPC,
-               x86_uregSP,
-               x86_ppword,
-       },
-       {
-               nil
-       }
-};
-
-Arch *arch;
-
-int
-setarch(void)
-{
-       int i;
-
-       if(mach != nil) {
-               for(i = 0; archtab[i].name != nil; i++) {
-                       if (strcmp(mach->name, archtab[i].name) == 0) {
-                               arch = &archtab[i];
-                               return 0;
-                       }
-               }
-       }
-       return -1;
-}
-
-int
-getthreads(void)
-{
-       int i, j, curn, found;
-       Map *curmap[nelem(map)];
-       int curthread[nelem(map)];
-       static int complained = 0;
-
-       curn = procthreadpids(pid, curthread, nelem(curthread));
-       if(curn <= 0)
-               return curn;
-
-       if(curn > nelem(map)) {
-               if(complained == 0) {
-                       fprint(2, "prof: too many threads; limiting to %d\n", nthread, nelem(map));
-                       complained = 1;
-               }
-               curn = nelem(map);
-       }
-       if(curn == nthread && memcmp(thread, curthread, curn*sizeof(*thread)) == 0)
-               return curn;    // no changes
-
-       // Number of threads has changed (might be the init case).
-       // A bit expensive but rare enough not to bother being clever.
-       for(i = 0; i < curn; i++) {
-               found = 0;
-               for(j = 0; j < nthread; j++) {
-                       if(curthread[i] == thread[j]) {
-                               found = 1;
-                               curmap[i] = map[j];
-                               map[j] = nil;
-                               break;
-                       }
-               }
-               if(found)
-                       continue;
-
-               // map new thread
-               curmap[i] = attachproc(curthread[i], &fhdr);
-               if(curmap[i] == nil) {
-                       fprint(2, "prof: can't attach to %d: %r\n", curthread[i]);
-                       return -1;
-               }
-       }
-
-       for(j = 0; j < nthread; j++)
-               if(map[j] != nil)
-                       detachproc(map[j]);
-
-       nthread = curn;
-       memmove(thread, curthread, nthread*sizeof thread[0]);
-       memmove(map, curmap, sizeof map);
-       return nthread;
-}
-
-int
-sample(Map *map)
-{
-       static int n;
-
-       n++;
-       if(registers) {
-               if(arch->getregs(map) < 0)
-                       goto bad;
-       } else {
-               // we need only two registers
-               if(arch->getPC(map) < 0)
-                       goto bad;
-               if(arch->getSP(map) < 0)
-                       goto bad;
-       }
-       return 1;
-bad:
-       if(n == 1)
-               fprint(2, "prof: can't read registers: %r\n");
-       return 0;
-}
-
-void
-addtohistogram(uvlong pc, uvlong callerpc, uvlong sp)
-{
-       int h;
-       PC *x;
-       
-       USED(sp);
-
-       h = (pc + callerpc*101) % Ncounters;
-       for(x = counters[h]; x != NULL; x = x->next) {
-               if(x->pc == pc && x->callerpc == callerpc) {
-                       x->count++;
-                       return;
-               }
-       }
-       x = malloc(sizeof(PC));
-       if(x == nil)
-               sysfatal("out of memory");
-       x->pc = pc;
-       x->callerpc = callerpc;
-       x->count = 1;
-       x->next = counters[h];
-       counters[h] = x;
-}
-
-void
-addppword(uvlong pc)
-{
-       if(pc == 0) {
-               return;
-       }
-       if(nppdata == ppalloc) {
-               ppalloc = (1000+nppdata)*2;
-               ppdata = realloc(ppdata, ppalloc * sizeof ppdata[0]);
-               if(ppdata == nil) {
-                       fprint(2, "prof: realloc failed: %r\n");
-                       exit(2);
-               }
-       }
-       ppdata[nppdata++] = pc;
-}
-
-void
-startpptrace(void)
-{
-       ppstart = nppdata;
-       addppword(~0);
-}
-
-void
-endpptrace(void)
-{
-       ppdata[ppstart] = nppdata-ppstart-1;
-}
-
-uvlong nextpc;
-
-void
-xptrace(Map *map, uvlong pc, uvlong sp, Symbol *sym)
-{
-       USED(map);
-
-       char buf[1024];
-       if(sym == nil){
-               fprint(2, "syms\n");
-               return;
-       }
-       if(histograms)
-               addtohistogram(nextpc, pc, sp);
-       if(!histograms || stacks > 1 || pprof) {
-               if(nextpc == 0)
-                       nextpc = sym->value;
-               if(stacks){
-                       fprint(2, "%s(", sym->name);
-                       fprint(2, ")");
-                       if(nextpc != sym->value)
-                               fprint(2, "+%#llux ", nextpc - sym->value);
-                       if(have_syms && linenums && fileline(buf, sizeof buf, pc)) {
-                               fprint(2, " %s", buf);
-                       }
-                       fprint(2, "\n");
-               }
-               if (pprof) {
-                       addppword(nextpc);
-               }
-       }
-       nextpc = pc;
-}
-
-void
-stacktracepcsp(Map *map, uvlong pc, uvlong sp)
-{
-       nextpc = pc;
-       if(pprof){
-               startpptrace();
-       }
-       if(machdata->ctrace==nil)
-               fprint(2, "no machdata->ctrace\n");
-       else if(machdata->ctrace(map, pc, sp, 0, xptrace) <= 0)
-               fprint(2, "no stack frame: pc=%#p sp=%#p\n", pc, sp);
-       else {
-               addtohistogram(nextpc, 0, sp);
-               if(stacks)
-                       fprint(2, "\n");
-       }
-       if(pprof){
-               endpptrace();
-       }
-}
-
-void
-printpc(Map *map, uvlong pc, uvlong sp)
-{
-       char buf[1024];
-       if(registers)
-               arch->regprint();
-       if(have_syms > 0 && linenums &&  fileline(buf, sizeof buf, pc))
-               fprint(2, "%s\n", buf);
-       if(have_syms > 0 && functions) {
-               symoff(buf, sizeof(buf), pc, CANY);
-               fprint(2, "%s\n", buf);
-       }
-       if(stacks || pprof){
-               stacktracepcsp(map, pc, sp);
-       }
-       else if(histograms){
-               addtohistogram(pc, 0, sp);
-       }
-}
-
-void
-ppmaps(void)
-{
-       int fd, n;
-       char tmp[100];
-       Seg *seg;
-
-       // If it's Linux, the info is in /proc/$pid/maps
-       snprint(tmp, sizeof tmp, "/proc/%d/maps", pid);
-       fd = open(tmp, 0);
-       if(fd >= 0) {
-               n = read(fd, ppmapdata, sizeof ppmapdata - 1);
-               close(fd);
-               if(n < 0) {
-                       fprint(2, "prof: can't read %s: %r\n", tmp);
-                       exit(2);
-               }
-               ppmapdata[n] = 0;
-               return;
-       }
-
-       // It's probably a mac. Synthesize an entry for the text file.
-       // The register segment may come first but it has a zero offset, so grab the first non-zero offset segment.
-       for(n = 0; n < 3; n++){
-               seg = &map[0]->seg[n];
-               if(seg->b == 0) {
-                       continue;
-               }
-               snprint(ppmapdata, sizeof ppmapdata,
-                       "%.16x-%.16x r-xp %d 00:00 34968549                           %s\n",
-                       seg->b, seg->e, seg->f, "/home/r/6.out"
-               );
-               return;
-       }
-       fprint(2, "prof: no text segment in maps for %s\n", file);
-       exit(2);
-}
-
-void
-samples(void)
-{
-       int i, pid, msec;
-       struct timespec req;
-       int getmaps;
-
-       req.tv_sec = delta_msec/1000;
-       req.tv_nsec = 1000000*(delta_msec % 1000);
-       getmaps = 0;
-       if(pprof)
-               getmaps= 1;
-       for(msec = 0; total_sec <= 0 || msec < 1000*total_sec; msec += delta_msec) {
-               nsample++;
-               nsamplethread += nthread;
-               for(i = 0; i < nthread; i++) {
-                       pid = thread[i];
-                       if(ctlproc(pid, "stop") < 0)
-                               return;
-                       if(!sample(map[i])) {
-                               ctlproc(pid, "start");
-                               return;
-                       }
-                       printpc(map[i], arch->uregPC(), arch->uregSP());
-                       ctlproc(pid, "start");
-               }
-               nanosleep(&req, NULL);
-               getthreads();
-               if(nthread == 0)
-                       break;
-               if(getmaps) {
-                       getmaps = 0;
-                       ppmaps();
-               }
-       }
-}
-
-typedef struct Func Func;
-struct Func
-{
-       Func *next;
-       Symbol s;
-       uint onstack;
-       uint leaf;
-};
-
-Func *func[257];
-int nfunc;
-
-Func*
-findfunc(uvlong pc)
-{
-       Func *f;
-       uint h;
-       Symbol s;
-
-       if(pc == 0)
-               return nil;
-
-       if(!findsym(pc, CTEXT, &s))
-               return nil;
-
-       h = s.value % nelem(func);
-       for(f = func[h]; f != NULL; f = f->next)
-               if(f->s.value == s.value)
-                       return f;
-
-       f = malloc(sizeof *f);
-       if(f == nil)
-               sysfatal("out of memory");
-       memset(f, 0, sizeof *f);
-       f->s = s;
-       f->next = func[h];
-       func[h] = f;
-       nfunc++;
-       return f;
-}
-
-int
-compareleaf(const void *va, const void *vb)
-{
-       Func *a, *b;
-
-       a = *(Func**)va;
-       b = *(Func**)vb;
-       if(a->leaf != b->leaf)
-               return b->leaf - a->leaf;
-       if(a->onstack != b->onstack)
-               return b->onstack - a->onstack;
-       return strcmp(a->s.name, b->s.name);
-}
-
-void
-dumphistogram(void)
-{
-       int i, h, n;
-       PC *x;
-       Func *f, **ff;
-
-       if(!histograms)
-               return;
-
-       // assign counts to functions.
-       for(h = 0; h < Ncounters; h++) {
-               for(x = counters[h]; x != NULL; x = x->next) {
-                       f = findfunc(x->pc);
-                       if(f) {
-                               f->onstack += x->count;
-                               f->leaf += x->count;
-                       }
-                       f = findfunc(x->callerpc);
-                       if(f)
-                               f->leaf -= x->count;
-               }
-       }
-
-       // build array
-       ff = malloc(nfunc*sizeof ff[0]);
-       if(ff == nil)
-               sysfatal("out of memory");
-       n = 0;
-       for(h = 0; h < nelem(func); h++)
-               for(f = func[h]; f != NULL; f = f->next)
-                       ff[n++] = f;
-
-       // sort by leaf counts
-       qsort(ff, nfunc, sizeof ff[0], compareleaf);
-
-       // print.
-       fprint(2, "%d samples (avg %.1g threads)\n", nsample, (double)nsamplethread/nsample);
-       for(i = 0; i < nfunc; i++) {
-               f = ff[i];
-               fprint(2, "%6.2f%%\t", 100.0*(double)f->leaf/nsample);
-               if(stacks)
-                       fprint(2, "%6.2f%%\t", 100.0*(double)f->onstack/nsample);
-               fprint(2, "%s\n", f->s.name);
-       }
-}
-
-typedef struct Trace Trace;
-struct Trace {
-       int     count;
-       int     npc;
-       uvlong  *pc;
-       Trace   *next;
-};
-
-void
-dumppprof(void)
-{
-       uvlong i, n, *p, *e;
-       int ntrace;
-       Trace *trace, *tp, *up, *prev;
-
-       if(!pprof)
-               return;
-       e = ppdata + nppdata;
-       // Create list of traces.  First, count the traces
-       ntrace = 0;
-       for(p = ppdata; p < e;) {
-               n = *p++;
-               p += n;
-               if(n == 0)
-                       continue;
-               ntrace++;
-       }
-       if(ntrace <= 0)
-               return;
-       // Allocate and link the traces together.
-       trace = malloc(ntrace * sizeof(Trace));
-       if(trace == nil)
-               sysfatal("out of memory");
-       tp = trace;
-       for(p = ppdata; p < e;) {
-               n = *p++;
-               if(n == 0)
-                       continue;
-               tp->count = 1;
-               tp->npc = n;
-               tp->pc = p;
-               tp->next = tp+1;
-               tp++;
-               p += n;
-       }
-       trace[ntrace-1].next = nil;
-       // Eliminate duplicates.  Lousy algorithm, although not as bad as it looks because
-       // the list collapses fast.
-       for(tp = trace; tp != nil; tp = tp->next) {
-               prev = tp;
-               for(up = tp->next; up != nil; up = up->next) {
-                       if(up->npc == tp->npc && memcmp(up->pc, tp->pc, up->npc*sizeof up->pc[0]) == 0) {
-                               tp->count++;
-                               prev->next = up->next;
-                       } else {
-                               prev = up;
-                       }
-               }
-       }
-       // Write file.
-       // See http://code.google.com/p/google-perftools/source/browse/trunk/doc/cpuprofile-fileformat.html
-       // 1) Header
-       arch->ppword(0);        // must be zero
-       arch->ppword(3);        // 3 words follow in header
-       arch->ppword(0);        // must be zero
-       arch->ppword(delta_msec * 1000);        // sampling period in microseconds
-       arch->ppword(0);        // must be zero (padding)
-       // 2) One record for each trace.
-       for(tp = trace; tp != nil; tp = tp->next) {
-               arch->ppword(tp->count);
-               arch->ppword(tp->npc);
-               for(i = 0; i < tp->npc; i++) {
-                       arch->ppword(tp->pc[i]);
-               }
-       }
-       // 3) Binary trailer
-       arch->ppword(0);        // must be zero
-       arch->ppword(1);        // must be one
-       arch->ppword(0);        // must be zero
-       // 4) Mapped objects.
-       Bwrite(pproffd, ppmapdata, strlen(ppmapdata));
-       // 5) That's it.
-       Bterm(pproffd);
-}
-
-int
-startprocess(char **argv)
-{
-       int pid;
-
-       if((pid = fork()) == 0) {
-               pid = getpid();
-               if(ctlproc(pid, "hang") < 0){
-                       fprint(2, "prof: child process could not hang\n");
-                       exits(0);
-               }
-               execv(argv[0], argv);
-               fprint(2, "prof: could not exec %s: %r\n", argv[0]);
-               exits(0);
-       }
-
-       if(pid == -1) {
-               fprint(2, "prof: could not fork\n");
-               exit(1);
-       }
-       if(ctlproc(pid, "attached") < 0 || ctlproc(pid, "waitstop") < 0) {
-               fprint(2, "prof: could not attach to child process: %r\n");
-               exit(1);
-       }
-       return pid;
-}
-
-void
-detach(void)
-{
-       int i;
-
-       for(i = 0; i < nthread; i++)
-               detachproc(map[i]);
-}
-
-int
-main(int argc, char *argv[])
-{
-       int i;
-       char *ppfile;
-
-       ARGBEGIN{
-       case 'P':
-               pprof =1;
-               ppfile = EARGF(Usage());
-               pproffd = Bopen(ppfile, OWRITE);
-               if(pproffd == nil) {
-                       fprint(2, "prof: cannot open %s: %r\n", ppfile);
-                       exit(2);
-               }
-               break;
-       case 'd':
-               delta_msec = atoi(EARGF(Usage()));
-               break;
-       case 't':
-               total_sec = atoi(EARGF(Usage()));
-               break;
-       case 'p':
-               pid = atoi(EARGF(Usage()));
-               break;
-       case 'f':
-               functions = 1;
-               break;
-       case 'h':
-               histograms = 1;
-               break;
-       case 'l':
-               linenums = 1;
-               break;
-       case 'r':
-               registers = 1;
-               break;
-       case 's':
-               stacks++;
-               break;
-       default:
-               Usage();
-       }ARGEND
-       if(pid <= 0 && argc == 0)
-               Usage();
-       if(functions+linenums+registers+stacks+pprof == 0)
-               histograms = 1;
-       if(!machbyname("amd64")) {
-               fprint(2, "prof: no amd64 support\n", pid);
-               exit(1);
-       }
-       if(argc > 0)
-               file = argv[0];
-       else if(pid) {
-               file = proctextfile(pid);
-               if (file == NULL) {
-                       fprint(2, "prof: can't find file for pid %d: %r\n", pid);
-                       fprint(2, "prof: on Darwin, need to provide file name explicitly\n");
-                       exit(1);
-               }
-       }
-       fd = open(file, 0);
-       if(fd < 0) {
-               fprint(2, "prof: can't open %s: %r\n", file);
-               exit(1);
-       }
-       if(crackhdr(fd, &fhdr)) {
-               have_syms = syminit(fd, &fhdr);
-               if(!have_syms) {
-                       fprint(2, "prof: no symbols for %s: %r\n", file);
-               }
-       } else {
-               fprint(2, "prof: crack header for %s: %r\n", file);
-               exit(1);
-       }
-       if(pid <= 0)
-               pid = startprocess(argv);
-       attachproc(pid, &fhdr); // initializes thread list
-       if(setarch() < 0) {
-               detach();
-               fprint(2, "prof: can't identify binary architecture for pid %d\n", pid);
-               exit(1);
-       }
-       if(getthreads() <= 0) {
-               detach();
-               fprint(2, "prof: can't find threads for pid %d\n", pid);
-               exit(1);
-       }
-       for(i = 0; i < nthread; i++)
-               ctlproc(thread[i], "start");
-       samples();
-       detach();
-       dumphistogram();
-       dumppprof();
-       exit(0);
-}
diff --git a/src/libmach/5.c b/src/libmach/5.c
deleted file mode 100644 (file)
index 49207a9..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-// Inferno libmach/5.c
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/5.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-/*
- * arm definition
- */
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include "ureg_arm.h"
-#include <mach.h>
-
-#define        REGOFF(x)       (uintptr) (&((struct UregArm *) 0)->x)
-
-#define SP             REGOFF(r13)
-#define PC             REGOFF(pc)
-
-#define        REGSIZE         sizeof(struct UregArm)
-
-Reglist armreglist[] =
-{
-       {"LINK",        REGOFF(link),           RINT|RRDONLY, 'X'},
-       {"TYPE",        REGOFF(type),           RINT|RRDONLY, 'X'},
-       {"PSR",         REGOFF(psr),            RINT|RRDONLY, 'X'},
-       {"PC",          PC,                     RINT, 'X'},
-       {"SP",          SP,                     RINT, 'X'},
-       {"R15",         PC,                     RINT, 'X'},
-       {"R14",         REGOFF(r14),            RINT, 'X'},
-       {"R13",         REGOFF(r13),            RINT, 'X'},
-       {"R12",         REGOFF(r12),            RINT, 'X'},
-       {"R11",         REGOFF(r11),            RINT, 'X'},
-       {"R10",         REGOFF(r10),            RINT, 'X'},
-       {"R9",          REGOFF(r9),             RINT, 'X'},
-       {"R8",          REGOFF(r8),             RINT, 'X'},
-       {"R7",          REGOFF(r7),             RINT, 'X'},
-       {"R6",          REGOFF(r6),             RINT, 'X'},
-       {"R5",          REGOFF(r5),             RINT, 'X'},
-       {"R4",          REGOFF(r4),             RINT, 'X'},
-       {"R3",          REGOFF(r3),             RINT, 'X'},
-       {"R2",          REGOFF(r2),             RINT, 'X'},
-       {"R1",          REGOFF(r1),             RINT, 'X'},
-       {"R0",          REGOFF(r0),             RINT, 'X'},
-       {  0 }
-};
-
-       /* the machine description */
-Mach marm =
-{
-       "arm",
-       MARM,           /* machine type */
-       armreglist,     /* register set */
-       REGSIZE,        /* register set size */
-       0,              /* fp register set size */
-       "PC",           /* name of PC */
-       "SP",           /* name of SP */
-       "R15",          /* name of link register */
-       "setR12",       /* static base register name */
-       0,              /* static base register value */
-       0x1000,         /* page size */
-       0xC0000000,     /* kernel base */
-       0,              /* kernel text mask */
-       4,              /* quantization of pc */
-       4,              /* szaddr */
-       4,              /* szreg */
-       4,              /* szfloat */
-       8,              /* szdouble */
-};
diff --git a/src/libmach/5db.c b/src/libmach/5db.c
deleted file mode 100644 (file)
index 99bc791..0000000
+++ /dev/null
@@ -1,1093 +0,0 @@
-// Inferno libmach/5db.c
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/5db.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include "ureg_arm.h"
-#include <mach.h>
-
-static int debug = 0;
-
-#define        BITS(a, b)      ((1<<(b+1))-(1<<a))
-
-#define LSR(v, s)      ((ulong)(v) >> (s))
-#define ASR(v, s)      ((long)(v) >> (s))
-#define ROR(v, s)      (LSR((v), (s)) | (((v) & ((1 << (s))-1)) << (32 - (s))))
-
-typedef struct Instr   Instr;
-struct Instr
-{
-       Map     *map;
-       ulong   w;
-       ulong   addr;
-       uchar   op;                     /* super opcode */
-
-       uchar   cond;                   /* bits 28-31 */
-       uchar   store;                  /* bit 20 */
-
-       uchar   rd;                     /* bits 12-15 */
-       uchar   rn;                     /* bits 16-19 */
-       uchar   rs;                     /* bits 0-11 (shifter operand) */
-
-       long    imm;                    /* rotated imm */
-       char*   curr;                   /* fill point in buffer */
-       char*   end;                    /* end of buffer */
-       char*   err;                    /* error message */
-};
-
-typedef struct Opcode Opcode;
-struct Opcode
-{
-       char*   o;
-       void    (*fmt)(Opcode*, Instr*);
-       ulong   (*foll)(Map*, Rgetter, Instr*, ulong);
-       char*   a;
-};
-
-static void    format(char*, Instr*, char*);
-static char    FRAMENAME[] = ".frame";
-
-/*
- * Arm-specific debugger interface
- */
-
-extern char    *armexcep(Map*, Rgetter);
-static int     armfoll(Map*, uvlong, Rgetter, uvlong*);
-static int     arminst(Map*, uvlong, char, char*, int);
-static int     armdas(Map*, uvlong, char*, int);
-static int     arminstlen(Map*, uvlong);
-
-/*
- *     Debugger interface
- */
-Machdata armmach =
-{
-       {0, 0, 0, 0xD},         /* break point */
-       4,                      /* break point size */
-
-       leswab,                 /* short to local byte order */
-       leswal,                 /* long to local byte order */
-       leswav,                 /* long to local byte order */
-       risctrace,              /* C traceback */
-       riscframe,              /* Frame finder */
-       armexcep,                       /* print exception */
-       0,                      /* breakpoint fixup */
-       0,                      /* single precision float printer */
-       0,                      /* double precision float printer */
-       armfoll,                /* following addresses */
-       arminst,                /* print instruction */
-       armdas,                 /* dissembler */
-       arminstlen,             /* instruction size */
-};
-
-char*
-armexcep(Map *map, Rgetter rget)
-{
-       long c;
-
-       c = (*rget)(map, "TYPE");
-       switch (c&0x1f) {
-       case 0x11:
-               return "Fiq interrupt";
-       case 0x12:
-               return "Mirq interrupt";
-       case 0x13:
-               return "SVC/SWI Exception";
-       case 0x17:
-               return "Prefetch Abort/Data Abort";
-       case 0x18:
-               return "Data Abort";
-       case 0x1b:
-               return "Undefined instruction/Breakpoint";
-       case 0x1f:
-               return "Sys trap";
-       default:
-               return "Undefined trap";
-       }
-}
-
-static
-char*  cond[16] =
-{
-       "EQ",   "NE",   "CS",   "CC",
-       "MI",   "PL",   "VS",   "VC",
-       "HI",   "LS",   "GE",   "LT",
-       "GT",   "LE",   0,      "NV"
-};
-
-static
-char*  shtype[4] =
-{
-       "<<",   ">>",   "->",   "@>"
-};
-
-static
-char *hb[4] =
-{
-       "???",  "HU", "B", "H"
-};
-
-static
-char*  addsub[2] =
-{
-       "-",    "+",
-};
-
-int
-armclass(long w)
-{
-       int op;
-
-       op = (w >> 25) & 0x7;
-       switch(op) {
-       case 0: /* data processing r,r,r */
-               op = ((w >> 4) & 0xf);
-               if(op == 0x9) {
-                       op = 48+16;             /* mul */
-                       if(w & (1<<24)) {
-                               op += 2;
-                               if(w & (1<<22))
-                                       op++;   /* swap */
-                               break;
-                       }
-                       if(w & (1<<21))
-                               op++;           /* mla */
-                       break;
-               }
-               if ((op & 0x9) == 0x9)          /* ld/st byte/half s/u */
-               {
-                       op = (48+16+4) + ((w >> 22) & 0x1) + ((w >> 19) & 0x2);
-                       break;
-               }
-               op = (w >> 21) & 0xf;
-               if(w & (1<<4))
-                       op += 32;
-               else
-               if(w & (31<<7))
-                       op += 16;
-               break;
-       case 1: /* data processing i,r,r */
-               op = (48) + ((w >> 21) & 0xf);
-               break;
-       case 2: /* load/store byte/word i(r) */
-               op = (48+24) + ((w >> 22) & 0x1) + ((w >> 19) & 0x2);
-               break;
-       case 3: /* load/store byte/word (r)(r) */
-               op = (48+24+4) + ((w >> 22) & 0x1) + ((w >> 19) & 0x2);
-               break;
-       case 4: /* block data transfer (r)(r) */
-               op = (48+24+4+4) + ((w >> 20) & 0x1);
-               break;
-       case 5: /* branch / branch link */
-               op = (48+24+4+4+2) + ((w >> 24) & 0x1);
-               break;
-       case 7: /* coprocessor crap */
-               op = (48+24+4+4+2+2) + ((w >> 3) & 0x2) + ((w >> 20) & 0x1);
-               break;
-       default:
-               op = (48+24+4+4+2+2+4);
-               break;
-       }
-       return op;
-}
-
-static int
-decode(Map *map, ulong pc, Instr *i)
-{
-       uint32 w;
-
-       if(get4(map, pc, &w) < 0) {
-               werrstr("can't read instruction: %r");
-               return -1;
-       }
-       i->w = w;
-       i->addr = pc;
-       i->cond = (w >> 28) & 0xF;
-       i->op = armclass(w);
-       i->map = map;
-       return 1;
-}
-
-static void
-bprint(Instr *i, char *fmt, ...)
-{
-       va_list arg;
-
-       va_start(arg, fmt);
-       i->curr = vseprint(i->curr, i->end, fmt, arg);
-       va_end(arg);
-}
-
-static int
-plocal(Instr *i)
-{
-       char *reg;
-       Symbol s;
-       char *fn;
-       int class;
-       int offset;
-
-       if(!findsym(i->addr, CTEXT, &s)) {
-               if(debug)fprint(2,"fn not found @%lux: %r\n", i->addr);
-               return 0;
-       }
-       fn = s.name;
-       if (!findlocal(&s, FRAMENAME, &s)) {
-               if(debug)fprint(2,"%s.%s not found @%s: %r\n", fn, FRAMENAME, s.name);
-                       return 0;
-       }
-       if(s.value > i->imm) {
-               class = CAUTO;
-               offset = s.value-i->imm;
-               reg = "(SP)";
-       } else {
-               class = CPARAM;
-               offset = i->imm-s.value-4;
-               reg = "(FP)";
-       }
-       if(!getauto(&s, offset, class, &s)) {
-               if(debug)fprint(2,"%s %s not found @%ux: %r\n", fn,
-                       class == CAUTO ? " auto" : "param", offset);
-               return 0;
-       }
-       bprint(i, "%s%c%d%s", s.name, class == CPARAM ? '+' : '-', s.value, reg);
-       return 1;
-}
-
-/*
- * Print value v as name[+offset]
- */
-int
-gsymoff(char *buf, int n, long v, int space)
-{
-       Symbol s;
-       int r;
-       long delta;
-
-       r = delta = 0;          /* to shut compiler up */
-       if (v) {
-               r = findsym(v, space, &s);
-               if (r)
-                       delta = v-s.value;
-               if (delta < 0)
-                       delta = -delta;
-       }
-       if (v == 0 || r == 0 || delta >= 4096)
-               return snprint(buf, n, "#%lux", v);
-       if (strcmp(s.name, ".string") == 0)
-               return snprint(buf, n, "#%lux", v);
-       if (!delta)
-               return snprint(buf, n, "%s", s.name);
-       if (s.type != 't' && s.type != 'T')
-               return snprint(buf, n, "%s+%llux", s.name, v-s.value);
-       else
-               return snprint(buf, n, "#%lux", v);
-}
-
-static void
-armdps(Opcode *o, Instr *i)
-{
-       i->store = (i->w >> 20) & 1;
-       i->rn = (i->w >> 16) & 0xf;
-       i->rd = (i->w >> 12) & 0xf;
-       i->rs = (i->w >> 0) & 0xf;
-       if(i->rn == 15 && i->rs == 0) {
-               if(i->op == 8) {
-                       format("MOVW", i,"CPSR, R%d");
-                       return;
-               } else
-               if(i->op == 10) {
-                       format("MOVW", i,"SPSR, R%d");
-                       return;
-               }
-       } else
-       if(i->rn == 9 && i->rd == 15) {
-               if(i->op == 9) {
-                       format("MOVW", i, "R%s, CPSR");
-                       return;
-               } else
-               if(i->op == 11) {
-                       format("MOVW", i, "R%s, SPSR");
-                       return;
-               }
-       }
-       format(o->o, i, o->a);
-}
-
-static void
-armdpi(Opcode *o, Instr *i)
-{
-       ulong v;
-       int c;
-
-       v = (i->w >> 0) & 0xff;
-       c = (i->w >> 8) & 0xf;
-       while(c) {
-               v = (v<<30) | (v>>2);
-               c--;
-       }
-       i->imm = v;
-       i->store = (i->w >> 20) & 1;
-       i->rn = (i->w >> 16) & 0xf;
-       i->rd = (i->w >> 12) & 0xf;
-       i->rs = i->w&0x0f;
-
-               /* RET is encoded as ADD #0,R14,R15 */
-       if((i->w & 0x0fffffff) == 0x028ef000){
-               format("RET%C", i, "");
-               return;
-       }
-       if((i->w & 0x0ff0ffff) == 0x0280f000){
-               format("B%C", i, "0(R%n)");
-               return;
-       }
-       format(o->o, i, o->a);
-}
-
-static void
-armsdti(Opcode *o, Instr *i)
-{
-       ulong v;
-
-       v = i->w & 0xfff;
-       if(!(i->w & (1<<23)))
-               v = -v;
-       i->store = ((i->w >> 23) & 0x2) | ((i->w >>21) & 0x1);
-       i->imm = v;
-       i->rn = (i->w >> 16) & 0xf;
-       i->rd = (i->w >> 12) & 0xf;
-               /* RET is encoded as LW.P x,R13,R15 */
-       if ((i->w & 0x0ffff000) == 0x049df000)
-       {
-               format("RET%C%p", i, "%I");
-               return;
-       }
-       format(o->o, i, o->a);
-}
-
-/* arm V4 ld/st halfword, signed byte */
-static void
-armhwby(Opcode *o, Instr *i)
-{
-       i->store = ((i->w >> 23) & 0x2) | ((i->w >>21) & 0x1);
-       i->imm = (i->w & 0xf) | ((i->w >> 8) & 0xf);
-       if (!(i->w & (1 << 23)))
-               i->imm = - i->imm;
-       i->rn = (i->w >> 16) & 0xf;
-       i->rd = (i->w >> 12) & 0xf;
-       i->rs = (i->w >> 0) & 0xf;
-       format(o->o, i, o->a);
-}
-
-static void
-armsdts(Opcode *o, Instr *i)
-{
-       i->store = ((i->w >> 23) & 0x2) | ((i->w >>21) & 0x1);
-       i->rs = (i->w >> 0) & 0xf;
-       i->rn = (i->w >> 16) & 0xf;
-       i->rd = (i->w >> 12) & 0xf;
-       format(o->o, i, o->a);
-}
-
-static void
-armbdt(Opcode *o, Instr *i)
-{
-       i->store = (i->w >> 21) & 0x3;          /* S & W bits */
-       i->rn = (i->w >> 16) & 0xf;
-       i->imm = i->w & 0xffff;
-       if(i->w == 0xe8fd8000)
-               format("RFE", i, "");
-       else
-               format(o->o, i, o->a);
-}
-
-/*
-static void
-armund(Opcode *o, Instr *i)
-{
-       format(o->o, i, o->a);
-}
-
-static void
-armcdt(Opcode *o, Instr *i)
-{
-       format(o->o, i, o->a);
-}
-*/
-
-static void
-armunk(Opcode *o, Instr *i)
-{
-       format(o->o, i, o->a);
-}
-
-static void
-armb(Opcode *o, Instr *i)
-{
-       ulong v;
-
-       v = i->w & 0xffffff;
-       if(v & 0x800000)
-               v |= ~0xffffff;
-       i->imm = (v<<2) + i->addr + 8;
-       format(o->o, i, o->a);
-}
-
-static void
-armco(Opcode *o, Instr *i)             /* coprocessor instructions */
-{
-       int op, p, cp;
-
-       char buf[1024];
-
-       i->rn = (i->w >> 16) & 0xf;
-       i->rd = (i->w >> 12) & 0xf;
-       i->rs = i->w&0xf;
-       cp = (i->w >> 8) & 0xf;
-       p = (i->w >> 5) & 0x7;
-       if(i->w&(1<<4)) {
-               op = (i->w >> 21) & 0x07;
-               snprint(buf, sizeof(buf), "#%x, #%x, R%d, C(%d), C(%d), #%x\n", cp, op, i->rd, i->rn, i->rs, p);
-       } else {
-               op = (i->w >> 20) & 0x0f;
-               snprint(buf, sizeof(buf), "#%x, #%x, C(%d), C(%d), C(%d), #%x\n", cp, op, i->rd, i->rn, i->rs, p);
-       }
-       format(o->o, i, buf);
-}
-
-static int
-armcondpass(Map *map, Rgetter rget, uchar cond)
-{
-       ulong psr;
-       uchar n;
-       uchar z;
-       uchar c;
-       uchar v;
-
-       psr = rget(map, "PSR");
-       n = (psr >> 31) & 1;
-       z = (psr >> 30) & 1;
-       c = (psr >> 29) & 1;
-       v = (psr >> 28) & 1;
-
-       switch(cond) {
-               case 0:         return z;
-               case 1:         return !z;
-               case 2:         return c;
-               case 3:         return !c;
-               case 4:         return n;
-               case 5:         return !n;
-               case 6:         return v;
-               case 7:         return !v;
-               case 8:         return c && !z;
-               case 9:         return !c || z;
-               case 10:        return n == v;
-               case 11:        return n != v;
-               case 12:        return !z && (n == v);
-               case 13:        return z && (n != v);
-               case 14:        return 1;
-               case 15:        return 0;
-       }
-       return 0;
-}
-
-static ulong
-armshiftval(Map *map, Rgetter rget, Instr *i)
-{
-       if(i->w & (1 << 25)) {                          /* immediate */
-               ulong imm = i->w & BITS(0, 7);
-               ulong s = (i->w & BITS(8, 11)) >> 7; /* this contains the *2 */
-               return ROR(imm, s);
-       } else {
-               char buf[8];
-               ulong v;
-               ulong s = (i->w & BITS(7,11)) >> 7;
-
-               sprint(buf, "R%ld", i->w & 0xf);
-               v = rget(map, buf);
-
-               switch((i->w & BITS(4, 6)) >> 4) {
-               case 0:                                 /* LSLIMM */
-                       return v << s;
-               case 1:                                 /* LSLREG */
-                       sprint(buf, "R%lud", s >> 1);
-                       s = rget(map, buf) & 0xFF;
-                       if(s >= 32) return 0;
-                       return v << s;
-               case 2:                                 /* LSRIMM */
-                       return LSR(v, s);
-               case 3:                                 /* LSRREG */
-                       sprint(buf, "R%ld", s >> 1);
-                       s = rget(map, buf) & 0xFF;
-                       if(s >= 32) return 0;
-                       return LSR(v, s);
-               case 4:                                 /* ASRIMM */
-                       if(s == 0) {
-                               if((v & (1U<<31)) == 0)
-                                       return 0;
-                               return 0xFFFFFFFF;
-                       }
-                       return ASR(v, s);
-               case 5:                                 /* ASRREG */
-                       sprint(buf, "R%ld", s >> 1);
-                       s = rget(map, buf) & 0xFF;
-                       if(s >= 32) {
-                               if((v & (1U<<31)) == 0)
-                                       return 0;
-                               return 0xFFFFFFFF;
-                       }
-                       return ASR(v, s);
-               case 6:                                 /* RORIMM */
-                       if(s == 0) {
-                               ulong c = (rget(map, "PSR") >> 29) & 1;
-
-                               return (c << 31) | LSR(v, 1);
-                       }
-                       return ROR(v, s);
-               case 7:                                 /* RORREG */
-                       sprint(buf, "R%ld", (s>>1)&0xF);
-                       s = rget(map, buf);
-                       if(s == 0 || (s & 0xF) == 0)
-                               return v;
-                       return ROR(v, s & 0xF);
-               }
-       }
-       return 0;
-}
-
-static int
-nbits(ulong v)
-{
-       int n = 0;
-       int i;
-
-       for(i=0; i < 32 ; i++) {
-               if(v & 1) ++n;
-               v >>= 1;
-       }
-
-       return n;
-}
-
-static ulong
-armmaddr(Map *map, Rgetter rget, Instr *i)
-{
-       ulong v;
-       ulong nb;
-       char buf[8];
-       ulong rn;
-
-       rn = (i->w >> 16) & 0xf;
-       sprint(buf,"R%ld", rn);
-
-       v = rget(map, buf);
-       nb = nbits(i->w & ((1 << 15) - 1));
-
-       switch((i->w >> 23) & 3) {
-               case 0: return (v - (nb*4)) + 4;
-               case 1: return v;
-               case 2: return v - (nb*4);
-               case 3: return v + 4;
-       }
-       return 0;
-}
-
-static ulong
-armaddr(Map *map, Rgetter rget, Instr *i)
-{
-       char buf[8];
-       ulong rn;
-
-       sprint(buf, "R%ld", (i->w >> 16) & 0xf);
-       rn = rget(map, buf);
-
-       if((i->w & (1<<24)) == 0) {                     /* POSTIDX */
-               sprint(buf, "R%ld", rn);
-               return rget(map, buf);
-       }
-
-       if((i->w & (1<<25)) == 0) {                     /* OFFSET */
-               sprint(buf, "R%ld", rn);
-               if(i->w & (1U<<23))
-                       return rget(map, buf) + (i->w & BITS(0,11));
-               return rget(map, buf) - (i->w & BITS(0,11));
-       } else {                                        /* REGOFF */
-               ulong index = 0;
-               uchar c;
-               uchar rm;
-
-               sprint(buf, "R%ld", i->w & 0xf);
-               rm = rget(map, buf);
-
-               switch((i->w & BITS(5,6)) >> 5) {
-               case 0: index = rm << ((i->w & BITS(7,11)) >> 7);       break;
-               case 1: index = LSR(rm, ((i->w & BITS(7,11)) >> 7));    break;
-               case 2: index = ASR(rm, ((i->w & BITS(7,11)) >> 7));    break;
-               case 3:
-                       if((i->w & BITS(7,11)) == 0) {
-                               c = (rget(map, "PSR") >> 29) & 1;
-                               index = c << 31 | LSR(rm, 1);
-                       } else {
-                               index = ROR(rm, ((i->w & BITS(7,11)) >> 7));
-                       }
-                       break;
-               }
-               if(i->w & (1<<23))
-                       return rn + index;
-               return rn - index;
-       }
-}
-
-static ulong
-armfadd(Map *map, Rgetter rget, Instr *i, ulong pc)
-{
-       char buf[8];
-       int r;
-
-       r = (i->w >> 12) & 0xf;
-       if(r != 15 || !armcondpass(map, rget, (i->w >> 28) & 0xf))
-               return pc+4;
-
-       r = (i->w >> 16) & 0xf;
-       sprint(buf, "R%d", r);
-
-       return rget(map, buf) + armshiftval(map, rget, i);
-}
-
-static ulong
-armfmovm(Map *map, Rgetter rget, Instr *i, ulong pc)
-{
-       uint32 v;
-       ulong addr;
-
-       v = i->w & 1<<15;
-       if(!v || !armcondpass(map, rget, (i->w>>28)&0xf))
-               return pc+4;
-
-       addr = armmaddr(map, rget, i) + nbits(i->w & BITS(0,15));
-       if(get4(map, addr, &v) < 0) {
-               werrstr("can't read addr: %r");
-               return -1;
-       }
-       return v;
-}
-
-static ulong
-armfbranch(Map *map, Rgetter rget, Instr *i, ulong pc)
-{
-       if(!armcondpass(map, rget, (i->w >> 28) & 0xf))
-               return pc+4;
-
-       return pc + (((signed long)i->w << 8) >> 6) + 8;
-}
-
-static ulong
-armfmov(Map *map, Rgetter rget, Instr *i, ulong pc)
-{
-       ulong rd;
-       uint32 v;
-
-       rd = (i->w >> 12) & 0xf;
-       if(rd != 15 || !armcondpass(map, rget, (i->w>>28)&0xf))
-               return pc+4;
-
-        /* LDR */
-       /* BUG: Needs LDH/B, too */
-       if(((i->w>>26)&0x3) == 1) {
-               if(get4(map, armaddr(map, rget, i), &v) < 0) {
-                       werrstr("can't read instruction: %r");
-                       return pc+4;
-               }
-               return v;
-       }
-
-        /* MOV */
-       return armshiftval(map, rget, i);
-}
-
-static Opcode opcodes[] =
-{
-       "AND%C%S",      armdps, 0,      "R%s,R%n,R%d",
-       "EOR%C%S",      armdps, 0,      "R%s,R%n,R%d",
-       "SUB%C%S",      armdps, 0,      "R%s,R%n,R%d",
-       "RSB%C%S",      armdps, 0,      "R%s,R%n,R%d",
-       "ADD%C%S",      armdps, armfadd,        "R%s,R%n,R%d",
-       "ADC%C%S",      armdps, 0,      "R%s,R%n,R%d",
-       "SBC%C%S",      armdps, 0,      "R%s,R%n,R%d",
-       "RSC%C%S",      armdps, 0,      "R%s,R%n,R%d",
-       "TST%C%S",      armdps, 0,      "R%s,R%n",
-       "TEQ%C%S",      armdps, 0,      "R%s,R%n",
-       "CMP%C%S",      armdps, 0,      "R%s,R%n",
-       "CMN%C%S",      armdps, 0,      "R%s,R%n",
-       "ORR%C%S",      armdps, 0,      "R%s,R%n,R%d",
-       "MOVW%C%S",     armdps, armfmov,        "R%s,R%d",
-       "BIC%C%S",      armdps, 0,      "R%s,R%n,R%d",
-       "MVN%C%S",      armdps, 0,      "R%s,R%d",
-
-/* 16 */
-       "AND%C%S",      armdps, 0,      "(R%s%h%m),R%n,R%d",
-       "EOR%C%S",      armdps, 0,      "(R%s%h%m),R%n,R%d",
-       "SUB%C%S",      armdps, 0,      "(R%s%h%m),R%n,R%d",
-       "RSB%C%S",      armdps, 0,      "(R%s%h%m),R%n,R%d",
-       "ADD%C%S",      armdps, armfadd,        "(R%s%h%m),R%n,R%d",
-       "ADC%C%S",      armdps, 0,      "(R%s%h%m),R%n,R%d",
-       "SBC%C%S",      armdps, 0,      "(R%s%h%m),R%n,R%d",
-       "RSC%C%S",      armdps, 0,      "(R%s%h%m),R%n,R%d",
-       "TST%C%S",      armdps, 0,      "(R%s%h%m),R%n",
-       "TEQ%C%S",      armdps, 0,      "(R%s%h%m),R%n",
-       "CMP%C%S",      armdps, 0,      "(R%s%h%m),R%n",
-       "CMN%C%S",      armdps, 0,      "(R%s%h%m),R%n",
-       "ORR%C%S",      armdps, 0,      "(R%s%h%m),R%n,R%d",
-       "MOVW%C%S",     armdps, armfmov,        "(R%s%h%m),R%d",
-       "BIC%C%S",      armdps, 0,      "(R%s%h%m),R%n,R%d",
-       "MVN%C%S",      armdps, 0,      "(R%s%h%m),R%d",
-
-/* 32 */
-       "AND%C%S",      armdps, 0,      "(R%s%hR%M),R%n,R%d",
-       "EOR%C%S",      armdps, 0,      "(R%s%hR%M),R%n,R%d",
-       "SUB%C%S",      armdps, 0,      "(R%s%hR%M),R%n,R%d",
-       "RSB%C%S",      armdps, 0,      "(R%s%hR%M),R%n,R%d",
-       "ADD%C%S",      armdps, armfadd,        "(R%s%hR%M),R%n,R%d",
-       "ADC%C%S",      armdps, 0,      "(R%s%hR%M),R%n,R%d",
-       "SBC%C%S",      armdps, 0,      "(R%s%hR%M),R%n,R%d",
-       "RSC%C%S",      armdps, 0,      "(R%s%hR%M),R%n,R%d",
-       "TST%C%S",      armdps, 0,      "(R%s%hR%M),R%n",
-       "TEQ%C%S",      armdps, 0,      "(R%s%hR%M),R%n",
-       "CMP%C%S",      armdps, 0,      "(R%s%hR%M),R%n",
-       "CMN%C%S",      armdps, 0,      "(R%s%hR%M),R%n",
-       "ORR%C%S",      armdps, 0,      "(R%s%hR%M),R%n,R%d",
-       "MOVW%C%S",     armdps, armfmov,        "(R%s%hR%M),R%d",
-       "BIC%C%S",      armdps, 0,      "(R%s%hR%M),R%n,R%d",
-       "MVN%C%S",      armdps, 0,      "(R%s%hR%M),R%d",
-
-/* 48 */
-       "AND%C%S",      armdpi, 0,      "$#%i,R%n,R%d",
-       "EOR%C%S",      armdpi, 0,      "$#%i,R%n,R%d",
-       "SUB%C%S",      armdpi, 0,      "$#%i,R%n,R%d",
-       "RSB%C%S",      armdpi, 0,      "$#%i,R%n,R%d",
-       "ADD%C%S",      armdpi, armfadd,        "$#%i,R%n,R%d",
-       "ADC%C%S",      armdpi, 0,      "$#%i,R%n,R%d",
-       "SBC%C%S",      armdpi, 0,      "$#%i,R%n,R%d",
-       "RSC%C%S",      armdpi, 0,      "$#%i,R%n,R%d",
-       "TST%C%S",      armdpi, 0,      "$#%i,R%n",
-       "TEQ%C%S",      armdpi, 0,      "$#%i,R%n",
-       "CMP%C%S",      armdpi, 0,      "$#%i,R%n",
-       "CMN%C%S",      armdpi, 0,      "$#%i,R%n",
-       "ORR%C%S",      armdpi, 0,      "$#%i,R%n,R%d",
-       "MOVW%C%S",     armdpi, armfmov,        "$#%i,R%d",
-       "BIC%C%S",      armdpi, 0,      "$#%i,R%n,R%d",
-       "MVN%C%S",      armdpi, 0,      "$#%i,R%d",
-
-/* 48+16 */
-       "MUL%C%S",      armdpi, 0,      "R%s,R%M,R%n",
-       "MULA%C%S",     armdpi, 0,      "R%s,R%M,R%n,R%d",
-       "SWPW",         armdpi, 0,      "R%s,(R%n),R%d",
-       "SWPB",         armdpi, 0,      "R%s,(R%n),R%d",
-
-/* 48+16+4 */
-       "MOV%u%C%p",    armhwby, 0,     "R%d,(R%n%UR%M)",
-       "MOV%u%C%p",    armhwby, 0,     "R%d,%I",
-       "MOV%u%C%p",    armhwby, armfmov,       "(R%n%UR%M),R%d",
-       "MOV%u%C%p",    armhwby, armfmov,       "%I,R%d",
-
-/* 48+24 */
-       "MOVW%C%p",     armsdti, 0,     "R%d,%I",
-       "MOVB%C%p",     armsdti, 0,     "R%d,%I",
-       "MOVW%C%p",     armsdti, armfmov,       "%I,R%d",
-       "MOVBU%C%p",    armsdti, armfmov,       "%I,R%d",
-
-       "MOVW%C%p",     armsdts, 0,     "R%d,(R%s%h%m)(R%n)",
-       "MOVB%C%p",     armsdts, 0,     "R%d,(R%s%h%m)(R%n)",
-       "MOVW%C%p",     armsdts, armfmov,       "(R%s%h%m)(R%n),R%d",
-       "MOVBU%C%p",    armsdts, armfmov,       "(R%s%h%m)(R%n),R%d",
-
-       "MOVM%C%P%a",   armbdt, armfmovm,               "[%r],(R%n)",
-       "MOVM%C%P%a",   armbdt, armfmovm,               "(R%n),[%r]",
-
-       "B%C",          armb, armfbranch,               "%b",
-       "BL%C",         armb, armfbranch,               "%b",
-
-       "CDP%C",        armco, 0,               "",
-       "CDP%C",        armco, 0,               "",
-       "MCR%C",        armco, 0,               "",
-       "MRC%C",        armco, 0,               "",
-
-       "UNK",          armunk, 0,      "",
-};
-
-static void
-gaddr(Instr *i)
-{
-       *i->curr++ = '$';
-       i->curr += gsymoff(i->curr, i->end-i->curr, i->imm, CANY);
-}
-
-static char *mode[] = { 0, "IA", "DB", "IB" };
-static char *pw[] = { "P", "PW", 0, "W" };
-static char *sw[] = { 0, "W", "S", "SW" };
-
-static void
-format(char *mnemonic, Instr *i, char *f)
-{
-       int j, k, m, n;
-       int g;
-       char *fmt;
-
-       if(mnemonic)
-               format(0, i, mnemonic);
-       if(f == 0)
-               return;
-       if(mnemonic)
-               if(i->curr < i->end)
-                       *i->curr++ = '\t';
-       for ( ; *f && i->curr < i->end; f++) {
-               if(*f != '%') {
-                       *i->curr++ = *f;
-                       continue;
-               }
-               switch (*++f) {
-
-               case 'C':       /* .CONDITION */
-                       if(cond[i->cond])
-                               bprint(i, ".%s", cond[i->cond]);
-                       break;
-
-               case 'S':       /* .STORE */
-                       if(i->store)
-                               bprint(i, ".S");
-                       break;
-
-               case 'P':       /* P & U bits for block move */
-                       n = (i->w >>23) & 0x3;
-                       if (mode[n])
-                               bprint(i, ".%s", mode[n]);
-                       break;
-
-               case 'p':       /* P & W bits for single data xfer*/
-                       if (pw[i->store])
-                               bprint(i, ".%s", pw[i->store]);
-                       break;
-
-               case 'a':       /* S & W bits for single data xfer*/
-                       if (sw[i->store])
-                               bprint(i, ".%s", sw[i->store]);
-                       break;
-
-               case 's':
-                       bprint(i, "%d", i->rs & 0xf);
-                       break;
-
-               case 'M':
-                       bprint(i, "%d", (i->w>>8) & 0xf);
-                       break;
-
-               case 'm':
-                       bprint(i, "%d", (i->w>>7) & 0x1f);
-                       break;
-
-               case 'h':
-                       bprint(i, shtype[(i->w>>5) & 0x3]);
-                       break;
-
-               case 'u':               /* Signed/unsigned Byte/Halfword */
-                       bprint(i, hb[(i->w>>5) & 0x3]);
-                       break;
-
-               case 'I':
-                       if (i->rn == 13) {
-                               if (plocal(i))
-                                       break;
-                       }
-                       g = 0;
-                       fmt = "#%lx(R%d)";
-                       if (i->rn == 15) {
-                               /* convert load of offset(PC) to a load immediate */
-                               uint32 x;
-                               if (get4(i->map, i->addr+i->imm+8, &x) > 0)
-                               {
-                                       i->imm = (int32)x;
-                                       g = 1;
-                                       fmt = "";
-                               }
-                       }
-                       if (mach->sb)
-                       {
-                               if (i->rd == 11) {
-                                       uint32 nxti;
-
-                                       if (get4(i->map, i->addr+4, &nxti) > 0) {
-                                               if ((nxti & 0x0e0f0fff) == 0x060c000b) {
-                                                       i->imm += mach->sb;
-                                                       g = 1;
-                                                       fmt = "-SB";
-                                               }
-                                       }
-                               }
-                               if (i->rn == 12)
-                               {
-                                       i->imm += mach->sb;
-                                       g = 1;
-                                       fmt = "-SB(SB)";
-                               }
-                       }
-                       if (g)
-                       {
-                               gaddr(i);
-                               bprint(i, fmt, i->rn);
-                       }
-                       else
-                               bprint(i, fmt, i->imm, i->rn);
-                       break;
-               case 'U':               /* Add/subtract from base */
-                       bprint(i, addsub[(i->w >> 23) & 1]);
-                       break;
-
-               case 'n':
-                       bprint(i, "%d", i->rn);
-                       break;
-
-               case 'd':
-                       bprint(i, "%d", i->rd);
-                       break;
-
-               case 'i':
-                       bprint(i, "%lux", i->imm);
-                       break;
-
-               case 'b':
-                       i->curr += symoff(i->curr, i->end-i->curr,
-                               i->imm, CTEXT);
-                       break;
-
-               case 'g':
-                       i->curr += gsymoff(i->curr, i->end-i->curr,
-                               i->imm, CANY);
-                       break;
-
-               case 'r':
-                       n = i->imm&0xffff;
-                       j = 0;
-                       k = 0;
-                       while(n) {
-                               m = j;
-                               while(n&0x1) {
-                                       j++;
-                                       n >>= 1;
-                               }
-                               if(j != m) {
-                                       if(k)
-                                               bprint(i, ",");
-                                       if(j == m+1)
-                                               bprint(i, "R%d", m);
-                                       else
-                                               bprint(i, "R%d-R%d", m, j-1);
-                                       k = 1;
-                               }
-                               j++;
-                               n >>= 1;
-                       }
-                       break;
-
-               case '\0':
-                       *i->curr++ = '%';
-                       return;
-
-               default:
-                       bprint(i, "%%%c", *f);
-                       break;
-               }
-       }
-       *i->curr = 0;
-}
-
-static int
-printins(Map *map, ulong pc, char *buf, int n)
-{
-       Instr i;
-
-       i.curr = buf;
-       i.end = buf+n-1;
-       if(decode(map, pc, &i) < 0)
-               return -1;
-
-       (*opcodes[i.op].fmt)(&opcodes[i.op], &i);
-       return 4;
-}
-
-static int
-arminst(Map *map, uvlong pc, char modifier, char *buf, int n)
-{
-       USED(modifier);
-       return printins(map, pc, buf, n);
-}
-
-static int
-armdas(Map *map, uvlong pc, char *buf, int n)
-{
-       Instr i;
-
-       i.curr = buf;
-       i.end = buf+n;
-       if(decode(map, pc, &i) < 0)
-               return -1;
-       if(i.end-i.curr > 8)
-               i.curr = _hexify(buf, i.w, 7);
-       *i.curr = 0;
-       return 4;
-}
-
-static int
-arminstlen(Map *map, uvlong pc)
-{
-       Instr i;
-
-       if(decode(map, pc, &i) < 0)
-               return -1;
-       return 4;
-}
-
-static int
-armfoll(Map *map, uvlong pc, Rgetter rget, uvlong *foll)
-{
-       ulong d;
-       Instr i;
-
-       if(decode(map, pc, &i) < 0)
-               return -1;
-
-       if(opcodes[i.op].foll) {
-               d = (*opcodes[i.op].foll)(map, rget, &i, pc);
-               if(d == -1)
-                       return -1;
-       } else
-               d = pc+4;
-
-       foll[0] = d;
-       return 1;
-}
diff --git a/src/libmach/6.c b/src/libmach/6.c
deleted file mode 100644 (file)
index e87a9fa..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-// Inferno libmach/6.c
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/6.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-/*
- * amd64 definition
- */
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include "ureg_amd64.h"
-#include <mach.h>
-
-#define        REGOFF(x)       offsetof(struct UregAmd64, x)
-
-#define        REGSIZE         sizeof(struct UregAmd64)
-#define FP_CTLS(x)     (REGSIZE+2*(x))
-#define FP_CTL(x)      (REGSIZE+4*(x))
-#define FP_REG(x)      (FP_CTL(8)+16*(x))
-#define XM_REG(x)      (FP_CTL(8)+8*16+16*(x))
-
-#define        FPREGSIZE       512     /* TO DO? currently only 0x1A0 used */
-
-Reglist amd64reglist[] = {
-       {"AX",          REGOFF(ax),     RINT, 'Y'},
-       {"BX",          REGOFF(bx),     RINT, 'Y'},
-       {"CX",          REGOFF(cx),     RINT, 'Y'},
-       {"DX",          REGOFF(dx),     RINT, 'Y'},
-       {"SI",          REGOFF(si),     RINT, 'Y'},
-       {"DI",          REGOFF(di),     RINT, 'Y'},
-       {"BP",          REGOFF(bp),     RINT, 'Y'},
-       {"R8",          REGOFF(r8),     RINT, 'Y'},
-       {"R9",          REGOFF(r9),     RINT, 'Y'},
-       {"R10",         REGOFF(r10),    RINT, 'Y'},
-       {"R11",         REGOFF(r11),    RINT, 'Y'},
-       {"R12",         REGOFF(r12),    RINT, 'Y'},
-       {"R13",         REGOFF(r13),    RINT, 'Y'},
-       {"R14",         REGOFF(r14),    RINT, 'Y'},
-       {"R15",         REGOFF(r15),    RINT, 'Y'},
-       {"DS",          REGOFF(ds),     RINT, 'x'},
-       {"ES",          REGOFF(es),     RINT, 'x'},
-       {"FS",          REGOFF(fs),     RINT, 'x'},
-       {"GS",          REGOFF(gs),     RINT, 'x'},
-       {"TYPE",        REGOFF(type),   RINT, 'Y'},
-       {"TRAP",        REGOFF(type),   RINT, 'Y'},     /* alias for acid */
-       {"ERROR",       REGOFF(error),  RINT, 'Y'},
-       {"IP",          REGOFF(ip),     RINT, 'Y'},
-       {"PC",          REGOFF(ip),     RINT, 'Y'},     /* alias for acid */
-       {"CS",          REGOFF(cs),     RINT, 'Y'},
-       {"FLAGS",       REGOFF(flags),  RINT, 'Y'},
-       {"SP",          REGOFF(sp),     RINT, 'Y'},
-       {"SS",          REGOFF(ss),     RINT, 'Y'},
-
-       {"FCW",         FP_CTLS(0),     RFLT, 'x'},
-       {"FSW",         FP_CTLS(1),     RFLT, 'x'},
-       {"FTW",         FP_CTLS(2),     RFLT, 'b'},
-       {"FOP",         FP_CTLS(3),     RFLT, 'x'},
-       {"RIP",         FP_CTL(2),      RFLT, 'Y'},
-       {"RDP",         FP_CTL(4),      RFLT, 'Y'},
-       {"MXCSR",       FP_CTL(6),      RFLT, 'X'},
-       {"MXCSRMASK",   FP_CTL(7),      RFLT, 'X'},
-       {"M0",          FP_REG(0),      RFLT, 'F'},     /* assumes double */
-       {"M1",          FP_REG(1),      RFLT, 'F'},
-       {"M2",          FP_REG(2),      RFLT, 'F'},
-       {"M3",          FP_REG(3),      RFLT, 'F'},
-       {"M4",          FP_REG(4),      RFLT, 'F'},
-       {"M5",          FP_REG(5),      RFLT, 'F'},
-       {"M6",          FP_REG(6),      RFLT, 'F'},
-       {"M7",          FP_REG(7),      RFLT, 'F'},
-       {"X0",          XM_REG(0),      RFLT, 'F'},     /* assumes double */
-       {"X1",          XM_REG(1),      RFLT, 'F'},
-       {"X2",          XM_REG(2),      RFLT, 'F'},
-       {"X3",          XM_REG(3),      RFLT, 'F'},
-       {"X4",          XM_REG(4),      RFLT, 'F'},
-       {"X5",          XM_REG(5),      RFLT, 'F'},
-       {"X6",          XM_REG(6),      RFLT, 'F'},
-       {"X7",          XM_REG(7),      RFLT, 'F'},
-       {"X8",          XM_REG(8),      RFLT, 'F'},
-       {"X9",          XM_REG(9),      RFLT, 'F'},
-       {"X10",         XM_REG(10),     RFLT, 'F'},
-       {"X11",         XM_REG(11),     RFLT, 'F'},
-       {"X12",         XM_REG(12),     RFLT, 'F'},
-       {"X13",         XM_REG(13),     RFLT, 'F'},
-       {"X14",         XM_REG(14),     RFLT, 'F'},
-       {"X15",         XM_REG(15),     RFLT, 'F'},
-       {"X16",         XM_REG(16),     RFLT, 'F'},
-/*
-       {"F0",          FP_REG(7),      RFLT, '3'},
-       {"F1",          FP_REG(6),      RFLT, '3'},
-       {"F2",          FP_REG(5),      RFLT, '3'},
-       {"F3",          FP_REG(4),      RFLT, '3'},
-       {"F4",          FP_REG(3),      RFLT, '3'},
-       {"F5",          FP_REG(2),      RFLT, '3'},
-       {"F6",          FP_REG(1),      RFLT, '3'},
-       {"F7",          FP_REG(0),      RFLT, '3'},
-*/
-       {  0 }
-};
-
-Mach mamd64=
-{
-       "amd64",
-       MAMD64,                 /* machine type */
-       amd64reglist,           /* register list */
-       REGSIZE,                /* size of registers in bytes */
-       FPREGSIZE,              /* size of fp registers in bytes */
-       "PC",                   /* name of PC */
-       "SP",                   /* name of SP */
-       0,                      /* link register */
-       "setSB",                /* static base register name (bogus anyways) */
-       0,                      /* static base register value */
-       0x1000,                 /* page size */
-       0xFFFFFFFF80110000ULL,  /* kernel base */
-       0xFFFF800000000000ULL,  /* kernel text mask */
-       0x00007FFFFFFFF000ULL,  /* user stack top */
-       1,                      /* quantization of pc */
-       8,                      /* szaddr */
-       4,                      /* szreg */
-       4,                      /* szfloat */
-       8,                      /* szdouble */
-};
diff --git a/src/libmach/8.c b/src/libmach/8.c
deleted file mode 100644 (file)
index c0a0818..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-// Inferno libmach/8.c
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/8.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-/*
- * 386 definition
- */
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <ureg_x86.h>
-#include <mach.h>
-
-#define        REGOFF(x)       (uintptr)(&((struct Ureg386 *) 0)->x)
-
-#define PC             REGOFF(pc)
-#define SP             REGOFF(sp)
-#define        AX              REGOFF(ax)
-
-#define        REGSIZE         sizeof(struct Ureg386)
-#define FP_CTL(x)      (REGSIZE+4*(x))
-#define FP_REG(x)      (FP_CTL(7)+10*(x))
-#define        FPREGSIZE       (7*4+8*10)
-
-Reglist i386reglist[] = {
-       {"DI",          REGOFF(di),     RINT, 'X'},
-       {"SI",          REGOFF(si),     RINT, 'X'},
-       {"BP",          REGOFF(bp),     RINT, 'X'},
-       {"BX",          REGOFF(bx),     RINT, 'X'},
-       {"DX",          REGOFF(dx),     RINT, 'X'},
-       {"CX",          REGOFF(cx),     RINT, 'X'},
-       {"AX",          REGOFF(ax),     RINT, 'X'},
-       {"GS",          REGOFF(gs),     RINT, 'X'},
-       {"FS",          REGOFF(fs),     RINT, 'X'},
-       {"ES",          REGOFF(es),     RINT, 'X'},
-       {"DS",          REGOFF(ds),     RINT, 'X'},
-       {"TRAP",        REGOFF(trap),   RINT, 'X'},
-       {"ECODE",       REGOFF(ecode),  RINT, 'X'},
-       {"PC",          PC,             RINT, 'X'},
-       {"CS",          REGOFF(cs),     RINT, 'X'},
-       {"EFLAGS",      REGOFF(flags),  RINT, 'X'},
-       {"SP",          SP,             RINT, 'X'},
-       {"SS",          REGOFF(ss),     RINT, 'X'},
-
-       {"E0",          FP_CTL(0),      RFLT, 'X'},
-       {"E1",          FP_CTL(1),      RFLT, 'X'},
-       {"E2",          FP_CTL(2),      RFLT, 'X'},
-       {"E3",          FP_CTL(3),      RFLT, 'X'},
-       {"E4",          FP_CTL(4),      RFLT, 'X'},
-       {"E5",          FP_CTL(5),      RFLT, 'X'},
-       {"E6",          FP_CTL(6),      RFLT, 'X'},
-       {"F0",          FP_REG(0),      RFLT, '3'},
-       {"F1",          FP_REG(1),      RFLT, '3'},
-       {"F2",          FP_REG(2),      RFLT, '3'},
-       {"F3",          FP_REG(3),      RFLT, '3'},
-       {"F4",          FP_REG(4),      RFLT, '3'},
-       {"F5",          FP_REG(5),      RFLT, '3'},
-       {"F6",          FP_REG(6),      RFLT, '3'},
-       {"F7",          FP_REG(7),      RFLT, '3'},
-       {  0 }
-};
-
-Mach mi386 =
-{
-       "386",
-       MI386,          /* machine type */
-       i386reglist,    /* register list */
-       REGSIZE,        /* size of registers in bytes */
-       FPREGSIZE,      /* size of fp registers in bytes */
-       "PC",           /* name of PC */
-       "SP",           /* name of SP */
-       0,              /* link register */
-       "setSB",        /* static base register name (bogus anyways) */
-       0,              /* static base register value */
-       0x1000,         /* page size */
-       0x80100000ULL,  /* kernel base */
-       0xF0000000ULL,  /* kernel text mask */
-       0xFFFFFFFFULL,  /* user stack top */
-       1,              /* quantization of pc */
-       4,              /* szaddr */
-       4,              /* szreg */
-       4,              /* szfloat */
-       8,              /* szdouble */
-};
diff --git a/src/libmach/8db.c b/src/libmach/8db.c
deleted file mode 100644 (file)
index e537006..0000000
+++ /dev/null
@@ -1,2443 +0,0 @@
-// Inferno libmach/8db.c
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/8db.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mach.h>
-#include <ureg_amd64.h>
-#include <ureg_x86.h>
-
-/*
- * i386-specific debugger interface
- * also amd64 extensions
- */
-
-static char    *i386excep(Map*, Rgetter);
-
-static int     i386trace(Map*, uvlong, uvlong, uvlong, Tracer);
-static uvlong  i386frame(Map*, uvlong, uvlong, uvlong, uvlong);
-static int     i386foll(Map*, uvlong, Rgetter, uvlong*);
-static int     i386inst(Map*, uvlong, char, char*, int);
-static int     i386das(Map*, uvlong, char*, int);
-static int     i386instlen(Map*, uvlong);
-
-static char    STARTSYM[] =    "_main";
-static char    GOSTARTSYM[] =  "sys·goexit";
-static char    PROFSYM[] =     "_mainp";
-static char    FRAMENAME[] =   ".frame";
-static char    LESSSTACK[] = "sys·lessstack";
-static char    MORESTACK[] = "sys·morestack";
-static char *excname[] =
-{
-[0] =  "divide error",
-[1] =  "debug exception",
-[4] =  "overflow",
-[5] =  "bounds check",
-[6] =  "invalid opcode",
-[7] =  "math coprocessor emulation",
-[8] =  "double fault",
-[9] =  "math coprocessor overrun",
-[10] = "invalid TSS",
-[11] = "segment not present",
-[12] = "stack exception",
-[13] = "general protection violation",
-[14] = "page fault",
-[16] = "math coprocessor error",
-[17] = "alignment check",
-[18] = "machine check",
-[19] = "floating-point exception",
-[24] = "clock",
-[25] = "keyboard",
-[27] = "modem status",
-[28] = "serial line status",
-[30] = "floppy disk",
-[36] = "mouse",
-[37] = "math coprocessor",
-[38] = "hard disk",
-[64] = "system call",
-};
-
-Machdata i386mach =
-{
-       {0xCC, 0, 0, 0},        /* break point: INT 3 */
-       1,                      /* break point size */
-
-       leswab,                 /* convert short to local byte order */
-       leswal,                 /* convert int32 to local byte order */
-       leswav,                 /* convert vlong to local byte order */
-       i386trace,              /* C traceback */
-       i386frame,              /* frame finder */
-       i386excep,              /* print exception */
-       0,                      /* breakpoint fixup */
-       leieeesftos,            /* single precision float printer */
-       leieeedftos,            /* double precision float printer */
-       i386foll,               /* following addresses */
-       i386inst,               /* print instruction */
-       i386das,                /* dissembler */
-       i386instlen,            /* instruction size calculation */
-};
-
-static char*
-i386excep(Map *map, Rgetter rget)
-{
-       uint32 c;
-       uvlong pc;
-       static char buf[16];
-
-       c = (*rget)(map, "TRAP");
-       if(c > 64 || excname[c] == 0) {
-               if (c == 3) {
-                       pc = (*rget)(map, "PC");
-                       if (get1(map, pc, (uchar*)buf, machdata->bpsize) > 0)
-                       if (memcmp(buf, machdata->bpinst, machdata->bpsize) == 0)
-                               return "breakpoint";
-               }
-               snprint(buf, sizeof(buf), "exception %d", c);
-               return buf;
-       } else
-               return excname[c];
-}
-
-static int
-i386trace(Map *map, uvlong pc, uvlong sp, uvlong link, Tracer trace)
-{
-       int i;
-       uvlong osp, pc1;
-       Symbol s, f, s1;
-       extern Mach mamd64;
-       int isamd64;
-       uvlong g, m, lessstack, morestack, stktop;
-
-       isamd64 = (mach == &mamd64);
-
-       // ../pkg/runtime/runtime.h
-       // G is
-       //      byte* stackguard
-       //      byte* stackbase (= Stktop*)
-       // TODO(rsc): Need some way to get at the g for other threads.
-       // Probably need to pass it into the trace function.
-       g = 0;
-       if(isamd64)
-               geta(map, offsetof(struct UregAmd64, r15), &g);
-       else {
-               // TODO(rsc): How to fetch g on 386?
-       }
-       stktop = 0;
-       if(g != 0)
-               geta(map, g+1*mach->szaddr, &stktop);
-
-       lessstack = 0;
-       if(lookup(0, LESSSTACK, &s))
-               lessstack = s.value;
-       morestack = 0;
-       if(lookup(0, MORESTACK, &s))
-               morestack = s.value;
-
-       USED(link);
-       osp = 0;
-       i = 0;
-
-       for(;;) {
-               if(!findsym(pc, CTEXT, &s)) {
-                       // check for closure return sequence
-                       uchar buf[8], *p;
-                       if(get1(map, pc, buf, 8) < 0)
-                               break;
-                       // ADDQ $xxx, SP; RET
-                       p = buf;
-                       if(mach == &mamd64) {
-                               if(p[0] != 0x48)
-                                       break;
-                               p++;
-                       }
-                       if(p[0] != 0x81 || p[1] != 0xc4 || p[6] != 0xc3)
-                               break;
-                       sp += p[2] | (p[3]<<8) | (p[4]<<16) | (p[5]<<24);
-                       if(geta(map, sp, &pc) < 0)
-                               break;
-                       sp += mach->szaddr;
-                       continue;
-               }
-
-               if (osp == sp)
-                       break;
-               osp = sp;
-
-               if(strcmp(STARTSYM, s.name) == 0 ||
-                  strcmp(GOSTARTSYM, s.name) == 0 ||
-                  strcmp(PROFSYM, s.name) == 0)
-                       break;
-
-               if(s.value == morestack) {
-                       if (0) {
-                               // This code is old and won't work anymore.
-                               // But no one uses it anyway.
-                               // Leave it obviously broken until someone needs it.
-                               // In the middle of morestack.
-                               // Caller is m->morepc.
-                               // Caller's caller is in m->morearg.
-                               // TODO(rsc): 386
-                               geta(map, offsetof(struct UregAmd64, r14), &m);
-       
-                               pc = 0;
-                               sp = 0;
-                               pc1 = 0;
-                               s1 = s;
-                               memset(&s, 0, sizeof s);
-                               geta(map, m+1*mach->szaddr, &pc1);      // m->morepc
-                               geta(map, m+2*mach->szaddr, &sp);       // m->morebuf.sp
-                               geta(map, m+3*mach->szaddr, &pc);       // m->morebuf.pc
-                               findsym(pc1, CTEXT, &s);
-                               (*trace)(map, pc1, sp-mach->szaddr, &s1);       // morestack symbol; caller's PC/SP
-       
-                               // caller's caller
-                               s1 = s;
-                               findsym(pc, CTEXT, &s);
-                               (*trace)(map, pc, sp, &s1);             // morestack's caller; caller's caller's PC/SP
-                               continue;
-                       } else {
-                               werrstr("morestack not implemented correctly");
-                               return -1;
-                       }
-               }
-
-               if(pc == lessstack) {
-                       // ../pkg/runtime/runtime.h
-                       // Stktop is
-                       //      byte* stackguard
-                       //      byte* stackbase
-                       //      Gobuf gobuf
-                       //              byte* sp;
-                       //              byte* pc;
-                       //              G*      g;
-                       if(!isamd64)
-                               fprint(2, "warning: cannot unwind stack split on 386\n");
-                       if(stktop == 0)
-                               break;
-                       pc = 0;
-                       sp = 0;
-                       geta(map, stktop+2*mach->szaddr, &sp);
-                       geta(map, stktop+3*mach->szaddr, &pc);
-                       geta(map, stktop+1*mach->szaddr, &stktop);
-                       (*trace)(map, pc, sp, &s1);
-                       continue;
-               }
-
-               s1 = s;
-               pc1 = 0;
-               if(pc != s.value) {     /* not at first instruction */
-                       if(findlocal(&s, FRAMENAME, &f) == 0)
-                               break;
-                       geta(map, sp, &pc1);
-                       sp += f.value-mach->szaddr;
-               }
-               if(geta(map, sp, &pc) < 0)
-                       break;
-
-               // If PC is not valid, assume we caught the function
-               // before it moved the stack pointer down or perhaps
-               // after it moved the stack pointer back up.
-               // Try the PC we'd have gotten without the stack
-               // pointer adjustment above (pc != s.value).
-               // This only matters for the first frame, and it is only
-               // a heuristic, but it does help.
-               if(!findsym(pc, CTEXT, &s) || strcmp(s.name, "etext") == 0)
-                       pc = pc1;
-
-               if(pc == 0)
-                       break;
-
-               if(pc != lessstack)
-                       (*trace)(map, pc, sp, &s1);
-               sp += mach->szaddr;
-
-               if(++i > 1000)
-                       break;
-       }
-       return i;
-}
-
-static uvlong
-i386frame(Map *map, uvlong addr, uvlong pc, uvlong sp, uvlong link)
-{
-       Symbol s, f;
-
-       USED(link);
-       while (findsym(pc, CTEXT, &s)) {
-               if(strcmp(STARTSYM, s.name) == 0 || strcmp(PROFSYM, s.name) == 0)
-                       break;
-
-               if(pc != s.value) {     /* not first instruction */
-                       if(findlocal(&s, FRAMENAME, &f) == 0)
-                               break;
-                       sp += f.value-mach->szaddr;
-               }
-
-               if (s.value == addr)
-                       return sp;
-
-               if (geta(map, sp, &pc) < 0)
-                       break;
-               sp += mach->szaddr;
-       }
-       return 0;
-}
-
-       /* I386/486 - Disassembler and related functions */
-
-/*
- *  an instruction
- */
-typedef struct Instr Instr;
-struct Instr
-{
-       uchar   mem[1+1+1+1+2+1+1+4+4];         /* raw instruction */
-       uvlong  addr;           /* address of start of instruction */
-       int     n;              /* number of bytes in instruction */
-       char    *prefix;        /* instr prefix */
-       char    *segment;       /* segment override */
-       uchar   jumptype;       /* set to the operand type for jump/ret/call */
-       uchar   amd64;
-       uchar   rex;            /* REX prefix (or zero) */
-       char    osize;          /* 'W' or 'L' (or 'Q' on amd64) */
-       char    asize;          /* address size 'W' or 'L' (or 'Q' or amd64) */
-       uchar   mod;            /* bits 6-7 of mod r/m field */
-       uchar   reg;            /* bits 3-5 of mod r/m field */
-       char    ss;             /* bits 6-7 of SIB */
-       schar   index;          /* bits 3-5 of SIB */
-       schar   base;           /* bits 0-2 of SIB */
-       char    rip;            /* RIP-relative in amd64 mode */
-       uchar   opre;           /* f2/f3 could introduce media */
-       short   seg;            /* segment of far address */
-       uint32  disp;           /* displacement */
-       uint32  imm;            /* immediate */
-       uint32  imm2;           /* second immediate operand */
-       uvlong  imm64;          /* big immediate */
-       char    *curr;          /* fill level in output buffer */
-       char    *end;           /* end of output buffer */
-       char    *err;           /* error message */
-};
-
-       /* 386 register (ha!) set */
-enum{
-       AX=0,
-       CX,
-       DX,
-       BX,
-       SP,
-       BP,
-       SI,
-       DI,
-
-       /* amd64 */
-       /* be careful: some unix system headers #define R8, R9, etc */
-       AMD64_R8,
-       AMD64_R9,
-       AMD64_R10,
-       AMD64_R11,
-       AMD64_R12,
-       AMD64_R13,
-       AMD64_R14,
-       AMD64_R15
-};
-
-       /* amd64 rex extension byte */
-enum{
-       REXW            = 1<<3, /* =1, 64-bit operand size */
-       REXR            = 1<<2, /* extend modrm reg */
-       REXX            = 1<<1, /* extend sib index */
-       REXB            = 1<<0  /* extend modrm r/m, sib base, or opcode reg */
-};
-
-       /* Operand Format codes */
-/*
-%A     -       address size register modifier (!asize -> 'E')
-%C     -       Control register CR0/CR1/CR2
-%D     -       Debug register DR0/DR1/DR2/DR3/DR6/DR7
-%I     -       second immediate operand
-%O     -       Operand size register modifier (!osize -> 'E')
-%T     -       Test register TR6/TR7
-%S     -       size code ('W' or 'L')
-%W     -       Weird opcode: OSIZE == 'W' => "CBW"; else => "CWDE"
-%d     -       displacement 16-32 bits
-%e     -       effective address - Mod R/M value
-%f     -       floating point register F0-F7 - from Mod R/M register
-%g     -       segment register
-%i     -       immediate operand 8-32 bits
-%p     -       PC-relative - signed displacement in immediate field
-%r     -       Reg from Mod R/M
-%w     -       Weird opcode: OSIZE == 'W' => "CWD"; else => "CDQ"
-*/
-
-typedef struct Optable Optable;
-struct Optable
-{
-       char    operand[2];
-       void    *proto;         /* actually either (char*) or (Optable*) */
-};
-       /* Operand decoding codes */
-enum {
-       Ib = 1,                 /* 8-bit immediate - (no sign extension)*/
-       Ibs,                    /* 8-bit immediate (sign extended) */
-       Jbs,                    /* 8-bit sign-extended immediate in jump or call */
-       Iw,                     /* 16-bit immediate -> imm */
-       Iw2,                    /* 16-bit immediate -> imm2 */
-       Iwd,                    /* Operand-sized immediate (no sign extension)*/
-       Iwdq,                   /* Operand-sized immediate, possibly 64 bits */
-       Awd,                    /* Address offset */
-       Iwds,                   /* Operand-sized immediate (sign extended) */
-       RM,                     /* Word or int32 R/M field with register (/r) */
-       RMB,                    /* Byte R/M field with register (/r) */
-       RMOP,                   /* Word or int32 R/M field with op code (/digit) */
-       RMOPB,                  /* Byte R/M field with op code (/digit) */
-       RMR,                    /* R/M register only (mod = 11) */
-       RMM,                    /* R/M memory only (mod = 0/1/2) */
-       Op_R0,                  /* Base reg of Mod R/M is literal 0x00 */
-       Op_R1,                  /* Base reg of Mod R/M is literal 0x01 */
-       FRMOP,                  /* Floating point R/M field with opcode */
-       FRMEX,                  /* Extended floating point R/M field with opcode */
-       JUMP,                   /* Jump or Call flag - no operand */
-       RET,                    /* Return flag - no operand */
-       OA,                     /* literal 0x0a byte */
-       PTR,                    /* Seg:Displacement addr (ptr16:16 or ptr16:32) */
-       AUX,                    /* Multi-byte op code - Auxiliary table */
-       AUXMM,                  /* multi-byte op code - auxiliary table chosen by prefix */
-       PRE,                    /* Instr Prefix */
-       OPRE,                   /* Instr Prefix or media op extension */
-       SEG,                    /* Segment Prefix */
-       OPOVER,                 /* Operand size override */
-       ADDOVER,                /* Address size override */
-};
-
-static Optable optab0F00[8]=
-{
-[0x00] =       { 0,0,          "MOVW   LDT,%e" },
-[0x01] =       { 0,0,          "MOVW   TR,%e" },
-[0x02] =       { 0,0,          "MOVW   %e,LDT" },
-[0x03] =       { 0,0,          "MOVW   %e,TR" },
-[0x04] =       { 0,0,          "VERR   %e" },
-[0x05] =       { 0,0,          "VERW   %e" },
-};
-
-static Optable optab0F01[8]=
-{
-[0x00] =       { 0,0,          "MOVL   GDTR,%e" },
-[0x01] =       { 0,0,          "MOVL   IDTR,%e" },
-[0x02] =       { 0,0,          "MOVL   %e,GDTR" },
-[0x03] =       { 0,0,          "MOVL   %e,IDTR" },
-[0x04] =       { 0,0,          "MOVW   MSW,%e" },      /* word */
-[0x06] =       { 0,0,          "MOVW   %e,MSW" },      /* word */
-[0x07] =       { 0,0,          "INVLPG %e" },          /* or SWAPGS */
-};
-
-static Optable optab0F01F8[1]=
-{
-[0x00] =       { 0,0,          "SWAPGS" },
-};
-
-/* 0F71 */
-/* 0F72 */
-/* 0F73 */
-
-static Optable optab0FAE[8]=
-{
-[0x00] =       { 0,0,          "FXSAVE %e" },
-[0x01] =       { 0,0,          "FXRSTOR        %e" },
-[0x02] =       { 0,0,          "LDMXCSR        %e" },
-[0x03] =       { 0,0,          "STMXCSR        %e" },
-[0x05] =       { 0,0,          "LFENCE" },
-[0x06] =       { 0,0,          "MFENCE" },
-[0x07] =       { 0,0,          "SFENCE" },
-};
-
-static Optable optab0F18[4]=
-{
-[0x00] =       { 0,0,          "PREFETCHNTA    %e" },
-[0x01] =       { 0,0,          "PREFECTCH0     %e" },
-[0x02] =       { 0,0,          "PREFECTCH1     %e" },
-[0x03] =       { 0,0,          "PREFECTCH2     %e" },
-};
-
-/* 0F0D */
-
-static Optable optab0FBA[8]=
-{
-[0x04] =       { Ib,0,         "BT%S   %i,%e" },
-[0x05] =       { Ib,0,         "BTS%S  %i,%e" },
-[0x06] =       { Ib,0,         "BTR%S  %i,%e" },
-[0x07] =       { Ib,0,         "BTC%S  %i,%e" },
-};
-
-static Optable optab0F0F[256]=
-{
-[0x0c] =       { 0,0,          "PI2FW  %m,%M" },
-[0x0d] =       { 0,0,          "PI2L   %m,%M" },
-[0x1c] =       { 0,0,          "PF2IW  %m,%M" },
-[0x1d] =       { 0,0,          "PF2IL  %m,%M" },
-[0x8a] =       { 0,0,          "PFNACC %m,%M" },
-[0x8e] =       { 0,0,          "PFPNACC        %m,%M" },
-[0x90] =       { 0,0,          "PFCMPGE        %m,%M" },
-[0x94] =       { 0,0,          "PFMIN  %m,%M" },
-[0x96] =       { 0,0,          "PFRCP  %m,%M" },
-[0x97] =       { 0,0,          "PFRSQRT        %m,%M" },
-[0x9a] =       { 0,0,          "PFSUB  %m,%M" },
-[0x9e] =       { 0,0,          "PFADD  %m,%M" },
-[0xa0] =       { 0,0,          "PFCMPGT        %m,%M" },
-[0xa4] =       { 0,0,          "PFMAX  %m,%M" },
-[0xa6] =       { 0,0,          "PFRCPIT1       %m,%M" },
-[0xa7] =       { 0,0,          "PFRSQIT1       %m,%M" },
-[0xaa] =       { 0,0,          "PFSUBR %m,%M" },
-[0xae] =       { 0,0,          "PFACC  %m,%M" },
-[0xb0] =       { 0,0,          "PFCMPEQ        %m,%M" },
-[0xb4] =       { 0,0,          "PFMUL  %m,%M" },
-[0xb6] =       { 0,0,          "PFRCPI2T       %m,%M" },
-[0xb7] =       { 0,0,          "PMULHRW        %m,%M" },
-[0xbb] =       { 0,0,          "PSWAPL %m,%M" },
-};
-
-static Optable optab0FC7[8]=
-{
-[0x01] =       { 0,0,          "CMPXCHG8B      %e" },
-};
-
-static Optable optab660F38[256]=
-{
-[0x00] =       { RM,0,         "PSHUFB %x,%X" },
-[0xdc] =       { RM,0,         "AESENC %x,%X" },
-[0xdb] =       { RM,0,         "AESIMC %x,%X," },
-[0xdd] =       { RM,0,         "AESENCLAST     %x,%X" },
-[0xde] =       { RM,0,         "AESDEC %x,%X" },
-[0xdf] =       { RM,0,         "AESDECLAST     %x,%X" },
-};
-
-static Optable optab660F3A[256]=
-{
-[0x22] =       { RM,Ib,                "PINSR%S        %i,%e,%X" },
-[0xdf] =       { RM,Ib,                "AESKEYGENASSIST        %i,%x,%X" },
-};
-
-static Optable optab660F71[8]=
-{
-[0x02] =       { Ib,0,         "PSRLW  %i,%X" },
-[0x04] =       { Ib,0,         "PSRAW  %i,%X" },
-[0x06] =       { Ib,0,         "PSLLW  %i,%X" },
-};
-
-static Optable optab660F72[8]=
-{
-[0x02] =       { Ib,0,         "PSRLL  %i,%X" },
-[0x04] =       { Ib,0,         "PSRAL  %i,%X" },
-[0x06] =       { Ib,0,         "PSLLL  %i,%X" },
-};
-
-static Optable optab660F73[8]=
-{
-[0x02] =       { Ib,0,         "PSRLQ  %i,%X" },
-[0x03] =       { Ib,0,         "PSRLO  %i,%X" },
-[0x06] =       { Ib,0,         "PSLLQ  %i,%X" },
-[0x07] =       { Ib,0,         "PSLLO  %i,%X" },
-};
-
-static Optable optab660F[256]=
-{
-[0x2B] =       { RM,0,         "MOVNTPD        %x,%e" },
-[0x2E] =       { RM,0,         "UCOMISD        %x,%X" },
-[0x2F] =       { RM,0,         "COMISD %x,%X" },
-[0x38] =       { AUX,0,                optab660F38 },
-[0x3A] =       { AUX,0,                optab660F3A },
-[0x5A] =       { RM,0,         "CVTPD2PS       %x,%X" },
-[0x5B] =       { RM,0,         "CVTPS2PL       %x,%X" },
-[0x6A] =       { RM,0,         "PUNPCKHLQ      %x,%X" },
-[0x6B] =       { RM,0,         "PACKSSLW       %x,%X" },
-[0x6C] =       { RM,0,         "PUNPCKLQDQ     %x,%X" },
-[0x6D] =       { RM,0,         "PUNPCKHQDQ     %x,%X" },
-[0x6E] =       { RM,0,         "MOV%S  %e,%X" },
-[0x6F] =       { RM,0,         "MOVO   %x,%X" },               /* MOVDQA */
-[0x70] =       { RM,Ib,                "PSHUFL %i,%x,%X" },
-[0x71] =       { RMOP,0,               optab660F71 },
-[0x72] =       { RMOP,0,               optab660F72 },
-[0x73] =       { RMOP,0,               optab660F73 },
-[0x7E] =       { RM,0,         "MOV%S  %X,%e" },
-[0x7F] =       { RM,0,         "MOVO   %X,%x" },
-[0xC4] =       { RM,Ib,                "PINSRW %i,%e,%X" },
-[0xC5] =       { RMR,Ib,               "PEXTRW %i,%X,%e" },
-[0xD4] =       { RM,0,         "PADDQ  %x,%X" },
-[0xD5] =       { RM,0,         "PMULLW %x,%X" },
-[0xD6] =       { RM,0,         "MOVQ   %X,%x" },
-[0xE6] =       { RM,0,         "CVTTPD2PL      %x,%X" },
-[0xE7] =       { RM,0,         "MOVNTO %X,%e" },
-[0xF7] =       { RM,0,         "MASKMOVOU      %x,%X" },
-};
-
-static Optable optabF20F38[256]=
-{
-[0xf0] =       { RM,0,         "CRC32B %e, %r" },
-[0xf1] =       { RM,0,         "CRC32%S        %e, %r" },
-};
-
-static Optable optabF20F[256]=
-{
-[0x10] =       { RM,0,         "MOVSD  %x,%X" },
-[0x11] =       { RM,0,         "MOVSD  %X,%x" },
-[0x2A] =       { RM,0,         "CVTS%S2SD      %e,%X" },
-[0x2C] =       { RM,0,         "CVTTSD2S%S     %x,%r" },
-[0x2D] =       { RM,0,         "CVTSD2S%S      %x,%r" },
-[0x38] =       { AUX,0,                optabF20F38 },
-[0x5A] =       { RM,0,         "CVTSD2SS       %x,%X" },
-[0x6F] =       { RM,0,         "MOVOU  %x,%X" },
-[0x70] =       { RM,Ib,                "PSHUFLW        %i,%x,%X" },
-[0x7F] =       { RM,0,         "MOVOU  %X,%x" },
-[0xD6] =       { RM,0,         "MOVQOZX        %M,%X" },
-[0xE6] =       { RM,0,         "CVTPD2PL       %x,%X" },
-};
-
-static Optable optabF30F[256]=
-{
-[0x10] =       { RM,0,         "MOVSS  %x,%X" },
-[0x11] =       { RM,0,         "MOVSS  %X,%x" },
-[0x2A] =       { RM,0,         "CVTS%S2SS      %e,%X" },
-[0x2C] =       { RM,0,         "CVTTSS2S%S     %x,%r" },
-[0x2D] =       { RM,0,         "CVTSS2S%S      %x,%r" },
-[0x5A] =       { RM,0,         "CVTSS2SD       %x,%X" },
-[0x5B] =       { RM,0,         "CVTTPS2PL      %x,%X" },
-[0x6F] =       { RM,0,         "MOVOU  %x,%X" },
-[0x70] =       { RM,Ib,                "PSHUFHW        %i,%x,%X" },
-[0x7E] =       { RM,0,         "MOVQOZX        %x,%X" },
-[0x7F] =       { RM,0,         "MOVOU  %X,%x" },
-[0xD6] =       { RM,0,         "MOVQOZX        %m*,%X" },
-[0xE6] =       { RM,0,         "CVTPL2PD       %x,%X" },
-};
-
-static Optable optab0F[256]=
-{
-[0x00] =       { RMOP,0,               optab0F00 },
-[0x01] =       { RMOP,0,               optab0F01 },
-[0x02] =       { RM,0,         "LAR    %e,%r" },
-[0x03] =       { RM,0,         "LSL    %e,%r" },
-[0x05] =       { 0,0,          "SYSCALL" },
-[0x06] =       { 0,0,          "CLTS" },
-[0x07] =       { 0,0,          "SYSRET" },
-[0x08] =       { 0,0,          "INVD" },
-[0x09] =       { 0,0,          "WBINVD" },
-[0x0B] =       { 0,0,          "UD2" },
-[0x0F] =       { RM,AUX,               optab0F0F },            /* 3DNow! */
-[0x10] =       { RM,0,         "MOVU%s %x,%X" },
-[0x11] =       { RM,0,         "MOVU%s %X,%x" },
-[0x12] =       { RM,0,         "MOV[H]L%s      %x,%X" },       /* TO DO: H if source is XMM */
-[0x13] =       { RM,0,         "MOVL%s %X,%e" },
-[0x14] =       { RM,0,         "UNPCKL%s       %x,%X" },
-[0x15] =       { RM,0,         "UNPCKH%s       %x,%X" },
-[0x16] =       { RM,0,         "MOV[L]H%s      %x,%X" },       /* TO DO: L if source is XMM */
-[0x17] =       { RM,0,         "MOVH%s %X,%x" },
-[0x18] =       { RMOP,0,               optab0F18 },
-[0x1F] =       { RM,0,         "NOP%S  %e" },
-[0x20] =       { RMR,0,                "MOVL   %C,%e" },
-[0x21] =       { RMR,0,                "MOVL   %D,%e" },
-[0x22] =       { RMR,0,                "MOVL   %e,%C" },
-[0x23] =       { RMR,0,                "MOVL   %e,%D" },
-[0x24] =       { RMR,0,                "MOVL   %T,%e" },
-[0x26] =       { RMR,0,                "MOVL   %e,%T" },
-[0x28] =       { RM,0,         "MOVA%s %x,%X" },
-[0x29] =       { RM,0,         "MOVA%s %X,%x" },
-[0x2A] =       { RM,0,         "CVTPL2%s       %m*,%X" },
-[0x2B] =       { RM,0,         "MOVNT%s        %X,%e" },
-[0x2C] =       { RM,0,         "CVTT%s2PL      %x,%M" },
-[0x2D] =       { RM,0,         "CVT%s2PL       %x,%M" },
-[0x2E] =       { RM,0,         "UCOMISS        %x,%X" },
-[0x2F] =       { RM,0,         "COMISS %x,%X" },
-[0x30] =       { 0,0,          "WRMSR" },
-[0x31] =       { 0,0,          "RDTSC" },
-[0x32] =       { 0,0,          "RDMSR" },
-[0x33] =       { 0,0,          "RDPMC" },
-[0x42] =       { RM,0,         "CMOVC  %e,%r" },               /* CF */
-[0x43] =       { RM,0,         "CMOVNC %e,%r" },               /* ¬ CF */
-[0x44] =       { RM,0,         "CMOVZ  %e,%r" },               /* ZF */
-[0x45] =       { RM,0,         "CMOVNZ %e,%r" },               /* ¬ ZF */
-[0x46] =       { RM,0,         "CMOVBE %e,%r" },               /* CF ∨ ZF */
-[0x47] =       { RM,0,         "CMOVA  %e,%r" },               /* ¬CF ∧ ¬ZF */
-[0x48] =       { RM,0,         "CMOVS  %e,%r" },               /* SF */
-[0x49] =       { RM,0,         "CMOVNS %e,%r" },               /* ¬ SF */
-[0x4A] =       { RM,0,         "CMOVP  %e,%r" },               /* PF */
-[0x4B] =       { RM,0,         "CMOVNP %e,%r" },               /* ¬ PF */
-[0x4C] =       { RM,0,         "CMOVLT %e,%r" },               /* LT ≡ OF ≠ SF */
-[0x4D] =       { RM,0,         "CMOVGE %e,%r" },               /* GE ≡ ZF ∨ SF */
-[0x4E] =       { RM,0,         "CMOVLE %e,%r" },               /* LE ≡ ZF ∨ LT */
-[0x4F] =       { RM,0,         "CMOVGT %e,%r" },               /* GT ≡ ¬ZF ∧ GE */
-[0x50] =       { RM,0,         "MOVMSK%s       %X,%r" },       /* TO DO: check */
-[0x51] =       { RM,0,         "SQRT%s %x,%X" },
-[0x52] =       { RM,0,         "RSQRT%s        %x,%X" },
-[0x53] =       { RM,0,         "RCP%s  %x,%X" },
-[0x54] =       { RM,0,         "AND%s  %x,%X" },
-[0x55] =       { RM,0,         "ANDN%s %x,%X" },
-[0x56] =       { RM,0,         "OR%s   %x,%X" },               /* TO DO: S/D */
-[0x57] =       { RM,0,         "XOR%s  %x,%X" },               /* S/D */
-[0x58] =       { RM,0,         "ADD%s  %x,%X" },               /* S/P S/D */
-[0x59] =       { RM,0,         "MUL%s  %x,%X" },
-[0x5A] =       { RM,0,         "CVTPS2PD       %x,%X" },
-[0x5B] =       { RM,0,         "CVTPL2PS       %x,%X" },
-[0x5C] =       { RM,0,         "SUB%s  %x,%X" },
-[0x5D] =       { RM,0,         "MIN%s  %x,%X" },
-[0x5E] =       { RM,0,         "DIV%s  %x,%X" },               /* TO DO: S/P S/D */
-[0x5F] =       { RM,0,         "MAX%s  %x,%X" },
-[0x60] =       { RM,0,         "PUNPCKLBW      %m,%M" },
-[0x61] =       { RM,0,         "PUNPCKLWL      %m,%M" },
-[0x62] =       { RM,0,         "PUNPCKLLQ      %m,%M" },
-[0x63] =       { RM,0,         "PACKSSWB       %m,%M" },
-[0x64] =       { RM,0,         "PCMPGTB        %m,%M" },
-[0x65] =       { RM,0,         "PCMPGTW        %m,%M" },
-[0x66] =       { RM,0,         "PCMPGTL        %m,%M" },
-[0x67] =       { RM,0,         "PACKUSWB       %m,%M" },
-[0x68] =       { RM,0,         "PUNPCKHBW      %m,%M" },
-[0x69] =       { RM,0,         "PUNPCKHWL      %m,%M" },
-[0x6A] =       { RM,0,         "PUNPCKHLQ      %m,%M" },
-[0x6B] =       { RM,0,         "PACKSSLW       %m,%M" },
-[0x6E] =       { RM,0,         "MOV%S  %e,%M" },
-[0x6F] =       { RM,0,         "MOVQ   %m,%M" },
-[0x70] =       { RM,Ib,                "PSHUFW %i,%m,%M" },
-[0x74] =       { RM,0,         "PCMPEQB        %m,%M" },
-[0x75] =       { RM,0,         "PCMPEQW        %m,%M" },
-[0x76] =       { RM,0,         "PCMPEQL        %m,%M" },
-[0x77] =       { 0,0,          "EMMS" },
-[0x7E] =       { RM,0,         "MOV%S  %M,%e" },
-[0x7F] =       { RM,0,         "MOVQ   %M,%m" },
-[0xAE] =       { RMOP,0,               optab0FAE },
-[0xAA] =       { 0,0,          "RSM" },
-[0xB0] =       { RM,0,         "CMPXCHGB       %r,%e" },
-[0xB1] =       { RM,0,         "CMPXCHG%S      %r,%e" },
-[0xC0] =       { RMB,0,                "XADDB  %r,%e" },
-[0xC1] =       { RM,0,         "XADD%S %r,%e" },
-[0xC2] =       { RM,Ib,                "CMP%s  %x,%X,%#i" },
-[0xC3] =       { RM,0,         "MOVNTI%S       %r,%e" },
-[0xC6] =       { RM,Ib,                "SHUF%s %i,%x,%X" },
-[0xC8] =       { 0,0,          "BSWAP  AX" },
-[0xC9] =       { 0,0,          "BSWAP  CX" },
-[0xCA] =       { 0,0,          "BSWAP  DX" },
-[0xCB] =       { 0,0,          "BSWAP  BX" },
-[0xCC] =       { 0,0,          "BSWAP  SP" },
-[0xCD] =       { 0,0,          "BSWAP  BP" },
-[0xCE] =       { 0,0,          "BSWAP  SI" },
-[0xCF] =       { 0,0,          "BSWAP  DI" },
-[0xD1] =       { RM,0,         "PSRLW  %m,%M" },
-[0xD2] =       { RM,0,         "PSRLL  %m,%M" },
-[0xD3] =       { RM,0,         "PSRLQ  %m,%M" },
-[0xD5] =       { RM,0,         "PMULLW %m,%M" },
-[0xD6] =       { RM,0,         "MOVQOZX        %m*,%X" },
-[0xD7] =       { RM,0,         "PMOVMSKB       %m,%r" },
-[0xD8] =       { RM,0,         "PSUBUSB        %m,%M" },
-[0xD9] =       { RM,0,         "PSUBUSW        %m,%M" },
-[0xDA] =       { RM,0,         "PMINUB %m,%M" },
-[0xDB] =       { RM,0,         "PAND   %m,%M" },
-[0xDC] =       { RM,0,         "PADDUSB        %m,%M" },
-[0xDD] =       { RM,0,         "PADDUSW        %m,%M" },
-[0xDE] =       { RM,0,         "PMAXUB %m,%M" },
-[0xDF] =       { RM,0,         "PANDN  %m,%M" },
-[0xE0] =       { RM,0,         "PAVGB  %m,%M" },
-[0xE1] =       { RM,0,         "PSRAW  %m,%M" },
-[0xE2] =       { RM,0,         "PSRAL  %m,%M" },
-[0xE3] =       { RM,0,         "PAVGW  %m,%M" },
-[0xE4] =       { RM,0,         "PMULHUW        %m,%M" },
-[0xE5] =       { RM,0,         "PMULHW %m,%M" },
-[0xE7] =       { RM,0,         "MOVNTQ %M,%e" },
-[0xE8] =       { RM,0,         "PSUBSB %m,%M" },
-[0xE9] =       { RM,0,         "PSUBSW %m,%M" },
-[0xEA] =       { RM,0,         "PMINSW %m,%M" },
-[0xEB] =       { RM,0,         "POR    %m,%M" },
-[0xEC] =       { RM,0,         "PADDSB %m,%M" },
-[0xED] =       { RM,0,         "PADDSW %m,%M" },
-[0xEE] =       { RM,0,         "PMAXSW %m,%M" },
-[0xEF] =       { RM,0,         "PXOR   %m,%M" },
-[0xF1] =       { RM,0,         "PSLLW  %m,%M" },
-[0xF2] =       { RM,0,         "PSLLL  %m,%M" },
-[0xF3] =       { RM,0,         "PSLLQ  %m,%M" },
-[0xF4] =       { RM,0,         "PMULULQ        %m,%M" },
-[0xF5] =       { RM,0,         "PMADDWL        %m,%M" },
-[0xF6] =       { RM,0,         "PSADBW %m,%M" },
-[0xF7] =       { RMR,0,                "MASKMOVQ       %m,%M" },
-[0xF8] =       { RM,0,         "PSUBB  %m,%M" },
-[0xF9] =       { RM,0,         "PSUBW  %m,%M" },
-[0xFA] =       { RM,0,         "PSUBL  %m,%M" },
-[0xFC] =       { RM,0,         "PADDB  %m,%M" },
-[0xFD] =       { RM,0,         "PADDW  %m,%M" },
-[0xFE] =       { RM,0,         "PADDL  %m,%M" },
-
-[0x80] =       { Iwds,0,               "JOS    %p" },
-[0x81] =       { Iwds,0,               "JOC    %p" },
-[0x82] =       { Iwds,0,               "JCS    %p" },
-[0x83] =       { Iwds,0,               "JCC    %p" },
-[0x84] =       { Iwds,0,               "JEQ    %p" },
-[0x85] =       { Iwds,0,               "JNE    %p" },
-[0x86] =       { Iwds,0,               "JLS    %p" },
-[0x87] =       { Iwds,0,               "JHI    %p" },
-[0x88] =       { Iwds,0,               "JMI    %p" },
-[0x89] =       { Iwds,0,               "JPL    %p" },
-[0x8a] =       { Iwds,0,               "JPS    %p" },
-[0x8b] =       { Iwds,0,               "JPC    %p" },
-[0x8c] =       { Iwds,0,               "JLT    %p" },
-[0x8d] =       { Iwds,0,               "JGE    %p" },
-[0x8e] =       { Iwds,0,               "JLE    %p" },
-[0x8f] =       { Iwds,0,               "JGT    %p" },
-[0x90] =       { RMB,0,                "SETOS  %e" },
-[0x91] =       { RMB,0,                "SETOC  %e" },
-[0x92] =       { RMB,0,                "SETCS  %e" },
-[0x93] =       { RMB,0,                "SETCC  %e" },
-[0x94] =       { RMB,0,                "SETEQ  %e" },
-[0x95] =       { RMB,0,                "SETNE  %e" },
-[0x96] =       { RMB,0,                "SETLS  %e" },
-[0x97] =       { RMB,0,                "SETHI  %e" },
-[0x98] =       { RMB,0,                "SETMI  %e" },
-[0x99] =       { RMB,0,                "SETPL  %e" },
-[0x9a] =       { RMB,0,                "SETPS  %e" },
-[0x9b] =       { RMB,0,                "SETPC  %e" },
-[0x9c] =       { RMB,0,                "SETLT  %e" },
-[0x9d] =       { RMB,0,                "SETGE  %e" },
-[0x9e] =       { RMB,0,                "SETLE  %e" },
-[0x9f] =       { RMB,0,                "SETGT  %e" },
-[0xa0] =       { 0,0,          "PUSHL  FS" },
-[0xa1] =       { 0,0,          "POPL   FS" },
-[0xa2] =       { 0,0,          "CPUID" },
-[0xa3] =       { RM,0,         "BT%S   %r,%e" },
-[0xa4] =       { RM,Ib,                "SHLD%S %r,%i,%e" },
-[0xa5] =       { RM,0,         "SHLD%S %r,CL,%e" },
-[0xa8] =       { 0,0,          "PUSHL  GS" },
-[0xa9] =       { 0,0,          "POPL   GS" },
-[0xab] =       { RM,0,         "BTS%S  %r,%e" },
-[0xac] =       { RM,Ib,                "SHRD%S %r,%i,%e" },
-[0xad] =       { RM,0,         "SHRD%S %r,CL,%e" },
-[0xaf] =       { RM,0,         "IMUL%S %e,%r" },
-[0xb2] =       { RMM,0,                "LSS    %e,%r" },
-[0xb3] =       { RM,0,         "BTR%S  %r,%e" },
-[0xb4] =       { RMM,0,                "LFS    %e,%r" },
-[0xb5] =       { RMM,0,                "LGS    %e,%r" },
-[0xb6] =       { RMB,0,                "MOVBZX %e,%R" },
-[0xb7] =       { RM,0,         "MOVWZX %e,%R" },
-[0xba] =       { RMOP,0,               optab0FBA },
-[0xbb] =       { RM,0,         "BTC%S  %e,%r" },
-[0xbc] =       { RM,0,         "BSF%S  %e,%r" },
-[0xbd] =       { RM,0,         "BSR%S  %e,%r" },
-[0xbe] =       { RMB,0,                "MOVBSX %e,%R" },
-[0xbf] =       { RM,0,         "MOVWSX %e,%R" },
-[0xc7] =       { RMOP,0,               optab0FC7 },
-};
-
-static Optable optab80[8]=
-{
-[0x00] =       { Ib,0,         "ADDB   %i,%e" },
-[0x01] =       { Ib,0,         "ORB    %i,%e" },
-[0x02] =       { Ib,0,         "ADCB   %i,%e" },
-[0x03] =       { Ib,0,         "SBBB   %i,%e" },
-[0x04] =       { Ib,0,         "ANDB   %i,%e" },
-[0x05] =       { Ib,0,         "SUBB   %i,%e" },
-[0x06] =       { Ib,0,         "XORB   %i,%e" },
-[0x07] =       { Ib,0,         "CMPB   %e,%i" },
-};
-
-static Optable optab81[8]=
-{
-[0x00] =       { Iwd,0,                "ADD%S  %i,%e" },
-[0x01] =       { Iwd,0,                "OR%S   %i,%e" },
-[0x02] =       { Iwd,0,                "ADC%S  %i,%e" },
-[0x03] =       { Iwd,0,                "SBB%S  %i,%e" },
-[0x04] =       { Iwd,0,                "AND%S  %i,%e" },
-[0x05] =       { Iwd,0,                "SUB%S  %i,%e" },
-[0x06] =       { Iwd,0,                "XOR%S  %i,%e" },
-[0x07] =       { Iwd,0,                "CMP%S  %e,%i" },
-};
-
-static Optable optab83[8]=
-{
-[0x00] =       { Ibs,0,                "ADD%S  %i,%e" },
-[0x01] =       { Ibs,0,                "OR%S   %i,%e" },
-[0x02] =       { Ibs,0,                "ADC%S  %i,%e" },
-[0x03] =       { Ibs,0,                "SBB%S  %i,%e" },
-[0x04] =       { Ibs,0,                "AND%S  %i,%e" },
-[0x05] =       { Ibs,0,                "SUB%S  %i,%e" },
-[0x06] =       { Ibs,0,                "XOR%S  %i,%e" },
-[0x07] =       { Ibs,0,                "CMP%S  %e,%i" },
-};
-
-static Optable optabC0[8] =
-{
-[0x00] =       { Ib,0,         "ROLB   %i,%e" },
-[0x01] =       { Ib,0,         "RORB   %i,%e" },
-[0x02] =       { Ib,0,         "RCLB   %i,%e" },
-[0x03] =       { Ib,0,         "RCRB   %i,%e" },
-[0x04] =       { Ib,0,         "SHLB   %i,%e" },
-[0x05] =       { Ib,0,         "SHRB   %i,%e" },
-[0x07] =       { Ib,0,         "SARB   %i,%e" },
-};
-
-static Optable optabC1[8] =
-{
-[0x00] =       { Ib,0,         "ROL%S  %i,%e" },
-[0x01] =       { Ib,0,         "ROR%S  %i,%e" },
-[0x02] =       { Ib,0,         "RCL%S  %i,%e" },
-[0x03] =       { Ib,0,         "RCR%S  %i,%e" },
-[0x04] =       { Ib,0,         "SHL%S  %i,%e" },
-[0x05] =       { Ib,0,         "SHR%S  %i,%e" },
-[0x07] =       { Ib,0,         "SAR%S  %i,%e" },
-};
-
-static Optable optabD0[8] =
-{
-[0x00] =       { 0,0,          "ROLB   %e" },
-[0x01] =       { 0,0,          "RORB   %e" },
-[0x02] =       { 0,0,          "RCLB   %e" },
-[0x03] =       { 0,0,          "RCRB   %e" },
-[0x04] =       { 0,0,          "SHLB   %e" },
-[0x05] =       { 0,0,          "SHRB   %e" },
-[0x07] =       { 0,0,          "SARB   %e" },
-};
-
-static Optable optabD1[8] =
-{
-[0x00] =       { 0,0,          "ROL%S  %e" },
-[0x01] =       { 0,0,          "ROR%S  %e" },
-[0x02] =       { 0,0,          "RCL%S  %e" },
-[0x03] =       { 0,0,          "RCR%S  %e" },
-[0x04] =       { 0,0,          "SHL%S  %e" },
-[0x05] =       { 0,0,          "SHR%S  %e" },
-[0x07] =       { 0,0,          "SAR%S  %e" },
-};
-
-static Optable optabD2[8] =
-{
-[0x00] =       { 0,0,          "ROLB   CL,%e" },
-[0x01] =       { 0,0,          "RORB   CL,%e" },
-[0x02] =       { 0,0,          "RCLB   CL,%e" },
-[0x03] =       { 0,0,          "RCRB   CL,%e" },
-[0x04] =       { 0,0,          "SHLB   CL,%e" },
-[0x05] =       { 0,0,          "SHRB   CL,%e" },
-[0x07] =       { 0,0,          "SARB   CL,%e" },
-};
-
-static Optable optabD3[8] =
-{
-[0x00] =       { 0,0,          "ROL%S  CL,%e" },
-[0x01] =       { 0,0,          "ROR%S  CL,%e" },
-[0x02] =       { 0,0,          "RCL%S  CL,%e" },
-[0x03] =       { 0,0,          "RCR%S  CL,%e" },
-[0x04] =       { 0,0,          "SHL%S  CL,%e" },
-[0x05] =       { 0,0,          "SHR%S  CL,%e" },
-[0x07] =       { 0,0,          "SAR%S  CL,%e" },
-};
-
-static Optable optabD8[8+8] =
-{
-[0x00] =       { 0,0,          "FADDF  %e,F0" },
-[0x01] =       { 0,0,          "FMULF  %e,F0" },
-[0x02] =       { 0,0,          "FCOMF  %e,F0" },
-[0x03] =       { 0,0,          "FCOMFP %e,F0" },
-[0x04] =       { 0,0,          "FSUBF  %e,F0" },
-[0x05] =       { 0,0,          "FSUBRF %e,F0" },
-[0x06] =       { 0,0,          "FDIVF  %e,F0" },
-[0x07] =       { 0,0,          "FDIVRF %e,F0" },
-[0x08] =       { 0,0,          "FADDD  %f,F0" },
-[0x09] =       { 0,0,          "FMULD  %f,F0" },
-[0x0a] =       { 0,0,          "FCOMD  %f,F0" },
-[0x0b] =       { 0,0,          "FCOMPD %f,F0" },
-[0x0c] =       { 0,0,          "FSUBD  %f,F0" },
-[0x0d] =       { 0,0,          "FSUBRD %f,F0" },
-[0x0e] =       { 0,0,          "FDIVD  %f,F0" },
-[0x0f] =       { 0,0,          "FDIVRD %f,F0" },
-};
-/*
- *     optabD9 and optabDB use the following encoding:
- *     if (0 <= modrm <= 2) instruction = optabDx[modrm&0x07];
- *     else instruction = optabDx[(modrm&0x3f)+8];
- *
- *     the instructions for MOD == 3, follow the 8 instructions
- *     for the other MOD values stored at the front of the table.
- */
-static Optable optabD9[64+8] =
-{
-[0x00] =       { 0,0,          "FMOVF  %e,F0" },
-[0x02] =       { 0,0,          "FMOVF  F0,%e" },
-[0x03] =       { 0,0,          "FMOVFP F0,%e" },
-[0x04] =       { 0,0,          "FLDENV%S       %e" },
-[0x05] =       { 0,0,          "FLDCW  %e" },
-[0x06] =       { 0,0,          "FSTENV%S       %e" },
-[0x07] =       { 0,0,          "FSTCW  %e" },
-[0x08] =       { 0,0,          "FMOVD  F0,F0" },               /* Mod R/M = 11xx xxxx*/
-[0x09] =       { 0,0,          "FMOVD  F1,F0" },
-[0x0a] =       { 0,0,          "FMOVD  F2,F0" },
-[0x0b] =       { 0,0,          "FMOVD  F3,F0" },
-[0x0c] =       { 0,0,          "FMOVD  F4,F0" },
-[0x0d] =       { 0,0,          "FMOVD  F5,F0" },
-[0x0e] =       { 0,0,          "FMOVD  F6,F0" },
-[0x0f] =       { 0,0,          "FMOVD  F7,F0" },
-[0x10] =       { 0,0,          "FXCHD  F0,F0" },
-[0x11] =       { 0,0,          "FXCHD  F1,F0" },
-[0x12] =       { 0,0,          "FXCHD  F2,F0" },
-[0x13] =       { 0,0,          "FXCHD  F3,F0" },
-[0x14] =       { 0,0,          "FXCHD  F4,F0" },
-[0x15] =       { 0,0,          "FXCHD  F5,F0" },
-[0x16] =       { 0,0,          "FXCHD  F6,F0" },
-[0x17] =       { 0,0,          "FXCHD  F7,F0" },
-[0x18] =       { 0,0,          "FNOP" },
-[0x28] =       { 0,0,          "FCHS" },
-[0x29] =       { 0,0,          "FABS" },
-[0x2c] =       { 0,0,          "FTST" },
-[0x2d] =       { 0,0,          "FXAM" },
-[0x30] =       { 0,0,          "FLD1" },
-[0x31] =       { 0,0,          "FLDL2T" },
-[0x32] =       { 0,0,          "FLDL2E" },
-[0x33] =       { 0,0,          "FLDPI" },
-[0x34] =       { 0,0,          "FLDLG2" },
-[0x35] =       { 0,0,          "FLDLN2" },
-[0x36] =       { 0,0,          "FLDZ" },
-[0x38] =       { 0,0,          "F2XM1" },
-[0x39] =       { 0,0,          "FYL2X" },
-[0x3a] =       { 0,0,          "FPTAN" },
-[0x3b] =       { 0,0,          "FPATAN" },
-[0x3c] =       { 0,0,          "FXTRACT" },
-[0x3d] =       { 0,0,          "FPREM1" },
-[0x3e] =       { 0,0,          "FDECSTP" },
-[0x3f] =       { 0,0,          "FNCSTP" },
-[0x40] =       { 0,0,          "FPREM" },
-[0x41] =       { 0,0,          "FYL2XP1" },
-[0x42] =       { 0,0,          "FSQRT" },
-[0x43] =       { 0,0,          "FSINCOS" },
-[0x44] =       { 0,0,          "FRNDINT" },
-[0x45] =       { 0,0,          "FSCALE" },
-[0x46] =       { 0,0,          "FSIN" },
-[0x47] =       { 0,0,          "FCOS" },
-};
-
-static Optable optabDA[8+8] =
-{
-[0x00] =       { 0,0,          "FADDL  %e,F0" },
-[0x01] =       { 0,0,          "FMULL  %e,F0" },
-[0x02] =       { 0,0,          "FCOML  %e,F0" },
-[0x03] =       { 0,0,          "FCOMLP %e,F0" },
-[0x04] =       { 0,0,          "FSUBL  %e,F0" },
-[0x05] =       { 0,0,          "FSUBRL %e,F0" },
-[0x06] =       { 0,0,          "FDIVL  %e,F0" },
-[0x07] =       { 0,0,          "FDIVRL %e,F0" },
-[0x08] =       { 0,0,          "FCMOVCS        %f,F0" },
-[0x09] =       { 0,0,          "FCMOVEQ        %f,F0" },
-[0x0a] =       { 0,0,          "FCMOVLS        %f,F0" },
-[0x0b] =       { 0,0,          "FCMOVUN        %f,F0" },
-[0x0d] =       { Op_R1,0,              "FUCOMPP" },
-};
-
-static Optable optabDB[8+64] =
-{
-[0x00] =       { 0,0,          "FMOVL  %e,F0" },
-[0x02] =       { 0,0,          "FMOVL  F0,%e" },
-[0x03] =       { 0,0,          "FMOVLP F0,%e" },
-[0x05] =       { 0,0,          "FMOVX  %e,F0" },
-[0x07] =       { 0,0,          "FMOVXP F0,%e" },
-[0x08] =       { 0,0,          "FCMOVCC        F0,F0" },       /* Mod R/M = 11xx xxxx*/
-[0x09] =       { 0,0,          "FCMOVCC        F1,F0" },
-[0x0a] =       { 0,0,          "FCMOVCC        F2,F0" },
-[0x0b] =       { 0,0,          "FCMOVCC        F3,F0" },
-[0x0c] =       { 0,0,          "FCMOVCC        F4,F0" },
-[0x0d] =       { 0,0,          "FCMOVCC        F5,F0" },
-[0x0e] =       { 0,0,          "FCMOVCC        F6,F0" },
-[0x0f] =       { 0,0,          "FCMOVCC        F7,F0" },
-[0x10] =       { 0,0,          "FCMOVNE        F0,F0" },
-[0x11] =       { 0,0,          "FCMOVNE        F1,F0" },
-[0x12] =       { 0,0,          "FCMOVNE        F2,F0" },
-[0x13] =       { 0,0,          "FCMOVNE        F3,F0" },
-[0x14] =       { 0,0,          "FCMOVNE        F4,F0" },
-[0x15] =       { 0,0,          "FCMOVNE        F5,F0" },
-[0x16] =       { 0,0,          "FCMOVNE        F6,F0" },
-[0x17] =       { 0,0,          "FCMOVNE        F7,F0" },
-[0x18] =       { 0,0,          "FCMOVHI        F0,F0" },
-[0x19] =       { 0,0,          "FCMOVHI        F1,F0" },
-[0x1a] =       { 0,0,          "FCMOVHI        F2,F0" },
-[0x1b] =       { 0,0,          "FCMOVHI        F3,F0" },
-[0x1c] =       { 0,0,          "FCMOVHI        F4,F0" },
-[0x1d] =       { 0,0,          "FCMOVHI        F5,F0" },
-[0x1e] =       { 0,0,          "FCMOVHI        F6,F0" },
-[0x1f] =       { 0,0,          "FCMOVHI        F7,F0" },
-[0x20] =       { 0,0,          "FCMOVNU        F0,F0" },
-[0x21] =       { 0,0,          "FCMOVNU        F1,F0" },
-[0x22] =       { 0,0,          "FCMOVNU        F2,F0" },
-[0x23] =       { 0,0,          "FCMOVNU        F3,F0" },
-[0x24] =       { 0,0,          "FCMOVNU        F4,F0" },
-[0x25] =       { 0,0,          "FCMOVNU        F5,F0" },
-[0x26] =       { 0,0,          "FCMOVNU        F6,F0" },
-[0x27] =       { 0,0,          "FCMOVNU        F7,F0" },
-[0x2a] =       { 0,0,          "FCLEX" },
-[0x2b] =       { 0,0,          "FINIT" },
-[0x30] =       { 0,0,          "FUCOMI F0,F0" },
-[0x31] =       { 0,0,          "FUCOMI F1,F0" },
-[0x32] =       { 0,0,          "FUCOMI F2,F0" },
-[0x33] =       { 0,0,          "FUCOMI F3,F0" },
-[0x34] =       { 0,0,          "FUCOMI F4,F0" },
-[0x35] =       { 0,0,          "FUCOMI F5,F0" },
-[0x36] =       { 0,0,          "FUCOMI F6,F0" },
-[0x37] =       { 0,0,          "FUCOMI F7,F0" },
-[0x38] =       { 0,0,          "FCOMI  F0,F0" },
-[0x39] =       { 0,0,          "FCOMI  F1,F0" },
-[0x3a] =       { 0,0,          "FCOMI  F2,F0" },
-[0x3b] =       { 0,0,          "FCOMI  F3,F0" },
-[0x3c] =       { 0,0,          "FCOMI  F4,F0" },
-[0x3d] =       { 0,0,          "FCOMI  F5,F0" },
-[0x3e] =       { 0,0,          "FCOMI  F6,F0" },
-[0x3f] =       { 0,0,          "FCOMI  F7,F0" },
-};
-
-static Optable optabDC[8+8] =
-{
-[0x00] =       { 0,0,          "FADDD  %e,F0" },
-[0x01] =       { 0,0,          "FMULD  %e,F0" },
-[0x02] =       { 0,0,          "FCOMD  %e,F0" },
-[0x03] =       { 0,0,          "FCOMDP %e,F0" },
-[0x04] =       { 0,0,          "FSUBD  %e,F0" },
-[0x05] =       { 0,0,          "FSUBRD %e,F0" },
-[0x06] =       { 0,0,          "FDIVD  %e,F0" },
-[0x07] =       { 0,0,          "FDIVRD %e,F0" },
-[0x08] =       { 0,0,          "FADDD  F0,%f" },
-[0x09] =       { 0,0,          "FMULD  F0,%f" },
-[0x0c] =       { 0,0,          "FSUBRD F0,%f" },
-[0x0d] =       { 0,0,          "FSUBD  F0,%f" },
-[0x0e] =       { 0,0,          "FDIVRD F0,%f" },
-[0x0f] =       { 0,0,          "FDIVD  F0,%f" },
-};
-
-static Optable optabDD[8+8] =
-{
-[0x00] =       { 0,0,          "FMOVD  %e,F0" },
-[0x02] =       { 0,0,          "FMOVD  F0,%e" },
-[0x03] =       { 0,0,          "FMOVDP F0,%e" },
-[0x04] =       { 0,0,          "FRSTOR%S       %e" },
-[0x06] =       { 0,0,          "FSAVE%S        %e" },
-[0x07] =       { 0,0,          "FSTSW  %e" },
-[0x08] =       { 0,0,          "FFREED %f" },
-[0x0a] =       { 0,0,          "FMOVD  %f,F0" },
-[0x0b] =       { 0,0,          "FMOVDP %f,F0" },
-[0x0c] =       { 0,0,          "FUCOMD %f,F0" },
-[0x0d] =       { 0,0,          "FUCOMDP        %f,F0" },
-};
-
-static Optable optabDE[8+8] =
-{
-[0x00] =       { 0,0,          "FADDW  %e,F0" },
-[0x01] =       { 0,0,          "FMULW  %e,F0" },
-[0x02] =       { 0,0,          "FCOMW  %e,F0" },
-[0x03] =       { 0,0,          "FCOMWP %e,F0" },
-[0x04] =       { 0,0,          "FSUBW  %e,F0" },
-[0x05] =       { 0,0,          "FSUBRW %e,F0" },
-[0x06] =       { 0,0,          "FDIVW  %e,F0" },
-[0x07] =       { 0,0,          "FDIVRW %e,F0" },
-[0x08] =       { 0,0,          "FADDDP F0,%f" },
-[0x09] =       { 0,0,          "FMULDP F0,%f" },
-[0x0b] =       { Op_R1,0,              "FCOMPDP" },
-[0x0c] =       { 0,0,          "FSUBRDP        F0,%f" },
-[0x0d] =       { 0,0,          "FSUBDP F0,%f" },
-[0x0e] =       { 0,0,          "FDIVRDP        F0,%f" },
-[0x0f] =       { 0,0,          "FDIVDP F0,%f" },
-};
-
-static Optable optabDF[8+8] =
-{
-[0x00] =       { 0,0,          "FMOVW  %e,F0" },
-[0x02] =       { 0,0,          "FMOVW  F0,%e" },
-[0x03] =       { 0,0,          "FMOVWP F0,%e" },
-[0x04] =       { 0,0,          "FBLD   %e" },
-[0x05] =       { 0,0,          "FMOVL  %e,F0" },
-[0x06] =       { 0,0,          "FBSTP  %e" },
-[0x07] =       { 0,0,          "FMOVLP F0,%e" },
-[0x0c] =       { Op_R0,0,              "FSTSW  %OAX" },
-[0x0d] =       { 0,0,          "FUCOMIP        F0,%f" },
-[0x0e] =       { 0,0,          "FCOMIP F0,%f" },
-};
-
-static Optable optabF6[8] =
-{
-[0x00] =       { Ib,0,         "TESTB  %i,%e" },
-[0x02] =       { 0,0,          "NOTB   %e" },
-[0x03] =       { 0,0,          "NEGB   %e" },
-[0x04] =       { 0,0,          "MULB   AL,%e" },
-[0x05] =       { 0,0,          "IMULB  AL,%e" },
-[0x06] =       { 0,0,          "DIVB   AL,%e" },
-[0x07] =       { 0,0,          "IDIVB  AL,%e" },
-};
-
-static Optable optabF7[8] =
-{
-[0x00] =       { Iwd,0,                "TEST%S %i,%e" },
-[0x02] =       { 0,0,          "NOT%S  %e" },
-[0x03] =       { 0,0,          "NEG%S  %e" },
-[0x04] =       { 0,0,          "MUL%S  %OAX,%e" },
-[0x05] =       { 0,0,          "IMUL%S %OAX,%e" },
-[0x06] =       { 0,0,          "DIV%S  %OAX,%e" },
-[0x07] =       { 0,0,          "IDIV%S %OAX,%e" },
-};
-
-static Optable optabFE[8] =
-{
-[0x00] =       { 0,0,          "INCB   %e" },
-[0x01] =       { 0,0,          "DECB   %e" },
-};
-
-static Optable optabFF[8] =
-{
-[0x00] =       { 0,0,          "INC%S  %e" },
-[0x01] =       { 0,0,          "DEC%S  %e" },
-[0x02] =       { JUMP,0,               "CALL*  %e" },
-[0x03] =       { JUMP,0,               "CALLF* %e" },
-[0x04] =       { JUMP,0,               "JMP*   %e" },
-[0x05] =       { JUMP,0,               "JMPF*  %e" },
-[0x06] =       { 0,0,          "PUSHL  %e" },
-};
-
-static Optable optable[256+2] =
-{
-[0x00] =       { RMB,0,                "ADDB   %r,%e" },
-[0x01] =       { RM,0,         "ADD%S  %r,%e" },
-[0x02] =       { RMB,0,                "ADDB   %e,%r" },
-[0x03] =       { RM,0,         "ADD%S  %e,%r" },
-[0x04] =       { Ib,0,         "ADDB   %i,AL" },
-[0x05] =       { Iwd,0,                "ADD%S  %i,%OAX" },
-[0x06] =       { 0,0,          "PUSHL  ES" },
-[0x07] =       { 0,0,          "POPL   ES" },
-[0x08] =       { RMB,0,                "ORB    %r,%e" },
-[0x09] =       { RM,0,         "OR%S   %r,%e" },
-[0x0a] =       { RMB,0,                "ORB    %e,%r" },
-[0x0b] =       { RM,0,         "OR%S   %e,%r" },
-[0x0c] =       { Ib,0,         "ORB    %i,AL" },
-[0x0d] =       { Iwd,0,                "OR%S   %i,%OAX" },
-[0x0e] =       { 0,0,          "PUSHL  CS" },
-[0x0f] =       { AUXMM,0,      optab0F },
-[0x10] =       { RMB,0,                "ADCB   %r,%e" },
-[0x11] =       { RM,0,         "ADC%S  %r,%e" },
-[0x12] =       { RMB,0,                "ADCB   %e,%r" },
-[0x13] =       { RM,0,         "ADC%S  %e,%r" },
-[0x14] =       { Ib,0,         "ADCB   %i,AL" },
-[0x15] =       { Iwd,0,                "ADC%S  %i,%OAX" },
-[0x16] =       { 0,0,          "PUSHL  SS" },
-[0x17] =       { 0,0,          "POPL   SS" },
-[0x18] =       { RMB,0,                "SBBB   %r,%e" },
-[0x19] =       { RM,0,         "SBB%S  %r,%e" },
-[0x1a] =       { RMB,0,                "SBBB   %e,%r" },
-[0x1b] =       { RM,0,         "SBB%S  %e,%r" },
-[0x1c] =       { Ib,0,         "SBBB   %i,AL" },
-[0x1d] =       { Iwd,0,                "SBB%S  %i,%OAX" },
-[0x1e] =       { 0,0,          "PUSHL  DS" },
-[0x1f] =       { 0,0,          "POPL   DS" },
-[0x20] =       { RMB,0,                "ANDB   %r,%e" },
-[0x21] =       { RM,0,         "AND%S  %r,%e" },
-[0x22] =       { RMB,0,                "ANDB   %e,%r" },
-[0x23] =       { RM,0,         "AND%S  %e,%r" },
-[0x24] =       { Ib,0,         "ANDB   %i,AL" },
-[0x25] =       { Iwd,0,                "AND%S  %i,%OAX" },
-[0x26] =       { SEG,0,                "ES:" },
-[0x27] =       { 0,0,          "DAA" },
-[0x28] =       { RMB,0,                "SUBB   %r,%e" },
-[0x29] =       { RM,0,         "SUB%S  %r,%e" },
-[0x2a] =       { RMB,0,                "SUBB   %e,%r" },
-[0x2b] =       { RM,0,         "SUB%S  %e,%r" },
-[0x2c] =       { Ib,0,         "SUBB   %i,AL" },
-[0x2d] =       { Iwd,0,                "SUB%S  %i,%OAX" },
-[0x2e] =       { SEG,0,                "CS:" },
-[0x2f] =       { 0,0,          "DAS" },
-[0x30] =       { RMB,0,                "XORB   %r,%e" },
-[0x31] =       { RM,0,         "XOR%S  %r,%e" },
-[0x32] =       { RMB,0,                "XORB   %e,%r" },
-[0x33] =       { RM,0,         "XOR%S  %e,%r" },
-[0x34] =       { Ib,0,         "XORB   %i,AL" },
-[0x35] =       { Iwd,0,                "XOR%S  %i,%OAX" },
-[0x36] =       { SEG,0,                "SS:" },
-[0x37] =       { 0,0,          "AAA" },
-[0x38] =       { RMB,0,                "CMPB   %r,%e" },
-[0x39] =       { RM,0,         "CMP%S  %r,%e" },
-[0x3a] =       { RMB,0,                "CMPB   %e,%r" },
-[0x3b] =       { RM,0,         "CMP%S  %e,%r" },
-[0x3c] =       { Ib,0,         "CMPB   %i,AL" },
-[0x3d] =       { Iwd,0,                "CMP%S  %i,%OAX" },
-[0x3e] =       { SEG,0,                "DS:" },
-[0x3f] =       { 0,0,          "AAS" },
-[0x40] =       { 0,0,          "INC%S  %OAX" },
-[0x41] =       { 0,0,          "INC%S  %OCX" },
-[0x42] =       { 0,0,          "INC%S  %ODX" },
-[0x43] =       { 0,0,          "INC%S  %OBX" },
-[0x44] =       { 0,0,          "INC%S  %OSP" },
-[0x45] =       { 0,0,          "INC%S  %OBP" },
-[0x46] =       { 0,0,          "INC%S  %OSI" },
-[0x47] =       { 0,0,          "INC%S  %ODI" },
-[0x48] =       { 0,0,          "DEC%S  %OAX" },
-[0x49] =       { 0,0,          "DEC%S  %OCX" },
-[0x4a] =       { 0,0,          "DEC%S  %ODX" },
-[0x4b] =       { 0,0,          "DEC%S  %OBX" },
-[0x4c] =       { 0,0,          "DEC%S  %OSP" },
-[0x4d] =       { 0,0,          "DEC%S  %OBP" },
-[0x4e] =       { 0,0,          "DEC%S  %OSI" },
-[0x4f] =       { 0,0,          "DEC%S  %ODI" },
-[0x50] =       { 0,0,          "PUSH%S %OAX" },
-[0x51] =       { 0,0,          "PUSH%S %OCX" },
-[0x52] =       { 0,0,          "PUSH%S %ODX" },
-[0x53] =       { 0,0,          "PUSH%S %OBX" },
-[0x54] =       { 0,0,          "PUSH%S %OSP" },
-[0x55] =       { 0,0,          "PUSH%S %OBP" },
-[0x56] =       { 0,0,          "PUSH%S %OSI" },
-[0x57] =       { 0,0,          "PUSH%S %ODI" },
-[0x58] =       { 0,0,          "POP%S  %OAX" },
-[0x59] =       { 0,0,          "POP%S  %OCX" },
-[0x5a] =       { 0,0,          "POP%S  %ODX" },
-[0x5b] =       { 0,0,          "POP%S  %OBX" },
-[0x5c] =       { 0,0,          "POP%S  %OSP" },
-[0x5d] =       { 0,0,          "POP%S  %OBP" },
-[0x5e] =       { 0,0,          "POP%S  %OSI" },
-[0x5f] =       { 0,0,          "POP%S  %ODI" },
-[0x60] =       { 0,0,          "PUSHA%S" },
-[0x61] =       { 0,0,          "POPA%S" },
-[0x62] =       { RMM,0,                "BOUND  %e,%r" },
-[0x63] =       { RM,0,         "ARPL   %r,%e" },
-[0x64] =       { SEG,0,                "FS:" },
-[0x65] =       { SEG,0,                "GS:" },
-[0x66] =       { OPOVER,0,     "" },
-[0x67] =       { ADDOVER,0,    "" },
-[0x68] =       { Iwd,0,                "PUSH%S %i" },
-[0x69] =       { RM,Iwd,               "IMUL%S %e,%i,%r" },
-[0x6a] =       { Ib,0,         "PUSH%S %i" },
-[0x6b] =       { RM,Ibs,               "IMUL%S %e,%i,%r" },
-[0x6c] =       { 0,0,          "INSB   DX,(%ODI)" },
-[0x6d] =       { 0,0,          "INS%S  DX,(%ODI)" },
-[0x6e] =       { 0,0,          "OUTSB  (%ASI),DX" },
-[0x6f] =       { 0,0,          "OUTS%S (%ASI),DX" },
-[0x70] =       { Jbs,0,                "JOS    %p" },
-[0x71] =       { Jbs,0,                "JOC    %p" },
-[0x72] =       { Jbs,0,                "JCS    %p" },
-[0x73] =       { Jbs,0,                "JCC    %p" },
-[0x74] =       { Jbs,0,                "JEQ    %p" },
-[0x75] =       { Jbs,0,                "JNE    %p" },
-[0x76] =       { Jbs,0,                "JLS    %p" },
-[0x77] =       { Jbs,0,                "JHI    %p" },
-[0x78] =       { Jbs,0,                "JMI    %p" },
-[0x79] =       { Jbs,0,                "JPL    %p" },
-[0x7a] =       { Jbs,0,                "JPS    %p" },
-[0x7b] =       { Jbs,0,                "JPC    %p" },
-[0x7c] =       { Jbs,0,                "JLT    %p" },
-[0x7d] =       { Jbs,0,                "JGE    %p" },
-[0x7e] =       { Jbs,0,                "JLE    %p" },
-[0x7f] =       { Jbs,0,                "JGT    %p" },
-[0x80] =       { RMOPB,0,      optab80 },
-[0x81] =       { RMOP,0,               optab81 },
-[0x83] =       { RMOP,0,               optab83 },
-[0x84] =       { RMB,0,                "TESTB  %r,%e" },
-[0x85] =       { RM,0,         "TEST%S %r,%e" },
-[0x86] =       { RMB,0,                "XCHGB  %r,%e" },
-[0x87] =       { RM,0,         "XCHG%S %r,%e" },
-[0x88] =       { RMB,0,                "MOVB   %r,%e" },
-[0x89] =       { RM,0,         "MOV%S  %r,%e" },
-[0x8a] =       { RMB,0,                "MOVB   %e,%r" },
-[0x8b] =       { RM,0,         "MOV%S  %e,%r" },
-[0x8c] =       { RM,0,         "MOVW   %g,%e" },
-[0x8d] =       { RM,0,         "LEA%S  %e,%r" },
-[0x8e] =       { RM,0,         "MOVW   %e,%g" },
-[0x8f] =       { RM,0,         "POP%S  %e" },
-[0x90] =       { 0,0,          "NOP" },
-[0x91] =       { 0,0,          "XCHG   %OCX,%OAX" },
-[0x92] =       { 0,0,          "XCHG   %ODX,%OAX" },
-[0x93] =       { 0,0,          "XCHG   %OBX,%OAX" },
-[0x94] =       { 0,0,          "XCHG   %OSP,%OAX" },
-[0x95] =       { 0,0,          "XCHG   %OBP,%OAX" },
-[0x96] =       { 0,0,          "XCHG   %OSI,%OAX" },
-[0x97] =       { 0,0,          "XCHG   %ODI,%OAX" },
-[0x98] =       { 0,0,          "%W" },                 /* miserable CBW or CWDE */
-[0x99] =       { 0,0,          "%w" },                 /* idiotic CWD or CDQ */
-[0x9a] =       { PTR,0,                "CALL%S %d" },
-[0x9b] =       { 0,0,          "WAIT" },
-[0x9c] =       { 0,0,          "PUSHF" },
-[0x9d] =       { 0,0,          "POPF" },
-[0x9e] =       { 0,0,          "SAHF" },
-[0x9f] =       { 0,0,          "LAHF" },
-[0xa0] =       { Awd,0,                "MOVB   %i,AL" },
-[0xa1] =       { Awd,0,                "MOV%S  %i,%OAX" },
-[0xa2] =       { Awd,0,                "MOVB   AL,%i" },
-[0xa3] =       { Awd,0,                "MOV%S  %OAX,%i" },
-[0xa4] =       { 0,0,          "MOVSB  (%ASI),(%ADI)" },
-[0xa5] =       { 0,0,          "MOVS%S (%ASI),(%ADI)" },
-[0xa6] =       { 0,0,          "CMPSB  (%ASI),(%ADI)" },
-[0xa7] =       { 0,0,          "CMPS%S (%ASI),(%ADI)" },
-[0xa8] =       { Ib,0,         "TESTB  %i,AL" },
-[0xa9] =       { Iwd,0,                "TEST%S %i,%OAX" },
-[0xaa] =       { 0,0,          "STOSB  AL,(%ADI)" },
-[0xab] =       { 0,0,          "STOS%S %OAX,(%ADI)" },
-[0xac] =       { 0,0,          "LODSB  (%ASI),AL" },
-[0xad] =       { 0,0,          "LODS%S (%ASI),%OAX" },
-[0xae] =       { 0,0,          "SCASB  (%ADI),AL" },
-[0xaf] =       { 0,0,          "SCAS%S (%ADI),%OAX" },
-[0xb0] =       { Ib,0,         "MOVB   %i,AL" },
-[0xb1] =       { Ib,0,         "MOVB   %i,CL" },
-[0xb2] =       { Ib,0,         "MOVB   %i,DL" },
-[0xb3] =       { Ib,0,         "MOVB   %i,BL" },
-[0xb4] =       { Ib,0,         "MOVB   %i,AH" },
-[0xb5] =       { Ib,0,         "MOVB   %i,CH" },
-[0xb6] =       { Ib,0,         "MOVB   %i,DH" },
-[0xb7] =       { Ib,0,         "MOVB   %i,BH" },
-[0xb8] =       { Iwdq,0,               "MOV%S  %i,%OAX" },
-[0xb9] =       { Iwdq,0,               "MOV%S  %i,%OCX" },
-[0xba] =       { Iwdq,0,               "MOV%S  %i,%ODX" },
-[0xbb] =       { Iwdq,0,               "MOV%S  %i,%OBX" },
-[0xbc] =       { Iwdq,0,               "MOV%S  %i,%OSP" },
-[0xbd] =       { Iwdq,0,               "MOV%S  %i,%OBP" },
-[0xbe] =       { Iwdq,0,               "MOV%S  %i,%OSI" },
-[0xbf] =       { Iwdq,0,               "MOV%S  %i,%ODI" },
-[0xc0] =       { RMOPB,0,      optabC0 },
-[0xc1] =       { RMOP,0,               optabC1 },
-[0xc2] =       { Iw,0,         "RET    %i" },
-[0xc3] =       { RET,0,                "RET" },
-[0xc4] =       { RM,0,         "LES    %e,%r" },
-[0xc5] =       { RM,0,         "LDS    %e,%r" },
-[0xc6] =       { RMB,Ib,               "MOVB   %i,%e" },
-[0xc7] =       { RM,Iwd,               "MOV%S  %i,%e" },
-[0xc8] =       { Iw2,Ib,               "ENTER  %i,%I" },               /* loony ENTER */
-[0xc9] =       { RET,0,                "LEAVE" },              /* bizarre LEAVE */
-[0xca] =       { Iw,0,         "RETF   %i" },
-[0xcb] =       { RET,0,                "RETF" },
-[0xcc] =       { 0,0,          "INT    3" },
-[0xcd] =       { Ib,0,         "INTB   %i" },
-[0xce] =       { 0,0,          "INTO" },
-[0xcf] =       { 0,0,          "IRET" },
-[0xd0] =       { RMOPB,0,      optabD0 },
-[0xd1] =       { RMOP,0,               optabD1 },
-[0xd2] =       { RMOPB,0,      optabD2 },
-[0xd3] =       { RMOP,0,               optabD3 },
-[0xd4] =       { OA,0,         "AAM" },
-[0xd5] =       { OA,0,         "AAD" },
-[0xd7] =       { 0,0,          "XLAT" },
-[0xd8] =       { FRMOP,0,      optabD8 },
-[0xd9] =       { FRMEX,0,      optabD9 },
-[0xda] =       { FRMOP,0,      optabDA },
-[0xdb] =       { FRMEX,0,      optabDB },
-[0xdc] =       { FRMOP,0,      optabDC },
-[0xdd] =       { FRMOP,0,      optabDD },
-[0xde] =       { FRMOP,0,      optabDE },
-[0xdf] =       { FRMOP,0,      optabDF },
-[0xe0] =       { Jbs,0,                "LOOPNE %p" },
-[0xe1] =       { Jbs,0,                "LOOPE  %p" },
-[0xe2] =       { Jbs,0,                "LOOP   %p" },
-[0xe3] =       { Jbs,0,                "JCXZ   %p" },
-[0xe4] =       { Ib,0,         "INB    %i,AL" },
-[0xe5] =       { Ib,0,         "IN%S   %i,%OAX" },
-[0xe6] =       { Ib,0,         "OUTB   AL,%i" },
-[0xe7] =       { Ib,0,         "OUT%S  %OAX,%i" },
-[0xe8] =       { Iwds,0,               "CALL   %p" },
-[0xe9] =       { Iwds,0,               "JMP    %p" },
-[0xea] =       { PTR,0,                "JMP    %d" },
-[0xeb] =       { Jbs,0,                "JMP    %p" },
-[0xec] =       { 0,0,          "INB    DX,AL" },
-[0xed] =       { 0,0,          "IN%S   DX,%OAX" },
-[0xee] =       { 0,0,          "OUTB   AL,DX" },
-[0xef] =       { 0,0,          "OUT%S  %OAX,DX" },
-[0xf0] =       { PRE,0,                "LOCK" },
-[0xf2] =       { OPRE,0,               "REPNE" },
-[0xf3] =       { OPRE,0,               "REP" },
-[0xf4] =       { 0,0,          "HLT" },
-[0xf5] =       { 0,0,          "CMC" },
-[0xf6] =       { RMOPB,0,      optabF6 },
-[0xf7] =       { RMOP,0,               optabF7 },
-[0xf8] =       { 0,0,          "CLC" },
-[0xf9] =       { 0,0,          "STC" },
-[0xfa] =       { 0,0,          "CLI" },
-[0xfb] =       { 0,0,          "STI" },
-[0xfc] =       { 0,0,          "CLD" },
-[0xfd] =       { 0,0,          "STD" },
-[0xfe] =       { RMOPB,0,      optabFE },
-[0xff] =       { RMOP,0,               optabFF },
-[0x100] =      { RM,0,         "MOVLQSX        %e,%r" },
-[0x101] =      { RM,0,         "MOVLQZX        %e,%r" },
-};
-
-/*
- *  get a byte of the instruction
- */
-static int
-igetc(Map *map, Instr *ip, uchar *c)
-{
-       if(ip->n+1 > sizeof(ip->mem)){
-               werrstr("instruction too long");
-               return -1;
-       }
-       if (get1(map, ip->addr+ip->n, c, 1) < 0) {
-               werrstr("can't read instruction: %r");
-               return -1;
-       }
-       ip->mem[ip->n++] = *c;
-       return 1;
-}
-
-/*
- *  get two bytes of the instruction
- */
-static int
-igets(Map *map, Instr *ip, ushort *sp)
-{
-       uchar c;
-       ushort s;
-
-       if (igetc(map, ip, &c) < 0)
-               return -1;
-       s = c;
-       if (igetc(map, ip, &c) < 0)
-               return -1;
-       s |= (c<<8);
-       *sp = s;
-       return 1;
-}
-
-/*
- *  get 4 bytes of the instruction
- */
-static int
-igetl(Map *map, Instr *ip, uint32 *lp)
-{
-       ushort s;
-       int32   l;
-
-       if (igets(map, ip, &s) < 0)
-               return -1;
-       l = s;
-       if (igets(map, ip, &s) < 0)
-               return -1;
-       l |= (s<<16);
-       *lp = l;
-       return 1;
-}
-
-/*
- *  get 8 bytes of the instruction
- *
-static int
-igetq(Map *map, Instr *ip, vlong *qp)
-{
-       uint32  l;
-       uvlong q;
-
-       if (igetl(map, ip, &l) < 0)
-               return -1;
-       q = l;
-       if (igetl(map, ip, &l) < 0)
-               return -1;
-       q |= ((uvlong)l<<32);
-       *qp = q;
-       return 1;
-}
- */
-
-static int
-getdisp(Map *map, Instr *ip, int mod, int rm, int code, int pcrel)
-{
-       uchar c;
-       ushort s;
-
-       if (mod > 2)
-               return 1;
-       if (mod == 1) {
-               if (igetc(map, ip, &c) < 0)
-                       return -1;
-               if (c&0x80)
-                       ip->disp = c|0xffffff00;
-               else
-                       ip->disp = c&0xff;
-       } else if (mod == 2 || rm == code) {
-               if (ip->asize == 'E') {
-                       if (igetl(map, ip, &ip->disp) < 0)
-                               return -1;
-                       if (mod == 0)
-                               ip->rip = pcrel;
-               } else {
-                       if (igets(map, ip, &s) < 0)
-                               return -1;
-                       if (s&0x8000)
-                               ip->disp = s|0xffff0000;
-                       else
-                               ip->disp = s;
-               }
-               if (mod == 0)
-                       ip->base = -1;
-       }
-       return 1;
-}
-
-static int
-modrm(Map *map, Instr *ip, uchar c)
-{
-       uchar rm, mod;
-
-       mod = (c>>6)&3;
-       rm = c&7;
-       ip->mod = mod;
-       ip->base = rm;
-       ip->reg = (c>>3)&7;
-       ip->rip = 0;
-       if (mod == 3)                   /* register */
-               return 1;
-       if (ip->asize == 0) {           /* 16-bit mode */
-               switch(rm) {
-               case 0:
-                       ip->base = BX; ip->index = SI;
-                       break;
-               case 1:
-                       ip->base = BX; ip->index = DI;
-                       break;
-               case 2:
-                       ip->base = BP; ip->index = SI;
-                       break;
-               case 3:
-                       ip->base = BP; ip->index = DI;
-                       break;
-               case 4:
-                       ip->base = SI;
-                       break;
-               case 5:
-                       ip->base = DI;
-                       break;
-               case 6:
-                       ip->base = BP;
-                       break;
-               case 7:
-                       ip->base = BX;
-                       break;
-               default:
-                       break;
-               }
-               return getdisp(map, ip, mod, rm, 6, 0);
-       }
-       if (rm == 4) {  /* scummy sib byte */
-               if (igetc(map, ip, &c) < 0)
-                       return -1;
-               ip->ss = (c>>6)&0x03;
-               ip->index = (c>>3)&0x07;
-               if (ip->index == 4)
-                       ip->index = -1;
-               ip->base = c&0x07;
-               return getdisp(map, ip, mod, ip->base, 5, 0);
-       }
-       return getdisp(map, ip, mod, rm, 5, ip->amd64);
-}
-
-static Optable *
-mkinstr(Map *map, Instr *ip, uvlong pc)
-{
-       int i, n, norex;
-       uchar c;
-       ushort s;
-       Optable *op, *obase;
-       char buf[128];
-
-       memset(ip, 0, sizeof(*ip));
-       norex = 1;
-       ip->base = -1;
-       ip->index = -1;
-       if(asstype == AI8086)
-               ip->osize = 'W';
-       else {
-               ip->osize = 'L';
-               ip->asize = 'E';
-               ip->amd64 = asstype != AI386;
-               norex = 0;
-       }
-       ip->addr = pc;
-       if (igetc(map, ip, &c) < 0)
-               return 0;
-       obase = optable;
-newop:
-       if(ip->amd64 && !norex){
-               if(c >= 0x40 && c <= 0x4f) {
-                       ip->rex = c;
-                       if(igetc(map, ip, &c) < 0)
-                               return 0;
-               }
-               if(c == 0x63){
-                       if(ip->rex&REXW)
-                               op = &obase[0x100];     /* MOVLQSX */
-                       else
-                               op = &obase[0x101];     /* MOVLQZX */
-                       goto hack;
-               }
-       }
-       op = &obase[c];
-hack:
-       if (op->proto == 0) {
-badop:
-               n = snprint(buf, sizeof(buf), "opcode: ??");
-               for (i = 0; i < ip->n && n < sizeof(buf)-3; i++, n+=2)
-                       _hexify(buf+n, ip->mem[i], 1);
-               strcpy(buf+n, "??");
-               werrstr(buf);
-               return 0;
-       }
-       for(i = 0; i < 2 && op->operand[i]; i++) {
-               switch(op->operand[i]) {
-               case Ib:        /* 8-bit immediate - (no sign extension)*/
-                       if (igetc(map, ip, &c) < 0)
-                               return 0;
-                       ip->imm = c&0xff;
-                       ip->imm64 = ip->imm;
-                       break;
-               case Jbs:       /* 8-bit jump immediate (sign extended) */
-                       if (igetc(map, ip, &c) < 0)
-                               return 0;
-                       if (c&0x80)
-                               ip->imm = c|0xffffff00;
-                       else
-                               ip->imm = c&0xff;
-                       ip->imm64 = (int32)ip->imm;
-                       ip->jumptype = Jbs;
-                       break;
-               case Ibs:       /* 8-bit immediate (sign extended) */
-                       if (igetc(map, ip, &c) < 0)
-                               return 0;
-                       if (c&0x80)
-                               if (ip->osize == 'L')
-                                       ip->imm = c|0xffffff00;
-                               else
-                                       ip->imm = c|0xff00;
-                       else
-                               ip->imm = c&0xff;
-                       ip->imm64 = (int32)ip->imm;
-                       break;
-               case Iw:        /* 16-bit immediate -> imm */
-                       if (igets(map, ip, &s) < 0)
-                               return 0;
-                       ip->imm = s&0xffff;
-                       ip->imm64 = ip->imm;
-                       ip->jumptype = Iw;
-                       break;
-               case Iw2:       /* 16-bit immediate -> in imm2*/
-                       if (igets(map, ip, &s) < 0)
-                               return 0;
-                       ip->imm2 = s&0xffff;
-                       break;
-               case Iwd:       /* Operand-sized immediate (no sign extension unless 64 bits)*/
-                       if (ip->osize == 'L') {
-                               if (igetl(map, ip, &ip->imm) < 0)
-                                       return 0;
-                               ip->imm64 = ip->imm;
-                               if(ip->rex&REXW && (ip->imm & (1<<31)) != 0)
-                                       ip->imm64 |= (vlong)~0 << 32;
-                       } else {
-                               if (igets(map, ip, &s)< 0)
-                                       return 0;
-                               ip->imm = s&0xffff;
-                               ip->imm64 = ip->imm;
-                       }
-                       break;
-               case Iwdq:      /* Operand-sized immediate, possibly big */
-                       if (ip->osize == 'L') {
-                               if (igetl(map, ip, &ip->imm) < 0)
-                                       return 0;
-                               ip->imm64 = ip->imm;
-                               if (ip->rex & REXW) {
-                                       uint32 l;
-                                       if (igetl(map, ip, &l) < 0)
-                                               return 0;
-                                       ip->imm64 |= (uvlong)l << 32;
-                               }
-                       } else {
-                               if (igets(map, ip, &s)< 0)
-                                       return 0;
-                               ip->imm = s&0xffff;
-                       }
-                       break;
-               case Awd:       /* Address-sized immediate (no sign extension)*/
-                       if (ip->asize == 'E') {
-                               if (igetl(map, ip, &ip->imm) < 0)
-                                       return 0;
-                               /* TO DO: REX */
-                       } else {
-                               if (igets(map, ip, &s)< 0)
-                                       return 0;
-                               ip->imm = s&0xffff;
-                       }
-                       break;
-               case Iwds:      /* Operand-sized immediate (sign extended) */
-                       if (ip->osize == 'L') {
-                               if (igetl(map, ip, &ip->imm) < 0)
-                                       return 0;
-                       } else {
-                               if (igets(map, ip, &s)< 0)
-                                       return 0;
-                               if (s&0x8000)
-                                       ip->imm = s|0xffff0000;
-                               else
-                                       ip->imm = s&0xffff;
-                       }
-                       ip->jumptype = Iwds;
-                       break;
-               case OA:        /* literal 0x0a byte */
-                       if (igetc(map, ip, &c) < 0)
-                               return 0;
-                       if (c != 0x0a)
-                               goto badop;
-                       break;
-               case Op_R0:     /* base register must be R0 */
-                       if (ip->base != 0)
-                               goto badop;
-                       break;
-               case Op_R1:     /* base register must be R1 */
-                       if (ip->base != 1)
-                               goto badop;
-                       break;
-               case RMB:       /* R/M field with byte register (/r)*/
-                       if (igetc(map, ip, &c) < 0)
-                               return 0;
-                       if (modrm(map, ip, c) < 0)
-                               return 0;
-                       ip->osize = 'B';
-                       break;
-               case RM:        /* R/M field with register (/r) */
-                       if (igetc(map, ip, &c) < 0)
-                               return 0;
-                       if (modrm(map, ip, c) < 0)
-                               return 0;
-                       break;
-               case RMOPB:     /* R/M field with op code (/digit) */
-                       if (igetc(map, ip, &c) < 0)
-                               return 0;
-                       if (modrm(map, ip, c) < 0)
-                               return 0;
-                       c = ip->reg;            /* secondary op code */
-                       obase = (Optable*)op->proto;
-                       ip->osize = 'B';
-                       goto newop;
-               case RMOP:      /* R/M field with op code (/digit) */
-                       if (igetc(map, ip, &c) < 0)
-                               return 0;
-                       if (modrm(map, ip, c) < 0)
-                               return 0;
-                       obase = (Optable*)op->proto;
-                       if(ip->amd64 && obase == optab0F01 && c == 0xF8)
-                               return optab0F01F8;
-                       c = ip->reg;
-                       goto newop;
-               case FRMOP:     /* FP R/M field with op code (/digit) */
-                       if (igetc(map, ip, &c) < 0)
-                               return 0;
-                       if (modrm(map, ip, c) < 0)
-                               return 0;
-                       if ((c&0xc0) == 0xc0)
-                               c = ip->reg+8;          /* 16 entry table */
-                       else
-                               c = ip->reg;
-                       obase = (Optable*)op->proto;
-                       goto newop;
-               case FRMEX:     /* Extended FP R/M field with op code (/digit) */
-                       if (igetc(map, ip, &c) < 0)
-                               return 0;
-                       if (modrm(map, ip, c) < 0)
-                               return 0;
-                       if ((c&0xc0) == 0xc0)
-                               c = (c&0x3f)+8;         /* 64-entry table */
-                       else
-                               c = ip->reg;
-                       obase = (Optable*)op->proto;
-                       goto newop;
-               case RMR:       /* R/M register only (mod = 11) */
-                       if (igetc(map, ip, &c) < 0)
-                               return 0;
-                       if ((c&0xc0) != 0xc0) {
-                               werrstr("invalid R/M register: %x", c);
-                               return 0;
-                       }
-                       if (modrm(map, ip, c) < 0)
-                               return 0;
-                       break;
-               case RMM:       /* R/M register only (mod = 11) */
-                       if (igetc(map, ip, &c) < 0)
-                               return 0;
-                       if ((c&0xc0) == 0xc0) {
-                               werrstr("invalid R/M memory mode: %x", c);
-                               return 0;
-                       }
-                       if (modrm(map, ip, c) < 0)
-                               return 0;
-                       break;
-               case PTR:       /* Seg:Displacement addr (ptr16:16 or ptr16:32) */
-                       if (ip->osize == 'L') {
-                               if (igetl(map, ip, &ip->disp) < 0)
-                                       return 0;
-                       } else {
-                               if (igets(map, ip, &s)< 0)
-                                       return 0;
-                               ip->disp = s&0xffff;
-                       }
-                       if (igets(map, ip, (ushort*)&ip->seg) < 0)
-                               return 0;
-                       ip->jumptype = PTR;
-                       break;
-               case AUXMM:     /* Multi-byte op code; prefix determines table selection */
-                       if (igetc(map, ip, &c) < 0)
-                               return 0;
-                       obase = (Optable*)op->proto;
-                       switch (ip->opre) {
-                       case 0x66:
-                               op = optab660F;
-                               break;
-                       case 0xF2:
-                               op = optabF20F;
-                               ip->prefix = 0; /* discard REPNE */
-                               break;
-                       case 0xF3:
-                               op = optabF30F;
-                               ip->prefix = 0; /* discard REP */
-                               break;
-                       default:
-                               op = nil;
-                               break;
-                       }
-                       if(op != nil && op[c].proto != nil)
-                               obase = op;
-                       /* otherwise the optab entry captures it */
-                       goto newop;
-               case AUX:       /* Multi-byte op code - Auxiliary table */
-                       obase = (Optable*)op->proto;
-                       if (igetc(map, ip, &c) < 0)
-                               return 0;
-                       goto newop;
-               case OPRE:      /* Instr Prefix or media op */
-                       ip->opre = c;
-                       /* fall through */
-               case PRE:       /* Instr Prefix */
-                       ip->prefix = (char*)op->proto;
-                       if (igetc(map, ip, &c) < 0)
-                               return 0;
-                       goto newop;
-               case SEG:       /* Segment Prefix */
-                       ip->segment = (char*)op->proto;
-                       if (igetc(map, ip, &c) < 0)
-                               return 0;
-                       goto newop;
-               case OPOVER:    /* Operand size override */
-                       ip->opre = c;
-                       ip->osize = 'W';
-                       if (igetc(map, ip, &c) < 0)
-                               return 0;
-                       if (c == 0x0F)
-                               ip->osize = 'L';
-                       else if (ip->amd64 && (c&0xF0) == 0x40)
-                               ip->osize = 'Q';
-                       goto newop;
-               case ADDOVER:   /* Address size override */
-                       ip->asize = 0;
-                       if (igetc(map, ip, &c) < 0)
-                               return 0;
-                       goto newop;
-               case JUMP:      /* mark instruction as JUMP or RET */
-               case RET:
-                       ip->jumptype = op->operand[i];
-                       break;
-               default:
-                       werrstr("bad operand type %d", op->operand[i]);
-                       return 0;
-               }
-       }
-       return op;
-}
-
-#pragma        varargck        argpos  bprint          2
-
-static void
-bprint(Instr *ip, char *fmt, ...)
-{
-       va_list arg;
-
-       va_start(arg, fmt);
-       ip->curr = vseprint(ip->curr, ip->end, fmt, arg);
-       va_end(arg);
-}
-
-/*
- *  if we want to call 16 bit regs AX,BX,CX,...
- *  and 32 bit regs EAX,EBX,ECX,... then
- *  change the defs of ANAME and ONAME to:
- *  #define    ANAME(ip)       ((ip->asize == 'E' ? "E" : "")
- *  #define    ONAME(ip)       ((ip)->osize == 'L' ? "E" : "")
- */
-#define        ANAME(ip)       ""
-#define        ONAME(ip)       ""
-
-static char *reg[] =  {
-[AX] = "AX",
-[CX] = "CX",
-[DX] = "DX",
-[BX] = "BX",
-[SP] = "SP",
-[BP] = "BP",
-[SI] = "SI",
-[DI] = "DI",
-
-       /* amd64 */
-[AMD64_R8] =   "R8",
-[AMD64_R9] =   "R9",
-[AMD64_R10] =  "R10",
-[AMD64_R11] =  "R11",
-[AMD64_R12] =  "R12",
-[AMD64_R13] =  "R13",
-[AMD64_R14] =  "R14",
-[AMD64_R15] =  "R15",
-};
-
-static char *breg[] = { "AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH" };
-static char *breg64[] = { "AL", "CL", "DL", "BL", "SPB", "BPB", "SIB", "DIB",
-       "R8B", "R9B", "R10B", "R11B", "R12B", "R13B", "R14B", "R15B" };
-static char *sreg[] = { "ES", "CS", "SS", "DS", "FS", "GS" };
-
-static void
-plocal(Instr *ip)
-{
-       int ret;
-       int32 offset;
-       Symbol s;
-       char *reg;
-
-       offset = ip->disp;
-       if (!findsym(ip->addr, CTEXT, &s) || !findlocal(&s, FRAMENAME, &s)) {
-               bprint(ip, "%ux(SP)", offset);
-               return;
-       }
-
-       if (s.value > ip->disp) {
-               ret = getauto(&s, s.value-ip->disp-mach->szaddr, CAUTO, &s);
-               reg = "(SP)";
-       } else {
-               offset -= s.value;
-               ret = getauto(&s, offset, CPARAM, &s);
-               reg = "(FP)";
-       }
-       if (ret)
-               bprint(ip, "%s+", s.name);
-       else
-               offset = ip->disp;
-       bprint(ip, "%ux%s", offset, reg);
-}
-
-static int
-isjmp(Instr *ip)
-{
-       switch(ip->jumptype){
-       case Iwds:
-       case Jbs:
-       case JUMP:
-               return 1;
-       default:
-               return 0;
-       }
-}
-
-/*
- * This is too smart for its own good, but it really is nice
- * to have accurate translations when debugging, and it
- * helps us identify which code is different in binaries that
- * are changed on sources.
- */
-static int
-issymref(Instr *ip, Symbol *s, int32 w, int32 val)
-{
-       Symbol next, tmp;
-       int32 isstring, size;
-
-       if (isjmp(ip))
-               return 1;
-       if (s->class==CTEXT && w==0)
-               return 1;
-       if (s->class==CDATA) {
-               /* use first bss symbol (or "end") rather than edata */
-               if (s->name[0]=='e' && strcmp(s->name, "edata") == 0){
-                       if((s ->index >= 0 && globalsym(&tmp, s->index+1) && tmp.value==s->value)
-                       || (s->index > 0 && globalsym(&tmp, s->index-1) && tmp.value==s->value))
-                               *s = tmp;
-               }
-               if (w == 0)
-                       return 1;
-               for (next=*s; next.value==s->value; next=tmp)
-                       if (!globalsym(&tmp, next.index+1))
-                               break;
-               size = next.value - s->value;
-               if (w >= size)
-                       return 0;
-               if (w > size-w)
-                       w = size-w;
-               /* huge distances are usually wrong except in .string */
-               isstring = (s->name[0]=='.' && strcmp(s->name, ".string") == 0);
-               if (w > 8192 && !isstring)
-                       return 0;
-               /* medium distances are tricky - look for constants */
-               /* near powers of two */
-               if ((val&(val-1)) == 0 || (val&(val+1)) == 0)
-                       return 0;
-               return 1;
-       }
-       return 0;
-}
-
-static void
-immediate(Instr *ip, vlong val)
-{
-       Symbol s;
-       int32 w;
-
-       if (findsym(val, CANY, &s)) {           /* TO DO */
-               w = val - s.value;
-               if (w < 0)
-                       w = -w;
-               if (issymref(ip, &s, w, val)) {
-                       if (w)
-                               bprint(ip, "%s+%#ux(SB)", s.name, w);
-                       else
-                               bprint(ip, "%s(SB)", s.name);
-                       return;
-               }
-/*
-               if (s.class==CDATA && globalsym(&s, s.index+1)) {
-                       w = s.value - val;
-                       if (w < 0)
-                               w = -w;
-                       if (w < 4096) {
-                               bprint(ip, "%s-%#lux(SB)", s.name, w);
-                               return;
-                       }
-               }
-*/
-       }
-       if((ip->rex & REXW) == 0)
-               bprint(ip, "%lux", (long)val);
-       else
-               bprint(ip, "%llux", val);
-}
-
-static void
-pea(Instr *ip)
-{
-       int base;
-
-       base = ip->base;
-       if(base >= 0 && (ip->rex & REXB))
-               base += 8;
-
-       if (ip->mod == 3) {
-               if (ip->osize == 'B')
-                       bprint(ip, (ip->rex & REXB? breg64: breg)[(uchar)ip->base]);
-               else
-                       bprint(ip, "%s%s", ANAME(ip), reg[base]);
-               return;
-       }
-
-       if (ip->segment)
-               bprint(ip, ip->segment);
-       if (ip->asize == 'E' && base == SP)
-               plocal(ip);
-       else {
-               if (ip->base < 0)
-                       immediate(ip, ip->disp);
-               else {
-                       bprint(ip, "%ux", ip->disp);
-                       if(ip->rip)
-                               bprint(ip, "(RIP)");
-                       bprint(ip,"(%s%s)", ANAME(ip), reg[ip->rex&REXB? ip->base+8: ip->base]);
-               }
-       }
-       if (ip->index >= 0)
-               bprint(ip,"(%s%s*%d)", ANAME(ip), reg[ip->rex&REXX? ip->index+8: ip->index], 1<<ip->ss);
-}
-
-static void
-prinstr(Instr *ip, char *fmt)
-{
-       int sharp;
-       vlong v;
-
-       if (ip->prefix)
-               bprint(ip, "%s ", ip->prefix);
-       for (; *fmt && ip->curr < ip->end; fmt++) {
-               if (*fmt != '%'){
-                       *ip->curr++ = *fmt;
-                       continue;
-               }
-               sharp = 0;
-               if(*++fmt == '#') {
-                       sharp = 1;
-                       ++fmt;
-               }
-               switch(*fmt){
-               case '%':
-                       *ip->curr++ = '%';
-                       break;
-               case 'A':
-                       bprint(ip, "%s", ANAME(ip));
-                       break;
-               case 'C':
-                       bprint(ip, "CR%d", ip->reg);
-                       break;
-               case 'D':
-                       if (ip->reg < 4 || ip->reg == 6 || ip->reg == 7)
-                               bprint(ip, "DR%d",ip->reg);
-                       else
-                               bprint(ip, "???");
-                       break;
-               case 'I':
-                       bprint(ip, "$");
-                       immediate(ip, ip->imm2);
-                       break;
-               case 'O':
-                       bprint(ip,"%s", ONAME(ip));
-                       break;
-               case 'i':
-                       if(!sharp)
-                               bprint(ip, "$");
-                       v = ip->imm;
-                       if(ip->rex & REXW)
-                               v = ip->imm64;
-                       immediate(ip, v);
-                       break;
-               case 'R':
-                       bprint(ip, "%s%s", ONAME(ip), reg[ip->rex&REXR? ip->reg+8: ip->reg]);
-                       break;
-               case 'S':
-                       if(ip->osize == 'Q' || ip->osize == 'L' && ip->rex & REXW)
-                               bprint(ip, "Q");
-                       else
-                               bprint(ip, "%c", ip->osize);
-                       break;
-               case 's':
-                       if(ip->opre == 0 || ip->opre == 0x66)
-                               bprint(ip, "P");
-                       else
-                               bprint(ip, "S");
-                       if(ip->opre == 0xf2 || ip->opre == 0x66)
-                               bprint(ip, "D");
-                       else
-                               bprint(ip, "S");
-                       break;
-               case 'T':
-                       if (ip->reg == 6 || ip->reg == 7)
-                               bprint(ip, "TR%d",ip->reg);
-                       else
-                               bprint(ip, "???");
-                       break;
-               case 'W':
-                       if (ip->osize == 'Q' || ip->osize == 'L' && ip->rex & REXW)
-                               bprint(ip, "CDQE");
-                       else if (ip->osize == 'L')
-                               bprint(ip,"CWDE");
-                       else
-                               bprint(ip, "CBW");
-                       break;
-               case 'd':
-                       bprint(ip,"%ux:%ux", ip->seg, ip->disp);
-                       break;
-               case 'm':
-                       if (ip->mod == 3 && ip->osize != 'B') {
-                               if(fmt[1] != '*'){
-                                       if(ip->opre != 0) {
-                                               bprint(ip, "X%d", ip->rex&REXB? ip->base+8: ip->base);
-                                               break;
-                                       }
-                               } else
-                                       fmt++;
-                               bprint(ip, "M%d", ip->base);
-                               break;
-                       }
-                       pea(ip);
-                       break;
-               case 'e':
-                       pea(ip);
-                       break;
-               case 'f':
-                       bprint(ip, "F%d", ip->base);
-                       break;
-               case 'g':
-                       if (ip->reg < 6)
-                               bprint(ip,"%s",sreg[ip->reg]);
-                       else
-                               bprint(ip,"???");
-                       break;
-               case 'p':
-                       /*
-                        * signed immediate in the uint32 ip->imm.
-                        */
-                       v = (int32)ip->imm;
-                       immediate(ip, v+ip->addr+ip->n);
-                       break;
-               case 'r':
-                       if (ip->osize == 'B')
-                               bprint(ip,"%s", (ip->rex? breg64: breg)[ip->rex&REXR? ip->reg+8: ip->reg]);
-                       else
-                               bprint(ip, reg[ip->rex&REXR? ip->reg+8: ip->reg]);
-                       break;
-               case 'w':
-                       if (ip->osize == 'Q' || ip->rex & REXW)
-                               bprint(ip, "CQO");
-                       else if (ip->osize == 'L')
-                               bprint(ip,"CDQ");
-                       else
-                               bprint(ip, "CWD");
-                       break;
-               case 'M':
-                       if(ip->opre != 0)
-                               bprint(ip, "X%d", ip->rex&REXR? ip->reg+8: ip->reg);
-                       else
-                               bprint(ip, "M%d", ip->reg);
-                       break;
-               case 'x':
-                       if (ip->mod == 3 && ip->osize != 'B') {
-                               bprint(ip, "X%d", ip->rex&REXB? ip->base+8: ip->base);
-                               break;
-                       }
-                       pea(ip);
-                       break;
-               case 'X':
-                       bprint(ip, "X%d", ip->rex&REXR? ip->reg+8: ip->reg);
-                       break;
-               default:
-                       bprint(ip, "%%%c", *fmt);
-                       break;
-               }
-       }
-       *ip->curr = 0;          /* there's always room for 1 byte */
-}
-
-static int
-i386inst(Map *map, uvlong pc, char modifier, char *buf, int n)
-{
-       Instr instr;
-       Optable *op;
-
-       USED(modifier);
-       op = mkinstr(map, &instr, pc);
-       if (op == 0) {
-               errstr(buf, n);
-               return -1;
-       }
-       instr.curr = buf;
-       instr.end = buf+n-1;
-       prinstr(&instr, op->proto);
-       return instr.n;
-}
-
-static int
-i386das(Map *map, uvlong pc, char *buf, int n)
-{
-       Instr instr;
-       int i;
-
-       if (mkinstr(map, &instr, pc) == 0) {
-               errstr(buf, n);
-               return -1;
-       }
-       for(i = 0; i < instr.n && n > 2; i++) {
-               _hexify(buf, instr.mem[i], 1);
-               buf += 2;
-               n -= 2;
-       }
-       *buf = 0;
-       return instr.n;
-}
-
-static int
-i386instlen(Map *map, uvlong pc)
-{
-       Instr i;
-
-       if (mkinstr(map, &i, pc))
-               return i.n;
-       return -1;
-}
-
-static int
-i386foll(Map *map, uvlong pc, Rgetter rget, uvlong *foll)
-{
-       Instr i;
-       Optable *op;
-       ushort s;
-       uvlong l, addr;
-       vlong v;
-       int n;
-
-       op = mkinstr(map, &i, pc);
-       if (!op)
-               return -1;
-
-       n = 0;
-
-       switch(i.jumptype) {
-       case RET:               /* RETURN or LEAVE */
-       case Iw:                /* RETURN */
-               if (strcmp(op->proto, "LEAVE") == 0) {
-                       if (geta(map, (*rget)(map, "BP"), &l) < 0)
-                               return -1;
-               } else if (geta(map, (*rget)(map, mach->sp), &l) < 0)
-                       return -1;
-               foll[0] = l;
-               return 1;
-       case Iwds:              /* pc relative JUMP or CALL*/
-       case Jbs:               /* pc relative JUMP or CALL */
-               v = (int32)i.imm;
-               foll[0] = pc+v+i.n;
-               n = 1;
-               break;
-       case PTR:               /* seg:displacement JUMP or CALL */
-               foll[0] = (i.seg<<4)+i.disp;
-               return 1;
-       case JUMP:              /* JUMP or CALL EA */
-
-               if(i.mod == 3) {
-                       foll[0] = (*rget)(map, reg[i.rex&REXB? i.base+8: i.base]);
-                       return 1;
-               }
-                       /* calculate the effective address */
-               addr = i.disp;
-               if (i.base >= 0) {
-                       if (geta(map, (*rget)(map, reg[i.rex&REXB? i.base+8: i.base]), &l) < 0)
-                               return -1;
-                       addr += l;
-               }
-               if (i.index >= 0) {
-                       if (geta(map, (*rget)(map, reg[i.rex&REXX? i.index+8: i.index]), &l) < 0)
-                               return -1;
-                       addr += l*(1<<i.ss);
-               }
-                       /* now retrieve a seg:disp value at that address */
-               if (get2(map, addr, &s) < 0)                    /* seg */
-                       return -1;
-               foll[0] = s<<4;
-               addr += 2;
-               if (i.asize == 'L') {
-                       if (geta(map, addr, &l) < 0)            /* disp32 */
-                               return -1;
-                       foll[0] += l;
-               } else {                                        /* disp16 */
-                       if (get2(map, addr, &s) < 0)
-                               return -1;
-                       foll[0] += s;
-               }
-               return 1;
-       default:
-               break;
-       }
-       if (strncmp(op->proto,"JMP", 3) == 0 || strncmp(op->proto,"CALL", 4) == 0)
-               return 1;
-       foll[n++] = pc+i.n;
-       return n;
-}
diff --git a/src/libmach/Makefile b/src/libmach/Makefile
deleted file mode 100644 (file)
index 62aba5d..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2012 The Go Authors.  All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-include ../Make.dist
diff --git a/src/libmach/access.c b/src/libmach/access.c
deleted file mode 100644 (file)
index 0ee75d1..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-// Inferno libmach/access.c
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/access.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-/*
- * functions to read and write an executable or file image
- */
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mach.h>
-
-static int     mget(Map*, uvlong, void*, int);
-static int     mput(Map*, uvlong, void*, int);
-static Seg*    reloc(Map*, uvlong, vlong*);
-
-/*
- * routines to get/put various types
- */
-int
-geta(Map *map, uvlong addr, uvlong *x)
-{
-       uint32 l;
-       uvlong vl;
-
-       if (mach->szaddr == 8){
-               if (get8(map, addr, &vl) < 0)
-                       return -1;
-               *x = vl;
-               return 1;
-       }
-
-       if (get4(map, addr, &l) < 0)
-               return -1;
-       *x = l;
-
-       return 1;
-}
-
-int
-get8(Map *map, uvlong addr, uvlong *x)
-{
-       if (!map) {
-               werrstr("get8: invalid map");
-               return -1;
-       }
-
-       if (map->nsegs == 1 && map->seg[0].fd < 0) {
-               *x = addr;
-               return 1;
-       }
-       if (mget(map, addr, x, 8) < 0)
-               return -1;
-       *x = machdata->swav(*x);
-       return 1;
-}
-
-int
-get4(Map *map, uvlong addr, uint32 *x)
-{
-       if (!map) {
-               werrstr("get4: invalid map");
-               return -1;
-       }
-
-       if (map->nsegs == 1 && map->seg[0].fd < 0) {
-               *x = addr;
-               return 1;
-       }
-       if (mget(map, addr, x, 4) < 0)
-               return -1;
-       *x = machdata->swal(*x);
-       return 1;
-}
-
-int
-get2(Map *map, uvlong addr, ushort *x)
-{
-       if (!map) {
-               werrstr("get2: invalid map");
-               return -1;
-       }
-
-       if (map->nsegs == 1 && map->seg[0].fd < 0) {
-               *x = addr;
-               return 1;
-       }
-       if (mget(map, addr, x, 2) < 0)
-               return -1;
-       *x = machdata->swab(*x);
-       return 1;
-}
-
-int
-get1(Map *map, uvlong addr, uchar *x, int size)
-{
-       uchar *cp;
-
-       if (!map) {
-               werrstr("get1: invalid map");
-               return -1;
-       }
-
-       if (map->nsegs == 1 && map->seg[0].fd < 0) {
-               cp = (uchar*)&addr;
-               while (cp < (uchar*)(&addr+1) && size-- > 0)
-                       *x++ = *cp++;
-               while (size-- > 0)
-                       *x++ = 0;
-       } else
-               return mget(map, addr, x, size);
-       return 1;
-}
-
-int
-puta(Map *map, uvlong addr, uvlong v)
-{
-       if (mach->szaddr == 8)
-               return put8(map, addr, v);
-
-       return put4(map, addr, v);
-}
-
-int
-put8(Map *map, uvlong addr, uvlong v)
-{
-       if (!map) {
-               werrstr("put8: invalid map");
-               return -1;
-       }
-       v = machdata->swav(v);
-       return mput(map, addr, &v, 8);
-}
-
-int
-put4(Map *map, uvlong addr, uint32 v)
-{
-       if (!map) {
-               werrstr("put4: invalid map");
-               return -1;
-       }
-       v = machdata->swal(v);
-       return mput(map, addr, &v, 4);
-}
-
-int
-put2(Map *map, uvlong addr, ushort v)
-{
-       if (!map) {
-               werrstr("put2: invalid map");
-               return -1;
-       }
-       v = machdata->swab(v);
-       return mput(map, addr, &v, 2);
-}
-
-int
-put1(Map *map, uvlong addr, uchar *v, int size)
-{
-       if (!map) {
-               werrstr("put1: invalid map");
-               return -1;
-       }
-       return mput(map, addr, v, size);
-}
-
-static int
-mget(Map *map, uvlong addr, void *buf, int size)
-{
-       uvlong off;
-       Seg *s;
-
-       s = reloc(map, addr, (vlong*)&off);
-       if (!s)
-               return -1;
-       if (s->rw == nil) {
-               werrstr("unreadable map");
-               return -1;
-       }
-       return s->rw(map, s, off, buf, size, 1);
-}
-
-static int
-mput(Map *map, uvlong addr, void *buf, int size)
-{
-       vlong off;
-       Seg *s;
-
-       s = reloc(map, addr, &off);
-       if (!s)
-               return -1;
-       if (s->rw == nil) {
-               werrstr("unwritable map");
-               return -1;
-       }
-       return s->rw(map, s, off, buf, size, 0);
-}
-
-/*
- *     convert address to file offset; returns nonzero if ok
- */
-static Seg*
-reloc(Map *map, uvlong addr, vlong *offp)
-{
-       int i;
-
-       for (i = 0; i < map->nsegs; i++) {
-               if (map->seg[i].inuse)
-               if (map->seg[i].b <= addr && addr < map->seg[i].e) {
-                       *offp = addr + map->seg[i].f - map->seg[i].b;
-                       return &map->seg[i];
-               }
-       }
-       werrstr("can't translate address %llux", addr);
-       return 0;
-}
diff --git a/src/libmach/darwin.c b/src/libmach/darwin.c
deleted file mode 100644 (file)
index aea5d4a..0000000
+++ /dev/null
@@ -1,890 +0,0 @@
-//     Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#define __DARWIN_UNIX03 0
-
-#include <u.h>
-#include <sys/ptrace.h>
-#include <sys/signal.h>
-#include <mach/mach.h>
-#include <mach/mach_traps.h>
-#include <errno.h>
-#include <libc.h>
-#include <bio.h>
-#include <mach.h>
-#include <ureg_x86.h>
-#include <ureg_amd64.h>
-#undef waitpid /* want Unix waitpid, not Plan 9 */
-
-extern mach_port_t mach_reply_port(void);      // should be in system headers, is not
-
-// Mach-error wrapper.
-// Takes a mach return code and converts it into 0 / -1,
-// setting errstr when it returns -1.
-
-static struct {
-       int code;
-       char *name;
-} macherr[] = {
-       KERN_INVALID_ADDRESS,   "invalid address",
-       KERN_PROTECTION_FAILURE,        "protection failure",
-       KERN_NO_SPACE,  "no space",
-       KERN_INVALID_ARGUMENT,  "invalid argument",
-       KERN_FAILURE,   "failure",
-       KERN_RESOURCE_SHORTAGE, "resource shortage",
-       KERN_NOT_RECEIVER,      "not receiver",
-       KERN_NO_ACCESS, "no access",
-       KERN_MEMORY_FAILURE,    "memory failure",
-       KERN_MEMORY_ERROR,      "memory error",
-       KERN_ALREADY_IN_SET,    "already in set",
-       KERN_NOT_IN_SET,        "not in set",
-       KERN_NAME_EXISTS,       "name exists",
-       KERN_ABORTED,   "aborted",
-       KERN_INVALID_NAME,      "invalid name",
-       KERN_INVALID_TASK,      "invalid task",
-       KERN_INVALID_RIGHT,     "invalid right",
-       KERN_INVALID_VALUE,     "invalid value",
-       KERN_UREFS_OVERFLOW,    "urefs overflow",
-       KERN_INVALID_CAPABILITY,        "invalid capability",
-       KERN_RIGHT_EXISTS,      "right exists",
-       KERN_INVALID_HOST,      "invalid host",
-       KERN_MEMORY_PRESENT,    "memory present",
-       KERN_MEMORY_DATA_MOVED, "memory data moved",
-       KERN_MEMORY_RESTART_COPY,       "memory restart copy",
-       KERN_INVALID_PROCESSOR_SET,     "invalid processor set",
-       KERN_POLICY_LIMIT,      "policy limit",
-       KERN_INVALID_POLICY,    "invalid policy",
-       KERN_INVALID_OBJECT,    "invalid object",
-       KERN_ALREADY_WAITING,   "already waiting",
-       KERN_DEFAULT_SET,       "default set",
-       KERN_EXCEPTION_PROTECTED,       "exception protected",
-       KERN_INVALID_LEDGER,    "invalid ledger",
-       KERN_INVALID_MEMORY_CONTROL,    "invalid memory control",
-       KERN_INVALID_SECURITY,  "invalid security",
-       KERN_NOT_DEPRESSED,     "not depressed",
-       KERN_TERMINATED,        "terminated",
-       KERN_LOCK_SET_DESTROYED,        "lock set destroyed",
-       KERN_LOCK_UNSTABLE,     "lock unstable",
-       KERN_LOCK_OWNED,        "lock owned",
-       KERN_LOCK_OWNED_SELF,   "lock owned self",
-       KERN_SEMAPHORE_DESTROYED,       "semaphore destroyed",
-       KERN_RPC_SERVER_TERMINATED,     "rpc server terminated",
-       KERN_RPC_TERMINATE_ORPHAN,      "rpc terminate orphan",
-       KERN_RPC_CONTINUE_ORPHAN,       "rpc continue orphan",
-       KERN_NOT_SUPPORTED,     "not supported",
-       KERN_NODE_DOWN, "node down",
-       KERN_NOT_WAITING,       "not waiting",
-       KERN_OPERATION_TIMED_OUT,       "operation timed out",
-       KERN_RETURN_MAX,        "return max",
-
-       MACH_SEND_IN_PROGRESS,  "send in progress",
-       MACH_SEND_INVALID_DATA, "send invalid data",
-       MACH_SEND_INVALID_DEST, "send invalid dest",
-       MACH_SEND_TIMED_OUT,    "send timed out",
-       MACH_SEND_INTERRUPTED,  "send interrupted",
-       MACH_SEND_MSG_TOO_SMALL,        "send msg too small",
-       MACH_SEND_INVALID_REPLY,        "send invalid reply",
-       MACH_SEND_INVALID_RIGHT,        "send invalid right",
-       MACH_SEND_INVALID_NOTIFY,       "send invalid notify",
-       MACH_SEND_INVALID_MEMORY,       "send invalid memory",
-       MACH_SEND_NO_BUFFER,    "send no buffer",
-       MACH_SEND_TOO_LARGE,    "send too large",
-       MACH_SEND_INVALID_TYPE, "send invalid type",
-       MACH_SEND_INVALID_HEADER,       "send invalid header",
-       MACH_SEND_INVALID_TRAILER,      "send invalid trailer",
-       MACH_SEND_INVALID_RT_OOL_SIZE,  "send invalid rt ool size",
-       MACH_RCV_IN_PROGRESS,   "rcv in progress",
-       MACH_RCV_INVALID_NAME,  "rcv invalid name",
-       MACH_RCV_TIMED_OUT,     "rcv timed out",
-       MACH_RCV_TOO_LARGE,     "rcv too large",
-       MACH_RCV_INTERRUPTED,   "rcv interrupted",
-       MACH_RCV_PORT_CHANGED,  "rcv port changed",
-       MACH_RCV_INVALID_NOTIFY,        "rcv invalid notify",
-       MACH_RCV_INVALID_DATA,  "rcv invalid data",
-       MACH_RCV_PORT_DIED,     "rcv port died",
-       MACH_RCV_IN_SET,        "rcv in set",
-       MACH_RCV_HEADER_ERROR,  "rcv header error",
-       MACH_RCV_BODY_ERROR,    "rcv body error",
-       MACH_RCV_INVALID_TYPE,  "rcv invalid type",
-       MACH_RCV_SCATTER_SMALL, "rcv scatter small",
-       MACH_RCV_INVALID_TRAILER,       "rcv invalid trailer",
-       MACH_RCV_IN_PROGRESS_TIMED,     "rcv in progress timed",
-
-       MIG_TYPE_ERROR, "mig type error",
-       MIG_REPLY_MISMATCH,     "mig reply mismatch",
-       MIG_REMOTE_ERROR,       "mig remote error",
-       MIG_BAD_ID,     "mig bad id",
-       MIG_BAD_ARGUMENTS,      "mig bad arguments",
-       MIG_NO_REPLY,   "mig no reply",
-       MIG_EXCEPTION,  "mig exception",
-       MIG_ARRAY_TOO_LARGE,    "mig array too large",
-       MIG_SERVER_DIED,        "server died",
-       MIG_TRAILER_ERROR,      "trailer has an unknown format",
-};
-
-static int
-me(kern_return_t r)
-{
-       int i;
-
-       if(r == 0)
-               return 0;
-
-       for(i=0; i<nelem(macherr); i++){
-               if(r == macherr[i].code){
-                       werrstr("mach: %s", macherr[i].name);
-                       return -1;
-               }
-       }
-       werrstr("mach error %#x", r);
-       return -1;
-}
-
-// Plan 9 and Linux do not distinguish between
-// process ids and thread ids, so the interface here doesn't either.
-// Unfortunately, Mach has three kinds of identifiers: process ids,
-// handles to tasks (processes), and handles to threads within a
-// process.  All of them are small integers.
-//
-// To accommodate Mach, we employ a clumsy hack: in this interface,
-// if you pass in a positive number, that's a process id.
-// If you pass in a negative number, that identifies a thread that
-// has been previously returned by procthreadpids (it indexes
-// into the Thread table below).
-
-// Table of threads we have handles for.
-typedef struct Thread Thread;
-struct Thread
-{
-       int pid;
-       mach_port_t task;
-       mach_port_t thread;
-       int stopped;
-       int exc;
-       int code[10];
-       Map *map;
-};
-static Thread thr[1000];
-static int nthr;
-static pthread_mutex_t mu;
-static pthread_cond_t cond;
-static void* excthread(void*);
-static void* waitthread(void*);
-static mach_port_t excport;
-
-enum {
-       ExcMask = EXC_MASK_BAD_ACCESS |
-               EXC_MASK_BAD_INSTRUCTION |
-               EXC_MASK_ARITHMETIC |
-               EXC_MASK_BREAKPOINT |
-               EXC_MASK_SOFTWARE
-};
-
-// Add process pid to the thread table.
-// If it's already there, don't re-add it (unless force != 0).
-static Thread*
-addpid(int pid, int force)
-{
-       int i, j;
-       mach_port_t task;
-       mach_port_t *thread;
-       uint nthread;
-       Thread *ret;
-       static int first = 1;
-
-       if(first){
-               // Allocate a port for exception messages and
-               // send all thread exceptions to that port.
-               // The excthread reads that port and signals
-               // us if we are waiting on that thread.
-               pthread_t p;
-               int err;
-
-               excport = mach_reply_port();
-               pthread_mutex_init(&mu, nil);
-               pthread_cond_init(&cond, nil);
-               err = pthread_create(&p, nil, excthread, nil);
-               if (err != 0) {
-                       fprint(2, "pthread_create failed: %s\n", strerror(err));
-                       abort();
-               }
-               err = pthread_create(&p, nil, waitthread, (void*)(uintptr)pid);
-               if (err != 0) {
-                       fprint(2, "pthread_create failed: %s\n", strerror(err));
-                       abort();
-               }
-               first = 0;
-       }
-
-       if(!force){
-               for(i=0; i<nthr; i++)
-                       if(thr[i].pid == pid)
-                               return &thr[i];
-       }
-       if(me(task_for_pid(mach_task_self(), pid, &task)) < 0)
-               return nil;
-       if(me(task_threads(task, &thread, &nthread)) < 0)
-               return nil;
-       mach_port_insert_right(mach_task_self(), excport, excport, MACH_MSG_TYPE_MAKE_SEND);
-       if(me(task_set_exception_ports(task, ExcMask,
-                       excport, EXCEPTION_DEFAULT, MACHINE_THREAD_STATE)) < 0){
-               fprint(2, "warning: cannot set excport: %r\n");
-       }
-       ret = nil;
-       for(j=0; j<nthread; j++){
-               if(force){
-                       // If we're forcing a refresh, don't re-add existing threads.
-                       for(i=0; i<nthr; i++)
-                               if(thr[i].pid == pid && thr[i].thread == thread[j]){
-                                       if(ret == nil)
-                                               ret = &thr[i];
-                                       goto skip;
-                               }
-               }
-               if(nthr >= nelem(thr))
-                       return nil;
-               // TODO: We probably should save the old thread exception
-               // ports for each bit and then put them back when we exit.
-               // Probably the BSD signal handlers have put stuff there.
-               mach_port_insert_right(mach_task_self(), excport, excport, MACH_MSG_TYPE_MAKE_SEND);
-               if(me(thread_set_exception_ports(thread[j], ExcMask,
-                               excport, EXCEPTION_DEFAULT, MACHINE_THREAD_STATE)) < 0){
-                       fprint(2, "warning: cannot set excport: %r\n");
-               }
-               thr[nthr].pid = pid;
-               thr[nthr].task = task;
-               thr[nthr].thread = thread[j];
-               if(ret == nil)
-                       ret = &thr[nthr];
-               nthr++;
-       skip:;
-       }
-       return ret;
-}
-
-static Thread*
-idtotable(int id)
-{
-       if(id >= 0)
-               return addpid(id, 1);
-
-       id = -(id+1);
-       if(id >= nthr)
-               return nil;
-       return &thr[id];
-}
-
-/*
-static int
-idtopid(int id)
-{
-       Thread *t;
-
-       if((t = idtotable(id)) == nil)
-               return -1;
-       return t->pid;
-}
-*/
-
-static mach_port_t
-idtotask(int id)
-{
-       Thread *t;
-
-       if((t = idtotable(id)) == nil)
-               return -1;
-       return t->task;
-}
-
-static mach_port_t
-idtothread(int id)
-{
-       Thread *t;
-
-       if((t = idtotable(id)) == nil)
-               return -1;
-       return t->thread;
-}
-
-static int machsegrw(Map *map, Seg *seg, uvlong addr, void *v, uint n, int isr);
-static int machregrw(Map *map, Seg *seg, uvlong addr, void *v, uint n, int isr);
-
-Map*
-attachproc(int id, Fhdr *fp)
-{
-       Thread *t;
-       Map *map;
-
-       if((t = idtotable(id)) == nil)
-               return nil;
-       if(t->map)
-               return t->map;
-       map = newmap(0, 4);
-       if(!map)
-               return nil;
-       map->pid = -((t-thr) + 1);
-       if(mach->regsize)
-               setmap(map, -1, 0, mach->regsize, 0, "regs", machregrw);
-       setmap(map, -1, fp->txtaddr, fp->txtaddr+fp->txtsz, fp->txtaddr, "*text", machsegrw);
-       setmap(map, -1, fp->dataddr, mach->utop, fp->dataddr, "*data", machsegrw);
-       t->map = map;
-       return map;
-}
-
-// Return list of ids for threads in id.
-int
-procthreadpids(int id, int *out, int nout)
-{
-       Thread *t;
-       int i, n, pid;
-
-       t = idtotable(id);
-       if(t == nil)
-               return -1;
-       pid = t->pid;
-       addpid(pid, 1); // force refresh of thread list
-       n = 0;
-       for(i=0; i<nthr; i++) {
-               if(thr[i].pid == pid) {
-                       if(n < nout)
-                               out[n] = -(i+1);
-                       n++;
-               }
-       }
-       return n;
-}
-
-// Detach from proc.
-// TODO(rsc): Perhaps should unsuspend any threads and clean-up the table.
-void
-detachproc(Map *m)
-{
-       free(m);
-}
-
-// Should return array of pending signals (notes)
-// but don't know how to do that on OS X.
-int
-procnotes(int pid, char ***pnotes)
-{
-       USED(pid);
-       *pnotes = 0;
-       return 0;
-}
-
-// There must be a way to do this.  Gdb can do it.
-// But I don't see, in the Apple gdb sources, how.
-char*
-proctextfile(int pid)
-{
-       USED(pid);
-       return nil;
-}
-
-// Read/write from a Mach data segment.
-static int
-machsegrw(Map *map, Seg *seg, uvlong addr, void *v, uint n, int isr)
-{
-       mach_port_t task;
-       int r;
-
-       USED(seg);
-
-       task = idtotask(map->pid);
-       if(task == -1)
-               return -1;
-
-       if(isr){
-               vm_size_t nn;
-               nn = n;
-               if(me(vm_read_overwrite(task, addr, n, (uintptr)v, &nn)) < 0) {
-                       fprint(2, "vm_read_overwrite %#llux %d to %p: %r\n", addr, n, v);
-                       return -1;
-               }
-               return nn;
-       }else{
-               r = vm_write(task, addr, (uintptr)v, n);
-               if(r == KERN_INVALID_ADDRESS){
-                       // Happens when writing to text segment.
-                       // Change protections.
-                       if(me(vm_protect(task, addr, n, 0, VM_PROT_WRITE|VM_PROT_READ|VM_PROT_EXECUTE)) < 0){
-                               fprint(2, "vm_protect: %s\n", r);
-                               return -1;
-                       }
-                       r = vm_write(task, addr, (uintptr)v, n);
-               }
-               if(r != 0){
-                       me(r);
-                       return -1;
-               }
-               return n;
-       }
-}
-
-// Convert Ureg offset to x86_thread_state32_t offset.
-static int
-go2darwin32(uvlong addr)
-{
-       switch(addr){
-       case offsetof(Ureg386, ax):
-               return offsetof(x86_thread_state32_t, eax);
-       case offsetof(Ureg386, bx):
-               return offsetof(x86_thread_state32_t, ebx);
-       case offsetof(Ureg386, cx):
-               return offsetof(x86_thread_state32_t, ecx);
-       case offsetof(Ureg386, dx):
-               return offsetof(x86_thread_state32_t, edx);
-       case offsetof(Ureg386, si):
-               return offsetof(x86_thread_state32_t, esi);
-       case offsetof(Ureg386, di):
-               return offsetof(x86_thread_state32_t, edi);
-       case offsetof(Ureg386, bp):
-               return offsetof(x86_thread_state32_t, ebp);
-       case offsetof(Ureg386, fs):
-               return offsetof(x86_thread_state32_t, fs);
-       case offsetof(Ureg386, gs):
-               return offsetof(x86_thread_state32_t, gs);
-       case offsetof(Ureg386, pc):
-               return offsetof(x86_thread_state32_t, eip);
-       case offsetof(Ureg386, cs):
-               return offsetof(x86_thread_state32_t, cs);
-       case offsetof(Ureg386, flags):
-               return offsetof(x86_thread_state32_t, eflags);
-       case offsetof(Ureg386, sp):
-               return offsetof(x86_thread_state32_t, esp);
-       }
-       return -1;
-}
-
-// Convert Ureg offset to x86_thread_state64_t offset.
-static int
-go2darwin64(uvlong addr)
-{
-       switch(addr){
-       case offsetof(UregAmd64, ax):
-               return offsetof(x86_thread_state64_t, rax);
-       case offsetof(UregAmd64, bx):
-               return offsetof(x86_thread_state64_t, rbx);
-       case offsetof(UregAmd64, cx):
-               return offsetof(x86_thread_state64_t, rcx);
-       case offsetof(UregAmd64, dx):
-               return offsetof(x86_thread_state64_t, rdx);
-       case offsetof(UregAmd64, si):
-               return offsetof(x86_thread_state64_t, rsi);
-       case offsetof(UregAmd64, di):
-               return offsetof(x86_thread_state64_t, rdi);
-       case offsetof(UregAmd64, bp):
-               return offsetof(x86_thread_state64_t, rbp);
-       case offsetof(UregAmd64, r8):
-               return offsetof(x86_thread_state64_t, r8);
-       case offsetof(UregAmd64, r9):
-               return offsetof(x86_thread_state64_t, r9);
-       case offsetof(UregAmd64, r10):
-               return offsetof(x86_thread_state64_t, r10);
-       case offsetof(UregAmd64, r11):
-               return offsetof(x86_thread_state64_t, r11);
-       case offsetof(UregAmd64, r12):
-               return offsetof(x86_thread_state64_t, r12);
-       case offsetof(UregAmd64, r13):
-               return offsetof(x86_thread_state64_t, r13);
-       case offsetof(UregAmd64, r14):
-               return offsetof(x86_thread_state64_t, r14);
-       case offsetof(UregAmd64, r15):
-               return offsetof(x86_thread_state64_t, r15);
-       case offsetof(UregAmd64, fs):
-               return offsetof(x86_thread_state64_t, fs);
-       case offsetof(UregAmd64, gs):
-               return offsetof(x86_thread_state64_t, gs);
-       case offsetof(UregAmd64, ip):
-               return offsetof(x86_thread_state64_t, rip);
-       case offsetof(UregAmd64, cs):
-               return offsetof(x86_thread_state64_t, cs);
-       case offsetof(UregAmd64, flags):
-               return offsetof(x86_thread_state64_t, rflags);
-       case offsetof(UregAmd64, sp):
-               return offsetof(x86_thread_state64_t, rsp);
-       }
-       return -1;
-}
-
-extern Mach mi386;
-
-// Read/write from fake register segment.
-static int
-machregrw(Map *map, Seg *seg, uvlong addr, void *v, uint n, int isr)
-{
-       uint nn, count, state;
-       mach_port_t thread;
-       int reg;
-       char buf[100];
-       union {
-               x86_thread_state64_t reg64;
-               x86_thread_state32_t reg32;
-               uchar p[1];
-       } u;
-       uchar *p;
-
-       USED(seg);
-
-       if(n > 8){
-               werrstr("asked for %d-byte register", n);
-               return -1;
-       }
-
-       thread = idtothread(map->pid);
-       if(thread == -1){
-               werrstr("no such id");
-               return -1;
-       }
-
-       if(mach == &mi386) {
-               count = x86_THREAD_STATE32_COUNT;
-               state = x86_THREAD_STATE32;
-               if((reg = go2darwin32(addr)) < 0 || reg+n > sizeof u){
-                       if(isr){
-                               memset(v, 0, n);
-                               return 0;
-                       }
-                       werrstr("register %llud not available", addr);
-                       return -1;
-               }
-       } else {
-               count = x86_THREAD_STATE64_COUNT;
-               state = x86_THREAD_STATE64;
-               if((reg = go2darwin64(addr)) < 0 || reg+n > sizeof u){
-                       if(isr){
-                               memset(v, 0, n);
-                               return 0;
-                       }
-                       werrstr("register %llud not available", addr);
-                       return -1;
-               }
-       }
-
-       if(!isr && me(thread_suspend(thread)) < 0){
-               werrstr("thread suspend %#x: %r", thread);
-               return -1;
-       }
-       nn = count;
-       if(me(thread_get_state(thread, state, (void*)u.p, &nn)) < 0){
-               if(!isr)
-                       thread_resume(thread);
-               rerrstr(buf, sizeof buf);
-               if(strstr(buf, "send invalid dest") != nil) 
-                       werrstr("process exited");
-               else
-                       werrstr("thread_get_state: %r");
-               return -1;
-       }
-
-       p = u.p+reg;
-       if(isr)
-               memmove(v, p, n);
-       else{
-               memmove(p, v, n);
-               nn = count;
-               if(me(thread_set_state(thread, state, (void*)u.p, nn)) < 0){
-                       thread_resume(thread);
-                       werrstr("thread_set_state: %r");
-                       return -1;
-               }
-
-               if(me(thread_resume(thread)) < 0){
-                       werrstr("thread_resume: %r");
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-enum
-{
-       FLAGS_TF = 0x100                // x86 single-step processor flag
-};
-
-// Is thread t suspended?
-static int
-threadstopped(Thread *t)
-{
-       struct thread_basic_info info;
-       uint size;
-
-       size = sizeof info;
-       if(me(thread_info(t->thread, THREAD_BASIC_INFO, (thread_info_t)&info, &size)) <  0){
-               fprint(2, "threadstopped thread_info %#x: %r\n");
-               return 1;
-       }
-       return info.suspend_count > 0;
-}
-
-// If thread t is suspended, start it up again.
-// If singlestep is set, only let it execute one instruction.
-static int
-threadstart(Thread *t, int singlestep)
-{
-       int i;
-       uint n;
-       struct thread_basic_info info;
-
-       if(!threadstopped(t))
-               return 0;
-
-       // Set or clear the processor single-step flag, as appropriate.
-       if(mach == &mi386) {
-               x86_thread_state32_t regs;
-               n = x86_THREAD_STATE32_COUNT;
-               if(me(thread_get_state(t->thread, x86_THREAD_STATE32,
-                               (thread_state_t)&regs,
-                               &n)) < 0)
-                       return -1;
-               if(singlestep)
-                       regs.eflags |= FLAGS_TF;
-               else
-                       regs.eflags &= ~FLAGS_TF;
-               if(me(thread_set_state(t->thread, x86_THREAD_STATE32,
-                               (thread_state_t)&regs,
-                               x86_THREAD_STATE32_COUNT)) < 0)
-                       return -1;
-       } else {
-               x86_thread_state64_t regs;
-               n = x86_THREAD_STATE64_COUNT;
-               if(me(thread_get_state(t->thread, x86_THREAD_STATE64,
-                               (thread_state_t)&regs,
-                               &n)) < 0)
-                       return -1;
-               if(singlestep)
-                       regs.rflags |= FLAGS_TF;
-               else
-                       regs.rflags &= ~FLAGS_TF;
-               if(me(thread_set_state(t->thread, x86_THREAD_STATE64,
-                               (thread_state_t)&regs,
-                               x86_THREAD_STATE64_COUNT)) < 0)
-                       return -1;
-       }
-
-       // Run.
-       n = sizeof info;
-       if(me(thread_info(t->thread, THREAD_BASIC_INFO, (thread_info_t)&info, &n)) < 0)
-               return -1;
-       for(i=0; i<info.suspend_count; i++)
-               if(me(thread_resume(t->thread)) < 0)
-                       return -1;
-       return 0;
-}
-
-// Stop thread t.
-static int
-threadstop(Thread *t)
-{
-       if(threadstopped(t))
-               return 0;
-       if(me(thread_suspend(t->thread)) < 0)
-               return -1;
-       return 0;
-}
-
-// Callback for exc_server below.  Called when a thread we are
-// watching has an exception like hitting a breakpoint.
-kern_return_t
-catch_exception_raise(mach_port_t eport, mach_port_t thread,
-       mach_port_t task, exception_type_t exception,
-       exception_data_t code, mach_msg_type_number_t ncode)
-{
-       Thread *t;
-       int i;
-
-       USED(eport);
-       USED(task);
-
-       t = nil;
-       for(i=0; i<nthr; i++){
-               if(thr[i].thread == thread){
-                       t = &thr[i];
-                       goto havet;
-               }
-       }
-       if(nthr > 0)
-               addpid(thr[0].pid, 1);
-       for(i=0; i<nthr; i++){
-               if(thr[i].thread == thread){
-                       t = &thr[i];
-                       goto havet;
-               }
-       }
-       fprint(2, "did not find thread in catch_exception_raise\n");
-       return KERN_SUCCESS;    // let thread continue
-
-havet:
-       t->exc = exception;
-       if(ncode > nelem(t->code))
-               ncode = nelem(t->code);
-       memmove(t->code, code, ncode*sizeof t->code[0]);
-
-       // Suspend thread, so that we can look at it & restart it later.
-       if(me(thread_suspend(thread)) < 0)
-               fprint(2, "catch_exception_raise thread_suspend: %r\n");
-
-       // Synchronize with waitstop below.
-       pthread_mutex_lock(&mu);
-       pthread_cond_broadcast(&cond);
-       pthread_mutex_unlock(&mu);
-
-       return KERN_SUCCESS;
-}
-
-// Exception watching thread, started in addpid above.
-static void*
-excthread(void *v)
-{
-       USED(v);
-       extern boolean_t exc_server(mach_msg_header_t *, mach_msg_header_t *);
-       mach_msg_server(exc_server, 2048, excport, 0);
-       return 0;
-}
-
-// Wait for pid to exit.
-static int exited;
-static void*
-waitthread(void *v)
-{
-       int pid, status;
-
-       pid = (int)(uintptr)v;
-       waitpid(pid, &status, 0);
-       exited = 1;
-       // Synchronize with waitstop below.
-       pthread_mutex_lock(&mu);
-       pthread_cond_broadcast(&cond);
-       pthread_mutex_unlock(&mu);
-       return nil;
-}
-
-// Wait for thread t to stop.
-static int
-waitstop(Thread *t)
-{
-       pthread_mutex_lock(&mu);
-       while(!exited && !threadstopped(t))
-               pthread_cond_wait(&cond, &mu);
-       pthread_mutex_unlock(&mu);
-       return 0;
-}
-
-int
-ctlproc(int id, char *msg)
-{
-       Thread *t;
-       int status;
-
-       // Hang/attached dance is for debugging newly exec'ed programs.
-       // After fork, the child does ctlproc("hang") before exec,
-       // and the parent does ctlproc("attached") and then waitstop.
-       // Using these requires the BSD ptrace interface, unlike everything
-       // else we do, which uses only the Mach interface.  Our goal here
-       // is to do as little as possible using ptrace and then flip over to Mach.
-
-       if(strcmp(msg, "hang") == 0)
-               return ptrace(PT_TRACE_ME, 0, 0, 0);
-
-       if(strcmp(msg, "attached") == 0){
-               // The pid "id" has done a ctlproc "hang" and then
-               // exec, so we should find it stoppped just before exec
-               // of the new program.
-               #undef waitpid
-               if(waitpid(id, &status, WUNTRACED) < 0){
-                       fprint(2, "ctlproc attached waitpid: %r\n");
-                       return -1;
-               }
-               if(WIFEXITED(status) || !WIFSTOPPED(status)){
-                       fprint(2, "ctlproc attached: bad process state\n");
-                       return -1;
-               }
-
-               // Find Mach thread for pid and suspend it.
-               t = addpid(id, 1);
-               if(t == nil) {
-                       fprint(2, "ctlproc attached: addpid: %r\n");
-                       return -1;
-               }
-               if(me(thread_suspend(t->thread)) < 0){
-                       fprint(2, "ctlproc attached: thread_suspend: %r\n");
-                       return -1;
-               }
-
-               // Let ptrace tell the process to keep going:
-               // then ptrace is out of the way and we're back in Mach land.
-               if(ptrace(PT_CONTINUE, id, (caddr_t)1, 0) < 0) {
-                       fprint(2, "ctlproc attached: ptrace continue: %r\n");
-                       return -1;
-               }
-               
-               return 0;
-       }
-
-       // All the other control messages require a Thread structure.
-       if((t = idtotable(id)) == nil){
-               werrstr("no such thread");
-               return -1;
-       }
-
-       if(strcmp(msg, "kill") == 0)
-               return ptrace(PT_KILL, t->pid, 0, 0);
-
-       if(strcmp(msg, "start") == 0)
-               return threadstart(t, 0);
-
-       if(strcmp(msg, "stop") == 0)
-               return threadstop(t);
-
-       if(strcmp(msg, "startstop") == 0){
-               if(threadstart(t, 0) < 0)
-                       return -1;
-               return waitstop(t);
-       }
-
-       if(strcmp(msg, "step") == 0){
-               if(threadstart(t, 1) < 0)
-                       return -1;
-               return waitstop(t);
-       }
-
-       if(strcmp(msg, "waitstop") == 0)
-               return waitstop(t);
-
-       // sysstop not available on OS X
-
-       werrstr("unknown control message");
-       return -1;
-}
-
-char*
-procstatus(int id)
-{
-       Thread *t;
-
-       if((t = idtotable(id)) == nil)
-               return "gone!";
-
-       if(threadstopped(t))
-               return "Stopped";
-
-       return "Running";
-}
-
diff --git a/src/libmach/dragonfly.c b/src/libmach/dragonfly.c
deleted file mode 100644 (file)
index 43dd005..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-// This is stubbed out for the moment. Will revisit when the time comes.
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mach.h>
-
-int
-ctlproc(int pid, char *msg)
-{
-       USED(pid);
-       USED(msg);
-
-       sysfatal("ctlproc unimplemented in DragonFly");
-       return -1;
-}
-
-char*
-proctextfile(int pid)
-{
-       USED(pid);
-       
-       sysfatal("proctextfile unimplemented in DragonFly");
-       return nil;
-}
-
-char*
-procstatus(int pid)
-{
-       USED(pid);
-
-       sysfatal("procstatus unimplemented in DragonFly");
-       return nil;
-}
-
-Map*
-attachproc(int pid, Fhdr *fp)
-{
-       USED(pid);
-       USED(fp);
-
-       sysfatal("attachproc unimplemented in DragonFly");
-       return nil;
-}
-
-void
-detachproc(Map *m)
-{
-       USED(m);
-
-       sysfatal("detachproc unimplemented in DragonFly");
-}
-
-int
-procthreadpids(int pid, int *p, int np)
-{
-       USED(pid);
-       USED(p);
-       USED(np);
-
-       sysfatal("procthreadpids unimplemented in DragonFly");
-       return -1;
-}
diff --git a/src/libmach/elf.h b/src/libmach/elf.h
deleted file mode 100644 (file)
index 8dbc983..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-// Inferno libmach/elf.h
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/elf.h
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-/*
- *     Definitions needed for  accessing ELF headers.
- *     32-bit and 64-bit structs differ.
- */
-typedef struct {
-       uchar   ident[16];      /* ident bytes */
-       ushort  type;           /* file type */
-       ushort  machine;        /* target machine */
-       int     version;        /* file version */
-       uint32  elfentry;       /* start address */
-       uint32  phoff;          /* phdr file offset */
-       uint32  shoff;          /* shdr file offset */
-       int     flags;          /* file flags */
-       ushort  ehsize;         /* sizeof ehdr */
-       ushort  phentsize;      /* sizeof phdr */
-       ushort  phnum;          /* number phdrs */
-       ushort  shentsize;      /* sizeof shdr */
-       ushort  shnum;          /* number shdrs */
-       ushort  shstrndx;       /* shdr string index */
-} Ehdr32;
-
-typedef struct {
-       uchar   ident[16];      /* ident bytes */
-       ushort  type;           /* file type */
-       ushort  machine;        /* target machine */
-       int     version;        /* file version */
-       uvlong  elfentry;       /* start address */
-       uvlong  phoff;          /* phdr file offset */
-       uvlong  shoff;          /* shdr file offset */
-       int     flags;          /* file flags */
-       ushort  ehsize;         /* sizeof ehdr */
-       ushort  phentsize;      /* sizeof phdr */
-       ushort  phnum;          /* number phdrs */
-       ushort  shentsize;      /* sizeof shdr */
-       ushort  shnum;          /* number shdrs */
-       ushort  shstrndx;       /* shdr string index */
-} Ehdr64;
-
-typedef struct {
-       int     type;           /* entry type */
-       uint32  offset;         /* file offset */
-       uint32  vaddr;          /* virtual address */
-       uint32  paddr;          /* physical address */
-       int     filesz;         /* file size */
-       uint32  memsz;          /* memory size */
-       int     flags;          /* entry flags */
-       int     align;          /* memory/file alignment */
-} Phdr32;
-
-typedef struct {
-       int     type;           /* entry type */
-       int     flags;          /* entry flags */
-       uvlong  offset;         /* file offset */
-       uvlong  vaddr;          /* virtual address */
-       uvlong  paddr;          /* physical address */
-       uvlong  filesz;         /* file size */
-       uvlong  memsz;          /* memory size */
-       uvlong  align;          /* memory/file alignment */
-} Phdr64;
-
-typedef struct {
-       uint32  name;           /* section name */
-       uint32  type;           /* SHT_... */
-       uint32  flags;          /* SHF_... */
-       uint32  addr;           /* virtual address */
-       uint32  offset;         /* file offset */
-       uint32  size;           /* section size */
-       uint32  link;           /* misc info */
-       uint32  info;           /* misc info */
-       uint32  addralign;      /* memory alignment */
-       uint32  entsize;        /* entry size if table */
-} Shdr32;
-
-typedef struct {
-       uint32  name;           /* section name */
-       uint32  type;           /* SHT_... */
-       uvlong  flags;          /* SHF_... */
-       uvlong  addr;           /* virtual address */
-       uvlong  offset;         /* file offset */
-       uvlong  size;           /* section size */
-       uint32  link;           /* misc info */
-       uint32  info;           /* misc info */
-       uvlong  addralign;      /* memory alignment */
-       uvlong  entsize;        /* entry size if table */
-} Shdr64;
-
-enum {
-       /* Ehdr codes */
-       MAG0 = 0,               /* ident[] indexes */
-       MAG1 = 1,
-       MAG2 = 2,
-       MAG3 = 3,
-       CLASS = 4,
-       DATA = 5,
-       VERSION = 6,
-
-       ELFCLASSNONE = 0,       /* ident[CLASS] */
-       ELFCLASS32 = 1,
-       ELFCLASS64 = 2,
-       ELFCLASSNUM = 3,
-
-       ELFDATANONE = 0,        /* ident[DATA] */
-       ELFDATA2LSB = 1,
-       ELFDATA2MSB = 2,
-       ELFDATANUM = 3,
-
-       NOETYPE = 0,            /* type */
-       REL = 1,
-       EXEC = 2,
-       DYN = 3,
-       CORE = 4,
-
-       NONE = 0,               /* machine */
-       M32 = 1,                /* AT&T WE 32100 */
-       SPARC = 2,              /* Sun SPARC */
-       I386 = 3,               /* Intel 80386 */
-       M68K = 4,               /* Motorola 68000 */
-       M88K = 5,               /* Motorola 88000 */
-       I486 = 6,               /* Intel 80486 */
-       I860 = 7,               /* Intel i860 */
-       MIPS = 8,               /* Mips R2000 */
-       S370 = 9,               /* Amdhal       */
-       SPARC64 = 18,           /* Sun SPARC v9 */
-       POWER = 20,             /* PowerPC */
-       ARM = 40,                       /* ARM */
-       AMD64 = 62,             /* Amd64 */
-
-       NO_VERSION = 0,         /* version, ident[VERSION] */
-       CURRENT = 1,
-
-       /* Phdr Codes */
-       NOPTYPE = 0,            /* type */
-       LOAD = 1,
-       DYNAMIC = 2,
-       INTERP = 3,
-       NOTE = 4,
-       SHLIB = 5,
-       PHDR = 6,
-
-       R = 0x4,                /* flags */
-       W = 0x2,
-       X = 0x1,
-
-       /* Shdr Codes */
-       Progbits = 1,   /* section types */
-       Strtab = 3,
-       Nobits = 8,
-
-       Swrite = 1,     /* section attributes */
-       Salloc = 2,
-       Sexec = 4,
-};
-
-#define        ELF_MAG         ((0x7f<<24) | ('E'<<16) | ('L'<<8) | 'F')
diff --git a/src/libmach/executable.c b/src/libmach/executable.c
deleted file mode 100644 (file)
index eae1444..0000000
+++ /dev/null
@@ -1,1525 +0,0 @@
-// Inferno libmach/executable.c
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/executable.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include       <u.h>
-#include       <libc.h>
-#include       <bio.h>
-#include       <bootexec.h>
-#include       <mach.h>
-#include       "elf.h"
-#include       "macho.h"
-
-/*
- *     All a.out header types.  The dummy entry allows canonical
- *     processing of the union as a sequence of int32s
- */
-
-typedef struct {
-       union{
-               /*struct { */
-                       Exec exechdr;           /* a.out.h */
-               /*      uvlong hdr[1];*/
-               /*};*/
-               Ehdr32 elfhdr32;                        /* elf.h */
-               Ehdr64 elfhdr64;                        /* elf.h */
-               struct mipsexec mips;   /* bootexec.h */
-               struct mips4kexec mipsk4;       /* bootexec.h */
-               struct sparcexec sparc; /* bootexec.h */
-               struct nextexec next;   /* bootexec.h */
-               Machhdr machhdr;        /* macho.h */
-       } e;
-       int32 dummy;                    /* padding to ensure extra int32 */
-} ExecHdr;
-
-static int     nextboot(int, Fhdr*, ExecHdr*);
-static int     sparcboot(int, Fhdr*, ExecHdr*);
-static int     mipsboot(int, Fhdr*, ExecHdr*);
-static int     mips4kboot(int, Fhdr*, ExecHdr*);
-static int     common(int, Fhdr*, ExecHdr*);
-static int     commonllp64(int, Fhdr*, ExecHdr*);
-static int     adotout(int, Fhdr*, ExecHdr*);
-static int     elfdotout(int, Fhdr*, ExecHdr*);
-static int     machdotout(int, Fhdr*, ExecHdr*);
-static int     armdotout(int, Fhdr*, ExecHdr*);
-static int     pedotout(int, Fhdr*, ExecHdr*);
-static void    setsym(Fhdr*, vlong, int32, vlong, int32, vlong, int32);
-static void    setdata(Fhdr*, uvlong, int32, vlong, int32);
-static void    settext(Fhdr*, uvlong, uvlong, int32, vlong);
-static void    hswal(void*, int, uint32(*)(uint32));
-static uvlong  _round(uvlong, uint32);
-
-/*
- *     definition of per-executable file type structures
- */
-
-typedef struct Exectable{
-       int32   magic;                  /* big-endian magic number of file */
-       char    *name;                  /* executable identifier */
-       char    *dlmname;               /* dynamically loadable module identifier */
-       uchar   type;                   /* Internal code */
-       uchar   _magic;                 /* _MAGIC() magic */
-       Mach    *mach;                  /* Per-machine data */
-       int32   hsize;                  /* header size */
-       uint32  (*swal)(uint32);                /* beswal or leswal */
-       int     (*hparse)(int, Fhdr*, ExecHdr*);
-} ExecTable;
-
-extern Mach    mmips;
-extern Mach    mmips2le;
-extern Mach    mmips2be;
-extern Mach    msparc;
-extern Mach    msparc64;
-extern Mach    m68020;
-extern Mach    mi386;
-extern Mach    mamd64;
-extern Mach    marm;
-extern Mach    mpower;
-extern Mach    mpower64;
-extern Mach    malpha;
-
-/* BUG: FIX THESE WHEN NEEDED */
-Mach   mmips;
-Mach   mmips2le;
-Mach   mmips2be;
-Mach   msparc;
-Mach   msparc64;
-Mach   m68020;
-Mach   mpower;
-Mach   mpower64;
-Mach   malpha;
-
-ExecTable exectab[] =
-{
-       { V_MAGIC,                      /* Mips v.out */
-               "mips plan 9 executable BE",
-               "mips plan 9 dlm BE",
-               FMIPS,
-               1,
-               &mmips,
-               sizeof(Exec),
-               beswal,
-               adotout },
-       { P_MAGIC,                      /* Mips 0.out (r3k le) */
-               "mips plan 9 executable LE",
-               "mips plan 9 dlm LE",
-               FMIPSLE,
-               1,
-               &mmips,
-               sizeof(Exec),
-               beswal,
-               adotout },
-       { M_MAGIC,                      /* Mips 4.out */
-               "mips 4k plan 9 executable BE",
-               "mips 4k plan 9 dlm BE",
-               FMIPS2BE,
-               1,
-               &mmips2be,
-               sizeof(Exec),
-               beswal,
-               adotout },
-       { N_MAGIC,                      /* Mips 0.out */
-               "mips 4k plan 9 executable LE",
-               "mips 4k plan 9 dlm LE",
-               FMIPS2LE,
-               1,
-               &mmips2le,
-               sizeof(Exec),
-               beswal,
-               adotout },
-       { 0x160<<16,                    /* Mips boot image */
-               "mips plan 9 boot image",
-               nil,
-               FMIPSB,
-               0,
-               &mmips,
-               sizeof(struct mipsexec),
-               beswal,
-               mipsboot },
-       { (0x160<<16)|3,                /* Mips boot image */
-               "mips 4k plan 9 boot image",
-               nil,
-               FMIPSB,
-               0,
-               &mmips2be,
-               sizeof(struct mips4kexec),
-               beswal,
-               mips4kboot },
-       { K_MAGIC,                      /* Sparc k.out */
-               "sparc plan 9 executable",
-               "sparc plan 9 dlm",
-               FSPARC,
-               1,
-               &msparc,
-               sizeof(Exec),
-               beswal,
-               adotout },
-       { 0x01030107,                   /* Sparc boot image */
-               "sparc plan 9 boot image",
-               nil,
-               FSPARCB,
-               0,
-               &msparc,
-               sizeof(struct sparcexec),
-               beswal,
-               sparcboot },
-       { U_MAGIC,                      /* Sparc64 u.out */
-               "sparc64 plan 9 executable",
-               "sparc64 plan 9 dlm",
-               FSPARC64,
-               1,
-               &msparc64,
-               sizeof(Exec),
-               beswal,
-               adotout },
-       { A_MAGIC,                      /* 68020 2.out & boot image */
-               "68020 plan 9 executable",
-               "68020 plan 9 dlm",
-               F68020,
-               1,
-               &m68020,
-               sizeof(Exec),
-               beswal,
-               common },
-       { 0xFEEDFACE,                   /* Next boot image */
-               "next plan 9 boot image",
-               nil,
-               FNEXTB,
-               0,
-               &m68020,
-               sizeof(struct nextexec),
-               beswal,
-               nextboot },
-       { I_MAGIC,                      /* I386 8.out & boot image */
-               "386 plan 9 executable",
-               "386 plan 9 dlm",
-               FI386,
-               1,
-               &mi386,
-               sizeof(Exec),
-               beswal,
-               common },
-       { S_MAGIC,                      /* amd64 6.out & boot image */
-               "amd64 plan 9 executable",
-               "amd64 plan 9 dlm",
-               FAMD64,
-               1,
-               &mamd64,
-               sizeof(Exec)+8,
-               nil,
-               commonllp64 },
-       { Q_MAGIC,                      /* PowerPC q.out & boot image */
-               "power plan 9 executable",
-               "power plan 9 dlm",
-               FPOWER,
-               1,
-               &mpower,
-               sizeof(Exec),
-               beswal,
-               common },
-       { T_MAGIC,                      /* power64 9.out & boot image */
-               "power64 plan 9 executable",
-               "power64 plan 9 dlm",
-               FPOWER64,
-               1,
-               &mpower64,
-               sizeof(Exec)+8,
-               nil,
-               commonllp64 },
-       { ELF_MAG,                      /* any elf32 or elf64 */
-               "elf executable",
-               nil,
-               FNONE,
-               0,
-               &mi386,
-               sizeof(Ehdr64),
-               nil,
-               elfdotout },
-       { MACH64_MAG,                   /* 64-bit MACH (apple mac) */
-               "mach executable",
-               nil,
-               FAMD64,
-               0,
-               &mamd64,
-               sizeof(Machhdr),
-               nil,
-               machdotout },
-       { MACH32_MAG,                   /* 32-bit MACH (apple mac) */
-               "mach executable",
-               nil,
-               FI386,
-               0,
-               &mi386,
-               sizeof(Machhdr),
-               nil,
-               machdotout },
-       { E_MAGIC,                      /* Arm 5.out and boot image */
-               "arm plan 9 executable",
-               "arm plan 9 dlm",
-               FARM,
-               1,
-               &marm,
-               sizeof(Exec),
-               beswal,
-               common },
-       { (143<<16)|0413,               /* (Free|Net)BSD Arm */
-               "arm *bsd executable",
-               nil,
-               FARM,
-               0,
-               &marm,
-               sizeof(Exec),
-               leswal,
-               armdotout },
-       { L_MAGIC,                      /* alpha 7.out */
-               "alpha plan 9 executable",
-               "alpha plan 9 dlm",
-               FALPHA,
-               1,
-               &malpha,
-               sizeof(Exec),
-               beswal,
-               common },
-       { 0x0700e0c3,                   /* alpha boot image */
-               "alpha plan 9 boot image",
-               nil,
-               FALPHA,
-               0,
-               &malpha,
-               sizeof(Exec),
-               beswal,
-               common },
-       { 0x4d5a9000,    /* see dosstub[] in pe.c */
-               "windows PE executable",
-               nil,
-               FWINPE,
-               0,
-               &mi386,
-               sizeof(Exec), /* TODO */
-               nil,
-               pedotout },
-       { 0 },
-};
-
-Mach   *mach = &mi386;                 /* Global current machine table */
-
-static ExecTable*
-couldbe4k(ExecTable *mp)
-{
-       Dir *d;
-       ExecTable *f;
-
-       if((d=dirstat("/proc/1/regs")) == nil)
-               return mp;
-       if(d->length < 32*8){           /* R3000 */
-               free(d);
-               return mp;
-       }
-       free(d);
-       for (f = exectab; f->magic; f++)
-               if(f->magic == M_MAGIC) {
-                       f->name = "mips plan 9 executable on mips2 kernel";
-                       return f;
-               }
-       return mp;
-}
-
-int
-crackhdr(int fd, Fhdr *fp)
-{
-       ExecTable *mp;
-       ExecHdr d;
-       int nb, ret;
-       uint32 magic;
-
-       fp->type = FNONE;
-       nb = read(fd, (char *)&d.e, sizeof(d.e));
-       if (nb <= 0)
-               return 0;
-
-       ret = 0;
-       magic = beswal(d.e.exechdr.magic);              /* big-endian */
-       for (mp = exectab; mp->magic; mp++) {
-               if (nb < mp->hsize)
-                       continue;
-
-               /*
-                * The magic number has morphed into something
-                * with fields (the straw was DYN_MAGIC) so now
-                * a flag is needed in Fhdr to distinguish _MAGIC()
-                * magic numbers from foreign magic numbers.
-                *
-                * This code is creaking a bit and if it has to
-                * be modified/extended much more it's probably
-                * time to step back and redo it all.
-                */
-               if(mp->_magic){
-                       if(mp->magic != (magic & ~DYN_MAGIC))
-                               continue;
-
-                       if(mp->magic == V_MAGIC)
-                               mp = couldbe4k(mp);
-
-                       if ((magic & DYN_MAGIC) && mp->dlmname != nil)
-                               fp->name = mp->dlmname;
-                       else
-                               fp->name = mp->name;
-               }
-               else{
-                       if(mp->magic != magic)
-                               continue;
-                       fp->name = mp->name;
-               }
-               fp->type = mp->type;
-               fp->hdrsz = mp->hsize;          /* will be zero on bootables */
-               fp->_magic = mp->_magic;
-               fp->magic = magic;
-
-               mach = mp->mach;
-               if(mp->swal != nil)
-                       hswal(&d, sizeof(d.e)/sizeof(uint32), mp->swal);
-               ret = mp->hparse(fd, fp, &d);
-               seek(fd, mp->hsize, 0);         /* seek to end of header */
-               break;
-       }
-       if(mp->magic == 0)
-               werrstr("unknown header type");
-       return ret;
-}
-
-/*
- * Convert header to canonical form
- */
-static void
-hswal(void *v, int n, uint32 (*swap)(uint32))
-{
-       uint32 *ulp;
-
-       for(ulp = v; n--; ulp++)
-               *ulp = (*swap)(*ulp);
-}
-
-/*
- *     Crack a normal a.out-type header
- */
-static int
-adotout(int fd, Fhdr *fp, ExecHdr *hp)
-{
-       int32 pgsize;
-
-       USED(fd);
-       pgsize = mach->pgsize;
-       settext(fp, hp->e.exechdr.entry, pgsize+sizeof(Exec),
-                       hp->e.exechdr.text, sizeof(Exec));
-       setdata(fp, _round(pgsize+fp->txtsz+sizeof(Exec), pgsize),
-               hp->e.exechdr.data, fp->txtsz+sizeof(Exec), hp->e.exechdr.bss);
-       setsym(fp, fp->datoff+fp->datsz, hp->e.exechdr.syms, 0, hp->e.exechdr.spsz, 0, hp->e.exechdr.pcsz);
-       return 1;
-}
-
-static void
-commonboot(Fhdr *fp)
-{
-       if (!(fp->entry & mach->ktmask))
-               return;
-
-       switch(fp->type) {                              /* boot image */
-       case F68020:
-               fp->type = F68020B;
-               fp->name = "68020 plan 9 boot image";
-               break;
-       case FI386:
-               fp->type = FI386B;
-               fp->txtaddr = (u32int)fp->entry;
-               fp->name = "386 plan 9 boot image";
-               fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize);
-               break;
-       case FARM:
-               fp->type = FARMB;
-               fp->txtaddr = (u32int)fp->entry;
-               fp->name = "ARM plan 9 boot image";
-               fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize);
-               return;
-       case FALPHA:
-               fp->type = FALPHAB;
-               fp->txtaddr = (u32int)fp->entry;
-               fp->name = "alpha plan 9 boot image";
-               fp->dataddr = fp->txtaddr+fp->txtsz;
-               break;
-       case FPOWER:
-               fp->type = FPOWERB;
-               fp->txtaddr = (u32int)fp->entry;
-               fp->name = "power plan 9 boot image";
-               fp->dataddr = fp->txtaddr+fp->txtsz;
-               break;
-       case FAMD64:
-               fp->type = FAMD64B;
-               fp->txtaddr = fp->entry;
-               fp->name = "amd64 plan 9 boot image";
-               fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize);
-               break;
-       default:
-               return;
-       }
-       fp->hdrsz = 0;                  /* header stripped */
-}
-
-/*
- *     _MAGIC() style headers and
- *     alpha plan9-style bootable images for axp "headerless" boot
- *
- */
-static int
-common(int fd, Fhdr *fp, ExecHdr *hp)
-{
-       adotout(fd, fp, hp);
-       if(hp->e.exechdr.magic & DYN_MAGIC) {
-               fp->txtaddr = 0;
-               fp->dataddr = fp->txtsz;
-               return 1;
-       }
-       commonboot(fp);
-       return 1;
-}
-
-static int
-commonllp64(int unused, Fhdr *fp, ExecHdr *hp)
-{
-       int32 pgsize;
-       uvlong entry;
-
-       USED(unused);
-
-       hswal(&hp->e, sizeof(Exec)/sizeof(int32), beswal);
-       if(!(hp->e.exechdr.magic & HDR_MAGIC))
-               return 0;
-
-       /*
-        * There can be more magic here if the
-        * header ever needs more expansion.
-        * For now just catch use of any of the
-        * unused bits.
-        */
-       if((hp->e.exechdr.magic & ~DYN_MAGIC)>>16)
-               return 0;
-       union {
-               char *p;
-               uvlong *v;
-       } u;
-       u.p = (char*)&hp->e.exechdr;
-       entry = beswav(*u.v);
-
-       pgsize = mach->pgsize;
-       settext(fp, entry, pgsize+fp->hdrsz, hp->e.exechdr.text, fp->hdrsz);
-       setdata(fp, _round(pgsize+fp->txtsz+fp->hdrsz, pgsize),
-               hp->e.exechdr.data, fp->txtsz+fp->hdrsz, hp->e.exechdr.bss);
-       setsym(fp, fp->datoff+fp->datsz, hp->e.exechdr.syms, 0, hp->e.exechdr.spsz, 0, hp->e.exechdr.pcsz);
-
-       if(hp->e.exechdr.magic & DYN_MAGIC) {
-               fp->txtaddr = 0;
-               fp->dataddr = fp->txtsz;
-               return 1;
-       }
-       commonboot(fp);
-       return 1;
-}
-
-/*
- *     mips bootable image.
- */
-static int
-mipsboot(int fd, Fhdr *fp, ExecHdr *hp)
-{
-       USED(fd);
-       USED(fp);
-       USED(hp);
-
-abort();
-#ifdef unused
-       USED(fd);
-       fp->type = FMIPSB;
-       switch(hp->e.exechdr.amagic) {
-       default:
-       case 0407:      /* some kind of mips */
-               settext(fp, (u32int)hp->e.mentry, (u32int)hp->e.text_start,
-                       hp->e.tsize, sizeof(struct mipsexec)+4);
-               setdata(fp, (u32int)hp->e.data_start, hp->e.dsize,
-                       fp->txtoff+hp->e.tsize, hp->e.bsize);
-               break;
-       case 0413:      /* some kind of mips */
-               settext(fp, (u32int)hp->e.mentry, (u32int)hp->e.text_start,
-                       hp->e.tsize, 0);
-               setdata(fp, (u32int)hp->e.data_start, hp->e.dsize,
-                       hp->e.tsize, hp->e.bsize);
-               break;
-       }
-       setsym(fp, hp->e.nsyms, 0, hp->e.pcsize, hp->e.symptr);
-       fp->hdrsz = 0;                  /* header stripped */
-#endif
-       return 1;
-}
-
-/*
- *     mips4k bootable image.
- */
-static int
-mips4kboot(int fd, Fhdr *fp, ExecHdr *hp)
-{
-       USED(fd);
-       USED(fp);
-       USED(hp);
-
-abort();
-#ifdef unused
-       USED(fd);
-       fp->type = FMIPSB;
-       switch(hp->e.h.amagic) {
-       default:
-       case 0407:      /* some kind of mips */
-               settext(fp, (u32int)hp->e.h.mentry, (u32int)hp->e.h.text_start,
-                       hp->e.h.tsize, sizeof(struct mips4kexec));
-               setdata(fp, (u32int)hp->e.h.data_start, hp->e.h.dsize,
-                       fp->txtoff+hp->e.h.tsize, hp->e.h.bsize);
-               break;
-       case 0413:      /* some kind of mips */
-               settext(fp, (u32int)hp->e.h.mentry, (u32int)hp->e.h.text_start,
-                       hp->e.h.tsize, 0);
-               setdata(fp, (u32int)hp->e.h.data_start, hp->e.h.dsize,
-                       hp->e.h.tsize, hp->e.h.bsize);
-               break;
-       }
-       setsym(fp, hp->e.h.nsyms, 0, hp->e.h.pcsize, hp->e.h.symptr);
-       fp->hdrsz = 0;                  /* header stripped */
-#endif
-       return 1;
-}
-
-/*
- *     sparc bootable image
- */
-static int
-sparcboot(int fd, Fhdr *fp, ExecHdr *hp)
-{
-       USED(fd);
-       USED(fp);
-       USED(hp);
-
-abort();
-#ifdef unused
-       USED(fd);
-       fp->type = FSPARCB;
-       settext(fp, hp->e.sentry, hp->e.sentry, hp->e.stext,
-               sizeof(struct sparcexec));
-       setdata(fp, hp->e.sentry+hp->e.stext, hp->e.sdata,
-               fp->txtoff+hp->e.stext, hp->e.sbss);
-       setsym(fp, hp->e.ssyms, 0, hp->e.sdrsize, fp->datoff+hp->e.sdata);
-       fp->hdrsz = 0;                  /* header stripped */
-#endif
-       return 1;
-}
-
-/*
- *     next bootable image
- */
-static int
-nextboot(int fd, Fhdr *fp, ExecHdr *hp)
-{
-       USED(fd);
-       USED(fp);
-       USED(hp);
-
-abort();
-#ifdef unused
-       USED(fd);
-       fp->type = FNEXTB;
-       settext(fp, hp->e.textc.vmaddr, hp->e.textc.vmaddr,
-               hp->e.texts.size, hp->e.texts.offset);
-       setdata(fp, hp->e.datac.vmaddr, hp->e.datas.size,
-               hp->e.datas.offset, hp->e.bsss.size);
-       setsym(fp, hp->e.symc.nsyms, hp->e.symc.spoff, hp->e.symc.pcoff,
-               hp->e.symc.symoff);
-       fp->hdrsz = 0;                  /* header stripped */
-#endif
-       return 1;
-}
-
-/*
- * Elf32 and Elf64 binaries.
- */
-static int
-elf64dotout(int fd, Fhdr *fp, ExecHdr *hp)
-{
-       uvlong (*swav)(uvlong);
-       uint32 (*swal)(uint32);
-       ushort (*swab)(ushort);
-       Ehdr64 *ep;
-       Phdr64 *ph, *pph;
-       Shdr64 *sh;
-       int i, it, id, is, phsz, shsz;
-
-       /* bitswap the header according to the DATA format */
-       ep = &hp->e.elfhdr64;
-       if(ep->ident[CLASS] != ELFCLASS64) {
-               werrstr("bad ELF class - not 32 bit or 64 bit");
-               return 0;
-       }
-       if(ep->ident[DATA] == ELFDATA2LSB) {
-               swab = leswab;
-               swal = leswal;
-               swav = leswav;
-       } else if(ep->ident[DATA] == ELFDATA2MSB) {
-               swab = beswab;
-               swal = beswal;
-               swav = beswav;
-       } else {
-               werrstr("bad ELF encoding - not big or little endian");
-               return 0;
-       }
-
-       ep->type = swab(ep->type);
-       ep->machine = swab(ep->machine);
-       ep->version = swal(ep->version);
-       ep->elfentry = swal(ep->elfentry);
-       ep->phoff = swav(ep->phoff);
-       ep->shoff = swav(ep->shoff);
-       ep->flags = swav(ep->flags);
-       ep->ehsize = swab(ep->ehsize);
-       ep->phentsize = swab(ep->phentsize);
-       ep->phnum = swab(ep->phnum);
-       ep->shentsize = swab(ep->shentsize);
-       ep->shnum = swab(ep->shnum);
-       ep->shstrndx = swab(ep->shstrndx);
-       if(ep->type != EXEC || ep->version != CURRENT)
-               return 0;
-
-       /* we could definitely support a lot more machines here */
-       fp->magic = ELF_MAG;
-       fp->hdrsz = (ep->ehsize+ep->phnum*ep->phentsize+16)&~15;
-       switch(ep->machine) {
-       case AMD64:
-               mach = &mamd64;
-               fp->type = FAMD64;
-               break;
-       default:
-               return 0;
-       }
-
-       if(ep->phentsize != sizeof(Phdr64)) {
-               werrstr("bad ELF header size");
-               return 0;
-       }
-       phsz = sizeof(Phdr64)*ep->phnum;
-       ph = malloc(phsz);
-       if(!ph)
-               return 0;
-       seek(fd, ep->phoff, 0);
-       if(read(fd, ph, phsz) < 0) {
-               free(ph);
-               return 0;
-       }
-       hswal(ph, phsz/sizeof(uint32), swal);
-
-       shsz = sizeof(Shdr64)*ep->shnum;
-       sh = malloc(shsz);
-       if(sh) {
-               seek(fd, ep->shoff, 0);
-               if(read(fd, sh, shsz) < 0) {
-                       free(sh);
-                       sh = 0;
-               } else
-                       hswal(sh, shsz/sizeof(uint32), swal);
-       }
-
-       /* find text, data and symbols and install them */
-       it = id = is = -1;
-       for(i = 0; i < ep->phnum; i++) {
-               if(ph[i].type == LOAD
-               && (ph[i].flags & (R|X)) == (R|X) && it == -1)
-                       it = i;
-               else if(ph[i].type == LOAD
-               && (ph[i].flags & (R|W)) == (R|W) && id == -1)
-                       id = i;
-               else if(ph[i].type == NOPTYPE && is == -1)
-                       is = i;
-       }
-       if(it == -1 || id == -1) {
-               /*
-                * The SPARC64 boot image is something of an ELF hack.
-                * Text+Data+BSS are represented by ph[0].  Symbols
-                * are represented by ph[1]:
-                *
-                *              filesz, memsz, vaddr, paddr, off
-                * ph[0] : txtsz+datsz, txtsz+datsz+bsssz, txtaddr-KZERO, datasize, txtoff
-                * ph[1] : symsz, lcsz, 0, 0, symoff
-                */
-               if(ep->machine == SPARC64 && ep->phnum == 2) {
-                       uint32 txtaddr, txtsz, dataddr, bsssz;
-
-                       txtaddr = ph[0].vaddr | 0x80000000;
-                       txtsz = ph[0].filesz - ph[0].paddr;
-                       dataddr = txtaddr + txtsz;
-                       bsssz = ph[0].memsz - ph[0].filesz;
-                       settext(fp, ep->elfentry | 0x80000000, txtaddr, txtsz, ph[0].offset);
-                       setdata(fp, dataddr, ph[0].paddr, ph[0].offset + txtsz, bsssz);
-                       setsym(fp, ph[1].offset, ph[1].filesz, 0, 0, 0, ph[1].memsz);
-                       free(ph);
-                       return 1;
-               }
-
-               werrstr("No TEXT or DATA sections");
-               free(ph);
-               free(sh);
-               return 0;
-       }
-
-       settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset);
-       pph = ph + id;
-       setdata(fp, pph->vaddr, pph->filesz, pph->offset, pph->memsz - pph->filesz);
-       if(is != -1)
-               setsym(fp, ph[is].offset, ph[is].filesz, 0, 0, 0, ph[is].memsz);
-       else if(sh != 0){
-               char *buf;
-               uvlong symsize = 0;
-               uvlong symoff = 0;
-               uvlong pclnsz = 0;
-               uvlong pclnoff = 0;
-
-               /* load shstrtab names */
-               buf = malloc(sh[ep->shstrndx].size);
-               if (buf == 0)
-                       goto done;
-               memset(buf, 0, sh[ep->shstrndx].size);
-               seek(fd, sh[ep->shstrndx].offset, 0);
-               i = read(fd, buf, sh[ep->shstrndx].size);
-               USED(i);        // shut up ubuntu gcc
-
-               for(i = 0; i < ep->shnum; i++) {
-                       if (strcmp(&buf[sh[i].name], ".gosymtab") == 0) {
-                               symsize = sh[i].size;
-                               symoff = sh[i].offset;
-                       }
-                       if (strcmp(&buf[sh[i].name], ".gopclntab") == 0) {
-                               pclnsz = sh[i].size;
-                               pclnoff = sh[i].offset;
-                       }
-               }
-               setsym(fp, symoff, symsize, 0, 0, pclnoff, pclnsz);
-               free(buf);
-       }
-done:
-       free(ph);
-       free(sh);
-       return 1;
-}
-
-static int
-elfdotout(int fd, Fhdr *fp, ExecHdr *hp)
-{
-
-       uint32 (*swal)(uint32);
-       ushort (*swab)(ushort);
-       Ehdr32 *ep;
-       Phdr32 *ph;
-       int i, it, id, is, phsz, shsz;
-       Shdr32 *sh;
-
-       /* bitswap the header according to the DATA format */
-       ep = &hp->e.elfhdr32;
-       if(ep->ident[CLASS] != ELFCLASS32) {
-               return elf64dotout(fd, fp, hp);
-       }
-       if(ep->ident[DATA] == ELFDATA2LSB) {
-               swab = leswab;
-               swal = leswal;
-       } else if(ep->ident[DATA] == ELFDATA2MSB) {
-               swab = beswab;
-               swal = beswal;
-       } else {
-               werrstr("bad ELF encoding - not big or little endian");
-               return 0;
-       }
-
-       ep->type = swab(ep->type);
-       ep->machine = swab(ep->machine);
-       ep->version = swal(ep->version);
-       ep->elfentry = swal(ep->elfentry);
-       ep->phoff = swal(ep->phoff);
-       ep->shoff = swal(ep->shoff);
-       ep->flags = swal(ep->flags);
-       ep->ehsize = swab(ep->ehsize);
-       ep->phentsize = swab(ep->phentsize);
-       ep->phnum = swab(ep->phnum);
-       ep->shentsize = swab(ep->shentsize);
-       ep->shnum = swab(ep->shnum);
-       ep->shstrndx = swab(ep->shstrndx);
-       if(ep->type != EXEC || ep->version != CURRENT)
-               return 0;
-
-       /* we could definitely support a lot more machines here */
-       fp->magic = ELF_MAG;
-       fp->hdrsz = (ep->ehsize+ep->phnum*ep->phentsize+16)&~15;
-       switch(ep->machine) {
-       case I386:
-               mach = &mi386;
-               fp->type = FI386;
-               break;
-       case MIPS:
-               mach = &mmips;
-               fp->type = FMIPS;
-               break;
-       case SPARC64:
-               mach = &msparc64;
-               fp->type = FSPARC64;
-               break;
-       case POWER:
-               mach = &mpower;
-               fp->type = FPOWER;
-               break;
-       case ARM:
-               mach = &marm;
-               fp->type = FARM;
-               break;
-       default:
-               return 0;
-       }
-
-       if(ep->phentsize != sizeof(Phdr32)) {
-               werrstr("bad ELF header size");
-               return 0;
-       }
-       phsz = sizeof(Phdr32)*ep->phnum;
-       ph = malloc(phsz);
-       if(!ph)
-               return 0;
-       seek(fd, ep->phoff, 0);
-       if(read(fd, ph, phsz) < 0) {
-               free(ph);
-               return 0;
-       }
-       hswal(ph, phsz/sizeof(uint32), swal);
-
-       shsz = sizeof(Shdr32)*ep->shnum;
-       sh = malloc(shsz);
-       if(sh) {
-               seek(fd, ep->shoff, 0);
-               if(read(fd, sh, shsz) < 0) {
-                       free(sh);
-                       sh = 0;
-               } else
-                       hswal(sh, shsz/sizeof(uint32), swal);
-       }
-
-       /* find text, data and symbols and install them */
-       it = id = is = -1;
-       for(i = 0; i < ep->phnum; i++) {
-               if(ph[i].type == LOAD
-               && (ph[i].flags & (R|X)) == (R|X) && it == -1)
-                       it = i;
-               else if(ph[i].type == LOAD
-               && (ph[i].flags & (R|W)) == (R|W) && id == -1)
-                       id = i;
-               else if(ph[i].type == NOPTYPE && is == -1)
-                       is = i;
-       }
-       if(it == -1 || id == -1) {
-               /*
-                * The SPARC64 boot image is something of an ELF hack.
-                * Text+Data+BSS are represented by ph[0].  Symbols
-                * are represented by ph[1]:
-                *
-                *              filesz, memsz, vaddr, paddr, off
-                * ph[0] : txtsz+datsz, txtsz+datsz+bsssz, txtaddr-KZERO, datasize, txtoff
-                * ph[1] : symsz, lcsz, 0, 0, symoff
-                */
-               if(ep->machine == SPARC64 && ep->phnum == 2) {
-                       uint32 txtaddr, txtsz, dataddr, bsssz;
-
-                       txtaddr = ph[0].vaddr | 0x80000000;
-                       txtsz = ph[0].filesz - ph[0].paddr;
-                       dataddr = txtaddr + txtsz;
-                       bsssz = ph[0].memsz - ph[0].filesz;
-                       settext(fp, ep->elfentry | 0x80000000, txtaddr, txtsz, ph[0].offset);
-                       setdata(fp, dataddr, ph[0].paddr, ph[0].offset + txtsz, bsssz);
-                       setsym(fp, ph[1].offset, ph[1].filesz, 0, 0, 0, ph[1].memsz);
-                       free(ph);
-                       return 1;
-               }
-
-               werrstr("No TEXT or DATA sections");
-               free(sh);
-               free(ph);
-               return 0;
-       }
-
-       settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset);
-       setdata(fp, ph[id].vaddr, ph[id].filesz, ph[id].offset, ph[id].memsz - ph[id].filesz);
-       if(is != -1)
-               setsym(fp, ph[is].offset, ph[is].filesz, 0, 0, 0, ph[is].memsz);
-       else if(sh != 0){
-               char *buf;
-               uvlong symsize = 0;
-               uvlong symoff = 0;
-               uvlong pclnsize = 0;
-               uvlong pclnoff = 0;
-
-               /* load shstrtab names */
-               buf = malloc(sh[ep->shstrndx].size);
-               if (buf == 0)
-                       goto done;
-               memset(buf, 0, sh[ep->shstrndx].size);
-               seek(fd, sh[ep->shstrndx].offset, 0);
-               i = read(fd, buf, sh[ep->shstrndx].size);
-               USED(i);        // shut up ubuntu gcc
-
-               for(i = 0; i < ep->shnum; i++) {
-                       if (strcmp(&buf[sh[i].name], ".gosymtab") == 0) {
-                               symsize = sh[i].size;
-                               symoff = sh[i].offset;
-                       }
-                       if (strcmp(&buf[sh[i].name], ".gopclntab") == 0) {
-                               pclnsize = sh[i].size;
-                               pclnoff = sh[i].offset;
-                       }
-               }
-               setsym(fp, symoff, symsize, 0, 0, pclnoff, pclnsize);
-               free(buf);
-       }
-done:
-       free(sh);
-       free(ph);
-       return 1;
-}
-
-static int
-machdotout(int fd, Fhdr *fp, ExecHdr *hp)
-{
-       uvlong (*swav)(uvlong);
-       uint32 (*swal)(uint32);
-       Machhdr *mp;
-       MachCmd **cmd;
-       MachSymSeg *symtab;
-       MachSymSeg *pclntab;
-       MachSeg64 *seg;
-       MachSect64 *sect;
-       MachSeg32 *seg32;
-       MachSect32 *sect32;
-       uvlong textsize, datasize, bsssize;
-       uchar *cmdbuf;
-       uchar *cmdp;
-       int i, j, hdrsize;
-       uint32 textva, textoff, datava, dataoff, symoff, symsize, pclnoff, pclnsize;
-
-       mp = &hp->e.machhdr;
-       if (leswal(mp->filetype) != MACH_EXECUTABLE_TYPE) {
-               werrstr("bad MACH executable type %#ux", leswal(mp->filetype));
-               return 0;
-       }
-
-       swal = leswal;
-       swav = leswav;
-
-       mp->magic = swal(mp->magic);
-       mp->cputype = swal(mp->cputype);
-       mp->cpusubtype = swal(mp->cpusubtype);
-       mp->filetype = swal(mp->filetype);
-       mp->ncmds = swal(mp->ncmds);
-       mp->sizeofcmds = swal(mp->sizeofcmds);
-       mp->flags = swal(mp->flags);
-       mp->reserved = swal(mp->reserved);
-
-       switch(mp->magic) {
-       case 0xFEEDFACE:        // 32-bit mach
-               if (mp->cputype != MACH_CPU_TYPE_X86) {
-                       werrstr("bad MACH cpu type - not 386");
-                       return 0;
-               }
-               if (mp->cpusubtype != MACH_CPU_SUBTYPE_X86) {
-                       werrstr("bad MACH cpu subtype - not 386");
-                       return 0;
-               }
-               if (mp->filetype != MACH_EXECUTABLE_TYPE) {
-                       werrstr("bad MACH executable type");
-                       return 0;
-               }
-               mach = &mi386;
-               fp->type = FI386;
-               hdrsize = 28;
-               break;
-
-       case 0xFEEDFACF:        // 64-bit mach
-               if (mp->cputype != MACH_CPU_TYPE_X86_64) {
-                       werrstr("bad MACH cpu type - not amd64");
-                       return 0;
-               }
-
-               if (mp->cpusubtype != MACH_CPU_SUBTYPE_X86 && mp->cpusubtype != MACH_CPU_SUBTYPE_X86_64) {
-                       werrstr("bad MACH cpu subtype - not amd64");
-                       return 0;
-               }
-               mach = &mamd64;
-               fp->type = FAMD64;
-               hdrsize = 32;
-               break;
-
-       default:
-               werrstr("not mach %#ux", mp->magic);
-               return 0;
-       }
-
-       cmdbuf = malloc(mp->sizeofcmds);
-       if(!cmdbuf) {
-               werrstr("out of memory");
-               return 0;
-       }
-       seek(fd, hdrsize, 0);
-       if(read(fd, cmdbuf, mp->sizeofcmds) != mp->sizeofcmds) {
-               free(cmdbuf);
-               return 0;
-       }
-       cmd = malloc(mp->ncmds * sizeof(MachCmd*));
-       if(!cmd) {
-               free(cmdbuf);
-               werrstr("out of memory");
-               return 0;
-       }
-       cmdp = cmdbuf;
-       textva = 0;
-       textoff = 0;
-       dataoff = 0;
-       datava = 0;
-       symtab = 0;
-       pclntab = 0;
-       textsize = 0;
-       datasize = 0;
-       bsssize = 0;
-       symoff = 0;
-       symsize = 0;
-       pclnoff = 0;
-       pclnsize = 0;
-       for (i = 0; i < mp->ncmds; i++) {
-               MachCmd *c;
-
-               cmd[i] = (MachCmd*)cmdp;
-               c = cmd[i];
-               c->type = swal(c->type);
-               c->size = swal(c->size);
-               switch(c->type) {
-               case MACH_SEGMENT_32:
-                       if(mp->magic != 0xFEEDFACE) {
-                               werrstr("segment 32 in mach 64");
-                               goto bad;
-                       }
-                       seg32 = (MachSeg32*)c;
-                       seg32->vmaddr = swav(seg32->vmaddr);
-                       seg32->vmsize = swav(seg32->vmsize);
-                       seg32->fileoff = swav(seg32->fileoff);
-                       seg32->filesize = swav(seg32->filesize);
-                       seg32->maxprot = swal(seg32->maxprot);
-                       seg32->initprot = swal(seg32->initprot);
-                       seg32->nsects = swal(seg32->nsects);
-                       seg32->flags = swal(seg32->flags);
-                       if (strcmp(seg32->segname, "__TEXT") == 0) {
-                               textva = seg32->vmaddr;
-                               textoff = seg32->fileoff;
-                               textsize = seg32->vmsize;
-                               sect32 = (MachSect32*)(cmdp + sizeof(MachSeg32));
-                               for(j = 0; j < seg32->nsects; j++, sect32++) {
-                                       if (strcmp(sect32->sectname, "__gosymtab") == 0) {
-                                               symoff = swal(sect32->offset);
-                                               symsize = swal(sect32->size);
-                                       }
-                                       if (strcmp(sect32->sectname, "__gopclntab") == 0) {
-                                               pclnoff = swal(sect32->offset);
-                                               pclnsize = swal(sect32->size);
-                                       }
-                               }
-                       }
-                       if (strcmp(seg32->segname, "__DATA") == 0) {
-                               datava = seg32->vmaddr;
-                               dataoff = seg32->fileoff;
-                               datasize = seg32->filesize;
-                               bsssize = seg32->vmsize - seg32->filesize;
-                       }
-                       break;
-
-               case MACH_SEGMENT_64:
-                       if(mp->magic != 0xFEEDFACF) {
-                               werrstr("segment 32 in mach 64");
-                               goto bad;
-                       }
-                       seg = (MachSeg64*)c;
-                       seg->vmaddr = swav(seg->vmaddr);
-                       seg->vmsize = swav(seg->vmsize);
-                       seg->fileoff = swav(seg->fileoff);
-                       seg->filesize = swav(seg->filesize);
-                       seg->maxprot = swal(seg->maxprot);
-                       seg->initprot = swal(seg->initprot);
-                       seg->nsects = swal(seg->nsects);
-                       seg->flags = swal(seg->flags);
-                       if (strcmp(seg->segname, "__TEXT") == 0) {
-                               textva = seg->vmaddr;
-                               textoff = seg->fileoff;
-                               textsize = seg->vmsize;
-                               sect = (MachSect64*)(cmdp + sizeof(MachSeg64));
-                               for(j = 0; j < seg->nsects; j++, sect++) {
-                                       if (strcmp(sect->sectname, "__gosymtab") == 0) {
-                                               symoff = swal(sect->offset);
-                                               symsize = swal(sect->size);
-                                       }
-                                       if (strcmp(sect->sectname, "__gopclntab") == 0) {
-                                               pclnoff = swal(sect->offset);
-                                               pclnsize = swal(sect->size);
-                                       }
-                               }
-                       }
-                       if (strcmp(seg->segname, "__DATA") == 0) {
-                               datava = seg->vmaddr;
-                               dataoff = seg->fileoff;
-                               datasize = seg->filesize;
-                               bsssize = seg->vmsize - seg->filesize;
-                       }
-                       break;
-               case MACH_UNIXTHREAD:
-                       break;
-               case MACH_SYMSEG:
-                       if (symtab == 0) {
-                               symtab = (MachSymSeg*)c;
-                               symoff = swal(symtab->fileoff);
-                               symsize = swal(symtab->filesize);
-                       } else if (pclntab == 0) {
-                               pclntab = (MachSymSeg*)c;
-                               pclnoff = swal(pclntab->fileoff);
-                               pclnsize = swal(pclntab->filesize);
-                       }
-                       break;
-               }
-               cmdp += c->size;
-       }
-       if (textva == 0 || datava == 0) {
-               free(cmd);
-               free(cmdbuf);
-               return 0;
-       }
-       /* compute entry by taking address after header - weird - BUG? */
-       settext(fp, textva+sizeof(Machhdr) + mp->sizeofcmds, textva, textsize, textoff);
-       setdata(fp, datava, datasize, dataoff, bsssize);
-       if(symoff > 0)
-               setsym(fp, symoff, symsize, 0, 0, pclnoff, pclnsize);
-       free(cmd);
-       free(cmdbuf);
-       return 1;
-bad:
-       free(cmd);
-       free(cmdbuf);
-       return 0;
-}
-
-/*
- * (Free|Net)BSD ARM header.
- */
-static int
-armdotout(int fd, Fhdr *fp, ExecHdr *hp)
-{
-       uvlong kbase;
-
-       USED(fd);
-       settext(fp, hp->e.exechdr.entry, sizeof(Exec), hp->e.exechdr.text, sizeof(Exec));
-       setdata(fp, fp->txtsz, hp->e.exechdr.data, fp->txtsz, hp->e.exechdr.bss);
-       setsym(fp, fp->datoff+fp->datsz, hp->e.exechdr.syms, 0, hp->e.exechdr.spsz, 0, hp->e.exechdr.pcsz);
-
-       kbase = 0xF0000000;
-       if ((fp->entry & kbase) == kbase) {             /* Boot image */
-               fp->txtaddr = kbase+sizeof(Exec);
-               fp->name = "ARM *BSD boot image";
-               fp->hdrsz = 0;          /* header stripped */
-               fp->dataddr = kbase+fp->txtsz;
-       }
-       return 1;
-}
-
-/*
- * Structures needed to parse PE image.
- */
-typedef struct {
-       uint16 Machine;
-       uint16 NumberOfSections;
-       uint32 TimeDateStamp;
-       uint32 PointerToSymbolTable;
-       uint32 NumberOfSymbols;
-       uint16 SizeOfOptionalHeader;
-       uint16 Characteristics;
-} IMAGE_FILE_HEADER;
-
-typedef struct {
-       uint8  Name[8];
-       uint32 VirtualSize;
-       uint32 VirtualAddress;
-       uint32 SizeOfRawData;
-       uint32 PointerToRawData;
-       uint32 PointerToRelocations;
-       uint32 PointerToLineNumbers;
-       uint16 NumberOfRelocations;
-       uint16 NumberOfLineNumbers;
-       uint32 Characteristics;
-} IMAGE_SECTION_HEADER;
-
-typedef struct {
-       uint32 VirtualAddress;
-       uint32 Size;
-} IMAGE_DATA_DIRECTORY;
-
-typedef struct {
-       uint16 Magic;
-       uint8  MajorLinkerVersion;
-       uint8  MinorLinkerVersion;
-       uint32 SizeOfCode;
-       uint32 SizeOfInitializedData;
-       uint32 SizeOfUninitializedData;
-       uint32 AddressOfEntryPoint;
-       uint32 BaseOfCode;
-       uint32 BaseOfData;
-       uint32 ImageBase;
-       uint32 SectionAlignment;
-       uint32 FileAlignment;
-       uint16 MajorOperatingSystemVersion;
-       uint16 MinorOperatingSystemVersion;
-       uint16 MajorImageVersion;
-       uint16 MinorImageVersion;
-       uint16 MajorSubsystemVersion;
-       uint16 MinorSubsystemVersion;
-       uint32 Win32VersionValue;
-       uint32 SizeOfImage;
-       uint32 SizeOfHeaders;
-       uint32 CheckSum;
-       uint16 Subsystem;
-       uint16 DllCharacteristics;
-       uint32 SizeOfStackReserve;
-       uint32 SizeOfStackCommit;
-       uint32 SizeOfHeapReserve;
-       uint32 SizeOfHeapCommit;
-       uint32 LoaderFlags;
-       uint32 NumberOfRvaAndSizes;
-       IMAGE_DATA_DIRECTORY DataDirectory[16];
-} IMAGE_OPTIONAL_HEADER;
-
-typedef struct {
-       uint16 Magic;
-       uint8  MajorLinkerVersion;
-       uint8  MinorLinkerVersion;
-       uint32 SizeOfCode;
-       uint32 SizeOfInitializedData;
-       uint32 SizeOfUninitializedData;
-       uint32 AddressOfEntryPoint;
-       uint32 BaseOfCode;
-       uint64 ImageBase;
-       uint32 SectionAlignment;
-       uint32 FileAlignment;
-       uint16 MajorOperatingSystemVersion;
-       uint16 MinorOperatingSystemVersion;
-       uint16 MajorImageVersion;
-       uint16 MinorImageVersion;
-       uint16 MajorSubsystemVersion;
-       uint16 MinorSubsystemVersion;
-       uint32 Win32VersionValue;
-       uint32 SizeOfImage;
-       uint32 SizeOfHeaders;
-       uint32 CheckSum;
-       uint16 Subsystem;
-       uint16 DllCharacteristics;
-       uint64 SizeOfStackReserve;
-       uint64 SizeOfStackCommit;
-       uint64 SizeOfHeapReserve;
-       uint64 SizeOfHeapCommit;
-       uint32 LoaderFlags;
-       uint32 NumberOfRvaAndSizes;
-       IMAGE_DATA_DIRECTORY DataDirectory[16];
-} PE64_IMAGE_OPTIONAL_HEADER;
-
-static int
-match8(void *buf, char *cmp)
-{
-       return strncmp((char*)buf, cmp, 8) == 0;
-}
-
-/*
- * Read from Windows PE/COFF .exe file image.
- */
-static int
-pedotout(int fd, Fhdr *fp, ExecHdr *hp)
-{
-       uint32 start, magic;
-       uint32 symtab, esymtab, pclntab, epclntab;
-       IMAGE_FILE_HEADER fh;
-       IMAGE_SECTION_HEADER sh;
-       IMAGE_OPTIONAL_HEADER oh;
-       PE64_IMAGE_OPTIONAL_HEADER oh64;
-       uint8 sym[18];
-       uint32 *valp, ib, entry;
-       int i, ohoffset;
-
-       USED(hp);
-       seek(fd, 0x3c, 0);
-       if (readn(fd, &start, sizeof(start)) != sizeof(start)) {
-               werrstr("crippled PE MSDOS header");
-               return 0;
-       }
-       start = leswal(start);
-
-       seek(fd, start, 0);
-       if (readn(fd, &magic, sizeof(magic)) != sizeof(magic)) {
-               werrstr("no PE magic number found");
-               return 0;
-       }
-       if (beswal(magic) != 0x50450000) {  /* "PE\0\0" */
-               werrstr("incorrect PE magic number");
-               return 0;
-       }
-
-       if (readn(fd, &fh, sizeof(fh)) != sizeof(fh)) {
-               werrstr("crippled PE File Header");
-               return 0;
-       }
-       if (fh.PointerToSymbolTable == 0) {
-               werrstr("zero pointer to COFF symbol table");
-               return 0;
-       }
-
-       ohoffset = seek(fd, 0, 1);
-       if (readn(fd, &oh, sizeof(oh)) != sizeof(oh)) {
-               werrstr("crippled PE Optional Header");
-               return 0;
-       }
-
-       switch(oh.Magic) {
-       case 0x10b:     // PE32
-               fp->type = FI386;
-               ib = leswal(oh.ImageBase);
-               entry = leswal(oh.AddressOfEntryPoint);
-               break;
-       case 0x20b:     // PE32+
-               fp->type = FAMD64;
-               seek(fd, ohoffset, 0);
-               if (readn(fd, &oh64, sizeof(oh64)) != sizeof(oh64)) {
-                       werrstr("crippled PE32+ Optional Header");
-                       return 0;
-               }
-               ib = leswal(oh64.ImageBase);
-               entry = leswal(oh64.AddressOfEntryPoint);
-               break;
-       default:
-               werrstr("invalid PE Optional Header magic number");
-               return 0;
-       }
-
-       fp->txtaddr = 0;
-       fp->dataddr = 0;
-       for (i=0; i<leswab(fh.NumberOfSections); i++) {
-               if (readn(fd, &sh, sizeof(sh)) != sizeof(sh)) {
-                       werrstr("could not read Section Header %d", i+1);
-                       return 0;
-               }
-               if (match8(sh.Name, ".text"))
-                       settext(fp, ib+entry, ib+leswal(sh.VirtualAddress), leswal(sh.VirtualSize), leswal(sh.PointerToRawData));
-               if (match8(sh.Name, ".data"))
-                       setdata(fp, ib+leswal(sh.VirtualAddress), leswal(sh.SizeOfRawData), leswal(sh.PointerToRawData), leswal(sh.VirtualSize)-leswal(sh.SizeOfRawData));
-       }
-       if (fp->txtaddr==0 || fp->dataddr==0) {
-               werrstr("no .text or .data");
-               return 0;
-       }
-
-       seek(fd, leswal(fh.PointerToSymbolTable), 0);
-       symtab = esymtab = pclntab = epclntab = 0;
-       for (i=0; i<leswal(fh.NumberOfSymbols); i++) {
-               if (readn(fd, sym, sizeof(sym)) != sizeof(sym)) {
-                       werrstr("crippled COFF symbol %d", i);
-                       return 0;
-               }
-               valp = (uint32 *)&sym[8];
-               if (match8(sym, "symtab"))
-                       symtab = leswal(*valp);
-               if (match8(sym, "esymtab"))
-                       esymtab = leswal(*valp);
-               if (match8(sym, "pclntab"))
-                       pclntab = leswal(*valp);
-               if (match8(sym, "epclntab"))
-                       epclntab = leswal(*valp);
-       }
-       if (symtab==0 || esymtab==0 || pclntab==0 || epclntab==0) {
-               werrstr("no symtab or esymtab or pclntab or epclntab in COFF symbol table");
-               return 0;
-       }
-       setsym(fp, symtab, esymtab-symtab, 0, 0, pclntab, epclntab-pclntab);
-
-       return 1;
-}
-
-static void
-settext(Fhdr *fp, uvlong e, uvlong a, int32 s, vlong off)
-{
-       fp->txtaddr = a;
-       fp->entry = e;
-       fp->txtsz = s;
-       fp->txtoff = off;
-}
-
-static void
-setdata(Fhdr *fp, uvlong a, int32 s, vlong off, int32 bss)
-{
-       fp->dataddr = a;
-       fp->datsz = s;
-       fp->datoff = off;
-       fp->bsssz = bss;
-}
-
-static void
-setsym(Fhdr *fp, vlong symoff, int32 symsz, vlong sppcoff, int32 sppcsz, vlong lnpcoff, int32 lnpcsz)
-{
-       fp->symoff = symoff;
-       fp->symsz = symsz;
-       
-       if(sppcoff == 0)
-               sppcoff = symoff+symsz;
-       fp->sppcoff = symoff;
-       fp->sppcsz = sppcsz;
-
-       if(lnpcoff == 0)
-               lnpcoff = sppcoff + sppcsz;
-       fp->lnpcoff = lnpcoff;
-       fp->lnpcsz = lnpcsz;
-}
-
-static uvlong
-_round(uvlong a, uint32 b)
-{
-       uvlong w;
-
-       w = (a/b)*b;
-       if (a!=w)
-               w += b;
-       return(w);
-}
diff --git a/src/libmach/fakeobj.c b/src/libmach/fakeobj.c
deleted file mode 100644 (file)
index a4a897c..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
- * obj.c
- * routines universal to all object files
- */
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <ar.h>
-#include <mach.h>
-#include "obj.h"
-
-int _is2(char* x) { USED(x); return 0; }
-int _is7(char* x) { USED(x); return 0; }
-int _is9(char* x) { USED(x); return 0; }
-int _isk(char* x) { USED(x); return 0; }
-int _isq(char* x) { USED(x); return 0; }
-int _isv(char* x) { USED(x); return 0; }
-int _isu(char* x) { USED(x); return 0; }
-int _read2(Biobuf* b, Prog* p) { USED(b); USED(p); return 0; }
-int _read7(Biobuf* b, Prog* p) { USED(b); USED(p); return 0; }
-int _read9(Biobuf* b, Prog* p) { USED(b); USED(p); return 0; }
-int _readk(Biobuf* b, Prog* p) { USED(b); USED(p); return 0; }
-int _readq(Biobuf* b, Prog* p) { USED(b); USED(p); return 0; }
-int _readv(Biobuf* b, Prog* p) { USED(b); USED(p); return 0; }
-int _readu(Biobuf* b, Prog* p) { USED(b); USED(p); return 0; }
diff --git a/src/libmach/freebsd.c b/src/libmach/freebsd.c
deleted file mode 100644 (file)
index c4e5efd..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-// This is stubbed out for the moment. Will revisit when the time comes.
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mach.h>
-
-int
-ctlproc(int pid, char *msg)
-{
-       USED(pid);
-       USED(msg);
-
-       sysfatal("ctlproc unimplemented in FreeBSD");
-       return -1;
-}
-
-char*
-proctextfile(int pid)
-{
-       USED(pid);
-       
-       sysfatal("proctextfile unimplemented in FreeBSD");
-       return nil;
-}
-
-char*
-procstatus(int pid)
-{
-       USED(pid);
-
-       sysfatal("procstatus unimplemented in FreeBSD");
-       return nil;
-}
-
-Map*
-attachproc(int pid, Fhdr *fp)
-{
-       USED(pid);
-       USED(fp);
-
-       sysfatal("attachproc unimplemented in FreeBSD");
-       return nil;
-}
-
-void
-detachproc(Map *m)
-{
-       USED(m);
-
-       sysfatal("detachproc unimplemented in FreeBSD");
-}
-
-int
-procthreadpids(int pid, int *p, int np)
-{
-       USED(pid);
-       USED(p);
-       USED(np);
-
-       sysfatal("procthreadpids unimplemented in FreeBSD");
-       return -1;
-}
diff --git a/src/libmach/linux.c b/src/libmach/linux.c
deleted file mode 100644 (file)
index 89f3b20..0000000
+++ /dev/null
@@ -1,1008 +0,0 @@
-// Derived from Plan 9 from User Space src/libmach/Linux.c
-// http://code.swtch.com/plan9port/src/tip/src/libmach/Linux.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2001-2007 Russ Cox.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include <u.h>
-#include <sys/syscall.h>       /* for tkill */
-#include <unistd.h>
-#include <dirent.h>
-#include <sys/ptrace.h>
-#include <sys/signal.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <libc.h>
-#include <bio.h>
-#include <mach.h>
-#include <ureg_x86.h>
-#include <ureg_amd64.h>
-#undef waitpid
-
-// The old glibc used with crosstool compilers on thresher
-// doesn't know these numbers, but the Linux kernel
-// had them as far back as 2.6.0.
-#ifndef WSTOPPED
-#define WSTOPPED 2
-#define WCONTINUED 8
-#define WIFCONTINUED(x) ((x) == 0xffff)
-#endif
-#ifndef PTRACE_SETOPTIONS
-#define PTRACE_SETOPTIONS 0x4200
-#define PTRACE_GETEVENTMSG 0x4201
-#define PTRACE_O_TRACEFORK 0x2
-#define PTRACE_O_TRACEVFORK 0x4
-#define PTRACE_O_TRACECLONE 0x8
-#define PTRACE_O_TRACEEXEC 0x10
-#define PTRACE_O_TRACEVFORKDONE 0x20
-#define PTRACE_O_TRACEEXIT 0x40
-#define PTRACE_EVENT_FORK 0x1
-#define PTRACE_EVENT_VFORK 0x2
-#define PTRACE_EVENT_CLONE 0x3
-#define PTRACE_EVENT_EXEC 0x4
-#define PTRACE_EVENT_VFORK_DONE 0x5
-#define PTRACE_EVENT_EXIT 0x6
-#endif
-
-static Maprw ptracesegrw;
-static Maprw ptraceregrw;
-
-// /usr/include/asm-x86_64/user.h
-struct user_regs_struct {
-       unsigned long r15,r14,r13,r12,rbp,rbx,r11,r10;
-       unsigned long r9,r8,rax,rcx,rdx,rsi,rdi,orig_rax;
-       unsigned long rip,cs,eflags;
-       unsigned long rsp,ss;
-       unsigned long fs_base, gs_base;
-       unsigned long ds,es,fs,gs;
-};
-
-// Linux gets very upset if a debugger forgets the reported state
-// of a debugged process, so we keep everything we know about
-// a debugged process in the LinuxThread structure.
-//
-// We can poll for state changes by calling waitpid and interpreting
-// the integer status code that comes back.  Wait1 does this.
-//
-// If the process is already running, it is an error to PTRACE_CONT it.
-//
-// If the process is already stopped, it is an error to stop it again.
-//
-// If the process is stopped because of a signal, the debugger must
-// relay the signal to the PTRACE_CONT call, or else the signal is
-// dropped.
-//
-// If the process exits, the debugger should detach so that the real
-// parent can reap the zombie.
-//
-// On first attach, the debugger should set a handful of flags in order
-// to catch future events like fork, clone, exec, etc.
-
-// One for every attached thread.
-typedef struct LinuxThread LinuxThread;
-struct LinuxThread
-{
-       int pid;
-       int tid;
-       int state;
-       int signal;
-       int child;
-       int exitcode;
-};
-
-static int trace = 0;
-
-static LinuxThread **thr;
-static int nthr;
-static int mthr;
-
-static int realpid(int pid);
-
-enum
-{
-       Unknown,
-       Detached,
-       Attached,
-       AttachStop,
-       Stopped,
-       Running,
-       Forking,
-       Vforking,
-       VforkDone,
-       Cloning,
-       Execing,
-       Exiting,
-       Exited,
-       Killed,
-
-       NSTATE,
-};
-
-static char* statestr[NSTATE] = {
-       "Unknown",
-       "Detached",
-       "Attached",
-       "AttachStop",
-       "Stopped",
-       "Running",
-       "Forking",
-       "Vforking",
-       "VforkDone",
-       "Cloning",
-       "Execing",
-       "Exiting",
-       "Exited",
-       "Killed"
-};
-
-static LinuxThread*
-attachthread(int pid, int tid, int *new, int newstate)
-{
-       int i, n, status;
-       LinuxThread **p, *t;
-       uintptr flags;
-
-       if(new)
-               *new = 0;
-
-       for(i=0; i<nthr; i++)
-               if((pid == 0 || thr[i]->pid == pid) && thr[i]->tid == tid) {
-                       t = thr[i];
-                       goto fixup;
-               }
-
-       if(!new)
-               return nil;
-
-       if(nthr >= mthr) {
-               n = mthr;
-               if(n == 0)
-                       n = 64;
-               else
-                       n *= 2;
-               p = realloc(thr, n*sizeof thr[0]);
-               if(p == nil)
-                       return nil;
-               thr = p;
-               mthr = n;
-       }
-
-       t = malloc(sizeof *t);
-       if(t == nil)
-               return nil;
-       memset(t, 0, sizeof *t);
-
-       thr[nthr++] = t;
-       if(pid == 0 && nthr > 0)
-               pid = thr[0]->pid;
-       t->pid = pid;
-       t->tid = tid;
-       t->state = newstate;
-       if(trace)
-               fprint(2, "new thread %d %d\n", t->pid, t->tid);
-       if(new)
-               *new = 1;
-
-fixup:
-       if(t->state == Detached) {
-               if(ptrace(PTRACE_ATTACH, tid, 0, 0) < 0) {
-                       fprint(2, "ptrace ATTACH %d: %r\n", tid);
-                       return nil;
-               }
-               t->state = Attached;
-       }
-
-       if(t->state == Attached) {
-               // wait for stop, so we can set options
-               if(waitpid(tid, &status, __WALL|WUNTRACED|WSTOPPED) < 0)
-                       return nil;
-               if(!WIFSTOPPED(status)) {
-                       fprint(2, "waitpid %d: status=%#x not stopped\n", tid);
-                       return nil;
-               }
-               t->state = AttachStop;
-       }
-
-       if(t->state == AttachStop) {
-               // set options so we'll find out about new threads
-               flags = PTRACE_O_TRACEFORK |
-                       PTRACE_O_TRACEVFORK |
-                       PTRACE_O_TRACECLONE |
-                       PTRACE_O_TRACEEXEC |
-                       PTRACE_O_TRACEVFORKDONE;
-               if(ptrace(PTRACE_SETOPTIONS, tid, 0, (void*)flags) < 0) {
-                       fprint(2, "ptrace PTRACE_SETOPTIONS %d: %r\n", tid);
-                       return nil;
-               }
-               t->state = Stopped;
-       }
-
-       return t;
-}
-
-static LinuxThread*
-findthread(int tid)
-{
-       return attachthread(0, tid, nil, 0);
-}
-
-int
-procthreadpids(int pid, int *p, int np)
-{
-       int i, n;
-       LinuxThread *t;
-
-       n = 0;
-       for(i=0; i<nthr; i++) {
-               t = thr[i];
-               if(t->pid == pid) {
-                       switch(t->state) {
-                       case Exited:
-                       case Detached:
-                       case Killed:
-                               break;
-
-                       default:
-                               if(n < np)
-                                       p[n] = t->tid;
-                               n++;
-                               break;
-                       }
-               }
-       }
-       return n;
-}
-
-// Execute a single wait and update the corresponding thread.
-static int
-wait1(int nohang)
-{
-       int tid, new, status, event;
-       ulong data;
-       LinuxThread *t;
-       enum
-       {
-               NormalStop = 0x137f
-       };
-
-       if(nohang != 0)
-               nohang = WNOHANG;
-
-       status = 0;
-       tid = waitpid(-1, &status, __WALL|WUNTRACED|WSTOPPED|WCONTINUED|nohang);
-
-       if(tid < 0)
-               return -1;
-       if(tid == 0)
-               return 0;
-
-       if(trace > 0 && status != NormalStop)
-               fprint(2, "TID %d: %#x\n", tid, status);
-
-       t = findthread(tid);
-       if(t == nil) {
-               // Sometimes the kernel tells us about new threads
-               // before we see the parent clone.
-               t = attachthread(0, tid, &new, Stopped);
-               if(t == nil) {
-                       fprint(2, "failed to attach to new thread %d\n", tid);
-                       return -1;
-               }
-       }
-
-       if(WIFSTOPPED(status)) {
-               t->state = Stopped;
-               t->signal = WSTOPSIG(status);
-               if(trace)
-                       fprint(2, "tid %d: stopped %#x%s\n", tid, status,
-                               status != NormalStop ? " ***" : "");
-               if(t->signal == SIGTRAP && (event = status>>16) != 0) { // ptrace event
-                       switch(event) {
-                       case PTRACE_EVENT_FORK:
-                               t->state = Forking;
-                               goto child;
-
-                       case PTRACE_EVENT_VFORK:
-                               t->state = Vforking;
-                               goto child;
-
-                       case PTRACE_EVENT_CLONE:
-                               t->state = Cloning;
-                               goto child;
-
-                       child:
-                               if(ptrace(PTRACE_GETEVENTMSG, t->tid, 0, &data) < 0) {
-                                       fprint(2, "ptrace GETEVENTMSG tid %d: %r\n", tid);
-                                       break;
-                               }
-                               t->child = data;
-                               attachthread(t->pid, t->child, &new, Running);
-                               break;
-
-                       case PTRACE_EVENT_EXEC:
-                               t->state = Execing;
-                               break;
-
-                       case PTRACE_EVENT_VFORK_DONE:
-                               t->state = VforkDone;
-                               break;
-
-                       case PTRACE_EVENT_EXIT:
-                               // We won't see this unless we set PTRACE_O_TRACEEXIT.
-                               // The debuggers assume that a read or write on a Map
-                               // will fail for a thread that has exited.  This event
-                               // breaks that assumption.  It's not a big deal: we
-                               // only lose the ability to see the register state at
-                               // the time of exit.
-                               if(trace)
-                                       fprint(2, "tid %d: exiting %#x\n", tid, status);
-                               t->state = Exiting;
-                               if(ptrace(PTRACE_GETEVENTMSG, t->tid, 0, &data) < 0) {
-                                       fprint(2, "ptrace GETEVENTMSG tid %d: %r\n", tid);
-                                       break;
-                               }
-                               t->exitcode = data;
-                               break;
-                       }
-               }
-       }
-       if(WIFCONTINUED(status)) {
-               if(trace)
-                       fprint(2, "tid %d: continued %#x\n", tid, status);
-               t->state = Running;
-       }
-       if(WIFEXITED(status)) {
-               if(trace)
-                       fprint(2, "tid %d: exited %#x\n", tid, status);
-               t->state = Exited;
-               t->exitcode = WEXITSTATUS(status);
-               t->signal = -1;
-               ptrace(PTRACE_DETACH, t->tid, 0, 0);
-               if(trace)
-                       fprint(2, "tid %d: detach exited\n", tid);
-       }
-       if(WIFSIGNALED(status)) {
-               if(trace)
-                       fprint(2, "tid %d: signaled %#x\n", tid, status);
-               t->state = Exited;
-               t->signal = WTERMSIG(status);
-               t->exitcode = -1;
-               ptrace(PTRACE_DETACH, t->tid, 0, 0);
-               if(trace)
-                       fprint(2, "tid %d: detach signaled\n", tid);
-       }
-       return 1;
-}
-
-static int
-waitstop(LinuxThread *t)
-{
-       while(t->state == Running)
-               if(wait1(0) < 0)
-                       return -1;
-       return 0;
-}
-
-// Attach to and stop all threads in process pid.
-// Must stop everyone in order to make sure we set
-// the "tell me about new threads" option in every
-// task.
-int
-attachallthreads(int pid)
-{
-       int tid, foundnew, new;
-       char buf[100];
-       DIR *d;
-       struct dirent *de;
-       LinuxThread *t;
-
-       if(pid == 0) {
-               fprint(2, "attachallthreads(0)\n");
-               return -1;
-       }
-
-       pid = realpid(pid);
-
-       snprint(buf, sizeof buf, "/proc/%d/task", pid);
-       if((d = opendir(buf)) == nil) {
-               fprint(2, "opendir %s: %r\n", buf);
-               return -1;
-       }
-
-       // Loop in case new threads are being created right now.
-       // We stop every thread as we find it, so eventually
-       // this has to stop (or the system runs out of procs).
-       do {
-               foundnew = 0;
-               while((de = readdir(d)) != nil) {
-                       tid = atoi(de->d_name);
-                       if(tid == 0)
-                               continue;
-                       t = attachthread(pid, tid, &new, Detached);
-                       foundnew |= new;
-                       if(t)
-                               waitstop(t);
-               }
-               rewinddir(d);
-       } while(foundnew);
-       closedir(d);
-
-       return 0;
-}
-
-Map*
-attachproc(int pid, Fhdr *fp)
-{
-       Map *map;
-
-       if(pid == 0) {
-               fprint(2, "attachproc(0)\n");
-               return nil;
-       }
-
-       if(findthread(pid) == nil && attachallthreads(pid) < 0)
-               return nil;
-
-       map = newmap(0, 4);
-       if (!map)
-               return 0;
-       map->pid = pid;
-       if(mach->regsize)
-               setmap(map, -1, 0, mach->regsize, 0, "regs", ptraceregrw);
-//     if(mach->fpregsize)
-//             setmap(map, -1, mach->regsize, mach->regsize+mach->fpregsize, 0, "fpregs", ptraceregrw);
-       setmap(map, -1, fp->txtaddr, fp->txtaddr+fp->txtsz, fp->txtaddr, "*text", ptracesegrw);
-       setmap(map, -1, fp->dataddr, mach->utop, fp->dataddr, "*data", ptracesegrw);
-       return map;
-}
-
-void
-detachproc(Map *m)
-{
-       LinuxThread *t;
-
-       t = findthread(m->pid);
-       if(t != nil) {
-               ptrace(PTRACE_DETACH, t->tid, 0, 0);
-               t->state = Detached;
-               if(trace)
-                       fprint(2, "tid %d: detachproc\n", t->tid);
-               // TODO(rsc): Reclaim thread structs somehow?
-       }
-       free(m);
-}
-
-/* /proc/pid/stat contains
-       pid
-       command in parens
-       0. state
-       1. ppid
-       2. pgrp
-       3. session
-       4. tty_nr
-       5. tpgid
-       6. flags (math=4, traced=10)
-       7. minflt
-       8. cminflt
-       9. majflt
-       10. cmajflt
-       11. utime
-       12. stime
-       13. cutime
-       14. cstime
-       15. priority
-       16. nice
-       17. 0
-       18. itrealvalue
-       19. starttime
-       20. vsize
-       21. rss
-       22. rlim
-       23. startcode
-       24. endcode
-       25. startstack
-       26. kstkesp
-       27. kstkeip
-       28. pending signal bitmap
-       29. blocked signal bitmap
-       30. ignored signal bitmap
-       31. caught signal bitmap
-       32. wchan
-       33. nswap
-       34. cnswap
-       35. exit_signal
-       36. processor
-*/
-
-static int
-readstat(int pid, char *buf, int nbuf, char **f, int nf)
-{
-       int fd, n;
-       char *p;
-
-       snprint(buf, nbuf, "/proc/%d/stat", pid);
-       if((fd = open(buf, OREAD)) < 0){
-               fprint(2, "open %s: %r\n", buf);
-               return -1;
-       }
-       n = read(fd, buf, nbuf-1);
-       close(fd);
-       if(n <= 0){
-               fprint(2, "read %s: %r\n", buf);
-               return -1;
-       }
-       buf[n] = 0;
-
-       /* command name is in parens, no parens afterward */
-       p = strrchr(buf, ')');
-       if(p == nil || *++p != ' '){
-               fprint(2, "bad format in /proc/%d/stat\n", pid);
-               return -1;
-       }
-       ++p;
-
-       nf = tokenize(p, f, nf);
-       if(0) print("code 0x%lux-0x%lux stack 0x%lux kstk 0x%lux keip 0x%lux pending 0x%lux\n",
-               strtoul(f[23], 0, 0), strtoul(f[24], 0, 0), strtoul(f[25], 0, 0),
-               strtoul(f[26], 0, 0), strtoul(f[27], 0, 0), strtoul(f[28], 0, 0));
-
-       return nf;
-}
-
-static char*
-readstatus(int pid, char *buf, int nbuf, char *key)
-{
-       int fd, n;
-       char *p;
-
-       snprint(buf, nbuf, "/proc/%d/status", pid);
-       if((fd = open(buf, OREAD)) < 0){
-               fprint(2, "open %s: %r\n", buf);
-               return nil;
-       }
-       n = read(fd, buf, nbuf-1);
-       close(fd);
-       if(n <= 0){
-               fprint(2, "read %s: %r\n", buf);
-               return nil;
-       }
-       buf[n] = 0;
-       p = strstr(buf, key);
-       if(p)
-               return p+strlen(key);
-       return nil;
-}
-
-int
-procnotes(int pid, char ***pnotes)
-{
-       char buf[1024], *f[40];
-       int i, n, nf;
-       char *s, **notes;
-       ulong sigs;
-       extern char *_p9sigstr(int, char*);
-
-       *pnotes = nil;
-       nf = readstat(pid, buf, sizeof buf, f, nelem(f));
-       if(nf <= 28)
-               return -1;
-
-       sigs = strtoul(f[28], 0, 0) & ~(1<<SIGCONT);
-       if(sigs == 0){
-               *pnotes = nil;
-               return 0;
-       }
-
-       notes = malloc(32*sizeof(char*));
-       if(notes == nil)
-               return -1;
-       memset(notes, 0, 32*sizeof(char*));
-       n = 0;
-       for(i=0; i<32; i++){
-               if((sigs&(1<<i)) == 0)
-                       continue;
-               if((s = _p9sigstr(i, nil)) == nil)
-                       continue;
-               notes[n++] = s;
-       }
-       *pnotes = notes;
-       return n;
-}
-
-static int
-realpid(int pid)
-{
-       char buf[1024], *p;
-
-       p = readstatus(pid, buf, sizeof buf, "\nTgid:");
-       if(p == nil)
-               return pid;
-       return atoi(p);
-}
-
-int
-ctlproc(int pid, char *msg)
-{
-       int new;
-       LinuxThread *t;
-       uintptr data;
-
-       while(wait1(1) > 0)
-               ;
-
-       if(strcmp(msg, "attached") == 0){
-               t = attachthread(pid, pid, &new, Attached);
-               if(t == nil)
-                       return -1;
-               return 0;
-       }
-
-       if(strcmp(msg, "hang") == 0){
-               if(pid == getpid())
-                       return ptrace(PTRACE_TRACEME, 0, 0, 0);
-               werrstr("can only hang self");
-               return -1;
-       }
-
-       t = findthread(pid);
-       if(t == nil) {
-               werrstr("not attached to pid %d", pid);
-               return -1;
-       }
-       if(t->state == Exited) {
-               werrstr("pid %d has exited", pid);
-               return -1;
-       }
-       if(t->state == Killed) {
-               werrstr("pid %d has been killed", pid);
-               return -1;
-       }
-
-       if(strcmp(msg, "kill") == 0) {
-               if(ptrace(PTRACE_KILL, pid, 0, 0) < 0)
-                       return -1;
-               t->state = Killed;
-               return 0;
-       }
-       if(strcmp(msg, "startstop") == 0){
-               if(ctlproc(pid, "start") < 0)
-                       return -1;
-               return waitstop(t);
-       }
-       if(strcmp(msg, "sysstop") == 0){
-               if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
-                       return -1;
-               t->state = Running;
-               return waitstop(t);
-       }
-       if(strcmp(msg, "stop") == 0){
-               if(trace > 1)
-                       fprint(2, "tid %d: tkill stop\n", pid);
-               if(t->state == Stopped)
-                       return 0;
-               if(syscall(__NR_tkill, pid, SIGSTOP) < 0)
-                       return -1;
-               return waitstop(t);
-       }
-       if(strcmp(msg, "step") == 0){
-               if(t->state == Running) {
-                       werrstr("cannot single-step unstopped %d", pid);
-                       return -1;
-               }
-               if(ptrace(PTRACE_SINGLESTEP, pid, 0, 0) < 0)
-                       return -1;
-               return waitstop(t);
-       }
-       if(strcmp(msg, "start") == 0) {
-               if(t->state == Running)
-                       return 0;
-               data = 0;
-               if(t->state == Stopped && t->signal != SIGSTOP && t->signal != SIGTRAP)
-                       data = t->signal;
-               if(trace && data)
-                       fprint(2, "tid %d: continue %lud\n", pid, (ulong)data);
-               if(ptrace(PTRACE_CONT, pid, 0, (void*)data) < 0)
-                       return -1;
-               t->state = Running;
-               return 0;
-       }
-       if(strcmp(msg, "waitstop") == 0) {
-               return waitstop(t);
-       }
-       werrstr("unknown control message '%s'", msg);
-       return -1;
-}
-
-char*
-proctextfile(int pid)
-{
-       static char buf[1024], pbuf[128];
-
-       snprint(pbuf, sizeof pbuf, "/proc/%d/exe", pid);
-       if(readlink(pbuf, buf, sizeof buf) >= 0)
-               return strdup(buf);
-       if(access(pbuf, AEXIST) >= 0)
-               return strdup(pbuf);
-       return nil;
-}
-
-
-static int
-ptracerw(int type, int xtype, int isr, int pid, uvlong addr, void *v, uint n)
-{
-       int i;
-       uintptr u, a;
-       uchar buf[sizeof(uintptr)];
-
-       for(i=0; i<n; i+=sizeof(uintptr)){
-               // Tread carefully here.  On recent versions of glibc,
-               // ptrace is a variadic function which means the third
-               // argument will be pushed onto the stack as a uvlong.
-               // This is fine on amd64 but will not work for 386.
-               // We must convert addr to a uintptr.
-               a = addr+i;
-               if(isr){
-                       errno = 0;
-                       u = ptrace(type, pid, a, 0);
-                       if(errno)
-                               goto ptraceerr;
-                       if(n-i >= sizeof(uintptr))
-                               memmove((char*)v+i, &u, sizeof(uintptr));
-                       else{
-                               memmove(buf, &u, sizeof u);
-                               memmove((char*)v+i, buf, n-i);
-                       }
-               }else{
-                       if(n-i >= sizeof(uintptr))
-                               u = *(uintptr*)((char*)v+i);
-                       else{
-                               errno = 0;
-                               u = ptrace(xtype, pid, a, 0);
-                               if(errno)
-                                       return -1;
-                               memmove(buf, &u, sizeof u);
-                               memmove(buf, (char*)v+i, n-i);
-                               memmove(&u, buf, sizeof u);
-                       }
-                       if(ptrace(type, pid, a, u) < 0)
-                               goto ptraceerr;
-               }
-       }
-       return 0;
-
-ptraceerr:
-       werrstr("ptrace %s addr=%#llux pid=%d: %r", isr ? "read" : "write", addr, pid);
-       return -1;
-}
-
-static int
-ptracesegrw(Map *map, Seg *seg, uvlong addr, void *v, uint n, int isr)
-{
-       USED(seg);
-
-       return ptracerw(isr ? PTRACE_PEEKDATA : PTRACE_POKEDATA, PTRACE_PEEKDATA,
-               isr, map->pid, addr, v, n);
-}
-
-// If the debugger is compiled as an x86-64 program,
-// then all the ptrace register read/writes are done on
-// a 64-bit register set.  If the target program
-// is a 32-bit program, the debugger is expected to
-// read the bottom half of the relevant registers
-// out of the 64-bit set.
-
-// Linux 32-bit is
-//     BX CX DX SI DI BP AX DS ES FS GS OrigAX IP CS EFLAGS SP SS
-
-// Linux 64-bit is
-//     R15 R14 R13 R12 BP BX R11 R10 R9 R8 AX CX DX SI DI OrigAX IP CS EFLAGS SP SS FSBase GSBase DS ES FS GS
-
-// Go 32-bit is
-//     DI SI BP NSP BX DX CX AX GS FS ES DS TRAP ECODE PC CS EFLAGS SP SS
-
-uint go32tolinux32tab[] = {
-       4, 3, 5, 15, 0, 2, 1, 6, 10, 9, 8, 7, -1, -1, 12, 13, 14, 15, 16
-};
-static int
-go32tolinux32(uvlong addr)
-{
-       int r;
-
-       if(addr%4 || addr/4 >= nelem(go32tolinux32tab))
-               return -1;
-       r = go32tolinux32tab[addr/4];
-       if(r < 0)
-               return -1;
-       return r*4;
-}
-
-uint go32tolinux64tab[] = {
-       14, 13, 4, 19, 5, 12, 11, 10, 26, 25, 24, 23, -1, -1, 16, 17, 18, 19, 20
-};
-static int
-go32tolinux64(uvlong addr)
-{
-       int r;
-
-       if(addr%4 || addr/4 >= nelem(go32tolinux64tab))
-               return -1;
-       r = go32tolinux64tab[addr/4];
-       if(r < 0)
-               return -1;
-       return r*8;
-}
-
-extern Mach mi386;
-extern Mach mamd64;
-
-static int
-go2linux(uvlong addr)
-{
-       if(sizeof(void*) == 4) {
-               if(mach == &mi386)
-                       return go32tolinux32(addr);
-               werrstr("unsupported architecture");
-               return -1;
-       }
-
-       if(mach == &mi386)
-               return go32tolinux64(addr);
-       if(mach != &mamd64) {
-               werrstr("unsupported architecture");
-               return -1;
-       }
-
-       switch(addr){
-       case offsetof(UregAmd64, ax):
-               return offsetof(struct user_regs_struct, rax);
-       case offsetof(UregAmd64, bx):
-               return offsetof(struct user_regs_struct, rbx);
-       case offsetof(UregAmd64, cx):
-               return offsetof(struct user_regs_struct, rcx);
-       case offsetof(UregAmd64, dx):
-               return offsetof(struct user_regs_struct, rdx);
-       case offsetof(UregAmd64, si):
-               return offsetof(struct user_regs_struct, rsi);
-       case offsetof(UregAmd64, di):
-               return offsetof(struct user_regs_struct, rdi);
-       case offsetof(UregAmd64, bp):
-               return offsetof(struct user_regs_struct, rbp);
-       case offsetof(UregAmd64, r8):
-               return offsetof(struct user_regs_struct, r8);
-       case offsetof(UregAmd64, r9):
-               return offsetof(struct user_regs_struct, r9);
-       case offsetof(UregAmd64, r10):
-               return offsetof(struct user_regs_struct, r10);
-       case offsetof(UregAmd64, r11):
-               return offsetof(struct user_regs_struct, r11);
-       case offsetof(UregAmd64, r12):
-               return offsetof(struct user_regs_struct, r12);
-       case offsetof(UregAmd64, r13):
-               return offsetof(struct user_regs_struct, r13);
-       case offsetof(UregAmd64, r14):
-               return offsetof(struct user_regs_struct, r14);
-       case offsetof(UregAmd64, r15):
-               return offsetof(struct user_regs_struct, r15);
-       case offsetof(UregAmd64, ds):
-               return offsetof(struct user_regs_struct, ds);
-       case offsetof(UregAmd64, es):
-               return offsetof(struct user_regs_struct, es);
-       case offsetof(UregAmd64, fs):
-               return offsetof(struct user_regs_struct, fs);
-       case offsetof(UregAmd64, gs):
-               return offsetof(struct user_regs_struct, gs);
-       case offsetof(UregAmd64, ip):
-               return offsetof(struct user_regs_struct, rip);
-       case offsetof(UregAmd64, cs):
-               return offsetof(struct user_regs_struct, cs);
-       case offsetof(UregAmd64, flags):
-               return offsetof(struct user_regs_struct, eflags);
-       case offsetof(UregAmd64, sp):
-               return offsetof(struct user_regs_struct, rsp);
-       case offsetof(UregAmd64, ss):
-               return offsetof(struct user_regs_struct, ss);
-       }
-       return -1;
-}
-
-static int
-ptraceregrw(Map *map, Seg *seg, uvlong addr, void *v, uint n, int isr)
-{
-       int laddr;
-       uvlong u;
-       
-       USED(seg);
-
-       if((laddr = go2linux(addr)) < 0){
-               if(isr){
-                       memset(v, 0, n);
-                       return 0;
-               }
-               werrstr("register %llud not available", addr);
-               return -1;
-       }
-
-       if(isr){
-               errno = 0;
-               u = ptrace(PTRACE_PEEKUSER, map->pid, laddr, 0);
-               if(errno)
-                       goto ptraceerr;
-               switch(n){
-               case 1:
-                       *(uint8*)v = u;
-                       break;
-               case 2:
-                       *(uint16*)v = u;
-                       break;
-               case 4:
-                       *(uint32*)v = u;
-                       break;
-               case 8:
-                       *(uint64*)v = u;
-                       break;
-               default:
-                       werrstr("bad register size");
-                       return -1;
-               }
-       }else{
-               switch(n){
-               case 1:
-                       u = *(uint8*)v;
-                       break;
-               case 2:
-                       u = *(uint16*)v;
-                       break;
-               case 4:
-                       u = *(uint32*)v;
-                       break;
-               case 8:
-                       u = *(uint64*)v;
-                       break;
-               default:
-                       werrstr("bad register size");
-                       return -1;
-               }
-               if(ptrace(PTRACE_POKEUSER, map->pid, laddr, (void*)(uintptr)u) < 0)
-                       goto ptraceerr;
-       }
-       return 0;
-
-ptraceerr:
-       werrstr("ptrace %s register laddr=%d pid=%d n=%d: %r", isr ? "read" : "write", laddr, map->pid, n);
-       return -1;
-}
-
-char*
-procstatus(int pid)
-{
-       LinuxThread *t;
-
-       t = findthread(pid);
-       if(t == nil)
-               return "???";
-
-       return statestr[t->state];
-}
diff --git a/src/libmach/machdata.c b/src/libmach/machdata.c
deleted file mode 100644 (file)
index 66c19f9..0000000
+++ /dev/null
@@ -1,477 +0,0 @@
-// Inferno libmach/machdata.c
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/machdata.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-/*
- * Debugger utilities shared by at least two architectures
- */
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mach.h>
-
-#define STARTSYM       "_main"
-#define PROFSYM                "_mainp"
-#define        FRAMENAME       ".frame"
-
-extern Machdata        mipsmach;
-
-int    asstype = AMIPS;                /* disassembler type */
-Machdata *machdata;            /* machine-dependent functions */
-
-int
-localaddr(Map *map, char *fn, char *var, uvlong *r, Rgetter rget)
-{
-       Symbol s;
-       uvlong fp, pc, sp, link;
-
-       if (!lookup(fn, 0, &s)) {
-               werrstr("function not found");
-               return -1;
-       }
-       pc = rget(map, mach->pc);
-       sp = rget(map, mach->sp);
-       if(mach->link)
-               link = rget(map, mach->link);
-       else
-               link = 0;
-       fp = machdata->findframe(map, s.value, pc, sp, link);
-       if (fp == 0) {
-               werrstr("stack frame not found");
-               return -1;
-       }
-
-       if (!var || !var[0]) {
-               *r = fp;
-               return 1;
-       }
-
-       if (findlocal(&s, var, &s) == 0) {
-               werrstr("local variable not found");
-               return -1;
-       }
-
-       switch (s.class) {
-       case CAUTO:
-               *r = fp - s.value;
-               break;
-       case CPARAM:            /* assume address size is stack width */
-               *r = fp + s.value + mach->szaddr;
-               break;
-       default:
-               werrstr("local variable not found: %d", s.class);
-               return -1;
-       }
-       return 1;
-}
-
-/*
- * Print value v as s.name[+offset] if possible, or just v.
- */
-int
-symoff(char *buf, int n, uvlong v, int space)
-{
-       Symbol s;
-       int r;
-       int32 delta;
-
-       r = delta = 0;          /* to shut compiler up */
-       if (v) {
-               r = findsym(v, space, &s);
-               if (r)
-                       delta = v-s.value;
-               if (delta < 0)
-                       delta = -delta;
-       }
-       if (v == 0 || r == 0)
-               return snprint(buf, n, "%llux", v);
-       if (s.type != 't' && s.type != 'T' && delta >= 4096)
-               return snprint(buf, n, "%llux", v);
-       else if (delta)
-               return snprint(buf, n, "%s+%#ux", s.name, delta);
-       else
-               return snprint(buf, n, "%s", s.name);
-}
-
-/*
- *     Format floating point registers
- *
- *     Register codes in format field:
- *     'X' - print as 32-bit hexadecimal value
- *     'F' - 64-bit double register when modif == 'F'; else 32-bit single reg
- *     'f' - 32-bit ieee float
- *     '8' - big endian 80-bit ieee extended float
- *     '3' - little endian 80-bit ieee extended float with hole in bytes 8&9
- */
-int
-fpformat(Map *map, Reglist *rp, char *buf, int n, int modif)
-{
-       char reg[12];
-       uint32 r;
-
-       switch(rp->rformat)
-       {
-       case 'X':
-               if (get4(map, rp->roffs, &r) < 0)
-                       return -1;
-               snprint(buf, n, "%ux", r);
-               break;
-       case 'F':       /* first reg of double reg pair */
-               if (modif == 'F')
-               if ((rp->rformat=='F') || (((rp+1)->rflags&RFLT) && (rp+1)->rformat == 'f')) {
-                       if (get1(map, rp->roffs, (uchar *)reg, 8) < 0)
-                               return -1;
-                       machdata->dftos(buf, n, reg);
-                       if (rp->rformat == 'F')
-                               return 1;
-                       return 2;
-               }
-                       /* treat it like 'f' */
-               if (get1(map, rp->roffs, (uchar *)reg, 4) < 0)
-                       return -1;
-               machdata->sftos(buf, n, reg);
-               break;
-       case 'f':       /* 32 bit float */
-               if (get1(map, rp->roffs, (uchar *)reg, 4) < 0)
-                       return -1;
-               machdata->sftos(buf, n, reg);
-               break;
-       case '3':       /* little endian ieee 80 with hole in bytes 8&9 */
-               if (get1(map, rp->roffs, (uchar *)reg, 10) < 0)
-                       return -1;
-               memmove(reg+10, reg+8, 2);      /* open hole */
-               memset(reg+8, 0, 2);            /* fill it */
-               leieee80ftos(buf, n, reg);
-               break;
-       case '8':       /* big-endian ieee 80 */
-               if (get1(map, rp->roffs, (uchar *)reg, 10) < 0)
-                       return -1;
-               beieee80ftos(buf, n, reg);
-               break;
-       default:        /* unknown */
-               break;
-       }
-       return 1;
-}
-
-char *
-_hexify(char *buf, uint32 p, int zeros)
-{
-       uint32 d;
-
-       d = p/16;
-       if(d)
-               buf = _hexify(buf, d, zeros-1);
-       else
-               while(zeros--)
-                       *buf++ = '0';
-       *buf++ = "0123456789abcdef"[p&0x0f];
-       return buf;
-}
-
-/*
- * These routines assume that if the number is representable
- * in IEEE floating point, it will be representable in the native
- * double format.  Naive but workable, probably.
- */
-int
-ieeedftos(char *buf, int n, uint32 h, uint32 l)
-{
-       double fr;
-       int exp;
-
-       if (n <= 0)
-               return 0;
-
-
-       if(h & (1L<<31)){
-               *buf++ = '-';
-               h &= ~(1L<<31);
-       }else
-               *buf++ = ' ';
-       n--;
-       if(l == 0 && h == 0)
-               return snprint(buf, n, "0.");
-       exp = (h>>20) & ((1L<<11)-1L);
-       if(exp == 0)
-               return snprint(buf, n, "DeN(%.8ux%.8ux)", h, l);
-       if(exp == ((1L<<11)-1L)){
-               if(l==0 && (h&((1L<<20)-1L)) == 0)
-                       return snprint(buf, n, "Inf");
-               else
-                       return snprint(buf, n, "NaN(%.8ux%.8ux)", h&((1<<20)-1), l);
-       }
-       exp -= (1L<<10) - 2L;
-       fr = l & ((1L<<16)-1L);
-       fr /= 1L<<16;
-       fr += (l>>16) & ((1L<<16)-1L);
-       fr /= 1L<<16;
-       fr += (h & (1L<<20)-1L) | (1L<<20);
-       fr /= 1L<<21;
-       fr = ldexp(fr, exp);
-       return snprint(buf, n, "%.18g", fr);
-}
-
-int
-ieeesftos(char *buf, int n, uint32 h)
-{
-       double fr;
-       int exp;
-
-       if (n <= 0)
-               return 0;
-
-       if(h & (1L<<31)){
-               *buf++ = '-';
-               h &= ~(1L<<31);
-       }else
-               *buf++ = ' ';
-       n--;
-       if(h == 0)
-               return snprint(buf, n, "0.");
-       exp = (h>>23) & ((1L<<8)-1L);
-       if(exp == 0)
-               return snprint(buf, n, "DeN(%.8ux)", h);
-       if(exp == ((1L<<8)-1L)){
-               if((h&((1L<<23)-1L)) == 0)
-                       return snprint(buf, n, "Inf");
-               else
-                       return snprint(buf, n, "NaN(%.8lux)", h&((1L<<23)-1L));
-       }
-       exp -= (1L<<7) - 2L;
-       fr = (h & ((1L<<23)-1L)) | (1L<<23);
-       fr /= 1L<<24;
-       fr = ldexp(fr, exp);
-       return snprint(buf, n, "%.9g", fr);
-}
-
-int
-beieeesftos(char *buf, int n, void *s)
-{
-       return ieeesftos(buf, n, beswal(*(uint32*)s));
-}
-
-int
-beieeedftos(char *buf, int n, void *s)
-{
-       return ieeedftos(buf, n, beswal(*(uint32*)s), beswal(((uint32*)(s))[1]));
-}
-
-int
-leieeesftos(char *buf, int n, void *s)
-{
-       return ieeesftos(buf, n, leswal(*(uint32*)s));
-}
-
-int
-leieeedftos(char *buf, int n, void *s)
-{
-       return ieeedftos(buf, n, leswal(((uint32*)(s))[1]), leswal(*(uint32*)s));
-}
-
-/* packed in 12 bytes, with s[2]==s[3]==0; mantissa starts at s[4]*/
-int
-beieee80ftos(char *buf, int n, void *s)
-{
-       uchar *reg = (uchar*)s;
-       int i;
-       uint32 x;
-       uchar ieee[8+8];        /* room for slop */
-       uchar *p, *q;
-
-       memset(ieee, 0, sizeof(ieee));
-       /* sign */
-       if(reg[0] & 0x80)
-               ieee[0] |= 0x80;
-
-       /* exponent */
-       x = ((reg[0]&0x7F)<<8) | reg[1];
-       if(x == 0)              /* number is ±0 */
-               goto done;
-       if(x == 0x7FFF){
-               if(memcmp(reg+4, ieee+1, 8) == 0){ /* infinity */
-                       x = 2047;
-               }else{                          /* NaN */
-                       x = 2047;
-                       ieee[7] = 0x1;          /* make sure */
-               }
-               ieee[0] |= x>>4;
-               ieee[1] |= (x&0xF)<<4;
-               goto done;
-       }
-       x -= 0x3FFF;            /* exponent bias */
-       x += 1023;
-       if(x >= (1<<11) || ((reg[4]&0x80)==0 && x!=0))
-               return snprint(buf, n, "not in range");
-       ieee[0] |= x>>4;
-       ieee[1] |= (x&0xF)<<4;
-
-       /* mantissa */
-       p = reg+4;
-       q = ieee+1;
-       for(i=0; i<56; i+=8, p++, q++){ /* move one byte */
-               x = (p[0]&0x7F) << 1;
-               if(p[1] & 0x80)
-                       x |= 1;
-               q[0] |= x>>4;
-               q[1] |= (x&0xF)<<4;
-       }
-    done:
-       return beieeedftos(buf, n, (void*)ieee);
-}
-
-int
-leieee80ftos(char *buf, int n, void *s)
-{
-       int i;
-       char *cp;
-       char b[12];
-
-       cp = (char*) s;
-       for(i=0; i<12; i++)
-               b[11-i] = *cp++;
-       return beieee80ftos(buf, n, b);
-}
-
-int
-cisctrace(Map *map, uvlong pc, uvlong sp, uvlong link, Tracer trace)
-{
-       Symbol s;
-       int found, i;
-       uvlong opc, moved;
-
-       USED(link);
-       i = 0;
-       opc = 0;
-       while(pc && opc != pc) {
-               moved = pc2sp(pc);
-               if (moved == ~0)
-                       break;
-               found = findsym(pc, CTEXT, &s);
-               if (!found)
-                       break;
-               if(strcmp(STARTSYM, s.name) == 0 || strcmp(PROFSYM, s.name) == 0)
-                       break;
-
-               sp += moved;
-               opc = pc;
-               if (geta(map, sp, &pc) < 0)
-                       break;
-               (*trace)(map, pc, sp, &s);
-               sp += mach->szaddr;     /*assumes address size = stack width*/
-               if(++i > 40)
-                       break;
-       }
-       return i;
-}
-
-int
-risctrace(Map *map, uvlong pc, uvlong sp, uvlong link, Tracer trace)
-{
-       int i;
-       Symbol s, f;
-       uvlong oldpc;
-
-       i = 0;
-       while(findsym(pc, CTEXT, &s)) {
-               if(strcmp(STARTSYM, s.name) == 0 || strcmp(PROFSYM, s.name) == 0)
-                       break;
-
-               if(pc == s.value)       /* at first instruction */
-                       f.value = 0;
-               else if(findlocal(&s, FRAMENAME, &f) == 0)
-                       break;
-
-               oldpc = pc;
-               if(s.type == 'L' || s.type == 'l' || pc <= s.value+mach->pcquant)
-                       pc = link;
-               else
-                       if (geta(map, sp, &pc) < 0)
-                               break;
-
-               if(pc == 0 || (pc == oldpc && f.value == 0))
-                       break;
-
-               sp += f.value;
-               (*trace)(map, pc-8, sp, &s);
-
-               if(++i > 40)
-                       break;
-       }
-       return i;
-}
-
-uvlong
-ciscframe(Map *map, uvlong addr, uvlong pc, uvlong sp, uvlong link)
-{
-       Symbol s;
-       uvlong moved;
-
-       USED(link);
-       for(;;) {
-               moved = pc2sp(pc);
-               if (moved  == ~0)
-                       break;
-               sp += moved;
-               findsym(pc, CTEXT, &s);
-               if (addr == s.value)
-                       return sp;
-               if (geta(map, sp, &pc) < 0)
-                       break;
-               sp += mach->szaddr;     /*assumes sizeof(addr) = stack width*/
-       }
-       return 0;
-}
-
-uvlong
-riscframe(Map *map, uvlong addr, uvlong pc, uvlong sp, uvlong link)
-{
-       Symbol s, f;
-
-       while (findsym(pc, CTEXT, &s)) {
-               if(strcmp(STARTSYM, s.name) == 0 || strcmp(PROFSYM, s.name) == 0)
-                       break;
-
-               if(pc == s.value)       /* at first instruction */
-                       f.value = 0;
-               else
-               if(findlocal(&s, FRAMENAME, &f) == 0)
-                       break;
-
-               sp += f.value;
-               if (s.value == addr)
-                       return sp;
-
-               if (s.type == 'L' || s.type == 'l' || pc-s.value <= mach->szaddr*2)
-                       pc = link;
-               else
-               if (geta(map, sp-f.value, &pc) < 0)
-                       break;
-       }
-       return 0;
-}
diff --git a/src/libmach/macho.h b/src/libmach/macho.h
deleted file mode 100644 (file)
index 9dfea5a..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
- *     Definitions needed for  accessing MACH object headers.
- */
-
-typedef struct {
-       uint32  magic;          /* mach magic number identifier */
-       uint32  cputype;        /* cpu specifier */
-       uint32  cpusubtype;     /* machine specifier */
-       uint32  filetype;       /* type of file */
-       uint32  ncmds;          /* number of load commands */
-       uint32  sizeofcmds;     /* the size of all the load commands */
-       uint32  flags;          /* flags */
-       uint32  reserved;       /* reserved */
-} Machhdr;
-
-typedef struct {
-       uint32  type;   /* type of load command */
-       uint32  size;   /* total size in bytes */
-} MachCmd;
-
-typedef struct  {
-       MachCmd cmd;
-       char            segname[16];    /* segment name */
-       uint32  vmaddr;         /* memory address of this segment */
-       uint32  vmsize;         /* memory size of this segment */
-       uint32  fileoff;        /* file offset of this segment */
-       uint32  filesize;       /* amount to map from the file */
-       uint32  maxprot;        /* maximum VM protection */
-       uint32  initprot;       /* initial VM protection */
-       uint32  nsects;         /* number of sections in segment */
-       uint32  flags;          /* flags */
-} MachSeg32; /* for 32-bit architectures */
-
-typedef struct  {
-       MachCmd cmd;
-       char            segname[16];    /* segment name */
-       uvlong  vmaddr;         /* memory address of this segment */
-       uvlong  vmsize;         /* memory size of this segment */
-       uvlong  fileoff;        /* file offset of this segment */
-       uvlong  filesize;       /* amount to map from the file */
-       uint32  maxprot;        /* maximum VM protection */
-       uint32  initprot;       /* initial VM protection */
-       uint32  nsects;         /* number of sections in segment */
-       uint32  flags;          /* flags */
-} MachSeg64; /* for 64-bit architectures */
-
-typedef struct  {
-       MachCmd cmd;
-       uint32  fileoff;        /* file offset of this segment */
-       uint32  filesize;       /* amount to map from the file */
-} MachSymSeg;
-
-typedef struct  {
-       char            sectname[16];   /* name of this section */
-       char            segname[16];    /* segment this section goes in */
-       uint32  addr;           /* memory address of this section */
-       uint32  size;           /* size in bytes of this section */
-       uint32  offset;         /* file offset of this section */
-       uint32  align;          /* section alignment (power of 2) */
-       uint32  reloff;         /* file offset of relocation entries */
-       uint32  nreloc;         /* number of relocation entries */
-       uint32  flags;          /* flags (section type and attributes)*/
-       uint32  reserved1;      /* reserved (for offset or index) */
-       uint32  reserved2;      /* reserved (for count or sizeof) */
-} MachSect32; /* for 32-bit architectures */
-
-typedef struct  {
-       char            sectname[16];   /* name of this section */
-       char            segname[16];    /* segment this section goes in */
-       uvlong  addr;           /* memory address of this section */
-       uvlong  size;           /* size in bytes of this section */
-       uint32  offset;         /* file offset of this section */
-       uint32  align;          /* section alignment (power of 2) */
-       uint32  reloff;         /* file offset of relocation entries */
-       uint32  nreloc;         /* number of relocation entries */
-       uint32  flags;          /* flags (section type and attributes)*/
-       uint32  reserved1;      /* reserved (for offset or index) */
-       uint32  reserved2;      /* reserved (for count or sizeof) */
-       uint32  reserved3;      /* reserved */
-} MachSect64; /* for 64-bit architectures */
-
-enum {
-       MACH_CPU_TYPE_X86_64 = (1<<24)|7,
-       MACH_CPU_TYPE_X86 = 7,
-       MACH_CPU_SUBTYPE_X86 = 3,
-       MACH_CPU_SUBTYPE_X86_64 = (1<<31)|3,
-       MACH_EXECUTABLE_TYPE = 2,
-       MACH_SEGMENT_32 = 1,    /* 32-bit mapped segment */
-       MACH_SEGMENT_64 = 0x19, /* 64-bit mapped segment */
-       MACH_SYMSEG = 3,        /* obsolete gdb symtab, reused by go */
-       MACH_UNIXTHREAD = 0x5,  /* thread (for stack) */
-};
-
-
-#define        MACH64_MAG              ((0xcf<<24) | (0xfa<<16) | (0xed<<8) | 0xfe)
-#define        MACH32_MAG              ((0xce<<24) | (0xfa<<16) | (0xed<<8) | 0xfe)
diff --git a/src/libmach/map.c b/src/libmach/map.c
deleted file mode 100644 (file)
index cd5ef09..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-// Derived from Inferno libmach/map.c and
-// Plan 9 from User Space src/libmach/map.c
-//
-// http://code.swtch.com/plan9port/src/tip/src/libmach/map.c
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/map.c
-//
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2001-2007 Russ Cox.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-/*
- * file map routines
- */
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mach.h>
-
-Map *
-newmap(Map *map, int n)
-{
-       int size;
-
-       size = sizeof(Map)+(n-1)*sizeof(Seg);
-       if (map == 0)
-               map = malloc(size);
-       else
-               map = realloc(map, size);
-       if (map == 0) {
-               werrstr("out of memory: %r");
-               return 0;
-       }
-       memset(map, 0, size);
-       map->nsegs = n;
-       return map;
-}
-
-int
-setmap(Map *map, int fd, uvlong b, uvlong e, vlong f, char *name, Maprw *rw)
-{
-       int i;
-
-       if (map == 0)
-               return 0;
-       for (i = 0; i < map->nsegs; i++)
-               if (!map->seg[i].inuse)
-                       break;
-       if (i >= map->nsegs)
-               return 0;
-       map->seg[i].b = b;
-       map->seg[i].e = e;
-       map->seg[i].f = f;
-       map->seg[i].inuse = 1;
-       map->seg[i].name = name;
-       map->seg[i].fd = fd;
-       map->seg[i].rw = rw;
-       return 1;
-}
-
-/*
-static uvlong
-stacktop(int pid)
-{
-       char buf[64];
-       int fd;
-       int n;
-       char *cp;
-
-       snprint(buf, sizeof(buf), "/proc/%d/segment", pid);
-       fd = open(buf, 0);
-       if (fd < 0)
-               return 0;
-       n = read(fd, buf, sizeof(buf)-1);
-       close(fd);
-       buf[n] = 0;
-       if (strncmp(buf, "Stack", 5))
-               return 0;
-       for (cp = buf+5; *cp && *cp == ' '; cp++)
-               ;
-       if (!*cp)
-               return 0;
-       cp = strchr(cp, ' ');
-       if (!cp)
-               return 0;
-       while (*cp && *cp == ' ')
-               cp++;
-       if (!*cp)
-               return 0;
-       return strtoull(cp, 0, 16);
-}
-*/
-
-int
-findseg(Map *map, char *name)
-{
-       int i;
-
-       if (!map)
-               return -1;
-       for (i = 0; i < map->nsegs; i++)
-               if (map->seg[i].inuse && !strcmp(map->seg[i].name, name))
-                       return i;
-       return -1;
-}
-
-void
-unusemap(Map *map, int i)
-{
-       if (map != 0 && 0 <= i && i < map->nsegs)
-               map->seg[i].inuse = 0;
-}
-
-int
-fdrw(Map *map, Seg *s, uvlong addr, void *v, uint n, int isread)
-{
-       int tot, m;
-       
-       USED(map);
-
-       for(tot=0; tot<n; tot+=m){
-               if(isread)
-                       m = pread(s->fd, (uchar*)v+tot, n-tot, addr+tot);
-               else
-                       m = pwrite(s->fd, (uchar*)v+tot, n-tot, addr+tot);
-               if(m == 0){
-                       werrstr("short %s", isread ? "read" : "write");
-                       return -1;
-               }
-               if(m < 0){
-                       werrstr("%s %d at %#llux (+%#llux): %r", isread ? "read" : "write", n, addr, s->f);
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-
-Map*
-loadmap(Map *map, int fd, Fhdr *fp)
-{
-       map = newmap(map, 2);
-       if (map == 0)
-               return 0;
-
-       map->seg[0].b = fp->txtaddr;
-       map->seg[0].e = fp->txtaddr+fp->txtsz;
-       map->seg[0].f = fp->txtoff;
-       map->seg[0].fd = fd;
-       map->seg[0].inuse = 1;
-       map->seg[0].name = "text";
-       map->seg[0].rw = fdrw;
-       map->seg[1].b = fp->dataddr;
-       map->seg[1].e = fp->dataddr+fp->datsz;
-       map->seg[1].f = fp->datoff;
-       map->seg[1].fd = fd;
-       map->seg[1].inuse = 1;
-       map->seg[1].name = "data";
-       map->seg[0].rw = fdrw;
-       return map;
-}
diff --git a/src/libmach/netbsd.c b/src/libmach/netbsd.c
deleted file mode 100644 (file)
index adeeff3..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-// This is stubbed out for the moment. Will revisit when the time comes.
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mach.h>
-
-int
-ctlproc(int pid, char *msg)
-{
-       USED(pid);
-       USED(msg);
-       sysfatal("ctlproc unimplemented in NetBSD");
-       return -1;
-}
-
-char*
-proctextfile(int pid)
-{
-       USED(pid);
-       sysfatal("proctextfile unimplemented in NetBSD");
-       return nil;
-}
-
-char*
-procstatus(int pid)
-{
-       USED(pid);
-       sysfatal("procstatus unimplemented in NetBSD");
-       return nil;
-}
-
-Map*
-attachproc(int pid, Fhdr *fp)
-{
-       USED(pid);
-       USED(fp);
-       sysfatal("attachproc unimplemented in NetBSD");
-       return nil;
-}
-
-void
-detachproc(Map *m)
-{
-       USED(m);
-       sysfatal("detachproc unimplemented in NetBSD");
-}
-
-int
-procthreadpids(int pid, int *p, int np)
-{
-       USED(pid);
-       USED(p);
-       USED(np);
-       sysfatal("procthreadpids unimplemented in NetBSD");
-       return -1;
-}
diff --git a/src/libmach/obj.c b/src/libmach/obj.c
deleted file mode 100644 (file)
index d350b56..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-// Inferno libmach/obj.c
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/obj.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-/*
- * obj.c
- * routines universal to all object files
- */
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <ar.h>
-#include <mach.h>
-#include "obj.h"
-
-int
-isar(Biobuf *bp)
-{
-       int n;
-       char magbuf[SARMAG];
-
-       n = Bread(bp, magbuf, SARMAG);
-       if(n == SARMAG && strncmp(magbuf, ARMAG, SARMAG) == 0)
-               return 1;
-       return 0;
-}
-
-/*
- * look for the next file in an archive
- */
-int
-nextar(Biobuf *bp, int offset, char *buf)
-{
-       struct ar_hdr a;
-       int i, r;
-       int32 arsize;
-
-       if (offset&01)
-               offset++;
-       Bseek(bp, offset, 0);
-       r = Bread(bp, &a, SAR_HDR);
-       if(r != SAR_HDR)
-               return 0;
-       if(strncmp(a.fmag, ARFMAG, sizeof(a.fmag)))
-               return -1;
-       for(i=0; i<sizeof(a.name) && i<SARNAME && a.name[i] != ' '; i++)
-               buf[i] = a.name[i];
-       buf[i] = 0;
-       arsize = strtol(a.size, 0, 0);
-       if (arsize&1)
-               arsize++;
-       return arsize + SAR_HDR;
-}
diff --git a/src/libmach/obj.h b/src/libmach/obj.h
deleted file mode 100644 (file)
index 35ec413..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-// Inferno libmach/obj.h
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/obj.h
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-/*
- * obj.h -- defs for dealing with object files
- */
-
-typedef enum Kind              /* variable defs and references in obj */
-{
-       aNone,                  /* we don't care about this prog */
-       aName,                  /* introduces a name */
-       aText,                  /* starts a function */
-       aData,                  /* references to a global object */
-} Kind;
-
-typedef struct Prog    Prog;
-
-struct Prog            /* info from .$O files */
-{
-       Kind    kind;           /* what kind of symbol */
-       char    type;           /* type of the symbol: ie, 'T', 'a', etc. */
-       char    sym;            /* index of symbol's name */
-       char    *id;            /* name for the symbol, if it introduces one */
-       uint    sig;            /* type signature for symbol */
-};
-
-#define UNKNOWN        '?'
-void           _offset(int, vlong);
diff --git a/src/libmach/openbsd.c b/src/libmach/openbsd.c
deleted file mode 100644 (file)
index ace8a22..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-// This is stubbed out for the moment. Will revisit when the time comes.
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mach.h>
-
-int
-ctlproc(int pid, char *msg)
-{
-       USED(pid);
-       USED(msg);
-       sysfatal("ctlproc unimplemented in OpenBSD");
-       return -1;
-}
-
-char*
-proctextfile(int pid)
-{
-       USED(pid);
-       sysfatal("proctextfile unimplemented in OpenBSD");
-       return nil;
-}
-
-char*
-procstatus(int pid)
-{
-       USED(pid);
-       sysfatal("procstatus unimplemented in OpenBSD");
-       return nil;
-}
-
-Map*
-attachproc(int pid, Fhdr *fp)
-{
-       USED(pid);
-       USED(fp);
-       sysfatal("attachproc unimplemented in OpenBSD");
-       return nil;
-}
-
-void
-detachproc(Map *m)
-{
-       USED(m);
-       sysfatal("detachproc unimplemented in OpenBSD");
-}
-
-int
-procthreadpids(int pid, int *p, int np)
-{
-       USED(pid);
-       USED(p);
-       USED(np);
-       sysfatal("procthreadpids unimplemented in OpenBSD");
-       return -1;
-}
diff --git a/src/libmach/plan9.c b/src/libmach/plan9.c
deleted file mode 100644 (file)
index 59e2649..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-// This is stubbed out for the moment. Will revisit when the time comes.
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mach.h>
-
-int
-ctlproc(int pid, char *msg)
-{
-       USED(pid);
-       USED(msg);
-
-       sysfatal("ctlproc unimplemented on Plan 9");
-       return -1;
-}
-
-char*
-proctextfile(int pid)
-{
-       USED(pid);
-
-       sysfatal("proctextfile unimplemented on Plan 9");
-       return nil;
-}
-
-char*
-procstatus(int pid)
-{
-       USED(pid);
-
-       sysfatal("procstatus unimplemented on Plan 9");
-       return nil;
-}
-
-Map*
-attachproc(int pid, Fhdr *fp)
-{
-       USED(pid);
-       USED(fp);
-
-       sysfatal("attachproc unimplemented on Plan 9");
-       return nil;
-}
-
-void
-detachproc(Map *m)
-{
-       USED(m);
-
-       sysfatal("detachproc unimplemented on Plan 9");
-}
-
-int
-procthreadpids(int pid, int *p, int np)
-{
-       USED(pid);
-       USED(p);
-       USED(np);
-
-       sysfatal("procthreadpids unimplemented on Plan 9");
-       return -1;
-}
-
-int 
-nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
-{
-       USED(rqtp);
-       USED(rmtp);
-
-       sysfatal("nanosleep unimplemented on Plan 9");
-       return -1;
-}
diff --git a/src/libmach/setmach.c b/src/libmach/setmach.c
deleted file mode 100644 (file)
index 0fa4d31..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-// Inferno libmach/setmach.c
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/setmach.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include       <u.h>
-#include       <libc.h>
-#include       <bio.h>
-#include       <mach.h>
-               /* table for selecting machine-dependent parameters */
-
-typedef        struct machtab Machtab;
-
-struct machtab
-{
-       char            *name;                  /* machine name */
-       short           type;                   /* executable type */
-       short           boottype;               /* bootable type */
-       int             asstype;                /* disassembler code */
-       Mach            *mach;                  /* machine description */
-       Machdata        *machdata;              /* machine functions */
-};
-
-/*
-extern Mach            mmips, msparc, m68020, mi386, mamd64,
-                       marm, mmips2be, mmips2le, mpower, mpower64, malpha, msparc64;
-extern Machdata        mipsmach, sparcmach, m68020mach, i386mach,
-                       armmach, mipsmach2le, powermach, alphamach, sparc64mach;
-*/
-extern Mach            mi386, mamd64, marm;
-extern Machdata                i386mach, armmach;
-
-/*
- *     machine selection table.  machines with native disassemblers should
- *     follow the plan 9 variant in the table; native modes are selectable
- *     only by name.
- */
-Machtab        machines[] =
-{
-       {       "386",                          /*plan 9 386*/
-               FI386,
-               FI386B,
-               AI386,
-               &mi386,
-               &i386mach,      },
-       {       "amd64",                        /*amd64*/
-               FAMD64,
-               FAMD64B,
-               AAMD64,
-               &mamd64,
-               &i386mach,      },
-       {       "arm",                          /*ARM*/
-               FARM,
-               FARMB,
-               AARM,
-               &marm,
-               &armmach,       },
-#ifdef unused
-       {       "68020",                        /*68020*/
-               F68020,
-               F68020B,
-               A68020,
-               &m68020,
-               &m68020mach,    },
-       {       "68020",                        /*Next 68040 bootable*/
-               F68020,
-               FNEXTB,
-               A68020,
-               &m68020,
-               &m68020mach,    },
-       {       "mips2LE",                      /*plan 9 mips2 little endian*/
-               FMIPS2LE,
-               0,
-               AMIPS,
-               &mmips2le,
-               &mipsmach2le,   },
-       {       "mips",                         /*plan 9 mips*/
-               FMIPS,
-               FMIPSB,
-               AMIPS,
-               &mmips,
-               &mipsmach,      },
-       {       "mips2",                        /*plan 9 mips2*/
-               FMIPS2BE,
-               FMIPSB,
-               AMIPS,
-               &mmips2be,
-               &mipsmach,      },              /* shares debuggers with native mips */
-       {       "mipsco",                       /*native mips - must follow plan 9*/
-               FMIPS,
-               FMIPSB,
-               AMIPSCO,
-               &mmips,
-               &mipsmach,      },
-       {       "sparc",                        /*plan 9 sparc */
-               FSPARC,
-               FSPARCB,
-               ASPARC,
-               &msparc,
-               &sparcmach,     },
-       {       "sunsparc",                     /*native sparc - must follow plan 9*/
-               FSPARC,
-               FSPARCB,
-               ASUNSPARC,
-               &msparc,
-               &sparcmach,     },
-       {       "86",                           /*8086 - a peach of a machine*/
-               FI386,
-               FI386B,
-               AI8086,
-               &mi386,
-               &i386mach,      },
-       {       "power",                        /*PowerPC*/
-               FPOWER,
-               FPOWERB,
-               APOWER,
-               &mpower,
-               &powermach,     },
-       {       "power64",                      /*PowerPC*/
-               FPOWER64,
-               FPOWER64B,
-               APOWER64,
-               &mpower64,
-               &powermach,     },
-       {       "alpha",                        /*Alpha*/
-               FALPHA,
-               FALPHAB,
-               AALPHA,
-               &malpha,
-               &alphamach,     },
-       {       "sparc64",                      /*plan 9 sparc64 */
-               FSPARC64,
-               FSPARCB,                        /* XXX? */
-               ASPARC64,
-               &msparc64,
-               &sparc64mach,   },
-#endif
-       {       0               },              /*the terminator*/
-};
-
-/*
- *     select a machine by executable file type
- */
-void
-machbytype(int type)
-{
-       Machtab *mp;
-
-       for (mp = machines; mp->name; mp++){
-               if (mp->type == type || mp->boottype == type) {
-                       asstype = mp->asstype;
-                       machdata = mp->machdata;
-                       break;
-               }
-       }
-}
-/*
- *     select a machine by name
- */
-int
-machbyname(char *name)
-{
-       Machtab *mp;
-
-       if (!name) {
-               asstype = AAMD64;
-               machdata = &i386mach;
-               mach = &mamd64;
-               return 1;
-       }
-       for (mp = machines; mp->name; mp++){
-               if (strcmp(mp->name, name) == 0) {
-                       asstype = mp->asstype;
-                       machdata = mp->machdata;
-                       mach = mp->mach;
-                       return 1;
-               }
-       }
-       return 0;
-}
diff --git a/src/libmach/solaris.c b/src/libmach/solaris.c
deleted file mode 100644 (file)
index ea49c2f..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-// This is stubbed out for the moment. Will revisit when the time comes.
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mach.h>
-
-int
-ctlproc(int pid, char *msg)
-{
-       USED(pid);
-       USED(msg);
-       sysfatal("ctlproc unimplemented in Solaris");
-       return -1;
-}
-
-char*
-proctextfile(int pid)
-{
-       USED(pid);
-       sysfatal("proctextfile unimplemented in Solaris");
-       return nil;
-}
-
-char*
-procstatus(int pid)
-{
-       USED(pid);
-       sysfatal("procstatus unimplemented in Solaris");
-       return nil;
-}
-
-Map*
-attachproc(int pid, Fhdr *fp)
-{
-       USED(pid);
-       USED(fp);
-       sysfatal("attachproc unimplemented in Solaris");
-       return nil;
-}
-
-void
-detachproc(Map *m)
-{
-       USED(m);
-       sysfatal("detachproc unimplemented in Solaris");
-}
-
-int
-procthreadpids(int pid, int *p, int np)
-{
-       USED(pid);
-       USED(p);
-       USED(np);
-       sysfatal("procthreadpids unimplemented in Solaris");
-       return -1;
-}
diff --git a/src/libmach/swap.c b/src/libmach/swap.c
deleted file mode 100644 (file)
index bc296a3..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-// Inferno libmach/swap.c
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/swap.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include <u.h>
-
-/*
- * big-endian short
- */
-ushort
-beswab(ushort s)
-{
-       uchar *p;
-
-       p = (uchar*)&s;
-       return (p[0]<<8) | p[1];
-}
-
-/*
- * big-endian int32
- */
-uint32
-beswal(uint32 l)
-{
-       uchar *p;
-
-       p = (uchar*)&l;
-       return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
-}
-
-/*
- * big-endian vlong
- */
-uvlong
-beswav(uvlong v)
-{
-       uchar *p;
-
-       p = (uchar*)&v;
-       return ((uvlong)p[0]<<56) | ((uvlong)p[1]<<48) | ((uvlong)p[2]<<40)
-                                 | ((uvlong)p[3]<<32) | ((uvlong)p[4]<<24)
-                                 | ((uvlong)p[5]<<16) | ((uvlong)p[6]<<8)
-                                 | (uvlong)p[7];
-}
-
-/*
- * little-endian short
- */
-ushort
-leswab(ushort s)
-{
-       uchar *p;
-
-       p = (uchar*)&s;
-       return (p[1]<<8) | p[0];
-}
-
-/*
- * little-endian int32
- */
-uint32
-leswal(uint32 l)
-{
-       uchar *p;
-
-       p = (uchar*)&l;
-       return (p[3]<<24) | (p[2]<<16) | (p[1]<<8) | p[0];
-}
-
-/*
- * little-endian vlong
- */
-uvlong
-leswav(uvlong v)
-{
-       uchar *p;
-
-       p = (uchar*)&v;
-       return ((uvlong)p[7]<<56) | ((uvlong)p[6]<<48) | ((uvlong)p[5]<<40)
-                                 | ((uvlong)p[4]<<32) | ((uvlong)p[3]<<24)
-                                 | ((uvlong)p[2]<<16) | ((uvlong)p[1]<<8)
-                                 | (uvlong)p[0];
-}
diff --git a/src/libmach/sym.c b/src/libmach/sym.c
deleted file mode 100644 (file)
index 75e3787..0000000
+++ /dev/null
@@ -1,1884 +0,0 @@
-// Inferno libmach/sym.c
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/sym.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.
-//     Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-//     Portions Copyright © 1997-1999 Vita Nuova Limited.
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-//     Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mach.h>
-
-#define        HUGEINT 0x7fffffff
-#define        NNAME   20              /* a relic of the past */
-
-typedef        struct txtsym Txtsym;
-typedef        struct file File;
-typedef        struct hist Hist;
-
-struct txtsym {                                /* Text Symbol table */
-       int     n;                      /* number of local vars */
-       Sym     **locals;               /* array of ptrs to autos */
-       Sym     *sym;                   /* function symbol entry */
-};
-
-struct hist {                          /* Stack of include files & #line directives */
-       char    *name;                  /* Assumes names Null terminated in file */
-       int32   line;                   /* line # where it was included */
-       int32   offset;                 /* line # of #line directive */
-};
-
-struct file {                          /* Per input file header to history stack */
-       uvlong  addr;                   /* address of first text sym */
-       union {
-               Txtsym  *txt;           /* first text symbol */
-               Sym     *sym;           /* only during initilization */
-       };
-       int     n;                      /* size of history stack */
-       Hist    *hist;                  /* history stack */
-};
-
-static int     debug = 0;
-
-static Sym     **autos;                /* Base of auto variables */
-static File    *files;                 /* Base of file arena */
-static int     fmaxi;                  /* largest file path index */
-static Sym     **fnames;               /* file names path component table */
-static Sym     **globals;              /* globals by addr table */
-static Hist    *hist;                  /* base of history stack */
-static int     isbuilt;                /* internal table init flag */
-static int32   nauto;                  /* number of automatics */
-static int32   nfiles;                 /* number of files */
-static int32   nglob;                  /* number of globals */
-static int32   nhist;                  /* number of history stack entries */
-static int32   nsym;                   /* number of symbols */
-static int     ntxt;                   /* number of text symbols */
-static uchar   *pcline;                /* start of pc-line state table */
-static uchar   *pclineend;             /* end of pc-line table */
-static uchar   *spoff;                 /* start of pc-sp state table */
-static uchar   *spoffend;              /* end of pc-sp offset table */
-static Sym     *symbols;               /* symbol table */
-static Txtsym  *txt;                   /* Base of text symbol table */
-static uvlong  txtstart;               /* start of text segment */
-static uvlong  txtend;                 /* end of text segment */
-static uvlong  firstinstr;             /* as found from symtab; needed for amd64 */
-
-static void    cleansyms(void);
-static int32   decodename(Biobuf*, Sym*);
-static short   *encfname(char*);
-static int     fline(char*, int, int32, Hist*, Hist**);
-static void    fillsym(Sym*, Symbol*);
-static int     findglobal(char*, Symbol*);
-static int     findlocvar(Symbol*, char *, Symbol*);
-static int     findtext(char*, Symbol*);
-static int     hcomp(Hist*, short*);
-static int     hline(File*, short*, int32*);
-static void    printhist(char*, Hist*, int);
-static int     buildtbls(void);
-static int     symcomp(const void*, const void*);
-static int     symerrmsg(int, char*);
-static int     txtcomp(const void*, const void*);
-static int     filecomp(const void*, const void*);
-
-/*
- * Go 1.2 pcln table (also contains pcsp).
- */
-#define Go12PclnMagic 0xfffffffb
-#define Go12PclnMagicRev 0xfbffffff
-static int     isgo12pcline(void);
-static uvlong go12pc2sp(uvlong);
-static int32 go12fileline(char*, int, uvlong);
-static void    go12clean(void);
-static uvlong go12file2pc(char*, int);
-
-/*
- *     initialize the symbol tables
- */
-int
-syminit(int fd, Fhdr *fp)
-{
-       Sym *p;
-       int32 i, l, size, symsz;
-       vlong vl;
-       Biobuf b;
-       int svalsz, newformat, shift;
-       uvlong (*swav)(uvlong);
-       uint32 (*swal)(uint32);
-       uchar buf[8], c;
-
-       if(fp->symsz == 0)
-               return 0;
-       if(fp->type == FNONE)
-               return 0;
-
-       swav = beswav;
-       swal = beswal;
-
-       cleansyms();
-       textseg(fp->txtaddr, fp);
-               /* minimum symbol record size = 4+1+2 bytes */
-       symbols = malloc((fp->symsz/(4+1+2)+1)*sizeof(Sym));
-       if(symbols == 0) {
-               werrstr("can't malloc %d bytes", fp->symsz);
-               return -1;
-       }
-       Binit(&b, fd, OREAD);
-       Bseek(&b, fp->symoff, 0);
-       memset(buf, 0, sizeof buf);
-       Bread(&b, buf, sizeof buf);
-       newformat = 0;
-       symsz = fp->symsz;
-       if(memcmp(buf, "\xfd\xff\xff\xff\x00\x00\x00", 7) == 0) {
-               swav = leswav;
-               swal = leswal;
-               newformat = 1;
-       } else if(memcmp(buf, "\xff\xff\xff\xfd\x00\x00\x00", 7) == 0) {
-               newformat = 1;
-       } else if(memcmp(buf, "\xfe\xff\xff\xff\x00\x00", 6) == 0) {
-               // Table format used between Go 1.0 and Go 1.1:
-               // little-endian but otherwise same as the old Go 1.0 table.
-               // Not likely to be seen much in practice, but easy to handle.
-               swav = leswav;
-               swal = leswal;
-               Bseek(&b, fp->symoff+6, 0);
-               symsz -= 6;
-       } else {
-               Bseek(&b, fp->symoff, 0);
-       }
-       svalsz = 0;
-       if(newformat) {
-               svalsz = buf[7];
-               if(svalsz != 4 && svalsz != 8) {
-                       werrstr("invalid word size %d bytes", svalsz);
-                       return -1;
-               }
-               symsz -= 8;
-       }
-
-       nsym = 0;
-       size = 0;
-       for(p = symbols; size < symsz; p++, nsym++) {
-               if(newformat) {
-                       // Go 1.1 format. See comment at top of ../pkg/runtime/symtab.c.
-                       if(Bread(&b, &c, 1) != 1)
-                               return symerrmsg(1, "symbol");
-                       if((c&0x3F) < 26)
-                               p->type = (c&0x3F)+ 'A';
-                       else
-                               p->type = (c&0x3F) - 26 + 'a';
-                       size++;
-
-                       if(c&0x40) {
-                               // Fixed-width address.
-                               if(svalsz == 8) {
-                                       if(Bread(&b, &vl, 8) != 8)
-                                               return symerrmsg(8, "symbol");
-                                       p->value = swav(vl);
-                               } else {
-                                       if(Bread(&b, &l, 4) != 4)
-                                               return symerrmsg(4, "symbol");
-                                       p->value = (u32int)swal(l);
-                               }
-                               size += svalsz;
-                       } else {
-                               // Varint address.
-                               shift = 0;
-                               p->value = 0;
-                               for(;;) {
-                                       if(Bread(&b, buf, 1) != 1)
-                                               return symerrmsg(1, "symbol");
-                                       p->value |= (uint64)(buf[0]&0x7F)<<shift;
-                                       shift += 7;
-                                       size++;
-                                       if((buf[0]&0x80) == 0)
-                                               break;
-                               }
-                       }
-                       p->gotype = 0;
-                       if(c&0x80) {
-                               // Has Go type. Fixed-width address.
-                               if(svalsz == 8) {
-                                       if(Bread(&b, &vl, 8) != 8)
-                                               return symerrmsg(8, "symbol");
-                                       p->gotype = swav(vl);
-                               } else {
-                                       if(Bread(&b, &l, 4) != 4)
-                                               return symerrmsg(4, "symbol");
-                                       p->gotype = (u32int)swal(l);
-                               }
-                               size += svalsz;
-                       }
-                       
-                       // Name.
-                       p->type |= 0x80; // for decodename
-                       i = decodename(&b, p);
-                       if(i < 0)
-                               return -1;
-                       size += i;
-               } else {
-                       // Go 1.0 format: Plan 9 format + go type symbol.
-                       if(fp->_magic && (fp->magic & HDR_MAGIC)){
-                               svalsz = 8;
-                               if(Bread(&b, &vl, 8) != 8)
-                                       return symerrmsg(8, "symbol");
-                               p->value = swav(vl);
-                       }
-                       else{
-                               svalsz = 4;
-                               if(Bread(&b, &l, 4) != 4)
-                                       return symerrmsg(4, "symbol");
-                               p->value = (u32int)swal(l);
-                       }
-                       if(Bread(&b, &p->type, sizeof(p->type)) != sizeof(p->type))
-                               return symerrmsg(sizeof(p->value), "symbol");
-       
-                       i = decodename(&b, p);
-                       if(i < 0)
-                               return -1;
-                       size += i+svalsz+sizeof(p->type);
-       
-                       if(svalsz == 8){
-                               if(Bread(&b, &vl, 8) != 8)
-                                       return symerrmsg(8, "symbol");
-                               p->gotype = swav(vl);
-                       }
-                       else{
-                               if(Bread(&b, &l, 4) != 4)
-                                       return symerrmsg(4, "symbol");
-                               p->gotype = (u32int)swal(l);
-                       }
-                       size += svalsz;
-               }
-
-               /* count global & auto vars, text symbols, and file names */
-               switch (p->type) {
-               case 'l':
-               case 'L':
-               case 't':
-               case 'T':
-                       ntxt++;
-                       break;
-               case 'd':
-               case 'D':
-               case 'b':
-               case 'B':
-                       nglob++;
-                       break;
-               case 'f':
-                       if(strcmp(p->name, ".frame") == 0) {
-                               p->type = 'm';
-                               nauto++;
-                       }
-                       else if(p->value > fmaxi)
-                               fmaxi = p->value;       /* highest path index */
-                       break;
-               case 'a':
-               case 'p':
-               case 'm':
-                       nauto++;
-                       break;
-               case 'z':
-                       if(p->value == 1) {             /* one extra per file */
-                               nhist++;
-                               nfiles++;
-                       }
-                       nhist++;
-                       break;
-               default:
-                       break;
-               }
-       }
-       if (debug)
-               print("NG: %d NT: %d NF: %d\n", nglob, ntxt, fmaxi);
-       if (fp->sppcsz) {                       /* pc-sp offset table */
-               spoff = (uchar *)malloc(fp->sppcsz);
-               if(spoff == 0) {
-                       werrstr("can't malloc %d bytes", fp->sppcsz);
-                       return -1;
-               }
-               Bseek(&b, fp->sppcoff, 0);
-               if(Bread(&b, spoff, fp->sppcsz) != fp->sppcsz){
-                       spoff = 0;
-                       return symerrmsg(fp->sppcsz, "sp-pc");
-               }
-               spoffend = spoff+fp->sppcsz;
-       }
-       if (fp->lnpcsz) {                       /* pc-line number table */
-               pcline = (uchar *)malloc(fp->lnpcsz);
-               if(pcline == 0) {
-                       werrstr("can't malloc %d bytes", fp->lnpcsz);
-                       return -1;
-               }
-               Bseek(&b, fp->lnpcoff, 0);
-               if(Bread(&b, pcline, fp->lnpcsz) != fp->lnpcsz){
-                       pcline = 0;
-                       return symerrmsg(fp->lnpcsz, "pc-line");
-               }
-               pclineend = pcline+fp->lnpcsz;
-       }
-       return nsym;
-}
-
-static int
-symerrmsg(int n, char *table)
-{
-       werrstr("can't read %d bytes of %s table", n, table);
-       return -1;
-}
-
-static int32
-decodename(Biobuf *bp, Sym *p)
-{
-       char *cp;
-       int c1, c2;
-       int32 n;
-       vlong o;
-
-       if((p->type & 0x80) == 0) {             /* old-style, fixed length names */
-               p->name = malloc(NNAME);
-               if(p->name == 0) {
-                       werrstr("can't malloc %d bytes", NNAME);
-                       return -1;
-               }
-               if(Bread(bp, p->name, NNAME) != NNAME)
-                       return symerrmsg(NNAME, "symbol");
-               Bseek(bp, 3, 1);
-               return NNAME+3;
-       }
-
-       p->type &= ~0x80;
-       if(p->type == 'z' || p->type == 'Z') {
-               o = Bseek(bp, 0, 1);
-               if(BGETC(bp) < 0) {
-                       werrstr("can't read symbol name");
-                       return -1;
-               }
-               for(;;) {
-                       c1 = BGETC(bp);
-                       c2 = BGETC(bp);
-                       if(c1 < 0 || c2 < 0) {
-                               werrstr("can't read symbol name");
-                               return -1;
-                       }
-                       if(c1 == 0 && c2 == 0)
-                               break;
-               }
-               n = Bseek(bp, 0, 1)-o;
-               p->name = malloc(n);
-               if(p->name == 0) {
-                       werrstr("can't malloc %d bytes", n);
-                       return -1;
-               }
-               Bseek(bp, -n, 1);
-               if(Bread(bp, p->name, n) != n) {
-                       werrstr("can't read %d bytes of symbol name", n);
-                       return -1;
-               }
-       } else {
-               cp = Brdline(bp, '\0');
-               if(cp == 0) {
-                       werrstr("can't read symbol name");
-                       return -1;
-               }
-               n = Blinelen(bp);
-               p->name = malloc(n);
-               if(p->name == 0) {
-                       werrstr("can't malloc %d bytes", n);
-                       return -1;
-               }
-               strcpy(p->name, cp);
-       }
-       return n;
-}
-
-/*
- *     free any previously loaded symbol tables
- */
-static void
-cleansyms(void)
-{
-       if(globals)
-               free(globals);
-       globals = 0;
-       nglob = 0;
-       if(txt)
-               free(txt);
-       txt = 0;
-       ntxt = 0;
-       if(fnames)
-               free(fnames);
-       fnames = 0;
-       fmaxi = 0;
-
-       if(files)
-               free(files);
-       files = 0;
-       nfiles = 0;
-       if(hist)
-               free(hist);
-       hist = 0;
-       nhist = 0;
-       if(autos)
-               free(autos);
-       autos = 0;
-       nauto = 0;
-       isbuilt = 0;
-       if(symbols)
-               free(symbols);
-       symbols = 0;
-       nsym = 0;
-       if(spoff)
-               free(spoff);
-       spoff = 0;
-       if(pcline)
-               free(pcline);
-       pcline = 0;
-       go12clean();
-}
-
-/*
- *     delimit the text segment
- */
-void
-textseg(uvlong base, Fhdr *fp)
-{
-       txtstart = base;
-       txtend = base+fp->txtsz;
-}
-
-/*
- *     symbase: return base and size of raw symbol table
- *             (special hack for high access rate operations)
- */
-Sym *
-symbase(int32 *n)
-{
-       *n = nsym;
-       return symbols;
-}
-
-/*
- *     Get the ith symbol table entry
- */
-Sym *
-getsym(int index)
-{
-       if(index >= 0 && index < nsym)
-               return &symbols[index];
-       return 0;
-}
-
-/*
- *     initialize internal symbol tables
- */
-static int
-buildtbls(void)
-{
-       int32 i;
-       int j, nh, ng, nt;
-       File *f;
-       Txtsym *tp;
-       Hist *hp;
-       Sym *p, **ap;
-
-       if(isbuilt)
-               return 1;
-       isbuilt = 1;
-                       /* allocate the tables */
-       firstinstr = 0;
-       if(nglob) {
-               globals = malloc(nglob*sizeof(*globals));
-               if(!globals) {
-                       werrstr("can't malloc global symbol table");
-                       return 0;
-               }
-       }
-       if(ntxt) {
-               txt = malloc(ntxt*sizeof(*txt));
-               if (!txt) {
-                       werrstr("can't malloc text symbol table");
-                       return 0;
-               }
-       }
-       fnames = malloc((fmaxi+1)*sizeof(*fnames));
-       if (!fnames) {
-               werrstr("can't malloc file name table");
-               return 0;
-       }
-       memset(fnames, 0, (fmaxi+1)*sizeof(*fnames));
-       files = malloc(nfiles*sizeof(*files));
-       if(!files) {
-               werrstr("can't malloc file table");
-               return 0;
-       }
-       hist = malloc(nhist*sizeof(Hist));
-       if(hist == 0) {
-               werrstr("can't malloc history stack");
-               return 0;
-       }
-       autos = malloc(nauto*sizeof(Sym*));
-       if(autos == 0) {
-               werrstr("can't malloc auto symbol table");
-               return 0;
-       }
-               /* load the tables */
-       ng = nt = nh = 0;
-       f = 0;
-       tp = 0;
-       i = nsym;
-       hp = hist;
-       ap = autos;
-       for(p = symbols; i-- > 0; p++) {
-//print("sym %d type %c name %s value %llux\n", p-symbols, p->type, p->name, p->value);
-               switch(p->type) {
-               case 'D':
-               case 'd':
-               case 'B':
-               case 'b':
-                       if(debug)
-                               print("Global: %s %llux\n", p->name, p->value);
-                       globals[ng++] = p;
-                       break;
-               case 'z':
-                       if(p->value == 1) {             /* New file */
-                               if(f) {
-                                       f->n = nh;
-                                       f->hist[nh].name = 0;   /* one extra */
-                                       hp += nh+1;
-                                       f++;
-                               }
-                               else
-                                       f = files;
-                               f->hist = hp;
-                               f->sym = 0;
-                               f->addr = 0;
-                               nh = 0;
-                       }
-                               /* alloc one slot extra as terminator */
-                       f->hist[nh].name = p->name;
-                       f->hist[nh].line = p->value;
-                       f->hist[nh].offset = 0;
-                       if(debug)
-                               printhist("-> ", &f->hist[nh], 1);
-                       nh++;
-                       break;
-               case 'Z':
-                       if(f && nh > 0)
-                               f->hist[nh-1].offset = p->value;
-                       break;
-               case 'T':
-               case 't':       /* Text: terminate history if first in file */
-               case 'L':
-               case 'l':
-                       tp = &txt[nt++];
-                       tp->n = 0;
-                       tp->sym = p;
-                       tp->locals = ap;
-                       if(debug)
-                               print("TEXT: %s at %llux\n", p->name, p->value);
-                       if (firstinstr == 0 || p->value < firstinstr)
-                               firstinstr = p->value;
-                       if(f && !f->sym) {                      /* first  */
-                               f->sym = p;
-                               f->addr = p->value;
-                       }
-                       break;
-               case 'a':
-               case 'p':
-               case 'm':               /* Local Vars */
-                       if(!tp)
-                               print("Warning: Free floating local var: %s\n",
-                                       p->name);
-                       else {
-                               if(debug)
-                                       print("Local: %s %llux\n", p->name, p->value);
-                               tp->locals[tp->n] = p;
-                               tp->n++;
-                               ap++;
-                       }
-                       break;
-               case 'f':               /* File names */
-                       if(debug)
-                               print("Fname: %s\n", p->name);
-                       fnames[p->value] = p;
-                       break;
-               default:
-                       break;
-               }
-       }
-               /* sort global and text tables into ascending address order */
-       qsort(globals, nglob, sizeof(Sym*), symcomp);
-       qsort(txt, ntxt, sizeof(Txtsym), txtcomp);
-       qsort(files, nfiles, sizeof(File), filecomp);
-       tp = txt;
-       for(i = 0, f = files; i < nfiles; i++, f++) {
-               for(j = 0; j < ntxt; j++) {
-                       if(f->sym == tp->sym) {
-                               if(debug) {
-                                       print("LINK: %s to at %llux", f->sym->name, f->addr);
-                                       printhist("... ", f->hist, 1);
-                               }
-                               f->txt = tp++;
-                               break;
-                       }
-                       if(++tp >= txt+ntxt)    /* wrap around */
-                               tp = txt;
-               }
-       }
-       return 1;
-}
-
-/*
- * find symbol function.var by name.
- *     fn != 0 && var != 0     => look for fn in text, var in data
- *     fn != 0 && var == 0     => look for fn in text
- *     fn == 0 && var != 0     => look for var first in text then in data space.
- */
-int
-lookup(char *fn, char *var, Symbol *s)
-{
-       int found;
-
-       if(buildtbls() == 0)
-               return 0;
-       if(fn) {
-               found = findtext(fn, s);
-               if(var == 0)            /* case 2: fn not in text */
-                       return found;
-               else if(!found)         /* case 1: fn not found */
-                       return 0;
-       } else if(var) {
-               found = findtext(var, s);
-               if(found)
-                       return 1;       /* case 3: var found in text */
-       } else return 0;                /* case 4: fn & var == zero */
-
-       if(found)
-               return findlocal(s, var, s);    /* case 1: fn found */
-       return findglobal(var, s);              /* case 3: var not found */
-
-}
-
-/*
- * strcmp, but allow '_' to match center dot (rune 00b7 == bytes c2 b7)
- */
-int
-cdotstrcmp(char *sym, char *user)
-{
-       for (;;) {
-               while (*sym == *user) {
-                       if (*sym++ == '\0')
-                               return 0;
-                       user++;
-               }
-               /* unequal - but maybe '_' matches center dot */
-               if (user[0] == '_' && (sym[0]&0xFF) == 0xc2 && (sym[1]&0xFF) == 0xb7) {
-                       /* '_' matches center dot - advance and continue */
-                       user++;
-                       sym += 2;
-                       continue;
-               }
-               break;
-       }
-       return *user - *sym;
-}
-
-/*
- * find a function by name
- */
-static int
-findtext(char *name, Symbol *s)
-{
-       int i;
-
-       for(i = 0; i < ntxt; i++) {
-               if(cdotstrcmp(txt[i].sym->name, name) == 0) {
-                       fillsym(txt[i].sym, s);
-                       s->handle = (void *) &txt[i];
-                       s->index = i;
-                       return 1;
-               }
-       }
-       return 0;
-}
-/*
- * find global variable by name
- */
-static int
-findglobal(char *name, Symbol *s)
-{
-       int32 i;
-
-       for(i = 0; i < nglob; i++) {
-               if(cdotstrcmp(globals[i]->name, name) == 0) {
-                       fillsym(globals[i], s);
-                       s->index = i;
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-/*
- *     find the local variable by name within a given function
- */
-int
-findlocal(Symbol *s1, char *name, Symbol *s2)
-{
-       if(s1 == 0)
-               return 0;
-       if(buildtbls() == 0)
-               return 0;
-       return findlocvar(s1, name, s2);
-}
-
-/*
- *     find the local variable by name within a given function
- *             (internal function - does no parameter validation)
- */
-static int
-findlocvar(Symbol *s1, char *name, Symbol *s2)
-{
-       Txtsym *tp;
-       int i;
-
-       tp = (Txtsym *)s1->handle;
-       if(tp && tp->locals) {
-               for(i = 0; i < tp->n; i++)
-                       if (cdotstrcmp(tp->locals[i]->name, name) == 0) {
-                               fillsym(tp->locals[i], s2);
-                               s2->handle = (void *)tp;
-                               s2->index = tp->n-1 - i;
-                               return 1;
-                       }
-       }
-       return 0;
-}
-
-/*
- *     Get ith text symbol
- */
-int
-textsym(Symbol *s, int index)
-{
-
-       if(buildtbls() == 0)
-               return 0;
-       if(index < 0 || index >= ntxt)
-               return 0;
-       fillsym(txt[index].sym, s);
-       s->handle = (void *)&txt[index];
-       s->index = index;
-       return 1;
-}
-
-/*
- *     Get ith file name
- */
-int
-filesym(int index, char *buf, int n)
-{
-       Hist *hp;
-
-       if(buildtbls() == 0)
-               return 0;
-       if(index < 0 || index >= nfiles)
-               return 0;
-       hp = files[index].hist;
-       if(!hp || !hp->name)
-               return 0;
-       return fileelem(fnames, (uchar*)hp->name, buf, n);
-}
-
-/*
- *     Lookup name of local variable located at an offset into the frame.
- *     The type selects either a parameter or automatic.
- */
-int
-getauto(Symbol *s1, int off, int type, Symbol *s2)
-{
-       Txtsym *tp;
-       Sym *p;
-       int i, t;
-
-       if(s1 == 0)
-               return 0;
-       if(type == CPARAM)
-               t = 'p';
-       else if(type == CAUTO)
-               t = 'a';
-       else
-               return 0;
-       if(buildtbls() == 0)
-               return 0;
-       tp = (Txtsym *)s1->handle;
-       if(tp == 0)
-               return 0;
-       for(i = 0; i < tp->n; i++) {
-               p = tp->locals[i];
-               if(p->type == t && p->value == off) {
-                       fillsym(p, s2);
-                       s2->handle = s1->handle;
-                       s2->index = tp->n-1 - i;
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-/*
- * Find text symbol containing addr; binary search assumes text array is sorted by addr
- */
-static int
-srchtext(uvlong addr)
-{
-       uvlong val;
-       int top, bot, mid;
-       Sym *sp;
-
-       val = addr;
-       bot = 0;
-       top = ntxt;
-       for (mid = (bot+top)/2; mid < top; mid = (bot+top)/2) {
-               sp = txt[mid].sym;
-               if(val < sp->value)
-                       top = mid;
-               else if(mid != ntxt-1 && val >= txt[mid+1].sym->value)
-                       bot = mid;
-               else
-                       return mid;
-       }
-       return -1;
-}
-
-/*
- * Find data symbol containing addr; binary search assumes data array is sorted by addr
- */
-static int
-srchdata(uvlong addr)
-{
-       uvlong val;
-       int top, bot, mid;
-       Sym *sp;
-
-       bot = 0;
-       top = nglob;
-       val = addr;
-       for(mid = (bot+top)/2; mid < top; mid = (bot+top)/2) {
-               sp = globals[mid];
-               if(val < sp->value)
-                       top = mid;
-               else if(mid < nglob-1 && val >= globals[mid+1]->value)
-                       bot = mid;
-               else
-                       return mid;
-       }
-       return -1;
-}
-
-/*
- * Find symbol containing val in specified search space
- * There is a special case when a value falls beyond the end
- * of the text segment; if the search space is CTEXT, that value
- * (usually etext) is returned.  If the search space is CANY, symbols in the
- * data space are searched for a match.
- */
-int
-findsym(uvlong val, int type, Symbol *s)
-{
-       int i;
-
-       if(buildtbls() == 0)
-               return 0;
-
-       if(type == CTEXT || type == CANY) {
-               i = srchtext(val);
-               if(i >= 0) {
-                       if(type == CTEXT || i != ntxt-1) {
-                               fillsym(txt[i].sym, s);
-                               s->handle = (void *) &txt[i];
-                               s->index = i;
-                               return 1;
-                       }
-               }
-       }
-       if(type == CDATA || type == CANY) {
-               i = srchdata(val);
-               if(i >= 0) {
-                       fillsym(globals[i], s);
-                       s->index = i;
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-/*
- *     Find the start and end address of the function containing addr
- */
-int
-fnbound(uvlong addr, uvlong *bounds)
-{
-       int i;
-
-       if(buildtbls() == 0)
-               return 0;
-
-       i = srchtext(addr);
-       if(0 <= i && i < ntxt-1) {
-               bounds[0] = txt[i].sym->value;
-               bounds[1] = txt[i+1].sym->value;
-               return 1;
-       }
-       return 0;
-}
-
-/*
- * get the ith local symbol for a function
- * the input symbol table is reverse ordered, so we reverse
- * accesses here to maintain approx. parameter ordering in a stack trace.
- */
-int
-localsym(Symbol *s, int index)
-{
-       Txtsym *tp;
-
-       if(s == 0 || index < 0)
-               return 0;
-       if(buildtbls() == 0)
-               return 0;
-
-       tp = (Txtsym *)s->handle;
-       if(tp && tp->locals && index < tp->n) {
-               fillsym(tp->locals[tp->n-index-1], s);  /* reverse */
-               s->handle = (void *)tp;
-               s->index = index;
-               return 1;
-       }
-       return 0;
-}
-
-/*
- * get the ith global symbol
- */
-int
-globalsym(Symbol *s, int index)
-{
-       if(s == 0)
-               return 0;
-       if(buildtbls() == 0)
-               return 0;
-
-       if(index >=0 && index < nglob) {
-               fillsym(globals[index], s);
-               s->index = index;
-               return 1;
-       }
-       return 0;
-}
-
-/*
- *     find the pc given a file name and line offset into it.
- */
-uvlong
-file2pc(char *file, int32 line)
-{
-       File *fp;
-       int32 i;
-       uvlong pc, start, end;
-       short *name;
-
-       if(isgo12pcline())
-               return go12file2pc(file, line);
-       if(buildtbls() == 0 || files == 0)
-               return ~(uvlong)0;
-       name = encfname(file);
-       if(name == 0) {                 /* encode the file name */
-               werrstr("file %s not found", file);
-               return ~(uvlong)0;
-       }
-               /* find this history stack */
-       for(i = 0, fp = files; i < nfiles; i++, fp++)
-               if (hline(fp, name, &line))
-                       break;
-       free(name);
-       if(i >= nfiles) {
-               werrstr("line %d in file %s not found", line, file);
-               return ~(uvlong)0;
-       }
-       start = fp->addr;               /* first text addr this file */
-       if(i < nfiles-1)
-               end = (fp+1)->addr;     /* first text addr next file */
-       else
-               end = 0;                /* last file in load module */
-       /*
-        * At this point, line contains the offset into the file.
-        * run the state machine to locate the pc closest to that value.
-        */
-       if(debug)
-               print("find pc for %d - between: %llux and %llux\n", line, start, end);
-       pc = line2addr(line, start, end);
-       if(pc == ~(uvlong)0) {
-               werrstr("line %d not in file %s", line, file);
-               return ~(uvlong)0;
-       }
-       return pc;
-}
-
-/*
- *     search for a path component index
- */
-static int
-pathcomp(char *s, int n)
-{
-       int i;
-
-       for(i = 0; i <= fmaxi; i++)
-               if(fnames[i] && strncmp(s, fnames[i]->name, n) == 0)
-                       return i;
-       return -1;
-}
-
-/*
- *     Encode a char file name as a sequence of short indices
- *     into the file name dictionary.
- */
-static short*
-encfname(char *file)
-{
-       int i, j;
-       char *cp, *cp2;
-       short *dest;
-
-       if(*file == '/')        /* always check first '/' */
-               cp2 = file+1;
-       else {
-               cp2 = strchr(file, '/');
-               if(!cp2)
-                       cp2 = strchr(file, 0);
-       }
-       cp = file;
-       dest = 0;
-       for(i = 0; *cp; i++) {
-               j = pathcomp(cp, cp2-cp);
-               if(j < 0)
-                       return 0;       /* not found */
-               dest = realloc(dest, (i+1)*sizeof(short));
-               dest[i] = j;
-               cp = cp2;
-               while(*cp == '/')       /* skip embedded '/'s */
-                       cp++;
-               cp2 = strchr(cp, '/');
-               if(!cp2)
-                       cp2 = strchr(cp, 0);
-       }
-       dest = realloc(dest, (i+1)*sizeof(short));
-       dest[i] = 0;
-       return dest;
-}
-
-/*
- *     Search a history stack for a matching file name accumulating
- *     the size of intervening files in the stack.
- */
-static int
-hline(File *fp, short *name, int32 *line)
-{
-       Hist *hp;
-       int offset, depth;
-       int32 ln;
-
-       for(hp = fp->hist; hp->name; hp++)              /* find name in stack */
-               if(hp->name[1] || hp->name[2]) {
-                       if(hcomp(hp, name))
-                               break;
-               }
-       if(!hp->name)           /* match not found */
-               return 0;
-       if(debug)
-               printhist("hline found ... ", hp, 1);
-       /*
-        * unwind the stack until empty or we hit an entry beyond our line
-        */
-       ln = *line;
-       offset = hp->line-1;
-       depth = 1;
-       for(hp++; depth && hp->name; hp++) {
-               if(debug)
-                       printhist("hline inspect ... ", hp, 1);
-               if(hp->name[1] || hp->name[2]) {
-                       if(hp->offset){                 /* Z record */
-                               offset = 0;
-                               if(hcomp(hp, name)) {
-                                       if(*line <= hp->offset)
-                                               break;
-                                       ln = *line+hp->line-hp->offset;
-                                       depth = 1;      /* implicit pop */
-                               } else
-                                       depth = 2;      /* implicit push */
-                       } else if(depth == 1 && ln < hp->line-offset)
-                                       break;          /* Beyond our line */
-                       else if(depth++ == 1)           /* push */
-                               offset -= hp->line;
-               } else if(--depth == 1)         /* pop */
-                       offset += hp->line;
-       }
-       *line = ln+offset;
-       return 1;
-}
-
-/*
- *     compare two encoded file names
- */
-static int
-hcomp(Hist *hp, short *sp)
-{
-       uchar *cp;
-       int i, j;
-       short *s;
-
-       cp = (uchar *)hp->name;
-       s = sp;
-       if (*s == 0)
-               return 0;
-       for (i = 1; j = (cp[i]<<8)|cp[i+1]; i += 2) {
-               if(j == 0)
-                       break;
-               if(*s == j)
-                       s++;
-               else
-                       s = sp;
-       }
-       return *s == 0;
-}
-
-/*
- *     Convert a pc to a "file:line {file:line}" string.
- */
-int32
-fileline(char *str, int n, uvlong dot)
-{
-       int32 line, top, bot, mid;
-       File *f;
-
-       if(isgo12pcline())
-               return go12fileline(str, n, dot);
-
-       *str = 0;
-       if(buildtbls() == 0)
-               return 0;
-               /* binary search assumes file list is sorted by addr */
-       bot = 0;
-       top = nfiles;
-       for (mid = (bot+top)/2; mid < top; mid = (bot+top)/2) {
-               f = &files[mid];
-               if(dot < f->addr)
-                       top = mid;
-               else if(mid < nfiles-1 && dot >= (f+1)->addr)
-                       bot = mid;
-               else {
-                       line = pc2line(dot);
-                       if(line > 0 && fline(str, n, line, f->hist, 0) >= 0)
-                               return 1;
-                       break;
-               }
-       }
-       return 0;
-}
-
-/*
- *     Convert a line number within a composite file to relative line
- *     number in a source file.  A composite file is the source
- *     file with included files inserted in line.
- */
-static int
-fline(char *str, int n, int32 line, Hist *base, Hist **ret)
-{
-       Hist *start;                    /* start of current level */
-       Hist *h;                        /* current entry */
-       int32 delta;                    /* sum of size of files this level */
-       int k;
-
-       start = base;
-       h = base;
-       delta = h->line;
-       while(h && h->name && line > h->line) {
-               if(h->name[1] || h->name[2]) {
-                       if(h->offset != 0) {    /* #line Directive */
-                               delta = h->line-h->offset+1;
-                               start = h;
-                               base = h++;
-                       } else {                /* beginning of File */
-                               if(start == base)
-                                       start = h++;
-                               else {
-                                       k = fline(str, n, line, start, &h);
-                                       if(k <= 0)
-                                               return k;
-                               }
-                       }
-               } else {
-                       if(start == base && ret) {      /* end of recursion level */
-                               *ret = h;
-                               return 1;
-                       } else {                        /* end of included file */
-                               delta += h->line-start->line;
-                               h++;
-                               start = base;
-                       }
-               }
-       }
-       if(!h)
-               return -1;
-       if(start != base)
-               line = line-start->line+1;
-       else
-               line = line-delta+1;
-       if(!h->name)
-               strncpy(str, "<eof>", n);
-       else {
-               k = fileelem(fnames, (uchar*)start->name, str, n);
-               if(k+8 < n)
-                       sprint(str+k, ":%d", line);
-       }
-/**********Remove comments for complete back-trace of include sequence
- *     if(start != base) {
- *             k = strlen(str);
- *             if(k+2 < n) {
- *                     str[k++] = ' ';
- *                     str[k++] = '{';
- *             }
- *             k += fileelem(fnames, (uchar*) base->name, str+k, n-k);
- *             if(k+10 < n)
- *                     sprint(str+k, ":%ld}", start->line-delta);
- *     }
- ********************/
-       return 0;
-}
-
-/*
- *     convert an encoded file name to a string.
- */
-int
-fileelem(Sym **fp, uchar *cp, char *buf, int n)
-{
-       int i, j;
-       char *c, *bp, *end;
-
-       bp = buf;
-       end = buf+n-1;
-       for(i = 1; j = (cp[i]<<8)|cp[i+1]; i+=2){
-               c = fp[j]->name;
-               if(bp != buf && bp[-1] != '/' && bp < end)
-                       *bp++ = '/';
-               while(bp < end && *c)
-                       *bp++ = *c++;
-       }
-       *bp = 0;
-       i =  bp-buf;
-       if(i > 1) {
-               cleanname(buf);
-               i = strlen(buf);
-       }
-       return i;
-}
-
-/*
- *     compare the values of two symbol table entries.
- */
-static int
-symcomp(const void *a, const void *b)
-{
-       int i;
-
-       i = (*(Sym**)a)->value - (*(Sym**)b)->value;
-       if (i)
-               return i;
-       return strcmp((*(Sym**)a)->name, (*(Sym**)b)->name);
-}
-
-/*
- *     compare the values of the symbols referenced by two text table entries
- */
-static int
-txtcomp(const void *a, const void *b)
-{
-       return ((Txtsym*)a)->sym->value - ((Txtsym*)b)->sym->value;
-}
-
-/*
- *     compare the values of the symbols referenced by two file table entries
- */
-static int
-filecomp(const void *a, const void *b)
-{
-       return ((File*)a)->addr - ((File*)b)->addr;
-}
-
-/*
- *     fill an interface Symbol structure from a symbol table entry
- */
-static void
-fillsym(Sym *sp, Symbol *s)
-{
-       s->type = sp->type;
-       s->value = sp->value;
-       s->name = sp->name;
-       s->index = 0;
-       switch(sp->type) {
-       case 'b':
-       case 'B':
-       case 'D':
-       case 'd':
-               s->class = CDATA;
-               break;
-       case 't':
-       case 'T':
-       case 'l':
-       case 'L':
-               s->class = CTEXT;
-               break;
-       case 'a':
-               s->class = CAUTO;
-               break;
-       case 'p':
-               s->class = CPARAM;
-               break;
-       case 'm':
-               s->class = CSTAB;
-               break;
-       default:
-               s->class = CNONE;
-               break;
-       }
-       s->handle = 0;
-}
-
-/*
- *     find the stack frame, given the pc
- */
-uvlong
-pc2sp(uvlong pc)
-{
-       uchar *c, u;
-       uvlong currpc, currsp;
-
-       if(isgo12pcline())
-               return go12pc2sp(pc);
-
-       if(spoff == 0)
-               return ~(uvlong)0;
-       currsp = 0;
-       currpc = txtstart - mach->pcquant;
-
-       if(pc<currpc || pc>txtend)
-               return ~(uvlong)0;
-       for(c = spoff; c < spoffend; c++) {
-               if (currpc >= pc)
-                       return currsp;
-               u = *c;
-               if (u == 0) {
-                       currsp += (c[1]<<24)|(c[2]<<16)|(c[3]<<8)|c[4];
-                       c += 4;
-               }
-               else if (u < 65)
-                       currsp += 4*u;
-               else if (u < 129)
-                       currsp -= 4*(u-64);
-               else
-                       currpc += mach->pcquant*(u-129);
-               currpc += mach->pcquant;
-       }
-       return ~(uvlong)0;
-}
-
-/*
- *     find the source file line number for a given value of the pc
- */
-int32
-pc2line(uvlong pc)
-{
-       uchar *c, u;
-       uvlong currpc;
-       int32 currline;
-
-       if(pcline == 0)
-               return -1;
-       currline = 0;
-       if (firstinstr != 0)
-               currpc = firstinstr-mach->pcquant;
-       else
-               currpc = txtstart-mach->pcquant;
-       if(pc<currpc || pc>txtend)
-               return -1;
-
-       for(c = pcline; c < pclineend && currpc < pc; c++) {
-               u = *c;
-               if(u == 0) {
-                       currline += (c[1]<<24)|(c[2]<<16)|(c[3]<<8)|c[4];
-                       c += 4;
-               }
-               else if(u < 65)
-                       currline += u;
-               else if(u < 129)
-                       currline -= (u-64);
-               else
-                       currpc += mach->pcquant*(u-129);
-               currpc += mach->pcquant;
-       }
-       return currline;
-}
-
-/*
- *     find the pc associated with a line number
- *     basepc and endpc are text addresses bounding the search.
- *     if endpc == 0, the end of the table is used (i.e., no upper bound).
- *     usually, basepc and endpc contain the first text address in
- *     a file and the first text address in the following file, respectively.
- */
-uvlong
-line2addr(int32 line, uvlong basepc, uvlong endpc)
-{
-       uchar *c,  u;
-       uvlong currpc, pc;
-       int32 currline;
-       int32 delta, d;
-       int found;
-
-       if(pcline == 0 || line == 0)
-               return ~(uvlong)0;
-
-       currline = 0;
-       currpc = txtstart-mach->pcquant;
-       pc = ~(uvlong)0;
-       found = 0;
-       delta = HUGEINT;
-
-       for(c = pcline; c < pclineend; c++) {
-               if(endpc && currpc >= endpc)    /* end of file of interest */
-                       break;
-               if(currpc >= basepc) {          /* proper file */
-                       if(currline >= line) {
-                               d = currline-line;
-                               found = 1;
-                       } else
-                               d = line-currline;
-                       if(d < delta) {
-                               delta = d;
-                               pc = currpc;
-                       }
-               }
-               u = *c;
-               if(u == 0) {
-                       currline += (c[1]<<24)|(c[2]<<16)|(c[3]<<8)|c[4];
-                       c += 4;
-               }
-               else if(u < 65)
-                       currline += u;
-               else if(u < 129)
-                       currline -= (u-64);
-               else
-                       currpc += mach->pcquant*(u-129);
-               currpc += mach->pcquant;
-       }
-       if(found)
-               return pc;
-       return ~(uvlong)0;
-}
-
-/*
- *     Print a history stack (debug). if count is 0, prints the whole stack
- */
-static void
-printhist(char *msg, Hist *hp, int count)
-{
-       int i;
-       uchar *cp;
-       char buf[128];
-
-       i = 0;
-       while(hp->name) {
-               if(count && ++i > count)
-                       break;
-               print("%s Line: %x (%d)  Offset: %x (%d)  Name: ", msg,
-                       hp->line, hp->line, hp->offset, hp->offset);
-               for(cp = (uchar *)hp->name+1; (*cp<<8)|cp[1]; cp += 2) {
-                       if (cp != (uchar *)hp->name+1)
-                               print("/");
-                       print("%x", (*cp<<8)|cp[1]);
-               }
-               fileelem(fnames, (uchar *) hp->name, buf, sizeof(buf));
-               print(" (%s)\n", buf);
-               hp++;
-       }
-}
-
-#ifdef DEBUG
-/*
- *     print the history stack for a file. (debug only)
- *     if (name == 0) => print all history stacks.
- */
-void
-dumphist(char *name)
-{
-       int i;
-       File *f;
-       short *fname;
-
-       if(buildtbls() == 0)
-               return;
-       if(name)
-               fname = encfname(name);
-       for(i = 0, f = files; i < nfiles; i++, f++)
-               if(fname == 0 || hcomp(f->hist, fname))
-                       printhist("> ", f->hist, f->n);
-
-       if(fname)
-               free(fname);
-}
-#endif
-
-// Go 1.2 pcln table
-// See golang.org/s/go12symtab.
-
-// Func layout
-#define FuncEntry (0)
-#define FuncName (pcptrsize)
-#define FuncArgs (pcptrsize+4)
-#define FuncFrame (pcptrsize+2*4)
-#define FuncPCSP (pcptrsize+3*4)
-#define FuncPCFile (pcptrsize+4*4)
-#define FuncPCLine (pcptrsize+5*4)
-
-static int32 pcquantum;
-static int32 pcptrsize;
-static uvlong (*pcswav)(uvlong);
-static uint32 (*pcswal)(uint32);
-static uvlong (*pcuintptr)(uchar*);
-static uchar *functab;
-static uint32 nfunctab;
-static uint32 *filetab;
-static uint32 nfiletab;
-
-static uint32
-xswal(uint32 v)
-{
-       return (v>>24) | ((v>>8)&0xFF00) | ((v<<8)&0xFF0000) | v<<24;
-}
-
-static uvlong
-xswav(uvlong v)
-{
-       return (uvlong)xswal(v)<<32 | xswal(v>>32);
-}
-
-static uvlong
-noswav(uvlong v)
-{
-       return v;
-}
-
-static uint32
-noswal(uint32 v)
-{
-       return v;
-}
-
-static uvlong
-readuintptr64(uchar *p)
-{
-       return pcswav(*(uvlong*)p);
-}
-
-static uvlong
-readuintptr32(uchar *p)
-{
-       return pcswal(*(uint32*)p);
-}
-
-static void
-go12clean(void)
-{
-       pcquantum = 0;
-       pcswav = nil;
-       pcswal = nil;
-       functab = nil;
-       nfunctab = 0;
-       filetab = nil;
-       nfiletab = 0;
-}
-
-static void
-go12init(void)
-{
-       uint32 m;
-       uchar *p;
-
-       if(pcquantum != 0)
-               return;
-       pcquantum = -1; // not go 1.2
-       if(pcline == nil || pclineend - pcline < 16 ||
-               pcline[4] != 0 || pcline[5] != 0 ||
-               (pcline[6] != 1 && pcline[6] != 4) ||
-               (pcline[7] != 4 && pcline[7] != 8))
-               return;
-
-       // header is magic, 00 00 pcquantum ptrsize
-       m = *(uint32*)pcline;
-       if(m == Go12PclnMagic) {
-               pcswav = noswav;
-               pcswal = noswal;
-       } else {
-               pcswav = xswav;
-               pcswal = xswal;
-       }
-       pcptrsize = pcline[7];
-       
-       if(pcptrsize == 4)
-               pcuintptr = readuintptr32;
-       else
-               pcuintptr = readuintptr64;
-
-       nfunctab = pcuintptr(pcline+8);
-       functab = pcline + 8 + pcptrsize;
-       
-       // functab is 2*nfunctab pointer-sized values.
-       // The offset to the file table follows.
-       p = functab + nfunctab*2*pcptrsize + pcptrsize;
-       if(p+4 > pclineend)
-               return;
-       filetab = (uint32*)(pcline + pcswal(*(uint32*)p));
-       if((uchar*)filetab+4 > pclineend)
-               return;
-       
-       // File table begins with count.
-       nfiletab = pcswal(filetab[0]);
-       if((uchar*)(filetab + nfiletab) > pclineend)
-               return;
-
-       // Committed.
-       pcquantum = pcline[6];
-}
-
-static int
-isgo12pcline(void)
-{
-       go12init();
-       return pcquantum > 0;
-}
-
-static uchar*
-go12findfunc(uvlong pc)
-{
-       uchar *f, *fm;
-       int32 nf, m;
-
-       if(pc < pcuintptr(functab) || pc >= pcuintptr(functab+2*nfunctab*pcptrsize))
-               return nil;
-
-       // binary search to find func with entry <= addr.
-       f = functab;
-       nf = nfunctab;
-       while(nf > 0) {
-               m = nf/2;
-               fm = f + 2*pcptrsize*m;
-               if(pcuintptr(fm) <= pc && pc < pcuintptr(fm+2*pcptrsize)) {
-                       f = pcline + pcuintptr(fm+pcptrsize);
-                       if(f >= pclineend)
-                               return nil;
-                       return f;
-               } else if(pc < pcuintptr(fm))
-                       nf = m;
-               else {
-                       f += (m+1)*2*pcptrsize;
-                       nf -= m+1;
-               }
-       }
-       return nil;
-}
-
-static uint32
-readvarint(uchar **pp)
-{
-       uchar *p;
-       uint32 v;
-       int32 shift;
-       
-       v = 0;
-       p = *pp;
-       for(shift = 0;; shift += 7) {
-               v |= (*p & 0x7F) << shift;
-               if(!(*p++ & 0x80))
-                       break;
-       }
-       *pp = p;
-       return v;
-}
-
-static char*
-pcstring(uint32 off)
-{
-       if(off == 0 || off >= pclineend - pcline ||
-          memchr(pcline + off, '\0', pclineend - (pcline + off)) == nil)
-               return "?";
-       return (char*)pcline+off;
-}
-
-
-static int
-step(uchar **pp, uvlong *pc, int32 *value, int first)
-{
-       uint32 uvdelta, pcdelta;
-       int32 vdelta;
-
-       uvdelta = readvarint(pp);
-       if(uvdelta == 0 && !first)
-               return 0;
-       if(uvdelta&1)
-               uvdelta = ~(uvdelta>>1);
-       else
-               uvdelta >>= 1;
-       vdelta = (int32)uvdelta;
-       pcdelta = readvarint(pp) * pcquantum;
-       *value += vdelta;
-       *pc += pcdelta;
-       return 1;
-}
-
-static int32
-pcvalue(uint32 off, uvlong entry, uvlong targetpc)
-{
-       uvlong pc;
-       int32 val;
-       uchar *p;
-       
-       val = -1;
-       pc = entry;
-       if(off == 0 || off >= pclineend - pcline)
-               return -1;      
-       p = pcline + off;
-       while(step(&p, &pc, &val, pc == entry)) {
-               if(targetpc < pc)
-                       return val;
-       }
-       return -1;
-}
-
-static uvlong
-go12pc2sp(uvlong pc)
-{
-       uchar *f;
-       uint32 off;
-       uvlong entry;
-       int32 sp;
-
-       f = go12findfunc(pc);
-       if(f == nil)
-               return ~(uvlong)0;
-       entry = pcuintptr(f+FuncEntry);
-       off = pcswal(*(uint32*)(f+FuncPCSP));
-       sp = pcvalue(off, entry, pc);
-       if(sp < 0)
-               return ~(uvlong)0;
-       return sp;
-}
-
-static int32
-go12fileline(char *str, int n, uvlong pc)
-{
-       uchar *f;
-       uint32 fileoff, lineoff;
-       uvlong entry;
-       int lno, fno;
-
-       f = go12findfunc(pc);
-       if(f == nil)
-               return 0;
-       entry = pcuintptr(f+FuncEntry);
-       fileoff = pcswal(*(uint32*)(f+FuncPCFile));
-       lineoff = pcswal(*(uint32*)(f+FuncPCLine));
-       lno = pcvalue(lineoff, entry, pc);
-       fno = pcvalue(fileoff, entry, pc);
-       if(lno < 0 || fno <= 0 || fno >= nfiletab) {
-               return 0;
-       }
-       snprint(str, n, "%s:%d", pcstring(pcswal(filetab[fno])), lno);
-       return 1;
-}
-
-static uvlong
-go12file2pc(char *file, int line)
-{
-       int fno;
-       int32 i, fval, lval;
-       uchar *func, *fp, *lp;
-       uvlong fpc, lpc, fstartpc, lstartpc, entry;
-
-       // Map file to file number.
-       // NOTE(rsc): Could introduce a hash table for repeated
-       // lookups if anyone ever calls this.
-       for(fno=1; fno<nfiletab; fno++)
-               if(strcmp(pcstring(pcswal(filetab[fno])), file) == 0)
-                       goto havefile;
-       werrstr("cannot find file");
-       return ~(uvlong)0;
-
-havefile:
-       // Consider each func.
-       // Run file number program to find file match,
-       // then run line number program to find line match.
-       // Most file number programs are tiny, and most will
-       // not mention the file number, so this should be fairly
-       // quick.
-       for(i=0; i<nfunctab; i++) {
-               func = pcline + pcuintptr(functab+i*2*pcptrsize+pcptrsize);
-               entry = pcuintptr(func+FuncEntry);
-               fp = pcline + pcswal(*(uint32*)(func+FuncPCFile));
-               lp = pcline + pcswal(*(uint32*)(func+FuncPCLine));
-               fval = lval = -1;
-               lpc = entry;
-               fpc = lpc;
-               fstartpc = fpc;
-               while(step(&fp, &fpc, &fval, fpc==entry)) {
-                       if(fval == fno && fstartpc < fpc) {
-                               lstartpc = lpc;
-                               while(lpc < fpc && step(&lp, &lpc, &lval, lpc==entry)) {
-                                       if(lval == line) {
-                                               if(fstartpc <= lstartpc) {
-                                                       return lstartpc;
-                                               }
-                                               if(fstartpc < lpc) {
-                                                       return fstartpc;
-                                               }
-                                       }
-                                       lstartpc = lpc;
-                               }
-                       }
-                       fstartpc = fpc;
-               }
-       }
-       werrstr("cannot find line in file");
-       return ~(uvlong)0;
-}
diff --git a/src/libmach/windows.c b/src/libmach/windows.c
deleted file mode 100644 (file)
index 9ffc3af..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-// This is stubbed out for the moment. Will revisit when the time comes.
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mach.h>
-
-int
-ctlproc(int pid, char *msg)
-{
-       USED(pid);
-       USED(msg);
-       sysfatal("ctlproc unimplemented in Windows");
-       return -1;
-}
-
-char*
-proctextfile(int pid)
-{
-       USED(pid);
-       sysfatal("proctextfile unimplemented in Windows");
-       return nil;
-}
-
-char*
-procstatus(int pid)
-{
-       USED(pid);
-       sysfatal("procstatus unimplemented in Windows");
-       return nil;
-}
-
-Map*
-attachproc(int pid, Fhdr *fp)
-{
-       USED(pid);
-       USED(fp);
-       sysfatal("attachproc unimplemented in Windows");
-       return nil;
-}
-
-void
-detachproc(Map *m)
-{
-       USED(m);
-       sysfatal("detachproc unimplemented in Windows");
-}
-
-int
-procthreadpids(int pid, int *p, int np)
-{
-       USED(pid);
-       USED(p);
-       USED(np);
-       sysfatal("procthreadpids unimplemented in Windows");
-       return -1;
-}
-
-int 
-pread(int fd, void *buf, int count, int offset)
-{
-       int oldoffset, n;
-       
-       oldoffset = seek(fd, offset, 0);
-       n = read(fd, buf, count);
-       seek(fd, oldoffset, 0);
-       return n;
-}
-
-int 
-pwrite(int fd, void *buf, int count, int offset)
-{
-       USED(fd);
-       USED(buf);
-       USED(count);
-       USED(offset);
-       sysfatal("pwrite unimplemented in Windows");
-       return -1;
-}
-
-int 
-nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
-{
-       USED(rqtp);
-       USED(rmtp);
-       sysfatal("nanosleep unimplemented in Windows");
-       return -1;
-}