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
--- /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, ¤t->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, ®, &r_m);
dtrace_rex_adjust(rex_prefix, mode, ®, &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, ®, &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.
#