# Makefile for GNU binary-file utilities
-# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
# This file is part of GNU binutils.
SRCONV_PROG=srconv sysdump coffdump
-
-
MANPAGES= ar nm objdump ranlib size strings strip objcopy nlmconv
PROGS = $(SIZE_PROG) $(OBJDUMP_PROG) $(NM_PROG) $(AR_PROG) $(STRINGS_PROG) $(STRIP_PROG) $(RANLIB_PROG) $(DEMANGLER_PROG) $(OBJCOPY_PROG) @BUILD_NLMCONV@ @BUILD_SRCONV@ @BUILD_DLLTOOL@
BFDDIR = $(BASEDIR)/bfd
INCDIR = $(BASEDIR)/include
INCLUDES = -I. -I$(srcdir) -I../bfd -I$(BFDDIR) -I$(INCDIR)
+DEP = mkdep
ALL_CFLAGS = $(INCLUDES) @HDEFINES@ $(CFLAGS)
+HFILES = arsup.h bucomm.h budbg.h coffgrok.h debug.h nlmconv.h
+
+GENERATED_HFILES = arparse.h sysroff.h sysinfo.h defparse.h
+
+CFILES = ar.c arsup.c bucomm.c coffdump.c coffgrok.c debug.c dlltool.c \
+ filemode.c ieee.c is-ranlib.c is-strip.c maybe-ranlib.c \
+ maybe-strip.c nlmconv.c nm.c not-ranlib.c not-strip.c \
+ objcopy.c objdump.c prdbg.c rddbg.c size.c srconv.c stabs.c \
+ strings.c sysdump.c version.c
+
+GENERATED_CFILES = \
+ underscore.c arparse.c arlex.c sysroff.c sysinfo.c syslex.c \
+ defparse.c deflex.c nlmheader.c
+
.c.o:
$(CC) -c $(ALL_CFLAGS) $<
$(NM_PROG): $(ADDL_LIBS) nm.o $(BFD)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(NM_PROG) nm.o $(ADDL_LIBS) $(EXTRALIBS)
-$(OBJDUMP_PROG): $(ADDL_LIBS) objdump.o $(BFD) $(OPCODES)
- $(CC) $(CFLAGS) $(LDFLAGS) -o $(OBJDUMP_PROG) objdump.o $(OPCODES) $(ADDL_LIBS) $(EXTRALIBS)
+OBJDUMP_OBJS = objdump.o rddbg.o debug.o stabs.o ieee.o prdbg.o
+
+$(OBJDUMP_PROG): $(ADDL_LIBS) $(OBJDUMP_OBJS) $(BFD) $(OPCODES)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $(OBJDUMP_PROG) $(OBJDUMP_OBJS) $(OPCODES) $(ADDL_LIBS) $(EXTRALIBS)
+
+underscore.c: stamp-under ; @true
-underscore.c: Makefile
- rm -f underscore.c
+stamp-under: Makefile
echo '/*WARNING: This file is automatically generated!*/' >underscore.t
echo "int prepends_underscore = @UNDERSCORE@;" >>underscore.t
- mv -f underscore.t underscore.c
+ $(srcdir)/../move-if-change underscore.t underscore.c
+ touch stamp-under
version.o: version.c Makefile
$(CC) -DVERSION='"$(VERSION)"' $(ALL_CFLAGS) -c $(srcdir)/version.c
$(CC_FOR_BUILD) -c -I. $(CFLAGS) $(srcdir)/sysinfo.c ; \
fi
-srconv.o: srconv.c sysroff.h sysroff.c coffgrok.h $(INCDIR)/coff/internal.h \
- ../bfd/libcoff.h config.h
-
srconv: srconv.o coffgrok.o $(ADDL_LIBS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ srconv.o coffgrok.o $(ADDL_LIBS) $(EXTRALIBS)
coffdump: coffdump.o coffgrok.o $(ADDL_LIBS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ coffdump.o coffgrok.o $(ADDL_LIBS) $(EXTRALIBS)
-sysdump.o: sysdump.c sysroff.h sysroff.c bucomm.h config.h
-
sysdump: sysdump.o $(ADDL_LIBS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ sysdump.o $(ADDL_LIBS) $(EXTRALIBS)
rm -f nlmheader.c
mv -f y.tab.c nlmheader.c
-nlmconv.o: nlmconv.c
+# coff/sym.h and coff/ecoff.h won't be found by the automatic dependency
+# scripts, since they are only included conditionally.
+nlmconv.o: nlmconv.c $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
ldname=`echo ld | sed '$(program_transform_name)'`; \
$(CC) -c -DLD_NAME="\"$${ldname}\"" @NLMCONV_DEFS@ $(ALL_CFLAGS) $(srcdir)/nlmconv.c
$(NLMCONV_PROG): nlmconv.o nlmheader.o $(ADDL_LIBS) $(BFD)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ nlmconv.o nlmheader.o $(ADDL_LIBS) $(EXTRALIBS)
-# This list of dependencies was generated by doing a make with gcc -MM
-# saving the output in a file and removing the gcc commands
-# changing "../../devo/binutils/../bfd" to "$(BFDDIR)"
-# removing "../../devo/binutils/"
-# changing "../include" to "$(INCDIR)"
-
-bucomm.o: bucomm.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
- $(INCDIR)/obstack.h \
- $(INCDIR)/fopen-same.h bucomm.h config.h
-filemode.o: filemode.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
- $(INCDIR)/obstack.h \
- $(INCDIR)/fopen-same.h
-size.o: size.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
- $(INCDIR)/obstack.h \
- $(INCDIR)/fopen-same.h $(INCDIR)/getopt.h config.h
-objdump.o: objdump.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
- $(INCDIR)/obstack.h \
- $(INCDIR)/fopen-same.h $(INCDIR)/getopt.h \
- $(INCDIR)/dis-asm.h $(INCDIR)/aout/aout64.h \
- $(INCDIR)/elf/internal.h $(INCDIR)/aout/stab.def config.h
-nm.o: nm.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
- $(INCDIR)/obstack.h \
- $(INCDIR)/fopen-same.h bucomm.h config.h $(INCDIR)/getopt.h \
- $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def \
- $(INCDIR)/aout/ranlib.h $(INCDIR)/demangle.h
-ar.o: ar.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
- $(INCDIR)/obstack.h \
- $(INCDIR)/fopen-same.h bucomm.h config.h $(INCDIR)/aout/ar.h \
- $(BFDDIR)/libbfd.h arsup.h
-arparse.o: arparse.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
- $(INCDIR)/obstack.h arsup.h
-arlex.o: arlex.c ./arparse.h
-not-ranlib.o: not-ranlib.c
-arsup.o: arsup.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
- $(INCDIR)/obstack.h arsup.h bucomm.h config.h
-strings.o: strings.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
- $(INCDIR)/obstack.h bucomm.h config.h
-objcopy.o: objcopy.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
- $(INCDIR)/obstack.h \
- $(INCDIR)/fopen-same.h bucomm.h config.h
-is-strip.o: is-strip.c
-is-ranlib.o: is-ranlib.c
-not-strip.o: not-strip.c
-nlmheader.o: nlmheader.c ../bfd/bfd.h \
- $(INCDIR)/fopen-same.h bucomm.h config.h \
- $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h nlmconv.h
-nlmconv.o: nlmconv.c ../bfd/bfd.h $(INCDIR)/libiberty.h \
- $(INCDIR)/fopen-same.h bucomm.h config.h \
- $(BFDDIR)/libnlm.h $(INCDIR)/nlm/common.h \
- $(INCDIR)/nlm/internal.h $(INCDIR)/nlm/external.h nlmconv.h \
- $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
-
-stage1: force
- - mkdir stage1
- - mv -f $(STAGESTUFF) stage1
-
-stage2: force
- - mkdir stage2
- - mv -f $(STAGESTUFF) stage2
-
-stage3: force
- - mkdir stage3
- - mv -f $(STAGESTUFF) stage3
-
-against=stage2
-
-comparison: force
- for i in $(STAGESTUFF) ; do cmp $$i $(against)/$$i ; done
-
-de-stage1: force
- - (cd stage1 ; mv -f * ..)
- - rmdir stage1
-
-de-stage2: force
- - (cd stage2 ; mv -f * ..)
- - rmdir stage2
-
-de-stage3: force
- - (cd stage3 ; mv -f * ..)
- - rmdir stage3
+# Targets to rebuild dependencies in this Makefile.
+# Have to get rid of .dep1 here so that "$?" later includes all of $(CFILES).
+.dep: dep.sed $(CFILES) $(HFILES) $(GENERATED_CFILES) $(GENERATED_HFILES) config.h
+ rm -f .dep1
+ $(MAKE) DEP=$(DEP) .dep1
+ sed -f dep.sed <.dep1 >.dep
+
+# This rule really wants a mkdep that runs "gcc -MM".
+.dep1: $(CFILES) $(GENERATED_CFILES)
+ rm -f .dep2
+ echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep2
+ $(DEP) -f .dep2 $(ALL_CFLAGS) $?
+ $(srcdir)/../move-if-change .dep2 .dep1
+
+dep.sed: dep-in.sed config.status
+ sed <$(srcdir)/dep-in.sed >dep.sed \
+ -e 's!@INCDIR@!$(INCDIR)!' \
+ -e 's!@SRCDIR@!$(srcdir)!'
+
+dep: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < Makefile > tmp-Makefile
+ cat .dep >> tmp-Makefile
+ $(srcdir)/../move-if-change tmp-Makefile Makefile
+
+dep-in: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.in > tmp-Makefile.in
+ cat .dep >> tmp-Makefile.in
+ $(srcdir)/../move-if-change tmp-Makefile.in $(srcdir)/Makefile.in
+
+.PHONY: dep dep-in
###
# DOCUMENTATION TARGETS
-rm -f *.o *~ \#* core binutils.?? binutils.??? y.output config.log
-rm -rf tmpdir
clean: mostlyclean
- -rm -f $(PROGS) underscore.c sysroff sysroff.c sysroff.h sysinfo
+ -rm -f $(PROGS) $(DEMANGLER_PROG).1 stamp-under
+ -rm -f underscore.c sysroff sysroff.c sysroff.h sysinfo dep.sed
distclean:
- -rm -f Makefile config.status *.o *~ \#* core y.* \
- binutils.?? binutils.??s binutils.aux binutils.log binutils.toc
+ -rm -f Makefile config.status *.o *~ \#* core y.*
+ -rm -f binutils.?? binutils.??s binutils.aux binutils.log binutils.toc
-rm -f $(PROGS) underscore.c config.h stamp-h config.cache config.log
+ -rm -f dep.sed stamp-under
maintainer-clean realclean: clean distclean
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
config.status: configure
$(SHELL) ./config.status --recheck
-### Local Variables: ***
-### mode:fundamental ***
-### page-delimiter: "^#\f" ***
-### End: ***
-### end of file
+# What appears below is generated by a hacked mkdep using gcc -MM.
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+
+ar.o: ar.c ../bfd/bfd.h $(INCDIR)/ansidecl.h $(INCDIR)/obstack.h \
+ $(INCDIR)/libiberty.h $(INCDIR)/progress.h bucomm.h \
+ config.h $(INCDIR)/fopen-same.h $(INCDIR)/aout/ar.h \
+ ../bfd/libbfd.h arsup.h
+arsup.o: arsup.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/obstack.h arsup.h $(INCDIR)/libiberty.h bucomm.h \
+ config.h $(INCDIR)/fopen-same.h
+bucomm.o: bucomm.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/obstack.h $(INCDIR)/libiberty.h bucomm.h \
+ config.h $(INCDIR)/fopen-same.h
+coffdump.o: coffdump.c coffgrok.h bucomm.h config.h \
+ $(INCDIR)/fopen-same.h
+coffgrok.o: coffgrok.c bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/coff/internal.h ../bfd/libcoff.h $(INCDIR)/bfdlink.h \
+ coffgrok.h
+debug.o: debug.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/obstack.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/libiberty.h debug.h
+dlltool.o: dlltool.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/obstack.h $(INCDIR)/libiberty.h bucomm.h \
+ config.h $(INCDIR)/fopen-same.h $(INCDIR)/getopt.h \
+ $(INCDIR)/demangle.h
+filemode.o: filemode.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/obstack.h
+ieee.o: ieee.c ../bfd/bfd.h $(INCDIR)/ansidecl.h $(INCDIR)/obstack.h \
+ $(INCDIR)/ieee.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/libiberty.h debug.h budbg.h
+is-ranlib.o: is-ranlib.c
+is-strip.o: is-strip.c
+maybe-ranlib.o: maybe-ranlib.c
+maybe-strip.o: maybe-strip.c
+nlmconv.o: nlmconv.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/obstack.h $(INCDIR)/libiberty.h bucomm.h \
+ config.h $(INCDIR)/fopen-same.h ../bfd/libnlm.h $(INCDIR)/nlm/common.h \
+ $(INCDIR)/nlm/internal.h $(INCDIR)/nlm/external.h nlmconv.h
+nm.o: nm.c ../bfd/bfd.h $(INCDIR)/ansidecl.h $(INCDIR)/obstack.h \
+ $(INCDIR)/progress.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/getopt.h $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def \
+ $(INCDIR)/aout/ranlib.h $(INCDIR)/demangle.h $(INCDIR)/libiberty.h
+not-ranlib.o: not-ranlib.c
+not-strip.o: not-strip.c
+objcopy.o: objcopy.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/obstack.h $(INCDIR)/progress.h bucomm.h config.h \
+ $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h
+objdump.o: objdump.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/obstack.h $(INCDIR)/getopt.h $(INCDIR)/progress.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/dis-asm.h \
+ $(INCDIR)/libiberty.h debug.h budbg.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/aout/stab.def
+prdbg.o: prdbg.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/obstack.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/libiberty.h debug.h budbg.h
+rddbg.o: rddbg.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/obstack.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/libiberty.h debug.h budbg.h
+size.o: size.c ../bfd/bfd.h $(INCDIR)/ansidecl.h $(INCDIR)/obstack.h \
+ $(INCDIR)/getopt.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/libiberty.h
+srconv.o: srconv.c bucomm.h config.h $(INCDIR)/fopen-same.h \
+ sysroff.h coffgrok.h $(INCDIR)/coff/internal.h ../bfd/libcoff.h \
+ $(INCDIR)/bfdlink.h sysroff.c
+stabs.o: stabs.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/obstack.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/libiberty.h debug.h budbg.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
+strings.o: strings.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/obstack.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/libiberty.h
+sysdump.o: sysdump.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/obstack.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ sysroff.h sysroff.c
+version.o: version.c
+underscore.o: underscore.c
+arparse.o: arparse.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/obstack.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ arsup.h
+arlex.o: arlex.c arparse.h
+sysroff.o: sysroff.c
+sysinfo.o: sysinfo.c
+syslex.o: syslex.c sysinfo.h
+defparse.o: defparse.c
+deflex.o: deflex.c defparse.h
+nlmheader.o: nlmheader.c ../bfd/bfd.h $(INCDIR)/obstack.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/nlm/common.h \
+ $(INCDIR)/nlm/internal.h nlmconv.h
+
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
--- /dev/null
+/* ieee.c -- Write out 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;
+};
+
+/* 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;
+};
+
+/* 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;
+ /* If this is a bitfield, this is the size in bits. If this is not
+ a bitfield, this is zero. */
+ unsigned long bitsize;
+ /* If this is a function type ('x' or 'X') this is the return type. */
+ debug_type return_type;
+};
+
+/* 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];
+};
+
+static void ieee_error
+ PARAMS ((bfd *, const bfd_byte *, const bfd_byte *, const char *));
+static void ieee_eof PARAMS ((bfd *));
+static char *savestring PARAMS ((const char *, unsigned long));
+static boolean ieee_read_number
+ PARAMS ((bfd *, const bfd_byte *, const bfd_byte **, const bfd_byte *,
+ bfd_vma *));
+static boolean ieee_read_optional_number
+ PARAMS ((bfd *, const bfd_byte *, const bfd_byte **, const bfd_byte *,
+ bfd_vma *, boolean *));
+static boolean ieee_read_id
+ PARAMS ((bfd *, const bfd_byte *, const bfd_byte **, const bfd_byte *,
+ const char **, unsigned long *));
+static boolean ieee_read_optional_id
+ PARAMS ((bfd *, const bfd_byte *, const bfd_byte **, const bfd_byte *,
+ const char **, unsigned long *, boolean *));
+static boolean ieee_read_expression
+ PARAMS ((bfd *, const bfd_byte *, const bfd_byte **, const bfd_byte *,
+ bfd_vma *));
+static debug_type ieee_builtin_type
+ PARAMS ((PTR, bfd *, struct ieee_types *, const bfd_byte *,
+ const bfd_byte *, unsigned int));
+static boolean ieee_read_type_index
+ PARAMS ((PTR, bfd *, struct ieee_types *, const bfd_byte *,
+ const bfd_byte **, const bfd_byte *, debug_type *));
+static int ieee_regno_to_gen PARAMS ((bfd *, int));
+static boolean parse_ieee_bb
+ PARAMS ((PTR, bfd *, struct ieee_types *, struct ieee_blockstack *,
+ const bfd_byte *, const bfd_byte **, const bfd_byte *));
+static boolean parse_ieee_be
+ PARAMS ((PTR, bfd *, struct ieee_blockstack *, const bfd_byte *,
+ const bfd_byte **, const bfd_byte *));
+static boolean parse_ieee_nn
+ PARAMS ((PTR, bfd *, struct ieee_vars *, const bfd_byte *,
+ const bfd_byte **, const bfd_byte *));
+static boolean parse_ieee_ty
+ PARAMS ((PTR, bfd *, struct ieee_types *, struct ieee_vars *,
+ const bfd_byte *, const bfd_byte **, const bfd_byte *));
+static boolean parse_ieee_atn
+ PARAMS ((PTR, bfd *, struct ieee_types *, struct ieee_vars *, int,
+ const bfd_byte *, const bfd_byte **, const bfd_byte *));
+static boolean ieee_require_asn
+ PARAMS ((bfd *, const bfd_byte *, const bfd_byte **, const bfd_byte *,
+ bfd_vma *));
+
+/* Report an error in the IEEE debugging information. */
+
+static void
+ieee_error (abfd, bytes, p, s)
+ bfd *abfd;
+ const bfd_byte *bytes;
+ const bfd_byte *p;
+ const char *s;
+{
+ if (p != NULL)
+ fprintf (stderr, "%s: 0x%lx: %s (0x%x)\n", bfd_get_filename (abfd),
+ (unsigned long) (p - bytes), s, *p);
+ else
+ fprintf (stderr, "%s: %s\n", bfd_get_filename (abfd), s);
+}
+
+/* Report an unexpected EOF in the IEEE debugging information. */
+
+static void
+ieee_eof (abfd)
+ bfd *abfd;
+{
+ ieee_error (abfd, (const bfd_byte *) NULL, (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 (abfd, bytes, pp, pend, pv)
+ bfd *abfd;
+ const bfd_byte *bytes;
+ const bfd_byte **pp;
+ const bfd_byte *pend;
+ bfd_vma *pv;
+{
+ return ieee_read_optional_number (abfd, bytes, pp, pend, 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 (abfd, bytes, pp, pend, pv, ppresent)
+ bfd *abfd;
+ const bfd_byte *bytes;
+ const bfd_byte **pp;
+ const bfd_byte *pend;
+ bfd_vma *pv;
+ boolean *ppresent;
+{
+ ieee_record_enum_type b;
+
+ if (*pp >= pend)
+ {
+ if (ppresent != NULL)
+ {
+ *ppresent = false;
+ return true;
+ }
+ ieee_eof (abfd);
+ 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 >= pend)
+ {
+ ieee_eof (abfd);
+ 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 (abfd, bytes, *pp - 1, "invalid number");
+ return false;
+}
+
+/* Read a required string from an IEEE file. */
+
+static boolean
+ieee_read_id (abfd, bytes, pp, pend, pname, pnamlen)
+ bfd *abfd;
+ const bfd_byte *bytes;
+ const bfd_byte **pp;
+ const bfd_byte *pend;
+ const char **pname;
+ unsigned long *pnamlen;
+{
+ return ieee_read_optional_id (abfd, bytes, pp, pend, 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 (abfd, bytes, pp, pend, pname, pnamlen, ppresent)
+ bfd *abfd;
+ const bfd_byte *bytes;
+ const bfd_byte **pp;
+ const bfd_byte *pend;
+ const char **pname;
+ unsigned long *pnamlen;
+ boolean *ppresent;
+{
+ bfd_byte b;
+ unsigned long len;
+
+ if (*pp >= pend)
+ {
+ ieee_eof (abfd);
+ 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 (abfd, bytes, *pp - 1, "invalid string length");
+ return false;
+ }
+
+ if ((unsigned long) (pend - *pp) < len)
+ {
+ ieee_eof (abfd);
+ 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 (abfd, bytes, pp, pend, pv)
+ bfd *abfd;
+ const bfd_byte *bytes;
+ const bfd_byte **pp;
+ const bfd_byte *pend;
+ 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 (abfd, bytes, pp, pend, &val, &present))
+ return false;
+
+ if (present)
+ {
+ if (esp - expr_stack >= EXPR_STACK_SIZE)
+ {
+ ieee_error (abfd, bytes, 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 (abfd, bytes, start,
+ "unsupported IEEE expression operator");
+ break;
+
+ case ieee_variable_R_enum:
+ {
+ bfd_vma indx;
+ asection *s;
+
+ if (! ieee_read_number (abfd, bytes, pp, pend, &indx))
+ return false;
+ for (s = abfd->sections; s != NULL; s = s->next)
+ if ((bfd_vma) s->target_index == indx)
+ break;
+ if (s == NULL)
+ {
+ ieee_error (abfd, bytes, start, "unknown section");
+ return false;
+ }
+
+ if (esp - expr_stack >= EXPR_STACK_SIZE)
+ {
+ ieee_error (abfd, bytes, start, "expression stack overflow");
+ return false;
+ }
+
+ *esp++ = bfd_get_section_vma (abfd, s);
+ }
+ break;
+
+ case ieee_function_plus_enum:
+ case ieee_function_minus_enum:
+ {
+ bfd_vma v1, v2;
+
+ if (esp - expr_stack < 2)
+ {
+ ieee_error (abfd, bytes, start, "expression stack underflow");
+ return false;
+ }
+
+ v1 = *--esp;
+ v2 = *--esp;
+ *esp++ = v1 + v2;
+ }
+ break;
+ }
+ }
+
+ if (esp - 1 != expr_stack)
+ {
+ ieee_error (abfd, bytes, expr_start, "expression stack mismatch");
+ return false;
+ }
+
+ *pv = *--esp;
+
+ return true;
+}
+
+/* Return an IEEE builtin type. */
+
+static debug_type
+ieee_builtin_type (dhandle, abfd, types, bytes, p, indx)
+ PTR dhandle;
+ bfd *abfd;
+ struct ieee_types *types;
+ const bfd_byte *bytes;
+ const bfd_byte *p;
+ unsigned int indx;
+{
+ boolean ptr;
+ debug_type type;
+ const char *name;
+
+ if (indx < BUILTIN_TYPE_COUNT
+ && types->builtins[indx] != DEBUG_TYPE_NULL)
+ return types->builtins[indx];
+
+ ptr = false;
+ switch (indx)
+ {
+ default:
+ ieee_error (abfd, bytes, p, "unknown builtin type");
+ return NULL;
+
+ case 32:
+ ptr = true;
+ /* Fall through. */
+ case 0:
+ type = debug_make_void_type (dhandle);
+ name = NULL;
+ break;
+
+ case 33:
+ ptr = true;
+ /* Fall through. */
+ case 1:
+ type = debug_make_void_type (dhandle);
+ name = "void";
+ break;
+
+ case 34:
+ ptr = true;
+ /* Fall through. */
+ case 2:
+ type = debug_make_int_type (dhandle, 1, false);
+ name = "signed char";
+ break;
+
+ case 35:
+ ptr = true;
+ /* Fall through. */
+ case 3:
+ type = debug_make_int_type (dhandle, 1, true);
+ name = "unsigned char";
+ break;
+
+ case 36:
+ ptr = true;
+ /* Fall through. */
+ case 4:
+ type = debug_make_int_type (dhandle, 2, false);
+ name = "signed short int";
+ break;
+
+ case 37:
+ ptr = true;
+ /* Fall through. */
+ case 5:
+ type = debug_make_int_type (dhandle, 2, true);
+ name = "unsigned short int";
+ break;
+
+ case 38:
+ ptr = true;
+ /* Fall through. */
+ case 6:
+ type = debug_make_int_type (dhandle, 4, false);
+ name = "signed long";
+ break;
+
+ case 39:
+ ptr = true;
+ /* Fall through. */
+ case 7:
+ type = debug_make_int_type (dhandle, 4, true);
+ name = "unsigned long";
+ break;
+
+ case 40:
+ ptr = true;
+ /* Fall through. */
+ case 8:
+ type = debug_make_int_type (dhandle, 8, false);
+ name = "signed long long";
+ break;
+
+ case 41:
+ ptr = true;
+ /* Fall through. */
+ case 9:
+ type = debug_make_int_type (dhandle, 8, true);
+ name = "unsigned long long";
+ break;
+
+ case 42:
+ ptr = true;
+ /* Fall through. */
+ case 10:
+ type = debug_make_float_type (dhandle, 4);
+ name = "float";
+ break;
+
+ case 43:
+ ptr = true;
+ /* Fall through. */
+ case 11:
+ type = debug_make_float_type (dhandle, 8);
+ name = "double";
+ break;
+
+ case 44:
+ ptr = true;
+ /* Fall through. */
+ case 12:
+ /* FIXME: The size for this type should depend upon the
+ processor. */
+ type = debug_make_float_type (dhandle, 12);
+ name = "long double";
+ break;
+
+ case 45:
+ ptr = true;
+ /* Fall through. */
+ case 13:
+ type = debug_make_float_type (dhandle, 16);
+ name = "long long double";
+ break;
+
+ case 46:
+ ptr = true;
+ /* Fall through. */
+ case 14:
+ type = debug_make_array_type (dhandle,
+ ieee_builtin_type (dhandle, abfd, types,
+ bytes, p, 19),
+ ieee_builtin_type (dhandle, abfd, types,
+ bytes, p, 16),
+ 0, -1, true);
+ name = "QUOTED STRING";
+ break;
+
+ case 47:
+ ptr = true;
+ /* Fall through. */
+ case 15:
+ /* FIXME: This should be a code address. */
+ type = debug_make_int_type (dhandle, 4, true);
+ name = "instruction address";
+ break;
+
+ case 48:
+ ptr = true;
+ /* Fall through. */
+ case 16:
+ /* FIXME: The size for this type should depend upon the
+ processor. */
+ type = debug_make_int_type (dhandle, 4, false);
+ name = "int";
+ break;
+
+ case 49:
+ ptr = true;
+ /* Fall through. */
+ case 17:
+ /* FIXME: The size for this type should depend upon the
+ processor. */
+ type = debug_make_int_type (dhandle, 4, true);
+ name = "unsigned";
+ break;
+
+ case 50:
+ ptr = true;
+ /* Fall through. */
+ case 18:
+ /* FIXME: The size for this type should depend upon the
+ processor. */
+ type = debug_make_int_type (dhandle, 4, true);
+ name = "unsigned int";
+ break;
+
+ case 51:
+ ptr = true;
+ /* Fall through. */
+ case 19:
+ type = debug_make_int_type (dhandle, 1, false);
+ name = "char";
+ break;
+
+ case 52:
+ ptr = true;
+ /* Fall through. */
+ case 20:
+ type = debug_make_int_type (dhandle, 4, false);
+ name = "long";
+ break;
+
+ case 53:
+ ptr = true;
+ /* Fall through. */
+ case 21:
+ type = debug_make_int_type (dhandle, 2, false);
+ name = "short";
+ break;
+
+ case 54:
+ ptr = true;
+ /* Fall through. */
+ case 22:
+ type = debug_make_int_type (dhandle, 2, true);
+ name = "unsigned short";
+ break;
+
+ case 55:
+ ptr = true;
+ /* Fall through. */
+ case 23:
+ type = debug_make_int_type (dhandle, 2, false);
+ name = "short int";
+ break;
+
+ case 56:
+ ptr = true;
+ /* Fall through. */
+ case 24:
+ type = debug_make_int_type (dhandle, 2, false);
+ name = "signed short";
+ break;
+
+ case 57:
+ ptr = true;
+ /* Fall through. */
+ case 25:
+ ieee_error (abfd, bytes, p, "BCD float type not supported");
+ return false;
+ }
+
+ if (ptr)
+ type = debug_make_pointer_type (dhandle, type);
+ else if (name != NULL)
+ type = debug_name_type (dhandle, name, type);
+
+ assert (indx < BUILTIN_TYPE_COUNT);
+
+ types->builtins[indx] = type;
+
+ return type;
+}
+
+/* Read a type index and return the corresponding type. */
+
+static boolean
+ieee_read_type_index (dhandle, abfd, types, bytes, pp, pend, ptype)
+ PTR dhandle;
+ bfd *abfd;
+ struct ieee_types *types;
+ const bfd_byte *bytes;
+ const bfd_byte **pp;
+ const bfd_byte *pend;
+ debug_type *ptype;
+{
+ const bfd_byte *start;
+ bfd_vma indx;
+
+ start = *pp;
+
+ if (! ieee_read_number (abfd, bytes, pp, pend, &indx))
+ return false;
+
+ if (indx < 256)
+ {
+ *ptype = ieee_builtin_type (dhandle, abfd, types, bytes, start, indx);
+ if (*ptype == NULL)
+ return false;
+ return true;
+ }
+
+ indx -= 256;
+ if (indx >= types->alloc
+ || types->types[indx].type == DEBUG_TYPE_NULL)
+ {
+ ieee_error (abfd, bytes, start, "undefined type");
+ return false;
+ }
+
+ *ptype = types->types[indx].type;
+
+ return true;
+}
+
+/* Convert a register number in IEEE debugging information into a
+ generic register number. */
+
+static int
+ieee_regno_to_gen (abfd, r)
+ bfd *abfd;
+ int r;
+{
+ return r;
+}
+
+/* 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_blockstack blockstack;
+ struct ieee_vars vars;
+ struct ieee_types types;
+ unsigned int i;
+ const bfd_byte *p, *pend;
+
+ blockstack.bsp = blockstack.stack;
+ vars.alloc = 0;
+ vars.vars = NULL;
+ types.alloc = 0;
+ types.types = NULL;
+ for (i = 0; i < BUILTIN_TYPE_COUNT; i++)
+ types.builtins[i] = DEBUG_TYPE_NULL;
+
+ p = bytes;
+ pend = bytes + len;
+ 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 (abfd, bytes, record_start, "unexpected number");
+ return false;
+ }
+
+ switch (c)
+ {
+ default:
+ ieee_error (abfd, bytes, record_start, "unexpected record type");
+ return false;
+
+ case ieee_bb_record_enum:
+ if (! parse_ieee_bb (dhandle, abfd, &types, &blockstack, bytes,
+ &p, pend))
+ return false;
+ break;
+
+ case ieee_be_record_enum:
+ if (! parse_ieee_be (dhandle, abfd, &blockstack, bytes, &p, pend))
+ return false;
+ break;
+
+ case ieee_nn_record:
+ if (! parse_ieee_nn (dhandle, abfd, &vars, bytes, &p, pend))
+ return false;
+ break;
+
+ case ieee_ty_record_enum:
+ if (! parse_ieee_ty (dhandle, abfd, &types, &vars, bytes, &p, pend))
+ return false;
+ break;
+
+ case ieee_atn_record_enum:
+ if (! parse_ieee_atn (dhandle, abfd, &types, &vars,
+ (blockstack.bsp <= blockstack.stack
+ ? 0
+ : blockstack.bsp[-1].kind),
+ bytes, &p, pend))
+ return false;
+ break;
+ }
+ }
+
+ if (blockstack.bsp != blockstack.stack)
+ {
+ ieee_error (abfd, (const bfd_byte *) NULL, (const bfd_byte *) NULL,
+ "blocks left on stack at end");
+ return false;
+ }
+
+ return true;
+}
+
+/* Handle an IEEE BB record. */
+
+static boolean
+parse_ieee_bb (dhandle, abfd, types, blockstack, bytes, pp, pend)
+ PTR dhandle;
+ bfd *abfd;
+ struct ieee_types *types;
+ struct ieee_blockstack *blockstack;
+ const bfd_byte *bytes;
+ const bfd_byte **pp;
+ const bfd_byte *pend;
+{
+ const bfd_byte *block_start;
+ bfd_byte b;
+ bfd_vma size;
+ const char *name;
+ unsigned long namlen;
+ char *namcopy;
+
+ block_start = *pp;
+
+ b = **pp;
+ ++*pp;
+
+ if (! ieee_read_number (abfd, bytes, pp, pend, &size)
+ || ! ieee_read_id (abfd, bytes, pp, pend, &name, &namlen))
+ return 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 (dhandle, namcopy))
+ return false;
+ break;
+
+ case 2:
+ /* BB2: Global type definitions. The name is supposed to be
+ empty, but we don't check. */
+ if (! debug_set_filename (dhandle, "*global*"))
+ return false;
+ 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 (abfd, bytes, pp, pend, &stackspace)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &typindx)
+ || ! ieee_read_expression (abfd, bytes, pp, pend, &offset))
+ return false;
+
+ /* We have no way to record the stack space. FIXME. */
+
+ if (typindx < 256)
+ {
+ return_type = ieee_builtin_type (dhandle, abfd, types, bytes,
+ block_start, typindx);
+ if (return_type == NULL)
+ return false;
+ }
+ else
+ {
+ typindx -= 256;
+ if (typindx >= types->alloc
+ || types->types[typindx].type == DEBUG_TYPE_NULL)
+ {
+ ieee_error (abfd, bytes, block_start, "undefined type index");
+ return false;
+ }
+ return_type = types->types[typindx].return_type;
+ if (return_type == NULL)
+ return_type = types->types[typindx].type;
+ }
+
+ namcopy = savestring (name, namlen);
+ if (namcopy == NULL)
+ return false;
+ if (! debug_record_function (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 (abfd, bytes, pp, pend, &ignore,
+ &present))
+ return false;
+ if (! present)
+ break;
+ }
+
+ namcopy = savestring (name, namlen);
+ if (namcopy == NULL)
+ return false;
+ if (! debug_start_source (dhandle, namcopy))
+ return false;
+ }
+ break;
+
+ case 6:
+ /* BB6: Local function or block. */
+ {
+ bfd_vma stackspace, typindx, offset;
+
+ if (! ieee_read_number (abfd, bytes, pp, pend, &stackspace)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &typindx)
+ || ! ieee_read_expression (abfd, bytes, pp, pend, &offset))
+ return false;
+
+ /* We have no way to record the stack space. FIXME. */
+
+ if (namlen == 0)
+ {
+ if (! debug_start_block (dhandle, offset))
+ return false;
+ /* Change b to indicate that this is a block
+ rather than a function. */
+ b = 0x86;
+ }
+ else
+ {
+ debug_type return_type;
+
+ if (typindx < 256)
+ {
+ return_type = ieee_builtin_type (dhandle, abfd, types, bytes,
+ block_start, typindx);
+ if (return_type == NULL)
+ return false;
+ }
+ else
+ {
+ typindx -= 256;
+ if (typindx >= types->alloc
+ || types->types[typindx].type == DEBUG_TYPE_NULL)
+ {
+ ieee_error (abfd, bytes, block_start,
+ "undefined type index");
+ return false;
+ }
+ return_type = types->types[typindx].return_type;
+ if (return_type == NULL)
+ return_type = types->types[typindx].type;
+ }
+
+ namcopy = savestring (name, namlen);
+ if (namcopy == NULL)
+ return false;
+ if (! debug_record_function (dhandle, namcopy, return_type,
+ false, offset))
+ return false;
+ }
+ }
+ break;
+
+ case 10:
+ /* BB10: Assembler module scope. 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 (! ieee_read_id (abfd, bytes, pp, pend, &inam, &inamlen)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &tool_type)
+ || ! ieee_read_optional_id (abfd, bytes, pp, pend, &vstr, &vstrlen,
+ &present))
+ return false;
+ for (i = 0; i < 6; i++)
+ {
+ bfd_vma ignore;
+
+ if (! ieee_read_optional_number (abfd, bytes, pp, pend, &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 (abfd, bytes, pp, pend, §ype)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &secindx)
+ || ! ieee_read_expression (abfd, bytes, pp, pend, &offset)
+ || ! ieee_read_optional_number (abfd, bytes, pp, pend, &map,
+ &present))
+ return false;
+ }
+ break;
+
+ default:
+ ieee_error (abfd, bytes, block_start, "unknown BB type");
+ return false;
+ }
+
+
+ /* Push this block on the block stack. */
+
+ if (blockstack->bsp >= blockstack->stack + BLOCKSTACK_SIZE)
+ {
+ ieee_error (abfd, (const bfd_byte *) NULL, (const bfd_byte *) NULL,
+ "stack overflow");
+ return false;
+ }
+
+ blockstack->bsp->kind = b;
+ if (b == 5)
+ blockstack->bsp->filename = namcopy;
+ ++blockstack->bsp;
+
+ return true;
+}
+
+/* Handle an IEEE BE record. */
+
+static boolean
+parse_ieee_be (dhandle, abfd, blockstack, bytes, pp, pend)
+ PTR dhandle;
+ bfd *abfd;
+ struct ieee_blockstack *blockstack;
+ const bfd_byte *bytes;
+ const bfd_byte **pp;
+ const bfd_byte *pend;
+{
+ bfd_vma offset;
+
+ if (blockstack->bsp <= blockstack->stack)
+ {
+ ieee_error (abfd, bytes, *pp, "stack underflow");
+ return false;
+ }
+ --blockstack->bsp;
+
+ switch (blockstack->bsp->kind)
+ {
+ case 4:
+ case 6:
+ if (! ieee_read_expression (abfd, bytes, pp, pend, &offset))
+ return false;
+ if (! debug_end_function (dhandle, offset))
+ return false;
+ break;
+
+ case 0x86:
+ /* This is BE6 when BB6 started a block rather than a local
+ function. */
+ if (! ieee_read_expression (abfd, bytes, pp, pend, &offset))
+ return false;
+ if (! debug_end_block (dhandle, offset))
+ 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 (blockstack->bsp > blockstack->stack)
+ {
+ struct ieee_block *bl;
+
+ bl = blockstack->bsp;
+ do
+ {
+ --bl;
+ if (bl->kind == 5)
+ {
+ if (! debug_start_source (dhandle, bl->filename))
+ return false;
+ break;
+ }
+ }
+ while (bl != blockstack->stack);
+ }
+ break;
+
+ case 11:
+ if (! ieee_read_expression (abfd, bytes, pp, pend, &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 (dhandle, abfd, vars, bytes, pp, pend)
+ PTR dhandle;
+ bfd *abfd;
+ struct ieee_vars *vars;
+ const bfd_byte *bytes;
+ const bfd_byte **pp;
+ const bfd_byte *pend;
+{
+ const bfd_byte *nn_start;
+ bfd_vma varindx;
+ const char *name;
+ unsigned long namlen;
+
+ nn_start = *pp;
+
+ if (! ieee_read_number (abfd, bytes, pp, pend, &varindx)
+ || ! ieee_read_id (abfd, bytes, pp, pend, &name, &namlen))
+ return false;
+
+ if (varindx < 32)
+ {
+ ieee_error (abfd, bytes, nn_start, "illegal variable index");
+ return false;
+ }
+ varindx -= 32;
+
+ if (varindx >= vars->alloc)
+ {
+ unsigned int alloc;
+
+ alloc = vars->alloc;
+ if (alloc == 0)
+ alloc = 4;
+ while (varindx >= alloc)
+ alloc *= 2;
+ vars->vars = ((struct ieee_var *)
+ xrealloc (vars->vars, alloc * sizeof *vars->vars));
+ memset (vars->vars + vars->alloc, 0,
+ (alloc - vars->alloc) * sizeof *vars->vars);
+ vars->alloc = alloc;
+ }
+
+ vars->vars[varindx].name = name;
+ vars->vars[varindx].namlen = namlen;
+
+ return true;
+}
+
+/* Parse a TY record. */
+
+static boolean
+parse_ieee_ty (dhandle, abfd, types, vars, bytes, pp, pend)
+ PTR dhandle;
+ bfd *abfd;
+ struct ieee_types *types;
+ struct ieee_vars *vars;
+ const bfd_byte *bytes;
+ const bfd_byte **pp;
+ const bfd_byte *pend;
+{
+ const bfd_byte *ty_start, *ty_var_start, *ty_code_start;
+ bfd_vma typeindx, varindx, tc;
+ debug_type type;
+ boolean tag, typdef;
+ unsigned long type_bitsize;
+ debug_type return_type;
+
+ ty_start = *pp;
+
+ if (! ieee_read_number (abfd, bytes, pp, pend, &typeindx))
+ return false;
+
+ if (typeindx < 256)
+ {
+ ieee_error (abfd, bytes, ty_start, "illegal type index");
+ return false;
+ }
+ typeindx -= 256;
+
+ if (typeindx >= types->alloc)
+ {
+ unsigned int nalloc;
+ struct ieee_type *t, *tend;
+
+ nalloc = types->alloc;
+ if (nalloc == 0)
+ nalloc = 4;
+ while (typeindx >= nalloc)
+ nalloc *= 2;
+ types->types = ((struct ieee_type *)
+ xrealloc (types->types, nalloc * sizeof *types->types));
+ tend = types->types + nalloc;
+ for (t = types->types + types->alloc; t < tend; t++)
+ {
+ t->bitsize = 0;
+ t->type = DEBUG_TYPE_NULL;
+ }
+ types->alloc = nalloc;
+ }
+
+ if (**pp != 0xce)
+ {
+ ieee_error (abfd, bytes, *pp, "unknown TY code");
+ return false;
+ }
+ ++*pp;
+
+ ty_var_start = *pp;
+
+ if (! ieee_read_number (abfd, bytes, pp, pend, &varindx))
+ return false;
+
+ if (varindx < 32)
+ {
+ ieee_error (abfd, bytes, ty_var_start, "illegal variable index");
+ return false;
+ }
+ varindx -= 32;
+
+ if (varindx >= vars->alloc || vars->vars[varindx].name == NULL)
+ {
+ ieee_error (abfd, bytes, ty_var_start, "undefined variable in TY");
+ return false;
+ }
+
+ ty_code_start = *pp;
+
+ if (! ieee_read_number (abfd, bytes, pp, pend, &tc))
+ return false;
+
+ tag = false;
+ typdef = false;
+ type_bitsize = 0;
+ return_type = DEBUG_TYPE_NULL;
+ switch (tc)
+ {
+ default:
+ ieee_error (abfd, bytes, 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 (abfd, bytes, pp, pend, &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 (dhandle, abfd, types, bytes, pp, pend,
+ &ele_type)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &lower)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &upper))
+ return false;
+ type = debug_make_array_type (dhandle, ele_type,
+ debug_make_int_type (dhandle, 4, false),
+ (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 (abfd, bytes, pp, pend, &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 (abfd, bytes, pp, pend, &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 (abfd, bytes, pp, pend, &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 (abfd, bytes, pp, pend, &name,
+ &namlen, &present))
+ return false;
+ if (! present)
+ break;
+ if (! ieee_read_type_index (dhandle, abfd, types, bytes, pp, pend,
+ &ftype)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &bitpos)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &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 (abfd, bytes, pp, pend, &name,
+ &namlen, &present))
+ return false;
+ if (! present)
+ break;
+ if (! ieee_read_number (abfd, bytes, pp, pend, &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 (dhandle, abfd, types, bytes, pp, pend, &t))
+ return false;
+ type = debug_make_pointer_type (dhandle, t);
+ }
+ break;
+
+ case 'R':
+ /* Range. */
+ {
+ bfd_vma low, high, signedp, size;
+
+ if (! ieee_read_number (abfd, bytes, pp, pend, &low)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &high)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &signedp)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &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 (abfd, bytes, pp, pend, &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 (abfd, bytes, pp, pend, &name,
+ &namlen, &present))
+ return false;
+ if (! present)
+ break;
+ if (! ieee_read_number (abfd, bytes, pp, pend, &tindx)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &offset))
+ return false;
+
+ if (tindx < 256)
+ {
+ ftype = ieee_builtin_type (dhandle, abfd, types, bytes,
+ ty_code_start, tindx);
+ bitsize = 0;
+ offset *= 8;
+ }
+ else
+ {
+ struct ieee_type *t;
+
+ tindx -= 256;
+ if (tindx >= types->alloc
+ || types->types[tindx].type == DEBUG_TYPE_NULL)
+ {
+ ieee_error (abfd, bytes, ty_start, "undefined type index");
+ return false;
+ }
+ t = &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 (dhandle, abfd, types, bytes, pp, pend,
+ &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;
+
+ /* FIXME: We ignore the attribute and the argument names. */
+
+ if (! ieee_read_number (abfd, bytes, pp, pend, &attr)
+ || ! ieee_read_type_index (dhandle, abfd, types, bytes, pp, pend,
+ &rtype)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &nargs))
+ return false;
+ do
+ {
+ const char *name;
+ unsigned long namlen;
+
+ if (! ieee_read_optional_id (abfd, bytes, pp, pend, &name,
+ &namlen, &present))
+ return false;
+ }
+ while (present);
+
+ type = debug_make_function_type (dhandle, rtype);
+ return_type = rtype;
+ }
+ break;
+
+ case 'Z':
+ /* Array with 0 lower bound. */
+ {
+ debug_type etype;
+ bfd_vma high;
+
+ if (! ieee_read_type_index (dhandle, abfd, types, bytes, pp, pend,
+ &etype)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &high))
+ return false;
+
+ type = debug_make_array_type (dhandle, etype,
+ debug_make_int_type (dhandle, 4, false),
+ 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 (abfd, bytes, pp, pend, &name, &namlen))
+ return false;
+
+ type = debug_make_complex_type (dhandle, tc == 'c' ? 4 : 8);
+ }
+ break;
+
+ case 'f':
+ /* Pascal file name. FIXME. */
+ ieee_error (abfd, bytes, ty_code_start,
+ "Pascal file name not supported");
+ return false;
+
+ case 'g':
+ /* Bitfield type. */
+ {
+ bfd_vma signedp, bitsize;
+
+ if (! ieee_read_number (abfd, bytes, pp, pend, &signedp)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &bitsize)
+ || ! ieee_read_type_index (dhandle, abfd, types, bytes, pp, pend,
+ &type))
+ return false;
+
+ /* FIXME: This is just a guess. */
+ if (! signedp)
+ type = debug_make_int_type (dhandle, 4, true);
+ type_bitsize = bitsize;
+ }
+ break;
+
+ case 'n':
+ /* Qualifier. */
+ {
+ bfd_vma kind;
+ debug_type t;
+
+ if (! ieee_read_number (abfd, bytes, pp, pend, &kind)
+ || ! ieee_read_type_index (dhandle, abfd, types, bytes, pp, pend,
+ &t))
+ return false;
+
+ switch (kind)
+ {
+ default:
+ ieee_error (abfd, bytes, 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 (abfd, bytes, pp, pend, &size)
+ || ! ieee_read_type_index (dhandle, abfd, types, bytes, pp, pend,
+ &etype))
+ return false;
+
+ /* FIXME: We ignore the size. */
+
+ type = debug_make_set_type (dhandle, etype, false);
+ }
+ break;
+
+ case 'x':
+ /* Procedure with compiler dependencies. FIXME: This is an
+ extern declaration, which we have no way of representing. */
+ {
+ bfd_vma attr, frame_type, push_mask, nargs, level, father;
+ debug_type rtype;
+ boolean present;
+
+ /* FIXME: We ignore almost all this information. */
+
+ if (! ieee_read_number (abfd, bytes, pp, pend, &attr)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &frame_type)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &push_mask)
+ || ! ieee_read_type_index (dhandle, abfd, types, bytes, pp, pend,
+ &rtype)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &nargs))
+ return false;
+ if (nargs != (bfd_vma) -1)
+ {
+ for (; nargs > 0; nargs--)
+ {
+ debug_type atype;
+
+ if (! ieee_read_type_index (dhandle, abfd, types, bytes, pp,
+ pend, &atype))
+ return false;
+ }
+ }
+ if (! ieee_read_number (abfd, bytes, pp, pend, &level)
+ || ! ieee_read_optional_number (abfd, bytes, pp, pend, &father,
+ &present))
+ return false;
+
+ type = debug_make_function_type (dhandle, rtype);
+ return_type = rtype;
+ }
+ break;
+ }
+
+ /* Record the type in the table. If the corresponding NN record has
+ a name, name it. FIXME: Is this always correct? */
+
+ if (type == NULL)
+ return false;
+
+ if ((tag || typdef)
+ && vars->vars[varindx].namlen > 0)
+ {
+ const char *name;
+
+ name = savestring (vars->vars[varindx].name,
+ vars->vars[varindx].namlen);
+ if (tag)
+ type = debug_tag_type (dhandle, name, type);
+ else
+ type = debug_name_type (dhandle, name, type);
+ if (type == NULL)
+ return false;
+ }
+
+ types->types[typeindx].type = type;
+ types->types[typeindx].bitsize = type_bitsize;
+ types->types[typeindx].return_type = return_type;
+
+ return true;
+}
+
+/* Parse an ATN record. */
+
+static boolean
+parse_ieee_atn (dhandle, abfd, types, vars, blocktype, bytes, pp, pend)
+ PTR dhandle;
+ bfd *abfd;
+ struct ieee_types *types;
+ struct ieee_vars *vars;
+ int blocktype;
+ const bfd_byte *bytes;
+ const bfd_byte **pp;
+ const bfd_byte *pend;
+{
+ const bfd_byte *atn_start, *atn_code_start;
+ bfd_vma varindx;
+ boolean zeroindx;
+ debug_type type;
+ bfd_vma atn_code;
+ bfd_vma v, v2, v3, v4, v5;
+ const char *name;
+ unsigned long namlen;
+ char *namcopy;
+ boolean present;
+
+ atn_start = *pp;
+
+ if (! ieee_read_number (abfd, bytes, pp, pend, &varindx)
+ || ! ieee_read_type_index (dhandle, abfd, types, bytes, pp, pend, &type))
+ return false;
+
+ atn_code_start = *pp;
+
+ if (! ieee_read_number (abfd, bytes, pp, pend, &atn_code))
+ return false;
+
+ if (varindx == 0)
+ {
+ zeroindx = true;
+ name = "";
+ namlen = 0;
+ }
+ else if (varindx < 32)
+ {
+ ieee_error (abfd, bytes, atn_start, "illegal variable index");
+ return false;
+ }
+ else
+ {
+ varindx -= 32;
+ zeroindx = false;
+ if (varindx >= vars->alloc || vars->vars[varindx].name == NULL)
+ {
+ ieee_error (abfd, bytes, atn_start, "undefined variable in ATN");
+ return false;
+ }
+
+ vars->vars[varindx].type = type;
+
+ name = vars->vars[varindx].name;
+ namlen = vars->vars[varindx].namlen;
+ }
+
+ switch (atn_code)
+ {
+ default:
+ ieee_error (abfd, bytes, atn_code_start, "unknown ATN type");
+ return false;
+
+ case 1:
+ /* Automatic variable. */
+ if (! ieee_read_number (abfd, bytes, pp, pend, &v))
+ return false;
+ namcopy = savestring (name, namlen);
+ if (type == NULL)
+ type = debug_make_void_type (dhandle);
+ return debug_record_variable (dhandle, namcopy, type, DEBUG_LOCAL, v);
+
+ case 2:
+ /* Register variable. */
+ if (! ieee_read_number (abfd, bytes, pp, pend, &v))
+ return false;
+ namcopy = savestring (name, namlen);
+ if (type == NULL)
+ type = debug_make_void_type (dhandle);
+ return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER,
+ ieee_regno_to_gen (abfd, v));
+
+ case 3:
+ /* Static variable. */
+ if (! ieee_require_asn (abfd, bytes, pp, pend, &v))
+ return false;
+ namcopy = savestring (name, namlen);
+ if (type == NULL)
+ type = debug_make_void_type (dhandle);
+ 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. */
+ return true;
+
+ case 5:
+ /* External variable. We don't currently record these. FIXME. */
+ return true;
+
+ case 7:
+ if (! ieee_read_number (abfd, bytes, pp, pend, &v)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &v2)
+ || ! ieee_read_optional_number (abfd, bytes, pp, pend, &v3,
+ &present))
+ return false;
+ if (present)
+ {
+ if (! ieee_read_optional_number (abfd, bytes, pp, pend, &v4,
+ &present))
+ return false;
+ }
+
+ /* We just ignore the two optional fields in v3 and v4, since
+ they are not defined. */
+
+ if (! ieee_require_asn (abfd, bytes, pp, pend, &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 (abfd, bytes, pp, pend, &v))
+ return false;
+ namcopy = savestring (name, namlen);
+ if (type == NULL)
+ type = debug_make_void_type (dhandle);
+ return debug_record_variable (dhandle, namcopy, type, DEBUG_GLOBAL, v);
+
+ case 9:
+ /* Variable lifetime information. */
+ if (! ieee_read_number (abfd, bytes, pp, pend, &v))
+ return false;
+
+ /* We have no way to record this information. FIXME. */
+ return true;
+
+ case 10:
+ /* Locked register. */
+ if (! ieee_read_number (abfd, bytes, pp, pend, &v)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &v2))
+ return false;
+
+ /* I don't know what this means. FIXME. */
+
+ ieee_error (abfd, bytes, atn_code_start, "unsupported ATN10");
+
+ /* Return true to keep going. */
+ return true;
+
+ case 11:
+ /* Reserved for FORTRAN common. */
+ ieee_error (abfd, bytes, 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 (abfd, bytes, pp, pend, &v)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &v2)
+ || ! ieee_read_optional_number (abfd, bytes, pp, pend, &v3,
+ &present))
+ return false;
+ if (present)
+ {
+ if (! ieee_read_optional_number (abfd, bytes, pp, pend, &v4,
+ &present))
+ return false;
+ if (present)
+ {
+ if (! ieee_read_optional_number (abfd, bytes, pp, pend, &v5,
+ &present))
+ return false;
+ }
+ }
+
+ /* We have no way to record this information. FIXME. */
+
+ ieee_error (abfd, bytes, 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. */
+ ieee_error (abfd, bytes, atn_code_start, "unsupported ATN16");
+ return false;
+
+ case 19:
+ /* Static variable from assembler. */
+ v2 = 0;
+ if (! ieee_read_number (abfd, bytes, pp, pend, &v)
+ || ! ieee_read_optional_number (abfd, bytes, pp, pend, &v2,
+ &present)
+ || ! ieee_require_asn (abfd, bytes, pp, pend, &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 (abfd, bytes, pp, pend, &v)
+ || ! ieee_read_number (abfd, bytes, pp, pend, &v2)
+ || ! ieee_read_optional_id (abfd, bytes, pp, pend, &name, &namlen,
+ &present))
+ return false;
+
+ /* We just ignore all of this stuff. FIXME. */
+
+ for (; v2 > 0; --v2)
+ {
+ ieee_record_enum_type c;
+ bfd_vma vindx;
+ const char *str;
+ unsigned long strlen;
+
+ c = (ieee_record_enum_type) **pp;
+ ++*pp;
+ if (c != ieee_at_record_enum
+ && c != ieee_e2_first_byte_enum)
+ {
+ ieee_error (abfd, bytes, *pp - 1, "bad misc record");
+ return false;
+ }
+
+ c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp);
+ ++*pp;
+ switch (c)
+ {
+ default:
+ ieee_error (abfd, bytes, *pp - 2, "bad misc record");
+ return false;
+
+ case ieee_atn_record_enum:
+ if (! ieee_read_number (abfd, bytes, pp, pend, &vindx))
+ return false;
+ if ((*pp)[0] != 0 || (*pp)[1] != 65)
+ {
+ ieee_error (abfd, bytes, *pp, "bad atn in misc");
+ return false;
+ }
+ *pp += 2;
+ if (! ieee_read_id (abfd, bytes, pp, pend, &str, &strlen))
+ return false;
+ break;
+
+ case ieee_asn_record_enum:
+ if (! ieee_read_number (abfd, bytes, pp, pend, &vindx)
+ || ! ieee_read_expression (abfd, bytes, pp, pend, &v3))
+ return false;
+ break;
+ }
+ }
+
+ return true;
+ }
+
+ /*NOTREACHED*/
+}
+
+/* Require an ASN record. */
+
+static boolean
+ieee_require_asn (abfd, bytes, pp, pend, pv)
+ bfd *abfd;
+ const bfd_byte *bytes;
+ const bfd_byte **pp;
+ const bfd_byte *pend;
+ 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 (abfd, bytes, 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 (abfd, bytes, start, "missing required ASN");
+ return false;
+ }
+ ++*pp;
+
+ /* Just ignore the variable index. */
+ if (! ieee_read_number (abfd, bytes, pp, pend, &varindx))
+ return false;
+
+ return ieee_read_expression (abfd, bytes, pp, pend, pv);
+}