summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xBUILD/compile-pentium-mysqlfs-debug2
-rw-r--r--Makefile.am2
-rw-r--r--README94
-rw-r--r--configure.in45
-rw-r--r--include/mysql_embed.h1
-rw-r--r--pstack/Makefile.am32
-rw-r--r--pstack/aout/Makefile.am4
-rw-r--r--pstack/aout/aout64.h475
-rw-r--r--pstack/aout/stab.def264
-rw-r--r--pstack/aout/stab_gnu.h37
-rw-r--r--pstack/bucomm.c238
-rw-r--r--pstack/bucomm.h91
-rw-r--r--pstack/budbg.h64
-rw-r--r--pstack/debug.c3509
-rw-r--r--pstack/debug.h798
-rw-r--r--pstack/demangle.h90
-rw-r--r--pstack/filemode.c266
-rw-r--r--pstack/ieee.c7602
-rw-r--r--pstack/ieee.h138
-rw-r--r--pstack/libiberty.h180
-rw-r--r--pstack/linuxthreads.c90
-rw-r--r--pstack/linuxthreads.h28
-rw-r--r--pstack/pstack.c2746
-rw-r--r--pstack/pstack.h22
-rw-r--r--pstack/pstacktrace.h24
-rw-r--r--pstack/rddbg.c462
-rw-r--r--pstack/stabs.c5082
-rw-r--r--sql/Makefile.am1
-rw-r--r--sql/mysqld.cc26
29 files changed, 14 insertions, 22399 deletions
diff --git a/BUILD/compile-pentium-mysqlfs-debug b/BUILD/compile-pentium-mysqlfs-debug
index c871200604e..0f457eec0bb 100755
--- a/BUILD/compile-pentium-mysqlfs-debug
+++ b/BUILD/compile-pentium-mysqlfs-debug
@@ -6,6 +6,6 @@ path=`dirname $0`
extra_flags="$pentium_cflags $debug_cflags"
extra_configs="$pentium_configs $debug_configs $static_link"
-extra_configs="$extra_configs --with-debug=full --with-mysqlfs --without-server --without-pstack"
+extra_configs="$extra_configs --with-debug=full --with-mysqlfs --without-server"
. "$path/FINISH.sh"
diff --git a/Makefile.am b/Makefile.am
index 4ce753ad8aa..9996d187cd4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -23,7 +23,6 @@ EXTRA_DIST = INSTALL-SOURCE INSTALL-WIN-SOURCE \
SUBDIRS = . include @docs_dirs@ @zlib_dir@ \
@readline_topdir@ sql-common scripts \
- @pstack_dir@ \
@sql_union_dirs@ unittest \
@sql_server@ @man_dirs@ tests \
netware @libmysqld_dirs@ \
@@ -32,7 +31,6 @@ SUBDIRS = . include @docs_dirs@ @zlib_dir@ \
DIST_SUBDIRS = . include Docs zlib \
cmd-line-utils sql-common scripts \
- pstack \
strings mysys dbug extra regex libmysql libmysql_r client unittest storage plugin \
vio sql man tests \
netware libmysqld \
diff --git a/README b/README
index ac92d77f8bd..71491e31a8c 100644
--- a/README
+++ b/README
@@ -1192,97 +1192,3 @@ library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
***************************************************************************
-
-%%The following software may be included in this product:
-pstack (part of GNU Binutils)
-
-Use of any of this software is governed by the terms of the license below:
-
-pstack is comprised of various .c and .h files; all begin like this:
-
-/* bucomm.h -- binutils common include file.
- Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
-
-This file is part of GNU Binutils.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
-
-***************************************************************************
-
-%%The following software may be included in this product:
-libiberty.h (part of pstack GNU Binutils)
-
-Use of any of this software is governed by the terms of the license below:
-
-See
-http://www.koders.com/c/fid99F596804BBE22C076522B848D5575F142079064.aspx
-
-/* Function declarations for libiberty.
- Written by Cygnus Support, 1994.
-
- The libiberty library provides a number of functions which are
- missing on some operating systems. We do not declare those here,
- to avoid conflicts with the system header files on operating
- systems that do support those functions. In this file we only
- declare those functions which are specific to libiberty. */
-
-***************************************************************************
-
-%%The following software may be included in this product:
-ieee.h (part of pstack GNU Binutils)
-
-Use of any of this software is governed by the terms of the license below:
-
-See
-http://src.opensolaris.org/source/xref//sfw/usr/src/cmd/gdb/gdb-6.3/include/ieee.h
-
-
-/* IEEE Standard 695-1980 "Universal Format for Object Modules"
-header file
- Contributed by Cygnus Support. */
-
-***************************************************************************
-
-%%The following software may be included in this product:
-pstack.c (part of pstack GNU Binutils)
-
-Use of any of this software is governed by the terms of the license below:
-
-/*
- pstack.c -- asynchronous stack trace of a running process
- Copyright (c) 1999 Ross Thompson
- Author: Ross Thompson
- Critical bug fix: Tim Waugh
-*/
-
-/*
- This file is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.
-*/
-
-***************************************************************************
diff --git a/configure.in b/configure.in
index 7fd581af009..6c9c64d9c86 100644
--- a/configure.in
+++ b/configure.in
@@ -910,46 +910,6 @@ struct request_info *req;
])
AC_SUBST(WRAPLIBS)
-if test "$TARGET_LINUX" = "true"; then
- AC_ARG_WITH(pstack,
- [ --with-pstack Use the pstack backtrace library],
- [ USE_PSTACK=$withval ],
- [ USE_PSTACK=no ])
- pstack_libs=
- pstack_dir=
- if test "$USE_PSTACK" = yes -a "$TARGET_LINUX" = "true" -a "$BASE_MACHINE_TYPE" = "i386"
- then
- have_libiberty= have_libbfd=
- my_save_LIBS="$LIBS"
-dnl I have no idea if this is a good test - can not find docs for libiberty
- AC_CHECK_LIB([iberty], [fdmatch],
- [have_libiberty=yes
- AC_CHECK_LIB([bfd], [bfd_openr], [have_libbfd=yes], , [-liberty])])
- LIBS="$my_save_LIBS"
-
- if test x"$have_libiberty" = xyes -a x"$have_libbfd" = xyes
- then
- pstack_dir="pstack"
- pstack_libs="../pstack/libpstack.a -lbfd -liberty"
- # We must link staticly when using pstack
- with_mysqld_ldflags="-all-static"
- AC_SUBST([pstack_dir])
- AC_SUBST([pstack_libs])
- AC_DEFINE([USE_PSTACK], [1], [the pstack backtrace library])
-dnl This check isn't needed, but might be nice to give some feedback....
-dnl AC_CHECK_HEADER(libiberty.h,
-dnl have_libiberty_h=yes,
-dnl have_libiberty_h=no)
- else
- USE_PSTACK="no"
- fi
- else
- USE_PSTACK="no"
- fi
-fi
-AC_MSG_CHECKING([if we should use pstack])
-AC_MSG_RESULT([$USE_PSTACK])
-
# Check for gtty if termio.h doesn't exists
if test "$ac_cv_header_termio_h" = "no" -a "$ac_cv_header_termios_h" = "no"
then
@@ -1178,7 +1138,7 @@ dnl Is this the right match for DEC OSF on alpha?
sql/Makefile.in)
# Use gen_lex_hash.linux instead of gen_lex_hash
# Add library dependencies to mysqld_DEPENDENCIES
- lib_DEPENDENCIES="\$(pstack_libs) \$(openssl_libs) \$(yassl_libs)"
+ lib_DEPENDENCIES="\$(openssl_libs) \$(yassl_libs)"
cat > $filesed << EOF
s,\(\./gen_lex_hash\)\$(EXEEXT),\1.linux,
s%\(mysqld_DEPENDENCIES = \)%\1$lib_DEPENDENCIES %
@@ -2880,9 +2840,6 @@ esac
AC_SUBST(MAKE_BINARY_DISTRIBUTION_OPTIONS)
# Output results
-if test -d "$srcdir/pstack" ; then
- AC_CONFIG_FILES(pstack/Makefile pstack/aout/Makefile)
-fi
if test -d "$srcdir/cmd-line-utils/readline" ; then
AC_CONFIG_FILES(cmd-line-utils/readline/Makefile)
fi
diff --git a/include/mysql_embed.h b/include/mysql_embed.h
index 4a7fd3ef63c..a7d6e610918 100644
--- a/include/mysql_embed.h
+++ b/include/mysql_embed.h
@@ -20,7 +20,6 @@
/* Things we don't need in the embedded version of MySQL */
/* TODO HF add #undef HAVE_VIO if we don't want client in embedded library */
-#undef HAVE_PSTACK /* No stacktrace */
#undef HAVE_OPENSSL
#undef HAVE_SMEM /* No shared memory */
#undef HAVE_NDBCLUSTER_DB /* No NDB cluster */
diff --git a/pstack/Makefile.am b/pstack/Makefile.am
deleted file mode 100644
index 870fed6ceeb..00000000000
--- a/pstack/Makefile.am
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2000-2003, 2005 MySQL AB
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-#
-# As pstack doesn't work on all configurations, we have to use
-# the USE_PSTACK hack to get all files into distribution
-#
-
-SUBDIRS = aout
-
-INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
-
-pkglib_LIBRARIES = libpstack.a
-libpstack_a_SOURCES = bucomm.c filemode.c linuxthreads.c rddbg.c \
- debug.c ieee.c pstack.c stabs.c
-noinst_HEADERS = bucomm.h debug.h ieee.h budbg.h demangle.h \
- linuxthreads.h pstack.h pstacktrace.h
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/pstack/aout/Makefile.am b/pstack/aout/Makefile.am
deleted file mode 100644
index 2e61555db87..00000000000
--- a/pstack/aout/Makefile.am
+++ /dev/null
@@ -1,4 +0,0 @@
-noinst_HEADERS = aout64.h stab.def stab_gnu.h
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/pstack/aout/aout64.h b/pstack/aout/aout64.h
deleted file mode 100644
index 76f1140b682..00000000000
--- a/pstack/aout/aout64.h
+++ /dev/null
@@ -1,475 +0,0 @@
-/* `a.out' object-file definitions, including extensions to 64-bit fields */
-
-#ifndef __A_OUT_64_H__
-#define __A_OUT_64_H__
-
-/* This is the layout on disk of the 32-bit or 64-bit exec header. */
-
-#ifndef external_exec
-struct external_exec
-{
- bfd_byte e_info[4]; /* magic number and stuff */
- bfd_byte e_text[BYTES_IN_WORD]; /* length of text section in bytes */
- bfd_byte e_data[BYTES_IN_WORD]; /* length of data section in bytes */
- bfd_byte e_bss[BYTES_IN_WORD]; /* length of bss area in bytes */
- bfd_byte e_syms[BYTES_IN_WORD]; /* length of symbol table in bytes */
- bfd_byte e_entry[BYTES_IN_WORD]; /* start address */
- bfd_byte e_trsize[BYTES_IN_WORD]; /* length of text relocation info */
- bfd_byte e_drsize[BYTES_IN_WORD]; /* length of data relocation info */
-};
-
-#define EXEC_BYTES_SIZE (4 + BYTES_IN_WORD * 7)
-
-/* Magic numbers for a.out files */
-
-#if ARCH_SIZE==64
-#define OMAGIC 0x1001 /* Code indicating object file */
-#define ZMAGIC 0x1002 /* Code indicating demand-paged executable. */
-#define NMAGIC 0x1003 /* Code indicating pure executable. */
-
-/* There is no 64-bit QMAGIC as far as I know. */
-
-#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
- && N_MAGIC(x) != NMAGIC \
- && N_MAGIC(x) != ZMAGIC)
-#else
-#define OMAGIC 0407 /* ...object file or impure executable. */
-#define NMAGIC 0410 /* Code indicating pure executable. */
-#define ZMAGIC 0413 /* Code indicating demand-paged executable. */
-#define BMAGIC 0415 /* Used by a b.out object. */
-
-/* This indicates a demand-paged executable with the header in the text.
- It is used by 386BSD (and variants) and Linux, at least. */
-#ifndef QMAGIC
-#define QMAGIC 0314
-#endif
-# ifndef N_BADMAG
-# define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
- && N_MAGIC(x) != NMAGIC \
- && N_MAGIC(x) != ZMAGIC \
- && N_MAGIC(x) != QMAGIC)
-# endif /* N_BADMAG */
-#endif
-
-#endif
-
-#ifdef QMAGIC
-#define N_IS_QMAGIC(x) (N_MAGIC (x) == QMAGIC)
-#else
-#define N_IS_QMAGIC(x) (0)
-#endif
-
-/* The difference between TARGET_PAGE_SIZE and N_SEGSIZE is that TARGET_PAGE_SIZE is
- the finest granularity at which you can page something, thus it
- controls the padding (if any) before the text segment of a ZMAGIC
- file. N_SEGSIZE is the resolution at which things can be marked as
- read-only versus read/write, so it controls the padding between the
- text segment and the data segment (in memory; on disk the padding
- between them is TARGET_PAGE_SIZE). TARGET_PAGE_SIZE and N_SEGSIZE are the same
- for most machines, but different for sun3. */
-
-/* By default, segment size is constant. But some machines override this
- to be a function of the a.out header (e.g. machine type). */
-
-#ifndef N_SEGSIZE
-#define N_SEGSIZE(x) SEGMENT_SIZE
-#endif
-
-/* Virtual memory address of the text section.
- This is getting very complicated. A good reason to discard a.out format
- for something that specifies these fields explicitly. But til then...
-
- * OMAGIC and NMAGIC files:
- (object files: text for "relocatable addr 0" right after the header)
- start at 0, offset is EXEC_BYTES_SIZE, size as stated.
- * The text address, offset, and size of ZMAGIC files depend
- on the entry point of the file:
- * entry point below TEXT_START_ADDR:
- (hack for SunOS shared libraries)
- start at 0, offset is 0, size as stated.
- * If N_HEADER_IN_TEXT(x) is true (which defaults to being the
- case when the entry point is EXEC_BYTES_SIZE or further into a page):
- no padding is needed; text can start after exec header. Sun
- considers the text segment of such files to include the exec header;
- for BFD's purposes, we don't, which makes more work for us.
- start at TEXT_START_ADDR + EXEC_BYTES_SIZE, offset is EXEC_BYTES_SIZE,
- size as stated minus EXEC_BYTES_SIZE.
- * If N_HEADER_IN_TEXT(x) is false (which defaults to being the case when
- the entry point is less than EXEC_BYTES_SIZE into a page (e.g. page
- aligned)): (padding is needed so that text can start at a page boundary)
- start at TEXT_START_ADDR, offset TARGET_PAGE_SIZE, size as stated.
-
- Specific configurations may want to hardwire N_HEADER_IN_TEXT,
- for efficiency or to allow people to play games with the entry point.
- In that case, you would #define N_HEADER_IN_TEXT(x) as 1 for sunos,
- and as 0 for most other hosts (Sony News, Vax Ultrix, etc).
- (Do this in the appropriate bfd target file.)
- (The default is a heuristic that will break if people try changing
- the entry point, perhaps with the ld -e flag.)
-
- * QMAGIC is always like a ZMAGIC for which N_HEADER_IN_TEXT is true,
- and for which the starting address is TARGET_PAGE_SIZE (or should this be
- SEGMENT_SIZE?) (TEXT_START_ADDR only applies to ZMAGIC, not to QMAGIC).
- */
-
-/* This macro is only relevant for ZMAGIC files; QMAGIC always has the header
- in the text. */
-#ifndef N_HEADER_IN_TEXT
-#define N_HEADER_IN_TEXT(x) (((x).a_entry & (TARGET_PAGE_SIZE-1)) >= EXEC_BYTES_SIZE)
-#endif
-
-/* Sun shared libraries, not linux. This macro is only relevant for ZMAGIC
- files. */
-#ifndef N_SHARED_LIB
-#define N_SHARED_LIB(x) ((x).a_entry < TEXT_START_ADDR)
-#endif
-
-/* Returning 0 not TEXT_START_ADDR for OMAGIC and NMAGIC is based on
- the assumption that we are dealing with a .o file, not an
- executable. This is necessary for OMAGIC (but means we don't work
- right on the output from ld -N); more questionable for NMAGIC. */
-
-#ifndef N_TXTADDR
-#define N_TXTADDR(x) \
- (/* The address of a QMAGIC file is always one page in, */ \
- /* with the header in the text. */ \
- N_IS_QMAGIC (x) ? TARGET_PAGE_SIZE + EXEC_BYTES_SIZE : \
- N_MAGIC(x) != ZMAGIC ? 0 : /* object file or NMAGIC */\
- N_SHARED_LIB(x) ? 0 : \
- N_HEADER_IN_TEXT(x) ? \
- TEXT_START_ADDR + EXEC_BYTES_SIZE : /* no padding */\
- TEXT_START_ADDR /* a page of padding */\
- )
-#endif
-
-/* If N_HEADER_IN_TEXT is not true for ZMAGIC, there is some padding
- to make the text segment start at a certain boundary. For most
- systems, this boundary is TARGET_PAGE_SIZE. But for Linux, in the
- time-honored tradition of crazy ZMAGIC hacks, it is 1024 which is
- not what TARGET_PAGE_SIZE needs to be for QMAGIC. */
-
-#ifndef ZMAGIC_DISK_BLOCK_SIZE
-#define ZMAGIC_DISK_BLOCK_SIZE TARGET_PAGE_SIZE
-#endif
-
-#define N_DISK_BLOCK_SIZE(x) \
- (N_MAGIC(x) == ZMAGIC ? ZMAGIC_DISK_BLOCK_SIZE : TARGET_PAGE_SIZE)
-
-/* Offset in an a.out of the start of the text section. */
-#ifndef N_TXTOFF
-#define N_TXTOFF(x) \
- (/* For {O,N,Q}MAGIC, no padding. */ \
- N_MAGIC(x) != ZMAGIC ? EXEC_BYTES_SIZE : \
- N_SHARED_LIB(x) ? 0 : \
- N_HEADER_IN_TEXT(x) ? \
- EXEC_BYTES_SIZE : /* no padding */\
- ZMAGIC_DISK_BLOCK_SIZE /* a page of padding */\
- )
-#endif
-/* Size of the text section. It's always as stated, except that we
- offset it to `undo' the adjustment to N_TXTADDR and N_TXTOFF
- for ZMAGIC files that nominally include the exec header
- as part of the first page of text. (BFD doesn't consider the
- exec header to be part of the text segment.) */
-#ifndef N_TXTSIZE
-#define N_TXTSIZE(x) \
- (/* For QMAGIC, we don't consider the header part of the text section. */\
- N_IS_QMAGIC (x) ? (x).a_text - EXEC_BYTES_SIZE : \
- (N_MAGIC(x) != ZMAGIC || N_SHARED_LIB(x)) ? (x).a_text : \
- N_HEADER_IN_TEXT(x) ? \
- (x).a_text - EXEC_BYTES_SIZE: /* no padding */\
- (x).a_text /* a page of padding */\
- )
-#endif
-/* The address of the data segment in virtual memory.
- It is the text segment address, plus text segment size, rounded
- up to a N_SEGSIZE boundary for pure or pageable files. */
-#ifndef N_DATADDR
-#define N_DATADDR(x) \
- (N_MAGIC(x)==OMAGIC? (N_TXTADDR(x)+N_TXTSIZE(x)) \
- : (N_SEGSIZE(x) + ((N_TXTADDR(x)+N_TXTSIZE(x)-1) & ~(N_SEGSIZE(x)-1))))
-#endif
-/* The address of the BSS segment -- immediately after the data segment. */
-
-#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)
-
-/* Offsets of the various portions of the file after the text segment. */
-
-/* For {Q,Z}MAGIC, there is padding to make the data segment start on
- a page boundary. Most of the time the a_text field (and thus
- N_TXTSIZE) already contains this padding. It is possible that for
- BSDI and/or 386BSD it sometimes doesn't contain the padding, and
- perhaps we should be adding it here. But this seems kind of
- questionable and probably should be BSDI/386BSD-specific if we do
- do it.
-
- For NMAGIC (at least for hp300 BSD, probably others), there is
- padding in memory only, not on disk, so we must *not* ever pad here
- for NMAGIC. */
-
-#ifndef N_DATOFF
-#define N_DATOFF(x) \
- (N_TXTOFF(x) + N_TXTSIZE(x))
-#endif
-
-#ifndef N_TRELOFF
-#define N_TRELOFF(x) ( N_DATOFF(x) + (x).a_data )
-#endif
-#ifndef N_DRELOFF
-#define N_DRELOFF(x) ( N_TRELOFF(x) + (x).a_trsize )
-#endif
-#ifndef N_SYMOFF
-#define N_SYMOFF(x) ( N_DRELOFF(x) + (x).a_drsize )
-#endif
-#ifndef N_STROFF
-#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms )
-#endif
-
-/* Symbols */
-#ifndef external_nlist
-struct external_nlist {
- bfd_byte e_strx[BYTES_IN_WORD]; /* index into string table of name */
- bfd_byte e_type[1]; /* type of symbol */
- bfd_byte e_other[1]; /* misc info (usually empty) */
- bfd_byte e_desc[2]; /* description field */
- bfd_byte e_value[BYTES_IN_WORD]; /* value of symbol */
-};
-#define EXTERNAL_NLIST_SIZE (BYTES_IN_WORD+4+BYTES_IN_WORD)
-#endif
-
-struct internal_nlist {
- unsigned long n_strx; /* index into string table of name */
- unsigned char n_type; /* type of symbol */
- unsigned char n_other; /* misc info (usually empty) */
- unsigned short n_desc; /* description field */
- bfd_vma n_value; /* value of symbol */
-};
-
-/* The n_type field is the symbol type, containing: */
-
-#define N_UNDF 0 /* Undefined symbol */
-#define N_ABS 2 /* Absolute symbol -- defined at particular addr */
-#define N_TEXT 4 /* Text sym -- defined at offset in text seg */
-#define N_DATA 6 /* Data sym -- defined at offset in data seg */
-#define N_BSS 8 /* BSS sym -- defined at offset in zero'd seg */
-#define N_COMM 0x12 /* Common symbol (visible after shared lib dynlink) */
-#define N_FN 0x1f /* File name of .o file */
-#define N_FN_SEQ 0x0C /* N_FN from Sequent compilers (sigh) */
-/* Note: N_EXT can only be usefully OR-ed with N_UNDF, N_ABS, N_TEXT,
- N_DATA, or N_BSS. When the low-order bit of other types is set,
- (e.g. N_WARNING versus N_FN), they are two different types. */
-#define N_EXT 1 /* External symbol (as opposed to local-to-this-file) */
-#define N_TYPE 0x1e
-#define N_STAB 0xe0 /* If any of these bits are on, it's a debug symbol */
-
-#define N_INDR 0x0a
-
-/* The following symbols refer to set elements.
- All the N_SET[ATDB] symbols with the same name form one set.
- Space is allocated for the set in the text section, and each set
- elements value is stored into one word of the space.
- The first word of the space is the length of the set (number of elements).
-
- The address of the set is made into an N_SETV symbol
- whose name is the same as the name of the set.
- This symbol acts like a N_DATA global symbol
- in that it can satisfy undefined external references. */
-
-/* These appear as input to LD, in a .o file. */
-#define N_SETA 0x14 /* Absolute set element symbol */
-#define N_SETT 0x16 /* Text set element symbol */
-#define N_SETD 0x18 /* Data set element symbol */
-#define N_SETB 0x1A /* Bss set element symbol */
-
-/* This is output from LD. */
-#define N_SETV 0x1C /* Pointer to set vector in data area. */
-
-/* Warning symbol. The text gives a warning message, the next symbol
- in the table will be undefined. When the symbol is referenced, the
- message is printed. */
-
-#define N_WARNING 0x1e
-
-/* Weak symbols. These are a GNU extension to the a.out format. The
- semantics are those of ELF weak symbols. Weak symbols are always
- externally visible. The N_WEAK? values are squeezed into the
- available slots. The value of a N_WEAKU symbol is 0. The values
- of the other types are the definitions. */
-#define N_WEAKU 0x0d /* Weak undefined symbol. */
-#define N_WEAKA 0x0e /* Weak absolute symbol. */
-#define N_WEAKT 0x0f /* Weak text symbol. */
-#define N_WEAKD 0x10 /* Weak data symbol. */
-#define N_WEAKB 0x11 /* Weak bss symbol. */
-
-/* Relocations
-
- There are two types of relocation flavours for a.out systems,
- standard and extended. The standard form is used on systems where the
- instruction has room for all the bits of an offset to the operand, whilst
- the extended form is used when an address operand has to be split over n
- instructions. Eg, on the 68k, each move instruction can reference
- the target with a displacement of 16 or 32 bits. On the sparc, move
- instructions use an offset of 14 bits, so the offset is stored in
- the reloc field, and the data in the section is ignored.
-*/
-
-/* This structure describes a single relocation to be performed.
- The text-relocation section of the file is a vector of these structures,
- all of which apply to the text section.
- Likewise, the data-relocation section applies to the data section. */
-
-struct reloc_std_external {
- bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */
- bfd_byte r_index[3]; /* symbol table index of symbol */
- bfd_byte r_type[1]; /* relocation type */
-};
-
-#define RELOC_STD_BITS_PCREL_BIG ((unsigned int) 0x80)
-#define RELOC_STD_BITS_PCREL_LITTLE ((unsigned int) 0x01)
-
-#define RELOC_STD_BITS_LENGTH_BIG ((unsigned int) 0x60)
-#define RELOC_STD_BITS_LENGTH_SH_BIG 5
-#define RELOC_STD_BITS_LENGTH_LITTLE ((unsigned int) 0x06)
-#define RELOC_STD_BITS_LENGTH_SH_LITTLE 1
-
-#define RELOC_STD_BITS_EXTERN_BIG ((unsigned int) 0x10)
-#define RELOC_STD_BITS_EXTERN_LITTLE ((unsigned int) 0x08)
-
-#define RELOC_STD_BITS_BASEREL_BIG ((unsigned int) 0x08)
-#define RELOC_STD_BITS_BASEREL_LITTLE ((unsigned int) 0x10)
-
-#define RELOC_STD_BITS_JMPTABLE_BIG ((unsigned int) 0x04)
-#define RELOC_STD_BITS_JMPTABLE_LITTLE ((unsigned int) 0x20)
-
-#define RELOC_STD_BITS_RELATIVE_BIG ((unsigned int) 0x02)
-#define RELOC_STD_BITS_RELATIVE_LITTLE ((unsigned int) 0x40)
-
-#define RELOC_STD_SIZE (BYTES_IN_WORD + 3 + 1) /* Bytes per relocation entry */
-
-struct reloc_std_internal
-{
- bfd_vma r_address; /* Address (within segment) to be relocated. */
- /* The meaning of r_symbolnum depends on r_extern. */
- unsigned int r_symbolnum:24;
- /* Nonzero means value is a pc-relative offset
- and it should be relocated for changes in its own address
- as well as for changes in the symbol or section specified. */
- unsigned int r_pcrel:1;
- /* Length (as exponent of 2) of the field to be relocated.
- Thus, a value of 2 indicates 1<<2 bytes. */
- unsigned int r_length:2;
- /* 1 => relocate with value of symbol.
- r_symbolnum is the index of the symbol
- in files the symbol table.
- 0 => relocate with the address of a segment.
- r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS
- (the N_EXT bit may be set also, but signifies nothing). */
- unsigned int r_extern:1;
- /* The next three bits are for SunOS shared libraries, and seem to
- be undocumented. */
- unsigned int r_baserel:1; /* Linkage table relative */
- unsigned int r_jmptable:1; /* pc-relative to jump table */
- unsigned int r_relative:1; /* "relative relocation" */
- /* unused */
- unsigned int r_pad:1; /* Padding -- set to zero */
-};
-
-
-/* EXTENDED RELOCS */
-
-struct reloc_ext_external {
- bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */
- bfd_byte r_index[3]; /* symbol table index of symbol */
- bfd_byte r_type[1]; /* relocation type */
- bfd_byte r_addend[BYTES_IN_WORD]; /* datum addend */
-};
-
-#define RELOC_EXT_BITS_EXTERN_BIG ((unsigned int) 0x80)
-#define RELOC_EXT_BITS_EXTERN_LITTLE ((unsigned int) 0x01)
-
-#define RELOC_EXT_BITS_TYPE_BIG ((unsigned int) 0x1F)
-#define RELOC_EXT_BITS_TYPE_SH_BIG 0
-#define RELOC_EXT_BITS_TYPE_LITTLE ((unsigned int) 0xF8)
-#define RELOC_EXT_BITS_TYPE_SH_LITTLE 3
-
-/* Bytes per relocation entry */
-#define RELOC_EXT_SIZE (BYTES_IN_WORD + 3 + 1 + BYTES_IN_WORD)
-
-enum reloc_type
-{
- /* simple relocations */
- RELOC_8, /* data[0:7] = addend + sv */
- RELOC_16, /* data[0:15] = addend + sv */
- RELOC_32, /* data[0:31] = addend + sv */
- /* pc-rel displacement */
- RELOC_DISP8, /* data[0:7] = addend - pc + sv */
- RELOC_DISP16, /* data[0:15] = addend - pc + sv */
- RELOC_DISP32, /* data[0:31] = addend - pc + sv */
- /* Special */
- RELOC_WDISP30, /* data[0:29] = (addend + sv - pc)>>2 */
- RELOC_WDISP22, /* data[0:21] = (addend + sv - pc)>>2 */
- RELOC_HI22, /* data[0:21] = (addend + sv)>>10 */
- RELOC_22, /* data[0:21] = (addend + sv) */
- RELOC_13, /* data[0:12] = (addend + sv) */
- RELOC_LO10, /* data[0:9] = (addend + sv) */
- RELOC_SFA_BASE,
- RELOC_SFA_OFF13,
- /* P.I.C. (base-relative) */
- RELOC_BASE10, /* Not sure - maybe we can do this the */
- RELOC_BASE13, /* right way now */
- RELOC_BASE22,
- /* for some sort of pc-rel P.I.C. (?) */
- RELOC_PC10,
- RELOC_PC22,
- /* P.I.C. jump table */
- RELOC_JMP_TBL,
- /* reputedly for shared libraries somehow */
- RELOC_SEGOFF16,
- RELOC_GLOB_DAT,
- RELOC_JMP_SLOT,
- RELOC_RELATIVE,
-
- RELOC_11,
- RELOC_WDISP2_14,
- RELOC_WDISP19,
- RELOC_HHI22, /* data[0:21] = (addend + sv) >> 42 */
- RELOC_HLO10, /* data[0:9] = (addend + sv) >> 32 */
-
- /* 29K relocation types */
- RELOC_JUMPTARG,
- RELOC_CONST,
- RELOC_CONSTH,
-
- /* All the new ones I can think of, for sparc v9 */
-
- RELOC_64, /* data[0:63] = addend + sv */
- RELOC_DISP64, /* data[0:63] = addend - pc + sv */
- RELOC_WDISP21, /* data[0:20] = (addend + sv - pc)>>2 */
- RELOC_DISP21, /* data[0:20] = addend - pc + sv */
- RELOC_DISP14, /* data[0:13] = addend - pc + sv */
- /* Q .
- What are the other ones,
- Since this is a clean slate, can we throw away the ones we dont
- understand ? Should we sort the values ? What about using a
- microcode format like the 68k ?
- */
- NO_RELOC
- };
-
-
-struct reloc_internal {
- bfd_vma r_address; /* offset of of data to relocate */
- long r_index; /* symbol table index of symbol */
- enum reloc_type r_type; /* relocation type */
- bfd_vma r_addend; /* datum addend */
-};
-
-/* Q.
- Should the length of the string table be 4 bytes or 8 bytes ?
-
- Q.
- What about archive indexes ?
-
- */
-
-#endif /* __A_OUT_64_H__ */
diff --git a/pstack/aout/stab.def b/pstack/aout/stab.def
deleted file mode 100644
index 3c6b456d3a9..00000000000
--- a/pstack/aout/stab.def
+++ /dev/null
@@ -1,264 +0,0 @@
-/* Table of DBX symbol codes for the GNU system.
- Copyright (C) 1988, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* New stab from Solaris 2. This uses an n_type of 0, which in a.out files
- overlaps the N_UNDF used for ordinary symbols. In ELF files, the
- debug information is in a different file section, so there is no conflict.
- This symbol's n_value gives the size of the string section associated
- with this file. The symbol's n_strx (relative to the just-updated
- string section start address) gives the name of the source file,
- e.g. "foo.c", without any path information. The symbol's n_desc gives
- the count of upcoming symbols associated with this file (not including
- this one). */
-/* __define_stab (N_UNDF, 0x00, "UNDF") */
-
-/* Global variable. Only the name is significant.
- To find the address, look in the corresponding external symbol. */
-__define_stab (N_GSYM, 0x20, "GSYM")
-
-/* Function name for BSD Fortran. Only the name is significant.
- To find the address, look in the corresponding external symbol. */
-__define_stab (N_FNAME, 0x22, "FNAME")
-
-/* Function name or text-segment variable for C. Value is its address.
- Desc is supposedly starting line number, but GCC doesn't set it
- and DBX seems not to miss it. */
-__define_stab (N_FUN, 0x24, "FUN")
-
-/* Data-segment variable with internal linkage. Value is its address.
- "Static Sym". */
-__define_stab (N_STSYM, 0x26, "STSYM")
-
-/* BSS-segment variable with internal linkage. Value is its address. */
-__define_stab (N_LCSYM, 0x28, "LCSYM")
-
-/* Name of main routine. Only the name is significant. */
-__define_stab (N_MAIN, 0x2a, "MAIN")
-
-/* Solaris2: Read-only data symbols. */
-__define_stab (N_ROSYM, 0x2c, "ROSYM")
-
-/* Global symbol in Pascal.
- Supposedly the value is its line number; I'm skeptical. */
-__define_stab (N_PC, 0x30, "PC")
-
-/* Number of symbols: 0, files,,funcs,lines according to Ultrix V4.0. */
-__define_stab (N_NSYMS, 0x32, "NSYMS")
-
-/* "No DST map for sym: name, ,0,type,ignored" according to Ultrix V4.0. */
-__define_stab (N_NOMAP, 0x34, "NOMAP")
-
-/* New stab from Solaris 2. Like N_SO, but for the object file. Two in
- a row provide the build directory and the relative path of the .o from it.
- Solaris2 uses this to avoid putting the stabs info into the linked
- executable; this stab goes into the ".stab.index" section, and the debugger
- reads the real stabs directly from the .o files instead. */
-__define_stab (N_OBJ, 0x38, "OBJ")
-
-/* New stab from Solaris 2. Options for the debugger, related to the
- source language for this module. E.g. whether to use ANSI
- integral promotions or traditional integral promotions. */
-__define_stab (N_OPT, 0x3c, "OPT")
-
-/* Register variable. Value is number of register. */
-__define_stab (N_RSYM, 0x40, "RSYM")
-
-/* Modula-2 compilation unit. Can someone say what info it contains? */
-__define_stab (N_M2C, 0x42, "M2C")
-
-/* Line number in text segment. Desc is the line number;
- value is corresponding address. On Solaris2, the line number is
- relative to the start of the current function. */
-__define_stab (N_SLINE, 0x44, "SLINE")
-
-/* Similar, for data segment. */
-__define_stab (N_DSLINE, 0x46, "DSLINE")
-
-/* Similar, for bss segment. */
-__define_stab (N_BSLINE, 0x48, "BSLINE")
-
-/* Sun's source-code browser stabs. ?? Don't know what the fields are.
- Supposedly the field is "path to associated .cb file". THIS VALUE
- OVERLAPS WITH N_BSLINE! */
-__define_stab_duplicate (N_BROWS, 0x48, "BROWS")
-
-/* GNU Modula-2 definition module dependency. Value is the modification time
- of the definition file. Other is non-zero if it is imported with the
- GNU M2 keyword %INITIALIZE. Perhaps N_M2C can be used if there
- are enough empty fields? */
-__define_stab(N_DEFD, 0x4a, "DEFD")
-
-/* New in Solaris2. Function start/body/end line numbers. */
-__define_stab(N_FLINE, 0x4C, "FLINE")
-
-/* THE FOLLOWING TWO STAB VALUES CONFLICT. Happily, one is for Modula-2
- and one is for C++. Still,... */
-/* GNU C++ exception variable. Name is variable name. */
-__define_stab (N_EHDECL, 0x50, "EHDECL")
-/* Modula2 info "for imc": name,,0,0,0 according to Ultrix V4.0. */
-__define_stab_duplicate (N_MOD2, 0x50, "MOD2")
-
-/* GNU C++ `catch' clause. Value is its address. Desc is nonzero if
- this entry is immediately followed by a CAUGHT stab saying what exception
- was caught. Multiple CAUGHT stabs means that multiple exceptions
- can be caught here. If Desc is 0, it means all exceptions are caught
- here. */
-__define_stab (N_CATCH, 0x54, "CATCH")
-
-/* Structure or union element. Value is offset in the structure. */
-__define_stab (N_SSYM, 0x60, "SSYM")
-
-/* Solaris2: Last stab emitted for module. */
-__define_stab (N_ENDM, 0x62, "ENDM")
-
-/* Name of main source file.
- Value is starting text address of the compilation.
- If multiple N_SO's appear, the first to contain a trailing / is the
- compilation directory. The first to not contain a trailing / is the
- source file name, relative to the compilation directory. Others (perhaps
- resulting from cfront) are ignored.
- On Solaris2, value is undefined, but desc is a source-language code. */
-
-__define_stab (N_SO, 0x64, "SO")
-
-/* Automatic variable in the stack. Value is offset from frame pointer.
- Also used for type descriptions. */
-__define_stab (N_LSYM, 0x80, "LSYM")
-
-/* Beginning of an include file. Only Sun uses this.
- In an object file, only the name is significant.
- The Sun linker puts data into some of the other fields. */
-__define_stab (N_BINCL, 0x82, "BINCL")
-
-/* Name of sub-source file (#include file).
- Value is starting text address of the compilation. */
-__define_stab (N_SOL, 0x84, "SOL")
-
-/* Parameter variable. Value is offset from argument pointer.
- (On most machines the argument pointer is the same as the frame pointer. */
-__define_stab (N_PSYM, 0xa0, "PSYM")
-
-/* End of an include file. No name.
- This and N_BINCL act as brackets around the file's output.
- In an object file, there is no significant data in this entry.
- The Sun linker puts data into some of the fields. */
-__define_stab (N_EINCL, 0xa2, "EINCL")
-
-/* Alternate entry point. Value is its address. */
-__define_stab (N_ENTRY, 0xa4, "ENTRY")
-
-/* Beginning of lexical block.
- The desc is the nesting level in lexical blocks.
- The value is the address of the start of the text for the block.
- The variables declared inside the block *precede* the N_LBRAC symbol.
- On Solaris2, the value is relative to the start of the current function. */
-__define_stab (N_LBRAC, 0xc0, "LBRAC")
-
-/* Place holder for deleted include file. Replaces a N_BINCL and everything
- up to the corresponding N_EINCL. The Sun linker generates these when
- it finds multiple identical copies of the symbols from an include file.
- This appears only in output from the Sun linker. */
-__define_stab (N_EXCL, 0xc2, "EXCL")
-
-/* Modula-2 scope information. Can someone say what info it contains? */
-__define_stab (N_SCOPE, 0xc4, "SCOPE")
-
-/* End of a lexical block. Desc matches the N_LBRAC's desc.
- The value is the address of the end of the text for the block.
- On Solaris2, the value is relative to the start of the current function. */
-__define_stab (N_RBRAC, 0xe0, "RBRAC")
-
-/* Begin named common block. Only the name is significant. */
-__define_stab (N_BCOMM, 0xe2, "BCOMM")
-
-/* End named common block. Only the name is significant
- (and it should match the N_BCOMM). */
-__define_stab (N_ECOMM, 0xe4, "ECOMM")
-
-/* Member of a common block; value is offset within the common block.
- This should occur within a BCOMM/ECOMM pair. */
-__define_stab (N_ECOML, 0xe8, "ECOML")
-
-/* Solaris2: Pascal "with" statement: type,,0,0,offset */
-__define_stab (N_WITH, 0xea, "WITH")
-
-/* These STAB's are used on Gould systems for Non-Base register symbols
- or something like that. FIXME. I have assigned the values at random
- since I don't have a Gould here. Fixups from Gould folk welcome... */
-__define_stab (N_NBTEXT, 0xF0, "NBTEXT")
-__define_stab (N_NBDATA, 0xF2, "NBDATA")
-__define_stab (N_NBBSS, 0xF4, "NBBSS")
-__define_stab (N_NBSTS, 0xF6, "NBSTS")
-__define_stab (N_NBLCS, 0xF8, "NBLCS")
-
-/* Second symbol entry containing a length-value for the preceding entry.
- The value is the length. */
-__define_stab (N_LENG, 0xfe, "LENG")
-
-/* The above information, in matrix format.
-
- STAB MATRIX
- _________________________________________________
- | 00 - 1F are not dbx stab symbols |
- | In most cases, the low bit is the EXTernal bit|
-
- | 00 UNDEF | 02 ABS | 04 TEXT | 06 DATA |
- | 01 |EXT | 03 |EXT | 05 |EXT | 07 |EXT |
-
- | 08 BSS | 0A INDR | 0C FN_SEQ | 0E WEAKA |
- | 09 |EXT | 0B | 0D WEAKU | 0F WEAKT |
-
- | 10 WEAKD | 12 COMM | 14 SETA | 16 SETT |
- | 11 WEAKB | 13 | 15 | 17 |
-
- | 18 SETD | 1A SETB | 1C SETV | 1E WARNING|
- | 19 | 1B | 1D | 1F FN |
-
- |_______________________________________________|
- | Debug entries with bit 01 set are unused. |
- | 20 GSYM | 22 FNAME | 24 FUN | 26 STSYM |
- | 28 LCSYM | 2A MAIN | 2C ROSYM | 2E |
- | 30 PC | 32 NSYMS | 34 NOMAP | 36 |
- | 38 OBJ | 3A | 3C OPT | 3E |
- | 40 RSYM | 42 M2C | 44 SLINE | 46 DSLINE |
- | 48 BSLINE*| 4A DEFD | 4C FLINE | 4E |
- | 50 EHDECL*| 52 | 54 CATCH | 56 |
- | 58 | 5A | 5C | 5E |
- | 60 SSYM | 62 ENDM | 64 SO | 66 |
- | 68 | 6A | 6C | 6E |
- | 70 | 72 | 74 | 76 |
- | 78 | 7A | 7C | 7E |
- | 80 LSYM | 82 BINCL | 84 SOL | 86 |
- | 88 | 8A | 8C | 8E |
- | 90 | 92 | 94 | 96 |
- | 98 | 9A | 9C | 9E |
- | A0 PSYM | A2 EINCL | A4 ENTRY | A6 |
- | A8 | AA | AC | AE |
- | B0 | B2 | B4 | B6 |
- | B8 | BA | BC | BE |
- | C0 LBRAC | C2 EXCL | C4 SCOPE | C6 |
- | C8 | CA | CC | CE |
- | D0 | D2 | D4 | D6 |
- | D8 | DA | DC | DE |
- | E0 RBRAC | E2 BCOMM | E4 ECOMM | E6 |
- | E8 ECOML | EA WITH | EC | EE |
- | F0 | F2 | F4 | F6 |
- | F8 | FA | FC | FE LENG |
- +-----------------------------------------------+
- * 50 EHDECL is also MOD2.
- * 48 BSLINE is also BROWS.
- */
diff --git a/pstack/aout/stab_gnu.h b/pstack/aout/stab_gnu.h
deleted file mode 100644
index 7d18e14a263..00000000000
--- a/pstack/aout/stab_gnu.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef __GNU_STAB__
-
-/* Indicate the GNU stab.h is in use. */
-
-#define __GNU_STAB__
-
-#define __define_stab(NAME, CODE, STRING) NAME=CODE,
-#define __define_stab_duplicate(NAME, CODE, STRING) NAME=CODE,
-
-enum __stab_debug_code
-{
-#include "aout/stab.def"
-LAST_UNUSED_STAB_CODE
-};
-
-#undef __define_stab
-
-/* Definitions of "desc" field for N_SO stabs in Solaris2. */
-
-#define N_SO_AS 1
-#define N_SO_C 2
-#define N_SO_ANSI_C 3
-#define N_SO_CC 4 /* C++ */
-#define N_SO_FORTRAN 5
-#define N_SO_PASCAL 6
-
-/* Solaris2: Floating point type values in basic types. */
-
-#define NF_NONE 0
-#define NF_SINGLE 1 /* IEEE 32-bit */
-#define NF_DOUBLE 2 /* IEEE 64-bit */
-#define NF_COMPLEX 3 /* Fortran complex */
-#define NF_COMPLEX16 4 /* Fortran double complex */
-#define NF_COMPLEX32 5 /* Fortran complex*16 */
-#define NF_LDOUBLE 6 /* Long double (whatever that is) */
-
-#endif /* __GNU_STAB_ */
diff --git a/pstack/bucomm.c b/pstack/bucomm.c
deleted file mode 100644
index d3231e71747..00000000000
--- a/pstack/bucomm.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/* bucomm.c -- Bin Utils COMmon code.
- Copyright (C) 1991, 92, 93, 94, 95, 1997 Free Software Foundation, Inc.
-
- This file is part of GNU Binutils.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-/* We might put this in a library someday so it could be dynamically
- loaded, but for now it's not necessary. */
-
-#include <bfd.h>
-#include <libiberty.h>
-#include "bucomm.h"
-
-#include <sys/stat.h>
-#include <time.h> /* ctime, maybe time_t */
-
-#ifdef ANSI_PROTOTYPES
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-/* Error reporting */
-
-char *program_name;
-
-void
-bfd_nonfatal (string)
- CONST char *string;
-{
- CONST char *errmsg = bfd_errmsg (bfd_get_error ());
-
- if (string)
- fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg);
- else
- fprintf (stderr, "%s: %s\n", program_name, errmsg);
-}
-
-void
-bfd_fatal (string)
- CONST char *string;
-{
- bfd_nonfatal (string);
- xexit (1);
-}
-
-#ifdef ANSI_PROTOTYPES
-void
-fatal (const char *format, ...)
-{
- va_list args;
-
- fprintf (stderr, "%s: ", program_name);
- va_start (args, format);
- vfprintf (stderr, format, args);
- va_end (args);
- putc ('\n', stderr);
- xexit (1);
-}
-#else
-void
-fatal (va_alist)
- va_dcl
-{
- char *Format;
- va_list args;
-
- fprintf (stderr, "%s: ", program_name);
- va_start (args);
- Format = va_arg (args, char *);
- vfprintf (stderr, Format, args);
- va_end (args);
- putc ('\n', stderr);
- xexit (1);
-}
-#endif
-
-/* Set the default BFD target based on the configured target. Doing
- this permits the binutils to be configured for a particular target,
- and linked against a shared BFD library which was configured for a
- different target. */
-
-#define TARGET "elf32-i386" /* FIXME: hard-coded! */
-void
-set_default_bfd_target ()
-{
- /* The macro TARGET is defined by Makefile. */
- const char *target = TARGET;
-
- if (! bfd_set_default_target (target))
- {
- char *errmsg;
-
- errmsg = (char *) xmalloc (100 + strlen (target));
- sprintf (errmsg, "can't set BFD default target to `%s'", target);
- bfd_fatal (errmsg);
- }
-}
-
-/* After a false return from bfd_check_format_matches with
- bfd_get_error () == bfd_error_file_ambiguously_recognized, print
- the possible matching targets. */
-
-void
-list_matching_formats (p)
- char **p;
-{
- fprintf(stderr, "%s: Matching formats:", program_name);
- while (*p)
- fprintf(stderr, " %s", *p++);
- fprintf(stderr, "\n");
-}
-
-/* List the supported targets. */
-
-void
-list_supported_targets (name, f)
- const char *name;
- FILE *f;
-{
- extern bfd_target *bfd_target_vector[];
- int t;
-
- if (name == NULL)
- fprintf (f, "Supported targets:");
- else
- fprintf (f, "%s: supported targets:", name);
- for (t = 0; bfd_target_vector[t] != NULL; t++)
- fprintf (f, " %s", bfd_target_vector[t]->name);
- fprintf (f, "\n");
-}
-
-/* Display the archive header for an element as if it were an ls -l listing:
-
- Mode User\tGroup\tSize\tDate Name */
-
-void
-print_arelt_descr (file, abfd, verbose)
- FILE *file;
- bfd *abfd;
- boolean verbose;
-{
- struct stat buf;
-
- if (verbose)
- {
- if (bfd_stat_arch_elt (abfd, &buf) == 0)
- {
- char modebuf[11];
- char timebuf[40];
- time_t when = buf.st_mtime;
- CONST char *ctime_result = (CONST char *) ctime (&when);
-
- /* POSIX format: skip weekday and seconds from ctime output. */
- sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
-
- mode_string (buf.st_mode, modebuf);
- modebuf[10] = '\0';
- /* POSIX 1003.2/D11 says to skip first character (entry type). */
- fprintf (file, "%s %ld/%ld %6ld %s ", modebuf + 1,
- (long) buf.st_uid, (long) buf.st_gid,
- (long) buf.st_size, timebuf);
- }
- }
-
- fprintf (file, "%s\n", bfd_get_filename (abfd));
-}
-
-/* Return the name of a temporary file in the same directory as FILENAME. */
-
-char *
-make_tempname (filename)
- char *filename;
-{
- static char template[] = "stXXXXXX";
- char *tmpname;
- char *slash = strrchr (filename, '/');
-
-#if defined (__DJGPP__) || defined (__GO32__) || defined (_WIN32)
- if (slash == NULL)
- slash = strrchr (filename, '\\');
-#endif
-
- if (slash != (char *) NULL)
- {
- char c;
-
- c = *slash;
- *slash = 0;
- tmpname = xmalloc (strlen (filename) + sizeof (template) + 1);
- strcpy (tmpname, filename);
- strcat (tmpname, "/");
- strcat (tmpname, template);
- mkstemp (tmpname);
- *slash = c;
- }
- else
- {
- tmpname = xmalloc (sizeof (template));
- strcpy (tmpname, template);
- mkstemp (tmpname);
- }
- return tmpname;
-}
-
-/* Parse a string into a VMA, with a fatal error if it can't be
- parsed. */
-
-bfd_vma
-parse_vma (s, arg)
- const char *s;
- const char *arg;
-{
- bfd_vma ret;
- const char *end;
-
- ret = bfd_scan_vma (s, &end, 0);
- if (*end != '\0')
- {
- fprintf (stderr, "%s: %s: bad number: %s\n", program_name, arg, s);
- exit (1);
- }
- return ret;
-}
diff --git a/pstack/bucomm.h b/pstack/bucomm.h
deleted file mode 100644
index 6b3633d8d63..00000000000
--- a/pstack/bucomm.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* bucomm.h -- binutils common include file.
- Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
-
-This file is part of GNU Binutils.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#ifndef _BUCOMM_H
-#define _BUCOMM_H
-
-#include "ansidecl.h"
-#include <stdio.h>
-#include <sys/types.h>
-
-#include <errno.h>
-#include <unistd.h>
-
-#include <string.h>
-
-#include <stdlib.h>
-
-#include <fcntl.h>
-
-#ifdef __GNUC__
-# undef alloca
-# define alloca __builtin_alloca
-#else
-# if HAVE_ALLOCA_H
-# include <alloca.h>
-# else
-# ifndef alloca /* predefined by HP cc +Olibcalls */
-# if !defined (__STDC__) && !defined (__hpux)
-char *alloca ();
-# else
-void *alloca ();
-# endif /* __STDC__, __hpux */
-# endif /* alloca */
-# endif /* HAVE_ALLOCA_H */
-#endif
-
-#ifndef BFD_TRUE_FALSE
-#define boolean bfd_boolean
-#define true TRUE
-#define false FALSE
-#endif
-
-/* bucomm.c */
-void bfd_nonfatal PARAMS ((CONST char *));
-
-void bfd_fatal PARAMS ((CONST char *));
-
-void fatal PARAMS ((CONST char *, ...));
-
-void set_default_bfd_target PARAMS ((void));
-
-void list_matching_formats PARAMS ((char **p));
-
-void list_supported_targets PARAMS ((const char *, FILE *));
-
-void print_arelt_descr PARAMS ((FILE *file, bfd *abfd, boolean verbose));
-
-char *make_tempname PARAMS ((char *));
-
-bfd_vma parse_vma PARAMS ((const char *, const char *));
-
-extern char *program_name;
-
-/* filemode.c */
-void mode_string PARAMS ((unsigned long mode, char *buf));
-
-/* version.c */
-extern void print_version PARAMS ((const char *));
-
-/* libiberty */
-PTR xmalloc PARAMS ((size_t));
-
-PTR xrealloc PARAMS ((PTR, size_t));
-
-#endif /* _BUCOMM_H */
diff --git a/pstack/budbg.h b/pstack/budbg.h
deleted file mode 100644
index 9f0203ad5e7..00000000000
--- a/pstack/budbg.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* budbg.c -- Interfaces to the generic debugging information routines.
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
- Written by Ian Lance Taylor <ian@cygnus.com>.
-
- This file is part of GNU Binutils.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-#ifndef BUDBG_H
-#define BUDBG_H
-
-#include <stdio.h>
-
-#ifndef BFD_TRUE_FALSE
-#define boolean bfd_boolean
-#define true TRUE
-#define false FALSE
-#endif
-
-/* Routine used to read generic debugging information. */
-
-extern PTR read_debugging_info PARAMS ((bfd *, asymbol **, long));
-
-/* Routine used to print generic debugging information. */
-
-extern boolean print_debugging_info PARAMS ((FILE *, PTR));
-
-/* Routines used to read and write stabs information. */
-
-extern PTR start_stab PARAMS ((PTR, bfd *, boolean, asymbol **, long));
-
-extern boolean finish_stab PARAMS ((PTR, PTR));
-
-extern boolean parse_stab PARAMS ((PTR, PTR, int, int, bfd_vma, const char *));
-
-extern boolean write_stabs_in_sections_debugging_info
- PARAMS ((bfd *, PTR, bfd_byte **, bfd_size_type *, bfd_byte **,
- bfd_size_type *));
-
-/* Routines used to read and write IEEE debugging information. */
-
-extern boolean parse_ieee
- PARAMS ((PTR, bfd *, const bfd_byte *, bfd_size_type));
-
-extern boolean write_ieee_debugging_info PARAMS ((bfd *, PTR));
-
-/* Routine used to read COFF debugging information. */
-
-extern boolean parse_coff PARAMS ((bfd *, asymbol **, long, PTR));
-
-#endif
diff --git a/pstack/debug.c b/pstack/debug.c
deleted file mode 100644
index 73412ae3f03..00000000000
--- a/pstack/debug.c
+++ /dev/null
@@ -1,3509 +0,0 @@
-/* debug.c -- Handle generic debugging information.
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
- Written by Ian Lance Taylor <ian@cygnus.com>.
-
- This file is part of GNU Binutils.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-/* This file implements a generic debugging format. We may eventually
- have readers which convert different formats into this generic
- format, and writers which write it out. The initial impetus for
- this was writing a convertor from stabs to HP IEEE-695 debugging
- format. */
-
-#include <stdio.h>
-#include <assert.h>
-
-#include <bfd.h>
-#include "bucomm.h"
-#include <libiberty.h>
-#include "debug.h"
-
-/* Global information we keep for debugging. A pointer to this
- structure is the debugging handle passed to all the routines. */
-
-struct debug_handle
-{
- /* A linked list of compilation units. */
- struct debug_unit *units;
- /* The current compilation unit. */
- struct debug_unit *current_unit;
- /* The current source file. */
- struct debug_file *current_file;
- /* The current function. */
- struct debug_function *current_function;
- /* The current block. */
- struct debug_block *current_block;
- /* The current line number information for the current unit. */
- struct debug_lineno *current_lineno;
- /* Mark. This is used by debug_write. */
- unsigned int mark;
- /* A struct/class ID used by debug_write. */
- unsigned int class_id;
- /* The base for class_id for this call to debug_write. */
- unsigned int base_id;
- /* The current line number in debug_write. */
- struct debug_lineno *current_write_lineno;
- unsigned int current_write_lineno_index;
- /* A list of classes which have assigned ID's during debug_write.
- This is linked through the next_id field of debug_class_type. */
- struct debug_class_id *id_list;
- /* A list used to avoid recursion during debug_type_samep. */
- struct debug_type_compare_list *compare_list;
-};
-
-/* Information we keep for a single compilation unit. */
-
-struct debug_unit
-{
- /* The next compilation unit. */
- struct debug_unit *next;
- /* A list of files included in this compilation unit. The first
- file is always the main one, and that is where the main file name
- is stored. */
- struct debug_file *files;
- /* Line number information for this compilation unit. This is not
- stored by function, because assembler code may have line number
- information without function information. */
- struct debug_lineno *linenos;
-};
-
-/* Information kept for a single source file. */
-
-struct debug_file
-{
- /* The next source file in this compilation unit. */
- struct debug_file *next;
- /* The name of the source file. */
- const char *filename;
- /* Global functions, variables, types, etc. */
- struct debug_namespace *globals;
-};
-
-/* A type. */
-
-struct debug_type
-{
- /* Kind of type. */
- enum debug_type_kind kind;
- /* Size of type (0 if not known). */
- unsigned int size;
- /* Type which is a pointer to this type. */
- debug_type pointer;
- /* Tagged union with additional information about the type. */
- union
- {
- /* DEBUG_KIND_INDIRECT. */
- struct debug_indirect_type *kindirect;
- /* DEBUG_KIND_INT. */
- /* Whether the integer is unsigned. */
- boolean kint;
- /* DEBUG_KIND_STRUCT, DEBUG_KIND_UNION, DEBUG_KIND_CLASS,
- DEBUG_KIND_UNION_CLASS. */
- struct debug_class_type *kclass;
- /* DEBUG_KIND_ENUM. */
- struct debug_enum_type *kenum;
- /* DEBUG_KIND_POINTER. */
- struct debug_type *kpointer;
- /* DEBUG_KIND_FUNCTION. */
- struct debug_function_type *kfunction;
- /* DEBUG_KIND_REFERENCE. */
- struct debug_type *kreference;
- /* DEBUG_KIND_RANGE. */
- struct debug_range_type *krange;
- /* DEBUG_KIND_ARRAY. */
- struct debug_array_type *karray;
- /* DEBUG_KIND_SET. */
- struct debug_set_type *kset;
- /* DEBUG_KIND_OFFSET. */
- struct debug_offset_type *koffset;
- /* DEBUG_KIND_METHOD. */
- struct debug_method_type *kmethod;
- /* DEBUG_KIND_CONST. */
- struct debug_type *kconst;
- /* DEBUG_KIND_VOLATILE. */
- struct debug_type *kvolatile;
- /* DEBUG_KIND_NAMED, DEBUG_KIND_TAGGED. */
- struct debug_named_type *knamed;
- } u;
-};
-
-/* Information kept for an indirect type. */
-
-struct debug_indirect_type
-{
- /* Slot where the final type will appear. */
- debug_type *slot;
- /* Tag. */
- const char *tag;
-};
-
-/* Information kept for a struct, union, or class. */
-
-struct debug_class_type
-{
- /* NULL terminated array of fields. */
- debug_field *fields;
- /* A mark field which indicates whether the struct has already been
- printed. */
- unsigned int mark;
- /* This is used to uniquely identify unnamed structs when printing. */
- unsigned int id;
- /* The remaining fields are only used for DEBUG_KIND_CLASS and
- DEBUG_KIND_UNION_CLASS. */
- /* NULL terminated array of base classes. */
- debug_baseclass *baseclasses;
- /* NULL terminated array of methods. */
- debug_method *methods;
- /* The type of the class providing the virtual function table for
- this class. This may point to the type itself. */
- debug_type vptrbase;
-};
-
-/* Information kept for an enum. */
-
-struct debug_enum_type
-{
- /* NULL terminated array of names. */
- const char **names;
- /* Array of corresponding values. */
- bfd_signed_vma *values;
-};
-
-/* Information kept for a function. FIXME: We should be able to
- record the parameter types. */
-
-struct debug_function_type
-{
- /* Return type. */
- debug_type return_type;
- /* NULL terminated array of argument types. */
- debug_type *arg_types;
- /* Whether the function takes a variable number of arguments. */
- boolean varargs;
-};
-
-/* Information kept for a range. */
-
-struct debug_range_type
-{
- /* Range base type. */
- debug_type type;
- /* Lower bound. */
- bfd_signed_vma lower;
- /* Upper bound. */
- bfd_signed_vma upper;
-};
-
-/* Information kept for an array. */
-
-struct debug_array_type
-{
- /* Element type. */
- debug_type element_type;
- /* Range type. */
- debug_type range_type;
- /* Lower bound. */
- bfd_signed_vma lower;
- /* Upper bound. */
- bfd_signed_vma upper;
- /* Whether this array is really a string. */
- boolean stringp;
-};
-
-/* Information kept for a set. */
-
-struct debug_set_type
-{
- /* Base type. */
- debug_type type;
- /* Whether this set is really a bitstring. */
- boolean bitstringp;
-};
-
-/* Information kept for an offset type (a based pointer). */
-
-struct debug_offset_type
-{
- /* The type the pointer is an offset from. */
- debug_type base_type;
- /* The type the pointer points to. */
- debug_type target_type;
-};
-
-/* Information kept for a method type. */
-
-struct debug_method_type
-{
- /* The return type. */
- debug_type return_type;
- /* The object type which this method is for. */
- debug_type domain_type;
- /* A NULL terminated array of argument types. */
- debug_type *arg_types;
- /* Whether the method takes a variable number of arguments. */
- boolean varargs;
-};
-
-/* Information kept for a named type. */
-
-struct debug_named_type
-{
- /* Name. */
- struct debug_name *name;
- /* Real type. */
- debug_type type;
-};
-
-/* A field in a struct or union. */
-
-struct debug_field
-{
- /* Name of the field. */
- const char *name;
- /* Type of the field. */
- struct debug_type *type;
- /* Visibility of the field. */
- enum debug_visibility visibility;
- /* Whether this is a static member. */
- boolean static_member;
- union
- {
- /* If static_member is false. */
- struct
- {
- /* Bit position of the field in the struct. */
- unsigned int bitpos;
- /* Size of the field in bits. */
- unsigned int bitsize;
- } f;
- /* If static_member is true. */
- struct
- {
- const char *physname;
- } s;
- } u;
-};
-
-/* A base class for an object. */
-
-struct debug_baseclass
-{
- /* Type of the base class. */
- struct debug_type *type;
- /* Bit position of the base class in the object. */
- unsigned int bitpos;
- /* Whether the base class is virtual. */
- boolean virtual;
- /* Visibility of the base class. */
- enum debug_visibility visibility;
-};
-
-/* A method of an object. */
-
-struct debug_method
-{
- /* The name of the method. */
- const char *name;
- /* A NULL terminated array of different types of variants. */
- struct debug_method_variant **variants;
-};
-
-/* The variants of a method function of an object. These indicate
- which method to run. */
-
-struct debug_method_variant
-{
- /* The physical name of the function. */
- const char *physname;
- /* The type of the function. */
- struct debug_type *type;
- /* The visibility of the function. */
- enum debug_visibility visibility;
- /* Whether the function is const. */
- boolean constp;
- /* Whether the function is volatile. */
- boolean volatilep;
- /* The offset to the function in the virtual function table. */
- bfd_vma voffset;
- /* If voffset is VOFFSET_STATIC_METHOD, this is a static method. */
-#define VOFFSET_STATIC_METHOD ((bfd_vma) -1)
- /* Context of a virtual method function. */
- struct debug_type *context;
-};
-
-/* A variable. This is the information we keep for a variable object.
- This has no name; a name is associated with a variable in a
- debug_name structure. */
-
-struct debug_variable
-{
- /* Kind of variable. */
- enum debug_var_kind kind;
- /* Type. */
- debug_type type;
- /* Value. The interpretation of the value depends upon kind. */
- bfd_vma val;
-};
-
-/* A function. This has no name; a name is associated with a function
- in a debug_name structure. */
-
-struct debug_function
-{
- /* Return type. */
- debug_type return_type;
- /* Parameter information. */
- struct debug_parameter *parameters;
- /* Block information. The first structure on the list is the main
- block of the function, and describes function local variables. */
- struct debug_block *blocks;
-};
-
-/* A function parameter. */
-
-struct debug_parameter
-{
- /* Next parameter. */
- struct debug_parameter *next;
- /* Name. */
- const char *name;
- /* Type. */
- debug_type type;
- /* Kind. */
- enum debug_parm_kind kind;
- /* Value (meaning depends upon kind). */
- bfd_vma val;
-};
-
-/* A typed constant. */
-
-struct debug_typed_constant
-{
- /* Type. */
- debug_type type;
- /* Value. FIXME: We may eventually need to support non-integral
- values. */
- bfd_vma val;
-};
-
-/* Information about a block within a function. */
-
-struct debug_block
-{
- /* Next block with the same parent. */
- struct debug_block *next;
- /* Parent block. */
- struct debug_block *parent;
- /* List of child blocks. */
- struct debug_block *children;
- /* Start address of the block. */
- bfd_vma start;
- /* End address of the block. */
- bfd_vma end;
- /* Local variables. */
- struct debug_namespace *locals;
-};
-
-/* Line number information we keep for a compilation unit. FIXME:
- This structure is easy to create, but can be very space
- inefficient. */
-
-struct debug_lineno
-{
- /* More line number information for this block. */
- struct debug_lineno *next;
- /* Source file. */
- struct debug_file *file;
- /* Line numbers, terminated by a -1 or the end of the array. */
-#define DEBUG_LINENO_COUNT 10
- unsigned long linenos[DEBUG_LINENO_COUNT];
- /* Addresses for the line numbers. */
- bfd_vma addrs[DEBUG_LINENO_COUNT];
-};
-
-/* A namespace. This is a mapping from names to objects. FIXME: This
- should be implemented as a hash table. */
-
-struct debug_namespace
-{
- /* List of items in this namespace. */
- struct debug_name *list;
- /* Pointer to where the next item in this namespace should go. */
- struct debug_name **tail;
-};
-
-/* Kinds of objects that appear in a namespace. */
-
-enum debug_object_kind
-{
- /* A type. */
- DEBUG_OBJECT_TYPE,
- /* A tagged type (really a different sort of namespace). */
- DEBUG_OBJECT_TAG,
- /* A variable. */
- DEBUG_OBJECT_VARIABLE,
- /* A function. */
- DEBUG_OBJECT_FUNCTION,
- /* An integer constant. */
- DEBUG_OBJECT_INT_CONSTANT,
- /* A floating point constant. */
- DEBUG_OBJECT_FLOAT_CONSTANT,
- /* A typed constant. */
- DEBUG_OBJECT_TYPED_CONSTANT
-};
-
-/* Linkage of an object that appears in a namespace. */
-
-enum debug_object_linkage
-{
- /* Local variable. */
- DEBUG_LINKAGE_AUTOMATIC,
- /* Static--either file static or function static, depending upon the
- namespace is. */
- DEBUG_LINKAGE_STATIC,
- /* Global. */
- DEBUG_LINKAGE_GLOBAL,
- /* No linkage. */
- DEBUG_LINKAGE_NONE
-};
-
-/* A name in a namespace. */
-
-struct debug_name
-{
- /* Next name in this namespace. */
- struct debug_name *next;
- /* Name. */
- const char *name;
- /* Mark. This is used by debug_write. */
- unsigned int mark;
- /* Kind of object. */
- enum debug_object_kind kind;
- /* Linkage of object. */
- enum debug_object_linkage linkage;
- /* Tagged union with additional information about the object. */
- union
- {
- /* DEBUG_OBJECT_TYPE. */
- struct debug_type *type;
- /* DEBUG_OBJECT_TAG. */
- struct debug_type *tag;
- /* DEBUG_OBJECT_VARIABLE. */
- struct debug_variable *variable;
- /* DEBUG_OBJECT_FUNCTION. */
- struct debug_function *function;
- /* DEBUG_OBJECT_INT_CONSTANT. */
- bfd_vma int_constant;
- /* DEBUG_OBJECT_FLOAT_CONSTANT. */
- double float_constant;
- /* DEBUG_OBJECT_TYPED_CONSTANT. */
- struct debug_typed_constant *typed_constant;
- } u;
-};
-
-/* During debug_write, a linked list of these structures is used to
- keep track of ID numbers that have been assigned to classes. */
-
-struct debug_class_id
-{
- /* Next ID number. */
- struct debug_class_id *next;
- /* The type with the ID. */
- struct debug_type *type;
- /* The tag; NULL if no tag. */
- const char *tag;
-};
-
-/* During debug_type_samep, a linked list of these structures is kept
- on the stack to avoid infinite recursion. */
-
-struct debug_type_compare_list
-{
- /* Next type on list. */
- struct debug_type_compare_list *next;
- /* The types we are comparing. */
- struct debug_type *t1;
- struct debug_type *t2;
-};
-
-/* Local functions. */
-
-static void debug_error PARAMS ((const char *));
-static struct debug_name *debug_add_to_namespace
- PARAMS ((struct debug_handle *, struct debug_namespace **, const char *,
- enum debug_object_kind, enum debug_object_linkage));
-static struct debug_name *debug_add_to_current_namespace
- PARAMS ((struct debug_handle *, const char *, enum debug_object_kind,
- enum debug_object_linkage));
-static struct debug_type *debug_make_type
- PARAMS ((struct debug_handle *, enum debug_type_kind, unsigned int));
-static struct debug_type *debug_get_real_type PARAMS ((PTR, debug_type));
-static boolean debug_write_name
- PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
- struct debug_name *));
-static boolean debug_write_type
- PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
- struct debug_type *, struct debug_name *));
-static boolean debug_write_class_type
- PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
- struct debug_type *, const char *));
-static boolean debug_write_function
- PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
- const char *, enum debug_object_linkage, struct debug_function *));
-static boolean debug_write_block
- PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
- struct debug_block *));
-static boolean debug_write_linenos
- PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
- bfd_vma));
-static boolean debug_set_class_id
- PARAMS ((struct debug_handle *, const char *, struct debug_type *));
-static boolean debug_type_samep
- PARAMS ((struct debug_handle *, struct debug_type *, struct debug_type *));
-static boolean debug_class_type_samep
- PARAMS ((struct debug_handle *, struct debug_type *, struct debug_type *));
-
-/* Issue an error message. */
-
-static void
-debug_error (message)
- const char *message;
-{
- fprintf (stderr, "%s\n", message);
-}
-
-/* Add an object to a namespace. */
-
-static struct debug_name *
-debug_add_to_namespace (info, nsp, name, kind, linkage)
- struct debug_handle *info;
- struct debug_namespace **nsp;
- const char *name;
- enum debug_object_kind kind;
- enum debug_object_linkage linkage;
-{
- struct debug_name *n;
- struct debug_namespace *ns;
-
- n = (struct debug_name *) xmalloc (sizeof *n);
- memset (n, 0, sizeof *n);
-
- n->name = name;
- n->kind = kind;
- n->linkage = linkage;
-
- ns = *nsp;
- if (ns == NULL)
- {
- ns = (struct debug_namespace *) xmalloc (sizeof *ns);
- memset (ns, 0, sizeof *ns);
-
- ns->tail = &ns->list;
-
- *nsp = ns;
- }
-
- *ns->tail = n;
- ns->tail = &n->next;
-
- return n;
-}
-
-/* Add an object to the current namespace. */
-
-static struct debug_name *
-debug_add_to_current_namespace (info, name, kind, linkage)
- struct debug_handle *info;
- const char *name;
- enum debug_object_kind kind;
- enum debug_object_linkage linkage;
-{
- struct debug_namespace **nsp;
-
- if (info->current_unit == NULL
- || info->current_file == NULL)
- {
- debug_error ("debug_add_to_current_namespace: no current file");
- return NULL;
- }
-
- if (info->current_block != NULL)
- nsp = &info->current_block->locals;
- else
- nsp = &info->current_file->globals;
-
- return debug_add_to_namespace (info, nsp, name, kind, linkage);
-}
-
-/* Return a handle for debugging information. */
-
-PTR
-debug_init ()
-{
- struct debug_handle *ret;
-
- ret = (struct debug_handle *) xmalloc (sizeof *ret);
- memset (ret, 0, sizeof *ret);
- return (PTR) ret;
-}
-
-/* Set the source filename. This implicitly starts a new compilation
- unit. */
-
-boolean
-debug_set_filename (handle, name)
- PTR handle;
- const char *name;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_file *nfile;
- struct debug_unit *nunit;
-
- if (name == NULL)
- name = "";
-
- nfile = (struct debug_file *) xmalloc (sizeof *nfile);
- memset (nfile, 0, sizeof *nfile);
-
- nfile->filename = name;
-
- nunit = (struct debug_unit *) xmalloc (sizeof *nunit);
- memset (nunit, 0, sizeof *nunit);
-
- nunit->files = nfile;
- info->current_file = nfile;
-
- if (info->current_unit != NULL)
- info->current_unit->next = nunit;
- else
- {
- assert (info->units == NULL);
- info->units = nunit;
- }
-
- info->current_unit = nunit;
-
- info->current_function = NULL;
- info->current_block = NULL;
- info->current_lineno = NULL;
-
- return true;
-}
-
-/* Change source files to the given file name. This is used for
- include files in a single compilation unit. */
-
-boolean
-debug_start_source (handle, name)
- PTR handle;
- const char *name;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_file *f, **pf;
-
- if (name == NULL)
- name = "";
-
- if (info->current_unit == NULL)
- {
- debug_error ("debug_start_source: no debug_set_filename call");
- return false;
- }
-
- for (f = info->current_unit->files; f != NULL; f = f->next)
- {
- if (f->filename[0] == name[0]
- && f->filename[1] == name[1]
- && strcmp (f->filename, name) == 0)
- {
- info->current_file = f;
- return true;
- }
- }
-
- f = (struct debug_file *) xmalloc (sizeof *f);
- memset (f, 0, sizeof *f);
-
- f->filename = name;
-
- for (pf = &info->current_file->next;
- *pf != NULL;
- pf = &(*pf)->next)
- ;
- *pf = f;
-
- info->current_file = f;
-
- return true;
-}
-
-/* Record a function definition. This implicitly starts a function
- block. The debug_type argument is the type of the return value.
- The boolean indicates whether the function is globally visible.
- The bfd_vma is the address of the start of the function. Currently
- the parameter types are specified by calls to
- debug_record_parameter. FIXME: There is no way to specify nested
- functions. */
-
-boolean
-debug_record_function (handle, name, return_type, global, addr)
- PTR handle;
- const char *name;
- debug_type return_type;
- boolean global;
- bfd_vma addr;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_function *f;
- struct debug_block *b;
- struct debug_name *n;
-
- if (name == NULL)
- name = "";
- if (return_type == NULL)
- return false;
-
- if (info->current_unit == NULL)
- {
- debug_error ("debug_record_function: no debug_set_filename call");
- return false;
- }
-
- f = (struct debug_function *) xmalloc (sizeof *f);
- memset (f, 0, sizeof *f);
-
- f->return_type = return_type;
-
- b = (struct debug_block *) xmalloc (sizeof *b);
- memset (b, 0, sizeof *b);
-
- b->start = addr;
- b->end = (bfd_vma) -1;
-
- f->blocks = b;
-
- info->current_function = f;
- info->current_block = b;
-
- /* FIXME: If we could handle nested functions, this would be the
- place: we would want to use a different namespace. */
- n = debug_add_to_namespace (info,
- &info->current_file->globals,
- name,
- DEBUG_OBJECT_FUNCTION,
- (global
- ? DEBUG_LINKAGE_GLOBAL
- : DEBUG_LINKAGE_STATIC));
- if (n == NULL)
- return false;
-
- n->u.function = f;
-
- return true;
-}
-
-/* Record a parameter for the current function. */
-
-boolean
-debug_record_parameter (handle, name, type, kind, val)
- PTR handle;
- const char *name;
- debug_type type;
- enum debug_parm_kind kind;
- bfd_vma val;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_parameter *p, **pp;
-
- if (name == NULL || type == NULL)
- return false;
-
- if (info->current_unit == NULL
- || info->current_function == NULL)
- {
- debug_error ("debug_record_parameter: no current function");
- return false;
- }
-
- p = (struct debug_parameter *) xmalloc (sizeof *p);
- memset (p, 0, sizeof *p);
-
- p->name = name;
- p->type = type;
- p->kind = kind;
- p->val = val;
-
- for (pp = &info->current_function->parameters;
- *pp != NULL;
- pp = &(*pp)->next)
- ;
- *pp = p;
-
- return true;
-}
-
-/* End a function. FIXME: This should handle function nesting. */
-
-boolean
-debug_end_function (handle, addr)
- PTR handle;
- bfd_vma addr;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
-
- if (info->current_unit == NULL
- || info->current_block == NULL
- || info->current_function == NULL)
- {
- debug_error ("debug_end_function: no current function");
- return false;
- }
-
- if (info->current_block->parent != NULL)
- {
- debug_error ("debug_end_function: some blocks were not closed");
- return false;
- }
-
- info->current_block->end = addr;
-
- info->current_function = NULL;
- info->current_block = NULL;
-
- return true;
-}
-
-/* Start a block in a function. All local information will be
- recorded in this block, until the matching call to debug_end_block.
- debug_start_block and debug_end_block may be nested. The bfd_vma
- argument is the address at which this block starts. */
-
-boolean
-debug_start_block (handle, addr)
- PTR handle;
- bfd_vma addr;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_block *b, **pb;
-
- /* We must always have a current block: debug_record_function sets
- one up. */
- if (info->current_unit == NULL
- || info->current_block == NULL)
- {
- debug_error ("debug_start_block: no current block");
- return false;
- }
-
- b = (struct debug_block *) xmalloc (sizeof *b);
- memset (b, 0, sizeof *b);
-
- b->parent = info->current_block;
- b->start = addr;
- b->end = (bfd_vma) -1;
-
- /* This new block is a child of the current block. */
- for (pb = &info->current_block->children;
- *pb != NULL;
- pb = &(*pb)->next)
- ;
- *pb = b;
-
- info->current_block = b;
-
- return true;
-}
-
-/* Finish a block in a function. This matches the call to
- debug_start_block. The argument is the address at which this block
- ends. */
-
-boolean
-debug_end_block (handle, addr)
- PTR handle;
- bfd_vma addr;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_block *parent;
-
- if (info->current_unit == NULL
- || info->current_block == NULL)
- {
- debug_error ("debug_end_block: no current block");
- return false;
- }
-
- parent = info->current_block->parent;
- if (parent == NULL)
- {
- debug_error ("debug_end_block: attempt to close top level block");
- return false;
- }
-
- info->current_block->end = addr;
-
- info->current_block = parent;
-
- return true;
-}
-
-/* Associate a line number in the current source file and function
- with a given address. */
-
-boolean
-debug_record_line (handle, lineno, addr)
- PTR handle;
- unsigned long lineno;
- bfd_vma addr;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_lineno *l;
- unsigned int i;
-
- if (info->current_unit == NULL)
- {
- debug_error ("debug_record_line: no current unit");
- return false;
- }
-
- l = info->current_lineno;
- if (l != NULL && l->file == info->current_file)
- {
- for (i = 0; i < DEBUG_LINENO_COUNT; i++)
- {
- if (l->linenos[i] == (unsigned long) -1)
- {
- l->linenos[i] = lineno;
- l->addrs[i] = addr;
- return true;
- }
- }
- }
-
- /* If we get here, then either 1) there is no current_lineno
- structure, which means this is the first line number in this
- compilation unit, 2) the current_lineno structure is for a
- different file, or 3) the current_lineno structure is full.
- Regardless, we want to allocate a new debug_lineno structure, put
- it in the right place, and make it the new current_lineno
- structure. */
-
- l = (struct debug_lineno *) xmalloc (sizeof *l);
- memset (l, 0, sizeof *l);
-
- l->file = info->current_file;
- l->linenos[0] = lineno;
- l->addrs[0] = addr;
- for (i = 1; i < DEBUG_LINENO_COUNT; i++)
- l->linenos[i] = (unsigned long) -1;
-
- if (info->current_lineno != NULL)
- info->current_lineno->next = l;
- else
- info->current_unit->linenos = l;
-
- info->current_lineno = l;
-
- return true;
-}
-
-/* Start a named common block. This is a block of variables that may
- move in memory. */
-
-boolean
-debug_start_common_block (handle, name)
- PTR handle;
- const char *name;
-{
- /* FIXME */
- debug_error ("debug_start_common_block: not implemented");
- return false;
-}
-
-/* End a named common block. */
-
-boolean
-debug_end_common_block (handle, name)
- PTR handle;
- const char *name;
-{
- /* FIXME */
- debug_error ("debug_end_common_block: not implemented");
- return false;
-}
-
-/* Record a named integer constant. */
-
-boolean
-debug_record_int_const (handle, name, val)
- PTR handle;
- const char *name;
- bfd_vma val;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_name *n;
-
- if (name == NULL)
- return false;
-
- n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_INT_CONSTANT,
- DEBUG_LINKAGE_NONE);
- if (n == NULL)
- return false;
-
- n->u.int_constant = val;
-
- return true;
-}
-
-/* Record a named floating point constant. */
-
-boolean
-debug_record_float_const (handle, name, val)
- PTR handle;
- const char *name;
- double val;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_name *n;
-
- if (name == NULL)
- return false;
-
- n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_FLOAT_CONSTANT,
- DEBUG_LINKAGE_NONE);
- if (n == NULL)
- return false;
-
- n->u.float_constant = val;
-
- return true;
-}
-
-/* Record a typed constant with an integral value. */
-
-boolean
-debug_record_typed_const (handle, name, type, val)
- PTR handle;
- const char *name;
- debug_type type;
- bfd_vma val;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_name *n;
- struct debug_typed_constant *tc;
-
- if (name == NULL || type == NULL)
- return false;
-
- n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_TYPED_CONSTANT,
- DEBUG_LINKAGE_NONE);
- if (n == NULL)
- return false;
-
- tc = (struct debug_typed_constant *) xmalloc (sizeof *tc);
- memset (tc, 0, sizeof *tc);
-
- tc->type = type;
- tc->val = val;
-
- n->u.typed_constant = tc;
-
- return true;
-}
-
-/* Record a label. */
-
-boolean
-debug_record_label (handle, name, type, addr)
- PTR handle;
- const char *name;
- debug_type type;
- bfd_vma addr;
-{
- /* FIXME. */
- debug_error ("debug_record_label not implemented");
- return false;
-}
-
-/* Record a variable. */
-
-boolean
-debug_record_variable (handle, name, type, kind, val)
- PTR handle;
- const char *name;
- debug_type type;
- enum debug_var_kind kind;
- bfd_vma val;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_namespace **nsp;
- enum debug_object_linkage linkage;
- struct debug_name *n;
- struct debug_variable *v;
-
- if (name == NULL || type == NULL)
- return false;
-
- if (info->current_unit == NULL
- || info->current_file == NULL)
- {
- debug_error ("debug_record_variable: no current file");
- return false;
- }
-
- if (kind == DEBUG_GLOBAL || kind == DEBUG_STATIC)
- {
- nsp = &info->current_file->globals;
- if (kind == DEBUG_GLOBAL)
- linkage = DEBUG_LINKAGE_GLOBAL;
- else
- linkage = DEBUG_LINKAGE_STATIC;
- }
- else
- {
- if (info->current_block == NULL)
- {
- debug_error ("debug_record_variable: no current block");
- return false;
- }
- nsp = &info->current_block->locals;
- linkage = DEBUG_LINKAGE_AUTOMATIC;
- }
-
- n = debug_add_to_namespace (info, nsp, name, DEBUG_OBJECT_VARIABLE, linkage);
- if (n == NULL)
- return false;
-
- v = (struct debug_variable *) xmalloc (sizeof *v);
- memset (v, 0, sizeof *v);
-
- v->kind = kind;
- v->type = type;
- v->val = val;
-
- n->u.variable = v;
-
- return true;
-}
-
-/* Make a type with a given kind and size. */
-
-/*ARGSUSED*/
-static struct debug_type *
-debug_make_type (info, kind, size)
- struct debug_handle *info;
- enum debug_type_kind kind;
- unsigned int size;
-{
- struct debug_type *t;
-
- t = (struct debug_type *) xmalloc (sizeof *t);
- memset (t, 0, sizeof *t);
-
- t->kind = kind;
- t->size = size;
-
- return t;
-}
-
-/* Make an indirect type which may be used as a placeholder for a type
- which is referenced before it is defined. */
-
-debug_type
-debug_make_indirect_type (handle, slot, tag)
- PTR handle;
- debug_type *slot;
- const char *tag;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_indirect_type *i;
-
- t = debug_make_type (info, DEBUG_KIND_INDIRECT, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- i = (struct debug_indirect_type *) xmalloc (sizeof *i);
- memset (i, 0, sizeof *i);
-
- i->slot = slot;
- i->tag = tag;
-
- t->u.kindirect = i;
-
- return t;
-}
-
-/* Make a void type. There is only one of these. */
-
-debug_type
-debug_make_void_type (handle)
- PTR handle;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
-
- return debug_make_type (info, DEBUG_KIND_VOID, 0);
-}
-
-/* Make an integer type of a given size. The boolean argument is true
- if the integer is unsigned. */
-
-debug_type
-debug_make_int_type (handle, size, unsignedp)
- PTR handle;
- unsigned int size;
- boolean unsignedp;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
-
- t = debug_make_type (info, DEBUG_KIND_INT, size);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- t->u.kint = unsignedp;
-
- return t;
-}
-
-/* Make a floating point type of a given size. FIXME: On some
- platforms, like an Alpha, you probably need to be able to specify
- the format. */
-
-debug_type
-debug_make_float_type (handle, size)
- PTR handle;
- unsigned int size;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
-
- return debug_make_type (info, DEBUG_KIND_FLOAT, size);
-}
-
-/* Make a boolean type of a given size. */
-
-debug_type
-debug_make_bool_type (handle, size)
- PTR handle;
- unsigned int size;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
-
- return debug_make_type (info, DEBUG_KIND_BOOL, size);
-}
-
-/* Make a complex type of a given size. */
-
-debug_type
-debug_make_complex_type (handle, size)
- PTR handle;
- unsigned int size;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
-
- return debug_make_type (info, DEBUG_KIND_COMPLEX, size);
-}
-
-/* Make a structure type. The second argument is true for a struct,
- false for a union. The third argument is the size of the struct.
- The fourth argument is a NULL terminated array of fields. */
-
-debug_type
-debug_make_struct_type (handle, structp, size, fields)
- PTR handle;
- boolean structp;
- bfd_vma size;
- debug_field *fields;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_class_type *c;
-
- t = debug_make_type (info,
- structp ? DEBUG_KIND_STRUCT : DEBUG_KIND_UNION,
- size);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- c = (struct debug_class_type *) xmalloc (sizeof *c);
- memset (c, 0, sizeof *c);
-
- c->fields = fields;
-
- t->u.kclass = c;
-
- return t;
-}
-
-/* Make an object type. The first three arguments after the handle
- are the same as for debug_make_struct_type. The next arguments are
- a NULL terminated array of base classes, a NULL terminated array of
- methods, the type of the object holding the virtual function table
- if it is not this object, and a boolean which is true if this
- object has its own virtual function table. */
-
-debug_type
-debug_make_object_type (handle, structp, size, fields, baseclasses,
- methods, vptrbase, ownvptr)
- PTR handle;
- boolean structp;
- bfd_vma size;
- debug_field *fields;
- debug_baseclass *baseclasses;
- debug_method *methods;
- debug_type vptrbase;
- boolean ownvptr;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_class_type *c;
-
- t = debug_make_type (info,
- structp ? DEBUG_KIND_CLASS : DEBUG_KIND_UNION_CLASS,
- size);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- c = (struct debug_class_type *) xmalloc (sizeof *c);
- memset (c, 0, sizeof *c);
-
- c->fields = fields;
- c->baseclasses = baseclasses;
- c->methods = methods;
- if (ownvptr)
- c->vptrbase = t;
- else
- c->vptrbase = vptrbase;
-
- t->u.kclass = c;
-
- return t;
-}
-
-/* Make an enumeration type. The arguments are a null terminated
- array of strings, and an array of corresponding values. */
-
-debug_type
-debug_make_enum_type (handle, names, values)
- PTR handle;
- const char **names;
- bfd_signed_vma *values;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_enum_type *e;
-
- t = debug_make_type (info, DEBUG_KIND_ENUM, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- e = (struct debug_enum_type *) xmalloc (sizeof *e);
- memset (e, 0, sizeof *e);
-
- e->names = names;
- e->values = values;
-
- t->u.kenum = e;
-
- return t;
-}
-
-/* Make a pointer to a given type. */
-
-debug_type
-debug_make_pointer_type (handle, type)
- PTR handle;
- debug_type type;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
-
- if (type == NULL)
- return DEBUG_TYPE_NULL;
-
- if (type->pointer != DEBUG_TYPE_NULL)
- return type->pointer;
-
- t = debug_make_type (info, DEBUG_KIND_POINTER, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- t->u.kpointer = type;
-
- type->pointer = t;
-
- return t;
-}
-
-/* Make a function returning a given type. FIXME: We should be able
- to record the parameter types. */
-
-debug_type
-debug_make_function_type (handle, type, arg_types, varargs)
- PTR handle;
- debug_type type;
- debug_type *arg_types;
- boolean varargs;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_function_type *f;
-
- if (type == NULL)
- return DEBUG_TYPE_NULL;
-
- t = debug_make_type (info, DEBUG_KIND_FUNCTION, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- f = (struct debug_function_type *) xmalloc (sizeof *f);
- memset (f, 0, sizeof *f);
-
- f->return_type = type;
- f->arg_types = arg_types;
- f->varargs = varargs;
-
- t->u.kfunction = f;
-
- return t;
-}
-
-/* Make a reference to a given type. */
-
-debug_type
-debug_make_reference_type (handle, type)
- PTR handle;
- debug_type type;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
-
- if (type == NULL)
- return DEBUG_TYPE_NULL;
-
- t = debug_make_type (info, DEBUG_KIND_REFERENCE, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- t->u.kreference = type;
-
- return t;
-}
-
-/* Make a range of a given type from a lower to an upper bound. */
-
-debug_type
-debug_make_range_type (handle, type, lower, upper)
- PTR handle;
- debug_type type;
- bfd_signed_vma lower;
- bfd_signed_vma upper;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_range_type *r;
-
- if (type == NULL)
- return DEBUG_TYPE_NULL;
-
- t = debug_make_type (info, DEBUG_KIND_RANGE, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- r = (struct debug_range_type *) xmalloc (sizeof *r);
- memset (r, 0, sizeof *r);
-
- r->type = type;
- r->lower = lower;
- r->upper = upper;
-
- t->u.krange = r;
-
- return t;
-}
-
-/* Make an array type. The second argument is the type of an element
- of the array. The third argument is the type of a range of the
- array. The fourth and fifth argument are the lower and upper
- bounds, respectively. The sixth argument is true if this array is
- actually a string, as in C. */
-
-debug_type
-debug_make_array_type (handle, element_type, range_type, lower, upper,
- stringp)
- PTR handle;
- debug_type element_type;
- debug_type range_type;
- bfd_signed_vma lower;
- bfd_signed_vma upper;
- boolean stringp;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_array_type *a;
-
- if (element_type == NULL || range_type == NULL)
- return DEBUG_TYPE_NULL;
-
- t = debug_make_type (info, DEBUG_KIND_ARRAY, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- a = (struct debug_array_type *) xmalloc (sizeof *a);
- memset (a, 0, sizeof *a);
-
- a->element_type = element_type;
- a->range_type = range_type;
- a->lower = lower;
- a->upper = upper;
- a->stringp = stringp;
-
- t->u.karray = a;
-
- return t;
-}
-
-/* Make a set of a given type. For example, a Pascal set type. The
- boolean argument is true if this set is actually a bitstring, as in
- CHILL. */
-
-debug_type
-debug_make_set_type (handle, type, bitstringp)
- PTR handle;
- debug_type type;
- boolean bitstringp;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_set_type *s;
-
- if (type == NULL)
- return DEBUG_TYPE_NULL;
-
- t = debug_make_type (info, DEBUG_KIND_SET, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- s = (struct debug_set_type *) xmalloc (sizeof *s);
- memset (s, 0, sizeof *s);
-
- s->type = type;
- s->bitstringp = bitstringp;
-
- t->u.kset = s;
-
- return t;
-}
-
-/* Make a type for a pointer which is relative to an object. The
- second argument is the type of the object to which the pointer is
- relative. The third argument is the type that the pointer points
- to. */
-
-debug_type
-debug_make_offset_type (handle, base_type, target_type)
- PTR handle;
- debug_type base_type;
- debug_type target_type;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_offset_type *o;
-
- if (base_type == NULL || target_type == NULL)
- return DEBUG_TYPE_NULL;
-
- t = debug_make_type (info, DEBUG_KIND_OFFSET, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- o = (struct debug_offset_type *) xmalloc (sizeof *o);
- memset (o, 0, sizeof *o);
-
- o->base_type = base_type;
- o->target_type = target_type;
-
- t->u.koffset = o;
-
- return t;
-}
-
-/* Make a type for a method function. The second argument is the
- return type, the third argument is the domain, and the fourth
- argument is a NULL terminated array of argument types. */
-
-debug_type
-debug_make_method_type (handle, return_type, domain_type, arg_types, varargs)
- PTR handle;
- debug_type return_type;
- debug_type domain_type;
- debug_type *arg_types;
- boolean varargs;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_method_type *m;
-
- if (return_type == NULL)
- return DEBUG_TYPE_NULL;
-
- t = debug_make_type (info, DEBUG_KIND_METHOD, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- m = (struct debug_method_type *) xmalloc (sizeof *m);
- memset (m, 0, sizeof *m);
-
- m->return_type = return_type;
- m->domain_type = domain_type;
- m->arg_types = arg_types;
- m->varargs = varargs;
-
- t->u.kmethod = m;
-
- return t;
-}
-
-/* Make a const qualified version of a given type. */
-
-debug_type
-debug_make_const_type (handle, type)
- PTR handle;
- debug_type type;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
-
- if (type == NULL)
- return DEBUG_TYPE_NULL;
-
- t = debug_make_type (info, DEBUG_KIND_CONST, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- t->u.kconst = type;
-
- return t;
-}
-
-/* Make a volatile qualified version of a given type. */
-
-debug_type
-debug_make_volatile_type (handle, type)
- PTR handle;
- debug_type type;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
-
- if (type == NULL)
- return DEBUG_TYPE_NULL;
-
- t = debug_make_type (info, DEBUG_KIND_VOLATILE, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- t->u.kvolatile = type;
-
- return t;
-}
-
-/* Make an undefined tagged type. For example, a struct which has
- been mentioned, but not defined. */
-
-debug_type
-debug_make_undefined_tagged_type (handle, name, kind)
- PTR handle;
- const char *name;
- enum debug_type_kind kind;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
-
- if (name == NULL)
- return DEBUG_TYPE_NULL;
-
- switch (kind)
- {
- case DEBUG_KIND_STRUCT:
- case DEBUG_KIND_UNION:
- case DEBUG_KIND_CLASS:
- case DEBUG_KIND_UNION_CLASS:
- case DEBUG_KIND_ENUM:
- break;
-
- default:
- debug_error ("debug_make_undefined_type: unsupported kind");
- return DEBUG_TYPE_NULL;
- }
-
- t = debug_make_type (info, kind, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- return debug_tag_type (handle, name, t);
-}
-
-/* Make a base class for an object. The second argument is the base
- class type. The third argument is the bit position of this base
- class in the object (always 0 unless doing multiple inheritance).
- The fourth argument is whether this is a virtual class. The fifth
- argument is the visibility of the base class. */
-
-/*ARGSUSED*/
-debug_baseclass
-debug_make_baseclass (handle, type, bitpos, virtual, visibility)
- PTR handle;
- debug_type type;
- bfd_vma bitpos;
- boolean virtual;
- enum debug_visibility visibility;
-{
- struct debug_baseclass *b;
-
- b = (struct debug_baseclass *) xmalloc (sizeof *b);
- memset (b, 0, sizeof *b);
-
- b->type = type;
- b->bitpos = bitpos;
- b->virtual = virtual;
- b->visibility = visibility;
-
- return b;
-}
-
-/* Make a field for a struct. The second argument is the name. The
- third argument is the type of the field. The fourth argument is
- the bit position of the field. The fifth argument is the size of
- the field (it may be zero). The sixth argument is the visibility
- of the field. */
-
-/*ARGSUSED*/
-debug_field
-debug_make_field (handle, name, type, bitpos, bitsize, visibility)
- PTR handle;
- const char *name;
- debug_type type;
- bfd_vma bitpos;
- bfd_vma bitsize;
- enum debug_visibility visibility;
-{
- struct debug_field *f;
-
- f = (struct debug_field *) xmalloc (sizeof *f);
- memset (f, 0, sizeof *f);
-
- f->name = name;
- f->type = type;
- f->static_member = false;
- f->u.f.bitpos = bitpos;
- f->u.f.bitsize = bitsize;
- f->visibility = visibility;
-
- return f;
-}
-
-/* Make a static member of an object. The second argument is the
- name. The third argument is the type of the member. The fourth
- argument is the physical name of the member (i.e., the name as a
- global variable). The fifth argument is the visibility of the
- member. */
-
-/*ARGSUSED*/
-debug_field
-debug_make_static_member (handle, name, type, physname, visibility)
- PTR handle;
- const char *name;
- debug_type type;
- const char *physname;
- enum debug_visibility visibility;
-{
- struct debug_field *f;
-
- f = (struct debug_field *) xmalloc (sizeof *f);
- memset (f, 0, sizeof *f);
-
- f->name = name;
- f->type = type;
- f->static_member = true;
- f->u.s.physname = physname;
- f->visibility = visibility;
-
- return f;
-}
-
-/* Make a method. The second argument is the name, and the third
- argument is a NULL terminated array of method variants. */
-
-/*ARGSUSED*/
-debug_method
-debug_make_method (handle, name, variants)
- PTR handle;
- const char *name;
- debug_method_variant *variants;
-{
- struct debug_method *m;
-
- m = (struct debug_method *) xmalloc (sizeof *m);
- memset (m, 0, sizeof *m);
-
- m->name = name;
- m->variants = variants;
-
- return m;
-}
-
-/* Make a method argument. The second argument is the real name of
- the function. The third argument is the type of the function. The
- fourth argument is the visibility. The fifth argument is whether
- this is a const function. The sixth argument is whether this is a
- volatile function. The seventh argument is the offset in the
- virtual function table, if any. The eighth argument is the virtual
- function context. FIXME: Are the const and volatile arguments
- necessary? Could we just use debug_make_const_type? */
-
-/*ARGSUSED*/
-debug_method_variant
-debug_make_method_variant (handle, physname, type, visibility, constp,
- volatilep, voffset, context)
- PTR handle;
- const char *physname;
- debug_type type;
- enum debug_visibility visibility;
- boolean constp;
- boolean volatilep;
- bfd_vma voffset;
- debug_type context;
-{
- struct debug_method_variant *m;
-
- m = (struct debug_method_variant *) xmalloc (sizeof *m);
- memset (m, 0, sizeof *m);
-
- m->physname = physname;
- m->type = type;
- m->visibility = visibility;
- m->constp = constp;
- m->volatilep = volatilep;
- m->voffset = voffset;
- m->context = context;
-
- return m;
-}
-
-/* Make a static method argument. The arguments are the same as for
- debug_make_method_variant, except that the last two are omitted
- since a static method can not also be virtual. */
-
-debug_method_variant
-debug_make_static_method_variant (handle, physname, type, visibility,
- constp, volatilep)
- PTR handle;
- const char *physname;
- debug_type type;
- enum debug_visibility visibility;
- boolean constp;
- boolean volatilep;
-{
- struct debug_method_variant *m;
-
- m = (struct debug_method_variant *) xmalloc (sizeof *m);
- memset (m, 0, sizeof *m);
-
- m->physname = physname;
- m->type = type;
- m->visibility = visibility;
- m->constp = constp;
- m->volatilep = volatilep;
- m->voffset = VOFFSET_STATIC_METHOD;
-
- return m;
-}
-
-/* Name a type. */
-
-debug_type
-debug_name_type (handle, name, type)
- PTR handle;
- const char *name;
- debug_type type;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_named_type *n;
- struct debug_name *nm;
-
- if (name == NULL || type == NULL)
- return DEBUG_TYPE_NULL;
-
- if (info->current_unit == NULL
- || info->current_file == NULL)
- {
- debug_error ("debug_name_type: no current file");
- return DEBUG_TYPE_NULL;
- /* return false; */
- }
-
- t = debug_make_type (info, DEBUG_KIND_NAMED, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- n = (struct debug_named_type *) xmalloc (sizeof *n);
- memset (n, 0, sizeof *n);
-
- n->type = type;
-
- t->u.knamed = n;
-
- /* We always add the name to the global namespace. This is probably
- wrong in some cases, but it seems to be right for stabs. FIXME. */
-
- nm = debug_add_to_namespace (info, &info->current_file->globals, name,
- DEBUG_OBJECT_TYPE, DEBUG_LINKAGE_NONE);
- if (nm == NULL)
- return DEBUG_TYPE_NULL;
-
- nm->u.type = t;
-
- n->name = nm;
-
- return t;
-}
-
-/* Tag a type. */
-
-debug_type
-debug_tag_type (handle, name, type)
- PTR handle;
- const char *name;
- debug_type type;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_type *t;
- struct debug_named_type *n;
- struct debug_name *nm;
-
- if (name == NULL || type == NULL)
- return DEBUG_TYPE_NULL;
-
- if (info->current_file == NULL)
- {
- debug_error ("debug_tag_type: no current file");
- return DEBUG_TYPE_NULL;
- }
-
- if (type->kind == DEBUG_KIND_TAGGED)
- {
- if (strcmp (type->u.knamed->name->name, name) == 0)
- return type;
- debug_error ("debug_tag_type: extra tag attempted");
- return DEBUG_TYPE_NULL;
- }
-
- t = debug_make_type (info, DEBUG_KIND_TAGGED, 0);
- if (t == NULL)
- return DEBUG_TYPE_NULL;
-
- n = (struct debug_named_type *) xmalloc (sizeof *n);
- memset (n, 0, sizeof *n);
-
- n->type = type;
-
- t->u.knamed = n;
-
- /* We keep a global namespace of tags for each compilation unit. I
- don't know if that is the right thing to do. */
-
- nm = debug_add_to_namespace (info, &info->current_file->globals, name,
- DEBUG_OBJECT_TAG, DEBUG_LINKAGE_NONE);
- if (nm == NULL)
- return DEBUG_TYPE_NULL;
-
- nm->u.tag = t;
-
- n->name = nm;
-
- return t;
-}
-
-/* Record the size of a given type. */
-
-/*ARGSUSED*/
-boolean
-debug_record_type_size (handle, type, size)
- PTR handle;
- debug_type type;
- unsigned int size;
-{
-#if 0
- if (type->size != 0 && type->size != size)
- fprintf (stderr, "Warning: changing type size from %d to %d\n",
- type->size, size);
-#endif
-
- type->size = size;
-
- return true;
-}
-
-/* Find a named type. */
-
-debug_type
-debug_find_named_type (handle, name)
- PTR handle;
- const char *name;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_block *b;
- struct debug_file *f;
-
- /* We only search the current compilation unit. I don't know if
- this is right or not. */
-
- if (info->current_unit == NULL)
- {
- debug_error ("debug_find_named_type: no current compilation unit");
- return DEBUG_TYPE_NULL;
- }
-
- for (b = info->current_block; b != NULL; b = b->parent)
- {
- if (b->locals != NULL)
- {
- struct debug_name *n;
-
- for (n = b->locals->list; n != NULL; n = n->next)
- {
- if (n->kind == DEBUG_OBJECT_TYPE
- && n->name[0] == name[0]
- && strcmp (n->name, name) == 0)
- return n->u.type;
- }
- }
- }
-
- for (f = info->current_unit->files; f != NULL; f = f->next)
- {
- if (f->globals != NULL)
- {
- struct debug_name *n;
-
- for (n = f->globals->list; n != NULL; n = n->next)
- {
- if (n->kind == DEBUG_OBJECT_TYPE
- && n->name[0] == name[0]
- && strcmp (n->name, name) == 0)
- return n->u.type;
- }
- }
- }
-
- return DEBUG_TYPE_NULL;
-}
-
-/* Find a tagged type. */
-
-debug_type
-debug_find_tagged_type (handle, name, kind)
- PTR handle;
- const char *name;
- enum debug_type_kind kind;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_unit *u;
-
- /* We search the globals of all the compilation units. I don't know
- if this is correct or not. It would be easy to change. */
-
- for (u = info->units; u != NULL; u = u->next)
- {
- struct debug_file *f;
-
- for (f = u->files; f != NULL; f = f->next)
- {
- struct debug_name *n;
-
- if (f->globals != NULL)
- {
- for (n = f->globals->list; n != NULL; n = n->next)
- {
- if (n->kind == DEBUG_OBJECT_TAG
- && (kind == DEBUG_KIND_ILLEGAL
- || n->u.tag->kind == kind)
- && n->name[0] == name[0]
- && strcmp (n->name, name) == 0)
- return n->u.tag;
- }
- }
- }
- }
-
- return DEBUG_TYPE_NULL;
-}
-
-/* Get a base type. */
-
-static struct debug_type *
-debug_get_real_type (handle, type)
- PTR handle;
- debug_type type;
-{
- switch (type->kind)
- {
- default:
- return type;
- case DEBUG_KIND_INDIRECT:
- if (*type->u.kindirect->slot != NULL)
- return debug_get_real_type (handle, *type->u.kindirect->slot);
- return type;
- case DEBUG_KIND_NAMED:
- case DEBUG_KIND_TAGGED:
- return debug_get_real_type (handle, type->u.knamed->type);
- }
- /*NOTREACHED*/
-}
-
-/* Get the kind of a type. */
-
-enum debug_type_kind
-debug_get_type_kind (handle, type)
- PTR handle;
- debug_type type;
-{
- if (type == NULL)
- return DEBUG_KIND_ILLEGAL;
- type = debug_get_real_type (handle, type);
- return type->kind;
-}
-
-/* Get the name of a type. */
-
-const char *
-debug_get_type_name (handle, type)
- PTR handle;
- debug_type type;
-{
- if (type->kind == DEBUG_KIND_INDIRECT)
- {
- if (*type->u.kindirect->slot != NULL)
- return debug_get_type_name (handle, *type->u.kindirect->slot);
- return type->u.kindirect->tag;
- }
- if (type->kind == DEBUG_KIND_NAMED
- || type->kind == DEBUG_KIND_TAGGED)
- return type->u.knamed->name->name;
- return NULL;
-}
-
-/* Get the size of a type. */
-
-bfd_vma
-debug_get_type_size (handle, type)
- PTR handle;
- debug_type type;
-{
- if (type == NULL)
- return 0;
-
- /* We don't call debug_get_real_type, because somebody might have
- called debug_record_type_size on a named or indirect type. */
-
- if (type->size != 0)
- return type->size;
-
- switch (type->kind)
- {
- default:
- return 0;
- case DEBUG_KIND_INDIRECT:
- if (*type->u.kindirect->slot != NULL)
- return debug_get_type_size (handle, *type->u.kindirect->slot);
- return 0;
- case DEBUG_KIND_NAMED:
- case DEBUG_KIND_TAGGED:
- return debug_get_type_size (handle, type->u.knamed->type);
- }
- /*NOTREACHED*/
-}
-
-/* Get the return type of a function or method type. */
-
-debug_type
-debug_get_return_type (handle, type)
- PTR handle;
- debug_type type;
-{
- if (type == NULL)
- return DEBUG_TYPE_NULL;
- type = debug_get_real_type (handle, type);
- switch (type->kind)
- {
- default:
- return DEBUG_TYPE_NULL;
- case DEBUG_KIND_FUNCTION:
- return type->u.kfunction->return_type;
- case DEBUG_KIND_METHOD:
- return type->u.kmethod->return_type;
- }
- /*NOTREACHED*/
-}
-
-/* Get the parameter types of a function or method type (except that
- we don't currently store the parameter types of a function). */
-
-const debug_type *
-debug_get_parameter_types (handle, type, pvarargs)
- PTR handle;
- debug_type type;
- boolean *pvarargs;
-{
- if (type == NULL)
- return NULL;
- type = debug_get_real_type (handle, type);
- switch (type->kind)
- {
- default:
- return NULL;
- case DEBUG_KIND_FUNCTION:
- *pvarargs = type->u.kfunction->varargs;
- return type->u.kfunction->arg_types;
- case DEBUG_KIND_METHOD:
- *pvarargs = type->u.kmethod->varargs;
- return type->u.kmethod->arg_types;
- }
- /*NOTREACHED*/
-}
-
-/* Get the target type of a type. */
-
-debug_type
-debug_get_target_type (handle, type)
- PTR handle;
- debug_type type;
-{
- if (type == NULL)
- return NULL;
- type = debug_get_real_type (handle, type);
- switch (type->kind)
- {
- default:
- return NULL;
- case DEBUG_KIND_POINTER:
- return type->u.kpointer;
- case DEBUG_KIND_REFERENCE:
- return type->u.kreference;
- case DEBUG_KIND_CONST:
- return type->u.kconst;
- case DEBUG_KIND_VOLATILE:
- return type->u.kvolatile;
- }
- /*NOTREACHED*/
-}
-
-/* Get the NULL terminated array of fields for a struct, union, or
- class. */
-
-const debug_field *
-debug_get_fields (handle, type)
- PTR handle;
- debug_type type;
-{
- if (type == NULL)
- return NULL;
- type = debug_get_real_type (handle, type);
- switch (type->kind)
- {
- default:
- return NULL;
- case DEBUG_KIND_STRUCT:
- case DEBUG_KIND_UNION:
- case DEBUG_KIND_CLASS:
- case DEBUG_KIND_UNION_CLASS:
- return type->u.kclass->fields;
- }
- /*NOTREACHED*/
-}
-
-/* Get the type of a field. */
-
-/*ARGSUSED*/
-debug_type
-debug_get_field_type (handle, field)
- PTR handle;
- debug_field field;
-{
- if (field == NULL)
- return NULL;
- return field->type;
-}
-
-/* Get the name of a field. */
-
-/*ARGSUSED*/
-const char *
-debug_get_field_name (handle, field)
- PTR handle;
- debug_field field;
-{
- if (field == NULL)
- return NULL;
- return field->name;
-}
-
-/* Get the bit position of a field. */
-
-/*ARGSUSED*/
-bfd_vma
-debug_get_field_bitpos (handle, field)
- PTR handle;
- debug_field field;
-{
- if (field == NULL || field->static_member)
- return (bfd_vma) -1;
- return field->u.f.bitpos;
-}
-
-/* Get the bit size of a field. */
-
-/*ARGSUSED*/
-bfd_vma
-debug_get_field_bitsize (handle, field)
- PTR handle;
- debug_field field;
-{
- if (field == NULL || field->static_member)
- return (bfd_vma) -1;
- return field->u.f.bitsize;
-}
-
-/* Get the visibility of a field. */
-
-/*ARGSUSED*/
-enum debug_visibility
-debug_get_field_visibility (handle, field)
- PTR handle;
- debug_field field;
-{
- if (field == NULL)
- return DEBUG_VISIBILITY_IGNORE;
- return field->visibility;
-}
-
-/* Get the physical name of a field. */
-
-const char *
-debug_get_field_physname (handle, field)
- PTR handle;
- debug_field field;
-{
- if (field == NULL || ! field->static_member)
- return NULL;
- return field->u.s.physname;
-}
-
-/* Write out the debugging information. This is given a handle to
- debugging information, and a set of function pointers to call. */
-
-boolean
-debug_write (handle, fns, fhandle)
- PTR handle;
- const struct debug_write_fns *fns;
- PTR fhandle;
-{
- struct debug_handle *info = (struct debug_handle *) handle;
- struct debug_unit *u;
-
- /* We use a mark to tell whether we have already written out a
- particular name. We use an integer, so that we don't have to
- clear the mark fields if we happen to write out the same
- information more than once. */
- ++info->mark;
-
- /* The base_id field holds an ID value which will never be used, so
- that we can tell whether we have assigned an ID during this call
- to debug_write. */
- info->base_id = info->class_id;
-
- /* We keep a linked list of classes for which was have assigned ID's
- during this call to debug_write. */
- info->id_list = NULL;
-
- for (u = info->units; u != NULL; u = u->next)
- {
- struct debug_file *f;
- boolean first_file;
-
- info->current_write_lineno = u->linenos;
- info->current_write_lineno_index = 0;
-
- if (! (*fns->start_compilation_unit) (fhandle, u->files->filename))
- return false;
-
- first_file = true;
- for (f = u->files; f != NULL; f = f->next)
- {
- struct debug_name *n;
-
- if (first_file)
- first_file = false;
- else
- {
- if (! (*fns->start_source) (fhandle, f->filename))
- return false;
- }
-
- if (f->globals != NULL)
- {
- for (n = f->globals->list; n != NULL; n = n->next)
- {
- if (! debug_write_name (info, fns, fhandle, n))
- return false;
- }
- }
- }
-
- /* Output any line number information which hasn't already been
- handled. */
- if (! debug_write_linenos (info, fns, fhandle, (bfd_vma) -1))
- return false;
- }
-
- return true;
-}
-
-/* Write out an element in a namespace. */
-
-static boolean
-debug_write_name (info, fns, fhandle, n)
- struct debug_handle *info;
- const struct debug_write_fns *fns;
- PTR fhandle;
- struct debug_name *n;
-{
- switch (n->kind)
- {
- case DEBUG_OBJECT_TYPE:
- if (! debug_write_type (info, fns, fhandle, n->u.type, n)
- || ! (*fns->typdef) (fhandle, n->name))
- return false;
- return true;
- case DEBUG_OBJECT_TAG:
- if (! debug_write_type (info, fns, fhandle, n->u.tag, n))
- return false;
- return (*fns->tag) (fhandle, n->name);
- case DEBUG_OBJECT_VARIABLE:
- if (! debug_write_type (info, fns, fhandle, n->u.variable->type,
- (struct debug_name *) NULL))
- return false;
- return (*fns->variable) (fhandle, n->name, n->u.variable->kind,
- n->u.variable->val);
- case DEBUG_OBJECT_FUNCTION:
- return debug_write_function (info, fns, fhandle, n->name,
- n->linkage, n->u.function);
- case DEBUG_OBJECT_INT_CONSTANT:
- return (*fns->int_constant) (fhandle, n->name, n->u.int_constant);
- case DEBUG_OBJECT_FLOAT_CONSTANT:
- return (*fns->float_constant) (fhandle, n->name, n->u.float_constant);
- case DEBUG_OBJECT_TYPED_CONSTANT:
- if (! debug_write_type (info, fns, fhandle, n->u.typed_constant->type,
- (struct debug_name *) NULL))
- return false;
- return (*fns->typed_constant) (fhandle, n->name,
- n->u.typed_constant->val);
- default:
- abort ();
- return false;
- }
- /*NOTREACHED*/
-}
-
-/* Write out a type. If the type is DEBUG_KIND_NAMED or
- DEBUG_KIND_TAGGED, then the name argument is the name for which we
- are about to call typedef or tag. If the type is anything else,
- then the name argument is a tag from a DEBUG_KIND_TAGGED type which
- points to this one. */
-
-static boolean
-debug_write_type (info, fns, fhandle, type, name)
- struct debug_handle *info;
- const struct debug_write_fns *fns;
- PTR fhandle;
- struct debug_type *type;
- struct debug_name *name;
-{
- unsigned int i;
- int is;
- const char *tag;
-
- /* If we have a name for this type, just output it. We only output
- typedef names after they have been defined. We output type tags
- whenever we are not actually defining them. */
- if ((type->kind == DEBUG_KIND_NAMED
- || type->kind == DEBUG_KIND_TAGGED)
- && (type->u.knamed->name->mark == info->mark
- || (type->kind == DEBUG_KIND_TAGGED
- && type->u.knamed->name != name)))
- {
- if (type->kind == DEBUG_KIND_NAMED)
- return (*fns->typedef_type) (fhandle, type->u.knamed->name->name);
- else
- {
- struct debug_type *real;
- unsigned int id;
-
- real = debug_get_real_type ((PTR) info, type);
- id = 0;
- if ((real->kind == DEBUG_KIND_STRUCT
- || real->kind == DEBUG_KIND_UNION
- || real->kind == DEBUG_KIND_CLASS
- || real->kind == DEBUG_KIND_UNION_CLASS)
- && real->u.kclass != NULL)
- {
- if (real->u.kclass->id <= info->base_id)
- {
- if (! debug_set_class_id (info,
- type->u.knamed->name->name,
- real))
- return false;
- }
- id = real->u.kclass->id;
- }
-
- return (*fns->tag_type) (fhandle, type->u.knamed->name->name, id,
- real->kind);
- }
- }
-
- /* Mark the name after we have already looked for a known name, so
- that we don't just define a type in terms of itself. We need to
- mark the name here so that a struct containing a pointer to
- itself will work. */
- if (name != NULL)
- name->mark = info->mark;
-
- tag = NULL;
- if (name != NULL
- && type->kind != DEBUG_KIND_NAMED
- && type->kind != DEBUG_KIND_TAGGED)
- {
- assert (name->kind == DEBUG_OBJECT_TAG);
- tag = name->name;
- }
-
- switch (type->kind)
- {
- case DEBUG_KIND_ILLEGAL:
- debug_error ("debug_write_type: illegal type encountered");
- return false;
- case DEBUG_KIND_INDIRECT:
- if (*type->u.kindirect->slot == DEBUG_TYPE_NULL)
- return (*fns->empty_type) (fhandle);
- return debug_write_type (info, fns, fhandle, *type->u.kindirect->slot,
- name);
- case DEBUG_KIND_VOID:
- return (*fns->void_type) (fhandle);
- case DEBUG_KIND_INT:
- return (*fns->int_type) (fhandle, type->size, type->u.kint);
- case DEBUG_KIND_FLOAT:
- return (*fns->float_type) (fhandle, type->size);
- case DEBUG_KIND_COMPLEX:
- return (*fns->complex_type) (fhandle, type->size);
- case DEBUG_KIND_BOOL:
- return (*fns->bool_type) (fhandle, type->size);
- case DEBUG_KIND_STRUCT:
- case DEBUG_KIND_UNION:
- if (type->u.kclass != NULL)
- {
- if (type->u.kclass->id <= info->base_id)
- {
- if (! debug_set_class_id (info, tag, type))
- return false;
- }
-
- if (info->mark == type->u.kclass->mark)
- {
- /* We are currently outputting this struct, or we have
- already output it. I don't know if this can happen,
- but it can happen for a class. */
- assert (type->u.kclass->id > info->base_id);
- return (*fns->tag_type) (fhandle, tag, type->u.kclass->id,
- type->kind);
- }
- type->u.kclass->mark = info->mark;
- }
-
- if (! (*fns->start_struct_type) (fhandle, tag,
- (type->u.kclass != NULL
- ? type->u.kclass->id
- : 0),
- type->kind == DEBUG_KIND_STRUCT,
- type->size))
- return false;
- if (type->u.kclass != NULL
- && type->u.kclass->fields != NULL)
- {
- for (i = 0; type->u.kclass->fields[i] != NULL; i++)
- {
- struct debug_field *f;
-
- f = type->u.kclass->fields[i];
- if (! debug_write_type (info, fns, fhandle, f->type,
- (struct debug_name *) NULL)
- || ! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos,
- f->u.f.bitsize, f->visibility))
- return false;
- }
- }
- return (*fns->end_struct_type) (fhandle);
- case DEBUG_KIND_CLASS:
- case DEBUG_KIND_UNION_CLASS:
- return debug_write_class_type (info, fns, fhandle, type, tag);
- case DEBUG_KIND_ENUM:
- if (type->u.kenum == NULL)
- return (*fns->enum_type) (fhandle, tag, (const char **) NULL,
- (bfd_signed_vma *) NULL);
- return (*fns->enum_type) (fhandle, tag, type->u.kenum->names,
- type->u.kenum->values);
- case DEBUG_KIND_POINTER:
- if (! debug_write_type (info, fns, fhandle, type->u.kpointer,
- (struct debug_name *) NULL))
- return false;
- return (*fns->pointer_type) (fhandle);
- case DEBUG_KIND_FUNCTION:
- if (! debug_write_type (info, fns, fhandle,
- type->u.kfunction->return_type,
- (struct debug_name *) NULL))
- return false;
- if (type->u.kfunction->arg_types == NULL)
- is = -1;
- else
- {
- for (is = 0; type->u.kfunction->arg_types[is] != NULL; is++)
- if (! debug_write_type (info, fns, fhandle,
- type->u.kfunction->arg_types[is],
- (struct debug_name *) NULL))
- return false;
- }
- return (*fns->function_type) (fhandle, is,
- type->u.kfunction->varargs);
- case DEBUG_KIND_REFERENCE:
- if (! debug_write_type (info, fns, fhandle, type->u.kreference,
- (struct debug_name *) NULL))
- return false;
- return (*fns->reference_type) (fhandle);
- case DEBUG_KIND_RANGE:
- if (! debug_write_type (info, fns, fhandle, type->u.krange->type,
- (struct debug_name *) NULL))
- return false;
- return (*fns->range_type) (fhandle, type->u.krange->lower,
- type->u.krange->upper);
- case DEBUG_KIND_ARRAY:
- if (! debug_write_type (info, fns, fhandle, type->u.karray->element_type,
- (struct debug_name *) NULL)
- || ! debug_write_type (info, fns, fhandle,
- type->u.karray->range_type,
- (struct debug_name *) NULL))
- return false;
- return (*fns->array_type) (fhandle, type->u.karray->lower,
- type->u.karray->upper,
- type->u.karray->stringp);
- case DEBUG_KIND_SET:
- if (! debug_write_type (info, fns, fhandle, type->u.kset->type,
- (struct debug_name *) NULL))
- return false;
- return (*fns->set_type) (fhandle, type->u.kset->bitstringp);
- case DEBUG_KIND_OFFSET:
- if (! debug_write_type (info, fns, fhandle, type->u.koffset->base_type,
- (struct debug_name *) NULL)
- || ! debug_write_type (info, fns, fhandle,
- type->u.koffset->target_type,
- (struct debug_name *) NULL))
- return false;
- return (*fns->offset_type) (fhandle);
- case DEBUG_KIND_METHOD:
- if (! debug_write_type (info, fns, fhandle,
- type->u.kmethod->return_type,
- (struct debug_name *) NULL))
- return false;
- if (type->u.kmethod->arg_types == NULL)
- is = -1;
- else
- {
- for (is = 0; type->u.kmethod->arg_types[is] != NULL; is++)
- if (! debug_write_type (info, fns, fhandle,
- type->u.kmethod->arg_types[is],
- (struct debug_name *) NULL))
- return false;
- }
- if (type->u.kmethod->domain_type != NULL)
- {
- if (! debug_write_type (info, fns, fhandle,
- type->u.kmethod->domain_type,
- (struct debug_name *) NULL))
- return false;
- }
- return (*fns->method_type) (fhandle,
- type->u.kmethod->domain_type != NULL,
- is,
- type->u.kmethod->varargs);
- case DEBUG_KIND_CONST:
- if (! debug_write_type (info, fns, fhandle, type->u.kconst,
- (struct debug_name *) NULL))
- return false;
- return (*fns->const_type) (fhandle);
- case DEBUG_KIND_VOLATILE:
- if (! debug_write_type (info, fns, fhandle, type->u.kvolatile,
- (struct debug_name *) NULL))
- return false;
- return (*fns->volatile_type) (fhandle);
- case DEBUG_KIND_NAMED:
- return debug_write_type (info, fns, fhandle, type->u.knamed->type,
- (struct debug_name *) NULL);
- case DEBUG_KIND_TAGGED:
- return debug_write_type (info, fns, fhandle, type->u.knamed->type,
- type->u.knamed->name);
- default:
- abort ();
- return false;
- }
-}
-
-/* Write out a class type. */
-
-static boolean
-debug_write_class_type (info, fns, fhandle, type, tag)
- struct debug_handle *info;
- const struct debug_write_fns *fns;
- PTR fhandle;
- struct debug_type *type;
- const char *tag;
-{
- unsigned int i;
- unsigned int id;
- struct debug_type *vptrbase;
-
- if (type->u.kclass == NULL)
- {
- id = 0;
- vptrbase = NULL;
- }
- else
- {
- if (type->u.kclass->id <= info->base_id)
- {
- if (! debug_set_class_id (info, tag, type))
- return false;
- }
-
- if (info->mark == type->u.kclass->mark)
- {
- /* We are currently outputting this class, or we have
- already output it. This can happen when there are
- methods for an anonymous class. */
- assert (type->u.kclass->id > info->base_id);
- return (*fns->tag_type) (fhandle, tag, type->u.kclass->id,
- type->kind);
- }
- type->u.kclass->mark = info->mark;
- id = type->u.kclass->id;
-
- vptrbase = type->u.kclass->vptrbase;
- if (vptrbase != NULL && vptrbase != type)
- {
- if (! debug_write_type (info, fns, fhandle, vptrbase,
- (struct debug_name *) NULL))
- return false;
- }
- }
-
- if (! (*fns->start_class_type) (fhandle, tag, id,
- type->kind == DEBUG_KIND_CLASS,
- type->size,
- vptrbase != NULL,
- vptrbase == type))
- return false;
-
- if (type->u.kclass != NULL)
- {
- if (type->u.kclass->fields != NULL)
- {
- for (i = 0; type->u.kclass->fields[i] != NULL; i++)
- {
- struct debug_field *f;
-
- f = type->u.kclass->fields[i];
- if (! debug_write_type (info, fns, fhandle, f->type,
- (struct debug_name *) NULL))
- return false;
- if (f->static_member)
- {
- if (! (*fns->class_static_member) (fhandle, f->name,
- f->u.s.physname,
- f->visibility))
- return false;
- }
- else
- {
- if (! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos,
- f->u.f.bitsize, f->visibility))
- return false;
- }
- }
- }
-
- if (type->u.kclass->baseclasses != NULL)
- {
- for (i = 0; type->u.kclass->baseclasses[i] != NULL; i++)
- {
- struct debug_baseclass *b;
-
- b = type->u.kclass->baseclasses[i];
- if (! debug_write_type (info, fns, fhandle, b->type,
- (struct debug_name *) NULL))
- return false;
- if (! (*fns->class_baseclass) (fhandle, b->bitpos, b->virtual,
- b->visibility))
- return false;
- }
- }
-
- if (type->u.kclass->methods != NULL)
- {
- for (i = 0; type->u.kclass->methods[i] != NULL; i++)
- {
- struct debug_method *m;
- unsigned int j;
-
- m = type->u.kclass->methods[i];
- if (! (*fns->class_start_method) (fhandle, m->name))
- return false;
- for (j = 0; m->variants[j] != NULL; j++)
- {
- struct debug_method_variant *v;
-
- v = m->variants[j];
- if (v->context != NULL)
- {
- if (! debug_write_type (info, fns, fhandle, v->context,
- (struct debug_name *) NULL))
- return false;
- }
- if (! debug_write_type (info, fns, fhandle, v->type,
- (struct debug_name *) NULL))
- return false;
- if (v->voffset != VOFFSET_STATIC_METHOD)
- {
- if (! (*fns->class_method_variant) (fhandle, v->physname,
- v->visibility,
- v->constp,
- v->volatilep,
- v->voffset,
- v->context != NULL))
- return false;
- }
- else
- {
- if (! (*fns->class_static_method_variant) (fhandle,
- v->physname,
- v->visibility,
- v->constp,
- v->volatilep))
- return false;
- }
- }
- if (! (*fns->class_end_method) (fhandle))
- return false;
- }
- }
- }
-
- return (*fns->end_class_type) (fhandle);
-}
-
-/* Write out information for a function. */
-
-static boolean
-debug_write_function (info, fns, fhandle, name, linkage, function)
- struct debug_handle *info;
- const struct debug_write_fns *fns;
- PTR fhandle;
- const char *name;
- enum debug_object_linkage linkage;
- struct debug_function *function;
-{
- struct debug_parameter *p;
- struct debug_block *b;
-
- if (! debug_write_linenos (info, fns, fhandle, function->blocks->start))
- return false;
-
- if (! debug_write_type (info, fns, fhandle, function->return_type,
- (struct debug_name *) NULL))
- return false;
-
- if (! (*fns->start_function) (fhandle, name,
- linkage == DEBUG_LINKAGE_GLOBAL))
- return false;
-
- for (p = function->parameters; p != NULL; p = p->next)
- {
- if (! debug_write_type (info, fns, fhandle, p->type,
- (struct debug_name *) NULL)
- || ! (*fns->function_parameter) (fhandle, p->name, p->kind, p->val))
- return false;
- }
-
- for (b = function->blocks; b != NULL; b = b->next)
- {
- if (! debug_write_block (info, fns, fhandle, b))
- return false;
- }
-
- return (*fns->end_function) (fhandle);
-}
-
-/* Write out information for a block. */
-
-static boolean
-debug_write_block (info, fns, fhandle, block)
- struct debug_handle *info;
- const struct debug_write_fns *fns;
- PTR fhandle;
- struct debug_block *block;
-{
- struct debug_name *n;
- struct debug_block *b;
-
- if (! debug_write_linenos (info, fns, fhandle, block->start))
- return false;
-
- /* I can't see any point to writing out a block with no local
- variables, so we don't bother, except for the top level block. */
- if (block->locals != NULL || block->parent == NULL)
- {
- if (! (*fns->start_block) (fhandle, block->start))
- return false;
- }
-
- if (block->locals != NULL)
- {
- for (n = block->locals->list; n != NULL; n = n->next)
- {
- if (! debug_write_name (info, fns, fhandle, n))
- return false;
- }
- }
-
- for (b = block->children; b != NULL; b = b->next)
- {
- if (! debug_write_block (info, fns, fhandle, b))
- return false;
- }
-
- if (! debug_write_linenos (info, fns, fhandle, block->end))
- return false;
-
- if (block->locals != NULL || block->parent == NULL)
- {
- if (! (*fns->end_block) (fhandle, block->end))
- return false;
- }
-
- return true;
-}
-
-/* Write out line number information up to ADDRESS. */
-
-static boolean
-debug_write_linenos (info, fns, fhandle, address)
- struct debug_handle *info;
- const struct debug_write_fns *fns;
- PTR fhandle;
- bfd_vma address;
-{
- while (info->current_write_lineno != NULL)
- {
- struct debug_lineno *l;
-
- l = info->current_write_lineno;
-
- while (info->current_write_lineno_index < DEBUG_LINENO_COUNT)
- {
- if (l->linenos[info->current_write_lineno_index]
- == (unsigned long) -1)
- break;
-
- if (l->addrs[info->current_write_lineno_index] >= address)
- return true;
-
- if (! (*fns->lineno) (fhandle, l->file->filename,
- l->linenos[info->current_write_lineno_index],
- l->addrs[info->current_write_lineno_index]))
- return false;
-
- ++info->current_write_lineno_index;
- }
-
- info->current_write_lineno = l->next;
- info->current_write_lineno_index = 0;
- }
-
- return true;
-}
-
-/* Get the ID number for a class. If during the same call to
- debug_write we find a struct with the same definition with the same
- name, we use the same ID. This type of things happens because the
- same struct will be defined by multiple compilation units. */
-
-static boolean
-debug_set_class_id (info, tag, type)
- struct debug_handle *info;
- const char *tag;
- struct debug_type *type;
-{
- struct debug_class_type *c;
- struct debug_class_id *l;
-
- assert (type->kind == DEBUG_KIND_STRUCT
- || type->kind == DEBUG_KIND_UNION
- || type->kind == DEBUG_KIND_CLASS
- || type->kind == DEBUG_KIND_UNION_CLASS);
-
- c = type->u.kclass;
-
- if (c->id > info->base_id)
- return true;
-
- for (l = info->id_list; l != NULL; l = l->next)
- {
- if (l->type->kind != type->kind)
- continue;
-
- if (tag == NULL)
- {
- if (l->tag != NULL)
- continue;
- }
- else
- {
- if (l->tag == NULL
- || l->tag[0] != tag[0]
- || strcmp (l->tag, tag) != 0)
- continue;
- }
-
- if (debug_type_samep (info, l->type, type))
- {
- c->id = l->type->u.kclass->id;
- return true;
- }
- }
-
- /* There are no identical types. Use a new ID, and add it to the
- list. */
- ++info->class_id;
- c->id = info->class_id;
-
- l = (struct debug_class_id *) xmalloc (sizeof *l);
- memset (l, 0, sizeof *l);
-
- l->type = type;
- l->tag = tag;
-
- l->next = info->id_list;
- info->id_list = l;
-
- return true;
-}
-
-/* See if two types are the same. At this point, we don't care about
- tags and the like. */
-
-static boolean
-debug_type_samep (info, t1, t2)
- struct debug_handle *info;
- struct debug_type *t1;
- struct debug_type *t2;
-{
- struct debug_type_compare_list *l;
- struct debug_type_compare_list top;
- boolean ret;
-
- if (t1 == NULL)
- return t2 == NULL;
- if (t2 == NULL)
- return false;
-
- while (t1->kind == DEBUG_KIND_INDIRECT)
- {
- t1 = *t1->u.kindirect->slot;
- if (t1 == NULL)
- return false;
- }
- while (t2->kind == DEBUG_KIND_INDIRECT)
- {
- t2 = *t2->u.kindirect->slot;
- if (t2 == NULL)
- return false;
- }
-
- if (t1 == t2)
- return true;
-
- /* As a special case, permit a typedef to match a tag, since C++
- debugging output will sometimes add a typedef where C debugging
- output will not. */
- if (t1->kind == DEBUG_KIND_NAMED
- && t2->kind == DEBUG_KIND_TAGGED)
- return debug_type_samep (info, t1->u.knamed->type, t2);
- else if (t1->kind == DEBUG_KIND_TAGGED
- && t2->kind == DEBUG_KIND_NAMED)
- return debug_type_samep (info, t1, t2->u.knamed->type);
-
- if (t1->kind != t2->kind
- || t1->size != t2->size)
- return false;
-
- /* Get rid of the trivial cases first. */
- switch (t1->kind)
- {
- default:
- break;
- case DEBUG_KIND_VOID:
- case DEBUG_KIND_FLOAT:
- case DEBUG_KIND_COMPLEX:
- case DEBUG_KIND_BOOL:
- return true;
- case DEBUG_KIND_INT:
- return t1->u.kint == t2->u.kint;
- }
-
- /* We have to avoid an infinite recursion. We do this by keeping a
- list of types which we are comparing. We just keep the list on
- the stack. If we encounter a pair of types we are currently
- comparing, we just assume that they are equal. */
- for (l = info->compare_list; l != NULL; l = l->next)
- {
- if (l->t1 == t1 && l->t2 == t2)
- return true;
- }
-
- top.t1 = t1;
- top.t2 = t2;
- top.next = info->compare_list;
- info->compare_list = &top;
-
- switch (t1->kind)
- {
- default:
- abort ();
- ret = false;
- break;
-
- case DEBUG_KIND_STRUCT:
- case DEBUG_KIND_UNION:
- case DEBUG_KIND_CLASS:
- case DEBUG_KIND_UNION_CLASS:
- if (t1->u.kclass == NULL)
- ret = t2->u.kclass == NULL;
- else if (t2->u.kclass == NULL)
- ret = false;
- else if (t1->u.kclass->id > info->base_id
- && t1->u.kclass->id == t2->u.kclass->id)
- ret = true;
- else
- ret = debug_class_type_samep (info, t1, t2);
- break;
-
- case DEBUG_KIND_ENUM:
- if (t1->u.kenum == NULL)
- ret = t2->u.kenum == NULL;
- else if (t2->u.kenum == NULL)
- ret = false;
- else
- {
- const char **pn1, **pn2;
- bfd_signed_vma *pv1, *pv2;
-
- pn1 = t1->u.kenum->names;
- pn2 = t2->u.kenum->names;
- pv1 = t1->u.kenum->values;
- pv2 = t2->u.kenum->values;
- while (*pn1 != NULL && *pn2 != NULL)
- {
- if (**pn1 != **pn2
- || *pv1 != *pv2
- || strcmp (*pn1, *pn2) != 0)
- break;
- ++pn1;
- ++pn2;
- ++pv1;
- ++pv2;
- }
- ret = *pn1 == NULL && *pn2 == NULL;
- }
- break;
-
- case DEBUG_KIND_POINTER:
- ret = debug_type_samep (info, t1->u.kpointer, t2->u.kpointer);
- break;
-
- case DEBUG_KIND_FUNCTION:
- if (t1->u.kfunction->varargs != t2->u.kfunction->varargs
- || ! debug_type_samep (info, t1->u.kfunction->return_type,
- t2->u.kfunction->return_type)
- || ((t1->u.kfunction->arg_types == NULL)
- != (t2->u.kfunction->arg_types == NULL)))
- ret = false;
- else if (t1->u.kfunction->arg_types == NULL)
- ret = true;
- else
- {
- struct debug_type **a1, **a2;
-
- a1 = t1->u.kfunction->arg_types;
- a2 = t2->u.kfunction->arg_types;
- while (*a1 != NULL && *a2 != NULL)
- if (! debug_type_samep (info, *a1, *a2))
- break;
- ret = *a1 == NULL && *a2 == NULL;
- }
- break;
-
- case DEBUG_KIND_REFERENCE:
- ret = debug_type_samep (info, t1->u.kreference, t2->u.kreference);
- break;
-
- case DEBUG_KIND_RANGE:
- ret = (t1->u.krange->lower == t2->u.krange->lower
- && t1->u.krange->upper == t2->u.krange->upper
- && debug_type_samep (info, t1->u.krange->type,
- t2->u.krange->type));
-
- case DEBUG_KIND_ARRAY:
- ret = (t1->u.karray->lower == t2->u.karray->lower
- && t1->u.karray->upper == t2->u.karray->upper
- && t1->u.karray->stringp == t2->u.karray->stringp
- && debug_type_samep (info, t1->u.karray->element_type,
- t2->u.karray->element_type));
- break;
-
- case DEBUG_KIND_SET:
- ret = (t1->u.kset->bitstringp == t2->u.kset->bitstringp
- && debug_type_samep (info, t1->u.kset->type, t2->u.kset->type));
- break;
-
- case DEBUG_KIND_OFFSET:
- ret = (debug_type_samep (info, t1->u.koffset->base_type,
- t2->u.koffset->base_type)
- && debug_type_samep (info, t1->u.koffset->target_type,
- t2->u.koffset->target_type));
- break;
-
- case DEBUG_KIND_METHOD:
- if (t1->u.kmethod->varargs != t2->u.kmethod->varargs
- || ! debug_type_samep (info, t1->u.kmethod->return_type,
- t2->u.kmethod->return_type)
- || ! debug_type_samep (info, t1->u.kmethod->domain_type,
- t2->u.kmethod->domain_type)
- || ((t1->u.kmethod->arg_types == NULL)
- != (t2->u.kmethod->arg_types == NULL)))
- ret = false;
- else if (t1->u.kmethod->arg_types == NULL)
- ret = true;
- else
- {
- struct debug_type **a1, **a2;
-
- a1 = t1->u.kmethod->arg_types;
- a2 = t2->u.kmethod->arg_types;
- while (*a1 != NULL && *a2 != NULL)
- if (! debug_type_samep (info, *a1, *a2))
- break;
- ret = *a1 == NULL && *a2 == NULL;
- }
- break;
-
- case DEBUG_KIND_CONST:
- ret = debug_type_samep (info, t1->u.kconst, t2->u.kconst);
- break;
-
- case DEBUG_KIND_VOLATILE:
- ret = debug_type_samep (info, t1->u.kvolatile, t2->u.kvolatile);
- break;
-
- case DEBUG_KIND_NAMED:
- case DEBUG_KIND_TAGGED:
- ret = (strcmp (t1->u.knamed->name->name, t2->u.knamed->name->name) == 0
- && debug_type_samep (info, t1->u.knamed->type,
- t2->u.knamed->type));
- break;
- }
-
- info->compare_list = top.next;
-
- return ret;
-}
-
-/* See if two classes are the same. This is a subroutine of
- debug_type_samep. */
-
-static boolean
-debug_class_type_samep (info, t1, t2)
- struct debug_handle *info;
- struct debug_type *t1;
- struct debug_type *t2;
-{
- struct debug_class_type *c1, *c2;
-
- c1 = t1->u.kclass;
- c2 = t2->u.kclass;
-
- if ((c1->fields == NULL) != (c2->fields == NULL)
- || (c1->baseclasses == NULL) != (c2->baseclasses == NULL)
- || (c1->methods == NULL) != (c2->methods == NULL)
- || (c1->vptrbase == NULL) != (c2->vptrbase == NULL))
- return false;
-
- if (c1->fields != NULL)
- {
- struct debug_field **pf1, **pf2;
-
- for (pf1 = c1->fields, pf2 = c2->fields;
- *pf1 != NULL && *pf2 != NULL;
- pf1++, pf2++)
- {
- struct debug_field *f1, *f2;
-
- f1 = *pf1;
- f2 = *pf2;
- if (f1->name[0] != f2->name[0]
- || f1->visibility != f2->visibility
- || f1->static_member != f2->static_member)
- return false;
- if (f1->static_member)
- {
- if (strcmp (f1->u.s.physname, f2->u.s.physname) != 0)
- return false;
- }
- else
- {
- if (f1->u.f.bitpos != f2->u.f.bitpos
- || f1->u.f.bitsize != f2->u.f.bitsize)
- return false;
- }
- /* We do the checks which require function calls last. We
- don't require that the types of fields have the same
- names, since that sometimes fails in the presence of
- typedefs and we really don't care. */
- if (strcmp (f1->name, f2->name) != 0
- || ! debug_type_samep (info,
- debug_get_real_type ((PTR) info,
- f1->type),
- debug_get_real_type ((PTR) info,
- f2->type)))
- return false;
- }
- if (*pf1 != NULL || *pf2 != NULL)
- return false;
- }
-
- if (c1->vptrbase != NULL)
- {
- if (! debug_type_samep (info, c1->vptrbase, c2->vptrbase))
- return false;
- }
-
- if (c1->baseclasses != NULL)
- {
- struct debug_baseclass **pb1, **pb2;
-
- for (pb1 = c1->baseclasses, pb2 = c2->baseclasses;
- *pb1 != NULL && *pb2 != NULL;
- ++pb1, ++pb2)
- {
- struct debug_baseclass *b1, *b2;
-
- b1 = *pb1;
- b2 = *pb2;
- if (b1->bitpos != b2->bitpos
- || b1->virtual != b2->virtual
- || b1->visibility != b2->visibility
- || ! debug_type_samep (info, b1->type, b2->type))
- return false;
- }
- if (*pb1 != NULL || *pb2 != NULL)
- return false;
- }
-
- if (c1->methods != NULL)
- {
- struct debug_method **pm1, **pm2;
-
- for (pm1 = c1->methods, pm2 = c2->methods;
- *pm1 != NULL && *pm2 != NULL;
- ++pm1, ++pm2)
- {
- struct debug_method *m1, *m2;
-
- m1 = *pm1;
- m2 = *pm2;
- if (m1->name[0] != m2->name[0]
- || strcmp (m1->name, m2->name) != 0
- || (m1->variants == NULL) != (m2->variants == NULL))
- return false;
- if (m1->variants == NULL)
- {
- struct debug_method_variant **pv1, **pv2;
-
- for (pv1 = m1->variants, pv2 = m2->variants;
- *pv1 != NULL && *pv2 != NULL;
- ++pv1, ++pv2)
- {
- struct debug_method_variant *v1, *v2;
-
- v1 = *pv1;
- v2 = *pv2;
- if (v1->physname[0] != v2->physname[0]
- || v1->visibility != v2->visibility
- || v1->constp != v2->constp
- || v1->volatilep != v2->volatilep
- || v1->voffset != v2->voffset
- || (v1->context == NULL) != (v2->context == NULL)
- || strcmp (v1->physname, v2->physname) != 0
- || ! debug_type_samep (info, v1->type, v2->type))
- return false;
- if (v1->context != NULL)
- {
- if (! debug_type_samep (info, v1->context,
- v2->context))
- return false;
- }
- }
- if (*pv1 != NULL || *pv2 != NULL)
- return false;
- }
- }
- if (*pm1 != NULL || *pm2 != NULL)
- return false;
- }
-
- return true;
-}
diff --git a/pstack/debug.h b/pstack/debug.h
deleted file mode 100644
index a4d3d8306cd..00000000000
--- a/pstack/debug.h
+++ /dev/null
@@ -1,798 +0,0 @@
-/* debug.h -- Describe generic debugging information.
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
- Written by Ian Lance Taylor <ian@cygnus.com>.
-
- This file is part of GNU Binutils.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-#ifndef DEBUG_H
-#define DEBUG_H
-
-/* This header file describes a generic debugging information format.
- We may eventually have readers which convert different formats into
- this generic format, and writers which write it out. The initial
- impetus for this was writing a convertor from stabs to HP IEEE-695
- debugging format. */
-
-/* Different kinds of types. */
-
-enum debug_type_kind
-{
- /* Not used. */
- DEBUG_KIND_ILLEGAL,
- /* Indirect via a pointer. */
- DEBUG_KIND_INDIRECT,
- /* Void. */
- DEBUG_KIND_VOID,
- /* Integer. */
- DEBUG_KIND_INT,
- /* Floating point. */
- DEBUG_KIND_FLOAT,
- /* Complex. */
- DEBUG_KIND_COMPLEX,
- /* Boolean. */
- DEBUG_KIND_BOOL,
- /* Struct. */
- DEBUG_KIND_STRUCT,
- /* Union. */
- DEBUG_KIND_UNION,
- /* Class. */
- DEBUG_KIND_CLASS,
- /* Union class (can this really happen?). */
- DEBUG_KIND_UNION_CLASS,
- /* Enumeration type. */
- DEBUG_KIND_ENUM,
- /* Pointer. */
- DEBUG_KIND_POINTER,
- /* Function. */
- DEBUG_KIND_FUNCTION,
- /* Reference. */
- DEBUG_KIND_REFERENCE,
- /* Range. */
- DEBUG_KIND_RANGE,
- /* Array. */
- DEBUG_KIND_ARRAY,
- /* Set. */
- DEBUG_KIND_SET,
- /* Based pointer. */
- DEBUG_KIND_OFFSET,
- /* Method. */
- DEBUG_KIND_METHOD,
- /* Const qualified type. */
- DEBUG_KIND_CONST,
- /* Volatile qualified type. */
- DEBUG_KIND_VOLATILE,
- /* Named type. */
- DEBUG_KIND_NAMED,
- /* Tagged type. */
- DEBUG_KIND_TAGGED
-};
-
-/* Different kinds of variables. */
-
-enum debug_var_kind
-{
- /* Not used. */
- DEBUG_VAR_ILLEGAL,
- /* A global variable. */
- DEBUG_GLOBAL,
- /* A static variable. */
- DEBUG_STATIC,
- /* A local static variable. */
- DEBUG_LOCAL_STATIC,
- /* A local variable. */
- DEBUG_LOCAL,
- /* A register variable. */
- DEBUG_REGISTER
-};
-
-/* Different kinds of function parameters. */
-
-enum debug_parm_kind
-{
- /* Not used. */
- DEBUG_PARM_ILLEGAL,
- /* A stack based parameter. */
- DEBUG_PARM_STACK,
- /* A register parameter. */
- DEBUG_PARM_REG,
- /* A stack based reference parameter. */
- DEBUG_PARM_REFERENCE,
- /* A register reference parameter. */
- DEBUG_PARM_REF_REG
-};
-
-/* Different kinds of visibility. */
-
-enum debug_visibility
-{
- /* A public field (e.g., a field in a C struct). */
- DEBUG_VISIBILITY_PUBLIC,
- /* A protected field. */
- DEBUG_VISIBILITY_PROTECTED,
- /* A private field. */
- DEBUG_VISIBILITY_PRIVATE,
- /* A field which should be ignored. */
- DEBUG_VISIBILITY_IGNORE
-};
-
-/* A type. */
-
-typedef struct debug_type *debug_type;
-
-#define DEBUG_TYPE_NULL ((debug_type) NULL)
-
-/* A field in a struct or union. */
-
-typedef struct debug_field *debug_field;
-
-#define DEBUG_FIELD_NULL ((debug_field) NULL)
-
-/* A base class for an object. */
-
-typedef struct debug_baseclass *debug_baseclass;
-
-#define DEBUG_BASECLASS_NULL ((debug_baseclass) NULL)
-
-/* A method of an object. */
-
-typedef struct debug_method *debug_method;
-
-#define DEBUG_METHOD_NULL ((debug_method) NULL)
-
-/* The arguments to a method function of an object. These indicate
- which method to run. */
-
-typedef struct debug_method_variant *debug_method_variant;
-
-#define DEBUG_METHOD_VARIANT_NULL ((debug_method_variant) NULL)
-
-/* This structure is passed to debug_write. It holds function
- pointers that debug_write will call based on the accumulated
- debugging information. */
-
-struct debug_write_fns
-{
- /* This is called at the start of each new compilation unit with the
- name of the main file in the new unit. */
- boolean (*start_compilation_unit) PARAMS ((PTR, const char *));
-
- /* This is called at the start of each source file within a
- compilation unit, before outputting any global information for
- that file. The argument is the name of the file. */
- boolean (*start_source) PARAMS ((PTR, const char *));
-
- /* Each writer must keep a stack of types. */
-
- /* Push an empty type onto the type stack. This type can appear if
- there is a reference to a type which is never defined. */
- boolean (*empty_type) PARAMS ((PTR));
-
- /* Push a void type onto the type stack. */
- boolean (*void_type) PARAMS ((PTR));
-
- /* Push an integer type onto the type stack, given the size and
- whether it is unsigned. */
- boolean (*int_type) PARAMS ((PTR, unsigned int, boolean));
-
- /* Push a floating type onto the type stack, given the size. */
- boolean (*float_type) PARAMS ((PTR, unsigned int));
-
- /* Push a complex type onto the type stack, given the size. */
- boolean (*complex_type) PARAMS ((PTR, unsigned int));
-
- /* Push a boolean type onto the type stack, given the size. */
- boolean (*bool_type) PARAMS ((PTR, unsigned int));
-
- /* Push an enum type onto the type stack, given the tag, a NULL
- terminated array of names and the associated values. If there is
- no tag, the tag argument will be NULL. If this is an undefined
- enum, the names and values arguments will be NULL. */
- boolean (*enum_type) PARAMS ((PTR, const char *, const char **,
- bfd_signed_vma *));
-
- /* Pop the top type on the type stack, and push a pointer to that
- type onto the type stack. */
- boolean (*pointer_type) PARAMS ((PTR));
-
- /* Push a function type onto the type stack. The second argument
- indicates the number of argument types that have been pushed onto
- the stack. If the number of argument types is passed as -1, then
- the argument types of the function are unknown, and no types have
- been pushed onto the stack. The third argument is true if the
- function takes a variable number of arguments. The return type
- of the function is pushed onto the type stack below the argument
- types, if any. */
- boolean (*function_type) PARAMS ((PTR, int, boolean));
-
- /* Pop the top type on the type stack, and push a reference to that
- type onto the type stack. */
- boolean (*reference_type) PARAMS ((PTR));
-
- /* Pop the top type on the type stack, and push a range of that type
- with the given lower and upper bounds onto the type stack. */
- boolean (*range_type) PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
-
- /* Push an array type onto the type stack. The top type on the type
- stack is the range, and the next type on the type stack is the
- element type. These should be popped before the array type is
- pushed. The arguments are the lower bound, the upper bound, and
- whether the array is a string. */
- boolean (*array_type) PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma,
- boolean));
-
- /* Pop the top type on the type stack, and push a set of that type
- onto the type stack. The argument indicates whether this set is
- a bitstring. */
- boolean (*set_type) PARAMS ((PTR, boolean));
-
- /* Push an offset type onto the type stack. The top type on the
- type stack is the target type, and the next type on the type
- stack is the base type. These should be popped before the offset
- type is pushed. */
- boolean (*offset_type) PARAMS ((PTR));
-
- /* Push a method type onto the type stack. If the second argument
- is true, the top type on the stack is the class to which the
- method belongs; otherwise, the class must be determined by the
- class to which the method is attached. The third argument is the
- number of argument types; these are pushed onto the type stack in
- reverse order (the first type popped is the last argument to the
- method). A value of -1 for the third argument means that no
- argument information is available. The fourth argument is true
- if the function takes a variable number of arguments. The next
- type on the type stack below the domain and the argument types is
- the return type of the method. All these types must be popped,
- and then the method type must be pushed. */
- boolean (*method_type) PARAMS ((PTR, boolean, int, boolean));
-
- /* Pop the top type off the type stack, and push a const qualified
- version of that type onto the type stack. */
- boolean (*const_type) PARAMS ((PTR));
-
- /* Pop the top type off the type stack, and push a volatile
- qualified version of that type onto the type stack. */
- boolean (*volatile_type) PARAMS ((PTR));
-
- /* Start building a struct. This is followed by calls to the
- struct_field function, and finished by a call to the
- end_struct_type function. The second argument is the tag; this
- will be NULL if there isn't one. If the second argument is NULL,
- the third argument is a constant identifying this struct for use
- with tag_type. The fourth argument is true for a struct, false
- for a union. The fifth argument is the size. If this is an
- undefined struct or union, the size will be 0 and struct_field
- will not be called before end_struct_type is called. */
- boolean (*start_struct_type) PARAMS ((PTR, const char *, unsigned int,
- boolean, unsigned int));
-
- /* Add a field to the struct type currently being built. The type
- of the field should be popped off the type stack. The arguments
- are the name, the bit position, the bit size (may be zero if the
- field is not packed), and the visibility. */
- boolean (*struct_field) PARAMS ((PTR, const char *, bfd_vma, bfd_vma,
- enum debug_visibility));
-
- /* Finish building a struct, and push it onto the type stack. */
- boolean (*end_struct_type) PARAMS ((PTR));
-
- /* Start building a class. This is followed by calls to several
- functions: struct_field, class_static_member, class_baseclass,
- class_start_method, class_method_variant,
- class_static_method_variant, and class_end_method. The class is
- finished by a call to end_class_type. The first five arguments
- are the same as for start_struct_type. The sixth argument is
- true if there is a virtual function table; if there is, the
- seventh argument is true if the virtual function table can be
- found in the type itself, and is false if the type of the object
- holding the virtual function table should be popped from the type
- stack. */
- boolean (*start_class_type) PARAMS ((PTR, const char *, unsigned int,
- boolean, unsigned int, boolean,
- boolean));
-
- /* Add a static member to the class currently being built. The
- arguments are the field name, the physical name, and the
- visibility. The type must be popped off the type stack. */
- boolean (*class_static_member) PARAMS ((PTR, const char *, const char *,
- enum debug_visibility));
-
- /* Add a baseclass to the class currently being built. The type of
- the baseclass must be popped off the type stack. The arguments
- are the bit position, whether the class is virtual, and the
- visibility. */
- boolean (*class_baseclass) PARAMS ((PTR, bfd_vma, boolean,
- enum debug_visibility));
-
- /* Start adding a method to the class currently being built. This
- is followed by calls to class_method_variant and
- class_static_method_variant to describe different variants of the
- method which take different arguments. The method is finished
- with a call to class_end_method. The argument is the method
- name. */
- boolean (*class_start_method) PARAMS ((PTR, const char *));
-
- /* Describe a variant to the class method currently being built.
- The type of the variant must be popped off the type stack. The
- second argument is the physical name of the function. The
- following arguments are the visibility, whether the variant is
- const, whether the variant is volatile, the offset in the virtual
- function table, and whether the context is on the type stack
- (below the variant type). */
- boolean (*class_method_variant) PARAMS ((PTR, const char *,
- enum debug_visibility,
- boolean, boolean,
- bfd_vma, boolean));
-
- /* Describe a static variant to the class method currently being
- built. The arguments are the same as for class_method_variant,
- except that the last two arguments are omitted. The type of the
- variant must be popped off the type stack. */
- boolean (*class_static_method_variant) PARAMS ((PTR, const char *,
- enum debug_visibility,
- boolean, boolean));
-
- /* Finish describing a class method. */
- boolean (*class_end_method) PARAMS ((PTR));
-
- /* Finish describing a class, and push it onto the type stack. */
- boolean (*end_class_type) PARAMS ((PTR));
-
- /* Push a type on the stack which was given a name by an earlier
- call to typdef. */
- boolean (*typedef_type) PARAMS ((PTR, const char *));
-
- /* Push a tagged type on the stack which was defined earlier. If
- the second argument is not NULL, the type was defined by a call
- to tag. If the second argument is NULL, the type was defined by
- a call to start_struct_type or start_class_type with a tag of
- NULL and the number of the third argument. Either way, the
- fourth argument is the tag kind. Note that this may be called
- for a struct (class) being defined, in between the call to
- start_struct_type (start_class_type) and the call to
- end_struct_type (end_class_type). */
- boolean (*tag_type) PARAMS ((PTR, const char *, unsigned int,
- enum debug_type_kind));
-
- /* Pop the type stack, and typedef it to the given name. */
- boolean (*typdef) PARAMS ((PTR, const char *));
-
- /* Pop the type stack, and declare it as a tagged struct or union or
- enum or whatever. The tag passed down here is redundant, since
- was also passed when enum_type, start_struct_type, or
- start_class_type was called. */
- boolean (*tag) PARAMS ((PTR, const char *));
-
- /* This is called to record a named integer constant. */
- boolean (*int_constant) PARAMS ((PTR, const char *, bfd_vma));
-
- /* This is called to record a named floating point constant. */
- boolean (*float_constant) PARAMS ((PTR, const char *, double));
-
- /* This is called to record a typed integer constant. The type is
- popped off the type stack. */
- boolean (*typed_constant) PARAMS ((PTR, const char *, bfd_vma));
-
- /* This is called to record a variable. The type is popped off the
- type stack. */
- boolean (*variable) PARAMS ((PTR, const char *, enum debug_var_kind,
- bfd_vma));
-
- /* Start writing out a function. The return type must be popped off
- the stack. The boolean is true if the function is global. This
- is followed by calls to function_parameter, followed by block
- information. */
- boolean (*start_function) PARAMS ((PTR, const char *, boolean));
-
- /* Record a function parameter for the current function. The type
- must be popped off the stack. */
- boolean (*function_parameter) PARAMS ((PTR, const char *,
- enum debug_parm_kind, bfd_vma));
-
- /* Start writing out a block. There is at least one top level block
- per function. Blocks may be nested. The argument is the
- starting address of the block. */
- boolean (*start_block) PARAMS ((PTR, bfd_vma));
-
- /* Finish writing out a block. The argument is the ending address
- of the block. */
- boolean (*end_block) PARAMS ((PTR, bfd_vma));
-
- /* Finish writing out a function. */
- boolean (*end_function) PARAMS ((PTR));
-
- /* Record line number information for the current compilation unit. */
- boolean (*lineno) PARAMS ((PTR, const char *, unsigned long, bfd_vma));
-};
-
-/* Exported functions. */
-
-/* The first argument to most of these functions is a handle. This
- handle is returned by the debug_init function. The purpose of the
- handle is to permit the debugging routines to not use static
- variables, and hence to be reentrant. This would be useful for a
- program which wanted to handle two executables simultaneously. */
-
-/* Return a debugging handle. */
-
-extern PTR debug_init PARAMS ((void));
-
-/* Set the source filename. This implicitly starts a new compilation
- unit. */
-
-extern boolean debug_set_filename PARAMS ((PTR, const char *));
-
-/* Change source files to the given file name. This is used for
- include files in a single compilation unit. */
-
-extern boolean debug_start_source PARAMS ((PTR, const char *));
-
-/* Record a function definition. This implicitly starts a function
- block. The debug_type argument is the type of the return value.
- The boolean indicates whether the function is globally visible.
- The bfd_vma is the address of the start of the function. Currently
- the parameter types are specified by calls to
- debug_record_parameter. */
-
-extern boolean debug_record_function
- PARAMS ((PTR, const char *, debug_type, boolean, bfd_vma));
-
-/* Record a parameter for the current function. */
-
-extern boolean debug_record_parameter
- PARAMS ((PTR, const char *, debug_type, enum debug_parm_kind, bfd_vma));
-
-/* End a function definition. The argument is the address where the
- function ends. */
-
-extern boolean debug_end_function PARAMS ((PTR, bfd_vma));
-
-/* Start a block in a function. All local information will be
- recorded in this block, until the matching call to debug_end_block.
- debug_start_block and debug_end_block may be nested. The argument
- is the address at which this block starts. */
-
-extern boolean debug_start_block PARAMS ((PTR, bfd_vma));
-
-/* Finish a block in a function. This matches the call to
- debug_start_block. The argument is the address at which this block
- ends. */
-
-extern boolean debug_end_block PARAMS ((PTR, bfd_vma));
-
-/* Associate a line number in the current source file with a given
- address. */
-
-extern boolean debug_record_line PARAMS ((PTR, unsigned long, bfd_vma));
-
-/* Start a named common block. This is a block of variables that may
- move in memory. */
-
-extern boolean debug_start_common_block PARAMS ((PTR, const char *));
-
-/* End a named common block. */
-
-extern boolean debug_end_common_block PARAMS ((PTR, const char *));
-
-/* Record a named integer constant. */
-
-extern boolean debug_record_int_const PARAMS ((PTR, const char *, bfd_vma));
-
-/* Record a named floating point constant. */
-
-extern boolean debug_record_float_const PARAMS ((PTR, const char *, double));
-
-/* Record a typed constant with an integral value. */
-
-extern boolean debug_record_typed_const
- PARAMS ((PTR, const char *, debug_type, bfd_vma));
-
-/* Record a label. */
-
-extern boolean debug_record_label
- PARAMS ((PTR, const char *, debug_type, bfd_vma));
-
-/* Record a variable. */
-
-extern boolean debug_record_variable
- PARAMS ((PTR, const char *, debug_type, enum debug_var_kind, bfd_vma));
-
-/* Make an indirect type. The first argument is a pointer to the
- location where the real type will be placed. The second argument
- is the type tag, if there is one; this may be NULL; the only
- purpose of this argument is so that debug_get_type_name can return
- something useful. This function may be used when a type is
- referenced before it is defined. */
-
-extern debug_type debug_make_indirect_type
- PARAMS ((PTR, debug_type *, const char *));
-
-/* Make a void type. */
-
-extern debug_type debug_make_void_type PARAMS ((PTR));
-
-/* Make an integer type of a given size. The boolean argument is true
- if the integer is unsigned. */
-
-extern debug_type debug_make_int_type PARAMS ((PTR, unsigned int, boolean));
-
-/* Make a floating point type of a given size. FIXME: On some
- platforms, like an Alpha, you probably need to be able to specify
- the format. */
-
-extern debug_type debug_make_float_type PARAMS ((PTR, unsigned int));
-
-/* Make a boolean type of a given size. */
-
-extern debug_type debug_make_bool_type PARAMS ((PTR, unsigned int));
-
-/* Make a complex type of a given size. */
-
-extern debug_type debug_make_complex_type PARAMS ((PTR, unsigned int));
-
-/* Make a structure type. The second argument is true for a struct,
- false for a union. The third argument is the size of the struct.
- The fourth argument is a NULL terminated array of fields. */
-
-extern debug_type debug_make_struct_type
- PARAMS ((PTR, boolean, bfd_vma, debug_field *));
-
-/* Make an object type. The first three arguments after the handle
- are the same as for debug_make_struct_type. The next arguments are
- a NULL terminated array of base classes, a NULL terminated array of
- methods, the type of the object holding the virtual function table
- if it is not this object, and a boolean which is true if this
- object has its own virtual function table. */
-
-extern debug_type debug_make_object_type
- PARAMS ((PTR, boolean, bfd_vma, debug_field *, debug_baseclass *,
- debug_method *, debug_type, boolean));
-
-/* Make an enumeration type. The arguments are a null terminated
- array of strings, and an array of corresponding values. */
-
-extern debug_type debug_make_enum_type
- PARAMS ((PTR, const char **, bfd_signed_vma *));
-
-/* Make a pointer to a given type. */
-
-extern debug_type debug_make_pointer_type
- PARAMS ((PTR, debug_type));
-
-/* Make a function type. The second argument is the return type. The
- third argument is a NULL terminated array of argument types. The
- fourth argument is true if the function takes a variable number of
- arguments. If the third argument is NULL, then the argument types
- are unknown. */
-
-extern debug_type debug_make_function_type
- PARAMS ((PTR, debug_type, debug_type *, boolean));
-
-/* Make a reference to a given type. */
-
-extern debug_type debug_make_reference_type PARAMS ((PTR, debug_type));
-
-/* Make a range of a given type from a lower to an upper bound. */
-
-extern debug_type debug_make_range_type
- PARAMS ((PTR, debug_type, bfd_signed_vma, bfd_signed_vma));
-
-/* Make an array type. The second argument is the type of an element
- of the array. The third argument is the type of a range of the
- array. The fourth and fifth argument are the lower and upper
- bounds, respectively (if the bounds are not known, lower should be
- 0 and upper should be -1). The sixth argument is true if this
- array is actually a string, as in C. */
-
-extern debug_type debug_make_array_type
- PARAMS ((PTR, debug_type, debug_type, bfd_signed_vma, bfd_signed_vma,
- boolean));
-
-/* Make a set of a given type. For example, a Pascal set type. The
- boolean argument is true if this set is actually a bitstring, as in
- CHILL. */
-
-extern debug_type debug_make_set_type PARAMS ((PTR, debug_type, boolean));
-
-/* Make a type for a pointer which is relative to an object. The
- second argument is the type of the object to which the pointer is
- relative. The third argument is the type that the pointer points
- to. */
-
-extern debug_type debug_make_offset_type
- PARAMS ((PTR, debug_type, debug_type));
-
-/* Make a type for a method function. The second argument is the
- return type. The third argument is the domain. The fourth
- argument is a NULL terminated array of argument types. The fifth
- argument is true if the function takes a variable number of
- arguments, in which case the array of argument types indicates the
- types of the first arguments. The domain and the argument array
- may be NULL, in which case this is a stub method and that
- information is not available. Stabs debugging uses this, and gets
- the argument types from the mangled name. */
-
-extern debug_type debug_make_method_type
- PARAMS ((PTR, debug_type, debug_type, debug_type *, boolean));
-
-/* Make a const qualified version of a given type. */
-
-extern debug_type debug_make_const_type PARAMS ((PTR, debug_type));
-
-/* Make a volatile qualified version of a given type. */
-
-extern debug_type debug_make_volatile_type PARAMS ((PTR, debug_type));
-
-/* Make an undefined tagged type. For example, a struct which has
- been mentioned, but not defined. */
-
-extern debug_type debug_make_undefined_tagged_type
- PARAMS ((PTR, const char *, enum debug_type_kind));
-
-/* Make a base class for an object. The second argument is the base
- class type. The third argument is the bit position of this base
- class in the object. The fourth argument is whether this is a
- virtual class. The fifth argument is the visibility of the base
- class. */
-
-extern debug_baseclass debug_make_baseclass
- PARAMS ((PTR, debug_type, bfd_vma, boolean, enum debug_visibility));
-
-/* Make a field for a struct. The second argument is the name. The
- third argument is the type of the field. The fourth argument is
- the bit position of the field. The fifth argument is the size of
- the field (it may be zero). The sixth argument is the visibility
- of the field. */
-
-extern debug_field debug_make_field
- PARAMS ((PTR, const char *, debug_type, bfd_vma, bfd_vma,
- enum debug_visibility));
-
-/* Make a static member of an object. The second argument is the
- name. The third argument is the type of the member. The fourth
- argument is the physical name of the member (i.e., the name as a
- global variable). The fifth argument is the visibility of the
- member. */
-
-extern debug_field debug_make_static_member
- PARAMS ((PTR, const char *, debug_type, const char *,
- enum debug_visibility));
-
-/* Make a method. The second argument is the name, and the third
- argument is a NULL terminated array of method variants. Each
- method variant is a method with this name but with different
- argument types. */
-
-extern debug_method debug_make_method
- PARAMS ((PTR, const char *, debug_method_variant *));
-
-/* Make a method variant. The second argument is the physical name of
- the function. The third argument is the type of the function,
- probably constructed by debug_make_method_type. The fourth
- argument is the visibility. The fifth argument is whether this is
- a const function. The sixth argument is whether this is a volatile
- function. The seventh argument is the index in the virtual
- function table, if any. The eighth argument is the virtual
- function context. */
-
-extern debug_method_variant debug_make_method_variant
- PARAMS ((PTR, const char *, debug_type, enum debug_visibility, boolean,
- boolean, bfd_vma, debug_type));
-
-/* Make a static method argument. The arguments are the same as for
- debug_make_method_variant, except that the last two are omitted
- since a static method can not also be virtual. */
-
-extern debug_method_variant debug_make_static_method_variant
- PARAMS ((PTR, const char *, debug_type, enum debug_visibility, boolean,
- boolean));
-
-/* Name a type. This returns a new type with an attached name. */
-
-extern debug_type debug_name_type PARAMS ((PTR, const char *, debug_type));
-
-/* Give a tag to a type, such as a struct or union. This returns a
- new type with an attached tag. */
-
-extern debug_type debug_tag_type PARAMS ((PTR, const char *, debug_type));
-
-/* Record the size of a given type. */
-
-extern boolean debug_record_type_size PARAMS ((PTR, debug_type, unsigned int));
-
-/* Find a named type. */
-
-extern debug_type debug_find_named_type PARAMS ((PTR, const char *));
-
-/* Find a tagged type. */
-
-extern debug_type debug_find_tagged_type
- PARAMS ((PTR, const char *, enum debug_type_kind));
-
-/* Get the kind of a type. */
-
-extern enum debug_type_kind debug_get_type_kind PARAMS ((PTR, debug_type));
-
-/* Get the name of a type. */
-
-extern const char *debug_get_type_name PARAMS ((PTR, debug_type));
-
-/* Get the size of a type. */
-
-extern bfd_vma debug_get_type_size PARAMS ((PTR, debug_type));
-
-/* Get the return type of a function or method type. */
-
-extern debug_type debug_get_return_type PARAMS ((PTR, debug_type));
-
-/* Get the NULL terminated array of parameter types for a function or
- method type (actually, parameter types are not currently stored for
- function types). This may be used to determine whether a method
- type is a stub method or not. The last argument points to a
- boolean which is set to true if the function takes a variable
- number of arguments. */
-
-extern const debug_type *debug_get_parameter_types PARAMS ((PTR,
- debug_type,
- boolean *));
-
-/* Get the target type of a pointer or reference or const or volatile
- type. */
-
-extern debug_type debug_get_target_type PARAMS ((PTR, debug_type));
-
-/* Get the NULL terminated array of fields for a struct, union, or
- class. */
-
-extern const debug_field *debug_get_fields PARAMS ((PTR, debug_type));
-
-/* Get the type of a field. */
-
-extern debug_type debug_get_field_type PARAMS ((PTR, debug_field));
-
-/* Get the name of a field. */
-
-extern const char *debug_get_field_name PARAMS ((PTR, debug_field));
-
-/* Get the bit position of a field within the containing structure.
- If the field is a static member, this will return (bfd_vma) -1. */
-
-extern bfd_vma debug_get_field_bitpos PARAMS ((PTR, debug_field));
-
-/* Get the bit size of a field. If the field is a static member, this
- will return (bfd_vma) -1. */
-
-extern bfd_vma debug_get_field_bitsize PARAMS ((PTR, debug_field));
-
-/* Get the visibility of a field. */
-
-extern enum debug_visibility debug_get_field_visibility
- PARAMS ((PTR, debug_field));
-
-/* Get the physical name of a field, if it is a static member. If the
- field is not a static member, this will return NULL. */
-
-extern const char *debug_get_field_physname PARAMS ((PTR, debug_field));
-
-/* Write out the recorded debugging information. This takes a set of
- function pointers which are called to do the actual writing. The
- first PTR is the debugging handle. The second PTR is a handle
- which is passed to the functions. */
-
-extern boolean debug_write PARAMS ((PTR, const struct debug_write_fns *, PTR));
-
-#endif /* DEBUG_H */
diff --git a/pstack/demangle.h b/pstack/demangle.h
deleted file mode 100644
index a961436ca77..00000000000
--- a/pstack/demangle.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Defs for interface to demanglers.
- Copyright 1992, 1995, 1996 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-
-#if !defined (DEMANGLE_H)
-#define DEMANGLE_H
-
-#ifdef IN_GCC
-#include "gansidecl.h"
-#define PARAMS(ARGS) PROTO(ARGS)
-#else /* ! IN_GCC */
-#include <ansidecl.h>
-#endif /* IN_GCC */
-
-/* Options passed to cplus_demangle (in 2nd parameter). */
-
-#define DMGL_NO_OPTS 0 /* For readability... */
-#define DMGL_PARAMS (1 << 0) /* Include function args */
-#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
-#define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */
-
-#define DMGL_AUTO (1 << 8)
-#define DMGL_GNU (1 << 9)
-#define DMGL_LUCID (1 << 10)
-#define DMGL_ARM (1 << 11)
-/* If none of these are set, use 'current_demangling_style' as the default. */
-#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM)
-
-/* Enumeration of possible demangling styles.
-
- Lucid and ARM styles are still kept logically distinct, even though
- they now both behave identically. The resulting style is actual the
- union of both. I.E. either style recognizes both "__pt__" and "__rf__"
- for operator "->", even though the first is lucid style and the second
- is ARM style. (FIXME?) */
-
-extern enum demangling_styles
-{
- unknown_demangling = 0,
- auto_demangling = DMGL_AUTO,
- gnu_demangling = DMGL_GNU,
- lucid_demangling = DMGL_LUCID,
- arm_demangling = DMGL_ARM
-} current_demangling_style;
-
-/* Define string names for the various demangling styles. */
-
-#define AUTO_DEMANGLING_STYLE_STRING "auto"
-#define GNU_DEMANGLING_STYLE_STRING "gnu"
-#define LUCID_DEMANGLING_STYLE_STRING "lucid"
-#define ARM_DEMANGLING_STYLE_STRING "arm"
-
-/* Some macros to test what demangling style is active. */
-
-#define CURRENT_DEMANGLING_STYLE current_demangling_style
-#define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO)
-#define GNU_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU)
-#define LUCID_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_LUCID)
-#define ARM_DEMANGLING (CURRENT_DEMANGLING_STYLE & DMGL_ARM)
-
-extern char *
-cplus_demangle PARAMS ((const char *mangled, int options));
-
-extern int
-cplus_demangle_opname PARAMS ((const char *opname, char *result, int options));
-
-extern const char *
-cplus_mangle_opname PARAMS ((const char *opname, int options));
-
-/* Note: This sets global state. FIXME if you care about multi-threading. */
-
-extern void
-set_cplus_marker_for_demangling PARAMS ((int ch));
-
-#endif /* DEMANGLE_H */
diff --git a/pstack/filemode.c b/pstack/filemode.c
deleted file mode 100644
index 58b52ba7489..00000000000
--- a/pstack/filemode.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/* filemode.c -- make a string describing file modes
- Copyright (C) 1985, 90, 91, 94, 95, 1997 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-#include "bfd.h"
-#include "bucomm.h"
-
-static char ftypelet PARAMS ((unsigned long));
-static void setst PARAMS ((unsigned long, char *));
-
-/* filemodestring - fill in string STR with an ls-style ASCII
- representation of the st_mode field of file stats block STATP.
- 10 characters are stored in STR; no terminating null is added.
- The characters stored in STR are:
-
- 0 File type. 'd' for directory, 'c' for character
- special, 'b' for block special, 'm' for multiplex,
- 'l' for symbolic link, 's' for socket, 'p' for fifo,
- '-' for any other file type
-
- 1 'r' if the owner may read, '-' otherwise.
-
- 2 'w' if the owner may write, '-' otherwise.
-
- 3 'x' if the owner may execute, 's' if the file is
- set-user-id, '-' otherwise.
- 'S' if the file is set-user-id, but the execute
- bit isn't set.
-
- 4 'r' if group members may read, '-' otherwise.
-
- 5 'w' if group members may write, '-' otherwise.
-
- 6 'x' if group members may execute, 's' if the file is
- set-group-id, '-' otherwise.
- 'S' if it is set-group-id but not executable.
-
- 7 'r' if any user may read, '-' otherwise.
-
- 8 'w' if any user may write, '-' otherwise.
-
- 9 'x' if any user may execute, 't' if the file is "sticky"
- (will be retained in swap space after execution), '-'
- otherwise.
- 'T' if the file is sticky but not executable. */
-
-#if 0
-
-/* This is not used; only mode_string is used. */
-
-void
-filemodestring (statp, str)
- struct stat *statp;
- char *str;
-{
- mode_string ((unsigned long) statp->st_mode, str);
-}
-
-#endif
-
-/* Get definitions for the file permission bits. */
-
-#ifndef S_IRWXU
-#define S_IRWXU 0700
-#endif
-#ifndef S_IRUSR
-#define S_IRUSR 0400
-#endif
-#ifndef S_IWUSR
-#define S_IWUSR 0200
-#endif
-#ifndef S_IXUSR
-#define S_IXUSR 0100
-#endif
-
-#ifndef S_IRWXG
-#define S_IRWXG 0070
-#endif
-#ifndef S_IRGRP
-#define S_IRGRP 0040
-#endif
-#ifndef S_IWGRP
-#define S_IWGRP 0020
-#endif
-#ifndef S_IXGRP
-#define S_IXGRP 0010
-#endif
-
-#ifndef S_IRWXO
-#define S_IRWXO 0007
-#endif
-#ifndef S_IROTH
-#define S_IROTH 0004
-#endif
-#ifndef S_IWOTH
-#define S_IWOTH 0002
-#endif
-#ifndef S_IXOTH
-#define S_IXOTH 0001
-#endif
-
-/* Like filemodestring, but only the relevant part of the `struct stat'
- is given as an argument. */
-
-void
-mode_string (mode, str)
- unsigned long mode;
- char *str;
-{
- str[0] = ftypelet ((unsigned long) mode);
- str[1] = (mode & S_IRUSR) != 0 ? 'r' : '-';
- str[2] = (mode & S_IWUSR) != 0 ? 'w' : '-';
- str[3] = (mode & S_IXUSR) != 0 ? 'x' : '-';
- str[4] = (mode & S_IRGRP) != 0 ? 'r' : '-';
- str[5] = (mode & S_IWGRP) != 0 ? 'w' : '-';
- str[6] = (mode & S_IXGRP) != 0 ? 'x' : '-';
- str[7] = (mode & S_IROTH) != 0 ? 'r' : '-';
- str[8] = (mode & S_IWOTH) != 0 ? 'w' : '-';
- str[9] = (mode & S_IXOTH) != 0 ? 'x' : '-';
- setst ((unsigned long) mode, str);
-}
-
-/* Return a character indicating the type of file described by
- file mode BITS:
- 'd' for directories
- 'b' for block special files
- 'c' for character special files
- 'm' for multiplexor files
- 'l' for symbolic links
- 's' for sockets
- 'p' for fifos
- '-' for any other file type. */
-
-#ifndef S_ISDIR
-#ifdef S_IFDIR
-#define S_ISDIR(i) (((i) & S_IFMT) == S_IFDIR)
-#else /* ! defined (S_IFDIR) */
-#define S_ISDIR(i) (((i) & 0170000) == 040000)
-#endif /* ! defined (S_IFDIR) */
-#endif /* ! defined (S_ISDIR) */
-
-#ifndef S_ISBLK
-#ifdef S_IFBLK
-#define S_ISBLK(i) (((i) & S_IFMT) == S_IFBLK)
-#else /* ! defined (S_IFBLK) */
-#define S_ISBLK(i) 0
-#endif /* ! defined (S_IFBLK) */
-#endif /* ! defined (S_ISBLK) */
-
-#ifndef S_ISCHR
-#ifdef S_IFCHR
-#define S_ISCHR(i) (((i) & S_IFMT) == S_IFCHR)
-#else /* ! defined (S_IFCHR) */
-#define S_ISCHR(i) 0
-#endif /* ! defined (S_IFCHR) */
-#endif /* ! defined (S_ISCHR) */
-
-#ifndef S_ISFIFO
-#ifdef S_IFIFO
-#define S_ISFIFO(i) (((i) & S_IFMT) == S_IFIFO)
-#else /* ! defined (S_IFIFO) */
-#define S_ISFIFO(i) 0
-#endif /* ! defined (S_IFIFO) */
-#endif /* ! defined (S_ISFIFO) */
-
-#ifndef S_ISSOCK
-#ifdef S_IFSOCK
-#define S_ISSOCK(i) (((i) & S_IFMT) == S_IFSOCK)
-#else /* ! defined (S_IFSOCK) */
-#define S_ISSOCK(i) 0
-#endif /* ! defined (S_IFSOCK) */
-#endif /* ! defined (S_ISSOCK) */
-
-#ifndef S_ISLNK
-#ifdef S_IFLNK
-#define S_ISLNK(i) (((i) & S_IFMT) == S_IFLNK)
-#else /* ! defined (S_IFLNK) */
-#define S_ISLNK(i) 0
-#endif /* ! defined (S_IFLNK) */
-#endif /* ! defined (S_ISLNK) */
-
-static char
-ftypelet (bits)
- unsigned long bits;
-{
- if (S_ISDIR (bits))
- return 'd';
- if (S_ISLNK (bits))
- return 'l';
- if (S_ISBLK (bits))
- return 'b';
- if (S_ISCHR (bits))
- return 'c';
- if (S_ISSOCK (bits))
- return 's';
- if (S_ISFIFO (bits))
- return 'p';
-
-#ifdef S_IFMT
-#ifdef S_IFMPC
- if ((bits & S_IFMT) == S_IFMPC
- || (bits & S_IFMT) == S_IFMPB)
- return 'm';
-#endif
-#ifdef S_IFNWK
- if ((bits & S_IFMT) == S_IFNWK)
- return 'n';
-#endif
-#endif
-
- return '-';
-}
-
-/* Set the 's' and 't' flags in file attributes string CHARS,
- according to the file mode BITS. */
-
-static void
-setst (bits, chars)
- unsigned long bits;
- char *chars;
-{
-#ifdef S_ISUID
- if (bits & S_ISUID)
- {
- if (chars[3] != 'x')
- /* Set-uid, but not executable by owner. */
- chars[3] = 'S';
- else
- chars[3] = 's';
- }
-#endif
-#ifdef S_ISGID
- if (bits & S_ISGID)
- {
- if (chars[6] != 'x')
- /* Set-gid, but not executable by group. */
- chars[6] = 'S';
- else
- chars[6] = 's';
- }
-#endif
-#ifdef S_ISVTX
- if (bits & S_ISVTX)
- {
- if (chars[9] != 'x')
- /* Sticky, but not executable by others. */
- chars[9] = 'T';
- else
- chars[9] = 't';
- }
-#endif
-}
diff --git a/pstack/ieee.c b/pstack/ieee.c
deleted file mode 100644
index 8084656a5ef..00000000000
--- a/pstack/ieee.c
+++ /dev/null
@@ -1,7602 +0,0 @@
-/* ieee.c -- Read and write IEEE-695 debugging information.
- Copyright (C) 1996 Free Software Foundation, Inc.
- Written by Ian Lance Taylor <ian@cygnus.com>.
-
- This file is part of GNU Binutils.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-/* This file reads and writes IEEE-695 debugging information. */
-
-#include <stdio.h>
-#include <assert.h>
-
-#include <bfd.h>
-#include "ieee.h"
-#include "bucomm.h"
-#include <libiberty.h>
-#include "debug.h"
-#include "budbg.h"
-
-/* This structure holds an entry on the block stack. */
-
-struct ieee_block
-{
- /* The kind of block. */
- int kind;
- /* The source file name, for a BB5 block. */
- const char *filename;
- /* The index of the function type, for a BB4 or BB6 block. */
- unsigned int fnindx;
- /* True if this function is being skipped. */
- boolean skip;
-};
-
-/* This structure is the block stack. */
-
-#define BLOCKSTACK_SIZE (16)
-
-struct ieee_blockstack
-{
- /* The stack pointer. */
- struct ieee_block *bsp;
- /* The stack. */
- struct ieee_block stack[BLOCKSTACK_SIZE];
-};
-
-/* This structure holds information for a variable. */
-
-struct ieee_var
-{
- /* Start of name. */
- const char *name;
- /* Length of name. */
- unsigned long namlen;
- /* Type. */
- debug_type type;
- /* Slot if we make an indirect type. */
- debug_type *pslot;
- /* Kind of variable or function. */
- enum
- {
- IEEE_UNKNOWN,
- IEEE_EXTERNAL,
- IEEE_GLOBAL,
- IEEE_STATIC,
- IEEE_LOCAL,
- IEEE_FUNCTION
- } kind;
-};
-
-/* This structure holds all the variables. */
-
-struct ieee_vars
-{
- /* Number of slots allocated. */
- unsigned int alloc;
- /* Variables. */
- struct ieee_var *vars;
-};
-
-/* This structure holds information for a type. We need this because
- we don't want to represent bitfields as real types. */
-
-struct ieee_type
-{
- /* Type. */
- debug_type type;
- /* Slot if this is type is referenced before it is defined. */
- debug_type *pslot;
- /* Slots for arguments if we make indirect types for them. */
- debug_type *arg_slots;
- /* If this is a bitfield, this is the size in bits. If this is not
- a bitfield, this is zero. */
- unsigned long bitsize;
-};
-
-/* This structure holds all the type information. */
-
-struct ieee_types
-{
- /* Number of slots allocated. */
- unsigned int alloc;
- /* Types. */
- struct ieee_type *types;
- /* Builtin types. */
-#define BUILTIN_TYPE_COUNT (60)
- debug_type builtins[BUILTIN_TYPE_COUNT];
-};
-
-/* This structure holds a linked last of structs with their tag names,
- so that we can convert them to C++ classes if necessary. */
-
-struct ieee_tag
-{
- /* Next tag. */
- struct ieee_tag *next;
- /* This tag name. */
- const char *name;
- /* The type of the tag. */
- debug_type type;
- /* The tagged type is an indirect type pointing at this slot. */
- debug_type slot;
- /* This is an array of slots used when a field type is converted
- into a indirect type, in case it needs to be later converted into
- a reference type. */
- debug_type *fslots;
-};
-
-/* This structure holds the information we pass around to the parsing
- functions. */
-
-struct ieee_info
-{
- /* The debugging handle. */
- PTR dhandle;
- /* The BFD. */
- bfd *abfd;
- /* The start of the bytes to be parsed. */
- const bfd_byte *bytes;
- /* The end of the bytes to be parsed. */
- const bfd_byte *pend;
- /* The block stack. */
- struct ieee_blockstack blockstack;
- /* Whether we have seen a BB1 or BB2. */
- boolean saw_filename;
- /* The variables. */
- struct ieee_vars vars;
- /* The global variables, after a global typedef block. */
- struct ieee_vars *global_vars;
- /* The types. */
- struct ieee_types types;
- /* The global types, after a global typedef block. */
- struct ieee_types *global_types;
- /* The list of tagged structs. */
- struct ieee_tag *tags;
-};
-
-/* Basic builtin types, not including the pointers. */
-
-enum builtin_types
-{
- builtin_unknown = 0,
- builtin_void = 1,
- builtin_signed_char = 2,
- builtin_unsigned_char = 3,
- builtin_signed_short_int = 4,
- builtin_unsigned_short_int = 5,
- builtin_signed_long = 6,
- builtin_unsigned_long = 7,
- builtin_signed_long_long = 8,
- builtin_unsigned_long_long = 9,
- builtin_float = 10,
- builtin_double = 11,
- builtin_long_double = 12,
- builtin_long_long_double = 13,
- builtin_quoted_string = 14,
- builtin_instruction_address = 15,
- builtin_int = 16,
- builtin_unsigned = 17,
- builtin_unsigned_int = 18,
- builtin_char = 19,
- builtin_long = 20,
- builtin_short = 21,
- builtin_unsigned_short = 22,
- builtin_short_int = 23,
- builtin_signed_short = 24,
- builtin_bcd_float = 25
-};
-
-/* These are the values found in the derivation flags of a 'b'
- component record of a 'T' type extension record in a C++ pmisc
- record. These are bitmasks. */
-
-/* Set for a private base class, clear for a public base class.
- Protected base classes are not supported. */
-#define BASEFLAGS_PRIVATE (0x1)
-/* Set for a virtual base class. */
-#define BASEFLAGS_VIRTUAL (0x2)
-/* Set for a friend class, clear for a base class. */
-#define BASEFLAGS_FRIEND (0x10)
-
-/* These are the values found in the specs flags of a 'd', 'm', or 'v'
- component record of a 'T' type extension record in a C++ pmisc
- record. The same flags are used for a 'M' record in a C++ pmisc
- record. */
-
-/* The lower two bits hold visibility information. */
-#define CXXFLAGS_VISIBILITY (0x3)
-/* This value in the lower two bits indicates a public member. */
-#define CXXFLAGS_VISIBILITY_PUBLIC (0x0)
-/* This value in the lower two bits indicates a private member. */
-#define CXXFLAGS_VISIBILITY_PRIVATE (0x1)
-/* This value in the lower two bits indicates a protected member. */
-#define CXXFLAGS_VISIBILITY_PROTECTED (0x2)
-/* Set for a static member. */
-#define CXXFLAGS_STATIC (0x4)
-/* Set for a virtual override. */
-#define CXXFLAGS_OVERRIDE (0x8)
-/* Set for a friend function. */
-#define CXXFLAGS_FRIEND (0x10)
-/* Set for a const function. */
-#define CXXFLAGS_CONST (0x20)
-/* Set for a volatile function. */
-#define CXXFLAGS_VOLATILE (0x40)
-/* Set for an overloaded function. */
-#define CXXFLAGS_OVERLOADED (0x80)
-/* Set for an operator function. */
-#define CXXFLAGS_OPERATOR (0x100)
-/* Set for a constructor or destructor. */
-#define CXXFLAGS_CTORDTOR (0x400)
-/* Set for a constructor. */
-#define CXXFLAGS_CTOR (0x200)
-/* Set for an inline function. */
-#define CXXFLAGS_INLINE (0x800)
-
-/* Local functions. */
-
-static void ieee_error
- PARAMS ((struct ieee_info *, const bfd_byte *, const char *));
-static void ieee_eof PARAMS ((struct ieee_info *));
-static char *savestring PARAMS ((const char *, unsigned long));
-static boolean ieee_read_number
- PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *));
-static boolean ieee_read_optional_number
- PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *, boolean *));
-static boolean ieee_read_id
- PARAMS ((struct ieee_info *, const bfd_byte **, const char **,
- unsigned long *));
-static boolean ieee_read_optional_id
- PARAMS ((struct ieee_info *, const bfd_byte **, const char **,
- unsigned long *, boolean *));
-static boolean ieee_read_expression
- PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *));
-static debug_type ieee_builtin_type
- PARAMS ((struct ieee_info *, const bfd_byte *, unsigned int));
-static boolean ieee_alloc_type
- PARAMS ((struct ieee_info *, unsigned int, boolean));
-static boolean ieee_read_type_index
- PARAMS ((struct ieee_info *, const bfd_byte **, debug_type *));
-static int ieee_regno_to_genreg PARAMS ((bfd *, int));
-static int ieee_genreg_to_regno PARAMS ((bfd *, int));
-static boolean parse_ieee_bb PARAMS ((struct ieee_info *, const bfd_byte **));
-static boolean parse_ieee_be PARAMS ((struct ieee_info *, const bfd_byte **));
-static boolean parse_ieee_nn PARAMS ((struct ieee_info *, const bfd_byte **));
-static boolean parse_ieee_ty PARAMS ((struct ieee_info *, const bfd_byte **));
-static boolean parse_ieee_atn PARAMS ((struct ieee_info *, const bfd_byte **));
-static boolean ieee_read_cxx_misc
- PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long));
-static boolean ieee_read_cxx_class
- PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long));
-static boolean ieee_read_cxx_defaults
- PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long));
-static boolean ieee_read_reference
- PARAMS ((struct ieee_info *, const bfd_byte **));
-static boolean ieee_require_asn
- PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *));
-static boolean ieee_require_atn65
- PARAMS ((struct ieee_info *, const bfd_byte **, const char **,
- unsigned long *));
-
-/* Report an error in the IEEE debugging information. */
-
-static void
-ieee_error (info, p, s)
- struct ieee_info *info;
- const bfd_byte *p;
- const char *s;
-{
- if (p != NULL)
- fprintf (stderr, "%s: 0x%lx: %s (0x%x)\n", bfd_get_filename (info->abfd),
- (unsigned long) (p - info->bytes), s, *p);
- else
- fprintf (stderr, "%s: %s\n", bfd_get_filename (info->abfd), s);
-}
-
-/* Report an unexpected EOF in the IEEE debugging information. */
-
-static void
-ieee_eof (info)
- struct ieee_info *info;
-{
- ieee_error (info, (const bfd_byte *) NULL,
- "unexpected end of debugging information");
-}
-
-/* Save a string in memory. */
-
-static char *
-savestring (start, len)
- const char *start;
- unsigned long len;
-{
- char *ret;
-
- ret = (char *) xmalloc (len + 1);
- memcpy (ret, start, len);
- ret[len] = '\0';
- return ret;
-}
-
-/* Read a number which must be present in an IEEE file. */
-
-static boolean
-ieee_read_number (info, pp, pv)
- struct ieee_info *info;
- const bfd_byte **pp;
- bfd_vma *pv;
-{
- return ieee_read_optional_number (info, pp, pv, (boolean *) NULL);
-}
-
-/* Read a number in an IEEE file. If ppresent is not NULL, the number
- need not be there. */
-
-static boolean
-ieee_read_optional_number (info, pp, pv, ppresent)
- struct ieee_info *info;
- const bfd_byte **pp;
- bfd_vma *pv;
- boolean *ppresent;
-{
- ieee_record_enum_type b;
-
- if (*pp >= info->pend)
- {
- if (ppresent != NULL)
- {
- *ppresent = false;
- return true;
- }
- ieee_eof (info);
- return false;
- }
-
- b = (ieee_record_enum_type) **pp;
- ++*pp;
-
- if (b <= ieee_number_end_enum)
- {
- *pv = (bfd_vma) b;
- if (ppresent != NULL)
- *ppresent = true;
- return true;
- }
-
- if (b >= ieee_number_repeat_start_enum && b <= ieee_number_repeat_end_enum)
- {
- unsigned int i;
-
- i = (int) b - (int) ieee_number_repeat_start_enum;
- if (*pp + i - 1 >= info->pend)
- {
- ieee_eof (info);
- return false;
- }
-
- *pv = 0;
- for (; i > 0; i--)
- {
- *pv <<= 8;
- *pv += **pp;
- ++*pp;
- }
-
- if (ppresent != NULL)
- *ppresent = true;
-
- return true;
- }
-
- if (ppresent != NULL)
- {
- --*pp;
- *ppresent = false;
- return true;
- }
-
- ieee_error (info, *pp - 1, "invalid number");
- return false;
-}
-
-/* Read a required string from an IEEE file. */
-
-static boolean
-ieee_read_id (info, pp, pname, pnamlen)
- struct ieee_info *info;
- const bfd_byte **pp;
- const char **pname;
- unsigned long *pnamlen;
-{
- return ieee_read_optional_id (info, pp, pname, pnamlen, (boolean *) NULL);
-}
-
-/* Read a string from an IEEE file. If ppresent is not NULL, the
- string is optional. */
-
-static boolean
-ieee_read_optional_id (info, pp, pname, pnamlen, ppresent)
- struct ieee_info *info;
- const bfd_byte **pp;
- const char **pname;
- unsigned long *pnamlen;
- boolean *ppresent;
-{
- bfd_byte b;
- unsigned long len;
-
- if (*pp >= info->pend)
- {
- ieee_eof (info);
- return false;
- }
-
- b = **pp;
- ++*pp;
-
- if (b <= 0x7f)
- len = b;
- else if ((ieee_record_enum_type) b == ieee_extension_length_1_enum)
- {
- len = **pp;
- ++*pp;
- }
- else if ((ieee_record_enum_type) b == ieee_extension_length_2_enum)
- {
- len = (**pp << 8) + (*pp)[1];
- *pp += 2;
- }
- else
- {
- if (ppresent != NULL)
- {
- --*pp;
- *ppresent = false;
- return true;
- }
- ieee_error (info, *pp - 1, "invalid string length");
- return false;
- }
-
- if ((unsigned long) (info->pend - *pp) < len)
- {
- ieee_eof (info);
- return false;
- }
-
- *pname = (const char *) *pp;
- *pnamlen = len;
- *pp += len;
-
- if (ppresent != NULL)
- *ppresent = true;
-
- return true;
-}
-
-/* Read an expression from an IEEE file. Since this code is only used
- to parse debugging information, I haven't bothered to write a full
- blown IEEE expression parser. I've only thrown in the things I've
- seen in debugging information. This can be easily extended if
- necessary. */
-
-static boolean
-ieee_read_expression (info, pp, pv)
- struct ieee_info *info;
- const bfd_byte **pp;
- bfd_vma *pv;
-{
- const bfd_byte *expr_start;
-#define EXPR_STACK_SIZE (10)
- bfd_vma expr_stack[EXPR_STACK_SIZE];
- bfd_vma *esp;
-
- expr_start = *pp;
-
- esp = expr_stack;
-
- while (1)
- {
- const bfd_byte *start;
- bfd_vma val;
- boolean present;
- ieee_record_enum_type c;
-
- start = *pp;
-
- if (! ieee_read_optional_number (info, pp, &val, &present))
- return false;
-
- if (present)
- {
- if (esp - expr_stack >= EXPR_STACK_SIZE)
- {
- ieee_error (info, start, "expression stack overflow");
- return false;
- }
- *esp++ = val;
- continue;
- }
-
- c = (ieee_record_enum_type) **pp;
-
- if (c >= ieee_module_beginning_enum)
- break;
-
- ++*pp;
-
- if (c == ieee_comma)
- break;
-
- switch (c)
- {
- default:
- ieee_error (info, start, "unsupported IEEE expression operator");
- break;
-
- case ieee_variable_R_enum:
- {
- bfd_vma indx;
- asection *s;
-
- if (! ieee_read_number (info, pp, &indx))
- return false;
- for (s = info->abfd->sections; s != NULL; s = s->next)
- if ((bfd_vma) s->target_index == indx)
- break;
- if (s == NULL)
- {
- ieee_error (info, start, "unknown section");
- return false;
- }
-
- if (esp - expr_stack >= EXPR_STACK_SIZE)
- {
- ieee_error (info, start, "expression stack overflow");
- return false;
- }
-
- *esp++ = bfd_get_section_vma (info->abfd, s);
- }
- break;
-
- case ieee_function_plus_enum:
- case ieee_function_minus_enum:
- {
- bfd_vma v1, v2;
-
- if (esp - expr_stack < 2)
- {
- ieee_error (info, start, "expression stack underflow");
- return false;
- }
-
- v1 = *--esp;
- v2 = *--esp;
- *esp++ = v1 + v2;
- }
- break;
- }
- }
-
- if (esp - 1 != expr_stack)
- {
- ieee_error (info, expr_start, "expression stack mismatch");
- return false;
- }
-
- *pv = *--esp;
-
- return true;
-}
-
-/* Return an IEEE builtin type. */
-
-static debug_type
-ieee_builtin_type (info, p, indx)
- struct ieee_info *info;
- const bfd_byte *p;
- unsigned int indx;
-{
- PTR dhandle;
- debug_type type;
- const char *name;
-
- if (indx < BUILTIN_TYPE_COUNT
- && info->types.builtins[indx] != DEBUG_TYPE_NULL)
- return info->types.builtins[indx];
-
- dhandle = info->dhandle;
-
- if (indx >= 32 && indx < 64)
- {
- type = debug_make_pointer_type (dhandle,
- ieee_builtin_type (info, p, indx - 32));
- assert (indx < BUILTIN_TYPE_COUNT);
- info->types.builtins[indx] = type;
- return type;
- }
-
- switch ((enum builtin_types) indx)
- {
- default:
- ieee_error (info, p, "unknown builtin type");
- return NULL;
-
- case builtin_unknown:
- type = debug_make_void_type (dhandle);
- name = NULL;
- break;
-
- case builtin_void:
- type = debug_make_void_type (dhandle);
- name = "void";
- break;
-
- case builtin_signed_char:
- type = debug_make_int_type (dhandle, 1, false);
- name = "signed char";
- break;
-
- case builtin_unsigned_char:
- type = debug_make_int_type (dhandle, 1, true);
- name = "unsigned char";
- break;
-
- case builtin_signed_short_int:
- type = debug_make_int_type (dhandle, 2, false);
- name = "signed short int";
- break;
-
- case builtin_unsigned_short_int:
- type = debug_make_int_type (dhandle, 2, true);
- name = "unsigned short int";
- break;
-
- case builtin_signed_long:
- type = debug_make_int_type (dhandle, 4, false);
- name = "signed long";
- break;
-
- case builtin_unsigned_long:
- type = debug_make_int_type (dhandle, 4, true);
- name = "unsigned long";
- break;
-
- case builtin_signed_long_long:
- type = debug_make_int_type (dhandle, 8, false);
- name = "signed long long";
- break;
-
- case builtin_unsigned_long_long:
- type = debug_make_int_type (dhandle, 8, true);
- name = "unsigned long long";
- break;
-
- case builtin_float:
- type = debug_make_float_type (dhandle, 4);
- name = "float";
- break;
-
- case builtin_double:
- type = debug_make_float_type (dhandle, 8);
- name = "double";
- break;
-
- case builtin_long_double:
- /* FIXME: The size for this type should depend upon the
- processor. */
- type = debug_make_float_type (dhandle, 12);
- name = "long double";
- break;
-
- case builtin_long_long_double:
- type = debug_make_float_type (dhandle, 16);
- name = "long long double";
- break;
-
- case builtin_quoted_string:
- type = debug_make_array_type (dhandle,
- ieee_builtin_type (info, p,
- ((unsigned int)
- builtin_char)),
- ieee_builtin_type (info, p,
- ((unsigned int)
- builtin_int)),
- 0, -1, true);
- name = "QUOTED STRING";
- break;
-
- case builtin_instruction_address:
- /* FIXME: This should be a code address. */
- type = debug_make_int_type (dhandle, 4, true);
- name = "instruction address";
- break;
-
- case builtin_int:
- /* FIXME: The size for this type should depend upon the
- processor. */
- type = debug_make_int_type (dhandle, 4, false);
- name = "int";
- break;
-
- case builtin_unsigned:
- /* FIXME: The size for this type should depend upon the
- processor. */
- type = debug_make_int_type (dhandle, 4, true);
- name = "unsigned";
- break;
-
- case builtin_unsigned_int:
- /* FIXME: The size for this type should depend upon the
- processor. */
- type = debug_make_int_type (dhandle, 4, true);
- name = "unsigned int";
- break;
-
- case builtin_char:
- type = debug_make_int_type (dhandle, 1, false);
- name = "char";
- break;
-
- case builtin_long:
- type = debug_make_int_type (dhandle, 4, false);
- name = "long";
- break;
-
- case builtin_short:
- type = debug_make_int_type (dhandle, 2, false);
- name = "short";
- break;
-
- case builtin_unsigned_short:
- type = debug_make_int_type (dhandle, 2, true);
- name = "unsigned short";
- break;
-
- case builtin_short_int:
- type = debug_make_int_type (dhandle, 2, false);
- name = "short int";
- break;
-
- case builtin_signed_short:
- type = debug_make_int_type (dhandle, 2, false);
- name = "signed short";
- break;
-
- case builtin_bcd_float:
- ieee_error (info, p, "BCD float type not supported");
- return DEBUG_TYPE_NULL;
- }
-
- if (name != NULL)
- type = debug_name_type (dhandle, name, type);
-
- assert (indx < BUILTIN_TYPE_COUNT);
-
- info->types.builtins[indx] = type;
-
- return type;
-}
-
-/* Allocate more space in the type table. If ref is true, this is a
- reference to the type; if it is not already defined, we should set
- up an indirect type. */
-
-static boolean
-ieee_alloc_type (info, indx, ref)
- struct ieee_info *info;
- unsigned int indx;
- boolean ref;
-{
- unsigned int nalloc;
- register struct ieee_type *t;
- struct ieee_type *tend;
-
- if (indx >= info->types.alloc)
- {
- nalloc = info->types.alloc;
- if (nalloc == 0)
- nalloc = 4;
- while (indx >= nalloc)
- nalloc *= 2;
-
- info->types.types = ((struct ieee_type *)
- xrealloc (info->types.types,
- nalloc * sizeof *info->types.types));
-
- memset (info->types.types + info->types.alloc, 0,
- (nalloc - info->types.alloc) * sizeof *info->types.types);
-
- tend = info->types.types + nalloc;
- for (t = info->types.types + info->types.alloc; t < tend; t++)
- t->type = DEBUG_TYPE_NULL;
-
- info->types.alloc = nalloc;
- }
-
- if (ref)
- {
- t = info->types.types + indx;
- if (t->type == NULL)
- {
- t->pslot = (debug_type *) xmalloc (sizeof *t->pslot);
- *t->pslot = DEBUG_TYPE_NULL;
- t->type = debug_make_indirect_type (info->dhandle, t->pslot,
- (const char *) NULL);
- if (t->type == NULL)
- return false;
- }
- }
-
- return true;
-}
-
-/* Read a type index and return the corresponding type. */
-
-static boolean
-ieee_read_type_index (info, pp, ptype)
- struct ieee_info *info;
- const bfd_byte **pp;
- debug_type *ptype;
-{
- const bfd_byte *start;
- bfd_vma indx;
-
- start = *pp;
-
- if (! ieee_read_number (info, pp, &indx))
- return false;
-
- if (indx < 256)
- {
- *ptype = ieee_builtin_type (info, start, indx);
- if (*ptype == NULL)
- return false;
- return true;
- }
-
- indx -= 256;
- if (! ieee_alloc_type (info, indx, true))
- return false;
-
- *ptype = info->types.types[indx].type;
-
- return true;
-}
-
-/* Parse IEEE debugging information for a file. This is passed the
- bytes which compose the Debug Information Part of an IEEE file. */
-
-boolean
-parse_ieee (dhandle, abfd, bytes, len)
- PTR dhandle;
- bfd *abfd;
- const bfd_byte *bytes;
- bfd_size_type len;
-{
- struct ieee_info info;
- unsigned int i;
- const bfd_byte *p, *pend;
-
- info.dhandle = dhandle;
- info.abfd = abfd;
- info.bytes = bytes;
- info.pend = bytes + len;
- info.blockstack.bsp = info.blockstack.stack;
- info.saw_filename = false;
- info.vars.alloc = 0;
- info.vars.vars = NULL;
- info.types.alloc = 0;
- info.types.types = NULL;
- info.tags = NULL;
- for (i = 0; i < BUILTIN_TYPE_COUNT; i++)
- info.types.builtins[i] = DEBUG_TYPE_NULL;
-
- p = bytes;
- pend = info.pend;
- while (p < pend)
- {
- const bfd_byte *record_start;
- ieee_record_enum_type c;
-
- record_start = p;
-
- c = (ieee_record_enum_type) *p++;
-
- if (c == ieee_at_record_enum)
- c = (ieee_record_enum_type) (((unsigned int) c << 8) | *p++);
-
- if (c <= ieee_number_repeat_end_enum)
- {
- ieee_error (&info, record_start, "unexpected number");
- return false;
- }
-
- switch (c)
- {
- default:
- ieee_error (&info, record_start, "unexpected record type");
- return false;
-
- case ieee_bb_record_enum:
- if (! parse_ieee_bb (&info, &p))
- return false;
- break;
-
- case ieee_be_record_enum:
- if (! parse_ieee_be (&info, &p))
- return false;
- break;
-
- case ieee_nn_record:
- if (! parse_ieee_nn (&info, &p))
- return false;
- break;
-
- case ieee_ty_record_enum:
- if (! parse_ieee_ty (&info, &p))
- return false;
- break;
-
- case ieee_atn_record_enum:
- if (! parse_ieee_atn (&info, &p))
- return false;
- break;
- }
- }
-
- if (info.blockstack.bsp != info.blockstack.stack)
- {
- ieee_error (&info, (const bfd_byte *) NULL,
- "blocks left on stack at end");
- return false;
- }
-
- return true;
-}
-
-/* Handle an IEEE BB record. */
-
-static boolean
-parse_ieee_bb (info, pp)
- struct ieee_info *info;
- const bfd_byte **pp;
-{
- const bfd_byte *block_start;
- bfd_byte b;
- bfd_vma size;
- const char *name;
- unsigned long namlen;
- char *namcopy = NULL;
- unsigned int fnindx;
- boolean skip;
-
- block_start = *pp;
-
- b = **pp;
- ++*pp;
-
- if (! ieee_read_number (info, pp, &size)
- || ! ieee_read_id (info, pp, &name, &namlen))
- return false;
-
- fnindx = (unsigned int) -1;
- skip = false;
-
- switch (b)
- {
- case 1:
- /* BB1: Type definitions local to a module. */
- namcopy = savestring (name, namlen);
- if (namcopy == NULL)
- return false;
- if (! debug_set_filename (info->dhandle, namcopy))
- return false;
- info->saw_filename = true;
-
- /* Discard any variables or types we may have seen before. */
- if (info->vars.vars != NULL)
- free (info->vars.vars);
- info->vars.vars = NULL;
- info->vars.alloc = 0;
- if (info->types.types != NULL)
- free (info->types.types);
- info->types.types = NULL;
- info->types.alloc = 0;
-
- /* Initialize the types to the global types. */
- if (info->global_types != NULL)
- {
- info->types.alloc = info->global_types->alloc;
- info->types.types = ((struct ieee_type *)
- xmalloc (info->types.alloc
- * sizeof (*info->types.types)));
- memcpy (info->types.types, info->global_types->types,
- info->types.alloc * sizeof (*info->types.types));
- }
-
- break;
-
- case 2:
- /* BB2: Global type definitions. The name is supposed to be
- empty, but we don't check. */
- if (! debug_set_filename (info->dhandle, "*global*"))
- return false;
- info->saw_filename = true;
- break;
-
- case 3:
- /* BB3: High level module block begin. We don't have to do
- anything here. The name is supposed to be the same as for
- the BB1, but we don't check. */
- break;
-
- case 4:
- /* BB4: Global function. */
- {
- bfd_vma stackspace, typindx, offset;
- debug_type return_type;
-
- if (! ieee_read_number (info, pp, &stackspace)
- || ! ieee_read_number (info, pp, &typindx)
- || ! ieee_read_expression (info, pp, &offset))
- return false;
-
- /* We have no way to record the stack space. FIXME. */
-
- if (typindx < 256)
- {
- return_type = ieee_builtin_type (info, block_start, typindx);
- if (return_type == DEBUG_TYPE_NULL)
- return false;
- }
- else
- {
- typindx -= 256;
- if (! ieee_alloc_type (info, typindx, true))
- return false;
- fnindx = typindx;
- return_type = info->types.types[typindx].type;
- if (debug_get_type_kind (info->dhandle, return_type)
- == DEBUG_KIND_FUNCTION)
- return_type = debug_get_return_type (info->dhandle,
- return_type);
- }
-
- namcopy = savestring (name, namlen);
- if (namcopy == NULL)
- return false;
- if (! debug_record_function (info->dhandle, namcopy, return_type,
- true, offset))
- return false;
- }
- break;
-
- case 5:
- /* BB5: File name for source line numbers. */
- {
- unsigned int i;
-
- /* We ignore the date and time. FIXME. */
- for (i = 0; i < 6; i++)
- {
- bfd_vma ignore;
- boolean present;
-
- if (! ieee_read_optional_number (info, pp, &ignore, &present))
- return false;
- if (! present)
- break;
- }
-
- namcopy = savestring (name, namlen);
- if (namcopy == NULL)
- return false;
- if (! debug_start_source (info->dhandle, namcopy))
- return false;
- }
- break;
-
- case 6:
- /* BB6: Local function or block. */
- {
- bfd_vma stackspace, typindx, offset;
-
- if (! ieee_read_number (info, pp, &stackspace)
- || ! ieee_read_number (info, pp, &typindx)
- || ! ieee_read_expression (info, pp, &offset))
- return false;
-
- /* We have no way to record the stack space. FIXME. */
-
- if (namlen == 0)
- {
- if (! debug_start_block (info->dhandle, offset))
- return false;
- /* Change b to indicate that this is a block
- rather than a function. */
- b = 0x86;
- }
- else
- {
- /* The MRI C++ compiler will output a fake function named
- __XRYCPP to hold C++ debugging information. We skip
- that function. This is not crucial, but it makes
- converting from IEEE to other debug formats work
- better. */
- if (strncmp (name, "__XRYCPP", namlen) == 0)
- skip = true;
- else
- {
- debug_type return_type;
-
- if (typindx < 256)
- {
- return_type = ieee_builtin_type (info, block_start,
- typindx);
- if (return_type == NULL)
- return false;
- }
- else
- {
- typindx -= 256;
- if (! ieee_alloc_type (info, typindx, true))
- return false;
- fnindx = typindx;
- return_type = info->types.types[typindx].type;
- if (debug_get_type_kind (info->dhandle, return_type)
- == DEBUG_KIND_FUNCTION)
- return_type = debug_get_return_type (info->dhandle,
- return_type);
- }
-
- namcopy = savestring (name, namlen);
- if (namcopy == NULL)
- return false;
- if (! debug_record_function (info->dhandle, namcopy,
- return_type, false, offset))
- return false;
- }
- }
- }
- break;
-
- case 10:
- /* BB10: Assembler module scope. In the normal case, we
- completely ignore all this information. FIXME. */
- {
- const char *inam, *vstr;
- unsigned long inamlen, vstrlen;
- bfd_vma tool_type;
- boolean present;
- unsigned int i;
-
- if (! info->saw_filename)
- {
- namcopy = savestring (name, namlen);
- if (namcopy == NULL)
- return false;
- if (! debug_set_filename (info->dhandle, namcopy))
- return false;
- info->saw_filename = true;
- }
-
- if (! ieee_read_id (info, pp, &inam, &inamlen)
- || ! ieee_read_number (info, pp, &tool_type)
- || ! ieee_read_optional_id (info, pp, &vstr, &vstrlen, &present))
- return false;
- for (i = 0; i < 6; i++)
- {
- bfd_vma ignore;
-
- if (! ieee_read_optional_number (info, pp, &ignore, &present))
- return false;
- if (! present)
- break;
- }
- }
- break;
-
- case 11:
- /* BB11: Module section. We completely ignore all this
- information. FIXME. */
- {
- bfd_vma sectype, secindx, offset, map;
- boolean present;
-
- if (! ieee_read_number (info, pp, &sectype)
- || ! ieee_read_number (info, pp, &secindx)
- || ! ieee_read_expression (info, pp, &offset)
- || ! ieee_read_optional_number (info, pp, &map, &present))
- return false;
- }
- break;
-
- default:
- ieee_error (info, block_start, "unknown BB type");
- return false;
- }
-
-
- /* Push this block on the block stack. */
-
- if (info->blockstack.bsp >= info->blockstack.stack + BLOCKSTACK_SIZE)
- {
- ieee_error (info, (const bfd_byte *) NULL, "stack overflow");
- return false;
- }
-
- info->blockstack.bsp->kind = b;
- if (b == 5)
- info->blockstack.bsp->filename = namcopy;
- info->blockstack.bsp->fnindx = fnindx;
- info->blockstack.bsp->skip = skip;
- ++info->blockstack.bsp;
-
- return true;
-}
-
-/* Handle an IEEE BE record. */
-
-static boolean
-parse_ieee_be (info, pp)
- struct ieee_info *info;
- const bfd_byte **pp;
-{
- bfd_vma offset;
-
- if (info->blockstack.bsp <= info->blockstack.stack)
- {
- ieee_error (info, *pp, "stack underflow");
- return false;
- }
- --info->blockstack.bsp;
-
- switch (info->blockstack.bsp->kind)
- {
- case 2:
- /* When we end the global typedefs block, we copy out the the
- contents of info->vars. This is because the variable indices
- may be reused in the local blocks. However, we need to
- preserve them so that we can locate a function returning a
- reference variable whose type is named in the global typedef
- block. */
- info->global_vars = ((struct ieee_vars *)
- xmalloc (sizeof *info->global_vars));
- info->global_vars->alloc = info->vars.alloc;
- info->global_vars->vars = ((struct ieee_var *)
- xmalloc (info->vars.alloc
- * sizeof (*info->vars.vars)));
- memcpy (info->global_vars->vars, info->vars.vars,
- info->vars.alloc * sizeof (*info->vars.vars));
-
- /* We also copy out the non builtin parts of info->types, since
- the types are discarded when we start a new block. */
- info->global_types = ((struct ieee_types *)
- xmalloc (sizeof *info->global_types));
- info->global_types->alloc = info->types.alloc;
- info->global_types->types = ((struct ieee_type *)
- xmalloc (info->types.alloc
- * sizeof (*info->types.types)));
- memcpy (info->global_types->types, info->types.types,
- info->types.alloc * sizeof (*info->types.types));
- memset (info->global_types->builtins, 0,
- sizeof (info->global_types->builtins));
-
- break;
-
- case 4:
- case 6:
- if (! ieee_read_expression (info, pp, &offset))
- return false;
- if (! info->blockstack.bsp->skip)
- {
- if (! debug_end_function (info->dhandle, offset + 1))
- return false;
- }
- break;
-
- case 0x86:
- /* This is BE6 when BB6 started a block rather than a local
- function. */
- if (! ieee_read_expression (info, pp, &offset))
- return false;
- if (! debug_end_block (info->dhandle, offset + 1))
- return false;
- break;
-
- case 5:
- /* When we end a BB5, we look up the stack for the last BB5, if
- there is one, so that we can call debug_start_source. */
- if (info->blockstack.bsp > info->blockstack.stack)
- {
- struct ieee_block *bl;
-
- bl = info->blockstack.bsp;
- do
- {
- --bl;
- if (bl->kind == 5)
- {
- if (! debug_start_source (info->dhandle, bl->filename))
- return false;
- break;
- }
- }
- while (bl != info->blockstack.stack);
- }
- break;
-
- case 11:
- if (! ieee_read_expression (info, pp, &offset))
- return false;
- /* We just ignore the module size. FIXME. */
- break;
-
- default:
- /* Other block types do not have any trailing information. */
- break;
- }
-
- return true;
-}
-
-/* Parse an NN record. */
-
-static boolean
-parse_ieee_nn (info, pp)
- struct ieee_info *info;
- const bfd_byte **pp;
-{
- const bfd_byte *nn_start;
- bfd_vma varindx;
- const char *name;
- unsigned long namlen;
-
- nn_start = *pp;
-
- if (! ieee_read_number (info, pp, &varindx)
- || ! ieee_read_id (info, pp, &name, &namlen))
- return false;
-
- if (varindx < 32)
- {
- ieee_error (info, nn_start, "illegal variable index");
- return false;
- }
- varindx -= 32;
-
- if (varindx >= info->vars.alloc)
- {
- unsigned int alloc;
-
- alloc = info->vars.alloc;
- if (alloc == 0)
- alloc = 4;
- while (varindx >= alloc)
- alloc *= 2;
- info->vars.vars = ((struct ieee_var *)
- xrealloc (info->vars.vars,
- alloc * sizeof *info->vars.vars));
- memset (info->vars.vars + info->vars.alloc, 0,
- (alloc - info->vars.alloc) * sizeof *info->vars.vars);
- info->vars.alloc = alloc;
- }
-
- info->vars.vars[varindx].name = name;
- info->vars.vars[varindx].namlen = namlen;
-
- return true;
-}
-
-/* Parse a TY record. */
-
-static boolean
-parse_ieee_ty (info, pp)
- struct ieee_info *info;
- const bfd_byte **pp;
-{
- const bfd_byte *ty_start, *ty_var_start, *ty_code_start;
- bfd_vma typeindx, varindx, tc;
- PTR dhandle;
- boolean tag, typdef;
- debug_type *arg_slots;
- unsigned long type_bitsize;
- debug_type type;
-
- ty_start = *pp;
-
- if (! ieee_read_number (info, pp, &typeindx))
- return false;
-
- if (typeindx < 256)
- {
- ieee_error (info, ty_start, "illegal type index");
- return false;
- }
-
- typeindx -= 256;
- if (! ieee_alloc_type (info, typeindx, false))
- return false;
-
- if (**pp != 0xce)
- {
- ieee_error (info, *pp, "unknown TY code");
- return false;
- }
- ++*pp;
-
- ty_var_start = *pp;
-
- if (! ieee_read_number (info, pp, &varindx))
- return false;
-
- if (varindx < 32)
- {
- ieee_error (info, ty_var_start, "illegal variable index");
- return false;
- }
- varindx -= 32;
-
- if (varindx >= info->vars.alloc || info->vars.vars[varindx].name == NULL)
- {
- ieee_error (info, ty_var_start, "undefined variable in TY");
- return false;
- }
-
- ty_code_start = *pp;
-
- if (! ieee_read_number (info, pp, &tc))
- return false;
-
- dhandle = info->dhandle;
-
- tag = false;
- typdef = false;
- arg_slots = NULL;
- type_bitsize = 0;
- switch (tc)
- {
- default:
- ieee_error (info, ty_code_start, "unknown TY code");
- return false;
-
- case '!':
- /* Unknown type, with size. We treat it as int. FIXME. */
- {
- bfd_vma size;
-
- if (! ieee_read_number (info, pp, &size))
- return false;
- type = debug_make_int_type (dhandle, size, false);
- }
- break;
-
- case 'A': /* Array. */
- case 'a': /* FORTRAN array in column/row order. FIXME: Not
- distinguished from normal array. */
- {
- debug_type ele_type;
- bfd_vma lower, upper;
-
- if (! ieee_read_type_index (info, pp, &ele_type)
- || ! ieee_read_number (info, pp, &lower)
- || ! ieee_read_number (info, pp, &upper))
- return false;
- type = debug_make_array_type (dhandle, ele_type,
- ieee_builtin_type (info, ty_code_start,
- ((unsigned int)
- builtin_int)),
- (bfd_signed_vma) lower,
- (bfd_signed_vma) upper,
- false);
- }
- break;
-
- case 'E':
- /* Simple enumeration. */
- {
- bfd_vma size;
- unsigned int alloc;
- const char **names;
- unsigned int c;
- bfd_signed_vma *vals;
- unsigned int i;
-
- if (! ieee_read_number (info, pp, &size))
- return false;
- /* FIXME: we ignore the enumeration size. */
-
- alloc = 10;
- names = (const char **) xmalloc (alloc * sizeof *names);
- memset (names, 0, alloc * sizeof *names);
- c = 0;
- while (1)
- {
- const char *name;
- unsigned long namlen;
- boolean present;
-
- if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
- return false;
- if (! present)
- break;
-
- if (c + 1 >= alloc)
- {
- alloc += 10;
- names = ((const char **)
- xrealloc (names, alloc * sizeof *names));
- }
-
- names[c] = savestring (name, namlen);
- if (names[c] == NULL)
- return false;
- ++c;
- }
-
- names[c] = NULL;
-
- vals = (bfd_signed_vma *) xmalloc (c * sizeof *vals);
- for (i = 0; i < c; i++)
- vals[i] = i;
-
- type = debug_make_enum_type (dhandle, names, vals);
- tag = true;
- }
- break;
-
- case 'G':
- /* Struct with bit fields. */
- {
- bfd_vma size;
- unsigned int alloc;
- debug_field *fields;
- unsigned int c;
-
- if (! ieee_read_number (info, pp, &size))
- return false;
-
- alloc = 10;
- fields = (debug_field *) xmalloc (alloc * sizeof *fields);
- c = 0;
- while (1)
- {
- const char *name;
- unsigned long namlen;
- boolean present;
- debug_type ftype;
- bfd_vma bitpos, bitsize;
-
- if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
- return false;
- if (! present)
- break;
- if (! ieee_read_type_index (info, pp, &ftype)
- || ! ieee_read_number (info, pp, &bitpos)
- || ! ieee_read_number (info, pp, &bitsize))
- return false;
-
- if (c + 1 >= alloc)
- {
- alloc += 10;
- fields = ((debug_field *)
- xrealloc (fields, alloc * sizeof *fields));
- }
-
- fields[c] = debug_make_field (dhandle, savestring (name, namlen),
- ftype, bitpos, bitsize,
- DEBUG_VISIBILITY_PUBLIC);
- if (fields[c] == NULL)
- return false;
- ++c;
- }
-
- fields[c] = NULL;
-
- type = debug_make_struct_type (dhandle, true, size, fields);
- tag = true;
- }
- break;
-
- case 'N':
- /* Enumeration. */
- {
- unsigned int alloc;
- const char **names;
- bfd_signed_vma *vals;
- unsigned int c;
-
- alloc = 10;
- names = (const char **) xmalloc (alloc * sizeof *names);
- vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *names);
- c = 0;
- while (1)
- {
- const char *name;
- unsigned long namlen;
- boolean present;
- bfd_vma val;
-
- if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
- return false;
- if (! present)
- break;
- if (! ieee_read_number (info, pp, &val))
- return false;
-
- /* If the length of the name is zero, then the value is
- actually the size of the enum. We ignore this
- information. FIXME. */
- if (namlen == 0)
- continue;
-
- if (c + 1 >= alloc)
- {
- alloc += 10;
- names = ((const char **)
- xrealloc (names, alloc * sizeof *names));
- vals = ((bfd_signed_vma *)
- xrealloc (vals, alloc * sizeof *vals));
- }
-
- names[c] = savestring (name, namlen);
- if (names[c] == NULL)
- return false;
- vals[c] = (bfd_signed_vma) val;
- ++c;
- }
-
- names[c] = NULL;
-
- type = debug_make_enum_type (dhandle, names, vals);
- tag = true;
- }
- break;
-
- case 'O': /* Small pointer. We don't distinguish small and large
- pointers. FIXME. */
- case 'P': /* Large pointer. */
- {
- debug_type t;
-
- if (! ieee_read_type_index (info, pp, &t))
- return false;
- type = debug_make_pointer_type (dhandle, t);
- }
- break;
-
- case 'R':
- /* Range. */
- {
- bfd_vma low, high, signedp, size;
-
- if (! ieee_read_number (info, pp, &low)
- || ! ieee_read_number (info, pp, &high)
- || ! ieee_read_number (info, pp, &signedp)
- || ! ieee_read_number (info, pp, &size))
- return false;
-
- type = debug_make_range_type (dhandle,
- debug_make_int_type (dhandle, size,
- ! signedp),
- (bfd_signed_vma) low,
- (bfd_signed_vma) high);
- }
- break;
-
- case 'S': /* Struct. */
- case 'U': /* Union. */
- {
- bfd_vma size;
- unsigned int alloc;
- debug_field *fields;
- unsigned int c;
-
- if (! ieee_read_number (info, pp, &size))
- return false;
-
- alloc = 10;
- fields = (debug_field *) xmalloc (alloc * sizeof *fields);
- c = 0;
- while (1)
- {
- const char *name;
- unsigned long namlen;
- boolean present;
- bfd_vma tindx;
- bfd_vma offset;
- debug_type ftype;
- bfd_vma bitsize;
-
- if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
- return false;
- if (! present)
- break;
- if (! ieee_read_number (info, pp, &tindx)
- || ! ieee_read_number (info, pp, &offset))
- return false;
-
- if (tindx < 256)
- {
- ftype = ieee_builtin_type (info, ty_code_start, tindx);
- bitsize = 0;
- offset *= 8;
- }
- else
- {
- struct ieee_type *t;
-
- tindx -= 256;
- if (! ieee_alloc_type (info, tindx, true))
- return false;
- t = info->types.types + tindx;
- ftype = t->type;
- bitsize = t->bitsize;
- if (bitsize == 0)
- offset *= 8;
- }
-
- if (c + 1 >= alloc)
- {
- alloc += 10;
- fields = ((debug_field *)
- xrealloc (fields, alloc * sizeof *fields));
- }
-
- fields[c] = debug_make_field (dhandle, savestring (name, namlen),
- ftype, offset, bitsize,
- DEBUG_VISIBILITY_PUBLIC);
- if (fields[c] == NULL)
- return false;
- ++c;
- }
-
- fields[c] = NULL;
-
- type = debug_make_struct_type (dhandle, tc == 'S', size, fields);
- tag = true;
- }
- break;
-
- case 'T':
- /* Typedef. */
- if (! ieee_read_type_index (info, pp, &type))
- return false;
- typdef = true;
- break;
-
- case 'X':
- /* Procedure. FIXME: This is an extern declaration, which we
- have no way of representing. */
- {
- bfd_vma attr;
- debug_type rtype;
- bfd_vma nargs;
- boolean present;
- struct ieee_var *pv;
-
- /* FIXME: We ignore the attribute and the argument names. */
-
- if (! ieee_read_number (info, pp, &attr)
- || ! ieee_read_type_index (info, pp, &rtype)
- || ! ieee_read_number (info, pp, &nargs))
- return false;
- do
- {
- const char *name;
- unsigned long namlen;
-
- if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
- return false;
- }
- while (present);
-
- pv = info->vars.vars + varindx;
- pv->kind = IEEE_EXTERNAL;
- if (pv->namlen > 0
- && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER)
- {
- /* Set up the return type as an indirect type pointing to
- the variable slot, so that we can change it to a
- reference later if appropriate. */
- pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot);
- *pv->pslot = rtype;
- rtype = debug_make_indirect_type (dhandle, pv->pslot,
- (const char *) NULL);
- }
-
- type = debug_make_function_type (dhandle, rtype, (debug_type *) NULL,
- false);
- }
- break;
-
- case 'V':
- /* Void. This is not documented, but the MRI compiler emits it. */
- type = debug_make_void_type (dhandle);
- break;
-
- case 'Z':
- /* Array with 0 lower bound. */
- {
- debug_type etype;
- bfd_vma high;
-
- if (! ieee_read_type_index (info, pp, &etype)
- || ! ieee_read_number (info, pp, &high))
- return false;
-
- type = debug_make_array_type (dhandle, etype,
- ieee_builtin_type (info, ty_code_start,
- ((unsigned int)
- builtin_int)),
- 0, (bfd_signed_vma) high, false);
- }
- break;
-
- case 'c': /* Complex. */
- case 'd': /* Double complex. */
- {
- const char *name;
- unsigned long namlen;
-
- /* FIXME: I don't know what the name means. */
-
- if (! ieee_read_id (info, pp, &name, &namlen))
- return false;
-
- type = debug_make_complex_type (dhandle, tc == 'c' ? 4 : 8);
- }
- break;
-
- case 'f':
- /* Pascal file name. FIXME. */
- ieee_error (info, ty_code_start, "Pascal file name not supported");
- return false;
-
- case 'g':
- /* Bitfield type. */
- {
- bfd_vma signedp, bitsize, dummy;
- const bfd_byte *hold;
- boolean present;
-
- if (! ieee_read_number (info, pp, &signedp)
- || ! ieee_read_number (info, pp, &bitsize))
- return false;
-
- /* I think the documentation says that there is a type index,
- but some actual files do not have one. */
- hold = *pp;
- if (! ieee_read_optional_number (info, pp, &dummy, &present))
- return false;
- if (! present)
- {
- /* FIXME: This is just a guess. */
- type = debug_make_int_type (dhandle, 4,
- signedp ? false : true);
- }
- else
- {
- *pp = hold;
- if (! ieee_read_type_index (info, pp, &type))
- return false;
- }
- type_bitsize = bitsize;
- }
- break;
-
- case 'n':
- /* Qualifier. */
- {
- bfd_vma kind;
- debug_type t;
-
- if (! ieee_read_number (info, pp, &kind)
- || ! ieee_read_type_index (info, pp, &t))
- return false;
-
- switch (kind)
- {
- default:
- ieee_error (info, ty_start, "unsupported qualifer");
- return false;
-
- case 1:
- type = debug_make_const_type (dhandle, t);
- break;
-
- case 2:
- type = debug_make_volatile_type (dhandle, t);
- break;
- }
- }
- break;
-
- case 's':
- /* Set. */
- {
- bfd_vma size;
- debug_type etype;
-
- if (! ieee_read_number (info, pp, &size)
- || ! ieee_read_type_index (info, pp, &etype))
- return false;
-
- /* FIXME: We ignore the size. */
-
- type = debug_make_set_type (dhandle, etype, false);
- }
- break;
-
- case 'x':
- /* Procedure with compiler dependencies. */
- {
- struct ieee_var *pv;
- bfd_vma attr, frame_type, push_mask, nargs, level, father;
- debug_type rtype;
- debug_type *arg_types;
- boolean varargs;
- boolean present;
-
- /* FIXME: We ignore some of this information. */
-
- pv = info->vars.vars + varindx;
-
- if (! ieee_read_number (info, pp, &attr)
- || ! ieee_read_number (info, pp, &frame_type)
- || ! ieee_read_number (info, pp, &push_mask)
- || ! ieee_read_type_index (info, pp, &rtype)
- || ! ieee_read_number (info, pp, &nargs))
- return false;
- if (nargs == (bfd_vma) -1)
- {
- arg_types = NULL;
- varargs = false;
- }
- else
- {
- unsigned int i;
-
- arg_types = ((debug_type *)
- xmalloc ((nargs + 1) * sizeof *arg_types));
- for (i = 0; i < nargs; i++)
- if (! ieee_read_type_index (info, pp, arg_types + i))
- return false;
-
- /* If the last type is pointer to void, this is really a
- varargs function. */
- varargs = false;
- if (nargs > 0)
- {
- debug_type last;
-
- last = arg_types[nargs - 1];
- if (debug_get_type_kind (dhandle, last) == DEBUG_KIND_POINTER
- && (debug_get_type_kind (dhandle,
- debug_get_target_type (dhandle,
- last))
- == DEBUG_KIND_VOID))
- {
- --nargs;
- varargs = true;
- }
- }
-
- /* If there are any pointer arguments, turn them into
- indirect types in case we later need to convert them to
- reference types. */
- for (i = 0; i < nargs; i++)
- {
- if (debug_get_type_kind (dhandle, arg_types[i])
- == DEBUG_KIND_POINTER)
- {
- if (arg_slots == NULL)
- {
- arg_slots = ((debug_type *)
- xmalloc (nargs * sizeof *arg_slots));
- memset (arg_slots, 0, nargs * sizeof *arg_slots);
- }
- arg_slots[i] = arg_types[i];
- arg_types[i] =
- debug_make_indirect_type (dhandle,
- arg_slots + i,
- (const char *) NULL);
- }
- }
-
- arg_types[nargs] = DEBUG_TYPE_NULL;
- }
- if (! ieee_read_number (info, pp, &level)
- || ! ieee_read_optional_number (info, pp, &father, &present))
- return false;
-
- /* We can't distinguish between a global function and a static
- function. */
- pv->kind = IEEE_FUNCTION;
-
- if (pv->namlen > 0
- && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER)
- {
- /* Set up the return type as an indirect type pointing to
- the variable slot, so that we can change it to a
- reference later if appropriate. */
- pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot);
- *pv->pslot = rtype;
- rtype = debug_make_indirect_type (dhandle, pv->pslot,
- (const char *) NULL);
- }
-
- type = debug_make_function_type (dhandle, rtype, arg_types, varargs);
- }
- break;
- }
-
- /* Record the type in the table. */
-
- if (type == DEBUG_TYPE_NULL)
- return false;
-
- info->vars.vars[varindx].type = type;
-
- if ((tag || typdef)
- && info->vars.vars[varindx].namlen > 0)
- {
- const char *name;
-
- name = savestring (info->vars.vars[varindx].name,
- info->vars.vars[varindx].namlen);
- if (typdef)
- type = debug_name_type (dhandle, name, type);
- else if (tc == 'E' || tc == 'N')
- type = debug_tag_type (dhandle, name, type);
- else
- {
- struct ieee_tag *it;
-
- /* We must allocate all struct tags as indirect types, so
- that if we later see a definition of the tag as a C++
- record we can update the indirect slot and automatically
- change all the existing references. */
- it = (struct ieee_tag *) xmalloc (sizeof *it);
- memset (it, 0, sizeof *it);
- it->next = info->tags;
- info->tags = it;
- it->name = name;
- it->slot = type;
-
- type = debug_make_indirect_type (dhandle, &it->slot, name);
- type = debug_tag_type (dhandle, name, type);
-
- it->type = type;
- }
- if (type == NULL)
- return false;
- }
-
- info->types.types[typeindx].type = type;
- info->types.types[typeindx].arg_slots = arg_slots;
- info->types.types[typeindx].bitsize = type_bitsize;
-
- /* We may have already allocated type as an indirect type pointing
- to slot. It does no harm to replace the indirect type with the
- real type. Filling in slot as well handles the indirect types
- which are already hanging around. */
- if (info->types.types[typeindx].pslot != NULL)
- *info->types.types[typeindx].pslot = type;
-
- return true;
-}
-
-/* Parse an ATN record. */
-
-static boolean
-parse_ieee_atn (info, pp)
- struct ieee_info *info;
- const bfd_byte **pp;
-{
- const bfd_byte *atn_start, *atn_code_start;
- bfd_vma varindx;
- struct ieee_var *pvar;
- debug_type type;
- bfd_vma atn_code;
- PTR dhandle;
- bfd_vma v, v2, v3, v4, v5;
- const char *name;
- unsigned long namlen;
- char *namcopy;
- boolean present;
- int blocktype;
-
- atn_start = *pp;
-
- if (! ieee_read_number (info, pp, &varindx)
- || ! ieee_read_type_index (info, pp, &type))
- return false;
-
- atn_code_start = *pp;
-
- if (! ieee_read_number (info, pp, &atn_code))
- return false;
-
- if (varindx == 0)
- {
- pvar = NULL;
- name = "";
- namlen = 0;
- }
- else if (varindx < 32)
- {
- ieee_error (info, atn_start, "illegal variable index");
- return false;
- }
- else
- {
- varindx -= 32;
- if (varindx >= info->vars.alloc
- || info->vars.vars[varindx].name == NULL)
- {
- /* The MRI compiler or linker sometimes omits the NN record
- for a pmisc record. */
- if (atn_code == 62)
- {
- if (varindx >= info->vars.alloc)
- {
- unsigned int alloc;
-
- alloc = info->vars.alloc;
- if (alloc == 0)
- alloc = 4;
- while (varindx >= alloc)
- alloc *= 2;
- info->vars.vars = ((struct ieee_var *)
- xrealloc (info->vars.vars,
- (alloc
- * sizeof *info->vars.vars)));
- memset (info->vars.vars + info->vars.alloc, 0,
- ((alloc - info->vars.alloc)
- * sizeof *info->vars.vars));
- info->vars.alloc = alloc;
- }
-
- pvar = info->vars.vars + varindx;
- pvar->name = "";
- pvar->namlen = 0;
- }
- else
- {
- ieee_error (info, atn_start, "undefined variable in ATN");
- return false;
- }
- }
-
- pvar = info->vars.vars + varindx;
-
- pvar->type = type;
-
- name = pvar->name;
- namlen = pvar->namlen;
- }
-
- dhandle = info->dhandle;
-
- /* If we are going to call debug_record_variable with a pointer
- type, change the type to an indirect type so that we can later
- change it to a reference type if we encounter a C++ pmisc 'R'
- record. */
- if (pvar != NULL
- && type != DEBUG_TYPE_NULL
- && debug_get_type_kind (dhandle, type) == DEBUG_KIND_POINTER)
- {
- switch (atn_code)
- {
- case 1:
- case 2:
- case 3:
- case 5:
- case 8:
- case 10:
- pvar->pslot = (debug_type *) xmalloc (sizeof *pvar->pslot);
- *pvar->pslot = type;
- type = debug_make_indirect_type (dhandle, pvar->pslot,
- (const char *) NULL);
- pvar->type = type;
- break;
- }
- }
-
- switch (atn_code)
- {
- default:
- ieee_error (info, atn_code_start, "unknown ATN type");
- return false;
-
- case 1:
- /* Automatic variable. */
- if (! ieee_read_number (info, pp, &v))
- return false;
- namcopy = savestring (name, namlen);
- if (type == NULL)
- type = debug_make_void_type (dhandle);
- if (pvar != NULL)
- pvar->kind = IEEE_LOCAL;
- return debug_record_variable (dhandle, namcopy, type, DEBUG_LOCAL, v);
-
- case 2:
- /* Register variable. */
- if (! ieee_read_number (info, pp, &v))
- return false;
- namcopy = savestring (name, namlen);
- if (type == NULL)
- type = debug_make_void_type (dhandle);
- if (pvar != NULL)
- pvar->kind = IEEE_LOCAL;
- return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER,
- ieee_regno_to_genreg (info->abfd, v));
-
- case 3:
- /* Static variable. */
- if (! ieee_require_asn (info, pp, &v))
- return false;
- namcopy = savestring (name, namlen);
- if (type == NULL)
- type = debug_make_void_type (dhandle);
- if (info->blockstack.bsp <= info->blockstack.stack)
- blocktype = 0;
- else
- blocktype = info->blockstack.bsp[-1].kind;
- if (pvar != NULL)
- {
- if (blocktype == 4 || blocktype == 6)
- pvar->kind = IEEE_LOCAL;
- else
- pvar->kind = IEEE_STATIC;
- }
- return debug_record_variable (dhandle, namcopy, type,
- (blocktype == 4 || blocktype == 6
- ? DEBUG_LOCAL_STATIC
- : DEBUG_STATIC),
- v);
-
- case 4:
- /* External function. We don't currently record these. FIXME. */
- if (pvar != NULL)
- pvar->kind = IEEE_EXTERNAL;
- return true;
-
- case 5:
- /* External variable. We don't currently record these. FIXME. */
- if (pvar != NULL)
- pvar->kind = IEEE_EXTERNAL;
- return true;
-
- case 7:
- if (! ieee_read_number (info, pp, &v)
- || ! ieee_read_number (info, pp, &v2)
- || ! ieee_read_optional_number (info, pp, &v3, &present))
- return false;
- if (present)
- {
- if (! ieee_read_optional_number (info, pp, &v4, &present))
- return false;
- }
-
- /* We just ignore the two optional fields in v3 and v4, since
- they are not defined. */
-
- if (! ieee_require_asn (info, pp, &v3))
- return false;
-
- /* We have no way to record the column number. FIXME. */
-
- return debug_record_line (dhandle, v, v3);
-
- case 8:
- /* Global variable. */
- if (! ieee_require_asn (info, pp, &v))
- return false;
- namcopy = savestring (name, namlen);
- if (type == NULL)
- type = debug_make_void_type (dhandle);
- if (pvar != NULL)
- pvar->kind = IEEE_GLOBAL;
- return debug_record_variable (dhandle, namcopy, type, DEBUG_GLOBAL, v);
-
- case 9:
- /* Variable lifetime information. */
- if (! ieee_read_number (info, pp, &v))
- return false;
-
- /* We have no way to record this information. FIXME. */
- return true;
-
- case 10:
- /* Locked register. The spec says that there are two required
- fields, but at least on occasion the MRI compiler only emits
- one. */
- if (! ieee_read_number (info, pp, &v)
- || ! ieee_read_optional_number (info, pp, &v2, &present))
- return false;
-
- /* I think this means a variable that is both in a register and
- a frame slot. We ignore the frame slot. FIXME. */
-
- namcopy = savestring (name, namlen);
- if (type == NULL)
- type = debug_make_void_type (dhandle);
- if (pvar != NULL)
- pvar->kind = IEEE_LOCAL;
- return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER, v);
-
- case 11:
- /* Reserved for FORTRAN common. */
- ieee_error (info, atn_code_start, "unsupported ATN11");
-
- /* Return true to keep going. */
- return true;
-
- case 12:
- /* Based variable. */
- v3 = 0;
- v4 = 0x80;
- v5 = 0;
- if (! ieee_read_number (info, pp, &v)
- || ! ieee_read_number (info, pp, &v2)
- || ! ieee_read_optional_number (info, pp, &v3, &present))
- return false;
- if (present)
- {
- if (! ieee_read_optional_number (info, pp, &v4, &present))
- return false;
- if (present)
- {
- if (! ieee_read_optional_number (info, pp, &v5, &present))
- return false;
- }
- }
-
- /* We have no way to record this information. FIXME. */
-
- ieee_error (info, atn_code_start, "unsupported ATN12");
-
- /* Return true to keep going. */
- return true;
-
- case 16:
- /* Constant. The description of this that I have is ambiguous,
- so I'm not going to try to implement it. */
- if (! ieee_read_number (info, pp, &v)
- || ! ieee_read_optional_number (info, pp, &v2, &present))
- return false;
- if (present)
- {
- if (! ieee_read_optional_number (info, pp, &v2, &present))
- return false;
- if (present)
- {
- if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
- return false;
- }
- }
-
- if ((ieee_record_enum_type) **pp == ieee_e2_first_byte_enum)
- {
- if (! ieee_require_asn (info, pp, &v3))
- return false;
- }
-
- return true;
-
- case 19:
- /* Static variable from assembler. */
- v2 = 0;
- if (! ieee_read_number (info, pp, &v)
- || ! ieee_read_optional_number (info, pp, &v2, &present)
- || ! ieee_require_asn (info, pp, &v3))
- return false;
- namcopy = savestring (name, namlen);
- /* We don't really handle this correctly. FIXME. */
- return debug_record_variable (dhandle, namcopy,
- debug_make_void_type (dhandle),
- v2 != 0 ? DEBUG_GLOBAL : DEBUG_STATIC,
- v3);
-
- case 62:
- /* Procedure miscellaneous information. */
- case 63:
- /* Variable miscellaneous information. */
- case 64:
- /* Module miscellaneous information. */
- if (! ieee_read_number (info, pp, &v)
- || ! ieee_read_number (info, pp, &v2)
- || ! ieee_read_optional_id (info, pp, &name, &namlen, &present))
- return false;
-
- if (atn_code == 62 && v == 80)
- {
- if (present)
- {
- ieee_error (info, atn_code_start,
- "unexpected string in C++ misc");
- return false;
- }
- return ieee_read_cxx_misc (info, pp, v2);
- }
-
- /* We just ignore all of this stuff. FIXME. */
-
- for (; v2 > 0; --v2)
- {
- switch ((ieee_record_enum_type) **pp)
- {
- default:
- ieee_error (info, *pp, "bad misc record");
- return false;
-
- case ieee_at_record_enum:
- if (! ieee_require_atn65 (info, pp, &name, &namlen))
- return false;
- break;
-
- case ieee_e2_first_byte_enum:
- if (! ieee_require_asn (info, pp, &v3))
- return false;
- break;
- }
- }
-
- return true;
- }
-
- /*NOTREACHED*/
-}
-
-/* Handle C++ debugging miscellaneous records. This is called for
- procedure miscellaneous records of type 80. */
-
-static boolean
-ieee_read_cxx_misc (info, pp, count)
- struct ieee_info *info;
- const bfd_byte **pp;
- unsigned long count;
-{
- const bfd_byte *start;
- bfd_vma category;
-
- start = *pp;
-
- /* Get the category of C++ misc record. */
- if (! ieee_require_asn (info, pp, &category))
- return false;
- --count;
-
- switch (category)
- {
- default:
- ieee_error (info, start, "unrecognized C++ misc record");
- return false;
-
- case 'T':
- if (! ieee_read_cxx_class (info, pp, count))
- return false;
- break;
-
- case 'M':
- {
- bfd_vma flags;
- const char *name;
- unsigned long namlen;
-
- /* The IEEE spec indicates that the 'M' record only has a
- flags field. The MRI compiler also emits the name of the
- function. */
-
- if (! ieee_require_asn (info, pp, &flags))
- return false;
- if (*pp < info->pend
- && (ieee_record_enum_type) **pp == ieee_at_record_enum)
- {
- if (! ieee_require_atn65 (info, pp, &name, &namlen))
- return false;
- }
-
- /* This is emitted for method functions, but I don't think we
- care very much. It might help if it told us useful
- information like the class with which this function is
- associated, but it doesn't, so it isn't helpful. */
- }
- break;
-
- case 'B':
- if (! ieee_read_cxx_defaults (info, pp, count))
- return false;
- break;
-
- case 'z':
- {
- const char *name, *mangled, *class;
- unsigned long namlen, mangledlen, classlen;
- bfd_vma control;
-
- /* Pointer to member. */
-
- if (! ieee_require_atn65 (info, pp, &name, &namlen)
- || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen)
- || ! ieee_require_atn65 (info, pp, &class, &classlen)
- || ! ieee_require_asn (info, pp, &control))
- return false;
-
- /* FIXME: We should now track down name and change its type. */
- }
- break;
-
- case 'R':
- if (! ieee_read_reference (info, pp))
- return false;
- break;
- }
-
- return true;
-}
-
-/* Read a C++ class definition. This is a pmisc type 80 record of
- category 'T'. */
-
-static boolean
-ieee_read_cxx_class (info, pp, count)
- struct ieee_info *info;
- const bfd_byte **pp;
- unsigned long count;
-{
- const bfd_byte *start;
- bfd_vma class;
- const char *tag;
- unsigned long taglen;
- struct ieee_tag *it;
- PTR dhandle;
- debug_field *fields;
- unsigned int field_count, field_alloc;
- debug_baseclass *baseclasses;
- unsigned int baseclasses_count, baseclasses_alloc;
- const debug_field *structfields;
- struct ieee_method
- {
- const char *name;
- unsigned long namlen;
- debug_method_variant *variants;
- unsigned count;
- unsigned int alloc;
- } *methods;
- unsigned int methods_count, methods_alloc;
- debug_type vptrbase;
- boolean ownvptr;
- debug_method *dmethods;
-
- start = *pp;
-
- if (! ieee_require_asn (info, pp, &class))
- return false;
- --count;
-
- if (! ieee_require_atn65 (info, pp, &tag, &taglen))
- return false;
- --count;
-
- /* Find the C struct with this name. */
- for (it = info->tags; it != NULL; it = it->next)
- if (it->name[0] == tag[0]
- && strncmp (it->name, tag, taglen) == 0
- && strlen (it->name) == taglen)
- break;
- if (it == NULL)
- {
- ieee_error (info, start, "undefined C++ object");
- return false;
- }
-
- dhandle = info->dhandle;
-
- fields = NULL;
- field_count = 0;
- field_alloc = 0;
- baseclasses = NULL;
- baseclasses_count = 0;
- baseclasses_alloc = 0;
- methods = NULL;
- methods_count = 0;
- methods_alloc = 0;
- vptrbase = DEBUG_TYPE_NULL;
- ownvptr = false;
-
- structfields = debug_get_fields (dhandle, it->type);
-
- while (count > 0)
- {
- bfd_vma id;
- const bfd_byte *spec_start;
-
- spec_start = *pp;
-
- if (! ieee_require_asn (info, pp, &id))
- return false;
- --count;
-
- switch (id)
- {
- default:
- ieee_error (info, spec_start, "unrecognized C++ object spec");
- return false;
-
- case 'b':
- {
- bfd_vma flags, cinline;
- const char *basename, *fieldname;
- unsigned long baselen, fieldlen;
- char *basecopy;
- debug_type basetype;
- bfd_vma bitpos;
- boolean virtualp;
- enum debug_visibility visibility;
- debug_baseclass baseclass;
-
- /* This represents a base or friend class. */
-
- if (! ieee_require_asn (info, pp, &flags)
- || ! ieee_require_atn65 (info, pp, &basename, &baselen)
- || ! ieee_require_asn (info, pp, &cinline)
- || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen))
- return false;
- count -= 4;
-
- /* We have no way of recording friend information, so we
- just ignore it. */
- if ((flags & BASEFLAGS_FRIEND) != 0)
- break;
-
- /* I assume that either all of the members of the
- baseclass are included in the object, starting at the
- beginning of the object, or that none of them are
- included. */
-
- if ((fieldlen == 0) == (cinline == 0))
- {
- ieee_error (info, start, "unsupported C++ object type");
- return false;
- }
-
- basecopy = savestring (basename, baselen);
- basetype = debug_find_tagged_type (dhandle, basecopy,
- DEBUG_KIND_ILLEGAL);
- free (basecopy);
- if (basetype == DEBUG_TYPE_NULL)
- {
- ieee_error (info, start, "C++ base class not defined");
- return false;
- }
-
- if (fieldlen == 0)
- bitpos = 0;
- else
- {
- const debug_field *pf;
-
- if (structfields == NULL)
- {
- ieee_error (info, start, "C++ object has no fields");
- return false;
- }
-
- for (pf = structfields; *pf != DEBUG_FIELD_NULL; pf++)
- {
- const char *fname;
-
- fname = debug_get_field_name (dhandle, *pf);
- if (fname == NULL)
- return false;
- if (fname[0] == fieldname[0]
- && strncmp (fname, fieldname, fieldlen) == 0
- && strlen (fname) == fieldlen)
- break;
- }
- if (*pf == DEBUG_FIELD_NULL)
- {
- ieee_error (info, start,
- "C++ base class not found in container");
- return false;
- }
-
- bitpos = debug_get_field_bitpos (dhandle, *pf);
- }
-
- if ((flags & BASEFLAGS_VIRTUAL) != 0)
- virtualp = true;
- else
- virtualp = false;
- if ((flags & BASEFLAGS_PRIVATE) != 0)
- visibility = DEBUG_VISIBILITY_PRIVATE;
- else
- visibility = DEBUG_VISIBILITY_PUBLIC;
-
- baseclass = debug_make_baseclass (dhandle, basetype, bitpos,
- virtualp, visibility);
- if (baseclass == DEBUG_BASECLASS_NULL)
- return false;
-
- if (baseclasses_count + 1 >= baseclasses_alloc)
- {
- baseclasses_alloc += 10;
- baseclasses = ((debug_baseclass *)
- xrealloc (baseclasses,
- (baseclasses_alloc
- * sizeof *baseclasses)));
- }
-
- baseclasses[baseclasses_count] = baseclass;
- ++baseclasses_count;
- baseclasses[baseclasses_count] = DEBUG_BASECLASS_NULL;
- }
- break;
-
- case 'd':
- {
- bfd_vma flags;
- const char *fieldname, *mangledname;
- unsigned long fieldlen, mangledlen;
- char *fieldcopy;
- boolean staticp;
- debug_type ftype;
- const debug_field *pf = NULL;
- enum debug_visibility visibility;
- debug_field field;
-
- /* This represents a data member. */
-
- if (! ieee_require_asn (info, pp, &flags)
- || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen)
- || ! ieee_require_atn65 (info, pp, &mangledname, &mangledlen))
- return false;
- count -= 3;
-
- fieldcopy = savestring (fieldname, fieldlen);
-
- staticp = (flags & CXXFLAGS_STATIC) != 0 ? true : false;
-
- if (staticp)
- {
- struct ieee_var *pv, *pvend;
-
- /* See if we can find a definition for this variable. */
- pv = info->vars.vars;
- pvend = pv + info->vars.alloc;
- for (; pv < pvend; pv++)
- if (pv->namlen == mangledlen
- && strncmp (pv->name, mangledname, mangledlen) == 0)
- break;
- if (pv < pvend)
- ftype = pv->type;
- else
- {
- /* This can happen if the variable is never used. */
- ftype = ieee_builtin_type (info, start,
- (unsigned int) builtin_void);
- }
- }
- else
- {
- unsigned int findx;
-
- if (structfields == NULL)
- {
- ieee_error (info, start, "C++ object has no fields");
- return false;
- }
-
- for (pf = structfields, findx = 0;
- *pf != DEBUG_FIELD_NULL;
- pf++, findx++)
- {
- const char *fname;
-
- fname = debug_get_field_name (dhandle, *pf);
- if (fname == NULL)
- return false;
- if (fname[0] == mangledname[0]
- && strncmp (fname, mangledname, mangledlen) == 0
- && strlen (fname) == mangledlen)
- break;
- }
- if (*pf == DEBUG_FIELD_NULL)
- {
- ieee_error (info, start,
- "C++ data member not found in container");
- return false;
- }
-
- ftype = debug_get_field_type (dhandle, *pf);
-
- if (debug_get_type_kind (dhandle, ftype) == DEBUG_KIND_POINTER)
- {
- /* We might need to convert this field into a
- reference type later on, so make it an indirect
- type. */
- if (it->fslots == NULL)
- {
- unsigned int fcnt;
- const debug_field *pfcnt;
-
- fcnt = 0;
- for (pfcnt = structfields;
- *pfcnt != DEBUG_FIELD_NULL;
- pfcnt++)
- ++fcnt;
- it->fslots = ((debug_type *)
- xmalloc (fcnt * sizeof *it->fslots));
- memset (it->fslots, 0,
- fcnt * sizeof *it->fslots);
- }
-
- if (ftype == DEBUG_TYPE_NULL)
- return false;
- it->fslots[findx] = ftype;
- ftype = debug_make_indirect_type (dhandle,
- it->fslots + findx,
- (const char *) NULL);
- }
- }
- if (ftype == DEBUG_TYPE_NULL)
- return false;
-
- switch (flags & CXXFLAGS_VISIBILITY)
- {
- default:
- ieee_error (info, start, "unknown C++ visibility");
- return false;
-
- case CXXFLAGS_VISIBILITY_PUBLIC:
- visibility = DEBUG_VISIBILITY_PUBLIC;
- break;
-
- case CXXFLAGS_VISIBILITY_PRIVATE:
- visibility = DEBUG_VISIBILITY_PRIVATE;
- break;
-
- case CXXFLAGS_VISIBILITY_PROTECTED:
- visibility = DEBUG_VISIBILITY_PROTECTED;
- break;
- }
-
- if (staticp)
- {
- char *mangledcopy;
-
- mangledcopy = savestring (mangledname, mangledlen);
-
- field = debug_make_static_member (dhandle, fieldcopy,
- ftype, mangledcopy,
- visibility);
- }
- else
- {
- bfd_vma bitpos, bitsize;
-
- bitpos = debug_get_field_bitpos (dhandle, *pf);
- bitsize = debug_get_field_bitsize (dhandle, *pf);
- if (bitpos == (bfd_vma) -1 || bitsize == (bfd_vma) -1)
- {
- ieee_error (info, start, "bad C++ field bit pos or size");
- return false;
- }
- field = debug_make_field (dhandle, fieldcopy, ftype, bitpos,
- bitsize, visibility);
- }
-
- if (field == DEBUG_FIELD_NULL)
- return false;
-
- if (field_count + 1 >= field_alloc)
- {
- field_alloc += 10;
- fields = ((debug_field *)
- xrealloc (fields, field_alloc * sizeof *fields));
- }
-
- fields[field_count] = field;
- ++field_count;
- fields[field_count] = DEBUG_FIELD_NULL;
- }
- break;
-
- case 'm':
- case 'v':
- {
- bfd_vma flags, voffset, control;
- const char *name, *mangled;
- unsigned long namlen, mangledlen;
- struct ieee_var *pv, *pvend;
- debug_type type;
- enum debug_visibility visibility;
- boolean constp, volatilep;
- char *mangledcopy;
- debug_method_variant mv;
- struct ieee_method *meth;
- unsigned int im;
-
- if (! ieee_require_asn (info, pp, &flags)
- || ! ieee_require_atn65 (info, pp, &name, &namlen)
- || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen))
- return false;
- count -= 3;
- if (id != 'v')
- voffset = 0;
- else
- {
- if (! ieee_require_asn (info, pp, &voffset))
- return false;
- --count;
- }
- if (! ieee_require_asn (info, pp, &control))
- return false;
- --count;
-
- /* We just ignore the control information. */
-
- /* We have no way to represent friend information, so we
- just ignore it. */
- if ((flags & CXXFLAGS_FRIEND) != 0)
- break;
-
- /* We should already have seen a type for the function. */
- pv = info->vars.vars;
- pvend = pv + info->vars.alloc;
- for (; pv < pvend; pv++)
- if (pv->namlen == mangledlen
- && strncmp (pv->name, mangled, mangledlen) == 0)
- break;
-
- if (pv >= pvend)
- {
- /* We won't have type information for this function if
- it is not included in this file. We don't try to
- handle this case. FIXME. */
- type = (debug_make_function_type
- (dhandle,
- ieee_builtin_type (info, start,
- (unsigned int) builtin_void),
- (debug_type *) NULL,
- false));
- }
- else
- {
- debug_type return_type;
- const debug_type *arg_types;
- boolean varargs;
-
- if (debug_get_type_kind (dhandle, pv->type)
- != DEBUG_KIND_FUNCTION)
- {
- ieee_error (info, start,
- "bad type for C++ method function");
- return false;
- }
-
- return_type = debug_get_return_type (dhandle, pv->type);
- arg_types = debug_get_parameter_types (dhandle, pv->type,
- &varargs);
- if (return_type == DEBUG_TYPE_NULL || arg_types == NULL)
- {
- ieee_error (info, start,
- "no type information for C++ method function");
- return false;
- }
-
- type = debug_make_method_type (dhandle, return_type, it->type,
- (debug_type *) arg_types,
- varargs);
- }
- if (type == DEBUG_TYPE_NULL)
- return false;
-
- switch (flags & CXXFLAGS_VISIBILITY)
- {
- default:
- ieee_error (info, start, "unknown C++ visibility");
- return false;
-
- case CXXFLAGS_VISIBILITY_PUBLIC:
- visibility = DEBUG_VISIBILITY_PUBLIC;
- break;
-
- case CXXFLAGS_VISIBILITY_PRIVATE:
- visibility = DEBUG_VISIBILITY_PRIVATE;
- break;
-
- case CXXFLAGS_VISIBILITY_PROTECTED:
- visibility = DEBUG_VISIBILITY_PROTECTED;
- break;
- }
-
- constp = (flags & CXXFLAGS_CONST) != 0 ? true : false;
- volatilep = (flags & CXXFLAGS_VOLATILE) != 0 ? true : false;
-
- mangledcopy = savestring (mangled, mangledlen);
-
- if ((flags & CXXFLAGS_STATIC) != 0)
- {
- if (id == 'v')
- {
- ieee_error (info, start, "C++ static virtual method");
- return false;
- }
- mv = debug_make_static_method_variant (dhandle, mangledcopy,
- type, visibility,
- constp, volatilep);
- }
- else
- {
- debug_type vcontext;
-
- if (id != 'v')
- vcontext = DEBUG_TYPE_NULL;
- else
- {
- /* FIXME: How can we calculate this correctly? */
- vcontext = it->type;
- }
- mv = debug_make_method_variant (dhandle, mangledcopy, type,
- visibility, constp,
- volatilep, voffset,
- vcontext);
- }
- if (mv == DEBUG_METHOD_VARIANT_NULL)
- return false;
-
- for (meth = methods, im = 0; im < methods_count; meth++, im++)
- if (meth->namlen == namlen
- && strncmp (meth->name, name, namlen) == 0)
- break;
- if (im >= methods_count)
- {
- if (methods_count >= methods_alloc)
- {
- methods_alloc += 10;
- methods = ((struct ieee_method *)
- xrealloc (methods,
- methods_alloc * sizeof *methods));
- }
- methods[methods_count].name = name;
- methods[methods_count].namlen = namlen;
- methods[methods_count].variants = NULL;
- methods[methods_count].count = 0;
- methods[methods_count].alloc = 0;
- meth = methods + methods_count;
- ++methods_count;
- }
-
- if (meth->count + 1 >= meth->alloc)
- {
- meth->alloc += 10;
- meth->variants = ((debug_method_variant *)
- xrealloc (meth->variants,
- (meth->alloc
- * sizeof *meth->variants)));
- }
-
- meth->variants[meth->count] = mv;
- ++meth->count;
- meth->variants[meth->count] = DEBUG_METHOD_VARIANT_NULL;
- }
- break;
-
- case 'o':
- {
- bfd_vma spec;
-
- /* We have no way to store this information, so we just
- ignore it. */
- if (! ieee_require_asn (info, pp, &spec))
- return false;
- --count;
- if ((spec & 4) != 0)
- {
- const char *filename;
- unsigned long filenamlen;
- bfd_vma lineno;
-
- if (! ieee_require_atn65 (info, pp, &filename, &filenamlen)
- || ! ieee_require_asn (info, pp, &lineno))
- return false;
- count -= 2;
- }
- else if ((spec & 8) != 0)
- {
- const char *mangled;
- unsigned long mangledlen;
-
- if (! ieee_require_atn65 (info, pp, &mangled, &mangledlen))
- return false;
- --count;
- }
- else
- {
- ieee_error (info, start,
- "unrecognized C++ object overhead spec");
- return false;
- }
- }
- break;
-
- case 'z':
- {
- const char *vname, *basename;
- unsigned long vnamelen, baselen;
- bfd_vma vsize, control;
-
- /* A virtual table pointer. */
-
- if (! ieee_require_atn65 (info, pp, &vname, &vnamelen)
- || ! ieee_require_asn (info, pp, &vsize)
- || ! ieee_require_atn65 (info, pp, &basename, &baselen)
- || ! ieee_require_asn (info, pp, &control))
- return false;
- count -= 4;
-
- /* We just ignore the control number. We don't care what
- the virtual table name is. We have no way to store the
- virtual table size, and I don't think we care anyhow. */
-
- /* FIXME: We can't handle multiple virtual table pointers. */
-
- if (baselen == 0)
- ownvptr = true;
- else
- {
- char *basecopy;
-
- basecopy = savestring (basename, baselen);
- vptrbase = debug_find_tagged_type (dhandle, basecopy,
- DEBUG_KIND_ILLEGAL);
- free (basecopy);
- if (vptrbase == DEBUG_TYPE_NULL)
- {
- ieee_error (info, start, "undefined C++ vtable");
- return false;
- }
- }
- }
- break;
- }
- }
-
- /* Now that we have seen all the method variants, we can call
- debug_make_method for each one. */
-
- if (methods_count == 0)
- dmethods = NULL;
- else
- {
- unsigned int i;
-
- dmethods = ((debug_method *)
- xmalloc ((methods_count + 1) * sizeof *dmethods));
- for (i = 0; i < methods_count; i++)
- {
- char *namcopy;
-
- namcopy = savestring (methods[i].name, methods[i].namlen);
- dmethods[i] = debug_make_method (dhandle, namcopy,
- methods[i].variants);
- if (dmethods[i] == DEBUG_METHOD_NULL)
- return false;
- }
- dmethods[i] = DEBUG_METHOD_NULL;
- free (methods);
- }
-
- /* The struct type was created as an indirect type pointing at
- it->slot. We update it->slot to automatically update all
- references to this struct. */
- it->slot = debug_make_object_type (dhandle,
- class != 'u',
- debug_get_type_size (dhandle,
- it->slot),
- fields, baseclasses, dmethods,
- vptrbase, ownvptr);
- if (it->slot == DEBUG_TYPE_NULL)
- return false;
-
- return true;
-}
-
-/* Read C++ default argument value and reference type information. */
-
-static boolean
-ieee_read_cxx_defaults (info, pp, count)
- struct ieee_info *info;
- const bfd_byte **pp;
- unsigned long count;
-{
- const bfd_byte *start;
- const char *fnname;
- unsigned long fnlen;
- bfd_vma defcount;
-
- start = *pp;
-
- /* Giving the function name before the argument count is an addendum
- to the spec. The function name is demangled, though, so this
- record must always refer to the current function. */
-
- if (info->blockstack.bsp <= info->blockstack.stack
- || info->blockstack.bsp[-1].fnindx == (unsigned int) -1)
- {
- ieee_error (info, start, "C++ default values not in a function");
- return false;
- }
-
- if (! ieee_require_atn65 (info, pp, &fnname, &fnlen)
- || ! ieee_require_asn (info, pp, &defcount))
- return false;
- count -= 2;
-
- while (defcount-- > 0)
- {
- bfd_vma type, val;
- const char *strval;
- unsigned long strvallen;
-
- if (! ieee_require_asn (info, pp, &type))
- return false;
- --count;
-
- switch (type)
- {
- case 0:
- case 4:
- break;
-
- case 1:
- case 2:
- if (! ieee_require_asn (info, pp, &val))
- return false;
- --count;
- break;
-
- case 3:
- case 7:
- if (! ieee_require_atn65 (info, pp, &strval, &strvallen))
- return false;
- --count;
- break;
-
- default:
- ieee_error (info, start, "unrecognized C++ default type");
- return false;
- }
-
- /* We have no way to record the default argument values, so we
- just ignore them. FIXME. */
- }
-
- /* Any remaining arguments are indices of parameters that are really
- reference type. */
- if (count > 0)
- {
- PTR dhandle;
- debug_type *arg_slots;
-
- dhandle = info->dhandle;
- arg_slots = info->types.types[info->blockstack.bsp[-1].fnindx].arg_slots;
- while (count-- > 0)
- {
- bfd_vma indx;
- debug_type target;
-
- if (! ieee_require_asn (info, pp, &indx))
- return false;
- /* The index is 1 based. */
- --indx;
- if (arg_slots == NULL
- || arg_slots[indx] == DEBUG_TYPE_NULL
- || (debug_get_type_kind (dhandle, arg_slots[indx])
- != DEBUG_KIND_POINTER))
- {
- ieee_error (info, start, "reference parameter is not a pointer");
- return false;
- }
-
- target = debug_get_target_type (dhandle, arg_slots[indx]);
- arg_slots[indx] = debug_make_reference_type (dhandle, target);
- if (arg_slots[indx] == DEBUG_TYPE_NULL)
- return false;
- }
- }
-
- return true;
-}
-
-/* Read a C++ reference definition. */
-
-static boolean
-ieee_read_reference (info, pp)
- struct ieee_info *info;
- const bfd_byte **pp;
-{
- const bfd_byte *start;
- bfd_vma flags;
- const char *class, *name;
- unsigned long classlen, namlen;
- debug_type *pslot;
- debug_type target;
-
- start = *pp;
-
- if (! ieee_require_asn (info, pp, &flags))
- return false;
-
- /* Giving the class name before the member name is in an addendum to
- the spec. */
- if (flags == 3)
- {
- if (! ieee_require_atn65 (info, pp, &class, &classlen))
- return false;
- }
-
- if (! ieee_require_atn65 (info, pp, &name, &namlen))
- return false;
-
- pslot = NULL;
- if (flags != 3)
- {
- int pass;
-
- /* We search from the last variable indices to the first in
- hopes of finding local variables correctly. We search the
- local variables on the first pass, and the global variables
- on the second. FIXME: This probably won't work in all cases.
- On the other hand, I don't know what will. */
- for (pass = 0; pass < 2; pass++)
- {
- struct ieee_vars *vars;
- int i;
- struct ieee_var *pv = NULL;
-
- if (pass == 0)
- vars = &info->vars;
- else
- {
- vars = info->global_vars;
- if (vars == NULL)
- break;
- }
-
- for (i = (int) vars->alloc - 1; i >= 0; i--)
- {
- boolean found;
-
- pv = vars->vars + i;
-
- if (pv->pslot == NULL
- || pv->namlen != namlen
- || strncmp (pv->name, name, namlen) != 0)
- continue;
-
- found = false;
- switch (flags)
- {
- default:
- ieee_error (info, start,
- "unrecognized C++ reference type");
- return false;
-
- case 0:
- /* Global variable or function. */
- if (pv->kind == IEEE_GLOBAL
- || pv->kind == IEEE_EXTERNAL
- || pv->kind == IEEE_FUNCTION)
- found = true;
- break;
-
- case 1:
- /* Global static variable or function. */
- if (pv->kind == IEEE_STATIC
- || pv->kind == IEEE_FUNCTION)
- found = true;
- break;
-
- case 2:
- /* Local variable. */
- if (pv->kind == IEEE_LOCAL)
- found = true;
- break;
- }
-
- if (found)
- break;
- }
-
- if (i >= 0)
- {
- pslot = pv->pslot;
- break;
- }
- }
- }
- else
- {
- struct ieee_tag *it;
-
- for (it = info->tags; it != NULL; it = it->next)
- {
- if (it->name[0] == class[0]
- && strncmp (it->name, class, classlen) == 0
- && strlen (it->name) == classlen)
- {
- if (it->fslots != NULL)
- {
- const debug_field *pf;
- unsigned int findx;
-
- pf = debug_get_fields (info->dhandle, it->type);
- if (pf == NULL)
- {
- ieee_error (info, start,
- "C++ reference in class with no fields");
- return false;
- }
-
- for (findx = 0; *pf != DEBUG_FIELD_NULL; pf++, findx++)
- {
- const char *fname;
-
- fname = debug_get_field_name (info->dhandle, *pf);
- if (fname == NULL)
- return false;
- if (strncmp (fname, name, namlen) == 0
- && strlen (fname) == namlen)
- {
- pslot = it->fslots + findx;
- break;
- }
- }
- }
-
- break;
- }
- }
- }
-
- if (pslot == NULL)
- {
- ieee_error (info, start, "C++ reference not found");
- return false;
- }
-
- /* We allocated the type of the object as an indirect type pointing
- to *pslot, which we can now update to be a reference type. */
- if (debug_get_type_kind (info->dhandle, *pslot) != DEBUG_KIND_POINTER)
- {
- ieee_error (info, start, "C++ reference is not pointer");
- return false;
- }
-
- target = debug_get_target_type (info->dhandle, *pslot);
- *pslot = debug_make_reference_type (info->dhandle, target);
- if (*pslot == DEBUG_TYPE_NULL)
- return false;
-
- return true;
-}
-
-/* Require an ASN record. */
-
-static boolean
-ieee_require_asn (info, pp, pv)
- struct ieee_info *info;
- const bfd_byte **pp;
- bfd_vma *pv;
-{
- const bfd_byte *start;
- ieee_record_enum_type c;
- bfd_vma varindx;
-
- start = *pp;
-
- c = (ieee_record_enum_type) **pp;
- if (c != ieee_e2_first_byte_enum)
- {
- ieee_error (info, start, "missing required ASN");
- return false;
- }
- ++*pp;
-
- c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp);
- if (c != ieee_asn_record_enum)
- {
- ieee_error (info, start, "missing required ASN");
- return false;
- }
- ++*pp;
-
- /* Just ignore the variable index. */
- if (! ieee_read_number (info, pp, &varindx))
- return false;
-
- return ieee_read_expression (info, pp, pv);
-}
-
-/* Require an ATN65 record. */
-
-static boolean
-ieee_require_atn65 (info, pp, pname, pnamlen)
- struct ieee_info *info;
- const bfd_byte **pp;
- const char **pname;
- unsigned long *pnamlen;
-{
- const bfd_byte *start;
- ieee_record_enum_type c;
- bfd_vma name_indx, type_indx, atn_code;
-
- start = *pp;
-
- c = (ieee_record_enum_type) **pp;
- if (c != ieee_at_record_enum)
- {
- ieee_error (info, start, "missing required ATN65");
- return false;
- }
- ++*pp;
-
- c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp);
- if (c != ieee_atn_record_enum)
- {
- ieee_error (info, start, "missing required ATN65");
- return false;
- }
- ++*pp;
-
- if (! ieee_read_number (info, pp, &name_indx)
- || ! ieee_read_number (info, pp, &type_indx)
- || ! ieee_read_number (info, pp, &atn_code))
- return false;
-
- /* Just ignore name_indx. */
-
- if (type_indx != 0 || atn_code != 65)
- {
- ieee_error (info, start, "bad ATN65 record");
- return false;
- }
-
- return ieee_read_id (info, pp, pname, pnamlen);
-}
-
-/* Convert a register number in IEEE debugging information into a
- generic register number. */
-
-static int
-ieee_regno_to_genreg (abfd, r)
- bfd *abfd;
- int r;
-{
- switch (bfd_get_arch (abfd))
- {
- case bfd_arch_m68k:
- /* For some reasons stabs adds 2 to the floating point register
- numbers. */
- if (r >= 16)
- r += 2;
- break;
-
- case bfd_arch_i960:
- /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and
- 32 to 35 for fp0 to fp3. */
- --r;
- break;
-
- default:
- break;
- }
-
- return r;
-}
-
-/* Convert a generic register number to an IEEE specific one. */
-
-static int
-ieee_genreg_to_regno (abfd, r)
- bfd *abfd;
- int r;
-{
- switch (bfd_get_arch (abfd))
- {
- case bfd_arch_m68k:
- /* For some reason stabs add 2 to the floating point register
- numbers. */
- if (r >= 18)
- r -= 2;
- break;
-
- case bfd_arch_i960:
- /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and
- 32 to 35 for fp0 to fp3. */
- ++r;
- break;
-
- default:
- break;
- }
-
- return r;
-}
-
-/* These routines build IEEE debugging information out of the generic
- debugging information. */
-
-/* We build the IEEE debugging information byte by byte. Rather than
- waste time copying data around, we use a linked list of buffers to
- hold the data. */
-
-#define IEEE_BUFSIZE (490)
-
-struct ieee_buf
-{
- /* Next buffer. */
- struct ieee_buf *next;
- /* Number of data bytes in this buffer. */
- unsigned int c;
- /* Bytes. */
- bfd_byte buf[IEEE_BUFSIZE];
-};
-
-/* A list of buffers. */
-
-struct ieee_buflist
-{
- /* Head of list. */
- struct ieee_buf *head;
- /* Tail--last buffer on list. */
- struct ieee_buf *tail;
-};
-
-/* In order to generate the BB11 blocks required by the HP emulator,
- we keep track of ranges of addresses which correspond to a given
- compilation unit. */
-
-struct ieee_range
-{
- /* Next range. */
- struct ieee_range *next;
- /* Low address. */
- bfd_vma low;
- /* High address. */
- bfd_vma high;
-};
-
-/* This structure holds information for a class on the type stack. */
-
-struct ieee_type_class
-{
- /* The name index in the debugging information. */
- unsigned int indx;
- /* The pmisc records for the class. */
- struct ieee_buflist pmiscbuf;
- /* The number of pmisc records. */
- unsigned int pmisccount;
- /* The name of the class holding the virtual table, if not this
- class. */
- const char *vclass;
- /* Whether this class holds its own virtual table. */
- boolean ownvptr;
- /* The largest virtual table offset seen so far. */
- bfd_vma voffset;
- /* The current method. */
- const char *method;
- /* Additional pmisc records used to record fields of reference type. */
- struct ieee_buflist refs;
-};
-
-/* This is how we store types for the writing routines. Most types
- are simply represented by a type index. */
-
-struct ieee_write_type
-{
- /* Type index. */
- unsigned int indx;
- /* The size of the type, if known. */
- unsigned int size;
- /* The name of the type, if any. */
- const char *name;
- /* If this is a function or method type, we build the type here, and
- only add it to the output buffers if we need it. */
- struct ieee_buflist fndef;
- /* If this is a struct, this is where the struct definition is
- built. */
- struct ieee_buflist strdef;
- /* If this is a class, this is where the class information is built. */
- struct ieee_type_class *classdef;
- /* Whether the type is unsigned. */
- unsigned int unsignedp : 1;
- /* Whether this is a reference type. */
- unsigned int referencep : 1;
- /* Whether this is in the local type block. */
- unsigned int localp : 1;
- /* Whether this is a duplicate struct definition which we are
- ignoring. */
- unsigned int ignorep : 1;
-};
-
-/* This is the type stack used by the debug writing routines. FIXME:
- We could generate more efficient output if we remembered when we
- have output a particular type before. */
-
-struct ieee_type_stack
-{
- /* Next entry on stack. */
- struct ieee_type_stack *next;
- /* Type information. */
- struct ieee_write_type type;
-};
-
-/* This is a list of associations between a name and some types.
- These are used for typedefs and tags. */
-
-struct ieee_name_type
-{
- /* Next type for this name. */
- struct ieee_name_type *next;
- /* ID number. For a typedef, this is the index of the type to which
- this name is typedefed. */
- unsigned int id;
- /* Type. */
- struct ieee_write_type type;
- /* If this is a tag which has not yet been defined, this is the
- kind. If the tag has been defined, this is DEBUG_KIND_ILLEGAL. */
- enum debug_type_kind kind;
-};
-
-/* We use a hash table to associate names and types. */
-
-struct ieee_name_type_hash_table
-{
- struct bfd_hash_table root;
-};
-
-struct ieee_name_type_hash_entry
-{
- struct bfd_hash_entry root;
- /* Information for this name. */
- struct ieee_name_type *types;
-};
-
-/* This is a list of enums. */
-
-struct ieee_defined_enum
-{
- /* Next enum. */
- struct ieee_defined_enum *next;
- /* Type index. */
- unsigned int indx;
- /* Whether this enum has been defined. */
- boolean defined;
- /* Tag. */
- const char *tag;
- /* Names. */
- const char **names;
- /* Values. */
- bfd_signed_vma *vals;
-};
-
-/* We keep a list of modified versions of types, so that we don't
- output them more than once. */
-
-struct ieee_modified_type
-{
- /* Pointer to this type. */
- unsigned int pointer;
- /* Function with unknown arguments returning this type. */
- unsigned int function;
- /* Const version of this type. */
- unsigned int const_qualified;
- /* Volatile version of this type. */
- unsigned int volatile_qualified;
- /* List of arrays of this type of various bounds. */
- struct ieee_modified_array_type *arrays;
-};
-
-/* A list of arrays bounds. */
-
-struct ieee_modified_array_type
-{
- /* Next array bounds. */
- struct ieee_modified_array_type *next;
- /* Type index with these bounds. */
- unsigned int indx;
- /* Low bound. */
- bfd_signed_vma low;
- /* High bound. */
- bfd_signed_vma high;
-};
-
-/* This is a list of pending function parameter information. We don't
- output them until we see the first block. */
-
-struct ieee_pending_parm
-{
- /* Next pending parameter. */
- struct ieee_pending_parm *next;
- /* Name. */
- const char *name;
- /* Type index. */
- unsigned int type;
- /* Whether the type is a reference. */
- boolean referencep;
- /* Kind. */
- enum debug_parm_kind kind;
- /* Value. */
- bfd_vma val;
-};
-
-/* This is the handle passed down by debug_write. */
-
-struct ieee_handle
-{
- /* BFD we are writing to. */
- bfd *abfd;
- /* Whether we got an error in a subroutine called via traverse or
- map_over_sections. */
- boolean error;
- /* Current data buffer list. */
- struct ieee_buflist *current;
- /* Current data buffer. */
- struct ieee_buf *curbuf;
- /* Filename of current compilation unit. */
- const char *filename;
- /* Module name of current compilation unit. */
- const char *modname;
- /* List of buffer for global types. */
- struct ieee_buflist global_types;
- /* List of finished data buffers. */
- struct ieee_buflist data;
- /* List of buffers for typedefs in the current compilation unit. */
- struct ieee_buflist types;
- /* List of buffers for variables and functions in the current
- compilation unit. */
- struct ieee_buflist vars;
- /* List of buffers for C++ class definitions in the current
- compilation unit. */
- struct ieee_buflist cxx;
- /* List of buffers for line numbers in the current compilation unit. */
- struct ieee_buflist linenos;
- /* Ranges for the current compilation unit. */
- struct ieee_range *ranges;
- /* Ranges for all debugging information. */
- struct ieee_range *global_ranges;
- /* Nested pending ranges. */
- struct ieee_range *pending_ranges;
- /* Type stack. */
- struct ieee_type_stack *type_stack;
- /* Next unallocated type index. */
- unsigned int type_indx;
- /* Next unallocated name index. */
- unsigned int name_indx;
- /* Typedefs. */
- struct ieee_name_type_hash_table typedefs;
- /* Tags. */
- struct ieee_name_type_hash_table tags;
- /* Enums. */
- struct ieee_defined_enum *enums;
- /* Modified versions of types. */
- struct ieee_modified_type *modified;
- /* Number of entries allocated in modified. */
- unsigned int modified_alloc;
- /* 4 byte complex type. */
- unsigned int complex_float_index;
- /* 8 byte complex type. */
- unsigned int complex_double_index;
- /* The depth of block nesting. This is 0 outside a function, and 1
- just after start_function is called. */
- unsigned int block_depth;
- /* The name of the current function. */
- const char *fnname;
- /* List of buffers for the type of the function we are currently
- writing out. */
- struct ieee_buflist fntype;
- /* List of buffers for the parameters of the function we are
- currently writing out. */
- struct ieee_buflist fnargs;
- /* Number of arguments written to fnargs. */
- unsigned int fnargcount;
- /* Pending function parameters. */
- struct ieee_pending_parm *pending_parms;
- /* Current line number filename. */
- const char *lineno_filename;
- /* Line number name index. */
- unsigned int lineno_name_indx;
- /* Filename of pending line number. */
- const char *pending_lineno_filename;
- /* Pending line number. */
- unsigned long pending_lineno;
- /* Address of pending line number. */
- bfd_vma pending_lineno_addr;
- /* Highest address seen at end of procedure. */
- bfd_vma highaddr;
-};
-
-static boolean ieee_init_buffer
- PARAMS ((struct ieee_handle *, struct ieee_buflist *));
-static boolean ieee_change_buffer
- PARAMS ((struct ieee_handle *, struct ieee_buflist *));
-static boolean ieee_append_buffer
- PARAMS ((struct ieee_handle *, struct ieee_buflist *,
- struct ieee_buflist *));
-static boolean ieee_real_write_byte PARAMS ((struct ieee_handle *, int));
-static boolean ieee_write_2bytes PARAMS ((struct ieee_handle *, int));
-static boolean ieee_write_number PARAMS ((struct ieee_handle *, bfd_vma));
-static boolean ieee_write_id PARAMS ((struct ieee_handle *, const char *));
-static boolean ieee_write_asn
- PARAMS ((struct ieee_handle *, unsigned int, bfd_vma));
-static boolean ieee_write_atn65
- PARAMS ((struct ieee_handle *, unsigned int, const char *));
-static boolean ieee_push_type
- PARAMS ((struct ieee_handle *, unsigned int, unsigned int, boolean,
- boolean));
-static unsigned int ieee_pop_type PARAMS ((struct ieee_handle *));
-static void ieee_pop_unused_type PARAMS ((struct ieee_handle *));
-static unsigned int ieee_pop_type_used
- PARAMS ((struct ieee_handle *, boolean));
-static boolean ieee_add_range
- PARAMS ((struct ieee_handle *, boolean, bfd_vma, bfd_vma));
-static boolean ieee_start_range PARAMS ((struct ieee_handle *, bfd_vma));
-static boolean ieee_end_range PARAMS ((struct ieee_handle *, bfd_vma));
-static boolean ieee_define_type
- PARAMS ((struct ieee_handle *, unsigned int, boolean, boolean));
-static boolean ieee_define_named_type
- PARAMS ((struct ieee_handle *, const char *, unsigned int, unsigned int,
- boolean, boolean, struct ieee_buflist *));
-static struct ieee_modified_type *ieee_get_modified_info
- PARAMS ((struct ieee_handle *, unsigned int));
-static struct bfd_hash_entry *ieee_name_type_newfunc
- PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
-static boolean ieee_write_undefined_tag
- PARAMS ((struct ieee_name_type_hash_entry *, PTR));
-static boolean ieee_finish_compilation_unit PARAMS ((struct ieee_handle *));
-static void ieee_add_bb11_blocks PARAMS ((bfd *, asection *, PTR));
-static boolean ieee_add_bb11
- PARAMS ((struct ieee_handle *, asection *, bfd_vma, bfd_vma));
-static boolean ieee_output_pending_parms PARAMS ((struct ieee_handle *));
-static unsigned int ieee_vis_to_flags PARAMS ((enum debug_visibility));
-static boolean ieee_class_method_var
- PARAMS ((struct ieee_handle *, const char *, enum debug_visibility, boolean,
- boolean, boolean, bfd_vma, boolean));
-
-static boolean ieee_start_compilation_unit PARAMS ((PTR, const char *));
-static boolean ieee_start_source PARAMS ((PTR, const char *));
-static boolean ieee_empty_type PARAMS ((PTR));
-static boolean ieee_void_type PARAMS ((PTR));
-static boolean ieee_int_type PARAMS ((PTR, unsigned int, boolean));
-static boolean ieee_float_type PARAMS ((PTR, unsigned int));
-static boolean ieee_complex_type PARAMS ((PTR, unsigned int));
-static boolean ieee_bool_type PARAMS ((PTR, unsigned int));
-static boolean ieee_enum_type
- PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
-static boolean ieee_pointer_type PARAMS ((PTR));
-static boolean ieee_function_type PARAMS ((PTR, int, boolean));
-static boolean ieee_reference_type PARAMS ((PTR));
-static boolean ieee_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
-static boolean ieee_array_type
- PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean));
-static boolean ieee_set_type PARAMS ((PTR, boolean));
-static boolean ieee_offset_type PARAMS ((PTR));
-static boolean ieee_method_type PARAMS ((PTR, boolean, int, boolean));
-static boolean ieee_const_type PARAMS ((PTR));
-static boolean ieee_volatile_type PARAMS ((PTR));
-static boolean ieee_start_struct_type
- PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int));
-static boolean ieee_struct_field
- PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
-static boolean ieee_end_struct_type PARAMS ((PTR));
-static boolean ieee_start_class_type
- PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean,
- boolean));
-static boolean ieee_class_static_member
- PARAMS ((PTR, const char *, const char *, enum debug_visibility));
-static boolean ieee_class_baseclass
- PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility));
-static boolean ieee_class_start_method PARAMS ((PTR, const char *));
-static boolean ieee_class_method_variant
- PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean,
- bfd_vma, boolean));
-static boolean ieee_class_static_method_variant
- PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean));
-static boolean ieee_class_end_method PARAMS ((PTR));
-static boolean ieee_end_class_type PARAMS ((PTR));
-static boolean ieee_typedef_type PARAMS ((PTR, const char *));
-static boolean ieee_tag_type
- PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind));
-static boolean ieee_typdef PARAMS ((PTR, const char *));
-static boolean ieee_tag PARAMS ((PTR, const char *));
-static boolean ieee_int_constant PARAMS ((PTR, const char *, bfd_vma));
-static boolean ieee_float_constant PARAMS ((PTR, const char *, double));
-static boolean ieee_typed_constant PARAMS ((PTR, const char *, bfd_vma));
-static boolean ieee_variable
- PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma));
-static boolean ieee_start_function PARAMS ((PTR, const char *, boolean));
-static boolean ieee_function_parameter
- PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
-static boolean ieee_start_block PARAMS ((PTR, bfd_vma));
-static boolean ieee_end_block PARAMS ((PTR, bfd_vma));
-static boolean ieee_end_function PARAMS ((PTR));
-static boolean ieee_lineno
- PARAMS ((PTR, const char *, unsigned long, bfd_vma));
-
-static const struct debug_write_fns ieee_fns =
-{
- ieee_start_compilation_unit,
- ieee_start_source,
- ieee_empty_type,
- ieee_void_type,
- ieee_int_type,
- ieee_float_type,
- ieee_complex_type,
- ieee_bool_type,
- ieee_enum_type,
- ieee_pointer_type,
- ieee_function_type,
- ieee_reference_type,
- ieee_range_type,
- ieee_array_type,
- ieee_set_type,
- ieee_offset_type,
- ieee_method_type,
- ieee_const_type,
- ieee_volatile_type,
- ieee_start_struct_type,
- ieee_struct_field,
- ieee_end_struct_type,
- ieee_start_class_type,
- ieee_class_static_member,
- ieee_class_baseclass,
- ieee_class_start_method,
- ieee_class_method_variant,
- ieee_class_static_method_variant,
- ieee_class_end_method,
- ieee_end_class_type,
- ieee_typedef_type,
- ieee_tag_type,
- ieee_typdef,
- ieee_tag,
- ieee_int_constant,
- ieee_float_constant,
- ieee_typed_constant,
- ieee_variable,
- ieee_start_function,
- ieee_function_parameter,
- ieee_start_block,
- ieee_end_block,
- ieee_end_function,
- ieee_lineno
-};
-
-/* Initialize a buffer to be empty. */
-
-/*ARGSUSED*/
-static boolean
-ieee_init_buffer (info, buflist)
- struct ieee_handle *info;
- struct ieee_buflist *buflist;
-{
- buflist->head = NULL;
- buflist->tail = NULL;
- return true;
-}
-
-/* See whether a buffer list has any data. */
-
-#define ieee_buffer_emptyp(buflist) ((buflist)->head == NULL)
-
-/* Change the current buffer to a specified buffer chain. */
-
-static boolean
-ieee_change_buffer (info, buflist)
- struct ieee_handle *info;
- struct ieee_buflist *buflist;
-{
- if (buflist->head == NULL)
- {
- struct ieee_buf *buf;
-
- buf = (struct ieee_buf *) xmalloc (sizeof *buf);
- buf->next = NULL;
- buf->c = 0;
- buflist->head = buf;
- buflist->tail = buf;
- }
-
- info->current = buflist;
- info->curbuf = buflist->tail;
-
- return true;
-}
-
-/* Append a buffer chain. */
-
-/*ARGSUSED*/
-static boolean
-ieee_append_buffer (info, mainbuf, newbuf)
- struct ieee_handle *info;
- struct ieee_buflist *mainbuf;
- struct ieee_buflist *newbuf;
-{
- if (newbuf->head != NULL)
- {
- if (mainbuf->head == NULL)
- mainbuf->head = newbuf->head;
- else
- mainbuf->tail->next = newbuf->head;
- mainbuf->tail = newbuf->tail;
- }
- return true;
-}
-
-/* Write a byte into the buffer. We use a macro for speed and a
- function for the complex cases. */
-
-#define ieee_write_byte(info, b) \
- ((info)->curbuf->c < IEEE_BUFSIZE \
- ? ((info)->curbuf->buf[(info)->curbuf->c++] = (b), true) \
- : ieee_real_write_byte ((info), (b)))
-
-static boolean
-ieee_real_write_byte (info, b)
- struct ieee_handle *info;
- int b;
-{
- if (info->curbuf->c >= IEEE_BUFSIZE)
- {
- struct ieee_buf *n;
-
- n = (struct ieee_buf *) xmalloc (sizeof *n);
- n->next = NULL;
- n->c = 0;
- if (info->current->head == NULL)
- info->current->head = n;
- else
- info->current->tail->next = n;
- info->current->tail = n;
- info->curbuf = n;
- }
-
- info->curbuf->buf[info->curbuf->c] = b;
- ++info->curbuf->c;
-
- return true;
-}
-
-/* Write out two bytes. */
-
-static boolean
-ieee_write_2bytes (info, i)
- struct ieee_handle *info;
- int i;
-{
- return (ieee_write_byte (info, i >> 8)
- && ieee_write_byte (info, i & 0xff));
-}
-
-/* Write out an integer. */
-
-static boolean
-ieee_write_number (info, v)
- struct ieee_handle *info;
- bfd_vma v;
-{
- bfd_vma t;
- bfd_byte ab[20];
- bfd_byte *p;
- unsigned int c;
-
- if (v <= (bfd_vma) ieee_number_end_enum)
- return ieee_write_byte (info, (int) v);
-
- t = v;
- p = ab + sizeof ab;
- while (t != 0)
- {
- *--p = t & 0xff;
- t >>= 8;
- }
- c = (ab + 20) - p;
-
- if (c > (unsigned int) (ieee_number_repeat_end_enum
- - ieee_number_repeat_start_enum))
- {
- fprintf (stderr, "IEEE numeric overflow: 0x");
- fprintf_vma (stderr, v);
- fprintf (stderr, "\n");
- return false;
- }
-
- if (! ieee_write_byte (info, (int) ieee_number_repeat_start_enum + c))
- return false;
- for (; c > 0; --c, ++p)
- {
- if (! ieee_write_byte (info, *p))
- return false;
- }
-
- return true;
-}
-
-/* Write out a string. */
-
-static boolean
-ieee_write_id (info, s)
- struct ieee_handle *info;
- const char *s;
-{
- unsigned int len;
-
- len = strlen (s);
- if (len <= 0x7f)
- {
- if (! ieee_write_byte (info, len))
- return false;
- }
- else if (len <= 0xff)
- {
- if (! ieee_write_byte (info, (int) ieee_extension_length_1_enum)
- || ! ieee_write_byte (info, len))
- return false;
- }
- else if (len <= 0xffff)
- {
- if (! ieee_write_byte (info, (int) ieee_extension_length_2_enum)
- || ! ieee_write_2bytes (info, len))
- return false;
- }
- else
- {
- fprintf (stderr, "IEEE string length overflow: %u\n", len);
- return false;
- }
-
- for (; *s != '\0'; s++)
- if (! ieee_write_byte (info, *s))
- return false;
-
- return true;
-}
-
-/* Write out an ASN record. */
-
-static boolean
-ieee_write_asn (info, indx, val)
- struct ieee_handle *info;
- unsigned int indx;
- bfd_vma val;
-{
- return (ieee_write_2bytes (info, (int) ieee_asn_record_enum)
- && ieee_write_number (info, indx)
- && ieee_write_number (info, val));
-}
-
-/* Write out an ATN65 record. */
-
-static boolean
-ieee_write_atn65 (info, indx, s)
- struct ieee_handle *info;
- unsigned int indx;
- const char *s;
-{
- return (ieee_write_2bytes (info, (int) ieee_atn_record_enum)
- && ieee_write_number (info, indx)
- && ieee_write_number (info, 0)
- && ieee_write_number (info, 65)
- && ieee_write_id (info, s));
-}
-
-/* Push a type index onto the type stack. */
-
-static boolean
-ieee_push_type (info, indx, size, unsignedp, localp)
- struct ieee_handle *info;
- unsigned int indx;
- unsigned int size;
- boolean unsignedp;
- boolean localp;
-{
- struct ieee_type_stack *ts;
-
- ts = (struct ieee_type_stack *) xmalloc (sizeof *ts);
- memset (ts, 0, sizeof *ts);
-
- ts->type.indx = indx;
- ts->type.size = size;
- ts->type.unsignedp = unsignedp;
- ts->type.localp = localp;
-
- ts->next = info->type_stack;
- info->type_stack = ts;
-
- return true;
-}
-
-/* Pop a type index off the type stack. */
-
-static unsigned int
-ieee_pop_type (info)
- struct ieee_handle *info;
-{
- return ieee_pop_type_used (info, true);
-}
-
-/* Pop an unused type index off the type stack. */
-
-static void
-ieee_pop_unused_type (info)
- struct ieee_handle *info;
-{
- (void) ieee_pop_type_used (info, false);
-}
-
-/* Pop a used or unused type index off the type stack. */
-
-static unsigned int
-ieee_pop_type_used (info, used)
- struct ieee_handle *info;
- boolean used;
-{
- struct ieee_type_stack *ts;
- unsigned int ret;
-
- ts = info->type_stack;
- assert (ts != NULL);
-
- /* If this is a function type, and we need it, we need to append the
- actual definition to the typedef block now. */
- if (used && ! ieee_buffer_emptyp (&ts->type.fndef))
- {
- struct ieee_buflist *buflist;
-
- if (ts->type.localp)
- {
- /* Make sure we have started the types block. */
- if (ieee_buffer_emptyp (&info->types))
- {
- if (! ieee_change_buffer (info, &info->types)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 1)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, info->modname))
- return false;
- }
- buflist = &info->types;
- }
- else
- {
- /* Make sure we started the global type block. */
- if (ieee_buffer_emptyp (&info->global_types))
- {
- if (! ieee_change_buffer (info, &info->global_types)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 2)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, ""))
- return false;
- }
- buflist = &info->global_types;
- }
-
- if (! ieee_append_buffer (info, buflist, &ts->type.fndef))
- return false;
- }
-
- ret = ts->type.indx;
- info->type_stack = ts->next;
- free (ts);
- return ret;
-}
-
-/* Add a range of bytes included in the current compilation unit. */
-
-static boolean
-ieee_add_range (info, global, low, high)
- struct ieee_handle *info;
- boolean global;
- bfd_vma low;
- bfd_vma high;
-{
- struct ieee_range **plist, *r, **pr;
-
- if (low == (bfd_vma) -1 || high == (bfd_vma) -1 || low == high)
- return true;
-
- if (global)
- plist = &info->global_ranges;
- else
- plist = &info->ranges;
-
- for (r = *plist; r != NULL; r = r->next)
- {
- if (high >= r->low && low <= r->high)
- {
- /* The new range overlaps r. */
- if (low < r->low)
- r->low = low;
- if (high > r->high)
- r->high = high;
- pr = &r->next;
- while (*pr != NULL && (*pr)->low <= r->high)
- {
- struct ieee_range *n;
-
- if ((*pr)->high > r->high)
- r->high = (*pr)->high;
- n = (*pr)->next;
- free (*pr);
- *pr = n;
- }
- return true;
- }
- }
-
- r = (struct ieee_range *) xmalloc (sizeof *r);
- memset (r, 0, sizeof *r);
-
- r->low = low;
- r->high = high;
-
- /* Store the ranges sorted by address. */
- for (pr = plist; *pr != NULL; pr = &(*pr)->next)
- if ((*pr)->low > high)
- break;
- r->next = *pr;
- *pr = r;
-
- return true;
-}
-
-/* Start a new range for which we only have the low address. */
-
-static boolean
-ieee_start_range (info, low)
- struct ieee_handle *info;
- bfd_vma low;
-{
- struct ieee_range *r;
-
- r = (struct ieee_range *) xmalloc (sizeof *r);
- memset (r, 0, sizeof *r);
- r->low = low;
- r->next = info->pending_ranges;
- info->pending_ranges = r;
- return true;
-}
-
-/* Finish a range started by ieee_start_range. */
-
-static boolean
-ieee_end_range (info, high)
- struct ieee_handle *info;
- bfd_vma high;
-{
- struct ieee_range *r;
- bfd_vma low;
-
- assert (info->pending_ranges != NULL);
- r = info->pending_ranges;
- low = r->low;
- info->pending_ranges = r->next;
- free (r);
- return ieee_add_range (info, false, low, high);
-}
-
-/* Start defining a type. */
-
-static boolean
-ieee_define_type (info, size, unsignedp, localp)
- struct ieee_handle *info;
- unsigned int size;
- boolean unsignedp;
- boolean localp;
-{
- return ieee_define_named_type (info, (const char *) NULL,
- (unsigned int) -1, size, unsignedp,
- localp, (struct ieee_buflist *) NULL);
-}
-
-/* Start defining a named type. */
-
-static boolean
-ieee_define_named_type (info, name, indx, size, unsignedp, localp, buflist)
- struct ieee_handle *info;
- const char *name;
- unsigned int indx;
- unsigned int size;
- boolean unsignedp;
- boolean localp;
- struct ieee_buflist *buflist;
-{
- unsigned int type_indx;
- unsigned int name_indx;
-
- if (indx != (unsigned int) -1)
- type_indx = indx;
- else
- {
- type_indx = info->type_indx;
- ++info->type_indx;
- }
-
- name_indx = info->name_indx;
- ++info->name_indx;
-
- if (name == NULL)
- name = "";
-
- /* If we were given a buffer, use it; otherwise, use either the
- local or the global type information, and make sure that the type
- block is started. */
- if (buflist != NULL)
- {
- if (! ieee_change_buffer (info, buflist))
- return false;
- }
- else if (localp)
- {
- if (! ieee_buffer_emptyp (&info->types))
- {
- if (! ieee_change_buffer (info, &info->types))
- return false;
- }
- else
- {
- if (! ieee_change_buffer (info, &info->types)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 1)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, info->modname))
- return false;
- }
- }
- else
- {
- if (! ieee_buffer_emptyp (&info->global_types))
- {
- if (! ieee_change_buffer (info, &info->global_types))
- return false;
- }
- else
- {
- if (! ieee_change_buffer (info, &info->global_types)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 2)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, ""))
- return false;
- }
- }
-
- /* Push the new type on the type stack, write out an NN record, and
- write out the start of a TY record. The caller will then finish
- the TY record. */
- if (! ieee_push_type (info, type_indx, size, unsignedp, localp))
- return false;
-
- return (ieee_write_byte (info, (int) ieee_nn_record)
- && ieee_write_number (info, name_indx)
- && ieee_write_id (info, name)
- && ieee_write_byte (info, (int) ieee_ty_record_enum)
- && ieee_write_number (info, type_indx)
- && ieee_write_byte (info, 0xce)
- && ieee_write_number (info, name_indx));
-}
-
-/* Get an entry to the list of modified versions of a type. */
-
-static struct ieee_modified_type *
-ieee_get_modified_info (info, indx)
- struct ieee_handle *info;
- unsigned int indx;
-{
- if (indx >= info->modified_alloc)
- {
- unsigned int nalloc;
-
- nalloc = info->modified_alloc;
- if (nalloc == 0)
- nalloc = 16;
- while (indx >= nalloc)
- nalloc *= 2;
- info->modified = ((struct ieee_modified_type *)
- xrealloc (info->modified,
- nalloc * sizeof *info->modified));
- memset (info->modified + info->modified_alloc, 0,
- (nalloc - info->modified_alloc) * sizeof *info->modified);
- info->modified_alloc = nalloc;
- }
-
- return info->modified + indx;
-}
-
-/* Routines for the hash table mapping names to types. */
-
-/* Initialize an entry in the hash table. */
-
-static struct bfd_hash_entry *
-ieee_name_type_newfunc (entry, table, string)
- struct bfd_hash_entry *entry;
- struct bfd_hash_table *table;
- const char *string;
-{
- struct ieee_name_type_hash_entry *ret =
- (struct ieee_name_type_hash_entry *) entry;
-
- /* Allocate the structure if it has not already been allocated by a
- subclass. */
- if (ret == NULL)
- ret = ((struct ieee_name_type_hash_entry *)
- bfd_hash_allocate (table, sizeof *ret));
- if (ret == NULL)
- return NULL;
-
- /* Call the allocation method of the superclass. */
- ret = ((struct ieee_name_type_hash_entry *)
- bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
- if (ret)
- {
- /* Set local fields. */
- ret->types = NULL;
- }
-
- return (struct bfd_hash_entry *) ret;
-}
-
-/* Look up an entry in the hash table. */
-
-#define ieee_name_type_hash_lookup(table, string, create, copy) \
- ((struct ieee_name_type_hash_entry *) \
- bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
-
-/* Traverse the hash table. */
-
-#define ieee_name_type_hash_traverse(table, func, info) \
- (bfd_hash_traverse \
- (&(table)->root, \
- (boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \
- (info)))
-
-/* The general routine to write out IEEE debugging information. */
-
-boolean
-write_ieee_debugging_info (abfd, dhandle)
- bfd *abfd;
- PTR dhandle;
-{
- struct ieee_handle info;
- asection *s;
- const char *err;
- struct ieee_buf *b;
-
- memset (&info, 0, sizeof info);
- info.abfd = abfd;
- info.type_indx = 256;
- info.name_indx = 32;
-
- if (! bfd_hash_table_init (&info.typedefs.root, ieee_name_type_newfunc)
- || ! bfd_hash_table_init (&info.tags.root, ieee_name_type_newfunc))
- return false;
-
- if (! ieee_init_buffer (&info, &info.global_types)
- || ! ieee_init_buffer (&info, &info.data)
- || ! ieee_init_buffer (&info, &info.types)
- || ! ieee_init_buffer (&info, &info.vars)
- || ! ieee_init_buffer (&info, &info.cxx)
- || ! ieee_init_buffer (&info, &info.linenos)
- || ! ieee_init_buffer (&info, &info.fntype)
- || ! ieee_init_buffer (&info, &info.fnargs))
- return false;
-
- if (! debug_write (dhandle, &ieee_fns, (PTR) &info))
- return false;
-
- if (info.filename != NULL)
- {
- if (! ieee_finish_compilation_unit (&info))
- return false;
- }
-
- /* Put any undefined tags in the global typedef information. */
- info.error = false;
- ieee_name_type_hash_traverse (&info.tags,
- ieee_write_undefined_tag,
- (PTR) &info);
- if (info.error)
- return false;
-
- /* Prepend the global typedef information to the other data. */
- if (! ieee_buffer_emptyp (&info.global_types))
- {
- /* The HP debugger seems to have a bug in which it ignores the
- last entry in the global types, so we add a dummy entry. */
- if (! ieee_change_buffer (&info, &info.global_types)
- || ! ieee_write_byte (&info, (int) ieee_nn_record)
- || ! ieee_write_number (&info, info.name_indx)
- || ! ieee_write_id (&info, "")
- || ! ieee_write_byte (&info, (int) ieee_ty_record_enum)
- || ! ieee_write_number (&info, info.type_indx)
- || ! ieee_write_byte (&info, 0xce)
- || ! ieee_write_number (&info, info.name_indx)
- || ! ieee_write_number (&info, 'P')
- || ! ieee_write_number (&info, (int) builtin_void + 32)
- || ! ieee_write_byte (&info, (int) ieee_be_record_enum))
- return false;
-
- if (! ieee_append_buffer (&info, &info.global_types, &info.data))
- return false;
- info.data = info.global_types;
- }
-
- /* Make sure that we have declare BB11 blocks for each range in the
- file. They are added to info->vars. */
- info.error = false;
- if (! ieee_init_buffer (&info, &info.vars))
- return false;
- bfd_map_over_sections (abfd, ieee_add_bb11_blocks, (PTR) &info);
- if (info.error)
- return false;
- if (! ieee_buffer_emptyp (&info.vars))
- {
- if (! ieee_change_buffer (&info, &info.vars)
- || ! ieee_write_byte (&info, (int) ieee_be_record_enum))
- return false;
-
- if (! ieee_append_buffer (&info, &info.data, &info.vars))
- return false;
- }
-
- /* Now all the data is in info.data. Write it out to the BFD. We
- normally would need to worry about whether all the other sections
- are set up yet, but the IEEE backend will handle this particular
- case correctly regardless. */
- if (ieee_buffer_emptyp (&info.data))
- {
- /* There is no debugging information. */
- return true;
- }
- err = NULL;
- s = bfd_make_section (abfd, ".debug");
- if (s == NULL)
- err = "bfd_make_section";
- if (err == NULL)
- {
- if (! bfd_set_section_flags (abfd, s, SEC_DEBUGGING | SEC_HAS_CONTENTS))
- err = "bfd_set_section_flags";
- }
- if (err == NULL)
- {
- bfd_size_type size;
-
- size = 0;
- for (b = info.data.head; b != NULL; b = b->next)
- size += b->c;
- if (! bfd_set_section_size (abfd, s, size))
- err = "bfd_set_section_size";
- }
- if (err == NULL)
- {
- file_ptr offset;
-
- offset = 0;
- for (b = info.data.head; b != NULL; b = b->next)
- {
- if (! bfd_set_section_contents (abfd, s, b->buf, offset, b->c))
- {
- err = "bfd_set_section_contents";
- break;
- }
- offset += b->c;
- }
- }
-
- if (err != NULL)
- {
- fprintf (stderr, "%s: %s: %s\n", bfd_get_filename (abfd), err,
- bfd_errmsg (bfd_get_error ()));
- return false;
- }
-
- bfd_hash_table_free (&info.typedefs.root);
- bfd_hash_table_free (&info.tags.root);
-
- return true;
-}
-
-/* Write out information for an undefined tag. This is called via
- ieee_name_type_hash_traverse. */
-
-static boolean
-ieee_write_undefined_tag (h, p)
- struct ieee_name_type_hash_entry *h;
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- struct ieee_name_type *nt;
-
- for (nt = h->types; nt != NULL; nt = nt->next)
- {
- unsigned int name_indx;
- char code;
-
- if (nt->kind == DEBUG_KIND_ILLEGAL)
- continue;
-
- if (ieee_buffer_emptyp (&info->global_types))
- {
- if (! ieee_change_buffer (info, &info->global_types)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 2)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, ""))
- {
- info->error = true;
- return false;
- }
- }
- else
- {
- if (! ieee_change_buffer (info, &info->global_types))
- {
- info->error = true;
- return false;
- }
- }
-
- name_indx = info->name_indx;
- ++info->name_indx;
- if (! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, name_indx)
- || ! ieee_write_id (info, nt->type.name)
- || ! ieee_write_byte (info, (int) ieee_ty_record_enum)
- || ! ieee_write_number (info, nt->type.indx)
- || ! ieee_write_byte (info, 0xce)
- || ! ieee_write_number (info, name_indx))
- {
- info->error = true;
- return false;
- }
-
- switch (nt->kind)
- {
- default:
- abort ();
- info->error = true;
- return false;
- case DEBUG_KIND_STRUCT:
- case DEBUG_KIND_CLASS:
- code = 'S';
- break;
- case DEBUG_KIND_UNION:
- case DEBUG_KIND_UNION_CLASS:
- code = 'U';
- break;
- case DEBUG_KIND_ENUM:
- code = 'E';
- break;
- }
- if (! ieee_write_number (info, code)
- || ! ieee_write_number (info, 0))
- {
- info->error = true;
- return false;
- }
- }
-
- return true;
-}
-
-/* Start writing out information for a compilation unit. */
-
-static boolean
-ieee_start_compilation_unit (p, filename)
- PTR p;
- const char *filename;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- const char *modname;
- char *c, *s;
- unsigned int nindx;
-
- if (info->filename != NULL)
- {
- if (! ieee_finish_compilation_unit (info))
- return false;
- }
-
- info->filename = filename;
- modname = strrchr (filename, '/');
- if (modname != NULL)
- ++modname;
- else
- {
- modname = strrchr (filename, '\\');
- if (modname != NULL)
- ++modname;
- else
- modname = filename;
- }
- c = xstrdup (modname);
- s = strrchr (c, '.');
- if (s != NULL)
- *s = '\0';
- info->modname = c;
-
- if (! ieee_init_buffer (info, &info->types)
- || ! ieee_init_buffer (info, &info->vars)
- || ! ieee_init_buffer (info, &info->cxx)
- || ! ieee_init_buffer (info, &info->linenos))
- return false;
- info->ranges = NULL;
-
- /* Always include a BB1 and a BB3 block. That is what the output of
- the MRI linker seems to look like. */
- if (! ieee_change_buffer (info, &info->types)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 1)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, info->modname))
- return false;
-
- nindx = info->name_indx;
- ++info->name_indx;
- if (! ieee_change_buffer (info, &info->vars)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 3)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, info->modname))
- return false;
-
- return true;
-}
-
-/* Finish up a compilation unit. */
-
-static boolean
-ieee_finish_compilation_unit (info)
- struct ieee_handle *info;
-{
- struct ieee_range *r;
-
- if (! ieee_buffer_emptyp (&info->types))
- {
- if (! ieee_change_buffer (info, &info->types)
- || ! ieee_write_byte (info, (int) ieee_be_record_enum))
- return false;
- }
-
- if (! ieee_buffer_emptyp (&info->cxx))
- {
- /* Append any C++ information to the global function and
- variable information. */
- assert (! ieee_buffer_emptyp (&info->vars));
- if (! ieee_change_buffer (info, &info->vars))
- return false;
-
- /* We put the pmisc records in a dummy procedure, just as the
- MRI compiler does. */
- if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 6)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, "__XRYCPP")
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, info->highaddr - 1)
- || ! ieee_append_buffer (info, &info->vars, &info->cxx)
- || ! ieee_change_buffer (info, &info->vars)
- || ! ieee_write_byte (info, (int) ieee_be_record_enum)
- || ! ieee_write_number (info, info->highaddr - 1))
- return false;
- }
-
- if (! ieee_buffer_emptyp (&info->vars))
- {
- if (! ieee_change_buffer (info, &info->vars)
- || ! ieee_write_byte (info, (int) ieee_be_record_enum))
- return false;
- }
-
- if (info->pending_lineno_filename != NULL)
- {
- /* Force out the pending line number. */
- if (! ieee_lineno ((PTR) info, (const char *) NULL, 0, (bfd_vma) -1))
- return false;
- }
- if (! ieee_buffer_emptyp (&info->linenos))
- {
- if (! ieee_change_buffer (info, &info->linenos)
- || ! ieee_write_byte (info, (int) ieee_be_record_enum))
- return false;
- if (strcmp (info->filename, info->lineno_filename) != 0)
- {
- /* We were not in the main file. We just closed the
- included line number block, and now we must close the
- main line number block. */
- if (! ieee_write_byte (info, (int) ieee_be_record_enum))
- return false;
- }
- }
-
- if (! ieee_append_buffer (info, &info->data, &info->types)
- || ! ieee_append_buffer (info, &info->data, &info->vars)
- || ! ieee_append_buffer (info, &info->data, &info->linenos))
- return false;
-
- /* Build BB10/BB11 blocks based on the ranges we recorded. */
- if (! ieee_change_buffer (info, &info->data))
- return false;
-
- if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 10)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, info->modname)
- || ! ieee_write_id (info, "")
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, "GNU objcopy"))
- return false;
-
- for (r = info->ranges; r != NULL; r = r->next)
- {
- bfd_vma low, high;
- asection *s;
- int kind;
-
- low = r->low;
- high = r->high;
-
- /* Find the section corresponding to this range. */
- for (s = info->abfd->sections; s != NULL; s = s->next)
- {
- if (bfd_get_section_vma (info->abfd, s) <= low
- && high <= (bfd_get_section_vma (info->abfd, s)
- + bfd_section_size (info->abfd, s)))
- break;
- }
-
- if (s == NULL)
- {
- /* Just ignore this range. */
- continue;
- }
-
- /* Coalesce ranges if it seems reasonable. */
- while (r->next != NULL
- && high + 0x1000 >= r->next->low
- && (r->next->high
- <= (bfd_get_section_vma (info->abfd, s)
- + bfd_section_size (info->abfd, s))))
- {
- r = r->next;
- high = r->high;
- }
-
- if ((s->flags & SEC_CODE) != 0)
- kind = 1;
- else if ((s->flags & SEC_READONLY) != 0)
- kind = 3;
- else
- kind = 2;
-
- if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 11)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, "")
- || ! ieee_write_number (info, kind)
- || ! ieee_write_number (info, s->index + IEEE_SECTION_NUMBER_BASE)
- || ! ieee_write_number (info, low)
- || ! ieee_write_byte (info, (int) ieee_be_record_enum)
- || ! ieee_write_number (info, high - low))
- return false;
-
- /* Add this range to the list of global ranges. */
- if (! ieee_add_range (info, true, low, high))
- return false;
- }
-
- if (! ieee_write_byte (info, (int) ieee_be_record_enum))
- return false;
-
- return true;
-}
-
-/* Add BB11 blocks describing each range that we have not already
- described. */
-
-static void
-ieee_add_bb11_blocks (abfd, sec, data)
- bfd *abfd;
- asection *sec;
- PTR data;
-{
- struct ieee_handle *info = (struct ieee_handle *) data;
- bfd_vma low, high;
- struct ieee_range *r;
-
- low = bfd_get_section_vma (abfd, sec);
- high = low + bfd_section_size (abfd, sec);
-
- /* Find the first range at or after this section. The ranges are
- sorted by address. */
- for (r = info->global_ranges; r != NULL; r = r->next)
- if (r->high > low)
- break;
-
- while (low < high)
- {
- if (r == NULL || r->low >= high)
- {
- if (! ieee_add_bb11 (info, sec, low, high))
- info->error = true;
- return;
- }
-
- if (low < r->low
- && r->low - low > 0x100)
- {
- if (! ieee_add_bb11 (info, sec, low, r->low))
- {
- info->error = true;
- return;
- }
- }
- low = r->high;
-
- r = r->next;
- }
-}
-
-/* Add a single BB11 block for a range. We add it to info->vars. */
-
-static boolean
-ieee_add_bb11 (info, sec, low, high)
- struct ieee_handle *info;
- asection *sec;
- bfd_vma low;
- bfd_vma high;
-{
- int kind;
-
- if (! ieee_buffer_emptyp (&info->vars))
- {
- if (! ieee_change_buffer (info, &info->vars))
- return false;
- }
- else
- {
- const char *filename, *modname;
- char *c, *s;
-
- /* Start the enclosing BB10 block. */
- filename = bfd_get_filename (info->abfd);
- modname = strrchr (filename, '/');
- if (modname != NULL)
- ++modname;
- else
- {
- modname = strrchr (filename, '\\');
- if (modname != NULL)
- ++modname;
- else
- modname = filename;
- }
- c = xstrdup (modname);
- s = strrchr (c, '.');
- if (s != NULL)
- *s = '\0';
-
- if (! ieee_change_buffer (info, &info->vars)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 10)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, c)
- || ! ieee_write_id (info, "")
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, "GNU objcopy"))
- return false;
-
- free (c);
- }
-
- if ((sec->flags & SEC_CODE) != 0)
- kind = 1;
- else if ((sec->flags & SEC_READONLY) != 0)
- kind = 3;
- else
- kind = 2;
-
- if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 11)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, "")
- || ! ieee_write_number (info, kind)
- || ! ieee_write_number (info, sec->index + IEEE_SECTION_NUMBER_BASE)
- || ! ieee_write_number (info, low)
- || ! ieee_write_byte (info, (int) ieee_be_record_enum)
- || ! ieee_write_number (info, high - low))
- return false;
-
- return true;
-}
-
-/* Start recording information from a particular source file. This is
- used to record which file defined which types, variables, etc. It
- is not used for line numbers, since the lineno entry point passes
- down the file name anyhow. IEEE debugging information doesn't seem
- to store this information anywhere. */
-
-/*ARGSUSED*/
-static boolean
-ieee_start_source (p, filename)
- PTR p;
- const char *filename;
-{
- return true;
-}
-
-/* Make an empty type. */
-
-static boolean
-ieee_empty_type (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- return ieee_push_type (info, (int) builtin_unknown, 0, false, false);
-}
-
-/* Make a void type. */
-
-static boolean
-ieee_void_type (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- return ieee_push_type (info, (int) builtin_void, 0, false, false);
-}
-
-/* Make an integer type. */
-
-static boolean
-ieee_int_type (p, size, unsignedp)
- PTR p;
- unsigned int size;
- boolean unsignedp;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int indx;
-
- switch (size)
- {
- case 1:
- indx = (int) builtin_signed_char;
- break;
- case 2:
- indx = (int) builtin_signed_short_int;
- break;
- case 4:
- indx = (int) builtin_signed_long;
- break;
- case 8:
- indx = (int) builtin_signed_long_long;
- break;
- default:
- fprintf (stderr, "IEEE unsupported integer type size %u\n", size);
- return false;
- }
-
- if (unsignedp)
- ++indx;
-
- return ieee_push_type (info, indx, size, unsignedp, false);
-}
-
-/* Make a floating point type. */
-
-static boolean
-ieee_float_type (p, size)
- PTR p;
- unsigned int size;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int indx;
-
- switch (size)
- {
- case 4:
- indx = (int) builtin_float;
- break;
- case 8:
- indx = (int) builtin_double;
- break;
- case 12:
- /* FIXME: This size really depends upon the processor. */
- indx = (int) builtin_long_double;
- break;
- case 16:
- indx = (int) builtin_long_long_double;
- break;
- default:
- fprintf (stderr, "IEEE unsupported float type size %u\n", size);
- return false;
- }
-
- return ieee_push_type (info, indx, size, false, false);
-}
-
-/* Make a complex type. */
-
-static boolean
-ieee_complex_type (p, size)
- PTR p;
- unsigned int size;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- char code;
-
- switch (size)
- {
- case 4:
- if (info->complex_float_index != 0)
- return ieee_push_type (info, info->complex_float_index, size * 2,
- false, false);
- code = 'c';
- break;
- case 12:
- case 16:
- /* These cases can be output by gcc -gstabs. Outputting the
- wrong type is better than crashing. */
- case 8:
- if (info->complex_double_index != 0)
- return ieee_push_type (info, info->complex_double_index, size * 2,
- false, false);
- code = 'd';
- break;
- default:
- fprintf (stderr, "IEEE unsupported complex type size %u\n", size);
- return false;
- }
-
- /* FIXME: I don't know what the string is for. */
- if (! ieee_define_type (info, size * 2, false, false)
- || ! ieee_write_number (info, code)
- || ! ieee_write_id (info, ""))
- return false;
-
- if (size == 4)
- info->complex_float_index = info->type_stack->type.indx;
- else
- info->complex_double_index = info->type_stack->type.indx;
-
- return true;
-}
-
-/* Make a boolean type. IEEE doesn't support these, so we just make
- an integer type instead. */
-
-static boolean
-ieee_bool_type (p, size)
- PTR p;
- unsigned int size;
-{
- return ieee_int_type (p, size, true);
-}
-
-/* Make an enumeration. */
-
-static boolean
-ieee_enum_type (p, tag, names, vals)
- PTR p;
- const char *tag;
- const char **names;
- bfd_signed_vma *vals;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- struct ieee_defined_enum *e;
- boolean localp, simple;
- unsigned int indx;
- int i = 0;
-
- localp = false;
- indx = (unsigned int) -1;
- for (e = info->enums; e != NULL; e = e->next)
- {
- if (tag == NULL)
- {
- if (e->tag != NULL)
- continue;
- }
- else
- {
- if (e->tag == NULL
- || tag[0] != e->tag[0]
- || strcmp (tag, e->tag) != 0)
- continue;
- }
-
- if (! e->defined)
- {
- /* This enum tag has been seen but not defined. */
- indx = e->indx;
- break;
- }
-
- if (names != NULL && e->names != NULL)
- {
- for (i = 0; names[i] != NULL && e->names[i] != NULL; i++)
- {
- if (names[i][0] != e->names[i][0]
- || vals[i] != e->vals[i]
- || strcmp (names[i], e->names[i]) != 0)
- break;
- }
- }
-
- if ((names == NULL && e->names == NULL)
- || (names != NULL
- && e->names != NULL
- && names[i] == NULL
- && e->names[i] == NULL))
- {
- /* We've seen this enum before. */
- return ieee_push_type (info, e->indx, 0, true, false);
- }
-
- if (tag != NULL)
- {
- /* We've already seen an enum of the same name, so we must make
- sure to output this one locally. */
- localp = true;
- break;
- }
- }
-
- /* If this is a simple enumeration, in which the values start at 0
- and always increment by 1, we can use type E. Otherwise we must
- use type N. */
-
- simple = true;
- if (names != NULL)
- {
- for (i = 0; names[i] != NULL; i++)
- {
- if (vals[i] != i)
- {
- simple = false;
- break;
- }
- }
- }
-
- if (! ieee_define_named_type (info, tag, indx, 0, true, localp,
- (struct ieee_buflist *) NULL)
- || ! ieee_write_number (info, simple ? 'E' : 'N'))
- return false;
- if (simple)
- {
- /* FIXME: This is supposed to be the enumeration size, but we
- don't store that. */
- if (! ieee_write_number (info, 4))
- return false;
- }
- if (names != NULL)
- {
- for (i = 0; names[i] != NULL; i++)
- {
- if (! ieee_write_id (info, names[i]))
- return false;
- if (! simple)
- {
- if (! ieee_write_number (info, vals[i]))
- return false;
- }
- }
- }
-
- if (! localp)
- {
- if (indx == (unsigned int) -1)
- {
- e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
- memset (e, 0, sizeof *e);
- e->indx = info->type_stack->type.indx;
- e->tag = tag;
-
- e->next = info->enums;
- info->enums = e;
- }
-
- e->names = names;
- e->vals = vals;
- e->defined = true;
- }
-
- return true;
-}
-
-/* Make a pointer type. */
-
-static boolean
-ieee_pointer_type (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- boolean localp;
- unsigned int indx;
- struct ieee_modified_type *m = NULL;
-
- localp = info->type_stack->type.localp;
- indx = ieee_pop_type (info);
-
- /* A pointer to a simple builtin type can be obtained by adding 32.
- FIXME: Will this be a short pointer, and will that matter? */
- if (indx < 32)
- return ieee_push_type (info, indx + 32, 0, true, false);
-
- if (! localp)
- {
- m = ieee_get_modified_info (p, indx);
- if (m == NULL)
- return false;
-
- /* FIXME: The size should depend upon the architecture. */
- if (m->pointer > 0)
- return ieee_push_type (info, m->pointer, 4, true, false);
- }
-
- if (! ieee_define_type (info, 4, true, localp)
- || ! ieee_write_number (info, 'P')
- || ! ieee_write_number (info, indx))
- return false;
-
- if (! localp)
- m->pointer = info->type_stack->type.indx;
-
- return true;
-}
-
-/* Make a function type. This will be called for a method, but we
- don't want to actually add it to the type table in that case. We
- handle this by defining the type in a private buffer, and only
- adding that buffer to the typedef block if we are going to use it. */
-
-static boolean
-ieee_function_type (p, argcount, varargs)
- PTR p;
- int argcount;
- boolean varargs;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- boolean localp;
- unsigned int *args = NULL;
- int i;
- unsigned int retindx;
- struct ieee_buflist fndef;
- struct ieee_modified_type *m;
-
- localp = false;
-
- if (argcount > 0)
- {
- args = (unsigned int *) xmalloc (argcount * sizeof *args);
- for (i = argcount - 1; i >= 0; i--)
- {
- if (info->type_stack->type.localp)
- localp = true;
- args[i] = ieee_pop_type (info);
- }
- }
- else if (argcount < 0)
- varargs = false;
-
- if (info->type_stack->type.localp)
- localp = true;
- retindx = ieee_pop_type (info);
-
- m = NULL;
- if (argcount < 0 && ! localp)
- {
- m = ieee_get_modified_info (p, retindx);
- if (m == NULL)
- return false;
-
- if (m->function > 0)
- return ieee_push_type (info, m->function, 0, true, false);
- }
-
- /* An attribute of 0x41 means that the frame and push mask are
- unknown. */
- if (! ieee_init_buffer (info, &fndef)
- || ! ieee_define_named_type (info, (const char *) NULL,
- (unsigned int) -1, 0, true, localp,
- &fndef)
- || ! ieee_write_number (info, 'x')
- || ! ieee_write_number (info, 0x41)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, retindx)
- || ! ieee_write_number (info, (bfd_vma) argcount + (varargs ? 1 : 0)))
- return false;
- if (argcount > 0)
- {
- for (i = 0; i < argcount; i++)
- if (! ieee_write_number (info, args[i]))
- return false;
- free (args);
- }
- if (varargs)
- {
- /* A varargs function is represented by writing out the last
- argument as type void *, although this makes little sense. */
- if (! ieee_write_number (info, (bfd_vma) builtin_void + 32))
- return false;
- }
-
- if (! ieee_write_number (info, 0))
- return false;
-
- /* We wrote the information into fndef, in case we don't need it.
- It will be appended to info->types by ieee_pop_type. */
- info->type_stack->type.fndef = fndef;
-
- if (m != NULL)
- m->function = info->type_stack->type.indx;
-
- return true;
-}
-
-/* Make a reference type. */
-
-static boolean
-ieee_reference_type (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- /* IEEE appears to record a normal pointer type, and then use a
- pmisc record to indicate that it is really a reference. */
-
- if (! ieee_pointer_type (p))
- return false;
- info->type_stack->type.referencep = true;
- return true;
-}
-
-/* Make a range type. */
-
-static boolean
-ieee_range_type (p, low, high)
- PTR p;
- bfd_signed_vma low;
- bfd_signed_vma high;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int size;
- boolean unsignedp, localp;
-
- size = info->type_stack->type.size;
- unsignedp = info->type_stack->type.unsignedp;
- localp = info->type_stack->type.localp;
- ieee_pop_unused_type (info);
- return (ieee_define_type (info, size, unsignedp, localp)
- && ieee_write_number (info, 'R')
- && ieee_write_number (info, (bfd_vma) low)
- && ieee_write_number (info, (bfd_vma) high)
- && ieee_write_number (info, unsignedp ? 0 : 1)
- && ieee_write_number (info, size));
-}
-
-/* Make an array type. */
-
-/*ARGSUSED*/
-static boolean
-ieee_array_type (p, low, high, stringp)
- PTR p;
- bfd_signed_vma low;
- bfd_signed_vma high;
- boolean stringp;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int eleindx;
- boolean localp;
- unsigned int size;
- struct ieee_modified_type *m = NULL;
- struct ieee_modified_array_type *a;
-
- /* IEEE does not store the range, so we just ignore it. */
- ieee_pop_unused_type (info);
- localp = info->type_stack->type.localp;
- size = info->type_stack->type.size;
- eleindx = ieee_pop_type (info);
-
- /* If we don't know the range, treat the size as exactly one
- element. */
- if (low < high)
- size *= (high - low) + 1;
-
- if (! localp)
- {
- m = ieee_get_modified_info (info, eleindx);
- if (m == NULL)
- return false;
-
- for (a = m->arrays; a != NULL; a = a->next)
- {
- if (a->low == low && a->high == high)
- return ieee_push_type (info, a->indx, size, false, false);
- }
- }
-
- if (! ieee_define_type (info, size, false, localp)
- || ! ieee_write_number (info, low == 0 ? 'Z' : 'C')
- || ! ieee_write_number (info, eleindx))
- return false;
- if (low != 0)
- {
- if (! ieee_write_number (info, low))
- return false;
- }
-
- if (! ieee_write_number (info, high + 1))
- return false;
-
- if (! localp)
- {
- a = (struct ieee_modified_array_type *) xmalloc (sizeof *a);
- memset (a, 0, sizeof *a);
-
- a->indx = info->type_stack->type.indx;
- a->low = low;
- a->high = high;
-
- a->next = m->arrays;
- m->arrays = a;
- }
-
- return true;
-}
-
-/* Make a set type. */
-
-static boolean
-ieee_set_type (p, bitstringp)
- PTR p;
- boolean bitstringp;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- boolean localp;
- unsigned int eleindx;
-
- localp = info->type_stack->type.localp;
- eleindx = ieee_pop_type (info);
-
- /* FIXME: We don't know the size, so we just use 4. */
-
- return (ieee_define_type (info, 0, true, localp)
- && ieee_write_number (info, 's')
- && ieee_write_number (info, 4)
- && ieee_write_number (info, eleindx));
-}
-
-/* Make an offset type. */
-
-static boolean
-ieee_offset_type (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int targetindx, baseindx;
-
- targetindx = ieee_pop_type (info);
- baseindx = ieee_pop_type (info);
-
- /* FIXME: The MRI C++ compiler does not appear to generate any
- useful type information about an offset type. It just records a
- pointer to member as an integer. The MRI/HP IEEE spec does
- describe a pmisc record which can be used for a pointer to
- member. Unfortunately, it does not describe the target type,
- which seems pretty important. I'm going to punt this for now. */
-
- return ieee_int_type (p, 4, true);
-}
-
-/* Make a method type. */
-
-static boolean
-ieee_method_type (p, domain, argcount, varargs)
- PTR p;
- boolean domain;
- int argcount;
- boolean varargs;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- /* FIXME: The MRI/HP IEEE spec defines a pmisc record to use for a
- method, but the definition is incomplete. We just output an 'x'
- type. */
-
- if (domain)
- ieee_pop_unused_type (info);
-
- return ieee_function_type (p, argcount, varargs);
-}
-
-/* Make a const qualified type. */
-
-static boolean
-ieee_const_type (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int size;
- boolean unsignedp, localp;
- unsigned int indx;
- struct ieee_modified_type *m = NULL;
-
- size = info->type_stack->type.size;
- unsignedp = info->type_stack->type.unsignedp;
- localp = info->type_stack->type.localp;
- indx = ieee_pop_type (info);
-
- if (! localp)
- {
- m = ieee_get_modified_info (info, indx);
- if (m == NULL)
- return false;
-
- if (m->const_qualified > 0)
- return ieee_push_type (info, m->const_qualified, size, unsignedp,
- false);
- }
-
- if (! ieee_define_type (info, size, unsignedp, localp)
- || ! ieee_write_number (info, 'n')
- || ! ieee_write_number (info, 1)
- || ! ieee_write_number (info, indx))
- return false;
-
- if (! localp)
- m->const_qualified = info->type_stack->type.indx;
-
- return true;
-}
-
-/* Make a volatile qualified type. */
-
-static boolean
-ieee_volatile_type (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int size;
- boolean unsignedp, localp;
- unsigned int indx;
- struct ieee_modified_type *m = NULL;
-
- size = info->type_stack->type.size;
- unsignedp = info->type_stack->type.unsignedp;
- localp = info->type_stack->type.localp;
- indx = ieee_pop_type (info);
-
- if (! localp)
- {
- m = ieee_get_modified_info (info, indx);
- if (m == NULL)
- return false;
-
- if (m->volatile_qualified > 0)
- return ieee_push_type (info, m->volatile_qualified, size, unsignedp,
- false);
- }
-
- if (! ieee_define_type (info, size, unsignedp, localp)
- || ! ieee_write_number (info, 'n')
- || ! ieee_write_number (info, 2)
- || ! ieee_write_number (info, indx))
- return false;
-
- if (! localp)
- m->volatile_qualified = info->type_stack->type.indx;
-
- return true;
-}
-
-/* Convert an enum debug_visibility into a CXXFLAGS value. */
-
-static unsigned int
-ieee_vis_to_flags (visibility)
- enum debug_visibility visibility;
-{
- switch (visibility)
- {
- default:
- abort ();
- case DEBUG_VISIBILITY_PUBLIC:
- return CXXFLAGS_VISIBILITY_PUBLIC;
- case DEBUG_VISIBILITY_PRIVATE:
- return CXXFLAGS_VISIBILITY_PRIVATE;
- case DEBUG_VISIBILITY_PROTECTED:
- return CXXFLAGS_VISIBILITY_PROTECTED;
- }
- /*NOTREACHED*/
-}
-
-/* Start defining a struct type. We build it in the strdef field on
- the stack, to avoid confusing type definitions required by the
- fields with the struct type itself. */
-
-static boolean
-ieee_start_struct_type (p, tag, id, structp, size)
- PTR p;
- const char *tag;
- unsigned int id;
- boolean structp;
- unsigned int size;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- boolean localp, ignorep;
- boolean copy;
- char ab[20];
- const char *look;
- struct ieee_name_type_hash_entry *h;
- struct ieee_name_type *nt, *ntlook;
- struct ieee_buflist strdef;
-
- localp = false;
- ignorep = false;
-
- /* We need to create a tag for internal use even if we don't want
- one for external use. This will let us refer to an anonymous
- struct. */
- if (tag != NULL)
- {
- look = tag;
- copy = false;
- }
- else
- {
- sprintf (ab, "__anon%u", id);
- look = ab;
- copy = true;
- }
-
- /* If we already have references to the tag, we must use the
- existing type index. */
- h = ieee_name_type_hash_lookup (&info->tags, look, true, copy);
- if (h == NULL)
- return false;
-
- nt = NULL;
- for (ntlook = h->types; ntlook != NULL; ntlook = ntlook->next)
- {
- if (ntlook->id == id)
- nt = ntlook;
- else if (! ntlook->type.localp)
- {
- /* We are creating a duplicate definition of a globally
- defined tag. Force it to be local to avoid
- confusion. */
- localp = true;
- }
- }
-
- if (nt != NULL)
- {
- assert (localp == nt->type.localp);
- if (nt->kind == DEBUG_KIND_ILLEGAL && ! localp)
- {
- /* We've already seen a global definition of the type.
- Ignore this new definition. */
- ignorep = true;
- }
- }
- else
- {
- nt = (struct ieee_name_type *) xmalloc (sizeof *nt);
- memset (nt, 0, sizeof *nt);
- nt->id = id;
- nt->type.name = h->root.string;
- nt->next = h->types;
- h->types = nt;
- nt->type.indx = info->type_indx;
- ++info->type_indx;
- }
-
- nt->kind = DEBUG_KIND_ILLEGAL;
-
- if (! ieee_init_buffer (info, &strdef)
- || ! ieee_define_named_type (info, tag, nt->type.indx, size, true,
- localp, &strdef)
- || ! ieee_write_number (info, structp ? 'S' : 'U')
- || ! ieee_write_number (info, size))
- return false;
-
- if (! ignorep)
- {
- const char *hold;
-
- /* We never want nt->type.name to be NULL. We want the rest of
- the type to be the object set up on the type stack; it will
- have a NULL name if tag is NULL. */
- hold = nt->type.name;
- nt->type = info->type_stack->type;
- nt->type.name = hold;
- }
-
- info->type_stack->type.name = tag;
- info->type_stack->type.strdef = strdef;
- info->type_stack->type.ignorep = ignorep;
-
- return true;
-}
-
-/* Add a field to a struct. */
-
-static boolean
-ieee_struct_field (p, name, bitpos, bitsize, visibility)
- PTR p;
- const char *name;
- bfd_vma bitpos;
- bfd_vma bitsize;
- enum debug_visibility visibility;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int size;
- boolean unsignedp;
- boolean referencep;
- boolean localp;
- unsigned int indx;
- bfd_vma offset;
-
- assert (info->type_stack != NULL
- && info->type_stack->next != NULL
- && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef));
-
- /* If we are ignoring this struct definition, just pop and ignore
- the type. */
- if (info->type_stack->next->type.ignorep)
- {
- ieee_pop_unused_type (info);
- return true;
- }
-
- size = info->type_stack->type.size;
- unsignedp = info->type_stack->type.unsignedp;
- referencep = info->type_stack->type.referencep;
- localp = info->type_stack->type.localp;
- indx = ieee_pop_type (info);
-
- if (localp)
- info->type_stack->type.localp = true;
-
- if (info->type_stack->type.classdef != NULL)
- {
- unsigned int flags;
- unsigned int nindx;
-
- /* This is a class. We must add a description of this field to
- the class records we are building. */
-
- flags = ieee_vis_to_flags (visibility);
- nindx = info->type_stack->type.classdef->indx;
- if (! ieee_change_buffer (info,
- &info->type_stack->type.classdef->pmiscbuf)
- || ! ieee_write_asn (info, nindx, 'd')
- || ! ieee_write_asn (info, nindx, flags)
- || ! ieee_write_atn65 (info, nindx, name)
- || ! ieee_write_atn65 (info, nindx, name))
- return false;
- info->type_stack->type.classdef->pmisccount += 4;
-
- if (referencep)
- {
- unsigned int nindx;
-
- /* We need to output a record recording that this field is
- really of reference type. We put this on the refs field
- of classdef, so that it can be appended to the C++
- records after the class is defined. */
-
- nindx = info->name_indx;
- ++info->name_indx;
-
- if (! ieee_change_buffer (info,
- &info->type_stack->type.classdef->refs)
- || ! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_id (info, "")
- || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 62)
- || ! ieee_write_number (info, 80)
- || ! ieee_write_number (info, 4)
- || ! ieee_write_asn (info, nindx, 'R')
- || ! ieee_write_asn (info, nindx, 3)
- || ! ieee_write_atn65 (info, nindx, info->type_stack->type.name)
- || ! ieee_write_atn65 (info, nindx, name))
- return false;
- }
- }
-
- /* If the bitsize doesn't match the expected size, we need to output
- a bitfield type. */
- if (size == 0 || bitsize == 0 || bitsize == size * 8)
- offset = bitpos / 8;
- else
- {
- if (! ieee_define_type (info, 0, unsignedp,
- info->type_stack->type.localp)
- || ! ieee_write_number (info, 'g')
- || ! ieee_write_number (info, unsignedp ? 0 : 1)
- || ! ieee_write_number (info, bitsize)
- || ! ieee_write_number (info, indx))
- return false;
- indx = ieee_pop_type (info);
- offset = bitpos;
- }
-
- /* Switch to the struct we are building in order to output this
- field definition. */
- return (ieee_change_buffer (info, &info->type_stack->type.strdef)
- && ieee_write_id (info, name)
- && ieee_write_number (info, indx)
- && ieee_write_number (info, offset));
-}
-
-/* Finish up a struct type. */
-
-static boolean
-ieee_end_struct_type (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- struct ieee_buflist *pb;
-
- assert (info->type_stack != NULL
- && ! ieee_buffer_emptyp (&info->type_stack->type.strdef));
-
- /* If we were ignoring this struct definition because it was a
- duplicate defintion, just through away whatever bytes we have
- accumulated. Leave the type on the stack. */
- if (info->type_stack->type.ignorep)
- return true;
-
- /* If this is not a duplicate definition of this tag, then localp
- will be false, and we can put it in the global type block.
- FIXME: We should avoid outputting duplicate definitions which are
- the same. */
- if (! info->type_stack->type.localp)
- {
- /* Make sure we have started the global type block. */
- if (ieee_buffer_emptyp (&info->global_types))
- {
- if (! ieee_change_buffer (info, &info->global_types)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 2)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, ""))
- return false;
- }
- pb = &info->global_types;
- }
- else
- {
- /* Make sure we have started the types block. */
- if (ieee_buffer_emptyp (&info->types))
- {
- if (! ieee_change_buffer (info, &info->types)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 1)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, info->modname))
- return false;
- }
- pb = &info->types;
- }
-
- /* Append the struct definition to the types. */
- if (! ieee_append_buffer (info, pb, &info->type_stack->type.strdef)
- || ! ieee_init_buffer (info, &info->type_stack->type.strdef))
- return false;
-
- /* Leave the struct on the type stack. */
-
- return true;
-}
-
-/* Start a class type. */
-
-static boolean
-ieee_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
- PTR p;
- const char *tag;
- unsigned int id;
- boolean structp;
- unsigned int size;
- boolean vptr;
- boolean ownvptr;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- const char *vclass;
- struct ieee_buflist pmiscbuf;
- unsigned int indx;
- struct ieee_type_class *classdef;
-
- /* A C++ class is output as a C++ struct along with a set of pmisc
- records describing the class. */
-
- /* We need to have a name so that we can associate the struct and
- the class. */
- if (tag == NULL)
- {
- char *t;
-
- t = (char *) xmalloc (20);
- sprintf (t, "__anon%u", id);
- tag = t;
- }
-
- /* We can't write out the virtual table information until we have
- finished the class, because we don't know the virtual table size.
- We get the size from the largest voffset we see. */
- vclass = NULL;
- if (vptr && ! ownvptr)
- {
- vclass = info->type_stack->type.name;
- assert (vclass != NULL);
- /* We don't call ieee_pop_unused_type, since the class should
- get defined. */
- (void) ieee_pop_type (info);
- }
-
- if (! ieee_start_struct_type (p, tag, id, structp, size))
- return false;
-
- indx = info->name_indx;
- ++info->name_indx;
-
- /* We write out pmisc records into the classdef field. We will
- write out the pmisc start after we know the number of records we
- need. */
- if (! ieee_init_buffer (info, &pmiscbuf)
- || ! ieee_change_buffer (info, &pmiscbuf)
- || ! ieee_write_asn (info, indx, 'T')
- || ! ieee_write_asn (info, indx, structp ? 'o' : 'u')
- || ! ieee_write_atn65 (info, indx, tag))
- return false;
-
- classdef = (struct ieee_type_class *) xmalloc (sizeof *classdef);
- memset (classdef, 0, sizeof *classdef);
-
- classdef->indx = indx;
- classdef->pmiscbuf = pmiscbuf;
- classdef->pmisccount = 3;
- classdef->vclass = vclass;
- classdef->ownvptr = ownvptr;
-
- info->type_stack->type.classdef = classdef;
-
- return true;
-}
-
-/* Add a static member to a class. */
-
-static boolean
-ieee_class_static_member (p, name, physname, visibility)
- PTR p;
- const char *name;
- const char *physname;
- enum debug_visibility visibility;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int flags;
- unsigned int nindx;
-
- /* We don't care about the type. Hopefully there will be a call to
- ieee_variable declaring the physical name and the type, since
- that is where an IEEE consumer must get the type. */
- ieee_pop_unused_type (info);
-
- assert (info->type_stack != NULL
- && info->type_stack->type.classdef != NULL);
-
- flags = ieee_vis_to_flags (visibility);
- flags |= CXXFLAGS_STATIC;
-
- nindx = info->type_stack->type.classdef->indx;
-
- if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf)
- || ! ieee_write_asn (info, nindx, 'd')
- || ! ieee_write_asn (info, nindx, flags)
- || ! ieee_write_atn65 (info, nindx, name)
- || ! ieee_write_atn65 (info, nindx, physname))
- return false;
- info->type_stack->type.classdef->pmisccount += 4;
-
- return true;
-}
-
-/* Add a base class to a class. */
-
-static boolean
-ieee_class_baseclass (p, bitpos, virtual, visibility)
- PTR p;
- bfd_vma bitpos;
- boolean virtual;
- enum debug_visibility visibility;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- const char *bname;
- boolean localp;
- unsigned int bindx;
- char *fname;
- unsigned int flags;
- unsigned int nindx;
-
- assert (info->type_stack != NULL
- && info->type_stack->type.name != NULL
- && info->type_stack->next != NULL
- && info->type_stack->next->type.classdef != NULL
- && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef));
-
- bname = info->type_stack->type.name;
- localp = info->type_stack->type.localp;
- bindx = ieee_pop_type (info);
-
- /* We are currently defining both a struct and a class. We must
- write out a field definition in the struct which holds the base
- class. The stabs debugging reader will create a field named
- _vb$CLASS for a virtual base class, so we just use that. FIXME:
- we should not depend upon a detail of stabs debugging. */
- if (virtual)
- {
- fname = (char *) xmalloc (strlen (bname) + sizeof "_vb$");
- sprintf (fname, "_vb$%s", bname);
- flags = BASEFLAGS_VIRTUAL;
- }
- else
- {
- if (localp)
- info->type_stack->type.localp = true;
-
- fname = (char *) xmalloc (strlen (bname) + sizeof "_b$");
- sprintf (fname, "_b$%s", bname);
-
- if (! ieee_change_buffer (info, &info->type_stack->type.strdef)
- || ! ieee_write_id (info, fname)
- || ! ieee_write_number (info, bindx)
- || ! ieee_write_number (info, bitpos / 8))
- return false;
- flags = 0;
- }
-
- if (visibility == DEBUG_VISIBILITY_PRIVATE)
- flags |= BASEFLAGS_PRIVATE;
-
- nindx = info->type_stack->type.classdef->indx;
-
- if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf)
- || ! ieee_write_asn (info, nindx, 'b')
- || ! ieee_write_asn (info, nindx, flags)
- || ! ieee_write_atn65 (info, nindx, bname)
- || ! ieee_write_asn (info, nindx, 0)
- || ! ieee_write_atn65 (info, nindx, fname))
- return false;
- info->type_stack->type.classdef->pmisccount += 5;
-
- free (fname);
-
- return true;
-}
-
-/* Start building a method for a class. */
-
-static boolean
-ieee_class_start_method (p, name)
- PTR p;
- const char *name;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- assert (info->type_stack != NULL
- && info->type_stack->type.classdef != NULL
- && info->type_stack->type.classdef->method == NULL);
-
- info->type_stack->type.classdef->method = name;
-
- return true;
-}
-
-/* Define a new method variant, either static or not. */
-
-static boolean
-ieee_class_method_var (info, physname, visibility, staticp, constp,
- volatilep, voffset, context)
- struct ieee_handle *info;
- const char *physname;
- enum debug_visibility visibility;
- boolean staticp;
- boolean constp;
- boolean volatilep;
- bfd_vma voffset;
- boolean context;
-{
- unsigned int flags;
- unsigned int nindx;
- boolean virtual;
-
- /* We don't need the type of the method. An IEEE consumer which
- wants the type must track down the function by the physical name
- and get the type from that. */
- ieee_pop_unused_type (info);
-
- /* We don't use the context. FIXME: We probably ought to use it to
- adjust the voffset somehow, but I don't really know how. */
- if (context)
- ieee_pop_unused_type (info);
-
- assert (info->type_stack != NULL
- && info->type_stack->type.classdef != NULL
- && info->type_stack->type.classdef->method != NULL);
-
- flags = ieee_vis_to_flags (visibility);
-
- /* FIXME: We never set CXXFLAGS_OVERRIDE, CXXFLAGS_OPERATOR,
- CXXFLAGS_CTORDTOR, CXXFLAGS_CTOR, or CXXFLAGS_INLINE. */
-
- if (staticp)
- flags |= CXXFLAGS_STATIC;
- if (constp)
- flags |= CXXFLAGS_CONST;
- if (volatilep)
- flags |= CXXFLAGS_VOLATILE;
-
- nindx = info->type_stack->type.classdef->indx;
-
- virtual = context || voffset > 0;
-
- if (! ieee_change_buffer (info,
- &info->type_stack->type.classdef->pmiscbuf)
- || ! ieee_write_asn (info, nindx, virtual ? 'v' : 'm')
- || ! ieee_write_asn (info, nindx, flags)
- || ! ieee_write_atn65 (info, nindx,
- info->type_stack->type.classdef->method)
- || ! ieee_write_atn65 (info, nindx, physname))
- return false;
-
- if (virtual)
- {
- if (voffset > info->type_stack->type.classdef->voffset)
- info->type_stack->type.classdef->voffset = voffset;
- if (! ieee_write_asn (info, nindx, voffset))
- return false;
- ++info->type_stack->type.classdef->pmisccount;
- }
-
- if (! ieee_write_asn (info, nindx, 0))
- return false;
-
- info->type_stack->type.classdef->pmisccount += 5;
-
- return true;
-}
-
-/* Define a new method variant. */
-
-static boolean
-ieee_class_method_variant (p, physname, visibility, constp, volatilep,
- voffset, context)
- PTR p;
- const char *physname;
- enum debug_visibility visibility;
- boolean constp;
- boolean volatilep;
- bfd_vma voffset;
- boolean context;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- return ieee_class_method_var (info, physname, visibility, false, constp,
- volatilep, voffset, context);
-}
-
-/* Define a new static method variant. */
-
-static boolean
-ieee_class_static_method_variant (p, physname, visibility, constp, volatilep)
- PTR p;
- const char *physname;
- enum debug_visibility visibility;
- boolean constp;
- boolean volatilep;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- return ieee_class_method_var (info, physname, visibility, true, constp,
- volatilep, 0, false);
-}
-
-/* Finish up a method. */
-
-static boolean
-ieee_class_end_method (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- assert (info->type_stack != NULL
- && info->type_stack->type.classdef != NULL
- && info->type_stack->type.classdef->method != NULL);
-
- info->type_stack->type.classdef->method = NULL;
-
- return true;
-}
-
-/* Finish up a class. */
-
-static boolean
-ieee_end_class_type (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int nindx;
-
- assert (info->type_stack != NULL
- && info->type_stack->type.classdef != NULL);
-
- /* If we were ignoring this class definition because it was a
- duplicate definition, just through away whatever bytes we have
- accumulated. Leave the type on the stack. */
- if (info->type_stack->type.ignorep)
- return true;
-
- nindx = info->type_stack->type.classdef->indx;
-
- /* If we have a virtual table, we can write out the information now. */
- if (info->type_stack->type.classdef->vclass != NULL
- || info->type_stack->type.classdef->ownvptr)
- {
- if (! ieee_change_buffer (info,
- &info->type_stack->type.classdef->pmiscbuf)
- || ! ieee_write_asn (info, nindx, 'z')
- || ! ieee_write_atn65 (info, nindx, "")
- || ! ieee_write_asn (info, nindx,
- info->type_stack->type.classdef->voffset))
- return false;
- if (info->type_stack->type.classdef->ownvptr)
- {
- if (! ieee_write_atn65 (info, nindx, ""))
- return false;
- }
- else
- {
- if (! ieee_write_atn65 (info, nindx,
- info->type_stack->type.classdef->vclass))
- return false;
- }
- if (! ieee_write_asn (info, nindx, 0))
- return false;
- info->type_stack->type.classdef->pmisccount += 5;
- }
-
- /* Now that we know the number of pmisc records, we can write out
- the atn62 which starts the pmisc records, and append them to the
- C++ buffers. */
-
- if (! ieee_change_buffer (info, &info->cxx)
- || ! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_id (info, "")
- || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 62)
- || ! ieee_write_number (info, 80)
- || ! ieee_write_number (info,
- info->type_stack->type.classdef->pmisccount))
- return false;
-
- if (! ieee_append_buffer (info, &info->cxx,
- &info->type_stack->type.classdef->pmiscbuf))
- return false;
- if (! ieee_buffer_emptyp (&info->type_stack->type.classdef->refs))
- {
- if (! ieee_append_buffer (info, &info->cxx,
- &info->type_stack->type.classdef->refs))
- return false;
- }
-
- return ieee_end_struct_type (p);
-}
-
-/* Push a previously seen typedef onto the type stack. */
-
-static boolean
-ieee_typedef_type (p, name)
- PTR p;
- const char *name;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- struct ieee_name_type_hash_entry *h;
- struct ieee_name_type *nt;
-
- h = ieee_name_type_hash_lookup (&info->typedefs, name, false, false);
-
- /* h should never be NULL, since that would imply that the generic
- debugging code has asked for a typedef which it has not yet
- defined. */
- assert (h != NULL);
-
- /* We always use the most recently defined type for this name, which
- will be the first one on the list. */
-
- nt = h->types;
- if (! ieee_push_type (info, nt->type.indx, nt->type.size,
- nt->type.unsignedp, nt->type.localp))
- return false;
-
- /* Copy over any other type information we may have. */
- info->type_stack->type = nt->type;
-
- return true;
-}
-
-/* Push a tagged type onto the type stack. */
-
-static boolean
-ieee_tag_type (p, name, id, kind)
- PTR p;
- const char *name;
- unsigned int id;
- enum debug_type_kind kind;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- boolean localp;
- boolean copy;
- char ab[20];
- struct ieee_name_type_hash_entry *h;
- struct ieee_name_type *nt;
-
- if (kind == DEBUG_KIND_ENUM)
- {
- struct ieee_defined_enum *e;
-
- if (name == NULL)
- abort ();
- for (e = info->enums; e != NULL; e = e->next)
- if (e->tag != NULL && strcmp (e->tag, name) == 0)
- return ieee_push_type (info, e->indx, 0, true, false);
-
- e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
- memset (e, 0, sizeof *e);
-
- e->indx = info->type_indx;
- ++info->type_indx;
- e->tag = name;
- e->defined = false;
-
- e->next = info->enums;
- info->enums = e;
-
- return ieee_push_type (info, e->indx, 0, true, false);
- }
-
- localp = false;
-
- copy = false;
- if (name == NULL)
- {
- sprintf (ab, "__anon%u", id);
- name = ab;
- copy = true;
- }
-
- h = ieee_name_type_hash_lookup (&info->tags, name, true, copy);
- if (h == NULL)
- return false;
-
- for (nt = h->types; nt != NULL; nt = nt->next)
- {
- if (nt->id == id)
- {
- if (! ieee_push_type (info, nt->type.indx, nt->type.size,
- nt->type.unsignedp, nt->type.localp))
- return false;
- /* Copy over any other type information we may have. */
- info->type_stack->type = nt->type;
- return true;
- }
-
- if (! nt->type.localp)
- {
- /* This is a duplicate of a global type, so it must be
- local. */
- localp = true;
- }
- }
-
- nt = (struct ieee_name_type *) xmalloc (sizeof *nt);
- memset (nt, 0, sizeof *nt);
-
- nt->id = id;
- nt->type.name = h->root.string;
- nt->type.indx = info->type_indx;
- nt->type.localp = localp;
- ++info->type_indx;
- nt->kind = kind;
-
- nt->next = h->types;
- h->types = nt;
-
- if (! ieee_push_type (info, nt->type.indx, 0, false, localp))
- return false;
-
- info->type_stack->type.name = h->root.string;
-
- return true;
-}
-
-/* Output a typedef. */
-
-static boolean
-ieee_typdef (p, name)
- PTR p;
- const char *name;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- struct ieee_write_type type;
- unsigned int indx;
- boolean found;
- boolean localp;
- struct ieee_name_type_hash_entry *h;
- struct ieee_name_type *nt;
-
- type = info->type_stack->type;
- indx = type.indx;
-
- /* If this is a simple builtin type using a builtin name, we don't
- want to output the typedef itself. We also want to change the
- type index to correspond to the name being used. We recognize
- names used in stabs debugging output even if they don't exactly
- correspond to the names used for the IEEE builtin types. */
- found = false;
- if (indx <= (unsigned int) builtin_bcd_float)
- {
- switch ((enum builtin_types) indx)
- {
- default:
- break;
-
- case builtin_void:
- if (strcmp (name, "void") == 0)
- found = true;
- break;
-
- case builtin_signed_char:
- case builtin_char:
- if (strcmp (name, "signed char") == 0)
- {
- indx = (unsigned int) builtin_signed_char;
- found = true;
- }
- else if (strcmp (name, "char") == 0)
- {
- indx = (unsigned int) builtin_char;
- found = true;
- }
- break;
-
- case builtin_unsigned_char:
- if (strcmp (name, "unsigned char") == 0)
- found = true;
- break;
-
- case builtin_signed_short_int:
- case builtin_short:
- case builtin_short_int:
- case builtin_signed_short:
- if (strcmp (name, "signed short int") == 0)
- {
- indx = (unsigned int) builtin_signed_short_int;
- found = true;
- }
- else if (strcmp (name, "short") == 0)
- {
- indx = (unsigned int) builtin_short;
- found = true;
- }
- else if (strcmp (name, "short int") == 0)
- {
- indx = (unsigned int) builtin_short_int;
- found = true;
- }
- else if (strcmp (name, "signed short") == 0)
- {
- indx = (unsigned int) builtin_signed_short;
- found = true;
- }
- break;
-
- case builtin_unsigned_short_int:
- case builtin_unsigned_short:
- if (strcmp (name, "unsigned short int") == 0
- || strcmp (name, "short unsigned int") == 0)
- {
- indx = builtin_unsigned_short_int;
- found = true;
- }
- else if (strcmp (name, "unsigned short") == 0)
- {
- indx = builtin_unsigned_short;
- found = true;
- }
- break;
-
- case builtin_signed_long:
- case builtin_int: /* FIXME: Size depends upon architecture. */
- case builtin_long:
- if (strcmp (name, "signed long") == 0)
- {
- indx = builtin_signed_long;
- found = true;
- }
- else if (strcmp (name, "int") == 0)
- {
- indx = builtin_int;
- found = true;
- }
- else if (strcmp (name, "long") == 0
- || strcmp (name, "long int") == 0)
- {
- indx = builtin_long;
- found = true;
- }
- break;
-
- case builtin_unsigned_long:
- case builtin_unsigned: /* FIXME: Size depends upon architecture. */
- case builtin_unsigned_int: /* FIXME: Like builtin_unsigned. */
- if (strcmp (name, "unsigned long") == 0
- || strcmp (name, "long unsigned int") == 0)
- {
- indx = builtin_unsigned_long;
- found = true;
- }
- else if (strcmp (name, "unsigned") == 0)
- {
- indx = builtin_unsigned;
- found = true;
- }
- else if (strcmp (name, "unsigned int") == 0)
- {
- indx = builtin_unsigned_int;
- found = true;
- }
- break;
-
- case builtin_signed_long_long:
- if (strcmp (name, "signed long long") == 0
- || strcmp (name, "long long int") == 0)
- found = true;
- break;
-
- case builtin_unsigned_long_long:
- if (strcmp (name, "unsigned long long") == 0
- || strcmp (name, "long long unsigned int") == 0)
- found = true;
- break;
-
- case builtin_float:
- if (strcmp (name, "float") == 0)
- found = true;
- break;
-
- case builtin_double:
- if (strcmp (name, "double") == 0)
- found = true;
- break;
-
- case builtin_long_double:
- if (strcmp (name, "long double") == 0)
- found = true;
- break;
-
- case builtin_long_long_double:
- if (strcmp (name, "long long double") == 0)
- found = true;
- break;
- }
-
- if (found)
- type.indx = indx;
- }
-
- h = ieee_name_type_hash_lookup (&info->typedefs, name, true, false);
- if (h == NULL)
- return false;
-
- /* See if we have already defined this type with this name. */
- localp = type.localp;
- for (nt = h->types; nt != NULL; nt = nt->next)
- {
- if (nt->id == indx)
- {
- /* If this is a global definition, then we don't need to
- do anything here. */
- if (! nt->type.localp)
- {
- ieee_pop_unused_type (info);
- return true;
- }
- }
- else
- {
- /* This is a duplicate definition, so make this one local. */
- localp = true;
- }
- }
-
- /* We need to add a new typedef for this type. */
-
- nt = (struct ieee_name_type *) xmalloc (sizeof *nt);
- memset (nt, 0, sizeof *nt);
- nt->id = indx;
- nt->type = type;
- nt->type.name = name;
- nt->type.localp = localp;
- nt->kind = DEBUG_KIND_ILLEGAL;
-
- nt->next = h->types;
- h->types = nt;
-
- if (found)
- {
- /* This is one of the builtin typedefs, so we don't need to
- actually define it. */
- ieee_pop_unused_type (info);
- return true;
- }
-
- indx = ieee_pop_type (info);
-
- if (! ieee_define_named_type (info, name, (unsigned int) -1, type.size,
- type.unsignedp, localp,
- (struct ieee_buflist *) NULL)
- || ! ieee_write_number (info, 'T')
- || ! ieee_write_number (info, indx))
- return false;
-
- /* Remove the type we just added to the type stack. This should not
- be ieee_pop_unused_type, since the type is used, we just don't
- need it now. */
- (void) ieee_pop_type (info);
-
- return true;
-}
-
-/* Output a tag for a type. We don't have to do anything here. */
-
-static boolean
-ieee_tag (p, name)
- PTR p;
- const char *name;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- /* This should not be ieee_pop_unused_type, since we want the type
- to be defined. */
- (void) ieee_pop_type (info);
- return true;
-}
-
-/* Output an integer constant. */
-
-static boolean
-ieee_int_constant (p, name, val)
- PTR p;
- const char *name;
- bfd_vma val;
-{
- /* FIXME. */
- return true;
-}
-
-/* Output a floating point constant. */
-
-static boolean
-ieee_float_constant (p, name, val)
- PTR p;
- const char *name;
- double val;
-{
- /* FIXME. */
- return true;
-}
-
-/* Output a typed constant. */
-
-static boolean
-ieee_typed_constant (p, name, val)
- PTR p;
- const char *name;
- bfd_vma val;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- /* FIXME. */
- ieee_pop_unused_type (info);
- return true;
-}
-
-/* Output a variable. */
-
-static boolean
-ieee_variable (p, name, kind, val)
- PTR p;
- const char *name;
- enum debug_var_kind kind;
- bfd_vma val;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- unsigned int name_indx;
- unsigned int size;
- boolean referencep;
- unsigned int type_indx;
- boolean asn;
- int refflag;
-
- size = info->type_stack->type.size;
- referencep = info->type_stack->type.referencep;
- type_indx = ieee_pop_type (info);
-
- assert (! ieee_buffer_emptyp (&info->vars));
- if (! ieee_change_buffer (info, &info->vars))
- return false;
-
- name_indx = info->name_indx;
- ++info->name_indx;
-
- /* Write out an NN and an ATN record for this variable. */
- if (! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, name_indx)
- || ! ieee_write_id (info, name)
- || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
- || ! ieee_write_number (info, name_indx)
- || ! ieee_write_number (info, type_indx))
- return false;
- switch (kind)
- {
- default:
- abort ();
- return false;
- case DEBUG_GLOBAL:
- if (! ieee_write_number (info, 8)
- || ! ieee_add_range (info, false, val, val + size))
- return false;
- refflag = 0;
- asn = true;
- break;
- case DEBUG_STATIC:
- if (! ieee_write_number (info, 3)
- || ! ieee_add_range (info, false, val, val + size))
- return false;
- refflag = 1;
- asn = true;
- break;
- case DEBUG_LOCAL_STATIC:
- if (! ieee_write_number (info, 3)
- || ! ieee_add_range (info, false, val, val + size))
- return false;
- refflag = 2;
- asn = true;
- break;
- case DEBUG_LOCAL:
- if (! ieee_write_number (info, 1)
- || ! ieee_write_number (info, val))
- return false;
- refflag = 2;
- asn = false;
- break;
- case DEBUG_REGISTER:
- if (! ieee_write_number (info, 2)
- || ! ieee_write_number (info,
- ieee_genreg_to_regno (info->abfd, val)))
- return false;
- refflag = 2;
- asn = false;
- break;
- }
-
- if (asn)
- {
- if (! ieee_write_asn (info, name_indx, val))
- return false;
- }
-
- /* If this is really a reference type, then we just output it with
- pointer type, and must now output a C++ record indicating that it
- is really reference type. */
- if (referencep)
- {
- unsigned int nindx;
-
- nindx = info->name_indx;
- ++info->name_indx;
-
- /* If this is a global variable, we want to output the misc
- record in the C++ misc record block. Otherwise, we want to
- output it just after the variable definition, which is where
- the current buffer is. */
- if (refflag != 2)
- {
- if (! ieee_change_buffer (info, &info->cxx))
- return false;
- }
-
- if (! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_id (info, "")
- || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 62)
- || ! ieee_write_number (info, 80)
- || ! ieee_write_number (info, 3)
- || ! ieee_write_asn (info, nindx, 'R')
- || ! ieee_write_asn (info, nindx, refflag)
- || ! ieee_write_atn65 (info, nindx, name))
- return false;
- }
-
- return true;
-}
-
-/* Start outputting information for a function. */
-
-static boolean
-ieee_start_function (p, name, global)
- PTR p;
- const char *name;
- boolean global;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- boolean referencep;
- unsigned int retindx, typeindx;
-
- referencep = info->type_stack->type.referencep;
- retindx = ieee_pop_type (info);
-
- /* Besides recording a BB4 or BB6 block, we record the type of the
- function in the BB1 typedef block. We can't write out the full
- type until we have seen all the parameters, so we accumulate it
- in info->fntype and info->fnargs. */
- if (! ieee_buffer_emptyp (&info->fntype))
- {
- /* FIXME: This might happen someday if we support nested
- functions. */
- abort ();
- }
-
- info->fnname = name;
-
- /* An attribute of 0x40 means that the push mask is unknown. */
- if (! ieee_define_named_type (info, name, (unsigned int) -1, 0, false, true,
- &info->fntype)
- || ! ieee_write_number (info, 'x')
- || ! ieee_write_number (info, 0x40)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, retindx))
- return false;
-
- typeindx = ieee_pop_type (info);
-
- if (! ieee_init_buffer (info, &info->fnargs))
- return false;
- info->fnargcount = 0;
-
- /* If the function return value is actually a reference type, we
- must add a record indicating that. */
- if (referencep)
- {
- unsigned int nindx;
-
- nindx = info->name_indx;
- ++info->name_indx;
- if (! ieee_change_buffer (info, &info->cxx)
- || ! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_id (info, "")
- || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 62)
- || ! ieee_write_number (info, 80)
- || ! ieee_write_number (info, 3)
- || ! ieee_write_asn (info, nindx, 'R')
- || ! ieee_write_asn (info, nindx, global ? 0 : 1)
- || ! ieee_write_atn65 (info, nindx, name))
- return false;
- }
-
- assert (! ieee_buffer_emptyp (&info->vars));
- if (! ieee_change_buffer (info, &info->vars))
- return false;
-
- /* The address is written out as the first block. */
-
- ++info->block_depth;
-
- return (ieee_write_byte (info, (int) ieee_bb_record_enum)
- && ieee_write_byte (info, global ? 4 : 6)
- && ieee_write_number (info, 0)
- && ieee_write_id (info, name)
- && ieee_write_number (info, 0)
- && ieee_write_number (info, typeindx));
-}
-
-/* Add a function parameter. This will normally be called before the
- first block, so we postpone them until we see the block. */
-
-static boolean
-ieee_function_parameter (p, name, kind, val)
- PTR p;
- const char *name;
- enum debug_parm_kind kind;
- bfd_vma val;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
- struct ieee_pending_parm *m, **pm;
-
- assert (info->block_depth == 1);
-
- m = (struct ieee_pending_parm *) xmalloc (sizeof *m);
- memset (m, 0, sizeof *m);
-
- m->next = NULL;
- m->name = name;
- m->referencep = info->type_stack->type.referencep;
- m->type = ieee_pop_type (info);
- m->kind = kind;
- m->val = val;
-
- for (pm = &info->pending_parms; *pm != NULL; pm = &(*pm)->next)
- ;
- *pm = m;
-
- /* Add the type to the fnargs list. */
- if (! ieee_change_buffer (info, &info->fnargs)
- || ! ieee_write_number (info, m->type))
- return false;
- ++info->fnargcount;
-
- return true;
-}
-
-/* Output pending function parameters. */
-
-static boolean
-ieee_output_pending_parms (info)
- struct ieee_handle *info;
-{
- struct ieee_pending_parm *m;
- unsigned int refcount;
-
- refcount = 0;
- for (m = info->pending_parms; m != NULL; m = m->next)
- {
- enum debug_var_kind vkind;
-
- switch (m->kind)
- {
- default:
- abort ();
- return false;
- case DEBUG_PARM_STACK:
- case DEBUG_PARM_REFERENCE:
- vkind = DEBUG_LOCAL;
- break;
- case DEBUG_PARM_REG:
- case DEBUG_PARM_REF_REG:
- vkind = DEBUG_REGISTER;
- break;
- }
-
- if (! ieee_push_type (info, m->type, 0, false, false))
- return false;
- info->type_stack->type.referencep = m->referencep;
- if (m->referencep)
- ++refcount;
- if (! ieee_variable ((PTR) info, m->name, vkind, m->val))
- return false;
- }
-
- /* If there are any reference parameters, we need to output a
- miscellaneous record indicating them. */
- if (refcount > 0)
- {
- unsigned int nindx, varindx;
-
- /* FIXME: The MRI compiler outputs the demangled function name
- here, but we are outputting the mangled name. */
- nindx = info->name_indx;
- ++info->name_indx;
- if (! ieee_change_buffer (info, &info->vars)
- || ! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_id (info, "")
- || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
- || ! ieee_write_number (info, nindx)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 62)
- || ! ieee_write_number (info, 80)
- || ! ieee_write_number (info, refcount + 3)
- || ! ieee_write_asn (info, nindx, 'B')
- || ! ieee_write_atn65 (info, nindx, info->fnname)
- || ! ieee_write_asn (info, nindx, 0))
- return false;
- for (m = info->pending_parms, varindx = 1;
- m != NULL;
- m = m->next, varindx++)
- {
- if (m->referencep)
- {
- if (! ieee_write_asn (info, nindx, varindx))
- return false;
- }
- }
- }
-
- m = info->pending_parms;
- while (m != NULL)
- {
- struct ieee_pending_parm *next;
-
- next = m->next;
- free (m);
- m = next;
- }
-
- info->pending_parms = NULL;
-
- return true;
-}
-
-/* Start a block. If this is the first block, we output the address
- to finish the BB4 or BB6, and then output the function parameters. */
-
-static boolean
-ieee_start_block (p, addr)
- PTR p;
- bfd_vma addr;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- if (! ieee_change_buffer (info, &info->vars))
- return false;
-
- if (info->block_depth == 1)
- {
- if (! ieee_write_number (info, addr)
- || ! ieee_output_pending_parms (info))
- return false;
- }
- else
- {
- if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 6)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, "")
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, addr))
- return false;
- }
-
- if (! ieee_start_range (info, addr))
- return false;
-
- ++info->block_depth;
-
- return true;
-}
-
-/* End a block. */
-
-static boolean
-ieee_end_block (p, addr)
- PTR p;
- bfd_vma addr;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- /* The address we are given is the end of the block, but IEEE seems
- to want to the address of the last byte in the block, so we
- subtract one. */
- if (! ieee_change_buffer (info, &info->vars)
- || ! ieee_write_byte (info, (int) ieee_be_record_enum)
- || ! ieee_write_number (info, addr - 1))
- return false;
-
- if (! ieee_end_range (info, addr))
- return false;
-
- --info->block_depth;
-
- if (addr > info->highaddr)
- info->highaddr = addr;
-
- return true;
-}
-
-/* End a function. */
-
-static boolean
-ieee_end_function (p)
- PTR p;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- assert (info->block_depth == 1);
-
- --info->block_depth;
-
- /* Now we can finish up fntype, and add it to the typdef section.
- At this point, fntype is the 'x' type up to the argument count,
- and fnargs is the argument types. We must add the argument
- count, and we must add the level. FIXME: We don't record varargs
- functions correctly. In fact, stabs debugging does not give us
- enough information to do so. */
- if (! ieee_change_buffer (info, &info->fntype)
- || ! ieee_write_number (info, info->fnargcount)
- || ! ieee_change_buffer (info, &info->fnargs)
- || ! ieee_write_number (info, 0))
- return false;
-
- /* Make sure the typdef block has been started. */
- if (ieee_buffer_emptyp (&info->types))
- {
- if (! ieee_change_buffer (info, &info->types)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 1)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, info->modname))
- return false;
- }
-
- if (! ieee_append_buffer (info, &info->types, &info->fntype)
- || ! ieee_append_buffer (info, &info->types, &info->fnargs))
- return false;
-
- info->fnname = NULL;
- if (! ieee_init_buffer (info, &info->fntype)
- || ! ieee_init_buffer (info, &info->fnargs))
- return false;
- info->fnargcount = 0;
-
- return true;
-}
-
-/* Record line number information. */
-
-static boolean
-ieee_lineno (p, filename, lineno, addr)
- PTR p;
- const char *filename;
- unsigned long lineno;
- bfd_vma addr;
-{
- struct ieee_handle *info = (struct ieee_handle *) p;
-
- assert (info->filename != NULL);
-
- /* The HP simulator seems to get confused when more than one line is
- listed for the same address, at least if they are in different
- files. We handle this by always listing the last line for a
- given address, since that seems to be the one that gdb uses. */
- if (info->pending_lineno_filename != NULL
- && addr != info->pending_lineno_addr)
- {
- /* Make sure we have a line number block. */
- if (! ieee_buffer_emptyp (&info->linenos))
- {
- if (! ieee_change_buffer (info, &info->linenos))
- return false;
- }
- else
- {
- info->lineno_name_indx = info->name_indx;
- ++info->name_indx;
- if (! ieee_change_buffer (info, &info->linenos)
- || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 5)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, info->filename)
- || ! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, info->lineno_name_indx)
- || ! ieee_write_id (info, ""))
- return false;
- info->lineno_filename = info->filename;
- }
-
- if (strcmp (info->pending_lineno_filename, info->lineno_filename) != 0)
- {
- if (strcmp (info->filename, info->lineno_filename) != 0)
- {
- /* We were not in the main file. Close the block for the
- included file. */
- if (! ieee_write_byte (info, (int) ieee_be_record_enum))
- return false;
- if (strcmp (info->filename, info->pending_lineno_filename) == 0)
- {
- /* We need a new NN record, and we aren't about to
- output one. */
- info->lineno_name_indx = info->name_indx;
- ++info->name_indx;
- if (! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, info->lineno_name_indx)
- || ! ieee_write_id (info, ""))
- return false;
- }
- }
- if (strcmp (info->filename, info->pending_lineno_filename) != 0)
- {
- /* We are not changing to the main file. Open a block for
- the new included file. */
- info->lineno_name_indx = info->name_indx;
- ++info->name_indx;
- if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
- || ! ieee_write_byte (info, 5)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_id (info, info->pending_lineno_filename)
- || ! ieee_write_byte (info, (int) ieee_nn_record)
- || ! ieee_write_number (info, info->lineno_name_indx)
- || ! ieee_write_id (info, ""))
- return false;
- }
- info->lineno_filename = info->pending_lineno_filename;
- }
-
- if (! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
- || ! ieee_write_number (info, info->lineno_name_indx)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_number (info, 7)
- || ! ieee_write_number (info, info->pending_lineno)
- || ! ieee_write_number (info, 0)
- || ! ieee_write_asn (info, info->lineno_name_indx,
- info->pending_lineno_addr))
- return false;
- }
-
- info->pending_lineno_filename = filename;
- info->pending_lineno = lineno;
- info->pending_lineno_addr = addr;
-
- return true;
-}
diff --git a/pstack/ieee.h b/pstack/ieee.h
deleted file mode 100644
index 56634b2819a..00000000000
--- a/pstack/ieee.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/* IEEE Standard 695-1980 "Universal Format for Object Modules" header file
- Contributed by Cygnus Support. */
-
-#define N_W_VARIABLES 8
-#define Module_Beginning 0xe0
-
-typedef struct ieee_module {
- char *processor;
- char *module_name;
-} ieee_module_begin_type;
-
-#define Address_Descriptor 0xec
-typedef struct ieee_address {
-bfd_vma number_of_bits_mau;
- bfd_vma number_of_maus_in_address;
-
- unsigned char byte_order;
-#define IEEE_LITTLE 0xcc
-#define IEEE_BIG 0xcd
-} ieee_address_descriptor_type;
-
-typedef union ieee_w_variable {
- file_ptr offset[N_W_VARIABLES];
- struct {
- file_ptr extension_record;
- file_ptr environmental_record;
- file_ptr section_part;
- file_ptr external_part;
- file_ptr debug_information_part;
- file_ptr data_part;
- file_ptr trailer_part;
- file_ptr me_record;
- } r;
-} ieee_w_variable_type;
-
-
-
-
-
-typedef enum ieee_record
-{
- ieee_number_start_enum = 0x00,
- ieee_number_end_enum=0x7f,
- ieee_number_repeat_start_enum = 0x80,
- ieee_number_repeat_end_enum = 0x88,
- ieee_number_repeat_4_enum = 0x84,
- ieee_number_repeat_3_enum = 0x83,
- ieee_number_repeat_2_enum = 0x82,
- ieee_number_repeat_1_enum = 0x81,
- ieee_module_beginning_enum = 0xe0,
- ieee_module_end_enum = 0xe1,
- ieee_extension_length_1_enum = 0xde,
- ieee_extension_length_2_enum = 0xdf,
- ieee_section_type_enum = 0xe6,
- ieee_section_alignment_enum = 0xe7,
- ieee_external_symbol_enum = 0xe8,
- ieee_comma = 0x90,
- ieee_external_reference_enum = 0xe9,
- ieee_set_current_section_enum = 0xe5,
- ieee_address_descriptor_enum = 0xec,
- ieee_load_constant_bytes_enum = 0xed,
- ieee_load_with_relocation_enum = 0xe4,
-
- ieee_variable_A_enum = 0xc1,
- ieee_variable_B_enum = 0xc2,
- ieee_variable_C_enum = 0xc3,
- ieee_variable_D_enum = 0xc4,
- ieee_variable_E_enum = 0xc5,
- ieee_variable_F_enum = 0xc6,
- ieee_variable_G_enum = 0xc7,
- ieee_variable_H_enum = 0xc8,
- ieee_variable_I_enum = 0xc9,
- ieee_variable_J_enum = 0xca,
- ieee_variable_K_enum = 0xcb,
- ieee_variable_L_enum = 0xcc,
- ieee_variable_M_enum = 0xcd,
- ieee_variable_N_enum = 0xce,
- ieee_variable_O_enum = 0xcf,
- ieee_variable_P_enum = 0xd0,
- ieee_variable_Q_enum = 0xd1,
- ieee_variable_R_enum = 0xd2,
- ieee_variable_S_enum = 0xd3,
- ieee_variable_T_enum = 0xd4,
- ieee_variable_U_enum = 0xd5,
- ieee_variable_V_enum = 0xd6,
- ieee_variable_W_enum = 0xd7,
- ieee_variable_X_enum = 0xd8,
- ieee_variable_Y_enum = 0xd9,
- ieee_variable_Z_enum = 0xda,
- ieee_function_plus_enum = 0xa5,
- ieee_function_minus_enum = 0xa6,
- ieee_function_signed_open_b_enum = 0xba,
- ieee_function_signed_close_b_enum = 0xbb,
-
- ieee_function_unsigned_open_b_enum = 0xbc,
- ieee_function_unsigned_close_b_enum = 0xbd,
-
- ieee_function_either_open_b_enum = 0xbe,
- ieee_function_either_close_b_enum = 0xbf,
- ieee_record_seperator_enum = 0xdb,
-
- ieee_e2_first_byte_enum = 0xe2,
- ieee_section_size_enum = 0xe2d3,
- ieee_physical_region_size_enum = 0xe2c1,
- ieee_region_base_address_enum = 0xe2c2,
- ieee_mau_size_enum = 0xe2c6,
- ieee_m_value_enum = 0xe2cd,
- ieee_section_base_address_enum = 0xe2cc,
- ieee_asn_record_enum = 0xe2ce,
- ieee_section_offset_enum = 0xe2d2,
- ieee_value_starting_address_enum = 0xe2c7,
- ieee_assign_value_to_variable_enum = 0xe2d7,
- ieee_set_current_pc_enum = 0xe2d0,
- ieee_value_record_enum = 0xe2c9,
- ieee_nn_record = 0xf0,
- ieee_at_record_enum = 0xf1,
- ieee_ty_record_enum = 0xf2,
- ieee_attribute_record_enum = 0xf1c9,
- ieee_atn_record_enum = 0xf1ce,
- ieee_external_reference_info_record_enum = 0xf1d8,
- ieee_weak_external_reference_enum= 0xf4,
- ieee_repeat_data_enum = 0xf7,
- ieee_bb_record_enum = 0xf8,
- ieee_be_record_enum = 0xf9
-} ieee_record_enum_type;
-
-
-typedef struct ieee_section {
- unsigned int section_index;
- unsigned int section_type;
- char *section_name;
- unsigned int parent_section_index;
- unsigned int sibling_section_index;
- unsigned int context_index;
-} ieee_section_type;
-#define IEEE_REFERENCE_BASE 11
-#define IEEE_PUBLIC_BASE 32
-#define IEEE_SECTION_NUMBER_BASE 1
diff --git a/pstack/libiberty.h b/pstack/libiberty.h
deleted file mode 100644
index ca0043d31c6..00000000000
--- a/pstack/libiberty.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/* Function declarations for libiberty.
- Written by Cygnus Support, 1994.
-
- The libiberty library provides a number of functions which are
- missing on some operating systems. We do not declare those here,
- to avoid conflicts with the system header files on operating
- systems that do support those functions. In this file we only
- declare those functions which are specific to libiberty. */
-
-#ifndef LIBIBERTY_H
-#define LIBIBERTY_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "ansidecl.h"
-
-/* Build an argument vector from a string. Allocates memory using
- malloc. Use freeargv to free the vector. */
-
-extern char **buildargv PARAMS ((char *));
-
-/* Free a vector returned by buildargv. */
-
-extern void freeargv PARAMS ((char **));
-
-/* Duplicate an argument vector. Allocates memory using malloc. Use
- freeargv to free the vector. */
-
-extern char **dupargv PARAMS ((char **));
-
-
-/* Return the last component of a path name. Note that we can't use a
- prototype here because the parameter is declared inconsistently
- across different systems, sometimes as "char *" and sometimes as
- "const char *" */
-
-#if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__)
-extern char *basename PARAMS ((const char *));
-#else
-extern char *basename ();
-#endif
-
-/* Concatenate an arbitrary number of strings, up to (char *) NULL.
- Allocates memory using xmalloc. */
-
-extern char *concat PARAMS ((const char *, ...));
-
-/* Check whether two file descriptors refer to the same file. */
-
-extern int fdmatch PARAMS ((int fd1, int fd2));
-
-/* Get the amount of time the process has run, in microseconds. */
-
-extern long get_run_time PARAMS ((void));
-
-/* Choose a temporary directory to use for scratch files. */
-
-extern char *choose_temp_base PARAMS ((void));
-
-/* Allocate memory filled with spaces. Allocates using malloc. */
-
-extern const char *spaces PARAMS ((int count));
-
-/* Return the maximum error number for which strerror will return a
- string. */
-
-extern int errno_max PARAMS ((void));
-
-/* Return the name of an errno value (e.g., strerrno (EINVAL) returns
- "EINVAL"). */
-
-extern const char *strerrno PARAMS ((int));
-
-/* Given the name of an errno value, return the value. */
-
-extern int strtoerrno PARAMS ((const char *));
-
-/* ANSI's strerror(), but more robust. */
-
-extern char *xstrerror PARAMS ((int));
-
-/* Return the maximum signal number for which strsignal will return a
- string. */
-
-extern int signo_max PARAMS ((void));
-
-/* Return a signal message string for a signal number
- (e.g., strsignal (SIGHUP) returns something like "Hangup"). */
-/* This is commented out as it can conflict with one in system headers.
- We still document its existence though. */
-
-/*extern const char *strsignal PARAMS ((int));*/
-
-/* Return the name of a signal number (e.g., strsigno (SIGHUP) returns
- "SIGHUP"). */
-
-extern const char *strsigno PARAMS ((int));
-
-/* Given the name of a signal, return its number. */
-
-extern int strtosigno PARAMS ((const char *));
-
-/* Register a function to be run by xexit. Returns 0 on success. */
-
-extern int xatexit PARAMS ((void (*fn) (void)));
-
-/* Exit, calling all the functions registered with xatexit. */
-
-#ifndef __GNUC__
-extern void xexit PARAMS ((int status));
-#else
-void xexit PARAMS ((int status)) __attribute__ ((noreturn));
-#endif
-
-/* Set the program name used by xmalloc. */
-
-extern void xmalloc_set_program_name PARAMS ((const char *));
-
-/* Allocate memory without fail. If malloc fails, this will print a
- message to stderr (using the name set by xmalloc_set_program_name,
- if any) and then call xexit. */
-
-#ifdef ANSI_PROTOTYPES
-/* Get a definition for size_t. */
-#include <stddef.h>
-#endif
-extern PTR xmalloc PARAMS ((size_t));
-
-/* Reallocate memory without fail. This works like xmalloc.
-
- FIXME: We do not declare the parameter types for the same reason as
- xmalloc. */
-
-extern PTR xrealloc PARAMS ((PTR, size_t));
-
-/* Allocate memory without fail and set it to zero. This works like
- xmalloc. */
-
-extern PTR xcalloc PARAMS ((size_t, size_t));
-
-/* Copy a string into a memory buffer without fail. */
-
-extern char *xstrdup PARAMS ((const char *));
-
-/* hex character manipulation routines */
-
-#define _hex_array_size 256
-#define _hex_bad 99
-extern char _hex_value[_hex_array_size];
-extern void hex_init PARAMS ((void));
-#define hex_p(c) (hex_value (c) != _hex_bad)
-/* If you change this, note well: Some code relies on side effects in
- the argument being performed exactly once. */
-#define hex_value(c) (_hex_value[(unsigned char) (c)])
-
-/* Definitions used by the pexecute routine. */
-
-#define PEXECUTE_FIRST 1
-#define PEXECUTE_LAST 2
-#define PEXECUTE_ONE (PEXECUTE_FIRST + PEXECUTE_LAST)
-#define PEXECUTE_SEARCH 4
-#define PEXECUTE_VERBOSE 8
-
-/* Execute a program. */
-
-extern int pexecute PARAMS ((const char *, char * const *, const char *,
- const char *, char **, char **, int));
-
-/* Wait for pexecute to finish. */
-
-extern int pwait PARAMS ((int, int *, int));
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* ! defined (LIBIBERTY_H) */
diff --git a/pstack/linuxthreads.c b/pstack/linuxthreads.c
deleted file mode 100644
index 8624bd21782..00000000000
--- a/pstack/linuxthreads.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/* $Header$ */
-
-/*
- * LinuxThreads specific stuff.
- */
-
-#include <sys/types.h>
-
-#include <assert.h>
-#include <limits.h> /* PTHREAD_THREADS_MAX */
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <signal.h>
-#include <sched.h>
-
-#include "linuxthreads.h"
-
-#define AT_INT(intval) *((int32_t*)(intval))
-
-/*
- * Internal LinuxThreads variables.
- * Official interface exposed to GDB.
- */
-#if 1
-extern volatile int __pthread_threads_debug;
-extern volatile char __pthread_handles;
-extern char __pthread_initial_thread;
-/*extern volatile Elf32_Sym* __pthread_manager_thread;*/
-extern const int __pthread_sizeof_handle;
-extern const int __pthread_offsetof_descr;
-extern const int __pthread_offsetof_pid;
-extern volatile int __pthread_handles_num;
-#endif /* 0 */
-
-/*
- * Notify others.
- */
-int
-linuxthreads_notify_others( const int signotify)
-{
- const pid_t mypid = getpid();
- //const pthread_t mytid = pthread_self();
- int i;
- int threadcount = 0;
- int threads[PTHREAD_THREADS_MAX];
- int pid;
-
- TRACE_FPRINTF((stderr, "theadcount:%d\n", __pthread_handles_num));
- if (__pthread_handles_num==2) {
- /* no threads beside the initial thread */
- return 0;
- }
- /*assert(maxthreads>=3);
- assert(maxthreads>=__pthread_handles_num+2);*/
-
- // take the initial thread with us
- pid = AT_INT(&__pthread_initial_thread + __pthread_offsetof_pid);
- if (pid!=mypid && pid!=0)
- threads[threadcount++] = pid;
- // don't know why, but always handles[0]==handles[1]
- for (i=1; i<__pthread_handles_num; ++i) {
- const int descr = AT_INT(&__pthread_handles+i*__pthread_sizeof_handle+__pthread_offsetof_descr);
- assert(descr!=0);
- pid = AT_INT(descr+__pthread_offsetof_pid);
- if (pid!=mypid && pid!=0)
- threads[threadcount++] = pid;
- }
- /* TRACE_FPRINTF((stderr, "Stopping threads...")); */
- //for (i=0; i<threadcount; ++i) {
- // /* TRACE_FPRINTF((stderr, "%d ", threads[i])); */
- // fflush(stdout);
- // kill(threads[i], SIGSTOP); /* Tell thread to stop */
- //}
- /* TRACE_FPRINTF((stderr, " done!\n")); */
- for (i=0; i<threadcount; ++i) {
- TRACE_FPRINTF((stderr, "--- NOTIFYING %d\n", threads[i]));
- kill(threads[i], signotify); /* Tell to print stack trace */
- /* TRACE_FPRINTF((stderr, "--- WAITING FOR %d\n", threads[i])); */
- /*pause(); Wait for confirmation. */
- }
- for (i=0; i<threadcount; ++i)
- sched_yield();
- for (i=0; i<threadcount; ++i) {
- TRACE_FPRINTF((stderr, "--- KILLING %d\n", threads[i]));
- kill(threads[i], SIGKILL); /* Tell thread die :) */
- }
- return __pthread_handles_num;
-}
-
diff --git a/pstack/linuxthreads.h b/pstack/linuxthreads.h
deleted file mode 100644
index f5eb0f652d8..00000000000
--- a/pstack/linuxthreads.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* $Header$ */
-
-/*
- * LinuxThreads specific stuff.
- */
-
-#ifndef pstack_linuxthreads_h_
-#define pstack_linuxthreads_h_
-
-#include <pthread.h>
-#include "pstacktrace.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Tell other threads to dump stacks...
- */
-int
-linuxthreads_notify_others( const int signotify);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* pstack_linuxthreads_h_ */
-
diff --git a/pstack/pstack.c b/pstack/pstack.c
deleted file mode 100644
index 4cdd80d68b5..00000000000
--- a/pstack/pstack.c
+++ /dev/null
@@ -1,2746 +0,0 @@
-/*
- pstack.c -- asynchronous stack trace of a running process
- Copyright (c) 1999 Ross Thompson
- Author: Ross Thompson <ross@whatsis.com>
- Critical bug fix: Tim Waugh
-*/
-
-/*
- This file is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-/* RESTRICTIONS:
-
- pstack currently works only on Linux, only on an x86 machine running
- 32 bit ELF binaries (64 bit not supported). Also, for symbolic
- information, you need to use a GNU compiler to generate your
- program, and you can't strip symbols from the binaries. For thread
- information to be dumped, you have to use the debug-aware version
- of libpthread.so. (To check, run 'nm' on your libpthread.so, and
- make sure that the symbol "__pthread_threads_debug" is defined.)
-
- The details of pulling stuff out of ELF files and running through
- program images is very platform specific, and I don't want to
- try to support modes or machine types I can't test in or on.
- If someone wants to generalize this to other architectures, I would
- be happy to help and coordinate the activity. Please send me whatever
- changes you make to support these machines, so that I can own the
- central font of all truth (at least as regards this program).
-
- Thanks
-*/
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/ptrace.h>
-#include <asm/ptrace.h>
-
-#include <assert.h>
-#include <fcntl.h>
-#include <link.h>
-#include <malloc.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <signal.h>
-#include <pthread.h>
-#include <limits.h> /* PTHREAD_THREADS_MAX */
-
-
-#include <bfd.h>
-
-#include "libiberty.h"
-
-#include "pstack.h" /* just one function */
-#include "budbg.h" /* binutils stuff related to debugging symbols. */
-#include "bucomm.h" /* some common stuff */
-#include "debug.h" /* and more binutils stuff... */
-#include "budbg.h"
-#include "linuxthreads.h" /* LinuxThreads specific stuff... */
-
-
-/*
- * fprintf for file descriptors :) NOTE: we have to use fixed-size buffer :)(
- * due to malloc's unavalaibility.
- */
-int
-fdprintf( int fd,
- const char* fmt,...)
-{
- char xbuf[2048];// FIXME: enough?
- va_list ap;
- int r;
- if (fd<0)
- return -1;
- va_start(ap, fmt);
- r = vsnprintf(xbuf, sizeof(xbuf), fmt, ap);
- va_end(ap);
- return write(fd, xbuf, r);
-}
-
-int
-fdputc( char c,
- int fd)
-{
- if (fd<0)
- return -1;
- return write(fd, &c, sizeof(c));
-}
-
-int
-fdputs( const char* s,
- int fd)
-{
- if (fd<0)
- return -1;
- return write(fd, s, strlen(s));
-}
-
-/*
- * Use this function to open log file.
- * Flags: truncate on opening.
- */
-static const char* path_format = "stack-trace-on-segv-%d.txt";
-static int
-open_log_file( const pthread_t tid,
- const pid_t pid)
-{
- char fname[PATH_MAX];
- int r;
- snprintf(fname, sizeof(fname), path_format, tid, pid);
- r = open(fname, O_WRONLY|O_CREAT|O_TRUNC,
- S_IRUSR|S_IWUSR);
- if (r<0)
- perror("open");
- return r;
-}
-/*
- * Add additional debugging information for functions.
- */
-
-/*
- * Lineno
- */
-typedef struct {
- int lineno;
- bfd_vma addr;
-} debug_lineno_t;
-
-/*
- * Block - a {} pair.
- */
-typedef struct debug_block_st {
- bfd_vma begin_addr; /* where did it start */
- bfd_vma end_addr; /* where did it end */
- struct debug_block_st* parent;
- struct debug_block_st* childs;
- int childs_count;
-} debug_block_t;
-
-/*
- * Function parameter.
- */
-typedef struct {
- bfd_vma offset; /* Offset in the stack */
- const char* name; /* And name. */
-} debug_parameter_t;
-
-/*
- * Extra information about functions.
- */
-typedef struct {
- asymbol* symbol; /* mangled function name, addr */
- debug_lineno_t* lines;
- int lines_count;
- int max_lines_count;
- const char* name;
- const char* filename;/* a file name it occured in... */
- debug_block_t* block; /* each function has a block, or not, you know */
- debug_parameter_t* argv; /* argument types. */
- int argc;
- int max_argc;
-} debug_function_t;
-
-/* This is the structure we use as a handle for these routines. */
-struct pr_handle
-{
- /* File to print information to. */
- FILE *f;
- /* Current indentation level. */
- unsigned int indent;
- /* Type stack. */
- struct pr_stack *stack;
- /* Parameter number we are about to output. */
- int parameter;
- debug_block_t* block; /* current block */
- debug_function_t* function; /* current function */
- debug_function_t* functions; /* all functions */
- int functions_size; /* current size */
- int functions_maxsize; /* maximum size */
-};
-
-/* The type stack. */
-
-struct pr_stack
-{
- /* Next element on the stack. */
- struct pr_stack *next;
- /* This element. */
- char *type;
- /* Current visibility of fields if this is a class. */
- enum debug_visibility visibility;
- /* Name of the current method we are handling. */
- const char *method;
-};
-
-static void indent PARAMS ((struct pr_handle *));
-static boolean push_type PARAMS ((struct pr_handle *, const char *));
-static boolean prepend_type PARAMS ((struct pr_handle *, const char *));
-static boolean append_type PARAMS ((struct pr_handle *, const char *));
-static boolean substitute_type PARAMS ((struct pr_handle *, const char *));
-static boolean indent_type PARAMS ((struct pr_handle *));
-static char *pop_type PARAMS ((struct pr_handle *));
-static void print_vma PARAMS ((bfd_vma, char *, boolean, boolean));
-static boolean pr_fix_visibility
- PARAMS ((struct pr_handle *, enum debug_visibility));
-
-static boolean pr_start_compilation_unit PARAMS ((PTR, const char *));
-static boolean pr_start_source PARAMS ((PTR, const char *));
-static boolean pr_empty_type PARAMS ((PTR));
-static boolean pr_void_type PARAMS ((PTR));
-static boolean pr_int_type PARAMS ((PTR, unsigned int, boolean));
-static boolean pr_float_type PARAMS ((PTR, unsigned int));
-static boolean pr_complex_type PARAMS ((PTR, unsigned int));
-static boolean pr_bool_type PARAMS ((PTR, unsigned int));
-static boolean pr_enum_type
- PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
-static boolean pr_pointer_type PARAMS ((PTR));
-static boolean pr_function_type PARAMS ((PTR, int, boolean));
-static boolean pr_reference_type PARAMS ((PTR));
-static boolean pr_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
-static boolean pr_array_type
- PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean));
-static boolean pr_set_type PARAMS ((PTR, boolean));
-static boolean pr_offset_type PARAMS ((PTR));
-static boolean pr_method_type PARAMS ((PTR, boolean, int, boolean));
-static boolean pr_const_type PARAMS ((PTR));
-static boolean pr_volatile_type PARAMS ((PTR));
-static boolean pr_start_struct_type
- PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int));
-static boolean pr_struct_field
- PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
-static boolean pr_end_struct_type PARAMS ((PTR));
-static boolean pr_start_class_type
- PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean,
- boolean));
-static boolean pr_class_static_member
- PARAMS ((PTR, const char *, const char *, enum debug_visibility));
-static boolean pr_class_baseclass
- PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility));
-static boolean pr_class_start_method PARAMS ((PTR, const char *));
-static boolean pr_class_method_variant
- PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean,
- bfd_vma, boolean));
-static boolean pr_class_static_method_variant
- PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean));
-static boolean pr_class_end_method PARAMS ((PTR));
-static boolean pr_end_class_type PARAMS ((PTR));
-static boolean pr_typedef_type PARAMS ((PTR, const char *));
-static boolean pr_tag_type
- PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind));
-static boolean pr_typdef PARAMS ((PTR, const char *));
-static boolean pr_tag PARAMS ((PTR, const char *));
-static boolean pr_int_constant PARAMS ((PTR, const char *, bfd_vma));
-static boolean pr_float_constant PARAMS ((PTR, const char *, double));
-static boolean pr_typed_constant PARAMS ((PTR, const char *, bfd_vma));
-static boolean pr_variable
- PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma));
-static boolean pr_start_function PARAMS ((PTR, const char *, boolean));
-static boolean pr_function_parameter
- PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
-static boolean pr_start_block PARAMS ((PTR, bfd_vma));
-static boolean pr_end_block PARAMS ((PTR, bfd_vma));
-static boolean pr_end_function PARAMS ((PTR));
-static boolean pr_lineno PARAMS ((PTR, const char *, unsigned long, bfd_vma));
-
-static const struct debug_write_fns pr_fns =
-{
- pr_start_compilation_unit,
- pr_start_source,
- pr_empty_type,
- pr_void_type,
- pr_int_type,
- pr_float_type,
- pr_complex_type,
- pr_bool_type,
- pr_enum_type,
- pr_pointer_type,
- pr_function_type,
- pr_reference_type,
- pr_range_type,
- pr_array_type,
- pr_set_type,
- pr_offset_type,
- pr_method_type,
- pr_const_type,
- pr_volatile_type,
- pr_start_struct_type,
- pr_struct_field,
- pr_end_struct_type,
- pr_start_class_type,
- pr_class_static_member,
- pr_class_baseclass,
- pr_class_start_method,
- pr_class_method_variant,
- pr_class_static_method_variant,
- pr_class_end_method,
- pr_end_class_type,
- pr_typedef_type,
- pr_tag_type,
- pr_typdef,
- pr_tag,
- pr_int_constant,
- pr_float_constant,
- pr_typed_constant,
- pr_variable,
- pr_start_function,
- pr_function_parameter,
- pr_start_block,
- pr_end_block,
- pr_end_function,
- pr_lineno
-};
-
-
-/* Indent to the current indentation level. */
-
-static void
-indent (info)
- struct pr_handle *info;
-{
- unsigned int i;
-
- for (i = 0; i < info->indent; i++)
- TRACE_PUTC ((' ', info->f));
-}
-
-/* Push a type on the type stack. */
-
-static boolean
-push_type (info, type)
- struct pr_handle *info;
- const char *type;
-{
- struct pr_stack *n;
-
- if (type == NULL)
- return false;
-
- n = (struct pr_stack *) xmalloc (sizeof *n);
- memset (n, 0, sizeof *n);
-
- n->type = xstrdup (type);
- n->visibility = DEBUG_VISIBILITY_IGNORE;
- n->method = NULL;
- n->next = info->stack;
- info->stack = n;
-
- return true;
-}
-
-/* Prepend a string onto the type on the top of the type stack. */
-
-static boolean
-prepend_type (info, s)
- struct pr_handle *info;
- const char *s;
-{
- char *n;
-
- assert (info->stack != NULL);
-
- n = (char *) xmalloc (strlen (s) + strlen (info->stack->type) + 1);
- sprintf (n, "%s%s", s, info->stack->type);
- free (info->stack->type);
- info->stack->type = n;
-
- return true;
-}
-
-/* Append a string to the type on the top of the type stack. */
-
-static boolean
-append_type (info, s)
- struct pr_handle *info;
- const char *s;
-{
- unsigned int len;
-
- if (s == NULL)
- return false;
-
- assert (info->stack != NULL);
-
- len = strlen (info->stack->type);
- info->stack->type = (char *) xrealloc (info->stack->type,
- len + strlen (s) + 1);
- strcpy (info->stack->type + len, s);
-
- return true;
-}
-
-/* We use an underscore to indicate where the name should go in a type
- string. This function substitutes a string for the underscore. If
- there is no underscore, the name follows the type. */
-
-static boolean
-substitute_type (info, s)
- struct pr_handle *info;
- const char *s;
-{
- char *u;
-
- assert (info->stack != NULL);
-
- u = strchr (info->stack->type, '|');
- if (u != NULL)
- {
- char *n;
-
- n = (char *) xmalloc (strlen (info->stack->type) + strlen (s));
-
- memcpy (n, info->stack->type, u - info->stack->type);
- strcpy (n + (u - info->stack->type), s);
- strcat (n, u + 1);
-
- free (info->stack->type);
- info->stack->type = n;
-
- return true;
- }
-
- if (strchr (s, '|') != NULL
- && (strchr (info->stack->type, '{') != NULL
- || strchr (info->stack->type, '(') != NULL))
- {
- if (! prepend_type (info, "(")
- || ! append_type (info, ")"))
- return false;
- }
-
- if (*s == '\0')
- return true;
-
- return (append_type (info, " ")
- && append_type (info, s));
-}
-
-/* Indent the type at the top of the stack by appending spaces. */
-
-static boolean
-indent_type (info)
- struct pr_handle *info;
-{
- unsigned int i;
-
- for (i = 0; i < info->indent; i++)
- {
- if (! append_type (info, " "))
- return false;
- }
-
- return true;
-}
-
-/* Pop a type from the type stack. */
-
-static char *
-pop_type (info)
- struct pr_handle *info;
-{
- struct pr_stack *o;
- char *ret;
-
- assert (info->stack != NULL);
-
- o = info->stack;
- info->stack = o->next;
- ret = o->type;
- free (o);
-
- return ret;
-}
-
-/* Print a VMA value into a string. */
-
-static void
-print_vma (vma, buf, unsignedp, hexp)
- bfd_vma vma;
- char *buf;
- boolean unsignedp;
- boolean hexp;
-{
- if (sizeof (vma) <= sizeof (unsigned long))
- {
- if (hexp)
- sprintf (buf, "0x%lx", (unsigned long) vma);
- else if (unsignedp)
- sprintf (buf, "%lu", (unsigned long) vma);
- else
- sprintf (buf, "%ld", (long) vma);
- }
- else
- {
- buf[0] = '0';
- buf[1] = 'x';
- sprintf_vma (buf + 2, vma);
- }
-}
-
-/* Start a new compilation unit. */
-
-static boolean
-pr_start_compilation_unit (p, filename)
- PTR p;
- const char *filename;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- assert (info->indent == 0);
-/*
- TRACE_FPRINTF( (info->f, "%s:\n", filename));
-*/
- return true;
-}
-
-/* Start a source file within a compilation unit. */
-
-static boolean
-pr_start_source (p, filename)
- PTR p;
- const char *filename;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- assert (info->indent == 0);
-/*
- TRACE_FPRINTF( (info->f, " %s:\n", filename));
-*/
- return true;
-}
-
-/* Push an empty type onto the type stack. */
-
-static boolean
-pr_empty_type (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- return push_type (info, "<undefined>");
-}
-
-/* Push a void type onto the type stack. */
-
-static boolean
-pr_void_type (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- return push_type (info, "void");
-}
-
-/* Push an integer type onto the type stack. */
-
-static boolean
-pr_int_type (p, size, unsignedp)
- PTR p;
- unsigned int size;
- boolean unsignedp;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char ab[10];
-
- sprintf (ab, "%sint%d", unsignedp ? "u" : "", size * 8);
- return push_type (info, ab);
-}
-
-/* Push a floating type onto the type stack. */
-
-static boolean
-pr_float_type (p, size)
- PTR p;
- unsigned int size;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char ab[10];
-
- if (size == 4)
- return push_type (info, "float");
- else if (size == 8)
- return push_type (info, "double");
-
- sprintf (ab, "float%d", size * 8);
- return push_type (info, ab);
-}
-
-/* Push a complex type onto the type stack. */
-
-static boolean
-pr_complex_type (p, size)
- PTR p;
- unsigned int size;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- if (! pr_float_type (p, size))
- return false;
-
- return prepend_type (info, "complex ");
-}
-
-/* Push a boolean type onto the type stack. */
-
-static boolean
-pr_bool_type (p, size)
- PTR p;
- unsigned int size;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char ab[10];
-
- sprintf (ab, "bool%d", size * 8);
-
- return push_type (info, ab);
-}
-
-/* Push an enum type onto the type stack. */
-
-static boolean
-pr_enum_type (p, tag, names, values)
- PTR p;
- const char *tag;
- const char **names;
- bfd_signed_vma *values;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- unsigned int i;
- bfd_signed_vma val;
-
- if (! push_type (info, "enum "))
- return false;
- if (tag != NULL)
- {
- if (! append_type (info, tag)
- || ! append_type (info, " "))
- return false;
- }
- if (! append_type (info, "{ "))
- return false;
-
- if (names == NULL)
- {
- if (! append_type (info, "/* undefined */"))
- return false;
- }
- else
- {
- val = 0;
- for (i = 0; names[i] != NULL; i++)
- {
- if (i > 0)
- {
- if (! append_type (info, ", "))
- return false;
- }
-
- if (! append_type (info, names[i]))
- return false;
-
- if (values[i] != val)
- {
- char ab[20];
-
- print_vma (values[i], ab, false, false);
- if (! append_type (info, " = ")
- || ! append_type (info, ab))
- return false;
- val = values[i];
- }
-
- ++val;
- }
- }
-
- return append_type (info, " }");
-}
-
-/* Turn the top type on the stack into a pointer. */
-
-static boolean
-pr_pointer_type (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *s;
-
- assert (info->stack != NULL);
-
- s = strchr (info->stack->type, '|');
- if (s != NULL && s[1] == '[')
- return substitute_type (info, "(*|)");
- return substitute_type (info, "*|");
-}
-
-/* Turn the top type on the stack into a function returning that type. */
-
-static boolean
-pr_function_type (p, argcount, varargs)
- PTR p;
- int argcount;
- boolean varargs;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char **arg_types;
- unsigned int len;
- char *s;
-
- assert (info->stack != NULL);
-
- len = 10;
-
- if (argcount <= 0)
- {
- arg_types = NULL;
- len += 15;
- }
- else
- {
- int i;
-
- arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
- for (i = argcount - 1; i >= 0; i--)
- {
- if (! substitute_type (info, ""))
- return false;
- arg_types[i] = pop_type (info);
- if (arg_types[i] == NULL)
- return false;
- len += strlen (arg_types[i]) + 2;
- }
- if (varargs)
- len += 5;
- }
-
- /* Now the return type is on the top of the stack. */
-
- s = (char *) xmalloc (len);
- strcpy (s, "(|) (");
-
- if (argcount < 0)
- {
-#if 0
- /* Turn off unknown arguments. */
- strcat (s, "/* unknown */");
-#endif
- }
- else
- {
- int i;
-
- for (i = 0; i < argcount; i++)
- {
- if (i > 0)
- strcat (s, ", ");
- strcat (s, arg_types[i]);
- }
- if (varargs)
- {
- if (i > 0)
- strcat (s, ", ");
- strcat (s, "...");
- }
- if (argcount > 0)
- free (arg_types);
- }
-
- strcat (s, ")");
-
- if (! substitute_type (info, s))
- return false;
-
- free (s);
-
- return true;
-}
-
-/* Turn the top type on the stack into a reference to that type. */
-
-static boolean
-pr_reference_type (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- assert (info->stack != NULL);
-
- return substitute_type (info, "&|");
-}
-
-/* Make a range type. */
-
-static boolean
-pr_range_type (p, lower, upper)
- PTR p;
- bfd_signed_vma lower;
- bfd_signed_vma upper;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char abl[20], abu[20];
-
- assert (info->stack != NULL);
-
- if (! substitute_type (info, ""))
- return false;
-
- print_vma (lower, abl, false, false);
- print_vma (upper, abu, false, false);
-
- return (prepend_type (info, "range (")
- && append_type (info, "):")
- && append_type (info, abl)
- && append_type (info, ":")
- && append_type (info, abu));
-}
-
-/* Make an array type. */
-
-/*ARGSUSED*/
-static boolean
-pr_array_type (p, lower, upper, stringp)
- PTR p;
- bfd_signed_vma lower;
- bfd_signed_vma upper;
- boolean stringp;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *range_type;
- char abl[20], abu[20], ab[50];
-
- range_type = pop_type (info);
- if (range_type == NULL)
- return false;
-
- if (lower == 0)
- {
- if (upper == -1)
- sprintf (ab, "|[]");
- else
- {
- print_vma (upper + 1, abu, false, false);
- sprintf (ab, "|[%s]", abu);
- }
- }
- else
- {
- print_vma (lower, abl, false, false);
- print_vma (upper, abu, false, false);
- sprintf (ab, "|[%s:%s]", abl, abu);
- }
-
- if (! substitute_type (info, ab))
- return false;
-
- if (strcmp (range_type, "int") != 0)
- {
- if (! append_type (info, ":")
- || ! append_type (info, range_type))
- return false;
- }
-
- if (stringp)
- {
- if (! append_type (info, " /* string */"))
- return false;
- }
-
- return true;
-}
-
-/* Make a set type. */
-
-/*ARGSUSED*/
-static boolean
-pr_set_type (p, bitstringp)
- PTR p;
- boolean bitstringp;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- if (! substitute_type (info, ""))
- return false;
-
- if (! prepend_type (info, "set { ")
- || ! append_type (info, " }"))
- return false;
-
- if (bitstringp)
- {
- if (! append_type (info, "/* bitstring */"))
- return false;
- }
-
- return true;
-}
-
-/* Make an offset type. */
-
-static boolean
-pr_offset_type (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *t;
-
- if (! substitute_type (info, ""))
- return false;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-
- return (substitute_type (info, "")
- && prepend_type (info, " ")
- && prepend_type (info, t)
- && append_type (info, "::|"));
-}
-
-/* Make a method type. */
-
-static boolean
-pr_method_type (p, domain, argcount, varargs)
- PTR p;
- boolean domain;
- int argcount;
- boolean varargs;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- unsigned int len;
- char *domain_type;
- char **arg_types;
- char *s;
-
- len = 10;
-
- if (! domain)
- domain_type = NULL;
- else
- {
- if (! substitute_type (info, ""))
- return false;
- domain_type = pop_type (info);
- if (domain_type == NULL)
- return false;
- if (strncmp (domain_type, "class ", sizeof "class " - 1) == 0
- && strchr (domain_type + sizeof "class " - 1, ' ') == NULL)
- domain_type += sizeof "class " - 1;
- else if (strncmp (domain_type, "union class ",
- sizeof "union class ") == 0
- && (strchr (domain_type + sizeof "union class " - 1, ' ')
- == NULL))
- domain_type += sizeof "union class " - 1;
- len += strlen (domain_type);
- }
-
- if (argcount <= 0)
- {
- arg_types = NULL;
- len += 15;
- }
- else
- {
- int i;
-
- arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
- for (i = argcount - 1; i >= 0; i--)
- {
- if (! substitute_type (info, ""))
- return false;
- arg_types[i] = pop_type (info);
- if (arg_types[i] == NULL)
- return false;
- len += strlen (arg_types[i]) + 2;
- }
- if (varargs)
- len += 5;
- }
-
- /* Now the return type is on the top of the stack. */
-
- s = (char *) xmalloc (len);
- if (! domain)
- *s = '\0';
- else
- strcpy (s, domain_type);
- strcat (s, "::| (");
-
- if (argcount < 0)
- strcat (s, "/* unknown */");
- else
- {
- int i;
-
- for (i = 0; i < argcount; i++)
- {
- if (i > 0)
- strcat (s, ", ");
- strcat (s, arg_types[i]);
- }
- if (varargs)
- {
- if (i > 0)
- strcat (s, ", ");
- strcat (s, "...");
- }
- if (argcount > 0)
- free (arg_types);
- }
-
- strcat (s, ")");
-
- if (! substitute_type (info, s))
- return false;
-
- free (s);
-
- return true;
-}
-
-/* Make a const qualified type. */
-
-static boolean
-pr_const_type (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- return substitute_type (info, "const |");
-}
-
-/* Make a volatile qualified type. */
-
-static boolean
-pr_volatile_type (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- return substitute_type (info, "volatile |");
-}
-
-/* Start accumulating a struct type. */
-
-static boolean
-pr_start_struct_type (p, tag, id, structp, size)
- PTR p;
- const char *tag;
- unsigned int id;
- boolean structp;
- unsigned int size;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- info->indent += 2;
-
- if (! push_type (info, structp ? "struct " : "union "))
- return false;
- if (tag != NULL)
- {
- if (! append_type (info, tag))
- return false;
- }
- else
- {
- char idbuf[20];
-
- sprintf (idbuf, "%%anon%u", id);
- if (! append_type (info, idbuf))
- return false;
- }
-
- if (! append_type (info, " {"))
- return false;
- if (size != 0 || tag != NULL)
- {
- char ab[30];
-
- if (! append_type (info, " /*"))
- return false;
-
- if (size != 0)
- {
- sprintf (ab, " size %u", size);
- if (! append_type (info, ab))
- return false;
- }
- if (tag != NULL)
- {
- sprintf (ab, " id %u", id);
- if (! append_type (info, ab))
- return false;
- }
- if (! append_type (info, " */"))
- return false;
- }
- if (! append_type (info, "\n"))
- return false;
-
- info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;
-
- return indent_type (info);
-}
-
-/* Output the visibility of a field in a struct. */
-
-static boolean
-pr_fix_visibility (info, visibility)
- struct pr_handle *info;
- enum debug_visibility visibility;
-{
- const char *s;
- char *t;
- unsigned int len;
-
- assert (info->stack != NULL);
-
- if (info->stack->visibility == visibility)
- return true;
-
- assert (info->stack->visibility != DEBUG_VISIBILITY_IGNORE);
-
- switch (visibility)
- {
- case DEBUG_VISIBILITY_PUBLIC:
- s = "public";
- break;
- case DEBUG_VISIBILITY_PRIVATE:
- s = "private";
- break;
- case DEBUG_VISIBILITY_PROTECTED:
- s = "protected";
- break;
- case DEBUG_VISIBILITY_IGNORE:
- s = "/* ignore */";
- break;
- default:
- abort ();
- return false;
- }
-
- /* Trim off a trailing space in the struct string, to make the
- output look a bit better, then stick on the visibility string. */
-
- t = info->stack->type;
- len = strlen (t);
- assert (t[len - 1] == ' ');
- t[len - 1] = '\0';
-
- if (! append_type (info, s)
- || ! append_type (info, ":\n")
- || ! indent_type (info))
- return false;
-
- info->stack->visibility = visibility;
-
- return true;
-}
-
-/* Add a field to a struct type. */
-
-static boolean
-pr_struct_field (p, name, bitpos, bitsize, visibility)
- PTR p;
- const char *name;
- bfd_vma bitpos;
- bfd_vma bitsize;
- enum debug_visibility visibility;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char ab[20];
- char *t;
-
- if (! substitute_type (info, name))
- return false;
-
- if (! append_type (info, "; /* "))
- return false;
-
- if (bitsize != 0)
- {
- print_vma (bitsize, ab, true, false);
- if (! append_type (info, "bitsize ")
- || ! append_type (info, ab)
- || ! append_type (info, ", "))
- return false;
- }
-
- print_vma (bitpos, ab, true, false);
- if (! append_type (info, "bitpos ")
- || ! append_type (info, ab)
- || ! append_type (info, " */\n")
- || ! indent_type (info))
- return false;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-
- if (! pr_fix_visibility (info, visibility))
- return false;
-
- return append_type (info, t);
-}
-
-/* Finish a struct type. */
-
-static boolean
-pr_end_struct_type (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *s;
-
- assert (info->stack != NULL);
- assert (info->indent >= 2);
-
- info->indent -= 2;
-
- /* Change the trailing indentation to have a close brace. */
- s = info->stack->type + strlen (info->stack->type) - 2;
- assert (s[0] == ' ' && s[1] == ' ' && s[2] == '\0');
-
- *s++ = '}';
- *s = '\0';
-
- return true;
-}
-
-/* Start a class type. */
-
-static boolean
-pr_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
- PTR p;
- const char *tag;
- unsigned int id;
- boolean structp;
- unsigned int size;
- boolean vptr;
- boolean ownvptr;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *tv = NULL;
-
- info->indent += 2;
-
- if (vptr && ! ownvptr)
- {
- tv = pop_type (info);
- if (tv == NULL)
- return false;
- }
-
- if (! push_type (info, structp ? "class " : "union class "))
- return false;
- if (tag != NULL)
- {
- if (! append_type (info, tag))
- return false;
- }
- else
- {
- char idbuf[20];
-
- sprintf (idbuf, "%%anon%u", id);
- if (! append_type (info, idbuf))
- return false;
- }
-
- if (! append_type (info, " {"))
- return false;
- if (size != 0 || vptr || ownvptr || tag != NULL)
- {
- if (! append_type (info, " /*"))
- return false;
-
- if (size != 0)
- {
- char ab[20];
-
- sprintf (ab, "%u", size);
- if (! append_type (info, " size ")
- || ! append_type (info, ab))
- return false;
- }
-
- if (vptr)
- {
- if (! append_type (info, " vtable "))
- return false;
- if (ownvptr)
- {
- if (! append_type (info, "self "))
- return false;
- }
- else
- {
- if (! append_type (info, tv)
- || ! append_type (info, " "))
- return false;
- }
- }
-
- if (tag != NULL)
- {
- char ab[30];
-
- sprintf (ab, " id %u", id);
- if (! append_type (info, ab))
- return false;
- }
-
- if (! append_type (info, " */"))
- return false;
- }
-
- info->stack->visibility = DEBUG_VISIBILITY_PRIVATE;
-
- return (append_type (info, "\n")
- && indent_type (info));
-}
-
-/* Add a static member to a class. */
-
-static boolean
-pr_class_static_member (p, name, physname, visibility)
- PTR p;
- const char *name;
- const char *physname;
- enum debug_visibility visibility;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *t;
-
- if (! substitute_type (info, name))
- return false;
-
- if (! prepend_type (info, "static ")
- || ! append_type (info, "; /* ")
- || ! append_type (info, physname)
- || ! append_type (info, " */\n")
- || ! indent_type (info))
- return false;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-
- if (! pr_fix_visibility (info, visibility))
- return false;
-
- return append_type (info, t);
-}
-
-/* Add a base class to a class. */
-
-static boolean
-pr_class_baseclass (p, bitpos, virtual, visibility)
- PTR p;
- bfd_vma bitpos;
- boolean virtual;
- enum debug_visibility visibility;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *t;
- const char *prefix;
- char ab[20];
- char *s, *l, *n;
-
- assert (info->stack != NULL && info->stack->next != NULL);
-
- if (! substitute_type (info, ""))
- return false;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-
- if (strncmp (t, "class ", sizeof "class " - 1) == 0)
- t += sizeof "class " - 1;
-
- /* Push it back on to take advantage of the prepend_type and
- append_type routines. */
- if (! push_type (info, t))
- return false;
-
- if (virtual)
- {
- if (! prepend_type (info, "virtual "))
- return false;
- }
-
- switch (visibility)
- {
- case DEBUG_VISIBILITY_PUBLIC:
- prefix = "public ";
- break;
- case DEBUG_VISIBILITY_PROTECTED:
- prefix = "protected ";
- break;
- case DEBUG_VISIBILITY_PRIVATE:
- prefix = "private ";
- break;
- default:
- prefix = "/* unknown visibility */ ";
- break;
- }
-
- if (! prepend_type (info, prefix))
- return false;
-
- if (bitpos != 0)
- {
- print_vma (bitpos, ab, true, false);
- if (! append_type (info, " /* bitpos ")
- || ! append_type (info, ab)
- || ! append_type (info, " */"))
- return false;
- }
-
- /* Now the top of the stack is something like "public A / * bitpos
- 10 * /". The next element on the stack is something like "class
- xx { / * size 8 * /\n...". We want to substitute the top of the
- stack in before the {. */
- s = strchr (info->stack->next->type, '{');
- assert (s != NULL);
- --s;
-
- /* If there is already a ':', then we already have a baseclass, and
- we must append this one after a comma. */
- for (l = info->stack->next->type; l != s; l++)
- if (*l == ':')
- break;
- if (! prepend_type (info, l == s ? " : " : ", "))
- return false;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-
- n = (char *) xmalloc (strlen (info->stack->type) + strlen (t) + 1);
- memcpy (n, info->stack->type, s - info->stack->type);
- strcpy (n + (s - info->stack->type), t);
- strcat (n, s);
-
- free (info->stack->type);
- info->stack->type = n;
-
- free (t);
-
- return true;
-}
-
-/* Start adding a method to a class. */
-
-static boolean
-pr_class_start_method (p, name)
- PTR p;
- const char *name;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- assert (info->stack != NULL);
- info->stack->method = name;
- return true;
-}
-
-/* Add a variant to a method. */
-
-static boolean
-pr_class_method_variant (p, physname, visibility, constp, volatilep, voffset,
- context)
- PTR p;
- const char *physname;
- enum debug_visibility visibility;
- boolean constp;
- boolean volatilep;
- bfd_vma voffset;
- boolean context;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *method_type;
- char *context_type;
-
- assert (info->stack != NULL);
- assert (info->stack->next != NULL);
-
- /* Put the const and volatile qualifiers on the type. */
- if (volatilep)
- {
- if (! append_type (info, " volatile"))
- return false;
- }
- if (constp)
- {
- if (! append_type (info, " const"))
- return false;
- }
-
- /* Stick the name of the method into its type. */
- if (! substitute_type (info,
- (context
- ? info->stack->next->next->method
- : info->stack->next->method)))
- return false;
-
- /* Get the type. */
- method_type = pop_type (info);
- if (method_type == NULL)
- return false;
-
- /* Pull off the context type if there is one. */
- if (! context)
- context_type = NULL;
- else
- {
- context_type = pop_type (info);
- if (context_type == NULL)
- return false;
- }
-
- /* Now the top of the stack is the class. */
-
- if (! pr_fix_visibility (info, visibility))
- return false;
-
- if (! append_type (info, method_type)
- || ! append_type (info, " /* ")
- || ! append_type (info, physname)
- || ! append_type (info, " "))
- return false;
- if (context || voffset != 0)
- {
- char ab[20];
-
- if (context)
- {
- if (! append_type (info, "context ")
- || ! append_type (info, context_type)
- || ! append_type (info, " "))
- return false;
- }
- print_vma (voffset, ab, true, false);
- if (! append_type (info, "voffset ")
- || ! append_type (info, ab))
- return false;
- }
-
- return (append_type (info, " */;\n")
- && indent_type (info));
-}
-
-/* Add a static variant to a method. */
-
-static boolean
-pr_class_static_method_variant (p, physname, visibility, constp, volatilep)
- PTR p;
- const char *physname;
- enum debug_visibility visibility;
- boolean constp;
- boolean volatilep;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *method_type;
-
- assert (info->stack != NULL);
- assert (info->stack->next != NULL);
- assert (info->stack->next->method != NULL);
-
- /* Put the const and volatile qualifiers on the type. */
- if (volatilep)
- {
- if (! append_type (info, " volatile"))
- return false;
- }
- if (constp)
- {
- if (! append_type (info, " const"))
- return false;
- }
-
- /* Mark it as static. */
- if (! prepend_type (info, "static "))
- return false;
-
- /* Stick the name of the method into its type. */
- if (! substitute_type (info, info->stack->next->method))
- return false;
-
- /* Get the type. */
- method_type = pop_type (info);
- if (method_type == NULL)
- return false;
-
- /* Now the top of the stack is the class. */
-
- if (! pr_fix_visibility (info, visibility))
- return false;
-
- return (append_type (info, method_type)
- && append_type (info, " /* ")
- && append_type (info, physname)
- && append_type (info, " */;\n")
- && indent_type (info));
-}
-
-/* Finish up a method. */
-
-static boolean
-pr_class_end_method (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- info->stack->method = NULL;
- return true;
-}
-
-/* Finish up a class. */
-
-static boolean
-pr_end_class_type (p)
- PTR p;
-{
- return pr_end_struct_type (p);
-}
-
-/* Push a type on the stack using a typedef name. */
-
-static boolean
-pr_typedef_type (p, name)
- PTR p;
- const char *name;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
- return push_type (info, name);
-}
-
-/* Push a type on the stack using a tag name. */
-
-static boolean
-pr_tag_type (p, name, id, kind)
- PTR p;
- const char *name;
- unsigned int id;
- enum debug_type_kind kind;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- const char *t, *tag;
- char idbuf[30];
-
- switch (kind)
- {
- case DEBUG_KIND_STRUCT:
- t = "struct ";
- break;
- case DEBUG_KIND_UNION:
- t = "union ";
- break;
- case DEBUG_KIND_ENUM:
- t = "enum ";
- break;
- case DEBUG_KIND_CLASS:
- t = "class ";
- break;
- case DEBUG_KIND_UNION_CLASS:
- t = "union class ";
- break;
- default:
- abort ();
- return false;
- }
-
- if (! push_type (info, t))
- return false;
- if (name != NULL)
- tag = name;
- else
- {
- sprintf (idbuf, "%%anon%u", id);
- tag = idbuf;
- }
-
- if (! append_type (info, tag))
- return false;
- if (name != NULL && kind != DEBUG_KIND_ENUM)
- {
- sprintf (idbuf, " /* id %u */", id);
- if (! append_type (info, idbuf))
- return false;
- }
-
- return true;
-}
-
-/* Output a typedef. */
-
-static boolean
-pr_typdef (p, name)
- PTR p;
- const char *name;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *s;
-
- if (! substitute_type (info, name))
- return false;
-
- s = pop_type (info);
- if (s == NULL)
- return false;
-/*
- indent (info);
- TRACE_FPRINTF( (info->f, "typedef %s;\n", s));
-*/
- free (s);
-
- return true;
-}
-
-/* Output a tag. The tag should already be in the string on the
- stack, so all we have to do here is print it out. */
-
-/*ARGSUSED*/
-static boolean
-pr_tag (p, name)
- PTR p;
- const char *name;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *t;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-/*
- indent (info);
- TRACE_FPRINTF( (info->f, "%s;\n", t));
-*/
- free (t);
-
- return true;
-}
-
-/* Output an integer constant. */
-
-static boolean
-pr_int_constant (p, name, val)
- PTR p;
- const char *name;
- bfd_vma val;
-{
-/*
- struct pr_handle *info = (struct pr_handle *) p;
- char ab[20];
- indent (info);
- print_vma (val, ab, false, false);
- TRACE_FPRINTF( (info->f, "const int %s = %s;\n", name, ab));
- */
- return true;
-}
-
-/* Output a floating point constant. */
-
-static boolean
-pr_float_constant (p, name, val)
- PTR p;
- const char *name;
- double val;
-{
-/*
- struct pr_handle *info = (struct pr_handle *) p;
- indent (info);
- TRACE_FPRINTF( (info->f, "const double %s = %g;\n", name, val));
- */
- return true;
-}
-
-/* Output a typed constant. */
-
-static boolean
-pr_typed_constant (p, name, val)
- PTR p;
- const char *name;
- bfd_vma val;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *t;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-/*
- char ab[20];
- indent (info);
- print_vma (val, ab, false, false);
- TRACE_FPRINTF( (info->f, "const %s %s = %s;\n", t, name, ab));
-*/
- free (t);
-
- return true;
-}
-
-/* Output a variable. */
-
-static boolean
-pr_variable (p, name, kind, val)
- PTR p;
- const char *name;
- enum debug_var_kind kind;
- bfd_vma val;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *t;
- char ab[20];
- (void)ab;
-
- if (! substitute_type (info, name))
- return false;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-
-#if 0
- indent (info);
- switch (kind)
- {
- case DEBUG_STATIC:
- case DEBUG_LOCAL_STATIC:
- TRACE_FPRINTF( (info->f, "static "));
- break;
- case DEBUG_REGISTER:
- TRACE_FPRINTF( (info->f, "register "));
- break;
- default:
- break;
- }
- print_vma (val, ab, true, true);
- TRACE_FPRINTF( (info->f, "%s /* %s */;\n", t, ab));
-#else /* 0 */
-#if 0
- if (kind==DEBUG_STATIC || kind==DEBUG_LOCAL_STATIC) {
- print_vma (val, ab, true, true);
- TRACE_FPRINTF( (info->f, "STATIC_VAR: %s /* %s */;\n", t, ab));
- }
-#endif /* 0 */
-#endif /* !0 */
-
- free (t);
-
- return true;
-}
-
-/* Start outputting a function. */
-
-static boolean
-pr_start_function (p, name, global)
- PTR p;
- const char *name;
- boolean global;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char *t;
-
- if (! substitute_type (info, name))
- return false;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-
-#if 0
- indent (info);
- if (! global)
- TRACE_FPRINTF( (info->f, "static "));
- TRACE_FPRINTF( (info->f, "%s (", t));
- info->parameter = 1;
-#else /* 0 */
- if (info->functions_size==info->functions_maxsize) {
- info->functions_maxsize *= 2;
- info->functions = xrealloc(info->functions,
- info->functions_maxsize*sizeof(debug_function_t));
- assert(info->functions!=0);
- }
- /* info->functions[info->functions_size] = xmalloc(sizeof(debug_function_t)); */
- info->function = &info->functions[info->functions_size];
- ++info->functions_size;
- info->function->symbol = NULL;
- info->function->lines = NULL;
- info->function->lines_count = 0;
- info->function->max_lines_count = 0;
- info->function->name = t;
- info->function->filename = NULL;
- info->function->block = NULL;
- info->function->argv = NULL;
- info->function->argc = 0;
- info->function->max_argc = 0;
-#endif /* !0 */
- return true;
-}
-
-/* Output a function parameter. */
-
-static boolean
-pr_function_parameter (p, name, kind, val)
- PTR p;
- const char *name;
- enum debug_parm_kind kind;
- bfd_vma val;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- debug_function_t* f = info->function;
- char *t;
- char ab[20];
- (void)ab;
-
- if (kind == DEBUG_PARM_REFERENCE
- || kind == DEBUG_PARM_REF_REG)
- {
- if (! pr_reference_type (p))
- return false;
- }
-
- if (! substitute_type (info, name))
- return false;
-
- t = pop_type (info);
- if (t == NULL)
- return false;
-
-#if 0
- if (info->parameter != 1)
- TRACE_FPRINTF( (info->f, ", "));
-
- if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG)
- TRACE_FPRINTF( (info->f, "register "));
-
- print_vma (val, ab, true, true);
- TRACE_FPRINTF( (info->f, "%s /* %s */", t, ab));
- free (t);
- ++info->parameter;
-#else /* 0 */
- assert(f!=NULL);
- if (f->argv==NULL) {
- f->max_argc = 7; /* rarely anyone has more than that many args... */
- f->argv = xmalloc(sizeof(debug_parameter_t)*f->max_argc);
- } else if (f->argc==f->max_argc) {
- f->max_argc *= 2;
- f->argv = realloc(f->argv,sizeof(debug_parameter_t)*f->max_argc);
- }
- f->argv[f->argc].offset = val;
- f->argv[f->argc].name = t;
- ++f->argc;
-#endif /* !0 */
- return true;
-}
-
-/* Start writing out a block. */
-
-static boolean
-pr_start_block (p, addr)
- PTR p;
- bfd_vma addr;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char ab[20];
- debug_block_t* block = 0;
- (void)ab;
-#if 0
- if (info->parameter > 0)
- {
- TRACE_FPRINTF( (info->f, ")\n"));
- info->parameter = 0;
- }
- indent (info);
- print_vma (addr, ab, true, true);
- TRACE_FPRINTF( (info->f, "{ /* %s */\n", ab));
- info->indent += 2;
-#else
- if (info->block) {
- if (info->block->childs_count==0)
- info->block->childs = xmalloc(sizeof(debug_block_t));
- else
- info->block->childs = xrealloc(info->block->childs,
- info->block->childs_count*sizeof(debug_block_t));
- block = &info->block->childs[info->block->childs_count];
- } else {
- block = xmalloc(sizeof(debug_block_t));
- info->function->block = block;
- }
- block->begin_addr = addr;
- block->end_addr = 0;
- block->parent = info->block;
- block->childs = NULL;
- block->childs_count = 0;
- info->block = block;
-#endif
- return true;
-}
-
-/* Write out line number information. */
-
-static boolean
-pr_lineno (p, filename, lineno, addr)
- PTR p;
- const char *filename;
- unsigned long lineno;
- bfd_vma addr;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- char ab[20];
- debug_function_t* f = info->function;
- (void)ab;
-
-#if 0
- indent (info);
- print_vma (addr, ab, true, true);
- TRACE_FPRINTF( (info->f, "/* file %s line %lu addr %s */\n", filename, lineno, ab));
-#else /* 0 */
- if (f==NULL) /* FIXME: skips junk silently. */
- return true;
- /* assert(f!=NULL); */
- if (f->filename==NULL) {
- f->filename = filename;
- assert(f->lines==0);
- f->max_lines_count = 4;
- f->lines = xmalloc(sizeof(debug_lineno_t)*f->max_lines_count);
- }
- if (f->lines_count==f->max_lines_count) {
- f->max_lines_count *= 2;
- f->lines = xrealloc(f->lines, sizeof(debug_lineno_t)*f->max_lines_count);
- }
- f->lines[f->lines_count].lineno = lineno;
- f->lines[f->lines_count].addr = addr;
- ++f->lines_count;
-#endif /* !0 */
-
- return true;
-}
-
-/* Finish writing out a block. */
-
-static boolean
-pr_end_block (p, addr)
- PTR p;
- bfd_vma addr;
-{
- struct pr_handle *info = (struct pr_handle *) p;
-
-#if 0
- char ab[20];
-
- info->indent -= 2;
- indent (info);
- print_vma (addr, ab, true, true);
- TRACE_FPRINTF( (info->f, "} /* %s */\n", ab));
-#else /* 0 */
- assert(info->block!=0);
- info->block->end_addr = addr;
- info->block = info->block->parent;
-#endif /* !0 */
-
- return true;
-}
-
-/* Finish writing out a function. */
-
-/*ARGSUSED*/
-static boolean
-pr_end_function (p)
- PTR p;
-{
- struct pr_handle *info = (struct pr_handle *) p;
- assert(info->block==0);
- info->function = NULL;
- return true;
-}
-
-/* third parameter to segv_action. */
-/* Got it after a bit of head scratching and stack dumping. */
-typedef struct {
- u_int32_t foo1; /* +0x00 */
- u_int32_t foo2;
- u_int32_t foo3;
- u_int32_t foo4; /* usually 2 */
- u_int32_t foo5; /* +0x10 */
- u_int32_t xgs; /* always zero */
- u_int32_t xfs; /* always zero */
- u_int32_t xes; /* always es=ds=ss */
- u_int32_t xds; /* +0x20 */
- u_int32_t edi;
- u_int32_t esi;
- u_int32_t ebp;
- u_int32_t esp; /* +0x30 */
- u_int32_t ebx;
- u_int32_t edx;
- u_int32_t ecx;
- u_int32_t eax; /* +0x40 */
- u_int32_t foo11; /* usually 0xe */
- u_int32_t foo12; /* usually 0x6 */
- u_int32_t eip; /* instruction pointer */
- u_int32_t xcs; /* +0x50 */
- u_int32_t foo21; /* usually 0x2 */
- u_int32_t foo22; /* second stack pointer?! Probably. */
- u_int32_t xss;
- u_int32_t foo31; /* +0x60 */ /* usually 0x0 */
- u_int32_t foo32; /* usually 0x2 */
- u_int32_t fault_addr; /* Address which caused a fault */
- u_int32_t foo41; /* usually 0x2 */
-} signal_regs_t;
-
-signal_regs_t* ptrace_regs = 0; /* Tells my_ptrace to "ptrace" current process" */
-/*
- * my_ptrace: small wrapper around ptrace.
- * Act as normal ptrace if ptrace_regs==0.
- * Read data from current process if ptrace_regs!=0.
- */
-static int
-my_ptrace( int request,
- int pid,
- int addr,
- int data)
-{
- if (ptrace_regs==0)
- return ptrace(request, pid, addr, data);
- /* we are tracing ourselves! */
- switch (request) {
- case PTRACE_ATTACH: return 0;
- case PTRACE_CONT: return 0;
- case PTRACE_DETACH: return 0;
- case PTRACE_PEEKUSER:
- switch (addr / 4) {
- case EIP: return ptrace_regs->eip;
- case EBP: return ptrace_regs->ebp;
- default: assert(0);
- }
- case PTRACE_PEEKTEXT: /* FALLTHROUGH */
- case PTRACE_PEEKDATA: return *(int*)(addr);
- default: assert(0);
- }
- errno = 1; /* what to do here? */
- return 1; /* failed?! */
-}
-
-#define MAXARGS 6
-
-/*
- * To minimize the number of parameters.
- */
-typedef struct {
- asymbol** syms; /* Sorted! */
- int symcount;
- debug_function_t** functions;
- int functions_size;
-} symbol_data_t;
-
-/*
- * Perform a search. A binary search for a symbol.
- */
-static void
-decode_symbol( symbol_data_t* symbol_data,
- const unsigned long addr,
- char* buf,
- const int bufsize)
-{
- asymbol** syms = symbol_data->syms;
- const int symcount = symbol_data->symcount;
- int bottom = 0;
- int top = symcount - 1;
- int i;
- if (symcount==0) {
- sprintf(buf, "????");
- return;
- }
- while (top>bottom+1) {
- i = (top+bottom) / 2;
- if (bfd_asymbol_value(syms[i])==addr) {
- sprintf(buf, "%s", syms[i]->name);
- return;
- } else if (bfd_asymbol_value(syms[i]) > addr)
- top = i;
- else
- bottom = i;
- }
- i = bottom;
- if (addr<bfd_asymbol_value(syms[i]) || addr>(syms[i]->section->vma+syms[i]->section->_cooked_size))
- sprintf(buf, "????");
- else
- sprintf(buf, "%s + 0x%lx", syms[i]->name, addr-bfd_asymbol_value(syms[i]));
-}
-
-/*
- * 1. Perform a binary search for an debug_function_t.
- * 2. Fill buf/bufsize with name, parameters and lineno, if found
- * Or with '????' otherwise.
- */
-static debug_function_t*
-find_debug_function_t( symbol_data_t* symbol_data,
- const pid_t pid,
- const unsigned long fp, /* frame pointer */
- const unsigned long addr,
- char* buf, /* string buffer */
- const int bufsize)/* FIXME: not used! */
-{
- debug_function_t** syms = symbol_data->functions;
- debug_function_t* f = NULL;
- debug_block_t* block = NULL;
- debug_lineno_t* lineno = NULL;
- const int symcount = symbol_data->functions_size;
- int bottom = 0;
- int top = symcount - 1;
- int i;
- char* bufptr = buf;
-
- if (symcount==0) {
- sprintf(buf, "????");
- return NULL;
- }
- while (top>bottom+1) {
- i = (top+bottom) / 2;
- if (syms[i]->block->begin_addr==addr) {
- f = syms[i];
- break;
- } else if (syms[i]->block->begin_addr > addr)
- top = i;
- else
- if (syms[i]->block->end_addr >= addr) {
- f = syms[i];
- break;
- } else
- bottom = i;
- }
- i = bottom;
- if (f!=0)
- block = f->block;
- else {
- block = syms[i]->block;
- if (block->begin_addr>=addr && block->end_addr<=addr)
- f = syms[i];
- }
- if (f==0)
- sprintf(buf, "????");
- else {
- /*
- * Do the backtrace the GDB way...
- */
- unsigned long arg;
- /* assert(f->lines_count>0); */
- if (f->lines_count>0) {
- lineno = &f->lines[f->lines_count-1];
- for (i=1; i<f->lines_count; ++i)
- if (f->lines[i].addr>addr) {
- lineno = &f->lines[i-1];
- break;
- }
- }
- bufptr[0] = 0;
- bufptr += sprintf(bufptr, "%s+0x%lx (", f->name, addr-block->begin_addr);
- for (i=0; i<f->argc; ++i) {
- bufptr += sprintf(bufptr, "%s = ", f->argv[i].name);
- /* FIXME: better parameter printing */
- errno = 0;
- arg = my_ptrace(PTRACE_PEEKDATA, pid, fp+f->argv[i].offset, 0);
- assert(errno==0);
- bufptr += sprintf(bufptr, "0x%x", arg);
- if (i!=f->argc-1)
- bufptr += sprintf(bufptr, ", ");
- }
- if (lineno!=0)
- bufptr += sprintf(bufptr, ") at %s:%d", f->filename, lineno->lineno);
- }
- return f;
-}
-
-/*
- * Advance through the stacks and display frames as needed.
- */
-static int
-my_crawl( int pid,
- symbol_data_t* symbol_data,
- int fout)
-{
- unsigned long pc = 0;
- unsigned long fp = 0;
- unsigned long nextfp;
- unsigned long nargs;
- unsigned long i;
- unsigned long arg;
- char buf[8096]; // FIXME: enough?
- debug_function_t* f = 0;
-
- errno = 0;
-
- pc = my_ptrace(PTRACE_PEEKUSER, pid, EIP * 4, 0);
- if (!errno)
- fp = my_ptrace(PTRACE_PEEKUSER, pid, EBP * 4, 0);
-
- if (!errno) {
-#if 1
- f = find_debug_function_t(symbol_data, pid, fp, pc, buf, sizeof(buf));
- fdprintf(fout,"0x%08lx: %s", pc, buf);
- for ( ; !errno && fp; ) {
- nextfp = my_ptrace(PTRACE_PEEKDATA, pid, fp, 0);
- if (errno)
- break;
-
- if (f==0) {
- nargs = (nextfp - fp - 8) / 4;
- if (nargs > MAXARGS)
- nargs = MAXARGS;
- if (nargs > 0) {
- fdputs(" (", fout);
- for (i = 1; i <= nargs; i++) {
- arg = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4 * (i + 1), 0);
- if (errno)
- break;
- fdprintf(fout,"%lx", arg);
- if (i < nargs)
- fdputs(", ", fout);
- }
- fdputc(')', fout);
- nargs = nextfp - fp - 8 - (4 * nargs);
- if (!errno && nargs > 0)
- fdprintf(fout," + %lx\n", nargs);
- else
- fdputc('\n', fout);
- } else
- fdputc('\n', fout);
- } else
- fdputc('\n', fout);
-
- if (errno || !nextfp)
- break;
- pc = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4, 0);
- fp = nextfp;
- if (errno)
- break;
- f = find_debug_function_t(symbol_data, pid, fp, pc, buf, sizeof(buf));
- fdprintf(fout,"0x%08lx: %s", pc, buf);
- }
-#else /* 1 */
- decode_symbol(symbol_data, pc, buf, sizeof(buf));
- fdprintf(fout,"0x%08lx: %s", pc, buf);
- for ( ; !errno && fp; ) {
- nextfp = my_ptrace(PTRACE_PEEKDATA, pid, fp, 0);
- if (errno)
- break;
-
- nargs = (nextfp - fp - 8) / 4;
- if (nargs > MAXARGS)
- nargs = MAXARGS;
- if (nargs > 0) {
- fputs(" (", fout);
- for (i = 1; i <= nargs; i++) {
- arg = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4 * (i + 1), 0);
- if (errno)
- break;
- fdprintf(fout,"%lx", arg);
- if (i < nargs)
- fputs(", ", fout);
- }
- fdputc(')', fout);
- nargs = nextfp - fp - 8 - (4 * nargs);
- if (!errno && nargs > 0)
- fdprintf(fout," + %lx\n", nargs);
- else
- fdputc('\n', fout);
- } else
- fdputc('\n', fout);
-
- if (errno || !nextfp)
- break;
- pc = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4, 0);
- fp = nextfp;
- if (errno)
- break;
- decode_symbol(symbol_data, pc, buf, sizeof(buf));
- fdprintf(fout,"0x%08lx: %s", pc, buf);
- }
-#endif /* !1 */
- }
- if (errno)
- perror("my_crawl");
- return errno;
-}
-
-/* layout from /usr/src/linux/arch/i386/kernel/process.c */
-static void
-show_regs( signal_regs_t* regs,
- int fd)
-{
- /* long cr0 = 0L, cr2 = 0L, cr3 = 0L; */
-
- fdprintf(fd,"\n");
- fdprintf(fd,"FAULT ADDR: %08x\n", regs->fault_addr);
- fdprintf(fd,"EIP: %04x:[<%08x>]",0xffff & regs->xcs,regs->eip);
- if (regs->xcs & 3)
- fdprintf(fd," ESP: %04x:%08x",0xffff & regs->xss,regs->esp);
- /*fdprintf(fd," EFLAGS: %08lx\n",regs->eflags); */
- fdprintf(fd, "\n");
- fdprintf(fd,"EAX: %08x EBX: %08x ECX: %08x EDX: %08x\n",
- regs->eax,regs->ebx,regs->ecx,regs->edx);
- fdprintf(fd,"ESI: %08x EDI: %08x EBP: %08x",
- regs->esi, regs->edi, regs->ebp);
- fdprintf(fd," DS: %04x ES: %04x\n",
- 0xffff & regs->xds,0xffff & regs->xes);
- /*
- __asm__("movl %%cr0, %0": "=r" (cr0));
- __asm__("movl %%cr2, %0": "=r" (cr2));
- __asm__("movl %%cr3, %0": "=r" (cr3));
- fprintf(stderr,"CR0: %08lx CR2: %08lx CR3: %08lx\n", cr0, cr2, cr3); */
-}
-
-/*
- * Load a BFD for an executable based on PID. Return 0 on failure.
- */
-static bfd*
-load_bfd( const int pid)
-{
- char filename[512];
- bfd* abfd = 0;
-
- /* Get the contents from procfs. */
-#if 1
- sprintf(filename, "/proc/%d/exe", pid);
-#else
- sprintf(filename, "crashing");
-#endif
-
- if ((abfd = bfd_openr (filename, 0))== NULL)
- bfd_nonfatal (filename);
- else {
- char** matching;
- assert(bfd_check_format(abfd, bfd_archive)!=true);
-
- /*
- * There is no indication in BFD documentation that it should be done.
- * God knows why...
- */
- if (!bfd_check_format_matches (abfd, bfd_object, &matching)) {
- bfd_nonfatal (bfd_get_filename (abfd));
- if (bfd_get_error () == bfd_error_file_ambiguously_recognized) {
- list_matching_formats (matching);
- free (matching);
- }
- }
- }
- return abfd;
-}
-
-/*
- * Those are for qsort. We need only function addresses, so all the others don't count.
- */
-/*
- * Compare two BFD::asymbol-s.
- */
-static int
-compare_symbols(const void* ap,
- const void* bp)
-{
- const asymbol *a = *(const asymbol **)ap;
- const asymbol *b = *(const asymbol **)bp;
- if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
- return 1;
- else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
- return -1;
- return 0;
-}
-
-/*
- * Compare two debug_asymbol_t-s.
- */
-static int
-compare_debug_function_t(const void* ap,
- const void* bp)
-{
- const debug_function_t *a = *(const debug_function_t **)ap;
- const debug_function_t *b = *(const debug_function_t **)bp;
- assert(a->block!=0);
- assert(b->block!=0);
- {
- const bfd_vma addr1 = a->block->begin_addr;
- const bfd_vma addr2 = b->block->begin_addr;
- if (addr1 > addr2)
- return 1;
- else if (addr2 > addr1)
- return -1;
- }
- return 0;
-}
-
-/*
- * Filter out (in place) symbols that are useless for stack tracing.
- * COUNT is the number of elements in SYMBOLS.
- * Return the number of useful symbols.
- */
-
-static long
-remove_useless_symbols( asymbol** symbols,
- long count)
-{
- asymbol** in_ptr = symbols;
- asymbol** out_ptr = symbols;
-
- while (--count >= 0) {
- asymbol *sym = *in_ptr++;
-
- if (sym->name == NULL || sym->name[0] == '\0' || sym->value==0)
- continue;
- if (sym->flags & (BSF_DEBUGGING))
- continue;
- if (bfd_is_und_section (sym->section) || bfd_is_com_section (sym->section))
- continue;
- *out_ptr++ = sym;
- }
- return out_ptr - symbols;
-}
-
-/*
- * Debugging information.
- */
-static bfd* abfd = 0;
-static PTR dhandle = 0;
-static asymbol** syms = 0;
-static long symcount = 0;
-static asymbol** sorted_syms = 0;
-static long sorted_symcount = 0;
-static debug_function_t** functions = 0;
-static int functions_size = 0;
-static int sigreport = SIGUSR1;
-static pthread_t segv_tid; /* What thread did SEGV? */
-static pid_t segv_pid;
-
-/*
- * We'll get here after a SIGSEGV. But you can install it on other signals, too :)
- * Because we are in the middle of the SIGSEGV, we are on our own. We can't do
- * any malloc(), any fopen(), nothing. The last is actually a sin. We event can't
- * fprintf(stderr,...)!!!
- */
-static void
-segv_action(int signo, siginfo_t* siginfo, void* ptr)
-{
- symbol_data_t symbol_data;
- int fd = -1;
-
- segv_pid = getpid();
- segv_tid = pthread_self();
- fd = open_log_file(segv_tid, segv_pid);
- /* signal(SIGSEGV, SIG_DFL); */
- ptrace_regs = (signal_regs_t*)ptr;
- assert(ptrace_regs!=0);
-
- /* Show user how guilty we are. */
- fdprintf(fd,"--------- SEGV in PROCESS %d, THREAD %d ---------------\n", segv_pid, pthread_self());
- show_regs(ptrace_regs, fd);
-
- /* Some form of stack trace, too. */
- fdprintf(fd, "STACK TRACE:\n");
-
- symbol_data.syms = sorted_syms;
- symbol_data.symcount = sorted_symcount;
- symbol_data.functions = functions;
- symbol_data.functions_size = functions_size;
- my_crawl(segv_pid, &symbol_data, fd);
- //fflush(stdout);
- close(fd);
- linuxthreads_notify_others(sigreport);
-}
-
-
-static void
-report_action(int signo, siginfo_t* siginfo, void* ptr)
-{
- const int pid = getpid();
- pthread_t tid = pthread_self();
- symbol_data_t symbol_data;
- int fd;
- if (pthread_equal(tid, segv_tid)) {
- /* We have already printed our stack trace... */
- return;
- }
-
- fd = open_log_file(tid, pid);
- fdprintf(fd, "REPORT: CURRENT PROCESS:%d, THREAD:%d\n", getpid(), pthread_self());
- /* signal(SIGSEGV, SIG_DFL); */
- ptrace_regs = (signal_regs_t*)ptr;
- assert(ptrace_regs!=0);
-
- /* Show user how guilty we are. */
- fdprintf(fd,"--------- STACK TRACE FOR PROCESS %d, THREAD %d ---------------\n", pid, pthread_self());
- show_regs(ptrace_regs, fd);
-
- /* Some form of stack trace, too. */
- fdprintf(fd, "STACK TRACE:\n");
-
- symbol_data.syms = sorted_syms;
- symbol_data.symcount = sorted_symcount;
- symbol_data.functions = functions;
- symbol_data.functions_size = functions_size;
- my_crawl(pid, &symbol_data, fd);
- //fflush(stdout);
- close(fd);
- /* Tell segv_thread to proceed after pause(). */
- /*pthread_kill(segv_tid, sigreport);
- kill(segv_pid, sigreport);
- pthread_cancel(tid); */
-}
-
-/*
- * Main library routine. Just call it on your program.
- */
-int
-pstack_install_segv_action( const char* path_format_)
-{
- const int pid = getpid();
- struct sigaction act;
-
- /* Store what we have to for later usage. */
- path_format = path_format_;
-
- /* We need a signal action for SIGSEGV and sigreport ! */
- sigreport = SIGUSR1;
- act.sa_handler = 0;
- sigemptyset(&act.sa_mask);
- act.sa_flags = SA_SIGINFO|SA_ONESHOT; /* Just one SIGSEGV. */
- act.sa_sigaction = segv_action;
- act.sa_restorer = NULL;
- if (sigaction(SIGSEGV, &act, NULL)!=0) {
- perror("sigaction");
- return 1;
- }
- act.sa_sigaction = report_action;
- act.sa_flags = SA_SIGINFO; /* But many sigreports. */
- if (sigaction(sigreport, &act, NULL)!=0) {
- perror("sigaction");
- return 1;
- }
-
- /* And a little setup for libiberty. */
- program_name = "crashing";
- xmalloc_set_program_name (program_name);
-
- /* Umm, and initialize BFD, too */
- bfd_init();
-#if 0
- list_supported_targets(0, stdout);
- set_default_bfd_target();
-#endif /* 0 */
-
- if ((abfd = load_bfd(pid))==0)
- fprintf(stderr, "BFD load failed..\n");
- else {
- long storage_needed= (bfd_get_file_flags(abfd) & HAS_SYMS) ?
- bfd_get_symtab_upper_bound (abfd) : 0;
- long i;
- (void)i;
-
- if (storage_needed < 0)
- fprintf(stderr, "Symbol table size estimation failure.\n");
- else if (storage_needed > 0) {
- syms = (asymbol **) xmalloc (storage_needed);
- symcount = bfd_canonicalize_symtab (abfd, syms);
-
- TRACE_FPRINTF((stderr, "TOTAL: %ld SYMBOLS.\n", symcount));
- /* We need debugging info, too! */
- if (symcount==0 || (dhandle = read_debugging_info (abfd, syms, symcount))==0)
- fprintf(stderr, "NO DEBUGGING INFORMATION FOUND.\n");
-
- /* We make a copy of syms to sort. We don't want to sort syms
- because that will screw up the relocs. */
- sorted_syms = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
- memcpy (sorted_syms, syms, symcount * sizeof (asymbol *));
-
-#if 0
- for (i=0; i<symcount; ++i)
- if (syms[i]->name!=0 && strlen(syms[i]->name)>0 && syms[i]->value!=0)
- printf("%08lx T %s\n", syms[i]->section->vma + syms[i]->value, syms[i]->name);
-#endif
- sorted_symcount = remove_useless_symbols (sorted_syms, symcount);
- TRACE_FPRINTF((stderr, "SORTED: %ld SYMBOLS.\n", sorted_symcount));
-
- /* Sort the symbols into section and symbol order */
- qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
-#if 0
- for (i=0; i<sorted_symcount; ++i)
- if (sorted_syms[i]->name!=0 && strlen(sorted_syms[i]->name)>0 && sorted_syms[i]->value!=0)
- printf("%08lx T %s\n", sorted_syms[i]->section->vma + sorted_syms[i]->value, sorted_syms[i]->name);
-#endif
- /* We have symbols, we need debugging info somehow sorted out. */
- if (dhandle==0) {
- fprintf(stderr, "STACK TRACE WILL BE UNCOMFORTABLE.\n");
- } else {
- /* Start collecting the debugging information.... */
- struct pr_handle info;
-
- info.f = stdout;
- info.indent = 0;
- info.stack = NULL;
- info.parameter = 0;
- info.block = NULL;
- info.function = NULL;
- info.functions_size = 0;
- info.functions_maxsize = 1000;
- info.functions = (debug_function_t*)xmalloc(sizeof(debug_function_t)*info.functions_maxsize);
- debug_write (dhandle, &pr_fns, (PTR) &info);
- TRACE_FPRINTF((stdout, "\n%d DEBUG SYMBOLS\n", info.functions_size));
- assert(info.functions_size!=0);
- functions = xmalloc(sizeof(debug_function_t*)*info.functions_size);
- functions_size = info.functions_size;
- for (i=0; i<functions_size; ++i)
- functions[i] = &info.functions[i];
- /* Sort the symbols into section and symbol order */
- qsort (functions, functions_size, sizeof(debug_function_t*),
- compare_debug_function_t);
-#if 0
- for (i=0; i<info.functions_size; ++i)
- fprintf(stdout, "%08lx T %s\n", info.functions[i].block->begin_addr, info.functions[i].name);
-#endif
- fflush(stdout);
- }
- } else /* storage_needed == 0 */
- fprintf(stderr, "NO SYMBOLS FOUND.\n");
- }
- return 0;
-}
-
-/*********************************************************************/
-/*********************************************************************/
-/*********************************************************************/
diff --git a/pstack/pstack.h b/pstack/pstack.h
deleted file mode 100644
index 4c4fad7e754..00000000000
--- a/pstack/pstack.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* $Header$ */
-
-#ifndef pstack_pstack_h_
-#define pstack_pstack_h_
-
-#include "pstacktrace.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Install the stack-trace-on-SEGV handler....
- */
-extern int
-pstack_install_segv_action( const char* path_format);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* pstack_pstack_h_ */
-
diff --git a/pstack/pstacktrace.h b/pstack/pstacktrace.h
deleted file mode 100644
index c884bcb9f87..00000000000
--- a/pstack/pstacktrace.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* $Header$ */
-
-/*
- * Debugging macros.
- */
-
-#ifndef pstacktrace_h_
-#define pstacktrace_h_
-
-#define PSTACK_DEBUG 1
-#undef PSTACK_DEBUG
-
-#ifdef PSTACK_DEBUG
-# define TRACE_PUTC(a) putc a
-# define TRACE_FPUTS(a) fputs a
-# define TRACE_FPRINTF(a) fprintf a
-#else /* PSTACK_DEBUG */
-# define TRACE_PUTC(a) (void)0
-# define TRACE_FPUTS(a) (void)0
-# define TRACE_FPRINTF(a) (void)0
-#endif /* !PSTACK_DEBUG */
-
-#endif /* pstacktrace_h_ */
-
diff --git a/pstack/rddbg.c b/pstack/rddbg.c
deleted file mode 100644
index be3dfc21c57..00000000000
--- a/pstack/rddbg.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/* rddbg.c -- Read debugging information into a generic form.
- Copyright (C) 1995, 96, 1997 Free Software Foundation, Inc.
- Written by Ian Lance Taylor <ian@cygnus.com>.
-
- This file is part of GNU Binutils.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-/* This file reads debugging information into a generic form. This
- file knows how to dig the debugging information out of an object
- file. */
-
-#include <bfd.h>
-#include "bucomm.h"
-#include <libiberty.h>
-#include "debug.h"
-#include "budbg.h"
-
-static boolean read_section_stabs_debugging_info
- PARAMS ((bfd *, asymbol **, long, PTR, boolean *));
-static boolean read_symbol_stabs_debugging_info
- PARAMS ((bfd *, asymbol **, long, PTR, boolean *));
-static boolean read_ieee_debugging_info PARAMS ((bfd *, PTR, boolean *));
-static void save_stab PARAMS ((int, int, bfd_vma, const char *));
-static void stab_context PARAMS ((void));
-static void free_saved_stabs PARAMS ((void));
-
-/* Read debugging information from a BFD. Returns a generic debugging
- pointer. */
-
-PTR
-read_debugging_info (abfd, syms, symcount)
- bfd *abfd;
- asymbol **syms;
- long symcount;
-{
- PTR dhandle;
- boolean found;
-
- dhandle = debug_init ();
- if (dhandle == NULL)
- return NULL;
-
- if (! read_section_stabs_debugging_info (abfd, syms, symcount, dhandle,
- &found))
- return NULL;
-
- if (bfd_get_flavour (abfd) == bfd_target_aout_flavour)
- {
- if (! read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle,
- &found))
- return NULL;
- }
-
- if (bfd_get_flavour (abfd) == bfd_target_ieee_flavour)
- {
- if (! read_ieee_debugging_info (abfd, dhandle, &found))
- return NULL;
- }
-
- /* Try reading the COFF symbols if we didn't find any stabs in COFF
- sections. */
- if (! found
- && bfd_get_flavour (abfd) == bfd_target_coff_flavour
- && symcount > 0)
- {
-#if 0
-/*
- * JZ: Do we need coff?
- */
- if (! parse_coff (abfd, syms, symcount, dhandle))
-#else
- fprintf (stderr, "%s: COFF support temporarily disabled\n",
- bfd_get_filename (abfd));
- return NULL;
-#endif
- return NULL;
- found = true;
- }
-
- if (! found)
- {
- fprintf (stderr, "%s: no recognized debugging information\n",
- bfd_get_filename (abfd));
- return NULL;
- }
-
- return dhandle;
-}
-
-/* Read stabs in sections debugging information from a BFD. */
-
-static boolean
-read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
- bfd *abfd;
- asymbol **syms;
- long symcount;
- PTR dhandle;
- boolean *pfound;
-{
- static struct
- {
- const char *secname;
- const char *strsecname;
- } names[] = { { ".stab", ".stabstr" } };
- unsigned int i;
- PTR shandle;
-
- *pfound = false;
- shandle = NULL;
-
- for (i = 0; i < sizeof names / sizeof names[0]; i++)
- {
- asection *sec, *strsec;
-
- sec = bfd_get_section_by_name (abfd, names[i].secname);
- strsec = bfd_get_section_by_name (abfd, names[i].strsecname);
- if (sec != NULL && strsec != NULL)
- {
- bfd_size_type stabsize, strsize;
- bfd_byte *stabs, *strings;
- bfd_byte *stab;
- bfd_size_type stroff, next_stroff;
-
- stabsize = bfd_section_size (abfd, sec);
- stabs = (bfd_byte *) xmalloc (stabsize);
- if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize))
- {
- fprintf (stderr, "%s: %s: %s\n",
- bfd_get_filename (abfd), names[i].secname,
- bfd_errmsg (bfd_get_error ()));
- return false;
- }
-
- strsize = bfd_section_size (abfd, strsec);
- strings = (bfd_byte *) xmalloc (strsize);
- if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize))
- {
- fprintf (stderr, "%s: %s: %s\n",
- bfd_get_filename (abfd), names[i].strsecname,
- bfd_errmsg (bfd_get_error ()));
- return false;
- }
-
- if (shandle == NULL)
- {
- shandle = start_stab (dhandle, abfd, true, syms, symcount);
- if (shandle == NULL)
- return false;
- }
-
- *pfound = true;
-
- stroff = 0;
- next_stroff = 0;
- for (stab = stabs; stab < stabs + stabsize; stab += 12)
- {
- bfd_size_type strx;
- int type;
- int other;
- int desc;
- bfd_vma value;
-
- /* This code presumes 32 bit values. */
-
- strx = bfd_get_32 (abfd, stab);
- type = bfd_get_8 (abfd, stab + 4);
- other = bfd_get_8 (abfd, stab + 5);
- desc = bfd_get_16 (abfd, stab + 6);
- value = bfd_get_32 (abfd, stab + 8);
-
- if (type == 0)
- {
- /* Special type 0 stabs indicate the offset to the
- next string table. */
- stroff = next_stroff;
- next_stroff += value;
- }
- else
- {
- char *f, *s;
-
- f = NULL;
- s = (char *) strings + stroff + strx;
- while (s[strlen (s) - 1] == '\\'
- && stab + 12 < stabs + stabsize)
- {
- char *p;
-
- stab += 12;
- p = s + strlen (s) - 1;
- *p = '\0';
- s = concat (s,
- ((char *) strings
- + stroff
- + bfd_get_32 (abfd, stab)),
- (const char *) NULL);
-
- /* We have to restore the backslash, because, if
- the linker is hashing stabs strings, we may
- see the same string more than once. */
- *p = '\\';
-
- if (f != NULL)
- free (f);
- f = s;
- }
-
- save_stab (type, desc, value, s);
-
- if (! parse_stab (dhandle, shandle, type, desc, value, s))
- {
-#if 0
-/*
- * JZ: skip the junk.
- */
- stab_context ();
- free_saved_stabs ();
- return false;
-#endif
- }
-
- /* Don't free f, since I think the stabs code
- expects strings to hang around. This should be
- straightened out. FIXME. */
- }
- }
-
- free_saved_stabs ();
- free (stabs);
-
- /* Don't free strings, since I think the stabs code expects
- the strings to hang around. This should be straightened
- out. FIXME. */
- }
- }
-
- if (shandle != NULL)
- {
- if (! finish_stab (dhandle, shandle))
- return false;
- }
-
- return true;
-}
-
-/* Read stabs in the symbol table. */
-
-static boolean
-read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
- bfd *abfd;
- asymbol **syms;
- long symcount;
- PTR dhandle;
- boolean *pfound;
-{
- PTR shandle;
- asymbol **ps, **symend;
-
- shandle = NULL;
- symend = syms + symcount;
- for (ps = syms; ps < symend; ps++)
- {
- symbol_info i;
-
- bfd_get_symbol_info (abfd, *ps, &i);
-
- if (i.type == '-')
- {
- const char *s;
- char *f;
-
- if (shandle == NULL)
- {
- shandle = start_stab (dhandle, abfd, false, syms, symcount);
- if (shandle == NULL)
- return false;
- }
-
- *pfound = true;
-
- s = i.name;
- f = NULL;
- while (s[strlen (s) - 1] == '\\'
- && ps + 1 < symend)
- {
- char *sc, *n;
-
- ++ps;
- sc = xstrdup (s);
- sc[strlen (sc) - 1] = '\0';
- n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL);
- free (sc);
- if (f != NULL)
- free (f);
- f = n;
- s = n;
- }
-
- save_stab (i.stab_type, i.stab_desc, i.value, s);
-
- if (! parse_stab (dhandle, shandle, i.stab_type, i.stab_desc,
- i.value, s))
- {
- stab_context ();
- free_saved_stabs ();
- return false;
- }
-
- /* Don't free f, since I think the stabs code expects
- strings to hang around. This should be straightened out.
- FIXME. */
- }
- }
-
- free_saved_stabs ();
-
- if (shandle != NULL)
- {
- if (! finish_stab (dhandle, shandle))
- return false;
- }
-
- return true;
-}
-
-/* Read IEEE debugging information. */
-
-static boolean
-read_ieee_debugging_info (abfd, dhandle, pfound)
- bfd *abfd;
- PTR dhandle;
- boolean *pfound;
-{
- asection *dsec;
- bfd_size_type size;
- bfd_byte *contents;
-
- /* The BFD backend puts the debugging information into a section
- named .debug. */
-
- dsec = bfd_get_section_by_name (abfd, ".debug");
- if (dsec == NULL)
- return true;
-
- size = bfd_section_size (abfd, dsec);
- contents = (bfd_byte *) xmalloc (size);
- if (! bfd_get_section_contents (abfd, dsec, contents, 0, size))
- return false;
-
- if (! parse_ieee (dhandle, abfd, contents, size))
- return false;
-
- free (contents);
-
- *pfound = true;
-
- return true;
-}
-
-/* Record stabs strings, so that we can give some context for errors. */
-
-#define SAVE_STABS_COUNT (16)
-
-struct saved_stab
-{
- int type;
- int desc;
- bfd_vma value;
- char *string;
-};
-
-static struct saved_stab saved_stabs[SAVE_STABS_COUNT];
-static int saved_stabs_index;
-
-/* Save a stabs string. */
-
-static void
-save_stab (type, desc, value, string)
- int type;
- int desc;
- bfd_vma value;
- const char *string;
-{
- if (saved_stabs[saved_stabs_index].string != NULL)
- free (saved_stabs[saved_stabs_index].string);
- saved_stabs[saved_stabs_index].type = type;
- saved_stabs[saved_stabs_index].desc = desc;
- saved_stabs[saved_stabs_index].value = value;
- saved_stabs[saved_stabs_index].string = xstrdup (string);
- saved_stabs_index = (saved_stabs_index + 1) % SAVE_STABS_COUNT;
-}
-
-/* Provide context for an error. */
-
-static void
-stab_context ()
-{
- int i;
-
- fprintf (stderr, "Last stabs entries before error:\n");
- fprintf (stderr, "n_type n_desc n_value string\n");
-
- i = saved_stabs_index;
- do
- {
- struct saved_stab *stabp;
-
- stabp = saved_stabs + i;
- if (stabp->string != NULL)
- {
- const char *s;
-
- s = bfd_get_stab_name (stabp->type);
- if (s != NULL)
- fprintf (stderr, "%-6s", s);
- else if (stabp->type == 0)
- fprintf (stderr, "HdrSym");
- else
- fprintf (stderr, "%-6d", stabp->type);
- fprintf (stderr, " %-6d ", stabp->desc);
- fprintf_vma (stderr, stabp->value);
- if (stabp->type != 0)
- fprintf (stderr, " %s", stabp->string);
- fprintf (stderr, "\n");
- }
- i = (i + 1) % SAVE_STABS_COUNT;
- }
- while (i != saved_stabs_index);
-}
-
-/* Free the saved stab strings. */
-
-static void
-free_saved_stabs ()
-{
- int i;
-
- for (i = 0; i < SAVE_STABS_COUNT; i++)
- {
- if (saved_stabs[i].string != NULL)
- {
- free (saved_stabs[i].string);
- saved_stabs[i].string = NULL;
- }
- }
-
- saved_stabs_index = 0;
-}
diff --git a/pstack/stabs.c b/pstack/stabs.c
deleted file mode 100644
index 076231d19cb..00000000000
--- a/pstack/stabs.c
+++ /dev/null
@@ -1,5082 +0,0 @@
-/* stabs.c -- Parse stabs debugging information
- Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
- Written by Ian Lance Taylor <ian@cygnus.com>.
-
- This file is part of GNU Binutils.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-/* This file contains code which parses stabs debugging information.
- The organization of this code is based on the gdb stabs reading
- code. The job it does is somewhat different, because it is not
- trying to identify the correct address for anything. */
-
-#include <stdio.h>
-#include <ctype.h>
-
-#include <bfd.h>
-#include "bucomm.h"
-#include <libiberty.h>
-#include "demangle.h"
-#include "debug.h"
-#include "budbg.h"
-
-/* Meaningless definition needs by aout64.h. FIXME. */
-#define BYTES_IN_WORD 4
-
-#include "aout/aout64.h"
-#include "aout/stab_gnu.h"
-
-/* The number of predefined XCOFF types. */
-
-#define XCOFF_TYPE_COUNT 34
-
-/* This structure is used as a handle so that the stab parsing doesn't
- need to use any static variables. */
-
-struct stab_handle
-{
- /* The BFD. */
- bfd *abfd;
- /* True if this is stabs in sections. */
- boolean sections;
- /* The symbol table. */
- asymbol **syms;
- /* The number of symbols. */
- long symcount;
- /* The accumulated file name string. */
- char *so_string;
- /* The value of the last N_SO symbol. */
- bfd_vma so_value;
- /* The value of the start of the file, so that we can handle file
- relative N_LBRAC and N_RBRAC symbols. */
- bfd_vma file_start_offset;
- /* The offset of the start of the function, so that we can handle
- function relative N_LBRAC and N_RBRAC symbols. */
- bfd_vma function_start_offset;
- /* The version number of gcc which compiled the current compilation
- unit, 0 if not compiled by gcc. */
- int gcc_compiled;
- /* Whether an N_OPT symbol was seen that was not generated by gcc,
- so that we can detect the SunPRO compiler. */
- boolean n_opt_found;
- /* The main file name. */
- char *main_filename;
- /* A stack of unfinished N_BINCL files. */
- struct bincl_file *bincl_stack;
- /* A list of finished N_BINCL files. */
- struct bincl_file *bincl_list;
- /* Whether we are inside a function or not. */
- boolean within_function;
- /* The address of the end of the function, used if we have seen an
- N_FUN symbol while in a function. This is -1 if we have not seen
- an N_FUN (the normal case). */
- bfd_vma function_end;
- /* The depth of block nesting. */
- int block_depth;
- /* List of pending variable definitions. */
- struct stab_pending_var *pending;
- /* Number of files for which we have types. */
- unsigned int files;
- /* Lists of types per file. */
- struct stab_types **file_types;
- /* Predefined XCOFF types. */
- debug_type xcoff_types[XCOFF_TYPE_COUNT];
- /* Undefined tags. */
- struct stab_tag *tags;
-};
-
-/* A list of these structures is used to hold pending variable
- definitions seen before the N_LBRAC of a block. */
-
-struct stab_pending_var
-{
- /* Next pending variable definition. */
- struct stab_pending_var *next;
- /* Name. */
- const char *name;
- /* Type. */
- debug_type type;
- /* Kind. */
- enum debug_var_kind kind;
- /* Value. */
- bfd_vma val;
-};
-
-/* A list of these structures is used to hold the types for a single
- file. */
-
-struct stab_types
-{
- /* Next set of slots for this file. */
- struct stab_types *next;
- /* Types indexed by type number. */
-#define STAB_TYPES_SLOTS (16)
- debug_type types[STAB_TYPES_SLOTS];
-};
-
-/* We keep a list of undefined tags that we encounter, so that we can
- fill them in if the tag is later defined. */
-
-struct stab_tag
-{
- /* Next undefined tag. */
- struct stab_tag *next;
- /* Tag name. */
- const char *name;
- /* Type kind. */
- enum debug_type_kind kind;
- /* Slot to hold real type when we discover it. If we don't, we fill
- in an undefined tag type. */
- debug_type slot;
- /* Indirect type we have created to point at slot. */
- debug_type type;
-};
-
-static char *savestring PARAMS ((const char *, int));
-static bfd_vma parse_number PARAMS ((const char **, boolean *));
-static void bad_stab PARAMS ((const char *));
-static void warn_stab PARAMS ((const char *, const char *));
-static boolean parse_stab_string
- PARAMS ((PTR, struct stab_handle *, int, int, bfd_vma, const char *));
-static debug_type parse_stab_type
- PARAMS ((PTR, struct stab_handle *, const char *, const char **,
- debug_type **));
-static boolean parse_stab_type_number
- PARAMS ((const char **, int *));
-static debug_type parse_stab_range_type
- PARAMS ((PTR, struct stab_handle *, const char *, const char **,
- const int *));
-static debug_type parse_stab_sun_builtin_type PARAMS ((PTR, const char **));
-static debug_type parse_stab_sun_floating_type
- PARAMS ((PTR, const char **));
-static debug_type parse_stab_enum_type PARAMS ((PTR, const char **));
-static debug_type parse_stab_struct_type
- PARAMS ((PTR, struct stab_handle *, const char *, const char **, boolean,
- const int *));
-static boolean parse_stab_baseclasses
- PARAMS ((PTR, struct stab_handle *, const char **, debug_baseclass **));
-static boolean parse_stab_struct_fields
- PARAMS ((PTR, struct stab_handle *, const char **, debug_field **,
- boolean *));
-static boolean parse_stab_cpp_abbrev
- PARAMS ((PTR, struct stab_handle *, const char **, debug_field *));
-static boolean parse_stab_one_struct_field
- PARAMS ((PTR, struct stab_handle *, const char **, const char *,
- debug_field *, boolean *));
-static boolean parse_stab_members
- PARAMS ((PTR, struct stab_handle *, const char *, const char **,
- const int *, debug_method **));
-static debug_type parse_stab_argtypes
- PARAMS ((PTR, struct stab_handle *, debug_type, const char *, const char *,
- debug_type, const char *, boolean, boolean, const char **));
-static boolean parse_stab_tilde_field
- PARAMS ((PTR, struct stab_handle *, const char **, const int *,
- debug_type *, boolean *));
-static debug_type parse_stab_array_type
- PARAMS ((PTR, struct stab_handle *, const char **, boolean));
-static void push_bincl PARAMS ((struct stab_handle *, const char *, bfd_vma));
-static const char *pop_bincl PARAMS ((struct stab_handle *));
-static boolean find_excl
- PARAMS ((struct stab_handle *, const char *, bfd_vma));
-static boolean stab_record_variable
- PARAMS ((PTR, struct stab_handle *, const char *, debug_type,
- enum debug_var_kind, bfd_vma));
-static boolean stab_emit_pending_vars PARAMS ((PTR, struct stab_handle *));
-static debug_type *stab_find_slot
- PARAMS ((struct stab_handle *, const int *));
-static debug_type stab_find_type
- PARAMS ((PTR, struct stab_handle *, const int *));
-static boolean stab_record_type
- PARAMS ((PTR, struct stab_handle *, const int *, debug_type));
-static debug_type stab_xcoff_builtin_type
- PARAMS ((PTR, struct stab_handle *, int));
-static debug_type stab_find_tagged_type
- PARAMS ((PTR, struct stab_handle *, const char *, int,
- enum debug_type_kind));
-static debug_type *stab_demangle_argtypes
- PARAMS ((PTR, struct stab_handle *, const char *, boolean *));
-
-/* Save a string in memory. */
-
-static char *
-savestring (start, len)
- const char *start;
- int len;
-{
- char *ret;
-
- ret = (char *) xmalloc (len + 1);
- memcpy (ret, start, len);
- ret[len] = '\0';
- return ret;
-}
-
-/* Read a number from a string. */
-
-static bfd_vma
-parse_number (pp, poverflow)
- const char **pp;
- boolean *poverflow;
-{
- unsigned long ul;
- const char *orig;
-
- if (poverflow != NULL)
- *poverflow = false;
-
- orig = *pp;
-
- errno = 0;
- ul = strtoul (*pp, (char **) pp, 0);
- if (ul + 1 != 0 || errno == 0)
- return (bfd_vma) ul;
-
- /* Note that even though strtoul overflowed, it should have set *pp
- to the end of the number, which is where we want it. */
-
- if (sizeof (bfd_vma) > sizeof (unsigned long))
- {
- const char *p;
- boolean neg;
- int base;
- bfd_vma over, lastdig;
- boolean overflow;
- bfd_vma v;
-
- /* Our own version of strtoul, for a bfd_vma. */
-
- p = orig;
-
- neg = false;
- if (*p == '+')
- ++p;
- else if (*p == '-')
- {
- neg = true;
- ++p;
- }
-
- base = 10;
- if (*p == '0')
- {
- if (p[1] == 'x' || p[1] == 'X')
- {
- base = 16;
- p += 2;
- }
- else
- {
- base = 8;
- ++p;
- }
- }
-
- over = ((bfd_vma) (bfd_signed_vma) -1) / (bfd_vma) base;
- lastdig = ((bfd_vma) (bfd_signed_vma) -1) % (bfd_vma) base;
-
- overflow = false;
- v = 0;
- while (1)
- {
- int d;
-
- d = *p++;
- if (isdigit ((unsigned char) d))
- d -= '0';
- else if (isupper ((unsigned char) d))
- d -= 'A';
- else if (islower ((unsigned char) d))
- d -= 'a';
- else
- break;
-
- if (d >= base)
- break;
-
- if (v > over || (v == over && (bfd_vma) d > lastdig))
- {
- overflow = true;
- break;
- }
- }
-
- if (! overflow)
- {
- if (neg)
- v = - v;
- return v;
- }
- }
-
- /* If we get here, the number is too large to represent in a
- bfd_vma. */
-
- if (poverflow != NULL)
- *poverflow = true;
- else
- warn_stab (orig, "numeric overflow");
-
- return 0;
-}
-
-/* Give an error for a bad stab string. */
-
-static void
-bad_stab (p)
- const char *p;
-{
- fprintf (stderr, "Bad stab: %s\n", p);
-}
-
-/* Warn about something in a stab string. */
-
-static void
-warn_stab (p, err)
- const char *p;
- const char *err;
-{
- fprintf (stderr, "Warning: %s: %s\n", err, p);
-}
-
-/* Create a handle to parse stabs symbols with. */
-
-/*ARGSUSED*/
-PTR
-start_stab (dhandle, abfd, sections, syms, symcount)
- PTR dhandle;
- bfd *abfd;
- boolean sections;
- asymbol **syms;
- long symcount;
-{
- struct stab_handle *ret;
-
- ret = (struct stab_handle *) xmalloc (sizeof *ret);
- memset (ret, 0, sizeof *ret);
- ret->abfd = abfd;
- ret->sections = sections;
- ret->syms = syms;
- ret->symcount = symcount;
- ret->files = 1;
- ret->file_types = (struct stab_types **) xmalloc (sizeof *ret->file_types);
- ret->file_types[0] = NULL;
- ret->function_end = (bfd_vma) -1;
- return (PTR) ret;
-}
-
-/* When we have processed all the stabs information, we need to go
- through and fill in all the undefined tags. */
-
-boolean
-finish_stab (dhandle, handle)
- PTR dhandle;
- PTR handle;
-{
- struct stab_handle *info = (struct stab_handle *) handle;
- struct stab_tag *st;
-
- if (info->within_function)
- {
- if (! stab_emit_pending_vars (dhandle, info)
- || ! debug_end_function (dhandle, info->function_end))
- return false;
- info->within_function = false;
- info->function_end = (bfd_vma) -1;
- }
-
- for (st = info->tags; st != NULL; st = st->next)
- {
- enum debug_type_kind kind;
-
- kind = st->kind;
- if (kind == DEBUG_KIND_ILLEGAL)
- kind = DEBUG_KIND_STRUCT;
- st->slot = debug_make_undefined_tagged_type (dhandle, st->name, kind);
- if (st->slot == DEBUG_TYPE_NULL)
- return false;
- }
-
- return true;
-}
-
-/* Handle a single stabs symbol. */
-
-boolean
-parse_stab (dhandle, handle, type, desc, value, string)
- PTR dhandle;
- PTR handle;
- int type;
- int desc;
- bfd_vma value;
- const char *string;
-{
- struct stab_handle *info = (struct stab_handle *) handle;
-
- /* gcc will emit two N_SO strings per compilation unit, one for the
- directory name and one for the file name. We just collect N_SO
- strings as we see them, and start the new compilation unit when
- we see a non N_SO symbol. */
- if (info->so_string != NULL
- && (type != N_SO || *string == '\0' || value != info->so_value))
- {
- if (! debug_set_filename (dhandle, info->so_string))
- return false;
- info->main_filename = info->so_string;
-
- info->gcc_compiled = 0;
- info->n_opt_found = false;
-
- /* Generally, for stabs in the symbol table, the N_LBRAC and
- N_RBRAC symbols are relative to the N_SO symbol value. */
- if (! info->sections)
- info->file_start_offset = info->so_value;
-
- /* We need to reset the mapping from type numbers to types. We
- can't free the old mapping, because of the use of
- debug_make_indirect_type. */
- info->files = 1;
- info->file_types = ((struct stab_types **)
- xmalloc (sizeof *info->file_types));
- info->file_types[0] = NULL;
-
- info->so_string = NULL;
-
- /* Now process whatever type we just got. */
- }
-
- switch (type)
- {
- case N_FN:
- case N_FN_SEQ:
- break;
-
- case N_LBRAC:
- /* Ignore extra outermost context from SunPRO cc and acc. */
- if (info->n_opt_found && desc == 1)
- break;
-
- if (! info->within_function)
- {
- fprintf (stderr, "N_LBRAC not within function\n");
- return false;
- }
-
- /* Start an inner lexical block. */
- if (! debug_start_block (dhandle,
- (value
- + info->file_start_offset
- + info->function_start_offset)))
- return false;
-
- /* Emit any pending variable definitions. */
- if (! stab_emit_pending_vars (dhandle, info))
- return false;
-
- ++info->block_depth;
- break;
-
- case N_RBRAC:
- /* Ignore extra outermost context from SunPRO cc and acc. */
- if (info->n_opt_found && desc == 1)
- break;
-
- /* We shouldn't have any pending variable definitions here, but,
- if we do, we probably need to emit them before closing the
- block. */
- if (! stab_emit_pending_vars (dhandle, info))
- return false;
-
- /* End an inner lexical block. */
- if (! debug_end_block (dhandle,
- (value
- + info->file_start_offset
- + info->function_start_offset)))
- return false;
-
- --info->block_depth;
- if (info->block_depth < 0)
- {
- fprintf (stderr, "Too many N_RBRACs\n");
- return false;
- }
- break;
-
- case N_SO:
- /* This always ends a function. */
- if (info->within_function)
- {
- bfd_vma endval;
-
- endval = value;
- if (*string != '\0'
- && info->function_end != (bfd_vma) -1
- && info->function_end < endval)
- endval = info->function_end;
- if (! stab_emit_pending_vars (dhandle, info)
- || ! debug_end_function (dhandle, endval))
- return false;
- info->within_function = false;
- info->function_end = (bfd_vma) -1;
- }
-
- /* An empty string is emitted by gcc at the end of a compilation
- unit. */
- if (*string == '\0')
- return true;
-
- /* Just accumulate strings until we see a non N_SO symbol. If
- the string starts with '/', we discard the previously
- accumulated strings. */
- if (info->so_string == NULL)
- info->so_string = xstrdup (string);
- else
- {
- char *f;
-
- f = info->so_string;
- if (*string == '/')
- info->so_string = xstrdup (string);
- else
- info->so_string = concat (info->so_string, string,
- (const char *) NULL);
- free (f);
- }
-
- info->so_value = value;
-
- break;
-
- case N_SOL:
- /* Start an include file. */
- if (! debug_start_source (dhandle, string))
- return false;
- break;
-
- case N_BINCL:
- /* Start an include file which may be replaced. */
- push_bincl (info, string, value);
- if (! debug_start_source (dhandle, string))
- return false;
- break;
-
- case N_EINCL:
- /* End an N_BINCL include. */
- if (! debug_start_source (dhandle, pop_bincl (info)))
- return false;
- break;
-
- case N_EXCL:
- /* This is a duplicate of a header file named by N_BINCL which
- was eliminated by the linker. */
- if (! find_excl (info, string, value))
- return false;
- break;
-
- case N_SLINE:
- if (! debug_record_line (dhandle, desc,
- value + info->function_start_offset))
- return false;
- break;
-
- case N_BCOMM:
- if (! debug_start_common_block (dhandle, string))
- return false;
- break;
-
- case N_ECOMM:
- if (! debug_end_common_block (dhandle, string))
- return false;
- break;
-
- case N_FUN:
- if (*string == '\0')
- {
- if (info->within_function)
- {
- /* This always marks the end of a function; we don't
- need to worry about info->function_end. */
- if (info->sections)
- value += info->function_start_offset;
- if (! stab_emit_pending_vars (dhandle, info)
- || ! debug_end_function (dhandle, value))
- return false;
- info->within_function = false;
- info->function_end = (bfd_vma) -1;
- }
- break;
- }
-
- /* A const static symbol in the .text section will have an N_FUN
- entry. We need to use these to mark the end of the function,
- in case we are looking at gcc output before it was changed to
- always emit an empty N_FUN. We can't call debug_end_function
- here, because it might be a local static symbol. */
- if (info->within_function
- && (info->function_end == (bfd_vma) -1
- || value < info->function_end))
- info->function_end = value;
-
- /* Fall through. */
- /* FIXME: gdb checks the string for N_STSYM, N_LCSYM or N_ROSYM
- symbols, and if it does not start with :S, gdb relocates the
- value to the start of the section. gcc always seems to use
- :S, so we don't worry about this. */
- /* Fall through. */
- default:
- {
- const char *colon;
-
- colon = strchr (string, ':');
- if (colon != NULL
- && (colon[1] == 'f' || colon[1] == 'F'))
- {
- if (info->within_function)
- {
- bfd_vma endval;
-
- endval = value;
- if (info->function_end != (bfd_vma) -1
- && info->function_end < endval)
- endval = info->function_end;
- if (! stab_emit_pending_vars (dhandle, info)
- || ! debug_end_function (dhandle, endval))
- return false;
- info->function_end = (bfd_vma) -1;
- }
- /* For stabs in sections, line numbers and block addresses
- are offsets from the start of the function. */
- if (info->sections)
- info->function_start_offset = value;
- info->within_function = true;
- }
-
- if (! parse_stab_string (dhandle, info, type, desc, value, string))
- return false;
- }
- break;
-
- case N_OPT:
- if (string != NULL && strcmp (string, "gcc2_compiled.") == 0)
- info->gcc_compiled = 2;
- else if (string != NULL && strcmp (string, "gcc_compiled.") == 0)
- info->gcc_compiled = 1;
- else
- info->n_opt_found = true;
- break;
-
- case N_OBJ:
- case N_ENDM:
- case N_MAIN:
- break;
- }
-
- return true;
-}
-
-/* Parse the stabs string. */
-
-static boolean
-parse_stab_string (dhandle, info, stabtype, desc, value, string)
- PTR dhandle;
- struct stab_handle *info;
- int stabtype;
- int desc;
- bfd_vma value;
- const char *string;
-{
- const char *p;
- char *name;
- int type;
- debug_type dtype;
- boolean synonym;
- unsigned int lineno;
- debug_type *slot;
-
- p = strchr (string, ':');
- if (p == NULL)
- return true;
-
- while (p[1] == ':')
- {
- p += 2;
- p = strchr (p, ':');
- if (p == NULL)
- {
- bad_stab (string);
- return false;
- }
- }
-
- /* GCC 2.x puts the line number in desc. SunOS apparently puts in
- the number of bytes occupied by a type or object, which we
- ignore. */
- if (info->gcc_compiled >= 2)
- lineno = desc;
- else
- lineno = 0;
-
- /* FIXME: Sometimes the special C++ names start with '.'. */
- name = NULL;
- if (string[0] == '$')
- {
- switch (string[1])
- {
- case 't':
- name = "this";
- break;
- case 'v':
- /* Was: name = "vptr"; */
- break;
- case 'e':
- name = "eh_throw";
- break;
- case '_':
- /* This was an anonymous type that was never fixed up. */
- break;
- case 'X':
- /* SunPRO (3.0 at least) static variable encoding. */
- break;
- default:
- warn_stab (string, "unknown C++ encoded name");
- break;
- }
- }
-
- if (name == NULL)
- {
- if (p == string || (string[0] == ' ' && p == string + 1))
- name = NULL;
- else
- name = savestring (string, p - string);
- }
-
- ++p;
- if (isdigit ((unsigned char) *p) || *p == '(' || *p == '-')
- type = 'l';
- else
- type = *p++;
-
- switch (type)
- {
- case 'c':
- /* c is a special case, not followed by a type-number.
- SYMBOL:c=iVALUE for an integer constant symbol.
- SYMBOL:c=rVALUE for a floating constant symbol.
- SYMBOL:c=eTYPE,INTVALUE for an enum constant symbol.
- e.g. "b:c=e6,0" for "const b = blob1"
- (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */
- if (*p != '=')
- {
- bad_stab (string);
- return false;
- }
- ++p;
- switch (*p++)
- {
- case 'r':
- /* Floating point constant. */
- if (! debug_record_float_const (dhandle, name, atof (p)))
- return false;
- break;
- case 'i':
- /* Integer constant. */
- /* Defining integer constants this way is kind of silly,
- since 'e' constants allows the compiler to give not only
- the value, but the type as well. C has at least int,
- long, unsigned int, and long long as constant types;
- other languages probably should have at least unsigned as
- well as signed constants. */
- if (! debug_record_int_const (dhandle, name, atoi (p)))
- return false;
- break;
- case 'e':
- /* SYMBOL:c=eTYPE,INTVALUE for a constant symbol whose value
- can be represented as integral.
- e.g. "b:c=e6,0" for "const b = blob1"
- (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL,
- &p, (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (*p != ',')
- {
- bad_stab (string);
- return false;
- }
- if (! debug_record_typed_const (dhandle, name, dtype, atoi (p)))
- return false;
- break;
- default:
- bad_stab (string);
- return false;
- }
-
- break;
-
- case 'C':
- /* The name of a caught exception. */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL,
- &p, (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! debug_record_label (dhandle, name, dtype, value))
- return false;
- break;
-
- case 'f':
- case 'F':
- /* A function definition. */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! debug_record_function (dhandle, name, dtype, type == 'F', value))
- return false;
-
- /* Sun acc puts declared types of arguments here. We don't care
- about their actual types (FIXME -- we should remember the whole
- function prototype), but the list may define some new types
- that we have to remember, so we must scan it now. */
- while (*p == ';')
- {
- ++p;
- if (parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL)
- == DEBUG_TYPE_NULL)
- return false;
- }
-
- break;
-
- case 'G':
- {
- char leading;
- long c;
- asymbol **ps;
-
- /* A global symbol. The value must be extracted from the
- symbol table. */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- leading = bfd_get_symbol_leading_char (info->abfd);
- for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps)
- {
- const char *n;
-
- n = bfd_asymbol_name (*ps);
- if (leading != '\0' && *n == leading)
- ++n;
- if (*n == *name && strcmp (n, name) == 0)
- break;
- }
- if (c > 0)
- value = bfd_asymbol_value (*ps);
- if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_GLOBAL,
- value))
- return false;
- }
- break;
-
- /* This case is faked by a conditional above, when there is no
- code letter in the dbx data. Dbx data never actually
- contains 'l'. */
- case 'l':
- case 's':
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL,
- value))
- return false;
- break;
-
- case 'p':
- /* A function parameter. */
- if (*p != 'F')
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- else
- {
- /* pF is a two-letter code that means a function parameter in
- Fortran. The type-number specifies the type of the return
- value. Translate it into a pointer-to-function type. */
- ++p;
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype != DEBUG_TYPE_NULL)
- {
- debug_type ftype;
-
- ftype = debug_make_function_type (dhandle, dtype,
- (debug_type *) NULL, false);
- dtype = debug_make_pointer_type (dhandle, ftype);
- }
- }
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_STACK,
- value))
- return false;
-
- /* FIXME: At this point gdb considers rearranging the parameter
- address on a big endian machine if it is smaller than an int.
- We have no way to do that, since we don't really know much
- about the target. */
-
- break;
-
- case 'P':
- if (stabtype == N_FUN)
- {
- /* Prototype of a function referenced by this file. */
- while (*p == ';')
- {
- ++p;
- if (parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL)
- == DEBUG_TYPE_NULL)
- return false;
- }
- break;
- }
- /* Fall through. */
- case 'R':
- /* Parameter which is in a register. */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REG,
- value))
- return false;
- break;
-
- case 'r':
- /* Register variable (either global or local). */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_REGISTER,
- value))
- return false;
-
- /* FIXME: At this point gdb checks to combine pairs of 'p' and
- 'r' stabs into a single 'P' stab. */
-
- break;
-
- case 'S':
- /* Static symbol at top level of file */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_STATIC,
- value))
- return false;
- break;
-
- case 't':
- /* A typedef. */
- dtype = parse_stab_type (dhandle, info, name, &p, &slot);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (name == NULL)
- {
- /* A nameless type. Nothing to do. */
- return true;
- }
-
- dtype = debug_name_type (dhandle, name, dtype);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
-
- if (slot != NULL)
- *slot = dtype;
-
- break;
-
- case 'T':
- /* Struct, union, or enum tag. For GNU C++, this can be be followed
- by 't' which means we are typedef'ing it as well. */
- if (*p != 't')
- {
- synonym = false;
- /* FIXME: gdb sets synonym to true if the current language
- is C++. */
- }
- else
- {
- synonym = true;
- ++p;
- }
-
- dtype = parse_stab_type (dhandle, info, name, &p, &slot);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (name == NULL)
- return true;
-
- dtype = debug_tag_type (dhandle, name, dtype);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (slot != NULL)
- *slot = dtype;
-
- /* See if we have a cross reference to this tag which we can now
- fill in. */
- {
- register struct stab_tag **pst;
-
- for (pst = &info->tags; *pst != NULL; pst = &(*pst)->next)
- {
- if ((*pst)->name[0] == name[0]
- && strcmp ((*pst)->name, name) == 0)
- {
- (*pst)->slot = dtype;
- *pst = (*pst)->next;
- break;
- }
- }
- }
-
- if (synonym)
- {
- dtype = debug_name_type (dhandle, name, dtype);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
-
- if (slot != NULL)
- *slot = dtype;
- }
-
- break;
-
- case 'V':
- /* Static symbol of local scope */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- /* FIXME: gdb checks os9k_stabs here. */
- if (! stab_record_variable (dhandle, info, name, dtype,
- DEBUG_LOCAL_STATIC, value))
- return false;
- break;
-
- case 'v':
- /* Reference parameter. */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REFERENCE,
- value))
- return false;
- break;
-
- case 'a':
- /* Reference parameter which is in a register. */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REF_REG,
- value))
- return false;
- break;
-
- case 'X':
- /* This is used by Sun FORTRAN for "function result value".
- Sun claims ("dbx and dbxtool interfaces", 2nd ed)
- that Pascal uses it too, but when I tried it Pascal used
- "x:3" (local symbol) instead. */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
- (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return false;
- if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL,
- value))
- return false;
- break;
-
- default:
- bad_stab (string);
- return false;
- }
-
- /* FIXME: gdb converts structure values to structure pointers in a
- couple of cases, depending upon the target. */
-
- return true;
-}
-
-/* Parse a stabs type. The typename argument is non-NULL if this is a
- typedef or a tag definition. The pp argument points to the stab
- string, and is updated. The slotp argument points to a place to
- store the slot used if the type is being defined. */
-
-static debug_type
-parse_stab_type (dhandle, info, typename, pp, slotp)
- PTR dhandle;
- struct stab_handle *info;
- const char *typename;
- const char **pp;
- debug_type **slotp;
-{
- const char *orig;
- int typenums[2];
- int size;
- boolean stringp;
- int descriptor;
- debug_type dtype;
-
- if (slotp != NULL)
- *slotp = NULL;
-
- orig = *pp;
-
- size = -1;
- stringp = false;
-
- /* Read type number if present. The type number may be omitted.
- for instance in a two-dimensional array declared with type
- "ar1;1;10;ar1;1;10;4". */
- if (! isdigit ((unsigned char) **pp) && **pp != '(' && **pp != '-')
- {
- /* 'typenums=' not present, type is anonymous. Read and return
- the definition, but don't put it in the type vector. */
- typenums[0] = typenums[1] = -1;
- }
- else
- {
- if (! parse_stab_type_number (pp, typenums))
- return DEBUG_TYPE_NULL;
-
- if (**pp != '=')
- {
- /* Type is not being defined here. Either it already
- exists, or this is a forward reference to it. */
- return stab_find_type (dhandle, info, typenums);
- }
-
- /* Only set the slot if the type is being defined. This means
- that the mapping from type numbers to types will only record
- the name of the typedef which defines a type. If we don't do
- this, then something like
- typedef int foo;
- int i;
- will record that i is of type foo. Unfortunately, stabs
- information is ambiguous about variable types. For this code,
- typedef int foo;
- int i;
- foo j;
- the stabs information records both i and j as having the same
- type. This could be fixed by patching the compiler. */
- if (slotp != NULL && typenums[0] >= 0 && typenums[1] >= 0)
- *slotp = stab_find_slot (info, typenums);
-
- /* Type is being defined here. */
- /* Skip the '='. */
- ++*pp;
-
- while (**pp == '@')
- {
- const char *p = *pp + 1;
- const char *attr;
-
- if (isdigit ((unsigned char) *p) || *p == '(' || *p == '-')
- {
- /* Member type. */
- break;
- }
-
- /* Type attributes. */
- attr = p;
-
- for (; *p != ';'; ++p)
- {
- if (*p == '\0')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- }
- *pp = p + 1;
-
- switch (*attr)
- {
- case 's':
- size = atoi (attr + 1);
- if (size <= 0)
- size = -1;
- break;
-
- case 'S':
- stringp = true;
- break;
-
- default:
- /* Ignore unrecognized type attributes, so future
- compilers can invent new ones. */
- break;
- }
- }
- }
-
- descriptor = **pp;
- ++*pp;
-
- switch (descriptor)
- {
- case 'x':
- {
- enum debug_type_kind code;
- const char *q1, *q2, *p;
-
- /* A cross reference to another type. */
-
- switch (**pp)
- {
- case 's':
- code = DEBUG_KIND_STRUCT;
- break;
- case 'u':
- code = DEBUG_KIND_UNION;
- break;
- case 'e':
- code = DEBUG_KIND_ENUM;
- break;
- default:
- /* Complain and keep going, so compilers can invent new
- cross-reference types. */
- warn_stab (orig, "unrecognized cross reference type");
- code = DEBUG_KIND_STRUCT;
- break;
- }
- ++*pp;
-
- q1 = strchr (*pp, '<');
- p = strchr (*pp, ':');
- if (p == NULL)
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- while (q1 != NULL && p > q1 && p[1] == ':')
- {
- q2 = strchr (q1, '>');
- if (q2 == NULL || q2 < p)
- break;
- p += 2;
- p = strchr (p, ':');
- if (p == NULL)
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- }
-
- dtype = stab_find_tagged_type (dhandle, info, *pp, p - *pp, code);
-
- *pp = p + 1;
- }
- break;
-
- case '-':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '(':
- {
- const char *hold;
- int xtypenums[2];
-
- /* This type is defined as another type. */
-
- (*pp)--;
- hold = *pp;
-
- /* Peek ahead at the number to detect void. */
- if (! parse_stab_type_number (pp, xtypenums))
- return DEBUG_TYPE_NULL;
-
- if (typenums[0] == xtypenums[0] && typenums[1] == xtypenums[1])
- {
- /* This type is being defined as itself, which means that
- it is void. */
- dtype = debug_make_void_type (dhandle);
- }
- else
- {
- *pp = hold;
-
- /* Go back to the number and have parse_stab_type get it.
- This means that we can deal with something like
- t(1,2)=(3,4)=... which the Lucid compiler uses. */
- dtype = parse_stab_type (dhandle, info, (const char *) NULL,
- pp, (debug_type **) NULL);
- if (dtype == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
- }
-
- if (typenums[0] != -1)
- {
- if (! stab_record_type (dhandle, info, typenums, dtype))
- return DEBUG_TYPE_NULL;
- }
-
- break;
- }
-
- case '*':
- dtype = debug_make_pointer_type (dhandle,
- parse_stab_type (dhandle, info,
- (const char *) NULL,
- pp,
- (debug_type **) NULL));
- break;
-
- case '&':
- /* Reference to another type. */
- dtype = (debug_make_reference_type
- (dhandle,
- parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL)));
- break;
-
- case 'f':
- /* Function returning another type. */
- /* FIXME: gdb checks os9k_stabs here. */
- dtype = (debug_make_function_type
- (dhandle,
- parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL),
- (debug_type *) NULL, false));
- break;
-
- case 'k':
- /* Const qualifier on some type (Sun). */
- /* FIXME: gdb accepts 'c' here if os9k_stabs. */
- dtype = debug_make_const_type (dhandle,
- parse_stab_type (dhandle, info,
- (const char *) NULL,
- pp,
- (debug_type **) NULL));
- break;
-
- case 'B':
- /* Volatile qual on some type (Sun). */
- /* FIXME: gdb accepts 'i' here if os9k_stabs. */
- dtype = (debug_make_volatile_type
- (dhandle,
- parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL)));
- break;
-
- case '@':
- /* Offset (class & variable) type. This is used for a pointer
- relative to an object. */
- {
- debug_type domain;
- debug_type memtype;
-
- /* Member type. */
-
- domain = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- if (domain == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
-
- if (**pp != ',')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- memtype = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- if (memtype == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
-
- dtype = debug_make_offset_type (dhandle, domain, memtype);
- }
- break;
-
- case '#':
- /* Method (class & fn) type. */
- if (**pp == '#')
- {
- debug_type return_type;
-
- ++*pp;
- return_type = parse_stab_type (dhandle, info, (const char *) NULL,
- pp, (debug_type **) NULL);
- if (return_type == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
- dtype = debug_make_method_type (dhandle, return_type,
- DEBUG_TYPE_NULL,
- (debug_type *) NULL, false);
- }
- else
- {
- debug_type domain;
- debug_type return_type;
- debug_type *args;
- unsigned int n;
- unsigned int alloc;
- boolean varargs;
-
- domain = parse_stab_type (dhandle, info, (const char *) NULL,
- pp, (debug_type **) NULL);
- if (domain == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
-
- if (**pp != ',')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- return_type = parse_stab_type (dhandle, info, (const char *) NULL,
- pp, (debug_type **) NULL);
- if (return_type == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
-
- alloc = 10;
- args = (debug_type *) xmalloc (alloc * sizeof *args);
- n = 0;
- while (**pp != ';')
- {
- if (**pp != ',')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- if (n + 1 >= alloc)
- {
- alloc += 10;
- args = ((debug_type *)
- xrealloc ((PTR) args, alloc * sizeof *args));
- }
-
- args[n] = parse_stab_type (dhandle, info, (const char *) NULL,
- pp, (debug_type **) NULL);
- if (args[n] == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
- ++n;
- }
- ++*pp;
-
- /* If the last type is not void, then this function takes a
- variable number of arguments. Otherwise, we must strip
- the void type. */
- if (n == 0
- || debug_get_type_kind (dhandle, args[n - 1]) != DEBUG_KIND_VOID)
- varargs = true;
- else
- {
- --n;
- varargs = false;
- }
-
- args[n] = DEBUG_TYPE_NULL;
-
- dtype = debug_make_method_type (dhandle, return_type, domain, args,
- varargs);
- }
- break;
-
- case 'r':
- /* Range type. */
- dtype = parse_stab_range_type (dhandle, info, typename, pp, typenums);
- break;
-
- case 'b':
- /* FIXME: gdb checks os9k_stabs here. */
- /* Sun ACC builtin int type. */
- dtype = parse_stab_sun_builtin_type (dhandle, pp);
- break;
-
- case 'R':
- /* Sun ACC builtin float type. */
- dtype = parse_stab_sun_floating_type (dhandle, pp);
- break;
-
- case 'e':
- /* Enumeration type. */
- dtype = parse_stab_enum_type (dhandle, pp);
- break;
-
- case 's':
- case 'u':
- /* Struct or union type. */
- dtype = parse_stab_struct_type (dhandle, info, typename, pp,
- descriptor == 's', typenums);
- break;
-
- case 'a':
- /* Array type. */
- if (**pp != 'r')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- dtype = parse_stab_array_type (dhandle, info, pp, stringp);
- break;
-
- case 'S':
- dtype = debug_make_set_type (dhandle,
- parse_stab_type (dhandle, info,
- (const char *) NULL,
- pp,
- (debug_type **) NULL),
- stringp);
- break;
-
- default:
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
-
- if (dtype == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
-
- if (typenums[0] != -1)
- {
- if (! stab_record_type (dhandle, info, typenums, dtype))
- return DEBUG_TYPE_NULL;
- }
-
- if (size != -1)
- {
- if (! debug_record_type_size (dhandle, dtype, (unsigned int) size))
- return DEBUG_TYPE_NULL;
- }
-
- return dtype;
-}
-
-/* Read a number by which a type is referred to in dbx data, or
- perhaps read a pair (FILENUM, TYPENUM) in parentheses. Just a
- single number N is equivalent to (0,N). Return the two numbers by
- storing them in the vector TYPENUMS. */
-
-static boolean
-parse_stab_type_number (pp, typenums)
- const char **pp;
- int *typenums;
-{
- const char *orig;
-
- orig = *pp;
-
- if (**pp != '(')
- {
- typenums[0] = 0;
- typenums[1] = (int) parse_number (pp, (boolean *) NULL);
- }
- else
- {
- ++*pp;
- typenums[0] = (int) parse_number (pp, (boolean *) NULL);
- if (**pp != ',')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
- typenums[1] = (int) parse_number (pp, (boolean *) NULL);
- if (**pp != ')')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
- }
-
- return true;
-}
-
-/* Parse a range type. */
-
-static debug_type
-parse_stab_range_type (dhandle, info, typename, pp, typenums)
- PTR dhandle;
- struct stab_handle *info;
- const char *typename;
- const char **pp;
- const int *typenums;
-{
- const char *orig;
- int rangenums[2];
- boolean self_subrange;
- debug_type index_type;
- const char *s2, *s3;
- bfd_signed_vma n2, n3;
- boolean ov2, ov3;
-
- orig = *pp;
-
- index_type = DEBUG_TYPE_NULL;
-
- /* First comes a type we are a subrange of.
- In C it is usually 0, 1 or the type being defined. */
- if (! parse_stab_type_number (pp, rangenums))
- return DEBUG_TYPE_NULL;
-
- self_subrange = (rangenums[0] == typenums[0]
- && rangenums[1] == typenums[1]);
-
- if (**pp == '=')
- {
- *pp = orig;
- index_type = parse_stab_type (dhandle, info, (const char *) NULL,
- pp, (debug_type **) NULL);
- if (index_type == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
- }
-
- if (**pp == ';')
- ++*pp;
-
- /* The remaining two operands are usually lower and upper bounds of
- the range. But in some special cases they mean something else. */
- s2 = *pp;
- n2 = parse_number (pp, &ov2);
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- s3 = *pp;
- n3 = parse_number (pp, &ov3);
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- if (ov2 || ov3)
- {
- /* gcc will emit range stabs for long long types. Handle this
- as a special case. FIXME: This needs to be more general. */
-#define LLLOW "01000000000000000000000;"
-#define LLHIGH "0777777777777777777777;"
-#define ULLHIGH "01777777777777777777777;"
- if (index_type == DEBUG_TYPE_NULL)
- {
- if (strncmp (s2, LLLOW, sizeof LLLOW - 1) == 0
- && strncmp (s3, LLHIGH, sizeof LLHIGH - 1) == 0)
- return debug_make_int_type (dhandle, 8, false);
- if (! ov2
- && n2 == 0
- && strncmp (s3, ULLHIGH, sizeof ULLHIGH - 1) == 0)
- return debug_make_int_type (dhandle, 8, true);
- }
-
- warn_stab (orig, "numeric overflow");
- }
-
- if (index_type == DEBUG_TYPE_NULL)
- {
- /* A type defined as a subrange of itself, with both bounds 0,
- is void. */
- if (self_subrange && n2 == 0 && n3 == 0)
- return debug_make_void_type (dhandle);
-
- /* A type defined as a subrange of itself, with n2 positive and
- n3 zero, is a complex type, and n2 is the number of bytes. */
- if (self_subrange && n3 == 0 && n2 > 0)
- return debug_make_complex_type (dhandle, n2);
-
- /* If n3 is zero and n2 is positive, this is a floating point
- type, and n2 is the number of bytes. */
- if (n3 == 0 && n2 > 0)
- return debug_make_float_type (dhandle, n2);
-
- /* If the upper bound is -1, this is an unsigned int. */
- if (n2 == 0 && n3 == -1)
- {
- /* When gcc is used with -gstabs, but not -gstabs+, it will emit
- long long int:t6=r1;0;-1;
- long long unsigned int:t7=r1;0;-1;
- We hack here to handle this reasonably. */
- if (typename != NULL)
- {
- if (strcmp (typename, "long long int") == 0)
- return debug_make_int_type (dhandle, 8, false);
- else if (strcmp (typename, "long long unsigned int") == 0)
- return debug_make_int_type (dhandle, 8, true);
- }
- /* FIXME: The size here really depends upon the target. */
- return debug_make_int_type (dhandle, 4, true);
- }
-
- /* A range of 0 to 127 is char. */
- if (self_subrange && n2 == 0 && n3 == 127)
- return debug_make_int_type (dhandle, 1, false);
-
- /* FIXME: gdb checks for the language CHILL here. */
-
- if (n2 == 0)
- {
- if (n3 < 0)
- return debug_make_int_type (dhandle, - n3, true);
- else if (n3 == 0xff)
- return debug_make_int_type (dhandle, 1, true);
- else if (n3 == 0xffff)
- return debug_make_int_type (dhandle, 2, true);
- /* -1 is used for the upper bound of (4 byte) "unsigned int"
- and "unsigned long", and we already checked for that, so
- don't need to test for it here. */
- }
- else if (n3 == 0
- && n2 < 0
- && (self_subrange || n2 == -8))
- return debug_make_int_type (dhandle, - n2, true);
- else if (n2 == - n3 - 1)
- {
- if (n3 == 0x7f)
- return debug_make_int_type (dhandle, 1, false);
- else if (n3 == 0x7fff)
- return debug_make_int_type (dhandle, 2, false);
- else if (n3 == 0x7fffffff)
- return debug_make_int_type (dhandle, 4, false);
- }
- }
-
- /* At this point I don't have the faintest idea how to deal with a
- self_subrange type; I'm going to assume that this is used as an
- idiom, and that all of them are special cases. So . . . */
- if (self_subrange)
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
-
- index_type = stab_find_type (dhandle, info, rangenums);
- if (index_type == DEBUG_TYPE_NULL)
- {
- /* Does this actually ever happen? Is that why we are worrying
- about dealing with it rather than just calling error_type? */
- warn_stab (orig, "missing index type");
- index_type = debug_make_int_type (dhandle, 4, false);
- }
-
- return debug_make_range_type (dhandle, index_type, n2, n3);
-}
-
-/* Sun's ACC uses a somewhat saner method for specifying the builtin
- typedefs in every file (for int, long, etc):
-
- type = b <signed> <width>; <offset>; <nbits>
- signed = u or s. Possible c in addition to u or s (for char?).
- offset = offset from high order bit to start bit of type.
- width is # bytes in object of this type, nbits is # bits in type.
-
- The width/offset stuff appears to be for small objects stored in
- larger ones (e.g. `shorts' in `int' registers). We ignore it for now,
- FIXME. */
-
-static debug_type
-parse_stab_sun_builtin_type (dhandle, pp)
- PTR dhandle;
- const char **pp;
-{
- const char *orig;
- boolean unsignedp;
- bfd_vma bits;
-
- orig = *pp;
-
- switch (**pp)
- {
- case 's':
- unsignedp = false;
- break;
- case 'u':
- unsignedp = true;
- break;
- default:
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- /* For some odd reason, all forms of char put a c here. This is strange
- because no other type has this honor. We can safely ignore this because
- we actually determine 'char'acterness by the number of bits specified in
- the descriptor. */
- if (**pp == 'c')
- ++*pp;
-
- /* The first number appears to be the number of bytes occupied
- by this type, except that unsigned short is 4 instead of 2.
- Since this information is redundant with the third number,
- we will ignore it. */
- (void) parse_number (pp, (boolean *) NULL);
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- /* The second number is always 0, so ignore it too. */
- (void) parse_number (pp, (boolean *) NULL);
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- /* The third number is the number of bits for this type. */
- bits = parse_number (pp, (boolean *) NULL);
-
- /* The type *should* end with a semicolon. If it are embedded
- in a larger type the semicolon may be the only way to know where
- the type ends. If this type is at the end of the stabstring we
- can deal with the omitted semicolon (but we don't have to like
- it). Don't bother to complain(), Sun's compiler omits the semicolon
- for "void". */
- if (**pp == ';')
- ++*pp;
-
- if (bits == 0)
- return debug_make_void_type (dhandle);
-
- return debug_make_int_type (dhandle, bits / 8, unsignedp);
-}
-
-/* Parse a builtin floating type generated by the Sun compiler. */
-
-static debug_type
-parse_stab_sun_floating_type (dhandle, pp)
- PTR dhandle;
- const char **pp;
-{
- const char *orig;
- bfd_vma details;
- bfd_vma bytes;
-
- orig = *pp;
-
- /* The first number has more details about the type, for example
- FN_COMPLEX. */
- details = parse_number (pp, (boolean *) NULL);
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
-
- /* The second number is the number of bytes occupied by this type */
- bytes = parse_number (pp, (boolean *) NULL);
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
-
- if (details == NF_COMPLEX
- || details == NF_COMPLEX16
- || details == NF_COMPLEX32)
- return debug_make_complex_type (dhandle, bytes);
-
- return debug_make_float_type (dhandle, bytes);
-}
-
-/* Handle an enum type. */
-
-static debug_type
-parse_stab_enum_type (dhandle, pp)
- PTR dhandle;
- const char **pp;
-{
- const char *orig;
- const char **names;
- bfd_signed_vma *values;
- unsigned int n;
- unsigned int alloc;
-
- orig = *pp;
-
- /* FIXME: gdb checks os9k_stabs here. */
-
- /* The aix4 compiler emits an extra field before the enum members;
- my guess is it's a type of some sort. Just ignore it. */
- if (**pp == '-')
- {
- while (**pp != ':')
- ++*pp;
- ++*pp;
- }
-
- /* Read the value-names and their values.
- The input syntax is NAME:VALUE,NAME:VALUE, and so on.
- A semicolon or comma instead of a NAME means the end. */
- alloc = 10;
- names = (const char **) xmalloc (alloc * sizeof *names);
- values = (bfd_signed_vma *) xmalloc (alloc * sizeof *values);
- n = 0;
- while (**pp != '\0' && **pp != ';' && **pp != ',')
- {
- const char *p;
- char *name;
- bfd_signed_vma val;
-
- p = *pp;
- while (*p != ':')
- ++p;
-
- name = savestring (*pp, p - *pp);
-
- *pp = p + 1;
- val = (bfd_signed_vma) parse_number (pp, (boolean *) NULL);
- if (**pp != ',')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- if (n + 1 >= alloc)
- {
- alloc += 10;
- names = ((const char **)
- xrealloc ((PTR) names, alloc * sizeof *names));
- values = ((bfd_signed_vma *)
- xrealloc ((PTR) values, alloc * sizeof *values));
- }
-
- names[n] = name;
- values[n] = val;
- ++n;
- }
-
- names[n] = NULL;
- values[n] = 0;
-
- if (**pp == ';')
- ++*pp;
-
- return debug_make_enum_type (dhandle, names, values);
-}
-
-/* Read the description of a structure (or union type) and return an object
- describing the type.
-
- PP points to a character pointer that points to the next unconsumed token
- in the the stabs string. For example, given stabs "A:T4=s4a:1,0,32;;",
- *PP will point to "4a:1,0,32;;". */
-
-static debug_type
-parse_stab_struct_type (dhandle, info, tagname, pp, structp, typenums)
- PTR dhandle;
- struct stab_handle *info;
- const char *tagname;
- const char **pp;
- boolean structp;
- const int *typenums;
-{
- const char *orig;
- bfd_vma size;
- debug_baseclass *baseclasses;
- debug_field *fields;
- boolean statics;
- debug_method *methods;
- debug_type vptrbase;
- boolean ownvptr;
-
- orig = *pp;
-
- /* Get the size. */
- size = parse_number (pp, (boolean *) NULL);
-
- /* Get the other information. */
- if (! parse_stab_baseclasses (dhandle, info, pp, &baseclasses)
- || ! parse_stab_struct_fields (dhandle, info, pp, &fields, &statics)
- || ! parse_stab_members (dhandle, info, tagname, pp, typenums, &methods)
- || ! parse_stab_tilde_field (dhandle, info, pp, typenums, &vptrbase,
- &ownvptr))
- return DEBUG_TYPE_NULL;
-
- if (! statics
- && baseclasses == NULL
- && methods == NULL
- && vptrbase == DEBUG_TYPE_NULL
- && ! ownvptr)
- return debug_make_struct_type (dhandle, structp, size, fields);
-
- return debug_make_object_type (dhandle, structp, size, fields, baseclasses,
- methods, vptrbase, ownvptr);
-}
-
-/* The stabs for C++ derived classes contain baseclass information which
- is marked by a '!' character after the total size. This function is
- called when we encounter the baseclass marker, and slurps up all the
- baseclass information.
-
- Immediately following the '!' marker is the number of base classes that
- the class is derived from, followed by information for each base class.
- For each base class, there are two visibility specifiers, a bit offset
- to the base class information within the derived class, a reference to
- the type for the base class, and a terminating semicolon.
-
- A typical example, with two base classes, would be "!2,020,19;0264,21;".
- ^^ ^ ^ ^ ^ ^ ^
- Baseclass information marker __________________|| | | | | | |
- Number of baseclasses __________________________| | | | | | |
- Visibility specifiers (2) ________________________| | | | | |
- Offset in bits from start of class _________________| | | | |
- Type number for base class ___________________________| | | |
- Visibility specifiers (2) _______________________________| | |
- Offset in bits from start of class ________________________| |
- Type number of base class ____________________________________|
-
- Return true for success, false for failure. */
-
-static boolean
-parse_stab_baseclasses (dhandle, info, pp, retp)
- PTR dhandle;
- struct stab_handle *info;
- const char **pp;
- debug_baseclass **retp;
-{
- const char *orig;
- unsigned int c, i;
- debug_baseclass *classes;
-
- *retp = NULL;
-
- orig = *pp;
-
- if (**pp != '!')
- {
- /* No base classes. */
- return true;
- }
- ++*pp;
-
- c = (unsigned int) parse_number (pp, (boolean *) NULL);
-
- if (**pp != ',')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
-
- classes = (debug_baseclass *) xmalloc ((c + 1) * sizeof (**retp));
-
- for (i = 0; i < c; i++)
- {
- boolean virtual;
- enum debug_visibility visibility;
- bfd_vma bitpos;
- debug_type type;
-
- switch (**pp)
- {
- case '0':
- virtual = false;
- break;
- case '1':
- virtual = true;
- break;
- default:
- warn_stab (orig, "unknown virtual character for baseclass");
- virtual = false;
- break;
- }
- ++*pp;
-
- switch (**pp)
- {
- case '0':
- visibility = DEBUG_VISIBILITY_PRIVATE;
- break;
- case '1':
- visibility = DEBUG_VISIBILITY_PROTECTED;
- break;
- case '2':
- visibility = DEBUG_VISIBILITY_PUBLIC;
- break;
- default:
- warn_stab (orig, "unknown visibility character for baseclass");
- visibility = DEBUG_VISIBILITY_PUBLIC;
- break;
- }
- ++*pp;
-
- /* The remaining value is the bit offset of the portion of the
- object corresponding to this baseclass. Always zero in the
- absence of multiple inheritance. */
- bitpos = parse_number (pp, (boolean *) NULL);
- if (**pp != ',')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
-
- type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- if (type == DEBUG_TYPE_NULL)
- return false;
-
- classes[i] = debug_make_baseclass (dhandle, type, bitpos, virtual,
- visibility);
- if (classes[i] == DEBUG_BASECLASS_NULL)
- return false;
-
- if (**pp != ';')
- return false;
- ++*pp;
- }
-
- classes[i] = DEBUG_BASECLASS_NULL;
-
- *retp = classes;
-
- return true;
-}
-
-/* Read struct or class data fields. They have the form:
-
- NAME : [VISIBILITY] TYPENUM , BITPOS , BITSIZE ;
-
- At the end, we see a semicolon instead of a field.
-
- In C++, this may wind up being NAME:?TYPENUM:PHYSNAME; for
- a static field.
-
- The optional VISIBILITY is one of:
-
- '/0' (VISIBILITY_PRIVATE)
- '/1' (VISIBILITY_PROTECTED)
- '/2' (VISIBILITY_PUBLIC)
- '/9' (VISIBILITY_IGNORE)
-
- or nothing, for C style fields with public visibility.
-
- Returns 1 for success, 0 for failure. */
-
-static boolean
-parse_stab_struct_fields (dhandle, info, pp, retp, staticsp)
- PTR dhandle;
- struct stab_handle *info;
- const char **pp;
- debug_field **retp;
- boolean *staticsp;
-{
- const char *orig;
- const char *p;
- debug_field *fields;
- unsigned int c;
- unsigned int alloc;
-
- *retp = NULL;
- *staticsp = false;
-
- orig = *pp;
-
- c = 0;
- alloc = 10;
- fields = (debug_field *) xmalloc (alloc * sizeof *fields);
- while (**pp != ';')
- {
- /* FIXME: gdb checks os9k_stabs here. */
-
- p = *pp;
-
- /* Add 1 to c to leave room for NULL pointer at end. */
- if (c + 1 >= alloc)
- {
- alloc += 10;
- fields = ((debug_field *)
- xrealloc ((PTR) fields, alloc * sizeof *fields));
- }
-
- /* If it starts with CPLUS_MARKER it is a special abbreviation,
- unless the CPLUS_MARKER is followed by an underscore, in
- which case it is just the name of an anonymous type, which we
- should handle like any other type name. We accept either '$'
- or '.', because a field name can never contain one of these
- characters except as a CPLUS_MARKER. */
-
- if ((*p == '$' || *p == '.') && p[1] != '_')
- {
- ++*pp;
- if (! parse_stab_cpp_abbrev (dhandle, info, pp, fields + c))
- return false;
- ++c;
- continue;
- }
-
- /* Look for the ':' that separates the field name from the field
- values. Data members are delimited by a single ':', while member
- functions are delimited by a pair of ':'s. When we hit the member
- functions (if any), terminate scan loop and return. */
-
- p = strchr (p, ':');
- if (p == NULL)
- {
- bad_stab (orig);
- return false;
- }
-
- if (p[1] == ':')
- break;
-
- if (! parse_stab_one_struct_field (dhandle, info, pp, p, fields + c,
- staticsp))
- return false;
-
- ++c;
- }
-
- fields[c] = DEBUG_FIELD_NULL;
-
- *retp = fields;
-
- return true;
-}
-
-/* Special GNU C++ name. */
-
-static boolean
-parse_stab_cpp_abbrev (dhandle, info, pp, retp)
- PTR dhandle;
- struct stab_handle *info;
- const char **pp;
- debug_field *retp;
-{
- const char *orig;
- int cpp_abbrev;
- debug_type context;
- const char *name;
- const char *typename;
- debug_type type;
- bfd_vma bitpos;
-
- *retp = DEBUG_FIELD_NULL;
-
- orig = *pp;
-
- if (**pp != 'v')
- {
- bad_stab (*pp);
- return false;
- }
- ++*pp;
-
- cpp_abbrev = **pp;
- ++*pp;
-
- /* At this point, *pp points to something like "22:23=*22...", where
- the type number before the ':' is the "context" and everything
- after is a regular type definition. Lookup the type, find it's
- name, and construct the field name. */
-
- context = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- if (context == DEBUG_TYPE_NULL)
- return false;
-
- switch (cpp_abbrev)
- {
- case 'f':
- /* $vf -- a virtual function table pointer. */
- name = "_vptr$";
- break;
- case 'b':
- /* $vb -- a virtual bsomethingorother */
- typename = debug_get_type_name (dhandle, context);
- if (typename == NULL)
- {
- warn_stab (orig, "unnamed $vb type");
- typename = "FOO";
- }
- name = concat ("_vb$", typename, (const char *) NULL);
- break;
- default:
- warn_stab (orig, "unrecognized C++ abbreviation");
- name = "INVALID_CPLUSPLUS_ABBREV";
- break;
- }
-
- if (**pp != ':')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
-
- type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- if (**pp != ',')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
-
- bitpos = parse_number (pp, (boolean *) NULL);
- if (**pp != ';')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
-
- *retp = debug_make_field (dhandle, name, type, bitpos, 0,
- DEBUG_VISIBILITY_PRIVATE);
- if (*retp == DEBUG_FIELD_NULL)
- return false;
-
- return true;
-}
-
-/* Parse a single field in a struct or union. */
-
-static boolean
-parse_stab_one_struct_field (dhandle, info, pp, p, retp, staticsp)
- PTR dhandle;
- struct stab_handle *info;
- const char **pp;
- const char *p;
- debug_field *retp;
- boolean *staticsp;
-{
- const char *orig;
- char *name;
- enum debug_visibility visibility;
- debug_type type;
- bfd_vma bitpos;
- bfd_vma bitsize;
-
- orig = *pp;
-
- /* FIXME: gdb checks ARM_DEMANGLING here. */
-
- name = savestring (*pp, p - *pp);
-
- *pp = p + 1;
-
- if (**pp != '/')
- visibility = DEBUG_VISIBILITY_PUBLIC;
- else
- {
- ++*pp;
- switch (**pp)
- {
- case '0':
- visibility = DEBUG_VISIBILITY_PRIVATE;
- break;
- case '1':
- visibility = DEBUG_VISIBILITY_PROTECTED;
- break;
- case '2':
- visibility = DEBUG_VISIBILITY_PUBLIC;
- break;
- default:
- warn_stab (orig, "unknown visibility character for field");
- visibility = DEBUG_VISIBILITY_PUBLIC;
- break;
- }
- ++*pp;
- }
-
- type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- if (type == DEBUG_TYPE_NULL)
- return false;
-
- if (**pp == ':')
- {
- char *varname;
-
- /* This is a static class member. */
- ++*pp;
- p = strchr (*pp, ';');
- if (p == NULL)
- {
- bad_stab (orig);
- return false;
- }
-
- varname = savestring (*pp, p - *pp);
-
- *pp = p + 1;
-
- *retp = debug_make_static_member (dhandle, name, type, varname,
- visibility);
- *staticsp = true;
-
- return true;
- }
-
- if (**pp != ',')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
-
- bitpos = parse_number (pp, (boolean *) NULL);
- if (**pp != ',')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
-
- bitsize = parse_number (pp, (boolean *) NULL);
- if (**pp != ';')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
-
- if (bitpos == 0 && bitsize == 0)
- {
- /* This can happen in two cases: (1) at least for gcc 2.4.5 or
- so, it is a field which has been optimized out. The correct
- stab for this case is to use VISIBILITY_IGNORE, but that is a
- recent invention. (2) It is a 0-size array. For example
- union { int num; char str[0]; } foo. Printing "<no value>"
- for str in "p foo" is OK, since foo.str (and thus foo.str[3])
- will continue to work, and a 0-size array as a whole doesn't
- have any contents to print.
-
- I suspect this probably could also happen with gcc -gstabs
- (not -gstabs+) for static fields, and perhaps other C++
- extensions. Hopefully few people use -gstabs with gdb, since
- it is intended for dbx compatibility. */
- visibility = DEBUG_VISIBILITY_IGNORE;
- }
-
- /* FIXME: gdb does some stuff here to mark fields as unpacked. */
-
- *retp = debug_make_field (dhandle, name, type, bitpos, bitsize, visibility);
-
- return true;
-}
-
-/* Read member function stabs info for C++ classes. The form of each member
- function data is:
-
- NAME :: TYPENUM[=type definition] ARGS : PHYSNAME ;
-
- An example with two member functions is:
-
- afunc1::20=##15;:i;2A.;afunc2::20:i;2A.;
-
- For the case of overloaded operators, the format is op$::*.funcs, where
- $ is the CPLUS_MARKER (usually '$'), `*' holds the place for an operator
- name (such as `+=') and `.' marks the end of the operator name. */
-
-static boolean
-parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
- PTR dhandle;
- struct stab_handle *info;
- const char *tagname;
- const char **pp;
- const int *typenums;
- debug_method **retp;
-{
- const char *orig;
- debug_method *methods;
- unsigned int c;
- unsigned int alloc;
-
- *retp = NULL;
-
- orig = *pp;
-
- alloc = 0;
- methods = NULL;
- c = 0;
-
- while (**pp != ';')
- {
- const char *p;
- char *name;
- debug_method_variant *variants;
- unsigned int cvars;
- unsigned int allocvars;
- debug_type look_ahead_type;
-
- p = strchr (*pp, ':');
- if (p == NULL || p[1] != ':')
- break;
-
- /* FIXME: Some systems use something other than '$' here. */
- if ((*pp)[0] != 'o' || (*pp)[1] != 'p' || (*pp)[2] != '$')
- {
- name = savestring (*pp, p - *pp);
- *pp = p + 2;
- }
- else
- {
- /* This is a completely wierd case. In order to stuff in the
- names that might contain colons (the usual name delimiter),
- Mike Tiemann defined a different name format which is
- signalled if the identifier is "op$". In that case, the
- format is "op$::XXXX." where XXXX is the name. This is
- used for names like "+" or "=". YUUUUUUUK! FIXME! */
- *pp = p + 2;
- for (p = *pp; *p != '.' && *p != '\0'; p++)
- ;
- if (*p != '.')
- {
- bad_stab (orig);
- return false;
- }
- name = savestring (*pp, p - *pp);
- *pp = p + 1;
- }
-
- allocvars = 10;
- variants = ((debug_method_variant *)
- xmalloc (allocvars * sizeof *variants));
- cvars = 0;
-
- look_ahead_type = DEBUG_TYPE_NULL;
-
- do
- {
- debug_type type;
- boolean stub;
- char *argtypes;
- enum debug_visibility visibility;
- boolean constp, volatilep, staticp;
- bfd_vma voffset;
- debug_type context;
- const char *physname;
- boolean varargs;
-
- if (look_ahead_type != DEBUG_TYPE_NULL)
- {
- /* g++ version 1 kludge */
- type = look_ahead_type;
- look_ahead_type = DEBUG_TYPE_NULL;
- }
- else
- {
- type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- if (type == DEBUG_TYPE_NULL)
- return false;
- if (**pp != ':')
- {
- bad_stab (orig);
- return false;
- }
- }
-
- ++*pp;
- p = strchr (*pp, ';');
- if (p == NULL)
- {
- bad_stab (orig);
- return false;
- }
-
- stub = false;
- if (debug_get_type_kind (dhandle, type) == DEBUG_KIND_METHOD
- && debug_get_parameter_types (dhandle, type, &varargs) == NULL)
- stub = true;
-
- argtypes = savestring (*pp, p - *pp);
- *pp = p + 1;
-
- switch (**pp)
- {
- case '0':
- visibility = DEBUG_VISIBILITY_PRIVATE;
- break;
- case '1':
- visibility = DEBUG_VISIBILITY_PROTECTED;
- break;
- default:
- visibility = DEBUG_VISIBILITY_PUBLIC;
- break;
- }
- ++*pp;
-
- constp = false;
- volatilep = false;
- switch (**pp)
- {
- case 'A':
- /* Normal function. */
- ++*pp;
- break;
- case 'B':
- /* const member function. */
- constp = true;
- ++*pp;
- break;
- case 'C':
- /* volatile member function. */
- volatilep = true;
- ++*pp;
- break;
- case 'D':
- /* const volatile member function. */
- constp = true;
- volatilep = true;
- ++*pp;
- break;
- case '*':
- case '?':
- case '.':
- /* File compiled with g++ version 1; no information. */
- break;
- default:
- warn_stab (orig, "const/volatile indicator missing");
- break;
- }
-
- staticp = false;
- switch (**pp)
- {
- case '*':
- /* virtual member function, followed by index. The sign
- bit is supposedly set to distinguish
- pointers-to-methods from virtual function indicies. */
- ++*pp;
- voffset = parse_number (pp, (boolean *) NULL);
- if (**pp != ';')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
- voffset &= 0x7fffffff;
-
- if (**pp == ';' || *pp == '\0')
- {
- /* Must be g++ version 1. */
- context = DEBUG_TYPE_NULL;
- }
- else
- {
- /* Figure out from whence this virtual function
- came. It may belong to virtual function table of
- one of its baseclasses. */
- look_ahead_type = parse_stab_type (dhandle, info,
- (const char *) NULL,
- pp,
- (debug_type **) NULL);
- if (**pp == ':')
- {
- /* g++ version 1 overloaded methods. */
- context = DEBUG_TYPE_NULL;
- }
- else
- {
- context = look_ahead_type;
- look_ahead_type = DEBUG_TYPE_NULL;
- if (**pp != ';')
- {
- bad_stab (orig);
- return false;
- }
- ++*pp;
- }
- }
- break;
-
- case '?':
- /* static member function. */
- ++*pp;
- staticp = true;
- voffset = 0;
- context = DEBUG_TYPE_NULL;
- if (strncmp (argtypes, name, strlen (name)) != 0)
- stub = true;
- break;
-
- default:
- warn_stab (orig, "member function type missing");
- voffset = 0;
- context = DEBUG_TYPE_NULL;
- break;
-
- case '.':
- ++*pp;
- voffset = 0;
- context = DEBUG_TYPE_NULL;
- break;
- }
-
- /* If the type is not a stub, then the argtypes string is
- the physical name of the function. Otherwise the
- argtypes string is the mangled form of the argument
- types, and the full type and the physical name must be
- extracted from them. */
- if (! stub)
- physname = argtypes;
- else
- {
- debug_type class_type, return_type;
-
- class_type = stab_find_type (dhandle, info, typenums);
- if (class_type == DEBUG_TYPE_NULL)
- return false;
- return_type = debug_get_return_type (dhandle, type);
- if (return_type == DEBUG_TYPE_NULL)
- {
- bad_stab (orig);
- return false;
- }
- type = parse_stab_argtypes (dhandle, info, class_type, name,
- tagname, return_type, argtypes,
- constp, volatilep, &physname);
- if (type == DEBUG_TYPE_NULL)
- return false;
- }
-
- if (cvars + 1 >= allocvars)
- {
- allocvars += 10;
- variants = ((debug_method_variant *)
- xrealloc ((PTR) variants,
- allocvars * sizeof *variants));
- }
-
- if (! staticp)
- variants[cvars] = debug_make_method_variant (dhandle, physname,
- type, visibility,
- constp, volatilep,
- voffset, context);
- else
- variants[cvars] = debug_make_static_method_variant (dhandle,
- physname,
- type,
- visibility,
- constp,
- volatilep);
- if (variants[cvars] == DEBUG_METHOD_VARIANT_NULL)
- return false;
-
- ++cvars;
- }
- while (**pp != ';' && **pp != '\0');
-
- variants[cvars] = DEBUG_METHOD_VARIANT_NULL;
-
- if (**pp != '\0')
- ++*pp;
-
- if (c + 1 >= alloc)
- {
- alloc += 10;
- methods = ((debug_method *)
- xrealloc ((PTR) methods, alloc * sizeof *methods));
- }
-
- methods[c] = debug_make_method (dhandle, name, variants);
-
- ++c;
- }
-
- if (methods != NULL)
- methods[c] = DEBUG_METHOD_NULL;
-
- *retp = methods;
-
- return true;
-}
-
-/* Parse a string representing argument types for a method. Stabs
- tries to save space by packing argument types into a mangled
- string. This string should give us enough information to extract
- both argument types and the physical name of the function, given
- the tag name. */
-
-static debug_type
-parse_stab_argtypes (dhandle, info, class_type, fieldname, tagname,
- return_type, argtypes, constp, volatilep, pphysname)
- PTR dhandle;
- struct stab_handle *info;
- debug_type class_type;
- const char *fieldname;
- const char *tagname;
- debug_type return_type;
- const char *argtypes;
- boolean constp;
- boolean volatilep;
- const char **pphysname;
-{
- boolean is_full_physname_constructor;
- boolean is_constructor;
- boolean is_destructor;
- debug_type *args;
- boolean varargs;
-
- /* Constructors are sometimes handled specially. */
- is_full_physname_constructor = ((argtypes[0] == '_'
- && argtypes[1] == '_'
- && (isdigit ((unsigned char) argtypes[2])
- || argtypes[2] == 'Q'
- || argtypes[2] == 't'))
- || strncmp (argtypes, "__ct", 4) == 0);
-
- is_constructor = (is_full_physname_constructor
- || (tagname != NULL
- && strcmp (fieldname, tagname) == 0));
- is_destructor = ((argtypes[0] == '_'
- && (argtypes[1] == '$' || argtypes[1] == '.')
- && argtypes[2] == '_')
- || strncmp (argtypes, "__dt", 4) == 0);
-
- if (is_destructor || is_full_physname_constructor)
- *pphysname = argtypes;
- else
- {
- unsigned int len;
- const char *const_prefix;
- const char *volatile_prefix;
- char buf[20];
- unsigned int mangled_name_len;
- char *physname;
-
- len = tagname == NULL ? 0 : strlen (tagname);
- const_prefix = constp ? "C" : "";
- volatile_prefix = volatilep ? "V" : "";
-
- if (len == 0)
- sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
- else if (tagname != NULL && strchr (tagname, '<') != NULL)
- {
- /* Template methods are fully mangled. */
- sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
- tagname = NULL;
- len = 0;
- }
- else
- sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);
-
- mangled_name_len = ((is_constructor ? 0 : strlen (fieldname))
- + strlen (buf)
- + len
- + strlen (argtypes)
- + 1);
-
- if (fieldname[0] == 'o'
- && fieldname[1] == 'p'
- && (fieldname[2] == '$' || fieldname[2] == '.'))
- {
- const char *opname;
-
- opname = cplus_mangle_opname (fieldname + 3, 0);
- if (opname == NULL)
- {
- fprintf (stderr, "No mangling for \"%s\"\n", fieldname);
- return DEBUG_TYPE_NULL;
- }
- mangled_name_len += strlen (opname);
- physname = (char *) xmalloc (mangled_name_len);
- strncpy (physname, fieldname, 3);
- strcpy (physname + 3, opname);
- }
- else
- {
- physname = (char *) xmalloc (mangled_name_len);
- if (is_constructor)
- physname[0] = '\0';
- else
- strcpy (physname, fieldname);
- }
-
- strcat (physname, buf);
- if (tagname != NULL)
- strcat (physname, tagname);
- strcat (physname, argtypes);
-
- *pphysname = physname;
- }
-
- if (*argtypes == '\0' || is_destructor)
- {
- args = (debug_type *) xmalloc (sizeof *args);
- *args = NULL;
- return debug_make_method_type (dhandle, return_type, class_type, args,
- false);
- }
-
- args = stab_demangle_argtypes (dhandle, info, *pphysname, &varargs);
- if (args == NULL)
- return DEBUG_TYPE_NULL;
-
- return debug_make_method_type (dhandle, return_type, class_type, args,
- varargs);
-}
-
-/* The tail end of stabs for C++ classes that contain a virtual function
- pointer contains a tilde, a %, and a type number.
- The type number refers to the base class (possibly this class itself) which
- contains the vtable pointer for the current class.
-
- This function is called when we have parsed all the method declarations,
- so we can look for the vptr base class info. */
-
-static boolean
-parse_stab_tilde_field (dhandle, info, pp, typenums, retvptrbase, retownvptr)
- PTR dhandle;
- struct stab_handle *info;
- const char **pp;
- const int *typenums;
- debug_type *retvptrbase;
- boolean *retownvptr;
-{
- const char *orig;
- const char *hold;
- int vtypenums[2];
-
- *retvptrbase = DEBUG_TYPE_NULL;
- *retownvptr = false;
-
- orig = *pp;
-
- /* If we are positioned at a ';', then skip it. */
- if (**pp == ';')
- ++*pp;
-
- if (**pp != '~')
- return true;
-
- ++*pp;
-
- if (**pp == '=' || **pp == '+' || **pp == '-')
- {
- /* Obsolete flags that used to indicate the presence of
- constructors and/or destructors. */
- ++*pp;
- }
-
- if (**pp != '%')
- return true;
-
- ++*pp;
-
- hold = *pp;
-
- /* The next number is the type number of the base class (possibly
- our own class) which supplies the vtable for this class. */
- if (! parse_stab_type_number (pp, vtypenums))
- return false;
-
- if (vtypenums[0] == typenums[0]
- && vtypenums[1] == typenums[1])
- *retownvptr = true;
- else
- {
- debug_type vtype;
- const char *p;
-
- *pp = hold;
-
- vtype = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- for (p = *pp; *p != ';' && *p != '\0'; p++)
- ;
- if (*p != ';')
- {
- bad_stab (orig);
- return false;
- }
-
- *retvptrbase = vtype;
-
- *pp = p + 1;
- }
-
- return true;
-}
-
-/* Read a definition of an array type. */
-
-static debug_type
-parse_stab_array_type (dhandle, info, pp, stringp)
- PTR dhandle;
- struct stab_handle *info;
- const char **pp;
- boolean stringp;
-{
- const char *orig;
- const char *p;
- int typenums[2];
- debug_type index_type;
- boolean adjustable;
- bfd_signed_vma lower, upper;
- debug_type element_type;
-
- /* Format of an array type:
- "ar<index type>;lower;upper;<array_contents_type>".
- OS9000: "arlower,upper;<array_contents_type>".
-
- Fortran adjustable arrays use Adigits or Tdigits for lower or upper;
- for these, produce a type like float[][]. */
-
- orig = *pp;
-
- /* FIXME: gdb checks os9k_stabs here. */
-
- /* If the index type is type 0, we take it as int. */
- p = *pp;
- if (! parse_stab_type_number (&p, typenums))
- return DEBUG_TYPE_NULL;
- if (typenums[0] == 0 && typenums[1] == 0 && **pp != '=')
- {
- index_type = debug_find_named_type (dhandle, "int");
- if (index_type == DEBUG_TYPE_NULL)
- {
- index_type = debug_make_int_type (dhandle, 4, false);
- if (index_type == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
- }
- *pp = p;
- }
- else
- {
- index_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- }
-
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- adjustable = false;
-
- if (! isdigit ((unsigned char) **pp) && **pp != '-')
- {
- ++*pp;
- adjustable = true;
- }
-
- lower = (bfd_signed_vma) parse_number (pp, (boolean *) NULL);
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- if (! isdigit ((unsigned char) **pp) && **pp != '-')
- {
- ++*pp;
- adjustable = true;
- }
-
- upper = (bfd_signed_vma) parse_number (pp, (boolean *) NULL);
- if (**pp != ';')
- {
- bad_stab (orig);
- return DEBUG_TYPE_NULL;
- }
- ++*pp;
-
- element_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
- (debug_type **) NULL);
- if (element_type == DEBUG_TYPE_NULL)
- return DEBUG_TYPE_NULL;
-
- if (adjustable)
- {
- lower = 0;
- upper = -1;
- }
-
- return debug_make_array_type (dhandle, element_type, index_type, lower,
- upper, stringp);
-}
-
-/* This struct holds information about files we have seen using
- N_BINCL. */
-
-struct bincl_file
-{
- /* The next N_BINCL file. */
- struct bincl_file *next;
- /* The next N_BINCL on the stack. */
- struct bincl_file *next_stack;
- /* The file name. */
- const char *name;
- /* The hash value. */
- bfd_vma hash;
- /* The file index. */
- unsigned int file;
- /* The list of types defined in this file. */
- struct stab_types *file_types;
-};
-
-/* Start a new N_BINCL file, pushing it onto the stack. */
-
-static void
-push_bincl (info, name, hash)
- struct stab_handle *info;
- const char *name;
- bfd_vma hash;
-{
- struct bincl_file *n;
-
- n = (struct bincl_file *) xmalloc (sizeof *n);
- n->next = info->bincl_list;
- n->next_stack = info->bincl_stack;
- n->name = name;
- n->hash = hash;
- n->file = info->files;
- n->file_types = NULL;
- info->bincl_list = n;
- info->bincl_stack = n;
-
- ++info->files;
- info->file_types = ((struct stab_types **)
- xrealloc ((PTR) info->file_types,
- (info->files
- * sizeof *info->file_types)));
- info->file_types[n->file] = NULL;
-}
-
-/* Finish an N_BINCL file, at an N_EINCL, popping the name off the
- stack. */
-
-static const char *
-pop_bincl (info)
- struct stab_handle *info;
-{
- struct bincl_file *o;
-
- o = info->bincl_stack;
- if (o == NULL)
- return info->main_filename;
- info->bincl_stack = o->next_stack;
-
- o->file_types = info->file_types[o->file];
-
- if (info->bincl_stack == NULL)
- return info->main_filename;
- return info->bincl_stack->name;
-}
-
-/* Handle an N_EXCL: get the types from the corresponding N_BINCL. */
-
-static boolean
-find_excl (info, name, hash)
- struct stab_handle *info;
- const char *name;
- bfd_vma hash;
-{
- struct bincl_file *l;
-
- ++info->files;
- info->file_types = ((struct stab_types **)
- xrealloc ((PTR) info->file_types,
- (info->files
- * sizeof *info->file_types)));
-
- for (l = info->bincl_list; l != NULL; l = l->next)
- if (l->hash == hash && strcmp (l->name, name) == 0)
- break;
- if (l == NULL)
- {
- warn_stab (name, "Undefined N_EXCL");
- info->file_types[info->files - 1] = NULL;
- return true;
- }
-
- info->file_types[info->files - 1] = l->file_types;
-
- return true;
-}
-
-/* Handle a variable definition. gcc emits variable definitions for a
- block before the N_LBRAC, so we must hold onto them until we see
- it. The SunPRO compiler emits variable definitions after the
- N_LBRAC, so we can call debug_record_variable immediately. */
-
-static boolean
-stab_record_variable (dhandle, info, name, type, kind, val)
- PTR dhandle;
- struct stab_handle *info;
- const char *name;
- debug_type type;
- enum debug_var_kind kind;
- bfd_vma val;
-{
- struct stab_pending_var *v;
-
- if ((kind == DEBUG_GLOBAL || kind == DEBUG_STATIC)
- || ! info->within_function
- || (info->gcc_compiled == 0 && info->n_opt_found))
- return debug_record_variable (dhandle, name, type, kind, val);
-
- v = (struct stab_pending_var *) xmalloc (sizeof *v);
- memset (v, 0, sizeof *v);
-
- v->next = info->pending;
- v->name = name;
- v->type = type;
- v->kind = kind;
- v->val = val;
- info->pending = v;
-
- return true;
-}
-
-/* Emit pending variable definitions. This is called after we see the
- N_LBRAC that starts the block. */
-
-static boolean
-stab_emit_pending_vars (dhandle, info)
- PTR dhandle;
- struct stab_handle *info;
-{
- struct stab_pending_var *v;
-
- v = info->pending;
- while (v != NULL)
- {
- struct stab_pending_var *next;
-
- if (! debug_record_variable (dhandle, v->name, v->type, v->kind, v->val))
- return false;
-
- next = v->next;
- free (v);
- v = next;
- }
-
- info->pending = NULL;
-
- return true;
-}
-
-/* Find the slot for a type in the database. */
-
-static debug_type *
-stab_find_slot (info, typenums)
- struct stab_handle *info;
- const int *typenums;
-{
- int filenum;
- int index;
- struct stab_types **ps;
-
- filenum = typenums[0];
- index = typenums[1];
-
- if (filenum < 0 || (unsigned int) filenum >= info->files)
- {
- fprintf (stderr, "Type file number %d out of range\n", filenum);
- return NULL;
- }
- if (index < 0)
- {
- fprintf (stderr, "Type index number %d out of range\n", index);
- return NULL;
- }
-
- ps = info->file_types + filenum;
-
- while (index >= STAB_TYPES_SLOTS)
- {
- if (*ps == NULL)
- {
- *ps = (struct stab_types *) xmalloc (sizeof **ps);
- memset (*ps, 0, sizeof **ps);
- }
- ps = &(*ps)->next;
- index -= STAB_TYPES_SLOTS;
- }
- if (*ps == NULL)
- {
- *ps = (struct stab_types *) xmalloc (sizeof **ps);
- memset (*ps, 0, sizeof **ps);
- }
-
- return (*ps)->types + index;
-}
-
-/* Find a type given a type number. If the type has not been
- allocated yet, create an indirect type. */
-
-static debug_type
-stab_find_type (dhandle, info, typenums)
- PTR dhandle;
- struct stab_handle *info;
- const int *typenums;
-{
- debug_type *slot;
-
- if (typenums[0] == 0 && typenums[1] < 0)
- {
- /* A negative type number indicates an XCOFF builtin type. */
- return stab_xcoff_builtin_type (dhandle, info, typenums[1]);
- }
-
- slot = stab_find_slot (info, typenums);
- if (slot == NULL)
- return DEBUG_TYPE_NULL;
-
- if (*slot == DEBUG_TYPE_NULL)
- return debug_make_indirect_type (dhandle, slot, (const char *) NULL);
-
- return *slot;
-}
-
-/* Record that a given type number refers to a given type. */
-
-static boolean
-stab_record_type (dhandle, info, typenums, type)
- PTR dhandle;
- struct stab_handle *info;
- const int *typenums;
- debug_type type;
-{
- debug_type *slot;
-
- slot = stab_find_slot (info, typenums);
- if (slot == NULL)
- return false;
-
- /* gdb appears to ignore type redefinitions, so we do as well. */
-
- *slot = type;
-
- return true;
-}
-
-/* Return an XCOFF builtin type. */
-
-static debug_type
-stab_xcoff_builtin_type (dhandle, info, typenum)
- PTR dhandle;
- struct stab_handle *info;
- int typenum;
-{
- debug_type rettype;
- const char *name;
-
- if (typenum >= 0 || typenum < -XCOFF_TYPE_COUNT)
- {
- fprintf (stderr, "Unrecognized XCOFF type %d\n", typenum);
- return DEBUG_TYPE_NULL;
- }
- if (info->xcoff_types[-typenum] != NULL)
- return info->xcoff_types[-typenum];
-
- switch (-typenum)
- {
- case 1:
- /* The size of this and all the other types are fixed, defined
- by the debugging format. */
- name = "int";
- rettype = debug_make_int_type (dhandle, 4, false);
- break;
- case 2:
- name = "char";
- rettype = debug_make_int_type (dhandle, 1, false);
- break;
- case 3:
- name = "short";
- rettype = debug_make_int_type (dhandle, 2, false);
- break;
- case 4:
- name = "long";
- rettype = debug_make_int_type (dhandle, 4, false);
- break;
- case 5:
- name = "unsigned char";
- rettype = debug_make_int_type (dhandle, 1, true);
- break;
- case 6:
- name = "signed char";
- rettype = debug_make_int_type (dhandle, 1, false);
- break;
- case 7:
- name = "unsigned short";
- rettype = debug_make_int_type (dhandle, 2, true);
- break;
- case 8:
- name = "unsigned int";
- rettype = debug_make_int_type (dhandle, 4, true);
- break;
- case 9:
- name = "unsigned";
- rettype = debug_make_int_type (dhandle, 4, true);
- case 10:
- name = "unsigned long";
- rettype = debug_make_int_type (dhandle, 4, true);
- break;
- case 11:
- name = "void";
- rettype = debug_make_void_type (dhandle);
- break;
- case 12:
- /* IEEE single precision (32 bit). */
- name = "float";
- rettype = debug_make_float_type (dhandle, 4);
- break;
- case 13:
- /* IEEE double precision (64 bit). */
- name = "double";
- rettype = debug_make_float_type (dhandle, 8);
- break;
- case 14:
- /* This is an IEEE double on the RS/6000, and different machines
- with different sizes for "long double" should use different
- negative type numbers. See stabs.texinfo. */
- name = "long double";
- rettype = debug_make_float_type (dhandle, 8);
- break;
- case 15:
- name = "integer";
- rettype = debug_make_int_type (dhandle, 4, false);
- break;
- case 16:
- name = "boolean";
- rettype = debug_make_bool_type (dhandle, 4);
- break;
- case 17:
- name = "short real";
- rettype = debug_make_float_type (dhandle, 4);
- break;
- case 18:
- name = "real";
- rettype = debug_make_float_type (dhandle, 8);
- break;
- case 19:
- /* FIXME */
- name = "stringptr";
- rettype = NULL;
- break;
- case 20:
- /* FIXME */
- name = "character";
- rettype = debug_make_int_type (dhandle, 1, true);
- break;
- case 21:
- name = "logical*1";
- rettype = debug_make_bool_type (dhandle, 1);
- break;
- case 22:
- name = "logical*2";
- rettype = debug_make_bool_type (dhandle, 2);
- break;
- case 23:
- name = "logical*4";
- rettype = debug_make_bool_type (dhandle, 4);
- break;
- case 24:
- name = "logical";
- rettype = debug_make_bool_type (dhandle, 4);
- break;
- case 25:
- /* Complex type consisting of two IEEE single precision values. */
- name = "complex";
- rettype = debug_make_complex_type (dhandle, 8);
- break;
- case 26:
- /* Complex type consisting of two IEEE double precision values. */
- name = "double complex";
- rettype = debug_make_complex_type (dhandle, 16);
- break;
- case 27:
- name = "integer*1";
- rettype = debug_make_int_type (dhandle, 1, false);
- break;
- case 28:
- name = "integer*2";
- rettype = debug_make_int_type (dhandle, 2, false);
- break;
- case 29:
- name = "integer*4";
- rettype = debug_make_int_type (dhandle, 4, false);
- break;
- case 30:
- /* FIXME */
- name = "wchar";
- rettype = debug_make_int_type (dhandle, 2, false);
- break;
- case 31:
- name = "long long";
- rettype = debug_make_int_type (dhandle, 8, false);
- break;
- case 32:
- name = "unsigned long long";
- rettype = debug_make_int_type (dhandle, 8, true);
- break;
- case 33:
- name = "logical*8";
- rettype = debug_make_bool_type (dhandle, 8);
- break;
- case 34:
- name = "integer*8";
- rettype = debug_make_int_type (dhandle, 8, false);
- break;
- default:
- abort ();
- }
-
- rettype = debug_name_type (dhandle, name, rettype);
-
- info->xcoff_types[-typenum] = rettype;
-
- return rettype;
-}
-
-/* Find or create a tagged type. */
-
-static debug_type
-stab_find_tagged_type (dhandle, info, p, len, kind)
- PTR dhandle;
- struct stab_handle *info;
- const char *p;
- int len;
- enum debug_type_kind kind;
-{
- char *name;
- debug_type dtype;
- struct stab_tag *st;
-
- name = savestring (p, len);
-
- /* We pass DEBUG_KIND_ILLEGAL because we want all tags in the same
- namespace. This is right for C, and I don't know how to handle
- other languages. FIXME. */
- dtype = debug_find_tagged_type (dhandle, name, DEBUG_KIND_ILLEGAL);
- if (dtype != DEBUG_TYPE_NULL)
- {
- free (name);
- return dtype;
- }
-
- /* We need to allocate an entry on the undefined tag list. */
- for (st = info->tags; st != NULL; st = st->next)
- {
- if (st->name[0] == name[0]
- && strcmp (st->name, name) == 0)
- {
- if (st->kind == DEBUG_KIND_ILLEGAL)
- st->kind = kind;
- free (name);
- break;
- }
- }
- if (st == NULL)
- {
- st = (struct stab_tag *) xmalloc (sizeof *st);
- memset (st, 0, sizeof *st);
-
- st->next = info->tags;
- st->name = name;
- st->kind = kind;
- st->slot = DEBUG_TYPE_NULL;
- st->type = debug_make_indirect_type (dhandle, &st->slot, name);
- info->tags = st;
- }
-
- return st->type;
-}
-
-/* In order to get the correct argument types for a stubbed method, we
- need to extract the argument types from a C++ mangled string.
- Since the argument types can refer back to the return type, this
- means that we must demangle the entire physical name. In gdb this
- is done by calling cplus_demangle and running the results back
- through the C++ expression parser. Since we have no expression
- parser, we must duplicate much of the work of cplus_demangle here.
-
- We assume that GNU style demangling is used, since this is only
- done for method stubs, and only g++ should output that form of
- debugging information. */
-
-/* This structure is used to hold a pointer to type information which
- demangling a string. */
-
-struct stab_demangle_typestring
-{
- /* The start of the type. This is not null terminated. */
- const char *typestring;
- /* The length of the type. */
- unsigned int len;
-};
-
-/* This structure is used to hold information while demangling a
- string. */
-
-struct stab_demangle_info
-{
- /* The debugging information handle. */
- PTR dhandle;
- /* The stab information handle. */
- struct stab_handle *info;
- /* The array of arguments we are building. */
- debug_type *args;
- /* Whether the method takes a variable number of arguments. */
- boolean varargs;
- /* The array of types we have remembered. */
- struct stab_demangle_typestring *typestrings;
- /* The number of typestrings. */
- unsigned int typestring_count;
- /* The number of typestring slots we have allocated. */
- unsigned int typestring_alloc;
-};
-
-static void stab_bad_demangle PARAMS ((const char *));
-static unsigned int stab_demangle_count PARAMS ((const char **));
-static boolean stab_demangle_get_count
- PARAMS ((const char **, unsigned int *));
-static boolean stab_demangle_prefix
- PARAMS ((struct stab_demangle_info *, const char **));
-static boolean stab_demangle_function_name
- PARAMS ((struct stab_demangle_info *, const char **, const char *));
-static boolean stab_demangle_signature
- PARAMS ((struct stab_demangle_info *, const char **));
-static boolean stab_demangle_qualified
- PARAMS ((struct stab_demangle_info *, const char **, debug_type *));
-static boolean stab_demangle_template
- PARAMS ((struct stab_demangle_info *, const char **));
-static boolean stab_demangle_class
- PARAMS ((struct stab_demangle_info *, const char **, const char **));
-static boolean stab_demangle_args
- PARAMS ((struct stab_demangle_info *, const char **, debug_type **,
- boolean *));
-static boolean stab_demangle_arg
- PARAMS ((struct stab_demangle_info *, const char **, debug_type **,
- unsigned int *, unsigned int *));
-static boolean stab_demangle_type
- PARAMS ((struct stab_demangle_info *, const char **, debug_type *));
-static boolean stab_demangle_fund_type
- PARAMS ((struct stab_demangle_info *, const char **, debug_type *));
-static boolean stab_demangle_remember_type
- PARAMS ((struct stab_demangle_info *, const char *, int));
-
-/* Warn about a bad demangling. */
-
-static void
-stab_bad_demangle (s)
- const char *s;
-{
- fprintf (stderr, "bad mangled name `%s'\n", s);
-}
-
-/* Get a count from a stab string. */
-
-static unsigned int
-stab_demangle_count (pp)
- const char **pp;
-{
- unsigned int count;
-
- count = 0;
- while (isdigit ((unsigned char) **pp))
- {
- count *= 10;
- count += **pp - '0';
- ++*pp;
- }
- return count;
-}
-
-/* Require a count in a string. The count may be multiple digits, in
- which case it must end in an underscore. */
-
-static boolean
-stab_demangle_get_count (pp, pi)
- const char **pp;
- unsigned int *pi;
-{
- if (! isdigit ((unsigned char) **pp))
- return false;
-
- *pi = **pp - '0';
- ++*pp;
- if (isdigit ((unsigned char) **pp))
- {
- unsigned int count;
- const char *p;
-
- count = *pi;
- p = *pp;
- do
- {
- count *= 10;
- count += *p - '0';
- ++p;
- }
- while (isdigit ((unsigned char) *p));
- if (*p == '_')
- {
- *pp = p + 1;
- *pi = count;
- }
- }
-
- return true;
-}
-
-/* This function demangles a physical name, returning a NULL
- terminated array of argument types. */
-
-static debug_type *
-stab_demangle_argtypes (dhandle, info, physname, pvarargs)
- PTR dhandle;
- struct stab_handle *info;
- const char *physname;
- boolean *pvarargs;
-{
- struct stab_demangle_info minfo;
-
- minfo.dhandle = dhandle;
- minfo.info = info;
- minfo.args = NULL;
- minfo.varargs = false;
- minfo.typestring_alloc = 10;
- minfo.typestrings = ((struct stab_demangle_typestring *)
- xmalloc (minfo.typestring_alloc
- * sizeof *minfo.typestrings));
- minfo.typestring_count = 0;
-
- /* cplus_demangle checks for special GNU mangled forms, but we can't
- see any of them in mangled method argument types. */
-
- if (! stab_demangle_prefix (&minfo, &physname))
- goto error_return;
-
- if (*physname != '\0')
- {
- if (! stab_demangle_signature (&minfo, &physname))
- goto error_return;
- }
-
- free (minfo.typestrings);
- minfo.typestrings = NULL;
-
- if (minfo.args == NULL)
- fprintf (stderr, "no argument types in mangled string\n");
-
- *pvarargs = minfo.varargs;
- return minfo.args;
-
- error_return:
- if (minfo.typestrings != NULL)
- free (minfo.typestrings);
- return NULL;
-}
-
-/* Demangle the prefix of the mangled name. */
-
-static boolean
-stab_demangle_prefix (minfo, pp)
- struct stab_demangle_info *minfo;
- const char **pp;
-{
- const char *scan;
- unsigned int i;
-
- /* cplus_demangle checks for global constructors and destructors,
- but we can't see them in mangled argument types. */
-
- /* Look for `__'. */
- scan = *pp;
- do
- {
- scan = strchr (scan, '_');
- }
- while (scan != NULL && *++scan != '_');
-
- if (scan == NULL)
- {
- stab_bad_demangle (*pp);
- return false;
- }
-
- --scan;
-
- /* We found `__'; move ahead to the last contiguous `__' pair. */
- i = strspn (scan, "_");
- if (i > 2)
- scan += i - 2;
-
- if (scan == *pp
- && (isdigit ((unsigned char) scan[2])
- || scan[2] == 'Q'
- || scan[2] == 't'))
- {
- /* This is a GNU style constructor name. */
- *pp = scan + 2;
- return true;
- }
- else if (scan == *pp
- && ! isdigit ((unsigned char) scan[2])
- && scan[2] != 't')
- {
- /* Look for the `__' that separates the prefix from the
- signature. */
- while (*scan == '_')
- ++scan;
- scan = strstr (scan, "__");
- if (scan == NULL || scan[2] == '\0')
- {
- stab_bad_demangle (*pp);
- return false;
- }
-
- return stab_demangle_function_name (minfo, pp, scan);
- }
- else if (scan[2] != '\0')
- {
- /* The name doesn't start with `__', but it does contain `__'. */
- return stab_demangle_function_name (minfo, pp, scan);
- }
- else
- {
- stab_bad_demangle (*pp);
- return false;
- }
- /*NOTREACHED*/
-}
-
-/* Demangle a function name prefix. The scan argument points to the
- double underscore which separates the function name from the
- signature. */
-
-static boolean
-stab_demangle_function_name (minfo, pp, scan)
- struct stab_demangle_info *minfo;
- const char **pp;
- const char *scan;
-{
- const char *name;
-
- /* The string from *pp to scan is the name of the function. We
- don't care about the name, since we just looking for argument
- types. However, for conversion operators, the name may include a
- type which we must remember in order to handle backreferences. */
-
- name = *pp;
- *pp = scan + 2;
-
- if (*pp - name >= 5
- && strncmp (name, "type", 4) == 0
- && (name[4] == '$' || name[4] == '.'))
- {
- const char *tem;
-
- /* This is a type conversion operator. */
- tem = name + 5;
- if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL))
- return false;
- }
- else if (name[0] == '_'
- && name[1] == '_'
- && name[2] == 'o'
- && name[3] == 'p')
- {
- const char *tem;
-
- /* This is a type conversion operator. */
- tem = name + 4;
- if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL))
- return false;
- }
-
- return true;
-}
-
-/* Demangle the signature. This is where the argument types are
- found. */
-
-static boolean
-stab_demangle_signature (minfo, pp)
- struct stab_demangle_info *minfo;
- const char **pp;
-{
- const char *orig;
- boolean expect_func, func_done;
- const char *hold;
-
- orig = *pp;
-
- expect_func = false;
- func_done = false;
- hold = NULL;
-
- while (**pp != '\0')
- {
- switch (**pp)
- {
- case 'Q':
- hold = *pp;
- if (! stab_demangle_qualified (minfo, pp, (debug_type *) NULL)
- || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
- return false;
- expect_func = true;
- hold = NULL;
- break;
-
- case 'S':
- /* Static member function. FIXME: Can this happen? */
- if (hold == NULL)
- hold = *pp;
- ++*pp;
- break;
-
- case 'C':
- /* Const member function. */
- if (hold == NULL)
- hold = *pp;
- ++*pp;
- break;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- if (hold == NULL)
- hold = *pp;
- if (! stab_demangle_class (minfo, pp, (const char **) NULL)
- || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
- return false;
- expect_func = true;
- hold = NULL;
- break;
-
- case 'F':
- /* Function. I don't know if this actually happens with g++
- output. */
- hold = NULL;
- func_done = true;
- ++*pp;
- if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
- return false;
- break;
-
- case 't':
- /* Template. */
- if (hold == NULL)
- hold = *pp;
- if (! stab_demangle_template (minfo, pp)
- || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
- return false;
- hold = NULL;
- expect_func = true;
- break;
-
- case '_':
- /* At the outermost level, we cannot have a return type
- specified, so if we run into another '_' at this point we
- are dealing with a mangled name that is either bogus, or
- has been mangled by some algorithm we don't know how to
- deal with. So just reject the entire demangling. */
- stab_bad_demangle (orig);
- return false;
-
- default:
- /* Assume we have stumbled onto the first outermost function
- argument token, and start processing args. */
- func_done = true;
- if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
- return false;
- break;
- }
-
- if (expect_func)
- {
- func_done = true;
- if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
- return false;
- }
- }
-
- if (! func_done)
- {
- /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
- bar__3fooi is 'foo::bar(int)'. We get here when we find the
- first case, and need to ensure that the '(void)' gets added
- to the current declp. */
- if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
- return false;
- }
-
- return true;
-}
-
-/* Demangle a qualified name, such as "Q25Outer5Inner" which is the
- mangled form of "Outer::Inner". */
-
-static boolean
-stab_demangle_qualified (minfo, pp, ptype)
- struct stab_demangle_info *minfo;
- const char **pp;
- debug_type *ptype;
-{
- const char *orig;
- const char *p;
- unsigned int qualifiers;
- debug_type context;
-
- orig = *pp;
-
- switch ((*pp)[1])
- {
- case '_':
- /* GNU mangled name with more than 9 classes. The count is
- preceded by an underscore (to distinguish it from the <= 9
- case) and followed by an underscore. */
- p = *pp + 2;
- if (! isdigit ((unsigned char) *p) || *p == '0')
- {
- stab_bad_demangle (orig);
- return false;
- }
- qualifiers = atoi (p);
- while (isdigit ((unsigned char) *p))
- ++p;
- if (*p != '_')
- {
- stab_bad_demangle (orig);
- return false;
- }
- *pp = p + 1;
- break;
-
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- qualifiers = (*pp)[1] - '0';
- /* Skip an optional underscore after the count. */
- if ((*pp)[2] == '_')
- ++*pp;
- *pp += 2;
- break;
-
- case '0':
- default:
- stab_bad_demangle (orig);
- return false;
- }
-
- context = DEBUG_TYPE_NULL;
-
- /* Pick off the names. */
- while (qualifiers-- > 0)
- {
- if (**pp == '_')
- ++*pp;
- if (**pp == 't')
- {
- /* FIXME: I don't know how to handle the ptype != NULL case
- here. */
- if (! stab_demangle_template (minfo, pp))
- return false;
- }
- else
- {
- unsigned int len;
-
- len = stab_demangle_count (pp);
- if (strlen (*pp) < len)
- {
- stab_bad_demangle (orig);
- return false;
- }
-
- if (ptype != NULL)
- {
- const debug_field *fields;
-
- fields = NULL;
- if (context != DEBUG_TYPE_NULL)
- fields = debug_get_fields (minfo->dhandle, context);
-
- context = DEBUG_TYPE_NULL;
-
- if (fields != NULL)
- {
- char *name;
-
- /* Try to find the type by looking through the
- fields of context until we find a field with the
- same type. This ought to work for a class
- defined within a class, but it won't work for,
- e.g., an enum defined within a class. stabs does
- not give us enough information to figure out the
- latter case. */
-
- name = savestring (*pp, len);
-
- for (; *fields != DEBUG_FIELD_NULL; fields++)
- {
- debug_type ft;
- const char *dn;
-
- ft = debug_get_field_type (minfo->dhandle, *fields);
- if (ft == NULL)
- return false;
- dn = debug_get_type_name (minfo->dhandle, ft);
- if (dn != NULL && strcmp (dn, name) == 0)
- {
- context = ft;
- break;
- }
- }
-
- free (name);
- }
-
- if (context == DEBUG_TYPE_NULL)
- {
- /* We have to fall back on finding the type by name.
- If there are more types to come, then this must
- be a class. Otherwise, it could be anything. */
-
- if (qualifiers == 0)
- {
- char *name;
-
- name = savestring (*pp, len);
- context = debug_find_named_type (minfo->dhandle,
- name);
- free (name);
- }
-
- if (context == DEBUG_TYPE_NULL)
- {
- context = stab_find_tagged_type (minfo->dhandle,
- minfo->info,
- *pp, len,
- (qualifiers == 0
- ? DEBUG_KIND_ILLEGAL
- : DEBUG_KIND_CLASS));
- if (context == DEBUG_TYPE_NULL)
- return false;
- }
- }
- }
-
- *pp += len;
- }
- }
-
- if (ptype != NULL)
- *ptype = context;
-
- return true;
-}
-
-/* Demangle a template. */
-
-static boolean
-stab_demangle_template (minfo, pp)
- struct stab_demangle_info *minfo;
- const char **pp;
-{
- const char *orig;
- unsigned int r, i;
-
- orig = *pp;
-
- ++*pp;
-
- /* Skip the template name. */
- r = stab_demangle_count (pp);
- if (r == 0 || strlen (*pp) < r)
- {
- stab_bad_demangle (orig);
- return false;
- }
- *pp += r;
-
- /* Get the size of the parameter list. */
- if (stab_demangle_get_count (pp, &r) == 0)
- {
- stab_bad_demangle (orig);
- return false;
- }
-
- for (i = 0; i < r; i++)
- {
- if (**pp == 'Z')
- {
- /* This is a type parameter. */
- ++*pp;
- if (! stab_demangle_type (minfo, pp, (debug_type *) NULL))
- return false;
- }
- else
- {
- const char *old_p;
- boolean pointerp, realp, integralp, charp, boolp;
- boolean done;
-
- old_p = *pp;
- pointerp = false;
- realp = false;
- integralp = false;
- charp = false;
- boolp = false;
- done = false;
-
- /* This is a value parameter. */
-
- if (! stab_demangle_type (minfo, pp, (debug_type *) NULL))
- return false;
-
- while (*old_p != '\0' && ! done)
- {
- switch (*old_p)
- {
- case 'P':
- case 'p':
- case 'R':
- pointerp = true;
- done = true;
- break;
- case 'C': /* Const. */
- case 'S': /* Signed. */
- case 'U': /* Unsigned. */
- case 'V': /* Volatile. */
- case 'F': /* Function. */
- case 'M': /* Member function. */
- case 'O': /* ??? */
- ++old_p;
- break;
- case 'Q': /* Qualified name. */
- integralp = true;
- done = true;
- break;
- case 'T': /* Remembered type. */
- abort ();
- case 'v': /* Void. */
- abort ();
- case 'x': /* Long long. */
- case 'l': /* Long. */
- case 'i': /* Int. */
- case 's': /* Short. */
- case 'w': /* Wchar_t. */
- integralp = true;
- done = true;
- break;
- case 'b': /* Bool. */
- boolp = true;
- done = true;
- break;
- case 'c': /* Char. */
- charp = true;
- done = true;
- break;
- case 'r': /* Long double. */
- case 'd': /* Double. */
- case 'f': /* Float. */
- realp = true;
- done = true;
- break;
- default:
- /* Assume it's a user defined integral type. */
- integralp = true;
- done = true;
- break;
- }
- }
-
- if (integralp)
- {
- if (**pp == 'm')
- ++*pp;
- while (isdigit ((unsigned char) **pp))
- ++*pp;
- }
- else if (charp)
- {
- unsigned int val;
-
- if (**pp == 'm')
- ++*pp;
- val = stab_demangle_count (pp);
- if (val == 0)
- {
- stab_bad_demangle (orig);
- return false;
- }
- }
- else if (boolp)
- {
- unsigned int val;
-
- val = stab_demangle_count (pp);
- if (val != 0 && val != 1)
- {
- stab_bad_demangle (orig);
- return false;
- }
- }
- else if (realp)
- {
- if (**pp == 'm')
- ++*pp;
- while (isdigit ((unsigned char) **pp))
- ++*pp;
- if (**pp == '.')
- {
- ++*pp;
- while (isdigit ((unsigned char) **pp))
- ++*pp;
- }
- if (**pp == 'e')
- {
- ++*pp;
- while (isdigit ((unsigned char) **pp))
- ++*pp;
- }
- }
- else if (pointerp)
- {
- unsigned int len;
-
- if (! stab_demangle_get_count (pp, &len))
- {
- stab_bad_demangle (orig);
- return false;
- }
- *pp += len;
- }
- }
- }
-
- return true;
-}
-
-/* Demangle a class name. */
-
-static boolean
-stab_demangle_class (minfo, pp, pstart)
- struct stab_demangle_info *minfo;
- const char **pp;
- const char **pstart;
-{
- const char *orig;
- unsigned int n;
-
- orig = *pp;
-
- n = stab_demangle_count (pp);
- if (strlen (*pp) < n)
- {
- stab_bad_demangle (orig);
- return false;
- }
-
- if (pstart != NULL)
- *pstart = *pp;
-
- *pp += n;
-
- return true;
-}
-
-/* Demangle function arguments. If the pargs argument is not NULL, it
- is set to a NULL terminated array holding the arguments. */
-
-static boolean
-stab_demangle_args (minfo, pp, pargs, pvarargs)
- struct stab_demangle_info *minfo;
- const char **pp;
- debug_type **pargs;
- boolean *pvarargs;
-{
- const char *orig;
- unsigned int alloc, count;
-
- orig = *pp;
-
- alloc = 10;
- if (pargs != NULL)
- {
- *pargs = (debug_type *) xmalloc (alloc * sizeof **pargs);
- *pvarargs = false;
- }
- count = 0;
-
- while (**pp != '_' && **pp != '\0' && **pp != 'e')
- {
- if (**pp == 'N' || **pp == 'T')
- {
- char temptype;
- unsigned int r, t;
-
- temptype = **pp;
- ++*pp;
-
- if (temptype == 'T')
- r = 1;
- else
- {
- if (! stab_demangle_get_count (pp, &r))
- {
- stab_bad_demangle (orig);
- return false;
- }
- }
-
- if (! stab_demangle_get_count (pp, &t))
- {
- stab_bad_demangle (orig);
- return false;
- }
-
- if (t >= minfo->typestring_count)
- {
- stab_bad_demangle (orig);
- return false;
- }
- while (r-- > 0)
- {
- const char *tem;
-
- tem = minfo->typestrings[t].typestring;
- if (! stab_demangle_arg (minfo, &tem, pargs, &count, &alloc))
- return false;
- }
- }
- else
- {
- if (! stab_demangle_arg (minfo, pp, pargs, &count, &alloc))
- return false;
- }
- }
-
- if (pargs != NULL)
- (*pargs)[count] = DEBUG_TYPE_NULL;
-
- if (**pp == 'e')
- {
- if (pargs != NULL)
- *pvarargs = true;
- ++*pp;
- }
-
- return true;
-}
-
-/* Demangle a single argument. */
-
-static boolean
-stab_demangle_arg (minfo, pp, pargs, pcount, palloc)
- struct stab_demangle_info *minfo;
- const char **pp;
- debug_type **pargs;
- unsigned int *pcount;
- unsigned int *palloc;
-{
- const char *start;
- debug_type type;
-
- start = *pp;
- if (! stab_demangle_type (minfo, pp,
- pargs == NULL ? (debug_type *) NULL : &type)
- || ! stab_demangle_remember_type (minfo, start, *pp - start))
- return false;
-
- if (pargs != NULL)
- {
- if (type == DEBUG_TYPE_NULL)
- return false;
-
- if (*pcount + 1 >= *palloc)
- {
- *palloc += 10;
- *pargs = ((debug_type *)
- xrealloc (*pargs, *palloc * sizeof **pargs));
- }
- (*pargs)[*pcount] = type;
- ++*pcount;
- }
-
- return true;
-}
-
-/* Demangle a type. If the ptype argument is not NULL, *ptype is set
- to the newly allocated type. */
-
-static boolean
-stab_demangle_type (minfo, pp, ptype)
- struct stab_demangle_info *minfo;
- const char **pp;
- debug_type *ptype;
-{
- const char *orig;
-
- orig = *pp;
-
- switch (**pp)
- {
- case 'P':
- case 'p':
- /* A pointer type. */
- ++*pp;
- if (! stab_demangle_type (minfo, pp, ptype))
- return false;
- if (ptype != NULL)
- *ptype = debug_make_pointer_type (minfo->dhandle, *ptype);
- break;
-
- case 'R':
- /* A reference type. */
- ++*pp;
- if (! stab_demangle_type (minfo, pp, ptype))
- return false;
- if (ptype != NULL)
- *ptype = debug_make_reference_type (minfo->dhandle, *ptype);
- break;
-
- case 'A':
- /* An array. */
- {
- unsigned long high;
-
- ++*pp;
- high = 0;
- while (**pp != '\0' && **pp != '_')
- {
- if (! isdigit ((unsigned char) **pp))
- {
- stab_bad_demangle (orig);
- return false;
- }
- high *= 10;
- high += **pp - '0';
- ++*pp;
- }
- if (**pp != '_')
- {
- stab_bad_demangle (orig);
- return false;
- }
- ++*pp;
-
- if (! stab_demangle_type (minfo, pp, ptype))
- return false;
- if (ptype != NULL)
- {
- debug_type int_type;
-
- int_type = debug_find_named_type (minfo->dhandle, "int");
- if (int_type == NULL)
- int_type = debug_make_int_type (minfo->dhandle, 4, false);
- *ptype = debug_make_array_type (minfo->dhandle, *ptype, int_type,
- 0, high, false);
- }
- }
- break;
-
- case 'T':
- /* A back reference to a remembered type. */
- {
- unsigned int i;
- const char *p;
-
- ++*pp;
- if (! stab_demangle_get_count (pp, &i))
- {
- stab_bad_demangle (orig);
- return false;
- }
- if (i >= minfo->typestring_count)
- {
- stab_bad_demangle (orig);
- return false;
- }
- p = minfo->typestrings[i].typestring;
- if (! stab_demangle_type (minfo, &p, ptype))
- return false;
- }
- break;
-
- case 'F':
- /* A function. */
- {
- debug_type *args;
- boolean varargs;
-
- ++*pp;
- if (! stab_demangle_args (minfo, pp,
- (ptype == NULL
- ? (debug_type **) NULL
- : &args),
- (ptype == NULL
- ? (boolean *) NULL
- : &varargs)))
- return false;
- if (**pp != '_')
- {
- /* cplus_demangle will accept a function without a return
- type, but I don't know when that will happen, or what
- to do if it does. */
- stab_bad_demangle (orig);
- return false;
- }
- ++*pp;
- if (! stab_demangle_type (minfo, pp, ptype))
- return false;
- if (ptype != NULL)
- *ptype = debug_make_function_type (minfo->dhandle, *ptype, args,
- varargs);
-
- }
- break;
-
- case 'M':
- case 'O':
- {
- boolean memberp, constp, volatilep;
- debug_type *args;
- boolean varargs;
- unsigned int n;
- const char *name;
-
- memberp = **pp == 'M';
- constp = false;
- volatilep = false;
- args = NULL;
- varargs = false;
-
- ++*pp;
- if (! isdigit ((unsigned char) **pp))
- {
- stab_bad_demangle (orig);
- return false;
- }
- n = stab_demangle_count (pp);
- if (strlen (*pp) < n)
- {
- stab_bad_demangle (orig);
- return false;
- }
- name = *pp;
- *pp += n;
-
- if (memberp)
- {
- if (**pp == 'C')
- {
- constp = true;
- ++*pp;
- }
- else if (**pp == 'V')
- {
- volatilep = true;
- ++*pp;
- }
- if (**pp != 'F')
- {
- stab_bad_demangle (orig);
- return false;
- }
- ++*pp;
- if (! stab_demangle_args (minfo, pp,
- (ptype == NULL
- ? (debug_type **) NULL
- : &args),
- (ptype == NULL
- ? (boolean *) NULL
- : &varargs)))
- return false;
- }
-
- if (**pp != '_')
- {
- stab_bad_demangle (orig);
- return false;
- }
- ++*pp;
-
- if (! stab_demangle_type (minfo, pp, ptype))
- return false;
-
- if (ptype != NULL)
- {
- debug_type class_type;
-
- class_type = stab_find_tagged_type (minfo->dhandle, minfo->info,
- name, (int) n,
- DEBUG_KIND_CLASS);
- if (class_type == DEBUG_TYPE_NULL)
- return false;
-
- if (! memberp)
- *ptype = debug_make_offset_type (minfo->dhandle, class_type,
- *ptype);
- else
- {
- /* FIXME: We have no way to record constp or
- volatilep. */
- *ptype = debug_make_method_type (minfo->dhandle, *ptype,
- class_type, args, varargs);
- }
- }
- }
- break;
-
- case 'G':
- ++*pp;
- if (! stab_demangle_type (minfo, pp, ptype))
- return false;
- break;
-
- case 'C':
- ++*pp;
- if (! stab_demangle_type (minfo, pp, ptype))
- return false;
- if (ptype != NULL)
- *ptype = debug_make_const_type (minfo->dhandle, *ptype);
- break;
-
- case 'Q':
- {
- const char *hold;
-
- hold = *pp;
- if (! stab_demangle_qualified (minfo, pp, ptype))
- return false;
- }
- break;
-
- default:
- if (! stab_demangle_fund_type (minfo, pp, ptype))
- return false;
- break;
- }
-
- return true;
-}
-
-/* Demangle a fundamental type. If the ptype argument is not NULL,
- *ptype is set to the newly allocated type. */
-
-static boolean
-stab_demangle_fund_type (minfo, pp, ptype)
- struct stab_demangle_info *minfo;
- const char **pp;
- debug_type *ptype;
-{
- const char *orig;
- boolean constp, volatilep, unsignedp, signedp;
- boolean done;
-
- orig = *pp;
-
- constp = false;
- volatilep = false;
- unsignedp = false;
- signedp = false;
-
- done = false;
- while (! done)
- {
- switch (**pp)
- {
- case 'C':
- constp = true;
- ++*pp;
- break;
-
- case 'U':
- unsignedp = true;
- ++*pp;
- break;
-
- case 'S':
- signedp = true;
- ++*pp;
- break;
-
- case 'V':
- volatilep = true;
- ++*pp;
- break;
-
- default:
- done = true;
- break;
- }
- }
-
- switch (**pp)
- {
- case '\0':
- case '_':
- /* cplus_demangle permits this, but I don't know what it means. */
- stab_bad_demangle (orig);
- break;
-
- case 'v': /* void */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle, "void");
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_void_type (minfo->dhandle);
- }
- ++*pp;
- break;
-
- case 'x': /* long long */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle,
- (unsignedp
- ? "long long unsigned int"
- : "long long int"));
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_int_type (minfo->dhandle, 8, unsignedp);
- }
- ++*pp;
- break;
-
- case 'l': /* long */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle,
- (unsignedp
- ? "long unsigned int"
- : "long int"));
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_int_type (minfo->dhandle, 4, unsignedp);
- }
- ++*pp;
- break;
-
- case 'i': /* int */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle,
- (unsignedp
- ? "unsigned int"
- : "int"));
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_int_type (minfo->dhandle, 4, unsignedp);
- }
- ++*pp;
- break;
-
- case 's': /* short */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle,
- (unsignedp
- ? "short unsigned int"
- : "short int"));
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_int_type (minfo->dhandle, 2, unsignedp);
- }
- ++*pp;
- break;
-
- case 'b': /* bool */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle, "bool");
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_bool_type (minfo->dhandle, 4);
- }
- ++*pp;
- break;
-
- case 'c': /* char */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle,
- (unsignedp
- ? "unsigned char"
- : (signedp
- ? "signed char"
- : "char")));
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_int_type (minfo->dhandle, 1, unsignedp);
- }
- ++*pp;
- break;
-
- case 'w': /* wchar_t */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle, "__wchar_t");
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_int_type (minfo->dhandle, 2, true);
- }
- ++*pp;
- break;
-
- case 'r': /* long double */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle, "long double");
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_float_type (minfo->dhandle, 8);
- }
- ++*pp;
- break;
-
- case 'd': /* double */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle, "double");
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_float_type (minfo->dhandle, 8);
- }
- ++*pp;
- break;
-
- case 'f': /* float */
- if (ptype != NULL)
- {
- *ptype = debug_find_named_type (minfo->dhandle, "float");
- if (*ptype == DEBUG_TYPE_NULL)
- *ptype = debug_make_float_type (minfo->dhandle, 4);
- }
- ++*pp;
- break;
-
- case 'G':
- ++*pp;
- if (! isdigit ((unsigned char) **pp))
- {
- stab_bad_demangle (orig);
- return false;
- }
- /* Fall through. */
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- {
- const char *hold;
-
- if (! stab_demangle_class (minfo, pp, &hold))
- return false;
- if (ptype != NULL)
- {
- char *name;
-
- name = savestring (hold, *pp - hold);
- *ptype = debug_find_named_type (minfo->dhandle, name);
- if (*ptype == DEBUG_TYPE_NULL)
- {
- /* FIXME: It is probably incorrect to assume that
- undefined types are tagged types. */
- *ptype = stab_find_tagged_type (minfo->dhandle, minfo->info,
- hold, *pp - hold,
- DEBUG_KIND_ILLEGAL);
- }
- free (name);
- }
- }
- break;
-
- case 't':
- if (! stab_demangle_template (minfo, pp))
- return false;
- if (ptype != NULL)
- {
- debug_type t;
-
- /* FIXME: I really don't know how a template should be
- represented in the current type system. Perhaps the
- template should be demangled into a string, and the type
- should be represented as a named type. However, I don't
- know what the base type of the named type should be. */
- t = debug_make_void_type (minfo->dhandle);
- t = debug_make_pointer_type (minfo->dhandle, t);
- t = debug_name_type (minfo->dhandle, "TEMPLATE", t);
- *ptype = t;
- }
- break;
-
- default:
- stab_bad_demangle (orig);
- return false;
- }
-
- if (ptype != NULL)
- {
- if (constp)
- *ptype = debug_make_const_type (minfo->dhandle, *ptype);
- if (volatilep)
- *ptype = debug_make_volatile_type (minfo->dhandle, *ptype);
- }
-
- return true;
-}
-
-/* Remember a type string in a demangled string. */
-
-static boolean
-stab_demangle_remember_type (minfo, p, len)
- struct stab_demangle_info *minfo;
- const char *p;
- int len;
-{
- if (minfo->typestring_count >= minfo->typestring_alloc)
- {
- minfo->typestring_alloc += 10;
- minfo->typestrings = ((struct stab_demangle_typestring *)
- xrealloc (minfo->typestrings,
- (minfo->typestring_alloc
- * sizeof *minfo->typestrings)));
- }
-
- minfo->typestrings[minfo->typestring_count].typestring = p;
- minfo->typestrings[minfo->typestring_count].len = (unsigned int) len;
- ++minfo->typestring_count;
-
- return true;
-}
diff --git a/sql/Makefile.am b/sql/Makefile.am
index 0b22481f850..40a3565cb91 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -41,7 +41,6 @@ mysqld_DEPENDENCIES= @mysql_plugin_libs@ $(SUPPORTING_LIBS) libndb.la
LDADD = $(SUPPORTING_LIBS) @ZLIB_LIBS@ @NDB_SCI_LIBS@
mysqld_LDADD = libndb.la \
@MYSQLD_EXTRA_LDFLAGS@ \
- @pstack_libs@ \
@mysql_plugin_libs@ \
$(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ \
$(yassl_libs) $(openssl_libs) @MYSQLD_EXTRA_LIBS@
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index d9c4c7fc3f5..d17ccc47abb 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -70,10 +70,8 @@
#endif
/* stack traces are only supported on linux intel */
-#if defined(__linux__) && defined(__i386__) && defined(USE_PSTACK)
+#if defined(__linux__) && defined(__i386__)
#define HAVE_STACK_TRACE_ON_SEGV
-#include "../pstack/pstack.h"
-char pstack_file_name[80];
#endif /* __linux__ */
/* We have HAVE_purify below as this speeds up the shutdown of MySQL */
@@ -2779,14 +2777,6 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
if (!opt_bootstrap)
create_pid_file();
-#ifdef HAVE_STACK_TRACE_ON_SEGV
- if (opt_do_pstack)
- {
- sprintf(pstack_file_name,"mysqld-%lu-%%d-%%d.backtrace", (ulong)getpid());
- pstack_install_segv_action(pstack_file_name);
- }
-#endif /* HAVE_STACK_TRACE_ON_SEGV */
-
/*
signal to start_signal_handler that we are ready
This works by waiting for start_signal_handler to free mutex,
@@ -5963,9 +5953,10 @@ struct my_option my_long_options[] =
NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
#ifdef HAVE_STACK_TRACE_ON_SEGV
- {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure.",
- &opt_do_pstack, &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0,
- 0, 0, 0, 0},
+ {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure. "
+ "This option is deprecated and has no effect; a symbolic stack trace will "
+ "be printed after a crash whenever possible.", &opt_do_pstack, &opt_do_pstack,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif /* HAVE_STACK_TRACE_ON_SEGV */
{"engine-condition-pushdown",
OPT_ENGINE_CONDITION_PUSHDOWN,
@@ -8654,6 +8645,13 @@ mysqld_get_one_option(int optid,
lower_case_table_names= argument ? atoi(argument) : 1;
lower_case_table_names_used= 1;
break;
+#ifdef HAVE_STACK_TRACE_ON_SEGV
+ case OPT_DO_PSTACK:
+ sql_print_warning("'--enable-pstack' is deprecated and will be removed "
+ "in a future release. A symbolic stack trace will be "
+ "printed after a crash whenever possible.");
+ break;
+#endif
#if defined(ENABLED_DEBUG_SYNC)
case OPT_DEBUG_SYNC_TIMEOUT:
/*