BSD 4_3_Net_2 development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Wed, 5 Jul 1989 05:47:00 +0000 (21:47 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Wed, 5 Jul 1989 05:47:00 +0000 (21:47 -0800)
Work on file usr/src/usr.bin/gdb/grot/munch
Work on file usr/src/usr.bin/gdb/config/npl-opcode.h
Work on file usr/src/usr.bin/gdb/obstack.c
Work on file usr/src/usr.bin/gdb/obstack.h
Work on file usr/src/usr.bin/gdb/config/pn-opcode.h
Work on file usr/src/usr.bin/gdb/regex.c
Work on file usr/src/usr.bin/gdb/regex.h
Work on file usr/src/usr.bin/gdb/grot/remote-sa.m68k.shar
Work on file usr/src/usr.bin/gdb/grot/standalone.c
Work on file usr/src/usr.bin/gdb/grot/stuff.c
Work on file usr/src/usr.bin/gdb/config/vax-opcode.h

Synthesized-from: CSRG/cd2/net.2

usr/src/usr.bin/gdb/config/npl-opcode.h [new file with mode: 0644]
usr/src/usr.bin/gdb/config/pn-opcode.h [new file with mode: 0644]
usr/src/usr.bin/gdb/config/vax-opcode.h [new file with mode: 0644]
usr/src/usr.bin/gdb/grot/munch [new file with mode: 0644]
usr/src/usr.bin/gdb/grot/remote-sa.m68k.shar [new file with mode: 0644]
usr/src/usr.bin/gdb/grot/standalone.c [new file with mode: 0644]
usr/src/usr.bin/gdb/grot/stuff.c [new file with mode: 0644]
usr/src/usr.bin/gdb/obstack.c [new file with mode: 0644]
usr/src/usr.bin/gdb/obstack.h [new file with mode: 0644]
usr/src/usr.bin/gdb/regex.c [new file with mode: 0644]
usr/src/usr.bin/gdb/regex.h [new file with mode: 0644]

diff --git a/usr/src/usr.bin/gdb/config/npl-opcode.h b/usr/src/usr.bin/gdb/config/npl-opcode.h
new file mode 100644 (file)
index 0000000..f18982b
--- /dev/null
@@ -0,0 +1,422 @@
+/* Print GOULD NPL instructions for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+struct gld_opcode
+{
+  char *name;
+  unsigned long opcode;
+  unsigned long mask;
+  char *args;
+  int length;
+};
+
+/* We store four bytes of opcode for all opcodes because that
+   is the most any of them need.  The actual length of an instruction
+   is always at least 2 bytes, and at most four.  The length of the
+   instruction is based on the opcode.
+
+   The mask component is a mask saying which bits must match
+   particular opcode in order for an instruction to be an instance
+   of that opcode.
+
+   The args component is a string containing characters
+   that are used to format the arguments to the instruction. */
+
+/* Kinds of operands:
+   r  Register in first field
+   R  Register in second field
+   b  Base register in first field
+   B  Base register in second field
+   v  Vector register in first field
+   V  Vector register in first field
+   A  Optional address register (base register)
+   X  Optional index register
+   I  Immediate data (16bits signed)
+   O  Offset field (16bits signed)
+   h  Offset field (15bits signed)
+   d  Offset field (14bits signed)
+   S  Shift count field
+
+   any other characters are printed as is...
+*/
+
+/* The assembler requires that this array be sorted as follows:
+   all instances of the same mnemonic must be consecutive.
+   All instances of the same mnemonic with the same number of operands
+   must be consecutive.
+ */
+struct gld_opcode gld_opcodes[] =
+{
+{ "lb",                0xb4080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lnb",       0xb8080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lbs",       0xec080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lh",                0xb4000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "lnh",       0xb8000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "lw",                0xb4000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lnw",       0xb8000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "ld",                0xb4000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "lnd",       0xb8000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "li",                0xf8000000,     0xfc7f0000,     "r,I",          4 },
+{ "lpa",       0x50080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "la",                0x50000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "labr",      0x58080000,     0xfc080000,     "b,xOA,X",      4 },
+{ "lbp",       0x90080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lhp",       0x90000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "lwp",       0x90000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "ldp",       0x90000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "suabr",     0x58000000,     0xfc080000,     "b,xOA,X",      4 },
+{ "lf",                0xbc000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lfbr",      0xbc080000,     0xfc080000,     "b,xOA,X",      4 },
+{ "lwbr",      0x5c000000,     0xfc080000,     "b,xOA,X",      4 },
+{ "stb",       0xd4080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "sth",       0xd4000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "stw",       0xd4000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "std",       0xd4000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "stf",       0xdc000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "stfbr",     0xdc080000,     0xfc080000,     "b,xOA,X",      4 },
+{ "stwbr",     0x54000000,     0xfc080000,     "b,xOA,X",      4 },
+{ "zmb",       0xd8080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "zmh",       0xd8000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "zmw",       0xd8000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "zmd",       0xd8000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "stbp",      0x94080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "sthp",      0x94000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "stwp",      0x94000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "stdp",      0x94000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "lil",       0xf8080000,     0xfc7f0000,     "r,D",          4 },
+{ "lwsl1",     0xec000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lwsl2",     0xfc000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lwsl3",     0xfc080000,     0xfc080000,     "r,xOA,X",      4 },
+
+{ "lvb",       0xb0080000,     0xfc080000,     "v,xOA,X",      4 },
+{ "lvh",       0xb0000001,     0xfc080001,     "v,xOA,X",      4 },
+{ "lvw",       0xb0000000,     0xfc080000,     "v,xOA,X",      4 },
+{ "lvd",       0xb0000002,     0xfc080002,     "v,xOA,X",      4 },
+{ "liv",       0x3c040000,     0xfc0f0000,     "v,R",          2 },
+{ "livf",      0x3c080000,     0xfc0f0000,     "v,R",          2 },
+{ "stvb",      0xd0080000,     0xfc080000,     "v,xOA,X",      4 },
+{ "stvh",      0xd0000001,     0xfc080001,     "v,xOA,X",      4 },
+{ "stvw",      0xd0000000,     0xfc080000,     "v,xOA,X",      4 },
+{ "stvd",      0xd0000002,     0xfc080002,     "v,xOA,X",      4 },
+
+{ "trr",       0x2c000000,     0xfc0f0000,     "r,R",          2 },
+{ "trn",       0x2c040000,     0xfc0f0000,     "r,R",          2 },
+{ "trnd",      0x2c0c0000,     0xfc0f0000,     "r,R",          2 },
+{ "trabs",     0x2c010000,     0xfc0f0000,     "r,R",          2 },
+{ "trabsd",    0x2c090000,     0xfc0f0000,     "r,R",          2 },
+{ "trc",       0x2c030000,     0xfc0f0000,     "r,R",          2 },
+{ "xcr",       0x28040000,     0xfc0f0000,     "r,R",          2 },
+{ "cxcr",      0x2c060000,     0xfc0f0000,     "r,R",          2 },
+{ "cxcrd",     0x2c0e0000,     0xfc0f0000,     "r,R",          2 },
+{ "tbrr",      0x2c020000,     0xfc0f0000,     "r,B",          2 },
+{ "trbr",      0x28030000,     0xfc0f0000,     "b,R",          2 },
+{ "xcbr",      0x28020000,     0xfc0f0000,     "b,B",          2 },
+{ "tbrbr",     0x28010000,     0xfc0f0000,     "b,B",          2 },
+
+{ "trvv",      0x28050000,     0xfc0f0000,     "v,V",          2 },
+{ "trvvn",     0x2c050000,     0xfc0f0000,     "v,V",          2 },
+{ "trvvnd",    0x2c0d0000,     0xfc0f0000,     "v,V",          2 },
+{ "trvab",     0x2c070000,     0xfc0f0000,     "v,V",          2 },
+{ "trvabd",    0x2c0f0000,     0xfc0f0000,     "v,V",          2 },
+{ "cmpv",      0x14060000,     0xfc0f0000,     "v,V",          2 },
+{ "expv",      0x14070000,     0xfc0f0000,     "v,V",          2 },
+{ "mrvvlt",    0x10030000,     0xfc0f0000,     "v,V",          2 },
+{ "mrvvle",    0x10040000,     0xfc0f0000,     "v,V",          2 },
+{ "mrvvgt",    0x14030000,     0xfc0f0000,     "v,V",          2 },
+{ "mrvvge",    0x14040000,     0xfc0f0000,     "v,V",          2 },
+{ "mrvveq",    0x10050000,     0xfc0f0000,     "v,V",          2 },
+{ "mrvvne",    0x10050000,     0xfc0f0000,     "v,V",          2 },
+{ "mrvrlt",    0x100d0000,     0xfc0f0000,     "v,R",          2 },
+{ "mrvrle",    0x100e0000,     0xfc0f0000,     "v,R",          2 },
+{ "mrvrgt",    0x140d0000,     0xfc0f0000,     "v,R",          2 },
+{ "mrvrge",    0x140e0000,     0xfc0f0000,     "v,R",          2 },
+{ "mrvreq",    0x100f0000,     0xfc0f0000,     "v,R",          2 },
+{ "mrvrne",    0x140f0000,     0xfc0f0000,     "v,R",          2 },
+{ "trvr",      0x140b0000,     0xfc0f0000,     "r,V",          2 },
+{ "trrv",      0x140c0000,     0xfc0f0000,     "v,R",          2 },
+
+{ "bu",                0x40000000,     0xff880000,     "xOA,X",        4 },
+{ "bns",       0x70080000,     0xff880000,     "xOA,X",        4 },
+{ "bnco",      0x70880000,     0xff880000,     "xOA,X",        4 },
+{ "bge",       0x71080000,     0xff880000,     "xOA,X",        4 },
+{ "bne",       0x71880000,     0xff880000,     "xOA,X",        4 },
+{ "bunge",     0x72080000,     0xff880000,     "xOA,X",        4 },
+{ "bunle",     0x72880000,     0xff880000,     "xOA,X",        4 },
+{ "bgt",       0x73080000,     0xff880000,     "xOA,X",        4 },
+{ "bnany",     0x73880000,     0xff880000,     "xOA,X",        4 },
+{ "bs" ,       0x70000000,     0xff880000,     "xOA,X",        4 },
+{ "bco",       0x70800000,     0xff880000,     "xOA,X",        4 },
+{ "blt",       0x71000000,     0xff880000,     "xOA,X",        4 },
+{ "beq",       0x71800000,     0xff880000,     "xOA,X",        4 },
+{ "buge",      0x72000000,     0xff880000,     "xOA,X",        4 },
+{ "bult",      0x72800000,     0xff880000,     "xOA,X",        4 },
+{ "ble",       0x73000000,     0xff880000,     "xOA,X",        4 },
+{ "bany",      0x73800000,     0xff880000,     "xOA,X",        4 },
+{ "brlnk",     0x44000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bib",       0x48000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bih",       0x48080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "biw",       0x4c000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bid",       0x4c080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bivb",      0x60000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bivh",      0x60080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bivw",      0x64000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bivd",      0x64080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bvsb",      0x68000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bvsh",      0x68080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bvsw",      0x6c000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bvsd",      0x6c080000,     0xfc080000,     "r,xOA,X",      4 },
+
+{ "camb",      0x80080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "camh",      0x80000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "camw",      0x80000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "camd",      0x80000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "car",       0x10000000,     0xfc0f0000,     "r,R",          2 },
+{ "card",      0x14000000,     0xfc0f0000,     "r,R",          2 },
+{ "ci",                0xf8050000,     0xfc7f0000,     "r,I",          4 },
+{ "chkbnd",    0x5c080000,     0xfc080000,     "r,xOA,X",      4 },
+
+{ "cavv",      0x10010000,     0xfc0f0000,     "v,V",          2 },
+{ "cavr",      0x10020000,     0xfc0f0000,     "v,R",          2 },
+{ "cavvd",     0x10090000,     0xfc0f0000,     "v,V",          2 },
+{ "cavrd",     0x100b0000,     0xfc0f0000,     "v,R",          2 },
+
+{ "anmb",      0x84080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "anmh",      0x84000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "anmw",      0x84000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "anmd",      0x84000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "anr",       0x04000000,     0xfc0f0000,     "r,R",          2 },
+{ "ani",       0xf8080000,     0xfc7f0000,     "r,I",          4 },
+{ "ormb",      0xb8080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "ormh",      0xb8000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "ormw",      0xb8000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "ormd",      0xb8000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "orr",       0x08000000,     0xfc0f0000,     "r,R",          2 },
+{ "oi",                0xf8090000,     0xfc7f0000,     "r,I",          4 },
+{ "eomb",      0x8c080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "eomh",      0x8c000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "eomw",      0x8c000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "eomd",      0x8c000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "eor",       0x0c000000,     0xfc0f0000,     "r,R",          2 },
+{ "eoi",       0xf80a0000,     0xfc7f0000,     "r,I",          4 },
+
+{ "anvv",      0x04010000,     0xfc0f0000,     "v,V",          2 },
+{ "anvr",      0x04020000,     0xfc0f0000,     "v,R",          2 },
+{ "orvv",      0x08010000,     0xfc0f0000,     "v,V",          2 },
+{ "orvr",      0x08020000,     0xfc0f0000,     "v,R",          2 },
+{ "eovv",      0x0c010000,     0xfc0f0000,     "v,V",          2 },
+{ "eovr",      0x0c020000,     0xfc0f0000,     "v,R",          2 },
+
+{ "sacz",      0x100c0000,     0xfc0f0000,     "r,R",          2 },
+{ "sla",       0x1c400000,     0xfc600000,     "r,S",          2 },
+{ "sll",       0x1c600000,     0xfc600000,     "r,S",          2 },
+{ "slc",       0x24400000,     0xfc600000,     "r,S",          2 },
+{ "slad",      0x20400000,     0xfc600000,     "r,S",          2 },
+{ "slld",      0x20600000,     0xfc600000,     "r,S",          2 },
+{ "sra",       0x1c000000,     0xfc600000,     "r,S",          2 },
+{ "srl",       0x1c200000,     0xfc600000,     "r,S",          2 },
+{ "src",       0x24000000,     0xfc600000,     "r,S",          2 },
+{ "srad",      0x20000000,     0xfc600000,     "r,S",          2 },
+{ "srld",      0x20200000,     0xfc600000,     "r,S",          2 },
+{ "sda",       0x3c030000,     0xfc0f0000,     "r,R",          2 },
+{ "sdl",       0x3c020000,     0xfc0f0000,     "r,R",          2 },
+{ "sdc",       0x3c010000,     0xfc0f0000,     "r,R",          2 },
+{ "sdad",      0x3c0b0000,     0xfc0f0000,     "r,R",          2 },
+{ "sdld",      0x3c0a0000,     0xfc0f0000,     "r,R",          2 },
+
+{ "svda",      0x3c070000,     0xfc0f0000,     "v,R",          2 },
+{ "svdl",      0x3c060000,     0xfc0f0000,     "v,R",          2 },
+{ "svdc",      0x3c050000,     0xfc0f0000,     "v,R",          2 },
+{ "svdad",     0x3c0e0000,     0xfc0f0000,     "v,R",          2 },
+{ "svdld",     0x3c0d0000,     0xfc0f0000,     "v,R",          2 },
+
+{ "sbm",       0xac080000,     0xfc080000,     "f,xOA,X",      4 },
+{ "zbm",       0xac000000,     0xfc080000,     "f,xOA,X",      4 },
+{ "tbm",       0xa8080000,     0xfc080000,     "f,xOA,X",      4 },
+{ "incmb",     0xa0000000,     0xfc080000,     "xOA,X",        4 },
+{ "incmh",     0xa0080000,     0xfc080000,     "xOA,X",        4 },
+{ "incmw",     0xa4000000,     0xfc080000,     "xOA,X",        4 },
+{ "incmd",     0xa4080000,     0xfc080000,     "xOA,X",        4 },
+{ "sbmd",      0x7c080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "zbmd",      0x7c000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "tbmd",      0x78080000,     0xfc080000,     "r,xOA,X",      4 },
+
+{ "ssm",       0x9c080000,     0xfc080000,     "f,xOA,X",      4 },
+{ "zsm",       0x9c000000,     0xfc080000,     "f,xOA,X",      4 },
+{ "tsm",       0x98080000,     0xfc080000,     "f,xOA,X",      4 },
+
+{ "admb",      0xc8080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "admh",      0xc8000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "admw",      0xc8000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "admd",      0xc8000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "adr",       0x38000000,     0xfc0f0000,     "r,R",          2 },
+{ "armb",      0xe8080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "armh",      0xe8000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "armw",      0xe8000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "armd",      0xe8000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "adi",       0xf8010000,     0xfc0f0000,     "r,I",          4 },
+{ "sumb",      0xcc080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "sumh",      0xcc000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "sumw",      0xcc000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "sumd",      0xcc000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "sur",       0x3c000000,     0xfc0f0000,     "r,R",          2 },
+{ "sui",       0xf8020000,     0xfc0f0000,     "r,I",          4 },
+{ "mpmb",      0xc0080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "mpmh",      0xc0000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "mpmw",      0xc0000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "mpr",       0x38020000,     0xfc0f0000,     "r,R",          2 },
+{ "mprd",      0x3c0f0000,     0xfc0f0000,     "r,R",          2 },
+{ "mpi",       0xf8030000,     0xfc0f0000,     "r,I",          4 },
+{ "dvmb",      0xc4080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "dvmh",      0xc4000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "dvmw",      0xc4000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "dvr",       0x380a0000,     0xfc0f0000,     "r,R",          2 },
+{ "dvi",       0xf8040000,     0xfc0f0000,     "r,I",          4 },
+{ "exs",       0x38080000,     0xfc0f0000,     "r,R",          2 },
+
+{ "advv",      0x30000000,     0xfc0f0000,     "v,V",          2 },
+{ "advvd",     0x30080000,     0xfc0f0000,     "v,V",          2 },
+{ "adrv",      0x34000000,     0xfc0f0000,     "v,R",          2 },
+{ "adrvd",     0x34080000,     0xfc0f0000,     "v,R",          2 },
+{ "suvv",      0x30010000,     0xfc0f0000,     "v,V",          2 },
+{ "suvvd",     0x30090000,     0xfc0f0000,     "v,V",          2 },
+{ "surv",      0x34010000,     0xfc0f0000,     "v,R",          2 },
+{ "survd",     0x34090000,     0xfc0f0000,     "v,R",          2 },
+{ "mpvv",      0x30020000,     0xfc0f0000,     "v,V",          2 },
+{ "mprv",      0x34020000,     0xfc0f0000,     "v,R",          2 },
+
+{ "adfw",      0xe0080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "adfd",      0xe0080002,     0xfc080002,     "r,xOA,X",      4 },
+{ "adrfw",     0x38010000,     0xfc0f0000,     "r,R",          2 },
+{ "adrfd",     0x38090000,     0xfc0f0000,     "r,R",          2 },
+{ "surfw",     0xe0000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "surfd",     0xe0000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "surfw",     0x38030000,     0xfc0f0000,     "r,R",          2 },
+{ "surfd",     0x380b0000,     0xfc0f0000,     "r,R",          2 },
+{ "mpfw",      0xe4080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "mpfd",      0xe4080002,     0xfc080002,     "r,xOA,X",      4 },
+{ "mprfw",     0x38060000,     0xfc0f0000,     "r,R",          2 },
+{ "mprfd",     0x380e0000,     0xfc0f0000,     "r,R",          2 },
+{ "rfw",       0xe4000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "rfd",       0xe4000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "rrfw",      0x0c0e0000,     0xfc0f0000,     "r",            2 },
+{ "rrfd",      0x0c0f0000,     0xfc0f0000,     "r",            2 },
+
+{ "advvfw",    0x30040000,     0xfc0f0000,     "v,V",          2 },
+{ "advvfd",    0x300c0000,     0xfc0f0000,     "v,V",          2 },
+{ "adrvfw",    0x34040000,     0xfc0f0000,     "v,R",          2 },
+{ "adrvfd",    0x340c0000,     0xfc0f0000,     "v,R",          2 },
+{ "suvvfw",    0x30050000,     0xfc0f0000,     "v,V",          2 },
+{ "suvvfd",    0x300d0000,     0xfc0f0000,     "v,V",          2 },
+{ "survfw",    0x34050000,     0xfc0f0000,     "v,R",          2 },
+{ "survfd",    0x340d0000,     0xfc0f0000,     "v,R",          2 },
+{ "mpvvfw",    0x30060000,     0xfc0f0000,     "v,V",          2 },
+{ "mpvvfd",    0x300e0000,     0xfc0f0000,     "v,V",          2 },
+{ "mprvfw",    0x34060000,     0xfc0f0000,     "v,R",          2 },
+{ "mprvfd",    0x340e0000,     0xfc0f0000,     "v,R",          2 },
+{ "rvfw",      0x30070000,     0xfc0f0000,     "v",            2 },
+{ "rvfd",      0x300f0000,     0xfc0f0000,     "v",            2 },
+
+{ "fltw",      0x38070000,     0xfc0f0000,     "r,R",          2 },
+{ "fltd",      0x380f0000,     0xfc0f0000,     "r,R",          2 },
+{ "fixw",      0x38050000,     0xfc0f0000,     "r,R",          2 },
+{ "fixd",      0x380d0000,     0xfc0f0000,     "r,R",          2 },
+{ "cfpds",     0x3c090000,     0xfc0f0000,     "r,R",          2 },
+
+{ "fltvw",     0x080d0000,     0xfc0f0000,     "v,V",          2 },
+{ "fltvd",     0x080f0000,     0xfc0f0000,     "v,V",          2 },
+{ "fixvw",     0x080c0000,     0xfc0f0000,     "v,V",          2 },
+{ "fixvd",     0x080e0000,     0xfc0f0000,     "v,V",          2 },
+{ "cfpvds",    0x0c0d0000,     0xfc0f0000,     "v,V",          2 },
+
+{ "orvrn",     0x000a0000,     0xfc0f0000,     "r,V",          2 },
+{ "andvrn",    0x00080000,     0xfc0f0000,     "r,V",          2 },
+{ "frsteq",    0x04090000,     0xfc0f0000,     "r,V",          2 },
+{ "sigma",     0x0c080000,     0xfc0f0000,     "r,V",          2 },
+{ "sigmad",    0x0c0a0000,     0xfc0f0000,     "r,V",          2 },
+{ "sigmf",     0x08080000,     0xfc0f0000,     "r,V",          2 },
+{ "sigmfd",    0x080a0000,     0xfc0f0000,     "r,V",          2 },
+{ "prodf",     0x04080000,     0xfc0f0000,     "r,V",          2 },
+{ "prodfd",    0x040a0000,     0xfc0f0000,     "r,V",          2 },
+{ "maxv",      0x10080000,     0xfc0f0000,     "r,V",          2 },
+{ "maxvd",     0x100a0000,     0xfc0f0000,     "r,V",          2 },
+{ "minv",      0x14080000,     0xfc0f0000,     "r,V",          2 },
+{ "minvd",     0x140a0000,     0xfc0f0000,     "r,V",          2 },
+
+{ "lpsd",      0xf0000000,     0xfc080000,     "xOA,X",        4 },
+{ "ldc",       0xf0080000,     0xfc080000,     "xOA,X",        4 },
+{ "spm",       0x040c0000,     0xfc0f0000,     "r",            2 },
+{ "rpm",       0x040d0000,     0xfc0f0000,     "r",            2 },
+{ "tritr",     0x00070000,     0xfc0f0000,     "r",            2 },
+{ "trrit",     0x00060000,     0xfc0f0000,     "r",            2 },
+{ "rpswt",     0x04080000,     0xfc0f0000,     "r",            2 },
+{ "exr",       0xf8070000,     0xfc0f0000,     "",             4 },
+{ "halt",      0x00000000,     0xfc0f0000,     "",             2 },
+{ "wait",      0x00010000,     0xfc0f0000,     "",             2 },
+{ "nop",       0x00020000,     0xfc0f0000,     "",             2 },
+{ "eiae",      0x00030000,     0xfc0f0000,     "",             2 },
+{ "efae",      0x000d0000,     0xfc0f0000,     "",             2 },
+{ "diae",      0x000e0000,     0xfc0f0000,     "",             2 },
+{ "dfae",      0x000f0000,     0xfc0f0000,     "",             2 },
+{ "spvc",      0xf8060000,     0xfc0f0000,     "r,T,N",        4 },
+{ "rdsts",     0x00090000,     0xfc0f0000,     "r",            2 },
+{ "setcpu",    0x000c0000,     0xfc0f0000,     "r",            2 },
+{ "cmc",       0x000b0000,     0xfc0f0000,     "r",            2 },
+{ "trrcu",     0x00040000,     0xfc0f0000,     "r",            2 },
+{ "attnio",    0x00050000,     0xfc0f0000,     "",             2 },
+{ "fudit",     0x28080000,     0xfc0f0000,     "",             2 },
+{ "break",     0x28090000,     0xfc0f0000,     "",             2 },
+{ "frzss",     0x280a0000,     0xfc0f0000,     "",             2 },
+{ "ripi",      0x04040000,     0xfc0f0000,     "r,R",          2 },
+{ "xcp",       0x04050000,     0xfc0f0000,     "r",            2 },
+{ "block",     0x04060000,     0xfc0f0000,     "",             2 },
+{ "unblock",   0x04070000,     0xfc0f0000,     "",             2 },
+{ "trsc",      0x08060000,     0xfc0f0000,     "r,R",          2 },
+{ "tscr",      0x08070000,     0xfc0f0000,     "r,R",          2 },
+{ "fq",                0x04080000,     0xfc0f0000,     "r",            2 },
+{ "flupte",    0x2c080000,     0xfc0f0000,     "r",            2 },
+{ "rviu",      0x040f0000,     0xfc0f0000,     "",             2 },
+{ "ldel",      0x280c0000,     0xfc0f0000,     "r,R",          2 },
+{ "ldu",       0x280d0000,     0xfc0f0000,     "r,R",          2 },
+{ "stdecc",    0x280b0000,     0xfc0f0000,     "r,R",          2 },
+{ "trpc",      0x08040000,     0xfc0f0000,     "r",            2 },
+{ "tpcr",      0x08050000,     0xfc0f0000,     "r",            2 },
+{ "ghalt",     0x0c050000,     0xfc0f0000,     "r",            2 },
+{ "grun",      0x0c040000,     0xfc0f0000,     "",             2 },
+{ "tmpr",      0x2c0a0000,     0xfc0f0000,     "r,R",          2 },
+{ "trmp",      0x2c0b0000,     0xfc0f0000,     "r,R",          2 },
+
+{ "trrve",     0x28060000,     0xfc0f0000,     "r",            2 },
+{ "trver",     0x28070000,     0xfc0f0000,     "r",            2 },
+{ "trvlr",     0x280f0000,     0xfc0f0000,     "r",            2 },
+
+{ "linkfl",    0x18000000,     0xfc0f0000,     "r,R",          2 },
+{ "linkbl",    0x18020000,     0xfc0f0000,     "r,R",          2 },
+{ "linkfp",    0x18010000,     0xfc0f0000,     "r,R",          2 },
+{ "linkbp",    0x18030000,     0xfc0f0000,     "r,R",          2 },
+{ "linkpl",    0x18040000,     0xfc0f0000,     "r,R",          2 },
+{ "ulinkl",    0x18080000,     0xfc0f0000,     "r,R",          2 },
+{ "ulinkp",    0x18090000,     0xfc0f0000,     "r,R",          2 },
+{ "ulinktl",   0x180a0000,     0xfc0f0000,     "r,R",          2 },
+{ "ulinktp",   0x180b0000,     0xfc0f0000,     "r,R",          2 },
+};
+
+int numopcodes = sizeof(gld_opcodes) / sizeof(gld_opcodes[0]);
+
+struct gld_opcode *endop = gld_opcodes + sizeof(gld_opcodes) /
+                               sizeof(gld_opcodes[0]);
diff --git a/usr/src/usr.bin/gdb/config/pn-opcode.h b/usr/src/usr.bin/gdb/config/pn-opcode.h
new file mode 100644 (file)
index 0000000..fb3ded8
--- /dev/null
@@ -0,0 +1,282 @@
+/* Print PN instructions for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+struct gld_opcode
+{
+  char *name;
+  unsigned long opcode;
+  unsigned long mask;
+  char *args;
+  int length;
+};
+
+/* We store four bytes of opcode for all opcodes because that
+   is the most any of them need.  The actual length of an instruction
+   is always at least 2 bytes, and at most four.  The length of the
+   instruction is based on the opcode.
+
+   The mask component is a mask saying which bits must match
+   particular opcode in order for an instruction to be an instance
+   of that opcode.
+
+   The args component is a string containing characters
+   that are used to format the arguments to the instruction. */
+
+/* Kinds of operands:
+   r  Register in first field
+   R  Register in second field
+   b  Base register in first field
+   B  Base register in second field
+   v  Vector register in first field
+   V  Vector register in first field
+   A  Optional address register (base register)
+   X  Optional index register
+   I  Immediate data (16bits signed)
+   O  Offset field (16bits signed)
+   h  Offset field (15bits signed)
+   d  Offset field (14bits signed)
+   S  Shift count field
+
+   any other characters are printed as is...
+*/
+
+/* The assembler requires that this array be sorted as follows:
+   all instances of the same mnemonic must be consecutive.
+   All instances of the same mnemonic with the same number of operands
+   must be consecutive.
+ */
+struct gld_opcode gld_opcodes[] =
+{
+{ "abm",       0xa0080000,     0xfc080000,     "f,xOA,X",      4 },
+{ "abr",       0x18080000,     0xfc0c0000,     "r,f",          2 },
+{ "aci",       0xfc770000,     0xfc7f8000,     "r,I",          4 },
+{ "adfd",      0xe0080002,     0xfc080002,     "r,xOA,X",      4 },
+{ "adfw",      0xe0080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "adi",       0xc8010000,     0xfc7f0000,     "r,I",          4 },
+{ "admb",      0xb8080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "admd",      0xb8000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "admh",      0xb8000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "admw",      0xb8000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "adr",       0x38000000,     0xfc0f0000,     "r,R",          2 },
+{ "adrfd",     0x38090000,     0xfc0f0000,     "r,R",          2 },
+{ "adrfw",     0x38010000,     0xfc0f0000,     "r,R",          2 },
+{ "adrm",      0x38080000,     0xfc0f0000,     "r,R",          2 },
+{ "ai",        0xfc030000,     0xfc07ffff,     "I",            4 },
+{ "anmb",      0x84080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "anmd",      0x84000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "anmh",      0x84000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "anmw",      0x84000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "anr",       0x04000000,     0xfc0f0000,     "r,R",          2 },
+{ "armb",      0xe8080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "armd",      0xe8000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "armh",      0xe8000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "armw",      0xe8000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bcf",       0xf0000000,     0xfc080000,     "I,xOA,X",      4 },
+{ "bct",       0xec000000,     0xfc080000,     "I,xOA,X",      4 },
+{ "bei",       0x00060000,     0xffff0000,     "",             2 },
+{ "bft",       0xf0000000,     0xff880000,     "xOA,X",        4 },
+{ "bib",       0xf4000000,     0xfc780000,     "r,xOA",        4 },
+{ "bid",       0xf4600000,     0xfc780000,     "r,xOA",        4 },
+{ "bih",       0xf4200000,     0xfc780000,     "r,xOA",        4 },
+{ "biw",       0xf4400000,     0xfc780000,     "r,xOA",        4 },
+{ "bl",        0xf8800000,     0xff880000,     "xOA,X",        4 },
+{ "bsub",      0x5c080000,     0xff8f0000,     "",             2 },
+{ "bsubm",     0x28080000,     0xfc080000,     "",             4 },
+{ "bu",        0xec000000,     0xff880000,     "xOA,X",        4 },
+{ "call",      0x28080000,     0xfc0f0000,     "",             2 },
+{ "callm",     0x5c080000,     0xff880000,     "",             4 },
+{ "camb",      0x90080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "camd",      0x90000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "camh",      0x90000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "camw",      0x90000000,     0xfc080000,     "r.xOA,X",      4 },
+{ "car",       0x10000000,     0xfc0f0000,     "r,R",          2 },
+{ "cd",        0xfc060000,     0xfc070000,     "r,f",          4 },
+{ "cea",       0x000f0000,     0xffff0000,     "",             2 },
+{ "ci",        0xc8050000,     0xfc7f0000,     "r,I",          4 },
+{ "cmc",       0x040a0000,     0xfc7f0000,     "r",            2 },
+{ "cmmb",      0x94080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "cmmd",      0x94000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "cmmh",      0x94000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "cmmw",      0x94000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "cmr",       0x14000000,     0xfc0f0000,     "r,R",          2 },
+{ "daci",      0xfc7f0000,     0xfc7f8000,     "r,I",          4 },
+{ "dae",       0x000e0000,     0xffff0000,     "",             2 },
+{ "dai",       0xfc040000,     0xfc07ffff,     "I",            4 },
+{ "dci",       0xfc6f0000,     0xfc7f8000,     "r,I",          4 },
+{ "di",        0xfc010000,     0xfc07ffff,     "I",            4 },
+{ "dvfd",      0xe4000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "dvfw",      0xe4000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "dvi",       0xc8040000,     0xfc7f0000,     "r,I",          4 },
+{ "dvmb",      0xc4080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "dvmh",      0xc4000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "dvmw",      0xc4000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "dvr",       0x380a0000,     0xfc0f0000,     "r,R",          2 },
+{ "dvrfd",     0x380c0000,     0xfc0f0000,     "r,R",          4 },
+{ "dvrfw",     0x38040000,     0xfc0f0000,     "r,xOA,X",      4 },
+{ "eae",       0x00080000,     0xffff0000,     "",             2 },
+{ "eci",       0xfc670000,     0xfc7f8080,     "r,I",          4 },
+{ "ecwcs",     0xfc4f0000,     0xfc7f8000,     "",             4 },
+{ "ei",        0xfc000000,     0xfc07ffff,     "I",            4 },
+{ "eomb",      0x8c080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "eomd",      0x8c000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "eomh",      0x8c000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "eomw",      0x8c000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "eor",       0x0c000000,     0xfc0f0000,     "r,R",          2 },
+{ "eorm",      0x0c080000,     0xfc0f0000,     "r,R",          2 },
+{ "es",        0x00040000,     0xfc7f0000,     "r",            2 },
+{ "exm",       0xa8000000,     0xff880000,     "xOA,X",        4 },
+{ "exr",       0xc8070000,     0xfc7f0000,     "r",            2 },
+{ "exrr",      0xc8070002,     0xfc7f0002,     "r",            2 },
+{ "fixd",      0x380d0000,     0xfc0f0000,     "r,R",          2 },
+{ "fixw",      0x38050000,     0xfc0f0000,     "r,R",          2 },
+{ "fltd",      0x380f0000,     0xfc0f0000,     "r,R",          2 },
+{ "fltw",      0x38070000,     0xfc0f0000,     "r,R",          2 },
+{ "grio",      0xfc3f0000,     0xfc7f8000,     "r,I",          4 },
+{ "halt",      0x00000000,     0xffff0000,     "",             2 },
+{ "hio",       0xfc370000,     0xfc7f8000,     "r,I",          4 },
+{ "jwcs",      0xfa080000,     0xff880000,     "xOA,X",        4 },
+{ "la",        0x50000000,     0xfc000000,     "r,xOA,X",      4 },
+{ "labr",      0x58080000,     0xfc080000,     "b,xOA,X",      4 },
+{ "lb",        0xac080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lcs",       0x00030000,     0xfc7f0000,     "r",            2 },
+{ "ld",        0xac000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "lear",      0x80000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lf",        0xcc000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lfbr",      0xcc080000,     0xfc080000,     "b,xOA,X",      4 },
+{ "lh",        0xac000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "li",        0xc8000000,     0xfc7f0000,     "r,I",          4 },
+{ "lmap",      0x2c070000,     0xfc7f0000,     "r",            2 },
+{ "lmb",       0xb0080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lmd",       0xb0000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "lmh",       0xb0000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "lmw",       0xb0000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lnb",       0xb4080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lnd",       0xb4000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "lnh",       0xb4000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "lnw",       0xb4000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lpsd",      0xf9800000,     0xff880000,     "r,xOA,X",      4 },
+{ "lpsdcm",    0xfa800000,     0xff880000,     "r,xOA,X",      4 },
+{ "lw",        0xac000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lwbr",      0x5c000000,     0xfc080000,     "b,xOA,X",      4 },
+{ "mpfd",      0xe4080002,     0xfc080002,     "r,xOA,X",      4 },
+{ "mpfw",      0xe4080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "mpi",       0xc8030000,     0xfc7f0000,     "r,I",          4 },
+{ "mpmb",      0xc0080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "mpmh",      0xc0000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "mpmw",      0xc0000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "mpr",       0x38020000,     0xfc0f0000,     "r,R",          2 },
+{ "mprfd",     0x380e0000,     0xfc0f0000,     "r,R",          2 },
+{ "mprfw",     0x38060000,     0xfc0f0000,     "r,R",          2 },
+{ "nop",       0x00020000,     0xffff0000,     "",             2 },
+{ "ormb",      0x88080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "ormd",      0x88000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "ormh",      0x88000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "ormw",      0x88000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "orr",       0x08000000,     0xfc0f0000,     "r,R",          2 },
+{ "orrm",      0x08080000,     0xfc0f0000,     "r,R",          2 },
+{ "rdsts",     0x00090000,     0xfc7f0000,     "r",            2 },
+{ "return",    0x280e0000,     0xfc7f0000,     "",             2 },
+{ "ri",        0xfc020000,     0xfc07ffff,     "I",            4 },
+{ "rnd",       0x00050000,     0xfc7f0000,     "r",            2 },
+{ "rpswt",     0x040b0000,     0xfc7f0000,     "r",            2 },
+{ "rschnl",    0xfc2f0000,     0xfc7f8000,     "r,I",          4 },
+{ "rsctl",     0xfc470000,     0xfc7f8000,     "r,I",          4 },
+{ "rwcs",      0x000b0000,     0xfc0f0000,     "r,R",          2 },
+{ "sacz",      0x10080000,     0xfc0f0000,     "r,R",          2 },
+{ "sbm",       0x98080000,     0xfc080000,     "f,xOA,X",      4 },
+{ "sbr",       0x18000000,     0xfc0c0000,     "r,f",          4 },
+{ "sea",       0x000d0000,     0xffff0000,     "",             2 },
+{ "setcpu",    0x2c090000,     0xfc7f0000,     "r",            2 },
+{ "sio",       0xfc170000,     0xfc7f8000,     "r,I",          4 },
+{ "sipu",      0x000a0000,     0xffff0000,     "",             2 },
+{ "sla",       0x1c400000,     0xfc600000,     "r,S",          2 },
+{ "slad",      0x20400000,     0xfc600000,     "r,S",          2 },
+{ "slc",       0x24400000,     0xfc600000,     "r,S",          2 },
+{ "sll",       0x1c600000,     0xfc600000,     "r,S",          2 },
+{ "slld",      0x20600000,     0xfc600000,     "r,S",          2 },
+{ "smc",       0x04070000,     0xfc070000,     "",             2 },
+{ "sra",       0x1c000000,     0xfc600000,     "r,S",          2 },
+{ "srad",      0x20000000,     0xfc600000,     "r,S",          2 },
+{ "src",       0x24000000,     0xfc600000,     "r,S",          2 },
+{ "srl",       0x1c200000,     0xfc600000,     "r,S",          2 },
+{ "srld",      0x20200000,     0xfc600000,     "r,S",          2 },
+{ "stb",       0xd4080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "std",       0xd4000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "stf",       0xdc000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "stfbr",     0x54000000,     0xfc080000,     "b,xOA,X",      4 },
+{ "sth",       0xd4000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "stmb",      0xd8080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "stmd",      0xd8000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "stmh",      0xd8000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "stmw",      0xd8000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "stpio",     0xfc270000,     0xfc7f8000,     "r,I",          4 },
+{ "stw",       0xd4000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "stwbr",     0x54000000,     0xfc080000,     "b,xOA,X",      4 },
+{ "suabr",     0x58000000,     0xfc080000,     "b,xOA,X",      4 },
+{ "sufd",      0xe0000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "sufw",      0xe0000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "sui",       0xc8020000,     0xfc7f0000,     "r,I",          4 },
+{ "sumb",      0xbc080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "sumd",      0xbc000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "sumh",      0xbc000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "sumw",      0xbc000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "sur",       0x3c000000,     0xfc0f0000,     "r,R",          2 },
+{ "surfd",     0x380b0000,     0xfc0f0000,     "r,xOA,X",      4 },
+{ "surfw",     0x38030000,     0xfc0f0000,     "r,R",          2 },
+{ "surm",      0x3c080000,     0xfc0f0000,     "r,R",          2 },
+{ "svc",       0xc8060000,     0xffff0000,     "",             4 },
+{ "tbm",       0xa4080000,     0xfc080000,     "f,xOA,X",      4 },
+{ "tbr",       0x180c0000,     0xfc0c0000,     "r,f",          2 },
+{ "tbrr",      0x2c020000,     0xfc0f0000,     "r,B",          2 },
+{ "tccr",      0x28040000,     0xfc7f0000,     "",             2 },
+{ "td",        0xfc050000,     0xfc070000,     "r,f",          4 },
+{ "tio",       0xfc1f0000,     0xfc7f8000,     "r,I",          4 },
+{ "tmapr",     0x2c0a0000,     0xfc0f0000,     "r,R",          2 },
+{ "tpcbr",     0x280c0000,     0xfc7f0000,     "r",            2 },
+{ "trbr",      0x2c010000,     0xfc0f0000,     "b,R",          2 },
+{ "trc",       0x2c030000,     0xfc0f0000,     "r,R",          2 },
+{ "trcc",      0x28050000,     0xfc7f0000,     "",             2 },
+{ "trcm",      0x2c0b0000,     0xfc0f0000,     "r,R",          2 },
+{ "trn",       0x2c040000,     0xfc0f0000,     "r,R",          2 },
+{ "trnm",      0x2c0c0000,     0xfc0f0000,     "r,R",          2 },
+{ "trr",       0x2c000000,     0xfc0f0000,     "r,R",          2 },
+{ "trrm",      0x2c080000,     0xfc0f0000,     "r,R",          2 },
+{ "trsc",      0x2c0e0000,     0xfc0f0000,     "r,R",          2 },
+{ "trsw",      0x28000000,     0xfc7f0000,     "r",            2 },
+{ "tscr",      0x2c0f0000,     0xfc0f0000,     "r,R",          2 },
+{ "uei",       0x00070000,     0xffff0000,     "",             2 },
+{ "wait",      0x00010000,     0xffff0000,     "",             2 },
+{ "wcwcs",     0xfc5f0000,     0xfc7f8000,     "",             4 },
+{ "wwcs",      0x000c0000,     0xfc0f0000,     "r,R",          2 },
+{ "xcbr",      0x28020000,     0xfc0f0000,     "b,B",          2 },
+{ "xcr",       0x2c050000,     0xfc0f0000,     "r,R",          2 },
+{ "xcrm",      0x2c0d0000,     0xfc0f0000,     "r,R",          2 },
+{ "zbm",       0x9c080000,     0xfc080000,     "f,xOA,X",      4 },
+{ "zbr",       0x18040000,     0xfc0c0000,     "r,f",          2 },
+{ "zmb",       0xf8080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "zmd",       0xf8000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "zmh",       0xf8000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "zmw",       0xf8000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "zr",        0x0c000000,     0xfc0f0000,     "r",            2 },
+};
+
+int numopcodes = sizeof(gld_opcodes) / sizeof(gld_opcodes[0]);
+
+struct gld_opcode *endop = gld_opcodes + sizeof(gld_opcodes) /
+               sizeof(gld_opcodes[0]);
diff --git a/usr/src/usr.bin/gdb/config/vax-opcode.h b/usr/src/usr.bin/gdb/config/vax-opcode.h
new file mode 100644 (file)
index 0000000..18a2ffb
--- /dev/null
@@ -0,0 +1,382 @@
+/* Vax opcde list.
+   Copyright (C) 1989, Free Software Foundation, Inc.
+
+This file is part of GDB and GAS.
+
+GDB and GAS are free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB and GAS are distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB or GAS; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#ifndef vax_opcodeT
+#define vax_opcodeT int
+#endif /* no vax_opcodeT */
+
+struct vot_wot                 /* vax opcode table: wot to do with this */
+                               /* particular opcode */
+{
+  char *            args;      /* how to compile said opcode */
+  vax_opcodeT       code;      /* op-code (may be > 8 bits!) */
+};
+
+struct vot                     /* vax opcode text */
+{
+  char *            name;      /* opcode name: lowercase string  [key]  */
+  struct vot_wot    detail;    /* rest of opcode table          [datum] */
+};
+
+#define vot_how args
+#define vot_code code
+#define vot_detail detail
+#define vot_name name
+
+static struct vot
+votstrs[] =
+{
+{    "halt",   {"",                    0x00    } },
+{    "nop",    {"",                    0x01    } },
+{    "rei",    {"",                    0x02    } },
+{    "bpt",    {"",                    0x03    } },
+{    "ret",    {"",                    0x04    } },
+{    "rsb",    {"",                    0x05    } },
+{    "ldpctx", {"",                    0x06    } },
+{    "svpctx", {"",                    0x07    } },
+{    "cvtps",  {"rwabrwab",            0x08    } },
+{    "cvtsp",  {"rwabrwab",            0x09    } },
+{    "index",  {"rlrlrlrlrlwl",        0x0a    } },
+{    "crc",    {"abrlrwab",            0x0b    } },
+{    "prober", {"rbrwab",              0x0c    } },
+{    "probew", {"rbrwab",              0x0d    } },
+{    "insque", {"abab",                0x0e    } },
+{    "remque", {"abwl",                0x0f    } },
+{    "bsbb",   {"bb",                  0x10    } },
+{    "brb",    {"bb",                  0x11    } },
+{    "bneq",   {"bb",                  0x12    } },
+{    "bnequ",  {"bb",                  0x12    } },
+{    "beql",   {"bb",                  0x13    } },
+{    "beqlu",  {"bb",                  0x13    } },
+{    "bgtr",   {"bb",                  0x14    } },
+{    "bleq",   {"bb",                  0x15    } },
+{    "jsb",    {"ab",                  0x16    } },
+{    "jmp",    {"ab",                  0x17    } },
+{    "bgeq",   {"bb",                  0x18    } },
+{    "blss",   {"bb",                  0x19    } },
+{    "bgtru",  {"bb",                  0x1a    } },
+{    "blequ",  {"bb",                  0x1b    } },
+{    "bvc",    {"bb",                  0x1c    } },
+{    "bvs",    {"bb",                  0x1d    } },
+{    "bcc",    {"bb",                  0x1e    } },
+{    "bgequ",  {"bb",                  0x1e    } },
+{    "blssu",  {"bb",                  0x1f    } },
+{    "bcs",    {"bb",                  0x1f    } },
+{    "addp4",  {"rwabrwab",            0x20    } },
+{    "addp6",  {"rwabrwabrwab",        0x21    } },
+{    "subp4",  {"rwabrwab",            0x22    } },
+{    "subp6",  {"rwabrwabrwab",        0x23    } },
+{    "cvtpt",  {"rwababrwab",          0x24    } },
+{    "mulp",   {"rwabrwabrwab",        0x25    } },
+{    "cvttp",  {"rwababrwab",          0x26    } },
+{    "divp",   {"rwabrwabrwab",        0x27    } },
+{    "movc3",  {"rwabab",              0x28    } },
+{    "cmpc3",  {"rwabab",              0x29    } },
+{    "scanc",  {"rwababrb",            0x2a    } },
+{    "spanc",  {"rwababrb",            0x2b    } },
+{    "movc5",  {"rwabrbrwab",          0x2c    } },
+{    "cmpc5",  {"rwabrbrwab",          0x2d    } },
+{    "movtc",  {"rwabrbabrwab",        0x2e    } },
+{    "movtuc", {"rwabrbabrwab",        0x2f    } },
+{    "bsbw",   {"bw",                  0x30    } },
+{    "brw",    {"bw",                  0x31    } },
+{    "cvtwl",  {"rwwl",                0x32    } },
+{    "cvtwb",  {"rwwb",                0x33    } },
+{    "movp",   {"rwabab",              0x34    } },
+{    "cmpp3",  {"rwabab",              0x35    } },
+{    "cvtpl",  {"rwabwl",              0x36    } },
+{    "cmpp4",  {"rwabrwab",            0x37    } },
+{    "editpc", {"rwababab",            0x38    } },
+{    "matchc", {"rwabrwab",            0x39    } },
+{    "locc",   {"rbrwab",              0x3a    } },
+{    "skpc",   {"rbrwab",              0x3b    } },
+{    "movzwl", {"rwwl",                0x3c    } },
+{    "acbw",   {"rwrwmwbw",            0x3d    } },
+{    "movaw",  {"awwl",                0x3e    } },
+{    "pushaw", {"aw",                  0x3f    } },
+{    "addf2",  {"rfmf",                0x40    } },
+{    "addf3",  {"rfrfwf",              0x41    } },
+{    "subf2",  {"rfmf",                0x42    } },
+{    "subf3",  {"rfrfwf",              0x43    } },
+{    "mulf2",  {"rfmf",                0x44    } },
+{    "mulf3",  {"rfrfwf",              0x45    } },
+{    "divf2",  {"rfmf",                0x46    } },
+{    "divf3",  {"rfrfwf",              0x47    } },
+{    "cvtfb",  {"rfwb",                0x48    } },
+{    "cvtfw",  {"rfww",                0x49    } },
+{    "cvtfl",  {"rfwl",                0x4a    } },
+{    "cvtrfl", {"rfwl",                0x4b    } },
+{    "cvtbf",  {"rbwf",                0x4c    } },
+{    "cvtwf",  {"rwwf",                0x4d    } },
+{    "cvtlf",  {"rlwf",                0x4e    } },
+{    "acbf",   {"rfrfmfbw",            0x4f    } },
+{    "movf",   {"rfwf",                0x50    } },
+{    "cmpf",   {"rfrf",                0x51    } },
+{    "mnegf",  {"rfwf",                0x52    } },
+{    "tstf",   {"rf",                  0x53    } },
+{    "emodf",  {"rfrbrfwlwf",          0x54    } },
+{    "polyf",  {"rfrwab",              0x55    } },
+{    "cvtfd",  {"rfwd",                0x56    } },
+                                        /* opcode 57 is not defined yet */
+{    "adawi",  {"rwmw",                0x58    } },
+                                        /* opcode 59 is not defined yet */
+                                        /* opcode 5a is not defined yet */
+                                        /* opcode 5b is not defined yet */
+{    "insqhi", {"abaq",                0x5c    } },
+{    "insqti", {"abaq",                0x5d    } },
+{    "remqhi", {"aqwl",                0x5e    } },
+{    "remqti", {"aqwl",                0x5f    } },
+{    "addd2",  {"rdmd",                0x60    } },
+{    "addd3",  {"rdrdwd",              0x61    } },
+{    "subd2",  {"rdmd",                0x62    } },
+{    "subd3",  {"rdrdwd",              0x63    } },
+{    "muld2",  {"rdmd",                0x64    } },
+{    "muld3",  {"rdrdwd",              0x65    } },
+{    "divd2",  {"rdmd",                0x66    } },
+{    "divd3",  {"rdrdwd",              0x67    } },
+{    "cvtdb",  {"rdwb",                0x68    } },
+{    "cvtdw",  {"rdww",                0x69    } },
+{    "cvtdl",  {"rdwl",                0x6a    } },
+{    "cvtrdl", {"rdwl",                0x6b    } },
+{    "cvtbd",  {"rbwd",                0x6c    } },
+{    "cvtwd",  {"rwwd",                0x6d    } },
+{    "cvtld",  {"rlwd",                0x6e    } },
+{    "acbd",   {"rdrdmdbw",            0x6f    } },
+{    "movd",   {"rdwd",                0x70    } },
+{    "cmpd",   {"rdrd",                0x71    } },
+{    "mnegd",  {"rdwd",                0x72    } },
+{    "tstd",   {"rd",                  0x73    } },
+{    "emodd",  {"rdrbrdwlwd",          0x74    } },
+{    "polyd",  {"rdrwab",              0x75    } },
+{    "cvtdf",  {"rdwf",                0x76    } },
+                                        /* opcode 77 is not defined yet */
+{    "ashl",   {"rbrlwl",              0x78    } },
+{    "ashq",   {"rbrqwq",              0x79    } },
+{    "emul",   {"rlrlrlwq",            0x7a    } },
+{    "ediv",   {"rlrqwlwl",            0x7b    } },
+{    "clrd",   {"wd",                  0x7c    } },
+{    "clrg",   {"wg",                  0x7c    } },
+{    "clrq",   {"wd",                  0x7c    } },
+{    "movq",   {"rqwq",                0x7d    } },
+{    "movaq",  {"aqwl",                0x7e    } },
+{    "movad",  {"adwl",                0x7e    } },
+{    "pushaq", {"aq",                  0x7f    } },
+{    "pushad", {"ad",                  0x7f    } },
+{    "addb2",  {"rbmb",                0x80    } },
+{    "addb3",  {"rbrbwb",              0x81    } },
+{    "subb2",  {"rbmb",                0x82    } },
+{    "subb3",  {"rbrbwb",              0x83    } },
+{    "mulb2",  {"rbmb",                0x84    } },
+{    "mulb3",  {"rbrbwb",              0x85    } },
+{    "divb2",  {"rbmb",                0x86    } },
+{    "divb3",  {"rbrbwb",              0x87    } },
+{    "bisb2",  {"rbmb",                0x88    } },
+{    "bisb3",  {"rbrbwb",              0x89    } },
+{    "bicb2",  {"rbmb",                0x8a    } },
+{    "bicb3",  {"rbrbwb",              0x8b    } },
+{    "xorb2",  {"rbmb",                0x8c    } },
+{    "xorb3",  {"rbrbwb",              0x8d    } },
+{    "mnegb",  {"rbwb",                0x8e    } },
+{    "caseb",  {"rbrbrb",              0x8f    } },
+{    "movb",   {"rbwb",                0x90    } },
+{    "cmpb",   {"rbrb",                0x91    } },
+{    "mcomb",  {"rbwb",                0x92    } },
+{    "bitb",   {"rbrb",                0x93    } },
+{    "clrb",   {"wb",                  0x94    } },
+{    "tstb",   {"rb",                  0x95    } },
+{    "incb",   {"mb",                  0x96    } },
+{    "decb",   {"mb",                  0x97    } },
+{    "cvtbl",  {"rbwl",                0x98    } },
+{    "cvtbw",  {"rbww",                0x99    } },
+{    "movzbl", {"rbwl",                0x9a    } },
+{    "movzbw", {"rbww",                0x9b    } },
+{    "rotl",   {"rbrlwl",              0x9c    } },
+{    "acbb",   {"rbrbmbbw",            0x9d    } },
+{    "movab",  {"abwl",                0x9e    } },
+{    "pushab", {"ab",                  0x9f    } },
+{    "addw2",  {"rwmw",                0xa0    } },
+{    "addw3",  {"rwrwww",              0xa1    } },
+{    "subw2",  {"rwmw",                0xa2    } },
+{    "subw3",  {"rwrwww",              0xa3    } },
+{    "mulw2",  {"rwmw",                0xa4    } },
+{    "mulw3",  {"rwrwww",              0xa5    } },
+{    "divw2",  {"rwmw",                0xa6    } },
+{    "divw3",  {"rwrwww",              0xa7    } },
+{    "bisw2",  {"rwmw",                0xa8    } },
+{    "bisw3",  {"rwrwww",              0xa9    } },
+{    "bicw2",  {"rwmw",                0xaa    } },
+{    "bicw3",  {"rwrwww",              0xab    } },
+{    "xorw2",  {"rwmw",                0xac    } },
+{    "xorw3",  {"rwrwww",              0xad    } },
+{    "mnegw",  {"rwww",                0xae    } },
+{    "casew",  {"rwrwrw",              0xaf    } },
+{    "movw",   {"rwww",                0xb0    } },
+{    "cmpw",   {"rwrw",                0xb1    } },
+{    "mcomw",  {"rwww",                0xb2    } },
+{    "bitw",   {"rwrw",                0xb3    } },
+{    "clrw",   {"ww",                  0xb4    } },
+{    "tstw",   {"rw",                  0xb5    } },
+{    "incw",   {"mw",                  0xb6    } },
+{    "decw",   {"mw",                  0xb7    } },
+{    "bispsw", {"rw",                  0xb8    } },
+{    "bicpsw", {"rw",                  0xb9    } },
+{    "popr",   {"rw",                  0xba    } },
+{    "pushr",  {"rw",                  0xbb    } },
+{    "chmk",   {"rw",                  0xbc    } },
+{    "chme",   {"rw",                  0xbd    } },
+{    "chms",   {"rw",                  0xbe    } },
+{    "chmu",   {"rw",                  0xbf    } },
+{    "addl2",  {"rlml",                0xc0    } },
+{    "addl3",  {"rlrlwl",              0xc1    } },
+{    "subl2",  {"rlml",                0xc2    } },
+{    "subl3",  {"rlrlwl",              0xc3    } },
+{    "mull2",  {"rlml",                0xc4    } },
+{    "mull3",  {"rlrlwl",              0xc5    } },
+{    "divl2",  {"rlml",                0xc6    } },
+{    "divl3",  {"rlrlwl",              0xc7    } },
+{    "bisl2",  {"rlml",                0xc8    } },
+{    "bisl3",  {"rlrlwl",              0xc9    } },
+{    "bicl2",  {"rlml",                0xca    } },
+{    "bicl3",  {"rlrlwl",              0xcb    } },
+{    "xorl2",  {"rlml",                0xcc    } },
+{    "xorl3",  {"rlrlwl",              0xcd    } },
+{    "mnegl",  {"rlwl",                0xce    } },
+{    "casel",  {"rlrlrl",              0xcf    } },
+{    "movl",   {"rlwl",                0xd0    } },
+{    "cmpl",   {"rlrl",                0xd1    } },
+{    "mcoml",  {"rlwl",                0xd2    } },
+{    "bitl",   {"rlrl",                0xd3    } },
+{    "clrf",   {"wf",                  0xd4    } },
+{    "clrl",   {"wl",                  0xd4    } },
+{    "tstl",   {"rl",                  0xd5    } },
+{    "incl",   {"ml",                  0xd6    } },
+{    "decl",   {"ml",                  0xd7    } },
+{    "adwc",   {"rlml",                0xd8    } },
+{    "sbwc",   {"rlml",                0xd9    } },
+{    "mtpr",   {"rlrl",                0xda    } },
+{    "mfpr",   {"rlwl",                0xdb    } },
+{    "movpsl", {"wl",                  0xdc    } },
+{    "pushl",  {"rl",                  0xdd    } },
+{    "moval",  {"alwl",                0xde    } },
+{    "movaf",  {"afwl",                0xde    } },
+{    "pushal", {"al",                  0xdf    } },
+{    "pushaf", {"af",                  0xdf    } },
+{    "bbs",    {"rlabbb",              0xe0    } },
+{    "bbc",    {"rlabbb",              0xe1    } },
+{    "bbss",   {"rlabbb",              0xe2    } },
+{    "bbcs",   {"rlabbb",              0xe3    } },
+{    "bbsc",   {"rlabbb",              0xe4    } },
+{    "bbcc",   {"rlabbb",              0xe5    } },
+{    "bbssi",  {"rlabbb",              0xe6    } },
+{    "bbcci",  {"rlabbb",              0xe7    } },
+{    "blbs",   {"rlbb",                0xe8    } },
+{    "blbc",   {"rlbb",                0xe9    } },
+{    "ffs",    {"rlrbvbwl",            0xea    } },
+{    "ffc",    {"rlrbvbwl",            0xeb    } },
+{    "cmpv",   {"rlrbvbrl",            0xec    } },
+{    "cmpzv",  {"rlrbvbrl",            0xed    } },
+{    "extv",   {"rlrbvbwl",            0xee    } },
+{    "extzv",  {"rlrbvbwl",            0xef    } },
+{    "insv",   {"rlrlrbvb",            0xf0    } },
+{    "acbl",   {"rlrlmlbw",            0xf1    } },
+{    "aoblss", {"rlmlbb",              0xf2    } },
+{    "aobleq", {"rlmlbb",              0xf3    } },
+{    "sobgeq", {"mlbb",                0xf4    } },
+{    "sobgtr", {"mlbb",                0xf5    } },
+{    "cvtlb",  {"rlwb",                0xf6    } },
+{    "cvtlw",  {"rlww",                0xf7    } },
+{    "ashp",   {"rbrwabrbrwab",        0xf8    } },
+{    "cvtlp",  {"rlrwab",              0xf9    } },
+{    "callg",  {"abab",                0xfa    } },
+{    "calls",  {"rlab",                0xfb    } },
+{    "xfc",    {"",                    0xfc    } },
+                                        /* undefined opcodes here */
+{    "cvtdh",  {"rdwh",                0x32fd  } },
+{    "cvtgf",  {"rgwh",                0x33fd  } },
+{    "addg2",  {"rgmg",                0x40fd  } },
+{    "addg3",  {"rgrgwg",              0x41fd  } },
+{    "subg2",  {"rgmg",                0x42fd  } },
+{    "subg3",  {"rgrgwg",              0x43fd  } },
+{    "mulg2",  {"rgmg",                0x44fd  } },
+{    "mulg3",  {"rgrgwg",              0x45fd  } },
+{    "divg2",  {"rgmg",                0x46fd  } },
+{    "divg3",  {"rgrgwg",              0x47fd  } },
+{    "cvtgb",  {"rgwb",                0x48fd  } },
+{    "cvtgw",  {"rgww",                0x49fd  } },
+{    "cvtgl",  {"rgwl",                0x4afd  } },
+{    "cvtrgl", {"rgwl",                0x4bfd  } },
+{    "cvtbg",  {"rbwg",                0x4cfd  } },
+{    "cvtwg",  {"rwwg",                0x4dfd  } },
+{    "cvtlg",  {"rlwg",                0x4efd  } },
+{    "acbg",   {"rgrgmgbw",            0x4ffd  } },
+{    "movg",   {"rgwg",                0x50fd  } },
+{    "cmpg",   {"rgrg",                0x51fd  } },
+{    "mnegg",  {"rgwg",                0x52fd  } },
+{    "tstg",   {"rg",                  0x53fd  } },
+{    "emodg",  {"rgrwrgwlwg",          0x54fd  } },
+{    "polyg",  {"rgrwab",              0x55fd  } },
+{    "cvtgh",  {"rgwh",                0x56fd  } },
+                                        /* undefined opcodes here */
+{    "addh2",  {"rhmh",                0x60fd  } },
+{    "addh3",  {"rhrhwh",              0x61fd  } },
+{    "subh2",  {"rhmh",                0x62fd  } },
+{    "subh3",  {"rhrhwh",              0x63fd  } },
+{    "mulh2",  {"rhmh",                0x64fd  } },
+{    "mulh3",  {"rhrhwh",              0x65fd  } },
+{    "divh2",  {"rhmh",                0x66fd  } },
+{    "divh3",  {"rhrhwh",              0x67fd  } },
+{    "cvthb",  {"rhwb",                0x68fd  } },
+{    "cvthw",  {"rhww",                0x69fd  } },
+{    "cvthl",  {"rhwl",                0x6afd  } },
+{    "cvtrhl", {"rhwl",                0x6bfd  } },
+{    "cvtbh",  {"rbwh",                0x6cfd  } },
+{    "cvtwh",  {"rwwh",                0x6dfd  } },
+{    "cvtlh",  {"rlwh",                0x6efd  } },
+{    "acbh",   {"rhrhmhbw",            0x6ffd  } },
+{    "movh",   {"rhwh",                0x70fd  } },
+{    "cmph",   {"rhrh",                0x71fd  } },
+{    "mnegh",  {"rhwh",                0x72fd  } },
+{    "tsth",   {"rh",                  0x73fd  } },
+{    "emodh",  {"rhrwrhwlwh",          0x74fd  } },
+{    "polyh",  {"rhrwab",              0x75fd  } },
+{    "cvthg",  {"rhwg",                0x76fd  } },
+                                        /* undefined opcodes here */
+{    "clrh",   {"wh",                  0x7cfd  } },
+{    "clro",   {"wo",                  0x7cfd  } },
+{    "movo",   {"rowo",                0x7dfd  } },
+{    "movah",  {"ahwl",                0x7efd  } },
+{    "movao",  {"aowl",                0x7efd  } },
+{    "pushah", {"ah",                  0x7ffd  } },
+{    "pushao", {"ao",                  0x7ffd  } },
+                                        /* undefined opcodes here */
+{    "cvtfh",  {"rfwh",                0x98fd  } },
+{    "cvtfg",  {"rfwg",                0x99fd  } },
+                                        /* undefined opcodes here */
+{    "cvthf",  {"rhwf",                0xf6fd  } },
+{    "cvthd",  {"rhwd",                0xf7fd  } },
+                                        /* undefined opcodes here */
+{    "bugl",   {"rl",                  0xfdff  } },
+{    "bugw",   {"rw",                  0xfeff  } },
+                                        /* undefined opcodes here */
+
+{      ""       ,   ""          } /* empty is end sentinel */
+
+};                             /* votstrs */
+
+/* end: vax.opcode.h */
diff --git a/usr/src/usr.bin/gdb/grot/munch b/usr/src/usr.bin/gdb/grot/munch
new file mode 100644 (file)
index 0000000..eef3927
--- /dev/null
@@ -0,0 +1,17 @@
+#! /bin/sh
+
+# create an initialization procedure from a list of .o files
+
+echo '/* Do not modify this file.  It is created automatically by "munch". */'
+echo 'void initialize_all_files () {'
+
+if test "$1" = "-DSYSV" ; then
+    shift;
+    nm $* | egrep '^(.*[^a-zA-Z_]_|_)initialize_' | \
+       sed -e 's/^.*\(_initialize_[a-zA-Z0-9_]*\)[^a-zA-Z0-9_].*$/   \1 ();/'
+else
+    nm -p $* | egrep 'T *__initialize_' | \
+       sed -e 's/^.*T *_*\(.*\)/    _\1 ();/'
+fi
+
+echo '}'
diff --git a/usr/src/usr.bin/gdb/grot/remote-sa.m68k.shar b/usr/src/usr.bin/gdb/grot/remote-sa.m68k.shar
new file mode 100644 (file)
index 0000000..ca82553
--- /dev/null
@@ -0,0 +1,893 @@
+# This is a shell archive.  Remove anything before this line,
+# then unpack it by saving it in a file and typing "sh file".
+#
+# Wrapped by Glenn Engel <glenne@labgre> on Mon Jun 12 15:19:20 1989
+#
+# This archive contains:
+#      remcom.c        
+#
+
+LANG=""; export LANG
+PATH=/bin:/usr/bin:$PATH; export PATH
+
+echo x - remcom.c
+cat >remcom.c <<'@EOF'
+
+/****************************************************************************
+
+               THIS SOFTWARE IS NOT COPYRIGHTED  
+   
+   HP offers the following for use in the public domain.  HP makes no
+   warranty with regard to the software or it's performance and the 
+   user accepts the software "AS IS" with all faults.
+
+   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+/****************************************************************************
+ *  $Header: remcom.c,v 1.25 89/05/16 14:34:00 glenne Exp $                   
+ *
+ *  $Module name: remcom.c $  
+ *  $Revision: 1.25 $
+ *  $Date: 89/05/16 14:34:00 $
+ *  $Contributor:     Lake Stevens Instrument Division$
+ *  
+ *  $Description:     low level support for gdb debugger. $
+ *
+ *  $Considerations:  only works on target hardware $
+ *
+ *  $Written by:      Glenn Engel $
+ *  $ModuleState:     Experimental $ 
+ *
+ *  $NOTES:           See Below $
+ * 
+ *  To enable debugger support, two things need to happen.  One, a
+ *  call to set_debug_traps() is necessary in order to allow any breakpoints
+ *  or error conditions to be properly intercepted and reported to gdb.
+ *  Two, a breakpoint needs to be generated to begin communication.  This
+ *  is most easily accomplished by a call to breakpoint().  Breakpoint()
+ *  simulates a breakpoint by executing a trap #1.
+ *  
+ *  Some explanation is probably necessary to explain how exceptions are
+ *  handled.  When an exception is encountered the 68000 pushes the current
+ *  program counter and status register onto the supervisor stack and then
+ *  transfers execution to a location specified in it's vector table.
+ *  The handlers for the exception vectors are hardwired to jmp to an address
+ *  given by the relation:  (exception - 256) * 6.  These are decending 
+ *  addresses starting from -6, -12, -18, ...  By allowing 6 bytes for
+ *  each entry, a jsr, jmp, bsr, ... can be used to enter the exception 
+ *  handler.  Using a jsr to handle an exception has an added benefit of
+ *  allowing a single handler to service several exceptions and use the
+ *  return address as the key differentiation.  The vector number can be
+ *  computed from the return address by [ exception = (addr + 1530) / 6 ].
+ *  The sole purpose of the routine _catchException is to compute the
+ *  exception number and push it on the stack in place of the return address.
+ *  The external function exceptionHandler() is
+ *  used to attach a specific handler to a specific 68k exception.
+ *  For 68020 machines, the ability to have a return address around just
+ *  so the vector can be determined is not necessary because the '020 pushes an
+ *  extra word onto the stack containing the vector offset
+ * 
+ *  Because gdb will sometimes write to the stack area to execute function
+ *  calls, this program cannot rely on using the supervisor stack so it
+ *  uses it's own stack area reserved in the int array remcomStack.  
+ * 
+ *************
+ *
+ *    The following gdb commands are supported:
+ * 
+ * command          function                               Return value
+ * 
+ *    g             return the value of the CPU registers  hex data or ENN
+ *    G             set the value of the CPU registers     OK or ENN
+ * 
+ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
+ *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
+ * 
+ *    c             Resume at current address              SNN   ( signal NN)
+ *    cAA..AA       Continue at address AA..AA             SNN
+ * 
+ *    s             Step one instruction                   SNN
+ *    sAA..AA       Step one instruction from AA..AA       SNN
+ * 
+ *    k             kill
+ *
+ *    ?             What was the last sigval ?             SNN   (signal NN)
+ * 
+ * All commands and responses are sent with a packet which includes a 
+ * checksum.  A packet consists of 
+ * 
+ * $<packet info>#<checksum>.
+ * 
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ * 
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer.  '-' indicates a failed transfer.
+ * 
+ * Example:
+ * 
+ * Host:                  Reply:
+ * $m0,10#2a               +$00010203040506070809101112131415#42
+ * 
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <setjmp.h>
+
+/************************************************************************
+ *
+ * external low-level support routines 
+ */
+typedef void (*ExceptionHook)(int);   /* pointer to function with int parm */
+typedef void (*Function)();           /* pointer to a function */
+
+extern putDebugChar();   /* write a single character      */
+extern getDebugChar();   /* read and return a single char */
+
+extern Function exceptionHandler();  /* assign an exception handler */
+extern ExceptionHook exceptionHook;  /* hook variable for errors/exceptions */
+
+
+/************************************************************************/
+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+/* at least NUMREGBYTES*2 are needed for register packets */
+#define BUFMAX 400
+
+static char initialized;  /* boolean flag. != 0 means we've been initialized */
+
+int     remote_debug = 0;
+/*  debug >  0 prints ill-formed commands in valid packets & checksum errors */ 
+
+char hexchars[]="0123456789abcdef";
+
+/* there are 180 bytes of registers on a 68020 w/68881      */
+/* many of the fpa registers are 12 byte (96 bit) registers */
+#define NUMREGBYTES 180
+enum regnames {D0,D1,D2,D3,D4,D5,D6,D7, 
+               A0,A1,A2,A3,A4,A5,A6,A7, 
+               PS,PC,
+               FP0,FP1,FP2,FP3,FP4,FP5,FP6,FP7,
+               FPCONTROL,FPSTATUS,FPIADDR
+              };
+
+typedef struct FrameStruct
+{
+    struct FrameStruct  *previous;
+    int       exceptionPC;      /* pc value when this frame created */
+    int       exceptionVector;  /* cpu vector causing exception     */
+    short     frameSize;        /* size of cpu frame in words       */
+    short     sr;               /* for 68000, this not always sr    */
+    int       pc;
+    short     format;
+    int       fsaveHeader;
+    int       morejunk[0];        /* exception frame, fp save... */
+} Frame;
+
+#define FRAMESIZE 500
+static Frame *lastFrame;
+static int   frameStack[FRAMESIZE];
+
+/*
+ * these should not be static cuz they can be used outside this module
+ */
+int registers[NUMREGBYTES/4];
+int superStack;
+
+static int remcomStack[400];
+static int* stackPtr = &remcomStack[399];
+
+/*
+ * In many cases, the system will want to continue exception processing
+ * when a continue command is given.  
+ * oldExceptionHook is a function to invoke in this case.
+ */
+
+static ExceptionHook oldExceptionHook;
+
+/* the size of the exception stack on the 68020 varies with the type of
+ * exception.  The following table is the number of WORDS used
+ * for each exception format.
+ */
+static short exceptionSize[] = { 4,4,6,4,4,4,4,4,29,10,16,46,4,4,4,4 };
+
+/************* jump buffer used for setjmp/longjmp **************************/
+jmp_buf env;
+
+/***************************  ASSEMBLY CODE MACROS *************************/
+/*                                                                        */
+
+#ifdef __HAVE_68881__
+/* do an fsave, then remember the address to begin a restore from */
+#define SAVE_FP_REGS()    asm(" fsave   a0@-");                \
+                         asm(" fmovemx fp0-fp7,_registers+72");        \
+                         asm(" fmoveml fpcr/fpsr/fpi,_registers+168"); 
+#define RESTORE_FP_REGS() asm(" fmoveml _registers+168,fpcr/fpsr/fpi"); \
+                         asm(" fmovemx _registers+72,fp0-fp7");        \
+                         asm(" frestore a0@+");
+#else
+#define SAVE_FP_REGS()
+#define RESTORE_FP_REGS()
+#endif /* __HAVE_68881__ */
+
+asm("
+.text
+.globl _return_to_super
+_return_to_super:
+        movel   _registers+60,sp /* get new stack pointer */        
+        movel   _lastFrame,a0   /* get last frame info  */              
+        bra     return_to_any
+
+.globl _return_to_user
+_return_to_user:
+        movel   _registers+60,a0 /* get usp */                          
+        movel   a0,usp           /* set usp */                         
+        movel   _superStack,sp  /* get original stack pointer */        
+
+return_to_any:
+        movel   _lastFrame,a0   /* get last frame info  */              
+        movel   a0@+,_lastFrame /* link in previous frame     */        
+        addql   #8,a0           /* skip over pc, vector#*/              
+        movew   a0@+,d0         /* get # of words in cpu frame */       
+        addw    d0,a0           /* point to end of data        */       
+        addw    d0,a0           /* point to end of data        */       
+        movel   a0,a1                                                   
+#                                                                       
+# copy the stack frame                                                  
+        subql   #1,d0                                                   
+copyUserLoop:                                                               
+        movew   a1@-,sp@-                                               
+        dbf     d0,copyUserLoop                                             
+");                                                                     
+        RESTORE_FP_REGS()                                              
+   asm("   moveml  _registers,d0-d7/a0-a6");                           
+   asm("   rte");  /* pop and go! */                                    
+
+#define DISABLE_INTERRUPTS()   asm("         oriw   #0x0700,sr");
+#define BREAKPOINT() asm("   trap #1");
+
+/* this function is called immediately when a level 7 interrupt occurs */
+/* if the previous interrupt level was 7 then we're already servicing  */
+/* this interrupt and an rte is in order to return to the debugger.    */
+/* For the 68000, the offset for sr is 6 due to the jsr return address */
+asm("
+.text
+.globl __debug_level7
+__debug_level7:
+       movew   d0,sp@-");
+#ifdef mc68020
+asm("  movew   sp@(2),d0");
+#else
+asm("  movew   sp@(6),d0");
+#endif
+asm("  andiw   #0x700,d0
+       cmpiw   #0x700,d0
+       beq     _already7
+        movew   sp@+,d0        
+        bra     __catchException
+_already7:
+       movew   sp@+,d0");
+#ifndef mc68020
+asm("  lea     sp@(4),sp");     /* pull off 68000 return address */
+#endif
+asm("  rte");
+
+extern void _catchException();
+
+#ifdef mc68020
+/* This function is called when a 68020 exception occurs.  It saves
+ * all the cpu and fpcp regs in the _registers array, creates a frame on a
+ * linked list of frames which has the cpu and fpcp stack frames needed
+ * to properly restore the context of these processors, and invokes
+ * an exception handler (remcom_handler).
+ *
+ * stack on entry:                       stack on exit:
+ *   N bytes of junk                     exception # MSWord
+ *   Exception Format Word               exception # MSWord
+ *   Program counter LSWord              
+ *   Program counter MSWord             
+ *   Status Register                    
+ *                                       
+ *                                       
+ */
+asm(" 
+.text
+.globl __catchException
+__catchException:");
+DISABLE_INTERRUPTS();
+asm("
+        moveml  d0-d7/a0-a6,_registers /* save registers        */
+       movel   _lastFrame,a0   /* last frame pointer */
+");
+SAVE_FP_REGS();        
+asm("
+       lea     _registers,a5   /* get address of registers     */
+        movew   sp@,d1          /* get status register          */
+        movew   d1,a5@(66)      /* save sr                     */      
+       movel   sp@(2),a4       /* save pc in a4 for later use  */
+        movel   a4,a5@(68)      /* save pc in _regisers[]              */
+
+#
+# figure out how many bytes in the stack frame
+       movew   sp@(6),d0       /* get '020 exception format    */
+        movew   d0,d2           /* make a copy of format word   */
+        andiw   #0xf000,d0      /* mask off format type         */
+        rolw    #5,d0           /* rotate into the low byte *2  */
+        lea     _exceptionSize,a1   
+        addw    d0,a1           /* index into the table         */
+       movew   a1@,d0          /* get number of words in frame */
+        movew   d0,d3           /* save it                      */
+        subw    d0,a0          /* adjust save pointer          */
+        subw    d0,a0          /* adjust save pointer(bytes)   */
+       movel   a0,a1           /* copy save pointer            */
+       subql   #1,d0           /* predecrement loop counter    */
+#
+# copy the frame
+saveFrameLoop:
+       movew   sp@+,a1@+
+       dbf     d0,saveFrameLoop
+#
+# now that the stack has been clenaed,
+# save the a7 in use at time of exception
+        movel   sp,_superStack  /* save supervisor sp           */
+        andiw   #0x2000,d1      /* were we in supervisor mode ? */
+        beq     userMode       
+        movel   a7,a5@(60)      /* save a7                  */
+        bra     a7saveDone
+userMode:  
+       movel   usp,a1          
+        movel   a1,a5@(60)      /* save user stack pointer     */
+a7saveDone:
+
+#
+# save size of frame
+        movew   d3,a0@-
+
+#
+# compute exception number
+       andl    #0xfff,d2       /* mask off vector offset       */
+       lsrw    #2,d2           /* divide by 4 to get vect num  */
+        movel   d2,a0@-         /* save it                      */
+#
+# save pc causing exception
+        movel   a4,a0@-
+#
+# save old frame link and set the new value
+       movel   _lastFrame,a1   /* last frame pointer */
+       movel   a1,a0@-         /* save pointer to prev frame   */
+        movel   a0,_lastFrame
+
+        movel   d2,sp@-                /* push exception num           */
+       movel   _exceptionHook,a0  /* get address of handler */
+        jbsr    a0@             /* and call it */
+        jmp     __returnFromException     /* now, return        */
+");
+#else /* mc68000 */
+/* This function is called when an exception occurs.  It translates the
+ * return address found on the stack into an exception vector # which
+ * is then handled by either handle_exception or a system handler.
+ * _catchException provides a front end for both.  
+ *
+ * stack on entry:                       stack on exit:
+ *   Program counter MSWord              exception # MSWord 
+ *   Program counter LSWord              exception # MSWord
+ *   Status Register                     
+ *   Return Address  MSWord              
+ *   Return Address  LSWord             
+ */
+asm("
+.text
+.globl __catchException
+__catchException:");
+DISABLE_INTERRUPTS();
+asm("
+        moveml d0-d7/a0-a6,_registers  /* save registers               */
+       movel   _lastFrame,a0   /* last frame pointer */
+");
+SAVE_FP_REGS();        
+asm("
+        lea     _registers,a5   /* get address of registers     */
+        movel   sp@+,d2         /* pop return address           */
+       addl    #1530,d2        /* convert return addr to       */
+       divs    #6,d2           /*  exception number            */
+       extl    d2   
+
+        moveql  #3,d3           /* assume a three word frame     */
+
+        cmpiw   #3,d2           /* bus error or address error ? */
+        bgt     normal          /* if >3 then normal error      */
+        movel   sp@+,a0@-       /* copy error info to frame buff*/
+        movel   sp@+,a0@-       /* these are never used         */
+        moveql  #7,d3           /* this is a 7 word frame       */
+     
+normal:   
+       movew   sp@+,d1         /* pop status register          */
+        movel   sp@+,a4         /* pop program counter          */
+        movew   d1,a5@(66)      /* save sr                     */      
+        movel   a4,a5@(68)      /* save pc in _regisers[]              */
+        movel   a4,a0@-         /* copy pc to frame buffer      */
+       movew   d1,a0@-         /* copy sr to frame buffer      */
+
+        movel   sp,_superStack  /* save supervisor sp          */
+
+        andiw   #0x2000,d1      /* were we in supervisor mode ? */
+        beq     userMode       
+        movel   a7,a5@(60)      /* save a7                  */
+        bra     saveDone             
+userMode:
+        movel   usp,a1         /* save user stack pointer      */
+        movel   a1,a5@(60)      /* save user stack pointer     */
+saveDone:
+
+        movew   d3,a0@-         /* push frame size in words     */
+        movel   d2,a0@-         /* push vector number           */
+        movel   a4,a0@-         /* push exception pc            */
+
+#
+# save old frame link and set the new value
+       movel   _lastFrame,a1   /* last frame pointer */
+       movel   a1,a0@-         /* save pointer to prev frame   */
+        movel   a0,_lastFrame
+
+        movel   d2,sp@-                /* push exception num           */
+       movel   _exceptionHook,a0  /* get address of handler */
+        jbsr    a0@             /* and call it */
+        jmp     __returnFromException     /* now, return        */
+");
+#endif
+
+
+/*
+ * remcomHandler is a front end for handle_exception.  It moves the
+ * stack pointer into an area reserved for debugger use in case the
+ * breakpoint happened in supervisor mode.
+ */
+asm("_remcomHandler:");
+asm("           addl    #4,sp");        /* pop off return address     */
+asm("           movel   sp@+,d0");      /* get the exception number   */
+asm("          movel   _stackPtr,sp"); /* move to remcom stack area  */
+asm("          movel   d0,sp@-");      /* push exception onto stack  */
+asm("          jbsr    _handle_exception");    /* this never returns */
+asm("           rts");                  /* return */
+
+void _returnFromException( Frame *frame )
+{
+    /* if no existing frame, dummy one up */
+    if (! frame)
+    {
+        frame = lastFrame -1;
+        frame->frameSize = 4;
+        frame->format = 0;
+        frame->fsaveHeader = 0;
+        frame->previous = lastFrame;
+    }
+
+#ifndef mc68020
+    /* a 68000 cannot use the internal info pushed onto a bus error
+     * or address error frame when doing an RTE so don't put this info
+     * onto the stack or the stack will creep every time this happens.
+     */
+    frame->frameSize=3;
+#endif
+
+    /* throw away any frames in the list after this frame */
+    lastFrame = frame;
+
+    frame->sr = registers[(int) PS];
+    frame->pc = registers[(int) PC];
+
+    if (registers[(int) PS] & 0x2000)
+    { 
+        /* return to supervisor mode... */
+        return_to_super();
+    }
+    else
+    { /* return to user mode */
+        return_to_user();
+    }
+}
+
+int hex(ch)
+char ch;
+{
+  if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10);
+  if ((ch >= '0') && (ch <= '9')) return (ch-'0');
+  return (0);
+}
+
+
+/* scan for the sequence $<data>#<checksum>     */
+void getpacket(buffer)
+char * buffer;
+{
+  unsigned char checksum;
+  unsigned char xmitcsum;
+  int  i;
+  int  count;
+  char ch;
+  
+  do {
+    /* wait around for the start character, ignore all other characters */
+    while ((ch = getDebugChar()) != '$'); 
+    checksum = 0;
+    count = 0;
+    
+    /* now, read until a # or end of buffer is found */
+    while (count < BUFMAX) {
+      ch = getDebugChar();
+      if (ch == '#') break;
+      checksum = checksum + ch;
+      buffer[count] = ch;
+      count = count + 1;
+      }
+    buffer[count] = 0;
+
+    if (ch == '#') {
+      xmitcsum = hex(getDebugChar()) << 4;
+      xmitcsum += hex(getDebugChar());
+      if ((remote_debug ) && (checksum != xmitcsum)) {
+        fprintf(stderr,"bad checksum.  My count = 0x%x, sent=0x%x. buf=%s\n",
+                                                    checksum,xmitcsum,buffer);
+      }
+      
+      if (checksum != xmitcsum) putDebugChar('-');  /* failed checksum */ 
+      else {
+        putDebugChar('+');  /* successful transfer */
+        /* if a sequence char is present, reply the sequence ID */
+        if (buffer[2] == ':') {
+           putDebugChar( buffer[0] );
+           putDebugChar( buffer[1] );
+           /* remove sequence chars from buffer */
+           count = strlen(buffer);
+           for (i=3; i <= count; i++) buffer[i-3] = buffer[i];
+        } 
+      } 
+    } 
+  } while (checksum != xmitcsum);
+  
+}
+
+/* send the packet in buffer.  The host get's one chance to read it.  
+   This routine does not wait for a positive acknowledge.  */
+
+
+void putpacket(buffer)
+char * buffer;
+{
+  unsigned char checksum;
+  int  count;
+  char ch;
+  
+  /*  $<packet info>#<checksum>. */
+  do {
+  putDebugChar('$');
+  checksum = 0;
+  count    = 0;
+  
+  while (ch=buffer[count]) {
+    if (! putDebugChar(ch)) return;
+    checksum += ch;
+    count += 1;
+  }
+  
+  putDebugChar('#');
+  putDebugChar(hexchars[checksum >> 4]);
+  putDebugChar(hexchars[checksum % 16]);
+
+  } while (1 == 0);  /* (getDebugChar() != '+'); */
+  
+}
+
+static char  inbuffer[BUFMAX];
+static char  outbuffer[BUFMAX];
+static short error;
+
+
+void debug_error(format, parm)
+char * format;
+char * parm;
+{
+  if (remote_debug) fprintf(stderr,format,parm);
+}
+
+/* convert the memory pointed to by mem into hex, placing result in buf */
+/* return a pointer to the last char put in buf (null) */
+char* mem2hex(mem, buf, count)
+char* mem;
+char* buf;
+int   count;
+{
+      int i;
+      unsigned char ch;
+      for (i=0;i<count;i++) {
+          ch = *mem++;
+          *buf++ = hexchars[ch >> 4];
+          *buf++ = hexchars[ch % 16];
+      }
+      *buf = 0; 
+      return(buf);
+}
+
+/* convert the hex array pointed to by buf into binary to be placed in mem */
+/* return a pointer to the character AFTER the last byte written */
+char* hex2mem(buf, mem, count)
+char* buf;
+char* mem;
+int   count;
+{
+      int i;
+      unsigned char ch;
+      for (i=0;i<count;i++) {
+          ch = hex(*buf++) << 4;
+          ch = ch + hex(*buf++);
+          *mem++ = ch;
+      }
+      return(mem);
+}
+
+/* a bus error has occurred, perform a longjmp
+   to return execution and allow handling of the error */
+
+void handle_buserror()
+{
+  longjmp(env,1);
+}
+
+/* this function takes the 68000 exception number and attempts to 
+   translate this number into a unix compatible signal value */
+int computeSignal( exceptionVector )
+int exceptionVector;
+{
+  int sigval;
+  switch (exceptionVector) {
+    case 2 : sigval = 10; break; /* bus error           */
+    case 3 : sigval = 10; break; /* address error       */
+    case 4 : sigval = 4;  break; /* illegal instruction */
+    case 5 : sigval = 8;  break; /* zero divide         */
+    case 6 : sigval = 16; break; /* chk instruction     */
+    case 7 : sigval = 16; break; /* trapv instruction   */
+    case 8 : sigval = 11; break; /* privilege violation */
+    case 9 : sigval = 5;  break; /* trace trap          */
+    case 10: sigval = 4;  break; /* line 1010 emulator  */
+    case 11: sigval = 4;  break; /* line 1111 emulator  */
+    case 31: sigval = 2;  break; /* interrupt           */
+    case 33: sigval = 5;  break; /* breakpoint          */
+    case 40: sigval = 8;  break; /* floating point err  */
+    case 48: sigval = 8;  break; /* floating point err  */
+    case 49: sigval = 8;  break; /* floating point err  */
+    case 50: sigval = 8;  break; /* zero divide         */
+    case 51: sigval = 8;  break; /* underflow           */
+    case 52: sigval = 8;  break; /* operand error       */
+    case 53: sigval = 8;  break; /* overflow            */
+    case 54: sigval = 8;  break; /* NAN                 */
+    default: 
+      sigval = 7;         /* "software generated"*/
+  }
+  return (sigval);
+}
+
+/*
+ * This function does all command procesing for interfacing to gdb.
+ */
+void handle_exception(int exceptionVector)
+{
+  int    sigval;
+  int    addr, length;
+  char * ptr;
+  int    newPC;
+  Frame  *frame;
+  
+  if (remote_debug) printf("vector=%d, sr=0x%x, pc=0x%x\n", 
+                           exceptionVector,
+                           registers[ PS ], 
+                           registers[ PC ]);
+
+  /* reply to host that an exception has occurred */
+  sigval = computeSignal( exceptionVector );
+  sprintf(outbuffer,"S%02x",sigval);
+  putpacket(outbuffer); 
+
+  while (1==1) { 
+    error = 0;
+    outbuffer[0] = 0;
+    getpacket(inbuffer);
+    switch (inbuffer[0]) {
+      case '?' : sprintf(outbuffer,"S%02x",sigval);
+                 break; 
+      case 'd' : remote_debug = !(remote_debug);  /* toggle debug flag */
+                 break; 
+      case 'g' : /* return the value of the CPU registers */
+                mem2hex((char*) registers, outbuffer, NUMREGBYTES);
+                break;
+      case 'G' : /* set the value of the CPU registers - return OK */
+                hex2mem(&inbuffer[1], (char*) registers, NUMREGBYTES);
+                strcpy(outbuffer,"OK");
+                break;
+      
+      /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
+      case 'm' : 
+               if (setjmp(env) == 0) {
+                   exceptionHandler(2,handle_buserror); 
+
+                   if (2 == sscanf(&inbuffer[1],"%x,%x",&addr,&length)) {
+                     mem2hex((char*) addr, outbuffer, length);
+                   }
+                   else {
+                     strcpy(outbuffer,"E01");
+                     debug_error("malformed read memory command: %s",inbuffer);
+                     }     
+                } 
+               else {
+                 exceptionHandler(2,_catchException);   
+                 strcpy(outbuffer,"E03");
+                 debug_error("bus error");
+                 }     
+                
+               /* restore handler for bus error */
+               exceptionHandler(2,_catchException);   
+               break;
+      
+      /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+      case 'M' : 
+               if (setjmp(env) == 0) {
+                   exceptionHandler(2,handle_buserror); 
+
+                   if (2 == sscanf(&inbuffer[1],"%x,%x:",&addr,&length)) {
+                     ptr = strchr(inbuffer,':');
+                     ptr += 1; /* point 1 past the colon */
+                     hex2mem(ptr, (char*) addr, length);
+                     strcpy(outbuffer,"OK");
+                   }
+                   else {
+                     strcpy(outbuffer,"E02");
+                     debug_error("malformed write memory command: %s",inbuffer);
+                     }     
+                } 
+               else {
+                 exceptionHandler(2,_catchException);   
+                 strcpy(outbuffer,"E03");
+                 debug_error("bus error");
+                 }     
+                break;
+     
+     /* cAA..AA    Continue at address AA..AA(optional) */
+     /* sAA..AA   Step one instruction from AA..AA(optional) */
+     case 'c' : 
+     case 's' : 
+          /* try to read optional parameter, addr unchanged if no parm */
+          if (1 == sscanf(&inbuffer[1],"%x",&registers[ PC ])); 
+          newPC = registers[ PC];
+          
+          /* clear the trace bit */
+          registers[ PS ] &= 0x7fff;
+          
+          /* set the trace bit if we're stepping */
+          if (inbuffer[0] == 's') registers[ PS ] |= 0x8000;
+          
+          /*
+           * look for newPC in the linked list of exception frames.
+           * if it is found, use the old frame it.  otherwise,
+           * fake up a dummy frame in returnFromException().
+           */
+          if (remote_debug) printf("new pc = 0x%x\n",newPC);
+          frame = lastFrame;
+          while (frame)
+          {
+              if (remote_debug)
+                  printf("frame at 0x%x has pc=0x%x, except#=%d\n",
+                         frame,frame->exceptionPC,
+                         frame->exceptionVector);
+              if (frame->exceptionPC == newPC) break;  /* bingo! a match */
+              /*
+               * for a breakpoint instruction, the saved pc may
+               * be off by two due to re-executing the instruction
+               * replaced by the trap instruction.  Check for this.
+               */
+              if ((frame->exceptionVector == 33) &&
+                  (frame->exceptionPC == (newPC+2))) break;
+              frame = frame->previous;
+          }
+          
+          /*
+           * If we found a match for the PC AND we are not returning
+           * as a result of a breakpoint (33),
+           * trace exception (9), nmi (31), jmp to
+           * the old exception handler as if this code never ran.
+           */
+          if (frame) 
+          {
+              if ((frame->exceptionVector != 9)  && 
+                  (frame->exceptionVector != 31) && 
+                  (frame->exceptionVector != 33))
+              { 
+                  /*
+                   * invoke the previous handler.
+                   */
+                  if (oldExceptionHook)
+                      (*oldExceptionHook) (frame->exceptionVector);
+                  newPC = registers[ PC ];    /* pc may have changed  */
+                  if (newPC != frame->exceptionPC)
+                  {
+                      if (remote_debug)
+                          printf("frame at 0x%x has pc=0x%x, except#=%d\n",
+                                 frame,frame->exceptionPC,
+                                 frame->exceptionVector);
+                      /* dispose of this frame, we're skipping it (longjump?)*/
+                      lastFrame = frame->previous;
+                      frame = (Frame *) 0;
+                  }
+              }
+          }         
+
+          _returnFromException( frame );
+
+          break;
+          
+      /* kill the program */
+      case 'k' :  /* do nothing */
+                break;
+      } /* switch */ 
+    
+    /* reply to the request */
+    putpacket(outbuffer); 
+    }
+}
+
+
+/* this function is used to set up exception handlers for tracing and 
+   breakpoints */
+void set_debug_traps()
+{
+extern void _debug_level7();
+extern void remcomHandler();
+int exception;
+
+  for (exception = 2; exception <= 23; exception++)
+      exceptionHandler(exception,_catchException);   
+
+  /* level 7 interrupt              */
+  exceptionHandler(31,_debug_level7);    
+  
+  /* breakpoint exception (trap #1) */
+  exceptionHandler(33,_catchException);
+  
+  /* floating point error (trap #8) */
+  exceptionHandler(40,_catchException);
+  
+  /* 48 to 54 are floating point coprocessor errors */
+  for (exception = 48; exception <= 54; exception++)
+      exceptionHandler(exception,_catchException);   
+
+  if (oldExceptionHook != remcomHandler)
+  {
+      oldExceptionHook = exceptionHook;
+      exceptionHook    = remcomHandler;
+  }
+  
+  initialized = 1;
+
+  lastFrame = (Frame *) &frameStack[FRAMESIZE-1];
+  lastFrame->previous = (Frame *) 0;
+}
+
+/* This function will generate a breakpoint exception.  It is used at the
+   beginning of a program to sync up with a debugger and can be used
+   otherwise as a quick means to stop program execution and "break" into
+   the debugger. */
+   
+void breakpoint()
+{
+  if (initialized) BREAKPOINT();
+}
+
+@EOF
+
+chmod 444 remcom.c
+
+exit 0
+
diff --git a/usr/src/usr.bin/gdb/grot/standalone.c b/usr/src/usr.bin/gdb/grot/standalone.c
new file mode 100644 (file)
index 0000000..5646fb6
--- /dev/null
@@ -0,0 +1,601 @@
+/* Interface to bare machine for GDB running as kernel debugger.
+   Copyright (C) 1986, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined (SIGTSTP) && defined (SIGIO)
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif /* SIGTSTP and SIGIO defined (must be 4.2) */
+
+#include "defs.h"
+#include "param.h"
+#include "symtab.h"
+#include "frame.h"
+#include "inferior.h"
+#include "wait.h"
+
+\f
+/* Random system calls, mostly no-ops to prevent link problems  */
+
+ioctl (desc, code, arg)
+{}
+
+int (* signal ()) ()
+{}
+
+kill ()
+{}
+
+getpid ()
+{
+  return 0;
+}
+
+sigsetmask ()
+{}
+
+chdir ()
+{}
+
+char *
+getwd (buf)
+     char *buf;
+{
+  buf[0] = '/';
+  buf[1] = 0;
+  return buf;
+}
+
+/* Used to check for existence of .gdbinit.  Say no.  */
+
+access ()
+{
+  return -1;
+}
+
+exit ()
+{
+  error ("Fatal error; restarting.");
+}
+\f
+/* Reading "files".  The contents of some files are written into kdb's
+   data area before it is run.  These files are used to contain the
+   symbol table for kdb to load, and the source files (in case the
+   kdb user wants to print them).  The symbols are stored in a file
+   named "kdb-symbols" in a.out format (except that all the text and
+   data have been stripped to save room).
+
+   The files are stored in the following format:
+   int     number of bytes of data for this file, including these four.
+   char[]  name of the file, ending with a null.
+   padding to multiple of 4 boundary.
+   char[]  file contents.  The length can be deduced from what was
+           specified before.  There is no terminating null here.
+
+   If the int at the front is zero, it means there are no more files.
+
+   Opening a file in kdb returns a nonzero value to indicate success,
+   but the value does not matter.  Only one file can be open, and only
+   for reading.  All the primitives for input from the file know
+   which file is open and ignore what is specified for the descriptor
+   or for the stdio stream.
+
+   Input with fgetc can be done either on the file that is open
+   or on stdin (which reads from the terminal through tty_input ()  */
+
+/* Address of data for the files stored in format described above.  */
+char *files_start;
+
+/* The file stream currently open:  */
+
+char *sourcebeg;               /* beginning of contents */
+int sourcesize;                        /* size of contents */
+char *sourceptr;               /* current read pointer */
+int sourceleft;                        /* number of bytes to eof */
+
+/* "descriptor" for the file now open.
+   Incremented at each close.
+   If specified descriptor does not match this,
+   it means the program is trying to use a closed descriptor.
+   We report an error for that.  */
+
+int sourcedesc;
+
+open (filename, modes)
+     char *filename;
+     int modes;
+{
+  register char *next;
+  extern int errno;
+
+  if (modes)
+    {
+      errno = EROFS;
+      return -1;
+    }
+
+  if (sourceptr)
+    {
+      errno = EMFILE;
+      return -1;
+    }
+
+  for (next - files_start; * (int *) next;
+       next += * (int *) next)
+    {
+      if (!strcmp (next + 4, filename))
+       {
+         sourcebeg = next + 4 + strlen (next + 4) + 1;
+         sourcebeg = (char *) (((int) sourcebeg + 3) & (-4));
+         sourceptr = sourcebeg;
+         sourcesize = next + * (int *) next - sourceptr;
+         sourceleft = sourcesize;
+         return sourcedesc;
+       }
+    }
+  return 0;
+}
+
+close (desc)
+     int desc;
+{
+  sourceptr = 0;
+  sourcedesc++;
+  /* Don't let sourcedesc get big enough to be confused with stdin.  */
+  if (sourcedesc == 100)
+    sourcedesc = 5;
+}
+
+FILE *
+fopen (filename, modes)
+     char *filename;
+     char *modes;
+{
+  return (FILE *) open (filename, *modes == 'w');
+}
+
+FILE *
+fdopen (desc)
+     int desc;
+{
+  return (FILE *) desc;
+}
+
+fclose (desc)
+     int desc;
+{
+  close (desc);
+}
+
+fstat (desc, statbuf)
+     struct stat *statbuf;
+{
+  extern int errno;
+
+  if (desc != sourcedesc)
+    {
+      errno = EBADF;
+      return -1;
+    }
+  statbuf->st_size = sourcesize;
+}
+
+myread (desc, destptr, size, filename)
+     int desc;
+     char *destptr;
+     int size;
+     char *filename;
+{
+  int len = min (sourceleft, size);
+  extern int errno;
+
+  if (desc != sourcedesc)
+    {
+      errno = EBADF;
+      return -1;
+    }
+
+  bcopy (sourceptr, destptr, len);
+  sourceleft -= len;
+  return len;
+}
+
+int
+fread (bufp, numelts, eltsize, stream)
+{
+  register int elts = min (numelts, sourceleft / eltsize);
+  register int len = elts * eltsize;
+  extern int errno;
+
+  if (stream != sourcedesc)
+    {
+      errno = EBADF;
+      return -1;
+    }
+
+  bcopy (sourceptr, bufp, len);
+  sourceleft -= len;
+  return elts;
+}
+
+int
+fgetc (desc)
+     int desc;
+{
+  extern int errno;
+
+  if (desc == (int) stdin)
+    return tty_input ();
+
+  if (desc != sourcedesc)
+    {
+      errno = EBADF;
+      return -1;
+    }
+
+  if (sourceleft-- <= 0)
+    return EOF;
+  return *sourceptr++;
+}
+
+lseek (desc, pos)
+     int desc;
+     int pos;
+{
+  extern int errno;
+
+  if (desc != sourcedesc)
+    {
+      errno = EBADF;
+      return -1;
+    }
+
+  if (pos < 0 || pos > sourcesize)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  sourceptr = sourcebeg + pos;
+  sourceleft = sourcesize - pos;
+}
+\f
+/* Output in kdb can go only to the terminal, so the stream
+   specified may be ignored.  */
+
+printf (a1, a2, a3, a4, a5, a6, a7, a8, a9)
+{
+  char buffer[1024];
+  sprintf (buffer, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+  display_string (buffer);
+}
+
+fprintf (ign, a1, a2, a3, a4, a5, a6, a7, a8, a9)
+{
+  char buffer[1024];
+  sprintf (buffer, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+  display_string (buffer);
+}
+
+fwrite (buf, numelts, size, stream)
+     register char *buf;
+     int numelts, size;
+{
+  register int i = numelts * size;
+  while (i-- > 0)
+    fputc (*buf++, stream);
+}
+
+fputc (c, ign)
+{
+  char buf[2];
+  buf[0] = c;
+  buf[1] = 0;
+  display_string (buf);
+}
+
+/* sprintf refers to this, but loading this from the
+   library would cause fflush to be loaded from it too.
+   In fact there should be no need to call this (I hope).  */
+
+_flsbuf ()
+{
+  error ("_flsbuf was actually called.");
+}
+
+fflush (ign)
+{
+}
+\f
+/* Entries into core and inflow, needed only to make things link ok.  */
+
+exec_file_command ()
+{}
+
+core_file_command ()
+{}
+
+char *
+get_exec_file (err)
+     int err;
+{
+  /* Makes one printout look reasonable; value does not matter otherwise.  */
+  return "run";
+}
+
+have_core_file_p ()
+{
+  return 0;
+}
+
+kill_command ()
+{
+  inferior_pid = 0;
+}
+
+terminal_inferior ()
+{}
+
+terminal_ours ()
+{}
+
+terminal_init_inferior ()
+{}
+
+write_inferior_register ()
+{}
+
+read_inferior_register ()
+{}
+
+read_memory (memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  bcopy (memaddr, myaddr, len);
+}
+
+/* Always return 0 indicating success.  */
+
+write_memory (memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  bcopy (myaddr, memaddr, len);
+  return 0;
+}
+
+static REGISTER_TYPE saved_regs[NUM_REGS];
+
+REGISTER_TYPE
+read_register (regno)
+     int regno;
+{
+  if (regno < 0 || regno >= NUM_REGS)
+    error ("Register number %d out of range.", regno);
+  return saved_regs[regno];
+}
+
+void
+write_register (regno, value)
+     int regno;
+     REGISTER_TYPE value;
+{
+  if (regno < 0 || regno >= NUM_REGS)
+    error ("Register number %d out of range.", regno);
+  saved_regs[regno] = value;
+}
+\f
+/* System calls needed in relation to running the "inferior".  */
+
+vfork ()
+{
+  /* Just appear to "succeed".  Say the inferior's pid is 1.  */
+  return 1;
+}
+
+/* These are called by code that normally runs in the inferior
+   that has just been forked.  That code never runs, when standalone,
+   and these definitions are so it will link without errors.  */
+
+ptrace ()
+{}
+
+setpgrp ()
+{}
+
+execle ()
+{}
+
+_exit ()
+{}
+\f
+/* Malloc calls these.  */
+
+malloc_warning (str)
+     char *str;
+{
+  printf ("\n%s.\n\n", str);
+}
+
+char *next_free;
+char *memory_limit;
+
+char *
+sbrk (amount)
+     int amount;
+{
+  if (next_free + amount > memory_limit)
+    return (char *) -1;
+  next_free += amount;
+  return next_free - amount;
+}
+
+/* Various ways malloc might ask where end of memory is.  */
+
+char *
+ulimit ()
+{
+  return memory_limit;
+}
+
+int
+vlimit ()
+{
+  return memory_limit - next_free;
+}
+
+getrlimit (addr)
+     struct rlimit *addr;
+{
+  addr->rlim_cur = memory_limit - next_free;
+}
+\f
+/* Context switching to and from program being debugged.  */
+
+/* GDB calls here to run the user program.
+   The frame pointer for this function is saved in
+   gdb_stack by save_frame_pointer; then we restore
+   all of the user program's registers, including PC and PS.  */
+
+static int fault_code;
+static REGISTER_TYPE gdb_stack;
+
+resume ()
+{
+  REGISTER_TYPE restore[NUM_REGS];
+
+  PUSH_FRAME_PTR;
+  save_frame_pointer ();
+
+  bcopy (saved_regs, restore, sizeof restore);
+  POP_REGISTERS;
+  /* Control does not drop through here!  */
+}
+
+save_frame_pointer (val)
+     CORE_ADDR val;
+{
+  gdb_stack = val;
+}
+
+/* Fault handlers call here, running in the user program stack.
+   They must first push a fault code,
+   old PC, old PS, and any other info about the fault.
+   The exact format is machine-dependent and is known only
+   in the definition of PUSH_REGISTERS.  */
+
+fault ()
+{
+  /* Transfer all registers and fault code to the stack
+     in canonical order: registers in order of GDB register number,
+     followed by fault code.  */
+  PUSH_REGISTERS;
+
+  /* Transfer them to saved_regs and fault_code.  */
+  save_registers ();
+
+  restore_gdb ();
+  /* Control does not reach here */
+}
+
+restore_gdb ()
+{
+  CORE_ADDR new_fp = gdb_stack;
+  /* Switch to GDB's stack  */
+  POP_FRAME_PTR;
+  /* Return from the function `resume'.  */
+}
+
+/* Assuming register contents and fault code have been pushed on the stack as
+   arguments to this function, copy them into the standard place
+   for the program's registers while GDB is running.  */
+
+save_registers (firstreg)
+     int firstreg;
+{
+  bcopy (&firstreg, saved_regs, sizeof saved_regs);
+  fault_code = (&firstreg)[NUM_REGS];
+}
+
+/* Store into the structure such as `wait' would return
+   the information on why the program faulted,
+   converted into a machine-independent signal number.  */
+
+static int fault_table[] = FAULT_TABLE;
+
+int
+wait (w)
+     WAITTYPE *w;
+{
+  WSETSTOP (*w, fault_table[fault_code / FAULT_CODE_UNITS]);
+  return inferior_pid;
+}
+\f
+/* Allocate a big space in which files for kdb to read will be stored.
+   Whatever is left is where malloc can allocate storage.
+
+   Initialize it, so that there will be space in the executable file
+   for it.  Then the files can be put into kdb by writing them into
+   kdb's executable file.  */
+
+/* The default size is as much space as we expect to be available
+   for kdb to use!  */
+
+#ifndef HEAP_SIZE
+#define HEAP_SIZE 400000
+#endif
+
+char heap[HEAP_SIZE] = {0};
+
+#ifndef STACK_SIZE
+#define STACK_SIZE 100000
+#endif
+
+int kdb_stack_beg[STACK_SIZE / sizeof (int)];
+int kdb_stack_end;
+
+_initialize_standalone ()
+{
+  register char *next;
+
+  /* Find start of data on files.  */
+
+  files_start = heap;
+
+  /* Find the end of the data on files.  */
+
+  for (next - files_start; * (int *) next;
+       next += * (int *) next)
+    {}
+
+  /* That is where free storage starts for sbrk to give out.  */
+  next_free = next;
+
+  memory_limit = heap + sizeof heap;
+}
+
diff --git a/usr/src/usr.bin/gdb/grot/stuff.c b/usr/src/usr.bin/gdb/grot/stuff.c
new file mode 100644 (file)
index 0000000..7a2173b
--- /dev/null
@@ -0,0 +1,167 @@
+/* Program to stuff files into a specially prepared space in kdb.
+   Copyright (C) 1986, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Written 13-Mar-86 by David Bridgham. */
+
+#include <stdio.h>
+#include <a.out.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+
+extern char *sys_errlist[];
+extern int errno;
+
+main (argc, argv)
+     int argc;
+     char *argv[];
+{
+  register char *cp;
+  char *outfile;
+  register int i;
+  int offset;
+  int out_fd, in_fd;
+  struct stat stat_buf;
+  int size, pad;
+  char buf[1024];
+  static char zeros[4] = {0};
+
+  if (argc < 4)
+    err("Not enough arguments\nUsage: %s -o kdb file1 file2 ...\n",
+       argv[0]);
+
+  outfile = 0;
+  for (i = 1; i < argc; i++)
+    {
+      if (strcmp (argv[i], "-o") == 0)
+       outfile = argv[++i];
+    }
+  if (outfile == 0)
+    err("Output file not specified\n");
+
+  offset = get_offset (outfile, "_heap");
+
+  out_fd = open (outfile, O_WRONLY);
+  if (out_fd < 0)
+    err ("Error opening %s for write: %s\n", outfile, sys_errlist[errno]);
+  if (lseek (out_fd, offset, 0) < 0)
+    err ("Error seeking to heap in %s: %s\n", outfile, sys_errlist[errno]);
+
+  /* For each file listed on the command line, write it into the
+   * 'heap' of the output file.  Make sure to skip the arguments
+   * that name the output file. */
+  for (i = 1; i < argc; i++)
+    {
+      if (strcmp (argv[i], "-o") == 0)
+       continue;
+      if ((in_fd = open (argv[i], O_RDONLY)) < 0)
+       err ("Error opening %s for read: %s\n", argv[i], sys_errlist[errno]);
+      if (fstat (in_fd, &stat_buf) < 0)
+       err ("Error stat'ing %s: %s\n", argv[i], sys_errlist[errno]);
+      size = strlen (argv[i]);
+      pad = 4 - (size & 3);
+      size += pad + stat_buf.st_size + sizeof (int);
+      write (out_fd, &size, sizeof (int));
+      write (out_fd, argv[i], strlen (argv[i]));
+      write (out_fd, zeros, pad);
+      while ((size = read (in_fd, buf, sizeof (buf))) > 0)
+       write (out_fd, buf, size);
+      close (in_fd);
+    }
+  size = 0;
+  write (out_fd, &size, sizeof (int));
+  close (out_fd);
+  return (0);
+}
+
+/* Read symbol table from file and returns the offset into the file
+ * where symbol sym_name is located.  If error, print message and
+ * exit. */
+get_offset (file, sym_name)
+     char *file;
+     char *sym_name;
+{
+  int f;
+  struct exec file_hdr;
+  struct nlist *symbol_table;
+  int size;
+  char *strings;
+
+  f = open (file, O_RDONLY);
+  if (f < 0)
+    err ("Error opening %s: %s\n", file, sys_errlist[errno]);
+  if (read (f, &file_hdr, sizeof (file_hdr)) < 0)
+    err ("Error reading exec structure: %s\n", sys_errlist[errno]);
+  if (N_BADMAG (file_hdr))
+    err ("File %s not an a.out file\n", file);
+
+  /* read in symbol table */
+  if ((symbol_table = (struct nlist *)malloc (file_hdr.a_syms)) == 0)
+    err ("Couldn't allocate space for symbol table\n");
+  if (lseek (f, N_SYMOFF (file_hdr), 0) == -1)
+    err ("lseek error: %s\n", sys_errlist[errno]);
+  if (read (f, symbol_table, file_hdr.a_syms) == -1)
+    err ("Error reading symbol table from %s: %s\n", file, sys_errlist[errno]);
+
+  /* read in string table */
+  if (read (f, &size, 4) == -1)
+    err ("reading string table size: %s\n", sys_errlist[errno]);
+  if ((strings = (char *)malloc (size)) == 0)
+    err ("Couldn't allocate memory for string table\n");
+  if (read (f, strings, size - 4) == -1)
+    err ("reading string table: %s\n", sys_errlist[errno]);
+
+  /* Find the core address at which the first byte of kdb text segment
+     should be loaded into core when kdb is run.  */
+  origin = find_symbol ("_etext", symbol_table, file_hdr.a_syms, strings)
+    - file_hdr.a_text;
+  /* Find the core address at which the heap will appear.  */
+  coreaddr = find_symbol (sym_name, symbol_table, file_hdr.a_syms, strings);
+  /* Return address in file of the heap data space.  */
+  return (N_TXTOFF (file_hdr) + core_addr - origin);
+}
+
+find_symbol (sym_name, symbol_table, length, strings)
+     char *sym_name;
+     struct nlist *symbol_table;
+     int length;
+     char *strings;
+{
+  register struct nlist *sym;
+
+  /* Find symbol in question */
+  for (sym = symbol_table;
+       sym != (struct nlist *)((char *)symbol_table + length);
+       sym++)
+      {
+       if ((sym->n_type & N_TYPE) != N_DATA) continue;
+       if (sym->n_un.n_strx == 0) continue;
+       if (strcmp (sym_name, strings + sym->n_un.n_strx - 4) == 0)
+         return sym->n_value;
+      }
+    err ("Data symbol %s not found in %s\n", sym_name, file);
+}
+
+err (msg, a1, a2, a3)
+     char *msg;
+     int a1, a2, a3;
+{
+  fprintf (stderr, msg, a1, a2, a3);
+  exit (-1);
+}
diff --git a/usr/src/usr.bin/gdb/obstack.c b/usr/src/usr.bin/gdb/obstack.c
new file mode 100644 (file)
index 0000000..6f4b282
--- /dev/null
@@ -0,0 +1,313 @@
+/* obstack.c - subroutines used implicitly by object stack macros
+   Copyright (C) 1988 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 1, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+In other words, you are welcome to use, share and improve this program.
+You are forbidden to forbid anyone else to use, share and improve
+what you give them.   Help stamp out software-hoarding!  */
+
+
+#include "obstack.h"
+
+#ifdef __STDC__
+#define POINTER void *
+#else
+#define POINTER char *
+#endif
+
+/* Determine default alignment.  */
+struct fooalign {char x; double d;};
+#define DEFAULT_ALIGNMENT ((char *)&((struct fooalign *) 0)->d - (char *)0)
+/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
+   But in fact it might be less smart and round addresses to as much as
+   DEFAULT_ROUNDING.  So we prepare for it to do that.  */
+union fooround {long x; double d;};
+#define DEFAULT_ROUNDING (sizeof (union fooround))
+
+/* When we copy a long block of data, this is the unit to do it with.
+   On some machines, copying successive ints does not work;
+   in such a case, redefine COPYING_UNIT to `long' (if that works)
+   or `char' as a last resort.  */
+#ifndef COPYING_UNIT
+#define COPYING_UNIT int
+#endif
+
+/* The non-GNU-C macros copy the obstack into this global variable
+   to avoid multiple evaluation.  */
+
+struct obstack *_obstack;
+\f
+/* Initialize an obstack H for use.  Specify chunk size SIZE (0 means default).
+   Objects start on multiples of ALIGNMENT (0 means use default).
+   CHUNKFUN is the function to use to allocate chunks,
+   and FREEFUN the function to free them.  */
+
+void
+_obstack_begin (h, size, alignment, chunkfun, freefun)
+     struct obstack *h;
+     int size;
+     int alignment;
+     POINTER (*chunkfun) ();
+     void (*freefun) ();
+{
+  register struct _obstack_chunk* chunk; /* points to new chunk */
+
+  if (alignment == 0)
+    alignment = DEFAULT_ALIGNMENT;
+  if (size == 0)
+    /* Default size is what GNU malloc can fit in a 4096-byte block.
+       Pick a number small enough that when rounded up to DEFAULT_ROUNDING
+       it is still smaller than 4096 - 4.  */
+    {
+      int extra = 4;
+      if (extra < DEFAULT_ROUNDING)
+       extra = DEFAULT_ROUNDING;
+      size = 4096 - extra;
+    }
+
+  h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
+  h->freefun = freefun;
+  h->chunk_size = size;
+  h->alignment_mask = alignment - 1;
+
+  chunk        = h->chunk = (*h->chunkfun) (h->chunk_size);
+  h->next_free = h->object_base = chunk->contents;
+  h->chunk_limit = chunk->limit
+   = (char *) chunk + h->chunk_size;
+  chunk->prev = 0;
+}
+
+/* Allocate a new current chunk for the obstack *H
+   on the assumption that LENGTH bytes need to be added
+   to the current object, or a new object of length LENGTH allocated.
+   Copies any partial object from the end of the old chunk
+   to the beginning of the new one.  */
+
+void
+_obstack_newchunk (h, length)
+     struct obstack *h;
+     int length;
+{
+  register struct _obstack_chunk*      old_chunk = h->chunk;
+  register struct _obstack_chunk*      new_chunk;
+  register long        new_size;
+  register int obj_size = h->next_free - h->object_base;
+  register int i;
+
+  /* Compute size for new chunk.  */
+  new_size = (obj_size + length) << 1;
+  if (new_size < h->chunk_size)
+    new_size = h->chunk_size;
+
+  /* Allocate and initialize the new chunk.  */
+  new_chunk = h->chunk = (*h->chunkfun) (new_size);
+  new_chunk->prev = old_chunk;
+  new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
+
+  /* Move the existing object to the new chunk.
+     Word at a time is fast and is safe because these
+     structures are aligned at least that much.  */
+  for (i = (obj_size + sizeof (COPYING_UNIT) - 1) / sizeof (COPYING_UNIT) - 1;
+       i >= 0; i--)
+    ((COPYING_UNIT *)new_chunk->contents)[i]
+      = ((COPYING_UNIT *)h->object_base)[i];
+
+  h->object_base = new_chunk->contents;
+  h->next_free = h->object_base + obj_size;
+}
+
+/* Return nonzero if object OBJ has been allocated from obstack H.
+   This is here for debugging.
+   If you use it in a program, you are probably losing.  */
+
+int
+_obstack_allocated_p (h, obj)
+     struct obstack *h;
+     POINTER obj;
+{
+  register struct _obstack_chunk*  lp; /* below addr of any objects in this chunk */
+  register struct _obstack_chunk*  plp;        /* point to previous chunk if any */
+
+  lp = (h)->chunk;
+  while (lp != 0 && ((POINTER)lp > obj || (POINTER)(lp)->limit < obj))
+    {
+      plp = lp -> prev;
+      lp = plp;
+    }
+  return lp != 0;
+}
+
+/* Free objects in obstack H, including OBJ and everything allocate
+   more recently than OBJ.  If OBJ is zero, free everything in H.  */
+
+void
+#ifdef __STDC__
+#undef obstack_free
+obstack_free (struct obstack *h, POINTER obj)
+#else
+_obstack_free (h, obj)
+     struct obstack *h;
+     POINTER obj;
+#endif
+{
+  register struct _obstack_chunk*  lp; /* below addr of any objects in this chunk */
+  register struct _obstack_chunk*  plp;        /* point to previous chunk if any */
+
+  lp = (h)->chunk;
+  while (lp != 0 && ((POINTER)lp > obj || (POINTER)(lp)->limit < obj))
+    {
+      plp = lp -> prev;
+      (*h->freefun) (lp);
+      lp = plp;
+    }
+  if (lp)
+    {
+      (h)->object_base = (h)->next_free = (char *)(obj);
+      (h)->chunk_limit = lp->limit;
+      (h)->chunk = lp;
+    }
+  else if (obj != 0)
+    /* obj is not in any of the chunks! */
+    abort ();
+}
+
+/* Let same .o link with output of gcc and other compilers.  */
+
+#ifdef __STDC__
+void
+_obstack_free (h, obj)
+     struct obstack *h;
+     POINTER obj;
+{
+  obstack_free (h, obj);
+}
+#endif
+\f
+#if 0
+/* These are now turned off because the applications do not use it
+   and it uses bcopy via obstack_grow, which causes trouble on sysV.  */
+
+/* Now define the functional versions of the obstack macros.
+   Define them to simply use the corresponding macros to do the job.  */
+
+#ifdef __STDC__
+/* These function definitions do not work with non-ANSI preprocessors;
+   they won't pass through the macro names in parentheses.  */
+
+/* The function names appear in parentheses in order to prevent
+   the macro-definitions of the names from being expanded there.  */
+
+POINTER (obstack_base) (obstack)
+     struct obstack *obstack;
+{
+  return obstack_base (obstack);
+}
+
+POINTER (obstack_next_free) (obstack)
+     struct obstack *obstack;
+{
+  return obstack_next_free (obstack);
+}
+
+int (obstack_object_size) (obstack)
+     struct obstack *obstack;
+{
+  return obstack_object_size (obstack);
+}
+
+int (obstack_room) (obstack)
+     struct obstack *obstack;
+{
+  return obstack_room (obstack);
+}
+
+void (obstack_grow) (obstack, pointer, length)
+     struct obstack *obstack;
+     POINTER pointer;
+     int length;
+{
+  obstack_grow (obstack, pointer, length);
+}
+
+void (obstack_grow0) (obstack, pointer, length)
+     struct obstack *obstack;
+     POINTER pointer;
+     int length;
+{
+  obstack_grow0 (obstack, pointer, length);
+}
+
+void (obstack_1grow) (obstack, character)
+     struct obstack *obstack;
+     int character;
+{
+  obstack_1grow (obstack, character);
+}
+
+void (obstack_blank) (obstack, length)
+     struct obstack *obstack;
+     int length;
+{
+  obstack_blank (obstack, length);
+}
+
+void (obstack_1grow_fast) (obstack, character)
+     struct obstack *obstack;
+     int character;
+{
+  obstack_1grow_fast (obstack, character);
+}
+
+void (obstack_blank_fast) (obstack, length)
+     struct obstack *obstack;
+     int length;
+{
+  obstack_blank_fast (obstack, length);
+}
+
+POINTER (obstack_finish) (obstack)
+     struct obstack *obstack;
+{
+  return obstack_finish (obstack);
+}
+
+POINTER (obstack_alloc) (obstack, length)
+     struct obstack *obstack;
+     int length;
+{
+  return obstack_alloc (obstack, length);
+}
+
+POINTER (obstack_copy) (obstack, pointer, length)
+     struct obstack *obstack;
+     POINTER pointer;
+     int length;
+{
+  return obstack_copy (obstack, pointer, length);
+}
+
+POINTER (obstack_copy0) (obstack, pointer, length)
+     struct obstack *obstack;
+     POINTER pointer;
+     int length;
+{
+  return obstack_copy0 (obstack, pointer, length);
+}
+
+#endif /* __STDC__ */
+
+#endif /* 0 */
diff --git a/usr/src/usr.bin/gdb/obstack.h b/usr/src/usr.bin/gdb/obstack.h
new file mode 100644 (file)
index 0000000..27c017e
--- /dev/null
@@ -0,0 +1,372 @@
+/* obstack.h - object stack macros
+   Copyright (C) 1988 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 1, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+In other words, you are welcome to use, share and improve this program.
+You are forbidden to forbid anyone else to use, share and improve
+what you give them.   Help stamp out software-hoarding!  */
+
+
+/* Summary:
+
+All the apparent functions defined here are macros. The idea
+is that you would use these pre-tested macros to solve a
+very specific set of problems, and they would run fast.
+Caution: no side-effects in arguments please!! They may be
+evaluated MANY times!!
+
+These macros operate a stack of objects.  Each object starts life
+small, and may grow to maturity.  (Consider building a word syllable
+by syllable.)  An object can move while it is growing.  Once it has
+been "finished" it never changes address again.  So the "top of the
+stack" is typically an immature growing object, while the rest of the
+stack is of mature, fixed size and fixed address objects.
+
+These routines grab large chunks of memory, using a function you
+supply, called `obstack_chunk_alloc'.  On occasion, they free chunks,
+by calling `obstack_chunk_free'.  You must define them and declare
+them before using any obstack macros.
+
+Each independent stack is represented by a `struct obstack'.
+Each of the obstack macros expects a pointer to such a structure
+as the first argument.
+
+One motivation for this package is the problem of growing char strings
+in symbol tables.  Unless you are "facist pig with a read-only mind"
+[Gosper's immortal quote from HAKMEM item 154, out of context] you
+would not like to put any arbitrary upper limit on the length of your
+symbols.
+
+In practice this often means you will build many short symbols and a
+few long symbols.  At the time you are reading a symbol you don't know
+how long it is.  One traditional method is to read a symbol into a
+buffer, realloc()ating the buffer every time you try to read a symbol
+that is longer than the buffer.  This is beaut, but you still will
+want to copy the symbol from the buffer to a more permanent
+symbol-table entry say about half the time.
+
+With obstacks, you can work differently.  Use one obstack for all symbol
+names.  As you read a symbol, grow the name in the obstack gradually.
+When the name is complete, finalize it.  Then, if the symbol exists already,
+free the newly read name.
+
+The way we do this is to take a large chunk, allocating memory from
+low addresses.  When you want to build a aymbol in the chunk you just
+add chars above the current "high water mark" in the chunk.  When you
+have finished adding chars, because you got to the end of the symbol,
+you know how long the chars are, and you can create a new object.
+Mostly the chars will not burst over the highest address of the chunk,
+because you would typically expect a chunk to be (say) 100 times as
+long as an average object.
+
+In case that isn't clear, when we have enough chars to make up
+the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
+so we just point to it where it lies.  No moving of chars is
+needed and this is the second win: potentially long strings need
+never be explicitly shuffled. Once an object is formed, it does not
+change its address during its lifetime.
+
+When the chars burst over a chunk boundary, we allocate a larger
+chunk, and then copy the partly formed object from the end of the old
+chunk to the beggining of the new larger chunk.  We then carry on
+accreting characters to the end of the object as we normaly would.
+
+A special macro is provided to add a single char at a time to a
+growing object.  This allows the use of register variables, which
+break the ordinary 'growth' macro.
+
+Summary:
+       We allocate large chunks.
+       We carve out one object at a time from the current chunk.
+       Once carved, an object never moves.
+       We are free to append data of any size to the currently
+         growing object.
+       Exactly one object is growing in an obstack at any one time.
+       You can run one obstack per control block.
+       You may have as many control blocks as you dare.
+       Because of the way we do it, you can `unwind' a obstack
+         back to a previous state. (You may remove objects much
+         as you would with a stack.)
+*/
+
+
+/* Don't do the contents of this file more than once.  */
+
+#ifndef __OBSTACKS__
+#define __OBSTACKS__
+\f
+/* We use subtraction of (char *)0 instead of casting to int
+   because on word-addressable machines a simple cast to int
+   may ignore the byte-within-word field of the pointer.  */
+
+#ifndef __PTR_TO_INT
+#define __PTR_TO_INT(P) ((P) - (char *)0)
+#endif
+
+#ifndef __INT_TO_PTR
+#define __INT_TO_PTR(P) ((P) + (char *)0)
+#endif
+
+struct _obstack_chunk          /* Lives at front of each chunk. */
+{
+  char  *limit;                        /* 1 past end of this chunk */
+  struct _obstack_chunk *prev; /* address of prior chunk or NULL */
+  char contents[4];            /* objects begin here */
+};
+
+struct obstack         /* control current object in current chunk */
+{
+  long chunk_size;             /* preferred size to allocate chunks in */
+  struct _obstack_chunk* chunk;        /* address of current struct obstack_chunk */
+  char *object_base;           /* address of object we are building */
+  char *next_free;             /* where to add next char to current object */
+  char *chunk_limit;           /* address of char after current chunk */
+  int  temp;                   /* Temporary for some macros.  */
+  int   alignment_mask;                /* Mask of alignment for each object. */
+  struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk.  */
+  void (*freefun) ();          /* User's function to free a chunk.  */
+};
+\f
+#ifdef __STDC__
+
+/* Do the function-declarations after the structs
+   but before defining the macros.  */
+
+void obstack_init (struct obstack *obstack);
+
+void * obstack_alloc (struct obstack *obstack, int size);
+
+void * obstack_copy (struct obstack *obstack, void *address, int size);
+void * obstack_copy0 (struct obstack *obstack, void *address, int size);
+
+void obstack_free (struct obstack *obstack, void *block);
+
+void obstack_blank (struct obstack *obstack, int size);
+
+void obstack_grow (struct obstack *obstack, void *data, int size);
+void obstack_grow0 (struct obstack *obstack, void *data, int size);
+
+void obstack_1grow (struct obstack *obstack, int data_char);
+
+void * obstack_finish (struct obstack *obstack);
+
+int obstack_object_size (struct obstack *obstack);
+
+int obstack_room (struct obstack *obstack);
+void obstack_1grow_fast (struct obstack *obstack, int data_char);
+void obstack_blank_fast (struct obstack *obstack, int size);
+
+void * obstack_base (struct obstack *obstack);
+void * obstack_next_free (struct obstack *obstack);
+int obstack_alignment_mask (struct obstack *obstack);
+int obstack_chunk_size (struct obstack *obstack);
+
+#endif /* __STDC__ */
+
+/* Non-ANSI C cannot really support alternative functions for these macros,
+   so we do not declare them.  */
+\f
+/* Pointer to beginning of object being allocated or to be allocated next.
+   Note that this might not be the final address of the object
+   because a new chunk might be needed to hold the final size.  */
+
+#define obstack_base(h) ((h)->object_base)
+
+/* Size for allocating ordinary chunks.  */
+
+#define obstack_chunk_size(h) ((h)->chunk_size)
+
+/* Pointer to next byte not yet allocated in current chunk.  */
+
+#define obstack_next_free(h)   ((h)->next_free)
+
+/* Mask specifying low bits that should be clear in address of an object.  */
+
+#define obstack_alignment_mask(h) ((h)->alignment_mask)
+
+#define obstack_init(h) \
+  _obstack_begin ((h), 0, 0, obstack_chunk_alloc, obstack_chunk_free)
+
+#define obstack_begin(h, size) \
+  _obstack_begin ((h), (size), 0, obstack_chunk_alloc, obstack_chunk_free)
+
+#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar)
+
+#define obstack_blank_fast(h,n) ((h)->next_free += (n))
+\f
+#if defined (__GNUC__) && defined (__STDC__)
+
+/* For GNU C, if not -traditional,
+   we can define these macros to compute all args only once
+   without using a global variable.
+   Also, we can avoid using the `temp' slot, to make faster code.  */
+
+#define obstack_object_size(OBSTACK)                                   \
+  ({ struct obstack *__o = (OBSTACK);                                  \
+     (unsigned) (__o->next_free - __o->object_base); })
+
+#define obstack_room(OBSTACK)                                          \
+  ({ struct obstack *__o = (OBSTACK);                                  \
+     (unsigned) (__o->chunk_limit - __o->next_free); })
+
+#define obstack_grow(OBSTACK,where,length)                             \
+({ struct obstack *__o = (OBSTACK);                                    \
+   int __len = (length);                                               \
+   ((__o->next_free + __len > __o->chunk_limit)                                \
+    ? _obstack_newchunk (__o, __len) : 0);                             \
+   bcopy (where, __o->next_free, __len);                               \
+   __o->next_free += __len;                                            \
+   (void) 0; })
+
+#define obstack_grow0(OBSTACK,where,length)                            \
+({ struct obstack *__o = (OBSTACK);                                    \
+   int __len = (length);                                               \
+   ((__o->next_free + __len + 1 > __o->chunk_limit)                    \
+    ? _obstack_newchunk (__o, __len + 1) : 0),                         \
+   bcopy (where, __o->next_free, __len),                               \
+   __o->next_free += __len,                                            \
+   *(__o->next_free)++ = 0;                                            \
+   (void) 0; })
+
+#define obstack_1grow(OBSTACK,datum)                                   \
+({ struct obstack *__o = (OBSTACK);                                    \
+   ((__o->next_free + 1 > __o->chunk_limit)                            \
+    ? _obstack_newchunk (__o, 1) : 0),                                 \
+   *(__o->next_free)++ = (datum);                                      \
+   (void) 0; })
+
+#define obstack_blank(OBSTACK,length)                                  \
+({ struct obstack *__o = (OBSTACK);                                    \
+   int __len = (length);                                               \
+   ((__o->next_free + __len > __o->chunk_limit)                                \
+    ? _obstack_newchunk (__o, __len) : 0);                             \
+   __o->next_free += __len;                                            \
+   (void) 0; })
+
+#define obstack_alloc(OBSTACK,length)                                  \
+({ struct obstack *__h = (OBSTACK);                                    \
+   obstack_blank (__h, (length));                                      \
+   obstack_finish (__h); })
+
+#define obstack_copy(OBSTACK,where,length)                             \
+({ struct obstack *__h = (OBSTACK);                                    \
+   obstack_grow (__h, (where), (length));                              \
+   obstack_finish (__h); })
+
+#define obstack_copy0(OBSTACK,where,length)                            \
+({ struct obstack *__h = (OBSTACK);                                    \
+   obstack_grow0 (__h, (where), (length));                             \
+   obstack_finish (__h); })
+
+#define obstack_finish(OBSTACK)                                        \
+({ struct obstack *__o = (OBSTACK);                                    \
+   void *value = (void *) __o->object_base;                            \
+   __o->next_free                                                      \
+     = __INT_TO_PTR ((__PTR_TO_INT (__o->next_free)+__o->alignment_mask)\
+                    & ~ (__o->alignment_mask));                        \
+   ((__o->next_free - (char *)__o->chunk                               \
+     > __o->chunk_limit - (char *)__o->chunk)                          \
+    ? (__o->next_free = __o->chunk_limit) : 0);                                \
+   __o->object_base = __o->next_free;                                  \
+   value; })
+
+#define obstack_free(OBSTACK, OBJ)                                     \
+({ struct obstack *__o = (OBSTACK);                                    \
+   void *__obj = (OBJ);                                                        \
+   if (__obj >= (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \
+     __o->next_free = __o->object_base = __obj;                                \
+   else (obstack_free) (__o, __obj); })
+\f
+#else /* not __GNUC__ or not __STDC__ */
+
+/* The non-GNU macros copy the obstack-pointer into this global variable
+   to avoid multiple evaluation.  */
+
+extern struct obstack *_obstack;
+
+#define obstack_object_size(h) \
+ (unsigned) (_obstack = (h), (h)->next_free - (h)->object_base)
+
+#define obstack_room(h)                \
+ (unsigned) (_obstack = (h), (h)->chunk_limit - (h)->next_free)
+
+#define obstack_grow(h,where,length)                                   \
+( (h)->temp = (length),                                                        \
+  (((h)->next_free + (h)->temp > (h)->chunk_limit)                     \
+   ? _obstack_newchunk ((h), (h)->temp) : 0),                          \
+  bcopy (where, (h)->next_free, (h)->temp),                            \
+  (h)->next_free += (h)->temp)
+
+#define obstack_grow0(h,where,length)                                  \
+( (h)->temp = (length),                                                        \
+  (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit)                 \
+   ? _obstack_newchunk ((h), (h)->temp + 1) : 0),                              \
+  bcopy (where, (h)->next_free, (h)->temp),                            \
+  (h)->next_free += (h)->temp,                                         \
+  *((h)->next_free)++ = 0)
+
+#define obstack_1grow(h,datum)                                         \
+( (((h)->next_free + 1 > (h)->chunk_limit)                             \
+   ? _obstack_newchunk ((h), 1) : 0),                                  \
+  *((h)->next_free)++ = (datum))
+
+#define obstack_blank(h,length)                                                \
+( (h)->temp = (length),                                                        \
+  (((h)->next_free + (h)->temp > (h)->chunk_limit)                     \
+   ? _obstack_newchunk ((h), (h)->temp) : 0),                          \
+  (h)->next_free += (h)->temp)
+
+#define obstack_alloc(h,length)                                                \
+ (obstack_blank ((h), (length)), obstack_finish ((h)))
+
+#define obstack_copy(h,where,length)                                   \
+ (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
+
+#define obstack_copy0(h,where,length)                                  \
+ (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
+
+#define obstack_finish(h)                                              \
+( (h)->temp = __PTR_TO_INT ((h)->object_base),                         \
+  (h)->next_free                                                       \
+    = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask)        \
+                   & ~ ((h)->alignment_mask)),                         \
+  (((h)->next_free - (char *)(h)->chunk                                        \
+    > (h)->chunk_limit - (char *)(h)->chunk)                           \
+   ? ((h)->next_free = (h)->chunk_limit) : 0),                         \
+  (h)->object_base = (h)->next_free,                                   \
+  __INT_TO_PTR ((h)->temp))
+
+#ifdef __STDC__
+#define obstack_free(h,obj)                                            \
+( (h)->temp = (char *)(obj) - (char *) (h)->chunk,                     \
+  (((h)->temp >= 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
+   ? (int) ((h)->next_free = (h)->object_base                          \
+           = (h)->temp + (char *) (h)->chunk)                          \
+   : ((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0)))
+#else
+#define obstack_free(h,obj)                                            \
+( (h)->temp = (char *)(obj) - (char *) (h)->chunk,                     \
+  (((h)->temp >= 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
+   ? (int) ((h)->next_free = (h)->object_base                          \
+           = (h)->temp + (char *) (h)->chunk)                          \
+   : (int) _obstack_free ((h), (h)->temp + (char *) (h)->chunk)))
+#endif
+
+#endif /* not __GNUC__ or not __STDC__ */
+
+#endif /* not __OBSTACKS__ */
+
diff --git a/usr/src/usr.bin/gdb/regex.c b/usr/src/usr.bin/gdb/regex.c
new file mode 100644 (file)
index 0000000..45c3478
--- /dev/null
@@ -0,0 +1,1738 @@
+/* Extended regular expression matching and search library.
+   Copyright (C) 1985, 1989 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+   In other words, you are welcome to use, share and improve this program.
+   You are forbidden to forbid anyone else to use, share and improve
+   what you give them.   Help stamp out software-hoarding!  */
+
+
+/* To test, compile with -Dtest.
+ This Dtestable feature turns this into a self-contained program
+ which reads a pattern, describes how it compiles,
+ then reads a string and searches for it.  */
+
+#ifdef emacs
+
+/* The `emacs' switch turns on certain special matching commands
+ that make sense only in emacs. */
+
+#include "config.h"
+#include "lisp.h"
+#include "buffer.h"
+#include "syntax.h"
+
+#else  /* not emacs */
+
+#ifdef USG
+#ifndef BSTRING
+#define bcopy(s,d,n)   memcpy((d),(s),(n))
+#define bcmp(s1,s2,n)  memcmp((s1),(s2),(n))
+#define bzero(s,n)     memset((s),0,(n))
+#endif
+#endif
+
+/* Make alloca work the best possible way.  */
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else
+#ifdef sparc
+#include <alloca.h>
+#endif
+#endif
+
+/*
+ * Define the syntax stuff, so we can do the \<...\> things.
+ */
+
+#ifndef Sword /* must be non-zero in some of the tests below... */
+#define Sword 1
+#endif
+
+#define SYNTAX(c) re_syntax_table[c]
+
+#ifdef SYNTAX_TABLE
+
+char *re_syntax_table;
+
+#else
+
+static char re_syntax_table[256];
+
+static void
+init_syntax_once ()
+{
+   register int c;
+   static int done = 0;
+
+   if (done)
+     return;
+
+   bzero (re_syntax_table, sizeof re_syntax_table);
+
+   for (c = 'a'; c <= 'z'; c++)
+     re_syntax_table[c] = Sword;
+
+   for (c = 'A'; c <= 'Z'; c++)
+     re_syntax_table[c] = Sword;
+
+   for (c = '0'; c <= '9'; c++)
+     re_syntax_table[c] = Sword;
+
+   done = 1;
+}
+
+#endif /* SYNTAX_TABLE */
+#endif /* not emacs */
+
+#include "regex.h"
+
+/* Number of failure points to allocate space for initially,
+ when matching.  If this number is exceeded, more space is allocated,
+ so it is not a hard limit.  */
+
+#ifndef NFAILURES
+#define NFAILURES 80
+#endif /* NFAILURES */
+
+/* width of a byte in bits */
+
+#define BYTEWIDTH 8
+
+#ifndef SIGN_EXTEND_CHAR
+#define SIGN_EXTEND_CHAR(x) (x)
+#endif
+\f
+static int obscure_syntax = 0;
+
+/* Specify the precise syntax of regexp for compilation.
+   This provides for compatibility for various utilities
+   which historically have different, incompatible syntaxes.
+
+   The argument SYNTAX is a bit-mask containing the two bits
+   RE_NO_BK_PARENS and RE_NO_BK_VBAR.  */
+
+int
+re_set_syntax (syntax)
+{
+  int ret;
+
+  ret = obscure_syntax;
+  obscure_syntax = syntax;
+  return ret;
+}
+\f
+/* re_compile_pattern takes a regular-expression string
+   and converts it into a buffer full of byte commands for matching.
+
+  PATTERN   is the address of the pattern string
+  SIZE      is the length of it.
+  BUFP     is a  struct re_pattern_buffer *  which points to the info
+           on where to store the byte commands.
+           This structure contains a  char *  which points to the
+           actual space, which should have been obtained with malloc.
+           re_compile_pattern may use  realloc  to grow the buffer space.
+
+  The number of bytes of commands can be found out by looking in
+  the  struct re_pattern_buffer  that bufp pointed to,
+  after re_compile_pattern returns.
+*/
+
+#define PATPUSH(ch) (*b++ = (char) (ch))
+
+#define PATFETCH(c) \
+ {if (p == pend) goto end_of_pattern; \
+  c = * (unsigned char *) p++; \
+  if (translate) c = translate[c]; }
+
+#define PATFETCH_RAW(c) \
+ {if (p == pend) goto end_of_pattern; \
+  c = * (unsigned char *) p++; }
+
+#define PATUNFETCH p--
+
+#define EXTEND_BUFFER \
+  { char *old_buffer = bufp->buffer; \
+    if (bufp->allocated == (1<<16)) goto too_big; \
+    bufp->allocated *= 2; \
+    if (bufp->allocated > (1<<16)) bufp->allocated = (1<<16); \
+    if (!(bufp->buffer = (char *) realloc (bufp->buffer, bufp->allocated))) \
+      goto memory_exhausted; \
+    c = bufp->buffer - old_buffer; \
+    b += c; \
+    if (fixup_jump) \
+      fixup_jump += c; \
+    if (laststart) \
+      laststart += c; \
+    begalt += c; \
+    if (pending_exact) \
+      pending_exact += c; \
+  }
+
+static int store_jump (), insert_jump ();
+
+char *
+re_compile_pattern (pattern, size, bufp)
+     char *pattern;
+     int size;
+     struct re_pattern_buffer *bufp;
+{
+  register char *b = bufp->buffer;
+  register char *p = pattern;
+  char *pend = pattern + size;
+  register unsigned c, c1;
+  char *p1;
+  unsigned char *translate = (unsigned char *) bufp->translate;
+
+  /* address of the count-byte of the most recently inserted "exactn" command.
+    This makes it possible to tell whether a new exact-match character
+    can be added to that command or requires a new "exactn" command. */
+     
+  char *pending_exact = 0;
+
+  /* address of the place where a forward-jump should go
+    to the end of the containing expression.
+    Each alternative of an "or", except the last, ends with a forward-jump
+    of this sort. */
+
+  char *fixup_jump = 0;
+
+  /* address of start of the most recently finished expression.
+    This tells postfix * where to find the start of its operand. */
+
+  char *laststart = 0;
+
+  /* In processing a repeat, 1 means zero matches is allowed */
+
+  char zero_times_ok;
+
+  /* In processing a repeat, 1 means many matches is allowed */
+
+  char many_times_ok;
+
+  /* address of beginning of regexp, or inside of last \( */
+
+  char *begalt = b;
+
+  /* Stack of information saved by \( and restored by \).
+     Four stack elements are pushed by each \(:
+       First, the value of b.
+       Second, the value of fixup_jump.
+       Third, the value of regnum.
+       Fourth, the value of begalt.  */
+
+  int stackb[40];
+  int *stackp = stackb;
+  int *stacke = stackb + 40;
+  int *stackt;
+
+  /* Counts \('s as they are encountered.  Remembered for the matching \),
+     where it becomes the "register number" to put in the stop_memory command */
+
+  int regnum = 1;
+
+  bufp->fastmap_accurate = 0;
+
+#ifndef emacs
+#ifndef SYNTAX_TABLE
+  /*
+   * Initialize the syntax table.
+   */
+   init_syntax_once();
+#endif
+#endif
+
+  if (bufp->allocated == 0)
+    {
+      bufp->allocated = 28;
+      if (bufp->buffer)
+       /* EXTEND_BUFFER loses when bufp->allocated is 0 */
+       bufp->buffer = (char *) realloc (bufp->buffer, 28);
+      else
+       /* Caller did not allocate a buffer.  Do it for him */
+       bufp->buffer = (char *) malloc (28);
+      if (!bufp->buffer) goto memory_exhausted;
+      begalt = b = bufp->buffer;
+    }
+
+  while (p != pend)
+    {
+      if (b - bufp->buffer > bufp->allocated - 10)
+       /* Note that EXTEND_BUFFER clobbers c */
+       EXTEND_BUFFER;
+
+      PATFETCH (c);
+
+      switch (c)
+       {
+       case '$':
+         if (obscure_syntax & RE_TIGHT_VBAR)
+           {
+             if (! (obscure_syntax & RE_CONTEXT_INDEP_OPS) && p != pend)
+               goto normal_char;
+             /* Make operand of last vbar end before this `$'.  */
+             if (fixup_jump)
+               store_jump (fixup_jump, jump, b);
+             fixup_jump = 0;
+             PATPUSH (endline);
+             break;
+           }
+
+         /* $ means succeed if at end of line, but only in special contexts.
+           If randomly in the middle of a pattern, it is a normal character. */
+         if (p == pend || *p == '\n'
+             || (obscure_syntax & RE_CONTEXT_INDEP_OPS)
+             || (obscure_syntax & RE_NO_BK_PARENS
+                 ? *p == ')'
+                 : *p == '\\' && p[1] == ')')
+             || (obscure_syntax & RE_NO_BK_VBAR
+                 ? *p == '|'
+                 : *p == '\\' && p[1] == '|'))
+           {
+             PATPUSH (endline);
+             break;
+           }
+         goto normal_char;
+
+       case '^':
+         /* ^ means succeed if at beg of line, but only if no preceding pattern. */
+
+         if (laststart && p[-2] != '\n'
+             && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
+           goto normal_char;
+         if (obscure_syntax & RE_TIGHT_VBAR)
+           {
+             if (p != pattern + 1
+                 && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
+               goto normal_char;
+             PATPUSH (begline);
+             begalt = b;
+           }
+         else
+           PATPUSH (begline);
+         break;
+
+       case '+':
+       case '?':
+         if (obscure_syntax & RE_BK_PLUS_QM)
+           goto normal_char;
+       handle_plus:
+       case '*':
+         /* If there is no previous pattern, char not special. */
+         if (!laststart && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
+           goto normal_char;
+         /* If there is a sequence of repetition chars,
+            collapse it down to equivalent to just one.  */
+         zero_times_ok = 0;
+         many_times_ok = 0;
+         while (1)
+           {
+             zero_times_ok |= c != '+';
+             many_times_ok |= c != '?';
+             if (p == pend)
+               break;
+             PATFETCH (c);
+             if (c == '*')
+               ;
+             else if (!(obscure_syntax & RE_BK_PLUS_QM)
+                      && (c == '+' || c == '?'))
+               ;
+             else if ((obscure_syntax & RE_BK_PLUS_QM)
+                      && c == '\\')
+               {
+                 int c1;
+                 PATFETCH (c1);
+                 if (!(c1 == '+' || c1 == '?'))
+                   {
+                     PATUNFETCH;
+                     PATUNFETCH;
+                     break;
+                   }
+                 c = c1;
+               }
+             else
+               {
+                 PATUNFETCH;
+                 break;
+               }
+           }
+
+         /* Star, etc. applied to an empty pattern is equivalent
+            to an empty pattern.  */
+         if (!laststart)
+           break;
+
+         /* Now we know whether 0 matches is allowed,
+            and whether 2 or more matches is allowed.  */
+         if (many_times_ok)
+           {
+             /* If more than one repetition is allowed,
+                put in a backward jump at the end.  */
+             store_jump (b, maybe_finalize_jump, laststart - 3);
+             b += 3;
+           }
+         insert_jump (on_failure_jump, laststart, b + 3, b);
+         pending_exact = 0;
+         b += 3;
+         if (!zero_times_ok)
+           {
+             /* At least one repetition required: insert before the loop
+                a skip over the initial on-failure-jump instruction */
+             insert_jump (dummy_failure_jump, laststart, laststart + 6, b);
+             b += 3;
+           }
+         break;
+
+       case '.':
+         laststart = b;
+         PATPUSH (anychar);
+         break;
+
+       case '[':
+         while (b - bufp->buffer
+                > bufp->allocated - 3 - (1 << BYTEWIDTH) / BYTEWIDTH)
+           /* Note that EXTEND_BUFFER clobbers c */
+           EXTEND_BUFFER;
+
+         laststart = b;
+         if (*p == '^')
+           PATPUSH (charset_not), p++;
+         else
+           PATPUSH (charset);
+         p1 = p;
+
+         PATPUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
+         /* Clear the whole map */
+         bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
+         /* Read in characters and ranges, setting map bits */
+         while (1)
+           {
+             PATFETCH (c);
+             if (c == ']' && p != p1 + 1) break;
+             if (*p == '-' && p[1] != ']')
+               {
+                 PATFETCH (c1);
+                 PATFETCH (c1);
+                 while (c <= c1)
+                   b[c / BYTEWIDTH] |= 1 << (c % BYTEWIDTH), c++;
+               }
+             else
+               {
+                 b[c / BYTEWIDTH] |= 1 << (c % BYTEWIDTH);
+               }
+           }
+         /* Discard any bitmap bytes that are all 0 at the end of the map.
+            Decrement the map-length byte too. */
+         while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
+           b[-1]--;
+         b += b[-1];
+         break;
+
+       case '(':
+         if (! (obscure_syntax & RE_NO_BK_PARENS))
+           goto normal_char;
+         else
+           goto handle_open;
+
+       case ')':
+         if (! (obscure_syntax & RE_NO_BK_PARENS))
+           goto normal_char;
+         else
+           goto handle_close;
+
+       case '\n':
+         if (! (obscure_syntax & RE_NEWLINE_OR))
+           goto normal_char;
+         else
+           goto handle_bar;
+
+       case '|':
+         if (! (obscure_syntax & RE_NO_BK_VBAR))
+           goto normal_char;
+         else
+           goto handle_bar;
+
+        case '\\':
+         if (p == pend) goto invalid_pattern;
+         PATFETCH_RAW (c);
+         switch (c)
+           {
+           case '(':
+             if (obscure_syntax & RE_NO_BK_PARENS)
+               goto normal_backsl;
+           handle_open:
+             if (stackp == stacke) goto nesting_too_deep;
+             if (regnum < RE_NREGS)
+               {
+                 PATPUSH (start_memory);
+                 PATPUSH (regnum);
+               }
+             *stackp++ = b - bufp->buffer;
+             *stackp++ = fixup_jump ? fixup_jump - bufp->buffer + 1 : 0;
+             *stackp++ = regnum++;
+             *stackp++ = begalt - bufp->buffer;
+             fixup_jump = 0;
+             laststart = 0;
+             begalt = b;
+             break;
+
+           case ')':
+             if (obscure_syntax & RE_NO_BK_PARENS)
+               goto normal_backsl;
+           handle_close:
+             if (stackp == stackb) goto unmatched_close;
+             begalt = *--stackp + bufp->buffer;
+             if (fixup_jump)
+               store_jump (fixup_jump, jump, b);
+             if (stackp[-1] < RE_NREGS)
+               {
+                 PATPUSH (stop_memory);
+                 PATPUSH (stackp[-1]);
+               }
+             stackp -= 2;
+             fixup_jump = 0;
+             if (*stackp)
+               fixup_jump = *stackp + bufp->buffer - 1;
+             laststart = *--stackp + bufp->buffer;
+             break;
+
+           case '|':
+             if (obscure_syntax & RE_NO_BK_VBAR)
+               goto normal_backsl;
+           handle_bar:
+             insert_jump (on_failure_jump, begalt, b + 6, b);
+             pending_exact = 0;
+             b += 3;
+             if (fixup_jump)
+               store_jump (fixup_jump, jump, b);
+             fixup_jump = b;
+             b += 3;
+             laststart = 0;
+             begalt = b;
+             break;
+
+#ifdef emacs
+           case '=':
+             PATPUSH (at_dot);
+             break;
+
+           case 's':   
+             laststart = b;
+             PATPUSH (syntaxspec);
+             PATFETCH (c);
+             PATPUSH (syntax_spec_code[c]);
+             break;
+
+           case 'S':
+             laststart = b;
+             PATPUSH (notsyntaxspec);
+             PATFETCH (c);
+             PATPUSH (syntax_spec_code[c]);
+             break;
+#endif /* emacs */
+
+           case 'w':
+             laststart = b;
+             PATPUSH (wordchar);
+             break;
+
+           case 'W':
+             laststart = b;
+             PATPUSH (notwordchar);
+             break;
+
+           case '<':
+             PATPUSH (wordbeg);
+             break;
+
+           case '>':
+             PATPUSH (wordend);
+             break;
+
+           case 'b':
+             PATPUSH (wordbound);
+             break;
+
+           case 'B':
+             PATPUSH (notwordbound);
+             break;
+
+           case '`':
+             PATPUSH (begbuf);
+             break;
+
+           case '\'':
+             PATPUSH (endbuf);
+             break;
+
+           case '1':
+           case '2':
+           case '3':
+           case '4':
+           case '5':
+           case '6':
+           case '7':
+           case '8':
+           case '9':
+             c1 = c - '0';
+             if (c1 >= regnum)
+               goto normal_char;
+             for (stackt = stackp - 2;  stackt > stackb;  stackt -= 4)
+               if (*stackt == c1)
+                 goto normal_char;
+             laststart = b;
+             PATPUSH (duplicate);
+             PATPUSH (c1);
+             break;
+
+           case '+':
+           case '?':
+             if (obscure_syntax & RE_BK_PLUS_QM)
+               goto handle_plus;
+
+           default:
+           normal_backsl:
+             /* You might think it would be useful for \ to mean
+                not to translate; but if we don't translate it
+                it will never match anything.  */
+             if (translate) c = translate[c];
+             goto normal_char;
+           }
+         break;
+
+       default:
+       normal_char:
+         if (!pending_exact || pending_exact + *pending_exact + 1 != b
+             || *pending_exact == 0177 || *p == '*' || *p == '^'
+             || ((obscure_syntax & RE_BK_PLUS_QM)
+                 ? *p == '\\' && (p[1] == '+' || p[1] == '?')
+                 : (*p == '+' || *p == '?')))
+           {
+             laststart = b;
+             PATPUSH (exactn);
+             pending_exact = b;
+             PATPUSH (0);
+           }
+         PATPUSH (c);
+         (*pending_exact)++;
+       }
+    }
+
+  if (fixup_jump)
+    store_jump (fixup_jump, jump, b);
+
+  if (stackp != stackb) goto unmatched_open;
+
+  bufp->used = b - bufp->buffer;
+  return 0;
+
+ invalid_pattern:
+  return "Invalid regular expression";
+
+ unmatched_open:
+  return "Unmatched \\(";
+
+ unmatched_close:
+  return "Unmatched \\)";
+
+ end_of_pattern:
+  return "Premature end of regular expression";
+
+ nesting_too_deep:
+  return "Nesting too deep";
+
+ too_big:
+  return "Regular expression too big";
+
+ memory_exhausted:
+  return "Memory exhausted";
+}
+
+/* Store where `from' points a jump operation to jump to where `to' points.
+  `opcode' is the opcode to store. */
+
+static int
+store_jump (from, opcode, to)
+     char *from, *to;
+     char opcode;
+{
+  from[0] = opcode;
+  from[1] = (to - (from + 3)) & 0377;
+  from[2] = (to - (from + 3)) >> 8;
+}
+
+/* Open up space at char FROM, and insert there a jump to TO.
+   CURRENT_END gives te end of the storage no in use,
+   so we know how much data to copy up.
+   OP is the opcode of the jump to insert.
+
+   If you call this function, you must zero out pending_exact.  */
+
+static int
+insert_jump (op, from, to, current_end)
+     char op;
+     char *from, *to, *current_end;
+{
+  register char *pto = current_end + 3;
+  register char *pfrom = current_end;
+  while (pfrom != from)
+    *--pto = *--pfrom;
+  store_jump (from, op, to);
+}
+\f
+/* Given a pattern, compute a fastmap from it.
+ The fastmap records which of the (1 << BYTEWIDTH) possible characters
+ can start a string that matches the pattern.
+ This fastmap is used by re_search to skip quickly over totally implausible text.
+
+ The caller must supply the address of a (1 << BYTEWIDTH)-byte data area
+ as bufp->fastmap.
+ The other components of bufp describe the pattern to be used.  */
+
+void
+re_compile_fastmap (bufp)
+     struct re_pattern_buffer *bufp;
+{
+  unsigned char *pattern = (unsigned char *) bufp->buffer;
+  int size = bufp->used;
+  register char *fastmap = bufp->fastmap;
+  register unsigned char *p = pattern;
+  register unsigned char *pend = pattern + size;
+  register int j, k;
+  unsigned char *translate = (unsigned char *) bufp->translate;
+
+  unsigned char *stackb[NFAILURES];
+  unsigned char **stackp = stackb;
+
+  bzero (fastmap, (1 << BYTEWIDTH));
+  bufp->fastmap_accurate = 1;
+  bufp->can_be_null = 0;
+      
+  while (p)
+    {
+      if (p == pend)
+       {
+         bufp->can_be_null = 1;
+         break;
+       }
+#ifdef SWITCH_ENUM_BUG
+      switch ((int) ((enum regexpcode) *p++))
+#else
+      switch ((enum regexpcode) *p++)
+#endif
+       {
+       case exactn:
+         if (translate)
+           fastmap[translate[p[1]]] = 1;
+         else
+           fastmap[p[1]] = 1;
+         break;
+
+        case begline:
+        case before_dot:
+       case at_dot:
+       case after_dot:
+       case begbuf:
+       case endbuf:
+       case wordbound:
+       case notwordbound:
+       case wordbeg:
+       case wordend:
+         continue;
+
+       case endline:
+         if (translate)
+           fastmap[translate['\n']] = 1;
+         else
+           fastmap['\n'] = 1;
+         if (bufp->can_be_null != 1)
+           bufp->can_be_null = 2;
+         break;
+
+       case finalize_jump:
+       case maybe_finalize_jump:
+       case jump:
+       case dummy_failure_jump:
+         bufp->can_be_null = 1;
+         j = *p++ & 0377;
+         j += SIGN_EXTEND_CHAR (*(char *)p) << 8;
+         p += j + 1;           /* The 1 compensates for missing ++ above */
+         if (j > 0)
+           continue;
+         /* Jump backward reached implies we just went through
+            the body of a loop and matched nothing.
+            Opcode jumped to should be an on_failure_jump.
+            Just treat it like an ordinary jump.
+            For a * loop, it has pushed its failure point already;
+            if so, discard that as redundant.  */
+         if ((enum regexpcode) *p != on_failure_jump)
+           continue;
+         p++;
+         j = *p++ & 0377;
+         j += SIGN_EXTEND_CHAR (*(char *)p) << 8;
+         p += j + 1;           /* The 1 compensates for missing ++ above */
+         if (stackp != stackb && *stackp == p)
+           stackp--;
+         continue;
+         
+       case on_failure_jump:
+         j = *p++ & 0377;
+         j += SIGN_EXTEND_CHAR (*(char *)p) << 8;
+         p++;
+         *++stackp = p + j;
+         continue;
+
+       case start_memory:
+       case stop_memory:
+         p++;
+         continue;
+
+       case duplicate:
+         bufp->can_be_null = 1;
+         fastmap['\n'] = 1;
+       case anychar:
+         for (j = 0; j < (1 << BYTEWIDTH); j++)
+           if (j != '\n')
+             fastmap[j] = 1;
+         if (bufp->can_be_null)
+           return;
+         /* Don't return; check the alternative paths
+            so we can set can_be_null if appropriate.  */
+         break;
+
+       case wordchar:
+         for (j = 0; j < (1 << BYTEWIDTH); j++)
+           if (SYNTAX (j) == Sword)
+             fastmap[j] = 1;
+         break;
+
+       case notwordchar:
+         for (j = 0; j < (1 << BYTEWIDTH); j++)
+           if (SYNTAX (j) != Sword)
+             fastmap[j] = 1;
+         break;
+
+#ifdef emacs
+       case syntaxspec:
+         k = *p++;
+         for (j = 0; j < (1 << BYTEWIDTH); j++)
+           if (SYNTAX (j) == (enum syntaxcode) k)
+             fastmap[j] = 1;
+         break;
+
+       case notsyntaxspec:
+         k = *p++;
+         for (j = 0; j < (1 << BYTEWIDTH); j++)
+           if (SYNTAX (j) != (enum syntaxcode) k)
+             fastmap[j] = 1;
+         break;
+#endif /* emacs */
+
+       case charset:
+         for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+           if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
+             {
+               if (translate)
+                 fastmap[translate[j]] = 1;
+               else
+                 fastmap[j] = 1;
+             }
+         break;
+
+       case charset_not:
+         /* Chars beyond end of map must be allowed */
+         for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
+           if (translate)
+             fastmap[translate[j]] = 1;
+           else
+             fastmap[j] = 1;
+
+         for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+           if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
+             {
+               if (translate)
+                 fastmap[translate[j]] = 1;
+               else
+                 fastmap[j] = 1;
+             }
+         break;
+       }
+
+      /* Get here means we have successfully found the possible starting characters
+        of one path of the pattern.  We need not follow this path any farther.
+        Instead, look at the next alternative remembered in the stack. */
+      if (stackp != stackb)
+       p = *stackp--;
+      else
+       break;
+    }
+}
+\f
+/* Like re_search_2, below, but only one string is specified. */
+
+int
+re_search (pbufp, string, size, startpos, range, regs)
+     struct re_pattern_buffer *pbufp;
+     char *string;
+     int size, startpos, range;
+     struct re_registers *regs;
+{
+  return re_search_2 (pbufp, 0, 0, string, size, startpos, range, regs, size);
+}
+
+/* Like re_match_2 but tries first a match starting at index STARTPOS,
+   then at STARTPOS + 1, and so on.
+   RANGE is the number of places to try before giving up.
+   If RANGE is negative, the starting positions tried are
+    STARTPOS, STARTPOS - 1, etc.
+   It is up to the caller to make sure that range is not so large
+   as to take the starting position outside of the input strings.
+
+The value returned is the position at which the match was found,
+ or -1 if no match was found,
+ or -2 if error (such as failure stack overflow).  */
+
+int
+re_search_2 (pbufp, string1, size1, string2, size2, startpos, range, regs, mstop)
+     struct re_pattern_buffer *pbufp;
+     char *string1, *string2;
+     int size1, size2;
+     int startpos;
+     register int range;
+     struct re_registers *regs;
+     int mstop;
+{
+  register char *fastmap = pbufp->fastmap;
+  register unsigned char *translate = (unsigned char *) pbufp->translate;
+  int total = size1 + size2;
+  int val;
+
+  /* Update the fastmap now if not correct already */
+  if (fastmap && !pbufp->fastmap_accurate)
+    re_compile_fastmap (pbufp);
+  
+  /* Don't waste time in a long search for a pattern
+     that says it is anchored.  */
+  if (pbufp->used > 0 && (enum regexpcode) pbufp->buffer[0] == begbuf
+      && range > 0)
+    {
+      if (startpos > 0)
+       return -1;
+      else
+       range = 1;
+    }
+
+  while (1)
+    {
+      /* If a fastmap is supplied, skip quickly over characters
+        that cannot possibly be the start of a match.
+        Note, however, that if the pattern can possibly match
+        the null string, we must test it at each starting point
+        so that we take the first null string we get.  */
+
+      if (fastmap && startpos < total && pbufp->can_be_null != 1)
+       {
+         if (range > 0)
+           {
+             register int lim = 0;
+             register unsigned char *p;
+             int irange = range;
+             if (startpos < size1 && startpos + range >= size1)
+               lim = range - (size1 - startpos);
+
+             p = ((unsigned char *)
+                  &(startpos >= size1 ? string2 - size1 : string1)[startpos]);
+
+             if (translate)
+               {
+                 while (range > lim && !fastmap[translate[*p++]])
+                   range--;
+               }
+             else
+               {
+                 while (range > lim && !fastmap[*p++])
+                   range--;
+               }
+             startpos += irange - range;
+           }
+         else
+           {
+             register unsigned char c;
+             if (startpos >= size1)
+               c = string2[startpos - size1];
+             else
+               c = string1[startpos];
+             c &= 0xff;
+             if (translate ? !fastmap[translate[c]] : !fastmap[c])
+               goto advance;
+           }
+       }
+
+      if (range >= 0 && startpos == total
+         && fastmap && pbufp->can_be_null == 0)
+       return -1;
+
+      val = re_match_2 (pbufp, string1, size1, string2, size2, startpos, regs, mstop);
+      if (0 <= val)
+       {
+         if (val == -2)
+           return -2;
+         return startpos;
+       }
+
+#ifdef C_ALLOCA
+      alloca (0);
+#endif /* C_ALLOCA */
+
+    advance:
+      if (!range) break;
+      if (range > 0) range--, startpos++; else range++, startpos--;
+    }
+  return -1;
+}
+\f
+#ifndef emacs   /* emacs never uses this */
+int
+re_match (pbufp, string, size, pos, regs)
+     struct re_pattern_buffer *pbufp;
+     char *string;
+     int size, pos;
+     struct re_registers *regs;
+{
+  return re_match_2 (pbufp, 0, 0, string, size, pos, regs, size);
+}
+#endif /* emacs */
+
+/* Maximum size of failure stack.  Beyond this, overflow is an error.  */
+
+int re_max_failures = 2000;
+
+static int bcmp_translate();
+/* Match the pattern described by PBUFP
+   against data which is the virtual concatenation of STRING1 and STRING2.
+   SIZE1 and SIZE2 are the sizes of the two data strings.
+   Start the match at position POS.
+   Do not consider matching past the position MSTOP.
+
+   If pbufp->fastmap is nonzero, then it had better be up to date.
+
+   The reason that the data to match are specified as two components
+   which are to be regarded as concatenated
+   is so this function can be used directly on the contents of an Emacs buffer.
+
+   -1 is returned if there is no match.  -2 is returned if there is
+   an error (such as match stack overflow).  Otherwise the value is the length
+   of the substring which was matched.  */
+
+int
+re_match_2 (pbufp, string1, size1, string2, size2, pos, regs, mstop)
+     struct re_pattern_buffer *pbufp;
+     unsigned char *string1, *string2;
+     int size1, size2;
+     int pos;
+     struct re_registers *regs;
+     int mstop;
+{
+  register unsigned char *p = (unsigned char *) pbufp->buffer;
+  register unsigned char *pend = p + pbufp->used;
+  /* End of first string */
+  unsigned char *end1;
+  /* End of second string */
+  unsigned char *end2;
+  /* Pointer just past last char to consider matching */
+  unsigned char *end_match_1, *end_match_2;
+  register unsigned char *d, *dend;
+  register int mcnt;
+  unsigned char *translate = (unsigned char *) pbufp->translate;
+
+ /* Failure point stack.  Each place that can handle a failure further down the line
+    pushes a failure point on this stack.  It consists of two char *'s.
+    The first one pushed is where to resume scanning the pattern;
+    the second pushed is where to resume scanning the strings.
+    If the latter is zero, the failure point is a "dummy".
+    If a failure happens and the innermost failure point is dormant,
+    it discards that failure point and tries the next one. */
+
+  unsigned char *initial_stack[2 * NFAILURES];
+  unsigned char **stackb = initial_stack;
+  unsigned char **stackp = stackb, **stacke = &stackb[2 * NFAILURES];
+
+  /* Information on the "contents" of registers.
+     These are pointers into the input strings; they record
+     just what was matched (on this attempt) by some part of the pattern.
+     The start_memory command stores the start of a register's contents
+     and the stop_memory command stores the end.
+
+     At that point, regstart[regnum] points to the first character in the register,
+     regend[regnum] points to the first character beyond the end of the register,
+     regstart_seg1[regnum] is true iff regstart[regnum] points into string1,
+     and regend_seg1[regnum] is true iff regend[regnum] points into string1.  */
+
+  unsigned char *regstart[RE_NREGS];
+  unsigned char *regend[RE_NREGS];
+  unsigned char regstart_seg1[RE_NREGS], regend_seg1[RE_NREGS];
+
+  /* Set up pointers to ends of strings.
+     Don't allow the second string to be empty unless both are empty.  */
+  if (!size2)
+    {
+      string2 = string1;
+      size2 = size1;
+      string1 = 0;
+      size1 = 0;
+    }
+  end1 = string1 + size1;
+  end2 = string2 + size2;
+
+  /* Compute where to stop matching, within the two strings */
+  if (mstop <= size1)
+    {
+      end_match_1 = string1 + mstop;
+      end_match_2 = string2;
+    }
+  else
+    {
+      end_match_1 = end1;
+      end_match_2 = string2 + mstop - size1;
+    }
+
+  /* Initialize \) text positions to -1
+     to mark ones that no \( or \) has been seen for.  */
+
+  for (mcnt = 0; mcnt < sizeof (regend) / sizeof (*regend); mcnt++)
+    regend[mcnt] = (unsigned char *) -1;
+
+  /* `p' scans through the pattern as `d' scans through the data.
+     `dend' is the end of the input string that `d' points within.
+     `d' is advanced into the following input string whenever necessary,
+     but this happens before fetching;
+     therefore, at the beginning of the loop,
+     `d' can be pointing at the end of a string,
+     but it cannot equal string2.  */
+
+  if (pos <= size1)
+    d = string1 + pos, dend = end_match_1;
+  else
+    d = string2 + pos - size1, dend = end_match_2;
+
+/* Write PREFETCH; just before fetching a character with *d.  */
+#define PREFETCH \
+ while (d == dend)                                                 \
+  { if (dend == end_match_2) goto fail;  /* end of string2 => failure */   \
+    d = string2;  /* end of string1 => advance to string2. */       \
+    dend = end_match_2; }
+
+  /* This loop loops over pattern commands.
+     It exits by returning from the function if match is complete,
+     or it drops through if match fails at this starting point in the input data. */
+
+  while (1)
+    {
+      if (p == pend)
+       /* End of pattern means we have succeeded! */
+       {
+         /* If caller wants register contents data back, convert it to indices */
+         if (regs)
+           {
+             regs->start[0] = pos;
+             if (dend == end_match_1)
+               regs->end[0] = d - string1;
+             else
+               regs->end[0] = d - string2 + size1;
+             for (mcnt = 1; mcnt < RE_NREGS; mcnt++)
+               {
+                 if (regend[mcnt] == (unsigned char *) -1)
+                   {
+                     regs->start[mcnt] = -1;
+                     regs->end[mcnt] = -1;
+                     continue;
+                   }
+                 if (regstart_seg1[mcnt])
+                   regs->start[mcnt] = regstart[mcnt] - string1;
+                 else
+                   regs->start[mcnt] = regstart[mcnt] - string2 + size1;
+                 if (regend_seg1[mcnt])
+                   regs->end[mcnt] = regend[mcnt] - string1;
+                 else
+                   regs->end[mcnt] = regend[mcnt] - string2 + size1;
+               }
+           }
+         if (dend == end_match_1)
+           return (d - string1 - pos);
+         else
+           return d - string2 + size1 - pos;
+       }
+
+      /* Otherwise match next pattern command */
+#ifdef SWITCH_ENUM_BUG
+      switch ((int) ((enum regexpcode) *p++))
+#else
+      switch ((enum regexpcode) *p++)
+#endif
+       {
+
+       /* \( is represented by a start_memory, \) by a stop_memory.
+           Both of those commands contain a "register number" argument.
+           The text matched within the \( and \) is recorded under that number.
+           Then, \<digit> turns into a `duplicate' command which
+           is followed by the numeric value of <digit> as the register number. */
+
+       case start_memory:
+         regstart[*p] = d;
+         regstart_seg1[*p++] = (dend == end_match_1);
+         break;
+
+       case stop_memory:
+         regend[*p] = d;
+         regend_seg1[*p++] = (dend == end_match_1);
+         break;
+
+       case duplicate:
+         {
+           int regno = *p++;   /* Get which register to match against */
+           register unsigned char *d2, *dend2;
+
+           d2 = regstart[regno];
+           dend2 = ((regstart_seg1[regno] == regend_seg1[regno])
+                    ? regend[regno] : end_match_1);
+           while (1)
+             {
+               /* Advance to next segment in register contents, if necessary */
+               while (d2 == dend2)
+                 {
+                   if (dend2 == end_match_2) break;
+                   if (dend2 == regend[regno]) break;
+                   d2 = string2, dend2 = regend[regno];  /* end of string1 => advance to string2. */
+                 }
+               /* At end of register contents => success */
+               if (d2 == dend2) break;
+
+               /* Advance to next segment in data being matched, if necessary */
+               PREFETCH;
+
+               /* mcnt gets # consecutive chars to compare */
+               mcnt = dend - d;
+               if (mcnt > dend2 - d2)
+                 mcnt = dend2 - d2;
+               /* Compare that many; failure if mismatch, else skip them. */
+               if (translate ? bcmp_translate (d, d2, mcnt, translate) : bcmp (d, d2, mcnt))
+                 goto fail;
+               d += mcnt, d2 += mcnt;
+             }
+         }
+         break;
+
+       case anychar:
+         /* fetch a data character */
+         PREFETCH;
+         /* Match anything but a newline.  */
+         if ((translate ? translate[*d++] : *d++) == '\n')
+           goto fail;
+         break;
+
+       case charset:
+       case charset_not:
+         {
+           /* Nonzero for charset_not */
+           int not = 0;
+           register int c;
+           if (*(p - 1) == (unsigned char) charset_not)
+             not = 1;
+
+           /* fetch a data character */
+           PREFETCH;
+
+           if (translate)
+             c = translate [*d];
+           else
+             c = *d;
+
+           if (c < *p * BYTEWIDTH
+               && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+             not = !not;
+
+           p += 1 + *p;
+
+           if (!not) goto fail;
+           d++;
+           break;
+         }
+
+       case begline:
+         if (d == string1 || d[-1] == '\n')
+           break;
+         goto fail;
+
+       case endline:
+         if (d == end2
+             || (d == end1 ? (size2 == 0 || *string2 == '\n') : *d == '\n'))
+           break;
+         goto fail;
+
+       /* "or" constructs ("|") are handled by starting each alternative
+           with an on_failure_jump that points to the start of the next alternative.
+           Each alternative except the last ends with a jump to the joining point.
+           (Actually, each jump except for the last one really jumps
+            to the following jump, because tensioning the jumps is a hassle.) */
+
+       /* The start of a stupid repeat has an on_failure_jump that points
+          past the end of the repeat text.
+          This makes a failure point so that, on failure to match a repetition,
+          matching restarts past as many repetitions have been found
+          with no way to fail and look for another one.  */
+
+       /* A smart repeat is similar but loops back to the on_failure_jump
+          so that each repetition makes another failure point. */
+
+       case on_failure_jump:
+         if (stackp == stacke)
+           {
+             unsigned char **stackx;
+             if (stacke - stackb > re_max_failures * 2)
+               return -2;
+             stackx = (unsigned char **) alloca (2 * (stacke - stackb)
+                                        * sizeof (char *));
+             bcopy (stackb, stackx, (stacke - stackb) * sizeof (char *));
+             stackp = stackx + (stackp - stackb);
+             stacke = stackx + 2 * (stacke - stackb);
+             stackb = stackx;
+           }
+         mcnt = *p++ & 0377;
+         mcnt += SIGN_EXTEND_CHAR (*(char *)p) << 8;
+         p++;
+         *stackp++ = mcnt + p;
+         *stackp++ = d;
+         break;
+
+       /* The end of a smart repeat has an maybe_finalize_jump back.
+          Change it either to a finalize_jump or an ordinary jump. */
+
+       case maybe_finalize_jump:
+         mcnt = *p++ & 0377;
+         mcnt += SIGN_EXTEND_CHAR (*(char *)p) << 8;
+         p++;
+         {
+           register unsigned char *p2 = p;
+           /* Compare what follows with the begining of the repeat.
+              If we can establish that there is nothing that they would
+              both match, we can change to finalize_jump */
+           while (p2 != pend
+                  && (*p2 == (unsigned char) stop_memory
+                      || *p2 == (unsigned char) start_memory))
+             p2++;
+           if (p2 == pend)
+             p[-3] = (unsigned char) finalize_jump;
+           else if (*p2 == (unsigned char) exactn
+                    || *p2 == (unsigned char) endline)
+             {
+               register int c = *p2 == (unsigned char) endline ? '\n' : p2[2];
+               register unsigned char *p1 = p + mcnt;
+               /* p1[0] ... p1[2] are an on_failure_jump.
+                  Examine what follows that */
+               if (p1[3] == (unsigned char) exactn && p1[5] != c)
+                 p[-3] = (unsigned char) finalize_jump;
+               else if (p1[3] == (unsigned char) charset
+                        || p1[3] == (unsigned char) charset_not)
+                 {
+                   int not = p1[3] == (unsigned char) charset_not;
+                   if (c < p1[4] * BYTEWIDTH
+                       && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+                     not = !not;
+                   /* not is 1 if c would match */
+                   /* That means it is not safe to finalize */
+                   if (!not)
+                     p[-3] = (unsigned char) finalize_jump;
+                 }
+             }
+         }
+         p -= 2;
+         if (p[-1] != (unsigned char) finalize_jump)
+           {
+             p[-1] = (unsigned char) jump;
+             goto nofinalize;
+           }
+
+       /* The end of a stupid repeat has a finalize-jump
+          back to the start, where another failure point will be made
+          which will point after all the repetitions found so far. */
+
+       case finalize_jump:
+         stackp -= 2;
+
+       case jump:
+       nofinalize:
+         mcnt = *p++ & 0377;
+         mcnt += SIGN_EXTEND_CHAR (*(char *)p) << 8;
+         p += mcnt + 1;        /* The 1 compensates for missing ++ above */
+         break;
+
+       case dummy_failure_jump:
+         if (stackp == stacke)
+           {
+             unsigned char **stackx
+               = (unsigned char **) alloca (2 * (stacke - stackb)
+                                            * sizeof (char *));
+             bcopy (stackb, stackx, (stacke - stackb) * sizeof (char *));
+             stackp = stackx + (stackp - stackb);
+             stacke = stackx + 2 * (stacke - stackb);
+             stackb = stackx;
+           }
+         *stackp++ = 0;
+         *stackp++ = 0;
+         goto nofinalize;
+
+       case wordbound:
+         if (d == string1  /* Points to first char */
+             || d == end2  /* Points to end */
+             || (d == end1 && size2 == 0)) /* Points to end */
+           break;
+         if ((SYNTAX (d[-1]) == Sword)
+             != (SYNTAX (d == end1 ? *string2 : *d) == Sword))
+           break;
+         goto fail;
+
+       case notwordbound:
+         if (d == string1  /* Points to first char */
+             || d == end2  /* Points to end */
+             || (d == end1 && size2 == 0)) /* Points to end */
+           goto fail;
+         if ((SYNTAX (d[-1]) == Sword)
+             != (SYNTAX (d == end1 ? *string2 : *d) == Sword))
+           goto fail;
+         break;
+
+       case wordbeg:
+         if (d == end2  /* Points to end */
+             || (d == end1 && size2 == 0) /* Points to end */
+             || SYNTAX (* (d == end1 ? string2 : d)) != Sword) /* Next char not a letter */
+           goto fail;
+         if (d == string1  /* Points to first char */
+             || SYNTAX (d[-1]) != Sword)  /* prev char not letter */
+           break;
+         goto fail;
+
+       case wordend:
+         if (d == string1  /* Points to first char */
+             || SYNTAX (d[-1]) != Sword)  /* prev char not letter */
+           goto fail;
+         if (d == end2  /* Points to end */
+             || (d == end1 && size2 == 0) /* Points to end */
+             || SYNTAX (d == end1 ? *string2 : *d) != Sword) /* Next char not a letter */
+           break;
+         goto fail;
+
+#ifdef emacs
+       case before_dot:
+         if (((d - string2 <= (unsigned) size2)
+              ? d - bf_p2 : d - bf_p1)
+             <= point)
+           goto fail;
+         break;
+
+       case at_dot:
+         if (((d - string2 <= (unsigned) size2)
+              ? d - bf_p2 : d - bf_p1)
+             == point)
+           goto fail;
+         break;
+
+       case after_dot:
+         if (((d - string2 <= (unsigned) size2)
+              ? d - bf_p2 : d - bf_p1)
+             >= point)
+           goto fail;
+         break;
+
+       case wordchar:
+         mcnt = (int) Sword;
+         goto matchsyntax;
+
+       case syntaxspec:
+         mcnt = *p++;
+       matchsyntax:
+         PREFETCH;
+         if (SYNTAX (*d++) != (enum syntaxcode) mcnt) goto fail;
+         break;
+         
+       case notwordchar:
+         mcnt = (int) Sword;
+         goto matchnotsyntax;
+
+       case notsyntaxspec:
+         mcnt = *p++;
+       matchnotsyntax:
+         PREFETCH;
+         if (SYNTAX (*d++) == (enum syntaxcode) mcnt) goto fail;
+         break;
+#else
+       case wordchar:
+         PREFETCH;
+         if (SYNTAX (*d++) == 0) goto fail;
+         break;
+         
+       case notwordchar:
+         PREFETCH;
+         if (SYNTAX (*d++) != 0) goto fail;
+         break;
+#endif /* not emacs */
+
+       case begbuf:
+         if (d == string1)     /* Note, d cannot equal string2 */
+           break;              /* unless string1 == string2.  */
+         goto fail;
+
+       case endbuf:
+         if (d == end2 || (d == end1 && size2 == 0))
+           break;
+         goto fail;
+
+       case exactn:
+         /* Match the next few pattern characters exactly.
+            mcnt is how many characters to match. */
+         mcnt = *p++;
+         if (translate)
+           {
+             do
+               {
+                 PREFETCH;
+                 if (translate[*d++] != *p++) goto fail;
+               }
+             while (--mcnt);
+           }
+         else
+           {
+             do
+               {
+                 PREFETCH;
+                 if (*d++ != *p++) goto fail;
+               }
+             while (--mcnt);
+           }
+         break;
+       }
+      continue;    /* Successfully matched one pattern command; keep matching */
+
+      /* Jump here if any matching operation fails. */
+    fail:
+      if (stackp != stackb)
+       /* A restart point is known.  Restart there and pop it. */
+       {
+         if (!stackp[-2])
+           {   /* If innermost failure point is dormant, flush it and keep looking */
+             stackp -= 2;
+             goto fail;
+           }
+         d = *--stackp;
+         p = *--stackp;
+         if (d >= string1 && d <= end1)
+           dend = end_match_1;
+       }
+      else break;   /* Matching at this starting point really fails! */
+    }
+  return -1;         /* Failure to match */
+}
+
+static int
+bcmp_translate (s1, s2, len, translate)
+     unsigned char *s1, *s2;
+     register int len;
+     unsigned char *translate;
+{
+  register unsigned char *p1 = s1, *p2 = s2;
+  while (len)
+    {
+      if (translate [*p1++] != translate [*p2++]) return 1;
+      len--;
+    }
+  return 0;
+}
+\f
+/* Entry points compatible with bsd4.2 regex library */
+
+#ifndef emacs
+
+static struct re_pattern_buffer re_comp_buf;
+
+char *
+re_comp (s)
+     char *s;
+{
+  if (!s)
+    {
+      if (!re_comp_buf.buffer)
+       return "No previous regular expression";
+      return 0;
+    }
+
+  if (!re_comp_buf.buffer)
+    {
+      if (!(re_comp_buf.buffer = (char *) malloc (200)))
+       return "Memory exhausted";
+      re_comp_buf.allocated = 200;
+      if (!(re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH)))
+       return "Memory exhausted";
+    }
+  return re_compile_pattern (s, strlen (s), &re_comp_buf);
+}
+
+int
+re_exec (s)
+     char *s;
+{
+  int len = strlen (s);
+  return 0 <= re_search (&re_comp_buf, s, len, 0, len, 0);
+}
+
+#endif /* emacs */
+\f
+#ifdef test
+
+#include <stdio.h>
+
+/* Indexed by a character, gives the upper case equivalent of the character */
+
+static char upcase[0400] = 
+  { 000, 001, 002, 003, 004, 005, 006, 007,
+    010, 011, 012, 013, 014, 015, 016, 017,
+    020, 021, 022, 023, 024, 025, 026, 027,
+    030, 031, 032, 033, 034, 035, 036, 037,
+    040, 041, 042, 043, 044, 045, 046, 047,
+    050, 051, 052, 053, 054, 055, 056, 057,
+    060, 061, 062, 063, 064, 065, 066, 067,
+    070, 071, 072, 073, 074, 075, 076, 077,
+    0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
+    0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
+    0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
+    0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
+    0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
+    0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
+    0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
+    0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
+    0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
+    0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
+    0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
+    0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
+    0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
+    0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
+    0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
+    0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
+    0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
+    0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
+    0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
+    0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
+    0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
+    0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
+    0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
+    0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377
+  };
+
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  char pat[80];
+  struct re_pattern_buffer buf;
+  int i;
+  char c;
+  char fastmap[(1 << BYTEWIDTH)];
+
+  /* Allow a command argument to specify the style of syntax.  */
+  if (argc > 1)
+    obscure_syntax = atoi (argv[1]);
+
+  buf.allocated = 40;
+  buf.buffer = (char *) malloc (buf.allocated);
+  buf.fastmap = fastmap;
+  buf.translate = upcase;
+
+  while (1)
+    {
+      gets (pat);
+
+      if (*pat)
+       {
+          re_compile_pattern (pat, strlen(pat), &buf);
+
+         for (i = 0; i < buf.used; i++)
+           printchar (buf.buffer[i]);
+
+         putchar ('\n');
+
+         printf ("%d allocated, %d used.\n", buf.allocated, buf.used);
+
+         re_compile_fastmap (&buf);
+         printf ("Allowed by fastmap: ");
+         for (i = 0; i < (1 << BYTEWIDTH); i++)
+           if (fastmap[i]) printchar (i);
+         putchar ('\n');
+       }
+
+      gets (pat);      /* Now read the string to match against */
+
+      i = re_match (&buf, pat, strlen (pat), 0, 0);
+      printf ("Match value %d.\n", i);
+    }
+}
+
+#ifdef NOTDEF
+print_buf (bufp)
+     struct re_pattern_buffer *bufp;
+{
+  int i;
+
+  printf ("buf is :\n----------------\n");
+  for (i = 0; i < bufp->used; i++)
+    printchar (bufp->buffer[i]);
+  
+  printf ("\n%d allocated, %d used.\n", bufp->allocated, bufp->used);
+  
+  printf ("Allowed by fastmap: ");
+  for (i = 0; i < (1 << BYTEWIDTH); i++)
+    if (bufp->fastmap[i])
+      printchar (i);
+  printf ("\nAllowed by translate: ");
+  if (bufp->translate)
+    for (i = 0; i < (1 << BYTEWIDTH); i++)
+      if (bufp->translate[i])
+       printchar (i);
+  printf ("\nfastmap is%s accurate\n", bufp->fastmap_accurate ? "" : "n't");
+  printf ("can %s be null\n----------", bufp->can_be_null ? "" : "not");
+}
+#endif
+
+printchar (c)
+     char c;
+{
+  if (c < 041 || c >= 0177)
+    {
+      putchar ('\\');
+      putchar (((c >> 6) & 3) + '0');
+      putchar (((c >> 3) & 7) + '0');
+      putchar ((c & 7) + '0');
+    }
+  else
+    putchar (c);
+}
+
+error (string)
+     char *string;
+{
+  puts (string);
+  exit (1);
+}
+
+#endif /* test */
diff --git a/usr/src/usr.bin/gdb/regex.h b/usr/src/usr.bin/gdb/regex.h
new file mode 100644 (file)
index 0000000..d0d8a82
--- /dev/null
@@ -0,0 +1,185 @@
+/* Definitions for data structures callers pass the regex library.
+   Copyright (C) 1985, 1989 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+   In other words, you are welcome to use, share and improve this program.
+   You are forbidden to forbid anyone else to use, share and improve
+   what you give them.   Help stamp out software-hoarding!  */
+
+
+/* Define number of parens for which we record the beginnings and ends.
+   This affects how much space the `struct re_registers' type takes up.  */
+#ifndef RE_NREGS
+#define RE_NREGS 10
+#endif
+
+/* These bits are used in the obscure_syntax variable to choose among
+   alternative regexp syntaxes.  */
+
+/* 1 means plain parentheses serve as grouping, and backslash
+     parentheses are needed for literal searching.
+   0 means backslash-parentheses are grouping, and plain parentheses
+     are for literal searching.  */
+#define RE_NO_BK_PARENS 1
+
+/* 1 means plain | serves as the "or"-operator, and \| is a literal.
+   0 means \| serves as the "or"-operator, and | is a literal.  */
+#define RE_NO_BK_VBAR 2
+
+/* 0 means plain + or ? serves as an operator, and \+, \? are literals.
+   1 means \+, \? are operators and plain +, ? are literals.  */
+#define RE_BK_PLUS_QM 4
+
+/* 1 means | binds tighter than ^ or $.
+   0 means the contrary.  */
+#define RE_TIGHT_VBAR 8
+
+/* 1 means treat \n as an _OR operator
+   0 means treat it as a normal character */
+#define RE_NEWLINE_OR 16
+
+/* 0 means that a special characters (such as *, ^, and $) always have
+     their special meaning regardless of the surrounding context.
+   1 means that special characters may act as normal characters in some
+     contexts.  Specifically, this applies to:
+       ^ - only special at the beginning, or after ( or |
+       $ - only special at the end, or before ) or |
+       *, +, ? - only special when not after the beginning, (, or | */
+#define RE_CONTEXT_INDEP_OPS 32
+
+/* Now define combinations of bits for the standard possibilities.  */
+#define RE_SYNTAX_AWK (RE_NO_BK_PARENS | RE_NO_BK_VBAR | RE_CONTEXT_INDEP_OPS)
+#define RE_SYNTAX_EGREP (RE_SYNTAX_AWK | RE_NEWLINE_OR)
+#define RE_SYNTAX_GREP (RE_BK_PLUS_QM | RE_NEWLINE_OR)
+#define RE_SYNTAX_EMACS 0
+
+/* This data structure is used to represent a compiled pattern. */
+
+struct re_pattern_buffer
+  {
+    char *buffer;      /* Space holding the compiled pattern commands. */
+    int allocated;     /* Size of space that  buffer  points to */
+    int used;          /* Length of portion of buffer actually occupied */
+    char *fastmap;     /* Pointer to fastmap, if any, or zero if none. */
+                       /* re_search uses the fastmap, if there is one,
+                          to skip quickly over totally implausible characters */
+    char *translate;   /* Translate table to apply to all characters before comparing.
+                          Or zero for no translation.
+                          The translation is applied to a pattern when it is compiled
+                          and to data when it is matched. */
+    char fastmap_accurate;
+                       /* Set to zero when a new pattern is stored,
+                          set to one when the fastmap is updated from it. */
+    char can_be_null;   /* Set to one by compiling fastmap
+                          if this pattern might match the null string.
+                          It does not necessarily match the null string
+                          in that case, but if this is zero, it cannot.
+                          2 as value means can match null string
+                          but at end of range or before a character
+                          listed in the fastmap.  */
+  };
+
+/* Structure to store "register" contents data in.
+
+   Pass the address of such a structure as an argument to re_match, etc.,
+   if you want this information back.
+
+   start[i] and end[i] record the string matched by \( ... \) grouping i,
+   for i from 1 to RE_NREGS - 1.
+   start[0] and end[0] record the entire string matched. */
+
+struct re_registers
+  {
+    int start[RE_NREGS];
+    int end[RE_NREGS];
+  };
+
+/* These are the command codes that appear in compiled regular expressions, one per byte.
+  Some command codes are followed by argument bytes.
+  A command code can specify any interpretation whatever for its arguments.
+  Zero-bytes may appear in the compiled regular expression. */
+
+enum regexpcode
+  {
+    unused,
+    exactn,    /* followed by one byte giving n, and then by n literal bytes */
+    begline,   /* fails unless at beginning of line */
+    endline,   /* fails unless at end of line */
+    jump,       /* followed by two bytes giving relative address to jump to */
+    on_failure_jump,    /* followed by two bytes giving relative address of place
+                           to resume at in case of failure. */
+    finalize_jump,      /* Throw away latest failure point and then jump to address. */
+    maybe_finalize_jump, /* Like jump but finalize if safe to do so.
+                           This is used to jump back to the beginning
+                           of a repeat.  If the command that follows
+                           this jump is clearly incompatible with the
+                           one at the beginning of the repeat, such that
+                           we can be sure that there is no use backtracking
+                           out of repetitions already completed,
+                           then we finalize. */
+    dummy_failure_jump,  /* jump, and push a dummy failure point.
+                           This failure point will be thrown away
+                           if an attempt is made to use it for a failure.
+                           A + construct makes this before the first repeat.  */
+    anychar,    /* matches any one character */
+    charset,     /* matches any one char belonging to specified set.
+                   First following byte is # bitmap bytes.
+                   Then come bytes for a bit-map saying which chars are in.
+                   Bits in each byte are ordered low-bit-first.
+                   A character is in the set if its bit is 1.
+                   A character too large to have a bit in the map
+                   is automatically not in the set */
+    charset_not, /* similar but match any character that is NOT one of those specified */
+    start_memory, /* starts remembering the text that is matched
+                   and stores it in a memory register.
+                   followed by one byte containing the register number.
+                   Register numbers must be in the range 0 through NREGS. */
+    stop_memory, /* stops remembering the text that is matched
+                   and stores it in a memory register.
+                   followed by one byte containing the register number.
+                   Register numbers must be in the range 0 through NREGS. */
+    duplicate,    /* match a duplicate of something remembered.
+                   Followed by one byte containing the index of the memory register. */
+    before_dot,         /* Succeeds if before dot */
+    at_dot,     /* Succeeds if at dot */
+    after_dot,  /* Succeeds if after dot */
+    begbuf,      /* Succeeds if at beginning of buffer */
+    endbuf,      /* Succeeds if at end of buffer */
+    wordchar,    /* Matches any word-constituent character */
+    notwordchar, /* Matches any char that is not a word-constituent */
+    wordbeg,    /* Succeeds if at word beginning */
+    wordend,    /* Succeeds if at word end */
+    wordbound,   /* Succeeds if at a word boundary */
+    notwordbound, /* Succeeds if not at a word boundary */
+    syntaxspec,  /* Matches any character whose syntax is specified.
+                   followed by a byte which contains a syntax code, Sword or such like */
+    notsyntaxspec /* Matches any character whose syntax differs from the specified. */
+  };
+\f
+extern char *re_compile_pattern ();
+/* Is this really advertised? */
+extern void re_compile_fastmap ();
+extern int re_search (), re_search_2 ();
+extern int re_match (), re_match_2 ();
+
+/* 4.2 bsd compatibility (yuck) */
+extern char *re_comp ();
+extern int re_exec ();
+
+#ifdef SYNTAX_TABLE
+extern char *re_syntax_table;
+#endif