* ieee.c: New file with code to read IEEE debugging information.
authorIan Lance Taylor <ian@airs.com>
Thu, 4 Jan 1996 21:35:04 +0000 (21:35 +0000)
committerIan Lance Taylor <ian@airs.com>
Thu, 4 Jan 1996 21:35:04 +0000 (21:35 +0000)
* budbg.h (parse_ieee): Declare.
* rddbg.c (read_debugging_info): Handle IEEE flavour files.
(read_ieee_debugging_info): New static function.
* Makefile.in: Rebuild dependencies.
(CFILES): Add ieee.c.
(OBJDUMP_OBJS): Add ieee.o.

binutils/.Sanitize
binutils/ChangeLog
binutils/Makefile.in
binutils/budbg.h
binutils/ieee.c [new file with mode: 0644]

index be71ab7a94fc0e7d5be3af7091d0d0368f39efff..a1bf341bf11f3bf88492450b9b047f0ae8b6c22b 100644 (file)
@@ -57,6 +57,7 @@ defparse.y
 deflex.l
 filemode.c
 gmalloc.c
+ieee.c
 is-ranlib.c
 is-strip.c
 mac-binutils.r
index bf952fede9217ced69db8f25a26f8a988f278fb8..4b7d71a5a72a8a51cf0fa1ac9654e5731416e58e 100644 (file)
@@ -1,3 +1,44 @@
+Thu Jan  4 16:31:21 1996  Ian Lance Taylor  <ian@cygnus.com>
+
+       * ieee.c: New file with code to read IEEE debugging information.
+       * budbg.h (parse_ieee): Declare.
+       * rddbg.c (read_debugging_info): Handle IEEE flavour files.
+       (read_ieee_debugging_info): New static function.
+       * Makefile.in: Rebuild dependencies.
+       (CFILES): Add ieee.c.
+       (OBJDUMP_OBJS): Add ieee.o.
+
+       * bucomm.h (xrealloc): Change type of first parameter from char *
+       to PTR.
+
+Tue Jan  2 17:44:07 1996  Ian Lance Taylor  <ian@cygnus.com>
+
+       * Makefile.in: Add targets to automatically rebuild dependencies.
+       Remove targets which just listed dependencies of .o files.
+       (DEP): New variable.
+       (HFILES, GENERATED_HFILES): New variables.
+       (CFILES, GENERATED_CFILES): New variables.
+       (underscore.c): Don't do anything, just depend upon stamp-under.
+       (stamp-under): New target; do what underscore.c used to do.
+       (nlmconv.o): Depend upon sym.h and ecoff.h.
+       (.dep, .dep1, dep.sed, dep, dep-in): New targets.
+       (stage1, stage2, stage3, against, comparison): Remove.
+       (de-stage1, de-stage2, de-stage3): Remove.
+       (clean, distclean): Remove stamp-under and dep.sed.
+       * dep-in.sed: New file.
+
+       Implement generic debugging support.  Implement a stabs reader and
+       a generic printer.
+       * budbg.h, debug.c, debug.h, prdbg.c, rddbg.c, stabs.c: New files.
+       * objdump.c: Include "debug.h" and "budbg.h".
+       (dump_debugging): New global variable.
+       (usage): Mention --debugging.
+       (long_options): Add "debugging".
+       (display_bfd): Handle --debugging.
+       * Makefile.in (OBJDUMP_OBJS): New variable.
+       ($(OBJDUMP_PROG)): Use $(OBJDUMP_OBJS).
+       * binutils.texi, objdump.1: Document --debugging.
+
 Sat Dec 30 09:59:51 1995  Jeffrey A Law  (law@cygnus.com)
 
        * nm.c ( long_options): Add "--defined-only" option.
index 67050bd9bf93eeca5385f6cc3bb23d78a4aa9a48..6801d562ab034143086ee4603b8021ba8fafcd4d 100644 (file)
@@ -1,5 +1,5 @@
 # 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.
 
@@ -107,8 +107,6 @@ DLLTOOL_PROG=dlltool
 
 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@
@@ -125,9 +123,24 @@ BASEDIR = $(srcdir)/..
 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) $<
 
@@ -255,14 +268,18 @@ $(STRIP_PROG): $(ADDL_LIBS) objcopy.o is-strip.o $(BFD)
 $(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
@@ -352,9 +369,6 @@ sysinfo.o: sysinfo.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)
 
@@ -378,8 +392,6 @@ dlltool.o:dlltool.c
 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)
 
@@ -390,93 +402,45 @@ nlmheader.c: nlmheader.y sysinfo.c
        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
@@ -561,11 +525,13 @@ mostlyclean:
        -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."
@@ -685,8 +651,95 @@ stamp-h: config.in config.status
 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
index e63841ee3bb23562365387d46496681430461ce8..aec0bf2ef9d23aac91f5514a66fde84bfe1dcc08 100644 (file)
@@ -1,5 +1,5 @@
 /* budbg.c -- Interfaces to the generic debugging information routines.
-   Copyright (C) 1995 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
    Written by Ian Lance Taylor <ian@cygnus.com>.
 
    This file is part of GNU Binutils.
@@ -26,7 +26,7 @@
 
 /* Routine used to read generic debugging information.  */
 
-extern PTR read_debugging_info PARAMS ((bfd *));
+extern PTR read_debugging_info PARAMS ((bfd *, asymbol **, long));
 
 /* Routine used to print generic debugging information.  */
 
@@ -34,10 +34,15 @@ extern boolean print_debugging_info PARAMS ((FILE *, PTR));
 
 /* Routines used to read stabs information.  */
 
-extern PTR start_stab PARAMS ((PTR));
+extern PTR start_stab PARAMS ((PTR, boolean));
 
 extern boolean finish_stab PARAMS ((PTR, PTR));
 
 extern boolean parse_stab PARAMS ((PTR, PTR, int, int, bfd_vma, const char *));
 
+/* Routine used to read IEEE information.  */
+
+extern boolean parse_ieee
+  PARAMS ((PTR, bfd *, const bfd_byte *, bfd_size_type));
+
 #endif
diff --git a/binutils/ieee.c b/binutils/ieee.c
new file mode 100644 (file)
index 0000000..9f95d5c
--- /dev/null
@@ -0,0 +1,2178 @@
+/* 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, &sectype)
+           || ! 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);
+}