PSARC 2005/673 dis(1) options and libdisasm.so.1
authoreschrock
Fri, 03 Mar 2006 22:38:03 -0800
changeset 1545 8f6fb1eeee38
parent 1544 938876158511
child 1546 d9237fea0148
PSARC 2005/673 dis(1) options and libdisasm.so.1 5034117 disassembler needs work 6237338 dis picks symbols inconsistently 6241243 disassembler options need to be updated post-1990 6241251 'dis -[Dd]' needs some surgery 6241264 need to move disassembler into a library 6294758 cafe sgs demangler should be torched
deleted_files/usr/src/cmd/mdb/intel/mdb/bits.c
deleted_files/usr/src/cmd/mdb/intel/mdb/dis.h
deleted_files/usr/src/cmd/mdb/intel/mdb/inteldis.c
deleted_files/usr/src/cmd/sgs/sgsdemangler/common/cafe_dem.h
deleted_files/usr/src/cmd/sgs/sgsdemangler/common/cafe_dem.y
deleted_files/usr/src/cmd/sgs/sgsdemangler/common/dem.c
deleted_files/usr/src/cmd/sgs/sgsdemangler/common/dem.h
usr/src/Makefile.lint
usr/src/cmd/Makefile
usr/src/cmd/dis/Makefile
usr/src/cmd/dis/dis_list.c
usr/src/cmd/dis/dis_list.h
usr/src/cmd/dis/dis_main.c
usr/src/cmd/dis/dis_target.c
usr/src/cmd/dis/dis_target.h
usr/src/cmd/dis/dis_util.c
usr/src/cmd/dis/dis_util.h
usr/src/cmd/mdb/Makefile.mdb
usr/src/cmd/mdb/Makefile.module
usr/src/cmd/mdb/common/kmdb/kmdb_create.c
usr/src/cmd/mdb/common/kmdb/kmdb_stubs.c
usr/src/cmd/mdb/common/kmdb/mapfile_skel
usr/src/cmd/mdb/common/mdb/mdb_disasm.c
usr/src/cmd/mdb/common/mdb/mdb_disasm_impl.h
usr/src/cmd/mdb/common/mdb/mdb_modapi.h
usr/src/cmd/mdb/intel/Makefile.kmdb
usr/src/cmd/mdb/intel/amd64/kmdb/Makefile
usr/src/cmd/mdb/intel/amd64/mdb/Makefile
usr/src/cmd/mdb/intel/ia32/Makefile
usr/src/cmd/mdb/intel/ia32/kmdb/Makefile
usr/src/cmd/mdb/intel/ia32/mdb/Makefile
usr/src/cmd/mdb/intel/mdb/bits.c
usr/src/cmd/mdb/intel/mdb/dis.h
usr/src/cmd/mdb/intel/mdb/inteldis.c
usr/src/cmd/mdb/sparc/v7/Makefile
usr/src/cmd/mdb/sparc/v9/Makefile
usr/src/cmd/mdb/sparc/v9/kmdb/Makefile
usr/src/cmd/mdb/sun4u/v9/kmdb/Makefile
usr/src/cmd/mdb/sun4v/v9/kmdb/Makefile
usr/src/cmd/sgs/Makefile
usr/src/cmd/sgs/sgsdemangler/Makefile.com
usr/src/cmd/sgs/sgsdemangler/Makefile.targ
usr/src/cmd/sgs/sgsdemangler/common/cafe_dem.h
usr/src/cmd/sgs/sgsdemangler/common/cafe_dem.y
usr/src/cmd/sgs/sgsdemangler/common/dem.c
usr/src/cmd/sgs/sgsdemangler/common/dem.h
usr/src/cmd/sgs/sgsdemangler/common/demangle.c
usr/src/common/dis/i386/dis_tables.c
usr/src/common/dis/i386/dis_tables.h
usr/src/lib/Makefile
usr/src/lib/libdisasm/Makefile
usr/src/lib/libdisasm/Makefile.com
usr/src/lib/libdisasm/Makefile.targ
usr/src/lib/libdisasm/amd64/Makefile
usr/src/lib/libdisasm/common/libdisasm.c
usr/src/lib/libdisasm/common/libdisasm.h
usr/src/lib/libdisasm/common/libdisasm_impl.h
usr/src/lib/libdisasm/common/linktest_stand.c
usr/src/lib/libdisasm/common/llib-ldisasm
usr/src/lib/libdisasm/i386/Makefile
usr/src/lib/libdisasm/i386/dis_i386.c
usr/src/lib/libdisasm/spec/Makefile
usr/src/lib/libdisasm/spec/Makefile.targ
usr/src/lib/libdisasm/spec/amd64/Makefile
usr/src/lib/libdisasm/spec/i386/Makefile
usr/src/lib/libdisasm/spec/libdisasm.spec
usr/src/lib/libdisasm/spec/sparc/Makefile
usr/src/lib/libdisasm/spec/sparcv9/Makefile
usr/src/lib/libdisasm/spec/versions
usr/src/pkgdefs/SUNWcsl/prototype_com
usr/src/pkgdefs/SUNWcsl/prototype_i386
usr/src/pkgdefs/SUNWcsl/prototype_sparc
usr/src/pkgdefs/SUNWmdb/prototype_sparc
usr/src/pkgdefs/SUNWmdbr/prototype_sparc
usr/src/pkgdefs/etc/exception_list_i386
usr/src/pkgdefs/etc/exception_list_sparc
usr/src/tools/scripts/bfu.sh
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/deleted_files/usr/src/cmd/mdb/intel/mdb/bits.c	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,157 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 1988 AT&T
+ * All rights reserved.
+ *
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include	"dis.h"
+
+/*
+ * Minimum instruction name field width
+ */
+#define	INST_MINWIDTH	7
+
+/* For communication to locsympr */
+const char *const *regname;
+static char mneu[256];  /* array to store disassembly for return */
+static uchar_t curbyte;	/* result of getbyte() */
+
+static	mdb_tgt_t 	*dis_target;
+static	mdb_tgt_as_t	dis_as;
+static	mdb_tgt_addr_t	dis_offset;
+static	ssize_t		dis_size;
+static	uchar_t		dis_buffer[64];
+
+static	mdb_tgt_addr_t	curloc;
+
+
+/*
+ * Get next byte from the instruction stream,
+ * set curbyte and increment curloc.
+ */
+/*ARGSUSED*/
+static int
+getbyte(void *notused)
+{
+	ulong_t index = (ulong_t)(curloc - dis_offset);
+
+	if (index >= dis_size) {
+		dis_size = mdb_tgt_aread(dis_target, dis_as, dis_buffer,
+			sizeof (dis_buffer), curloc);
+
+		if (dis_size <= 0) {
+			dis_offset = 0;
+			dis_size = 0;
+			curbyte = 0;
+			return (-1);
+		}
+
+		dis_offset = curloc;
+		index = 0;
+	}
+
+	curbyte = dis_buffer[index];
+	curloc++;
+	return (curbyte);
+}
+
+static int
+symlookup(uint64_t addr, char *buf, size_t len)
+{
+	(void) mdb_iob_snprintf(buf, len, "%a", (uintptr_t)addr);
+	if (strncmp(buf, "0x", 2) == 0) {
+		if (len > 0)
+			*buf = '\0';
+		return (-1);
+	}
+	return (0);
+}
+
+/*
+ * disassemble an instruction. Mode can be DIS_IA32 or DIS_AMD64.
+ */
+/*ARGSUSED*/
+static void
+disasm(int mode)
+{
+	dis86_t		x86dis;
+	uint_t		cpu_mode = SIZE32;
+
+#ifdef __amd64
+	if (mode == DIS_AMD64)
+		cpu_mode = SIZE64;
+#endif
+
+	bzero(&x86dis, sizeof (dis86_t));
+	x86dis.d86_check_func = NULL;
+	x86dis.d86_get_byte = getbyte;
+	x86dis.d86_sprintf_func =
+	    (int (*)(char *, size_t, const char *, ...))mdb_iob_snprintf;
+	x86dis.d86_sym_lookup = symlookup;
+
+	if (dtrace_disx86(&x86dis, cpu_mode) != 0) {
+		(void) strcpy(mneu, "***ERROR--unknown op code***");
+		return;
+	}
+
+	dtrace_disx86_str(&x86dis, cpu_mode, curloc, mneu, sizeof (mneu));
+}
+
+/*ARGSUSED*/
+mdb_tgt_addr_t
+ia32dis_ins2str(mdb_disasm_t *dp, mdb_tgt_t *t, mdb_tgt_as_t as,
+    char *buf, size_t len, mdb_tgt_addr_t pc)
+{
+	char *cp;
+
+	dis_target = t;		/* target pointer */
+	dis_as = as;		/* address space identifier */
+	dis_offset = pc;	/* address of current instruction */
+	dis_size = 1;		/* size of current instruction */
+
+	if (mdb_tgt_aread(t, as, &dis_buffer[0], sizeof (char), pc) == -1) {
+		warn("failed to read instruction at %llr", pc);
+		return (pc);
+	}
+
+	/*
+	 * Disassemble one instruction starting at curloc,
+	 * increment curloc to the following location,
+	 * and leave the ascii result in mneu[]. dp->dis_data
+	 * holds the disassembly mode; DIS_AMD64 or DIS_IA32.
+	 */
+	curloc = pc;
+	disasm((uintptr_t)dp->dis_data);
+
+	cp = mneu + strlen(mneu);
+	while (cp-- > mneu && *cp == ' ')
+		*cp = '\0';
+	(void) mdb_snprintf(buf, len, "%s", mneu);
+	return (curloc);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/deleted_files/usr/src/cmd/mdb/intel/mdb/dis.h	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*	Copyright (c) 1988 AT&T	*/
+/*	  All Rights Reserved  	*/
+
+
+#ifndef _DIS_H
+#define	_DIS_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <string.h>
+#include <dis_tables.h>
+
+#include <mdb/mdb_disasm_impl.h>
+#include <mdb/mdb_err.h>
+#include <mdb/mdb_io.h>
+#include <mdb/mdb.h>
+
+#define	NHEX	40	/* max # chars in object per line	*/
+#define	NLINE	1024	/* max # chars in mnemonic per line	*/
+#define	TRUE	1
+#define	FALSE	0
+#define	LEAD	1
+#define	NOLEAD	0
+#define	NOLEADSHORT 2
+
+#define	DIS_IA32	0
+#define	DIS_AMD64	1
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DIS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/deleted_files/usr/src/cmd/mdb/intel/mdb/inteldis.c	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,134 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include "dis.h"
+
+extern mdb_tgt_addr_t ia32dis_ins2str(mdb_disasm_t *, mdb_tgt_t *,
+    mdb_tgt_as_t, char *, size_t, mdb_tgt_addr_t);
+
+/*ARGSUSED*/
+static void
+ia32dis_destroy(mdb_disasm_t *dp)
+{
+	/* Nothing to do here */
+}
+
+static mdb_tgt_addr_t
+ia32dis_previns(mdb_disasm_t *dp, mdb_tgt_t *t, mdb_tgt_as_t as,
+    mdb_tgt_addr_t pc, uint_t n)
+{
+	mdb_tgt_addr_t *hist, addr, naddr;
+	mdb_tgt_addr_t res = pc;
+	GElf_Sym sym;
+	int cur, nseen;
+	char c;
+
+	if (mdb_lookup_by_addr(pc, MDB_SYM_FUZZY, &c, 1, &sym) < 0 ||
+	    sym.st_value == pc)
+		return (pc); /* we need to be in the middle of a symbol */
+
+	hist = mdb_zalloc(sizeof (mdb_tgt_addr_t) * n, UM_SLEEP);
+
+	for (cur = 0, nseen = 0, addr = sym.st_value; addr < pc; addr = naddr) {
+		hist[cur] = addr;
+		cur = (cur + 1) % n;
+		nseen++;
+
+		if (mdb_tgt_aread(t, as, &c, 1, addr) != 1 ||
+		    (naddr = ia32dis_ins2str(dp, t, as, &c, 1, addr)) == addr)
+			goto done; /* no progress or can't read - give up */
+	}
+
+	if (addr != pc) {
+		/*
+		 * We scanned past %pc, but didn't find an instruction that
+		 * started at %pc.  This means that either the caller specified
+		 * an invalid address, or we ran into something other than code
+		 * during our scan.  Virtually any combination of bytes can be
+		 * construed as a valid Intel instruction, so any non-code bytes
+		 * we encounter will have thrown off the scan.
+		 */
+		goto done;
+	}
+
+	res = hist[(cur + n - MIN(n, nseen)) % n];
+
+done:
+	mdb_free(hist, sizeof (mdb_tgt_addr_t) * n);
+	return (res);
+}
+
+/*ARGSUSED*/
+static mdb_tgt_addr_t
+ia32dis_nextins(mdb_disasm_t *dp, mdb_tgt_t *t, mdb_tgt_as_t as,
+    mdb_tgt_addr_t pc)
+{
+	mdb_tgt_addr_t npc;
+	char c;
+
+	if ((npc = ia32dis_ins2str(dp, t, as, &c, 1, pc)) == pc)
+		return (pc);
+
+	/*
+	 * Probe the address to make sure we can read something from it - we
+	 * want the address we return to actually contain something.
+	 */
+	if (mdb_tgt_aread(t, as, &c, 1, npc) != 1)
+		return (pc);
+
+	return (npc);
+}
+
+static const mdb_dis_ops_t ia32dis_ops = {
+	ia32dis_destroy,
+	ia32dis_ins2str,
+	ia32dis_previns,
+	ia32dis_nextins
+};
+
+int
+ia32_create(mdb_disasm_t *dp)
+{
+	dp->dis_name = "ia32";
+	dp->dis_desc = "Intel 32-bit disassembler";
+	dp->dis_ops = &ia32dis_ops;
+	dp->dis_data = (void *)DIS_IA32;
+
+	return (0);
+}
+
+int
+amd64_create(mdb_disasm_t *dp)
+{
+	dp->dis_name = "amd64";
+	dp->dis_desc = "AMD64 and IA32e 64-bit disassembler";
+	dp->dis_ops = &ia32dis_ops;
+	dp->dis_data = (void *)DIS_AMD64;
+
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/deleted_files/usr/src/cmd/sgs/sgsdemangler/common/cafe_dem.h	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,168 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ *	Copyright 1993 by Sun Microsystems, Inc.
+ *	All Rights Reserved.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/***************************************************************** 
+
+  Copyright  1993 Sun Microsystems 
+  All Rights Reserved.
+
+  %W% %G% %U%
+
+  Revisions
+     06/10/93 - Raymond Lai  Created
+
+******************************************************************/
+
+#ifndef _CAFE_DEM_H
+#define _CAFE_DEM_H
+
+#include "dem.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Note: NDEM_type starts with 1000 so that dbx can tell a NDEM_name
+   structure from a DEM (cfront) one.
+*/
+
+enum NDEM_type {
+	NDEM_other = 1000,	/* default */
+	NDEM_constructor, NDEM_destructor, NDEM_operator, NDEM_conversion,
+	NDEM_unnamed_arg, NDEM_static_constructor, NDEM_static_destructor
+};
+
+typedef struct NDEM_modifier {
+	char			 is_signed : 1;
+	char			 is_volatile : 1;
+	char			 is_unsigned : 1;
+	char			 is_const : 1;
+	char			 is_static : 1;
+} NDEM_modifier;
+
+struct NDEM_class;
+struct NDEM_arg;
+
+/* A cafe name.  This can be either a (static) data member, a function member,
+   or a global function.
+*/
+
+typedef struct NDEM_name {
+	enum NDEM_type		 type;
+	struct NDEM_class	*qual_class;
+	char 			*raw_name;
+	struct NDEM_arg		*conv_t;	/* for conversion function */
+	struct NDEM_arg		*f_args;	/* for function */
+	struct NDEM_modifier	 f_modifier;	/* for member function */
+} NDEM_name;
+
+/* A class. */
+
+typedef struct NDEM_class {
+	struct NDEM_class	*qual_class;
+	char			*raw_class_name;
+	struct NDEM_arg		*t_args;	/* for template class */
+} NDEM_class;
+
+/* A function pointer (as an argument). */
+
+typedef struct NDEM_fptr {
+	struct NDEM_class	*qual_class;
+	struct NDEM_arg		*f_args;
+	struct NDEM_arg		*return_t;
+	struct NDEM_arg		*decls;		/* function declarator list */
+} NDEM_fptr;
+
+/* A member data pointer (as an argument). */
+
+typedef struct NDEM_mdptr {
+	struct NDEM_class	*qual_class;
+	struct NDEM_arg		*mem_data_t;
+} NDEM_mdptr;
+
+/* An abbreviation record (for arguments like "NDC", "TB"). */
+
+typedef struct NDEM_abbrev_rec {
+	int			 repetition_number;
+	int			 param_number;
+} NDEM_abbrev_rec;
+
+/* A pointer, reference, or array introduces a type of its own... */
+
+enum NDEM_decl_type {
+	NDEM_pointer = 1, NDEM_reference, NDEM_array
+};
+
+typedef struct NDEM_declarator {
+	enum NDEM_decl_type	 decl_type;
+	struct NDEM_arg		*real_arg;
+	char			*array_size;	/* if an array */
+} NDEM_declarator;
+
+enum NDEM_arg_type {
+	NDEM_basic_type, NDEM_user_defined_type, NDEM_function_ptr, NDEM_decl,
+	NDEM_mem_data_ptr,
+	NDEM_abbrev_N, NDEM_abbrev_T,
+	NDEM_i_const, /* template integral constant argument */
+	NDEM_p_const  /* template pointer constant argument */
+};
+
+/* A type. */
+
+typedef struct NDEM_arg {
+	enum NDEM_arg_type		 arg_type;
+	union {
+		char			 basic_t;
+		struct NDEM_class	*user_defined_t;
+		struct NDEM_fptr	*function_ptr;
+		struct NDEM_mdptr	*mem_data_ptr;
+		struct NDEM_abbrev_rec	 abbrev_rec;
+		struct NDEM_declarator	 decl;
+		char			*pt_constant;
+		struct NDEM_name	*temp_p_arg;
+	} arg_data;
+	struct NDEM_modifier		 modifier;
+	struct NDEM_arg			*next;
+} NDEM_arg;
+
+#ifdef DBX_SUPPORT
+
+extern int		cafe_dem		(char *, NDEM_name *, char *);
+extern enum DEM_TYPE	cafe_getfieldtype	(NDEM_name *);
+extern char		*cafe_getclass		(NDEM_name *, char *);
+extern char		*cafe_getname		(NDEM_name *, char *);
+extern char		**cafe_getparentclass	(NDEM_name *, char **);
+extern char		*cafe_gettemplatename	(NDEM_name *);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/deleted_files/usr/src/cmd/sgs/sgsdemangler/common/cafe_dem.y	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,1615 @@
+%{
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *	Copyright 1993-2000 by Sun Microsystems, Inc.
+ *	All Rights Reserved
+ */
+/***************************************************************** 
+
+  %W% %G% %U%
+
+  Revisions
+     06/10/93 - Raymond Lai  Created
+
+******************************************************************/
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "cafe_dem.h"
+
+#define		 DEM_VERSION	0
+#define		 CHECK_OLD_PREFIX(s) (s[0] == '$')
+#define		 CHECK_PREFIX(s) (s[0] == '_' && s[1] == '_' && \
+				isdigit(s[2]) && DEM_VERSION >= s[2] - '0')
+
+static char	 ll_cur_char;
+static int	 ll_id_size = 0;	/* the default token is of size 1 */
+static char	*yytext;
+
+#define		 BUFSIZE	8192
+static char	 name_buffer[BUFSIZE];
+static char	*mem_reservoir;
+
+#define 	 ALIGN_MASK	03
+
+static void *allocate(size_t size)
+{
+	char *pos;
+
+	while ((unsigned long)mem_reservoir & ALIGN_MASK)
+		++mem_reservoir;
+	pos = mem_reservoir;
+	mem_reservoir += size;
+	return pos;
+}
+
+/* Will only be called by print_template_args() and print_function_args()
+   to deallocate the excess memory allocated for argument array.
+*/
+
+static void deallocate(size_t size)
+{
+	mem_reservoir -= size;
+}
+
+static char *convert_number(int n)
+{
+	int i, len = 0;
+	static char tmp[1024];
+	char *s;
+
+	if (n == 0) return NULL;
+
+	do {
+		tmp[len++] = n % 10 + '0';
+	} while ((n /= 10) > 0);
+
+	s = allocate(len+1);
+	i = 0;
+	while (--len >= 0)
+		s[i++] = tmp[len];
+	s[i] = '\0';
+
+	return s;
+}
+
+static NDEM_name *result;
+static NDEM_arg *conv_type;
+static NDEM_modifier save_modifier, current_modifier = { 0, 0, 0, 0, 0 };
+
+static void reset_current_modifier()
+{
+	current_modifier.is_signed = current_modifier.is_volatile =
+	current_modifier.is_unsigned = current_modifier.is_const =
+	current_modifier.is_static = 0;
+}
+
+enum Boolean { TRUE = 1, FALSE = 0 };
+
+/* Don't build function argument structures when yyparse() is called by
+   cafe_dem()...
+*/
+static enum Boolean from_cafe_dem = FALSE;
+static enum Boolean build_args = TRUE;
+
+/* Function arguments of embedded functions still need to be handled.  For
+   example:
+
+   $fDfoo7$FBfPvi44D_Dbarv == foo<&f(void*, int), 3>::bar( <IGNORE> )
+          ^^^^^^^                 ^^^^^^^^^^^^^^
+
+   The following stack is used for this purpose.  When the parser is called
+   by cafe_dem() to parse a function, it first pushes a TRUE onto the stack.
+   All subsequent values pushed into the stack are FALSE.
+
+   Note the stack doesn't need to be large.
+*/
+static enum Boolean stack[10];
+static int sk_top = 0;
+
+#define push(f) stack[sk_top++] = f
+#define pop() stack[--sk_top]
+
+/*________________________________________________________________________*/
+
+%}
+
+%union {
+	int		 i_val;
+	char		 c_val;
+	char		*s_val;
+	NDEM_name	*n_val;
+	NDEM_class	*class_val;
+	NDEM_arg	*arg_val;
+	NDEM_fptr	*fptr_val;
+}
+
+%token IDENTIFIER NUMBER
+
+%type <i_val> big_number uname_size
+
+%type <s_val> uname_spec uname_specN op_name optimize_number
+
+%type <n_val> function_name global_data_name
+
+/* namespace_spec is used solely for qualifying class(es) for now... */
+%type <class_val> class_spec class_specN namespace_spec
+
+%type <arg_val> template_spec template_arg_spec t_arg_spec arg_spec
+		arg_type formal_arg_spec arg_abbrev type_declarator
+		modifier_n_declarator
+
+%type <fptr_val> function_arg_spec
+
+%% 
+
+
+mangled_name :
+	function_name
+	    {	 result = $1; }
+|	global_data_name
+	    {	 result = $1; }
+|	internal_name
+|	external_linkage_name
+|	error
+	    {	 return 1;   }
+;
+
+PREFIX :
+	'_' '_' VERSION
+	    {	if (DEM_VERSION < ll_cur_char - '0') YYERROR;   }
+|	'$'
+;
+
+VERSION :
+	'0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'
+;
+
+UPPER_LETTER :
+	'A'|'B'|'C'|'D'|'E'|'F'|'G'|'H'|'I'|'J'|'K'|'L'|'M'|'N'|'O'|
+	'P'|'Q'|'R'|'S'|'T'|'U'|'V'|'W'|'X'|'Y'|'Z'
+;
+
+LOWER_LETTER :
+	'a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'i'|'j'|'k'|'l'|'m'|'n'|'o'|
+	'p'|'q'|'r'|'s'|'t'|'u'|'v'|'w'|'x'|'y'|'z'
+;
+
+/* Upper case letter represent the numbers 0 thru 25.  Lower case are the 
+*  numbers  26 thru 51.  A prefix of '0' adds 52 to the value. e.g.:
+*
+*      C = 2
+*      c = 28
+*      y = 50
+*     0y = 102
+*
+*
+* The key features are that:
+*      -numbers less than or equal to 51 are only one character
+*      -the end of a big_number can be found when embedded in a
+*       string: e.g.
+*
+*		 Dfoo = big_number 3, string "foo"
+*		 OCB  = big_number 54, string "B"
+*/
+
+big_number :  
+	UPPER_LETTER 
+	    {	$$ = ll_cur_char - 'A';   }
+|	LOWER_LETTER 
+	    {	$$ = ll_cur_char - 'a' + 26;   }
+|	'0' big_number 
+	    {	$$ = 52 + $2;   }
+;
+
+/*"identifier" is defined the the ANSI committee */
+
+uname : 
+	IDENTIFIER      
+;
+				       
+
+uname_spec : 
+	uname_size
+	    {	ll_id_size = $1;   }
+	uname
+	    {
+		if (build_args)
+		{
+		    $$ = allocate($1+1);
+		    (void) strncpy($$, yytext, $1);
+		    *($$+$1) = '\0';
+		}
+		else
+		    $$ = NULL;
+	    }
+;
+
+uname_size : 
+	big_number
+;
+
+class_specN : 
+	namespace_spec class_spec
+	    {
+		if (build_args)
+		{
+		    $2->qual_class = $1;
+		    $$ = $2;
+		}
+		else
+		    $$ = NULL;
+	    }
+;
+
+class_spec : 
+	fun_local_spec uname_spec template_spec
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_class));
+		    $$->raw_class_name = $2;
+		    $$->t_args = $3;
+		}
+		else
+		    $$ = NULL;
+	    }
+;
+
+uname_specN : 
+	namespace_spec uname_spec
+	    {
+		$$ = $2;
+	    }
+;
+
+namespace_spec : 
+	/* nil */
+	    {	$$ = NULL;   }
+|	namespace_spec '1' uname_spec
+|	namespace_spec '5' class_specN
+	    {
+		if (build_args)
+		{
+		    $3->qual_class = $1;
+		    $$ = $3;
+		}
+		else
+		    $$ = NULL;
+	    }
+;
+
+template_spec :
+	/* nil */
+	    {	$$ = NULL;   }
+|	'7' template_arg_spec '_'
+	    {	$$ = $2;   }
+;
+
+template_arg_spec :
+	t_arg_spec
+|	template_arg_spec t_arg_spec
+	    {
+		if (build_args)
+		{
+		    NDEM_arg *tmp = $1;
+		    while (tmp->next) tmp = tmp->next;
+		    tmp->next = $2;
+		}
+		$$ = $1;
+	    }
+;
+
+t_arg_spec :
+	arg_spec
+|	'4' optimize_number
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_i_const;
+		    $$->arg_data.pt_constant = $2;
+		}
+		else
+		    $$ = NULL;
+	    }
+|	'4' optimize_number 'n'
+	    {
+		if (build_args)
+		{
+		    char *s = allocate(strlen($2)+2);
+		    s[0] = '-';
+		    (void) strcpy(s+1, $2);
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_i_const;
+		    $$->arg_data.pt_constant = s;
+		}
+		else
+		    $$ = NULL;
+	    }
+|	'4' function_name '_'
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_p_const;
+		    $$->arg_data.temp_p_arg = $2;
+		}
+		else
+		    $$ = NULL;
+	    }
+|	'4' global_data_name '_'
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_p_const;
+		    $$->arg_data.temp_p_arg = $2;
+		}
+		else
+		    $$ = NULL;
+	    }
+;
+
+optimize_number :
+	big_number
+	    {
+		if (build_args)
+		    $$ = convert_number($1);
+		else
+		    $$ = NULL;
+	    }
+|	'8' big_number
+	    {	ll_id_size = $2;   }
+	uname
+	    {
+		if (build_args)
+		{
+		    $$ = allocate($2+1);
+		    (void) strncpy($$, yytext, $2);
+		    *($$+$2) = '\0';
+		}
+		else
+		    $$ = NULL;
+	    }
+;
+
+/*
+* ".F" signifies a standard function
+* ".f" is a member function
+* ".O" is a global operator function
+* ".o" is a member operator function
+*/
+
+function_name : 
+	PREFIX 'F'
+	    {
+		push(from_cafe_dem);
+		from_cafe_dem = FALSE;
+	    }
+	uname_specN
+	    {
+		if (pop())
+		    build_args = FALSE;
+	    }
+	formal_arg_spec 
+	    {
+		$$ = allocate(sizeof(NDEM_name));
+		if ($4[0] == 'O')
+		    $$->type = NDEM_conversion;
+		else
+		    $$->type = NDEM_other;
+		$$->raw_name = $4;
+		$$->f_args = $6;
+	    }
+|	PREFIX 'C'
+	    {
+		push(from_cafe_dem);
+		from_cafe_dem = FALSE;
+	    }
+	uname_specN
+	    {
+		if (pop())
+		    build_args = FALSE;
+	    }
+	formal_arg_spec 
+	    {
+		$$ = allocate(sizeof(NDEM_name));
+		$$->type = NDEM_static_constructor;
+		$$->raw_name = "__STATIC_CONSTRUCTOR";
+		$$->f_args = $6;
+	    }
+|	PREFIX 'D'
+	    {
+		push(from_cafe_dem);
+		from_cafe_dem = FALSE;
+	    }
+	uname_specN
+	    {
+		if (pop())
+		    build_args = FALSE;
+	    }
+	formal_arg_spec 
+	    {
+		$$ = allocate(sizeof(NDEM_name));
+		$$->type = NDEM_static_destructor;
+		$$->raw_name = "__STATIC_DESTRUCTOR";
+		$$->f_args = $6;
+	    }
+|	PREFIX 'f'
+	    {
+		push(from_cafe_dem);
+		from_cafe_dem = FALSE;
+	    }
+	class_specN uname_spec
+	    {
+		if (pop())
+		    build_args = FALSE;
+	    }
+	formal_arg_spec f_modifier
+	    {
+		$$ = allocate(sizeof(NDEM_name));
+		$$->type = NDEM_other;
+		$$->qual_class = $4;
+		$$->raw_name = $5;
+		$$->f_args = $7;
+		$$->f_modifier = current_modifier;
+		reset_current_modifier();
+	    }
+|	PREFIX 'O'
+	    {
+		push(from_cafe_dem);
+		from_cafe_dem = FALSE;
+	    }
+	op_name namespace_spec
+	    {
+		if (pop())
+		    build_args = FALSE;
+	    }
+	formal_arg_spec 
+	    {
+		$$ = allocate(sizeof(NDEM_name));
+		if ($4[0] == 'O')
+		{
+		    $$->type = NDEM_conversion;
+		    $$->conv_t = conv_type;
+		}
+		else if ($4[0] == 'C')
+		    $$->type = NDEM_constructor;
+		else if ($4[0] == 'D')
+		    $$->type = NDEM_destructor;
+		else
+		    $$->type = NDEM_operator;
+		$$->raw_name = $4;
+		$$->f_args = $7;
+	    }
+|	PREFIX 'o'
+	    {
+		push(from_cafe_dem);
+		from_cafe_dem = FALSE;
+	    }
+	class_specN op_name
+	    {
+		if (pop())
+		    build_args = FALSE;
+	    }
+	formal_arg_spec f_modifier
+	    {
+		$$ = allocate(sizeof(NDEM_name));
+		if ($5[0] == 'O')
+		{
+		    $$->type = NDEM_conversion;
+		    $$->conv_t = conv_type;
+		}
+		else if ($5[0] == 'C')
+		    $$->type = NDEM_constructor;
+		else if ($5[0] == 'D')
+		    $$->type = NDEM_destructor;
+		else
+		    $$->type = NDEM_operator;
+		$$->qual_class = $4;
+		$$->raw_name = $5;
+		$$->f_args = $7;
+		$$->f_modifier = current_modifier;
+		reset_current_modifier();
+	    }
+;
+
+f_modifier:
+	/* nil */
+|	'K'
+	    { current_modifier.is_const = 1; }
+|	'W'
+	    { current_modifier.is_volatile = 1; }
+|	'T'
+	    { current_modifier.is_static = 1; }
+;
+
+/* Note: "adv" and "add" have been changed to "gav" and "gad" to avoid
+*  grammar conflicts.
+*
+* See p. 125 of the ARM.  Note that operator T() is now "op" class_specN.
+*/
+
+op_name : 
+	'm' 'l'
+	    { $$ = "*"; }
+|	'm' 'd'
+	    { $$ = "%"; }
+|	'm' 'i'
+	    { $$ = "-"; }
+|	'r' 's'
+	    { $$ = ">>"; }
+|	'n' 'e'
+	    { $$ = "!="; }
+|	'g' 't'
+	    { $$ = ">"; }
+|	'g' 'e'
+	    { $$ = ">="; }
+|	'o' 'r'
+	    { $$ = "|"; }
+|	'a' 'a'
+	    { $$ = "&&"; }
+|	'n' 't'
+	    { $$ = "!"; }
+|       'p' 'p'
+	    { $$ = "++"; }
+|	'a' 's'
+	    { $$ = "="; }
+|	'a' 'p' 'l'
+	    { $$ = "+="; }
+|	'a' 'm' 'u'
+	    { $$ = "*="; }
+|	'a' 'm' 'd'
+	    { $$ = "%="; }
+|	'a' 'r' 's'
+	    { $$ = ">>="; }
+|	'a' 'o' 'r'
+	    { $$ = "|="; }
+|	'c' 'm'
+	    { $$ = ","; }
+|	'd' 'v'
+	    { $$ = "/"; }
+|       'p' 'l'
+	    { $$ = "+"; }
+|	'l' 's'
+	    { $$ = "<<"; }
+|	'e' 'q'
+	    { $$ = "=="; }
+|	'l' 't'
+	    { $$ = "<"; }
+|	'l' 'e'
+	    { $$ = "<="; }
+|	'a' 'd'
+	    { $$ = "&"; }
+|	'e' 'r'
+	    { $$ = "^"; }
+|	'o' 'o'
+	    { $$ = "||"; }
+|	'c' 'o'
+	    { $$ = "~"; }
+|	'm' 'm'
+	    { $$ = "--"; }
+|       'r' 'f'
+	    { $$ = "->"; }
+|	'a' 'm' 'i'
+	    { $$ = "-="; }
+|	'g' 'd' 'v'
+/*	'a' 'd' 'v'	*/
+	    { $$ = "/="; }
+|	'a' 'l' 's'
+	    { $$ = "<<="; }
+|	'g' 'a' 'd'
+/*	'a' 'a' 'd'	*/
+	    { $$ = "&="; }
+|	'a' 'e' 'r'
+	    { $$ = "^="; }
+|	'r' 'm'
+	    { $$ = "->*"; }
+|	'c' 'l'
+	    { $$ = "()"; }
+|	'v' 'c'
+	    { $$ = "[]"; }
+|       'c' 't'
+	    { $$ = "C"; }
+|	'd' 't'
+	    { $$ = "D"; }
+|	'n' 'w'
+	    { $$ = "new"; }
+|	'd' 'l'
+	    { $$ = "delete"; }
+|	'o' 'p' arg_spec
+	    {
+		conv_type = $3;
+		$$ = "O";
+	    }
+;
+
+/* "$N" is for global data (they are mangled when their addresses are
+	passed as template arguments).
+*  "$d" is for static data members
+*/
+
+global_data_name : 
+	PREFIX 'N' namespace_spec uname_spec
+	    {
+		$$ = allocate(sizeof(NDEM_name));
+		$$->type = NDEM_other;
+		$$->raw_name = $4;
+	    }
+|	PREFIX 'd' class_specN uname_spec
+	    {
+		$$ = allocate(sizeof(NDEM_name));
+		$$->type = NDEM_other;
+		$$->qual_class = $3;
+		$$->raw_name = $4;
+	    }
+;
+
+/*
+*  "$P" is for compiler private data and must be file local or block local.
+*  "$X" is for extensions and can be global.  The big_number should be used
+*     to serialize the extensions since collisions between different compilers
+*     can occur. (Note that "P" is file local and doesn't have this problem.)
+*  "$V" is for virtual tables.  It is to be global.
+*/ 
+
+internal_name : 
+ 	 PREFIX 'P' private_id 
+|	 PREFIX 'X' big_number private_id 
+| 	 PREFIX 'V' class_specN
+;
+
+private_id : 
+	/* FIXUP: This is implementation specific */
+;
+
+external_linkage_name : 
+	/* defined by other languages ABI */
+;
+
+/* This is used to add info for function local classes.  The big_number is a
+*  compiler dependent scope identifier and can be omitted if not needed.
+*/
+
+/* Note that function local classes only need to be mangled when the linker
+*  will see them, such as when a member function will be instantiated.
+*/
+
+fun_local_spec : 
+ 	/* nil */ 
+|	'2' fun_local_scope
+; 
+
+fun_local_scope :
+	big_number
+|	'8' big_number
+	    {   ll_id_size = $2;   }
+	uname
+;
+
+arg_spec : 
+	modifier_n_declarator arg_type
+	    {
+		if (build_args)
+		{
+		    $2->modifier = current_modifier;
+		    reset_current_modifier();
+		    if ($1) {
+		        if ($2->arg_type == NDEM_function_ptr) {
+			    $2->arg_data.function_ptr->decls = $1;
+			    $$ = $2;
+		        }
+		        else {
+			    NDEM_arg *tmp = $1;
+			    while (tmp->arg_data.decl.real_arg)
+			        tmp = tmp->arg_data.decl.real_arg;
+			    tmp->arg_data.decl.real_arg = $2;
+			    $$ = $1;
+		        }
+		    }
+		    else
+		        $$ = $2;
+		}
+		else
+		    $$ = NULL;
+	    }
+|	arg_abbrev
+;
+
+function_arg_spec :
+	'F' formal_arg_spec '_' arg_spec
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_fptr));
+		    $$->f_args = $2;
+		    $$->return_t = $4;
+		}
+		else
+		    $$ = NULL;
+	    }
+|	'M' class_specN 'F' formal_arg_spec f_modifier
+	    {
+		if (build_args)
+		{
+		    save_modifier = current_modifier;
+		    reset_current_modifier();
+		}
+	    }
+	'_' arg_spec
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_fptr));
+		    $$->qual_class = $2;
+		    $$->f_args = $4;
+		    $$->return_t = $8;
+		    current_modifier = save_modifier;
+		}
+		else
+		    $$ = NULL;
+	    }
+;
+
+formal_arg_spec :
+	formal_arg_spec arg_spec
+	    {
+		if (build_args)
+		{
+		    NDEM_arg *tmp = $1;
+		    while (tmp->next) tmp = tmp->next;
+		    tmp->next = $2;
+		    $$ = $1;
+		}
+		else
+		    $$ = NULL;
+	    }
+|	arg_spec
+;
+
+modifier_n_declarator :
+	/* nil */
+	    {	 $$ = NULL;   }
+|	modifier_n_declarator modifier
+|	modifier_n_declarator type_declarator
+	    {
+		if (build_args)
+		{
+		    if ($1) {
+		        NDEM_arg *tmp = $1;
+		        while (tmp->arg_data.decl.real_arg)
+			    tmp = tmp->arg_data.decl.real_arg;
+		        tmp->arg_data.decl.real_arg = $2;
+		        $$ = $1;
+		    }
+		    else
+		        $$ = $2;
+		}
+		else
+		    $$ = NULL;
+	    }
+;
+
+modifier : 
+	'C'
+	    {
+		if (build_args)
+		    current_modifier.is_const = 1;
+	    }
+|	'S'
+	    {
+		if (build_args)
+		    current_modifier.is_signed = 1;
+	    }
+|	'U'
+	    {
+		if (build_args)
+		    current_modifier.is_unsigned = 1;
+	    }
+|	'V'
+	    {
+		if (build_args)
+		    current_modifier.is_volatile = 1;
+	    }
+;
+
+type_declarator : 
+	'P' 
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_decl;
+		    $$->arg_data.decl.decl_type = NDEM_pointer;
+		    $$->modifier = current_modifier;
+		    reset_current_modifier();
+		}
+		else
+		    $$ = NULL;
+	    }
+|	'R' 
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_decl;
+		    $$->arg_data.decl.decl_type = NDEM_reference;
+		    $$->modifier = current_modifier;
+		    reset_current_modifier();
+		}
+		else
+		    $$ = NULL;
+	    }
+|	'A' big_number 
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_decl;
+		    $$->arg_data.decl.decl_type = NDEM_array;
+		    $$->arg_data.decl.array_size = convert_number($2);
+		    $$->modifier = current_modifier;
+		    reset_current_modifier();
+		}
+		else
+		    $$ = NULL;
+	    }
+|	'A' '8' big_number
+	    {	ll_id_size = $3;   }
+	uname
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_decl;
+		    $$->arg_data.decl.decl_type = NDEM_array;
+		    $$->arg_data.decl.array_size = allocate($3+1);
+		    (void) strncpy($$->arg_data.decl.array_size, yytext, $3);
+		    *($$->arg_data.decl.array_size+$3) = '\0';
+		    $$->modifier = current_modifier;
+		    reset_current_modifier();
+		}
+		else
+		    $$ = NULL;
+	    }
+;
+
+arg_type : 
+	'v' 
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_basic_type;
+		    $$->arg_data.basic_t = 'v';
+		}
+		else
+		    $$ = NULL;
+	    }
+|	'c' 
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_basic_type;
+		    $$->arg_data.basic_t = 'c';
+		}
+		else
+		    $$ = NULL;
+	    }
+|	's' 
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_basic_type;
+		    $$->arg_data.basic_t = 's';
+		}
+		else
+		    $$ = NULL;
+	    }
+|	'i' 
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_basic_type;
+		    $$->arg_data.basic_t = 'i';
+		}
+		else
+		    $$ = NULL;
+	    }
+|	'l' 
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_basic_type;
+		    $$->arg_data.basic_t = 'l';
+		}
+		else
+		    $$ = NULL;
+	    }
+|	'f' 
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_basic_type;
+		    $$->arg_data.basic_t = 'f';
+		}
+		else
+		    $$ = NULL;
+	    }
+|	'd' 
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_basic_type;
+		    $$->arg_data.basic_t = 'd';
+		}
+		else
+		    $$ = NULL;
+	    }
+|	'D' 
+/*	'r'	*/
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_basic_type;
+		    $$->arg_data.basic_t = 'D';
+		}
+		else
+		    $$ = NULL;
+	    }
+|	'L'
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_basic_type;
+		    $$->arg_data.basic_t = 'L';
+		}
+		else
+		    $$ = NULL;
+	    }
+| 	'e' 
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_basic_type;
+		    $$->arg_data.basic_t = 'e';
+		}
+		else
+		    $$ = NULL;
+	    }
+| 	'G' 
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_basic_type;
+		    $$->arg_data.basic_t = 'G';
+		}
+		else
+		    $$ = NULL;
+	    }
+| 	'w' 
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_basic_type;
+		    $$->arg_data.basic_t = 'w';
+		}
+		else
+		    $$ = NULL;
+	    }
+|	'6' class_specN
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_user_defined_type;
+		    $$->arg_data.user_defined_t = $2;
+		}
+		else
+		    $$ = NULL;
+	    }
+|	function_arg_spec
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_function_ptr;
+		    $$->arg_data.function_ptr = $1;
+		}
+		else
+		    $$ = NULL;
+	    }
+|	'M' class_specN 'D' arg_spec
+	    {
+		if (build_args)
+		{
+		    NDEM_mdptr *t = allocate(sizeof(NDEM_mdptr));
+		    t->qual_class = $2;
+		    t->mem_data_t = $4;
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_mem_data_ptr;
+		    $$->arg_data.mem_data_ptr = t;
+		}
+		else
+		    $$ = NULL;
+	    }
+;
+
+arg_abbrev : 
+	'N' big_number big_number 
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_abbrev_N;
+		    $$->arg_data.abbrev_rec.repetition_number = $2;
+		    $$->arg_data.abbrev_rec.param_number = $3;
+		}
+		else
+		    $$ = NULL;
+	    }
+|	'T' big_number   
+	    {
+		if (build_args)
+		{
+		    $$ = allocate(sizeof(NDEM_arg));
+		    $$->arg_type = NDEM_abbrev_T;
+		    $$->arg_data.abbrev_rec.param_number = $2;
+		}
+		else
+		    $$ = NULL;
+	    }
+;
+
+
+/* EXAMPLES:
+
+    ***  THIS SECTION NEEDS TO BE UPDATED !! ***
+
+  C++ constuct               New                  Cfront
+  ------------              -----                --------
+
+   P(int);                  .FAPi                 P__fi
+
+   class a
+   {
+      Q (double);           .fAaAQd               Q__1aFd
+      class b
+      {
+         R(...);            .f5AaAbARe            R__Q21a|bFe
+      }
+      S(a);                 .fAaAS5Aa             S__1aFa 
+   }
+
+   namespace n
+   {
+      T(void);              .F1AnATv
+      class c
+      {
+         U(void);           .f1AnAcAUv
+         namespace m
+         {
+            W(void)         .F1An5Ac1AmAWv
+         }
+      }
+      namespace p
+      {
+         X(void);           .F1An1ApAXv
+      }
+   }            
+
+
+ NOTES
+           
+The dot (.), can be replaced by any character that is not valid in the 
+first position of the linker symbols of languages that C++ will be
+linked with.
+
+
+Numeric switches:
+
+
+     Number           Rule              Preceeds
+-------------------------------------------------------          
+       0         big_number          more numbers
+       1         namespace_spec      a namespace
+       2         fun_local_spec      a class local to a function 
+       3         template_spec       a template spec
+       4         fun_local_spec      a scope id
+       5         namespace_spec      a class
+       6         arg_spec            a class object as an argument
+
+Type Letters
+
+  
+     Letter           Rule              Type
+-------------------------------------------------------
+      .F         function_name       function
+      .f         function_name       member function
+      .s         function_name       static member function
+      .O         function_name       operator
+      .o         function_name       operator member
+      .D         global_data_name    global data
+      .d         global_data_name    static member data
+      .P         internal_name       name, private to compiler
+      .X         internal_name       a compiler extension 
+      .V         internal_name       virtual table
+
+Naming convention frequently, but not always, followed:
+
+     (anything)_size        a big_number giving size of the next item
+
+     (anything)_spec        an item, including its size, e.g.: class_spec
+
+     (anything)_specN       same as (anything)_spec but with optional 
+                            name space
+
+*/    
+
+%%
+
+static char *out_buffer;
+static int obx = 0;		/* out_buffer index */
+
+static void put_characters(char *s, size_t len)
+{
+    size_t i;
+    for (i = 0;  i < len; ++i)
+	out_buffer[obx++] = s[i];
+}
+
+#define put_string(s)						\
+{								\
+    put_characters(s, strlen(s));				\
+}
+
+static void print_simple_type(char t)
+{
+    switch(t) {
+
+	case 'v':
+	    put_characters("void", 4);
+	    break;
+
+	case 'c':
+	    put_characters("char", 4);
+	    break;
+
+	case 's':
+	    put_characters("short", 5);
+	    break;
+
+	case 'i':
+	    put_characters("int", 3);
+	    break;
+
+	case 'l':
+	    put_characters("long", 4);
+	    break;
+
+	case 'f':
+	    put_characters("float", 5);
+	    break;
+
+	case 'd':
+	    put_characters("double", 6);
+	    break;
+
+	case 'D':
+	    put_characters("long double", 11);
+	    break;
+
+	case 'L':
+	    put_characters("long long", 9);
+	    break;
+
+	case 'e':
+	    put_characters("...", 3);
+	    break;
+
+	case 'w':
+	    put_characters("wchar_t", 7);
+	    break;
+
+	case 'G':
+	    put_characters("T", 1);
+	    break;
+    }
+}
+
+static void print_class(NDEM_class *, int);
+static void print_function_args(NDEM_arg *);
+static void print_name(NDEM_name *);
+
+static void print_modifier(NDEM_modifier mod)
+{
+    if (mod.is_const) put_characters("const ", 6);
+    if (mod.is_signed) put_characters("signed ", 7);
+    if (mod.is_unsigned) put_characters("unsigned ", 9);
+    if (mod.is_volatile) put_characters("volatile ", 9);
+}
+
+/* print modifier(s) of pointers */
+static void print_p_modifier(NDEM_modifier mod)
+{
+    if (mod.is_const) put_characters(" const", 6);
+    if (mod.is_volatile) put_characters(" volatile", 9);
+}
+
+static void print_arg(NDEM_arg *arg)
+{
+    if (! arg) return;
+
+    switch(arg->arg_type) {
+
+        case NDEM_basic_type:
+	    print_modifier(arg->modifier);
+	    print_simple_type(arg->arg_data.basic_t);
+	    break;
+
+	case NDEM_user_defined_type:
+	    print_modifier(arg->modifier);
+	    print_class(arg->arg_data.user_defined_t, 1);
+	    break;
+
+	case NDEM_function_ptr:
+	    print_arg(arg->arg_data.function_ptr->return_t);
+	    put_characters(" (", 2);
+	    if (arg->arg_data.function_ptr->qual_class)
+	    {
+		print_class(arg->arg_data.function_ptr->qual_class, 1);
+		put_characters("::", 2);
+	    }
+	    print_arg(arg->arg_data.function_ptr->decls);
+	    put_characters(")", 1);
+	    print_function_args(arg->arg_data.function_ptr->f_args);
+	    print_p_modifier(arg->modifier);
+	    break;
+
+	case NDEM_mem_data_ptr:
+	    print_arg(arg->arg_data.mem_data_ptr->mem_data_t);
+	    put_characters(" ", 1);
+	    print_class(arg->arg_data.mem_data_ptr->qual_class, 1);
+	    put_characters("::", 2);
+	    break;
+
+	case NDEM_decl:
+	    /* The last node in function pointer declarator list is NULL.
+	    */
+	    if (arg->arg_data.decl.real_arg)
+	    	print_arg(arg->arg_data.decl.real_arg);
+	    switch(arg->arg_data.decl.decl_type) {
+
+		case NDEM_pointer:
+		    put_characters("*", 1);
+		    break;
+
+		case NDEM_reference:
+		    put_characters("&", 1);
+		    break;
+
+		case NDEM_array:
+		    put_characters("[", 1);
+		    if (arg->arg_data.decl.array_size)
+			put_string(arg->arg_data.decl.array_size)
+		    put_characters("]", 1);
+		    break;
+	    }
+	    print_p_modifier(arg->modifier);
+	    break;
+
+	case NDEM_i_const:
+	    if (arg->arg_data.pt_constant)
+		put_string(arg->arg_data.pt_constant)
+	    else
+		put_characters("0", 1);
+	    break;
+
+	case NDEM_p_const:
+	    put_characters("&", 1);
+	    print_name(arg->arg_data.temp_p_arg);
+	    break;
+
+	case NDEM_abbrev_N:
+	case NDEM_abbrev_T:
+	   /* should never come to here! */
+	default:
+	    break;
+    }
+}
+
+static void flat_args(NDEM_arg *in, NDEM_arg **arg_arr, int *n_ptr)
+{
+    int i, n = 0;
+
+    while (in)
+    {
+	if (in->arg_type == NDEM_abbrev_T || in->arg_type == NDEM_abbrev_N)
+	{
+	    /* first align with arg_arr index... */
+	    in->arg_data.abbrev_rec.param_number -= 1;
+
+	    if (in->arg_data.abbrev_rec.param_number >= n)
+	    {
+		/* something's wrong.  skip the argument */
+		in = in->next;
+		break;
+	    }
+	    if (in->arg_type == NDEM_abbrev_T)
+		arg_arr[n++] = arg_arr[in->arg_data.abbrev_rec.param_number];
+	    else
+		for (i = 0;  i < in->arg_data.abbrev_rec.repetition_number;  i++)
+		    arg_arr[n++] = arg_arr[in->arg_data.abbrev_rec.param_number];
+	}
+	else
+	    arg_arr[n++] = in;
+	in = in->next;
+    }
+    *n_ptr = n;
+}
+
+#define MAX_ARG 300
+static const int arg_array_size = sizeof(NDEM_arg *) * MAX_ARG;
+
+static void print_template_args(NDEM_arg *arg)
+{
+    NDEM_arg **new_arg_list;
+    int no_of_args, i;
+
+    if (! arg)
+    {
+	put_characters("<?>", 3);
+	return;
+    }
+
+    put_characters("<", 1);
+    new_arg_list = allocate(arg_array_size);
+    flat_args(arg, new_arg_list, &no_of_args);
+
+    /* deallocate the excess memory...
+    */
+    deallocate(arg_array_size - sizeof(NDEM_arg *) * no_of_args);
+
+    for(i = 0;  i < no_of_args;  ++i)
+    {
+	print_arg(new_arg_list[i]);
+	if (i < no_of_args - 1)
+	    put_characters(", ", 2);
+    }
+    put_characters(">", 1);
+}
+
+static void print_function_args(NDEM_arg *arg)
+{
+    NDEM_arg **new_arg_list;
+    int no_of_args, i;
+
+    if (! arg)
+    {
+		put_characters("(?)", 3);
+		return;
+    }
+
+    put_characters("(", 1);
+    new_arg_list = allocate(arg_array_size);
+    flat_args(arg, new_arg_list, &no_of_args);
+
+    /* deallocate the excess memory...
+    */
+    deallocate(arg_array_size - sizeof(NDEM_arg *) * no_of_args);
+
+    for(i = 0;  i < no_of_args;  ++i)
+    {
+	print_arg(new_arg_list[i]);
+	if (i < no_of_args - 1)
+	    put_characters(", ", 2);
+    }
+    put_characters(")", 1);
+}
+
+static void print_class(NDEM_class *cl, int full_qual_name)
+{
+    if (! cl) return;
+    if (cl->qual_class && full_qual_name)
+    {
+	print_class(cl->qual_class, full_qual_name);
+	put_characters("::", 2);
+    }
+    put_string(cl->raw_class_name)
+    if (cl->t_args)
+	print_template_args(cl->t_args);
+}
+
+static void print_name(NDEM_name *name)
+{
+    if (! name) return;
+
+    switch (name->type) {
+
+	case NDEM_constructor:
+	    print_class(name->qual_class, 1);
+	    put_characters("::", 2);
+	    print_class(name->qual_class, 0);
+	    print_function_args(name->f_args);
+	    print_p_modifier(name->f_modifier);
+	    break;
+
+	case NDEM_destructor:
+	    print_class(name->qual_class, 1);
+	    put_characters("::~", 3);
+	    print_class(name->qual_class, 0);
+	    print_function_args(name->f_args);
+	    print_p_modifier(name->f_modifier);
+	    break;
+
+	case NDEM_operator:
+	case NDEM_conversion:
+	    if (name->qual_class)
+	    {
+		if (name->f_modifier.is_static)
+		    put_characters("static ", 7);
+		print_class(name->qual_class, 1);
+		put_characters("::", 2);
+	    }
+	    put_characters("operator ", 9);
+	    if (name->type != NDEM_conversion)
+		put_string(name->raw_name)
+	    else
+		print_arg(name->conv_t);
+	    print_function_args(name->f_args);
+	    if (name->qual_class)
+		print_p_modifier(name->f_modifier);
+	    break;
+
+	case NDEM_static_constructor:
+	case NDEM_static_destructor:
+	case NDEM_other:
+	    if (name->qual_class)
+	    {
+		if (name->f_modifier.is_static)
+		    put_characters("static ", 7);
+		print_class(name->qual_class, 1);
+		put_characters("::", 2);
+	    }
+	    put_string(name->raw_name)
+	    if (name->f_args)
+	    {
+		print_function_args(name->f_args);
+		if (name->qual_class)
+		    print_p_modifier(name->f_modifier);
+	    }
+	    break;
+
+	case NDEM_unnamed_arg:
+	default:
+	    break;
+    }
+}
+
+static void print_global_name(NDEM_name *name)
+{
+    print_name(name);
+    put_characters("\0", 1);	/* insert the ending '\0' */
+}
+
+static char *in_buffer;
+static int ibx;			/* in_buffer index */
+static size_t in_len = 0;	/* symbol length */
+
+static void startup(char *in, char *mem, size_t mem_size)
+{
+    if (in) {
+	in_buffer = in;
+	ibx = ll_id_size = sk_top = 0;
+	in_len = strlen(in);
+    }
+    mem_reservoir = mem;
+    (void) memset(mem_reservoir, 0, mem_size);
+}
+
+int yylex(void)
+{
+
+    if (ibx + (ll_id_size? ll_id_size - 1 : 0) >= in_len)
+	return 0;
+
+    if (! ll_id_size)
+	return (ll_cur_char = in_buffer[ibx++]);
+    else
+    {
+	yytext = in_buffer + ibx;
+	ibx += ll_id_size;
+	ll_id_size = 0;
+	return IDENTIFIER;
+    }
+}
+
+
+int demangle(char *in, char *out)
+{
+    if (in == NULL || !*in || out == NULL) return -1;
+
+    if (CHECK_PREFIX(in))
+    {
+	startup(in, name_buffer, BUFSIZE);
+	if (yyparse() == 0)
+	{
+	    out_buffer = out;
+	    obx = 0;	/* reset out_buffer index */
+	    print_global_name(result);
+	    return 0;
+	}
+	else
+	{
+	    /* definitely not a cfront name! */
+	    (void) strcpy(out, in);
+	    return -1;
+	}
+    }
+
+    /* Not a cafe symbol, try cfront demangler... */
+    return cfront_demangle(in, out);
+}
+
+static void yyerror(char *msg)
+{
+	(void) msg;
+}
+
+
+/* The code below is provided for tools nm, prof, and gprof.
+*/
+
+char *cafe_demangle(char *in, char *out)
+{
+    if (in == NULL || !*in || out == NULL) return in;
+
+    if (CHECK_PREFIX(in))
+    {
+	startup(in, name_buffer, BUFSIZE);
+	if (yyparse() == 0)
+	{
+	    out_buffer = out;
+	    obx = 0;
+	    print_global_name(result);
+	    return out;
+	}
+    }
+
+    /* not a cafe symbol... */
+    return in;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/deleted_files/usr/src/cmd/sgs/sgsdemangler/common/dem.c	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,1670 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/*******************************************************************************
+ 
+C++ source for the C++ Language System, Release 3.0.  This product
+is a new release of the original cfront developed in the computer
+science research center of AT&T Bell Laboratories.
+
+Copyright (c) 1991 AT&T and UNIX System Laboratories, Inc.
+Copyright (c) 1984, 1989, 1990 AT&T.  All Rights Reserved.
+
+*******************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include "cafe_dem.h"
+
+/************************* CUSTOMIZATION SECTION *************************/
+
+#ifndef ELF_OBJ
+static int clip_under = 1;			/* ignore first "_" on names */
+#else
+static int clip_under = 0;
+#endif
+
+#define SP_ALIGN 0x4			/* alignment of dynamic space blocks */
+
+/*#define DEM_MAIN*/			/* set if want standalone program */
+
+/************************************************************************/
+
+#define MAXLINE 2048			/* general buffer use */
+
+#define MAXARG 400			/* max arguments in a function */
+
+#define STRCMP(s, t) ((s)[0] != (t)[0] || strcmp((s), (t)) != 0)
+
+static char* spbase;
+static char cc;
+static char* base;
+static int baselen;
+#define gc() {cc = baselen >= 1 ? *base++ : 0, baselen--;}
+
+static int waserror = 0;
+
+#define MAXSTACK 200
+static char* stackp[MAXSTACK];
+static int stackl[MAXSTACK];
+static char stackc[MAXSTACK];
+static int sp = -1;
+
+#define ERROR() {waserror = 1; return NULL;}
+
+/************************* UTILITIES *************************/
+
+/* fatal errors */
+static void fatal(char* msg, char* arg1, char* arg2)
+{
+	char buf[MAXLINE];
+
+	(void) sprintf(buf, msg, arg1, arg2);
+	(void) fprintf(stderr, "demangle fatal error: %s\n", buf);
+
+	exit(1);
+}
+
+/* get space */
+static char* gs(size_t s)
+{
+	char* p;
+
+	if (s < 1)
+		fatal("bad argument to gs()", (char*)0, (char*)0);
+
+	/* align space on SP_ALIGN boundary */
+
+	while ((unsigned long)spbase & (SP_ALIGN - 1))
+		spbase++;
+
+	p = spbase;
+	spbase += s;
+
+	return p;
+}
+
+/* copy a string */
+static char* copy(char* s)
+{
+	char* p;
+
+	if (s == NULL || !*s)
+		fatal("bad argument to copy()", (char*)0, (char*)0);
+
+	p = gs(strlen(s) + 1);
+	(void) strcpy(p, s);
+	return p;
+}
+
+/************************* DEMANGLE UTILITIES *************************/
+
+/* push a string to scan */
+static void push(char* s, int n)
+{
+	if (s == NULL || !*s || n < 1)
+		fatal("bad argument to push()", (char*)0, (char*)0);
+	if (sp + 1 >= MAXSTACK)
+		fatal("overflow of stack in push()", (char*)0, (char*)0);
+
+	sp++;
+	stackp[sp] = base;
+	stackl[sp] = baselen;
+	stackc[sp] = cc;
+	base = s;
+	baselen = n;
+	gc();
+}
+
+static void pop()
+{
+	if (sp < 0)
+		fatal("bad argument to pop()", (char*)0, (char*)0);
+
+	base = stackp[sp];
+	baselen = stackl[sp];
+	cc = stackc[sp];
+	sp--;
+}
+
+/************************* DEMANGLER *************************/
+
+/* get a class name */
+static DEMARG* getarglist();
+static DEMCL* getclass()
+{
+	int n;
+	char nbuf[MAXLINE];
+	int i;
+	int j;
+	int iter;
+	DEMCL* p;
+	DEMCL* clhead;
+	DEMCL* curr;
+	DEMARG* ap;
+
+	iter = 1;
+	clhead = NULL;
+	curr = NULL;
+
+	/* fix for ambiguity in encoding */
+
+	i = 0;
+	if (isdigit(base[0])) {
+		i = 1;
+		if (isdigit(base[1]))
+			i = 2;
+	}
+	if (isdigit(cc) && base[i] == 'Q' && isdigit(base[i + 1]) &&
+	    base[i + 2] == '_') {
+		gc();
+		if (i)
+			gc();
+		if (i == 2)
+			gc();
+	}
+
+	/* might be nested class */
+
+	if (cc == 'Q') {
+		gc();
+		if (!isdigit(cc))
+			ERROR();
+		iter = cc - '0';
+		if (iter < 1)
+			ERROR();
+		gc();
+		if (cc != '_')
+			ERROR();
+		gc();
+	}
+
+	/* grab number of classes expected */
+
+	while (iter-- > 0) {
+
+		/* get a class */
+
+		if (!isdigit(cc))
+			ERROR();
+		n = cc - '0';
+		gc();
+		if (isdigit(cc)) {
+			n = n * 10 + cc - '0';
+			gc();
+		}
+		if (isdigit(cc)) {
+			n = n * 10 + cc - '0';
+			gc();
+		}
+		if (n < 1)
+			ERROR();
+		for (i = 0; i < n; i++) {
+			if (!isalnum(cc) && cc != '_')
+				ERROR();
+			nbuf[i] = cc;
+			gc();
+		}
+		nbuf[i] = 0;
+		p = (DEMCL*)gs(sizeof(DEMCL));
+		p->rname = copy(nbuf);
+		p->clargs = NULL;
+
+		/* might be a template class */
+
+		for (j = 0; j < i; j++) {
+			if (nbuf[j] == '_' && nbuf[j + 1] == '_' &&
+			    nbuf[j + 2] == 'p' && nbuf[j + 3] == 't')
+				break;
+		}
+		if (j == 0)
+			ERROR();
+		if (j == i) {
+			p->name = copy(nbuf);
+		}
+		else {
+			if (nbuf[j + 4] != '_' || nbuf[j + 5] != '_')
+				ERROR();
+			nbuf[j] = 0;
+			p->name = copy(nbuf);
+			j += 6;
+			if (!isdigit(nbuf[j]))
+				ERROR();
+			n = nbuf[j] - '0';
+			j++;
+			if (isdigit(nbuf[j])) {
+				n = n * 10 + nbuf[j] - '0';
+				j++;
+			}
+			if (isdigit(nbuf[j])) {
+				n = n * 10 + nbuf[j] - '0';
+				j++;
+			}
+			if (n < 2)
+				ERROR();
+			if (nbuf[j] != '_')
+				ERROR();
+			j++;
+			n--;
+			if (!nbuf[j])
+				ERROR();
+
+			/* get arguments for template class */
+
+			push(nbuf + j, n);
+			if ((ap = getarglist()) == NULL || cc)
+				ERROR();
+			pop();
+			p->clargs = ap;
+		}
+		p->next = NULL;
+
+		/* link in to list */
+
+		if (clhead != NULL) {
+			curr->next = p;
+			curr = p;
+		}
+		else {
+			clhead = p;
+			curr = clhead;
+		}
+	}
+
+	return clhead;
+}
+
+/* copy an argument */
+static DEMARG* arg_copy(DEMARG* p)
+{
+	DEMARG* p2;
+
+	if (p == NULL)
+		fatal("bad argument to arg_copy()", (char*)0, (char*)0);
+
+	p2 = (DEMARG*)gs(sizeof(DEMARG));
+	p2->mods = p->mods;
+	p2->base = p->base;
+	p2->arr = p->arr;
+	p2->func = p->func;
+	p2->clname = p->clname;
+	p2->mname = p->mname;
+	p2->lit = p->lit;
+	p2->ret = p->ret;
+	p2->next = NULL;
+
+	return p2;
+}
+
+/* get an argument */
+static DEMARG* getarg(int acmax, DEMARG* arg_cache[], int* ncount)
+{
+	char mods[100];
+	int mc;
+	int type;
+	static DEMARG* p;
+	DEMCL* clp;
+	long n;
+	DEMARG* farg;
+	DEMARG* fret;
+	DEMARG* getarglist();
+	char litbuf[MAXLINE];
+	size_t lp;
+	int foundx;
+	long arrdim[100];
+	int arrp;
+	int i;
+	int wasm;
+	int waslm;
+	char buf[MAXLINE];
+	char buf2[MAXLINE];
+	void dem_printcl();
+	DEMCL* clist[100];
+	int clc;
+	int ic;
+
+	/* might be stuff remaining from Nnn */
+
+	if (ncount != NULL && *ncount > 0) {
+		(*ncount)--;
+		return arg_copy(p);
+	}
+
+	mc = 0;
+	type = 0;
+	clp = NULL;
+	farg = NULL;
+	fret = NULL;
+	lp = 0;
+	foundx = 0;
+	arrp = 0;
+	wasm = 0;
+	clc = 0;
+
+	/* get type */
+
+	while (!type) {
+		switch (cc) {
+
+			/* modifiers and declarators */
+
+			case 'X':
+				gc();
+				foundx = 1;
+				break;
+			case 'U':
+			case 'C':
+			case 'V':
+			case 'S':
+			case 'P':
+			case 'R':
+				mods[mc++] = cc;
+				gc();
+				break;
+
+			/* fundamental types */
+
+			case 'v':
+			case 'c':
+			case 's':
+			case 'i':
+			case 'l':
+			case 'f':
+			case 'd':
+			case 'r':
+			case 'e':
+			case 'G':
+				type = cc;
+				gc();
+				break;
+
+			/* arrays */
+
+			case 'A':
+				mods[mc++] = cc;
+				gc();
+				if (!isdigit(cc))
+					ERROR();
+				n = cc - '0';
+				gc();
+				while (isdigit(cc)) {
+					n = n * 10 + cc - '0';
+					gc();
+				}
+				if (cc != '_')
+					ERROR();
+				gc();
+				arrdim[arrp++] = n;
+				break;
+
+			/* functions */
+
+			case 'F':
+				type = cc;
+				gc();
+				if ((farg = getarglist()) == NULL)
+					ERROR();
+				if (cc != '_')
+					ERROR();
+				gc();
+				if ((fret = getarg(-1, (DEMARG**)0, (int*)0)) == NULL)
+					ERROR();
+				break;
+
+			/* pointers to member */
+
+			case 'M':
+				mods[mc++] = cc;
+				wasm = 1;
+				gc();
+				if ((clist[clc++] = getclass()) == NULL)
+					ERROR();
+				break;
+
+			/* repeat previous argument */
+
+			case 'T':
+				gc();
+tcase:
+				if (!isdigit(cc))
+					ERROR();
+				n = cc - '0';
+				gc();
+				if (n < 1)
+					ERROR();
+				if (arg_cache == NULL || n - 1 > acmax)
+					ERROR();
+				p = arg_copy(arg_cache[n - 1]);
+				return p;
+
+			/* repeat previous argument N times */
+
+			case 'N':
+				gc();
+				if (!isdigit(cc))
+					ERROR();
+				if (ncount == NULL)
+					ERROR();
+				*ncount = cc - '0' - 1;
+				if (*ncount < 0)
+					ERROR();
+				gc();
+				goto tcase;
+
+			/* class, struct, union, enum */
+
+			case '1': case '2': case '3': case '4': case '5':
+			case '6': case '7': case '8': case '9': case 'Q':
+				if ((clp = getclass()) == NULL)
+					ERROR();
+				type = 'C';
+				break;
+
+			default:
+				return NULL;
+		}
+	}
+
+	/* template literals */
+
+	if (type && foundx) {
+		n = 0;
+		waslm = 0;
+		if (cc == 'L' && base[0] == 'M') {
+			gc();
+			gc();
+			while (cc != '_' && cc)
+				gc();
+			if (!cc)
+				ERROR();
+			gc();
+			while (cc != '_' && cc)
+				gc();
+			if (!cc)
+				ERROR();
+			gc();
+			n = cc - '0';
+			gc();
+			if (isdigit(cc)) {
+				n = n * 10 + cc - '0';
+				gc();
+			}
+			if (isdigit(cc)) {
+				n = n * 10 + cc - '0';
+				gc();
+			}
+			waslm = 1;
+		}
+		else if (cc == 'L') {
+			gc();
+			if (!isdigit(cc))
+				ERROR();
+			n = cc - '0';
+			gc();
+			if (isdigit(cc) && base[0] == '_') {
+				n = n * 10 + cc - '0';
+				gc();
+				gc();
+			}
+			if (cc == 'n') {
+				gc();
+				n--;
+				litbuf[lp++] = '-';
+			}
+		}
+		else if (cc == '0') {
+			n = 1;
+		}
+		else if (isdigit(cc)) {
+			n = cc - '0';
+			gc();
+			if (isdigit(cc)) {
+				n = n * 10 + cc - '0';
+				gc();
+			}
+		}
+		else {
+			ERROR();
+		}
+		if (!n && waslm) {
+			(void) strcpy(litbuf, "0");
+			lp = 1;
+		}
+		else {
+			ic = -1;
+			while (n-- > 0) {
+				if (!isalnum(cc) && cc != '_')
+					ERROR();
+				litbuf[lp++] = cc;
+				gc();
+				if (n > 0 && lp >= 2 &&
+				    litbuf[lp - 1] == '_' && litbuf[lp - 2] == '_') {
+					if ((clist[ic = clc++] = getclass()) == NULL)
+						ERROR();
+					litbuf[lp - 1] = 0;
+					litbuf[lp - 2] = 0;
+					lp -= 2;
+					break;
+				}	
+			}
+			litbuf[lp] = 0;
+			if ((wasm && waslm) || ic >= 0) {
+				dem_printcl(clist[ic >= 0 ? ic : 0], buf2);
+				(void) sprintf(buf, "%s::%s", buf2, litbuf);
+				(void) strcpy(litbuf, buf);
+				lp = strlen(litbuf);
+			}
+		}
+	}
+
+	mods[mc] = 0;
+	litbuf[lp] = 0;
+	p = (DEMARG*)gs(sizeof(DEMARG));
+	p->mods = mc ? copy(mods) : NULL;
+	p->lit = lp ? copy(litbuf) : NULL;
+	if (arrp > 0) {
+		p->arr = (long*)gs(sizeof(long) * arrp);
+		for (i = 0; i < arrp; i++)
+			p->arr[i] = arrdim[i];
+	}
+	else {
+		p->arr = NULL;
+	}
+	/* LINTED */
+	p->base = (char)type;
+	p->func = farg;
+	p->ret = fret;
+	p->clname = clp;
+	if (clc > 0) {
+		p->mname = (DEMCL**)gs(sizeof(DEMCL*) * (clc + 1));
+		for (i = 0; i < clc; i++)
+			p->mname[i] = clist[i];
+		p->mname[clc] = NULL;
+	}
+	else {
+		p->mname = NULL;
+	}
+	p->next = NULL;
+
+	return p;
+}
+
+/* get list of arguments */
+static DEMARG* getarglist()
+{
+	DEMARG* p;
+	DEMARG* head;
+	DEMARG* curr;
+	DEMARG* arg_cache[MAXARG];
+	int acmax;
+	int ncount;
+
+	head = NULL;
+	curr = NULL;
+
+	acmax = -1;
+	ncount = 0;
+
+	for (;;) {
+
+		/* get the argument */
+
+		p = getarg(acmax, arg_cache, &ncount);
+		if (p == NULL) {
+			if (waserror)
+				return NULL;
+			return head;
+		}
+
+		/* cache it for Tn and Nnn */
+
+		arg_cache[++acmax] = p;
+		if (curr == NULL) {
+			head = p;
+			curr = head;
+		}
+		else {
+			curr->next = p;
+			curr = p;
+		}
+	}
+}
+
+/* entry point for demangling */
+int dem(char* s, DEM* p, char* buf)
+{
+	char nbuf[MAXLINE];
+	int nc;
+	long n;
+	char* t;
+	char* t2;
+	char* t3;
+	char* ob;
+	int flag;
+	int cuflag;
+	char buf2[MAXLINE];
+	enum DEM_TYPE dt;
+
+	if (s == NULL || p == NULL || buf == NULL)
+		return -1;
+
+	cuflag = 0;
+
+	if (clip_under && *s == '_')
+		s++, cuflag = 1;
+
+	if (!*s)
+		return -1;
+
+	/* set up space and input buffer management */
+
+	spbase = buf;
+	sp = -1;
+	waserror = 0;
+
+	p->fargs = NULL;
+	p->cl = NULL;
+	p->sc = 0;
+	p->args = NULL;
+	p->f = NULL;
+	p->vtname = NULL;
+	p->slev = -1;
+	p->type = DEM_NONE;
+
+	/* special case local variables */
+
+	if (cuflag)
+		s--;
+	if (s[0] == '_' && s[1] == '_' && isdigit(s[2])) {
+		t = s + 2;
+		n = 0;
+		while (isdigit(*t)) {
+			n = n * 10 + *t - '0';
+			t++;
+		}
+		if (*t) {
+			p->f = copy(t);
+			/* LINTED */
+			p->slev = (short)n;
+			goto done2;
+		}
+	}
+	if (cuflag)
+		s++;
+
+	/* special case sti/sti/ptbl */
+
+	if (s[0] == '_' && s[1] == '_' &&
+	    (!strncmp(s, "__sti__", 7) || !strncmp(s, "__std__", 7) ||
+	    !strncmp(s, "__ptbl_vec__", 12))) {
+		p->sc = s[4];
+		t = (s[2] == 's' ? s + 7 : s + 12);
+		while (*t == '_')
+			t++;
+		p->f = copy(t);
+		if ((t2 = strstr(p->f, "_cc_")) != NULL)
+			nc = 3; 
+		else if ((t2 = strstr(p->f, "_c_")) != NULL)
+			nc = 2; 
+		else if ((t2 = strstr(p->f, "_C_")) != NULL)
+			nc = 2; 
+		else if ((t2 = strstr(p->f, "_cxx_")) != NULL)
+			nc = 4; 
+		else if ((t2 = strstr(p->f, "_h_")) != NULL)
+			nc = 2; 
+		if (t2) 
+			*(t2+nc) = 0; 
+		cc = 0;
+		goto done2;
+	}
+
+	/* special case type names */
+
+	if (cuflag)
+		s--;
+	t = s;
+	flag = 0;
+	while (t[0] && (t[0] != '_' || t == s || t[-1] != '_'))
+		t++;
+	if (t[0] == '_' && t[1] == 'p' && t[2] == 't' &&
+	    t[3] == '_' && t[4] == '_')
+		flag = 1;
+	if (t[0] == '_' && t[1] == '_' && t[2] == 'p' && t[3] == 't' &&
+	    t[4] == '_' && t[5] == '_')
+		flag = 1;
+	if (!flag) {
+		t = s;
+		if ((t[0] == '_' && t[1] == '_' && t[2] == 'Q' &&
+		    isdigit(t[3]) && t[4] == '_'))
+			flag = 2;
+	}
+	if (flag) {
+		sp = -1;
+		waserror = 0;
+		if (flag == 1) {
+			(void) sprintf(buf2, "%ld%s", strlen(s), s);
+			push(buf2, 9999);
+		}
+		else {
+			push(s + 2, 9999);
+		}
+		if ((p->cl = getclass()) == NULL)
+			return -1;
+		cc = 0;
+		goto done2;
+	}
+	if (cuflag)
+		s++;
+
+	sp = -1;
+	push(s, 9999);
+	waserror = 0;
+
+	/* get function name */
+
+	nc = 0;
+	nbuf[0] = 0;
+	while (isalnum(cc) || cc == '_') {
+		nbuf[nc++] = cc;
+		nbuf[nc] = 0;
+		if (!base[0] ||
+		    (base[0] == '_' && base[1] == '_' && base[2] != '_')) {
+			gc();
+			break;
+		}
+		gc();
+
+		/* conversion operators */
+
+		if (!STRCMP(nbuf, "__op")) {
+			ob = base - 1;
+			if ((p->fargs = getarg(-1, (DEMARG**)0, (int*)0)) == NULL)
+				return -1;
+			while (ob < base - 1)
+				nbuf[nc++] = *ob++;
+			nbuf[nc] = 0;
+			break;
+		}
+	}
+	if (!isalpha(nbuf[0]) && nbuf[0] != '_')
+		return -1;
+
+	/* pick off delimiter */
+
+	if (cc == '_' && base[0] == '_') {
+		gc();
+		gc();
+		if (!cc)
+			return -1;
+	}
+
+	/* get class name */
+
+	if (isdigit(cc) || cc == 'Q') {
+		if ((p->cl = getclass()) == NULL)
+			return -1;
+	}
+
+	/* a function template */
+
+	else if (cc == 'p' && !strncmp(base, "t__F", 4)) {
+		gc();
+		gc();
+		gc();
+		gc();
+		gc();
+		if (!isdigit(cc))
+			return -1;
+		n = cc - '0';
+		gc();
+		if (isdigit(cc)) {
+			n = n * 10 + cc - '0';
+			gc();
+		}
+		if (isdigit(cc)) {
+			n = n * 10 + cc - '0';
+			gc();
+		}
+		if (n < 1)
+			return -1;
+		while (n-- > 0) {
+			if (!isalnum(cc) && cc != '_')
+				return -1;
+			gc();
+		}
+		if (cc != '_' || base[0] != '_')
+			return -1;
+		gc();
+		gc();
+	}
+
+	if (!STRCMP(nbuf, "__vtbl")) {
+		if (cc == '_' && base[0] == '_' && base[1])
+			p->vtname = copy(base + 1);
+		goto done;
+	}
+
+	/* const/static member functions */
+
+	if ((cc == 'C' || cc == 'S') && base[0] == 'F') {
+		p->sc = cc;
+		gc();
+	}
+
+	/* get arg list for function */
+
+	if (cc == 'F') {
+		gc();
+		if ((p->args = getarglist()) == NULL)
+			return -1;
+	}
+
+done:
+	if ((cc && STRCMP(nbuf, "__vtbl")) || waserror)
+		return -1;
+
+	p->f = copy(nbuf);
+
+done2:
+
+	/* figure out type we got */
+
+	dt = DEM_NONE;
+	if (p->sc) {
+		switch (p->sc) {
+			case 'i':
+				dt = DEM_STI;
+				break;
+			case 'd':
+				dt = DEM_STD;
+				break;
+			case 'b':
+				dt = DEM_PTBL;
+				break;
+			case 'C':
+				dt = DEM_CMFUNC;
+				break;
+			case 'S':
+				dt = DEM_SMFUNC;
+				break;
+			default:
+				fatal("bad type set for p->sc", (char*)0, (char*)0);
+				break;
+		}
+	}
+	else if (p->slev != -1) {
+		dt = DEM_LOCAL;
+	}
+	else if (p->args != NULL) {
+		if (p->fargs != NULL) {
+			dt = DEM_OMFUNC;
+		}
+		else if (p->cl != NULL) {
+			t3 = p->f;
+			if (t3[0] == '_' && t3[1] == '_') {
+				if (t3[2] == 'c' && t3[3] == 't' && !t3[4])
+					dt = DEM_CTOR;
+				else if (t3[2] == 'd' && t3[3] == 't' &&
+				    !t3[4])
+					dt = DEM_DTOR;
+				else
+					dt = DEM_MFUNC;
+			}
+			else {
+				dt = DEM_MFUNC;
+			}
+		}
+		else {
+			dt = DEM_FUNC;
+		}
+	}
+	else if (p->f == NULL && p->cl != NULL) {
+		if (p->cl->clargs != NULL)
+			dt = DEM_TTYPE;
+		else
+			dt = DEM_CTYPE;
+	}
+	else if (p->f != NULL) {
+		if (p->cl != NULL) {
+			t3 = p->f;
+			if (t3[0] == '_' && t3[1] == '_' && t3[2] == 'v' &&
+			    t3[3] == 't' && t3[4] == 'b' && t3[5] == 'l' &&
+			    !t3[6])
+				dt = DEM_VTBL;
+			else
+				dt = DEM_MDATA;
+		}
+		else {
+			dt = DEM_DATA;
+		}
+	}
+
+	if (dt == DEM_NONE)
+		fatal("cannot characterize type of input", (char*)0, (char*)0);
+
+	p->type = dt;
+
+	return 0;
+}
+
+/************************* PRINT AN UNMANGLED NAME *************************/
+
+/* format a class name */
+void dem_printcl(DEMCL* p, char* buf)
+{
+	int i;
+	char buf2[MAXLINE];
+	void dem_printarglist();
+
+	if (p == NULL || buf == NULL)
+		fatal("bad argument to dem_printcl()", (char*)0, (char*)0);
+
+	buf[0] = 0;
+	i = 0;
+	while (p != NULL) {
+		i++;
+
+		/* handle nested */
+
+		if (i > 1)
+			(void) strcat(buf, "::");
+		(void) strcat(buf, p->name);
+
+		/* template class */
+
+		if (p->clargs != NULL) {
+			if (buf[strlen(buf) - 1] == '<')
+				(void) strcat(buf, " ");
+			(void) strcat(buf, "<");
+			dem_printarglist(p->clargs, buf2, 0);
+			(void) strcat(buf, buf2);
+			if (buf[strlen(buf) - 1] == '>')
+				(void) strcat(buf, " ");
+			(void) strcat(buf, ">");
+		}
+		p = p->next;
+	}
+}
+
+/* format an argument list */
+void dem_printarglist(DEMARG* p, char* buf, int sv)
+{
+	int i;
+	char buf2[MAXLINE];
+	void dem_printarg();
+
+	if (p == NULL || buf == NULL || sv < 0 || sv > 1)
+		fatal("bad argument to dem_printarglist()", (char*)0, (char*)0);
+
+	/* special case single "..." argument */
+
+	if (p->base == 'v' && p->mods == NULL && p->next != NULL &&
+	    p->next->base == 'e' && p->next->next == NULL) {
+		(void) strcpy(buf, "...");
+		return;
+	}
+
+	/* special case single "void" argument */
+
+	if (p->base == 'v' && p->mods == NULL) {
+		(void) strcpy(buf, "void");
+		return;
+	}
+
+	buf[0] = 0;
+	i = 0;
+	while (p != NULL) {
+		i++;
+		if (i > 1)
+			(void) strcat(buf, p->base == 'e' ? " " : ",");
+		dem_printarg(p, buf2, sv);
+		(void) strcat(buf, buf2);
+		p = p->next;
+	}
+}
+
+/* format a single argument */
+void dem_printarg(DEMARG* p, char* buf, int f)
+{
+	char* t;
+	char bufc[MAXLINE];
+	char bufc2[MAXLINE];
+	char farg[MAXLINE];
+	char fret[MAXLINE];
+	char* m;
+	char* mm;
+	char pref[MAXLINE];
+	int arrindx;
+	long dim;
+	char scr[MAXLINE];
+	char ptrs[MAXLINE];
+	int i;
+	int sv;
+	char* s;
+	char* trail;
+	int clc;
+
+	if (p == NULL || buf == NULL || f < 0 || f > 1)
+		fatal("bad argument to dem_printarg()", (char*)0, (char*)0);
+
+	/* format the underlying type */
+
+	sv = !f;
+
+	switch (p->base) {
+
+		/* fundamental types */
+
+		case 'v':
+			t = "void";
+			break;
+		case 'c':
+			t = "char";
+			break;
+		case 's':
+			t = "short";
+			break;
+		case 'i':
+			t = "int";
+			break;
+		case 'l':
+			t = "long";
+			break;
+		case 'f':
+			t = "float";
+			break;
+		case 'd':
+			t = "double";
+			break;
+		case 'r':
+			t = "long double";
+			break;
+		case 'G':
+			t = "T";
+			break;
+		case 'e':
+			t = "...";
+			sv = 1;
+			break;
+
+		/* functions */
+
+		case 'F':
+			dem_printarg(p->ret, fret, 0);
+			dem_printarglist(p->func, farg, 0);
+			break;
+
+		/* class, struct, union, enum */
+
+		case 'C':
+			dem_printcl(p->clname, bufc);
+			t = bufc;
+			break;
+
+		default:
+			fatal("bad base type in dem_printarg()", (char*)0, (char*)0);
+			break;
+	}
+
+	/* handle modifiers and declarators */
+
+	pref[0] = 0;
+	m = p->mods;
+	if (m == NULL)
+		m = "";
+
+	/* const and unsigned */
+
+	mm = m;
+	while (*mm) {
+		if (mm[0] == 'C' && (mm[1] != 'P' && mm[1] != 'R' && mm[1] != 'M') && (mm[1] || p->base != 'F')) {
+			(void) strcat(pref, "const ");
+			break;
+		}
+		mm++;
+	}
+	mm = m;
+	while (*mm) {
+		if (*mm == 'U') {
+			(void) strcat(pref, "unsigned ");
+			break;
+		}
+		mm++;
+	}
+
+	/* go through modifier list */
+
+	mm = m;
+	ptrs[0] = 0;
+	arrindx = 0;
+	clc = 0;
+	while (*mm) {
+		if (mm[0] == 'P') {
+			(void) sprintf(scr, "*%s", ptrs);
+			(void) strcpy(ptrs, scr);
+		}
+		else if (mm[0] == 'R') {
+			(void) sprintf(scr, "&%s", ptrs);
+			(void) strcpy(ptrs, scr);
+		}
+		else if (mm[0] == 'M') {
+			dem_printcl(p->mname[clc++], bufc2);
+			(void) sprintf(scr, "%s::*%s", bufc2, ptrs);
+			(void) strcpy(ptrs, scr);
+		}
+		else if (mm[0] == 'C' && mm[1] == 'P') {
+			(void) sprintf(scr, " *const%s%s", isalnum(ptrs[0]) || ptrs[0] == '_' ? " " : "", ptrs);
+			(void) strcpy(ptrs, scr);
+			mm++;
+		}
+		else if (mm[0] == 'C' && mm[1] == 'R') {
+			(void) sprintf(scr, " &const%s%s", isalnum(ptrs[0]) || ptrs[0] == '_' ? " " : "", ptrs);
+			(void) strcpy(ptrs, scr);
+			mm++;
+		}
+		else if (mm[0] == 'C' && mm[1] == 'M') {
+			dem_printcl(p->mname[clc++], bufc2);
+			(void) sprintf(scr, "%s::*const%s%s", bufc2, isalnum(ptrs[0]) || ptrs[0] == '_' ? " " : "", ptrs);
+			(void) strcpy(ptrs, scr);
+			mm++;
+		}
+		else if (mm[0] == 'A') {
+			dim = p->arr[arrindx++];
+			s = sv ? "" : "@";
+			if (!ptrs[0]) {
+				(void) sprintf(scr, "%s[%ld]", s, dim);
+				sv = 1;
+			}
+			else if (ptrs[0] == '(' || ptrs[0] == '[') {
+				(void) sprintf(scr, "%s[%ld]", ptrs, dim);
+			}
+			else {
+				(void) sprintf(scr, "(%s%s)[%ld]", ptrs, s, dim);
+				sv = 1;
+			}
+			(void) strcpy(ptrs, scr);
+		}
+		else if (mm[0] == 'U' || mm[0] == 'C' || mm[0] == 'S') {
+			/* ignore */
+		}
+		else {
+			fatal("bad value in modifier list", (char*)0, (char*)0);
+		}
+		mm++;
+	}
+
+	/* put it together */
+
+	s = sv ? "" : "@";
+	if (p->base == 'F') {
+		i = 0;
+		if (ptrs[0] == ' ')
+			i = 1;
+		trail = "";
+		if (p->mods != NULL && p->mods[strlen(p->mods) - 1] == 'C')
+			trail = " const";
+		if (ptrs[i])
+			(void) sprintf(buf, "%s%s (%s%s)(%s)%s", pref, fret, ptrs + i,
+			    s, farg, trail);
+		else
+			(void) sprintf(buf, "%s%s %s(%s)%s", pref, fret, s, farg, trail);
+	}
+	else {
+		(void) sprintf(buf, "%s%s%s%s%s", pref, t, ptrs[0] == '(' || isalnum(ptrs[0]) || ptrs[0] == '_' ? " " : "", ptrs, s);
+	}
+	if (p->lit != NULL) {
+		if (isdigit(p->lit[0]) || p->lit[0] == '-')
+			(void) sprintf(scr, "(%s)%s", buf, p->lit);
+		else
+			(void) sprintf(scr, "&%s", p->lit);
+		(void) strcpy(buf, scr);
+	}
+}
+
+struct Ops {
+	char* encode;
+	char* name;
+};
+
+static struct Ops ops[] = {
+	"__pp",		"operator++",
+	"__as",		"operator=",
+	"__vc",		"operator[]",
+	"__nw",		"operator new",
+	"__dl",		"operator delete",
+	"__rf",		"operator->",
+	"__ml",		"operator*",
+	"__mm",		"operator--",
+	"__oo",		"operator||",
+	"__md",		"operator%",
+	"__mi",		"operator-",
+	"__rs",		"operator>>",
+	"__ne",		"operator!=",
+	"__gt",		"operator>",
+	"__ge",		"operator>=",
+	"__or",		"operator|",
+	"__aa",		"operator&&",
+	"__nt",		"operator!",
+	"__apl",	"operator+=",
+	"__amu",	"operator*=",
+	"__amd",	"operator%=",
+	"__ars",	"operator>>=",
+	"__aor",	"operator|=",
+	"__cm",		"operator,",
+	"__dv",		"operator/",
+	"__pl",		"operator+",
+	"__ls",		"operator<<",
+	"__eq",		"operator==",
+	"__lt",		"operator<",
+	"__le",		"operator<=",
+	"__ad",		"operator&",
+	"__er",		"operator^",
+	"__co",		"operator~",
+	"__ami",	"operator-=",
+	"__adv",	"operator/=",
+	"__als",	"operator<<=",
+	"__aad",	"operator&=",
+	"__aer",	"operator^=",
+	"__rm",		"operator->*",
+	"__cl",		"operator()",
+	NULL,		NULL
+};
+
+/* format a function name */
+void dem_printfunc(DEM* dp, char* buf)
+{
+	int i;
+	char buf2[MAXLINE];
+
+	if (dp == NULL || buf == NULL)
+		fatal("bad argument to dem_printfunc()", (char*)0, (char*)0);
+
+	if (dp->f[0] == '_' && dp->f[1] == '_') {
+
+		/* conversion operators */
+
+		if (!strncmp(dp->f, "__op", 4) && dp->fargs != NULL) {
+			dem_printarg(dp->fargs, buf2, 0);
+			(void) sprintf(buf, "operator %s", buf2);		
+		}
+
+		/* might be overloaded operator */
+
+		else {
+			i = 0;
+			while (ops[i].encode != NULL && strcmp(ops[i].encode, dp->f))
+				i++;
+			if (ops[i].encode != NULL)
+				(void) strcpy(buf, ops[i].name);
+			else
+				(void) strcpy(buf, dp->f);
+		}
+	}
+	else {
+		(void) strcpy(buf, dp->f);
+	}
+}
+
+/* entry point to formatting functions */
+int dem_print(DEM* p, char* buf)
+{
+	char buf2[MAXLINE];
+	char* s;
+	int t;
+
+	if (p == NULL || buf == NULL)
+		return -1;
+
+	buf[0] = 0;
+
+	/* type names */
+
+	if (p->f == NULL && p->cl != NULL) {
+		dem_printcl(p->cl, buf);
+		return 0;
+	}
+
+	/* sti/std */
+
+	if (p->sc == 'i' || p->sc == 'd') {
+		(void) sprintf(buf, "%s:__st%c", p->f, p->sc);
+		return 0;
+	}
+	if (p->sc == 'b') {
+		(void) sprintf(buf, "%s:__ptbl_vec", p->f);
+		return 0;
+	}
+
+	/* format class name */
+
+	buf2[0] = 0;
+	if (p->cl != NULL) {
+		dem_printcl(p->cl, buf2);
+		(void) strcat(buf, buf2);
+		(void) strcat(buf, "::");
+	}
+
+	/* special case constructors and destructors */
+
+	s = buf2 + strlen(buf2) - 1;
+	t = 0;
+	while (s >= buf2) {
+		if (*s == '>')
+			t++;
+		else if (*s == '<')
+			t--;
+		else if (*s == ':' && !t)
+			break;
+		s--;
+	}
+	if (!STRCMP(p->f, "__ct")) {
+		(void) strcat(buf, s + 1);
+	}
+	else if (!STRCMP(p->f, "__dt")) {
+		(void) strcat(buf, "~");
+		(void) strcat(buf, s + 1);
+	}
+	else {
+		dem_printfunc(p, buf2);
+		(void) strcat(buf, buf2);
+	}
+
+	/* format argument list */
+
+	if (p->args != NULL) {
+		(void) strcat(buf, "(");
+		dem_printarglist(p->args, buf2, 0);
+		(void) strcat(buf, buf2);
+		(void) strcat(buf, ")");
+	}
+
+	/* const member functions */
+
+	if (p->sc == 'C')
+		(void) strcat(buf, " const");
+
+	return 0;
+}
+
+/* explain a type */
+char* dem_explain(enum DEM_TYPE t)
+{
+	switch (t) {
+		case DEM_STI:
+			return "static construction function";
+		case DEM_STD:
+			return "static destruction function";
+		case DEM_VTBL:
+			return "virtual table";
+		case DEM_PTBL:
+			return "ptbl vector pointing to vtbls";
+		case DEM_FUNC:
+			return "function";
+		case DEM_MFUNC:
+			return "member function";
+		case DEM_SMFUNC:
+			return "static member function";
+		case DEM_CMFUNC:
+			return "constant member function";
+		case DEM_OMFUNC:
+			return "conversion operator member function";
+		case DEM_CTOR:
+			return "constructor";
+		case DEM_DTOR:
+			return "destructor";
+		case DEM_DATA:
+			return "data";
+		case DEM_MDATA:
+			return "member data";
+		case DEM_LOCAL:
+			return "local variable";
+		case DEM_CTYPE:
+			return "class type";
+		case DEM_TTYPE:
+			return "template type";
+		default:
+			fatal("bad type passed to dem_explain()", (char*)0, (char*)0);
+			return "";
+	}
+}
+
+/* ------------------------------------------------------------------------ */
+
+/* demangle in --> out */
+int cfront_demangle(char* in, char* out)
+{
+	char sbuf[MAXDBUF];
+	DEM d;
+
+	if (in == NULL || !*in || out == NULL)
+		return -1;
+
+	if (dem(in, &d, sbuf) < 0) {
+		(void) strcpy(out, in);
+		return -1;
+	}
+
+	(void) dem_print(&d, out);
+
+	return 0;
+}
+
+/*
+    The routines below are provided to enable the tools nm,
+    prof, and gprof to use the demangling function provided
+    in this file.
+    Entry point is DemangleAndFormat()   --MK
+*/
+
+#include <string.h>
+
+static int CheckSpecialCase( char *, DEM *);
+static void ProcessVtname( DEM *);
+static char *FormatName( char *, char *, char *);
+
+static char d_buf[512];
+static char *ctor_str = "static constructor function for %s";
+static char *dtor_str = "static destructor function for %s";
+static char *ptbl_str = "pointer to the virtual table vector for %s";
+static char *vtbl_str = "virtual table for class %s";
+
+extern char *cafe_demangle(char *, char *);
+
+char *DemangleAndFormat(char  *name, char  *format)
+{
+  char dn[MAXDBUF];  /* demangled name */
+  char dn2[MAXDBUF];  /* demangled name */
+  DEM  dem_struct;
+  int  dem_ret_val;
+
+  char *cafe_out = cafe_demangle(name, dn);
+  if (cafe_out != name)
+  {
+    /* a cafe symbol...
+    */
+    return FormatName(name, cafe_out, format);
+  }
+
+  dem_ret_val = dem( name, &dem_struct, dn2);
+
+  if ((dem_ret_val < 0) || !(strcmp(name, dn2)))
+  {     /* name not demangled */
+    d_buf[0] = '\0';
+  }
+  else   /* name demangled by dem() */
+  {
+    if (CheckSpecialCase( name, &dem_struct))
+    {
+      name = FormatName( name, d_buf, format);
+    }
+    else   /* not a special case */
+    {
+      (void) dem_print( &dem_struct, dn);
+      name = FormatName( name, dn, format);
+    }
+  }
+
+  return (name);
+}  /* DemangleAndFormat */
+
+
+/* alloc memory and create name in necessary format.
+   Return name string
+*/
+static char *FormatName(char  *OldName, char  *NewName, char  *format)
+{
+  size_t length = strlen(format) + strlen(NewName) + strlen(OldName) - 3;
+  char *hold = OldName;
+
+  OldName = (char *)malloc( length );
+  (void) sprintf(OldName, format, NewName, hold);
+  return (OldName);
+}
+
+
+/*
+   Check for special cases: __sti__, _std__, __ptbl_vec__, __vtbl__
+   use demP for the procesing 
+   Return 1 if it is a special case, otherwise return 0.
+*/
+static int CheckSpecialCase(char  *name, DEM   *demP)
+{
+  int  retVal = 1;
+
+  if (demP->sc == 'i')   /* __sti__ */
+  {
+    (void) sprintf( d_buf, ctor_str, demP->f);
+  }
+  else if (demP->sc == 'd')  /* __std__ */
+  {
+    (void) sprintf( d_buf, dtor_str, demP->f);
+  }
+  else if (demP->sc == 'b')  /*  __ptbl_vec__ */
+  {
+    (void) sprintf( d_buf, ptbl_str, demP->f);
+  }
+  else if (demP->vtname != NULL)  /* __vtbl__ with file name */
+  {
+    ProcessVtname( demP);
+  }
+  else if (demP->cl != NULL)   /* check for __vtbl__ without file name */
+  {
+    if (strncmp( name, "__vtbl__", 8) == 0)
+      (void) sprintf( d_buf, vtbl_str, demP->cl->name);
+    else
+      retVal = 0;  /* not a special case */
+  }
+  else
+  {
+    retVal = 0;   /* not a special case */
+    d_buf[0] = '\0';
+  }
+
+  return (retVal);
+}
+
+
+/* process demP->vtname */
+/*   called by CheckSpecialCase() */
+
+static void ProcessVtname(DEM  *demP)
+{
+  char  *nameString;
+  char  *tail;
+  size_t   len;
+  int   marker;
+  char  saveChar;
+
+  nameString = demP->vtname;
+
+  /* check if mangled name of derived class (a heuristic)           */
+  /* different possibilities for string demP->vtname:               */
+  /*   (1) 'filename_ext'  class name in file                       */
+  /*   (2) '%dname'        class derived from class                 */
+  /*   (3) '%dname__filename_ext' class derived from class in file  */
+  /* note: the filename itself could start with a digit             */
+  len = strlen( nameString);
+  if (*(nameString + len - 2) == '_')
+    marker = 2;
+  else if (*(nameString + len - 3) == '_')
+    marker = 3;
+  else
+    marker = 0;
+  if (!isdigit(*nameString))  /* case (1) */
+  {
+    (void) sprintf( d_buf, vtbl_str, demP->cl ? demP->cl->name : "??");
+    (void) strcat( d_buf, " in ");
+    if (marker > 0)
+      *(nameString + len - marker) = '.';
+    (void) strcat( d_buf, nameString);
+    if (marker > 0)
+      *(nameString + len - marker) = '_';
+  }
+
+  else if ((tail = strstr( nameString, "__")) == NULL)
+  {  /* could be case (1) or case (2) */
+     /* case (1) if filename starts with a digit */
+    if (marker == 0)  /* case (2) */
+    {
+      while (isdigit( *nameString))
+        nameString++;
+      (void) sprintf( d_buf, vtbl_str, nameString);
+      (void) strcat( d_buf, " derived from ");
+      (void) strcat( d_buf, demP->cl ? demP->cl->name : "??");
+    }
+    else  /* case (1) */
+    {
+      (void) sprintf( d_buf, vtbl_str, demP->cl ? demP->cl->name : "??");
+      (void) strcat( d_buf, " in ");
+      if (marker > 0)
+        *(nameString + len - marker) = '.';
+      (void) strcat( d_buf, nameString);
+      if (marker > 0)
+        *(nameString + len - marker) = '_';
+    }
+  }
+
+  else   /* case (3) */
+  {
+    while (isdigit( *nameString))
+      nameString++;
+    saveChar = *(nameString + (tail - nameString));
+    *(nameString + (tail - nameString)) = '\0';
+    (void) sprintf( d_buf, vtbl_str, nameString);
+    (void) strcat( d_buf, " derived from ");
+    (void) strcat( d_buf, demP->cl ? demP->cl->name : "??");
+    *(nameString + (tail - nameString)) = saveChar;
+    tail += 2;  /* skip "__" */
+    len = strlen( tail);
+    (void) strcat( d_buf, " in ");
+    if (marker > 0)
+      *(tail + len - marker) = '.';
+    (void) strcat( d_buf, tail);
+    if (marker > 0)
+      *(tail + len - marker) = '_';
+  }
+}  /* ProcessVtname */
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/deleted_files/usr/src/cmd/sgs/sgsdemangler/common/dem.h	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,135 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/*******************************************************************************
+ 
+C++ source for the C++ Language System, Release 3.0.  This product
+is a new release of the original cfront developed in the computer
+science research center of AT&T Bell Laboratories.
+
+Copyright (c) 1991 AT&T and UNIX System Laboratories, Inc.
+Copyright (c) 1984, 1989, 1990 AT&T.  All Rights Reserved.
+
+*******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct DEMARG DEMARG;
+typedef struct DEMCL DEMCL;
+typedef struct DEM DEM;
+
+enum DEM_TYPE {
+	DEM_NONE,		/* placeholder */
+	DEM_STI,		/* static construction function */
+	DEM_STD,		/* static destruction function */
+	DEM_VTBL,		/* virtual table */
+	DEM_PTBL,		/* ptbl vector */
+	DEM_FUNC,		/* function */
+	DEM_MFUNC,		/* member function */
+	DEM_SMFUNC,		/* static member function */
+	DEM_CMFUNC,		/* const member function */
+	DEM_OMFUNC,		/* conversion operator member function */
+	DEM_CTOR,		/* constructor */
+	DEM_DTOR,		/* destructor */
+	DEM_DATA,		/* data */
+	DEM_MDATA,		/* member data */
+	DEM_LOCAL,		/* local variable */
+	DEM_CTYPE,		/* class type */
+	DEM_TTYPE,		/* template class type */
+
+	DEM_TYPE_END		/* used for cafe support... */
+};
+
+struct DEMARG {
+	char* mods;		/* modifiers and declarators (page 123 in */
+				/* ARM), e.g. "CP" */
+
+	long* arr;		/* dimension if mod[i] == 'A' else NULL */
+
+	DEMARG* func;		/* list of arguments if base == 'F' */
+				/* else NULL */
+
+	DEMARG* ret;		/* return type if base == 'F' else NULL */
+
+	DEMCL* clname;		/* class/enum name if base == "C" */
+
+	DEMCL** mname;		/* class name if mod[i] == "M" */
+				/* in argument list (pointers to members) */
+
+	DEMARG* next;		/* next argument or NULL */
+
+	char* lit;		/* literal value for PT arguments */
+				/* e.g. "59" in A<59> */
+
+	char base;		/* base type of argument, */
+				/* 'C' for class/enum types */
+};
+
+struct DEMCL {
+	char* name;		/* name of class or enum without PT args */
+				/* e.g. "Vector" */
+
+	DEMARG* clargs;		/* arguments to class, NULL if not PT */
+
+	char* rname;		/* raw class name with __pt__ if PT */
+				/* e.g. "A__pt__2_i" */
+
+	DEMCL* next;		/* next class name, NULL if not nested */
+};
+
+struct DEM {
+	enum DEM_TYPE type;	/* type of name that was demangled */
+	char* f;		/* function or data name;  NULL if type name */
+				/* see page 125 of ARM for predefined list */
+
+	char* vtname;		/* if != NULL name of source file for vtbl */
+
+	DEMARG* fargs;		/* arguments of function name if __opargs__ */
+				/* else NULL */
+
+	DEMCL* cl;		/* name of relevant class or enum or NULL */
+				/* used also for type-name-only input */
+
+	DEMARG* args;		/* args to function, NULL if data or type */
+
+
+	short slev;		/* scope level for local variables or -1 */
+
+	char sc;		/* storage class type 'S' or 'C' or: */
+				/* i -> __sti   d --> __std */
+				/* b -> __ptbl_vec */
+};
+
+#define MAXDBUF 8192
+
+int demangle();
+int cfront_demangle();
+void dem_printarg();
+void dem_printarglist();
+int dem_print();
+void dem_printfunc();
+int dem();
+void dem_printcl();
+char* dem_explain();
--- a/usr/src/Makefile.lint	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/Makefile.lint	Fri Mar 03 22:38:03 2006 -0800
@@ -101,6 +101,7 @@
 	cmd/devmgmt \
 	cmd/dfs.cmds \
 	cmd/diff3 \
+	cmd/dis \
 	cmd/dirname \
 	cmd/diskscan \
 	cmd/dispadmin \
@@ -302,6 +303,7 @@
 	lib/libdhcpdu \
 	lib/libdhcpsvc \
 	lib/libdhcputil \
+	lib/libdisasm \
 	lib/libdiskmgt \
 	lib/libdladm \
 	lib/libdlpi \
--- a/usr/src/cmd/Makefile	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -124,6 +124,7 @@
 	diffmk		\
 	dircmp		\
 	dirname		\
+	dis		\
 	diskmgtd	\
 	dispadmin	\
 	dladm		\
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/dis/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,50 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+
+PROG=	dis
+OBJS=	dis_target.o dis_main.o dis_util.o dis_list.o
+SRCS=	$(OBJS:%.o=%.c)
+
+include ../Makefile.cmd
+
+LDLIBS += -ldisasm -luutil -lelf
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+	$(LINK.c) -o $@ $(OBJS) $(LDLIBS)
+	$(POST_PROCESS)
+
+install: all $(ROOTCCSBINPROG)
+
+clean:
+	$(RM) $(OBJS) $(PROG)
+
+lint: lint_SRCS
+
+include ../Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/dis/dis_list.c	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,410 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "dis_target.h"
+#include "dis_list.h"
+#include "dis_util.h"
+
+/*
+ * List support functions.
+ *
+ * Support routines for managing lists of sections and functions.  We first
+ * process the command line arguments into lists of strings.  For each target,
+ * we resolve these strings against the set of available sections and/or
+ * functions to arrive at the set of objects to disassemble.
+ *
+ * We export two types of lists, namelists and resolvelists.  The first is used
+ * to record names given as command line options.  The latter is used to
+ * maintain the data objects specific to a given target.
+ */
+
+typedef struct unresolved_name {
+	const char	*un_name;	/* name of function or object */
+	int		un_value;	/* user-supplied data */
+	int		un_mark;	/* internal counter */
+	uu_list_node_t	un_node;	/* uulist node */
+} unresolved_name_t;
+
+typedef struct resolved_name {
+	void		*rn_data;	/* section or function data */
+	int		rn_value;	/* user-supplied data */
+	uu_list_node_t	rn_node;	/* uulist node */
+} resolved_name_t;
+
+static uu_list_pool_t *unresolved_pool;
+static uu_list_pool_t *resolved_pool;
+static int current_mark = 0;
+
+static void
+initialize_pools(void)
+{
+	unresolved_pool = uu_list_pool_create(
+	    "unresolved_pool", sizeof (unresolved_name_t),
+	    offsetof(unresolved_name_t, un_node), NULL, 0);
+	resolved_pool = uu_list_pool_create(
+	    "resolved_pool", sizeof (resolved_name_t),
+	    offsetof(resolved_name_t, rn_node), NULL, 0);
+
+	if (unresolved_pool == NULL ||
+	    resolved_pool == NULL)
+		die("out of memory");
+}
+
+/*
+ * Returns an empty list of unresolved names.
+ */
+dis_namelist_t *
+dis_namelist_create(void)
+{
+	uu_list_t *listp;
+
+	/*
+	 * If this is the first request to create a list, initialize the list
+	 * pools.
+	 */
+	if (unresolved_pool == NULL)
+		initialize_pools();
+
+	if ((listp = uu_list_create(unresolved_pool, NULL, 0)) == NULL)
+		die("out of memory");
+
+	return (listp);
+}
+
+/*
+ * Adds the given name to the unresolved list.  'value' is an arbitrary value
+ * which is preserved for this entry, even when resolved against a target.  This
+ * allows the caller to associate similar behavior (such as the difference
+ * between -d, -D, and -s) without having to create multiple lists.
+ */
+void
+dis_namelist_add(dis_namelist_t *list, const char *name, int value)
+{
+	unresolved_name_t *node;
+
+	node = safe_malloc(sizeof (unresolved_name_t));
+
+	node->un_name = name;
+	node->un_value = value;
+	node->un_mark = 0;
+
+	(void) uu_list_insert_before(list, NULL, node);
+}
+
+/*
+ * Internal callback structure used
+ */
+typedef struct cb_data {
+	int		cb_mark;
+	uu_list_t	*cb_source;
+	uu_list_t	*cb_resolved;
+} cb_data_t;
+
+/*
+ * For each section, walk the list of unresolved names and resolve those that
+ * correspond to real functions.  We mark functions as we see them, and re-walk
+ * the list a second time to warn about functions we didn't find.
+ *
+ * This is an O(n * m) algorithm, but we typically search for only a single
+ * function.
+ */
+/* ARGSUSED */
+static void
+walk_sections(dis_tgt_t *tgt, dis_scn_t *scn, void *data)
+{
+	cb_data_t *cb = data;
+	unresolved_name_t *unp;
+	uu_list_walk_t *walk;
+
+	if ((walk = uu_list_walk_start(cb->cb_source, UU_DEFAULT)) == NULL)
+		die("out of memory");
+
+	while ((unp = uu_list_walk_next(walk)) != NULL) {
+		if (strcmp(unp->un_name, dis_section_name(scn)) == 0) {
+			resolved_name_t *resolved;
+
+			/*
+			 * Mark the current node as seen
+			 */
+			unp->un_mark = cb->cb_mark;
+
+			/*
+			 * Add the data to the resolved list
+			 */
+			resolved = safe_malloc(sizeof (resolved_name_t));
+
+			resolved->rn_data = dis_section_copy(scn);
+			resolved->rn_value = unp->un_value;
+
+			(void) uu_list_insert_before(cb->cb_resolved, NULL,
+			    resolved);
+		}
+	}
+
+	uu_list_walk_end(walk);
+}
+
+/*
+ * Take a list of unresolved names and create a resolved list of sections.  We
+ * rely on walk_sections() to do the dirty work.  After resolving the sections,
+ * we check for any unmarked names and warn the user about missing sections.
+ */
+dis_scnlist_t *
+dis_namelist_resolve_sections(dis_namelist_t *namelist, dis_tgt_t *tgt)
+{
+	uu_list_t *listp;
+	cb_data_t cb;
+	unresolved_name_t *unp;
+	uu_list_walk_t *walk;
+
+	/*
+	 * Walk all sections in the target, calling walk_sections() for each
+	 * one.
+	 */
+	if ((listp = uu_list_create(resolved_pool, NULL, UU_DEFAULT)) == NULL)
+		die("out of memory");
+
+	cb.cb_mark = ++current_mark;
+	cb.cb_source = namelist;
+	cb.cb_resolved = listp;
+
+	dis_tgt_section_iter(tgt, walk_sections, &cb);
+
+	/*
+	 * Walk all elements of the unresolved list, and report any that we
+	 * didn't mark in the process.
+	 */
+	if ((walk = uu_list_walk_start(namelist, UU_DEFAULT)) == NULL)
+		die("out of memory");
+
+	while ((unp = uu_list_walk_next(walk)) != NULL) {
+		if (unp->un_mark != current_mark)
+			warn("failed to find section '%s' in '%s'",
+			    unp->un_name, dis_tgt_name(tgt));
+	}
+
+	uu_list_walk_end(walk);
+
+	return (listp);
+}
+
+/*
+ * Similar to walk_sections(), but for functions.
+ */
+/* ARGSUSED */
+static void
+walk_functions(dis_tgt_t *tgt, dis_func_t *func, void *data)
+{
+	cb_data_t *cb = data;
+	unresolved_name_t *unp;
+	uu_list_walk_t *walk;
+
+	if ((walk = uu_list_walk_start(cb->cb_source, UU_DEFAULT)) == NULL)
+		die("out of memory");
+
+	while ((unp = uu_list_walk_next(walk)) != NULL) {
+		if (strcmp(unp->un_name, dis_function_name(func)) == 0) {
+			resolved_name_t *resolved;
+
+			unp->un_mark = cb->cb_mark;
+
+			resolved = safe_malloc(sizeof (resolved_name_t));
+
+			resolved->rn_data = dis_function_copy(func);
+			resolved->rn_value = unp->un_value;
+
+			(void) uu_list_insert_before(cb->cb_resolved, NULL,
+			    resolved);
+		}
+	}
+
+	uu_list_walk_end(walk);
+}
+
+/*
+ * Take a list of unresolved names and create a resolved list of functions.  We
+ * rely on walk_functions() to do the dirty work.  After resolving the
+ * functions, * we check for any unmarked names and warn the user about missing
+ * functions.
+ */
+dis_funclist_t *
+dis_namelist_resolve_functions(dis_namelist_t *namelist, dis_tgt_t *tgt)
+{
+	uu_list_t *listp;
+	uu_list_walk_t *walk;
+	unresolved_name_t *unp;
+	cb_data_t cb;
+
+	if ((listp = uu_list_create(resolved_pool, NULL, UU_DEFAULT)) == NULL)
+		die("out of memory");
+
+	cb.cb_mark = ++current_mark;
+	cb.cb_source = namelist;
+	cb.cb_resolved = listp;
+
+	dis_tgt_function_iter(tgt, walk_functions, &cb);
+
+	/*
+	 * Walk unresolved list and report any missing functions.
+	 */
+	if ((walk = uu_list_walk_start(namelist, UU_DEFAULT)) == NULL)
+		die("out of memory");
+
+	while ((unp = uu_list_walk_next(walk)) != NULL) {
+		if (unp->un_mark != current_mark)
+			warn("failed to find function '%s' in '%s'",
+			    unp->un_name, dis_tgt_name(tgt));
+	}
+
+	uu_list_walk_end(walk);
+
+	return (listp);
+}
+
+/*
+ * Returns true if the given list is empty.
+ */
+int
+dis_namelist_empty(dis_namelist_t *list)
+{
+	return (uu_list_numnodes(list) == 0);
+}
+
+static void
+free_list(uu_list_t *list)
+{
+	uu_list_walk_t *walk;
+	void *data;
+
+	if ((walk = uu_list_walk_start(list, UU_WALK_ROBUST)) == NULL)
+		die("out of memory");
+
+	while ((data = uu_list_walk_next(walk)) != NULL) {
+		uu_list_remove(list, data);
+		free(data);
+	}
+
+	uu_list_walk_end(walk);
+
+	uu_list_destroy(list);
+}
+
+/*
+ * Destroy a list of sections.  First, walk the list and free the associated
+ * section data.  Pass the list onto to free_list() to clean up the rest of the
+ * list.
+ */
+void
+dis_scnlist_destroy(dis_scnlist_t *list)
+{
+	uu_list_walk_t *walk;
+	resolved_name_t *data;
+
+	if ((walk = uu_list_walk_start(list, UU_DEFAULT)) == NULL)
+		die("out of memory");
+
+	while ((data = uu_list_walk_next(walk)) != NULL)
+		dis_section_free(data->rn_data);
+
+	uu_list_walk_end(walk);
+
+	free_list(list);
+}
+
+/*
+ * Destroy a list of functions.  First, walk the list and free the associated
+ * function data.  Pass the list onto to free_list() to clean up the rest of the
+ * list.
+ */
+void
+dis_funclist_destroy(dis_funclist_t *list)
+{
+	uu_list_walk_t *walk;
+	resolved_name_t *data;
+
+	if ((walk = uu_list_walk_start(list, UU_DEFAULT)) == NULL)
+		die("out of memory");
+
+	while ((data = uu_list_walk_next(walk)) != NULL)
+		dis_function_free(data->rn_data);
+
+	uu_list_walk_end(walk);
+
+	free_list(list);
+}
+
+/*
+ * Destroy a lis tof unresolved names.
+ */
+void
+dis_namelist_destroy(dis_namelist_t *list)
+{
+	free_list(list);
+}
+
+/*
+ * Iterate over a resolved list of sections.
+ */
+void
+dis_scnlist_iter(uu_list_t *list, void (*func)(dis_scn_t *, int, void *),
+    void *arg)
+{
+	uu_list_walk_t *walk;
+	resolved_name_t *data;
+
+	if ((walk = uu_list_walk_start(list, UU_DEFAULT)) == NULL)
+		die("out of memory");
+
+	while ((data = uu_list_walk_next(walk)) != NULL)
+		func(data->rn_data, data->rn_value, arg);
+
+	uu_list_walk_end(walk);
+}
+
+/*
+ * Iterate over a resolved list of functions.
+ */
+void
+dis_funclist_iter(uu_list_t *list, void (*func)(dis_func_t *, int, void *),
+    void *arg)
+{
+	uu_list_walk_t *walk;
+	resolved_name_t *data;
+
+	if ((walk = uu_list_walk_start(list, UU_DEFAULT)) == NULL)
+		die("out of memory");
+
+	while ((data = uu_list_walk_next(walk)) != NULL)
+		func(data->rn_data, data->rn_value, arg);
+
+	uu_list_walk_end(walk);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/dis/dis_list.h	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_DIS_LIST_H
+#define	_DIS_LIST_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <libuutil.h>
+
+/* #include "dis_target.h" */
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef uu_list_t dis_namelist_t;
+typedef uu_list_t dis_scnlist_t;
+typedef uu_list_t dis_funclist_t;
+
+dis_namelist_t *dis_namelist_create(void);
+void dis_namelist_add(dis_namelist_t *, const char *, int);
+dis_funclist_t *dis_namelist_resolve_functions(dis_namelist_t *, dis_tgt_t *);
+dis_scnlist_t *dis_namelist_resolve_sections(dis_namelist_t *, dis_tgt_t *);
+void dis_scnlist_iter(dis_scnlist_t *, void (*)(dis_scn_t *, int, void *),
+    void *);
+void dis_funclist_iter(dis_funclist_t *, void (*)(dis_func_t *, int, void *),
+    void *);
+int dis_namelist_empty(dis_namelist_t *);
+void dis_scnlist_destroy(dis_scnlist_t *);
+void dis_funclist_destroy(dis_funclist_t *);
+void dis_namelist_destroy(dis_namelist_t *);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _DIS_LIST_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/dis/dis_main.c	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,682 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <ctype.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/sysmacros.h>
+#include <sys/elf_SPARC.h>
+
+#include <libdisasm.h>
+
+#include "dis_target.h"
+#include "dis_util.h"
+#include "dis_list.h"
+
+int g_demangle;		/* Demangle C++ names */
+int g_quiet;		/* Quiet mode */
+int g_numeric;		/* Numeric mode */
+int g_flags;		/* libdisasm language flags */
+int g_doall;		/* true if no functions or sections were given */
+
+dis_namelist_t *g_funclist;	/* list of functions to disassemble, if any */
+dis_namelist_t *g_seclist;	/* list of sections to disassemble, if any */
+
+/*
+ * Section options for -d, -D, and -s
+ */
+#define	DIS_DATA_RELATIVE	1
+#define	DIS_DATA_ABSOLUTE	2
+#define	DIS_TEXT		3
+
+/*
+ * libdisasm callback data.  Keeps track of current data (function or section)
+ * and offset within that data.
+ */
+typedef struct dis_buffer {
+	dis_tgt_t	*db_tgt;	/* current dis target */
+	void		*db_data;	/* function or section data */
+	uint64_t	db_addr;	/* address of function start */
+	size_t		db_size;	/* size of data */
+	uint64_t	db_nextaddr;	/* next address to be read */
+} dis_buffer_t;
+
+#define	MINSYMWIDTH	22	/* Minimum width of symbol portion of line */
+
+/*
+ * Given a symbol+offset as returned by dis_tgt_lookup(), print an appropriately
+ * formatted symbol, based on the offset and current setttings.
+ */
+void
+getsymname(uint64_t addr, const char *symbol, off_t offset, char *buf,
+    size_t buflen)
+{
+	if (symbol == NULL || g_numeric)
+		(void) snprintf(buf, buflen, "%llx", addr);
+	else {
+		if (g_demangle)
+			symbol = dis_demangle(symbol);
+
+		if (offset == 0)
+			(void) snprintf(buf, buflen, "%s", symbol);
+		else if (g_flags & DIS_OCTAL)
+			(void) snprintf(buf, buflen, "%s+0%o", symbol, offset);
+		else
+			(void) snprintf(buf, buflen, "%s+0x%x", symbol, offset);
+	}
+}
+
+/*
+ * The main disassembly routine.  Given a fixed-sized buffer and starting
+ * address, disassemble the data using the supplied target and libdisasm handle.
+ */
+void
+dis_data(dis_tgt_t *tgt, dis_handle_t *dhp, uint64_t addr, void *data,
+    size_t datalen)
+{
+	dis_buffer_t db = { 0 };
+	char buf[BUFSIZE];
+	char symbuf[BUFSIZE];
+	const char *symbol;
+	off_t symoffset;
+	int i;
+	int bytesperline;
+	size_t symsize;
+	int isfunc;
+	size_t symwidth = 0;
+
+	db.db_tgt = tgt;
+	db.db_data = data;
+	db.db_addr = addr;
+	db.db_size = datalen;
+
+	dis_set_data(dhp, &db);
+
+	if ((bytesperline = dis_max_instrlen(dhp)) > 6)
+		bytesperline = 6;
+
+	while (addr < db.db_addr + db.db_size) {
+
+		if (dis_disassemble(dhp, addr, buf, BUFSIZE) != 0) {
+			/*
+			 * If we encounter an invalid opcode, we just
+			 * print "*** invalid opcode ***" at that first bad
+			 * instruction and continue with printing the rest
+			 * of the instruction stream as hex data,
+			 * We then find the next valid symbol in the section,
+			 * and disassemble from there.
+			 */
+			off_t next;
+
+			(void) snprintf(buf, sizeof (buf),
+			    "*** invalid opcode ***");
+
+			if ((next = dis_tgt_next_symbol(tgt, addr)) == 0) {
+				db.db_nextaddr = db.db_addr + db.db_size;
+			} else {
+				if (next > db.db_size)
+					db.db_nextaddr = db.db_addr +
+					    db.db_size;
+				else
+					db.db_nextaddr = addr + next;
+			}
+		}
+
+		/*
+		 * Print out the line as:
+		 *
+		 * 	address:	bytes	text
+		 *
+		 * If there are more than 6 bytes in any given instruction,
+		 * spread the bytes across two lines.  We try to get symbolic
+		 * information for the address, but if that fails we print out
+		 * the numeric address instead.
+		 *
+		 * We try to keep the address portion of the text aligned at
+		 * MINSYMWIDTH characters.  If we are disassembling a function
+		 * with a long name, this can be annoying.  So we pick a width
+		 * based on the maximum width that the current symbol can be.
+		 * This at least produces text aligned within each function.
+		 */
+		symbol = dis_tgt_lookup(tgt, addr, &symoffset, 1, &symsize,
+		    &isfunc);
+		/* Get the maximum length for this symbol */
+		getsymname(addr, symbol, symsize, symbuf, sizeof (symbuf));
+		symwidth = MAX(strlen(symbuf), MINSYMWIDTH);
+
+		getsymname(addr, symbol, symoffset, symbuf, sizeof (symbuf));
+
+		/*
+		 * If we've crossed a new function boundary, print out the
+		 * function name on a blank line.
+		 */
+		if (!g_quiet && symoffset == 0 && symbol != NULL && isfunc)
+			(void) printf("%s()\n", symbol);
+
+		(void) printf("    %s:%*s ", symbuf,
+		    symwidth - strlen(symbuf), "");
+
+		/* print bytes */
+		for (i = 0; i < MIN(bytesperline, (db.db_nextaddr - addr));
+		    i++) {
+			int byte = *((uchar_t *)data + (addr - db.db_addr) + i);
+			if (g_flags & DIS_OCTAL)
+				(void) printf("%03o ", byte);
+			else
+				(void) printf("%02x ", byte);
+		}
+
+		/* trailing spaces for missing bytes */
+		for (; i < bytesperline; i++) {
+			if (g_flags & DIS_OCTAL)
+				(void) printf("    ");
+			else
+				(void) printf("   ");
+		}
+
+		/* contents of disassembly */
+		(void) printf(" %s", buf);
+
+		/* excess bytes that spill over onto subsequent lines */
+		for (; i < db.db_nextaddr - addr; i++) {
+			int byte = *((uchar_t *)data + (addr - db.db_addr) + i);
+			if (i % bytesperline == 0)
+				(void) printf("\n    %*s  ", symwidth, "");
+			if (g_flags & DIS_OCTAL)
+				(void) printf("%03o ", byte);
+			else
+				(void) printf("%02x ", byte);
+		}
+
+		(void) printf("\n");
+
+		addr = db.db_nextaddr;
+	}
+}
+
+/*
+ * libdisasm wrapper around symbol lookup.  Invoke the target-specific lookup
+ * function, and convert the result using getsymname().
+ */
+int
+do_lookup(void *data, uint64_t addr, char *buf, size_t buflen, uint64_t *start,
+    size_t *symlen)
+{
+	dis_buffer_t *db = data;
+	const char *symbol;
+	off_t offset;
+	size_t size;
+
+	/*
+	 * If NULL symbol is returned, getsymname takes care of
+	 * printing appropriate address in buf instead of symbol.
+	 */
+	symbol = dis_tgt_lookup(db->db_tgt, addr, &offset, 0, &size, NULL);
+
+	if (buf != NULL)
+		getsymname(addr, symbol, offset, buf, buflen);
+
+	if (start != NULL)
+		*start = addr - offset;
+	if (symlen != NULL)
+		*symlen = size;
+
+	return (0);
+}
+
+/*
+ * libdisasm wrapper around target reading.  libdisasm will always read data
+ * in order, so update our current offset within the buffer appropriately.
+ * We only support reading from within the current object; libdisasm should
+ * never ask us to do otherwise.
+ */
+int
+do_read(void *data, uint64_t addr, void *buf, size_t len)
+{
+	dis_buffer_t *db = data;
+	size_t offset;
+
+	if (addr < db->db_addr || addr >= db->db_addr + db->db_size)
+		return (-1);
+
+	offset = addr - db->db_addr;
+	len = MIN(len, db->db_size - offset);
+
+	(void) memcpy(buf, (char *)db->db_data + offset, len);
+
+	db->db_nextaddr = addr + len;
+
+	return (len);
+}
+
+/*
+ * Routine to dump raw data in a human-readable format.  Used by the -d and -D
+ * options.  We model our output after the xxd(1) program, which gives nicely
+ * formatted output, along with an ASCII translation of the result.
+ */
+void
+dump_data(uint64_t addr, void *data, size_t datalen)
+{
+	uintptr_t curaddr = addr & (~0xf);
+	uint8_t *bytes = data;
+	int i;
+	int width;
+
+	/*
+	 * Determine if the address given to us fits in 32-bit range, in which
+	 * case use a 4-byte width.
+	 */
+	if (((addr + datalen) & 0xffffffff00000000ULL) == 0ULL)
+		width = 8;
+	else
+		width = 16;
+
+	while (curaddr < addr + datalen) {
+		/*
+		 * Display leading address
+		 */
+		(void) printf("%0*x: ", width, curaddr);
+
+		/*
+		 * Print out data in two-byte chunks.  If the current address
+		 * is before the starting address or after the end of the
+		 * section, print spaces.
+		 */
+		for (i = 0; i < 16; i++) {
+			if (curaddr + i < addr ||curaddr + i >= addr + datalen)
+				(void) printf("  ");
+			else
+				(void) printf("%02x",
+				    bytes[curaddr + i - addr]);
+
+			if (i & 1)
+				(void) printf(" ");
+		}
+
+		(void) printf(" ");
+
+		/*
+		 * Print out the ASCII representation
+		 */
+		for (i = 0; i < 16; i++) {
+			if (curaddr + i < addr ||
+			    curaddr + i >= addr + datalen) {
+				(void) printf(" ");
+			} else {
+				uint8_t byte = bytes[curaddr + i - addr];
+				if (isprint(byte))
+					(void) printf("%c", byte);
+				else
+					(void) printf(".");
+			}
+		}
+
+		(void) printf("\n");
+
+		curaddr += 16;
+	}
+}
+
+/*
+ * Disassemble a section implicitly specified as part of a file.  This function
+ * is called for all sections when no other flags are specified.  We ignore any
+ * data sections, and print out only those sections containing text.
+ */
+void
+dis_text_section(dis_tgt_t *tgt, dis_scn_t *scn, void *data)
+{
+	dis_handle_t *dhp = data;
+
+	/* ignore data sections */
+	if (!dis_section_istext(scn))
+		return;
+
+	if (!g_quiet)
+		(void) printf("\nsection %s\n", dis_section_name(scn));
+
+	dis_data(tgt, dhp, dis_section_addr(scn), dis_section_data(scn),
+	    dis_section_size(scn));
+}
+
+/*
+ * Structure passed to dis_named_{section,function} which keeps track of both
+ * the target and the libdisasm handle.
+ */
+typedef struct callback_arg {
+	dis_tgt_t	*ca_tgt;
+	dis_handle_t	*ca_handle;
+} callback_arg_t;
+
+/*
+ * Disassemble a section explicitly named with -s, -d, or -D.  The 'type'
+ * argument contains the type of argument given.  Pass the data onto the
+ * appropriate helper routine.
+ */
+void
+dis_named_section(dis_scn_t *scn, int type, void *data)
+{
+	callback_arg_t *ca = data;
+
+	if (!g_quiet)
+		(void) printf("\nsection %s\n", dis_section_name(scn));
+
+	switch (type) {
+	case DIS_DATA_RELATIVE:
+		dump_data(0, dis_section_data(scn), dis_section_size(scn));
+		break;
+	case DIS_DATA_ABSOLUTE:
+		dump_data(dis_section_addr(scn), dis_section_data(scn),
+		    dis_section_size(scn));
+		break;
+	case DIS_TEXT:
+		dis_data(ca->ca_tgt, ca->ca_handle, dis_section_addr(scn),
+		    dis_section_data(scn), dis_section_size(scn));
+		break;
+	}
+}
+
+/*
+ * Disassemble a function explicitly specified with '-F'.  The 'type' argument
+ * is unused.
+ */
+/* ARGSUSED */
+void
+dis_named_function(dis_func_t *func, int type, void *data)
+{
+	callback_arg_t *ca = data;
+
+	dis_data(ca->ca_tgt, ca->ca_handle, dis_function_addr(func),
+	    dis_function_data(func), dis_function_size(func));
+}
+
+/*
+ * Disassemble a complete file.  First, we determine the type of the file based
+ * on the ELF machine type, and instantiate a version of the disassembler
+ * appropriate for the file.  We then resolve any named sections or functions
+ * against the file, and iterate over the results (or all sections if no flags
+ * were specified).
+ */
+void
+dis_file(const char *filename)
+{
+	dis_tgt_t *tgt, *current;
+	dis_scnlist_t *sections;
+	dis_funclist_t *functions;
+	dis_handle_t *dhp;
+	GElf_Ehdr ehdr;
+
+	/*
+	 * First, initialize the target
+	 */
+	if ((tgt = dis_tgt_create(filename)) == NULL)
+		return;
+
+	if (!g_quiet)
+		(void) printf("disassembly for %s\n\n",  filename);
+
+	/*
+	 * A given file may contain multiple targets (if it is an archive, for
+	 * example).  We iterate over all possible targets if this is the case.
+	 */
+	for (current = tgt; current != NULL; current = dis_tgt_next(current)) {
+		dis_tgt_ehdr(current, &ehdr);
+
+		/*
+		 * Eventually, this should probably live within libdisasm, and
+		 * we should be able to disassemble targets from different
+		 * architectures.  For now, we only support objects as the
+		 * native machine type.
+		 */
+		switch (ehdr.e_machine) {
+#ifdef __sparc
+		case EM_SPARC:
+			if (ehdr.e_ident[EI_CLASS] != ELFCLASS32 ||
+			    ehdr.e_ident[EI_DATA] != ELFDATA2MSB) {
+				warn("invalid E_IDENT field for SPARC object");
+				return;
+			}
+			g_flags |= DIS_SPARC_V8;
+			break;
+
+		case EM_SPARC32PLUS:
+			if (ehdr.e_ident[EI_CLASS] != ELFCLASS32 ||
+			    ehdr.e_ident[EI_DATA] != ELFDATA2MSB) {
+				warn("invalid E_IDENT field for SPARC object");
+				return;
+			}
+
+			switch (ehdr.e_flags & EF_SPARC_32PLUS_MASK) {
+			case (EF_SPARC_32PLUS | EF_SPARC_SUN_US1 |
+			    EF_SPARC_SUN_US3):
+			case (EF_SPARC_32PLUS | EF_SPARC_SUN_US1):
+				g_flags |= DIS_SPARC_V9 | DIS_SPARC_V9_SGI;
+			default:
+				g_flags |= DIS_SPARC_V9;
+			}
+			break;
+
+		case EM_SPARCV9:
+			if (ehdr.e_ident[EI_CLASS] != ELFCLASS64 ||
+			    ehdr.e_ident[EI_DATA] != ELFDATA2MSB) {
+				warn("invalid E_IDENT field for SPARC object");
+				return;
+			}
+
+			g_flags |= DIS_SPARC_V9 | DIS_SPARC_V9_SGI;
+			break;
+#endif /* __sparc */
+
+#if defined(__i386) || defined(__amd64)
+		case EM_386:
+			g_flags |= DIS_X86_SIZE32;
+			break;
+
+		case EM_AMD64:
+			g_flags |= DIS_X86_SIZE64;
+			break;
+#endif /* __i386 || __amd64 */
+
+		default:
+			die("%s: unsupported ELF machine 0x%x", filename,
+			    ehdr.e_machine);
+		}
+
+		if (!g_quiet && dis_tgt_member(current) != NULL)
+			(void) printf("\narchive member %s\n",
+			    dis_tgt_member(current));
+
+		/*
+		 * Instantiate a libdisasm handle based on the file type.
+		 */
+		if ((dhp = dis_handle_create(g_flags, current, do_lookup,
+		    do_read)) == NULL)
+			die("%s: failed to initialize disassembler: %s",
+			    filename, dis_strerror(dis_errno()));
+
+		if (g_doall) {
+			/*
+			 * With no arguments, iterate over all sections and
+			 * disassemble only those that contain text.
+			 */
+			dis_tgt_section_iter(current, dis_text_section, dhp);
+		} else {
+			callback_arg_t ca;
+
+			ca.ca_tgt = current;
+			ca.ca_handle = dhp;
+
+			/*
+			 * If sections or functions were explicitly specified,
+			 * resolve those names against the object, and iterate
+			 * over just the resulting data.
+			 */
+			sections = dis_namelist_resolve_sections(g_seclist,
+			    current);
+			functions = dis_namelist_resolve_functions(g_funclist,
+			    current);
+
+			dis_scnlist_iter(sections, dis_named_section, &ca);
+			dis_funclist_iter(functions, dis_named_function, &ca);
+
+			dis_scnlist_destroy(sections);
+			dis_funclist_destroy(functions);
+		}
+
+		dis_handle_destroy(dhp);
+	}
+
+	dis_tgt_destroy(tgt);
+}
+
+void
+usage(void)
+{
+	(void) fprintf(stderr, "usage: dis [-CVoqn] [-d sec] \n");
+	(void) fprintf(stderr, "\t[-D sec] [-F function] [-t sec] file ..\n");
+	exit(2);
+}
+
+typedef struct lib_node {
+	char *path;
+	struct lib_node *next;
+} lib_node_t;
+
+int
+main(int argc, char **argv)
+{
+	int optchar;
+	int i;
+	lib_node_t *libs = NULL;
+
+	g_funclist = dis_namelist_create();
+	g_seclist = dis_namelist_create();
+
+	while ((optchar = getopt(argc, argv, "Cd:D:F:l:Lot:Vqn")) != -1) {
+		switch (optchar) {
+		case 'C':
+			g_demangle = 1;
+			break;
+		case 'd':
+			dis_namelist_add(g_seclist, optarg, DIS_DATA_RELATIVE);
+			break;
+		case 'D':
+			dis_namelist_add(g_seclist, optarg, DIS_DATA_ABSOLUTE);
+			break;
+		case 'F':
+			dis_namelist_add(g_funclist, optarg, 0);
+			break;
+		case 'l': {
+			/*
+			 * The '-l foo' option historically would attempt to
+			 * disassemble '$LIBDIR/libfoo.a'.  The $LIBDIR
+			 * environment variable has never been supported or
+			 * documented for our linker.  However, until this
+			 * option is formally EOLed, we have to support it.
+			 */
+			char *dir;
+			lib_node_t *node;
+			size_t len;
+
+			if ((dir = getenv("LIBDIR")) == NULL ||
+			    dir[0] == '\0')
+				dir = "/usr/lib";
+			node = safe_malloc(sizeof (lib_node_t));
+			len = strlen(optarg) + strlen(dir) + sizeof ("/lib.a");
+			node->path = safe_malloc(len);
+
+			(void) snprintf(node->path, len, "%s/lib%s.a", dir,
+			    optarg);
+			node->next = libs;
+			libs = node;
+			break;
+		}
+		case 'L':
+			/*
+			 * The '-L' option historically would attempt to read
+			 * the .debug section of the target to determine source
+			 * line information in order to annotate the output.
+			 * No compiler has emitted these sections in many years,
+			 * and the option has never done what it purported to
+			 * do.  We silently consume the option for
+			 * compatibility.
+			 */
+			break;
+		case 'n':
+			g_numeric = 1;
+			break;
+		case 'o':
+			g_flags |= DIS_OCTAL;
+			break;
+		case 'q':
+			g_quiet = 1;
+			break;
+		case 't':
+			dis_namelist_add(g_seclist, optarg, DIS_TEXT);
+			break;
+		case 'V':
+			(void) printf("Solaris disassembler version 1.0\n");
+			return (0);
+		default:
+			usage();
+			break;
+		}
+	}
+
+	argc -= optind;
+	argv += optind;
+
+	if (argc == 0 && libs == NULL) {
+		warn("no objects specified");
+		usage();
+	}
+
+	if (dis_namelist_empty(g_funclist) && dis_namelist_empty(g_seclist))
+		g_doall = 1;
+
+	/*
+	 * See comment for 'l' option, above.
+	 */
+	while (libs != NULL) {
+		lib_node_t *node = libs->next;
+
+		dis_file(libs->path);
+		free(libs->path);
+		free(libs);
+		libs = node;
+	}
+
+	for (i = 0; i < argc; i++)
+		dis_file(argv[i]);
+
+	dis_namelist_destroy(g_funclist);
+	dis_namelist_destroy(g_seclist);
+
+	return (g_error);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/dis/dis_target.c	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,825 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <libelf.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+
+#include "dis_target.h"
+#include "dis_util.h"
+
+/*
+ * Standard ELF disassembler target.
+ *
+ * We only support disassembly of ELF files, though this target interface could
+ * be extended in the future.  Each basic type (target, func, section) contains
+ * enough information to uniquely identify the location within the file.  The
+ * interfaces use libelf(3LIB) to do the actual processing of the file.
+ */
+
+/*
+ * Symbol table entry type.  We maintain our own symbol table sorted by address,
+ * with the symbol name already resolved against the ELF symbol table.
+ */
+typedef struct sym_entry {
+	GElf_Sym	se_sym;		/* value of symbol */
+	char		*se_name;	/* name of symbol */
+	int		se_shndx;	/* section where symbol is located */
+} sym_entry_t;
+
+/*
+ * Target data structure.  This structure keeps track of the ELF file
+ * information, a few bits of pre-processed section index information, and
+ * sorted versions of the symbol table.  We also keep track of the last symbol
+ * looked up, as the majority of lookups remain within the same symbol.
+ */
+struct dis_tgt {
+	Elf		*dt_elf;	/* libelf handle */
+	Elf		*dt_elf_root;	/* main libelf handle (for archives) */
+	const char	*dt_filename;	/* name of file */
+	int		dt_fd;		/* underlying file descriptor */
+	size_t		dt_shstrndx;	/* section index of .shstrtab */
+	size_t		dt_symidx;	/* section index of symbol table */
+	sym_entry_t	*dt_symcache;	/* last symbol looked up */
+	sym_entry_t	*dt_symtab;	/* sorted symbol table */
+	int		dt_symcount;	/* # of symbol table entries */
+	struct dis_tgt	*dt_next;	/* next target (for archives) */
+	Elf_Arhdr	*dt_arhdr;	/* archive header (for archives) */
+};
+
+/*
+ * Function data structure.  We resolve the symbol and lookup the associated ELF
+ * data when building this structure.  The offset is calculated based on the
+ * section's starting address.
+ */
+struct dis_func {
+	sym_entry_t	*df_sym;	/* symbol table reference */
+	Elf_Data	*df_data;	/* associated ELF data */
+	size_t		df_offset;	/* offset within data */
+};
+
+/*
+ * Section data structure.  We store the entire section header so that we can
+ * determine some properties (such as whether or not it contains text) after
+ * building the structure.
+ */
+struct dis_scn {
+	GElf_Shdr	ds_shdr;
+	const char	*ds_name;
+	Elf_Data	*ds_data;
+};
+
+/* Lifted from Psymtab.c */
+#define	DATA_TYPES      \
+	((1 << STT_OBJECT) | (1 << STT_FUNC) | \
+	(1 << STT_COMMON) | (1 << STT_TLS))
+#define	IS_DATA_TYPE(tp)	(((1 << (tp)) & DATA_TYPES) != 0)
+
+/*
+ * Pick out the best symbol to used based on the sections available in the
+ * target.  We prefer SHT_SYMTAB over SHT_DYNSYM.
+ */
+/* ARGSUSED */
+static void
+get_symtab(dis_tgt_t *tgt, dis_scn_t *scn, void *data)
+{
+	int *index = data;
+
+	*index += 1;
+
+	/*
+	 * Prefer SHT_SYMTAB over SHT_DYNSYM
+	 */
+	if (scn->ds_shdr.sh_type == SHT_DYNSYM && tgt->dt_symidx == 0)
+		tgt->dt_symidx = *index;
+	else if (scn->ds_shdr.sh_type == SHT_SYMTAB)
+		tgt->dt_symidx = *index;
+}
+
+static int
+sym_compare(const void *a, const void *b)
+{
+	const sym_entry_t *syma = a;
+	const sym_entry_t *symb = b;
+	const char *aname = syma->se_name;
+	const char *bname = symb->se_name;
+
+	if (syma->se_sym.st_value < symb->se_sym.st_value)
+		return (-1);
+
+	if (syma->se_sym.st_value > symb->se_sym.st_value)
+		return (1);
+
+	/*
+	 * Prefer functions over non-functions
+	 */
+	if (GELF_ST_TYPE(syma->se_sym.st_info) !=
+	    GELF_ST_TYPE(symb->se_sym.st_info)) {
+		if (GELF_ST_TYPE(syma->se_sym.st_info) == STT_FUNC)
+			return (-1);
+		if (GELF_ST_TYPE(symb->se_sym.st_info) == STT_FUNC)
+			return (1);
+	}
+
+	/*
+	 * For symbols with the same address and type, we sort them according to
+	 * a hierarchy:
+	 *
+	 * 	1. weak symbols (common name)
+	 * 	2. global symbols (external name)
+	 * 	3. local symbols
+	 */
+	if (GELF_ST_BIND(syma->se_sym.st_info) !=
+	    GELF_ST_BIND(symb->se_sym.st_info)) {
+		if (GELF_ST_BIND(syma->se_sym.st_info) == STB_WEAK)
+			return (-1);
+		if (GELF_ST_BIND(symb->se_sym.st_info) == STB_WEAK)
+			return (1);
+
+		if (GELF_ST_BIND(syma->se_sym.st_info) == STB_GLOBAL)
+			return (-1);
+		if (GELF_ST_BIND(symb->se_sym.st_info) == STB_GLOBAL)
+			return (1);
+	}
+
+	/*
+	 * As a last resort, if we have multiple symbols of the same type at the
+	 * same address, prefer the version with the fewest leading underscores.
+	 */
+	if (aname == NULL)
+		return (-1);
+	if (bname == NULL)
+		return (1);
+
+	while (*aname == '_' && *bname == '_') {
+		aname++;
+		bname++;
+	}
+
+	if (*bname == '_')
+		return (-1);
+	if (*aname == '_')
+		return (1);
+
+	/*
+	 * Prefer the symbol with the smaller size.
+	 */
+	if (syma->se_sym.st_size < symb->se_sym.st_size)
+		return (-1);
+	if (syma->se_sym.st_size > symb->se_sym.st_size)
+		return (1);
+
+	/*
+	 * We really do have two identical symbols for some reason.  Just report
+	 * them as equal, and to the lucky one go the spoils.
+	 */
+	return (0);
+}
+
+/*
+ * Construct an optimized symbol table sorted by starting address.
+ */
+static void
+construct_symtab(dis_tgt_t *tgt)
+{
+	Elf_Scn *scn;
+	GElf_Shdr shdr;
+	Elf_Data *symdata;
+	int i;
+	GElf_Word *symshndx = NULL;
+	int symshndx_size;
+	sym_entry_t *sym;
+	sym_entry_t *p_symtab = NULL;
+	int nsym = 0; /* count of symbols we're not interested in */
+
+	/*
+	 * Find the symshndx section, if any
+	 */
+	for (scn = elf_nextscn(tgt->dt_elf, NULL); scn != NULL;
+	    scn = elf_nextscn(tgt->dt_elf, scn)) {
+		if (gelf_getshdr(scn, &shdr) == NULL)
+			break;
+		if (shdr.sh_type == SHT_SYMTAB_SHNDX &&
+		    shdr.sh_link == tgt->dt_symidx) {
+			Elf_Data	*data;
+
+			if ((data = elf_getdata(scn, NULL)) != NULL) {
+				symshndx = (GElf_Word *)data->d_buf;
+				symshndx_size = data->d_size /
+				    sizeof (GElf_Word);
+				break;
+			}
+		}
+	}
+
+	if ((scn = elf_getscn(tgt->dt_elf, tgt->dt_symidx)) == NULL)
+		die("%s: failed to get section information", tgt->dt_filename);
+	if (gelf_getshdr(scn, &shdr) == NULL)
+		die("%s: failed to get section header", tgt->dt_filename);
+	if (shdr.sh_entsize == 0)
+		die("%s: symbol table has zero size", tgt->dt_filename);
+
+	if ((symdata = elf_getdata(scn, NULL)) == NULL)
+		die("%s: failed to get symbol table", tgt->dt_filename);
+
+	tgt->dt_symcount = symdata->d_size / gelf_fsize(tgt->dt_elf, ELF_T_SYM,
+		1, EV_CURRENT);
+
+	p_symtab = safe_malloc(tgt->dt_symcount * sizeof (sym_entry_t));
+
+	for (i = 0, sym = p_symtab; i < tgt->dt_symcount; i++) {
+		(void) memset(sym, sizeof (sym_entry_t), 0);
+		if (gelf_getsym(symdata, i, &(sym->se_sym)) == NULL) {
+			warn("%s: gelf_getsym returned NULL for %d",
+				tgt->dt_filename, i);
+			nsym++;
+			continue;
+		}
+
+		/*
+		 * We're only interested in data symbols.
+		 */
+		if (!IS_DATA_TYPE(GELF_ST_TYPE(sym->se_sym.st_info))) {
+			nsym++;
+			continue;
+		}
+
+		if (sym->se_sym.st_shndx == SHN_XINDEX && symshndx != NULL) {
+			if (i > symshndx_size) {
+				warn("%s: bad SHNX_XINDEX %d",
+					tgt->dt_filename, i);
+				sym->se_shndx = -1;
+			} else {
+				sym->se_shndx = symshndx[i];
+			}
+		} else {
+			sym->se_shndx = sym->se_sym.st_shndx;
+		}
+
+		if ((sym->se_name = elf_strptr(tgt->dt_elf, shdr.sh_link,
+		    (size_t)sym->se_sym.st_name)) == NULL) {
+			warn("%s: failed to lookup symbol %d name",
+				tgt->dt_filename, i);
+			nsym++;
+			continue;
+		}
+
+		sym++;
+	}
+
+	tgt->dt_symcount -= nsym;
+	tgt->dt_symtab = realloc(p_symtab,
+				tgt->dt_symcount * sizeof (sym_entry_t));
+
+	qsort(tgt->dt_symtab, tgt->dt_symcount, sizeof (sym_entry_t),
+	    sym_compare);
+}
+
+/*
+ * Create a target backed by an ELF file.
+ */
+dis_tgt_t *
+dis_tgt_create(const char *file)
+{
+	dis_tgt_t *tgt, *current;
+	int idx;
+	Elf *elf;
+	GElf_Ehdr ehdr;
+	Elf_Arhdr *arhdr = NULL;
+	int cmd;
+
+	if (elf_version(EV_CURRENT) == EV_NONE)
+		die("libelf(3ELF) out of date");
+
+	tgt = safe_malloc(sizeof (dis_tgt_t));
+
+	if ((tgt->dt_fd = open(file, O_RDONLY)) < 0) {
+		warn("%s: failed opening file, reason: %s", file,
+			strerror(errno));
+		free(tgt);
+		return (NULL);
+	}
+
+	if ((tgt->dt_elf_root =
+	    elf_begin(tgt->dt_fd, ELF_C_READ, NULL)) == NULL) {
+		warn("%s: invalid or corrupt ELF file", file);
+		dis_tgt_destroy(tgt);
+		return (NULL);
+	}
+
+	current = tgt;
+	cmd = ELF_C_READ;
+	while ((elf = elf_begin(tgt->dt_fd, cmd, tgt->dt_elf_root)) != NULL) {
+
+		if (elf_kind(tgt->dt_elf_root) == ELF_K_AR &&
+		    (arhdr = elf_getarhdr(elf)) == NULL) {
+			warn("%s: malformed archive", file);
+			dis_tgt_destroy(tgt);
+			return (NULL);
+		}
+
+		/*
+		 * Make sure that this Elf file is sane
+		 */
+		if (gelf_getehdr(elf, &ehdr) == NULL) {
+			if (arhdr != NULL) {
+				/*
+				 * For archives, we drive on in the face of bad
+				 * members.  The "/" and "//" members are
+				 * special, and should be silently ignored.
+				 */
+				if (strcmp(arhdr->ar_name, "/") != 0 &&
+				    strcmp(arhdr->ar_name, "//") != 0)
+					warn("%s[%s]: invalid file type",
+					    file, arhdr->ar_name);
+				cmd = elf_next(elf);
+				(void) elf_end(elf);
+				continue;
+			}
+
+			warn("%s: invalid file type", file);
+			dis_tgt_destroy(tgt);
+			return (NULL);
+		}
+
+		/*
+		 * If we're seeing a new Elf object, then we have an
+		 * archive. In this case, we create a new target, and chain it
+		 * off the master target.  We can later iterate over these
+		 * targets using dis_tgt_next().
+		 */
+		if (current->dt_elf != NULL) {
+			dis_tgt_t *next = safe_malloc(sizeof (dis_tgt_t));
+			next->dt_elf_root = tgt->dt_elf_root;
+			next->dt_fd = -1;
+			current->dt_next = next;
+			current = next;
+		}
+		current->dt_elf = elf;
+		current->dt_arhdr = arhdr;
+
+		if (elf_getshstrndx(elf, &current->dt_shstrndx) == -1) {
+			warn("%s: failed to get section string table for "
+			    "file", file);
+			dis_tgt_destroy(tgt);
+			return (NULL);
+		}
+
+		idx = 0;
+		dis_tgt_section_iter(current, get_symtab, &idx);
+
+		if (current->dt_symidx != 0)
+			construct_symtab(current);
+
+		current->dt_filename = file;
+
+		cmd = elf_next(elf);
+	}
+
+	/*
+	 * Final sanity check.  If we had an archive with no members, then bail
+	 * out with a nice message.
+	 */
+	if (tgt->dt_elf == NULL) {
+		warn("%s: empty archive\n", file);
+		dis_tgt_destroy(tgt);
+		return (NULL);
+	}
+
+	return (tgt);
+}
+
+/*
+ * Return the filename associated with the target.
+ */
+const char *
+dis_tgt_name(dis_tgt_t *tgt)
+{
+	return (tgt->dt_filename);
+}
+
+/*
+ * Return the archive member name, if any.
+ */
+const char *
+dis_tgt_member(dis_tgt_t *tgt)
+{
+	if (tgt->dt_arhdr)
+		return (tgt->dt_arhdr->ar_name);
+	else
+		return (NULL);
+}
+
+/*
+ * Return the Elf_Ehdr associated with this target.  Needed to determine which
+ * disassembler to use.
+ */
+void
+dis_tgt_ehdr(dis_tgt_t *tgt, GElf_Ehdr *ehdr)
+{
+	(void) gelf_getehdr(tgt->dt_elf, ehdr);
+}
+
+/*
+ * Return the next target in the list, if this is an archive.
+ */
+dis_tgt_t *
+dis_tgt_next(dis_tgt_t *tgt)
+{
+	return (tgt->dt_next);
+}
+
+/*
+ * Destroy a target and free up any associated memory.
+ */
+void
+dis_tgt_destroy(dis_tgt_t *tgt)
+{
+	dis_tgt_t *current, *next;
+
+	current = tgt->dt_next;
+	while (current != NULL) {
+		next = current->dt_next;
+		if (current->dt_elf)
+			(void) elf_end(current->dt_elf);
+		if (current->dt_symtab)
+			free(current->dt_symtab);
+		free(current);
+		current = next;
+	}
+
+	if (tgt->dt_elf)
+		(void) elf_end(tgt->dt_elf);
+	if (tgt->dt_elf_root)
+		(void) elf_end(tgt->dt_elf_root);
+
+	if (tgt->dt_symtab)
+		free(tgt->dt_symtab);
+
+	free(tgt);
+}
+
+/*
+ * Given an address, returns the name of the corresponding symbol, as well as
+ * the offset within that symbol.  If no matching symbol is found, then NULL is
+ * returned.
+ *
+ * If 'cache_result' is specified, then we keep track of the resulting symbol.
+ * This cached result is consulted first on subsequent lookups in order to avoid
+ * unecessary lookups.  This flag should be used for resolving the current PC,
+ * as the majority of addresses stay within the current function.
+ */
+const char *
+dis_tgt_lookup(dis_tgt_t *tgt, uint64_t addr, off_t *offset, int cache_result,
+    size_t *size, int *isfunc)
+{
+	int lo, hi, mid;
+	sym_entry_t *sym, *osym, *match;
+	int found;
+
+	if (tgt->dt_symcache != NULL &&
+	    addr >= tgt->dt_symcache->se_sym.st_value &&
+	    addr < tgt->dt_symcache->se_sym.st_value +
+	    tgt->dt_symcache->se_sym.st_size) {
+		*offset = addr - tgt->dt_symcache->se_sym.st_value;
+		*size = tgt->dt_symcache->se_sym.st_size;
+		return (tgt->dt_symcache->se_name);
+	}
+
+	lo = 0;
+	hi = (tgt->dt_symcount - 1);
+	found = 0;
+	match = osym = NULL;
+	while (lo <= hi) {
+		mid = (lo + hi) / 2;
+
+		sym = &tgt->dt_symtab[mid];
+
+		if (addr >= sym->se_sym.st_value &&
+		    addr < sym->se_sym.st_value + sym->se_sym.st_size &&
+		    (!found || sym->se_sym.st_value > osym->se_sym.st_value)) {
+			osym = sym;
+			found = 1;
+		} else if (addr == sym->se_sym.st_value) {
+			/*
+			 * Particularly for .plt objects, it's possible to have
+			 * a zero sized object.  We want to return this, but we
+			 * want it to be a last resort.
+			 */
+			match = sym;
+		}
+
+		if (addr < sym->se_sym.st_value)
+			hi = mid - 1;
+		else
+			lo = mid + 1;
+	}
+
+	if (!found) {
+		if (match)
+			osym = match;
+		else
+			return (NULL);
+	}
+
+	/*
+	 * Walk backwards to find the best match.
+	 */
+	do {
+		sym = osym;
+
+		if (osym == tgt->dt_symtab)
+			break;
+
+		osym = osym - 1;
+	} while ((sym->se_sym.st_value == osym->se_sym.st_value) &&
+		(addr >= osym->se_sym.st_value) &&
+		(addr < osym->se_sym.st_value + osym->se_sym.st_size));
+
+	if (cache_result)
+		tgt->dt_symcache = sym;
+
+	*offset = addr - sym->se_sym.st_value;
+	*size = sym->se_sym.st_size;
+	if (isfunc)
+		*isfunc = (GELF_ST_TYPE(sym->se_sym.st_info) == STT_FUNC);
+
+	return (sym->se_name);
+}
+
+/*
+ * Given an address, return the starting offset of the next symbol in the file.
+ * Relies on the fact that this is only used when we encounter a bad instruction
+ * in the input stream, so we know that the last symbol looked up will be in the
+ * cache.
+ */
+off_t
+dis_tgt_next_symbol(dis_tgt_t *tgt, uint64_t addr)
+{
+	sym_entry_t *sym = tgt->dt_symcache;
+	uint64_t start;
+
+	/* make sure the cached symbol and address are valid */
+	if (sym == NULL || addr < sym->se_sym.st_value ||
+	    addr >= sym->se_sym.st_value + sym->se_sym.st_size)
+		return (0);
+
+	start = sym->se_sym.st_value;
+
+	/* find the next symbol */
+	while (sym != tgt->dt_symtab + tgt->dt_symcount &&
+	    sym->se_sym.st_value == start)
+		sym++;
+
+	return (sym->se_sym.st_value - addr);
+}
+
+/*
+ * Iterate over all sections in the target, executing the given callback for
+ * each.
+ */
+void
+dis_tgt_section_iter(dis_tgt_t *tgt, section_iter_f func, void *data)
+{
+	dis_scn_t sdata;
+	Elf_Scn *scn;
+	int idx;
+
+	for (scn = elf_nextscn(tgt->dt_elf, NULL), idx = 1; scn != NULL;
+	    scn = elf_nextscn(tgt->dt_elf, scn), idx++) {
+
+		if (gelf_getshdr(scn, &sdata.ds_shdr) == NULL) {
+			warn("%s: failed to get section %d header",
+			    tgt->dt_filename, idx);
+			continue;
+		}
+
+		if ((sdata.ds_name = elf_strptr(tgt->dt_elf, tgt->dt_shstrndx,
+		    sdata.ds_shdr.sh_name)) == NULL) {
+			warn("%s: failed to get section %d name",
+			    tgt->dt_filename, idx);
+			continue;
+		}
+
+		if ((sdata.ds_data = elf_getdata(scn, NULL)) == NULL) {
+			warn("%s: failed to get data for section '%s'",
+			    tgt->dt_filename, sdata.ds_name);
+			continue;
+		}
+
+		func(tgt, &sdata, data);
+	}
+}
+
+/*
+ * Return 1 if the given section contains text, 0 otherwise.
+ */
+int
+dis_section_istext(dis_scn_t *scn)
+{
+	return ((scn->ds_shdr.sh_type == SHT_PROGBITS) &&
+	    (scn->ds_shdr.sh_flags == (SHF_ALLOC | SHF_EXECINSTR)));
+}
+
+/*
+ * Return a pointer to the section data.
+ */
+void *
+dis_section_data(dis_scn_t *scn)
+{
+	return (scn->ds_data->d_buf);
+}
+
+/*
+ * Return the size of the section data.
+ */
+size_t
+dis_section_size(dis_scn_t *scn)
+{
+	return (scn->ds_data->d_size);
+}
+
+/*
+ * Return the address for the given section.
+ */
+uint64_t
+dis_section_addr(dis_scn_t *scn)
+{
+	return (scn->ds_shdr.sh_addr);
+}
+
+/*
+ * Return the name of the current section.
+ */
+const char *
+dis_section_name(dis_scn_t *scn)
+{
+	return (scn->ds_name);
+}
+
+/*
+ * Create an allocated copy of the given section
+ */
+dis_scn_t *
+dis_section_copy(dis_scn_t *scn)
+{
+	dis_scn_t *new;
+
+	new = safe_malloc(sizeof (dis_scn_t));
+	(void) memcpy(new, scn, sizeof (dis_scn_t));
+
+	return (new);
+}
+
+/*
+ * Free section memory
+ */
+void
+dis_section_free(dis_scn_t *scn)
+{
+	free(scn);
+}
+
+/*
+ * Iterate over all functions in the target, executing the given callback for
+ * each one.
+ */
+void
+dis_tgt_function_iter(dis_tgt_t *tgt, function_iter_f func, void *data)
+{
+	int i;
+	sym_entry_t *sym;
+	dis_func_t df;
+	Elf_Scn *scn;
+	GElf_Shdr	shdr;
+
+	for (i = 0, sym = tgt->dt_symtab; i < tgt->dt_symcount; i++, sym++) {
+
+		/* ignore non-functions */
+		if ((GELF_ST_TYPE(sym->se_sym.st_info) != STT_FUNC) ||
+		    sym->se_name == NULL ||
+		    sym->se_sym.st_size == 0 ||
+		    sym->se_shndx == -1)
+			continue;
+
+		/* get the ELF data associated with this function */
+		if ((scn = elf_getscn(tgt->dt_elf, sym->se_shndx)) == NULL ||
+		    gelf_getshdr(scn, &shdr) == NULL ||
+		    (df.df_data = elf_getdata(scn, NULL)) == NULL ||
+		    df.df_data->d_size == 0) {
+			warn("%s: failed to read section %d",
+			    tgt->dt_filename, sym->se_shndx);
+			continue;
+		}
+
+		/*
+		 * Verify that the address lies within the section that we think
+		 * it does.
+		 */
+		if (sym->se_sym.st_value < shdr.sh_addr ||
+		    (sym->se_sym.st_value + sym->se_sym.st_size) >
+		    (shdr.sh_addr + shdr.sh_size)) {
+			warn("%s: bad section %d for address %p",
+				tgt->dt_filename, sym->se_sym.st_shndx,
+				sym->se_sym.st_value);
+			continue;
+		}
+
+		df.df_sym = sym;
+		df.df_offset = sym->se_sym.st_value - shdr.sh_addr;
+
+		func(tgt, &df, data);
+	}
+}
+
+/*
+ * Return the data associated with a given function.
+ */
+void *
+dis_function_data(dis_func_t *func)
+{
+	return ((char *)func->df_data->d_buf + func->df_offset);
+}
+
+/*
+ * Return the size of a function.
+ */
+size_t
+dis_function_size(dis_func_t *func)
+{
+	return (func->df_sym->se_sym.st_size);
+}
+
+/*
+ * Return the address of a function.
+ */
+uint64_t
+dis_function_addr(dis_func_t *func)
+{
+	return (func->df_sym->se_sym.st_value);
+}
+
+/*
+ * Return the name of the function
+ */
+const char *
+dis_function_name(dis_func_t *func)
+{
+	return (func->df_sym->se_name);
+}
+
+/*
+ * Return a copy of a function.
+ */
+dis_func_t *
+dis_function_copy(dis_func_t *func)
+{
+	dis_func_t *new;
+
+	new = safe_malloc(sizeof (dis_func_t));
+	(void) memcpy(new, func, sizeof (dis_func_t));
+
+	return (new);
+}
+
+/*
+ * Free function memory
+ */
+void
+dis_function_free(dis_func_t *func)
+{
+	free(func);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/dis/dis_target.h	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,91 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_DIS_TARGET_H
+#define	_DIS_TARGET_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <gelf.h>
+#include <sys/types.h>
+
+/*
+ * Basic types
+ */
+typedef struct dis_tgt dis_tgt_t;
+typedef struct dis_func dis_func_t;
+typedef struct dis_scn dis_scn_t;
+
+/*
+ * Target management
+ */
+dis_tgt_t *dis_tgt_create(const char *);
+void dis_tgt_destroy(dis_tgt_t *);
+const char *dis_tgt_lookup(dis_tgt_t *, uint64_t, off_t *, int, size_t *,
+    int *);
+const char *dis_tgt_name(dis_tgt_t *);
+const char *dis_tgt_member(dis_tgt_t *);
+void dis_tgt_ehdr(dis_tgt_t *, GElf_Ehdr *);
+off_t dis_tgt_next_symbol(dis_tgt_t *, uint64_t);
+dis_tgt_t *dis_tgt_next(dis_tgt_t *);
+
+/*
+ * Section management
+ */
+typedef void (*section_iter_f)(dis_tgt_t *, dis_scn_t *, void *);
+void dis_tgt_section_iter(dis_tgt_t *, section_iter_f, void *);
+
+int dis_section_istext(dis_scn_t *);
+void *dis_section_data(dis_scn_t *);
+size_t dis_section_size(dis_scn_t *);
+uint64_t dis_section_addr(dis_scn_t *);
+const char *dis_section_name(dis_scn_t *);
+dis_scn_t *dis_section_copy(dis_scn_t *);
+void dis_section_free(dis_scn_t *);
+
+/*
+ * Function management
+ */
+typedef void (*function_iter_f)(dis_tgt_t *, dis_func_t *, void *);
+void dis_tgt_function_iter(dis_tgt_t *, function_iter_f, void *);
+dis_func_t *dis_tgt_function_lookup(dis_tgt_t *, const char *);
+
+void *dis_function_data(dis_func_t *);
+size_t dis_function_size(dis_func_t *);
+uint64_t dis_function_addr(dis_func_t *);
+const char *dis_function_name(dis_func_t *);
+dis_func_t *dis_function_copy(dis_func_t *);
+void dis_function_free(dis_func_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DIS_TARGET_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/dis/dis_util.c	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,147 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <dlfcn.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <demangle.h>
+
+#include "dis_util.h"
+
+int g_error;	/* global process exit status, set when warn() is called */
+
+/*
+ * Fatal error.  Print out the error with a leading "dis: ", and then exit the
+ * program.
+ */
+void
+die(const char *fmt, ...)
+{
+	va_list ap;
+
+	(void) fprintf(stderr, "dis: fatal: ");
+
+	va_start(ap, fmt);
+	(void) vfprintf(stderr, fmt, ap);
+	va_end(ap);
+
+	(void) fprintf(stderr, "\n");
+
+	exit(1);
+}
+
+/*
+ * Non-fatal error.  Print out the error with a leading "dis: ", set the global
+ * error flag, and return.
+ */
+void
+warn(const char *fmt, ...)
+{
+	va_list ap;
+
+	(void) fprintf(stderr, "dis: warning: ");
+
+	va_start(ap, fmt);
+	(void) vfprintf(stderr, fmt, ap);
+	va_end(ap);
+
+	(void) fprintf(stderr, "\n");
+
+	g_error = 1;
+}
+
+/*
+ * Convenience wrapper around malloc() to cleanly exit if any allocation fails.
+ */
+void *
+safe_malloc(size_t size)
+{
+	void *ret;
+
+	if ((ret = calloc(1, size)) == NULL)
+		die("Out of memory");
+
+	return (ret);
+}
+
+
+/*
+ * Generic interface to demangle C++ names.  Calls cplus_demangle to do the
+ * necessary translation.  If the translation fails, the argument is returned
+ * unchanged.  The memory returned is only valid until the next call to
+ * demangle().
+ *
+ * We dlopen() libdemangle.so rather than linking directly against it in case it
+ * is not installed on the system.
+ */
+const char *
+dis_demangle(const char *name)
+{
+	static char *demangled_name;
+	static int (*demangle_func)() = NULL;
+	static int size = BUFSIZE;
+	static int first_flag = 0;
+	int ret;
+
+	/*
+	 * If this is the first call, allocate storage
+	 * for the buffer.
+	 */
+	if (first_flag == 0) {
+		void *demangle_hand;
+
+		demangle_hand = dlopen("libdemangle.so.1", RTLD_LAZY);
+		if (demangle_hand != NULL)
+			demangle_func = (int (*)(int))dlsym(
+				demangle_hand, "cplus_demangle");
+
+		demangled_name = safe_malloc(size);
+		first_flag = 1;
+	}
+
+	/*
+	 * If libdemangle is not present, pass through unchanged.
+	 */
+	if (demangle_func == NULL)
+		return (name);
+
+	/*
+	 * The function returns -1 when the buffer size is not sufficient.
+	 */
+	while ((ret = (*demangle_func)(name, demangled_name, size)) == -1) {
+		free(demangled_name);
+		size = size + BUFSIZE;
+		demangled_name = safe_malloc(size);
+	}
+
+	if (ret != 0)
+		return (name);
+
+	return (demangled_name);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/dis/dis_util.h	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DIS_UTIL_H
+#define	_DIS_UTIL_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <sys/types.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+void die(const char *, ...);
+void warn(const char *, ...);
+
+void *safe_malloc(size_t);
+const char *dis_demangle(const char *);
+
+int g_error;
+
+#define	BUFSIZE	1024
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _DIS_UTIL_H */
--- a/usr/src/cmd/mdb/Makefile.mdb	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/mdb/Makefile.mdb	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -85,7 +84,7 @@
 $(NOT_RELEASE_BUILD)CPPFLAGS += -DDEBUG
 CPPFLAGS += -D_MDB -I. -I../.. -I../../../common
 
-LDLIBS += -ltermcap -lkvm -lproc -lrtld_db -lctf -lumem \
+LDLIBS += -ltermcap -lkvm -lproc -lrtld_db -lctf -lumem -ldisasm \
 	$(ZLAZYLOAD) -lscf $(ZNOLAZYLOAD)
 
 LINTFLAGS += -n -errtags=yes
--- a/usr/src/cmd/mdb/Makefile.module	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/mdb/Makefile.module	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -66,10 +65,6 @@
 TARGETS_kvm_mdb		= $(MODFILE)
 TARGETS_kvm_both	= $(TARGETS_kvm_mdb) $(TARGETS_kvm_kmdb)
 TARGETS_kvm		= $(TARGETS_kvm_$(TARGETS_kvm_type))
-TARGETS_disasm_kmdb	= $(KMODFILE)
-TARGETS_disasm_mdb	= $(MODFILE)
-TARGETS_disasm_both	= $(TARGETS_disasm_mdb) $(TARGETS_disasm_kmdb)
-TARGETS_disasm		= $(TARGETS_disasm_$(TARGETS_kvm_type))
 TARGETS_proc		= $(MODFILE)
 TARGETS_raw		= $(MODFILE)
 TARGETS			= $(TARGETS_$(MDBTGT))
@@ -80,10 +75,6 @@
 ROOTTGTS_kvm_mdb	= $(ROOTMOD)/$(MODULE)
 ROOTTGTS_kvm_both	= $(ROOTTGTS_kvm_mdb) $(ROOTTGTS_kvm_kmdb)
 ROOTTGTS_kvm		= $(ROOTTGTS_kvm_$(ROOTTGTS_kvm_type))
-ROOTTGTS_disasm_kmdb	= $(ROOTKMOD)/$(KMODULE)
-ROOTTGTS_disasm_mdb	= $(ROOTMOD)/$(MODULE)
-ROOTTGTS_disasm_both	= $(ROOTTGTS_disasm_mdb) $(ROOTTGTS_disasm_kmdb)
-ROOTTGTS_disasm		= $(ROOTTGTS_disasm_$(TARGETS_kvm_type))
 ROOTTGTS_proc		= $(ROOTMOD)/$(MODULE)
 ROOTTGTS_raw		= $(ROOTMOD)/$(MODULE)
 ROOTTGTS		= $(ROOTTGTS_$(MDBTGT))
@@ -96,9 +87,6 @@
 LINTFILES_kvm_both	= $(KLINTOBJS) $(LINTOBJS)
 LINTFILES_kvm_mdb	= $(LINTOBJS)
 LINTFILES_kvm		= $(LINTFILES_kvm_$(LINTFILES_kvm_type))
-LINTFILES_disasm_both	= $(KLINTOBJS) $(LINTOBJS)
-LINTFILES_disasm_mdb	= $(LINTOBJS)
-LINTFILES_disasm	= $(LINTFILES_disasm_$(TARGETS_kvm_type))
 LINTFILES_proc		= $(LINTOBJS)
 LINTFILES_raw		= $(LINTOBJS)
 LINTFILES		= $(LINTFILES_$(MDBTGT))
@@ -177,7 +165,8 @@
 LINKTESTOBJ = $(KMDBDIR)/kmdb_modlinktest.o
 
 KMDB_LINKTEST = \
-	$(LD) -zdefs -dy -r -o [email protected] $(KMODOBJS) $(LINKTESTOBJ) && \
+	$(LD) $(ZDEFS) -dy -r -o [email protected] $(KMODOBJS) \
+	$(STANDOBJS) $(LINKTESTOBJ) && \
 	$(RM) [email protected]
 
 KMDB_LINKTEST_ENABLE=$(POUND_SIGN)
@@ -189,7 +178,8 @@
 KMDB_FPTEST_CMD = $(KMDB_FPTEST)
 
 $(KMODFILE): kmod .WAIT $(KMODOBJS) $(MAPFILE)
-	$(LD) -dy -r $(MAPFILE:%=-M%) -Nmisc/kmdbmod -o $@ $(KMODOBJS)
+	$(LD) -dy -r $(MAPFILE:%=-M%) -Nmisc/kmdbmod -o $@ $(KMODOBJS) \
+	$(STANDOBJS)
 	$(KMDB_LINKTEST_CMD)
 	$(KMDB_FPTEST_CMD)
 	$(CTFMERGE) -f -L VERSION -o $@ $(KMODOBJS)
@@ -199,7 +189,7 @@
 	$(KMDB_LINKTEST)
 
 linktest_check:
-	@if [ "$(MDBTGT)" != "kvm" ] && [ "$(MDBTGT)" != "disasm" ] ; then \
+	@if [ "$(MDBTGT)" != "kvm" ] ; then \
 		echo "ERROR: linktest is not supported non-kvm/disasm dmods" \
 		    >&2 ; \
 		exit 1 ; \
--- a/usr/src/cmd/mdb/common/kmdb/kmdb_create.c	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/mdb/common/kmdb/kmdb_create.c	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -40,7 +39,4 @@
 void
 mdb_create_loadable_disasms(void)
 {
-#ifdef __sparc
-	(void) mdb_module_load("sparc", MDB_MOD_SILENT | MDB_MOD_DEFER);
-#endif
 }
--- a/usr/src/cmd/mdb/common/kmdb/kmdb_stubs.c	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/mdb/common/kmdb/kmdb_stubs.c	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -34,6 +33,7 @@
 #include <unistd.h>
 #include <libproc.h>
 #include <sys/time.h>
+#include <sys/utsname.h>
 
 #include <kmdb/kmdb_dpi.h>
 #include <kmdb/kmdb_promif.h>
@@ -180,3 +180,12 @@
 	kmdb_dpi_reboot();
 #endif
 }
+
+#if defined(__i386) && !defined(__amd64)
+/*ARGSUSED*/
+int
+_nuname(struct utsname *buf)
+{
+	return (-1);
+}
+#endif
--- a/usr/src/cmd/mdb/common/kmdb/mapfile_skel	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/mdb/common/kmdb/mapfile_skel	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
  */
 /* BEGIN PROLOGUE */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -46,6 +45,11 @@
 		/* There should be only one - ours */
 		errno;
 
+		/* <sys/utsname.h> implictly references this on x86 */
+#if defined(__i386) && !defined(__amd64)
+		_nuname;
+#endif
+
 		mdb_tgt_aread;
 		mdb_dis_create;
 		mdb_dis_destroy;
--- a/usr/src/cmd/mdb/common/mdb/mdb_disasm.c	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/mdb/common/mdb/mdb_disasm.c	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -34,6 +33,8 @@
 #include <mdb/mdb_nv.h>
 #include <mdb/mdb.h>
 
+#include <libdisasm.h>
+
 int
 mdb_dis_select(const char *name)
 {
@@ -174,6 +175,304 @@
 	return (DCMD_OK);
 }
 
+/*
+ * Generic libdisasm disassembler interfaces.
+ */
+
+#define	DISBUFSZ	64
+
+/*
+ * Internal structure used by the read and lookup routines.
+ */
+typedef struct dis_buf {
+	mdb_tgt_t	*db_tgt;
+	mdb_tgt_as_t	db_as;
+	mdb_tgt_addr_t	db_addr;
+	mdb_tgt_addr_t	db_nextaddr;
+	uchar_t		db_buf[DISBUFSZ];
+	ssize_t		db_bufsize;
+} dis_buf_t;
+
+/*
+ * Disassembler support routine for lookup up an address.  Rely on mdb's "%a"
+ * qualifier to convert the address to a symbol.
+ */
+/*ARGSUSED*/
+static int
+libdisasm_lookup(void *data, uint64_t addr, char *buf, size_t buflen,
+    uint64_t *start, size_t *len)
+{
+	if (buf != NULL) {
+		GElf_Sym sym;
+
+#ifdef __sparc
+		uint32_t instr[3];
+		uint32_t dtrace_id;
+
+		/*
+		 * On SPARC, DTrace FBT trampoline entries have a sethi/or pair
+		 * that indicates the dtrace probe id; this may appear as the
+		 * first two instructions or one instruction into the
+		 * trampoline.
+		 */
+		if (mdb_vread(instr, sizeof (instr), (uintptr_t)addr) ==
+		    sizeof (instr)) {
+			if ((instr[0] & 0xfffc0000) == 0x11000000 &&
+			    (instr[1] & 0xffffe000) == 0x90122000) {
+				dtrace_id = (instr[0] << 10) |
+				    (instr[1] & 0x1fff);
+				(void) mdb_snprintf(buf, sizeof (buf), "dt=%#x",
+				    dtrace_id);
+				goto out;
+			} else if ((instr[1] & 0xfffc0000) == 0x11000000 &&
+			    (instr[2] & 0xffffe000) == 0x90122000) {
+				dtrace_id = (instr[1] << 10) |
+				    (instr[2] & 0x1fff);
+				(void) mdb_snprintf(buf, sizeof (buf), "dt=%#x",
+				    dtrace_id);
+				goto out;
+			}
+		}
+#endif
+		if (mdb_lookup_by_addr((uintptr_t)addr, MDB_SYM_FUZZY,
+					buf, buflen, &sym) < 0) {
+			if (buflen > 0)
+				*buf = '\0';
+			return (-1);
+		}
+	}
+
+#ifdef __sparc
+out:
+#endif
+	if (start != NULL || len != NULL) {
+		GElf_Sym sym;
+		char c;
+
+		if (mdb_lookup_by_addr(addr, MDB_SYM_FUZZY, &c, 1, &sym) < 0)
+			return (-1);
+
+		if (start != NULL)
+			*start = sym.st_value;
+		if (len != NULL)
+			*len = sym.st_size;
+	}
+
+	return (0);
+}
+
+/*
+ * Disassembler support routine for reading from the target.  Rather than having
+ * to read one byte at a time, we read from the address space in chunks.  If the
+ * current address doesn't lie within our buffer range, we read in the chunk
+ * starting from the given address.
+ */
+static int
+libdisasm_read(void *data, uint64_t pc, void *buf, size_t buflen)
+{
+	dis_buf_t *db = data;
+	size_t offset;
+	size_t len;
+
+	if (pc - db->db_addr >= db->db_bufsize) {
+		if ((db->db_bufsize = mdb_tgt_aread(db->db_tgt, db->db_as,
+		    db->db_buf, sizeof (db->db_buf), pc)) == -1)
+			return (-1);
+		db->db_addr = pc;
+	}
+
+	offset = pc - db->db_addr;
+
+	len = MIN(buflen, db->db_bufsize - offset);
+
+	memcpy(buf, (char *)db->db_buf + offset, len);
+	db->db_nextaddr = pc + len;
+
+	return (len);
+}
+
+static mdb_tgt_addr_t
+libdisasm_ins2str(mdb_disasm_t *dp, mdb_tgt_t *t, mdb_tgt_as_t as,
+    char *buf, size_t len, mdb_tgt_addr_t pc)
+{
+	dis_handle_t *dhp = dp->dis_data;
+	dis_buf_t db = { 0 };
+
+	/*
+	 * Set the libdisasm data to point to our buffer.  This will be
+	 * passed as the first argument to the lookup and read functions.
+	 */
+	db.db_tgt = t;
+	db.db_as = as;
+
+	dis_set_data(dhp, &db);
+
+	/*
+	 * Attempt to disassemble the instruction
+	 */
+	if (dis_disassemble(dhp, pc, buf, len) != 0)
+		(void) mdb_snprintf(buf, len,
+		    "***ERROR--unknown op code***");
+
+	/*
+	 * Return the updated location
+	 */
+	return (db.db_nextaddr);
+}
+
+static mdb_tgt_addr_t
+libdisasm_previns(mdb_disasm_t *dp, mdb_tgt_t *t, mdb_tgt_as_t as,
+    mdb_tgt_addr_t pc, uint_t n)
+{
+	dis_handle_t *dhp = dp->dis_data;
+	dis_buf_t db = { 0 };
+
+	/*
+	 * Set the libdisasm data to point to our buffer.  This will be
+	 * passed as the first argument to the lookup and read functions.
+	 */
+	db.db_tgt = t;
+	db.db_as = as;
+
+	dis_set_data(dhp, &db);
+
+	return (dis_previnstr(dhp, pc, n));
+}
+
+/*ARGSUSED*/
+static mdb_tgt_addr_t
+libdisasm_nextins(mdb_disasm_t *dp, mdb_tgt_t *t, mdb_tgt_as_t as,
+    mdb_tgt_addr_t pc)
+{
+	mdb_tgt_addr_t npc;
+	char c;
+
+	if ((npc = libdisasm_ins2str(dp, t, as, &c, 1, pc)) == pc)
+		return (pc);
+
+	/*
+	 * Probe the address to make sure we can read something from it - we
+	 * want the address we return to actually contain something.
+	 */
+	if (mdb_tgt_aread(t, as, &c, 1, npc) != 1)
+		return (pc);
+
+	return (npc);
+}
+
+static void
+libdisasm_destroy(mdb_disasm_t *dp)
+{
+	dis_handle_t *dhp = dp->dis_data;
+
+	dis_handle_destroy(dhp);
+}
+
+static const mdb_dis_ops_t libdisasm_ops = {
+	libdisasm_destroy,
+	libdisasm_ins2str,
+	libdisasm_previns,
+	libdisasm_nextins
+};
+
+/*
+ * Generic function for creating a libdisasm-backed disassembler.  Creates an
+ * MDB disassembler with the given name backed by libdis with the given flags.
+ */
+static int
+libdisasm_create(mdb_disasm_t *dp, const char *name,
+		const char *desc, int flags)
+{
+	if ((dp->dis_data = dis_handle_create(flags, NULL, libdisasm_lookup,
+	    libdisasm_read)) == NULL)
+		return (-1);
+
+	dp->dis_name = name;
+	dp->dis_ops = &libdisasm_ops;
+	dp->dis_desc = desc;
+
+	return (0);
+}
+
+
+#if defined(__i386) || defined(__amd64)
+static int
+ia32_create(mdb_disasm_t *dp)
+{
+	return (libdisasm_create(dp,
+	    "ia32",
+	    "Intel 32-bit disassembler",
+	    DIS_X86_SIZE32));
+}
+#endif
+
+#if defined(__amd64)
+static int
+amd64_create(mdb_disasm_t *dp)
+{
+	return (libdisasm_create(dp,
+	    "amd64",
+	    "AMD64 and IA32e 64-bit disassembler",
+	    DIS_X86_SIZE64));
+}
+#endif
+
+#if defined(__sparc)
+static int
+sparc1_create(mdb_disasm_t *dp)
+{
+	return (libdisasm_create(dp,
+	    "1",
+	    "SPARC-v8 disassembler",
+	    DIS_SPARC_V8));
+}
+
+static int
+sparc2_create(mdb_disasm_t *dp)
+{
+	return (libdisasm_create(dp,
+	    "2",
+	    "SPARC-v9 disassembler",
+	    DIS_SPARC_V9));
+}
+
+static int
+sparc4_create(mdb_disasm_t *dp)
+{
+	return (libdisasm_create(dp,
+	    "4",
+	    "UltraSPARC1-v9 disassembler",
+	    DIS_SPARC_V9 | DIS_SPARC_V9_SGI));
+}
+
+static int
+sparcv8_create(mdb_disasm_t *dp)
+{
+	return (libdisasm_create(dp,
+	    "v8",
+	    "SPARC-v8 disassembler",
+	    DIS_SPARC_V8));
+}
+
+static int
+sparcv9_create(mdb_disasm_t *dp)
+{
+	return (libdisasm_create(dp,
+	    "v9",
+	    "SPARC-v9 disassembler",
+	    DIS_SPARC_V9));
+}
+
+static int
+sparcv9plus_create(mdb_disasm_t *dp)
+{
+	return (libdisasm_create(dp,
+	    "v9plus",
+	    "UltraSPARC1-v9 disassembler",
+	    DIS_SPARC_V9 | DIS_SPARC_V9_SGI));
+}
+#endif
+
 /*ARGSUSED*/
 static void
 defdis_destroy(mdb_disasm_t *dp)
@@ -223,12 +522,19 @@
 }
 
 mdb_dis_ctor_f *const mdb_dis_builtins[] = {
+	defdis_create,
 #if defined(__amd64)
 	ia32_create,
 	amd64_create,
 #elif defined(__i386)
 	ia32_create,
+#elif defined(__sparc)
+	sparc1_create,
+	sparc2_create,
+	sparc4_create,
+	sparcv8_create,
+	sparcv9_create,
+	sparcv9plus_create,
 #endif
-	defdis_create,
 	NULL
 };
--- a/usr/src/cmd/mdb/common/mdb/mdb_disasm_impl.h	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/mdb/common/mdb/mdb_disasm_impl.h	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -63,24 +62,6 @@
 	void *dis_data;			/* Private storage */
 };
 
-#ifdef _MDB
-
-#if defined(__sparc)
-extern mdb_dis_ctor_f sparc1_create;
-extern mdb_dis_ctor_f sparc2_create;
-extern mdb_dis_ctor_f sparc4_create;
-extern mdb_dis_ctor_f sparcv8_create;
-extern mdb_dis_ctor_f sparcv9_create;
-extern mdb_dis_ctor_f sparcv9plus_create;
-#else /* __i386 */
-extern mdb_dis_ctor_f ia32_create;
-#if defined(__amd64)
-extern mdb_dis_ctor_f amd64_create;
-#endif /* __amd64 */
-#endif	/* __sparc */
-
-#endif	/* _MDB */
-
 #ifdef	__cplusplus
 }
 #endif
--- a/usr/src/cmd/mdb/common/mdb/mdb_modapi.h	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/mdb/common/mdb/mdb_modapi.h	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -288,6 +287,7 @@
 extern void *mdb_callback_add(int, mdb_callback_f, void *);
 extern void mdb_callback_remove(void *);
 
+extern size_t strlcat(char *, const char *, size_t);
 extern char *strcat(char *, const char *);
 extern char *strcpy(char *, const char *);
 extern char *strncpy(char *, const char *, size_t);
--- a/usr/src/cmd/mdb/intel/Makefile.kmdb	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/mdb/intel/Makefile.kmdb	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,10 +19,10 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-# ident	"%Z%%M%	%I%	%E% SMI"
+#ident	"%Z%%M%	%I%	%E% SMI"
 #
 
 PROMSRCS += \
@@ -34,9 +33,6 @@
 	prom_putchar.c
 
 KMDBSRCS += \
-	bits.c \
-	dis_tables.c \
-	inteldis.c \
 	kaif.c \
 	kaif_activate.c \
 	kaif_idt.c \
@@ -60,7 +56,6 @@
 CTXOFFUSERS = \
 	kmdb_setcontext.o
 
-OSINCDIRS += $(SRC)/common/dis/i386
 CPPFLAGS += -DDIS_TEXT
 
 $(CTXOFFUSERS) $(CTXOFFUSERS:%.o=%.ln): kmdb_context_off.h
@@ -86,16 +81,9 @@
 	../../kmdb/kmdb_dpi_isadep.h \
 	$(MAPFILE_SOURCES_$(MACH))
 
-%.o: $(SRC)/common/dis/i386/%.c
-	$(COMPILE.c) $<
-	$(CTFCONVERT_O)
-
 %.o: ../../../../../uts/intel/promif/%.c
 	$(COMPILE.c) $<
 	$(CTFCONVERT_O)
 
-%.ln: $(SRC)/common/dis/i386/%.c
-	$(LINT.c) -c $<
-
 %.ln: ../../../../../uts/intel/promif/%.c
 	$(LINT.c) -c $<
--- a/usr/src/cmd/mdb/intel/amd64/kmdb/Makefile	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/mdb/intel/amd64/kmdb/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
@@ -63,6 +62,8 @@
 include ../../Makefile.amd64
 include ../../../Makefile.kmdb
 
+STANDLIBS += $(ROOT)/usr/lib/amd64/libstanddisasm.so
+
 INCDIRS += $(SRC)/uts/i86pc $(SRC)/common/dis/i386
 
 CPPFLAGS += -DDIS_TEXT
--- a/usr/src/cmd/mdb/intel/amd64/mdb/Makefile	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/mdb/intel/amd64/mdb/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,16 +19,12 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
 
-SRCS =	\
-	bits.c \
-	dis_tables.c \
-	inteldis.c \
-	kvm_amd64dep.c \
+SRCS =	kvm_amd64dep.c \
 	mdb_amd64util.c \
 	proc_amd64dep.c
 
@@ -41,24 +36,17 @@
 	$(COMPILE.c) $<
 	$(CTFCONVERT_O)
 
-%.o: $(SRC)/common/dis/i386/%.c
-	$(COMPILE.c) $<
-	$(CTFCONVERT_O)
-
 %.ln: %.c
 	$(LINT.c) -c $<
 
 %.ln: ../../mdb/%.c
 	$(LINT.c) -c $<
 
-%.ln: $(SRC)/common/dis/i386/%.c
-	$(LINT.c) -c $<
-
 include ../../../../Makefile.cmd
 include ../../../../Makefile.cmd.64
 include ../../Makefile.amd64
 include ../../../Makefile.mdb
 
-CPPFLAGS += -I../../mdb -I$(SRC)/common/dis/i386 -DDIS_TEXT
+CPPFLAGS += -I../../mdb
 
 install: all $(ISAEXEC) $(ROOTPROG64) $(ROOTLINK64)
--- a/usr/src/cmd/mdb/intel/ia32/Makefile	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/mdb/intel/ia32/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
--- a/usr/src/cmd/mdb/intel/ia32/kmdb/Makefile	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/mdb/intel/ia32/kmdb/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
@@ -54,6 +53,8 @@
 include ../../Makefile.ia32
 include ../../../Makefile.kmdb
 
+STANDLIBS += $(ROOT)/usr/lib/libstanddisasm.so
+
 INCDIRS += $(SRC)/uts/i86pc
 
 CPPFLAGS += -DDIS_TEXT
--- a/usr/src/cmd/mdb/intel/ia32/mdb/Makefile	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/mdb/intel/ia32/mdb/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,15 +19,12 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
 
-SRCS =	bits.c \
-	dis_tables.c \
-	inteldis.c \
-	kvm_ia32dep.c \
+SRCS =	kvm_ia32dep.c \
 	mdb_ia32util.c \
 	proc_ia32dep.c
 
@@ -36,21 +32,14 @@
 	$(COMPILE.c) $<
 	$(CTFCONVERT_O)
 
-%.o: $(SRC)/common/dis/i386/%.c
-	$(COMPILE.c) $<
-	$(CTFCONVERT_O)
-
 %.ln: ../../mdb/%.c
 	$(LINT.c) -c $<
 
-%.ln: $(SRC)/common/dis/i386/%.c
-	$(LINT.c) -c $<
-
 include ../../../../Makefile.cmd
 include ../../Makefile.ia32
 include ../../../Makefile.mdb
 
-CPPFLAGS += -I../../mdb -I$(SRC)/common/dis/i386 -DDIS_TEXT
+CPPFLAGS += -I../../mdb
 
 install: all $(ISAEXEC) $(ROOTPROG32) $(ROOTLINK32)
 	-$(RM) $(ROOTPROG)
--- a/usr/src/cmd/mdb/intel/mdb/bits.c	Fri Mar 03 20:08:16 2006 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 1988 AT&T
- * All rights reserved.
- *
- */
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-#include	"dis.h"
-
-/*
- * Minimum instruction name field width
- */
-#define	INST_MINWIDTH	7
-
-/* For communication to locsympr */
-const char *const *regname;
-static char mneu[256];  /* array to store disassembly for return */
-static uchar_t curbyte;	/* result of getbyte() */
-
-static	mdb_tgt_t 	*dis_target;
-static	mdb_tgt_as_t	dis_as;
-static	mdb_tgt_addr_t	dis_offset;
-static	ssize_t		dis_size;
-static	uchar_t		dis_buffer[64];
-
-static	mdb_tgt_addr_t	curloc;
-
-
-/*
- * Get next byte from the instruction stream,
- * set curbyte and increment curloc.
- */
-/*ARGSUSED*/
-static int
-getbyte(void *notused)
-{
-	ulong_t index = (ulong_t)(curloc - dis_offset);
-
-	if (index >= dis_size) {
-		dis_size = mdb_tgt_aread(dis_target, dis_as, dis_buffer,
-			sizeof (dis_buffer), curloc);
-
-		if (dis_size <= 0) {
-			dis_offset = 0;
-			dis_size = 0;
-			curbyte = 0;
-			return (-1);
-		}
-
-		dis_offset = curloc;
-		index = 0;
-	}
-
-	curbyte = dis_buffer[index];
-	curloc++;
-	return (curbyte);
-}
-
-static int
-symlookup(uint64_t addr, char *buf, size_t len)
-{
-	(void) mdb_iob_snprintf(buf, len, "%a", (uintptr_t)addr);
-	if (strncmp(buf, "0x", 2) == 0) {
-		if (len > 0)
-			*buf = '\0';
-		return (-1);
-	}
-	return (0);
-}
-
-/*
- * disassemble an instruction. Mode can be DIS_IA32 or DIS_AMD64.
- */
-/*ARGSUSED*/
-static void
-disasm(int mode)
-{
-	dis86_t		x86dis;
-	uint_t		cpu_mode = SIZE32;
-
-#ifdef __amd64
-	if (mode == DIS_AMD64)
-		cpu_mode = SIZE64;
-#endif
-
-	bzero(&x86dis, sizeof (dis86_t));
-	x86dis.d86_check_func = NULL;
-	x86dis.d86_get_byte = getbyte;
-	x86dis.d86_sprintf_func =
-	    (int (*)(char *, size_t, const char *, ...))mdb_iob_snprintf;
-	x86dis.d86_sym_lookup = symlookup;
-
-	if (dtrace_disx86(&x86dis, cpu_mode) != 0) {
-		(void) strcpy(mneu, "***ERROR--unknown op code***");
-		return;
-	}
-
-	dtrace_disx86_str(&x86dis, cpu_mode, curloc, mneu, sizeof (mneu));
-}
-
-/*ARGSUSED*/
-mdb_tgt_addr_t
-ia32dis_ins2str(mdb_disasm_t *dp, mdb_tgt_t *t, mdb_tgt_as_t as,
-    char *buf, size_t len, mdb_tgt_addr_t pc)
-{
-	char *cp;
-
-	dis_target = t;		/* target pointer */
-	dis_as = as;		/* address space identifier */
-	dis_offset = pc;	/* address of current instruction */
-	dis_size = 1;		/* size of current instruction */
-
-	if (mdb_tgt_aread(t, as, &dis_buffer[0], sizeof (char), pc) == -1) {
-		warn("failed to read instruction at %llr", pc);
-		return (pc);
-	}
-
-	/*
-	 * Disassemble one instruction starting at curloc,
-	 * increment curloc to the following location,
-	 * and leave the ascii result in mneu[]. dp->dis_data
-	 * holds the disassembly mode; DIS_AMD64 or DIS_IA32.
-	 */
-	curloc = pc;
-	disasm((uintptr_t)dp->dis_data);
-
-	cp = mneu + strlen(mneu);
-	while (cp-- > mneu && *cp == ' ')
-		*cp = '\0';
-	(void) mdb_snprintf(buf, len, "%s", mneu);
-	return (curloc);
-}
--- a/usr/src/cmd/mdb/intel/mdb/dis.h	Fri Mar 03 20:08:16 2006 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*	Copyright (c) 1988 AT&T	*/
-/*	  All Rights Reserved  	*/
-
-
-#ifndef _DIS_H
-#define	_DIS_H
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <string.h>
-#include <dis_tables.h>
-
-#include <mdb/mdb_disasm_impl.h>
-#include <mdb/mdb_err.h>
-#include <mdb/mdb_io.h>
-#include <mdb/mdb.h>
-
-#define	NHEX	40	/* max # chars in object per line	*/
-#define	NLINE	1024	/* max # chars in mnemonic per line	*/
-#define	TRUE	1
-#define	FALSE	0
-#define	LEAD	1
-#define	NOLEAD	0
-#define	NOLEADSHORT 2
-
-#define	DIS_IA32	0
-#define	DIS_AMD64	1
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _DIS_H */
--- a/usr/src/cmd/mdb/intel/mdb/inteldis.c	Fri Mar 03 20:08:16 2006 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-#include "dis.h"
-
-extern mdb_tgt_addr_t ia32dis_ins2str(mdb_disasm_t *, mdb_tgt_t *,
-    mdb_tgt_as_t, char *, size_t, mdb_tgt_addr_t);
-
-/*ARGSUSED*/
-static void
-ia32dis_destroy(mdb_disasm_t *dp)
-{
-	/* Nothing to do here */
-}
-
-static mdb_tgt_addr_t
-ia32dis_previns(mdb_disasm_t *dp, mdb_tgt_t *t, mdb_tgt_as_t as,
-    mdb_tgt_addr_t pc, uint_t n)
-{
-	mdb_tgt_addr_t *hist, addr, naddr;
-	mdb_tgt_addr_t res = pc;
-	GElf_Sym sym;
-	int cur, nseen;
-	char c;
-
-	if (mdb_lookup_by_addr(pc, MDB_SYM_FUZZY, &c, 1, &sym) < 0 ||
-	    sym.st_value == pc)
-		return (pc); /* we need to be in the middle of a symbol */
-
-	hist = mdb_zalloc(sizeof (mdb_tgt_addr_t) * n, UM_SLEEP);
-
-	for (cur = 0, nseen = 0, addr = sym.st_value; addr < pc; addr = naddr) {
-		hist[cur] = addr;
-		cur = (cur + 1) % n;
-		nseen++;
-
-		if (mdb_tgt_aread(t, as, &c, 1, addr) != 1 ||
-		    (naddr = ia32dis_ins2str(dp, t, as, &c, 1, addr)) == addr)
-			goto done; /* no progress or can't read - give up */
-	}
-
-	if (addr != pc) {
-		/*
-		 * We scanned past %pc, but didn't find an instruction that
-		 * started at %pc.  This means that either the caller specified
-		 * an invalid address, or we ran into something other than code
-		 * during our scan.  Virtually any combination of bytes can be
-		 * construed as a valid Intel instruction, so any non-code bytes
-		 * we encounter will have thrown off the scan.
-		 */
-		goto done;
-	}
-
-	res = hist[(cur + n - MIN(n, nseen)) % n];
-
-done:
-	mdb_free(hist, sizeof (mdb_tgt_addr_t) * n);
-	return (res);
-}
-
-/*ARGSUSED*/
-static mdb_tgt_addr_t
-ia32dis_nextins(mdb_disasm_t *dp, mdb_tgt_t *t, mdb_tgt_as_t as,
-    mdb_tgt_addr_t pc)
-{
-	mdb_tgt_addr_t npc;
-	char c;
-
-	if ((npc = ia32dis_ins2str(dp, t, as, &c, 1, pc)) == pc)
-		return (pc);
-
-	/*
-	 * Probe the address to make sure we can read something from it - we
-	 * want the address we return to actually contain something.
-	 */
-	if (mdb_tgt_aread(t, as, &c, 1, npc) != 1)
-		return (pc);
-
-	return (npc);
-}
-
-static const mdb_dis_ops_t ia32dis_ops = {
-	ia32dis_destroy,
-	ia32dis_ins2str,
-	ia32dis_previns,
-	ia32dis_nextins
-};
-
-int
-ia32_create(mdb_disasm_t *dp)
-{
-	dp->dis_name = "ia32";
-	dp->dis_desc = "Intel 32-bit disassembler";
-	dp->dis_ops = &ia32dis_ops;
-	dp->dis_data = (void *)DIS_IA32;
-
-	return (0);
-}
-
-int
-amd64_create(mdb_disasm_t *dp)
-{
-	dp->dis_name = "amd64";
-	dp->dis_desc = "AMD64 and IA32e 64-bit disassembler";
-	dp->dis_ops = &ia32dis_ops;
-	dp->dis_data = (void *)DIS_AMD64;
-
-	return (0);
-}
--- a/usr/src/cmd/mdb/sparc/v7/Makefile	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/mdb/sparc/v7/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
@@ -31,8 +30,6 @@
 	$(COMMON_MODULES_PROC) \
 	$(COMMON_MODULES_PROC_32BIT)
 
-$(CLOSED_BUILD)MODULES += $(CLOSED)/cmd/mdb/sparc/v7/sparcdis
-
 SUBDIRS = mdb $(MODULES)
 
 include ../../Makefile.subdirs
--- a/usr/src/cmd/mdb/sparc/v9/Makefile	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/mdb/sparc/v9/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
@@ -37,8 +36,7 @@
 $(CLOSED_BUILD)MODULES += \
 	$(CLOSED_COMMON_MODULES_KVM:%=$(CLOSED)/cmd/mdb/sparc/v9/%)
 $(CLOSED_BUILD)MODULES += \
-	$(CLOSED)/cmd/mdb/sparc/v9/isp \
-	$(CLOSED)/cmd/mdb/sparc/v9/sparcdis
+	$(CLOSED)/cmd/mdb/sparc/v9/isp
 
 #
 # a "$(MODULES): kmdb" rule would seem to do the trick but, for some reason,
--- a/usr/src/cmd/mdb/sparc/v9/kmdb/Makefile	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/mdb/sparc/v9/kmdb/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
@@ -32,6 +31,8 @@
 include ../../Makefile.kmdb.64
 include ../../../Makefile.kmdb
 
+STANDLIBS += $(ROOT)/usr/lib/sparcv9/libstanddisasm.so
+
 all:	kmdb_modlinktest.o
 lint:	FRC
 
--- a/usr/src/cmd/mdb/sun4u/v9/kmdb/Makefile	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/mdb/sun4u/v9/kmdb/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
@@ -49,6 +48,8 @@
 include ../../../sparc/Makefile.kmdb.64
 include ../../../Makefile.kmdb
 
+STANDLIBS += $(ROOT)/usr/lib/sparcv9/libstanddisasm.so
+
 KMDB_FPTEST = \
 	$(FINDFP) -x kaif_resume -x kaif_trap_common $@
 
--- a/usr/src/cmd/mdb/sun4v/v9/kmdb/Makefile	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/mdb/sun4v/v9/kmdb/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
@@ -49,6 +48,8 @@
 include ../../../sparc/Makefile.kmdb.64
 include ../../../Makefile.kmdb
 
+STANDLIBS += $(ROOT)/usr/lib/sparcv9/libstanddisasm.so
+
 KMDB_FPTEST = \
 	$(FINDFP) -x kaif_resume -x kaif_trap_common $@
 
--- a/usr/src/cmd/sgs/Makefile	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/sgs/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -75,8 +74,6 @@
 		unifdef		\
 		yacc
 
-$(CLOSED_BUILD)SUBDIRS-common += $(CLOSED)/cmd/sgs/dis
-
 SUBDIRS-i386=
 SUBDIRS-sparc=	rtld.4.x
 
--- a/usr/src/cmd/sgs/sgsdemangler/Makefile.com	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/sgs/sgsdemangler/Makefile.com	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,10 +19,10 @@
 # CDDL HEADER END
 #
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+#ident	"%Z%%M%	%I%	%E% SMI"
 #
 
 LIBRARY =	libdemangle.a
@@ -35,9 +34,9 @@
 CFLAGS64 +=	$(C_PICFLAGS64)
 
 
-CLEANFILES +=	y.tab.c y.tab.h llib-ldemangle.ln lint.out
+CLEANFILES +=	llib-ldemangle.ln lint.out
 
-OBJECTS=	cafe_dem.o	dem.o		demangle.o
+OBJECTS=	demangle.o
 
 CFLAGS +=	-erroff=E_STATEMENT_NOT_REACHED
 CFLAGS64 +=	-erroff=E_STATEMENT_NOT_REACHED
--- a/usr/src/cmd/sgs/sgsdemangler/Makefile.targ	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/sgs/sgsdemangler/Makefile.targ	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,18 +19,11 @@
 # CDDL HEADER END
 #
 #
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
 #ident	"%Z%%M%	%I%	%E% SMI"
 #
-# Copyright (c) 1998,2001 by Sun Microsystems, Inc.
-# All rights reserved.
-
-objs/cafe_dem.o: \
-		../common/cafe_dem.y ../common/cafe_dem.h ../common/dem.h
-		yacc ../common/cafe_dem.y
-		$(COMPILE.c) -I../common -c y.tab.c -o $@
-
-objs/dem.o:	../common/dem.c
-		$(COMPILE.c) -I../common -c ../common/dem.c -o $@
 
 objs/demangle.o: \
 		../common/demangle.c
--- a/usr/src/cmd/sgs/sgsdemangler/common/cafe_dem.h	Fri Mar 03 20:08:16 2006 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- *	Copyright 1993 by Sun Microsystems, Inc.
- *	All Rights Reserved.
- */
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-/***************************************************************** 
-
-  Copyright  1993 Sun Microsystems 
-  All Rights Reserved.
-
-  %W% %G% %U%
-
-  Revisions
-     06/10/93 - Raymond Lai  Created
-
-******************************************************************/
-
-#ifndef _CAFE_DEM_H
-#define _CAFE_DEM_H
-
-#include "dem.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Note: NDEM_type starts with 1000 so that dbx can tell a NDEM_name
-   structure from a DEM (cfront) one.
-*/
-
-enum NDEM_type {
-	NDEM_other = 1000,	/* default */
-	NDEM_constructor, NDEM_destructor, NDEM_operator, NDEM_conversion,
-	NDEM_unnamed_arg, NDEM_static_constructor, NDEM_static_destructor
-};
-
-typedef struct NDEM_modifier {
-	char			 is_signed : 1;
-	char			 is_volatile : 1;
-	char			 is_unsigned : 1;
-	char			 is_const : 1;
-	char			 is_static : 1;
-} NDEM_modifier;
-
-struct NDEM_class;
-struct NDEM_arg;
-
-/* A cafe name.  This can be either a (static) data member, a function member,
-   or a global function.
-*/
-
-typedef struct NDEM_name {
-	enum NDEM_type		 type;
-	struct NDEM_class	*qual_class;
-	char 			*raw_name;
-	struct NDEM_arg		*conv_t;	/* for conversion function */
-	struct NDEM_arg		*f_args;	/* for function */
-	struct NDEM_modifier	 f_modifier;	/* for member function */
-} NDEM_name;
-
-/* A class. */
-
-typedef struct NDEM_class {
-	struct NDEM_class	*qual_class;
-	char			*raw_class_name;
-	struct NDEM_arg		*t_args;	/* for template class */
-} NDEM_class;
-
-/* A function pointer (as an argument). */
-
-typedef struct NDEM_fptr {
-	struct NDEM_class	*qual_class;
-	struct NDEM_arg		*f_args;
-	struct NDEM_arg		*return_t;
-	struct NDEM_arg		*decls;		/* function declarator list */
-} NDEM_fptr;
-
-/* A member data pointer (as an argument). */
-
-typedef struct NDEM_mdptr {
-	struct NDEM_class	*qual_class;
-	struct NDEM_arg		*mem_data_t;
-} NDEM_mdptr;
-
-/* An abbreviation record (for arguments like "NDC", "TB"). */
-
-typedef struct NDEM_abbrev_rec {
-	int			 repetition_number;
-	int			 param_number;
-} NDEM_abbrev_rec;
-
-/* A pointer, reference, or array introduces a type of its own... */
-
-enum NDEM_decl_type {
-	NDEM_pointer = 1, NDEM_reference, NDEM_array
-};
-
-typedef struct NDEM_declarator {
-	enum NDEM_decl_type	 decl_type;
-	struct NDEM_arg		*real_arg;
-	char			*array_size;	/* if an array */
-} NDEM_declarator;
-
-enum NDEM_arg_type {
-	NDEM_basic_type, NDEM_user_defined_type, NDEM_function_ptr, NDEM_decl,
-	NDEM_mem_data_ptr,
-	NDEM_abbrev_N, NDEM_abbrev_T,
-	NDEM_i_const, /* template integral constant argument */
-	NDEM_p_const  /* template pointer constant argument */
-};
-
-/* A type. */
-
-typedef struct NDEM_arg {
-	enum NDEM_arg_type		 arg_type;
-	union {
-		char			 basic_t;
-		struct NDEM_class	*user_defined_t;
-		struct NDEM_fptr	*function_ptr;
-		struct NDEM_mdptr	*mem_data_ptr;
-		struct NDEM_abbrev_rec	 abbrev_rec;
-		struct NDEM_declarator	 decl;
-		char			*pt_constant;
-		struct NDEM_name	*temp_p_arg;
-	} arg_data;
-	struct NDEM_modifier		 modifier;
-	struct NDEM_arg			*next;
-} NDEM_arg;
-
-#ifdef DBX_SUPPORT
-
-extern int		cafe_dem		(char *, NDEM_name *, char *);
-extern enum DEM_TYPE	cafe_getfieldtype	(NDEM_name *);
-extern char		*cafe_getclass		(NDEM_name *, char *);
-extern char		*cafe_getname		(NDEM_name *, char *);
-extern char		**cafe_getparentclass	(NDEM_name *, char **);
-extern char		*cafe_gettemplatename	(NDEM_name *);
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
--- a/usr/src/cmd/sgs/sgsdemangler/common/cafe_dem.y	Fri Mar 03 20:08:16 2006 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1615 +0,0 @@
-%{
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *	Copyright 1993-2000 by Sun Microsystems, Inc.
- *	All Rights Reserved
- */
-/***************************************************************** 
-
-  %W% %G% %U%
-
-  Revisions
-     06/10/93 - Raymond Lai  Created
-
-******************************************************************/
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include "cafe_dem.h"
-
-#define		 DEM_VERSION	0
-#define		 CHECK_OLD_PREFIX(s) (s[0] == '$')
-#define		 CHECK_PREFIX(s) (s[0] == '_' && s[1] == '_' && \
-				isdigit(s[2]) && DEM_VERSION >= s[2] - '0')
-
-static char	 ll_cur_char;
-static int	 ll_id_size = 0;	/* the default token is of size 1 */
-static char	*yytext;
-
-#define		 BUFSIZE	8192
-static char	 name_buffer[BUFSIZE];
-static char	*mem_reservoir;
-
-#define 	 ALIGN_MASK	03
-
-static void *allocate(size_t size)
-{
-	char *pos;
-
-	while ((unsigned long)mem_reservoir & ALIGN_MASK)
-		++mem_reservoir;
-	pos = mem_reservoir;
-	mem_reservoir += size;
-	return pos;
-}
-
-/* Will only be called by print_template_args() and print_function_args()
-   to deallocate the excess memory allocated for argument array.
-*/
-
-static void deallocate(size_t size)
-{
-	mem_reservoir -= size;
-}
-
-static char *convert_number(int n)
-{
-	int i, len = 0;
-	static char tmp[1024];
-	char *s;
-
-	if (n == 0) return NULL;
-
-	do {
-		tmp[len++] = n % 10 + '0';
-	} while ((n /= 10) > 0);
-
-	s = allocate(len+1);
-	i = 0;
-	while (--len >= 0)
-		s[i++] = tmp[len];
-	s[i] = '\0';
-
-	return s;
-}
-
-static NDEM_name *result;
-static NDEM_arg *conv_type;
-static NDEM_modifier save_modifier, current_modifier = { 0, 0, 0, 0, 0 };
-
-static void reset_current_modifier()
-{
-	current_modifier.is_signed = current_modifier.is_volatile =
-	current_modifier.is_unsigned = current_modifier.is_const =
-	current_modifier.is_static = 0;
-}
-
-enum Boolean { TRUE = 1, FALSE = 0 };
-
-/* Don't build function argument structures when yyparse() is called by
-   cafe_dem()...
-*/
-static enum Boolean from_cafe_dem = FALSE;
-static enum Boolean build_args = TRUE;
-
-/* Function arguments of embedded functions still need to be handled.  For
-   example:
-
-   $fDfoo7$FBfPvi44D_Dbarv == foo<&f(void*, int), 3>::bar( <IGNORE> )
-          ^^^^^^^                 ^^^^^^^^^^^^^^
-
-   The following stack is used for this purpose.  When the parser is called
-   by cafe_dem() to parse a function, it first pushes a TRUE onto the stack.
-   All subsequent values pushed into the stack are FALSE.
-
-   Note the stack doesn't need to be large.
-*/
-static enum Boolean stack[10];
-static int sk_top = 0;
-
-#define push(f) stack[sk_top++] = f
-#define pop() stack[--sk_top]
-
-/*________________________________________________________________________*/
-
-%}
-
-%union {
-	int		 i_val;
-	char		 c_val;
-	char		*s_val;
-	NDEM_name	*n_val;
-	NDEM_class	*class_val;
-	NDEM_arg	*arg_val;
-	NDEM_fptr	*fptr_val;
-}
-
-%token IDENTIFIER NUMBER
-
-%type <i_val> big_number uname_size
-
-%type <s_val> uname_spec uname_specN op_name optimize_number
-
-%type <n_val> function_name global_data_name
-
-/* namespace_spec is used solely for qualifying class(es) for now... */
-%type <class_val> class_spec class_specN namespace_spec
-
-%type <arg_val> template_spec template_arg_spec t_arg_spec arg_spec
-		arg_type formal_arg_spec arg_abbrev type_declarator
-		modifier_n_declarator
-
-%type <fptr_val> function_arg_spec
-
-%% 
-
-
-mangled_name :
-	function_name
-	    {	 result = $1; }
-|	global_data_name
-	    {	 result = $1; }
-|	internal_name
-|	external_linkage_name
-|	error
-	    {	 return 1;   }
-;
-
-PREFIX :
-	'_' '_' VERSION
-	    {	if (DEM_VERSION < ll_cur_char - '0') YYERROR;   }
-|	'$'
-;
-
-VERSION :
-	'0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'
-;
-
-UPPER_LETTER :
-	'A'|'B'|'C'|'D'|'E'|'F'|'G'|'H'|'I'|'J'|'K'|'L'|'M'|'N'|'O'|
-	'P'|'Q'|'R'|'S'|'T'|'U'|'V'|'W'|'X'|'Y'|'Z'
-;
-
-LOWER_LETTER :
-	'a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'i'|'j'|'k'|'l'|'m'|'n'|'o'|
-	'p'|'q'|'r'|'s'|'t'|'u'|'v'|'w'|'x'|'y'|'z'
-;
-
-/* Upper case letter represent the numbers 0 thru 25.  Lower case are the 
-*  numbers  26 thru 51.  A prefix of '0' adds 52 to the value. e.g.:
-*
-*      C = 2
-*      c = 28
-*      y = 50
-*     0y = 102
-*
-*
-* The key features are that:
-*      -numbers less than or equal to 51 are only one character
-*      -the end of a big_number can be found when embedded in a
-*       string: e.g.
-*
-*		 Dfoo = big_number 3, string "foo"
-*		 OCB  = big_number 54, string "B"
-*/
-
-big_number :  
-	UPPER_LETTER 
-	    {	$$ = ll_cur_char - 'A';   }
-|	LOWER_LETTER 
-	    {	$$ = ll_cur_char - 'a' + 26;   }
-|	'0' big_number 
-	    {	$$ = 52 + $2;   }
-;
-
-/*"identifier" is defined the the ANSI committee */
-
-uname : 
-	IDENTIFIER      
-;
-				       
-
-uname_spec : 
-	uname_size
-	    {	ll_id_size = $1;   }
-	uname
-	    {
-		if (build_args)
-		{
-		    $$ = allocate($1+1);
-		    (void) strncpy($$, yytext, $1);
-		    *($$+$1) = '\0';
-		}
-		else
-		    $$ = NULL;
-	    }
-;
-
-uname_size : 
-	big_number
-;
-
-class_specN : 
-	namespace_spec class_spec
-	    {
-		if (build_args)
-		{
-		    $2->qual_class = $1;
-		    $$ = $2;
-		}
-		else
-		    $$ = NULL;
-	    }
-;
-
-class_spec : 
-	fun_local_spec uname_spec template_spec
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_class));
-		    $$->raw_class_name = $2;
-		    $$->t_args = $3;
-		}
-		else
-		    $$ = NULL;
-	    }
-;
-
-uname_specN : 
-	namespace_spec uname_spec
-	    {
-		$$ = $2;
-	    }
-;
-
-namespace_spec : 
-	/* nil */
-	    {	$$ = NULL;   }
-|	namespace_spec '1' uname_spec
-|	namespace_spec '5' class_specN
-	    {
-		if (build_args)
-		{
-		    $3->qual_class = $1;
-		    $$ = $3;
-		}
-		else
-		    $$ = NULL;
-	    }
-;
-
-template_spec :
-	/* nil */
-	    {	$$ = NULL;   }
-|	'7' template_arg_spec '_'
-	    {	$$ = $2;   }
-;
-
-template_arg_spec :
-	t_arg_spec
-|	template_arg_spec t_arg_spec
-	    {
-		if (build_args)
-		{
-		    NDEM_arg *tmp = $1;
-		    while (tmp->next) tmp = tmp->next;
-		    tmp->next = $2;
-		}
-		$$ = $1;
-	    }
-;
-
-t_arg_spec :
-	arg_spec
-|	'4' optimize_number
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_i_const;
-		    $$->arg_data.pt_constant = $2;
-		}
-		else
-		    $$ = NULL;
-	    }
-|	'4' optimize_number 'n'
-	    {
-		if (build_args)
-		{
-		    char *s = allocate(strlen($2)+2);
-		    s[0] = '-';
-		    (void) strcpy(s+1, $2);
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_i_const;
-		    $$->arg_data.pt_constant = s;
-		}
-		else
-		    $$ = NULL;
-	    }
-|	'4' function_name '_'
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_p_const;
-		    $$->arg_data.temp_p_arg = $2;
-		}
-		else
-		    $$ = NULL;
-	    }
-|	'4' global_data_name '_'
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_p_const;
-		    $$->arg_data.temp_p_arg = $2;
-		}
-		else
-		    $$ = NULL;
-	    }
-;
-
-optimize_number :
-	big_number
-	    {
-		if (build_args)
-		    $$ = convert_number($1);
-		else
-		    $$ = NULL;
-	    }
-|	'8' big_number
-	    {	ll_id_size = $2;   }
-	uname
-	    {
-		if (build_args)
-		{
-		    $$ = allocate($2+1);
-		    (void) strncpy($$, yytext, $2);
-		    *($$+$2) = '\0';
-		}
-		else
-		    $$ = NULL;
-	    }
-;
-
-/*
-* ".F" signifies a standard function
-* ".f" is a member function
-* ".O" is a global operator function
-* ".o" is a member operator function
-*/
-
-function_name : 
-	PREFIX 'F'
-	    {
-		push(from_cafe_dem);
-		from_cafe_dem = FALSE;
-	    }
-	uname_specN
-	    {
-		if (pop())
-		    build_args = FALSE;
-	    }
-	formal_arg_spec 
-	    {
-		$$ = allocate(sizeof(NDEM_name));
-		if ($4[0] == 'O')
-		    $$->type = NDEM_conversion;
-		else
-		    $$->type = NDEM_other;
-		$$->raw_name = $4;
-		$$->f_args = $6;
-	    }
-|	PREFIX 'C'
-	    {
-		push(from_cafe_dem);
-		from_cafe_dem = FALSE;
-	    }
-	uname_specN
-	    {
-		if (pop())
-		    build_args = FALSE;
-	    }
-	formal_arg_spec 
-	    {
-		$$ = allocate(sizeof(NDEM_name));
-		$$->type = NDEM_static_constructor;
-		$$->raw_name = "__STATIC_CONSTRUCTOR";
-		$$->f_args = $6;
-	    }
-|	PREFIX 'D'
-	    {
-		push(from_cafe_dem);
-		from_cafe_dem = FALSE;
-	    }
-	uname_specN
-	    {
-		if (pop())
-		    build_args = FALSE;
-	    }
-	formal_arg_spec 
-	    {
-		$$ = allocate(sizeof(NDEM_name));
-		$$->type = NDEM_static_destructor;
-		$$->raw_name = "__STATIC_DESTRUCTOR";
-		$$->f_args = $6;
-	    }
-|	PREFIX 'f'
-	    {
-		push(from_cafe_dem);
-		from_cafe_dem = FALSE;
-	    }
-	class_specN uname_spec
-	    {
-		if (pop())
-		    build_args = FALSE;
-	    }
-	formal_arg_spec f_modifier
-	    {
-		$$ = allocate(sizeof(NDEM_name));
-		$$->type = NDEM_other;
-		$$->qual_class = $4;
-		$$->raw_name = $5;
-		$$->f_args = $7;
-		$$->f_modifier = current_modifier;
-		reset_current_modifier();
-	    }
-|	PREFIX 'O'
-	    {
-		push(from_cafe_dem);
-		from_cafe_dem = FALSE;
-	    }
-	op_name namespace_spec
-	    {
-		if (pop())
-		    build_args = FALSE;
-	    }
-	formal_arg_spec 
-	    {
-		$$ = allocate(sizeof(NDEM_name));
-		if ($4[0] == 'O')
-		{
-		    $$->type = NDEM_conversion;
-		    $$->conv_t = conv_type;
-		}
-		else if ($4[0] == 'C')
-		    $$->type = NDEM_constructor;
-		else if ($4[0] == 'D')
-		    $$->type = NDEM_destructor;
-		else
-		    $$->type = NDEM_operator;
-		$$->raw_name = $4;
-		$$->f_args = $7;
-	    }
-|	PREFIX 'o'
-	    {
-		push(from_cafe_dem);
-		from_cafe_dem = FALSE;
-	    }
-	class_specN op_name
-	    {
-		if (pop())
-		    build_args = FALSE;
-	    }
-	formal_arg_spec f_modifier
-	    {
-		$$ = allocate(sizeof(NDEM_name));
-		if ($5[0] == 'O')
-		{
-		    $$->type = NDEM_conversion;
-		    $$->conv_t = conv_type;
-		}
-		else if ($5[0] == 'C')
-		    $$->type = NDEM_constructor;
-		else if ($5[0] == 'D')
-		    $$->type = NDEM_destructor;
-		else
-		    $$->type = NDEM_operator;
-		$$->qual_class = $4;
-		$$->raw_name = $5;
-		$$->f_args = $7;
-		$$->f_modifier = current_modifier;
-		reset_current_modifier();
-	    }
-;
-
-f_modifier:
-	/* nil */
-|	'K'
-	    { current_modifier.is_const = 1; }
-|	'W'
-	    { current_modifier.is_volatile = 1; }
-|	'T'
-	    { current_modifier.is_static = 1; }
-;
-
-/* Note: "adv" and "add" have been changed to "gav" and "gad" to avoid
-*  grammar conflicts.
-*
-* See p. 125 of the ARM.  Note that operator T() is now "op" class_specN.
-*/
-
-op_name : 
-	'm' 'l'
-	    { $$ = "*"; }
-|	'm' 'd'
-	    { $$ = "%"; }
-|	'm' 'i'
-	    { $$ = "-"; }
-|	'r' 's'
-	    { $$ = ">>"; }
-|	'n' 'e'
-	    { $$ = "!="; }
-|	'g' 't'
-	    { $$ = ">"; }
-|	'g' 'e'
-	    { $$ = ">="; }
-|	'o' 'r'
-	    { $$ = "|"; }
-|	'a' 'a'
-	    { $$ = "&&"; }
-|	'n' 't'
-	    { $$ = "!"; }
-|       'p' 'p'
-	    { $$ = "++"; }
-|	'a' 's'
-	    { $$ = "="; }
-|	'a' 'p' 'l'
-	    { $$ = "+="; }
-|	'a' 'm' 'u'
-	    { $$ = "*="; }
-|	'a' 'm' 'd'
-	    { $$ = "%="; }
-|	'a' 'r' 's'
-	    { $$ = ">>="; }
-|	'a' 'o' 'r'
-	    { $$ = "|="; }
-|	'c' 'm'
-	    { $$ = ","; }
-|	'd' 'v'
-	    { $$ = "/"; }
-|       'p' 'l'
-	    { $$ = "+"; }
-|	'l' 's'
-	    { $$ = "<<"; }
-|	'e' 'q'
-	    { $$ = "=="; }
-|	'l' 't'
-	    { $$ = "<"; }
-|	'l' 'e'
-	    { $$ = "<="; }
-|	'a' 'd'
-	    { $$ = "&"; }
-|	'e' 'r'
-	    { $$ = "^"; }
-|	'o' 'o'
-	    { $$ = "||"; }
-|	'c' 'o'
-	    { $$ = "~"; }
-|	'm' 'm'
-	    { $$ = "--"; }
-|       'r' 'f'
-	    { $$ = "->"; }
-|	'a' 'm' 'i'
-	    { $$ = "-="; }
-|	'g' 'd' 'v'
-/*	'a' 'd' 'v'	*/
-	    { $$ = "/="; }
-|	'a' 'l' 's'
-	    { $$ = "<<="; }
-|	'g' 'a' 'd'
-/*	'a' 'a' 'd'	*/
-	    { $$ = "&="; }
-|	'a' 'e' 'r'
-	    { $$ = "^="; }
-|	'r' 'm'
-	    { $$ = "->*"; }
-|	'c' 'l'
-	    { $$ = "()"; }
-|	'v' 'c'
-	    { $$ = "[]"; }
-|       'c' 't'
-	    { $$ = "C"; }
-|	'd' 't'
-	    { $$ = "D"; }
-|	'n' 'w'
-	    { $$ = "new"; }
-|	'd' 'l'
-	    { $$ = "delete"; }
-|	'o' 'p' arg_spec
-	    {
-		conv_type = $3;
-		$$ = "O";
-	    }
-;
-
-/* "$N" is for global data (they are mangled when their addresses are
-	passed as template arguments).
-*  "$d" is for static data members
-*/
-
-global_data_name : 
-	PREFIX 'N' namespace_spec uname_spec
-	    {
-		$$ = allocate(sizeof(NDEM_name));
-		$$->type = NDEM_other;
-		$$->raw_name = $4;
-	    }
-|	PREFIX 'd' class_specN uname_spec
-	    {
-		$$ = allocate(sizeof(NDEM_name));
-		$$->type = NDEM_other;
-		$$->qual_class = $3;
-		$$->raw_name = $4;
-	    }
-;
-
-/*
-*  "$P" is for compiler private data and must be file local or block local.
-*  "$X" is for extensions and can be global.  The big_number should be used
-*     to serialize the extensions since collisions between different compilers
-*     can occur. (Note that "P" is file local and doesn't have this problem.)
-*  "$V" is for virtual tables.  It is to be global.
-*/ 
-
-internal_name : 
- 	 PREFIX 'P' private_id 
-|	 PREFIX 'X' big_number private_id 
-| 	 PREFIX 'V' class_specN
-;
-
-private_id : 
-	/* FIXUP: This is implementation specific */
-;
-
-external_linkage_name : 
-	/* defined by other languages ABI */
-;
-
-/* This is used to add info for function local classes.  The big_number is a
-*  compiler dependent scope identifier and can be omitted if not needed.
-*/
-
-/* Note that function local classes only need to be mangled when the linker
-*  will see them, such as when a member function will be instantiated.
-*/
-
-fun_local_spec : 
- 	/* nil */ 
-|	'2' fun_local_scope
-; 
-
-fun_local_scope :
-	big_number
-|	'8' big_number
-	    {   ll_id_size = $2;   }
-	uname
-;
-
-arg_spec : 
-	modifier_n_declarator arg_type
-	    {
-		if (build_args)
-		{
-		    $2->modifier = current_modifier;
-		    reset_current_modifier();
-		    if ($1) {
-		        if ($2->arg_type == NDEM_function_ptr) {
-			    $2->arg_data.function_ptr->decls = $1;
-			    $$ = $2;
-		        }
-		        else {
-			    NDEM_arg *tmp = $1;
-			    while (tmp->arg_data.decl.real_arg)
-			        tmp = tmp->arg_data.decl.real_arg;
-			    tmp->arg_data.decl.real_arg = $2;
-			    $$ = $1;
-		        }
-		    }
-		    else
-		        $$ = $2;
-		}
-		else
-		    $$ = NULL;
-	    }
-|	arg_abbrev
-;
-
-function_arg_spec :
-	'F' formal_arg_spec '_' arg_spec
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_fptr));
-		    $$->f_args = $2;
-		    $$->return_t = $4;
-		}
-		else
-		    $$ = NULL;
-	    }
-|	'M' class_specN 'F' formal_arg_spec f_modifier
-	    {
-		if (build_args)
-		{
-		    save_modifier = current_modifier;
-		    reset_current_modifier();
-		}
-	    }
-	'_' arg_spec
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_fptr));
-		    $$->qual_class = $2;
-		    $$->f_args = $4;
-		    $$->return_t = $8;
-		    current_modifier = save_modifier;
-		}
-		else
-		    $$ = NULL;
-	    }
-;
-
-formal_arg_spec :
-	formal_arg_spec arg_spec
-	    {
-		if (build_args)
-		{
-		    NDEM_arg *tmp = $1;
-		    while (tmp->next) tmp = tmp->next;
-		    tmp->next = $2;
-		    $$ = $1;
-		}
-		else
-		    $$ = NULL;
-	    }
-|	arg_spec
-;
-
-modifier_n_declarator :
-	/* nil */
-	    {	 $$ = NULL;   }
-|	modifier_n_declarator modifier
-|	modifier_n_declarator type_declarator
-	    {
-		if (build_args)
-		{
-		    if ($1) {
-		        NDEM_arg *tmp = $1;
-		        while (tmp->arg_data.decl.real_arg)
-			    tmp = tmp->arg_data.decl.real_arg;
-		        tmp->arg_data.decl.real_arg = $2;
-		        $$ = $1;
-		    }
-		    else
-		        $$ = $2;
-		}
-		else
-		    $$ = NULL;
-	    }
-;
-
-modifier : 
-	'C'
-	    {
-		if (build_args)
-		    current_modifier.is_const = 1;
-	    }
-|	'S'
-	    {
-		if (build_args)
-		    current_modifier.is_signed = 1;
-	    }
-|	'U'
-	    {
-		if (build_args)
-		    current_modifier.is_unsigned = 1;
-	    }
-|	'V'
-	    {
-		if (build_args)
-		    current_modifier.is_volatile = 1;
-	    }
-;
-
-type_declarator : 
-	'P' 
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_decl;
-		    $$->arg_data.decl.decl_type = NDEM_pointer;
-		    $$->modifier = current_modifier;
-		    reset_current_modifier();
-		}
-		else
-		    $$ = NULL;
-	    }
-|	'R' 
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_decl;
-		    $$->arg_data.decl.decl_type = NDEM_reference;
-		    $$->modifier = current_modifier;
-		    reset_current_modifier();
-		}
-		else
-		    $$ = NULL;
-	    }
-|	'A' big_number 
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_decl;
-		    $$->arg_data.decl.decl_type = NDEM_array;
-		    $$->arg_data.decl.array_size = convert_number($2);
-		    $$->modifier = current_modifier;
-		    reset_current_modifier();
-		}
-		else
-		    $$ = NULL;
-	    }
-|	'A' '8' big_number
-	    {	ll_id_size = $3;   }
-	uname
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_decl;
-		    $$->arg_data.decl.decl_type = NDEM_array;
-		    $$->arg_data.decl.array_size = allocate($3+1);
-		    (void) strncpy($$->arg_data.decl.array_size, yytext, $3);
-		    *($$->arg_data.decl.array_size+$3) = '\0';
-		    $$->modifier = current_modifier;
-		    reset_current_modifier();
-		}
-		else
-		    $$ = NULL;
-	    }
-;
-
-arg_type : 
-	'v' 
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_basic_type;
-		    $$->arg_data.basic_t = 'v';
-		}
-		else
-		    $$ = NULL;
-	    }
-|	'c' 
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_basic_type;
-		    $$->arg_data.basic_t = 'c';
-		}
-		else
-		    $$ = NULL;
-	    }
-|	's' 
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_basic_type;
-		    $$->arg_data.basic_t = 's';
-		}
-		else
-		    $$ = NULL;
-	    }
-|	'i' 
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_basic_type;
-		    $$->arg_data.basic_t = 'i';
-		}
-		else
-		    $$ = NULL;
-	    }
-|	'l' 
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_basic_type;
-		    $$->arg_data.basic_t = 'l';
-		}
-		else
-		    $$ = NULL;
-	    }
-|	'f' 
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_basic_type;
-		    $$->arg_data.basic_t = 'f';
-		}
-		else
-		    $$ = NULL;
-	    }
-|	'd' 
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_basic_type;
-		    $$->arg_data.basic_t = 'd';
-		}
-		else
-		    $$ = NULL;
-	    }
-|	'D' 
-/*	'r'	*/
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_basic_type;
-		    $$->arg_data.basic_t = 'D';
-		}
-		else
-		    $$ = NULL;
-	    }
-|	'L'
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_basic_type;
-		    $$->arg_data.basic_t = 'L';
-		}
-		else
-		    $$ = NULL;
-	    }
-| 	'e' 
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_basic_type;
-		    $$->arg_data.basic_t = 'e';
-		}
-		else
-		    $$ = NULL;
-	    }
-| 	'G' 
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_basic_type;
-		    $$->arg_data.basic_t = 'G';
-		}
-		else
-		    $$ = NULL;
-	    }
-| 	'w' 
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_basic_type;
-		    $$->arg_data.basic_t = 'w';
-		}
-		else
-		    $$ = NULL;
-	    }
-|	'6' class_specN
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_user_defined_type;
-		    $$->arg_data.user_defined_t = $2;
-		}
-		else
-		    $$ = NULL;
-	    }
-|	function_arg_spec
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_function_ptr;
-		    $$->arg_data.function_ptr = $1;
-		}
-		else
-		    $$ = NULL;
-	    }
-|	'M' class_specN 'D' arg_spec
-	    {
-		if (build_args)
-		{
-		    NDEM_mdptr *t = allocate(sizeof(NDEM_mdptr));
-		    t->qual_class = $2;
-		    t->mem_data_t = $4;
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_mem_data_ptr;
-		    $$->arg_data.mem_data_ptr = t;
-		}
-		else
-		    $$ = NULL;
-	    }
-;
-
-arg_abbrev : 
-	'N' big_number big_number 
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_abbrev_N;
-		    $$->arg_data.abbrev_rec.repetition_number = $2;
-		    $$->arg_data.abbrev_rec.param_number = $3;
-		}
-		else
-		    $$ = NULL;
-	    }
-|	'T' big_number   
-	    {
-		if (build_args)
-		{
-		    $$ = allocate(sizeof(NDEM_arg));
-		    $$->arg_type = NDEM_abbrev_T;
-		    $$->arg_data.abbrev_rec.param_number = $2;
-		}
-		else
-		    $$ = NULL;
-	    }
-;
-
-
-/* EXAMPLES:
-
-    ***  THIS SECTION NEEDS TO BE UPDATED !! ***
-
-  C++ constuct               New                  Cfront
-  ------------              -----                --------
-
-   P(int);                  .FAPi                 P__fi
-
-   class a
-   {
-      Q (double);           .fAaAQd               Q__1aFd
-      class b
-      {
-         R(...);            .f5AaAbARe            R__Q21a|bFe
-      }
-      S(a);                 .fAaAS5Aa             S__1aFa 
-   }
-
-   namespace n
-   {
-      T(void);              .F1AnATv
-      class c
-      {
-         U(void);           .f1AnAcAUv
-         namespace m
-         {
-            W(void)         .F1An5Ac1AmAWv
-         }
-      }
-      namespace p
-      {
-         X(void);           .F1An1ApAXv
-      }
-   }            
-
-
- NOTES
-           
-The dot (.), can be replaced by any character that is not valid in the 
-first position of the linker symbols of languages that C++ will be
-linked with.
-
-
-Numeric switches:
-
-
-     Number           Rule              Preceeds
--------------------------------------------------------          
-       0         big_number          more numbers
-       1         namespace_spec      a namespace
-       2         fun_local_spec      a class local to a function 
-       3         template_spec       a template spec
-       4         fun_local_spec      a scope id
-       5         namespace_spec      a class
-       6         arg_spec            a class object as an argument
-
-Type Letters
-
-  
-     Letter           Rule              Type
--------------------------------------------------------
-      .F         function_name       function
-      .f         function_name       member function
-      .s         function_name       static member function
-      .O         function_name       operator
-      .o         function_name       operator member
-      .D         global_data_name    global data
-      .d         global_data_name    static member data
-      .P         internal_name       name, private to compiler
-      .X         internal_name       a compiler extension 
-      .V         internal_name       virtual table
-
-Naming convention frequently, but not always, followed:
-
-     (anything)_size        a big_number giving size of the next item
-
-     (anything)_spec        an item, including its size, e.g.: class_spec
-
-     (anything)_specN       same as (anything)_spec but with optional 
-                            name space
-
-*/    
-
-%%
-
-static char *out_buffer;
-static int obx = 0;		/* out_buffer index */
-
-static void put_characters(char *s, size_t len)
-{
-    size_t i;
-    for (i = 0;  i < len; ++i)
-	out_buffer[obx++] = s[i];
-}
-
-#define put_string(s)						\
-{								\
-    put_characters(s, strlen(s));				\
-}
-
-static void print_simple_type(char t)
-{
-    switch(t) {
-
-	case 'v':
-	    put_characters("void", 4);
-	    break;
-
-	case 'c':
-	    put_characters("char", 4);
-	    break;
-
-	case 's':
-	    put_characters("short", 5);
-	    break;
-
-	case 'i':
-	    put_characters("int", 3);
-	    break;
-
-	case 'l':
-	    put_characters("long", 4);
-	    break;
-
-	case 'f':
-	    put_characters("float", 5);
-	    break;
-
-	case 'd':
-	    put_characters("double", 6);
-	    break;
-
-	case 'D':
-	    put_characters("long double", 11);
-	    break;
-
-	case 'L':
-	    put_characters("long long", 9);
-	    break;
-
-	case 'e':
-	    put_characters("...", 3);
-	    break;
-
-	case 'w':
-	    put_characters("wchar_t", 7);
-	    break;
-
-	case 'G':
-	    put_characters("T", 1);
-	    break;
-    }
-}
-
-static void print_class(NDEM_class *, int);
-static void print_function_args(NDEM_arg *);
-static void print_name(NDEM_name *);
-
-static void print_modifier(NDEM_modifier mod)
-{
-    if (mod.is_const) put_characters("const ", 6);
-    if (mod.is_signed) put_characters("signed ", 7);
-    if (mod.is_unsigned) put_characters("unsigned ", 9);
-    if (mod.is_volatile) put_characters("volatile ", 9);
-}
-
-/* print modifier(s) of pointers */
-static void print_p_modifier(NDEM_modifier mod)
-{
-    if (mod.is_const) put_characters(" const", 6);
-    if (mod.is_volatile) put_characters(" volatile", 9);
-}
-
-static void print_arg(NDEM_arg *arg)
-{
-    if (! arg) return;
-
-    switch(arg->arg_type) {
-
-        case NDEM_basic_type:
-	    print_modifier(arg->modifier);
-	    print_simple_type(arg->arg_data.basic_t);
-	    break;
-
-	case NDEM_user_defined_type:
-	    print_modifier(arg->modifier);
-	    print_class(arg->arg_data.user_defined_t, 1);
-	    break;
-
-	case NDEM_function_ptr:
-	    print_arg(arg->arg_data.function_ptr->return_t);
-	    put_characters(" (", 2);
-	    if (arg->arg_data.function_ptr->qual_class)
-	    {
-		print_class(arg->arg_data.function_ptr->qual_class, 1);
-		put_characters("::", 2);
-	    }
-	    print_arg(arg->arg_data.function_ptr->decls);
-	    put_characters(")", 1);
-	    print_function_args(arg->arg_data.function_ptr->f_args);
-	    print_p_modifier(arg->modifier);
-	    break;
-
-	case NDEM_mem_data_ptr:
-	    print_arg(arg->arg_data.mem_data_ptr->mem_data_t);
-	    put_characters(" ", 1);
-	    print_class(arg->arg_data.mem_data_ptr->qual_class, 1);
-	    put_characters("::", 2);
-	    break;
-
-	case NDEM_decl:
-	    /* The last node in function pointer declarator list is NULL.
-	    */
-	    if (arg->arg_data.decl.real_arg)
-	    	print_arg(arg->arg_data.decl.real_arg);
-	    switch(arg->arg_data.decl.decl_type) {
-
-		case NDEM_pointer:
-		    put_characters("*", 1);
-		    break;
-
-		case NDEM_reference:
-		    put_characters("&", 1);
-		    break;
-
-		case NDEM_array:
-		    put_characters("[", 1);
-		    if (arg->arg_data.decl.array_size)
-			put_string(arg->arg_data.decl.array_size)
-		    put_characters("]", 1);
-		    break;
-	    }
-	    print_p_modifier(arg->modifier);
-	    break;
-
-	case NDEM_i_const:
-	    if (arg->arg_data.pt_constant)
-		put_string(arg->arg_data.pt_constant)
-	    else
-		put_characters("0", 1);
-	    break;
-
-	case NDEM_p_const:
-	    put_characters("&", 1);
-	    print_name(arg->arg_data.temp_p_arg);
-	    break;
-
-	case NDEM_abbrev_N:
-	case NDEM_abbrev_T:
-	   /* should never come to here! */
-	default:
-	    break;
-    }
-}
-
-static void flat_args(NDEM_arg *in, NDEM_arg **arg_arr, int *n_ptr)
-{
-    int i, n = 0;
-
-    while (in)
-    {
-	if (in->arg_type == NDEM_abbrev_T || in->arg_type == NDEM_abbrev_N)
-	{
-	    /* first align with arg_arr index... */
-	    in->arg_data.abbrev_rec.param_number -= 1;
-
-	    if (in->arg_data.abbrev_rec.param_number >= n)
-	    {
-		/* something's wrong.  skip the argument */
-		in = in->next;
-		break;
-	    }
-	    if (in->arg_type == NDEM_abbrev_T)
-		arg_arr[n++] = arg_arr[in->arg_data.abbrev_rec.param_number];
-	    else
-		for (i = 0;  i < in->arg_data.abbrev_rec.repetition_number;  i++)
-		    arg_arr[n++] = arg_arr[in->arg_data.abbrev_rec.param_number];
-	}
-	else
-	    arg_arr[n++] = in;
-	in = in->next;
-    }
-    *n_ptr = n;
-}
-
-#define MAX_ARG 300
-static const int arg_array_size = sizeof(NDEM_arg *) * MAX_ARG;
-
-static void print_template_args(NDEM_arg *arg)
-{
-    NDEM_arg **new_arg_list;
-    int no_of_args, i;
-
-    if (! arg)
-    {
-	put_characters("<?>", 3);
-	return;
-    }
-
-    put_characters("<", 1);
-    new_arg_list = allocate(arg_array_size);
-    flat_args(arg, new_arg_list, &no_of_args);
-
-    /* deallocate the excess memory...
-    */
-    deallocate(arg_array_size - sizeof(NDEM_arg *) * no_of_args);
-
-    for(i = 0;  i < no_of_args;  ++i)
-    {
-	print_arg(new_arg_list[i]);
-	if (i < no_of_args - 1)
-	    put_characters(", ", 2);
-    }
-    put_characters(">", 1);
-}
-
-static void print_function_args(NDEM_arg *arg)
-{
-    NDEM_arg **new_arg_list;
-    int no_of_args, i;
-
-    if (! arg)
-    {
-		put_characters("(?)", 3);
-		return;
-    }
-
-    put_characters("(", 1);
-    new_arg_list = allocate(arg_array_size);
-    flat_args(arg, new_arg_list, &no_of_args);
-
-    /* deallocate the excess memory...
-    */
-    deallocate(arg_array_size - sizeof(NDEM_arg *) * no_of_args);
-
-    for(i = 0;  i < no_of_args;  ++i)
-    {
-	print_arg(new_arg_list[i]);
-	if (i < no_of_args - 1)
-	    put_characters(", ", 2);
-    }
-    put_characters(")", 1);
-}
-
-static void print_class(NDEM_class *cl, int full_qual_name)
-{
-    if (! cl) return;
-    if (cl->qual_class && full_qual_name)
-    {
-	print_class(cl->qual_class, full_qual_name);
-	put_characters("::", 2);
-    }
-    put_string(cl->raw_class_name)
-    if (cl->t_args)
-	print_template_args(cl->t_args);
-}
-
-static void print_name(NDEM_name *name)
-{
-    if (! name) return;
-
-    switch (name->type) {
-
-	case NDEM_constructor:
-	    print_class(name->qual_class, 1);
-	    put_characters("::", 2);
-	    print_class(name->qual_class, 0);
-	    print_function_args(name->f_args);
-	    print_p_modifier(name->f_modifier);
-	    break;
-
-	case NDEM_destructor:
-	    print_class(name->qual_class, 1);
-	    put_characters("::~", 3);
-	    print_class(name->qual_class, 0);
-	    print_function_args(name->f_args);
-	    print_p_modifier(name->f_modifier);
-	    break;
-
-	case NDEM_operator:
-	case NDEM_conversion:
-	    if (name->qual_class)
-	    {
-		if (name->f_modifier.is_static)
-		    put_characters("static ", 7);
-		print_class(name->qual_class, 1);
-		put_characters("::", 2);
-	    }
-	    put_characters("operator ", 9);
-	    if (name->type != NDEM_conversion)
-		put_string(name->raw_name)
-	    else
-		print_arg(name->conv_t);
-	    print_function_args(name->f_args);
-	    if (name->qual_class)
-		print_p_modifier(name->f_modifier);
-	    break;
-
-	case NDEM_static_constructor:
-	case NDEM_static_destructor:
-	case NDEM_other:
-	    if (name->qual_class)
-	    {
-		if (name->f_modifier.is_static)
-		    put_characters("static ", 7);
-		print_class(name->qual_class, 1);
-		put_characters("::", 2);
-	    }
-	    put_string(name->raw_name)
-	    if (name->f_args)
-	    {
-		print_function_args(name->f_args);
-		if (name->qual_class)
-		    print_p_modifier(name->f_modifier);
-	    }
-	    break;
-
-	case NDEM_unnamed_arg:
-	default:
-	    break;
-    }
-}
-
-static void print_global_name(NDEM_name *name)
-{
-    print_name(name);
-    put_characters("\0", 1);	/* insert the ending '\0' */
-}
-
-static char *in_buffer;
-static int ibx;			/* in_buffer index */
-static size_t in_len = 0;	/* symbol length */
-
-static void startup(char *in, char *mem, size_t mem_size)
-{
-    if (in) {
-	in_buffer = in;
-	ibx = ll_id_size = sk_top = 0;
-	in_len = strlen(in);
-    }
-    mem_reservoir = mem;
-    (void) memset(mem_reservoir, 0, mem_size);
-}
-
-int yylex(void)
-{
-
-    if (ibx + (ll_id_size? ll_id_size - 1 : 0) >= in_len)
-	return 0;
-
-    if (! ll_id_size)
-	return (ll_cur_char = in_buffer[ibx++]);
-    else
-    {
-	yytext = in_buffer + ibx;
-	ibx += ll_id_size;
-	ll_id_size = 0;
-	return IDENTIFIER;
-    }
-}
-
-
-int demangle(char *in, char *out)
-{
-    if (in == NULL || !*in || out == NULL) return -1;
-
-    if (CHECK_PREFIX(in))
-    {
-	startup(in, name_buffer, BUFSIZE);
-	if (yyparse() == 0)
-	{
-	    out_buffer = out;
-	    obx = 0;	/* reset out_buffer index */
-	    print_global_name(result);
-	    return 0;
-	}
-	else
-	{
-	    /* definitely not a cfront name! */
-	    (void) strcpy(out, in);
-	    return -1;
-	}
-    }
-
-    /* Not a cafe symbol, try cfront demangler... */
-    return cfront_demangle(in, out);
-}
-
-static void yyerror(char *msg)
-{
-	(void) msg;
-}
-
-
-/* The code below is provided for tools nm, prof, and gprof.
-*/
-
-char *cafe_demangle(char *in, char *out)
-{
-    if (in == NULL || !*in || out == NULL) return in;
-
-    if (CHECK_PREFIX(in))
-    {
-	startup(in, name_buffer, BUFSIZE);
-	if (yyparse() == 0)
-	{
-	    out_buffer = out;
-	    obx = 0;
-	    print_global_name(result);
-	    return out;
-	}
-    }
-
-    /* not a cafe symbol... */
-    return in;
-}
--- a/usr/src/cmd/sgs/sgsdemangler/common/dem.c	Fri Mar 03 20:08:16 2006 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1670 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-/*******************************************************************************
- 
-C++ source for the C++ Language System, Release 3.0.  This product
-is a new release of the original cfront developed in the computer
-science research center of AT&T Bell Laboratories.
-
-Copyright (c) 1991 AT&T and UNIX System Laboratories, Inc.
-Copyright (c) 1984, 1989, 1990 AT&T.  All Rights Reserved.
-
-*******************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include "cafe_dem.h"
-
-/************************* CUSTOMIZATION SECTION *************************/
-
-#ifndef ELF_OBJ
-static int clip_under = 1;			/* ignore first "_" on names */
-#else
-static int clip_under = 0;
-#endif
-
-#define SP_ALIGN 0x4			/* alignment of dynamic space blocks */
-
-/*#define DEM_MAIN*/			/* set if want standalone program */
-
-/************************************************************************/
-
-#define MAXLINE 2048			/* general buffer use */
-
-#define MAXARG 400			/* max arguments in a function */
-
-#define STRCMP(s, t) ((s)[0] != (t)[0] || strcmp((s), (t)) != 0)
-
-static char* spbase;
-static char cc;
-static char* base;
-static int baselen;
-#define gc() {cc = baselen >= 1 ? *base++ : 0, baselen--;}
-
-static int waserror = 0;
-
-#define MAXSTACK 200
-static char* stackp[MAXSTACK];
-static int stackl[MAXSTACK];
-static char stackc[MAXSTACK];
-static int sp = -1;
-
-#define ERROR() {waserror = 1; return NULL;}
-
-/************************* UTILITIES *************************/
-
-/* fatal errors */
-static void fatal(char* msg, char* arg1, char* arg2)
-{
-	char buf[MAXLINE];
-
-	(void) sprintf(buf, msg, arg1, arg2);
-	(void) fprintf(stderr, "demangle fatal error: %s\n", buf);
-
-	exit(1);
-}
-
-/* get space */
-static char* gs(size_t s)
-{
-	char* p;
-
-	if (s < 1)
-		fatal("bad argument to gs()", (char*)0, (char*)0);
-
-	/* align space on SP_ALIGN boundary */
-
-	while ((unsigned long)spbase & (SP_ALIGN - 1))
-		spbase++;
-
-	p = spbase;
-	spbase += s;
-
-	return p;
-}
-
-/* copy a string */
-static char* copy(char* s)
-{
-	char* p;
-
-	if (s == NULL || !*s)
-		fatal("bad argument to copy()", (char*)0, (char*)0);
-
-	p = gs(strlen(s) + 1);
-	(void) strcpy(p, s);
-	return p;
-}
-
-/************************* DEMANGLE UTILITIES *************************/
-
-/* push a string to scan */
-static void push(char* s, int n)
-{
-	if (s == NULL || !*s || n < 1)
-		fatal("bad argument to push()", (char*)0, (char*)0);
-	if (sp + 1 >= MAXSTACK)
-		fatal("overflow of stack in push()", (char*)0, (char*)0);
-
-	sp++;
-	stackp[sp] = base;
-	stackl[sp] = baselen;
-	stackc[sp] = cc;
-	base = s;
-	baselen = n;
-	gc();
-}
-
-static void pop()
-{
-	if (sp < 0)
-		fatal("bad argument to pop()", (char*)0, (char*)0);
-
-	base = stackp[sp];
-	baselen = stackl[sp];
-	cc = stackc[sp];
-	sp--;
-}
-
-/************************* DEMANGLER *************************/
-
-/* get a class name */
-static DEMARG* getarglist();
-static DEMCL* getclass()
-{
-	int n;
-	char nbuf[MAXLINE];
-	int i;
-	int j;
-	int iter;
-	DEMCL* p;
-	DEMCL* clhead;
-	DEMCL* curr;
-	DEMARG* ap;
-
-	iter = 1;
-	clhead = NULL;
-	curr = NULL;
-
-	/* fix for ambiguity in encoding */
-
-	i = 0;
-	if (isdigit(base[0])) {
-		i = 1;
-		if (isdigit(base[1]))
-			i = 2;
-	}
-	if (isdigit(cc) && base[i] == 'Q' && isdigit(base[i + 1]) &&
-	    base[i + 2] == '_') {
-		gc();
-		if (i)
-			gc();
-		if (i == 2)
-			gc();
-	}
-
-	/* might be nested class */
-
-	if (cc == 'Q') {
-		gc();
-		if (!isdigit(cc))
-			ERROR();
-		iter = cc - '0';
-		if (iter < 1)
-			ERROR();
-		gc();
-		if (cc != '_')
-			ERROR();
-		gc();
-	}
-
-	/* grab number of classes expected */
-
-	while (iter-- > 0) {
-
-		/* get a class */
-
-		if (!isdigit(cc))
-			ERROR();
-		n = cc - '0';
-		gc();
-		if (isdigit(cc)) {
-			n = n * 10 + cc - '0';
-			gc();
-		}
-		if (isdigit(cc)) {
-			n = n * 10 + cc - '0';
-			gc();
-		}
-		if (n < 1)
-			ERROR();
-		for (i = 0; i < n; i++) {
-			if (!isalnum(cc) && cc != '_')
-				ERROR();
-			nbuf[i] = cc;
-			gc();
-		}
-		nbuf[i] = 0;
-		p = (DEMCL*)gs(sizeof(DEMCL));
-		p->rname = copy(nbuf);
-		p->clargs = NULL;
-
-		/* might be a template class */
-
-		for (j = 0; j < i; j++) {
-			if (nbuf[j] == '_' && nbuf[j + 1] == '_' &&
-			    nbuf[j + 2] == 'p' && nbuf[j + 3] == 't')
-				break;
-		}
-		if (j == 0)
-			ERROR();
-		if (j == i) {
-			p->name = copy(nbuf);
-		}
-		else {
-			if (nbuf[j + 4] != '_' || nbuf[j + 5] != '_')
-				ERROR();
-			nbuf[j] = 0;
-			p->name = copy(nbuf);
-			j += 6;
-			if (!isdigit(nbuf[j]))
-				ERROR();
-			n = nbuf[j] - '0';
-			j++;
-			if (isdigit(nbuf[j])) {
-				n = n * 10 + nbuf[j] - '0';
-				j++;
-			}
-			if (isdigit(nbuf[j])) {
-				n = n * 10 + nbuf[j] - '0';
-				j++;
-			}
-			if (n < 2)
-				ERROR();
-			if (nbuf[j] != '_')
-				ERROR();
-			j++;
-			n--;
-			if (!nbuf[j])
-				ERROR();
-
-			/* get arguments for template class */
-
-			push(nbuf + j, n);
-			if ((ap = getarglist()) == NULL || cc)
-				ERROR();
-			pop();
-			p->clargs = ap;
-		}
-		p->next = NULL;
-
-		/* link in to list */
-
-		if (clhead != NULL) {
-			curr->next = p;
-			curr = p;
-		}
-		else {
-			clhead = p;
-			curr = clhead;
-		}
-	}
-
-	return clhead;
-}
-
-/* copy an argument */
-static DEMARG* arg_copy(DEMARG* p)
-{
-	DEMARG* p2;
-
-	if (p == NULL)
-		fatal("bad argument to arg_copy()", (char*)0, (char*)0);
-
-	p2 = (DEMARG*)gs(sizeof(DEMARG));
-	p2->mods = p->mods;
-	p2->base = p->base;
-	p2->arr = p->arr;
-	p2->func = p->func;
-	p2->clname = p->clname;
-	p2->mname = p->mname;
-	p2->lit = p->lit;
-	p2->ret = p->ret;
-	p2->next = NULL;
-
-	return p2;
-}
-
-/* get an argument */
-static DEMARG* getarg(int acmax, DEMARG* arg_cache[], int* ncount)
-{
-	char mods[100];
-	int mc;
-	int type;
-	static DEMARG* p;
-	DEMCL* clp;
-	long n;
-	DEMARG* farg;
-	DEMARG* fret;
-	DEMARG* getarglist();
-	char litbuf[MAXLINE];
-	size_t lp;
-	int foundx;
-	long arrdim[100];
-	int arrp;
-	int i;
-	int wasm;
-	int waslm;
-	char buf[MAXLINE];
-	char buf2[MAXLINE];
-	void dem_printcl();
-	DEMCL* clist[100];
-	int clc;
-	int ic;
-
-	/* might be stuff remaining from Nnn */
-
-	if (ncount != NULL && *ncount > 0) {
-		(*ncount)--;
-		return arg_copy(p);
-	}
-
-	mc = 0;
-	type = 0;
-	clp = NULL;
-	farg = NULL;
-	fret = NULL;
-	lp = 0;
-	foundx = 0;
-	arrp = 0;
-	wasm = 0;
-	clc = 0;
-
-	/* get type */
-
-	while (!type) {
-		switch (cc) {
-
-			/* modifiers and declarators */
-
-			case 'X':
-				gc();
-				foundx = 1;
-				break;
-			case 'U':
-			case 'C':
-			case 'V':
-			case 'S':
-			case 'P':
-			case 'R':
-				mods[mc++] = cc;
-				gc();
-				break;
-
-			/* fundamental types */
-
-			case 'v':
-			case 'c':
-			case 's':
-			case 'i':
-			case 'l':
-			case 'f':
-			case 'd':
-			case 'r':
-			case 'e':
-			case 'G':
-				type = cc;
-				gc();
-				break;
-
-			/* arrays */
-
-			case 'A':
-				mods[mc++] = cc;
-				gc();
-				if (!isdigit(cc))
-					ERROR();
-				n = cc - '0';
-				gc();
-				while (isdigit(cc)) {
-					n = n * 10 + cc - '0';
-					gc();
-				}
-				if (cc != '_')
-					ERROR();
-				gc();
-				arrdim[arrp++] = n;
-				break;
-
-			/* functions */
-
-			case 'F':
-				type = cc;
-				gc();
-				if ((farg = getarglist()) == NULL)
-					ERROR();
-				if (cc != '_')
-					ERROR();
-				gc();
-				if ((fret = getarg(-1, (DEMARG**)0, (int*)0)) == NULL)
-					ERROR();
-				break;
-
-			/* pointers to member */
-
-			case 'M':
-				mods[mc++] = cc;
-				wasm = 1;
-				gc();
-				if ((clist[clc++] = getclass()) == NULL)
-					ERROR();
-				break;
-
-			/* repeat previous argument */
-
-			case 'T':
-				gc();
-tcase:
-				if (!isdigit(cc))
-					ERROR();
-				n = cc - '0';
-				gc();
-				if (n < 1)
-					ERROR();
-				if (arg_cache == NULL || n - 1 > acmax)
-					ERROR();
-				p = arg_copy(arg_cache[n - 1]);
-				return p;
-
-			/* repeat previous argument N times */
-
-			case 'N':
-				gc();
-				if (!isdigit(cc))
-					ERROR();
-				if (ncount == NULL)
-					ERROR();
-				*ncount = cc - '0' - 1;
-				if (*ncount < 0)
-					ERROR();
-				gc();
-				goto tcase;
-
-			/* class, struct, union, enum */
-
-			case '1': case '2': case '3': case '4': case '5':
-			case '6': case '7': case '8': case '9': case 'Q':
-				if ((clp = getclass()) == NULL)
-					ERROR();
-				type = 'C';
-				break;
-
-			default:
-				return NULL;
-		}
-	}
-
-	/* template literals */
-
-	if (type && foundx) {
-		n = 0;
-		waslm = 0;
-		if (cc == 'L' && base[0] == 'M') {
-			gc();
-			gc();
-			while (cc != '_' && cc)
-				gc();
-			if (!cc)
-				ERROR();
-			gc();
-			while (cc != '_' && cc)
-				gc();
-			if (!cc)
-				ERROR();
-			gc();
-			n = cc - '0';
-			gc();
-			if (isdigit(cc)) {
-				n = n * 10 + cc - '0';
-				gc();
-			}
-			if (isdigit(cc)) {
-				n = n * 10 + cc - '0';
-				gc();
-			}
-			waslm = 1;
-		}
-		else if (cc == 'L') {
-			gc();
-			if (!isdigit(cc))
-				ERROR();
-			n = cc - '0';
-			gc();
-			if (isdigit(cc) && base[0] == '_') {
-				n = n * 10 + cc - '0';
-				gc();
-				gc();
-			}
-			if (cc == 'n') {
-				gc();
-				n--;
-				litbuf[lp++] = '-';
-			}
-		}
-		else if (cc == '0') {
-			n = 1;
-		}
-		else if (isdigit(cc)) {
-			n = cc - '0';
-			gc();
-			if (isdigit(cc)) {
-				n = n * 10 + cc - '0';
-				gc();
-			}
-		}
-		else {
-			ERROR();
-		}
-		if (!n && waslm) {
-			(void) strcpy(litbuf, "0");
-			lp = 1;
-		}
-		else {
-			ic = -1;
-			while (n-- > 0) {
-				if (!isalnum(cc) && cc != '_')
-					ERROR();
-				litbuf[lp++] = cc;
-				gc();
-				if (n > 0 && lp >= 2 &&
-				    litbuf[lp - 1] == '_' && litbuf[lp - 2] == '_') {
-					if ((clist[ic = clc++] = getclass()) == NULL)
-						ERROR();
-					litbuf[lp - 1] = 0;
-					litbuf[lp - 2] = 0;
-					lp -= 2;
-					break;
-				}	
-			}
-			litbuf[lp] = 0;
-			if ((wasm && waslm) || ic >= 0) {
-				dem_printcl(clist[ic >= 0 ? ic : 0], buf2);
-				(void) sprintf(buf, "%s::%s", buf2, litbuf);
-				(void) strcpy(litbuf, buf);
-				lp = strlen(litbuf);
-			}
-		}
-	}
-
-	mods[mc] = 0;
-	litbuf[lp] = 0;
-	p = (DEMARG*)gs(sizeof(DEMARG));
-	p->mods = mc ? copy(mods) : NULL;
-	p->lit = lp ? copy(litbuf) : NULL;
-	if (arrp > 0) {
-		p->arr = (long*)gs(sizeof(long) * arrp);
-		for (i = 0; i < arrp; i++)
-			p->arr[i] = arrdim[i];
-	}
-	else {
-		p->arr = NULL;
-	}
-	/* LINTED */
-	p->base = (char)type;
-	p->func = farg;
-	p->ret = fret;
-	p->clname = clp;
-	if (clc > 0) {
-		p->mname = (DEMCL**)gs(sizeof(DEMCL*) * (clc + 1));
-		for (i = 0; i < clc; i++)
-			p->mname[i] = clist[i];
-		p->mname[clc] = NULL;
-	}
-	else {
-		p->mname = NULL;
-	}
-	p->next = NULL;
-
-	return p;
-}
-
-/* get list of arguments */
-static DEMARG* getarglist()
-{
-	DEMARG* p;
-	DEMARG* head;
-	DEMARG* curr;
-	DEMARG* arg_cache[MAXARG];
-	int acmax;
-	int ncount;
-
-	head = NULL;
-	curr = NULL;
-
-	acmax = -1;
-	ncount = 0;
-
-	for (;;) {
-
-		/* get the argument */
-
-		p = getarg(acmax, arg_cache, &ncount);
-		if (p == NULL) {
-			if (waserror)
-				return NULL;
-			return head;
-		}
-
-		/* cache it for Tn and Nnn */
-
-		arg_cache[++acmax] = p;
-		if (curr == NULL) {
-			head = p;
-			curr = head;
-		}
-		else {
-			curr->next = p;
-			curr = p;
-		}
-	}
-}
-
-/* entry point for demangling */
-int dem(char* s, DEM* p, char* buf)
-{
-	char nbuf[MAXLINE];
-	int nc;
-	long n;
-	char* t;
-	char* t2;
-	char* t3;
-	char* ob;
-	int flag;
-	int cuflag;
-	char buf2[MAXLINE];
-	enum DEM_TYPE dt;
-
-	if (s == NULL || p == NULL || buf == NULL)
-		return -1;
-
-	cuflag = 0;
-
-	if (clip_under && *s == '_')
-		s++, cuflag = 1;
-
-	if (!*s)
-		return -1;
-
-	/* set up space and input buffer management */
-
-	spbase = buf;
-	sp = -1;
-	waserror = 0;
-
-	p->fargs = NULL;
-	p->cl = NULL;
-	p->sc = 0;
-	p->args = NULL;
-	p->f = NULL;
-	p->vtname = NULL;
-	p->slev = -1;
-	p->type = DEM_NONE;
-
-	/* special case local variables */
-
-	if (cuflag)
-		s--;
-	if (s[0] == '_' && s[1] == '_' && isdigit(s[2])) {
-		t = s + 2;
-		n = 0;
-		while (isdigit(*t)) {
-			n = n * 10 + *t - '0';
-			t++;
-		}
-		if (*t) {
-			p->f = copy(t);
-			/* LINTED */
-			p->slev = (short)n;
-			goto done2;
-		}
-	}
-	if (cuflag)
-		s++;
-
-	/* special case sti/sti/ptbl */
-
-	if (s[0] == '_' && s[1] == '_' &&
-	    (!strncmp(s, "__sti__", 7) || !strncmp(s, "__std__", 7) ||
-	    !strncmp(s, "__ptbl_vec__", 12))) {
-		p->sc = s[4];
-		t = (s[2] == 's' ? s + 7 : s + 12);
-		while (*t == '_')
-			t++;
-		p->f = copy(t);
-		if ((t2 = strstr(p->f, "_cc_")) != NULL)
-			nc = 3; 
-		else if ((t2 = strstr(p->f, "_c_")) != NULL)
-			nc = 2; 
-		else if ((t2 = strstr(p->f, "_C_")) != NULL)
-			nc = 2; 
-		else if ((t2 = strstr(p->f, "_cxx_")) != NULL)
-			nc = 4; 
-		else if ((t2 = strstr(p->f, "_h_")) != NULL)
-			nc = 2; 
-		if (t2) 
-			*(t2+nc) = 0; 
-		cc = 0;
-		goto done2;
-	}
-
-	/* special case type names */
-
-	if (cuflag)
-		s--;
-	t = s;
-	flag = 0;
-	while (t[0] && (t[0] != '_' || t == s || t[-1] != '_'))
-		t++;
-	if (t[0] == '_' && t[1] == 'p' && t[2] == 't' &&
-	    t[3] == '_' && t[4] == '_')
-		flag = 1;
-	if (t[0] == '_' && t[1] == '_' && t[2] == 'p' && t[3] == 't' &&
-	    t[4] == '_' && t[5] == '_')
-		flag = 1;
-	if (!flag) {
-		t = s;
-		if ((t[0] == '_' && t[1] == '_' && t[2] == 'Q' &&
-		    isdigit(t[3]) && t[4] == '_'))
-			flag = 2;
-	}
-	if (flag) {
-		sp = -1;
-		waserror = 0;
-		if (flag == 1) {
-			(void) sprintf(buf2, "%ld%s", strlen(s), s);
-			push(buf2, 9999);
-		}
-		else {
-			push(s + 2, 9999);
-		}
-		if ((p->cl = getclass()) == NULL)
-			return -1;
-		cc = 0;
-		goto done2;
-	}
-	if (cuflag)
-		s++;
-
-	sp = -1;
-	push(s, 9999);
-	waserror = 0;
-
-	/* get function name */
-
-	nc = 0;
-	nbuf[0] = 0;
-	while (isalnum(cc) || cc == '_') {
-		nbuf[nc++] = cc;
-		nbuf[nc] = 0;
-		if (!base[0] ||
-		    (base[0] == '_' && base[1] == '_' && base[2] != '_')) {
-			gc();
-			break;
-		}
-		gc();
-
-		/* conversion operators */
-
-		if (!STRCMP(nbuf, "__op")) {
-			ob = base - 1;
-			if ((p->fargs = getarg(-1, (DEMARG**)0, (int*)0)) == NULL)
-				return -1;
-			while (ob < base - 1)
-				nbuf[nc++] = *ob++;
-			nbuf[nc] = 0;
-			break;
-		}
-	}
-	if (!isalpha(nbuf[0]) && nbuf[0] != '_')
-		return -1;
-
-	/* pick off delimiter */
-
-	if (cc == '_' && base[0] == '_') {
-		gc();
-		gc();
-		if (!cc)
-			return -1;
-	}
-
-	/* get class name */
-
-	if (isdigit(cc) || cc == 'Q') {
-		if ((p->cl = getclass()) == NULL)
-			return -1;
-	}
-
-	/* a function template */
-
-	else if (cc == 'p' && !strncmp(base, "t__F", 4)) {
-		gc();
-		gc();
-		gc();
-		gc();
-		gc();
-		if (!isdigit(cc))
-			return -1;
-		n = cc - '0';
-		gc();
-		if (isdigit(cc)) {
-			n = n * 10 + cc - '0';
-			gc();
-		}
-		if (isdigit(cc)) {
-			n = n * 10 + cc - '0';
-			gc();
-		}
-		if (n < 1)
-			return -1;
-		while (n-- > 0) {
-			if (!isalnum(cc) && cc != '_')
-				return -1;
-			gc();
-		}
-		if (cc != '_' || base[0] != '_')
-			return -1;
-		gc();
-		gc();
-	}
-
-	if (!STRCMP(nbuf, "__vtbl")) {
-		if (cc == '_' && base[0] == '_' && base[1])
-			p->vtname = copy(base + 1);
-		goto done;
-	}
-
-	/* const/static member functions */
-
-	if ((cc == 'C' || cc == 'S') && base[0] == 'F') {
-		p->sc = cc;
-		gc();
-	}
-
-	/* get arg list for function */
-
-	if (cc == 'F') {
-		gc();
-		if ((p->args = getarglist()) == NULL)
-			return -1;
-	}
-
-done:
-	if ((cc && STRCMP(nbuf, "__vtbl")) || waserror)
-		return -1;
-
-	p->f = copy(nbuf);
-
-done2:
-
-	/* figure out type we got */
-
-	dt = DEM_NONE;
-	if (p->sc) {
-		switch (p->sc) {
-			case 'i':
-				dt = DEM_STI;
-				break;
-			case 'd':
-				dt = DEM_STD;
-				break;
-			case 'b':
-				dt = DEM_PTBL;
-				break;
-			case 'C':
-				dt = DEM_CMFUNC;
-				break;
-			case 'S':
-				dt = DEM_SMFUNC;
-				break;
-			default:
-				fatal("bad type set for p->sc", (char*)0, (char*)0);
-				break;
-		}
-	}
-	else if (p->slev != -1) {
-		dt = DEM_LOCAL;
-	}
-	else if (p->args != NULL) {
-		if (p->fargs != NULL) {
-			dt = DEM_OMFUNC;
-		}
-		else if (p->cl != NULL) {
-			t3 = p->f;
-			if (t3[0] == '_' && t3[1] == '_') {
-				if (t3[2] == 'c' && t3[3] == 't' && !t3[4])
-					dt = DEM_CTOR;
-				else if (t3[2] == 'd' && t3[3] == 't' &&
-				    !t3[4])
-					dt = DEM_DTOR;
-				else
-					dt = DEM_MFUNC;
-			}
-			else {
-				dt = DEM_MFUNC;
-			}
-		}
-		else {
-			dt = DEM_FUNC;
-		}
-	}
-	else if (p->f == NULL && p->cl != NULL) {
-		if (p->cl->clargs != NULL)
-			dt = DEM_TTYPE;
-		else
-			dt = DEM_CTYPE;
-	}
-	else if (p->f != NULL) {
-		if (p->cl != NULL) {
-			t3 = p->f;
-			if (t3[0] == '_' && t3[1] == '_' && t3[2] == 'v' &&
-			    t3[3] == 't' && t3[4] == 'b' && t3[5] == 'l' &&
-			    !t3[6])
-				dt = DEM_VTBL;
-			else
-				dt = DEM_MDATA;
-		}
-		else {
-			dt = DEM_DATA;
-		}
-	}
-
-	if (dt == DEM_NONE)
-		fatal("cannot characterize type of input", (char*)0, (char*)0);
-
-	p->type = dt;
-
-	return 0;
-}
-
-/************************* PRINT AN UNMANGLED NAME *************************/
-
-/* format a class name */
-void dem_printcl(DEMCL* p, char* buf)
-{
-	int i;
-	char buf2[MAXLINE];
-	void dem_printarglist();
-
-	if (p == NULL || buf == NULL)
-		fatal("bad argument to dem_printcl()", (char*)0, (char*)0);
-
-	buf[0] = 0;
-	i = 0;
-	while (p != NULL) {
-		i++;
-
-		/* handle nested */
-
-		if (i > 1)
-			(void) strcat(buf, "::");
-		(void) strcat(buf, p->name);
-
-		/* template class */
-
-		if (p->clargs != NULL) {
-			if (buf[strlen(buf) - 1] == '<')
-				(void) strcat(buf, " ");
-			(void) strcat(buf, "<");
-			dem_printarglist(p->clargs, buf2, 0);
-			(void) strcat(buf, buf2);
-			if (buf[strlen(buf) - 1] == '>')
-				(void) strcat(buf, " ");
-			(void) strcat(buf, ">");
-		}
-		p = p->next;
-	}
-}
-
-/* format an argument list */
-void dem_printarglist(DEMARG* p, char* buf, int sv)
-{
-	int i;
-	char buf2[MAXLINE];
-	void dem_printarg();
-
-	if (p == NULL || buf == NULL || sv < 0 || sv > 1)
-		fatal("bad argument to dem_printarglist()", (char*)0, (char*)0);
-
-	/* special case single "..." argument */
-
-	if (p->base == 'v' && p->mods == NULL && p->next != NULL &&
-	    p->next->base == 'e' && p->next->next == NULL) {
-		(void) strcpy(buf, "...");
-		return;
-	}
-
-	/* special case single "void" argument */
-
-	if (p->base == 'v' && p->mods == NULL) {
-		(void) strcpy(buf, "void");
-		return;
-	}
-
-	buf[0] = 0;
-	i = 0;
-	while (p != NULL) {
-		i++;
-		if (i > 1)
-			(void) strcat(buf, p->base == 'e' ? " " : ",");
-		dem_printarg(p, buf2, sv);
-		(void) strcat(buf, buf2);
-		p = p->next;
-	}
-}
-
-/* format a single argument */
-void dem_printarg(DEMARG* p, char* buf, int f)
-{
-	char* t;
-	char bufc[MAXLINE];
-	char bufc2[MAXLINE];
-	char farg[MAXLINE];
-	char fret[MAXLINE];
-	char* m;
-	char* mm;
-	char pref[MAXLINE];
-	int arrindx;
-	long dim;
-	char scr[MAXLINE];
-	char ptrs[MAXLINE];
-	int i;
-	int sv;
-	char* s;
-	char* trail;
-	int clc;
-
-	if (p == NULL || buf == NULL || f < 0 || f > 1)
-		fatal("bad argument to dem_printarg()", (char*)0, (char*)0);
-
-	/* format the underlying type */
-
-	sv = !f;
-
-	switch (p->base) {
-
-		/* fundamental types */
-
-		case 'v':
-			t = "void";
-			break;
-		case 'c':
-			t = "char";
-			break;
-		case 's':
-			t = "short";
-			break;
-		case 'i':
-			t = "int";
-			break;
-		case 'l':
-			t = "long";
-			break;
-		case 'f':
-			t = "float";
-			break;
-		case 'd':
-			t = "double";
-			break;
-		case 'r':
-			t = "long double";
-			break;
-		case 'G':
-			t = "T";
-			break;
-		case 'e':
-			t = "...";
-			sv = 1;
-			break;
-
-		/* functions */
-
-		case 'F':
-			dem_printarg(p->ret, fret, 0);
-			dem_printarglist(p->func, farg, 0);
-			break;
-
-		/* class, struct, union, enum */
-
-		case 'C':
-			dem_printcl(p->clname, bufc);
-			t = bufc;
-			break;
-
-		default:
-			fatal("bad base type in dem_printarg()", (char*)0, (char*)0);
-			break;
-	}
-
-	/* handle modifiers and declarators */
-
-	pref[0] = 0;
-	m = p->mods;
-	if (m == NULL)
-		m = "";
-
-	/* const and unsigned */
-
-	mm = m;
-	while (*mm) {
-		if (mm[0] == 'C' && (mm[1] != 'P' && mm[1] != 'R' && mm[1] != 'M') && (mm[1] || p->base != 'F')) {
-			(void) strcat(pref, "const ");
-			break;
-		}
-		mm++;
-	}
-	mm = m;
-	while (*mm) {
-		if (*mm == 'U') {
-			(void) strcat(pref, "unsigned ");
-			break;
-		}
-		mm++;
-	}
-
-	/* go through modifier list */
-
-	mm = m;
-	ptrs[0] = 0;
-	arrindx = 0;
-	clc = 0;
-	while (*mm) {
-		if (mm[0] == 'P') {
-			(void) sprintf(scr, "*%s", ptrs);
-			(void) strcpy(ptrs, scr);
-		}
-		else if (mm[0] == 'R') {
-			(void) sprintf(scr, "&%s", ptrs);
-			(void) strcpy(ptrs, scr);
-		}
-		else if (mm[0] == 'M') {
-			dem_printcl(p->mname[clc++], bufc2);
-			(void) sprintf(scr, "%s::*%s", bufc2, ptrs);
-			(void) strcpy(ptrs, scr);
-		}
-		else if (mm[0] == 'C' && mm[1] == 'P') {
-			(void) sprintf(scr, " *const%s%s", isalnum(ptrs[0]) || ptrs[0] == '_' ? " " : "", ptrs);
-			(void) strcpy(ptrs, scr);
-			mm++;
-		}
-		else if (mm[0] == 'C' && mm[1] == 'R') {
-			(void) sprintf(scr, " &const%s%s", isalnum(ptrs[0]) || ptrs[0] == '_' ? " " : "", ptrs);
-			(void) strcpy(ptrs, scr);
-			mm++;
-		}
-		else if (mm[0] == 'C' && mm[1] == 'M') {
-			dem_printcl(p->mname[clc++], bufc2);
-			(void) sprintf(scr, "%s::*const%s%s", bufc2, isalnum(ptrs[0]) || ptrs[0] == '_' ? " " : "", ptrs);
-			(void) strcpy(ptrs, scr);
-			mm++;
-		}
-		else if (mm[0] == 'A') {
-			dim = p->arr[arrindx++];
-			s = sv ? "" : "@";
-			if (!ptrs[0]) {
-				(void) sprintf(scr, "%s[%ld]", s, dim);
-				sv = 1;
-			}
-			else if (ptrs[0] == '(' || ptrs[0] == '[') {
-				(void) sprintf(scr, "%s[%ld]", ptrs, dim);
-			}
-			else {
-				(void) sprintf(scr, "(%s%s)[%ld]", ptrs, s, dim);
-				sv = 1;
-			}
-			(void) strcpy(ptrs, scr);
-		}
-		else if (mm[0] == 'U' || mm[0] == 'C' || mm[0] == 'S') {
-			/* ignore */
-		}
-		else {
-			fatal("bad value in modifier list", (char*)0, (char*)0);
-		}
-		mm++;
-	}
-
-	/* put it together */
-
-	s = sv ? "" : "@";
-	if (p->base == 'F') {
-		i = 0;
-		if (ptrs[0] == ' ')
-			i = 1;
-		trail = "";
-		if (p->mods != NULL && p->mods[strlen(p->mods) - 1] == 'C')
-			trail = " const";
-		if (ptrs[i])
-			(void) sprintf(buf, "%s%s (%s%s)(%s)%s", pref, fret, ptrs + i,
-			    s, farg, trail);
-		else
-			(void) sprintf(buf, "%s%s %s(%s)%s", pref, fret, s, farg, trail);
-	}
-	else {
-		(void) sprintf(buf, "%s%s%s%s%s", pref, t, ptrs[0] == '(' || isalnum(ptrs[0]) || ptrs[0] == '_' ? " " : "", ptrs, s);
-	}
-	if (p->lit != NULL) {
-		if (isdigit(p->lit[0]) || p->lit[0] == '-')
-			(void) sprintf(scr, "(%s)%s", buf, p->lit);
-		else
-			(void) sprintf(scr, "&%s", p->lit);
-		(void) strcpy(buf, scr);
-	}
-}
-
-struct Ops {
-	char* encode;
-	char* name;
-};
-
-static struct Ops ops[] = {
-	"__pp",		"operator++",
-	"__as",		"operator=",
-	"__vc",		"operator[]",
-	"__nw",		"operator new",
-	"__dl",		"operator delete",
-	"__rf",		"operator->",
-	"__ml",		"operator*",
-	"__mm",		"operator--",
-	"__oo",		"operator||",
-	"__md",		"operator%",
-	"__mi",		"operator-",
-	"__rs",		"operator>>",
-	"__ne",		"operator!=",
-	"__gt",		"operator>",
-	"__ge",		"operator>=",
-	"__or",		"operator|",
-	"__aa",		"operator&&",
-	"__nt",		"operator!",
-	"__apl",	"operator+=",
-	"__amu",	"operator*=",
-	"__amd",	"operator%=",
-	"__ars",	"operator>>=",
-	"__aor",	"operator|=",
-	"__cm",		"operator,",
-	"__dv",		"operator/",
-	"__pl",		"operator+",
-	"__ls",		"operator<<",
-	"__eq",		"operator==",
-	"__lt",		"operator<",
-	"__le",		"operator<=",
-	"__ad",		"operator&",
-	"__er",		"operator^",
-	"__co",		"operator~",
-	"__ami",	"operator-=",
-	"__adv",	"operator/=",
-	"__als",	"operator<<=",
-	"__aad",	"operator&=",
-	"__aer",	"operator^=",
-	"__rm",		"operator->*",
-	"__cl",		"operator()",
-	NULL,		NULL
-};
-
-/* format a function name */
-void dem_printfunc(DEM* dp, char* buf)
-{
-	int i;
-	char buf2[MAXLINE];
-
-	if (dp == NULL || buf == NULL)
-		fatal("bad argument to dem_printfunc()", (char*)0, (char*)0);
-
-	if (dp->f[0] == '_' && dp->f[1] == '_') {
-
-		/* conversion operators */
-
-		if (!strncmp(dp->f, "__op", 4) && dp->fargs != NULL) {
-			dem_printarg(dp->fargs, buf2, 0);
-			(void) sprintf(buf, "operator %s", buf2);		
-		}
-
-		/* might be overloaded operator */
-
-		else {
-			i = 0;
-			while (ops[i].encode != NULL && strcmp(ops[i].encode, dp->f))
-				i++;
-			if (ops[i].encode != NULL)
-				(void) strcpy(buf, ops[i].name);
-			else
-				(void) strcpy(buf, dp->f);
-		}
-	}
-	else {
-		(void) strcpy(buf, dp->f);
-	}
-}
-
-/* entry point to formatting functions */
-int dem_print(DEM* p, char* buf)
-{
-	char buf2[MAXLINE];
-	char* s;
-	int t;
-
-	if (p == NULL || buf == NULL)
-		return -1;
-
-	buf[0] = 0;
-
-	/* type names */
-
-	if (p->f == NULL && p->cl != NULL) {
-		dem_printcl(p->cl, buf);
-		return 0;
-	}
-
-	/* sti/std */
-
-	if (p->sc == 'i' || p->sc == 'd') {
-		(void) sprintf(buf, "%s:__st%c", p->f, p->sc);
-		return 0;
-	}
-	if (p->sc == 'b') {
-		(void) sprintf(buf, "%s:__ptbl_vec", p->f);
-		return 0;
-	}
-
-	/* format class name */
-
-	buf2[0] = 0;
-	if (p->cl != NULL) {
-		dem_printcl(p->cl, buf2);
-		(void) strcat(buf, buf2);
-		(void) strcat(buf, "::");
-	}
-
-	/* special case constructors and destructors */
-
-	s = buf2 + strlen(buf2) - 1;
-	t = 0;
-	while (s >= buf2) {
-		if (*s == '>')
-			t++;
-		else if (*s == '<')
-			t--;
-		else if (*s == ':' && !t)
-			break;
-		s--;
-	}
-	if (!STRCMP(p->f, "__ct")) {
-		(void) strcat(buf, s + 1);
-	}
-	else if (!STRCMP(p->f, "__dt")) {
-		(void) strcat(buf, "~");
-		(void) strcat(buf, s + 1);
-	}
-	else {
-		dem_printfunc(p, buf2);
-		(void) strcat(buf, buf2);
-	}
-
-	/* format argument list */
-
-	if (p->args != NULL) {
-		(void) strcat(buf, "(");
-		dem_printarglist(p->args, buf2, 0);
-		(void) strcat(buf, buf2);
-		(void) strcat(buf, ")");
-	}
-
-	/* const member functions */
-
-	if (p->sc == 'C')
-		(void) strcat(buf, " const");
-
-	return 0;
-}
-
-/* explain a type */
-char* dem_explain(enum DEM_TYPE t)
-{
-	switch (t) {
-		case DEM_STI:
-			return "static construction function";
-		case DEM_STD:
-			return "static destruction function";
-		case DEM_VTBL:
-			return "virtual table";
-		case DEM_PTBL:
-			return "ptbl vector pointing to vtbls";
-		case DEM_FUNC:
-			return "function";
-		case DEM_MFUNC:
-			return "member function";
-		case DEM_SMFUNC:
-			return "static member function";
-		case DEM_CMFUNC:
-			return "constant member function";
-		case DEM_OMFUNC:
-			return "conversion operator member function";
-		case DEM_CTOR:
-			return "constructor";
-		case DEM_DTOR:
-			return "destructor";
-		case DEM_DATA:
-			return "data";
-		case DEM_MDATA:
-			return "member data";
-		case DEM_LOCAL:
-			return "local variable";
-		case DEM_CTYPE:
-			return "class type";
-		case DEM_TTYPE:
-			return "template type";
-		default:
-			fatal("bad type passed to dem_explain()", (char*)0, (char*)0);
-			return "";
-	}
-}
-
-/* ------------------------------------------------------------------------ */
-
-/* demangle in --> out */
-int cfront_demangle(char* in, char* out)
-{
-	char sbuf[MAXDBUF];
-	DEM d;
-
-	if (in == NULL || !*in || out == NULL)
-		return -1;
-
-	if (dem(in, &d, sbuf) < 0) {
-		(void) strcpy(out, in);
-		return -1;
-	}
-
-	(void) dem_print(&d, out);
-
-	return 0;
-}
-
-/*
-    The routines below are provided to enable the tools nm,
-    prof, and gprof to use the demangling function provided
-    in this file.
-    Entry point is DemangleAndFormat()   --MK
-*/
-
-#include <string.h>
-
-static int CheckSpecialCase( char *, DEM *);
-static void ProcessVtname( DEM *);
-static char *FormatName( char *, char *, char *);
-
-static char d_buf[512];
-static char *ctor_str = "static constructor function for %s";
-static char *dtor_str = "static destructor function for %s";
-static char *ptbl_str = "pointer to the virtual table vector for %s";
-static char *vtbl_str = "virtual table for class %s";
-
-extern char *cafe_demangle(char *, char *);
-
-char *DemangleAndFormat(char  *name, char  *format)
-{
-  char dn[MAXDBUF];  /* demangled name */
-  char dn2[MAXDBUF];  /* demangled name */
-  DEM  dem_struct;
-  int  dem_ret_val;
-
-  char *cafe_out = cafe_demangle(name, dn);
-  if (cafe_out != name)
-  {
-    /* a cafe symbol...
-    */
-    return FormatName(name, cafe_out, format);
-  }
-
-  dem_ret_val = dem( name, &dem_struct, dn2);
-
-  if ((dem_ret_val < 0) || !(strcmp(name, dn2)))
-  {     /* name not demangled */
-    d_buf[0] = '\0';
-  }
-  else   /* name demangled by dem() */
-  {
-    if (CheckSpecialCase( name, &dem_struct))
-    {
-      name = FormatName( name, d_buf, format);
-    }
-    else   /* not a special case */
-    {
-      (void) dem_print( &dem_struct, dn);
-      name = FormatName( name, dn, format);
-    }
-  }
-
-  return (name);
-}  /* DemangleAndFormat */
-
-
-/* alloc memory and create name in necessary format.
-   Return name string
-*/
-static char *FormatName(char  *OldName, char  *NewName, char  *format)
-{
-  size_t length = strlen(format) + strlen(NewName) + strlen(OldName) - 3;
-  char *hold = OldName;
-
-  OldName = (char *)malloc( length );
-  (void) sprintf(OldName, format, NewName, hold);
-  return (OldName);
-}
-
-
-/*
-   Check for special cases: __sti__, _std__, __ptbl_vec__, __vtbl__
-   use demP for the procesing 
-   Return 1 if it is a special case, otherwise return 0.
-*/
-static int CheckSpecialCase(char  *name, DEM   *demP)
-{
-  int  retVal = 1;
-
-  if (demP->sc == 'i')   /* __sti__ */
-  {
-    (void) sprintf( d_buf, ctor_str, demP->f);
-  }
-  else if (demP->sc == 'd')  /* __std__ */
-  {
-    (void) sprintf( d_buf, dtor_str, demP->f);
-  }
-  else if (demP->sc == 'b')  /*  __ptbl_vec__ */
-  {
-    (void) sprintf( d_buf, ptbl_str, demP->f);
-  }
-  else if (demP->vtname != NULL)  /* __vtbl__ with file name */
-  {
-    ProcessVtname( demP);
-  }
-  else if (demP->cl != NULL)   /* check for __vtbl__ without file name */
-  {
-    if (strncmp( name, "__vtbl__", 8) == 0)
-      (void) sprintf( d_buf, vtbl_str, demP->cl->name);
-    else
-      retVal = 0;  /* not a special case */
-  }
-  else
-  {
-    retVal = 0;   /* not a special case */
-    d_buf[0] = '\0';
-  }
-
-  return (retVal);
-}
-
-
-/* process demP->vtname */
-/*   called by CheckSpecialCase() */
-
-static void ProcessVtname(DEM  *demP)
-{
-  char  *nameString;
-  char  *tail;
-  size_t   len;
-  int   marker;
-  char  saveChar;
-
-  nameString = demP->vtname;
-
-  /* check if mangled name of derived class (a heuristic)           */
-  /* different possibilities for string demP->vtname:               */
-  /*   (1) 'filename_ext'  class name in file                       */
-  /*   (2) '%dname'        class derived from class                 */
-  /*   (3) '%dname__filename_ext' class derived from class in file  */
-  /* note: the filename itself could start with a digit             */
-  len = strlen( nameString);
-  if (*(nameString + len - 2) == '_')
-    marker = 2;
-  else if (*(nameString + len - 3) == '_')
-    marker = 3;
-  else
-    marker = 0;
-  if (!isdigit(*nameString))  /* case (1) */
-  {
-    (void) sprintf( d_buf, vtbl_str, demP->cl ? demP->cl->name : "??");
-    (void) strcat( d_buf, " in ");
-    if (marker > 0)
-      *(nameString + len - marker) = '.';
-    (void) strcat( d_buf, nameString);
-    if (marker > 0)
-      *(nameString + len - marker) = '_';
-  }
-
-  else if ((tail = strstr( nameString, "__")) == NULL)
-  {  /* could be case (1) or case (2) */
-     /* case (1) if filename starts with a digit */
-    if (marker == 0)  /* case (2) */
-    {
-      while (isdigit( *nameString))
-        nameString++;
-      (void) sprintf( d_buf, vtbl_str, nameString);
-      (void) strcat( d_buf, " derived from ");
-      (void) strcat( d_buf, demP->cl ? demP->cl->name : "??");
-    }
-    else  /* case (1) */
-    {
-      (void) sprintf( d_buf, vtbl_str, demP->cl ? demP->cl->name : "??");
-      (void) strcat( d_buf, " in ");
-      if (marker > 0)
-        *(nameString + len - marker) = '.';
-      (void) strcat( d_buf, nameString);
-      if (marker > 0)
-        *(nameString + len - marker) = '_';
-    }
-  }
-
-  else   /* case (3) */
-  {
-    while (isdigit( *nameString))
-      nameString++;
-    saveChar = *(nameString + (tail - nameString));
-    *(nameString + (tail - nameString)) = '\0';
-    (void) sprintf( d_buf, vtbl_str, nameString);
-    (void) strcat( d_buf, " derived from ");
-    (void) strcat( d_buf, demP->cl ? demP->cl->name : "??");
-    *(nameString + (tail - nameString)) = saveChar;
-    tail += 2;  /* skip "__" */
-    len = strlen( tail);
-    (void) strcat( d_buf, " in ");
-    if (marker > 0)
-      *(tail + len - marker) = '.';
-    (void) strcat( d_buf, tail);
-    if (marker > 0)
-      *(tail + len - marker) = '_';
-  }
-}  /* ProcessVtname */
-
-
--- a/usr/src/cmd/sgs/sgsdemangler/common/dem.h	Fri Mar 03 20:08:16 2006 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-/*******************************************************************************
- 
-C++ source for the C++ Language System, Release 3.0.  This product
-is a new release of the original cfront developed in the computer
-science research center of AT&T Bell Laboratories.
-
-Copyright (c) 1991 AT&T and UNIX System Laboratories, Inc.
-Copyright (c) 1984, 1989, 1990 AT&T.  All Rights Reserved.
-
-*******************************************************************************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct DEMARG DEMARG;
-typedef struct DEMCL DEMCL;
-typedef struct DEM DEM;
-
-enum DEM_TYPE {
-	DEM_NONE,		/* placeholder */
-	DEM_STI,		/* static construction function */
-	DEM_STD,		/* static destruction function */
-	DEM_VTBL,		/* virtual table */
-	DEM_PTBL,		/* ptbl vector */
-	DEM_FUNC,		/* function */
-	DEM_MFUNC,		/* member function */
-	DEM_SMFUNC,		/* static member function */
-	DEM_CMFUNC,		/* const member function */
-	DEM_OMFUNC,		/* conversion operator member function */
-	DEM_CTOR,		/* constructor */
-	DEM_DTOR,		/* destructor */
-	DEM_DATA,		/* data */
-	DEM_MDATA,		/* member data */
-	DEM_LOCAL,		/* local variable */
-	DEM_CTYPE,		/* class type */
-	DEM_TTYPE,		/* template class type */
-
-	DEM_TYPE_END		/* used for cafe support... */
-};
-
-struct DEMARG {
-	char* mods;		/* modifiers and declarators (page 123 in */
-				/* ARM), e.g. "CP" */
-
-	long* arr;		/* dimension if mod[i] == 'A' else NULL */
-
-	DEMARG* func;		/* list of arguments if base == 'F' */
-				/* else NULL */
-
-	DEMARG* ret;		/* return type if base == 'F' else NULL */
-
-	DEMCL* clname;		/* class/enum name if base == "C" */
-
-	DEMCL** mname;		/* class name if mod[i] == "M" */
-				/* in argument list (pointers to members) */
-
-	DEMARG* next;		/* next argument or NULL */
-
-	char* lit;		/* literal value for PT arguments */
-				/* e.g. "59" in A<59> */
-
-	char base;		/* base type of argument, */
-				/* 'C' for class/enum types */
-};
-
-struct DEMCL {
-	char* name;		/* name of class or enum without PT args */
-				/* e.g. "Vector" */
-
-	DEMARG* clargs;		/* arguments to class, NULL if not PT */
-
-	char* rname;		/* raw class name with __pt__ if PT */
-				/* e.g. "A__pt__2_i" */
-
-	DEMCL* next;		/* next class name, NULL if not nested */
-};
-
-struct DEM {
-	enum DEM_TYPE type;	/* type of name that was demangled */
-	char* f;		/* function or data name;  NULL if type name */
-				/* see page 125 of ARM for predefined list */
-
-	char* vtname;		/* if != NULL name of source file for vtbl */
-
-	DEMARG* fargs;		/* arguments of function name if __opargs__ */
-				/* else NULL */
-
-	DEMCL* cl;		/* name of relevant class or enum or NULL */
-				/* used also for type-name-only input */
-
-	DEMARG* args;		/* args to function, NULL if data or type */
-
-
-	short slev;		/* scope level for local variables or -1 */
-
-	char sc;		/* storage class type 'S' or 'C' or: */
-				/* i -> __sti   d --> __std */
-				/* b -> __ptbl_vec */
-};
-
-#define MAXDBUF 8192
-
-int demangle();
-int cfront_demangle();
-void dem_printarg();
-void dem_printarglist();
-int dem_print();
-void dem_printfunc();
-int dem();
-void dem_printcl();
-char* dem_explain();
--- a/usr/src/cmd/sgs/sgsdemangler/common/demangle.c	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/cmd/sgs/sgsdemangler/common/demangle.c	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,16 +18,17 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
+
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <dlfcn.h>
-#include "dem.h"
 
 /*
  * C++ Demangling
@@ -36,53 +36,19 @@
 #define	LIBDEMANGLE	"libdemangle.so.1"
 #define	DEMANGLEFUNC	"cplus_demangle"
 
-extern char *cafe_demangle(char *, char *);
-
-/*
- * This is a backup routine which uses routine from CAFE
- * project. The -3 value is returned when the demangling
- * did not succeed.
- * (The -1 value is intentionally not used.)
- */
-/*ARGSUSED*/
-static int
-sgs_cafe_demangle(char *name, char *demangled_name, int limit)
-{
-	char *cafe_out;
-	DEM dem_struct;
-	int dem_ret_val;
+#define	MAXDBUF		1024
 
-	cafe_out = cafe_demangle(
-			(char *)name,
-			(char *)demangled_name);
-
-	if (cafe_out != name) {
-		return (0);
-	}
-
-	dem_ret_val = dem(name, &dem_struct, demangled_name);
-
-	if (dem_ret_val < 0)
-		return (-3);
-
-	return (0);
-}
-
-/*
- *
- */
 char *
 sgs_demangle(char *name)
 {
 	static char *demangled_name;
-	static int (*demangle_func)() = 0;
+	static int (*demangle_func)() = NULL;
 	static int first_flag = 0;
 	static int size = MAXDBUF;
 	int ret;
 
 	/*
-	 * If this is the first time called,
-	 * decide which demangling function to use.
+	 * Determine if libdemangle is available.
 	 */
 	if (first_flag == 0) {
 		void *demangle_hand;
@@ -92,42 +58,33 @@
 			demangle_func = (int (*)(int))dlsym(
 				demangle_hand, DEMANGLEFUNC);
 
-		if (demangle_func == NULL)
-			demangle_func = sgs_cafe_demangle;
-
-		/*
-		 * Allocate the buffer
-		 */
-		demangled_name = (char *) malloc(size);
-		if (demangled_name == NULL)
-			return (name);
-
 		first_flag = 1;
 	}
 
 	/*
-	 * If malloc() failed in the previous call,
-	 * demangle_name is NULL. So the following codes are
-	 * here.
+	 * Pass through name untouched if libdemangle is not available.
+	 */
+	if (demangle_func == NULL)
+		return (name);
+
+	/*
+	 * If this is the first call (or malloc() failed previously) allocate a
+	 * new buffer for storage.
 	 */
 	if (demangled_name == NULL) {
 		size = MAXDBUF;
-		demangled_name = (char *) malloc(size);
+		demangled_name = malloc(size);
 		if (demangled_name == NULL)
 			return (name);
 	}
 
 	/*
-	 * When we use the real one.
-	 * The real function returns -1 when the buffer size
-	 * is not sufficient.
-	 *
-	 * When we use the back up function, it never returns -1.
+	 * libdemangle returns -1 when the buffer size is not sufficient.
 	 */
 	while ((ret = (*demangle_func)(name, demangled_name, size)) == -1) {
 		free(demangled_name);
 		size = size + MAXDBUF;
-		demangled_name = (char *) malloc(size);
+		demangled_name = malloc(size);
 		if (demangled_name == NULL)
 			return (name);
 	}
--- a/usr/src/common/dis/i386/dis_tables.c	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/common/dis/i386/dis_tables.c	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -1436,7 +1435,7 @@
 {
 #ifdef DIS_TEXT
 	if (x->d86_seg_prefix) {
-		strlcat(x->d86_opnd[opindex].d86_prefix,
+		(void) strlcat(x->d86_opnd[opindex].d86_prefix,
 		    x->d86_seg_prefix, PFIXLEN);
 	}
 #endif
@@ -1480,39 +1479,39 @@
 #ifdef DIS_TEXT
 		switch (wbit) {
 		case MM_OPND:
-			strlcat(opnd, dis_MMREG[r_m], OPLEN);
+			(void) strlcat(opnd, dis_MMREG[r_m], OPLEN);
 			break;
 		case XMM_OPND:
-			strlcat(opnd, dis_XMMREG[r_m], OPLEN);
+			(void) strlcat(opnd, dis_XMMREG[r_m], OPLEN);
 			break;
 		case SEG_OPND:
-			strlcat(opnd, dis_SEGREG[r_m], OPLEN);
+			(void) strlcat(opnd, dis_SEGREG[r_m], OPLEN);
 			break;
 		case CONTROL_OPND:
-			strlcat(opnd, dis_CONTROLREG[r_m], OPLEN);
+			(void) strlcat(opnd, dis_CONTROLREG[r_m], OPLEN);
 			break;
 		case DEBUG_OPND:
-			strlcat(opnd, dis_DEBUGREG[r_m], OPLEN);
+			(void) strlcat(opnd, dis_DEBUGREG[r_m], OPLEN);
 			break;
 		case TEST_OPND:
-			strlcat(opnd, dis_TESTREG[r_m], OPLEN);
+			(void) strlcat(opnd, dis_TESTREG[r_m], OPLEN);
 			break;
 		case BYTE_OPND:
 			if (x->d86_rex_prefix == 0)
-				strlcat(opnd, dis_REG8[r_m], OPLEN);
+				(void) strlcat(opnd, dis_REG8[r_m], OPLEN);
 			else
-				strlcat(opnd, dis_REG8_REX[r_m], OPLEN);
+				(void) strlcat(opnd, dis_REG8_REX[r_m], OPLEN);
 			break;
 		case WORD_OPND:
-			strlcat(opnd, dis_REG16[r_m], OPLEN);
+			(void) strlcat(opnd, dis_REG16[r_m], OPLEN);
 			break;
 		case LONG_OPND:
 			if (x->d86_opnd_size == SIZE16)
-				strlcat(opnd, dis_REG16[r_m], OPLEN);
+				(void) strlcat(opnd, dis_REG16[r_m], OPLEN);
 			else if (x->d86_opnd_size == SIZE32)
-				strlcat(opnd, dis_REG32[r_m], OPLEN);
+				(void) strlcat(opnd, dis_REG32[r_m], OPLEN);
 			else
-				strlcat(opnd, dis_REG64[r_m], OPLEN);
+				(void) strlcat(opnd, dis_REG64[r_m], OPLEN);
 			break;
 		}
 #endif /* DIS_TEXT */
@@ -1543,7 +1542,7 @@
 			x->d86_opnd[opindex].d86_mode = MODE_NONE;
 		else
 			x->d86_opnd[opindex].d86_mode = MODE_OFFSET;
-		strlcat(opnd, dis_addr16[mode][r_m], OPLEN);
+		(void) strlcat(opnd, dis_addr16[mode][r_m], OPLEN);
 #endif
 		return;
 	}
@@ -1593,17 +1592,17 @@
 	if (have_SIB == 0) {
 		if (x->d86_mode == SIZE32) {
 			if (mode == 0)
-				strlcat(opnd, dis_addr32_mode0[r_m],
+				(void) strlcat(opnd, dis_addr32_mode0[r_m],
 				    OPLEN);
 			else
-				strlcat(opnd, dis_addr32_mode12[r_m],
+				(void) strlcat(opnd, dis_addr32_mode12[r_m],
 				    OPLEN);
 		} else {
 			if (mode == 0)
-				strlcat(opnd, dis_addr64_mode0[r_m],
+				(void) strlcat(opnd, dis_addr64_mode0[r_m],
 				    OPLEN);
 			else
-				strlcat(opnd, dis_addr64_mode12[r_m],
+				(void) strlcat(opnd, dis_addr64_mode12[r_m],
 				    OPLEN);
 		}
 	} else {
@@ -1619,12 +1618,12 @@
 		 */
 		if (base == EBP_REGNO && mode == 0) {
 			if (index != ESP_REGNO) {
-				strlcat(opnd, "(", OPLEN);
+				(void) strlcat(opnd, "(", OPLEN);
 				need_paren = 1;
 			}
 		} else {
-			strlcat(opnd, "(", OPLEN);
-			strlcat(opnd, regs[base], OPLEN);
+			(void) strlcat(opnd, "(", OPLEN);
+			(void) strlcat(opnd, regs[base], OPLEN);
 			need_paren = 1;
 		}
 
@@ -1632,12 +1631,12 @@
 		 * print the index (if any)
 		 */
 		if (index != ESP_REGNO) {
-			strlcat(opnd, ",", OPLEN);
-			strlcat(opnd, regs[index], OPLEN);
-			strlcat(opnd, dis_scale_factor[ss], OPLEN);
+			(void) strlcat(opnd, ",", OPLEN);
+			(void) strlcat(opnd, regs[index], OPLEN);
+			(void) strlcat(opnd, dis_scale_factor[ss], OPLEN);
 		} else
 			if (need_paren)
-				strlcat(opnd, ")", OPLEN);
+				(void) strlcat(opnd, ")", OPLEN);
 	}
 #endif
 }
@@ -1764,9 +1763,9 @@
 		goto error;
 
 	if (opcode1 == 0 && opcode2 == 0 &&
-	    x->d86_check_func != NULL && x->d86_check_func()) {
+	    x->d86_check_func != NULL && x->d86_check_func(x->d86_data)) {
 #ifdef DIS_TEXT
-		strncpy(x->d86_mneu, ".byte\t0", OPLEN);
+		(void) strncpy(x->d86_mneu, ".byte\t0", OPLEN);
 #endif
 		goto done;
 	}
@@ -2036,22 +2035,22 @@
 	 * including the prefixes.
 	 */
 	if (lock_prefix)
-		strlcat(x->d86_mneu, "lock ", OPLEN);
+		(void) strlcat(x->d86_mneu, "lock ", OPLEN);
 
 	if (rep_prefix == 0xf2)
-		strlcat(x->d86_mneu, "repnz ", OPLEN);
+		(void) strlcat(x->d86_mneu, "repnz ", OPLEN);
 	else if (rep_prefix == 0xf3)
-		strlcat(x->d86_mneu, "repz ", OPLEN);
+		(void) strlcat(x->d86_mneu, "repz ", OPLEN);
 
 	if (cpu_mode == SIZE64 && addr_size_prefix)
-		strlcat(x->d86_mneu, "addr32 ", OPLEN);
+		(void) strlcat(x->d86_mneu, "addr32 ", OPLEN);
 
 	if (dp->it_adrmode != CBW &&
 	    dp->it_adrmode != CWD &&
 	    dp->it_adrmode != XMMSFNC) {
 		if (strcmp(dp->it_name, "INVALID") == 0)
 			goto error;
-		strlcat(x->d86_mneu, dp->it_name, OPLEN);
+		(void) strlcat(x->d86_mneu, dp->it_name, OPLEN);
 		if (dp->it_suffix) {
 			char *types[] = {"", "w", "l", "q"};
 			if (opcode_bytes == 2 && opcode4 == 4) {
@@ -2061,8 +2060,10 @@
 						break;
 				}
 				x->d86_mneu[i - 1] = *types[opnd_size];
-			} else
-				strlcat(x->d86_mneu, types[opnd_size], OPLEN);
+			} else {
+				(void) strlcat(x->d86_mneu, types[opnd_size],
+				    OPLEN);
+			}
 		}
 	}
 #endif
@@ -2083,7 +2084,7 @@
 	case MOVSXZ:
 #ifdef DIS_TEXT
 		if (rex_prefix == 0)
-			strncpy(x->d86_mneu, "movzld", OPLEN);
+			(void) strncpy(x->d86_mneu, "movzld", OPLEN);
 #endif
 		dtrace_get_modrm(x, &mode, &reg, &r_m);
 		dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
@@ -2274,7 +2275,7 @@
 		dtrace_get_operand(x, mode, r_m, wbit, 1);
 #ifdef DIS_TEXT
 		if (vbit) {
-			strlcat(x->d86_opnd[0].d86_opnd, "%cl", OPLEN);
+			(void) strlcat(x->d86_opnd[0].d86_opnd, "%cl", OPLEN);
 		} else {
 			x->d86_opnd[0].d86_mode = MODE_SIGNED;
 			x->d86_opnd[0].d86_value_size = 1;
@@ -2310,7 +2311,7 @@
 	case SWAPGS:
 		if (cpu_mode == SIZE64 && mode == 3 && r_m == 0) {
 #ifdef DIS_TEXT
-			strncpy(x->d86_mneu, "swapgs", OPLEN);
+			(void) strncpy(x->d86_mneu, "swapgs", OPLEN);
 #endif
 			NOMEM;
 			break;
@@ -2520,9 +2521,9 @@
 		 */
 		if (mode == REG_ONLY) {
 			if (strcmp(dp->it_name, "movlps") == 0)
-				strncpy(x->d86_mneu, "movhlps", OPLEN);
+				(void) strncpy(x->d86_mneu, "movhlps", OPLEN);
 			else if (strcmp(dp->it_name, "movhps") == 0)
-				strncpy(x->d86_mneu, "movlhps", OPLEN);
+				(void) strncpy(x->d86_mneu, "movlhps", OPLEN);
 		}
 #endif
 		if (dp->it_adrmode == XMMXIMPL)
@@ -2554,7 +2555,7 @@
 #ifdef DIS_TEXT
 		if (mode == REG_ONLY) {
 			if (strcmp(dp->it_name, "movhps") == 0)
-				strncpy(x->d86_mneu, "movlhps", OPLEN);
+				(void) strncpy(x->d86_mneu, "movlhps", OPLEN);
 			else
 				goto error;
 		}
@@ -2630,10 +2631,10 @@
 			if (pred >= (sizeof (dis_PREDSUFFIX) / sizeof (char *)))
 				goto error;
 
-			strncpy(x->d86_mneu, "cmp", OPLEN);
-			strlcat(x->d86_mneu, dis_PREDSUFFIX[pred],
+			(void) strncpy(x->d86_mneu, "cmp", OPLEN);
+			(void) strlcat(x->d86_mneu, dis_PREDSUFFIX[pred],
 			    OPLEN);
-			strlcat(x->d86_mneu,
+			(void) strlcat(x->d86_mneu,
 			    dp->it_name + strlen(dp->it_name) - 2,
 			    OPLEN);
 			x->d86_opnd[0] = x->d86_opnd[1];
@@ -2664,19 +2665,19 @@
 		dtrace_check_override(x, 0);
 		x->d86_numopnds = 2;
 		if (addr_size == SIZE64) {
-			strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
+			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
 			    OPLEN);
-			strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
+			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
 			    OPLEN);
 		} else if (addr_size == SIZE32) {
-			strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
+			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
 			    OPLEN);
-			strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
+			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
 			    OPLEN);
 		} else {
-			strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
+			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
 			    OPLEN);
-			strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
+			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
 			    OPLEN);
 		}
 #endif
@@ -2691,13 +2692,13 @@
 		x->d86_numopnds = 2;
 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 0);
 		if (addr_size == SIZE64)
-			strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
+			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%rdi)",
 			    OPLEN);
 		else if (addr_size == SIZE32)
-			strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
+			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%edi)",
 			    OPLEN);
 		else
-			strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
+			(void) strlcat(x->d86_opnd[1].d86_opnd, "(%di)",
 			    OPLEN);
 #endif
 		break;
@@ -2709,13 +2710,13 @@
 		dtrace_check_override(x, 0);
 		x->d86_numopnds = 2;
 		if (addr_size == SIZE64)
-			strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
+			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%rsi)",
 			    OPLEN);
 		else if (addr_size == SIZE32)
-			strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
+			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%esi)",
 			    OPLEN);
 		else
-			strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
+			(void) strlcat(x->d86_opnd[0].d86_opnd, "(%si)",
 			    OPLEN);
 		dtrace_get_operand(x, REG_ONLY, EAX_REGNO, wbit, 1);
 #endif
@@ -2733,7 +2734,7 @@
 	/* jmp/call indirect to memory or register operand		*/
 	case INM:
 #ifdef DIS_TEXT
-		strlcat(x->d86_opnd[0].d86_prefix, "*", OPLEN);
+		(void) strlcat(x->d86_opnd[0].d86_prefix, "*", OPLEN);
 #endif
 		dtrace_rex_adjust(rex_prefix, mode, NULL, &r_m);
 		dtrace_get_operand(x, mode, r_m, LONG_OPND, 0);
@@ -2813,7 +2814,7 @@
 		x->d86_numopnds = 1;
 		dtrace_check_override(x, 0);
 #ifdef DIS_TEXT
-		strlcat(x->d86_opnd[0].d86_opnd, "(%dx)", OPLEN);
+		(void) strlcat(x->d86_opnd[0].d86_opnd, "(%dx)", OPLEN);
 #endif
 		NOMEM;
 		break;
@@ -2854,11 +2855,11 @@
 	case CBW:
 #ifdef DIS_TEXT
 		if (opnd_size == SIZE16)
-			strlcat(x->d86_mneu, "cbtw", OPLEN);
+			(void) strlcat(x->d86_mneu, "cbtw", OPLEN);
 		else if (opnd_size == SIZE32)
-			strlcat(x->d86_mneu, "cwtl", OPLEN);
+			(void) strlcat(x->d86_mneu, "cwtl", OPLEN);
 		else
-			strlcat(x->d86_mneu, "cltq", OPLEN);
+			(void) strlcat(x->d86_mneu, "cltq", OPLEN);
 #endif
 		wbit = LONG_OPND;
 		NOMEM;
@@ -2867,11 +2868,11 @@
 	case CWD:
 #ifdef DIS_TEXT
 		if (opnd_size == SIZE16)
-			strlcat(x->d86_mneu, "cwtd", OPLEN);
+			(void) strlcat(x->d86_mneu, "cwtd", OPLEN);
 		else if (opnd_size == SIZE32)
-			strlcat(x->d86_mneu, "cltd", OPLEN);
+			(void) strlcat(x->d86_mneu, "cltd", OPLEN);
 		else
-			strlcat(x->d86_mneu, "cqtd", OPLEN);
+			(void) strlcat(x->d86_mneu, "cqtd", OPLEN);
 #endif
 		wbit = LONG_OPND;
 		NOMEM;
@@ -2887,9 +2888,9 @@
 		/* sfence doesn't take operands */
 #ifdef DIS_TEXT
 		if (mode == REG_ONLY) {
-			strlcat(x->d86_mneu, "sfence", OPLEN);
+			(void) strlcat(x->d86_mneu, "sfence", OPLEN);
 		} else {
-			strlcat(x->d86_mneu, "clflush", OPLEN);
+			(void) strlcat(x->d86_mneu, "clflush", OPLEN);
 			dtrace_rex_adjust(rex_prefix, mode, &reg, &r_m);
 			dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0);
 			NOMEM;
@@ -2932,7 +2933,7 @@
 	case F:
 #ifdef DIS_TEXT
 		x->d86_numopnds = 1;
-		strlcat(x->d86_opnd[0].d86_opnd, "%st(X)", OPLEN);
+		(void) strlcat(x->d86_opnd[0].d86_opnd, "%st(X)", OPLEN);
 		x->d86_opnd[0].d86_opnd[4] = r_m + '0';
 #endif
 		NOMEM;
@@ -2945,8 +2946,8 @@
 	case FFC:				/* case for vbit always = 0 */
 #ifdef DIS_TEXT
 		x->d86_numopnds = 2;
-		strlcat(x->d86_opnd[1 - vbit].d86_opnd, "%st", OPLEN);
-		strlcat(x->d86_opnd[vbit].d86_opnd, "%st(X)", OPLEN);
+		(void) strlcat(x->d86_opnd[1 - vbit].d86_opnd, "%st", OPLEN);
+		(void) strlcat(x->d86_opnd[vbit].d86_opnd, "%st(X)", OPLEN);
 		x->d86_opnd[vbit].d86_opnd[4] = r_m + '0';
 #endif
 		NOMEM;
@@ -3022,7 +3023,7 @@
 
 error:
 #ifdef DIS_TEXT
-	strlcat(x->d86_mneu, "undef", OPLEN);
+	(void) strlcat(x->d86_mneu, "undef", OPLEN);
 #endif
 	return (1);
 }
@@ -3075,6 +3076,12 @@
 
 	dis->d86_sprintf_func(buf, buflen, "%-6s ", dis->d86_mneu);
 
+	/*
+	 * For PC-relative jumps, the pc is really the next pc after executing
+	 * this instruction, so increment it appropriately.
+	 */
+	pc += dis->d86_len;
+
 	for (i = 0; i < dis->d86_numopnds; i++) {
 		d86opnd_t *op = &dis->d86_opnd[i];
 		int64_t sv;
@@ -3099,7 +3106,8 @@
 		case MODE_OFFSET:
 
 			if (dis->d86_seg_prefix)
-				strlcat(buf, dis->d86_seg_prefix, buflen);
+				(void) strlcat(buf, dis->d86_seg_prefix,
+				    buflen);
 
 			switch (op->d86_value_size) {
 			case 1:
@@ -3121,7 +3129,7 @@
 
 			if (op->d86_mode == MODE_SIGNED ||
 			    op->d86_mode == MODE_IMPLIED)
-				strlcat(buf, "$", buflen);
+				(void) strlcat(buf, "$", buflen);
 
 			if (sv < 0 && sv > -0xffff &&
 			    !isunsigned_op(dis->d86_mneu)) {
@@ -3135,7 +3143,7 @@
 				    (dis->d86_flags & DIS_OP_OCTAL) ?
 				    "0%llo" : "0x%llx", sv & mask);
 			}
-			strlcat(buf, op->d86_opnd, buflen);
+			(void) strlcat(buf, op->d86_opnd, buflen);
 			break;
 
 		case MODE_IPREL:
@@ -3163,17 +3171,17 @@
 				    (dis->d86_flags & DIS_OP_OCTAL) ?
 				    "+0%llo" : "+0x%llx", sv + dis->d86_len);
 
-			strlcat(buf, "\t<", buflen);
+			(void) strlcat(buf, "\t<", buflen);
 
 			if (dis->d86_sym_lookup == NULL ||
-			    dis->d86_sym_lookup(pc + sv, buf + strlen(buf),
-			    buflen - strlen(buf)) != 0)
+			    dis->d86_sym_lookup(dis->d86_data, pc + sv,
+			    buf + strlen(buf), buflen - strlen(buf)) != 0)
 				dis->d86_sprintf_func(buf + strlen(buf),
 				    buflen - strlen(buf),
 				    (dis->d86_flags & DIS_OP_OCTAL) ?
 				    "0%llo" : "0x%llx", pc + sv);
 
-			strlcat(buf, ">", buflen);
+			(void) strlcat(buf, ">", buflen);
 
 			break;
 		}
--- a/usr/src/common/dis/i386/dis_tables.h	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/common/dis/i386/dis_tables.h	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -82,10 +81,10 @@
 	uint_t		d86_addr_size;
 	uint_t		d86_got_modrm;
 	struct d86opnd	d86_opnd[3];		/* up to 3 operands */
-	int		(*d86_check_func)();
+	int		(*d86_check_func)(void *);
 	int		(*d86_get_byte)(void *);
 #ifdef DIS_TEXT
-	int		(*d86_sym_lookup)(uint64_t, char *, size_t);
+	int		(*d86_sym_lookup)(void *, uint64_t, char *, size_t);
 	int		(*d86_sprintf_func)(char *, size_t, const char *, ...);
 	int		d86_flags;
 	uint_t		d86_imm_bytes;
--- a/usr/src/lib/Makefile	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/lib/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -177,6 +177,7 @@
 	watchmalloc	\
 	madv		\
 	mpss		\
+	libdisasm	\
 	libwrap		\
 	libxcurses	\
 	libxcurses2	\
@@ -306,6 +307,7 @@
 	libdhcpagent	\
 	libdhcpsvc	\
 	libdhcputil	\
+	libdisasm	\
 	libdtrace	\
 	libdtrace_jni	\
 	libeti		\
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdisasm/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,60 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+
+
+include ../Makefile.lib
+
+HDRS=		libdisasm.h
+
+HDRDIR=		common
+$(INTEL_BLD)SUBDIRS= $(MACH)
+$(INTEL_BLD)$(BUILD64)SUBDIRS += $(MACH64)
+$(CLOSED_BLD)SUBDIRS += $(CLOSED)/lib/libdisasm
+
+all := 		TARGET = all
+clean :=	TARGET = clean
+clobber :=	TARGET = clobber
+install	:=	TARGET = install
+lint :=		TARGET = lint
+
+.KEEP_STATE:
+
+$(INTEL_BLD)SPECDIR= spec
+
+all clean clobber install: $(SPECDIR) .WAIT $(SUBDIRS)
+
+lint: $(SUBDIRS)
+
+install_h:	$(ROOTHDRS)
+
+check:		$(CHECKHDRS)
+
+$(SUBDIRS) spec: FRC
+	@cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include ../Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdisasm/Makefile.com	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,141 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+
+#
+# The build process for libdisasm is sightly different from that used by other
+# libraries, because libdisasm must be built in two flavors - as a standalone
+# for use by kmdb and as a normal library.  We use $(CURTYPE) to indicate the
+# current flavor being built.
+#
+# The SPARC library is built from the closed gate.  This Makefile is shared
+# between both environments, so all paths must be absolute.
+#
+
+LIBRARY=	libdisasm.a
+STANDLIBRARY=	libstanddisasm.so
+VERS=		.1
+
+# By default, we build the shared library.  Construction of the standalone
+# is specifically requested by architecture-specific Makefiles.
+TYPES=		library
+CURTYPE=	library
+
+COMDIR=		$(SRC)/lib/libdisasm/common
+SPECDIR=	$(SRC)/lib/libdisasm/spec
+
+# Files specific to the library version of libdisasm
+OBJECTS_library =
+SRC_libary = $(OBJECTS_library:%.o=$(COMDIR)/%.c)
+
+#
+# Architecture-dependent files common to both versions of libdisasm
+#
+OBJECTS_common_i386 = dis_i386.o dis_tables.o
+OBJECTS_common_sparc = dis_sparc.o
+
+SRCS_common_i386 = $(ISASRCDIR)/dis_i386.c $(SRC)/common/dis/i386/dis_tables.c
+SRCS_common_sparc = $(ISASRCDIR)/dis_sparc.c
+
+#
+# Architecture-independent files common to both version of libdisasm
+#
+OBJECTS_common_common = libdisasm.o
+SRC_common_common = $(OBJECTS_common_common:%.o=$(COMDIR)/%.c)
+
+
+OBJECTS=				\
+	$(OBJECTS_$(CURTYPE))		\
+	$(OBJECTS_common_$(MACH))	\
+	$(OBJECTS_common_common)
+
+include $(SRC)/lib/Makefile.lib
+
+SRCS=					\
+	$(SRCS_$(CURTYPE))		\
+	$(SRCS_common_$(MACH))		\
+	$(SRCS_common_common)
+
+#
+# Used to verify that the standalone doesn't have any unexpected external
+# dependencies.
+#
+LINKTEST_OBJ = objs/linktest_stand.o
+
+CLOBBERFILES_standalone = $(LINKTEST_OBJ)
+CLOBBERFILES += $(CLOBBERFILES_$(CURTYPE))
+
+LIBS_standalone	= $(STANDLIBRARY)
+LIBS_library = $(DYNLIB) $(LINTLIB)
+LIBS = $(LIBS_$(CURTYPE))
+
+MAPDIR=		$(SPECDIR)/$(TRANSMACH)
+SPECMAPFILE=	$(MAPDIR)/mapfile
+
+LDLIBS +=	-lc
+
+LDFLAGS_standalone = -znoversion -Breduce -dy -r
+LDFLAGS = $(LDFLAGS_$(CURTYPE))
+
+ASFLAGS_standalone = -DDIS_STANDALONE
+ASFLAGS_library =
+ASFLAGS += -P $(ASFLAGS_$(CURTYPE)) -D_ASM
+
+$(LINTLIB) := SRCS = $(COMDIR)/$(LINTSRC)
+
+# We want the thread-specific errno in the library, but we don't want it in
+# the standalone.  $(DTS_ERRNO) is designed to add -D_TS_ERRNO to $(CPPFLAGS),
+# in order to enable this feature.  Conveniently, -D_REENTRANT does the same
+# thing.  As such, we null out $(DTS_ERRNO) to ensure that the standalone
+# doesn't get it.
+DTS_ERRNO=
+
+# We need to rename some standard functions so we can easily implement them 
+# in consumers.
+STAND_RENAMED_FUNCS= \
+	snprintf
+
+CPPFLAGS_standalone = -DDIS_STANDALONE $(STAND_RENAMED_FUNCS:%=-D%=mdb_%) \
+	-I$(SRC)/cmd/mdb/common
+CPPFLAGS_library = -D_REENTRANT
+CPPFLAGS +=	-I$(COMDIR) $(CPPFLAGS_$(CURTYPE))
+
+#
+# For x86, we have to link to sources in usr/src/common
+#
+CPPFLAGS_dis_i386 = -I$(SRC)/common/dis/i386 -DDIS_TEXT
+CPPFLAGS_dis_sparc =
+CPPFLAGS +=	$(CPPFLAGS_dis_$(MACH))
+
+CFLAGS_standalone = $(STAND_FLAGS_32)
+CFLAGS_common =
+CFLAGS += $(CFLAGS_$(CURTYPE)) $(CFLAGS_common)
+
+CFLAGS64_standalone = $(STAND_FLAGS_64)
+CFLAGS64 += $(CCVERBOSE) $(CFLAGS64_$(CURTYPE)) $(CFLAGS64_common)
+
+DYNFLAGS +=     $(ZINTERPOSE)
+
+.KEEP_STATE:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdisasm/Makefile.targ	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,100 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+# We build each flavor in a separate make invocation to improve clarity(!) in
+# Makefile.com.  The subordinate makes have $(CURTYPE) set to indicate the
+# flavor they're supposed to build.  This causes the correct set of source
+# files and compiler and linker flags to be selected.
+#
+# The SPARC library is built from the closed gate.  This Makefile is shared
+# between both environments, so all paths must be absolute.
+#
+
+install: $(TYPES:%=install.%)
+
+all: $(TYPES:%=all.%)
+
+$(TYPES:%=all.%):
+	@CURTYPE=$(@:all.%=%) $(MAKE) [email protected]
+
+$(TYPES:%=install.%):
+	@CURTYPE=$(@:install.%=%) $(MAKE) [email protected]
+
+install.library.targ: all.library $(INSTALL_DEPS_library)
+install.standalone.targ: all.standalone $(INSTALL_DEPS_standalone)
+
+all.library.targ: $(LIBS)
+all.standalone.targ: $(STANDLIBRARY)
+
+lint: $(TYPES:%=lint.%)
+
+$(TYPES:%=lint.%):
+	@CURTYPE=$(@:lint.%=%) $(MAKE) lintcheck
+
+$(STANDLIBRARY): $(OBJS) $(LINKTEST_OBJ)
+	$(LD) -Breduce -zdefs $(LDFLAGS) -o [email protected] $(OBJS) $(LINKTEST_OBJ)
+	rm [email protected]
+	$(LD) $(LDFLAGS) -o $@ $(OBJS)
+
+$(DYNLIB):	$(MAPFILE)
+
+$(MAPFILE):
+	@cd $(MAPDIR); $(MAKE) mapfile
+
+clobber: $(TYPES:%=clobber.%)
+
+$(TYPES:%=clobber.%):
+	@CURTYPE=$(@:clobber.%=%) $(MAKE) clobber.targ
+
+clobber.targ: clean
+	-$(RM) $(CLOBBERTARGFILES)
+
+# include library targets
+include $(SRC)/lib/Makefile.targ
+
+$(PICS): pics
+$(OBJS): objs
+
+objs/%.o pics/%.o: $(ISASRCDIR)/%.c
+	$(COMPILE.c) -o $@ $<
+	$(POST_PROCESS_O)
+
+objs/%.o pics/%.o: $(ISASRCDIR)/%.s
+	$(COMPILE.s) -o $@ $<
+	$(POST_PROCESS_O)
+
+objs/%.o pics/%.o: $(COMDIR)/%.c
+	$(COMPILE.c) -o $@ $<
+	$(POST_PROCESS_O)
+
+# install rule for lint library target
+$(ROOTLINTDIR)/%: $(COMDIR)/%
+	$(INS.file)
+
+# install rule for x86 common source
+objs/%.o pics/%.o: $(SRC)/common/dis/i386/%.c
+	$(COMPILE.c) -o $@ $<
+	$(POST_PROCESS_O)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdisasm/amd64/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,37 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+
+ISASRCDIR=../$(MACH)/
+
+include ../Makefile.com
+include ../../Makefile.lib.64
+
+TYPES=library standalone
+
+INSTALL_DEPS_library = $(ROOTLINKS64) $(ROOTLINT64) $(ROOTLIBS64)
+INSTALL_DEPS_standalone = $(ROOTLIBS64)
+
+include ../Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdisasm/common/libdisasm.c	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,92 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <libdisasm.h>
+#include <stdlib.h>
+#ifdef DIS_STANDALONE
+#include <mdb/mdb_modapi.h>
+#endif
+
+static int _dis_errno;
+
+/*
+ * For the standalone library, we need to link against mdb's malloc/free.
+ * Otherwise, use the standard malloc/free.
+ */
+#ifdef DIS_STANDALONE
+void *
+dis_zalloc(size_t bytes)
+{
+	return (mdb_zalloc(bytes, UM_SLEEP));
+}
+
+void
+dis_free(void *ptr, size_t bytes)
+{
+	mdb_free(ptr, bytes);
+}
+#else
+void *
+dis_zalloc(size_t bytes)
+{
+	return (calloc(1, bytes));
+}
+
+/*ARGSUSED*/
+void
+dis_free(void *ptr, size_t bytes)
+{
+	free(ptr);
+}
+#endif
+
+int
+dis_seterrno(int error)
+{
+	_dis_errno = error;
+	return (-1);
+}
+
+int
+dis_errno(void)
+{
+	return (_dis_errno);
+}
+
+const char *
+dis_strerror(int error)
+{
+	switch (error) {
+	case E_DIS_NOMEM:
+		return ("out of memory");
+	case E_DIS_INVALFLAG:
+		return ("invalid flags for this architecture");
+	default:
+		return ("unknown error");
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdisasm/common/libdisasm.h	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_LIBDISASM_H
+#define	_LIBDISASM_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <sys/types.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct dis_handle dis_handle_t;
+
+#define	DIS_DEFAULT		0x0
+
+/* SPARC disassembler flags */
+#define	DIS_SPARC_V8		0x01
+#define	DIS_SPARC_V9		0x02
+#define	DIS_SPARC_V9_SGI	0x04
+
+/* x86 diassembler flags (mutually exclusive) */
+#define	DIS_X86_SIZE16		0x08
+#define	DIS_X86_SIZE32		0x10
+#define	DIS_X86_SIZE64		0x20
+
+/* generic disassembler flags */
+#define	DIS_OCTAL		0x40
+
+typedef int (*dis_lookup_f)(void *, uint64_t, char *, size_t, uint64_t *,
+    size_t *);
+typedef int (*dis_read_f)(void *, uint64_t, void *, size_t);
+
+extern dis_handle_t *dis_handle_create(int, void *, dis_lookup_f, dis_read_f);
+extern void dis_handle_destroy(dis_handle_t *);
+
+extern int dis_disassemble(dis_handle_t *, uint64_t, char *, size_t);
+extern uint64_t dis_previnstr(dis_handle_t *, uint64_t, int n);
+extern void dis_set_data(dis_handle_t *, void *);
+extern int dis_max_instrlen(dis_handle_t *);
+
+/* libdisasm errors */
+#define	E_DIS_NOMEM		1	/* Out of memory */
+#define	E_DIS_INVALFLAG		2	/* Invalid flag for this architecture */
+
+extern int dis_errno(void);
+extern const char *dis_strerror(int);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _LIBDISASM_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdisasm/common/libdisasm_impl.h	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_LIBDISASM_IMPL_H
+#define	_LIBDISASM_IMPL_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+extern int dis_seterrno(int);
+
+extern void *dis_zalloc(size_t);
+extern void dis_free(void *, size_t);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _LIBDISASM_IMPL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdisasm/common/linktest_stand.c	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/*
+ * This file is used to verify that the standalone's external dependencies
+ * haven't changed in a way that'll break things that use it.
+ */
+
+void mdb_free(void) {}
+void snprintf(void) {}
+void mdb_zalloc(void) {}
+void strcmp(void) {}
+void strlen(void) {}
+void strlcat(void) {}
+void strncpy(void) {}
+void strncmp(void) {}
+void memcpy(void) {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdisasm/common/llib-ldisasm	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,35 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*LINTLIBRARY*/
+/*PROTOLIB1*/
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/* LINTLIBRARY */
+/* PROTOLIB1 */
+
+#include <libdisasm.h>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdisasm/i386/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+
+ISASRCDIR=.
+
+include ../Makefile.com
+
+TYPES=library standalone
+
+INSTALL_DEPS_library =		$(ROOTLINKS) $(ROOTLINT) $(ROOTLIBS)
+INSTALL_DEPS_standalone =	$(ROOTLIBS)
+
+include ../Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdisasm/i386/dis_i386.c	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,225 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <libdisasm.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "dis_tables.h"
+#include "libdisasm_impl.h"
+
+struct dis_handle {
+	void		*dh_data;
+	int		dh_flags;
+	dis_lookup_f	dh_lookup;
+	dis_read_f	dh_read;
+	int		dh_mode;
+	dis86_t		dh_dis;
+	uint64_t	dh_addr;
+	uint64_t	dh_end;
+};
+
+/*
+ * Returns true if we are near the end of a function.  This is a cheap hack at
+ * detecting NULL padding between functions.  If we're within a few bytes of the
+ * next function, or past the start, then return true.
+ */
+static int
+check_func(void *data)
+{
+	dis_handle_t *dhp = data;
+	uint64_t start;
+	size_t len;
+
+	if (dhp->dh_lookup(dhp->dh_data, dhp->dh_addr, NULL, 0, &start, &len)
+	    != 0)
+		return (0);
+
+	if (start < dhp->dh_addr)
+		return (dhp->dh_addr > start + len - 0x10);
+
+	return (1);
+}
+
+static int
+get_byte(void *data)
+{
+	uchar_t byte;
+	dis_handle_t *dhp = data;
+
+	if (dhp->dh_read(dhp->dh_data, dhp->dh_addr, &byte,
+	    sizeof (byte)) < sizeof (byte))
+		return (-1);
+
+	dhp->dh_addr++;
+
+	return ((int)byte);
+}
+
+static int
+do_lookup(void *data, uint64_t addr, char *buf, size_t buflen)
+{
+	dis_handle_t *dhp = data;
+
+	return (dhp->dh_lookup(dhp->dh_data, addr, buf, buflen, NULL, NULL));
+}
+
+dis_handle_t *
+dis_handle_create(int flags, void *data, dis_lookup_f lookup_func,
+    dis_read_f read_func)
+{
+	dis_handle_t *dhp;
+
+	/*
+	 * Validate architecture flags
+	 */
+	if (flags & ~(DIS_X86_SIZE16 | DIS_X86_SIZE32 | DIS_X86_SIZE64 |
+	    DIS_OCTAL)) {
+		(void) dis_seterrno(E_DIS_INVALFLAG);
+		return (NULL);
+	}
+
+	/*
+	 * Create and initialize the internal structure
+	 */
+	if ((dhp = dis_zalloc(sizeof (struct dis_handle))) == NULL) {
+		(void) dis_seterrno(E_DIS_NOMEM);
+		return (NULL);
+	}
+
+	dhp->dh_lookup = lookup_func;
+	dhp->dh_read = read_func;
+	dhp->dh_flags = flags;
+	dhp->dh_data = data;
+
+	/*
+	 * Initialize x86-specific architecture structure
+	 */
+	if (flags & DIS_X86_SIZE16)
+		dhp->dh_mode = SIZE16;
+	else if (flags & DIS_X86_SIZE64)
+		dhp->dh_mode = SIZE64;
+	else
+		dhp->dh_mode = SIZE32;
+
+	if (flags & DIS_OCTAL)
+		dhp->dh_dis.d86_flags = DIS_OP_OCTAL;
+
+	dhp->dh_dis.d86_sprintf_func = snprintf;
+	dhp->dh_dis.d86_get_byte = get_byte;
+	dhp->dh_dis.d86_sym_lookup = do_lookup;
+	dhp->dh_dis.d86_check_func = check_func;
+
+	dhp->dh_dis.d86_data = dhp;
+
+	return (dhp);
+}
+
+int
+dis_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen)
+{
+	dhp->dh_addr = addr;
+
+	if (dtrace_disx86(&dhp->dh_dis, dhp->dh_mode) != 0)
+		return (-1);
+
+	if (buf != NULL)
+		dtrace_disx86_str(&dhp->dh_dis, dhp->dh_mode, addr, buf,
+		    buflen);
+
+	return (0);
+}
+
+void
+dis_handle_destroy(dis_handle_t *dhp)
+{
+	dis_free(dhp, sizeof (dis_handle_t));
+}
+
+void
+dis_set_data(dis_handle_t *dhp, void *data)
+{
+	dhp->dh_data = data;
+}
+
+/* ARGSUSED */
+int
+dis_max_instrlen(dis_handle_t *dhp)
+{
+	return (15);
+}
+
+#define	MIN(a, b)	((a) < (b) ? (a) : (b))
+
+/*
+ * Return the previous instruction.  On x86, we have no choice except to
+ * disassemble everything from the start of the symbol, and stop when we have
+ * reached our instruction address.  If we're not in the middle of a known
+ * symbol, then we return the same address to indicate failure.
+ */
+uint64_t
+dis_previnstr(dis_handle_t *dhp, uint64_t pc, int n)
+{
+	uint64_t *hist, addr, start;
+	int cur, nseen;
+	uint64_t res = pc;
+
+	if (dhp->dh_lookup(dhp->dh_data, pc, NULL, 0, &start, NULL) != 0 ||
+	    start == pc)
+		return (res);
+
+	hist = dis_zalloc(sizeof (uint64_t) * n);
+
+	for (cur = 0, nseen = 0, addr = start; addr < pc; addr = dhp->dh_addr) {
+		hist[cur] = addr;
+		cur = (cur + 1) % n;
+		nseen++;
+
+		/* if we cannot make forward progress, give up */
+		if (dis_disassemble(dhp, addr, NULL, 0) != 0)
+			goto done;
+	}
+
+	if (addr != pc) {
+		/*
+		 * We scanned past %pc, but didn't find an instruction that
+		 * started at %pc.  This means that either the caller specified
+		 * an invalid address, or we ran into something other than code
+		 * during our scan.  Virtually any combination of bytes can be
+		 * construed as a valid Intel instruction, so any non-code bytes
+		 * we encounter will have thrown off the scan.
+		 */
+		goto done;
+	}
+
+	res = hist[(cur + n - MIN(n, nseen)) % n];
+
+done:
+	dis_free(hist, sizeof (uint64_t) * n);
+	return (res);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdisasm/spec/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,27 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+
+include $(SRC)/lib/Makefile.spec.arch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdisasm/spec/Makefile.targ	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+
+LIBRARY=        libdisasm.a
+VERS=           .1
+
+OBJECTS=        libdisasm.o
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdisasm/spec/amd64/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,34 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+include $(SRC)/lib/Makefile.spec
+
+install: $(ROOTABILIB64)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdisasm/spec/i386/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,33 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.spec
+
+install: $(ROOTABILIB)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdisasm/spec/libdisasm.spec	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,57 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#ident	"%Z%%M%	%I%	%E% SMI"
+
+function	dis_disassemble
+version		SUNWprivate_1.1
+end
+
+function	dis_errno
+version		SUNWprivate_1.1
+end
+
+function	dis_handle_create
+version		SUNWprivate_1.1
+end
+
+function	dis_handle_destroy
+version		SUNWprivate_1.1
+end
+
+function	dis_max_instrlen
+version		SUNWprivate_1.1
+end
+
+function	dis_previnstr
+version		SUNWprivate_1.1
+end
+
+function	dis_set_data
+version		SUNWprivate_1.1
+end
+
+function	dis_strerror
+version		SUNWprivate_1.1
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdisasm/spec/sparc/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,33 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.spec
+
+install: $(ROOTABILIB)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdisasm/spec/sparcv9/Makefile	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,34 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+include $(SRC)/lib/Makefile.spec
+
+install: $(ROOTABILIB64)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdisasm/spec/versions	Fri Mar 03 22:38:03 2006 -0800
@@ -0,0 +1,43 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#ident	"%Z%%M%	%I%	%E% SMI"
+
+sparc {
+        SUNW_1.1;
+        SUNWprivate_1.1;
+}
+sparcv9 {
+        SUNW_1.1;
+        SUNWprivate_1.1;
+}
+i386 {
+        SUNW_1.1;
+        SUNWprivate_1.1;
+}
+amd64 {
+        SUNW_1.1;
+        SUNWprivate_1.1;
+}
--- a/usr/src/pkgdefs/SUNWcsl/prototype_com	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/pkgdefs/SUNWcsl/prototype_com	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -109,6 +108,8 @@
 s none usr/lib/libdevinfo.so.1=../../lib/libdevinfo.so.1
 s none usr/lib/libdhcpagent.so.1=../../lib/libdhcpagent.so.1
 s none usr/lib/libdhcputil.so.1=../../lib/libdhcputil.so.1
+f none usr/lib/libdisasm.so.1 755 root bin
+s none usr/lib/libdisasm.so=./libdisasm.so.1
 s none usr/lib/libdl.so=../../lib/libdl.so.1
 s none usr/lib/libdl.so.1=../../lib/libdl.so.1
 s none usr/lib/libdoor.so=../../lib/libdoor.so.1
--- a/usr/src/pkgdefs/SUNWcsl/prototype_i386	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/pkgdefs/SUNWcsl/prototype_i386	Fri Mar 03 22:38:03 2006 -0800
@@ -20,7 +20,7 @@
 #
 
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -219,6 +219,8 @@
 s none usr/lib/amd64/libdevid.so=../../../lib/amd64/libdevid.so.1
 s none usr/lib/amd64/libdevinfo.so.1=../../../lib/amd64/libdevinfo.so.1
 s none usr/lib/amd64/libdevinfo.so=../../../lib/amd64/libdevinfo.so.1
+f none usr/lib/amd64/libdisasm.so.1 755 root bin
+s none usr/lib/amd64/libdisasm.so=libdisasm.so.1
 s none usr/lib/amd64/libdl.so.1=../../../lib/amd64/libdl.so.1
 s none usr/lib/amd64/libdl.so=../../../lib/amd64/libdl.so.1
 s none usr/lib/amd64/libdoor.so.1=../../../lib/amd64/libdoor.so.1
--- a/usr/src/pkgdefs/SUNWcsl/prototype_sparc	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/pkgdefs/SUNWcsl/prototype_sparc	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -150,6 +149,8 @@
 s none usr/lib/sparcv9/libctf.so=../../../lib/sparcv9/libctf.so.1
 s none usr/lib/sparcv9/libcurses.so.1=../../../lib/sparcv9/libcurses.so.1
 s none usr/lib/sparcv9/libcurses.so=../../../lib/sparcv9/libcurses.so.1
+f none usr/lib/sparcv9/libdisasm.so.1 755 root bin
+s none usr/lib/sparcv9/libdisasm.so=libdisasm.so.1
 f none usr/lib/sparcv9/libform.so.1 755 root bin
 s none usr/lib/sparcv9/libform.so=libform.so.1
 s none usr/lib/sparcv9/libgen.so.1=../../../lib/sparcv9/libgen.so.1
--- a/usr/src/pkgdefs/SUNWmdb/prototype_sparc	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/pkgdefs/SUNWmdb/prototype_sparc	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
@@ -38,9 +37,6 @@
 d none usr/bin/sparcv9 755 root bin
 f none usr/bin/sparcv9/mdb 555 root bin
 l none usr/bin/sparcv9/adb=../../../usr/bin/sparcv9/mdb
-f none usr/lib/mdb/disasm/sparc.so 555 root sys
-d none usr/lib/mdb/disasm/sparcv9 755 root sys
-f none usr/lib/mdb/disasm/sparcv9/sparc.so 555 root sys
 d none usr/lib/mdb/kvm/sparcv9 755 root sys
 f none usr/lib/mdb/kvm/sparcv9/audiosup.so 555 root sys
 f none usr/lib/mdb/kvm/sparcv9/cpc.so 555 root sys
--- a/usr/src/pkgdefs/SUNWmdbr/prototype_sparc	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/pkgdefs/SUNWmdbr/prototype_sparc	Fri Mar 03 22:38:03 2006 -0800
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -54,7 +53,6 @@
 f none kernel/kmdb/sparcv9/sctp 555 root sys
 f none kernel/kmdb/sparcv9/s1394 555 root sys
 f none kernel/kmdb/sparcv9/sd 555 root sys
-f none kernel/kmdb/sparcv9/sparc 555 root sys
 f none kernel/kmdb/sparcv9/specfs 555 root sys
 f none kernel/kmdb/sparcv9/sppp 555 root sys
 f none kernel/kmdb/sparcv9/ssd 555 root sys
--- a/usr/src/pkgdefs/etc/exception_list_i386	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/pkgdefs/etc/exception_list_i386	Fri Mar 03 22:38:03 2006 -0800
@@ -414,6 +414,13 @@
 lib/llib-lproc.ln		i386
 lib/amd64/llib-lproc.ln		i386
 #
+# Private interfaces for libdisasm
+#
+usr/include/libdisasm.h		i386
+usr/lib/llib-ldisasm		i386
+usr/lib/llib-ldisasm.ln		i386
+usr/lib/amd64/llib-ldisasm.ln	i386
+#
 # This file is used for private communication between mdb, drv/kmdb, and
 # misc/kmdb.  The interfaces described herein are not intended for customer
 # use, and are thus excluded from packaging.
@@ -768,3 +775,10 @@
 #
 usr/include/sys/scsi/adapters/mpapi_impl.h	i386
 usr/include/sys/scsi/adapters/mpapi_scsi_vhci.h	i386
+
+#
+# This library is installed in the proto area by the build of libdisasm, and is
+# only used when building the KMDB disasm module.
+#
+usr/lib/libstanddisasm.so		i386
+usr/lib/amd64/libstanddisasm.so		i386
--- a/usr/src/pkgdefs/etc/exception_list_sparc	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/pkgdefs/etc/exception_list_sparc	Fri Mar 03 22:38:03 2006 -0800
@@ -421,6 +421,13 @@
 lib/llib-lproc.ln		sparc
 lib/sparcv9/llib-lproc.ln	sparc
 #
+# Private libdisasm interfaces
+#
+usr/include/libdisasm.h		sparc
+usr/lib/llib-ldisasm		sparc
+usr/lib/llib-ldisasm.ln		sparc
+usr/lib/sparcv9/llib-ldisasm.ln	sparc
+#
 # This file is used for private communication between mdb, drv/kmdb, and
 # misc/kmdb.  The interfaces described herein are not intended for customer
 # use, and are thus excluded from packaging.
@@ -829,3 +836,9 @@
 #
 usr/include/sys/scsi/adapters/mpapi_impl.h	sparc
 usr/include/sys/scsi/adapters/mpapi_scsi_vhci.h	sparc
+
+#
+# This library is installed in the proto area by the build of libdisasm, and is
+# only used when building the KMDB disasm module.
+#
+usr/lib/sparcv9/libstanddisasm.so	sparc
--- a/usr/src/tools/scripts/bfu.sh	Fri Mar 03 20:08:16 2006 -0800
+++ b/usr/src/tools/scripts/bfu.sh	Fri Mar 03 22:38:03 2006 -0800
@@ -4366,6 +4366,14 @@
 	smf_handle_new_services
 
 	#
+	# Remove obsolete disassembler module
+	#
+	if [ $target_isa = sparc ]; then 
+		rm -rf $usr/lib/mdb/disasm/*
+		rm -f $root/kernel/kmdb/sparcv9/sparc
+	fi
+
+	#
 	# Remove obsolete Sun-Fire-880 (daktari) FMA Fault Tree directory
 	# and file.  Backwards BFUs will resurrect them from the archives.
 	#